Skip to content

Commit

Permalink
Pageant: introduce an API for passphrase prompts.
Browse files Browse the repository at this point in the history
This begins to head towards the goal of storing a key file encrypted
in Pageant, and decrypting it on demand via a GUI prompt the first
time a client requests a signature from it. That won't be a facility
available in all situations, so we have to be able to return failure
from the prompt.

More precisely, there are two versions of this API, one in
PageantClient and one in PageantListenerClient: the stream
implementation of PageantClient implements the former API and hands it
off to the latter. Windows Pageant has to directly implement both (but
they will end up funnelling to the same function within winpgnt.c).

NFC: for the moment, the new API functions are never called, and every
implementation of them returns failure.
  • Loading branch information
sgtatham committed Feb 2, 2020
1 parent be30aac commit 08d5c23
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 0 deletions.
10 changes: 10 additions & 0 deletions pageant.c
Original file line number Diff line number Diff line change
Expand Up @@ -1037,9 +1037,19 @@ static void pageant_conn_got_response(
}
}

static bool pageant_conn_ask_passphrase(
PageantClient *pc, PageantClientDialogId *dlgid, const char *msg)
{
struct pageant_conn_state *pcs =
container_of(pc, struct pageant_conn_state, pc);
return pageant_listener_client_ask_passphrase(pcs->plc, dlgid, msg);
}


static const struct PageantClientVtable pageant_connection_clientvt = {
pageant_conn_log,
pageant_conn_got_response,
pageant_conn_ask_passphrase,
};

static void pageant_conn_receive(
Expand Down
18 changes: 18 additions & 0 deletions pageant.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ typedef struct PageantClientVtable PageantClientVtable;
typedef struct PageantClient PageantClient;
typedef struct PageantClientInfo PageantClientInfo;
typedef struct PageantClientRequestId PageantClientRequestId;
typedef struct PageantClientDialogId PageantClientDialogId;
struct PageantClient {
const struct PageantClientVtable *vt;
PageantClientInfo *info; /* used by the central Pageant code */
Expand All @@ -32,6 +33,8 @@ struct PageantClientVtable {
const char *fmt, va_list ap);
void (*got_response)(PageantClient *pc, PageantClientRequestId *reqid,
ptrlen response);
bool (*ask_passphrase)(PageantClient *pc, PageantClientDialogId *dlgid,
const char *msg);
};

static inline void pageant_client_log_v(
Expand All @@ -54,6 +57,9 @@ static inline PRINTF_LIKE(3, 4) void pageant_client_log(
static inline void pageant_client_got_response(
PageantClient *pc, PageantClientRequestId *reqid, ptrlen response)
{ pc->vt->got_response(pc, reqid, response); }
static inline bool pageant_client_ask_passphrase(
PageantClient *pc, PageantClientDialogId *dlgid, const char *msg)
{ return pc->vt->ask_passphrase(pc, dlgid, msg); }

/* PageantClientRequestId is used to match up responses to the agent
* requests they refer to. A client may allocate one of these for each
Expand Down Expand Up @@ -91,6 +97,13 @@ void pageant_unregister_client(PageantClient *pc);
void pageant_handle_msg(PageantClient *pc, PageantClientRequestId *reqid,
ptrlen msg);

/*
* Send the core Pageant code a response to a passphrase request.
*/
void pageant_passphrase_request_success(PageantClientDialogId *dlgid,
ptrlen passphrase);
void pageant_passphrase_request_refused(PageantClientDialogId *dlgid);

/*
* Construct a list of public keys, just as the two LIST_IDENTITIES
* requests would have returned them.
Expand Down Expand Up @@ -145,6 +158,8 @@ struct PageantListenerClient {
};
struct PageantListenerClientVtable {
void (*log)(PageantListenerClient *, const char *fmt, va_list ap);
bool (*ask_passphrase)(PageantListenerClient *pc,
PageantClientDialogId *dlgid, const char *msg);
};

static inline void pageant_listener_client_log_v(
Expand All @@ -163,6 +178,9 @@ static inline PRINTF_LIKE(2, 3) void pageant_listener_client_log(
va_end(ap);
}
}
static inline bool pageant_listener_client_ask_passphrase(
PageantListenerClient *plc, PageantClientDialogId *dlgid, const char *msg)
{ return plc->vt->ask_passphrase(plc, dlgid, msg); }

struct pageant_listen_state;
struct pageant_listen_state *pageant_listener_new(
Expand Down
8 changes: 8 additions & 0 deletions unix/uxpgnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,16 @@ static void uxpgnt_log(PageantListenerClient *plc, const char *fmt, va_list ap)
fprintf(pageant_logfp, "\n");
}

static bool uxpgnt_ask_passphrase(
PageantListenerClient *plc, PageantClientDialogId *dlgid, const char *msg)
{
/* FIXME: we don't yet support dialog boxes */
return false;
}

static const PageantListenerClientVtable uxpgnt_vtable = {
uxpgnt_log,
uxpgnt_ask_passphrase,
};

/*
Expand Down
16 changes: 16 additions & 0 deletions windows/winpgnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -792,9 +792,17 @@ static void wm_copydata_got_response(
SetEvent(wmct.ev_reply_ready);
}

static bool wm_copydata_ask_passphrase(
PageantClient *pc, PageantClientDialogId *dlgid, const char *msg)
{
/* FIXME: we don't yet support dialog boxes */
return false;
}

static const PageantClientVtable wmcpc_vtable = {
NULL, /* no logging in this client */
wm_copydata_got_response,
wm_copydata_ask_passphrase,
};

static char *answer_filemapping_message(const char *mapname)
Expand Down Expand Up @@ -1176,11 +1184,19 @@ void cleanup_exit(int code)
exit(code);
}

static bool winpgnt_listener_ask_passphrase(
PageantListenerClient *plc, PageantClientDialogId *dlgid, const char *msg)
{
/* FIXME: we don't yet support dialog boxes */
return false;
}

struct winpgnt_client {
PageantListenerClient plc;
};
static const PageantListenerClientVtable winpgnt_vtable = {
NULL, /* no logging */
winpgnt_listener_ask_passphrase,
};

static struct winpgnt_client wpc[1];
Expand Down

0 comments on commit 08d5c23

Please sign in to comment.