pwned.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include <ctype.h>
  2. #include "curl.h"
  3. #include "sha.h"
  4. // https://haveibeenpwned.com/API/v2#SearchingPwnedPasswordsByRange
  5. #define HASH_PREFIX_LENGTH 5
  6. #define HASH_SUFFIX_LENGTH 35
  7. #define BASEURL "https://api.pwnedpasswords.com/range/"
  8. #define BASEURL_SIZE (sizeof BASEURL)
  9. #define URL_SIZE (BASEURL_SIZE + HASH_PREFIX_LENGTH)
  10. char *getURL(const char* hash) {
  11. char *url = malloc(URL_SIZE);
  12. if (url == NULL) return NULL;
  13. snprintf(url, URL_SIZE, "%s%s", BASEURL, hash);
  14. return url;
  15. }
  16. int printNumber(char *text) {
  17. char *part = strchr(text, ':');
  18. if (part == NULL) return 0;
  19. printf("This is how many times your password was pwned: %s\n", part+1);
  20. return 1;
  21. }
  22. int findSuffix(const char *suffix, char *data) {
  23. char *token = strtok(data, "\n");
  24. while (token != NULL) {
  25. if (strncmp(token, suffix, HASH_SUFFIX_LENGTH) == 0) {
  26. if (!printNumber(token)) {
  27. puts("Hash found, but can't obtain the number!");
  28. return 0;
  29. }
  30. return 1;
  31. }
  32. token = strtok(NULL, "\n");
  33. }
  34. return 0;
  35. }
  36. void usage(const char *app) {
  37. printf("Usage:\n%s <password>\n", app);
  38. }
  39. int main(int argc, char **argv) {
  40. if (argc < 2) {
  41. usage(argv[0]);
  42. return 1;
  43. }
  44. char *hash = getHash(argv[1]);
  45. if (hash == NULL) {
  46. puts("Couldn't get hash!");
  47. return 1;
  48. }
  49. char *url = getURL(hash);
  50. if (url == NULL) {
  51. puts("Couldn't get URL!");
  52. return 1;
  53. }
  54. char *data = getData(url);
  55. if (data == NULL) {
  56. puts("Couldn't get data from the API!");
  57. return 1;
  58. }
  59. free(url);
  60. if (!findSuffix(hash+HASH_PREFIX_LENGTH, data)) puts("Password not pwned!");
  61. free(hash);
  62. free(data);
  63. }