+# 1.5.0
+* 侵害されたパスワードの確認の追加
+
# 1.4.0
* Haiku対応
* macOS対応
#include "src/genpass.h"
#include "src/otppass.h"
#include "src/findpass.h"
+#include "src/vulnpass.h"
#include <unistd.h>
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",
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;
#include "common.h"
+
#include <stdio.h>
#include <string.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+#define MAXFINDLEN 1024
char *getbasedir(int trailing) {
char *lang = getlang();
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;
}
newNode->data = strdup(data);
+ if (!newNode->data) {
+ free(newNode);
+ return;
+ }
newNode->next = NULL;
if (list->tail) {
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);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#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));
}
}
#include "common.h"
-void scanDir(const char *dpath, const char *rpath, List *fpaths);
void findpass(const char *dpath, const char *txt);
#endif
gpgme_ctx_t ctx;
gpgme_error_t err;
gpgme_data_t in = NULL, out = NULL;
+ char *gpgpath = NULL;
FILE *gpgfile;
// GPGMEライブラリを設置
// 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");
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);
// 復号化したパスワードを表示する
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");
}
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);
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <dirent.h>
+
+#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);
+}
--- /dev/null
+#ifndef VULNPASS_H
+#define VULNPASS_H
+
+void vulnpass(const char *dpath);
+
+#endif