mirror of
https://github.com/angt/secret
synced 2025-01-19 22:26:16 +01:00
Check pass when starting agent
And use O_RDONLY when it's possible. Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
parent
9e35f4afc6
commit
7baf7e1a92
1 changed files with 38 additions and 32 deletions
70
secret.c
70
secret.c
|
@ -49,7 +49,7 @@ static struct {
|
||||||
char ctx_master[hydro_pwhash_CONTEXTBYTES];
|
char ctx_master[hydro_pwhash_CONTEXTBYTES];
|
||||||
char ctx_secret[hydro_secretbox_CONTEXTBYTES];
|
char ctx_secret[hydro_secretbox_CONTEXTBYTES];
|
||||||
char ctx_passwd[hydro_pwhash_CONTEXTBYTES];
|
char ctx_passwd[hydro_pwhash_CONTEXTBYTES];
|
||||||
int known_key;
|
int pass_ok;
|
||||||
} s = {
|
} s = {
|
||||||
.pipe = {-1, -1},
|
.pipe = {-1, -1},
|
||||||
.ctx_master = "MASTER",
|
.ctx_master = "MASTER",
|
||||||
|
@ -203,38 +203,40 @@ s_ask_pass(void *buf, size_t size, const char *prompt)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
s_open_secret(int use_tty)
|
s_open_secret(int use_tty, int flags)
|
||||||
{
|
{
|
||||||
int fd = open(s.path, O_RDWR);
|
int fd = open(s.path, flags);
|
||||||
|
|
||||||
if (fd == -1) switch (errno) {
|
if (fd == -1) switch (errno) {
|
||||||
case ENOENT: s_fatal("Secret store %s doesn't exist", s.path);
|
case ENOENT: s_fatal("Secret store %s doesn't exist", s.path);
|
||||||
default: s_fatal("%s: %s", s.path, strerror(errno));
|
default: s_fatal("%s: %s", s.path, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct flock fl = {
|
|
||||||
.l_type = F_WRLCK,
|
|
||||||
.l_whence = SEEK_SET,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (fcntl(fd, F_SETLKW, &fl))
|
|
||||||
s_fatal("Unable to lock %s", s.path);
|
|
||||||
|
|
||||||
if (s_read(fd, s.hdr.buf, sizeof(s.hdr.buf)) != sizeof(s.hdr.buf))
|
if (s_read(fd, s.hdr.buf, sizeof(s.hdr.buf)) != sizeof(s.hdr.buf))
|
||||||
s_fatal("Unable to read %s", s.path);
|
s_fatal("Unable to read %s", s.path);
|
||||||
|
|
||||||
if (s.hdr.version != S_VER_MAJOR)
|
if (s.hdr.version != S_VER_MAJOR)
|
||||||
s_fatal("Unkown version %" PRIu8, s.hdr.version);
|
s_fatal("Unkown version %" PRIu8, s.hdr.version);
|
||||||
|
|
||||||
|
if (flags == O_RDWR) {
|
||||||
|
struct flock fl = {
|
||||||
|
.l_type = F_WRLCK,
|
||||||
|
.l_whence = SEEK_SET,
|
||||||
|
};
|
||||||
|
if (fcntl(fd, F_SETLKW, &fl))
|
||||||
|
s_fatal("Unable to lock %s", s.path);
|
||||||
|
}
|
||||||
|
|
||||||
const char *agent = getenv(S_ENV_AGENT);
|
const char *agent = getenv(S_ENV_AGENT);
|
||||||
int wfd = -1, rfd = -1;
|
int wfd = -1, rfd = -1;
|
||||||
|
|
||||||
if (agent && sscanf(agent, "%d.%d", &wfd, &rfd) == 2 &&
|
if (agent && sscanf(agent, "%d.%d", &wfd, &rfd) == 2 &&
|
||||||
wfd >= 0 && rfd >= 0 &&
|
wfd >= 0 && rfd >= 0 &&
|
||||||
s_write(wfd, "", 1) == 1 &&
|
s_write(wfd, "", 1) == 1 &&
|
||||||
s_read(rfd, s.x.key, sizeof(s.x.key)) == sizeof(s.x.key))
|
s_read(rfd, s.x.key, sizeof(s.x.key)) == sizeof(s.x.key)) {
|
||||||
|
s.pass_ok = 1;
|
||||||
return fd;
|
return fd;
|
||||||
|
}
|
||||||
if (!use_tty)
|
if (!use_tty)
|
||||||
s_exit(0);
|
s_exit(0);
|
||||||
|
|
||||||
|
@ -260,7 +262,7 @@ s_keylen(const char *str)
|
||||||
static void
|
static void
|
||||||
s_print_keys(int use_tty)
|
s_print_keys(int use_tty)
|
||||||
{
|
{
|
||||||
int fd = s_open_secret(use_tty);
|
int fd = s_open_secret(use_tty, O_RDONLY);
|
||||||
|
|
||||||
while (s_read(fd, s.enc, sizeof(s.enc)) == sizeof(s.enc)) {
|
while (s_read(fd, s.enc, sizeof(s.enc)) == sizeof(s.enc)) {
|
||||||
if (hydro_secretbox_decrypt(&s.x.entry,
|
if (hydro_secretbox_decrypt(&s.x.entry,
|
||||||
|
@ -276,25 +278,37 @@ s_print_keys(int use_tty)
|
||||||
static const char *
|
static const char *
|
||||||
s_get_secret(int fd, const char *key, int create)
|
s_get_secret(int fd, const char *key, int create)
|
||||||
{
|
{
|
||||||
size_t len = s_keylen(key);
|
size_t len = key ? s_keylen(key) : 0;
|
||||||
|
|
||||||
while (s_read(fd, s.enc, sizeof(s.enc)) == sizeof(s.enc)) {
|
while (s_read(fd, s.enc, sizeof(s.enc)) == sizeof(s.enc)) {
|
||||||
if (hydro_secretbox_decrypt(&s.x.entry,
|
if (hydro_secretbox_decrypt(&s.x.entry,
|
||||||
s.enc, sizeof(s.enc), 0,
|
s.enc, sizeof(s.enc), 0,
|
||||||
s.ctx_secret, s.x.key))
|
s.ctx_secret, s.x.key))
|
||||||
continue;
|
continue;
|
||||||
if (hydro_equal(s.x.entry.msg, key, len + 1)) {
|
if (key && hydro_equal(s.x.entry.msg, key, len + 1)) {
|
||||||
if (create)
|
if (create)
|
||||||
s_fatal("Secret %s exists!", key);
|
s_fatal("Secret %s exists!", key);
|
||||||
if (lseek(fd, -(off_t)sizeof(s.enc), SEEK_CUR) == (off_t)-1)
|
if (lseek(fd, -(off_t)sizeof(s.enc), SEEK_CUR) == (off_t)-1)
|
||||||
s_fatal("seek: %s", strerror(errno));
|
s_fatal("seek: %s", strerror(errno));
|
||||||
return &s.x.entry.msg[len + 1];
|
return &s.x.entry.msg[len + 1];
|
||||||
}
|
}
|
||||||
s.known_key = 1;
|
s.pass_ok = 1;
|
||||||
}
|
}
|
||||||
if (!create)
|
if (key && !create)
|
||||||
s_fatal("Secret %s not found", key);
|
s_fatal("Secret %s not found", key);
|
||||||
|
if (s.pass_ok)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
char check[sizeof(s.x.key)];
|
||||||
|
|
||||||
|
s_ask_pass(check, sizeof(check),
|
||||||
|
"It's the first time you use this passphrase.\n"
|
||||||
|
"Please, retype it to confirm: ");
|
||||||
|
|
||||||
|
if (!hydro_equal(s.x.key, check, sizeof(check)))
|
||||||
|
s_fatal("Passphrases don't match!");
|
||||||
|
|
||||||
|
s.pass_ok = 1;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,18 +407,8 @@ s_do(int argc, char **argv, void *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd = s_open_secret(1);
|
int fd = s_open_secret(1, O_RDWR);
|
||||||
const char *old = s_get_secret(fd, argv[1], op & s_op_create);
|
const char *old = s_get_secret(fd, argv[1], op & s_op_create);
|
||||||
|
|
||||||
if (!old && !s.known_key) {
|
|
||||||
char check[sizeof(s.x.key)];
|
|
||||||
s_ask_pass(check, sizeof(check),
|
|
||||||
"It's the first time you use this passphrase.\n"
|
|
||||||
"Please, retype it to confirm: ");
|
|
||||||
if (!hydro_equal(s.x.key, check, sizeof(check)))
|
|
||||||
s_fatal("Passphrases don't match!");
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char secret[S_ENTRYSIZE];
|
unsigned char secret[S_ENTRYSIZE];
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
|
@ -439,7 +443,7 @@ s_show(int argc, char **argv, void *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd = s_open_secret(1);
|
int fd = s_open_secret(1, O_RDONLY);
|
||||||
const char *secret = s_get_secret(fd, argv[1], 0);
|
const char *secret = s_get_secret(fd, argv[1], 0);
|
||||||
|
|
||||||
if (secret) {
|
if (secret) {
|
||||||
|
@ -458,7 +462,7 @@ s_pass(int argc, char **argv, void *data)
|
||||||
printf("Usage: %s KEY [SUBKEY...]\n", argv[0]);
|
printf("Usage: %s KEY [SUBKEY...]\n", argv[0]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
close(s_open_secret(1));
|
close(s_open_secret(1, O_RDONLY));
|
||||||
|
|
||||||
uint8_t buf[hydro_pwhash_MASTERKEYBYTES];
|
uint8_t buf[hydro_pwhash_MASTERKEYBYTES];
|
||||||
uint8_t key[hydro_pwhash_MASTERKEYBYTES];
|
uint8_t key[hydro_pwhash_MASTERKEYBYTES];
|
||||||
|
@ -509,7 +513,9 @@ s_agent(int argc, char **argv, void *data)
|
||||||
if (getenv(S_ENV_AGENT))
|
if (getenv(S_ENV_AGENT))
|
||||||
s_fatal("Already running...");
|
s_fatal("Already running...");
|
||||||
|
|
||||||
close(s_open_secret(1));
|
int fd = s_open_secret(1, O_RDONLY);
|
||||||
|
s_get_secret(fd, NULL, 0);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
int rfd[2], wfd[2];
|
int rfd[2], wfd[2];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue