]> Nishi Git Mirror - sp.git/commitdiff
ワンタイムパスワード(OTP)を表示せずにコピー機能性の追加 (#31)
author諏訪子 <suwako@076.moe>
Wed, 9 Oct 2024 05:44:11 +0000 (14:44 +0900)
committer諏訪子 <suwako@076.moe>
Wed, 9 Oct 2024 05:44:11 +0000 (14:44 +0900)
CHANGELOG.md
main.c
man/sp-en.1
man/sp-jp.1
src/otppass.c
src/otppass.h
src/yankpass.c

index c06054fe0a71c3ba934613acf88637fd046b9b13..ee0331f1690b332b6e5be4e358ebde4681d9f3f4 100644 (file)
@@ -3,6 +3,7 @@
 * 侵害されたパスワードの確認の追加
 * 複数サイトで同じパスワードを利用かどうか、パスワードの長さ、又はパスワードの強さの確認
 * パスワードコピーの期間を設定出来る様に
+* ワンタイムパスワード(OTP)を表示せずにコピー機能性の追加
 
 # 1.4.0
 * Haiku対応
diff --git a/main.c b/main.c
index 0d1dc41a9869f29bb440ba016add9e109a378ce0..5bc9d07788577afec56483c930b1a8992231ae48 100644 (file)
--- a/main.c
+++ b/main.c
@@ -15,7 +15,7 @@
 
 const char *sofname = "sp";
 const char *version = "1.5.0";
-const char *avalopt = "abcdefgilosvy";
+const char *avalopt = "abcdefgiloOsvy";
 const char *madefor = "simpas 1.1.0";
 
 void usage() {
@@ -113,7 +113,12 @@ 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);
+      otppass(fullPath, 0, 0);
+      free(fullPath);
+    } else if (strcmp(argv[1], "-O") == 0) {
+      char *fullPath = getfullpath(argv[2]);
+      if (fullPath == NULL) return -1;
+      otppass(fullPath, 1, 30);
       free(fullPath);
     } else if (strcmp(argv[1], "-f") == 0) {
       char *fullPath = getfullpath(NULL);
@@ -134,6 +139,13 @@ int main(int argc, char *argv[]) {
       int i;
       if (sscanf(argv[3], "%d", &i) == 0) yankpass(argv[2], 45);
       else yankpass(argv[2], 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]));
