pwned.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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_PREFIX_SIZE 6
  7. #define HASH_SUFFIX_LENGTH 35
  8. #define HASH_SUFFIX_SIZE 36
  9. #define URL_SIZE 43
  10. #define BASEURL_SIZE 38
  11. char *getURL(const char* hash) {
  12. const char *baseURL = "https://api.pwnedpasswords.com/range/";
  13. char *url = malloc(URL_SIZE);
  14. if (url == NULL) return NULL;
  15. strncpy(url, baseURL, BASEURL_SIZE);
  16. strncat(url, hash, HASH_PREFIX_LENGTH);
  17. return url;
  18. }
  19. char *getSuffixUppercase(const char *hash) {
  20. char hashSuffix[HASH_SUFFIX_SIZE];
  21. strcpy(hashSuffix, hash+HASH_PREFIX_LENGTH);
  22. char *suffixUpper = malloc(HASH_SUFFIX_SIZE);
  23. if (suffixUpper == NULL) {
  24. puts("Couldn't allocate memory for suffix!");
  25. return NULL;
  26. }
  27. for (int i = 0; i < HASH_SUFFIX_LENGTH; i++) {
  28. int c = hashSuffix[i];
  29. c = toupper(c);
  30. sprintf(suffixUpper+i, "%c", c);
  31. }
  32. suffixUpper[HASH_SUFFIX_LENGTH] = 0;
  33. return suffixUpper;
  34. }
  35. int printNumber(char *text) {
  36. char *state;
  37. char *part = strtok_r(text, ":", &state);
  38. if (part == NULL) return 0;
  39. part = strtok_r(NULL, ":", &state);
  40. if (part != NULL) {
  41. printf("This is how many times your password was pwned: %s\n", part);
  42. return 1;
  43. }
  44. return 0;
  45. }
  46. int findSuffix(const char *suffix, char *data) {
  47. char *token = strtok(data, "\n");
  48. while (token != NULL) {
  49. if (strncmp(token, suffix, HASH_SUFFIX_LENGTH) == 0) {
  50. if (!printNumber(token)) {
  51. puts("Hash found, but can't obtain the number!");
  52. return 0;
  53. }
  54. return 1;
  55. }
  56. token = strtok(NULL, "\n");
  57. }
  58. return 0;
  59. }
  60. void usage(const char *app) {
  61. printf("Usage:\n%s <password>\n", app);
  62. }
  63. int main(int argc, char **argv) {
  64. if (argc < 2) {
  65. usage(argv[0]);
  66. return 1;
  67. }
  68. char *hash = getHash(argv[1]);
  69. if (hash == NULL) {
  70. puts("Couldn't get hash!");
  71. return 1;
  72. }
  73. char *url = getURL(hash);
  74. if (url == NULL) {
  75. puts("Couldn't get URL!");
  76. return 1;
  77. }
  78. char *suffix = getSuffixUppercase(hash);
  79. if (suffix == NULL) {
  80. puts("Couldn't make suffix uppercase!");
  81. return 1;
  82. }
  83. free(hash);
  84. char *data = getData(url);
  85. if (data == NULL) {
  86. puts("Couldn't get data from the API!");
  87. return 1;
  88. }
  89. free(url);
  90. if (!findSuffix(suffix, data)) puts("Password not pwned!");
  91. free(data);
  92. free(suffix);
  93. }