コミットを比較
11 コミット
作成者 | SHA1 | 日付 |
---|---|---|
守矢諏訪子 | ffa3590ec7 | |
守矢諏訪子 | 53a5739fa4 | |
守矢諏訪子 | 3976c11d91 | |
守矢諏訪子 | a4f76ab2d9 | |
守矢諏訪子 | e0d792f5c3 | |
守矢諏訪子 | a7d6f12c46 | |
守矢諏訪子 | 330722bb68 | |
守矢諏訪子 | f68a09c490 | |
守矢諏訪子 | 55543618e5 | |
守矢諏訪子 | c42f23f79f | |
守矢諏訪子 | 000e111406 |
15
CHANGELOG.md
15
CHANGELOG.md
|
@ -1,3 +1,18 @@
|
|||
# 1.2.0
|
||||
* やっとTOTP機能性を修正した
|
||||
* makeを実行したら、バイナリがもっと小さくなる
|
||||
* パスワードの長さの延長
|
||||
* パスワード追加機能性で、パスワードが既に存在するかどうか確認
|
||||
* パスワード削除機能性で、パスワードが存在ないかどうか確認
|
||||
* パスワード変更機能性の追加
|
||||
* zsh対応の修正
|
||||
|
||||
# 1.1.2
|
||||
* OpenBSDでのコンパイラーが発生された問題を修正した
|
||||
|
||||
# 1.1.1
|
||||
* make install-zsh部分を修正
|
||||
|
||||
# 1.1.0
|
||||
* TOTP対応
|
||||
* READMEファイルで使い方を詳しく説明する
|
||||
|
|
23
Makefile
23
Makefile
|
@ -1,14 +1,25 @@
|
|||
NAME=sp
|
||||
VERSION=1.1.0
|
||||
# Linux、Haiku、かIllumos = /usr、FreeBSDかOpenBSD = /usr/local、NetBSD = /usr/pkg
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
NAME := $(shell cat main.c | grep "const char\* sofname" | awk '{print $$5}' | sed "s/\"//g" | sed "s/;//" )
|
||||
VERSION := $(shell cat main.c | grep "const char\* version" | awk '{print $$5}' | sed "s/\"//g" | sed "s/;//" )
|
||||
PREFIX=/usr
|
||||
ifeq ($(UNAME_S),FreeBSD)
|
||||
PREFIX=/usr/local
|
||||
endif
|
||||
ifeq ($(UNAME_S),OpenBSD)
|
||||
PREFIX=/usr/local
|
||||
endif
|
||||
ifeq ($(UNAME_S),NetBSD)
|
||||
PREFIX=/usr/pkg
|
||||
endif
|
||||
CC=cc
|
||||
FILES=main.c showpass.c yankpass.c addpass.c delpass.c listpass.c genpass.c initpass.c otppass.c
|
||||
CFLAGS=-Wall -Wextra -g
|
||||
FILES=main.c showpass.c yankpass.c addpass.c delpass.c listpass.c genpass.c initpass.c otppass.c base32.c
|
||||
CFLAGS=-Wall -Wextra -O3 -I${PREFIX}/include -L${PREFIX}/lib
|
||||
LDFLAGS=-lgpgme -lcrypto
|
||||
|
||||
all:
|
||||
${CC} ${CFLAGS} -o ${NAME} ${FILES} ${LDFLAGS}
|
||||
strip ${NAME}
|
||||
|
||||
clean:
|
||||
rm -f ${NAME}
|
||||
|
@ -27,7 +38,7 @@ install: all
|
|||
chmod 755 ${DESTDIR}${PREFIX}/bin/${NAME}
|
||||
|
||||
install-zsh:
|
||||
cp sp-completion.zsh /usr/share/zsh/site-functions/_sp
|
||||
cp sp-completion.zsh ${DESTDIR}${PREFIX}/share/zsh/site-functions/_sp
|
||||
|
||||
uninstall:
|
||||
rm -f ${DESTDIR}${PREFIX}/bin/${NAME}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
```sh
|
||||
doas prt-get depinst gpgme gnupg pinentry
|
||||
doas make install
|
||||
doas make install-zsh
|
||||
```
|
||||
|
||||
又は
|
||||
|
@ -23,18 +24,21 @@ prt-get depinst sp
|
|||
```sh
|
||||
doas pacman -S base-devel gpgme gnupg pinentry
|
||||
doas make install
|
||||
doas make install-zsh
|
||||
```
|
||||
|
||||
### OpenBSD
|
||||
```sh
|
||||
doas pkg_add gmake gpgme gnupg pinentry
|
||||
doas gmake install PREFIX=/usr/local
|
||||
doas gmake install-zsh PREFIX=/usr/local
|
||||
```
|
||||
|
||||
### FreeBSD
|
||||
```sh
|
||||
doas pkg install gmake gpgme gnupg pinentry
|
||||
doas gmake install PREFIX=/usr/local
|
||||
doas gmake install-zsh PREFIX=/usr/local
|
||||
```
|
||||
|
||||
## 初期設定
|
||||
|
|
45
addpass.c
45
addpass.c
|
@ -74,8 +74,34 @@ void getpasswd(char* prompt, char*pw, size_t pwlen) {
|
|||
}
|
||||
|
||||
void addpass(char* file) {
|
||||
char pass[100];
|
||||
char knin[100];
|
||||
// パスを準備
|
||||
char* homedir = getenv("HOME");
|
||||
if (homedir == NULL) {
|
||||
perror("ホームディレクトリを受取に失敗。");
|
||||
return;
|
||||
}
|
||||
|
||||
char* basedir = "/.local/share/sp/";
|
||||
char* ext = ".gpg";
|
||||
|
||||
char pass[256];
|
||||
char knin[256];
|
||||
|
||||
int alllen = snprintf(NULL, 0, "%s%s%s%s", homedir, basedir, file, ext) + 1;
|
||||
char* gpgpathchk = malloc(alllen);
|
||||
if (gpgpathchk == NULL) {
|
||||
perror("メモリを割当に失敗。");
|
||||
return;
|
||||
}
|
||||
|
||||
// ファイルが既に存在するかどうか確認
|
||||
snprintf(gpgpathchk, alllen, "%s%s%s%s", homedir, basedir, file, ext);
|
||||
if (access(gpgpathchk, F_OK) != -1) {
|
||||
fprintf(stderr, "パスワードが既に存在しています。\n変更するには、「 sp -e %s 」を実行して下さい。\n", file);
|
||||
free(gpgpathchk);
|
||||
return;
|
||||
}
|
||||
free(gpgpathchk);
|
||||
|
||||
// パスワードを受け取る
|
||||
getpasswd("パスワード: ", pass, sizeof(pass));
|
||||
|
@ -126,16 +152,6 @@ void addpass(char* file) {
|
|||
|
||||
gpgme_data_new(&out);
|
||||
|
||||
// パスを準備
|
||||
char* homedir = getenv("HOME");
|
||||
if (homedir == NULL) {
|
||||
perror("ホームディレクトリを受取に失敗。");
|
||||
return;
|
||||
}
|
||||
|
||||
char* basedir = "/.local/share/sp/";
|
||||
char* ext = ".gpg";
|
||||
|
||||
// 鍵を受け取る
|
||||
char keypath[256];
|
||||
snprintf(keypath, sizeof(keypath), "%s%s%s", homedir, basedir, ".gpg-id");
|
||||
|
@ -148,8 +164,8 @@ void addpass(char* file) {
|
|||
return;
|
||||
}
|
||||
|
||||
char* keyid = malloc(100);
|
||||
if (!fgets(keyid, 100, keyfile)) {
|
||||
char* keyid = malloc(256);
|
||||
if (!fgets(keyid, 256, keyfile)) {
|
||||
perror("鍵IDを読込に失敗。");
|
||||
fclose(keyfile);
|
||||
free(keyid);
|
||||
|
@ -183,7 +199,6 @@ void addpass(char* file) {
|
|||
}
|
||||
|
||||
// 暗号化したタイルを開く
|
||||
int alllen = snprintf(NULL, 0, "%s%s%s%s", homedir, basedir, file, ext) + 1;
|
||||
char* gpgpath = malloc(alllen);
|
||||
if (gpgpath == NULL) {
|
||||
cleanup(ctx, key[0], in, out);
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
#include "base32.h"
|
||||
|
||||
int char_to_val(char c) {
|
||||
const char *base32_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||
char *ptr = strchr(base32_alphabet, c);
|
||||
return ptr ? ptr - base32_alphabet : -1;
|
||||
}
|
||||
|
||||
unsigned char *base32_decode(const char *encoded, size_t *out_len) {
|
||||
size_t encoded_len = strlen(encoded);
|
||||
size_t padding = 0;
|
||||
for (int i = encoded_len - 1; i >= 0 && encoded[i] == '='; --i) {
|
||||
++padding;
|
||||
}
|
||||
|
||||
*out_len = (encoded_len - padding) * 5 / 8;
|
||||
if (*out_len == 0) return NULL;
|
||||
|
||||
unsigned char *decoded = malloc(*out_len);
|
||||
if (!decoded) return NULL;
|
||||
|
||||
int buffer = 0, bits_left = 0, count = 0;
|
||||
for (size_t i = 0; i < encoded_len - padding; ++i) {
|
||||
int val = char_to_val(encoded[i]);
|
||||
if (val < 0) {
|
||||
free(decoded);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer <<= 5;
|
||||
buffer |= val;
|
||||
bits_left += 5;
|
||||
|
||||
if (bits_left >= 8) {
|
||||
decoded[count++] = (unsigned char) (buffer >> (bits_left - 8));
|
||||
bits_left -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
*out_len = count;
|
||||
return decoded;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef BASE32_H
|
||||
#define BASE32_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
unsigned char *base32_decode(const char *encoded, size_t *out_len);
|
||||
|
||||
#endif
|
41
delpass.c
41
delpass.c
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "delpass.h"
|
||||
|
||||
int delpass(char* file) {
|
||||
int delpass(char* file, int force) {
|
||||
// パスを準備
|
||||
char pwfile[512];
|
||||
char* homedir = getenv("HOME");
|
||||
|
@ -15,6 +15,23 @@ int delpass(char* file) {
|
|||
|
||||
char* basedir = "/.local/share/sp/";
|
||||
char* ext = ".gpg";
|
||||
|
||||
int alllen = snprintf(NULL, 0, "%s%s%s%s", homedir, basedir, file, ext) + 1;
|
||||
char* gpgpathchk = malloc(alllen);
|
||||
if (gpgpathchk == NULL) {
|
||||
perror("メモリを割当に失敗。");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ファイルが既に存在するかどうか確認
|
||||
snprintf(gpgpathchk, alllen, "%s%s%s%s", homedir, basedir, file, ext);
|
||||
if (access(gpgpathchk, F_OK) != 0) {
|
||||
fprintf(stderr, "パスワードが存在しません。\n");
|
||||
free(gpgpathchk);
|
||||
return -1;
|
||||
}
|
||||
free(gpgpathchk);
|
||||
|
||||
int needed = snprintf(pwfile, sizeof(pwfile), "%s%s%s%s", homedir, basedir, file, ext);
|
||||
if (needed >= (int)sizeof(pwfile)) {
|
||||
fprintf(stderr, "エラー:パスが長すぎる。\n");
|
||||
|
@ -22,21 +39,25 @@ int delpass(char* file) {
|
|||
}
|
||||
|
||||
// 削除を確認する
|
||||
printf("パスワード「%s」を本当に削除する事が宜しいでしょうか? (y/N): ", file);
|
||||
int confirm = getchar();
|
||||
if (confirm != 'y' && confirm != 'Y') {
|
||||
printf("削除しませんでした。\n");
|
||||
return -1;
|
||||
}
|
||||
if (force == 0) { // パスワードの変更のばあい、確認は不要
|
||||
printf("パスワード「%s」を本当に削除する事が宜しいでしょうか? (y/N): ", file);
|
||||
int confirm = getchar();
|
||||
if (confirm != 'y' && confirm != 'Y') {
|
||||
printf("削除しませんでした。\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ch;
|
||||
while ((ch = getchar()) != '\n' && ch != EOF);
|
||||
int ch;
|
||||
while ((ch = getchar()) != '\n' && ch != EOF);
|
||||
}
|
||||
|
||||
if (unlink(pwfile) == -1) {
|
||||
perror("パスワードを削除出来ませんですた。");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (force == 1) return 0;
|
||||
|
||||
printf("パスワードを削除しました。\n");
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef DELPASS_H
|
||||
#define DELPASS_H
|
||||
|
||||
int delpass(char* file);
|
||||
int delpass(char* file, int force);
|
||||
|
||||
#endif
|
||||
|
|
29
main.c
29
main.c
|
@ -16,18 +16,19 @@
|
|||
void helpme();
|
||||
|
||||
const char* sofname = "sp";
|
||||
const char* version = "1.1.0";
|
||||
const char* version = "1.2.0";
|
||||
|
||||
void helpme() {
|
||||
printf("076 sp - シンプルなパスワードマネージャー\n");
|
||||
printf("https://076.moe/ | https://gitler.moe/suwako/sp\n\n");
|
||||
printf("使い方:\n");
|
||||
printf("076 %s %s - シンプルなパスワードマネージャー\n", sofname, version);
|
||||
printf("https://076.moe/ | https://gitler.moe/suwako/%s\n\n", sofname);
|
||||
puts ("使い方:\n");
|
||||
printf("%s -i <gpg-id> :GPGと使ってパスワードストレージを初期設定\n", sofname);
|
||||
printf("%s -s <パスワード名> :パスワードを表示\n", sofname);
|
||||
printf("%s -y <パスワード名> :パスワードを表示せずクリップボードにコピーする\n", sofname);
|
||||
printf("%s -l :パスワード一覧を表示\n", sofname);
|
||||
printf("%s -a <パスワード名> :パスワードを追加\n", sofname);
|
||||
printf("%s -d <パスワード名> :パスワードを削除\n", sofname);
|
||||
printf("%s -e <パスワード名> :パスワードを変更\n", sofname);
|
||||
printf("%s -g <文字数> [risk|secure] :希望文字数でパスワードをランダムに作成する。risk=英数字のみ(不安)、secure=英数字+特別文字(デフォルト)を使用\n", sofname);
|
||||
printf("%s -o <パスワード名>\n :ワンタイムパスワード(TOTP)を表示。存在しなければ、創作する\n", sofname);
|
||||
printf("%s -h :ヘルプを表示\n", sofname);
|
||||
|
@ -57,14 +58,30 @@ int main (int argc, char* argv[]) {
|
|||
listpass(basePath, 0);
|
||||
}
|
||||
else if (argc == 3 && strcmp(argv[1], "-a") == 0) addpass(argv[2]);
|
||||
else if (argc == 3 && strcmp(argv[1], "-d") == 0) delpass(argv[2]);
|
||||
else if (argc == 3 && strcmp(argv[1], "-d") == 0) delpass(argv[2], 0);
|
||||
else if (argc == 3 && strcmp(argv[1], "-e") == 0) {
|
||||
delpass(argv[2], 1);
|
||||
addpass(argv[2]);
|
||||
}
|
||||
else if (strcmp(argv[1], "-g") == 0) {
|
||||
if (argc == 3) genpass(atoi(argv[2]), true);
|
||||
else if (argc == 4 && strcmp(argv[3], "risk") == 0) genpass(atoi(argv[2]), false);
|
||||
else if (argc == 4 && strcmp(argv[3], "secure") == 0) genpass(atoi(argv[2]), true);
|
||||
else helpme();
|
||||
}
|
||||
else if (argc == 3 && strcmp(argv[1], "-o") == 0) otppass(argv[2]);
|
||||
else if (argc == 3 && strcmp(argv[1], "-o") == 0) {
|
||||
char fullPath[512];
|
||||
char* homedir = getenv("HOME");
|
||||
if (homedir == NULL) {
|
||||
perror("ホームディレクトリを受取に失敗。");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* basedir = "/.local/share/sp/";
|
||||
snprintf(fullPath, sizeof(fullPath), "%s%s%s.gpg", homedir, basedir, argv[2]);
|
||||
|
||||
otppass(fullPath);
|
||||
}
|
||||
else if (argc == 2 && strcmp(argv[1], "-v") == 0) printf("%s-%s\n", sofname, version);
|
||||
else helpme();
|
||||
|
||||
|
|
131
otppass.c
131
otppass.c
|
@ -1,26 +1,123 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <gpgme.h>
|
||||
|
||||
unsigned long generate_totp(const unsigned char* secret, size_t keylen) {
|
||||
unsigned long timestep = time(NULL) / 30;
|
||||
unsigned char hmacres[20];
|
||||
#include "base32.h"
|
||||
#include "otppass.h"
|
||||
|
||||
HMAC(EVP_sha1(), secret, keylen, (unsigned char*)×tep, sizeof(timestep), hmacres, NULL);
|
||||
unsigned char* extract_secret(const char* otpauth_url, size_t* decoded_len) {
|
||||
const char* secret_start = strstr(otpauth_url, "secret=");
|
||||
if (!secret_start) {
|
||||
fprintf(stderr, "OTPAuth URLの中に、シークレットを見つけられませんでした。\n");
|
||||
return NULL;
|
||||
}
|
||||
secret_start += 7;
|
||||
|
||||
int offset = hmacres[19] & 0xF;
|
||||
unsigned long trunhash = (hmacres[offset] & 0x7F) << 24 |
|
||||
(hmacres[offset + 1] & 0xFF) << 16 |
|
||||
(hmacres[offset + 2] & 0xFF) << 8 |
|
||||
(hmacres[offset + 3] & 0xFF);
|
||||
|
||||
unsigned long otp = trunhash % 1000000;
|
||||
return otp;
|
||||
const char* secret_end = strchr(secret_start, '&');
|
||||
if (!secret_end) {
|
||||
if (secret_start[0] != '\0') {
|
||||
secret_end = secret_start + strlen(secret_start);
|
||||
} else {
|
||||
secret_end = secret_start;
|
||||
}
|
||||
}
|
||||
|
||||
if (secret_end < secret_start) {
|
||||
fprintf(stderr, "不正なシークレットの距離。\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t secret_len = secret_end - secret_start;
|
||||
char* secret_encoded = (char*)malloc(secret_len + 1);
|
||||
|
||||
if (secret_encoded == NULL) {
|
||||
fprintf(stderr, "メモリの役割に失敗。\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strncpy(secret_encoded, secret_start, secret_len);
|
||||
secret_encoded[secret_len] = '\0';
|
||||
|
||||
unsigned char* secret_decoded = base32_decode(secret_encoded, decoded_len);
|
||||
free(secret_encoded);
|
||||
|
||||
if (!secret_decoded) {
|
||||
fprintf(stderr, "BASE32の復号化に失敗。\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return secret_decoded;
|
||||
}
|
||||
|
||||
uint32_t generate_totp(const char *secret, uint64_t counter) {
|
||||
counter = htobe64(counter);
|
||||
|
||||
unsigned char hash[SHA_DIGEST_LENGTH];
|
||||
HMAC(EVP_sha1(), secret, strlen(secret), (unsigned char *)&counter, sizeof(counter), hash, NULL);
|
||||
|
||||
int offset = hash[SHA_DIGEST_LENGTH - 1] & 0x0F;
|
||||
uint32_t truncated_hash =
|
||||
(hash[offset] & 0x7F) << 24 |
|
||||
(hash[offset + 1] & 0xFF) << 16 |
|
||||
(hash[offset + 2] & 0xFF) << 8 |
|
||||
(hash[offset + 3] & 0xFF);
|
||||
|
||||
return truncated_hash % 1000000;
|
||||
}
|
||||
|
||||
void otppass(char* file) {
|
||||
const char* secret = file;
|
||||
unsigned long otp = generate_totp((unsigned char*)secret, strlen(secret));
|
||||
printf("%06lu\n", otp);
|
||||
gpgme_ctx_t ctx;
|
||||
gpgme_error_t err;
|
||||
gpgme_data_t in, out;
|
||||
size_t secret_len;
|
||||
|
||||
gpgme_check_version(NULL);
|
||||
err = gpgme_new(&ctx);
|
||||
if (err) {
|
||||
fprintf(stderr, "GPGMEを創作に失敗\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
err = gpgme_data_new_from_file(&in, file, 1);
|
||||
if (err) {
|
||||
fprintf(stderr, "GPGファイルを読込に失敗\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
err = gpgme_data_new(&out);
|
||||
if (err) {
|
||||
fprintf(stderr, "GPGデータを読込に失敗\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
err = gpgme_op_decrypt(ctx, in, out);
|
||||
if (err) {
|
||||
fprintf(stderr, "GPGを復号化に失敗\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char* secret = gpgme_data_release_and_get_mem(out, &secret_len);
|
||||
if (!secret) {
|
||||
fprintf(stderr, "GPGを受取に失敗\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
size_t decoded_len;
|
||||
unsigned char* secret_decoded = extract_secret(secret, &decoded_len);
|
||||
if (!secret_decoded) {
|
||||
fprintf(stderr, "シークレットの抽出またはデコードに失敗しました\n");
|
||||
free(secret);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
time_t current_time = time(NULL);
|
||||
uint64_t counter = current_time / 30;
|
||||
uint32_t otp = generate_totp((const char*)secret_decoded, counter);
|
||||
printf("%06d\n", otp);
|
||||
|
||||
gpgme_data_release(in);
|
||||
gpgme_release(ctx);
|
||||
free(secret);
|
||||
free(secret_decoded);
|
||||
}
|
||||
|
|
14
showpass.c
14
showpass.c
|
@ -18,7 +18,7 @@ void clean_up(gpgme_ctx_t ctx, gpgme_data_t in, gpgme_data_t out, FILE* gpgfile,
|
|||
void showpass(char* file) {
|
||||
gpgme_ctx_t ctx;
|
||||
gpgme_error_t err;
|
||||
gpgme_data_t in, out;
|
||||
gpgme_data_t in = NULL, out = NULL;
|
||||
FILE *gpgfile;
|
||||
|
||||
// GPGMEライブラリを設置
|
||||
|
@ -52,7 +52,7 @@ void showpass(char* file) {
|
|||
return;
|
||||
}
|
||||
|
||||
sprintf(gpgpath, "%s%s%s%s", homedir, basedir, file, ext);
|
||||
snprintf(gpgpath, alllen, "%s%s%s%s", homedir, basedir, file, ext);
|
||||
gpgfile = fopen(gpgpath, "rb");
|
||||
if (gpgfile == NULL) {
|
||||
perror("ファイルを開くに失敗。");
|
||||
|
@ -61,7 +61,15 @@ void showpass(char* file) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (gpgme_data_new_from_stream(&in, gpgfile) != GPG_ERR_NO_ERROR || gpgme_data_new(&out) != GPG_ERR_NO_ERROR) {
|
||||
// ファイルからinデータオブジェクトを創作
|
||||
if (gpgme_data_new_from_stream(&in, gpgfile) != GPG_ERR_NO_ERROR) {
|
||||
fprintf(stderr, "GPGMEデータオブジェクトを創作に失敗。\n");
|
||||
clean_up(ctx, in, out, gpgfile, gpgpath);
|
||||
return;
|
||||
}
|
||||
|
||||
// outデータオブジェクトを創作
|
||||
if (gpgme_data_new(&out) != GPG_ERR_NO_ERROR) {
|
||||
fprintf(stderr, "GPGMEデータオブジェクトを創作に失敗。\n");
|
||||
clean_up(ctx, in, out, gpgfile, gpgpath);
|
||||
return;
|
||||
|
|
|
@ -1,28 +1,48 @@
|
|||
# compdef sp
|
||||
#compdef sp
|
||||
#autoload
|
||||
|
||||
_sp () {
|
||||
local state
|
||||
local -a options
|
||||
local -a entries
|
||||
|
||||
_arguments -C \
|
||||
'-i[GPGと使ってパスワードストレージを初期設定]: :_sp_complete_keys' \
|
||||
'-s[パスワードを表示]: :_sp_complete_entries' \
|
||||
'-y[パスワードを表示せずクリップボードにコピーする]: :_sp_complete_entries' \
|
||||
'-l[パスワード一覧を表示]' \
|
||||
'-a[パスワードを追加]: :_sp_complete_entries' \
|
||||
'-d[パスワードを削除]: :_sp_complete_entries' \
|
||||
'-g[希望文字数でパスワードをランダムに作成する]: :_sp_complete_entries' \
|
||||
'-o[ワンタイムパスワード(TOTP)を表示]: :_sp_complete_entries' \
|
||||
'-h[ヘルプを表示]' \
|
||||
'-v[バージョンを表示]' \
|
||||
'*:: :->subcmds'
|
||||
|
||||
case $state in
|
||||
subcmds)
|
||||
_message "no more arguments"
|
||||
;;
|
||||
esac
|
||||
local cmd
|
||||
if (( CURRENT > 2)); then
|
||||
cmd=${words[2]}
|
||||
curcontext="${curcontext%:*:*}:pass-$cmd"
|
||||
(( CURRENT-- ))
|
||||
shift words
|
||||
case "${cmd}" in
|
||||
-i)
|
||||
_sp_complete_keys
|
||||
;;
|
||||
-i|-y|-d|-a|-e|-o)
|
||||
_sp_complete_entries_helper
|
||||
;;
|
||||
-g)
|
||||
local -a subcommands
|
||||
subcommands=(
|
||||
"secure:英数字+特別文字(デフォルト)"
|
||||
"risk:英数字のみ(不安)"
|
||||
)
|
||||
;;
|
||||
-s)
|
||||
_sp_cmd_show
|
||||
;;
|
||||
esac
|
||||
else
|
||||
local -a subcommands
|
||||
subcommands=(
|
||||
"-i:GPGと使ってパスワードストレージを初期設定"
|
||||
"-s:パスワードを表示"
|
||||
"-y:パスワードを表示せずクリップボードにコピーする"
|
||||
"-l:パスワード一覧を表示"
|
||||
"-a:パスワードを追加"
|
||||
"-d:パスワードを削除"
|
||||
"-e:パスワードを変更"
|
||||
"-g:希望文字数でパスワードをランダムに作成する。risk=英数字のみ(不安)、secure=英数字+特別文字(デフォルト)を使用"
|
||||
"-o:ワンタイムパスワード(TOTP)を表示。存在しなければ、創作する"
|
||||
"-h:ヘルプを表示"
|
||||
"-v:バージョンを表示"
|
||||
)
|
||||
_sp_cmd_show
|
||||
fi
|
||||
}
|
||||
|
||||
_sp_cmd_show () {
|
||||
|
@ -35,9 +55,9 @@ _sp_complete_entries() {
|
|||
|
||||
_sp_complete_entries_helper () {
|
||||
local IFS=$'\n'
|
||||
local prefix="${SP_DIR:-$HOME/.local/share/sp}"
|
||||
entries=("${(f)$(find -L "$prefix" \( -name .git -o -name .gpg-id \) -prune -o -type f -print 2>/dev/null | sed -e "s#${prefix}/##" -e 's#\.gpg$##')}")
|
||||
_describe 'password entries' entries
|
||||
local prefix
|
||||
zstyle -s ":completion:${curcontext}:" prefix prefix || prefix="${SP_DIR:-$HOME/.local/share/sp}"
|
||||
_values -C 'passwords' ${$(find -L "$prefix" \( -name .git -o -name .gpg-id \) -prune -o $@ -print 2>/dev/null | sed -e "s#${prefix}/\{0,1\}##" -e 's#\.gpg##' -e 's#\\#\\\\#g' -e 's#:#\\:#g' | sort):-""}
|
||||
}
|
||||
|
||||
_sp_complete_keys () {
|
||||
|
@ -45,4 +65,4 @@ _sp_complete_keys () {
|
|||
_values 'gpg keys' $(gpg2 --list-secret-keys --with-colons | cut -d : -f 10 | sort -u | sed '/^$/d')
|
||||
}
|
||||
|
||||
compdef _sp sp
|
||||
_sp
|
||||
|
|
|
@ -52,7 +52,7 @@ void yankpass(char* file) {
|
|||
return;
|
||||
}
|
||||
|
||||
sprintf(gpgpath, "%s%s%s%s", homedir, basedir, file, ext);
|
||||
snprintf(gpgpath, alllen, "%s%s%s%s", homedir, basedir, file, ext);
|
||||
gpgfile = fopen(gpgpath, "rb");
|
||||
if (gpgfile == NULL) {
|
||||
perror("ファイルを開くに失敗。");
|
||||
|
|
読み込み中…
新しいイシューから参照