From f23de329be5382305e93431a94374e8f0552d5be Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E8=AB=8F=E8=A8=AA=E5=AD=90?= Date: Mon, 4 Nov 2024 19:28:20 +0900 Subject: [PATCH] =?utf8?q?=E3=82=B3=E3=83=B3=E3=83=95=E3=82=A3=E3=82=B0?= =?utf8?q?=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=81=AE=E8=BF=BD=E5=8A=A0?= =?utf8?q?=20(#26)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- Makefile | 59 +++++++++++++----- main.c | 27 +++++--- sp.conf | 10 +++ src/addpass.c | 2 - src/chkpass.c | 2 - src/common.c | 165 +++++++++++++++++++++++++++++++++++++++++++++---- src/common.h | 20 +++++- src/delpass.c | 2 - src/genpass.c | 2 - src/initpass.c | 2 - src/listpass.c | 2 - src/otppass.c | 4 -- src/showpass.c | 2 - src/vulnpass.c | 2 - src/yankpass.c | 2 - 15 files changed, 243 insertions(+), 60 deletions(-) create mode 100644 sp.conf diff --git a/Makefile b/Makefile index 7490165..5845c4f 100644 --- a/Makefile +++ b/Makefile @@ -1,19 +1,31 @@ UNAME_S != uname -s UNAME_M != uname -m OS = ${UNAME_S} +ARCH = ${UNAME_M} +FAMILY = "unknown" .if ${UNAME_S} == "OpenBSD" OS = openbsd +FAMILY = bsd .elif ${UNAME_S} == "NetBSD" OS = netbsd +FAMILY = bsd .elif ${UNAME_S} == "FreeBSD" OS = freebsd +FAMILY = bsd .elif ${UNAME_S} == "Linux" OS = linux +FAMILY = linux +.elif ${UNAME_S} == "Haiku" +OS = haiku +FAMILY = beos +.elif ${UNAME_S} == "Darwin" +OS = macos +FAMILY = darwin .endif .if ${UNAME_M} == "x86_64" -UNAME_M = amd64 +ARCH = amd64 .endif NAME != cat main.c | grep "const char \*sofname" | awk '{print $$5}' | \ @@ -21,21 +33,21 @@ NAME != cat main.c | grep "const char \*sofname" | awk '{print $$5}' | \ VERSION != cat main.c | grep "const char \*version" | awk '{print $$5}' | \ sed "s/\"//g" | sed "s/;//" PREFIX = /usr/local -.if ${UNAME_S} == "Haiku" +.if ${OS} == "haiku" PREFIX = /boot/home/config/non-packaged -.elif ${UNAME_S} == "Linux" +.elif ${OS} == "linux" PREFIX = /usr .endif MANPREFIX = ${PREFIX}/share/man -.if ${UNAME_S} == "OpenBSD" +.if ${OS} == "openbsd" MANPREFIX = ${PREFIX}/man -.elif ${UNAME_S} == "Haiku" +.elif ${OS} == "haiku" MANPREFIX = ${PREFIX}/documentation/man .endif DATAPREFIX = ${PREFIX}/share -.if ${UNAME_S} == "Haiku" +.if ${OS} == "haiku" DATAPREFIX = ${PREFIX}/data .endif @@ -43,26 +55,41 @@ CC = cc FILES = main.c src/*.c CFLAGS = -Wall -Wextra -I/usr/include -L/usr/lib -.if ${UNAME_S} == "NetBSD" -CFLAGS += -I/usr/pkg/include -L/usr/pkg/lib -I/usr/local/include -L/usr/local/lib -.elif ${UNAME_S} == "OpenBSD" || ${UNAME_S} == "FreeBSD" +.if ${OS} == "haiku" +CFLAGS += -I/boot/system/develop/headers -L/boot/system/develop/lib +.else +CFLAGS += -I/usr/include -L/usr/lib +.endif + +.if ${OS} == "freebsd" || ${OS} == "openbsd" || ${OS} == "netbsd" || ${OS} == "dragonfly" CFLAGS += -I/usr/local/include -L/usr/local/lib .endif +.if ${OS} == "netbsd" +CFLAGS += -I/usr/pkg/include -L/usr/pkg/lib +.endif +.if ${OS} == "haiku" +LDFLAGS = -lnetwork -lgpgme -lcrypto +.else LDFLAGS = -lgpgme -lcrypto +.endif -.if ${UNAME_S} == "OpenBSD" +.if ${OS} == "openbsd" LDFLAGS += -lc -lassuan -lgpg-error -lintl -liconv -.elif ${UNAME_S} == "FreeBSD" +.elif ${OS} == "freebsd" LDFLAGS += -lc -lassuan -lgpg-error -lthr -lintl -.elif ${UNAME_S} == "NetBSD" +.elif ${OS} == "netbsd" LDFLAGS += -lcrypt -lc -lassuan -lgpg-error -lintl -.elif ${UNAME_S} == "Linux" +.elif ${OS} == "linux" LDFLAGS += -lc -lassuan -lgpg-error .endif all: +.if ${OS} == "haiku" || ${OS} == "macos" + ${CC} -O3 ${CFLAGS} -o ${NAME} ${FILES} ${LDFLAGS} +.else ${CC} -O3 ${CFLAGS} -o ${NAME} ${FILES} -static ${LDFLAGS} +.endif strip ${NAME} debug: @@ -86,10 +113,10 @@ man: release/man/${VERSION}/${NAME}-jp.1 release: - mkdir -p release/bin/${VERSION}/${OS}/${UNAME_M} - ${CC} -O3 ${CFLAGS} -o release/bin/${VERSION}/${OS}/${UNAME_M}/${NAME} ${FILES} \ + mkdir -p release/bin/${VERSION}/${OS}/${ARCH} + ${CC} -O3 ${CFLAGS} -o release/bin/${VERSION}/${OS}/${ARCH}/${NAME} ${FILES} \ -static ${LDFLAGS} - strip release/bin/${VERSION}/${OS}/${UNAME_M}/${NAME} + strip release/bin/${VERSION}/${OS}/${ARCH}/${NAME} install: mkdir -p ${DESTDIR}${PREFIX}/bin ${DESTDIR}${MANPREFIX}/man1 diff --git a/main.c b/main.c index 5bc9d07..374c7ab 100644 --- a/main.c +++ b/main.c @@ -24,8 +24,6 @@ void usage() { } char *getfullpath(char *arg) { - char *lang = getlang(); - char *basedir = getbasedir(1); size_t fullPathLen; char *fullPath; @@ -50,8 +48,6 @@ char *getfullpath(char *arg) { } void editpass(char *file) { - char *lang = getlang(); - #if defined(__HAIKU__) const char *tmpfile = "/boot/system/cache/sp-tmp.gpg"; #else @@ -82,6 +78,9 @@ int main(int argc, char *argv[]) { return 0; } + Config *cf = getconfig(); + lang = getlang(cf); + if (strcmp(argv[1], "-g") == 0) { if (argc > 4) { usage(); @@ -105,7 +104,10 @@ int main(int argc, char *argv[]) { if (pass == NULL) return -1; printf("%s\n", pass); } - else if (strcmp(argv[1], "-y") == 0) yankpass(argv[2], 45); + else if (strcmp(argv[1], "-y") == 0) { + int timeout = (copyTimeFromCnf == 1 ? cnf->passtimeout : 45); + yankpass(argv[2], timeout); + } else if (strcmp(argv[1], "-a") == 0) addpass(argv[2]); else if (strcmp(argv[1], "-d") == 0) delpass(argv[2], 0); else if (strcmp(argv[1], "-e") == 0) { @@ -118,7 +120,8 @@ int main(int argc, char *argv[]) { } else if (strcmp(argv[1], "-O") == 0) { char *fullPath = getfullpath(argv[2]); if (fullPath == NULL) return -1; - otppass(fullPath, 1, 30); + int timeout = (otpTimeFromCnf == 1 ? cnf->otptimeout : 30); + otppass(fullPath, 1, timeout); free(fullPath); } else if (strcmp(argv[1], "-f") == 0) { char *fullPath = getfullpath(NULL); @@ -137,14 +140,18 @@ int main(int argc, char *argv[]) { } else if (argc == 4) { if (strcmp(argv[1], "-y") == 0) { int i; - if (sscanf(argv[3], "%d", &i) == 0) yankpass(argv[2], 45); - else yankpass(argv[2], atoi(argv[3])); + if (sscanf(argv[3], "%d", &i) == 0) + yankpass(argv[2], (copyTimeFromCnf == 1 ? cnf->passtimeout : 45)); + else + yankpass(argv[2], (copyTimeFromCnf == 1 ? cnf->passtimeout : atoi(argv[3]))); } else if (strcmp(argv[1], "-O") == 0) { char *fullPath = getfullpath(argv[2]); if (fullPath == NULL) return -1; int i; - if (sscanf(argv[3], "%d", &i) == 0) otppass(fullPath, 1, 30); - else otppass(fullPath, 1, atoi(argv[3])); + if (sscanf(argv[3], "%d", &i) == 0) + otppass(fullPath, 1, (otpTimeFromCnf == 1 ? cnf->otptimeout : 30)); + else + otppass(fullPath, 1, (otpTimeFromCnf == 1 ? cnf->otptimeout : atoi(argv[3]))); free(fullPath); } } else if (argc == 2) { diff --git a/sp.conf b/sp.conf new file mode 100644 index 0000000..9819f06 --- /dev/null +++ b/sp.conf @@ -0,0 +1,10 @@ +cloud sync username = suwako +cloud sync password = ○○ +cloud sync instance = sp.076.moe +cloud sync enabled = false +simpas show password = false +simpas theme = dark +simpas language = ja +sp timeout password = 45 +sp timeout otp = 30 +sp language = ja diff --git a/src/addpass.c b/src/addpass.c index 4998275..6efe219 100644 --- a/src/addpass.c +++ b/src/addpass.c @@ -37,8 +37,6 @@ void getpasswd(char *prompt, char *pw, size_t pwlen) { } int addpass(char *file) { - char *lang = getlang(); - // パスを準備 char *basedir = getbasedir(1); char *ext = ".gpg"; diff --git a/src/chkpass.c b/src/chkpass.c index cc5f93f..a46be24 100644 --- a/src/chkpass.c +++ b/src/chkpass.c @@ -107,8 +107,6 @@ void chkDupPass(const char *path, const char *pass, char *lang) { } void chkpass(const char *dpath, const char *mode) { - char *lang = getlang(); - if (strncmp(mode, "all", 3) != 0 && strncmp(mode, "length", 6) != 0 && strncmp(mode, "strength", 8) != 0 && strncmp(mode, "duplicate", 9) != 0) { if (strncmp(lang, "en", 2) == 0) diff --git a/src/common.c b/src/common.c index 4253a9d..7fe67c3 100644 --- a/src/common.c +++ b/src/common.c @@ -4,12 +4,157 @@ #include #include #include +#include #define MAXFINDLEN 1024 +char *lang = "ja"; +int langFromCnf; +int copyTimeFromCnf; +int otpTimeFromCnf; +Config *cnf; + +Config *getconfig() { + const char *configpath = getconfigpath(); + if (!configpath) { + return NULL; + } -char *getbasedir(int trailing) { - char *lang = getlang(); + cnf = malloc(sizeof(Config)); + if (!cnf) return NULL; + + strncpy(cnf->syncname, "", sizeof(cnf->syncname) - 1); + strncpy(cnf->syncpass, "", sizeof(cnf->syncpass) - 1); + strncpy(cnf->syncinstance, "", sizeof(cnf->syncinstance) - 1); + cnf->syncenable = 0; + cnf->passtimeout = 45; + cnf->otptimeout = 30; + strncpy(cnf->language, "ja", sizeof(cnf->language) - 1); + + cnf->syncname[sizeof(cnf->syncname) - 1] = '\0'; + cnf->syncpass[sizeof(cnf->syncpass) - 1] = '\0'; + cnf->syncinstance[sizeof(cnf->syncinstance) - 1] = '\0'; + cnf->language[sizeof(cnf->language) - 1] = '\0'; + + FILE *fp = fopen(configpath, "r"); + if (!fp) { + free(cnf); + return NULL; + } + + char line[128]; + while (fgets(line, sizeof(line), fp)) { + if (line[0] == '#' || line[0] == '\n') continue; + const char *p; + + if ((p = strstr(line, "cloud sync username = ")) != NULL) { + sscanf(p + strlen("cloud sync username = "), "%511s", cnf->syncname); + } + + if ((p = strstr(line, "cloud sync password = ")) != NULL) { + sscanf(p + strlen("cloud sync password = "), "%511s", cnf->syncpass); + } + + if ((p = strstr(line, "cloud sync instance = ")) != NULL) { + sscanf(p + strlen("cloud sync instance = "), "%511s", cnf->syncinstance); + } + + if ((p = strstr(line, "cloud sync enabled = true")) != NULL) { + cnf->syncenable = 1; + } + + if ((p = strstr(line, "sp timeout password = ")) != NULL) { + sscanf(p + strlen("sp timeout password = "), "%d", &cnf->passtimeout); + if (cnf->passtimeout != 45) copyTimeFromCnf = 1; + } + + if ((p = strstr(line, "sp timeout otp = ")) != NULL) { + sscanf(p + strlen("sp timeout otp = "), "%d", &cnf->otptimeout); + if (cnf->otptimeout != 30) otpTimeFromCnf = 1; + } + + if ((p = strstr(line, "sp language = ")) != NULL) { + sscanf(p + strlen("sp language = "), "%2s", cnf->language); + if (strncmp(cnf->language, "ja", 2) != 0) langFromCnf = 1; + } + } + + fclose(fp); + + return cnf; +} + +const char *getconfigpath() { +#if defined(_WIN32) + const char *homedir = getenv("HOME"); + + const char *localdata = "\\AppData\\Local\\076\\sp\\sp.conf"; + const char *roamdata = "\\AppData\\Roaming\\076\\sp\\sp.conf"; + const char *sysdata = "C:\\ProgramData\\sp\\sp.conf"; + + if (homedir) { + static char lpath[512]; + static char rpath[512]; + + snprintf(lpath, sizeof(lpath), "%s%s", homedir, localdata); + if (access(lpath, F_OK) != -1) { + return lpath; + } + snprintf(rpath, sizeof(rpath), "%s%s", homedir, roamdata); + if (access(rpath, F_OK) != -1) { + return rpath; + } + } + + if (access(syspath, F_OK) != -1) { + return syspath; + } +#elif defined(__HAIKU__) + const char *cnfpath = "/boot/home/config/settings/sp/sp.conf"; + if (access(cnfpath, F_OK) != -1) { + return cnfpath; + } +#else + const char *homedir = getenv("HOME"); + + const char *userpath = "/.config/sp.conf"; + const char *wrongpath = "/.sp.conf"; + const char *netbsdpath = "/usr/pkg/etc/sp.conf"; + const char *freebsdpath = "/usr/local/etc/sp.conf"; + const char *syspath = "/etc/sp.conf"; + + static char correctuser[512]; + static char incorrectuser[512]; + + if (homedir) { + snprintf(correctuser, sizeof(correctuser), "%s%s", homedir, userpath); + if (access(correctuser, F_OK) != -1) { + return correctuser; + } + + snprintf(incorrectuser, sizeof(incorrectuser), "%s%s", homedir, wrongpath); + if (access(incorrectuser, F_OK) != -1) { + return incorrectuser; + } + } + + if (access(netbsdpath, F_OK) != -1) { + return netbsdpath; + } + + if (access(freebsdpath, F_OK) != -1) { + return freebsdpath; + } + + if (access(syspath, F_OK) != -1) { + return syspath; + } +#endif + + return NULL; +} + +char *getbasedir(int trailing) { char *homedir = getenv("HOME"); if (homedir == NULL) { if (strncmp(lang, "en", 2) == 0) @@ -45,13 +190,13 @@ char *getbasedir(int trailing) { return res; } -char *getlang() { - char *lang = NULL; - - lang = getenv("SP_LANG"); - if (lang == NULL) lang = "ja"; +char *getlang(Config *cf) { + if (langFromCnf == 1) { + return cf->language; + } - return lang; + char *env = getenv("SP_LANG"); + return (env ? env : "ja"); } int mkdir_r(const char *path, mode_t mode) { @@ -134,8 +279,6 @@ void rmext(char *filename) { 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) @@ -263,7 +406,7 @@ void handle_sigint(int sig) { system("echo -n \"\" | xclip -selection clipboard"); } - if (strncmp(getlang(), "en", 2) == 0) { + if (strncmp(lang, "en", 2) == 0) { printf("\nClipboard cleared and program aborted.\n"); } else { printf("\nクリップボードをクリアし、プログラムが中止されました。\n"); diff --git a/src/common.h b/src/common.h index 2e06fd5..557f1c7 100644 --- a/src/common.h +++ b/src/common.h @@ -22,14 +22,32 @@ typedef struct { size_t size; } List; +typedef struct { + char syncname[512]; + char syncpass[512]; + char syncinstance[1024]; + int syncenable; + int passtimeout; + int otptimeout; + char language[3]; +} Config; + +Config *getconfig(); +const char *getconfigpath(); char *getbasedir(int trailing); -char *getlang(); +char *getlang(Config *cf); 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); void handle_sigint(int sig); +extern char *lang; +extern int langFromCnf; +extern int copyTimeFromCnf; +extern int otpTimeFromCnf; +extern Config *cnf; + // C言語のvector void initList(List *list); void addElement(List *list, const char *data); diff --git a/src/delpass.c b/src/delpass.c index 91f5d69..7278679 100644 --- a/src/delpass.c +++ b/src/delpass.c @@ -58,8 +58,6 @@ void freetokens(char **tokens, int numtokens) { } int delpass(char *file, int force) { - char *lang = getlang(); - // パスを準備 char pwfile[512]; char *basedir = getbasedir(1); diff --git a/src/genpass.c b/src/genpass.c index bbd4cab..386bce6 100644 --- a/src/genpass.c +++ b/src/genpass.c @@ -2,8 +2,6 @@ #include "genpass.h" void genpass(int count, bool issecure) { - char *lang = getlang(); - const char *charset_risky = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; const char *charset_secure = diff --git a/src/initpass.c b/src/initpass.c index c73cfb7..d57cffd 100644 --- a/src/initpass.c +++ b/src/initpass.c @@ -2,8 +2,6 @@ #include "initpass.h" void initpass(char *gpgid) { - char *lang = getlang(); - char *basedir = getbasedir(1); if (mkdir_r(basedir, 0755) != 0 && errno != EEXIST) { diff --git a/src/listpass.c b/src/listpass.c index cc2e08f..73afd33 100644 --- a/src/listpass.c +++ b/src/listpass.c @@ -4,8 +4,6 @@ #include "listpass.h" void listpass(char *basePath, int level) { - char *lang = getlang(); - struct dirent *entry; DIR* dir = opendir(basePath); if (!dir) { diff --git a/src/otppass.c b/src/otppass.c index 1124fc1..514a4ef 100644 --- a/src/otppass.c +++ b/src/otppass.c @@ -13,8 +13,6 @@ #include "otppass.h" unsigned char *extract_secret(const char *otpauth_url, size_t *decoded_len) { - char *lang = getlang(); - const char *secret_start = strstr(otpauth_url, "secret="); if (!secret_start) { if (strncmp(lang, "en", 2) == 0) @@ -111,8 +109,6 @@ uint32_t generate_totp(const char *secret, uint64_t counter) { void otppass(char *file, int isCopy, int copyTimeout) { if (isCopy == 1 && copyTimeout > 300) copyTimeout = 300; - char *lang = getlang(); - int isGay = (getenv("WAYLAND_DISPLAY") != NULL); // Xセッションではない場合(例えば、SSH、TTY等)、otppass()を実行して diff --git a/src/showpass.c b/src/showpass.c index 89a4173..2da48c9 100644 --- a/src/showpass.c +++ b/src/showpass.c @@ -18,8 +18,6 @@ void clean_up( } const char *showpass(char *file) { - char *lang = getlang(); - gpgme_ctx_t ctx; gpgme_error_t err; gpgme_data_t in = NULL, out = NULL; diff --git a/src/vulnpass.c b/src/vulnpass.c index 0478092..708f911 100644 --- a/src/vulnpass.c +++ b/src/vulnpass.c @@ -17,8 +17,6 @@ List vulnFullpaths; List vulnDispaths; void vulnpass(const char *dpath) { - char *lang = getlang(); - // pwndサーバに接続 int sock; struct sockaddr_in srv; diff --git a/src/yankpass.c b/src/yankpass.c index c1b5435..74ef77e 100644 --- a/src/yankpass.c +++ b/src/yankpass.c @@ -7,8 +7,6 @@ void yankpass(char *file, int copyTimeout) { if (copyTimeout > 300) copyTimeout = 300; - char *lang = getlang(); - int isGay = (getenv("WAYLAND_DISPLAY") != NULL); // Xセッションではない場合(例えば、SSH、TTY等)、showpass()を実行して -- 2.43.0