summaryrefslogtreecommitdiffstats
path: root/agent/command-ssh.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2021-01-25 10:35:06 +0100
committerWerner Koch <wk@gnupg.org>2021-01-25 10:35:06 +0100
commit224e26cf7b67f22bb0140133eac6b4ad24f3b1b7 (patch)
tree8ffb4f94ef64331109af30f6984237be37da61e4 /agent/command-ssh.c
parentscd:p15: Show the ATR as part of the TokenInfo diagnostics. (diff)
downloadgnupg2-224e26cf7b67f22bb0140133eac6b4ad24f3b1b7.tar.xz
gnupg2-224e26cf7b67f22bb0140133eac6b4ad24f3b1b7.zip
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>
Diffstat (limited to 'agent/command-ssh.c')
-rw-r--r--agent/command-ssh.c86
1 files changed, 85 insertions, 1 deletions
diff --git a/agent/command-ssh.c b/agent/command-ssh.c
index ee9270491..393ee91e9 100644
--- a/agent/command-ssh.c
+++ b/agent/command-ssh.c
@@ -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