1.1.0
このコミットが含まれているのは:
コミット
75890ee790
|
@ -1,2 +1,9 @@
|
|||
# 1.1.0
|
||||
* TOTP対応
|
||||
* READMEファイルで使い方を詳しく説明する
|
||||
* zshキャプチャー
|
||||
* パスワード追加関数を安定化
|
||||
* パスワード表示とパスワードのコピー関数で、GNU Passで保存したパスワードの場合は改行を追加しない様に
|
||||
|
||||
# 1.0.0
|
||||
* 最初リリース
|
||||
|
|
9
Makefile
9
Makefile
|
@ -1,11 +1,11 @@
|
|||
NAME=sp
|
||||
VERSION=1.0.0
|
||||
VERSION=1.1.0
|
||||
# Linux、Haiku、かIllumos = /usr、FreeBSDかOpenBSD = /usr/local、NetBSD = /usr/pkg
|
||||
PREFIX=/usr
|
||||
CC=cc
|
||||
FILES=main.c showpass.c yankpass.c addpass.c delpass.c listpass.c genpass.c initpass.c
|
||||
FILES=main.c showpass.c yankpass.c addpass.c delpass.c listpass.c genpass.c initpass.c otppass.c
|
||||
CFLAGS=-Wall -Wextra -g
|
||||
LDFLAGS=-lgpgme
|
||||
LDFLAGS=-lgpgme -lcrypto
|
||||
|
||||
all:
|
||||
${CC} ${CFLAGS} -o ${NAME} ${FILES} ${LDFLAGS}
|
||||
|
@ -25,6 +25,9 @@ install: all
|
|||
cp -f ${NAME} ${DESTDIR}${PREFIX}/bin
|
||||
chmod 755 ${DESTDIR}${PREFIX}/bin/${NAME}
|
||||
|
||||
install-zsh:
|
||||
cp sp-completion.zsh /usr/share/zsh/site-functions/_sp
|
||||
|
||||
uninstall:
|
||||
rm -f ${DESTDIR}${PREFIX}/bin/${NAME}
|
||||
|
||||
|
|
60
README.md
60
README.md
|
@ -39,3 +39,63 @@ doas gmake install PREFIX=/usr/local
|
|||
|
||||
## 初期設定
|
||||
「gpg -k」でGPG鍵IDを確認して、「sp -i [GPG ID]」を実行して下さい。
|
||||
|
||||
## 使い方
|
||||
### パスワードの作成
|
||||
#### 強いパスワードの場合
|
||||
```sh
|
||||
$ sp -g 64
|
||||
nSYGSF2lWGCUsqKCRB_~mZm+spaU<zvtt%um'01$tj4h,^nB6JqX#Cm$!U+s;c7:
|
||||
```
|
||||
又は
|
||||
```sh
|
||||
$ sp -g 64 secure
|
||||
nSYGSF2lWGCUsqKCRB_~mZm+spaU<zvtt%um'01$tj4h,^nB6JqX#Cm$!U+s;c7:
|
||||
```
|
||||
|
||||
#### 弱いパスワードの場合
|
||||
```sh
|
||||
$ sp -g 12 risk
|
||||
2aKBwb858mzg
|
||||
```
|
||||
|
||||
### パスワードの追加
|
||||
「suwako」というユーザー名の場合:
|
||||
```sh
|
||||
$ sp -a 076.moe/suwako
|
||||
パスワード:
|
||||
パスワード(確認用):
|
||||
パスワードを保存出来ました。
|
||||
```
|
||||
入力中は何も表示されないので、ご注意下さい。
|
||||
|
||||
### パスワードの表示
|
||||
```sh
|
||||
$ sp -s 076.moe/suwako
|
||||
nSYGSF2lWGCUsqKCRB_~mZm+spaU<zvtt%um'01$tj4h,^nB6JqX#Cm$!U+s;c7:
|
||||
```
|
||||
表示せずコピーする場合は、「sp -y 076.moe/suwako」を使用して下さい。
|
||||
|
||||
### パスワードの削除
|
||||
```sh
|
||||
$ sp -d 076.moe/suwako
|
||||
パスワード「076.moe/suwako」を本当に削除する事が宜しいでしょうか? (y/N): y
|
||||
パスワードを削除しました。
|
||||
```
|
||||
|
||||
## TOTP(ワンタイムパスワード)
|
||||
### QRコードから
|
||||
QRコードをダウンロードし、zbarimgを使用して「QR-Code:」以降の部分をコピーし、spに追加して下さい。\
|
||||
`sp -a`を実行すると、「パスワード」を聞かれますが、TOTPの場合は「otpauth://」から始まる文字列をコピペして下さい。
|
||||
```sh
|
||||
$ zbarimg -q gitler.png
|
||||
QR-Code:otpauth://totp/Gitler%20%28gitler.moe%29:suwako?algorithm=SHA1&digits=6&issuer=Gitler%20%28gitler.moe%29&period=30&secret=〇〇
|
||||
|
||||
$ sp -a gitler-otp
|
||||
パスワード:
|
||||
パスワード(確認用):
|
||||
パスワードを保存出来ました。
|
||||
|
||||
$ sp -q gitler-otp
|
||||
123456
|
||||
```
|
||||
|
|
23
addpass.c
23
addpass.c
|
@ -57,13 +57,20 @@ void getpasswd(char* prompt, char*pw, size_t pwlen) {
|
|||
tcsetattr(fileno(stdin), TCSANOW, &new);
|
||||
|
||||
// パスワードを読み込む
|
||||
fgets(pw, pwlen, stdin);
|
||||
if (fgets(pw, pwlen, stdin) != NULL) {
|
||||
// あれば、改行を取り消す
|
||||
size_t len = strlen(pw);
|
||||
if (len > 0 && pw[len - 1] == '\n') {
|
||||
pw[len - 1] = '\0';
|
||||
} else {
|
||||
// 掃除
|
||||
int c;
|
||||
while ((c = getchar()) != '\n' && c != EOF);
|
||||
}
|
||||
}
|
||||
|
||||
// 端末設定をもとに戻す
|
||||
tcsetattr(fileno(stdin), TCSANOW, &old);
|
||||
|
||||
// 改行文字を取り消す
|
||||
pw[strcspn(pw, "\n")] = 0;
|
||||
}
|
||||
|
||||
void addpass(char* file) {
|
||||
|
@ -233,8 +240,14 @@ void addpass(char* file) {
|
|||
|
||||
char buffer[512];
|
||||
ssize_t read_bytes;
|
||||
|
||||
while ((read_bytes = gpgme_data_read(out, buffer, sizeof(buffer))) > 0) {
|
||||
fwrite(buffer, 1, read_bytes, gpgfile);
|
||||
if (fwrite(buffer, 1, (size_t)read_bytes, gpgfile) != (size_t)read_bytes) {
|
||||
perror("パスワードを書き込みに失敗");
|
||||
free(gpgpath);
|
||||
cleanup(ctx, key[0], in, out);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 掃除
|
||||
|
|
8
main.c
8
main.c
|
@ -12,11 +12,11 @@
|
|||
#include "addpass.h"
|
||||
#include "delpass.h"
|
||||
#include "genpass.h"
|
||||
void otppass(char* file);
|
||||
#include "otppass.h"
|
||||
void helpme();
|
||||
|
||||
const char* sofname = "sp";
|
||||
const char* version = "1.0.0";
|
||||
const char* version = "1.1.0";
|
||||
|
||||
void helpme() {
|
||||
printf("076 sp - シンプルなパスワードマネージャー\n");
|
||||
|
@ -29,7 +29,7 @@ void helpme() {
|
|||
printf("%s -a <パスワード名> :パスワードを追加\n", sofname);
|
||||
printf("%s -d <パスワード名> :パスワードを削除\n", sofname);
|
||||
printf("%s -g <文字数> [risk|secure] :希望文字数でパスワードをランダムに作成する。risk=英数字のみ(不安)、secure=英数字+特別文字(デフォルト)を使用\n", sofname);
|
||||
/* printf("%s -o <パスワード名>\n :ワンタイムパスワード(TOTP)を表示。存在しなければ、創作する", sofname); */
|
||||
printf("%s -o <パスワード名>\n :ワンタイムパスワード(TOTP)を表示。存在しなければ、創作する\n", sofname);
|
||||
printf("%s -h :ヘルプを表示\n", sofname);
|
||||
printf("%s -v :バージョンを表示\n", sofname);
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ int main (int argc, char* argv[]) {
|
|||
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) printf("TODO: otp\n");
|
||||
else if (argc == 3 && strcmp(argv[1], "-o") == 0) otppass(argv[2]);
|
||||
else if (argc == 2 && strcmp(argv[1], "-v") == 0) printf("%s-%s\n", sofname, version);
|
||||
else helpme();
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
unsigned long generate_totp(const unsigned char* secret, size_t keylen) {
|
||||
unsigned long timestep = time(NULL) / 30;
|
||||
unsigned char hmacres[20];
|
||||
|
||||
HMAC(EVP_sha1(), secret, keylen, (unsigned char*)×tep, sizeof(timestep), hmacres, NULL);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void otppass(char* file) {
|
||||
const char* secret = file;
|
||||
unsigned long otp = generate_totp((unsigned char*)secret, strlen(secret));
|
||||
printf("%06lu\n", otp);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef OTPPASS_H
|
||||
#define OTPPASS_H
|
||||
|
||||
void otppass(char* file);
|
||||
|
||||
#endif
|
13
showpass.c
13
showpass.c
|
@ -1,5 +1,6 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include <gpgme.h>
|
||||
|
@ -83,9 +84,17 @@ void showpass(char* file) {
|
|||
gpgme_data_seek(out, 0, SEEK_SET);
|
||||
char buffer[512];
|
||||
ssize_t read_bytes;
|
||||
bool islastnl = false;
|
||||
|
||||
while ((read_bytes = gpgme_data_read(out, buffer, sizeof(buffer) - 1)) > 0) {
|
||||
buffer[read_bytes] = '\0';
|
||||
printf("%s", buffer);
|
||||
fwrite(buffer, 1, read_bytes, stdout);
|
||||
if (buffer[read_bytes - 1] == '\n') {
|
||||
islastnl = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!islastnl) {
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
// 掃除
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
# compdef sp
|
||||
|
||||
_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
|
||||
}
|
||||
|
||||
_sp_cmd_show () {
|
||||
_sp_complete_entries
|
||||
}
|
||||
|
||||
_sp_complete_entries() {
|
||||
_sp_complete_entries_helper -type f
|
||||
}
|
||||
|
||||
_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
|
||||
}
|
||||
|
||||
_sp_complete_keys () {
|
||||
local IFS=$'\n'
|
||||
_values 'gpg keys' $(gpg2 --list-secret-keys --with-colons | cut -d : -f 10 | sort -u | sed '/^$/d')
|
||||
}
|
||||
|
||||
compdef _sp sp
|
|
@ -98,12 +98,18 @@ void yankpass(char* file) {
|
|||
|
||||
char buffer[512];
|
||||
ssize_t read_bytes;
|
||||
while ((read_bytes = gpgme_data_read(out, buffer, 511)) > 0) {
|
||||
|
||||
while ((read_bytes = gpgme_data_read(out, buffer, sizeof(buffer))) > 0) {
|
||||
if (buffer[read_bytes - 1] == '\n') {
|
||||
read_bytes--;
|
||||
}
|
||||
fwrite(buffer, 1, read_bytes, pipe);
|
||||
}
|
||||
|
||||
pclose(pipe);
|
||||
|
||||
// 45秒後、クリップボードから削除する
|
||||
printf("パスワードをクリップボードに追加しました。\n45秒後はクリップボードから取り消されます。\n");
|
||||
sleep(45);
|
||||
system("echo -n | xclip -selection clipboard");
|
||||
|
||||
|
|
読み込み中…
新しいイシューから参照