Make the Pageant core serialise GUI requests.

This commit is contained in:
Simon Tatham 2020-02-08 18:08:20 +00:00
Родитель 55005a08ea
Коммит ff1a297f77
2 изменённых файлов: 18 добавлений и 5 удалений

Просмотреть файл

@ -120,6 +120,10 @@ struct PageantSignOp {
PageantAsyncOp pao; PageantAsyncOp pao;
}; };
/* Master lock that indicates whether a GUI request is currently in
* progress */
static bool gui_request_in_progress = false;
static void failure(PageantClient *pc, PageantClientRequestId *reqid, static void failure(PageantClient *pc, PageantClientRequestId *reqid,
strbuf *sb, const char *fmt, ...); strbuf *sb, const char *fmt, ...);
static void fail_requests_for_key(PageantKey *pk, const char *reason); static void fail_requests_for_key(PageantKey *pk, const char *reason);
@ -332,6 +336,8 @@ static void signop_free(PageantAsyncOp *pao)
static bool request_passphrase(PageantClient *pc, PageantKey *pk) static bool request_passphrase(PageantClient *pc, PageantKey *pk)
{ {
if (!pk->decryption_prompt_active) { if (!pk->decryption_prompt_active) {
assert(!gui_request_in_progress);
strbuf *sb = strbuf_new(); strbuf *sb = strbuf_new();
strbuf_catf(sb, "Enter passphrase to decrypt key '%s'", pk->comment); strbuf_catf(sb, "Enter passphrase to decrypt key '%s'", pk->comment);
bool created_dlg = pageant_client_ask_passphrase( bool created_dlg = pageant_client_ask_passphrase(
@ -341,6 +347,7 @@ static bool request_passphrase(PageantClient *pc, PageantKey *pk)
if (!created_dlg) if (!created_dlg)
return false; return false;
gui_request_in_progress = true;
pk->decryption_prompt_active = true; pk->decryption_prompt_active = true;
} }
@ -354,6 +361,9 @@ static void signop_coroutine(PageantAsyncOp *pao)
crBegin(so->crLine); crBegin(so->crLine);
while (!so->pk->skey && gui_request_in_progress)
crReturnV;
if (!so->pk->skey) { if (!so->pk->skey) {
assert(so->pk->encrypted_key_file); assert(so->pk->encrypted_key_file);
@ -448,6 +458,9 @@ void pageant_passphrase_request_success(PageantClientDialogId *dlgid,
{ {
PageantKey *pk = container_of(dlgid, PageantKey, dlgid); PageantKey *pk = container_of(dlgid, PageantKey, dlgid);
assert(gui_request_in_progress);
gui_request_in_progress = false;
if (!pk->skey) { if (!pk->skey) {
const char *error; const char *error;
@ -497,6 +510,10 @@ void pageant_passphrase_request_success(PageantClientDialogId *dlgid,
void pageant_passphrase_request_refused(PageantClientDialogId *dlgid) void pageant_passphrase_request_refused(PageantClientDialogId *dlgid)
{ {
PageantKey *pk = container_of(dlgid, PageantKey, dlgid); PageantKey *pk = container_of(dlgid, PageantKey, dlgid);
assert(gui_request_in_progress);
gui_request_in_progress = false;
unblock_requests_for_key(pk); unblock_requests_for_key(pk);
} }

Просмотреть файл

@ -61,11 +61,7 @@ static bool uxpgnt_ask_passphrase(
if (!upc->debug_prompt_possible) if (!upc->debug_prompt_possible)
return false; return false;
/* assert(!upc->dlgid); /* Pageant core should be serialising requests */
* FIXME; we ought to check upc->dlgid here, and if it's already
* not NULL, queue this request up behind the previous one rather
* than trying to confusingly run both at oncec.
*/
fprintf(upc->logfp, "pageant passphrase request: %s\n", msg); fprintf(upc->logfp, "pageant passphrase request: %s\n", msg);
upc->debug_prompt_active = true; upc->debug_prompt_active = true;