Bugzilla – Attachment 2303 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]
Incomplete patch for sshd to use ssh-agent for hostkeys
sshd-agent.patch (text/plain), 10.74 KB, created by
Zev Weiss
on 2013-06-26 13:10:31 AEST
(
hide
)
Description:
Incomplete patch for sshd to use ssh-agent for hostkeys
Filename:
MIME Type:
Creator:
Zev Weiss
Created:
2013-06-26 13:10:31 AEST
Size:
10.74 KB
patch
obsolete
>commit 7a199748b4d66d980ec6ec6c3c4213313a587a0a >Author: Zev Weiss <zev@bewilderbeest.net> >Date: 2013-06-24 01:04:09 -0700 > > Privsep-friendly agent-based encrypted hostkey support. > > Only the privsep monitor talks to the agent. > >diff --git a/auth.h b/auth.h >index a406e13..d91f845 100644 >--- a/auth.h >+++ b/auth.h >@@ -197,6 +197,7 @@ 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 *); >diff --git a/kex.h b/kex.h >index 680264a..b77a2c2 100644 >--- a/kex.h >+++ b/kex.h >@@ -139,6 +139,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 a/kexdhs.c b/kexdhs.c >index 1512863..f6d43f2 100644 >--- a/kexdhs.c >+++ b/kexdhs.c >@@ -80,9 +80,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) >@@ -144,9 +141,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 a/kexecdhs.c b/kexecdhs.c >index c42dcf4..eec5fb6 100644 >--- a/kexecdhs.c >+++ b/kexecdhs.c >@@ -78,9 +78,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); >@@ -139,9 +136,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 a/kexgexs.c b/kexgexs.c >index a543dda..3ef7710 100644 >--- a/kexgexs.c >+++ b/kexgexs.c >@@ -68,10 +68,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) { >@@ -187,9 +183,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 a/monitor.c b/monitor.c >index 7286126..8f289b5 100644 >--- a/monitor.c >+++ b/monitor.c >@@ -97,6 +97,7 @@ > #include "ssh2.h" > #include "jpake.h" > #include "roaming.h" >+#include "authfd.h" > > #ifdef GSSAPI > static Gssctxt *gsscontext = NULL; >@@ -686,6 +687,8 @@ mm_answer_moduli(int sock, Buffer *m) > return (0); > } > >+extern AuthenticationConnection *auth_conn; >+ > int > mm_answer_sign(int sock, Buffer *m) > { >@@ -714,10 +717,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); > >diff --git a/sshd.c b/sshd.c >index 1306a62..a4a788b 100644 >--- a/sshd.c >+++ b/sshd.c >@@ -106,6 +106,7 @@ > #include "canohost.h" > #include "hostfile.h" > #include "auth.h" >+#include "authfd.h" > #include "misc.h" > #include "msg.h" > #include "dispatch.h" >@@ -194,6 +195,9 @@ char *server_version_string = NULL; > /* for rekeying XXX fixme */ > Kex *xxx_kex; > >+/* Daemon's agent connection */ >+AuthenticationConnection *auth_conn = NULL; >+ > /* > * Any really sensitive data in the application is contained in this > * structure. The idea is that this structure could be locked into memory so >@@ -206,6 +210,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; >@@ -652,11 +657,18 @@ privsep_preauth(Authctxt *authctxt) > } else if (pid != 0) { > debug2("Network child is on pid %ld", (long)pid); > >+ auth_conn = ssh_get_authentication_connection(); >+ > pmonitor->m_pid = pid; > if (box != NULL) > ssh_sandbox_parent_preauth(box, pid); > monitor_child_preauth(authctxt, pmonitor); > >+ if (auth_conn) { >+ ssh_close_authentication_connection(auth_conn); >+ auth_conn = NULL; >+ } >+ > /* Sync memory */ > monitor_sync(pmonitor); > >@@ -704,10 +716,11 @@ privsep_postauth(Authctxt *authctxt) > u_int32_t rnd[256]; > > #ifdef DISABLE_FD_PASSING >- if (1) { >+ if (1) > #else >- if (authctxt->pw->pw_uid == 0 || options.use_login) { >+ if (authctxt->pw->pw_uid == 0 || options.use_login) > #endif >+ { > /* File descriptor passing is broken or root login */ > use_privsep = 0; > goto skip; >@@ -767,6 +780,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: >@@ -819,6 +834,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) >@@ -848,6 +865,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) > { >@@ -860,6 +885,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); >@@ -1344,6 +1371,9 @@ main(int ac, char **av) > u_int64_t ibytes, obytes; > mode_t new_umask; > Key *key; >+ Key *pubkey; >+ char *pubkey_comment; >+ int have_agent, keytype; > Authctxt *authctxt; > struct connection_info *connection_info = get_connection_info(0, 0); > >@@ -1623,22 +1653,40 @@ main(int ac, char **av) > } > endpwent(); > >- /* 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; >+ } >+ >+ 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], >+ &pubkey_comment); > 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) { > 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) { >+ } else >+ keytype = key->type; >+ >+ switch (keytype) { > case KEY_RSA1: > sensitive_data.ssh1_host_key = key; > sensitive_data.have_ssh1_key = 1; >@@ -1649,8 +1697,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"); >@@ -2020,15 +2068,21 @@ 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) >+ auth_conn = ssh_get_authentication_connection(); > > /* perform the key exchange */ > /* authenticate user and start session */ > if (compat20) { > do_ssh2_kex(); > do_authentication2(authctxt); >+ if (!use_privsep && auth_conn) { >+ ssh_close_authentication_connection(auth_conn); >+ auth_conn = NULL; >+ } > } else { > do_ssh1_kex(); > do_authentication(authctxt); >@@ -2336,6 +2390,23 @@ do_ssh1_kex(void) > packet_write_wait(); > } > >+static void >+kex_server_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 > */ >@@ -2386,6 +2457,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 = kex_server_sign; > > xxx_kex = kex; >
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
Actions:
View
|
Diff
Attachments on
bug 1974
:
2125
|
2303
|
2306
|
2307
|
2308
|
2309