pwned.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #include <ctype.h>
  2. #include "curl.h"
  3. #include "sha.h"
  4. // https://haveibeenpwned.com/API/v2#SearchingPwnedPasswordsByRange
  5. #define HASH_PREFIX_SIZE 5
  6. #define HASH_SUFFIX_SIZE 35
  7. #define URL_SIZE 43
  8. char *getURL(const char* hash) {
  9. const char *baseURL = "https://api.pwnedpasswords.com/range/";
  10. char *url = calloc(URL_SIZE, 1);
  11. strncpy(url, baseURL, strlen(baseURL));
  12. strncat(url, hash, HASH_PREFIX_SIZE);
  13. return url;
  14. }
  15. char *getSuffixUppercase(const char *hash) {
  16. char hashSuffix[HASH_SUFFIX_SIZE + 1];
  17. strncpy(hashSuffix, hash+HASH_PREFIX_SIZE, HASH_SUFFIX_SIZE);
  18. char *suffixUpper = malloc(HASH_SUFFIX_SIZE + 1);
  19. if (suffixUpper == NULL) {
  20. puts("Couldn't allocate memory for suffix!");
  21. return NULL;
  22. }
  23. for (int i = 0; i < HASH_SUFFIX_SIZE; i++) {
  24. int c = hashSuffix[i];
  25. c = toupper(c);
  26. sprintf(suffixUpper+i, "%c", c);
  27. }
  28. return suffixUpper;
  29. }
  30. void printNumber(const char *data) {
  31. for (int i = 0; data[i] != '\n'; i++)
  32. putchar(data[i]);
  33. putchar('\n');
  34. }
  35. int findSuffix(const char *suffix, const char *data) {
  36. for (int i = 0; data[i] != 0; i++) {
  37. int j;
  38. for (j = 0; suffix[j] != 0; j++)
  39. if (data[i+j] != suffix[j])
  40. break;
  41. if (suffix[j] == 0 && data[i+j] == ':') {
  42. printf("This is how many times your password was pwned: ");
  43. printNumber(data+i+j+1);
  44. return 1;
  45. }
  46. }
  47. return 0;
  48. }
  49. void usage(const char *app) {
  50. printf("Usage:\n%s <password>\n", app);
  51. }
  52. int main(int argc, char **argv) {
  53. if (argc < 2) {
  54. usage(argv[0]);
  55. return 1;
  56. }
  57. char *hash = getHash(argv[1]);
  58. if (hash == NULL) {
  59. puts("Couldn't get hash!");
  60. return 1;
  61. }
  62. char *url = getURL(hash);
  63. char *suffix = getSuffixUppercase(hash);
  64. if (suffix == NULL) {
  65. puts("Couldn't make suffix uppercase!");
  66. return 1;
  67. }
  68. free(hash);
  69. char *data = getData(url);
  70. if (data == NULL) {
  71. puts("Couldn't get data from the API!");
  72. return 1;
  73. }
  74. free(url);
  75. if (!findSuffix(suffix, data)) puts("Password not pwned!");
  76. free(data);
  77. free(suffix);
  78. }