pwned.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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. size_t toCopy = BASEURL_SIZE;
  14. strncpy(url, BASEURL, toCopy);
  15. strncat(url, hash, HASH_PREFIX_LENGTH);
  16. return url;
  17. }
  18. int printNumber(char *text) {
  19. char *part = strchr(text, ':');
  20. if (part == NULL) return 0;
  21. printf("This is how many times your password was pwned: %s\n", part+1);
  22. return 1;
  23. }
  24. int findSuffix(const char *suffix, char *data) {
  25. char *token = strtok(data, "\n");
  26. while (token != NULL) {
  27. if (strncmp(token, suffix, HASH_SUFFIX_LENGTH) == 0) {
  28. if (!printNumber(token)) {
  29. puts("Hash found, but can't obtain the number!");
  30. return 0;
  31. }
  32. return 1;
  33. }
  34. token = strtok(NULL, "\n");
  35. }
  36. return 0;
  37. }
  38. void usage(const char *app) {
  39. printf("Usage:\n%s <password>\n", app);
  40. }
  41. int main(int argc, char **argv) {
  42. if (argc < 2) {
  43. usage(argv[0]);
  44. return 1;
  45. }
  46. char *hash = getHash(argv[1]);
  47. if (hash == NULL) {
  48. puts("Couldn't get hash!");
  49. return 1;
  50. }
  51. char *url = getURL(hash);
  52. if (url == NULL) {
  53. puts("Couldn't get URL!");
  54. return 1;
  55. }
  56. char *data = getData(url);
  57. if (data == NULL) {
  58. puts("Couldn't get data from the API!");
  59. return 1;
  60. }
  61. free(url);
  62. if (!findSuffix(hash+HASH_PREFIX_LENGTH, data)) puts("Password not pwned!");
  63. free(hash);
  64. free(data);
  65. }