mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
agent: Support ssh-agent extensions for environment variables.
* common/session-env.c (session_env_list_stdenvnames): Extend to allow return all names as one string. * agent/command-ssh.c (SSH_REQUEST_EXTENSION): New. (SSH_RESPONSE_EXTENSION_FAILURE): New. (request_specs): Add handler for the extension command. (ssh_handler_extension): New. -- The extension mechanism is specified in https://tools.ietf.org/html/draft-miller-ssh-agent-04 Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
60499d9894
commit
224e26cf7b
@ -70,6 +70,7 @@
|
||||
#define SSH_REQUEST_LOCK 22
|
||||
#define SSH_REQUEST_UNLOCK 23
|
||||
#define SSH_REQUEST_ADD_ID_CONSTRAINED 25
|
||||
#define SSH_REQUEST_EXTENSION 27
|
||||
|
||||
/* Options. */
|
||||
#define SSH_OPT_CONSTRAIN_LIFETIME 1
|
||||
@ -80,6 +81,7 @@
|
||||
#define SSH_RESPONSE_FAILURE 5
|
||||
#define SSH_RESPONSE_IDENTITIES_ANSWER 12
|
||||
#define SSH_RESPONSE_SIGN_RESPONSE 14
|
||||
#define SSH_RESPONSE_EXTENSION_FAILURE 28
|
||||
|
||||
/* Other constants. */
|
||||
#define SSH_DSA_SIGNATURE_PADDING 20
|
||||
@ -249,6 +251,9 @@ static gpg_error_t ssh_handler_lock (ctrl_t ctrl,
|
||||
static gpg_error_t ssh_handler_unlock (ctrl_t ctrl,
|
||||
estream_t request,
|
||||
estream_t response);
|
||||
static gpg_error_t ssh_handler_extension (ctrl_t ctrl,
|
||||
estream_t request,
|
||||
estream_t response);
|
||||
|
||||
static gpg_error_t ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis);
|
||||
static gpg_error_t ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec,
|
||||
@ -290,7 +295,8 @@ static const ssh_request_spec_t request_specs[] =
|
||||
REQUEST_SPEC_DEFINE (REMOVE_IDENTITY, remove_identity, 0),
|
||||
REQUEST_SPEC_DEFINE (REMOVE_ALL_IDENTITIES, remove_all_identities, 0),
|
||||
REQUEST_SPEC_DEFINE (LOCK, lock, 0),
|
||||
REQUEST_SPEC_DEFINE (UNLOCK, unlock, 0)
|
||||
REQUEST_SPEC_DEFINE (UNLOCK, unlock, 0),
|
||||
REQUEST_SPEC_DEFINE (EXTENSION, extension, 0)
|
||||
#undef REQUEST_SPEC_DEFINE
|
||||
};
|
||||
|
||||
@ -3304,6 +3310,84 @@ ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response)
|
||||
return ret_err;
|
||||
}
|
||||
|
||||
/* Handler for the "extension" command. */
|
||||
static gpg_error_t
|
||||
ssh_handler_extension (ctrl_t ctrl, estream_t request, estream_t response)
|
||||
{
|
||||
gpg_error_t ret_err;
|
||||
gpg_error_t err;
|
||||
char *exttype = NULL;
|
||||
char *name = NULL;
|
||||
char *value = NULL;
|
||||
|
||||
err = stream_read_cstring (request, &exttype);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
if (opt.verbose)
|
||||
log_info ("ssh-agent extension '%s' received\n", exttype);
|
||||
if (!strcmp (exttype, "ssh-env@gnupg.org"))
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
xfree (name); name = NULL;
|
||||
err = stream_read_cstring (request, &name);
|
||||
if (gpg_err_code (err) == GPG_ERR_EOF)
|
||||
break; /* ready. */
|
||||
if (err)
|
||||
{
|
||||
if (opt.verbose)
|
||||
log_error ("error reading ssh-agent env name\n");
|
||||
goto leave;
|
||||
}
|
||||
xfree (value); value = NULL;
|
||||
err = stream_read_cstring (request, &value);
|
||||
if (err)
|
||||
{
|
||||
if (opt.verbose)
|
||||
log_error ("error reading ssh-agent env value\n");
|
||||
goto leave;
|
||||
}
|
||||
if (opt.debug)
|
||||
log_debug ("ssh-agent env '%s'='%s'\n", name, value);
|
||||
err = session_env_setenv (ctrl->session_env, name,
|
||||
*value? value : NULL);
|
||||
if (err)
|
||||
{
|
||||
log_error ("error setting ssh-agent env value: %s\n",
|
||||
gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
err = 0;
|
||||
}
|
||||
else if (!strcmp (exttype, "ssh-envnames@gnupg.org"))
|
||||
{
|
||||
ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
|
||||
if (!ret_err)
|
||||
ret_err = stream_write_cstring
|
||||
(response, session_env_list_stdenvnames (NULL, NULL));
|
||||
goto finalleave;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opt.verbose)
|
||||
log_info ("ssh-agent extension '%s' not supported\n", exttype);
|
||||
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
leave:
|
||||
if (!err)
|
||||
ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
|
||||
else
|
||||
ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
|
||||
finalleave:
|
||||
xfree (exttype);
|
||||
xfree (name);
|
||||
xfree (value);
|
||||
return ret_err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Return the request specification for the request identified by TYPE
|
||||
|
@ -98,13 +98,45 @@ static size_t lastallocatedarraysize;
|
||||
|
||||
/* Return the names of standard environment variables one after the
|
||||
other. The caller needs to set the value at the address of
|
||||
ITERATOR initially to 0 and then call this function until it returns
|
||||
NULL. */
|
||||
ITERATOR initially to 0 and then call this function until it
|
||||
returns NULL. If ITERATOR is NULL, a single comma delimited string
|
||||
with the names is returned; NULL is never returned in this case and
|
||||
R_ASSNAME is ignored. */
|
||||
const char *
|
||||
session_env_list_stdenvnames (int *iterator, const char **r_assname)
|
||||
{
|
||||
int idx = *iterator;
|
||||
int idx;
|
||||
static char *commastring;
|
||||
|
||||
if (!iterator)
|
||||
{
|
||||
if (!commastring)
|
||||
{
|
||||
size_t len = 0;
|
||||
char *p;
|
||||
|
||||
for (idx = 0; idx < DIM (stdenvnames); idx++)
|
||||
len += strlen (stdenvnames[idx].name) + 1;
|
||||
commastring = xtrymalloc (len);
|
||||
if (!commastring)
|
||||
{
|
||||
log_error ("%s: error allocating string: %s\n", __func__,
|
||||
gpg_strerror (gpg_error_from_syserror ()));
|
||||
return "GPG_TTY,TERM,DISPLAY";
|
||||
}
|
||||
p = commastring;
|
||||
for (idx = 0; idx < DIM (stdenvnames); idx++)
|
||||
{
|
||||
if (idx)
|
||||
*p++ = ',';
|
||||
p = stpcpy (p, stdenvnames[idx].name);
|
||||
}
|
||||
gpgrt_annotate_leaked_object (commastring);
|
||||
}
|
||||
return commastring;
|
||||
}
|
||||
|
||||
idx = *iterator;
|
||||
if (idx < 0 || idx >= DIM (stdenvnames))
|
||||
return NULL;
|
||||
*iterator = idx + 1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user