Be careful when talking to a secret agent

Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
Adrien Gallouët 2020-06-07 09:36:11 +00:00
parent 4372928147
commit 2fb802b769

View file

@ -109,9 +109,9 @@ s_read(int fd, void *data, size_t size)
if (r == 0) if (r == 0)
break; break;
if (r == (ssize_t)-1) switch (errno) { if (r == (ssize_t)-1) switch (errno) {
case EAGAIN: if (!poll(&pfd, 1, 200)) return 1; /* FALLTHRU */ case EAGAIN: if (poll(&pfd, 1, 200) < 1) return done; /* FALLTHRU */
case EINTR: continue; case EINTR: continue;
default: s_fatal("read: %s", strerror(errno)); default: return done;
} }
done += r; done += r;
} }
@ -129,9 +129,9 @@ s_write(int fd, const void *data, size_t size)
if (r == 0) if (r == 0)
break; break;
if (r == (ssize_t)-1) switch (errno) { if (r == (ssize_t)-1) switch (errno) {
case EAGAIN: if (!poll(&pfd, 1, 200)) return 1; /* FALLTHRU */ case EAGAIN: if (poll(&pfd, 1, 200) < 1) return done; /* FALLTHRU */
case EINTR: continue; case EINTR: continue;
default: s_fatal("write: %s", strerror(errno)); default: return done;
} }
done += r; done += r;
} }
@ -208,6 +208,24 @@ s_ask_pass(void *buf, size_t size, const char *prompt)
if (r) s_oops(__LINE__); if (r) s_oops(__LINE__);
} }
static int
s_ask_agent(void)
{
const char *agent = getenv(S_ENV_AGENT);
int wfd = -1, rfd = -1;
if (!agent || sscanf(agent, "%d.%d", &wfd, &rfd) != 2 || wfd < 0 || rfd < 0)
return 1;
s_write(wfd, "", 1);
if (s_read(rfd, s.x.key, sizeof(s.x.key)) != sizeof(s.x.key))
return 1;
s.pass_ok = 1;
return 0;
}
static int static int
s_open_secret(int use_tty, int flags) s_open_secret(int use_tty, int flags)
{ {
@ -223,16 +241,9 @@ s_open_secret(int use_tty, int flags)
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);
const char *agent = getenv(S_ENV_AGENT); if (!s_ask_agent())
int wfd = -1, rfd = -1;
if (agent && sscanf(agent, "%d.%d", &wfd, &rfd) == 2 &&
wfd >= 0 && rfd >= 0 &&
s_write(wfd, "", 1) == 1 &&
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);