Bugzilla – Attachment 2309 Details for
Bug 1974
Support for encrypted host keys
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
updated patch (against openbsd cvs)
sshd-agent-3.diff (text/plain), 14.26 KB, created by
Markus Friedl
on 2013-07-07 18:49:22 AEST
(
hide
)
Description:
updated patch (against openbsd cvs)
Filename:
MIME Type:
Creator:
Markus Friedl
Created:
2013-07-07 18:49:22 AEST
Size:
14.26 KB
patch
obsolete
>diff --git auth.h auth.h >index 2ce518a..a001901 100644 >--- auth.h >+++ auth.h >@@ -174,10 +174,12 @@ check_key_in_hostfiles(struct passwd *, Key *, const char *, > > /* hostkey handling */ > Key *get_hostkey_by_index(int); >+Key *get_hostkey_public_by_index(int); > Key *get_hostkey_public_by_type(int); > Key *get_hostkey_private_by_type(int); > int get_hostkey_index(Key *); > int ssh1_session_key(BIGNUM *); >+void sshd_hostkey_sign(Key *, Key *, u_char **, u_int *, u_char *, u_int); > > /* debug messages during authentication */ > void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); >diff --git kex.h kex.h >index 28e15c8..e151fb6 100644 >--- kex.h >+++ kex.h >@@ -136,6 +136,7 @@ struct Kex { > Key *(*load_host_public_key)(int); > Key *(*load_host_private_key)(int); > int (*host_key_index)(Key *); >+ void (*sign)(Key *, Key *, u_char **, u_int *, u_char *, u_int); > void (*kex[KEX_MAX])(Kex *); > }; > >diff --git kexdhs.c kexdhs.c >index abbd544..81880df 100644 >--- kexdhs.c >+++ kexdhs.c >@@ -77,9 +77,6 @@ kexdh_server(Kex *kex) > if (server_host_public == NULL) > fatal("Unsupported hostkey type %d", kex->hostkey_type); > server_host_private = kex->load_host_private_key(kex->hostkey_type); >- if (server_host_private == NULL) >- fatal("Missing private key for hostkey type %d", >- kex->hostkey_type); > > /* key, cert */ > if ((dh_client_pub = BN_new()) == NULL) >@@ -141,9 +138,8 @@ kexdh_server(Kex *kex) > } > > /* sign H */ >- if (PRIVSEP(key_sign(server_host_private, &signature, &slen, hash, >- hashlen)) < 0) >- fatal("kexdh_server: key_sign failed"); >+ kex->sign(server_host_private, server_host_public, &signature, &slen, >+ hash, hashlen); > > /* destroy_sensitive_data(); */ > >diff --git kexecdhs.c kexecdhs.c >index 5a3307e..30f61f3 100644 >--- kexecdhs.c >+++ kexecdhs.c >@@ -74,9 +74,6 @@ kexecdh_server(Kex *kex) > if (server_host_public == NULL) > fatal("Unsupported hostkey type %d", kex->hostkey_type); > server_host_private = kex->load_host_private_key(kex->hostkey_type); >- if (server_host_private == NULL) >- fatal("Missing private key for hostkey type %d", >- kex->hostkey_type); > > debug("expecting SSH2_MSG_KEX_ECDH_INIT"); > packet_read_expect(SSH2_MSG_KEX_ECDH_INIT); >@@ -135,9 +132,8 @@ kexecdh_server(Kex *kex) > } > > /* sign H */ >- if (PRIVSEP(key_sign(server_host_private, &signature, &slen, >- hash, hashlen)) < 0) >- fatal("kexdh_server: key_sign failed"); >+ kex->sign(server_host_private, server_host_public, &signature, &slen, >+ hash, hashlen); > > /* destroy_sensitive_data(); */ > >diff --git kexgexs.c kexgexs.c >index cabe3b5..f57e4f2 100644 >--- kexgexs.c >+++ kexgexs.c >@@ -65,10 +65,6 @@ kexgex_server(Kex *kex) > if (server_host_public == NULL) > fatal("Unsupported hostkey type %d", kex->hostkey_type); > server_host_private = kex->load_host_private_key(kex->hostkey_type); >- if (server_host_private == NULL) >- fatal("Missing private key for hostkey type %d", >- kex->hostkey_type); >- > > type = packet_read(); > switch (type) { >@@ -184,9 +180,8 @@ kexgex_server(Kex *kex) > } > > /* sign H */ >- if (PRIVSEP(key_sign(server_host_private, &signature, &slen, hash, >- hashlen)) < 0) >- fatal("kexgex_server: key_sign failed"); >+ kex->sign(server_host_private, server_host_public, &signature, &slen, >+ hash, hashlen); > > /* destroy_sensitive_data(); */ > >diff --git monitor.c monitor.c >index 4fad8ee..dcb7b17 100644 >--- monitor.c >+++ monitor.c >@@ -75,6 +75,7 @@ > #include "ssh2.h" > #include "jpake.h" > #include "roaming.h" >+#include "authfd.h" > > #ifdef GSSAPI > static Gssctxt *gsscontext = NULL; >@@ -594,6 +595,8 @@ mm_answer_moduli(int sock, Buffer *m) > return (0); > } > >+extern AuthenticationConnection *auth_conn; >+ > int > mm_answer_sign(int sock, Buffer *m) > { >@@ -622,10 +625,16 @@ mm_answer_sign(int sock, Buffer *m) > memcpy(session_id2, p, session_id2_len); > } > >- if ((key = get_hostkey_by_index(keyid)) == NULL) >+ if ((key = get_hostkey_by_index(keyid)) != NULL) { >+ if (key_sign(key, &signature, &siglen, p, datlen) < 0) >+ fatal("%s: key_sign failed", __func__); >+ } else if ((key = get_hostkey_public_by_index(keyid)) != NULL && >+ auth_conn != NULL) { >+ if (ssh_agent_sign(auth_conn, key, &signature, &siglen, p, >+ datlen) < 0) >+ fatal("%s: ssh_agent_sign failed", __func__); >+ } else > fatal("%s: no hostkey from index %d", __func__, keyid); >- if (key_sign(key, &signature, &siglen, p, datlen) < 0) >- fatal("%s: key_sign failed", __func__); > > debug3("%s: signature %p(%u)", __func__, signature, siglen); > >@@ -1533,6 +1542,7 @@ mm_get_kex(Buffer *m) > kex->load_host_public_key=&get_hostkey_public_by_type; > kex->load_host_private_key=&get_hostkey_private_by_type; > kex->host_key_index=&get_hostkey_index; >+ kex->sign = sshd_hostkey_sign; > > return (kex); > } >diff --git servconf.c servconf.c >index 518d86e..35ee6a3 100644 >--- servconf.c >+++ servconf.c >@@ -70,6 +70,7 @@ initialize_server_options(ServerOptions *options) > options->address_family = -1; > options->num_host_key_files = 0; > options->num_host_cert_files = 0; >+ options->host_key_agent = NULL; > options->pid_file = NULL; > options->server_key_bits = -1; > options->login_grace_time = -1; >@@ -315,7 +316,7 @@ typedef enum { > sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, > sKexAlgorithms, sIPQoS, sVersionAddendum, > sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, >- sAuthenticationMethods, >+ sAuthenticationMethods, sHostKeyAgent, > sDeprecated, sUnsupported > } ServerOpCodes; > >@@ -332,6 +333,7 @@ static struct { > { "port", sPort, SSHCFG_GLOBAL }, > { "hostkey", sHostKeyFile, SSHCFG_GLOBAL }, > { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */ >+ { "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL }, > { "pidfile", sPidFile, SSHCFG_GLOBAL }, > { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL }, > { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL }, >@@ -931,6 +933,17 @@ process_server_config_line(ServerOptions *options, char *line, > } > break; > >+ case sHostKeyAgent: >+ charptr = &options->host_key_agent; >+ arg = strdelim(&cp); >+ if (!arg || *arg == '\0') >+ fatal("%s line %d: missing socket name.", >+ filename, linenum); >+ if (*activep && *charptr == NULL) >+ *charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ? >+ xstrdup(arg) : derelativise_path(arg); >+ break; >+ > case sHostCertificate: > intptr = &options->num_host_cert_files; > if (*intptr >= MAX_HOSTKEYS) >@@ -1959,6 +1972,7 @@ dump_config(ServerOptions *o) > dump_cfg_string(sVersionAddendum, o->version_addendum); > dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); > dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); >+ dump_cfg_string(sHostKeyAgent, o->host_key_agent); > > /* string arguments requiring a lookup */ > dump_cfg_string(sLogLevel, log_level_name(o->log_level)); >diff --git servconf.h servconf.h >index d32f2a1..94e2c62 100644 >--- servconf.h >+++ servconf.h >@@ -65,6 +65,7 @@ typedef struct { > int num_host_key_files; /* Number of files for host keys. */ > char *host_cert_files[MAX_HOSTCERTS]; /* Files containing host certs. */ > int num_host_cert_files; /* Number of files for host certs. */ >+ char *host_key_agent; /* ssh-agent socket for host keys. */ > char *pid_file; /* Where to put our pid */ > int server_key_bits;/* Size of the server key. */ > int login_grace_time; /* Disconnect if no auth in this time >diff --git session.c session.c >index cf04d33..4c257d1 100644 >--- session.c >+++ session.c >@@ -70,6 +70,7 @@ > #include "hostfile.h" > #include "auth.h" > #include "auth-options.h" >+#include "authfd.h" > #include "pathnames.h" > #include "log.h" > #include "servconf.h" >@@ -1261,6 +1262,13 @@ launch_login(struct passwd *pw, const char *hostname) > static void > child_close_fds(void) > { >+ extern AuthenticationConnection *auth_conn; >+ >+ if (auth_conn) { >+ ssh_close_authentication_connection(auth_conn); >+ auth_conn = NULL; >+ } >+ > if (packet_get_connection_in() == packet_get_connection_out()) > close(packet_get_connection_in()); > else { >diff --git sshd.c sshd.c >index 76b7f25..f44730c 100644 >--- sshd.c >+++ sshd.c >@@ -90,6 +90,7 @@ > #include "canohost.h" > #include "hostfile.h" > #include "auth.h" >+#include "authfd.h" > #include "misc.h" > #include "msg.h" > #include "dispatch.h" >@@ -177,6 +178,10 @@ char *server_version_string = NULL; > /* for rekeying XXX fixme */ > Kex *xxx_kex; > >+/* Daemon's agent connection */ >+AuthenticationConnection *auth_conn = NULL; >+int have_agent = 0; >+ > /* > * Any really sensitive data in the application is contained in this > * structure. The idea is that this structure could be locked into memory so >@@ -189,6 +194,7 @@ struct { > Key *server_key; /* ephemeral server key */ > Key *ssh1_host_key; /* ssh1 host key */ > Key **host_keys; /* all private host keys */ >+ Key **host_pubkeys; /* all public host keys */ > Key **host_certificates; /* all public host certificates */ > int have_ssh1_key; > int have_ssh2_key; >@@ -640,6 +646,8 @@ privsep_preauth(Authctxt *authctxt) > debug2("Network child is on pid %ld", (long)pid); > > pmonitor->m_pid = pid; >+ if (have_agent) >+ auth_conn = ssh_get_authentication_connection(); > if (box != NULL) > ssh_sandbox_parent_preauth(box, pid); > monitor_child_preauth(authctxt, pmonitor); >@@ -750,6 +758,8 @@ list_hostkey_types(void) > for (i = 0; i < options.num_host_key_files; i++) { > key = sensitive_data.host_keys[i]; > if (key == NULL) >+ key = sensitive_data.host_pubkeys[i]; >+ if (key == NULL) > continue; > switch (key->type) { > case KEY_RSA: >@@ -802,6 +812,8 @@ get_hostkey_by_type(int type, int need_private) > break; > default: > key = sensitive_data.host_keys[i]; >+ if (key == NULL && !need_private) >+ key = sensitive_data.host_pubkeys[i]; > break; > } > if (key != NULL && key->type == type) >@@ -831,6 +843,14 @@ get_hostkey_by_index(int ind) > return (sensitive_data.host_keys[ind]); > } > >+Key * >+get_hostkey_public_by_index(int ind) >+{ >+ if (ind < 0 || ind >= options.num_host_key_files) >+ return (NULL); >+ return (sensitive_data.host_pubkeys[ind]); >+} >+ > int > get_hostkey_index(Key *key) > { >@@ -843,6 +863,8 @@ get_hostkey_index(Key *key) > } else { > if (key == sensitive_data.host_keys[i]) > return (i); >+ if (key == sensitive_data.host_pubkeys[i]) >+ return (i); > } > } > return (-1); >@@ -1310,6 +1332,8 @@ main(int ac, char **av) > u_int64_t ibytes, obytes; > mode_t new_umask; > Key *key; >+ Key *pubkey; >+ int keytype; > Authctxt *authctxt; > struct connection_info *connection_info = get_connection_info(0, 0); > >@@ -1542,22 +1566,45 @@ main(int ac, char **av) > debug("sshd version %s, %s", SSH_VERSION, > SSLeay_version(SSLEAY_VERSION)); > >- /* load private host keys */ >+ /* load host keys */ > sensitive_data.host_keys = xcalloc(options.num_host_key_files, > sizeof(Key *)); >- for (i = 0; i < options.num_host_key_files; i++) >+ sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files, >+ sizeof(Key *)); >+ for (i = 0; i < options.num_host_key_files; i++) { > sensitive_data.host_keys[i] = NULL; >+ sensitive_data.host_pubkeys[i] = NULL; >+ } >+ >+ if (options.host_key_agent) { >+ if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME)) >+ setenv(SSH_AUTHSOCKET_ENV_NAME, >+ options.host_key_agent, 1); >+ have_agent = ssh_agent_present(); >+ } > > for (i = 0; i < options.num_host_key_files; i++) { > key = key_load_private(options.host_key_files[i], "", NULL); >+ pubkey = key_load_public(options.host_key_files[i], NULL); > sensitive_data.host_keys[i] = key; >- if (key == NULL) { >+ sensitive_data.host_pubkeys[i] = pubkey; >+ >+ if (key == NULL && pubkey != NULL && pubkey->type != KEY_RSA1 && >+ have_agent) { >+ debug("will rely on agent for hostkey %s", >+ options.host_key_files[i]); >+ keytype = pubkey->type; >+ } else if (key != NULL) { >+ keytype = key->type; >+ } else { > error("Could not load host key: %s", > options.host_key_files[i]); > sensitive_data.host_keys[i] = NULL; >+ sensitive_data.host_pubkeys[i] = NULL; > continue; > } >- switch (key->type) { >+ >+ switch (keytype) { > case KEY_RSA1: > sensitive_data.ssh1_host_key = key; > sensitive_data.have_ssh1_key = 1; >@@ -1568,8 +1615,8 @@ main(int ac, char **av) > sensitive_data.have_ssh2_key = 1; > break; > } >- debug("private host key: #%d type %d %s", i, key->type, >- key_type(key)); >+ debug("private host key: #%d type %d %s", i, keytype, >+ key_type(key ? key : pubkey)); > } > if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { > logit("Disabling protocol version 1. Could not load host key"); >@@ -1906,9 +1953,11 @@ main(int ac, char **av) > buffer_init(&loginmsg); > auth_debug_reset(); > >- if (use_privsep) >+ if (use_privsep) { > if (privsep_preauth(authctxt) == 1) > goto authenticated; >+ } else if (compat20 && have_agent) >+ auth_conn = ssh_get_authentication_connection(); > > /* perform the key exchange */ > /* authenticate user and start session */ >@@ -2194,6 +2243,23 @@ do_ssh1_kex(void) > packet_write_wait(); > } > >+void >+sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, u_int *slen, >+ u_char *data, u_int dlen) >+{ >+ if (privkey) { >+ if (PRIVSEP(key_sign(privkey, signature, slen, data, dlen) < 0)) >+ fatal("%s: key_sign failed", __func__); >+ } else if (use_privsep) { >+ if (mm_key_sign(pubkey, signature, slen, data, dlen) < 0) >+ fatal("%s: pubkey_sign failed", __func__); >+ } else { >+ if (ssh_agent_sign(auth_conn, pubkey, signature, slen, data, >+ dlen)) >+ fatal("%s: ssh_agent_sign failed", __func__); >+ } >+} >+ > /* > * SSH2 key exchange: diffie-hellman-group1-sha1 > */ >@@ -2244,6 +2310,7 @@ do_ssh2_kex(void) > kex->load_host_public_key=&get_hostkey_public_by_type; > kex->load_host_private_key=&get_hostkey_private_by_type; > kex->host_key_index=&get_hostkey_index; >+ kex->sign = sshd_hostkey_sign; > > xxx_kex = kex; > >diff --git sshd_config.5 sshd_config.5 >index 23970b8..895ab63 100644 >--- sshd_config.5 >+++ sshd_config.5 >@@ -547,6 +547,18 @@ keys are used for version 1 and > or > .Dq rsa > are used for version 2 of the SSH protocol. >+It is also possible to specify public host key files instead. >+In this case operations on the private key will be delegated >+to an >+.Xr ssh-agent 1 . >+.It Cm HostKeyAgent >+Identifies the UNIX-domain socket used to communicate >+with an agent that has access to the private host keys. >+If >+.Dq SSH_AUTH_SOCK >+is specified, the location of the socket will be read from the >+.Ev SSH_AUTH_SOCK >+environment variable. > .It Cm IgnoreRhosts > Specifies that > .Pa .rhosts
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
djm
:
ok+
Actions:
View
|
Diff
Attachments on
bug 1974
:
2125
|
2303
|
2306
|
2307
|
2308
| 2309