mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-18 14:17:03 +01:00
Fixed agent access for gpg.
This commit is contained in:
parent
ecf7ad43f6
commit
8684a78518
@ -1,3 +1,13 @@
|
||||
2006-10-04 Werner Koch <wk@g10code.com>
|
||||
|
||||
* call-pinentry.c (agent_get_passphrase): Changed to return the
|
||||
unencoded passphrase.
|
||||
(agent_askpin, agent_get_passphrase, agent_get_confirmation): Need
|
||||
to map the cancel error.
|
||||
* command.c (send_back_passphrase): New.
|
||||
(cmd_get_passphrase): Use it here. Also implement --data option.
|
||||
(skip_options): New.
|
||||
|
||||
2006-09-26 Werner Koch <wk@g10code.com>
|
||||
|
||||
* learncard.c (agent_handle_learn): Send back the keypair
|
||||
|
@ -413,6 +413,13 @@ agent_askpin (ctrl_t ctrl,
|
||||
|
||||
rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
|
||||
NULL, NULL, NULL, NULL);
|
||||
/* Most pinentries out in the wild return the old Assuan error code
|
||||
for canceled which gets translated to an assuan Cancel error and
|
||||
not to the code for a user cancel. Fix this here. */
|
||||
if (rc && gpg_err_source (rc)
|
||||
&& gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
|
||||
rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
|
||||
|
||||
if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
|
||||
errtext = is_pin? _("PIN too long")
|
||||
: _("Passphrase too long");
|
||||
@ -456,9 +463,8 @@ agent_askpin (ctrl_t ctrl,
|
||||
|
||||
|
||||
|
||||
/* Ask for the passphrase using the supplied arguments. The
|
||||
passphrase is returned in RETPASS as an hex encoded string to be
|
||||
freed by the caller */
|
||||
/* Ask for the passphrase using the supplied arguments. The returned
|
||||
passphrase needs to be freed by the caller. */
|
||||
int
|
||||
agent_get_passphrase (ctrl_t ctrl,
|
||||
char **retpass, const char *desc, const char *prompt,
|
||||
@ -468,9 +474,6 @@ agent_get_passphrase (ctrl_t ctrl,
|
||||
int rc;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
struct entry_parm_s parm;
|
||||
unsigned char *p;
|
||||
char *hexstring;
|
||||
int i;
|
||||
|
||||
*retpass = NULL;
|
||||
if (opt.batch)
|
||||
@ -515,27 +518,18 @@ agent_get_passphrase (ctrl_t ctrl,
|
||||
return unlock_pinentry (out_of_core ());
|
||||
|
||||
assuan_begin_confidential (entry_ctx);
|
||||
rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, NULL, NULL, NULL, NULL);
|
||||
rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
|
||||
NULL, NULL, NULL, NULL);
|
||||
/* Most pinentries out in the wild return the old Assuan error code
|
||||
for canceled which gets translated to an assuan Cancel error and
|
||||
not to the code for a user cancel. Fix this here. */
|
||||
if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
|
||||
rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
|
||||
if (rc)
|
||||
{
|
||||
xfree (parm.buffer);
|
||||
return unlock_pinentry (rc);
|
||||
}
|
||||
|
||||
hexstring = gcry_malloc_secure (strlen ((char*)parm.buffer)*2+1);
|
||||
if (!hexstring)
|
||||
{
|
||||
gpg_error_t tmperr = out_of_core ();
|
||||
xfree (parm.buffer);
|
||||
return unlock_pinentry (tmperr);
|
||||
}
|
||||
|
||||
for (i=0, p=parm.buffer; *p; p++, i += 2)
|
||||
sprintf (hexstring+i, "%02X", *p);
|
||||
|
||||
xfree (parm.buffer);
|
||||
*retpass = hexstring;
|
||||
return unlock_pinentry (0);
|
||||
xfree (parm.buffer);
|
||||
else
|
||||
*retpass = parm.buffer;
|
||||
return unlock_pinentry (rc);
|
||||
}
|
||||
|
||||
|
||||
@ -561,6 +555,12 @@ agent_get_confirmation (ctrl_t ctrl,
|
||||
snprintf (line, DIM(line)-1, "RESET");
|
||||
line[DIM(line)-1] = 0;
|
||||
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
/* Most pinentries out in the wild return the old Assuan error code
|
||||
for canceled which gets translated to an assuan Cancel error and
|
||||
not to the code for a user cancel. Fix this here. */
|
||||
if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
|
||||
rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
|
||||
|
||||
if (rc)
|
||||
return unlock_pinentry (rc);
|
||||
|
||||
|
@ -136,6 +136,23 @@ has_option (const char *line, const char *name)
|
||||
return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
|
||||
}
|
||||
|
||||
/* Skip over options. It is assumed that leading spaces have been
|
||||
removed (this is the case for lines passed to a handler from
|
||||
assuan). Bkanls after the options are also removed. */
|
||||
static char *
|
||||
skip_options (char *line)
|
||||
{
|
||||
while ( *line == '-' && line[1] == '-' )
|
||||
{
|
||||
while (*line && !spacep (line))
|
||||
line++;
|
||||
while (spacep (line))
|
||||
line++;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
/* Replace all '+' by a blank. */
|
||||
static void
|
||||
plus_to_blank (char *s)
|
||||
@ -639,7 +656,33 @@ cmd_readkey (assuan_context_t ctx, char *line)
|
||||
|
||||
|
||||
|
||||
/* GET_PASSPHRASE <cache_id> [<error_message> <prompt> <description>]
|
||||
static int
|
||||
send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw)
|
||||
{
|
||||
size_t n;
|
||||
int rc;
|
||||
|
||||
assuan_begin_confidential (ctx);
|
||||
n = strlen (pw);
|
||||
if (via_data)
|
||||
rc = assuan_send_data (ctx, pw, n);
|
||||
else
|
||||
{
|
||||
char *p = xtrymalloc_secure (n*2+1);
|
||||
if (!p)
|
||||
rc = gpg_error_from_syserror ();
|
||||
else
|
||||
{
|
||||
bin2hex (pw, n, p);
|
||||
rc = assuan_set_okay_line (ctx, p);
|
||||
xfree (p);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* GET_PASSPHRASE [--data] <cache_id> [<error_message> <prompt> <description>]
|
||||
|
||||
This function is usually used to ask for a passphrase to be used
|
||||
for conventional encryption, but may also be used by programs which
|
||||
@ -648,6 +691,9 @@ cmd_readkey (assuan_context_t ctx, char *line)
|
||||
agent either returns with an error or with a OK followed by the hex
|
||||
encoded passphrase. Note that the length of the strings is
|
||||
implicitly limited by the maximum length of a command.
|
||||
|
||||
If the option "--data" is used the passphrase is returned by usual
|
||||
data lines and not on the okay line.
|
||||
*/
|
||||
|
||||
static int
|
||||
@ -660,11 +706,12 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
|
||||
char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
|
||||
char *p;
|
||||
void *cache_marker;
|
||||
int opt_data;
|
||||
|
||||
/* parse the stuff */
|
||||
for (p=line; *p == ' '; p++)
|
||||
;
|
||||
cacheid = p;
|
||||
opt_data = has_option (line, "--data");
|
||||
line = skip_options (line);
|
||||
|
||||
cacheid = line;
|
||||
p = strchr (cacheid, ' ');
|
||||
if (p)
|
||||
{
|
||||
@ -706,13 +753,11 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
|
||||
if (!strcmp (desc, "X"))
|
||||
desc = NULL;
|
||||
|
||||
/* Note: we store the hexified versions in the cache. */
|
||||
pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL, &cache_marker)
|
||||
: NULL;
|
||||
if (pw)
|
||||
{
|
||||
assuan_begin_confidential (ctx);
|
||||
rc = assuan_set_okay_line (ctx, pw);
|
||||
rc = send_back_passphrase (ctx, opt_data, pw);
|
||||
agent_unlock_cache_entry (&cache_marker);
|
||||
}
|
||||
else
|
||||
@ -733,8 +778,7 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
|
||||
{
|
||||
if (cacheid)
|
||||
agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
|
||||
assuan_begin_confidential (ctx);
|
||||
rc = assuan_set_okay_line (ctx, response);
|
||||
rc = send_back_passphrase (ctx, opt_data, response);
|
||||
xfree (response);
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,11 @@
|
||||
2006-10-04 Werner Koch <wk@g10code.com>
|
||||
|
||||
* membuf.c (init_membuf_secure): New.
|
||||
(put_membuf): Make sure that ERRNO is set even if the underlying
|
||||
malloc code does not work properly.
|
||||
(get_membuf): Set ERRNO on error.
|
||||
(get_membuf): Allow to pass LEN as NULL.
|
||||
|
||||
2006-10-02 Werner Koch <wk@g10code.com>
|
||||
|
||||
* iobuf.c (iobuf_unread): Removed. This code is not required.
|
||||
|
@ -42,7 +42,19 @@ init_membuf (membuf_t *mb, int initiallen)
|
||||
mb->out_of_core = 0;
|
||||
mb->buf = xtrymalloc (initiallen);
|
||||
if (!mb->buf)
|
||||
mb->out_of_core = errno;
|
||||
mb->out_of_core = errno;
|
||||
}
|
||||
|
||||
/* Same as init_membuf but allocates the buffer in secure memory. */
|
||||
void
|
||||
init_membuf_secure (membuf_t *mb, int initiallen)
|
||||
{
|
||||
mb->len = 0;
|
||||
mb->size = initiallen;
|
||||
mb->out_of_core = 0;
|
||||
mb->buf = xtrymalloc (initiallen);
|
||||
if (!mb->buf)
|
||||
mb->out_of_core = errno;
|
||||
}
|
||||
|
||||
|
||||
@ -60,7 +72,7 @@ put_membuf (membuf_t *mb, const void *buf, size_t len)
|
||||
p = xtryrealloc (mb->buf, mb->size);
|
||||
if (!p)
|
||||
{
|
||||
mb->out_of_core = errno;
|
||||
mb->out_of_core = errno ? errno : ENOMEM;
|
||||
/* Wipe out what we already accumulated. This is required
|
||||
in case we are storing sensitive data here. The membuf
|
||||
API does not provide another way to cleanup after an
|
||||
@ -84,11 +96,13 @@ get_membuf (membuf_t *mb, size_t *len)
|
||||
{
|
||||
xfree (mb->buf);
|
||||
mb->buf = NULL;
|
||||
errno = mb->out_of_core;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = mb->buf;
|
||||
*len = mb->len;
|
||||
if (len)
|
||||
*len = mb->len;
|
||||
mb->buf = NULL;
|
||||
mb->out_of_core = ENOMEM; /* hack to make sure it won't get reused. */
|
||||
return p;
|
||||
|
@ -24,7 +24,8 @@
|
||||
|
||||
/* The definition of the structure is private, we only need it here,
|
||||
so it can be allocated on the stack. */
|
||||
struct private_membuf_s {
|
||||
struct private_membuf_s
|
||||
{
|
||||
size_t len;
|
||||
size_t size;
|
||||
char *buf;
|
||||
@ -35,6 +36,7 @@ typedef struct private_membuf_s membuf_t;
|
||||
|
||||
|
||||
void init_membuf (membuf_t *mb, int initiallen);
|
||||
void init_membuf_secure (membuf_t *mb, int initiallen);
|
||||
void put_membuf (membuf_t *mb, const void *buf, size_t len);
|
||||
void *get_membuf (membuf_t *mb, size_t *len);
|
||||
|
||||
|
@ -970,12 +970,15 @@ special handling of passphrases. This command uses a syntax which helps
|
||||
clients to use the agent with minimum effort.
|
||||
|
||||
@example
|
||||
GET_PASSPHRASE @var{cache_id} [@var{error_message} @var{prompt} @var{description}]
|
||||
GET_PASSPHRASE [--data] @var{cache_id} [@var{error_message} @var{prompt} @var{description}]
|
||||
@end example
|
||||
|
||||
@var{cache_id} is expected to be a hex string used for caching a
|
||||
@var{cache_id} is expected to be a string used to identify a cached
|
||||
passphrase. Use a @code{X} to bypass the cache. With no other
|
||||
arguments the agent returns a cached passphrase or an error.
|
||||
arguments the agent returns a cached passphrase or an error. By
|
||||
convention either the hexified fingerprint of the key shall be used for
|
||||
@var{cache_id} or an arbitrary string prefixed with the name of the
|
||||
calling application and a colon: Like @code{gpg:somestring}.
|
||||
|
||||
@var{error_message} is either a single @code{X} for no error message or
|
||||
a string to be shown as an error message like (e.g. "invalid
|
||||
@ -988,9 +991,11 @@ replaced by @code{+}.
|
||||
@var{description} is a text shown above the entry field. Blanks must be
|
||||
percent escaped or replaced by @code{+}.
|
||||
|
||||
The agent either returns with an error or with a OK followed by the
|
||||
hex encoded passphrase. Note that the length of the strings is
|
||||
implicitly limited by the maximum length of a command.
|
||||
The agent either returns with an error or with a OK followed by the hex
|
||||
encoded passphrase. Note that the length of the strings is implicitly
|
||||
limited by the maximum length of a command. If the option
|
||||
@option{--data} is used, the passphrase is not returned on the OK line
|
||||
but by regular data lines; this is the preferred method.
|
||||
|
||||
@example
|
||||
CLEAR_PASSPHRASE @var{cache_id}
|
||||
|
@ -2184,6 +2184,7 @@ signatures to prevent the mail system from breaking the signature. Note
|
||||
that all other PGP versions do it this way too. Enabled by
|
||||
default. @option{--no-escape-from-lines} disables this option.
|
||||
|
||||
@ifset gpgone
|
||||
@item --passphrase-fd @code{n}
|
||||
Read the passphrase from file descriptor @code{n}. Only the first line
|
||||
will be read from file descriptor @code{n}. If you use 0 for @code{n},
|
||||
@ -2202,6 +2203,7 @@ Use @code{string} as the passphrase. This can only be used if only one
|
||||
passphrase is supplied. Obviously, this is of very questionable
|
||||
security on a multi-user system. Don't use this option if you can
|
||||
avoid it.
|
||||
@end ifset
|
||||
|
||||
@item --command-fd @code{n}
|
||||
This is a replacement for the deprecated shared-memory IPC mode.
|
||||
|
@ -1,8 +1,26 @@
|
||||
2006-10-04 Werner Koch <wk@g10code.com>
|
||||
|
||||
* call-agent.c (agent_havekey): Removed.
|
||||
(percent_plus_escape): New.
|
||||
(agent_get_passphrase): New.
|
||||
(agent_clear_passphrase): New.
|
||||
|
||||
* passphrase.c: Changed so that we always require the agent.
|
||||
(agent_send_option, agent_send_all_options, agent_open): Removed.
|
||||
(agent_get_passphrase): Cleaned up. Does now use the call-agent
|
||||
functions. Renamed to
|
||||
(passphrase_get): .. this. Changed all callers.
|
||||
(passphrase_clear_cache): Rewritten.
|
||||
(passphrase_to_dek, hash_passphrase): Re-indented.
|
||||
|
||||
* gpg.c (main): Made --use-agent a dummy option.
|
||||
* seckey-cert.c (check_secret_key): We require the agent, so always
|
||||
allow for 3 tries.
|
||||
|
||||
* gpg.c (main): Print a warning if -sat has been used.
|
||||
(main): Removed the special treatment of the -k option. -k is now
|
||||
an alias for --list-keys.
|
||||
(main): Removed --list-ownertrust.
|
||||
|
||||
2006-10-02 Werner Koch <wk@g10code.com>
|
||||
|
||||
|
208
g10/call-agent.c
208
g10/call-agent.c
@ -218,6 +218,30 @@ unescape_status_string (const unsigned char *s)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* Copy the text ATEXT into the buffer P and do plus '+' and percent
|
||||
escaping. Note that the provided buffer needs to be 3 times the
|
||||
size of ATEXT plus 1. Returns a pointer to the leading Nul in P. */
|
||||
static char *
|
||||
percent_plus_escape (char *p, const char *atext)
|
||||
{
|
||||
const unsigned char *s;
|
||||
|
||||
for (s=atext; *s; s++)
|
||||
{
|
||||
if (*s < ' ' || *s == '+')
|
||||
{
|
||||
sprintf (p, "%%%02X", *s);
|
||||
p += 3;
|
||||
}
|
||||
else if (*s == ' ')
|
||||
*p++ = '+';
|
||||
else
|
||||
*p++ = *s;
|
||||
}
|
||||
*p = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Take a 20 byte hexencoded string and put it into the the provided
|
||||
20 byte buffer FPR in binary format. */
|
||||
static int
|
||||
@ -257,93 +281,6 @@ store_serialno (const char *line)
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
/* Handle a KEYPARMS inquiry. Note, we only send the data,
|
||||
assuan_transact takes care of flushing and writing the end */
|
||||
static int
|
||||
inq_genkey_parms (void *opaque, const char *keyword)
|
||||
{
|
||||
struct genkey_parm_s *parm = opaque;
|
||||
int rc;
|
||||
|
||||
rc = assuan_send_data (parm->ctx, parm->sexp, parm->sexplen);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Call the agent to generate a new key */
|
||||
int
|
||||
agent_genkey (KsbaConstSexp keyparms, KsbaSexp *r_pubkey)
|
||||
{
|
||||
int rc;
|
||||
struct genkey_parm_s gk_parm;
|
||||
membuf_t data;
|
||||
size_t len;
|
||||
char *buf;
|
||||
|
||||
*r_pubkey = NULL;
|
||||
rc = start_agent ();
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = assuan_transact (agent_ctx, "RESET", NULL, NULL,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
init_membuf (&data, 1024);
|
||||
gk_parm.ctx = agent_ctx;
|
||||
gk_parm.sexp = keyparms;
|
||||
gk_parm.sexplen = gcry_sexp_canon_len (keyparms, 0, NULL, NULL);
|
||||
if (!gk_parm.sexplen)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
rc = assuan_transact (agent_ctx, "GENKEY",
|
||||
membuf_data_cb, &data,
|
||||
inq_genkey_parms, &gk_parm, NULL, NULL);
|
||||
if (rc)
|
||||
{
|
||||
xfree (get_membuf (&data, &len));
|
||||
return rc;
|
||||
}
|
||||
buf = get_membuf (&data, &len);
|
||||
if (!buf)
|
||||
return gpg_error (GPG_ERR_ENOMEM);
|
||||
if (!gcry_sexp_canon_len (buf, len, NULL, NULL))
|
||||
{
|
||||
xfree (buf);
|
||||
return gpg_error (GPG_ERR_INV_SEXP);
|
||||
}
|
||||
*r_pubkey = buf;
|
||||
return 0;
|
||||
}
|
||||
#endif /*0*/
|
||||
|
||||
|
||||
|
||||
/* Ask the agent whether the corresponding secret key is available for
|
||||
the given keygrip. */
|
||||
int
|
||||
agent_havekey (const char *hexkeygrip)
|
||||
{
|
||||
int rc;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
|
||||
rc = start_agent ();
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (!hexkeygrip || strlen (hexkeygrip) != 40)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
snprintf (line, DIM(line)-1, "HAVEKEY %s", hexkeygrip);
|
||||
line[DIM(line)-1] = 0;
|
||||
|
||||
rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* Release the card info structure INFO. */
|
||||
void
|
||||
@ -856,3 +793,100 @@ agent_clear_pin_cache (const char *sn)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Note: All strings shall be UTF-8. On success the caler needs to
|
||||
free the string stored at R_PASSPHRASE. On error NULL will be
|
||||
stored at R_PASSPHRASE and an appropriate fpf error code
|
||||
returned. */
|
||||
gpg_error_t
|
||||
agent_get_passphrase (const char *cache_id,
|
||||
const char *err_msg,
|
||||
const char *prompt,
|
||||
const char *desc_msg,
|
||||
char **r_passphrase)
|
||||
{
|
||||
int rc;
|
||||
char *line, *p;
|
||||
char cmd[] = "GET_PASSPHRASE --data -- ";
|
||||
membuf_t data;
|
||||
|
||||
*r_passphrase = NULL;
|
||||
|
||||
rc = start_agent ();
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* We allocate 3 times the needed space for the texts so that
|
||||
there is enough space for escaping. */
|
||||
line = xtrymalloc ( strlen (cmd) + 1
|
||||
+ (cache_id? 3*strlen (cache_id): 1) + 1
|
||||
+ (err_msg? 3*strlen (err_msg): 1) + 1
|
||||
+ (prompt? 3*strlen (prompt): 1) + 1
|
||||
+ (desc_msg? 3*strlen (desc_msg): 1) + 1
|
||||
+ 1);
|
||||
if (!line)
|
||||
return gpg_error_from_syserror ();
|
||||
|
||||
p = stpcpy (line, cmd);
|
||||
if (cache_id && *cache_id)
|
||||
p = percent_plus_escape (p, cache_id);
|
||||
else
|
||||
*p++ = 'X';
|
||||
*p++ = ' ';
|
||||
|
||||
if (err_msg && *err_msg)
|
||||
p = percent_plus_escape (p, err_msg);
|
||||
else
|
||||
*p++ = 'X';
|
||||
*p++ = ' ';
|
||||
|
||||
if (prompt && *prompt)
|
||||
p = percent_plus_escape (p, prompt);
|
||||
else
|
||||
*p++ = 'X';
|
||||
*p++ = ' ';
|
||||
|
||||
if (desc_msg && *desc_msg)
|
||||
p = percent_plus_escape (p, desc_msg);
|
||||
else
|
||||
*p++ = 'X';
|
||||
*p = 0;
|
||||
|
||||
init_membuf_secure (&data, 64);
|
||||
rc = assuan_transact (agent_ctx, line,
|
||||
membuf_data_cb, &data, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (rc)
|
||||
xfree (get_membuf (&data, NULL));
|
||||
else
|
||||
{
|
||||
put_membuf (&data, "", 1);
|
||||
*r_passphrase = get_membuf (&data, NULL);
|
||||
if (!*r_passphrase)
|
||||
rc = gpg_error_from_syserror ();
|
||||
}
|
||||
xfree (line);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
gpg_error_t
|
||||
agent_clear_passphrase (const char *cache_id)
|
||||
{
|
||||
int rc;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
|
||||
if (!cache_id || !*cache_id)
|
||||
return 0;
|
||||
|
||||
rc = start_agent ();
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
snprintf (line, DIM(line)-1, "CLEAR_PASSPHRASE %s", cache_id);
|
||||
line[DIM(line)-1] = 0;
|
||||
return assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
@ -73,10 +73,6 @@ int agent_learn (struct agent_card_info_s *info);
|
||||
/* Update INFO with the attribute NAME. */
|
||||
int agent_scd_getattr (const char *name, struct agent_card_info_s *info);
|
||||
|
||||
/* Check whether the secret key for the key identified by HEXKEYGRIP
|
||||
is available. Return 0 for yes or an error code. */
|
||||
int agent_havekey (const char *hexkeygrip);
|
||||
|
||||
/* Send a SETATTR command to the SCdaemon. */
|
||||
int agent_scd_setattr (const char *name,
|
||||
const unsigned char *value, size_t valuelen,
|
||||
@ -110,5 +106,16 @@ int agent_scd_checkpin (const char *serialno);
|
||||
void agent_clear_pin_cache (const char *sn);
|
||||
|
||||
|
||||
/* Send the GET_PASSPHRASE command to the agent. */
|
||||
gpg_error_t agent_get_passphrase (const char *cache_id,
|
||||
const char *err_msg,
|
||||
const char *prompt,
|
||||
const char *desc_msg,
|
||||
char **r_passphrase);
|
||||
|
||||
/* Send the CLEAR_PASSPHRASE command to the agent. */
|
||||
gpg_error_t agent_clear_passphrase (const char *cache_id);
|
||||
|
||||
|
||||
#endif /*GNUPG_G10_CALL_AGENT_H*/
|
||||
|
||||
|
88
g10/gpg.c
88
g10/gpg.c
@ -78,7 +78,7 @@ enum cmd_and_opt_values
|
||||
aDecrypt = 'd',
|
||||
aEncr = 'e',
|
||||
oInteractive = 'i',
|
||||
oListKeys = 'k',
|
||||
aListKeys = 'k',
|
||||
oDryRun = 'n',
|
||||
oOutput = 'o',
|
||||
oQuiet = 'q',
|
||||
@ -140,7 +140,6 @@ enum cmd_and_opt_values
|
||||
aListTrustDB,
|
||||
aListTrustPath,
|
||||
aExportOwnerTrust,
|
||||
aListOwnerTrust,
|
||||
aImportOwnerTrust,
|
||||
aDeArmor,
|
||||
aEnArmor,
|
||||
@ -554,7 +553,6 @@ static ARGPARSE_OPTS opts[] = {
|
||||
" --fingerprint [names] show fingerprints\n" ) },
|
||||
|
||||
/* hidden options */
|
||||
{ aListOwnerTrust, "list-ownertrust", 256, "@"}, /* deprecated */
|
||||
{ aPrintMDs, "print-mds" , 256, "@"}, /* old */
|
||||
{ aListTrustDB, "list-trustdb",0 , "@"},
|
||||
/* Not yet used */
|
||||
@ -1896,7 +1894,7 @@ main (int argc, char **argv )
|
||||
/* malloc hooks go here ... */
|
||||
assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
|
||||
assuan_set_assuan_err_source (GPG_ERR_SOURCE_DEFAULT);
|
||||
|
||||
|
||||
|
||||
set_native_charset (NULL); /* Try to auto set the character set */
|
||||
|
||||
@ -2014,25 +2012,45 @@ main (int argc, char **argv )
|
||||
case aCardEdit:
|
||||
case aChangePIN:
|
||||
#endif /* ENABLE_CARD_SUPPORT*/
|
||||
case aListKeys:
|
||||
case aListSigs:
|
||||
case aExportSecret:
|
||||
case aExportSecretSub:
|
||||
case aSym:
|
||||
case aClearsign:
|
||||
case aGenRevoke:
|
||||
case aDesigRevoke:
|
||||
case aPrimegen:
|
||||
case aGenRandom:
|
||||
case aPrintMD:
|
||||
case aPrintMDs:
|
||||
case aListTrustDB:
|
||||
case aCheckTrustDB:
|
||||
case aUpdateTrustDB:
|
||||
case aFixTrustDB:
|
||||
case aListTrustPath:
|
||||
case aDeArmor:
|
||||
case aEnArmor:
|
||||
case aSign:
|
||||
case aSignKey:
|
||||
case aLSignKey:
|
||||
case aStore:
|
||||
case aExportOwnerTrust:
|
||||
case aImportOwnerTrust:
|
||||
case aRebuildKeydbCaches:
|
||||
set_cmd (&cmd, pargs.r_opt);
|
||||
break;
|
||||
|
||||
case aListKeys: set_cmd( &cmd, aListKeys); break;
|
||||
case aListSigs: set_cmd( &cmd, aListSigs); break;
|
||||
case aExportSecret: set_cmd( &cmd, aExportSecret); break;
|
||||
case aExportSecretSub: set_cmd( &cmd, aExportSecretSub); break;
|
||||
case aKeygen:
|
||||
case aEditKey:
|
||||
case aDeleteSecretKeys:
|
||||
set_cmd( &cmd, aDeleteSecretKeys);
|
||||
greeting=1;
|
||||
break;
|
||||
case aDeleteSecretAndPublicKeys:
|
||||
set_cmd( &cmd, aDeleteSecretAndPublicKeys);
|
||||
greeting=1;
|
||||
case aDeleteKeys:
|
||||
set_cmd (&cmd, pargs.r_opt);
|
||||
greeting=1;
|
||||
break;
|
||||
case aDeleteKeys: set_cmd( &cmd, aDeleteKeys); greeting=1; break;
|
||||
|
||||
case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
|
||||
case aSym: set_cmd( &cmd, aSym); break;
|
||||
|
||||
case aDecryptFiles: multifile=1; /* fall through */
|
||||
case aDecrypt: set_cmd( &cmd, aDecrypt); break;
|
||||
@ -2043,32 +2061,6 @@ main (int argc, char **argv )
|
||||
case aVerifyFiles: multifile=1; /* fall through */
|
||||
case aVerify: set_cmd( &cmd, aVerify); break;
|
||||
|
||||
case aSign: set_cmd( &cmd, aSign ); break;
|
||||
case aKeygen: set_cmd( &cmd, aKeygen); greeting=1; break;
|
||||
case aSignKey: set_cmd( &cmd, aSignKey); break;
|
||||
case aLSignKey: set_cmd( &cmd, aLSignKey); break;
|
||||
case aStore: set_cmd( &cmd, aStore); break;
|
||||
case aEditKey: set_cmd( &cmd, aEditKey); greeting=1; break;
|
||||
case aClearsign: set_cmd( &cmd, aClearsign); break;
|
||||
case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
|
||||
case aDesigRevoke: set_cmd( &cmd, aDesigRevoke); break;
|
||||
case aPrimegen: set_cmd( &cmd, aPrimegen); break;
|
||||
case aGenRandom: set_cmd( &cmd, aGenRandom); break;
|
||||
case aPrintMD: set_cmd( &cmd, aPrintMD); break;
|
||||
case aPrintMDs: set_cmd( &cmd, aPrintMDs); break;
|
||||
case aListTrustDB: set_cmd( &cmd, aListTrustDB); break;
|
||||
case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break;
|
||||
case aUpdateTrustDB: set_cmd( &cmd, aUpdateTrustDB); break;
|
||||
case aFixTrustDB: set_cmd( &cmd, aFixTrustDB); break;
|
||||
case aListTrustPath: set_cmd( &cmd, aListTrustPath); break;
|
||||
case aDeArmor: set_cmd( &cmd, aDeArmor); break;
|
||||
case aEnArmor: set_cmd( &cmd, aEnArmor); break;
|
||||
case aListOwnerTrust:
|
||||
deprecated_warning(configname,configlineno,
|
||||
"--list-ownertrust","--export-ownertrust","");
|
||||
case aExportOwnerTrust: set_cmd( &cmd, aExportOwnerTrust); break;
|
||||
case aImportOwnerTrust: set_cmd( &cmd, aImportOwnerTrust); break;
|
||||
case aRebuildKeydbCaches: set_cmd( &cmd, aRebuildKeydbCaches); break;
|
||||
|
||||
case oArmor: opt.armor = 1; opt.no_armor=0; break;
|
||||
case oOutput: opt.outfile = pargs.r.ret_str; break;
|
||||
@ -2085,15 +2077,8 @@ main (int argc, char **argv )
|
||||
break;
|
||||
|
||||
case oBatch: opt.batch = 1; nogreeting = 1; break;
|
||||
case oUseAgent:
|
||||
#ifndef __riscos__
|
||||
opt.use_agent = 1;
|
||||
#else /* __riscos__ */
|
||||
opt.use_agent = 0;
|
||||
riscos_not_implemented("use-agent");
|
||||
#endif /* __riscos__ */
|
||||
break;
|
||||
case oNoUseAgent: opt.use_agent = 0; break;
|
||||
case oUseAgent: /* Dummy. */
|
||||
case oNoUseAgent: /* Dummy. */ break;
|
||||
case oGpgAgentInfo: opt.gpg_agent_info = pargs.r.ret_str; break;
|
||||
case oAnswerYes: opt.answer_yes = 1; break;
|
||||
case oAnswerNo: opt.answer_no = 1; break;
|
||||
@ -2397,7 +2382,6 @@ main (int argc, char **argv )
|
||||
break;
|
||||
case oPasswdFD:
|
||||
pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
|
||||
opt.use_agent = 0;
|
||||
break;
|
||||
case oPasswdFile:
|
||||
pwfd = open_info_file (pargs.r.ret_str, 0);
|
||||
@ -2809,8 +2793,6 @@ main (int argc, char **argv )
|
||||
}
|
||||
#endif
|
||||
|
||||
log_info ("WARNING: This version of gpg is not ready for use, use gpg 1.4.x\n");
|
||||
|
||||
/* FIXME: We should use logging to a file only in server mode;
|
||||
however we have not yet implemetyed that. Thus we try to get
|
||||
away with --batch as indication for logging to file
|
||||
|
@ -184,7 +184,7 @@ struct
|
||||
int command_fd;
|
||||
const char *override_session_key;
|
||||
int show_session_key;
|
||||
int use_agent;
|
||||
|
||||
const char *gpg_agent_info;
|
||||
int try_all_secrets;
|
||||
int no_expensive_trust_checks;
|
||||
|
1048
g10/passphrase.c
1048
g10/passphrase.c
File diff suppressed because it is too large
Load Diff
@ -284,7 +284,7 @@ check_secret_key( PKT_secret_key *sk, int n )
|
||||
mode=0;
|
||||
|
||||
if( n < 1 )
|
||||
n = (opt.batch && !opt.use_agent)? 1 : 3; /* use the default value */
|
||||
n = 3; /* Use the default value */
|
||||
|
||||
for(i=0; i < n && gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE; i++ ) {
|
||||
int canceled = 0;
|
||||
|
375
po/pt_BR.po
375
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
375
po/zh_CN.po
375
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
375
po/zh_TW.po
375
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user