1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

* no-pth.c, Makefile.am: Removed.

* call-scd.c: Seirialized all scdaeom access when using Pth.

* cache.c: Made the cache Pth-thread-safe.
(agent_unlock_cache_entry): New.
* findkey.c (unprotect): Unlock the returned cache value.
* command.c (cmd_get_passphrase): Ditto.

* gpg-agent.c (main): Register pth_read/write with Assuan.
This commit is contained in:
Werner Koch 2002-05-23 09:07:45 +00:00
parent 72f48d9e8a
commit b209c17be9
12 changed files with 416 additions and 162 deletions

View file

@ -27,6 +27,9 @@
#include <assert.h>
#include <unistd.h>
#include <sys/stat.h>
#ifdef USE_GNU_PTH
# include <pth.h>
#endif
#include "agent.h"
#include "../assuan/assuan.h"
@ -38,6 +41,9 @@
#endif
static ASSUAN_CONTEXT entry_ctx = NULL;
#ifdef USE_GNU_PTH
static pth_mutex_t entry_lock = PTH_MUTEX_INIT;
#endif
/* data to be passed to our callbacks */
struct entry_parm_s {
@ -49,7 +55,24 @@ struct entry_parm_s {
/* Fork off the pin entry if this has not already been done */
static int
unlock_pinentry (int rc)
{
#ifdef USE_GNU_PTH
if (!pth_mutex_release (&entry_lock))
{
log_error ("failed to release the entry lock\n");
if (!rc)
rc = GNUPG_Internal_Error;
}
#endif
return rc;
}
/* Fork off the pin entry if this has not already been done. Note,
that this function must always be used to aquire the lock for the
pinentry - we will serialize _all_ pinentry calls.
*/
static int
start_pinentry (void)
{
@ -58,10 +81,16 @@ start_pinentry (void)
ASSUAN_CONTEXT ctx;
const char *argv[5];
#ifdef USE_GNU_PTH
if (!pth_mutex_acquire (&entry_lock, 0, NULL))
{
log_error ("failed to acquire the entry lock\n");
return GNUPG_Internal_Error;
}
#endif
if (entry_ctx)
return 0; /* No need to serialize things becuase the agent is
expected to tun as a single-thread (or may be in
future using libpth) */
return 0;
if (opt.verbose)
log_info ("no running PIN Entry - starting it\n");
@ -69,7 +98,7 @@ start_pinentry (void)
if (fflush (NULL))
{
log_error ("error flushing pending output: %s\n", strerror (errno));
return seterr (Write_Error);
return unlock_pinentry (seterr (Write_Error));
}
/* FIXME: change the default location of the program */
@ -80,6 +109,7 @@ start_pinentry (void)
else
pgmname++;
/* FIXME: We must do this thread specific */
argv[0] = pgmname;
if (opt.display)
{
@ -96,7 +126,7 @@ start_pinentry (void)
{
log_error ("can't connect to the PIN entry module: %s\n",
assuan_strerror (rc));
return seterr (No_PIN_Entry);
return unlock_pinentry (seterr (No_PIN_Entry));
}
entry_ctx = ctx;
@ -107,47 +137,47 @@ start_pinentry (void)
opt.no_grab? "OPTION no-grab":"OPTION grab",
NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
if (opt.ttyname)
{
char *optstr;
if (asprintf (&optstr, "OPTION ttyname=%s", opt.ttyname) < 0 )
return GNUPG_Out_Of_Core;
return unlock_pinentry (GNUPG_Out_Of_Core);
rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
NULL);
free (optstr);
if (rc)
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
}
if (opt.ttytype)
{
char *optstr;
if (asprintf (&optstr, "OPTION ttytype=%s", opt.ttytype) < 0 )
return GNUPG_Out_Of_Core;
return unlock_pinentry (GNUPG_Out_Of_Core);
rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
NULL);
if (rc)
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
}
if (opt.lc_ctype)
{
char *optstr;
if (asprintf (&optstr, "OPTION lc-ctype=%s", opt.lc_ctype) < 0 )
return GNUPG_Out_Of_Core;
return unlock_pinentry (GNUPG_Out_Of_Core);
rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
NULL);
if (rc)
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
}
if (opt.lc_messages)
{
char *optstr;
if (asprintf (&optstr, "OPTION lc-messages=%s", opt.lc_messages) < 0 )
return GNUPG_Out_Of_Core;
return unlock_pinentry (GNUPG_Out_Of_Core);
rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
NULL);
if (rc)
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
}
return 0;
}
@ -213,14 +243,14 @@ agent_askpin (const char *desc_text, const char *start_err_text,
line[DIM(line)-1] = 0;
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
rc = assuan_transact (entry_ctx,
pininfo->min_digits? "SETPROMPT PIN:"
: "SETPROMPT Passphrase:",
NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)
{
@ -242,7 +272,7 @@ agent_askpin (const char *desc_text, const char *start_err_text,
line[DIM(line)-1] = 0;
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
errtext = NULL;
}
@ -251,9 +281,9 @@ agent_askpin (const char *desc_text, const char *start_err_text,
errtext = pininfo->min_digits? trans ("PIN too long")
: trans ("Passphrase too long");
else if (rc)
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
if (!errtext && !pininfo->min_digits)
return 0; /* okay, got a passphrase */
return unlock_pinentry (0); /* okay, got a passphrase */
if (!errtext && !all_digitsp (pininfo->pin))
errtext = trans ("Invalid characters in PIN");
if (!errtext && pininfo->max_digits
@ -264,10 +294,11 @@ agent_askpin (const char *desc_text, const char *start_err_text,
errtext = trans ("PIN too short");
if (!errtext)
return 0; /* okay, got a PIN */
return unlock_pinentry (0); /* okay, got a PIN */
}
return pininfo->min_digits? GNUPG_Bad_PIN : GNUPG_Bad_Passphrase;
return unlock_pinentry (pininfo->min_digits? GNUPG_Bad_PIN
: GNUPG_Bad_Passphrase);
}
@ -301,13 +332,13 @@ agent_get_passphrase (char **retpass, const char *desc, const char *prompt,
line[DIM(line)-1] = 0;
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
snprintf (line, DIM(line)-1, "SETPROMPT %s", prompt? prompt : "Passphrase");
line[DIM(line)-1] = 0;
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
if (errtext)
{
@ -315,28 +346,28 @@ agent_get_passphrase (char **retpass, const char *desc, const char *prompt,
line[DIM(line)-1] = 0;
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
}
memset (&parm, 0, sizeof parm);
parm.size = ASSUAN_LINELENGTH/2 - 5;
parm.buffer = gcry_malloc_secure (parm.size+10);
if (!parm.buffer)
return seterr (Out_Of_Core);
return unlock_pinentry (seterr (Out_Of_Core));
assuan_begin_confidential (entry_ctx);
rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, NULL, NULL, NULL, NULL);
if (rc)
{
xfree (parm.buffer);
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
}
hexstring = gcry_malloc_secure (strlen (parm.buffer)*2+1);
if (!hexstring)
{
xfree (parm.buffer);
return seterr (Out_Of_Core);
return unlock_pinentry (seterr (Out_Of_Core));
}
for (i=0, p=parm.buffer; *p; p++, i += 2)
@ -344,7 +375,7 @@ agent_get_passphrase (char **retpass, const char *desc, const char *prompt,
xfree (parm.buffer);
*retpass = hexstring;
return 0;
return unlock_pinentry (0);
}
@ -370,7 +401,7 @@ agent_get_confirmation (const char *desc, const char *ok, const char *cancel)
line[DIM(line)-1] = 0;
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
if (ok)
{
@ -378,7 +409,7 @@ agent_get_confirmation (const char *desc, const char *ok, const char *cancel)
line[DIM(line)-1] = 0;
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
}
if (cancel)
{
@ -386,11 +417,11 @@ agent_get_confirmation (const char *desc, const char *ok, const char *cancel)
line[DIM(line)-1] = 0;
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
}
rc = assuan_transact (entry_ctx, "CONFIRM", NULL, NULL, NULL, NULL, NULL, NULL);
return map_assuan_err (rc);
return unlock_pinentry (map_assuan_err (rc));
}