mirror of
https://github.com/angt/secret
synced 2024-12-28 22:23:46 +01:00
Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
parent
f2d0b64d35
commit
6acaa49202
2 changed files with 45 additions and 32 deletions
59
README.md
59
README.md
|
@ -4,59 +4,76 @@ Keep your little secrets, publicly.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Only one file to backup: `~/.secret`.
|
`secret` is the simplest secret store you can think of:
|
||||||
- No configuration: get back your file and you're done.
|
|
||||||
- URLs/logins/scopes are encrypted too.
|
- Requires only one file `~/.secret` that you can share publicly without fear.
|
||||||
- Secret agent that allows shell completion (only `bash` for now).
|
- No configuration. Get back your file and you're done.
|
||||||
- Support many passwords (a visual hash might be required).
|
- Secret's name (hostname, mail, login, etc.) are also encrypted.
|
||||||
|
- Secret agent only trusts subprocesses. Not all user processes! How nice is that?
|
||||||
|
- Supports multiple passphrases. Not super user-friendly but nice to have.
|
||||||
- Depends only on the [libhydrogen](https://libhydrogen.org/) library.
|
- Depends only on the [libhydrogen](https://libhydrogen.org/) library.
|
||||||
- Small, simple and non obfuscated C code.
|
- Small, simple and non obfuscated C code. Well, I hope so :)
|
||||||
|
|
||||||
## Build and install
|
## Build and install
|
||||||
|
|
||||||
$ make install prefix=/usr
|
$ git clone https://github.com/angt/secret --recursive
|
||||||
|
$ cd secret
|
||||||
|
$ make
|
||||||
|
|
||||||
Currently, bash completion is not installed. Download and source the file [argz.sh](argz/argz.sh) then:
|
Then, as `root`:
|
||||||
|
|
||||||
|
# make install prefix=/usr
|
||||||
|
|
||||||
|
Currently, bash completion is not installed.
|
||||||
|
Download the file [argz.sh](argz/argz.sh) then:
|
||||||
|
|
||||||
|
$ . argz.sh
|
||||||
$ complete -F _argz secret
|
$ complete -F _argz secret
|
||||||
|
|
||||||
|
Completion for secrets is only available in a trusted shell. See below.
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
$ secret
|
| Command | Description |
|
||||||
Available commands:
|
|--------------------|-----------------------------------------------------|
|
||||||
init Init a secret storage for the user
|
| init | Init a secret storage for the user at `~/.secret`. |
|
||||||
list List all secrets for a given passphrase
|
| list | List all secrets for a given passphrase. |
|
||||||
add Add a new secret
|
| add KEY | Add a new secret. |
|
||||||
show Show an existing secret
|
| show KEY | Show an existing secret. |
|
||||||
change Change an existing secret
|
| change KEY | Change an existing secret. |
|
||||||
agent Run a process in a trusted zone
|
| agent CMD [ARG]... | Run a process in a trusted zone. Typically a shell. |
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
Initialize secret:
|
Initialize secret for the current user:
|
||||||
|
|
||||||
$ secret init
|
$ secret init
|
||||||
|
|
||||||
Add a new generated secret called 'test':
|
Add a new generated secret:
|
||||||
|
|
||||||
$ secret add test
|
$ secret add test
|
||||||
Password:
|
Password:
|
||||||
Secret [random]:
|
Secret [random]:
|
||||||
9{6u0ue>5&W2+z#OR:`X<@-#
|
9{6u0ue>5&W2+z#OR:`X<@-#
|
||||||
|
|
||||||
Show secret 'test':
|
Show the secret:
|
||||||
|
|
||||||
$ secret show test
|
$ secret show test
|
||||||
Password:
|
Password:
|
||||||
9{6u0ue>5&W2+z#OR:`X<@-#
|
9{6u0ue>5&W2+z#OR:`X<@-#
|
||||||
|
|
||||||
Start a secret zone:
|
Start `bash` in a trusted zone:
|
||||||
|
|
||||||
$ secret agent bash
|
$ secret agent bash
|
||||||
Password:
|
Password:
|
||||||
|
|
||||||
You can now manipulate your secrets easily and with completion:
|
Now you can play with your little secrets, but only in this shell:
|
||||||
|
|
||||||
$ ./secret show test
|
$ ./secret show test
|
||||||
9{6u0ue>5&W2+z#OR:`X<@-#
|
9{6u0ue>5&W2+z#OR:`X<@-#
|
||||||
|
|
||||||
|
Note that passphrase was not required.
|
||||||
|
|
||||||
|
---
|
||||||
|
For feature requests and bug reports,
|
||||||
|
please create an [issue](https://github.com/angt/secret/issues).
|
||||||
|
|
18
secret.c
18
secret.c
|
@ -1,19 +1,19 @@
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <poll.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/poll.h>
|
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <signal.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "argz/argz.c"
|
#include "argz/argz.c"
|
||||||
#include "libhydrogen/hydrogen.c"
|
#include "libhydrogen/hydrogen.c"
|
||||||
|
|
||||||
#define S_COUNT(x) (sizeof(x) / sizeof((x)[0]))
|
#define S_COUNT(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
#define S_CTX_MASTER "MASTER"
|
#define S_CTX_MASTER "MASTER"
|
||||||
#define S_CTX_SECRET "SECRET"
|
#define S_CTX_SECRET "SECRET"
|
||||||
#define S_ENV_AGENT "SECRET_AGENT"
|
#define S_ENV_AGENT "SECRET_AGENT"
|
||||||
|
@ -53,7 +53,6 @@ s_fatal(const char *fmt, ...)
|
||||||
buf[0] = '?';
|
buf[0] = '?';
|
||||||
size = 1;
|
size = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size > (size_t)ret)
|
if (size > (size_t)ret)
|
||||||
size = (size_t)ret;
|
size = (size_t)ret;
|
||||||
|
|
||||||
|
@ -122,7 +121,7 @@ s_input(unsigned char *buf, size_t size, const char *prompt)
|
||||||
struct termios old;
|
struct termios old;
|
||||||
tcgetattr(fd, &old);
|
tcgetattr(fd, &old);
|
||||||
|
|
||||||
struct termios new = old;;
|
struct termios new = old;
|
||||||
new.c_lflag &= ~(ECHO | ECHONL);
|
new.c_lflag &= ~(ECHO | ECHONL);
|
||||||
|
|
||||||
tcsetattr(fd, TCSAFLUSH, &new);
|
tcsetattr(fd, TCSAFLUSH, &new);
|
||||||
|
@ -164,7 +163,7 @@ s_open_secret(int use_tty)
|
||||||
int fd = open(s.path, O_RDWR);
|
int fd = open(s.path, O_RDWR);
|
||||||
|
|
||||||
if (fd == -1) switch (errno) {
|
if (fd == -1) switch (errno) {
|
||||||
case ENOENT: s_fatal("No secret store: %s", s.path);
|
case ENOENT: s_fatal("No %s", s.path);
|
||||||
default: s_fatal("%s: %s", s.path, strerror(errno));
|
default: s_fatal("%s: %s", s.path, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +173,7 @@ s_open_secret(int use_tty)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (fcntl(fd, F_SETLKW, &fl))
|
if (fcntl(fd, F_SETLKW, &fl))
|
||||||
s_fatal("Unable to lock secret store: %s", s.path);
|
s_fatal("Unable to lock %s", s.path);
|
||||||
|
|
||||||
uint8_t master[hydro_pwhash_MASTERKEYBYTES];
|
uint8_t master[hydro_pwhash_MASTERKEYBYTES];
|
||||||
|
|
||||||
|
@ -219,7 +218,6 @@ s_print_keys(int use_tty)
|
||||||
s_write(1, s.x.msg, strnlen(s.x.msg, sizeof(s.x.msg)));
|
s_write(1, s.x.msg, strnlen(s.x.msg, sizeof(s.x.msg)));
|
||||||
s_write(1, "\n", 1);
|
s_write(1, "\n", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -258,7 +256,6 @@ s_get_secret(int fd, const char *key, int create)
|
||||||
return &s.x.msg[len + 1];
|
return &s.x.msg[len + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!create)
|
if (!create)
|
||||||
s_fatal("Secret %s not found", key);
|
s_fatal("Secret %s not found", key);
|
||||||
|
|
||||||
|
@ -505,7 +502,6 @@ s_agent(int argc, char **argv, void *data)
|
||||||
case ECHILD: s_exit(0);
|
case ECHILD: s_exit(0);
|
||||||
default: s_fatal("waitpid: %s", strerror(errno));
|
default: s_fatal("waitpid: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret == pid) &&
|
if ((ret == pid) &&
|
||||||
(WIFEXITED(status) || WIFSIGNALED(status)))
|
(WIFEXITED(status) || WIFSIGNALED(status)))
|
||||||
s_exit(0);
|
s_exit(0);
|
||||||
|
|
Loading…
Reference in a new issue