* 侵害されたパスワードの確認の追加
* 複数サイトで同じパスワードを利用かどうか、パスワードの長さ、又はパスワードの強さの確認
* パスワードコピーの期間を設定出来る様に
+* ワンタイムパスワード(OTP)を表示せずにコピー機能性の追加
# 1.4.0
* Haiku対応
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() {
} 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);
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);
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
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
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
シンプルなパスワードマネージャー。
\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
#include <openssl/hmac.h>
#include <openssl/sha.h>
+#include <unistd.h>
+
#if defined(__APPLE)
#include <libkern/OSByteOrder.h>
#define htobe64(x) OSSwapHostToBigInt64(x)
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;
if (strncmp(lang, "en", 2) == 0)
perror("Failed to read the GPG file");
else perror("GPGファイルを読込に失敗");
+ gpgme_release(ctx);
exit(1);
}
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);
}
if (strncmp(lang, "en", 2) == 0)
perror("Failed to decrypt the GPG");
else perror("GPGを復号化に失敗");
+ gpgme_release(ctx);
+ gpgme_data_release(in);
exit(1);
}
if (strncmp(lang, "en", 2) == 0)
perror("Failed to get the GPG");
else perror("GPGを受取に失敗");
+ gpgme_data_release(in);
+ gpgme_release(ctx);
exit(1);
}
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);
}
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);
+ }
}
#ifndef OTPPASS_H
#define OTPPASS_H
-void otppass(char* file);
+void otppass(char* file, int isCopy, int copyTimeout);
#endif
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」を実行します。");
// xclipを準備して
FILE *pipe = popen("xclip -selection clipboard", "w");
if (pipe == NULL) {
-
// 掃除
fclose(gpgfile);
free(gpgpath);