mirror of https://github.com/skeeto/enchive.git
Add pinentry support on Windows
parent
a07053778f
commit
50624f2373
118
src/enchive.c
118
src/enchive.c
|
@ -438,11 +438,6 @@ get_passphrase_dumb(char *buf, size_t len, char *prompt)
|
||||||
buf[passlen - 1] = 0;
|
buf[passlen - 1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__)
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <termios.h>
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pinentry_decode(char *buf, size_t blen, const char *str)
|
pinentry_decode(char *buf, size_t blen, const char *str)
|
||||||
{
|
{
|
||||||
|
@ -469,32 +464,10 @@ pinentry_decode(char *buf, size_t blen, const char *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
invoke_pinentry(char *buf, size_t len, char *prompt)
|
pinentry(FILE *pfi, FILE *pfo, char *buf, size_t len, char *prompt)
|
||||||
{
|
{
|
||||||
int pin[2];
|
|
||||||
int pout[2];
|
|
||||||
pid_t pid;
|
|
||||||
|
|
||||||
if (pipe(pin) != 0)
|
|
||||||
fatal("could not start pinentry -- %s", strerror(errno));
|
|
||||||
if (pipe(pout) != 0)
|
|
||||||
fatal("could not start pinentry -- %s", strerror(errno));
|
|
||||||
|
|
||||||
pid = fork();
|
|
||||||
if (pid == -1)
|
|
||||||
fatal("pinentry fork() failed -- %s", strerror(errno));
|
|
||||||
if (pid) {
|
|
||||||
FILE *pfi, *pfo;
|
|
||||||
char line[ENCHIVE_PASSPHRASE_MAX * 3 + 32];
|
char line[ENCHIVE_PASSPHRASE_MAX * 3 + 32];
|
||||||
|
|
||||||
close(pin[0]);
|
|
||||||
close(pout[1]);
|
|
||||||
|
|
||||||
if (!(pfi = fdopen(pin[1], "w")))
|
|
||||||
fatal("fdopen() input -- %s", strerror(errno));
|
|
||||||
if (!(pfo = fdopen(pout[0], "r")))
|
|
||||||
fatal("fdopen() output -- %s", strerror(errno));
|
|
||||||
|
|
||||||
if (!fgets(line, sizeof(line), pfo))
|
if (!fgets(line, sizeof(line), pfo))
|
||||||
/* Likely caused by exec() failure, so exit quietly. */
|
/* Likely caused by exec() failure, so exit quietly. */
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -522,6 +495,40 @@ invoke_pinentry(char *buf, size_t len, char *prompt)
|
||||||
pinentry_decode(buf, len, line + 2);
|
pinentry_decode(buf, len, line + 2);
|
||||||
else
|
else
|
||||||
fatal("pinentry protocol failure");
|
fatal("pinentry protocol failure");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__)
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
pinentry_unix(char *buf, size_t len, char *prompt)
|
||||||
|
{
|
||||||
|
int pin[2];
|
||||||
|
int pout[2];
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
if (pipe(pin) != 0)
|
||||||
|
fatal("could not start pinentry -- %s", strerror(errno));
|
||||||
|
if (pipe(pout) != 0)
|
||||||
|
fatal("could not start pinentry -- %s", strerror(errno));
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if (pid == -1)
|
||||||
|
fatal("pinentry fork() failed -- %s", strerror(errno));
|
||||||
|
if (pid) {
|
||||||
|
FILE *pfi, *pfo;
|
||||||
|
|
||||||
|
close(pin[0]);
|
||||||
|
close(pout[1]);
|
||||||
|
|
||||||
|
if (!(pfi = fdopen(pin[1], "w")))
|
||||||
|
fatal("fdopen() input -- %s", strerror(errno));
|
||||||
|
if (!(pfo = fdopen(pout[0], "r")))
|
||||||
|
fatal("fdopen() output -- %s", strerror(errno));
|
||||||
|
|
||||||
|
pinentry(pfi, pfo, buf, len, prompt);
|
||||||
|
|
||||||
fclose(pfo);
|
fclose(pfo);
|
||||||
fclose(pfi);
|
fclose(pfi);
|
||||||
|
@ -542,7 +549,7 @@ get_passphrase(char *buf, size_t len, char *prompt)
|
||||||
int tty;
|
int tty;
|
||||||
|
|
||||||
if (pinentry_path) {
|
if (pinentry_path) {
|
||||||
invoke_pinentry(buf, len, prompt);
|
pinentry_unix(buf, len, prompt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,6 +584,50 @@ get_passphrase(char *buf, size_t len, char *prompt)
|
||||||
|
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
pinentry_win32(char *buf, size_t len, char *prompt)
|
||||||
|
{
|
||||||
|
BOOL r;
|
||||||
|
int fdi, fdo;
|
||||||
|
FILE *pfi, *pfo;
|
||||||
|
HANDLE pi[2], po[2];
|
||||||
|
PROCESS_INFORMATION proc;
|
||||||
|
STARTUPINFOA info = {sizeof(info)};
|
||||||
|
SECURITY_ATTRIBUTES attr = {sizeof(attr), 0, TRUE};
|
||||||
|
|
||||||
|
r = CreatePipe(&pi[0], &pi[1], &attr, 0);
|
||||||
|
if (!r) fatal("could not start pinentry");
|
||||||
|
r = CreatePipe(&po[0], &po[1], &attr, 0);
|
||||||
|
if (!r) fatal("could not start pinentry");
|
||||||
|
|
||||||
|
info.hStdInput = pi[0];
|
||||||
|
info.hStdOutput = po[1];
|
||||||
|
info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
|
||||||
|
info.dwFlags = STARTF_USESTDHANDLES;
|
||||||
|
|
||||||
|
r = CreateProcessA(0, pinentry_path, 0, 0, TRUE, 0, 0, 0, &info, &proc);
|
||||||
|
if (!r) fatal("could not start pinentry: %s", pinentry_path);
|
||||||
|
CloseHandle(po[1]);
|
||||||
|
CloseHandle(pi[0]);
|
||||||
|
|
||||||
|
fdi = _open_osfhandle((intptr_t)pi[1], _O_APPEND);
|
||||||
|
if (fdi == -1) fatal("could not start pinentry");
|
||||||
|
pfi = fdopen(fdi, "wb");
|
||||||
|
if (!pfi) fatal("could not start pinentry");
|
||||||
|
|
||||||
|
fdo = _open_osfhandle((intptr_t)po[0], _O_RDONLY);
|
||||||
|
if (fdo == -1) fatal("could not start pinentry");
|
||||||
|
pfo = fdopen(fdo, "rb");
|
||||||
|
if (!pfo) fatal("could not start pinentry");
|
||||||
|
setvbuf(pfo, 0, _IONBF, 0);
|
||||||
|
|
||||||
|
pinentry(pfi, pfo, buf, len, prompt);
|
||||||
|
|
||||||
|
fclose(pfo);
|
||||||
|
fclose(pfi);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_passphrase(char *buf, size_t len, char *prompt)
|
get_passphrase(char *buf, size_t len, char *prompt)
|
||||||
|
@ -588,6 +639,11 @@ get_passphrase(char *buf, size_t len, char *prompt)
|
||||||
HANDLE hi, ho = INVALID_HANDLE_VALUE;
|
HANDLE hi, ho = INVALID_HANDLE_VALUE;
|
||||||
unsigned char *p = (unsigned char *)buf;
|
unsigned char *p = (unsigned char *)buf;
|
||||||
|
|
||||||
|
if (pinentry_path) {
|
||||||
|
pinentry_win32(buf, len, prompt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set up input console handle */
|
/* Set up input console handle */
|
||||||
hi = CreateFileA(
|
hi = CreateFileA(
|
||||||
"CONIN$", GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0
|
"CONIN$", GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0
|
||||||
|
@ -1669,11 +1725,9 @@ main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
{ /* Set stdin/stdout to binary mode. */
|
/* Set stdin/stdout to binary mode. */
|
||||||
int _setmode(int, int);
|
|
||||||
_setmode(0, 0x8000);
|
_setmode(0, 0x8000);
|
||||||
_setmode(1, 0x8000);
|
_setmode(1, 0x8000);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (parse_command(command)) {
|
switch (parse_command(command)) {
|
||||||
|
|
Loading…
Reference in New Issue