Added comamnds PUTVAL and GETVAL

This commit is contained in:
Werner Koch 2006-09-04 08:07:12 +00:00
parent 1c4af2666b
commit 529a543bb7
2 changed files with 197 additions and 4 deletions

View File

@ -1,3 +1,8 @@
2006-09-04 Werner Koch <wk@g10code.com>
* command.c (percent_plus_unescape): New.
(cmd_get_val, cmd_putval): New.
2006-08-29 Werner Koch <wk@g10code.com>
* command-ssh.c (stream_read_mpi): Sanity check for early

View File

@ -49,8 +49,9 @@
#endif
/* Data used to associate an Assuan context with local server data */
struct server_local_s {
ASSUAN_CONTEXT assuan_ctx;
struct server_local_s
{
assuan_context_t assuan_ctx;
int message_fd;
int use_cache_for_signing;
char *keydesc; /* Allocated description for the next key
@ -58,6 +59,20 @@ struct server_local_s {
};
/* An entry for the getval/putval commands. */
struct putval_item_s
{
struct putval_item_s *next;
size_t off; /* Offset to the value into DATA. */
size_t len; /* Length of the value. */
char d[1]; /* Key | Nul | value. */
};
/* A list of key value pairs fpr the getval/putval commands. */
static struct putval_item_s *putval_list;
@ -133,6 +148,42 @@ plus_to_blank (char *s)
}
/* Do the percent and plus/space unescaping in place and return the
length of the valid buffer. */
static size_t
percent_plus_unescape (char *string)
{
unsigned char *p = string;
size_t n = 0;
while (*string)
{
if (*string == '%' && string[1] && string[2])
{
string++;
*p++ = xtoi_2 (string);
n++;
string+= 2;
}
else if (*string == '+')
{
*p++ = ' ';
n++;
string++;
}
else
{
*p++ = *string++;
n++;
}
}
return n;
}
/* Parse a hex string. Return an Assuan error code or 0 on success and the
length of the parsed string in LEN. */
static int
@ -310,7 +361,7 @@ cmd_sigkey (ASSUAN_CONTEXT ctx, char *line)
}
/* SETKEYDESC plus_percent_escaped_string:
/* SETKEYDESC plus_percent_escaped_string
Set a description to be used for the next PKSIGN or PKDECRYPT
operation if this operation requires the entry of a passphrase. If
@ -318,7 +369,7 @@ cmd_sigkey (ASSUAN_CONTEXT ctx, char *line)
this description implictly selects the label used for the entry
box; if the string contains the string PIN (which in general will
not be translated), "PIN" is used, otherwise the translation of
'passphrase" is used. The description string should not contain
"passphrase" is used. The description string should not contain
blanks unless they are percent or '+' escaped.
The description is only valid for the next PKSIGN or PKDECRYPT
@ -876,6 +927,141 @@ cmd_scd (ASSUAN_CONTEXT ctx, char *line)
}
/* GETVAL <key>
Return the value for KEY from the special environment as created by
PUTVAL.
*/
static int
cmd_getval (assuan_context_t ctx, char *line)
{
int rc = 0;
char *key = NULL;
char *p;
struct putval_item_s *vl;
for (p=line; *p == ' '; p++)
;
key = p;
p = strchr (key, ' ');
if (p)
{
*p++ = 0;
for (; *p == ' '; p++)
;
if (*p)
return set_error (Parameter_Error, "too many arguments");
}
if (!key || !*key)
return set_error (Parameter_Error, "no key given");
for (vl=putval_list; vl; vl = vl->next)
if ( !strcmp (vl->d, key) )
break;
if (vl) /* Got an entry. */
{
rc = assuan_send_data (ctx, vl->d+vl->off, vl->len);
if (rc)
rc = map_assuan_err (rc);
}
else
return gpg_error (GPG_ERR_NO_DATA);
if (rc)
log_error ("command getval failed: %s\n", gpg_strerror (rc));
return map_to_assuan_status (rc);
}
/* PUTVAL <key> [<percent_escaped_value>]
The gpg-agent maintains a kind of environment which may be used to
store key/value pairs in it, so that they can be retrieved later.
This may be used by helper daemons to daemonize themself on
invocation and register them with gpg-agent. Callers of the
daemon's service may now first try connect to get the information
for that service from gpg-agent through the GETVAL command and then
try to connect to that daemon. Only if that fails they may start
an own instance of the service daemon.
KEY is an an arbitrary symbol with the same syntax rules as keys
for shell environment variables. PERCENT_ESCAPED_VALUE is the
corresponsing value; they should be similar to the values of
envronment variables but gpg-agent does not enforce any
restrictions. If that value is not given any value under that KEY
is removed from this special environment.
*/
static int
cmd_putval (assuan_context_t ctx, char *line)
{
int rc = 0;
char *key = NULL;
char *value = NULL;
size_t valuelen = 0;
char *p;
struct putval_item_s *vl, *vlprev;
for (p=line; *p == ' '; p++)
;
key = p;
p = strchr (key, ' ');
if (p)
{
*p++ = 0;
for (; *p == ' '; p++)
;
if (*p)
{
value = p;
p = strchr (value, ' ');
if (p)
*p = 0;
valuelen = percent_plus_unescape (value);
}
}
if (!key || !*key)
return set_error (Parameter_Error, "no key given");
for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next)
if ( !strcmp (vl->d, key) )
break;
if (vl) /* Delete old entry. */
{
if (vlprev)
vlprev->next = vl->next;
else
putval_list = vl->next;
xfree (vl);
}
if (valuelen) /* Add entry. */
{
vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen);
if (!vl)
rc = gpg_error_from_errno (errno);
else
{
vl->len = valuelen;
vl->off = strlen (key) + 1;
strcpy (vl->d, key);
memcpy (vl->d + vl->off, value, valuelen);
vl->next = putval_list;
putval_list = vl;
}
}
if (rc)
log_error ("command putval failed: %s\n", gpg_strerror (rc));
return map_to_assuan_status (rc);
}
/* UPDATESTARTUPTTY
@ -999,6 +1185,8 @@ register_commands (ASSUAN_CONTEXT ctx)
{ "INPUT", NULL },
{ "OUTPUT", NULL },
{ "SCD", cmd_scd },
{ "GETVAL", cmd_getval },
{ "PUTVAL", cmd_putval },
{ "UPDATESTARTUPTTY", cmd_updatestartuptty },
{ NULL }
};