Bugzilla – Attachment 230 Details for
Bug 387
command="" in authorized_keys fails when sshd_config has "PermitRootLogon forced-commands-only"
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
fix
U (text/plain), 43.84 KB, created by
Markus Friedl
on 2003-02-17 01:41:00 AEDT
(
hide
)
Description:
fix
Filename:
MIME Type:
Creator:
Markus Friedl
Created:
2003-02-17 01:41:00 AEDT
Size:
43.84 KB
patch
obsolete
>Index: kex.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/kex.c,v >retrieving revision 1.53 >diff -u -r1.53 kex.c >--- kex.c 2 Feb 2003 10:56:08 -0000 1.53 >+++ kex.c 16 Feb 2003 14:37:13 -0000 >@@ -44,11 +44,6 @@ > > #define KEX_COOKIE_LEN 16 > >-/* Use privilege separation for sshd */ >-int use_privsep; >-struct monitor *pmonitor; >- >- > /* prototype */ > static void kex_kexinit_finish(Kex *); > static void kex_choose_conf(Kex *); >@@ -237,14 +232,10 @@ > > kex_choose_conf(kex); > >- switch (kex->kex_type) { >- case DH_GRP1_SHA1: >- kexdh(kex); >- break; >- case DH_GEX_SHA1: >- kexgex(kex); >- break; >- default: >+ if (kex->kex_type >= 0 && kex->kex_type < KEX_MAX && >+ kex->kex[kex->kex_type] != NULL) { >+ (kex->kex[kex->kex_type])(kex); >+ } else { > fatal("Unsupported key exchange %d", kex->kex_type); > } > } >@@ -301,9 +292,9 @@ > if (k->name == NULL) > fatal("no kex alg"); > if (strcmp(k->name, KEX_DH1) == 0) { >- k->kex_type = DH_GRP1_SHA1; >+ k->kex_type = KEX_DH_GRP1_SHA1; > } else if (strcmp(k->name, KEX_DHGEX) == 0) { >- k->kex_type = DH_GEX_SHA1; >+ k->kex_type = KEX_DH_GEX_SHA1; > } else > fatal("bad kex alg %s", k->name); > } >Index: kex.h >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/kex.h,v >retrieving revision 1.32 >diff -u -r1.32 kex.h >--- kex.h 9 Sep 2002 14:54:14 -0000 1.32 >+++ kex.h 16 Feb 2003 14:37:13 -0000 >@@ -55,8 +55,9 @@ > }; > > enum kex_exchange { >- DH_GRP1_SHA1, >- DH_GEX_SHA1 >+ KEX_DH_GRP1_SHA1, >+ KEX_DH_GEX_SHA1, >+ KEX_MAX > }; > > #define KEX_INIT_SENT 0x0001 >@@ -112,6 +113,7 @@ > int (*verify_host_key)(Key *); > Key *(*load_host_key)(int); > int (*host_key_index)(Key *); >+ void (*kex[KEX_MAX])(Kex *); > }; > > Kex *kex_setup(char *[PROPOSAL_MAX]); >@@ -121,10 +123,19 @@ > void kex_input_kexinit(int, u_int32_t, void *); > void kex_derive_keys(Kex *, u_char *, BIGNUM *); > >-void kexdh(Kex *); >-void kexgex(Kex *); >- > Newkeys *kex_get_newkeys(int); >+ >+void kexdh_client(Kex *); >+void kexdh_server(Kex *); >+void kexgex_client(Kex *); >+void kexgex_server(Kex *); >+ >+u_char * >+kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, >+ BIGNUM *, BIGNUM *, BIGNUM *); >+u_char * >+kexgex_hash(char *, char *, char *, int, char *, int, u_char *, int, >+ int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *); > > #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) > void dump_digest(char *, u_char *, int); >Index: kexdh.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/kexdh.c,v >retrieving revision 1.18 >diff -u -r1.18 kexdh.c >--- kexdh.c 18 Mar 2002 17:50:31 -0000 1.18 >+++ kexdh.c 16 Feb 2003 14:37:13 -0000 >@@ -25,21 +25,13 @@ > #include "includes.h" > RCSID("$OpenBSD: kexdh.c,v 1.18 2002/03/18 17:50:31 provos Exp $"); > >-#include <openssl/crypto.h> >-#include <openssl/bn.h> >+#include <openssl/evp.h> > >-#include "xmalloc.h" > #include "buffer.h" > #include "bufaux.h" >-#include "key.h" >-#include "kex.h" >-#include "log.h" >-#include "packet.h" >-#include "dh.h" > #include "ssh2.h" >-#include "monitor_wrap.h" > >-static u_char * >+u_char * > kex_dh_hash( > char *client_version_string, > char *server_version_string, >@@ -85,223 +77,4 @@ > dump_digest("hash", digest, EVP_MD_size(evp_md)); > #endif > return digest; >-} >- >-/* client */ >- >-static void >-kexdh_client(Kex *kex) >-{ >- BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; >- DH *dh; >- Key *server_host_key; >- u_char *server_host_key_blob = NULL, *signature = NULL; >- u_char *kbuf, *hash; >- u_int klen, kout, slen, sbloblen; >- >- /* generate and send 'e', client DH public key */ >- dh = dh_new_group1(); >- dh_gen_key(dh, kex->we_need * 8); >- packet_start(SSH2_MSG_KEXDH_INIT); >- packet_put_bignum2(dh->pub_key); >- packet_send(); >- >- debug("sending SSH2_MSG_KEXDH_INIT"); >-#ifdef DEBUG_KEXDH >- DHparams_print_fp(stderr, dh); >- fprintf(stderr, "pub= "); >- BN_print_fp(stderr, dh->pub_key); >- fprintf(stderr, "\n"); >-#endif >- >- debug("expecting SSH2_MSG_KEXDH_REPLY"); >- packet_read_expect(SSH2_MSG_KEXDH_REPLY); >- >- /* key, cert */ >- server_host_key_blob = packet_get_string(&sbloblen); >- server_host_key = key_from_blob(server_host_key_blob, sbloblen); >- if (server_host_key == NULL) >- fatal("cannot decode server_host_key_blob"); >- if (server_host_key->type != kex->hostkey_type) >- fatal("type mismatch for decoded server_host_key_blob"); >- if (kex->verify_host_key == NULL) >- fatal("cannot verify server_host_key"); >- if (kex->verify_host_key(server_host_key) == -1) >- fatal("server_host_key verification failed"); >- >- /* DH paramter f, server public DH key */ >- if ((dh_server_pub = BN_new()) == NULL) >- fatal("dh_server_pub == NULL"); >- packet_get_bignum2(dh_server_pub); >- >-#ifdef DEBUG_KEXDH >- fprintf(stderr, "dh_server_pub= "); >- BN_print_fp(stderr, dh_server_pub); >- fprintf(stderr, "\n"); >- debug("bits %d", BN_num_bits(dh_server_pub)); >-#endif >- >- /* signed H */ >- signature = packet_get_string(&slen); >- packet_check_eom(); >- >- if (!dh_pub_is_valid(dh, dh_server_pub)) >- packet_disconnect("bad server public DH value"); >- >- klen = DH_size(dh); >- kbuf = xmalloc(klen); >- kout = DH_compute_key(kbuf, dh_server_pub, dh); >-#ifdef DEBUG_KEXDH >- dump_digest("shared secret", kbuf, kout); >-#endif >- if ((shared_secret = BN_new()) == NULL) >- fatal("kexdh_client: BN_new failed"); >- BN_bin2bn(kbuf, kout, shared_secret); >- memset(kbuf, 0, klen); >- xfree(kbuf); >- >- /* calc and verify H */ >- hash = kex_dh_hash( >- kex->client_version_string, >- kex->server_version_string, >- buffer_ptr(&kex->my), buffer_len(&kex->my), >- buffer_ptr(&kex->peer), buffer_len(&kex->peer), >- server_host_key_blob, sbloblen, >- dh->pub_key, >- dh_server_pub, >- shared_secret >- ); >- xfree(server_host_key_blob); >- BN_clear_free(dh_server_pub); >- DH_free(dh); >- >- if (key_verify(server_host_key, signature, slen, hash, 20) != 1) >- fatal("key_verify failed for server_host_key"); >- key_free(server_host_key); >- xfree(signature); >- >- /* save session id */ >- if (kex->session_id == NULL) { >- kex->session_id_len = 20; >- kex->session_id = xmalloc(kex->session_id_len); >- memcpy(kex->session_id, hash, kex->session_id_len); >- } >- >- kex_derive_keys(kex, hash, shared_secret); >- BN_clear_free(shared_secret); >- kex_finish(kex); >-} >- >-/* server */ >- >-static void >-kexdh_server(Kex *kex) >-{ >- BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; >- DH *dh; >- Key *server_host_key; >- u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; >- u_int sbloblen, klen, kout; >- u_int slen; >- >- /* generate server DH public key */ >- dh = dh_new_group1(); >- dh_gen_key(dh, kex->we_need * 8); >- >- debug("expecting SSH2_MSG_KEXDH_INIT"); >- packet_read_expect(SSH2_MSG_KEXDH_INIT); >- >- if (kex->load_host_key == NULL) >- fatal("Cannot load hostkey"); >- server_host_key = kex->load_host_key(kex->hostkey_type); >- if (server_host_key == NULL) >- fatal("Unsupported hostkey type %d", kex->hostkey_type); >- >- /* key, cert */ >- if ((dh_client_pub = BN_new()) == NULL) >- fatal("dh_client_pub == NULL"); >- packet_get_bignum2(dh_client_pub); >- packet_check_eom(); >- >-#ifdef DEBUG_KEXDH >- fprintf(stderr, "dh_client_pub= "); >- BN_print_fp(stderr, dh_client_pub); >- fprintf(stderr, "\n"); >- debug("bits %d", BN_num_bits(dh_client_pub)); >-#endif >- >-#ifdef DEBUG_KEXDH >- DHparams_print_fp(stderr, dh); >- fprintf(stderr, "pub= "); >- BN_print_fp(stderr, dh->pub_key); >- fprintf(stderr, "\n"); >-#endif >- if (!dh_pub_is_valid(dh, dh_client_pub)) >- packet_disconnect("bad client public DH value"); >- >- klen = DH_size(dh); >- kbuf = xmalloc(klen); >- kout = DH_compute_key(kbuf, dh_client_pub, dh); >-#ifdef DEBUG_KEXDH >- dump_digest("shared secret", kbuf, kout); >-#endif >- if ((shared_secret = BN_new()) == NULL) >- fatal("kexdh_server: BN_new failed"); >- BN_bin2bn(kbuf, kout, shared_secret); >- memset(kbuf, 0, klen); >- xfree(kbuf); >- >- key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); >- >- /* calc H */ >- hash = kex_dh_hash( >- kex->client_version_string, >- kex->server_version_string, >- buffer_ptr(&kex->peer), buffer_len(&kex->peer), >- buffer_ptr(&kex->my), buffer_len(&kex->my), >- server_host_key_blob, sbloblen, >- dh_client_pub, >- dh->pub_key, >- shared_secret >- ); >- BN_clear_free(dh_client_pub); >- >- /* save session id := H */ >- /* XXX hashlen depends on KEX */ >- if (kex->session_id == NULL) { >- kex->session_id_len = 20; >- kex->session_id = xmalloc(kex->session_id_len); >- memcpy(kex->session_id, hash, kex->session_id_len); >- } >- >- /* sign H */ >- /* XXX hashlen depends on KEX */ >- PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20)); >- >- /* destroy_sensitive_data(); */ >- >- /* send server hostkey, DH pubkey 'f' and singed H */ >- packet_start(SSH2_MSG_KEXDH_REPLY); >- packet_put_string(server_host_key_blob, sbloblen); >- packet_put_bignum2(dh->pub_key); /* f */ >- packet_put_string(signature, slen); >- packet_send(); >- >- xfree(signature); >- xfree(server_host_key_blob); >- /* have keys, free DH */ >- DH_free(dh); >- >- kex_derive_keys(kex, hash, shared_secret); >- BN_clear_free(shared_secret); >- kex_finish(kex); >-} >- >-void >-kexdh(Kex *kex) >-{ >- if (kex->server) >- kexdh_server(kex); >- else >- kexdh_client(kex); > } >Index: kexdhc.c >=================================================================== >RCS file: kexdhc.c >diff -N kexdhc.c >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ kexdhc.c 16 Feb 2003 14:37:13 -0000 >@@ -0,0 +1,137 @@ >+/* >+ * Copyright (c) 2001 Markus Friedl. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR >+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES >+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. >+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, >+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT >+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, >+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF >+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "includes.h" >+RCSID("$OpenBSD: kexdh.c,v 1.18 2002/03/18 17:50:31 provos Exp $"); >+ >+#include "xmalloc.h" >+#include "key.h" >+#include "kex.h" >+#include "log.h" >+#include "packet.h" >+#include "dh.h" >+#include "ssh2.h" >+ >+void >+kexdh_client(Kex *kex) >+{ >+ BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; >+ DH *dh; >+ Key *server_host_key; >+ u_char *server_host_key_blob = NULL, *signature = NULL; >+ u_char *kbuf, *hash; >+ u_int klen, kout, slen, sbloblen; >+ >+ /* generate and send 'e', client DH public key */ >+ dh = dh_new_group1(); >+ dh_gen_key(dh, kex->we_need * 8); >+ packet_start(SSH2_MSG_KEXDH_INIT); >+ packet_put_bignum2(dh->pub_key); >+ packet_send(); >+ >+ debug("sending SSH2_MSG_KEXDH_INIT"); >+#ifdef DEBUG_KEXDH >+ DHparams_print_fp(stderr, dh); >+ fprintf(stderr, "pub= "); >+ BN_print_fp(stderr, dh->pub_key); >+ fprintf(stderr, "\n"); >+#endif >+ >+ debug("expecting SSH2_MSG_KEXDH_REPLY"); >+ packet_read_expect(SSH2_MSG_KEXDH_REPLY); >+ >+ /* key, cert */ >+ server_host_key_blob = packet_get_string(&sbloblen); >+ server_host_key = key_from_blob(server_host_key_blob, sbloblen); >+ if (server_host_key == NULL) >+ fatal("cannot decode server_host_key_blob"); >+ if (server_host_key->type != kex->hostkey_type) >+ fatal("type mismatch for decoded server_host_key_blob"); >+ if (kex->verify_host_key == NULL) >+ fatal("cannot verify server_host_key"); >+ if (kex->verify_host_key(server_host_key) == -1) >+ fatal("server_host_key verification failed"); >+ >+ /* DH paramter f, server public DH key */ >+ if ((dh_server_pub = BN_new()) == NULL) >+ fatal("dh_server_pub == NULL"); >+ packet_get_bignum2(dh_server_pub); >+ >+#ifdef DEBUG_KEXDH >+ fprintf(stderr, "dh_server_pub= "); >+ BN_print_fp(stderr, dh_server_pub); >+ fprintf(stderr, "\n"); >+ debug("bits %d", BN_num_bits(dh_server_pub)); >+#endif >+ >+ /* signed H */ >+ signature = packet_get_string(&slen); >+ packet_check_eom(); >+ >+ if (!dh_pub_is_valid(dh, dh_server_pub)) >+ packet_disconnect("bad server public DH value"); >+ >+ klen = DH_size(dh); >+ kbuf = xmalloc(klen); >+ kout = DH_compute_key(kbuf, dh_server_pub, dh); >+#ifdef DEBUG_KEXDH >+ dump_digest("shared secret", kbuf, kout); >+#endif >+ if ((shared_secret = BN_new()) == NULL) >+ fatal("kexdh_client: BN_new failed"); >+ BN_bin2bn(kbuf, kout, shared_secret); >+ memset(kbuf, 0, klen); >+ xfree(kbuf); >+ >+ /* calc and verify H */ >+ hash = kex_dh_hash( >+ kex->client_version_string, >+ kex->server_version_string, >+ buffer_ptr(&kex->my), buffer_len(&kex->my), >+ buffer_ptr(&kex->peer), buffer_len(&kex->peer), >+ server_host_key_blob, sbloblen, >+ dh->pub_key, >+ dh_server_pub, >+ shared_secret >+ ); >+ xfree(server_host_key_blob); >+ BN_clear_free(dh_server_pub); >+ DH_free(dh); >+ >+ if (key_verify(server_host_key, signature, slen, hash, 20) != 1) >+ fatal("key_verify failed for server_host_key"); >+ key_free(server_host_key); >+ xfree(signature); >+ >+ /* save session id */ >+ if (kex->session_id == NULL) { >+ kex->session_id_len = 20; >+ kex->session_id = xmalloc(kex->session_id_len); >+ memcpy(kex->session_id, hash, kex->session_id_len); >+ } >+ >+ kex_derive_keys(kex, hash, shared_secret); >+ BN_clear_free(shared_secret); >+ kex_finish(kex); >+} >Index: kexdhs.c >=================================================================== >RCS file: kexdhs.c >diff -N kexdhs.c >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ kexdhs.c 16 Feb 2003 14:37:13 -0000 >@@ -0,0 +1,138 @@ >+/* >+ * Copyright (c) 2001 Markus Friedl. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR >+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES >+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. >+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, >+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT >+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, >+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF >+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "includes.h" >+RCSID("$OpenBSD: kexdh.c,v 1.18 2002/03/18 17:50:31 provos Exp $"); >+ >+#include "xmalloc.h" >+#include "key.h" >+#include "kex.h" >+#include "log.h" >+#include "packet.h" >+#include "dh.h" >+#include "ssh2.h" >+#include "monitor_wrap.h" >+ >+void >+kexdh_server(Kex *kex) >+{ >+ BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; >+ DH *dh; >+ Key *server_host_key; >+ u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; >+ u_int sbloblen, klen, kout; >+ u_int slen; >+ >+ /* generate server DH public key */ >+ dh = dh_new_group1(); >+ dh_gen_key(dh, kex->we_need * 8); >+ >+ debug("expecting SSH2_MSG_KEXDH_INIT"); >+ packet_read_expect(SSH2_MSG_KEXDH_INIT); >+ >+ if (kex->load_host_key == NULL) >+ fatal("Cannot load hostkey"); >+ server_host_key = kex->load_host_key(kex->hostkey_type); >+ if (server_host_key == NULL) >+ fatal("Unsupported hostkey type %d", kex->hostkey_type); >+ >+ /* key, cert */ >+ if ((dh_client_pub = BN_new()) == NULL) >+ fatal("dh_client_pub == NULL"); >+ packet_get_bignum2(dh_client_pub); >+ packet_check_eom(); >+ >+#ifdef DEBUG_KEXDH >+ fprintf(stderr, "dh_client_pub= "); >+ BN_print_fp(stderr, dh_client_pub); >+ fprintf(stderr, "\n"); >+ debug("bits %d", BN_num_bits(dh_client_pub)); >+#endif >+ >+#ifdef DEBUG_KEXDH >+ DHparams_print_fp(stderr, dh); >+ fprintf(stderr, "pub= "); >+ BN_print_fp(stderr, dh->pub_key); >+ fprintf(stderr, "\n"); >+#endif >+ if (!dh_pub_is_valid(dh, dh_client_pub)) >+ packet_disconnect("bad client public DH value"); >+ >+ klen = DH_size(dh); >+ kbuf = xmalloc(klen); >+ kout = DH_compute_key(kbuf, dh_client_pub, dh); >+#ifdef DEBUG_KEXDH >+ dump_digest("shared secret", kbuf, kout); >+#endif >+ if ((shared_secret = BN_new()) == NULL) >+ fatal("kexdh_server: BN_new failed"); >+ BN_bin2bn(kbuf, kout, shared_secret); >+ memset(kbuf, 0, klen); >+ xfree(kbuf); >+ >+ key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); >+ >+ /* calc H */ >+ hash = kex_dh_hash( >+ kex->client_version_string, >+ kex->server_version_string, >+ buffer_ptr(&kex->peer), buffer_len(&kex->peer), >+ buffer_ptr(&kex->my), buffer_len(&kex->my), >+ server_host_key_blob, sbloblen, >+ dh_client_pub, >+ dh->pub_key, >+ shared_secret >+ ); >+ BN_clear_free(dh_client_pub); >+ >+ /* save session id := H */ >+ /* XXX hashlen depends on KEX */ >+ if (kex->session_id == NULL) { >+ kex->session_id_len = 20; >+ kex->session_id = xmalloc(kex->session_id_len); >+ memcpy(kex->session_id, hash, kex->session_id_len); >+ } >+ >+ /* sign H */ >+ /* XXX hashlen depends on KEX */ >+ PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20)); >+ >+ /* destroy_sensitive_data(); */ >+ >+ /* send server hostkey, DH pubkey 'f' and singed H */ >+ packet_start(SSH2_MSG_KEXDH_REPLY); >+ packet_put_string(server_host_key_blob, sbloblen); >+ packet_put_bignum2(dh->pub_key); /* f */ >+ packet_put_string(signature, slen); >+ packet_send(); >+ >+ xfree(signature); >+ xfree(server_host_key_blob); >+ /* have keys, free DH */ >+ DH_free(dh); >+ >+ kex_derive_keys(kex, hash, shared_secret); >+ BN_clear_free(shared_secret); >+ kex_finish(kex); >+} >Index: kexgex.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/kexgex.c,v >retrieving revision 1.22 >diff -u -r1.22 kexgex.c >--- kexgex.c 24 Mar 2002 17:27:03 -0000 1.22 >+++ kexgex.c 16 Feb 2003 14:37:13 -0000 >@@ -26,21 +26,14 @@ > #include "includes.h" > RCSID("$OpenBSD: kexgex.c,v 1.22 2002/03/24 17:27:03 stevesk Exp $"); > >-#include <openssl/bn.h> >+#include <openssl/evp.h> > >-#include "xmalloc.h" > #include "buffer.h" > #include "bufaux.h" >-#include "key.h" > #include "kex.h" >-#include "log.h" >-#include "packet.h" >-#include "dh.h" > #include "ssh2.h" >-#include "compat.h" >-#include "monitor_wrap.h" > >-static u_char * >+u_char * > kexgex_hash( > char *client_version_string, > char *server_version_string, >@@ -96,319 +89,4 @@ > dump_digest("hash", digest, EVP_MD_size(evp_md)); > #endif > return digest; >-} >- >-/* client */ >- >-static void >-kexgex_client(Kex *kex) >-{ >- BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; >- BIGNUM *p = NULL, *g = NULL; >- Key *server_host_key; >- u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; >- u_int klen, kout, slen, sbloblen; >- int min, max, nbits; >- DH *dh; >- >- nbits = dh_estimate(kex->we_need * 8); >- >- if (datafellows & SSH_OLD_DHGEX) { >- debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD sent"); >- >- /* Old GEX request */ >- packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); >- packet_put_int(nbits); >- min = DH_GRP_MIN; >- max = DH_GRP_MAX; >- } else { >- debug("SSH2_MSG_KEX_DH_GEX_REQUEST sent"); >- >- /* New GEX request */ >- min = DH_GRP_MIN; >- max = DH_GRP_MAX; >- packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); >- packet_put_int(min); >- packet_put_int(nbits); >- packet_put_int(max); >- } >-#ifdef DEBUG_KEXDH >- fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n", >- min, nbits, max); >-#endif >- packet_send(); >- >- debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP"); >- packet_read_expect(SSH2_MSG_KEX_DH_GEX_GROUP); >- >- if ((p = BN_new()) == NULL) >- fatal("BN_new"); >- packet_get_bignum2(p); >- if ((g = BN_new()) == NULL) >- fatal("BN_new"); >- packet_get_bignum2(g); >- packet_check_eom(); >- >- if (BN_num_bits(p) < min || BN_num_bits(p) > max) >- fatal("DH_GEX group out of range: %d !< %d !< %d", >- min, BN_num_bits(p), max); >- >- dh = dh_new_group(g, p); >- dh_gen_key(dh, kex->we_need * 8); >- >-#ifdef DEBUG_KEXDH >- DHparams_print_fp(stderr, dh); >- fprintf(stderr, "pub= "); >- BN_print_fp(stderr, dh->pub_key); >- fprintf(stderr, "\n"); >-#endif >- >- debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); >- /* generate and send 'e', client DH public key */ >- packet_start(SSH2_MSG_KEX_DH_GEX_INIT); >- packet_put_bignum2(dh->pub_key); >- packet_send(); >- >- debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY"); >- packet_read_expect(SSH2_MSG_KEX_DH_GEX_REPLY); >- >- /* key, cert */ >- server_host_key_blob = packet_get_string(&sbloblen); >- server_host_key = key_from_blob(server_host_key_blob, sbloblen); >- if (server_host_key == NULL) >- fatal("cannot decode server_host_key_blob"); >- if (server_host_key->type != kex->hostkey_type) >- fatal("type mismatch for decoded server_host_key_blob"); >- if (kex->verify_host_key == NULL) >- fatal("cannot verify server_host_key"); >- if (kex->verify_host_key(server_host_key) == -1) >- fatal("server_host_key verification failed"); >- >- /* DH paramter f, server public DH key */ >- if ((dh_server_pub = BN_new()) == NULL) >- fatal("dh_server_pub == NULL"); >- packet_get_bignum2(dh_server_pub); >- >-#ifdef DEBUG_KEXDH >- fprintf(stderr, "dh_server_pub= "); >- BN_print_fp(stderr, dh_server_pub); >- fprintf(stderr, "\n"); >- debug("bits %d", BN_num_bits(dh_server_pub)); >-#endif >- >- /* signed H */ >- signature = packet_get_string(&slen); >- packet_check_eom(); >- >- if (!dh_pub_is_valid(dh, dh_server_pub)) >- packet_disconnect("bad server public DH value"); >- >- klen = DH_size(dh); >- kbuf = xmalloc(klen); >- kout = DH_compute_key(kbuf, dh_server_pub, dh); >-#ifdef DEBUG_KEXDH >- dump_digest("shared secret", kbuf, kout); >-#endif >- if ((shared_secret = BN_new()) == NULL) >- fatal("kexgex_client: BN_new failed"); >- BN_bin2bn(kbuf, kout, shared_secret); >- memset(kbuf, 0, klen); >- xfree(kbuf); >- >- if (datafellows & SSH_OLD_DHGEX) >- min = max = -1; >- >- /* calc and verify H */ >- hash = kexgex_hash( >- kex->client_version_string, >- kex->server_version_string, >- buffer_ptr(&kex->my), buffer_len(&kex->my), >- buffer_ptr(&kex->peer), buffer_len(&kex->peer), >- server_host_key_blob, sbloblen, >- min, nbits, max, >- dh->p, dh->g, >- dh->pub_key, >- dh_server_pub, >- shared_secret >- ); >- /* have keys, free DH */ >- DH_free(dh); >- xfree(server_host_key_blob); >- BN_clear_free(dh_server_pub); >- >- if (key_verify(server_host_key, signature, slen, hash, 20) != 1) >- fatal("key_verify failed for server_host_key"); >- key_free(server_host_key); >- xfree(signature); >- >- /* save session id */ >- if (kex->session_id == NULL) { >- kex->session_id_len = 20; >- kex->session_id = xmalloc(kex->session_id_len); >- memcpy(kex->session_id, hash, kex->session_id_len); >- } >- kex_derive_keys(kex, hash, shared_secret); >- BN_clear_free(shared_secret); >- >- kex_finish(kex); >-} >- >-/* server */ >- >-static void >-kexgex_server(Kex *kex) >-{ >- BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; >- Key *server_host_key; >- DH *dh; >- u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; >- u_int sbloblen, klen, kout, slen; >- int min = -1, max = -1, nbits = -1, type; >- >- if (kex->load_host_key == NULL) >- fatal("Cannot load hostkey"); >- server_host_key = kex->load_host_key(kex->hostkey_type); >- if (server_host_key == NULL) >- fatal("Unsupported hostkey type %d", kex->hostkey_type); >- >- type = packet_read(); >- switch (type) { >- case SSH2_MSG_KEX_DH_GEX_REQUEST: >- debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); >- min = packet_get_int(); >- nbits = packet_get_int(); >- max = packet_get_int(); >- min = MAX(DH_GRP_MIN, min); >- max = MIN(DH_GRP_MAX, max); >- break; >- case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: >- debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); >- nbits = packet_get_int(); >- min = DH_GRP_MIN; >- max = DH_GRP_MAX; >- /* unused for old GEX */ >- break; >- default: >- fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type); >- } >- packet_check_eom(); >- >- if (max < min || nbits < min || max < nbits) >- fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d", >- min, nbits, max); >- >- /* Contact privileged parent */ >- dh = PRIVSEP(choose_dh(min, nbits, max)); >- if (dh == NULL) >- packet_disconnect("Protocol error: no matching DH grp found"); >- >- debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); >- packet_start(SSH2_MSG_KEX_DH_GEX_GROUP); >- packet_put_bignum2(dh->p); >- packet_put_bignum2(dh->g); >- packet_send(); >- >- /* flush */ >- packet_write_wait(); >- >- /* Compute our exchange value in parallel with the client */ >- dh_gen_key(dh, kex->we_need * 8); >- >- debug("expecting SSH2_MSG_KEX_DH_GEX_INIT"); >- packet_read_expect(SSH2_MSG_KEX_DH_GEX_INIT); >- >- /* key, cert */ >- if ((dh_client_pub = BN_new()) == NULL) >- fatal("dh_client_pub == NULL"); >- packet_get_bignum2(dh_client_pub); >- packet_check_eom(); >- >-#ifdef DEBUG_KEXDH >- fprintf(stderr, "dh_client_pub= "); >- BN_print_fp(stderr, dh_client_pub); >- fprintf(stderr, "\n"); >- debug("bits %d", BN_num_bits(dh_client_pub)); >-#endif >- >-#ifdef DEBUG_KEXDH >- DHparams_print_fp(stderr, dh); >- fprintf(stderr, "pub= "); >- BN_print_fp(stderr, dh->pub_key); >- fprintf(stderr, "\n"); >-#endif >- if (!dh_pub_is_valid(dh, dh_client_pub)) >- packet_disconnect("bad client public DH value"); >- >- klen = DH_size(dh); >- kbuf = xmalloc(klen); >- kout = DH_compute_key(kbuf, dh_client_pub, dh); >-#ifdef DEBUG_KEXDH >- dump_digest("shared secret", kbuf, kout); >-#endif >- if ((shared_secret = BN_new()) == NULL) >- fatal("kexgex_server: BN_new failed"); >- BN_bin2bn(kbuf, kout, shared_secret); >- memset(kbuf, 0, klen); >- xfree(kbuf); >- >- key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); >- >- if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) >- min = max = -1; >- >- /* calc H */ /* XXX depends on 'kex' */ >- hash = kexgex_hash( >- kex->client_version_string, >- kex->server_version_string, >- buffer_ptr(&kex->peer), buffer_len(&kex->peer), >- buffer_ptr(&kex->my), buffer_len(&kex->my), >- server_host_key_blob, sbloblen, >- min, nbits, max, >- dh->p, dh->g, >- dh_client_pub, >- dh->pub_key, >- shared_secret >- ); >- BN_clear_free(dh_client_pub); >- >- /* save session id := H */ >- /* XXX hashlen depends on KEX */ >- if (kex->session_id == NULL) { >- kex->session_id_len = 20; >- kex->session_id = xmalloc(kex->session_id_len); >- memcpy(kex->session_id, hash, kex->session_id_len); >- } >- >- /* sign H */ >- /* XXX hashlen depends on KEX */ >- PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20)); >- >- /* destroy_sensitive_data(); */ >- >- /* send server hostkey, DH pubkey 'f' and singed H */ >- debug("SSH2_MSG_KEX_DH_GEX_REPLY sent"); >- packet_start(SSH2_MSG_KEX_DH_GEX_REPLY); >- packet_put_string(server_host_key_blob, sbloblen); >- packet_put_bignum2(dh->pub_key); /* f */ >- packet_put_string(signature, slen); >- packet_send(); >- >- xfree(signature); >- xfree(server_host_key_blob); >- /* have keys, free DH */ >- DH_free(dh); >- >- kex_derive_keys(kex, hash, shared_secret); >- BN_clear_free(shared_secret); >- >- kex_finish(kex); >-} >- >-void >-kexgex(Kex *kex) >-{ >- if (kex->server) >- kexgex_server(kex); >- else >- kexgex_client(kex); > } >Index: kexgexc.c >=================================================================== >RCS file: kexgexc.c >diff -N kexgexc.c >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ kexgexc.c 16 Feb 2003 14:37:13 -0000 >@@ -0,0 +1,189 @@ >+/* >+ * Copyright (c) 2000 Niels Provos. All rights reserved. >+ * Copyright (c) 2001 Markus Friedl. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR >+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES >+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. >+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, >+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT >+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, >+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF >+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "includes.h" >+RCSID("$OpenBSD: kexgex.c,v 1.22 2002/03/24 17:27:03 stevesk Exp $"); >+ >+#include "xmalloc.h" >+#include "key.h" >+#include "kex.h" >+#include "log.h" >+#include "packet.h" >+#include "dh.h" >+#include "ssh2.h" >+#include "compat.h" >+ >+void >+kexgex_client(Kex *kex) >+{ >+ BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; >+ BIGNUM *p = NULL, *g = NULL; >+ Key *server_host_key; >+ u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; >+ u_int klen, kout, slen, sbloblen; >+ int min, max, nbits; >+ DH *dh; >+ >+ nbits = dh_estimate(kex->we_need * 8); >+ >+ if (datafellows & SSH_OLD_DHGEX) { >+ debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD sent"); >+ >+ /* Old GEX request */ >+ packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); >+ packet_put_int(nbits); >+ min = DH_GRP_MIN; >+ max = DH_GRP_MAX; >+ } else { >+ debug("SSH2_MSG_KEX_DH_GEX_REQUEST sent"); >+ >+ /* New GEX request */ >+ min = DH_GRP_MIN; >+ max = DH_GRP_MAX; >+ packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); >+ packet_put_int(min); >+ packet_put_int(nbits); >+ packet_put_int(max); >+ } >+#ifdef DEBUG_KEXDH >+ fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n", >+ min, nbits, max); >+#endif >+ packet_send(); >+ >+ debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP"); >+ packet_read_expect(SSH2_MSG_KEX_DH_GEX_GROUP); >+ >+ if ((p = BN_new()) == NULL) >+ fatal("BN_new"); >+ packet_get_bignum2(p); >+ if ((g = BN_new()) == NULL) >+ fatal("BN_new"); >+ packet_get_bignum2(g); >+ packet_check_eom(); >+ >+ if (BN_num_bits(p) < min || BN_num_bits(p) > max) >+ fatal("DH_GEX group out of range: %d !< %d !< %d", >+ min, BN_num_bits(p), max); >+ >+ dh = dh_new_group(g, p); >+ dh_gen_key(dh, kex->we_need * 8); >+ >+#ifdef DEBUG_KEXDH >+ DHparams_print_fp(stderr, dh); >+ fprintf(stderr, "pub= "); >+ BN_print_fp(stderr, dh->pub_key); >+ fprintf(stderr, "\n"); >+#endif >+ >+ debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); >+ /* generate and send 'e', client DH public key */ >+ packet_start(SSH2_MSG_KEX_DH_GEX_INIT); >+ packet_put_bignum2(dh->pub_key); >+ packet_send(); >+ >+ debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY"); >+ packet_read_expect(SSH2_MSG_KEX_DH_GEX_REPLY); >+ >+ /* key, cert */ >+ server_host_key_blob = packet_get_string(&sbloblen); >+ server_host_key = key_from_blob(server_host_key_blob, sbloblen); >+ if (server_host_key == NULL) >+ fatal("cannot decode server_host_key_blob"); >+ if (server_host_key->type != kex->hostkey_type) >+ fatal("type mismatch for decoded server_host_key_blob"); >+ if (kex->verify_host_key == NULL) >+ fatal("cannot verify server_host_key"); >+ if (kex->verify_host_key(server_host_key) == -1) >+ fatal("server_host_key verification failed"); >+ >+ /* DH paramter f, server public DH key */ >+ if ((dh_server_pub = BN_new()) == NULL) >+ fatal("dh_server_pub == NULL"); >+ packet_get_bignum2(dh_server_pub); >+ >+#ifdef DEBUG_KEXDH >+ fprintf(stderr, "dh_server_pub= "); >+ BN_print_fp(stderr, dh_server_pub); >+ fprintf(stderr, "\n"); >+ debug("bits %d", BN_num_bits(dh_server_pub)); >+#endif >+ >+ /* signed H */ >+ signature = packet_get_string(&slen); >+ packet_check_eom(); >+ >+ if (!dh_pub_is_valid(dh, dh_server_pub)) >+ packet_disconnect("bad server public DH value"); >+ >+ klen = DH_size(dh); >+ kbuf = xmalloc(klen); >+ kout = DH_compute_key(kbuf, dh_server_pub, dh); >+#ifdef DEBUG_KEXDH >+ dump_digest("shared secret", kbuf, kout); >+#endif >+ if ((shared_secret = BN_new()) == NULL) >+ fatal("kexgex_client: BN_new failed"); >+ BN_bin2bn(kbuf, kout, shared_secret); >+ memset(kbuf, 0, klen); >+ xfree(kbuf); >+ >+ if (datafellows & SSH_OLD_DHGEX) >+ min = max = -1; >+ >+ /* calc and verify H */ >+ hash = kexgex_hash( >+ kex->client_version_string, >+ kex->server_version_string, >+ buffer_ptr(&kex->my), buffer_len(&kex->my), >+ buffer_ptr(&kex->peer), buffer_len(&kex->peer), >+ server_host_key_blob, sbloblen, >+ min, nbits, max, >+ dh->p, dh->g, >+ dh->pub_key, >+ dh_server_pub, >+ shared_secret >+ ); >+ /* have keys, free DH */ >+ DH_free(dh); >+ xfree(server_host_key_blob); >+ BN_clear_free(dh_server_pub); >+ >+ if (key_verify(server_host_key, signature, slen, hash, 20) != 1) >+ fatal("key_verify failed for server_host_key"); >+ key_free(server_host_key); >+ xfree(signature); >+ >+ /* save session id */ >+ if (kex->session_id == NULL) { >+ kex->session_id_len = 20; >+ kex->session_id = xmalloc(kex->session_id_len); >+ memcpy(kex->session_id, hash, kex->session_id_len); >+ } >+ kex_derive_keys(kex, hash, shared_secret); >+ BN_clear_free(shared_secret); >+ >+ kex_finish(kex); >+} >Index: kexgexs.c >=================================================================== >RCS file: kexgexs.c >diff -N kexgexs.c >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ kexgexs.c 16 Feb 2003 14:37:13 -0000 >@@ -0,0 +1,186 @@ >+/* >+ * Copyright (c) 2000 Niels Provos. All rights reserved. >+ * Copyright (c) 2001 Markus Friedl. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR >+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES >+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. >+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, >+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT >+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, >+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF >+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "includes.h" >+RCSID("$OpenBSD: kexgex.c,v 1.22 2002/03/24 17:27:03 stevesk Exp $"); >+ >+#include "xmalloc.h" >+#include "key.h" >+#include "kex.h" >+#include "log.h" >+#include "packet.h" >+#include "dh.h" >+#include "ssh2.h" >+#include "compat.h" >+#include "monitor_wrap.h" >+ >+void >+kexgex_server(Kex *kex) >+{ >+ BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; >+ Key *server_host_key; >+ DH *dh; >+ u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; >+ u_int sbloblen, klen, kout, slen; >+ int min = -1, max = -1, nbits = -1, type; >+ >+ if (kex->load_host_key == NULL) >+ fatal("Cannot load hostkey"); >+ server_host_key = kex->load_host_key(kex->hostkey_type); >+ if (server_host_key == NULL) >+ fatal("Unsupported hostkey type %d", kex->hostkey_type); >+ >+ type = packet_read(); >+ switch (type) { >+ case SSH2_MSG_KEX_DH_GEX_REQUEST: >+ debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); >+ min = packet_get_int(); >+ nbits = packet_get_int(); >+ max = packet_get_int(); >+ min = MAX(DH_GRP_MIN, min); >+ max = MIN(DH_GRP_MAX, max); >+ break; >+ case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: >+ debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); >+ nbits = packet_get_int(); >+ min = DH_GRP_MIN; >+ max = DH_GRP_MAX; >+ /* unused for old GEX */ >+ break; >+ default: >+ fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type); >+ } >+ packet_check_eom(); >+ >+ if (max < min || nbits < min || max < nbits) >+ fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d", >+ min, nbits, max); >+ >+ /* Contact privileged parent */ >+ dh = PRIVSEP(choose_dh(min, nbits, max)); >+ if (dh == NULL) >+ packet_disconnect("Protocol error: no matching DH grp found"); >+ >+ debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); >+ packet_start(SSH2_MSG_KEX_DH_GEX_GROUP); >+ packet_put_bignum2(dh->p); >+ packet_put_bignum2(dh->g); >+ packet_send(); >+ >+ /* flush */ >+ packet_write_wait(); >+ >+ /* Compute our exchange value in parallel with the client */ >+ dh_gen_key(dh, kex->we_need * 8); >+ >+ debug("expecting SSH2_MSG_KEX_DH_GEX_INIT"); >+ packet_read_expect(SSH2_MSG_KEX_DH_GEX_INIT); >+ >+ /* key, cert */ >+ if ((dh_client_pub = BN_new()) == NULL) >+ fatal("dh_client_pub == NULL"); >+ packet_get_bignum2(dh_client_pub); >+ packet_check_eom(); >+ >+#ifdef DEBUG_KEXDH >+ fprintf(stderr, "dh_client_pub= "); >+ BN_print_fp(stderr, dh_client_pub); >+ fprintf(stderr, "\n"); >+ debug("bits %d", BN_num_bits(dh_client_pub)); >+#endif >+ >+#ifdef DEBUG_KEXDH >+ DHparams_print_fp(stderr, dh); >+ fprintf(stderr, "pub= "); >+ BN_print_fp(stderr, dh->pub_key); >+ fprintf(stderr, "\n"); >+#endif >+ if (!dh_pub_is_valid(dh, dh_client_pub)) >+ packet_disconnect("bad client public DH value"); >+ >+ klen = DH_size(dh); >+ kbuf = xmalloc(klen); >+ kout = DH_compute_key(kbuf, dh_client_pub, dh); >+#ifdef DEBUG_KEXDH >+ dump_digest("shared secret", kbuf, kout); >+#endif >+ if ((shared_secret = BN_new()) == NULL) >+ fatal("kexgex_server: BN_new failed"); >+ BN_bin2bn(kbuf, kout, shared_secret); >+ memset(kbuf, 0, klen); >+ xfree(kbuf); >+ >+ key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); >+ >+ if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) >+ min = max = -1; >+ >+ /* calc H */ /* XXX depends on 'kex' */ >+ hash = kexgex_hash( >+ kex->client_version_string, >+ kex->server_version_string, >+ buffer_ptr(&kex->peer), buffer_len(&kex->peer), >+ buffer_ptr(&kex->my), buffer_len(&kex->my), >+ server_host_key_blob, sbloblen, >+ min, nbits, max, >+ dh->p, dh->g, >+ dh_client_pub, >+ dh->pub_key, >+ shared_secret >+ ); >+ BN_clear_free(dh_client_pub); >+ >+ /* save session id := H */ >+ /* XXX hashlen depends on KEX */ >+ if (kex->session_id == NULL) { >+ kex->session_id_len = 20; >+ kex->session_id = xmalloc(kex->session_id_len); >+ memcpy(kex->session_id, hash, kex->session_id_len); >+ } >+ >+ /* sign H */ >+ /* XXX hashlen depends on KEX */ >+ PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20)); >+ >+ /* destroy_sensitive_data(); */ >+ >+ /* send server hostkey, DH pubkey 'f' and singed H */ >+ debug("SSH2_MSG_KEX_DH_GEX_REPLY sent"); >+ packet_start(SSH2_MSG_KEX_DH_GEX_REPLY); >+ packet_put_string(server_host_key_blob, sbloblen); >+ packet_put_bignum2(dh->pub_key); /* f */ >+ packet_put_string(signature, slen); >+ packet_send(); >+ >+ xfree(signature); >+ xfree(server_host_key_blob); >+ /* have keys, free DH */ >+ DH_free(dh); >+ >+ kex_derive_keys(kex, hash, shared_secret); >+ BN_clear_free(shared_secret); >+ >+ kex_finish(kex); >+} >Index: monitor.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/monitor.c,v >retrieving revision 1.31 >diff -u -r1.31 monitor.c >--- monitor.c 4 Feb 2003 09:33:22 -0000 1.31 >+++ monitor.c 16 Feb 2003 14:37:13 -0000 >@@ -791,6 +791,7 @@ > > buffer_clear(m); > buffer_put_int(m, allowed); >+ buffer_put_int(m, forced_command != NULL); > > mm_append_debug(m); > >@@ -1153,6 +1154,7 @@ > } > buffer_clear(m); > buffer_put_int(m, allowed); >+ buffer_put_int(m, forced_command != NULL); > > /* clear temporarily storage (used by generate challenge) */ > monitor_reset_key_state(); >Index: monitor_wrap.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/monitor_wrap.c,v >retrieving revision 1.21 >diff -u -r1.21 monitor_wrap.c >--- monitor_wrap.c 4 Feb 2003 09:33:22 -0000 1.21 >+++ monitor_wrap.c 16 Feb 2003 14:37:13 -0000 >@@ -34,6 +34,7 @@ > #include "dh.h" > #include "kex.h" > #include "auth.h" >+#include "auth-options.h" > #include "buffer.h" > #include "bufaux.h" > #include "packet.h" >@@ -310,7 +311,7 @@ > Buffer m; > u_char *blob; > u_int len; >- int allowed = 0; >+ int allowed = 0, have_forced = 0; > > debug3("%s entering", __func__); > >@@ -332,6 +333,14 @@ > > allowed = buffer_get_int(&m); > >+ /* fake forced command */ >+ if (forced_command) { >+ xfree(forced_command); >+ forced_command = NULL; >+ } >+ have_forced = buffer_get_int(&m); >+ forced_command = have_forced ? xstrdup("true") : NULL; >+ > /* Send potential debug messages */ > mm_send_debug(&m); > >@@ -834,7 +843,7 @@ > Key *key; > u_char *blob; > u_int blen; >- int allowed = 0; >+ int allowed = 0, have_forced = 0; > > debug3("%s entering", __func__); > >@@ -845,6 +854,14 @@ > mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m); > > allowed = buffer_get_int(&m); >+ >+ /* fake forced command */ >+ if (forced_command) { >+ xfree(forced_command); >+ forced_command = NULL; >+ } >+ have_forced = buffer_get_int(&m); >+ forced_command = have_forced ? xstrdup("true") : NULL; > > if (allowed && rkey != NULL) { > blob = buffer_get_string(&m, &blen); >Index: ssh-keyscan.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/ssh-keyscan.c,v >retrieving revision 1.40 >diff -u -r1.40 ssh-keyscan.c >--- ssh-keyscan.c 6 Jul 2002 17:47:58 -0000 1.40 >+++ ssh-keyscan.c 16 Feb 2003 14:37:13 -0000 >@@ -335,6 +335,8 @@ > myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA? > "ssh-dss": "ssh-rsa"; > c->c_kex = kex_setup(myproposal); >+ c->c_kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; >+ c->c_kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; > c->c_kex->verify_host_key = hostjump; > > if (!(j = setjmp(kexjmp))) { >Index: sshconnect2.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/sshconnect2.c,v >retrieving revision 1.110 >diff -u -r1.110 sshconnect2.c >--- sshconnect2.c 19 Dec 2002 00:07:02 -0000 1.110 >+++ sshconnect2.c 16 Feb 2003 14:37:13 -0000 >@@ -110,6 +110,8 @@ > > /* start key exchange */ > kex = kex_setup(myproposal); >+ kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; >+ kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; > kex->client_version_string=client_version_string; > kex->server_version_string=server_version_string; > kex->verify_host_key=&verify_host_key_callback; >Index: sshd.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/sshd.c,v >retrieving revision 1.262 >diff -u -r1.262 sshd.c >--- sshd.c 27 Jan 2003 17:06:31 -0000 1.262 >+++ sshd.c 16 Feb 2003 14:37:13 -0000 >@@ -189,8 +189,8 @@ > int startup_pipe; /* in child */ > > /* variables used for privilege separation */ >-extern struct monitor *pmonitor; >-extern int use_privsep; >+int use_privsep; >+struct monitor *pmonitor; > > /* Prototypes for various functions defined later in this file. */ > void destroy_sensitive_data(void); >@@ -1746,6 +1746,8 @@ > > /* start key exchange */ > kex = kex_setup(myproposal); >+ kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; >+ kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; > kex->server = 1; > kex->client_version_string=client_version_string; > kex->server_version_string=server_version_string; >Index: lib/Makefile >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/lib/Makefile,v >retrieving revision 1.37 >diff -u -r1.37 Makefile >--- lib/Makefile 12 Jan 2003 16:59:14 -0000 1.37 >+++ lib/Makefile 16 Feb 2003 14:37:13 -0000 >@@ -9,6 +9,7 @@ > rsa.c tildexpand.c ttymodes.c xmalloc.c atomicio.c \ > key.c dispatch.c kex.c mac.c uuencode.c misc.c \ > rijndael.c ssh-dss.c ssh-rsa.c dh.c kexdh.c kexgex.c \ >+ kexdhs.c kexdhc.c kexgexs.c kexgexc.c \ > scard.c monitor_wrap.c monitor_fdpass.c msg.c progressmeter.c > > DEBUGLIBS= no
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 387
:
139
|
225
| 230