mirror of git://git.gnupg.org/gnupg.git
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>
|
2006-09-26 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* learncard.c (agent_handle_learn): Send back the keypair
|
* 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,
|
rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
|
||||||
NULL, NULL, 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 (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
|
if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
|
||||||
errtext = is_pin? _("PIN too long")
|
errtext = is_pin? _("PIN too long")
|
||||||
: _("Passphrase too long");
|
: _("Passphrase too long");
|
||||||
|
@ -456,9 +463,8 @@ agent_askpin (ctrl_t ctrl,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Ask for the passphrase using the supplied arguments. The
|
/* Ask for the passphrase using the supplied arguments. The returned
|
||||||
passphrase is returned in RETPASS as an hex encoded string to be
|
passphrase needs to be freed by the caller. */
|
||||||
freed by the caller */
|
|
||||||
int
|
int
|
||||||
agent_get_passphrase (ctrl_t ctrl,
|
agent_get_passphrase (ctrl_t ctrl,
|
||||||
char **retpass, const char *desc, const char *prompt,
|
char **retpass, const char *desc, const char *prompt,
|
||||||
|
@ -468,9 +474,6 @@ agent_get_passphrase (ctrl_t ctrl,
|
||||||
int rc;
|
int rc;
|
||||||
char line[ASSUAN_LINELENGTH];
|
char line[ASSUAN_LINELENGTH];
|
||||||
struct entry_parm_s parm;
|
struct entry_parm_s parm;
|
||||||
unsigned char *p;
|
|
||||||
char *hexstring;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
*retpass = NULL;
|
*retpass = NULL;
|
||||||
if (opt.batch)
|
if (opt.batch)
|
||||||
|
@ -515,27 +518,18 @@ agent_get_passphrase (ctrl_t ctrl,
|
||||||
return unlock_pinentry (out_of_core ());
|
return unlock_pinentry (out_of_core ());
|
||||||
|
|
||||||
assuan_begin_confidential (entry_ctx);
|
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)
|
if (rc)
|
||||||
{
|
xfree (parm.buffer);
|
||||||
xfree (parm.buffer);
|
else
|
||||||
return unlock_pinentry (rc);
|
*retpass = 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -561,6 +555,12 @@ agent_get_confirmation (ctrl_t ctrl,
|
||||||
snprintf (line, DIM(line)-1, "RESET");
|
snprintf (line, DIM(line)-1, "RESET");
|
||||||
line[DIM(line)-1] = 0;
|
line[DIM(line)-1] = 0;
|
||||||
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
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)
|
if (rc)
|
||||||
return unlock_pinentry (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)));
|
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. */
|
/* Replace all '+' by a blank. */
|
||||||
static void
|
static void
|
||||||
plus_to_blank (char *s)
|
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
|
This function is usually used to ask for a passphrase to be used
|
||||||
for conventional encryption, but may also be used by programs which
|
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
|
agent either returns with an error or with a OK followed by the hex
|
||||||
encoded passphrase. Note that the length of the strings is
|
encoded passphrase. Note that the length of the strings is
|
||||||
implicitly limited by the maximum length of a command.
|
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
|
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 *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
|
||||||
char *p;
|
char *p;
|
||||||
void *cache_marker;
|
void *cache_marker;
|
||||||
|
int opt_data;
|
||||||
|
|
||||||
/* parse the stuff */
|
opt_data = has_option (line, "--data");
|
||||||
for (p=line; *p == ' '; p++)
|
line = skip_options (line);
|
||||||
;
|
|
||||||
cacheid = p;
|
cacheid = line;
|
||||||
p = strchr (cacheid, ' ');
|
p = strchr (cacheid, ' ');
|
||||||
if (p)
|
if (p)
|
||||||
{
|
{
|
||||||
|
@ -706,13 +753,11 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
|
||||||
if (!strcmp (desc, "X"))
|
if (!strcmp (desc, "X"))
|
||||||
desc = NULL;
|
desc = NULL;
|
||||||
|
|
||||||
/* Note: we store the hexified versions in the cache. */
|
|
||||||
pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL, &cache_marker)
|
pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL, &cache_marker)
|
||||||
: NULL;
|
: NULL;
|
||||||
if (pw)
|
if (pw)
|
||||||
{
|
{
|
||||||
assuan_begin_confidential (ctx);
|
rc = send_back_passphrase (ctx, opt_data, pw);
|
||||||
rc = assuan_set_okay_line (ctx, pw);
|
|
||||||
agent_unlock_cache_entry (&cache_marker);
|
agent_unlock_cache_entry (&cache_marker);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -733,8 +778,7 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
if (cacheid)
|
if (cacheid)
|
||||||
agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
|
agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
|
||||||
assuan_begin_confidential (ctx);
|
rc = send_back_passphrase (ctx, opt_data, response);
|
||||||
rc = assuan_set_okay_line (ctx, response);
|
|
||||||
xfree (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>
|
2006-10-02 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* iobuf.c (iobuf_unread): Removed. This code is not required.
|
* 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->out_of_core = 0;
|
||||||
mb->buf = xtrymalloc (initiallen);
|
mb->buf = xtrymalloc (initiallen);
|
||||||
if (!mb->buf)
|
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);
|
p = xtryrealloc (mb->buf, mb->size);
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
mb->out_of_core = errno;
|
mb->out_of_core = errno ? errno : ENOMEM;
|
||||||
/* Wipe out what we already accumulated. This is required
|
/* Wipe out what we already accumulated. This is required
|
||||||
in case we are storing sensitive data here. The membuf
|
in case we are storing sensitive data here. The membuf
|
||||||
API does not provide another way to cleanup after an
|
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);
|
xfree (mb->buf);
|
||||||
mb->buf = NULL;
|
mb->buf = NULL;
|
||||||
|
errno = mb->out_of_core;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = mb->buf;
|
p = mb->buf;
|
||||||
*len = mb->len;
|
if (len)
|
||||||
|
*len = mb->len;
|
||||||
mb->buf = NULL;
|
mb->buf = NULL;
|
||||||
mb->out_of_core = ENOMEM; /* hack to make sure it won't get reused. */
|
mb->out_of_core = ENOMEM; /* hack to make sure it won't get reused. */
|
||||||
return p;
|
return p;
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
|
|
||||||
/* The definition of the structure is private, we only need it here,
|
/* The definition of the structure is private, we only need it here,
|
||||||
so it can be allocated on the stack. */
|
so it can be allocated on the stack. */
|
||||||
struct private_membuf_s {
|
struct private_membuf_s
|
||||||
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
size_t size;
|
size_t size;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
@ -35,6 +36,7 @@ typedef struct private_membuf_s membuf_t;
|
||||||
|
|
||||||
|
|
||||||
void init_membuf (membuf_t *mb, int initiallen);
|
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 put_membuf (membuf_t *mb, const void *buf, size_t len);
|
||||||
void *get_membuf (membuf_t *mb, 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.
|
clients to use the agent with minimum effort.
|
||||||
|
|
||||||
@example
|
@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
|
@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
|
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
|
@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
|
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
|
@var{description} is a text shown above the entry field. Blanks must be
|
||||||
percent escaped or replaced by @code{+}.
|
percent escaped or replaced by @code{+}.
|
||||||
|
|
||||||
The agent either returns with an error or with a OK followed by the
|
The agent either returns with an error or with a OK followed by the hex
|
||||||
hex encoded passphrase. Note that the length of the strings is
|
encoded passphrase. Note that the length of the strings is implicitly
|
||||||
implicitly limited by the maximum length of a command.
|
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
|
@example
|
||||||
CLEAR_PASSPHRASE @var{cache_id}
|
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
|
that all other PGP versions do it this way too. Enabled by
|
||||||
default. @option{--no-escape-from-lines} disables this option.
|
default. @option{--no-escape-from-lines} disables this option.
|
||||||
|
|
||||||
|
@ifset gpgone
|
||||||
@item --passphrase-fd @code{n}
|
@item --passphrase-fd @code{n}
|
||||||
Read the passphrase from file descriptor @code{n}. Only the first line
|
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},
|
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
|
passphrase is supplied. Obviously, this is of very questionable
|
||||||
security on a multi-user system. Don't use this option if you can
|
security on a multi-user system. Don't use this option if you can
|
||||||
avoid it.
|
avoid it.
|
||||||
|
@end ifset
|
||||||
|
|
||||||
@item --command-fd @code{n}
|
@item --command-fd @code{n}
|
||||||
This is a replacement for the deprecated shared-memory IPC mode.
|
This is a replacement for the deprecated shared-memory IPC mode.
|
||||||
|
|
|
@ -1,8 +1,26 @@
|
||||||
2006-10-04 Werner Koch <wk@g10code.com>
|
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.
|
* gpg.c (main): Print a warning if -sat has been used.
|
||||||
(main): Removed the special treatment of the -k option. -k is now
|
(main): Removed the special treatment of the -k option. -k is now
|
||||||
an alias for --list-keys.
|
an alias for --list-keys.
|
||||||
|
(main): Removed --list-ownertrust.
|
||||||
|
|
||||||
2006-10-02 Werner Koch <wk@g10code.com>
|
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;
|
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
|
/* Take a 20 byte hexencoded string and put it into the the provided
|
||||||
20 byte buffer FPR in binary format. */
|
20 byte buffer FPR in binary format. */
|
||||||
static int
|
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. */
|
/* Release the card info structure INFO. */
|
||||||
void
|
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. */
|
/* Update INFO with the attribute NAME. */
|
||||||
int agent_scd_getattr (const char *name, struct agent_card_info_s *info);
|
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. */
|
/* Send a SETATTR command to the SCdaemon. */
|
||||||
int agent_scd_setattr (const char *name,
|
int agent_scd_setattr (const char *name,
|
||||||
const unsigned char *value, size_t valuelen,
|
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);
|
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*/
|
#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',
|
aDecrypt = 'd',
|
||||||
aEncr = 'e',
|
aEncr = 'e',
|
||||||
oInteractive = 'i',
|
oInteractive = 'i',
|
||||||
oListKeys = 'k',
|
aListKeys = 'k',
|
||||||
oDryRun = 'n',
|
oDryRun = 'n',
|
||||||
oOutput = 'o',
|
oOutput = 'o',
|
||||||
oQuiet = 'q',
|
oQuiet = 'q',
|
||||||
|
@ -140,7 +140,6 @@ enum cmd_and_opt_values
|
||||||
aListTrustDB,
|
aListTrustDB,
|
||||||
aListTrustPath,
|
aListTrustPath,
|
||||||
aExportOwnerTrust,
|
aExportOwnerTrust,
|
||||||
aListOwnerTrust,
|
|
||||||
aImportOwnerTrust,
|
aImportOwnerTrust,
|
||||||
aDeArmor,
|
aDeArmor,
|
||||||
aEnArmor,
|
aEnArmor,
|
||||||
|
@ -554,7 +553,6 @@ static ARGPARSE_OPTS opts[] = {
|
||||||
" --fingerprint [names] show fingerprints\n" ) },
|
" --fingerprint [names] show fingerprints\n" ) },
|
||||||
|
|
||||||
/* hidden options */
|
/* hidden options */
|
||||||
{ aListOwnerTrust, "list-ownertrust", 256, "@"}, /* deprecated */
|
|
||||||
{ aPrintMDs, "print-mds" , 256, "@"}, /* old */
|
{ aPrintMDs, "print-mds" , 256, "@"}, /* old */
|
||||||
{ aListTrustDB, "list-trustdb",0 , "@"},
|
{ aListTrustDB, "list-trustdb",0 , "@"},
|
||||||
/* Not yet used */
|
/* Not yet used */
|
||||||
|
@ -1896,7 +1894,7 @@ main (int argc, char **argv )
|
||||||
/* malloc hooks go here ... */
|
/* malloc hooks go here ... */
|
||||||
assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
|
assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
|
||||||
assuan_set_assuan_err_source (GPG_ERR_SOURCE_DEFAULT);
|
assuan_set_assuan_err_source (GPG_ERR_SOURCE_DEFAULT);
|
||||||
|
|
||||||
|
|
||||||
set_native_charset (NULL); /* Try to auto set the character set */
|
set_native_charset (NULL); /* Try to auto set the character set */
|
||||||
|
|
||||||
|
@ -2014,25 +2012,45 @@ main (int argc, char **argv )
|
||||||
case aCardEdit:
|
case aCardEdit:
|
||||||
case aChangePIN:
|
case aChangePIN:
|
||||||
#endif /* ENABLE_CARD_SUPPORT*/
|
#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);
|
set_cmd (&cmd, pargs.r_opt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case aListKeys: set_cmd( &cmd, aListKeys); break;
|
case aKeygen:
|
||||||
case aListSigs: set_cmd( &cmd, aListSigs); break;
|
case aEditKey:
|
||||||
case aExportSecret: set_cmd( &cmd, aExportSecret); break;
|
|
||||||
case aExportSecretSub: set_cmd( &cmd, aExportSecretSub); break;
|
|
||||||
case aDeleteSecretKeys:
|
case aDeleteSecretKeys:
|
||||||
set_cmd( &cmd, aDeleteSecretKeys);
|
|
||||||
greeting=1;
|
|
||||||
break;
|
|
||||||
case aDeleteSecretAndPublicKeys:
|
case aDeleteSecretAndPublicKeys:
|
||||||
set_cmd( &cmd, aDeleteSecretAndPublicKeys);
|
case aDeleteKeys:
|
||||||
greeting=1;
|
set_cmd (&cmd, pargs.r_opt);
|
||||||
|
greeting=1;
|
||||||
break;
|
break;
|
||||||
case aDeleteKeys: set_cmd( &cmd, aDeleteKeys); greeting=1; break;
|
|
||||||
|
|
||||||
case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); 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 aDecryptFiles: multifile=1; /* fall through */
|
||||||
case aDecrypt: set_cmd( &cmd, aDecrypt); break;
|
case aDecrypt: set_cmd( &cmd, aDecrypt); break;
|
||||||
|
@ -2043,32 +2061,6 @@ main (int argc, char **argv )
|
||||||
case aVerifyFiles: multifile=1; /* fall through */
|
case aVerifyFiles: multifile=1; /* fall through */
|
||||||
case aVerify: set_cmd( &cmd, aVerify); break;
|
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 oArmor: opt.armor = 1; opt.no_armor=0; break;
|
||||||
case oOutput: opt.outfile = pargs.r.ret_str; break;
|
case oOutput: opt.outfile = pargs.r.ret_str; break;
|
||||||
|
@ -2085,15 +2077,8 @@ main (int argc, char **argv )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case oBatch: opt.batch = 1; nogreeting = 1; break;
|
case oBatch: opt.batch = 1; nogreeting = 1; break;
|
||||||
case oUseAgent:
|
case oUseAgent: /* Dummy. */
|
||||||
#ifndef __riscos__
|
case oNoUseAgent: /* Dummy. */ break;
|
||||||
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 oGpgAgentInfo: opt.gpg_agent_info = pargs.r.ret_str; break;
|
case oGpgAgentInfo: opt.gpg_agent_info = pargs.r.ret_str; break;
|
||||||
case oAnswerYes: opt.answer_yes = 1; break;
|
case oAnswerYes: opt.answer_yes = 1; break;
|
||||||
case oAnswerNo: opt.answer_no = 1; break;
|
case oAnswerNo: opt.answer_no = 1; break;
|
||||||
|
@ -2397,7 +2382,6 @@ main (int argc, char **argv )
|
||||||
break;
|
break;
|
||||||
case oPasswdFD:
|
case oPasswdFD:
|
||||||
pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
|
pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
|
||||||
opt.use_agent = 0;
|
|
||||||
break;
|
break;
|
||||||
case oPasswdFile:
|
case oPasswdFile:
|
||||||
pwfd = open_info_file (pargs.r.ret_str, 0);
|
pwfd = open_info_file (pargs.r.ret_str, 0);
|
||||||
|
@ -2809,8 +2793,6 @@ main (int argc, char **argv )
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
/* FIXME: We should use logging to a file only in server mode;
|
||||||
however we have not yet implemetyed that. Thus we try to get
|
however we have not yet implemetyed that. Thus we try to get
|
||||||
away with --batch as indication for logging to file
|
away with --batch as indication for logging to file
|
||||||
|
|
|
@ -184,7 +184,7 @@ struct
|
||||||
int command_fd;
|
int command_fd;
|
||||||
const char *override_session_key;
|
const char *override_session_key;
|
||||||
int show_session_key;
|
int show_session_key;
|
||||||
int use_agent;
|
|
||||||
const char *gpg_agent_info;
|
const char *gpg_agent_info;
|
||||||
int try_all_secrets;
|
int try_all_secrets;
|
||||||
int no_expensive_trust_checks;
|
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;
|
mode=0;
|
||||||
|
|
||||||
if( n < 1 )
|
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++ ) {
|
for(i=0; i < n && gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE; i++ ) {
|
||||||
int canceled = 0;
|
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…
Reference in New Issue