From: 諏訪子 Date: Sun, 29 Sep 2024 09:42:34 +0000 (+0900) Subject: メモリリークの修正+侵害されたパスワードの確認 #4 X-Git-Url: http://10.11.0.4:5575/?a=commitdiff_plain;h=84dd6539dc3f1646349e439de9d23a7ce2015f41;p=sp.git メモリリークの修正+侵害されたパスワードの確認 #4 --- diff --git a/CHANGELOG.md b/CHANGELOG.md index bcc465c..94c5124 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 1.5.0 +* 侵害されたパスワードの確認の追加 + # 1.4.0 * Haiku対応 * macOS対応 diff --git a/main.c b/main.c index 1c568ee..0c5aebb 100644 --- a/main.c +++ b/main.c @@ -8,13 +8,14 @@ #include "src/genpass.h" #include "src/otppass.h" #include "src/findpass.h" +#include "src/vulnpass.h" #include const char *sofname = "sp"; -const char *version = "1.4.0"; -const char *avalopt = "adefgilosvy"; -const char *madefor = "simpas 1.0.0"; +const char *version = "1.5.0"; +const char *avalopt = "abdefgilosvy"; +const char *madefor = "simpas 1.1.0"; void usage() { printf("%s-%s (%s)\nusage: %s [-%s]\n", @@ -127,10 +128,10 @@ int main(int argc, char *argv[]) { if (basePath == NULL) return -1; if (strcmp(argv[1], "-l") == 0) listpass(basePath, 0); + else if (strcmp(argv[1], "-b") == 0) vulnpass(basePath); else if (strcmp(argv[1], "-v") == 0) { printf("%s-%s (%s)\n", sofname, version, madefor); - } - else { + } else { usage(); free(basePath); return 1; diff --git a/src/common.c b/src/common.c index 928e4f7..58c975e 100644 --- a/src/common.c +++ b/src/common.c @@ -1,6 +1,11 @@ #include "common.h" + #include #include +#include +#include + +#define MAXFINDLEN 1024 char *getbasedir(int trailing) { char *lang = getlang(); @@ -103,6 +108,73 @@ int tmpcopy(const char *inpath, const char *outpath) { return 0; } +#if defined(__linux__) +char *strcasestr(const char *haystack, const char *needle) { + size_t needle_len = strlen(needle); + if (needle_len == 0) { + return (char *)haystack; + } + + while (*haystack) { + if (strncasecmp(haystack, needle, needle_len) == 0) { + return (char *)haystack; + } + haystack++; + } + return NULL; +} +#endif + +void rmext(char *filename) { + char *ext = strrchr(filename, '.'); + if (ext != NULL && strcmp(ext, ".gpg") == 0) { + *ext = '\0'; + } +} + +void scanDir(const char *dpath, const char *rpath, List *fpaths, + List *fullpaths, List *dispaths) { + char *lang = getlang(); + + DIR *dir = opendir(dpath); + if (!dir) { + if (strncmp(lang, "en", 2) == 0) + perror("Could not open directory"); + else perror("ディレクトリを開けられません"); + exit(EXIT_FAILURE); + } + + struct dirent *entry; + while ((entry = readdir(dir)) != NULL) { + const char *name = entry->d_name; + if (strncmp(name, ".", 1) == 0 || strncmp(name, "..", 2) == 0) continue; + + char fpath[MAXFINDLEN]; + snprintf(fpath, sizeof(fpath), "%s/%s", dpath, name); + + struct stat s; + if (stat(fpath, &s) != 0) { + closedir(dir); + return; + } + + if (S_ISDIR(s.st_mode)) { + scanDir(fpath, rpath, fpaths, fullpaths, dispaths); + } else if (strstr(name, ".gpg") != NULL) { + const char *rel = fpath + strlen(rpath) + 1; + addElement(fpaths, rel); + addElement(fullpaths, fpath); + char *disname = strdup(rel); + rmext(disname); + addElement(dispaths, disname); + + free(disname); + } + } + + closedir(dir); +} + void initList(List *list) { list->head = NULL; list->tail = NULL; @@ -116,6 +188,10 @@ void addElement(List *list, const char *data) { } newNode->data = strdup(data); + if (!newNode->data) { + free(newNode); + return; + } newNode->next = NULL; if (list->tail) { diff --git a/src/common.h b/src/common.h index 4b86504..dead7fe 100644 --- a/src/common.h +++ b/src/common.h @@ -25,6 +25,8 @@ char *getbasedir(int trailing); char *getlang(); int mkdir_r(const char *path, mode_t mode); int tmpcopy(const char *inpath, const char *outpath); +void scanDir(const char *dpath, const char *rpath, List *fpaths, + List *fullpaths, List *dispaths); // C言語のvector void initList(List *list); diff --git a/src/findpass.c b/src/findpass.c index 69c5690..698f6c0 100644 --- a/src/findpass.c +++ b/src/findpass.c @@ -4,90 +4,20 @@ #include #include #include -#include -#include -#define MAXFINDLEN 1024 - -List fullpaths; -List dispaths; - -#if defined(__linux__) -char *strcasestr(const char *haystack, const char *needle) { - size_t needle_len = strlen(needle); - if (needle_len == 0) { - return (char *)haystack; - } - - while (*haystack) { - if (strncasecmp(haystack, needle, needle_len) == 0) { - return (char *)haystack; - } - haystack++; - } - return NULL; -} -#endif - -void rmext(char *filename) { - char *ext = strrchr(filename, '.'); - if (ext != NULL && strcmp(ext, ".gpg") == 0) { - *ext = '\0'; - } -} - -void scanDir(const char *dpath, const char *rpath, List *fpaths) { - char *lang = getlang(); - - DIR *dir = opendir(dpath); - if (!dir) { - if (strncmp(lang, "en", 2) == 0) - perror("Could not open directory"); - else perror("ディレクトリを開けられません"); - exit(EXIT_FAILURE); - } - - struct dirent *entry; - while ((entry = readdir(dir)) != NULL) { - const char *name = entry->d_name; - if (strncmp(name, ".", 1) == 0 || strncmp(name, "..", 2) == 0) continue; - - char fpath[MAXFINDLEN]; - snprintf(fpath, sizeof(fpath), "%s/%s", dpath, name); - - struct stat s; - if (stat(fpath, &s) != 0) { - closedir(dir); - return; - } - - if (S_ISDIR(s.st_mode)) { - scanDir(fpath, rpath, fpaths); - } else if (strstr(name, ".gpg") != NULL) { - const char *rel = fpath + strlen(rpath) + 1; - addElement(fpaths, rel); - addElement(&fullpaths, fpath); - char *disname = strdup(rel); - rmext(disname); - addElement(&dispaths, disname); - - free(disname); - } - } - - closedir(dir); -} +List findFullpaths; +List findDispaths; void findpass(const char *dpath, const char *txt) { List fpaths; initList(&fpaths); - initList(&fullpaths); - initList(&dispaths); - scanDir(dpath, dpath, &fpaths); + initList(&findFullpaths); + initList(&findDispaths); + scanDir(dpath, dpath, &fpaths, &findFullpaths, &findDispaths); - for (size_t i = 0; i < dispaths.size; i++) { - if (strcasestr(getElement(&dispaths, i), txt) != NULL) { - printf("%s\n", getElement(&dispaths, i)); + for (size_t i = 0; i < findDispaths.size; i++) { + if (strcasestr(getElement(&findDispaths, i), txt) != NULL) { + printf("%s\n", getElement(&findDispaths, i)); } } diff --git a/src/findpass.h b/src/findpass.h index 7a34761..338cc10 100644 --- a/src/findpass.h +++ b/src/findpass.h @@ -3,7 +3,6 @@ #include "common.h" -void scanDir(const char *dpath, const char *rpath, List *fpaths); void findpass(const char *dpath, const char *txt); #endif diff --git a/src/showpass.c b/src/showpass.c index 713d362..e1b09c1 100644 --- a/src/showpass.c +++ b/src/showpass.c @@ -23,6 +23,7 @@ const char *showpass(char *file) { gpgme_ctx_t ctx; gpgme_error_t err; gpgme_data_t in = NULL, out = NULL; + char *gpgpath = NULL; FILE *gpgfile; // GPGMEライブラリを設置 @@ -41,12 +42,19 @@ const char *showpass(char *file) { // OpenPGPプロトコールを設定 gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP); + if (err) { + if (strncmp(lang, "en", 2) == 0) + fprintf(stderr, "Failed to set OpenPGP protocol: %s\n", gpgme_strerror(err)); + else fprintf(stderr, "OpenPGP付トロコールの設置に失敗:%s\n", gpgme_strerror(err)); + clean_up(ctx, in, out, gpgfile, gpgpath); + return NULL; + } // 暗号化したタイルを開く char *basedir = getbasedir(1); char *ext = ".gpg"; int alllen = snprintf(NULL, 0, "%s%s%s", basedir, file, ext) + 1; - char *gpgpath = malloc(alllen); + gpgpath = malloc(alllen); if (gpgpath == NULL) { if (strncmp(lang, "en", 2) == 0) perror("Failed to allocate memeory"); @@ -92,8 +100,10 @@ const char *showpass(char *file) { err = gpgme_op_decrypt(ctx, in, out); if (err) { if (strncmp(lang, "en", 2) == 0) - fprintf(stderr, "Failed to decrypt: %s\n", gpgme_strerror(err)); - else fprintf(stderr, "復号化に失敗: %s\n", gpgme_strerror(err)); + fprintf(stderr, "Failed to decrypt: %s (source: %s)\n", + gpgme_strerror(err), gpgme_strsource(err)); + else fprintf(stderr, "復号化に失敗: %s (元: %s)\n", + gpgme_strerror(err), gpgme_strsource(err)); // 掃除 clean_up(ctx, in, out, gpgfile, gpgpath); @@ -102,8 +112,10 @@ const char *showpass(char *file) { // 復号化したパスワードを表示する gpgme_data_seek(out, 0, SEEK_SET); + size_t bufsize = 512; + size_t totsize = 0; char buffer[512]; - char *res = malloc(512 * sizeof(char)); + char *res = malloc(bufsize); if (res == NULL) { if (strncmp(lang, "en", 2) == 0) perror("Failed to allocate memory"); @@ -113,15 +125,22 @@ const char *showpass(char *file) { } ssize_t read_bytes; - int i = 0; while ((read_bytes = gpgme_data_read(out, buffer, sizeof(buffer) - 1)) > 0) { - memcpy(res + i, buffer, read_bytes); - i += read_bytes; + if (totsize + read_bytes >= bufsize) { + bufsize *= 2; + res = realloc(res, bufsize); + if (res == NULL) { + perror("Failed to reallocate memory"); + clean_up(ctx, in, out, gpgfile, gpgpath); + return NULL; + } + } + memcpy(res + totsize, buffer, read_bytes); + totsize += read_bytes; } - res[i] = '\0'; - if (res[i-1] == '\n') res[i-1] = '\0'; + res[totsize] = '\0'; // 掃除 clean_up(ctx, in, out, gpgfile, gpgpath); diff --git a/src/vulnpass.c b/src/vulnpass.c new file mode 100644 index 0000000..0478092 --- /dev/null +++ b/src/vulnpass.c @@ -0,0 +1,141 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vulnpass.h" +#include "showpass.h" +#include "common.h" + +List vulnFullpaths; +List vulnDispaths; + +void vulnpass(const char *dpath) { + char *lang = getlang(); + + // pwndサーバに接続 + int sock; + struct sockaddr_in srv; + struct addrinfo hints, *addr; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + + int status = getaddrinfo("076.moe", NULL, &hints, &addr); + if (status != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status)); + return; + } + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == -1) { + const char *ero = strncmp(lang, "en", 2) == 0 ? + "Failed to create socket" : "ソケットを作成に失敗"; + perror(ero); + return; + } + + srv.sin_addr = ((struct sockaddr_in *)(addr->ai_addr))->sin_addr; + srv.sin_family = AF_INET; + srv.sin_port = htons(9951); + + freeaddrinfo(addr); + + if (connect(sock, (struct sockaddr *)&srv, sizeof(srv)) < 0) { + const char *ero = strncmp(lang, "en", 2) == 0 ? "Failed to connect" : "接続に失敗"; + perror(ero); + close(sock); + return; + } + + // パスワードをスキャンして + List fpaths; + initList(&fpaths); + initList(&vulnFullpaths); + initList(&vulnDispaths); + scanDir(dpath, dpath, &fpaths, &vulnFullpaths, &vulnDispaths); + int vulncount = 0; + + puts(strncmp(lang, "en", 2) == 0 ? + "Checking, please wait for a while..." : "確認中。暫くお待ち下さい・・・"); + + for (size_t i = 0; i < vulnDispaths.size; i++) { + const char *pass = showpass(getElement(&vulnDispaths, i)); + if (!pass) continue; + char res[256]; + int reslen = 0; + + if (send(sock, pass, strlen(pass), 0) < 0) { + const char *ero = strncmp(lang, "en", 2) == 0 ? + "Failed to send" : "送信に失敗"; + perror(ero); + close(sock); + freeList(&fpaths); + return; + } + + reslen = recv(sock, res, sizeof(res) -1, 0); + if (reslen < 0) { + const char *ero = strncmp(lang, "en", 2) == 0 ? + "Failed to retreive" : "受取に失敗"; + perror(ero); + close(sock); + freeList(&fpaths); + return; + } + + res[reslen] = '\0'; + + if (strncmp(res, "0", 1) != 0) { + printf("【!】"); + if (strncmp(lang, "en", 2) == 0) { + printf("The password \"%s\" has been breached %d times.\n", + getElement(&vulnDispaths, i), atoi(res)); + } else { + printf("パスワード「%s」は%d回に漏洩されました。\n", + getElement(&vulnDispaths, i), atoi(res)); + } + + vulncount++; + } + + close(sock); + + // 再接続 + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == -1) { + const char *ero = strncmp(lang, "en", 2) == 0 ? + "Failed to create socket" : "ソケットを作成に失敗"; + perror(ero); + return; + } + + if (connect(sock, (struct sockaddr *)&srv, sizeof(srv)) < 0) { + const char *ero = strncmp(lang, "en", 2) == 0 ? + "Failed to reconnect" : "再接続に失敗"; + perror(ero); + close(sock); + return; + } + } + + if (strncmp(lang, "en", 2) == 0) { + printf("\nTotal breached: %d\n", vulncount); + if (vulncount > 0) + printf("It's advised to change any of the breached " + "passwords as soon as possible!\n"); + } else { + printf("\n漏洩したパスワードの合計: %d\n", vulncount); + if (vulncount > 0) + printf("漏洩したパスワードは出来るだけ早く変更する事をお勧めします!\n"); + } + + freeList(&fpaths); +} diff --git a/src/vulnpass.h b/src/vulnpass.h new file mode 100644 index 0000000..f87f2e6 --- /dev/null +++ b/src/vulnpass.h @@ -0,0 +1,6 @@ +#ifndef VULNPASS_H +#define VULNPASS_H + +void vulnpass(const char *dpath); + +#endif