+      free(fullPath);
     }
   } else if (argc == 2) {
     char *basePath = getfullpath(NULL);
index 30affba8289cf398409d311b77275a05cc494101..a942e492834d3575b6d78a726021cb64f0992fbe 100644 (file)
@@ -3,7 +3,7 @@
 sp - Simple Password Manager
 .br
 .B sp
-[-bfi] [-i \fI\,gpg-id\fR] [-adeos \fI\,password\fR] [-c \fI,all\fR|\fI,length\fR|\fI,strength\fR|\fI,duplicate\fR] [-g [\fI\,length\fR] [\fI\,secure\fR|\fI\,risk\fR]] [-y \fI\,password\fR [\fI,seconds\fR]]
+[-bfi] [-i \fI\,gpg-id\fR] [-adeos \fI\,password\fR] [-c \fI,all\fR|\fI,length\fR|\fI,strength\fR|\fI,duplicate\fR] [-g [\fI\,length\fR] [\fI\,secure\fR|\fI\,risk\fR]] [-Oy \fI\,password\fR [\fI,seconds\fR]]
 .SH DESCRIPTION
 .PP
 Simple Password Manager
@@ -44,9 +44,13 @@ Initialize password storage using GPG
 Show a list of passwords
 .TP
 \fB\,o\fR \fI\,password\fR
-ワンタイムパスワード(TOTP)を表示
 Show one time password (TOTP)
 .TP
+\fB\,O\fR \fI\,password\fR \fI\,seconds\fR
+Copy one time password (TOTP)
+.br
+The default is 30 seconds.
+.TP
 \fB\,s\fR \fI\,password\fR
 Show password
 .TP
index 94fe122e0de21f69d8aab881bfa416a4d467a9fb..a52d0b7394976a638fb010dd4c296eb2c53534cb 100644 (file)
@@ -3,7 +3,7 @@
 sp - Simple Password Manager
 .br
 .B sp
-[-bfi] [-i \fI\,gpg-id\fR] [-adeos \fI\,password\fR] [-c \fI,all\fR|\fI,length\fR|\fI,strength\fR|\fI,duplicate\fR] [-g [\fI\,length\fR] [\fI\,secure\fR|\fI\,risk\fR]] [-y \fI\,password\fR [\fI,seconds\fR]]
+[-bfi] [-i \fI\,gpg-id\fR] [-adeos \fI\,password\fR] [-c \fI,all\fR|\fI,length\fR|\fI,strength\fR|\fI,duplicate\fR] [-g [\fI\,length\fR] [\fI\,secure\fR|\fI\,risk\fR]] [-Oy \fI\,password\fR [\fI,seconds\fR]]
 .SH 説明
 .PP
 シンプルなパスワードマネージャー。
@@ -46,6 +46,11 @@ GPGと使ってパスワードストレージを初期設定
 \fB\,o\fR \fI\,password\fR
 ワンタイムパスワード(TOTP)を表示
 .TP
+\fB\,O\fR \fI\,password\fR \fI,seconds\fR
+ワンタイムパスワード(TOTP)をコピー
+.br
+デフォルトは30秒です。
+.TP
 \fB\,s\fR \fI\,password\fR
 パスワードを表示
 .TP
index 4d15eb2c160df8ea44f9238293edd495856426e5..34e7126062ed1e0f592f33aee37a77016de9600d 100644 (file)
@@ -1,6 +1,8 @@
 #include <openssl/hmac.h>
 #include <openssl/sha.h>
 
+#include <unistd.h>
+
 #if defined(__APPLE)
 #include <libkern/OSByteOrder.h>
 #define htobe64(x) OSSwapHostToBigInt64(x)
@@ -107,9 +109,19 @@ uint32_t generate_totp(const char *secret, uint64_t counter) {
   return truncated_hash % 1000000;
 }
 
-void otppass(char *file) {
+void otppass(char *file, int isCopy, int copyTimeout) {
+  if (isCopy == 1 && copyTimeout > 300) copyTimeout = 300;
   char *lang = getlang();
 
+  // Xセッションではない場合(例えば、SSH、TTY、Gayland等)、showpass()を実行して
+  if (isCopy == 1 && getenv("DISPLAY") == NULL) {
+    if (strncmp(lang, "en", 2) == 0)
+      puts("There is no X session, so running 'sp -o'.");
+    else puts("Xセッションではありませんので、「sp -o」を実行します。");
+    otppass(file, 0, 0);
+    return;
+  }
+
   gpgme_ctx_t ctx;
   gpgme_error_t err;
   gpgme_data_t in, out;
@@ -129,6 +141,7 @@ void otppass(char *file) {
     if (strncmp(lang, "en", 2) == 0)
       perror("Failed to read the GPG file");
     else perror("GPGファイルを読込に失敗");
+    gpgme_release(ctx);
     exit(1);
   }
 
@@ -137,6 +150,8 @@ void otppass(char *file) {
     if (strncmp(lang, "en", 2) == 0)
       perror("Failed to read the GPG data");
     else perror("GPGデータを読込に失敗");
+    gpgme_release(ctx);
+    gpgme_data_release(in);
     exit(1);
   }
 
@@ -145,6 +160,8 @@ void otppass(char *file) {
     if (strncmp(lang, "en", 2) == 0)
       perror("Failed to decrypt the GPG");
     else perror("GPGを復号化に失敗");
+    gpgme_release(ctx);
+    gpgme_data_release(in);
     exit(1);
   }
 
@@ -153,6 +170,8 @@ void otppass(char *file) {
     if (strncmp(lang, "en", 2) == 0)
       perror("Failed to get the GPG");
     else perror("GPGを受取に失敗");
+    gpgme_data_release(in);
+    gpgme_release(ctx);
     exit(1);
   }
 
@@ -164,7 +183,9 @@ void otppass(char *file) {
     if (strncmp(lang, "en", 2) == 0)
       perror("Failed to decode or export secret");
     else perror("シークレットの抽出又はデコードに失敗しました");
-    free(secret);
+    gpgme_data_release(in);
+    gpgme_release(ctx);
+    gpgme_free(secret);
     exit(1);
   }
 
@@ -179,5 +200,35 @@ void otppass(char *file) {
   gpgme_free(secret);
   free(secret_decoded);
 
-  printf("%06d\n", otp);
+  if (isCopy) {
+    char cmd[64];
+    snprintf(cmd, sizeof(cmd), "echo -n %06d | xclip -selection clipboard", otp);
+    int ret = system(cmd);
+    if (ret != 0) {
+      char *ero = (strncmp(lang, "en", 2) == 0 ?
+          "Failed to copy OTP." : "OTPをコピーに失敗。");
+      fprintf(stderr, "%s\n", ero);
+    }
+
+    // 何(デフォルトは30)秒後、クリップボードから削除する
+    if (strncmp(lang, "en", 2) == 0)
+      printf(
+        "%s\n%s%d%s\n",
+        "Added the one time password to the clipboard.",
+        "After ",
+        copyTimeout,
+        " seconds it'll be deleted from the clipboard."
+      );
+    else
+      printf(
+      "%s\n%d%s\n",
+        "ワンタイムパスワードをクリップボードに追加しました。",
+        copyTimeout,
+        "秒後はクリップボードから取り消されます。"
+      );
+    sleep(copyTimeout);
+    system("echo -n \"\" | xclip -selection clipboard");
+  } else {
+    printf("%06d\n", otp);
+  }
 }
index b916b09db0a98a7bf9300619661f4f715482278a..db96da9dd74c765a16cdb721075de91f69ec33ff 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef OTPPASS_H
 #define OTPPASS_H
 
-void otppass(char* file);
+void otppass(char* file, int isCopy, int copyTimeout);
 
 #endif
index 0851f2c8bb37acb9924302683953e8de072cfcae..6d64ad754947007c38735abdb528318fa9953a88 100644 (file)
@@ -10,7 +10,7 @@ void yankpass(char *file, int copyTimeout) {
   char *lang = getlang();
 
   // Xセッションではない場合(例えば、SSH、TTY、Gayland等)、showpass()を実行して
-  if (getenv("DISPLAY") == NULL) { 
+  if (getenv("DISPLAY") == NULL) {
     if (strncmp(lang, "en", 2) == 0)
       puts("There is no X session, so running 'sp -s'.");
     else puts("Xセッションではありませんので、「sp -s」を実行します。");
@@ -89,7 +89,6 @@ void yankpass(char *file, int copyTimeout) {
   // xclipを準備して
   FILE *pipe = popen("xclip -selection clipboard", "w");
   if (pipe == NULL) {
-
     // 掃除
     fclose(gpgfile);
     free(gpgpath);