annotate cli-kex.c @ 1659:d32bcb5c557d

Add Ed25519 support (#91) * Add support for Ed25519 as a public key type Ed25519 is a elliptic curve signature scheme that offers better security than ECDSA and DSA and good performance. It may be used for both user and host keys. OpenSSH key import and fuzzer are not supported yet. Initially inspired by Peter Szabo. * Add curve25519 and ed25519 fuzzers * Add import and export of Ed25519 keys
author Vladislav Grishenko <themiron@users.noreply.github.com>
date Wed, 11 Mar 2020 21:09:45 +0500
parents 06d52bcb8094
children ba6fc7afe1c5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
26
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1 /*
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2 * Dropbear - a SSH2 server
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3 *
74
e3adf4cf5465 License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents: 59
diff changeset
4 * Copyright (c) 2002-2004 Matt Johnston
e3adf4cf5465 License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents: 59
diff changeset
5 * Copyright (c) 2004 by Mihnea Stoenescu
26
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
6 * All rights reserved.
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
7 *
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
9 * of this software and associated documentation files (the "Software"), to deal
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
10 * in the Software without restriction, including without limitation the rights
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
12 * copies of the Software, and to permit persons to whom the Software is
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
13 * furnished to do so, subject to the following conditions:
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
14 *
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
15 * The above copyright notice and this permission notice shall be included in
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
16 * all copies or substantial portions of the Software.
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
17 *
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
24 * SOFTWARE. */
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
25
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
26 #include "includes.h"
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
27 #include "session.h"
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
28 #include "dbutil.h"
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
29 #include "algo.h"
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
30 #include "buffer.h"
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
31 #include "session.h"
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
32 #include "kex.h"
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
33 #include "ssh.h"
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
34 #include "packet.h"
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
35 #include "bignum.h"
858
220f55d540ae rename random.h to dbrandom.h since some OSes have a system random.h
Matt Johnston <matt@ucc.asn.au>
parents: 850
diff changeset
36 #include "dbrandom.h"
26
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
37 #include "runopts.h"
33
f789045062e6 Progressing client support
Matt Johnston <matt@ucc.asn.au>
parents: 26
diff changeset
38 #include "signkey.h"
761
ac2158e3e403 ecc kind of works, needs fixing/testing
Matt Johnston <matt@ucc.asn.au>
parents: 759
diff changeset
39 #include "ecc.h"
26
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
40
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
41
1459
06d52bcb8094 Pointer parameter could be declared as pointing to const
Francois Perrad <francois.perrad@gadz.org>
parents: 1295
diff changeset
42 static void checkhostkey(const unsigned char* keyblob, unsigned int keybloblen);
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
43 #define MAX_KNOWNHOSTS_LINE 4500
26
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
44
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
45 void send_msg_kexdh_init() {
739
d44325108d0e first_kex_packet_follows working, needs tidying
Matt Johnston <matt@ucc.asn.au>
parents: 723
diff changeset
46 TRACE(("send_msg_kexdh_init()"))
26
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
47
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
48 CHECKCLEARTOWRITE();
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
49 buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_INIT);
848
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
50 switch (ses.newkeys->algo_kex->mode) {
1294
56aba7dedbea options for disabling "normal" DH
Matt Johnston <matt@ucc.asn.au>
parents: 1257
diff changeset
51 #if DROPBEAR_NORMAL_DH
848
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
52 case DROPBEAR_KEX_NORMAL_DH:
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
53 if (ses.newkeys->algo_kex != cli_ses.param_kex_algo
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
54 || !cli_ses.dh_param) {
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
55 if (cli_ses.dh_param) {
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
56 free_kexdh_param(cli_ses.dh_param);
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
57 }
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
58 cli_ses.dh_param = gen_kexdh_param();
801
7dcb46da72d9 merge in HEAD
Matt Johnston <matt@ucc.asn.au>
parents: 765 775
diff changeset
59 }
848
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
60 buf_putmpint(ses.writepayload, &cli_ses.dh_param->pub);
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
61 break;
1294
56aba7dedbea options for disabling "normal" DH
Matt Johnston <matt@ucc.asn.au>
parents: 1257
diff changeset
62 #endif
1295
750ec4ec4cbe Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents: 1294
diff changeset
63 #if DROPBEAR_ECDH
848
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
64 case DROPBEAR_KEX_ECDH:
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
65 if (ses.newkeys->algo_kex != cli_ses.param_kex_algo
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
66 || !cli_ses.ecdh_param) {
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
67 if (cli_ses.ecdh_param) {
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
68 free_kexecdh_param(cli_ses.ecdh_param);
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
69 }
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
70 cli_ses.ecdh_param = gen_kexecdh_param();
801
7dcb46da72d9 merge in HEAD
Matt Johnston <matt@ucc.asn.au>
parents: 765 775
diff changeset
71 }
848
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
72 buf_put_ecc_raw_pubkey_string(ses.writepayload, &cli_ses.ecdh_param->key);
1294
56aba7dedbea options for disabling "normal" DH
Matt Johnston <matt@ucc.asn.au>
parents: 1257
diff changeset
73 break;
755
b07eb3dc23ec refactor kexdh code a bit, start working on ecdh etc
Matt Johnston <matt@ucc.asn.au>
parents: 723
diff changeset
74 #endif
1295
750ec4ec4cbe Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents: 1294
diff changeset
75 #if DROPBEAR_CURVE25519
848
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
76 case DROPBEAR_KEX_CURVE25519:
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
77 if (ses.newkeys->algo_kex != cli_ses.param_kex_algo
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
78 || !cli_ses.curve25519_param) {
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
79 if (cli_ses.curve25519_param) {
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
80 free_kexcurve25519_param(cli_ses.curve25519_param);
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
81 }
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
82 cli_ses.curve25519_param = gen_kexcurve25519_param();
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
83 }
1659
d32bcb5c557d Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents: 1459
diff changeset
84 buf_putstring(ses.writepayload, cli_ses.curve25519_param->pub, CURVE25519_LEN);
1294
56aba7dedbea options for disabling "normal" DH
Matt Johnston <matt@ucc.asn.au>
parents: 1257
diff changeset
85 break;
848
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
86 #endif
755
b07eb3dc23ec refactor kexdh code a bit, start working on ecdh etc
Matt Johnston <matt@ucc.asn.au>
parents: 723
diff changeset
87 }
848
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
88
801
7dcb46da72d9 merge in HEAD
Matt Johnston <matt@ucc.asn.au>
parents: 765 775
diff changeset
89 cli_ses.param_kex_algo = ses.newkeys->algo_kex;
26
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
90 encrypt_packet();
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
91 }
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
92
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
93 /* Handle a diffie-hellman key exchange reply. */
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
94 void recv_msg_kexdh_reply() {
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
95
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
96 sign_key *hostkey = NULL;
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
97 unsigned int type, keybloblen;
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
98 unsigned char* keyblob = NULL;
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
99
165
0cfba3034be5 Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents: 106
diff changeset
100 TRACE(("enter recv_msg_kexdh_reply"))
84
29a5c7c62350 default initialisers for mp_ints
Matt Johnston <matt@ucc.asn.au>
parents: 80
diff changeset
101
29a5c7c62350 default initialisers for mp_ints
Matt Johnston <matt@ucc.asn.au>
parents: 80
diff changeset
102 if (cli_ses.kex_state != KEXDH_INIT_SENT) {
29a5c7c62350 default initialisers for mp_ints
Matt Johnston <matt@ucc.asn.au>
parents: 80
diff changeset
103 dropbear_exit("Received out-of-order kexdhreply");
29a5c7c62350 default initialisers for mp_ints
Matt Johnston <matt@ucc.asn.au>
parents: 80
diff changeset
104 }
26
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
105 type = ses.newkeys->algo_hostkey;
165
0cfba3034be5 Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents: 106
diff changeset
106 TRACE(("type is %d", type))
26
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
107
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
108 hostkey = new_sign_key();
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
109 keybloblen = buf_getint(ses.payload);
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
110
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
111 keyblob = buf_getptr(ses.payload, keybloblen);
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
112 if (!ses.kexstate.donefirstkex) {
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
113 /* Only makes sense the first time */
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
114 checkhostkey(keyblob, keybloblen);
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
115 }
34
e2a1eaa19f22 Client mostly works up to password auth
Matt Johnston <matt@ucc.asn.au>
parents: 33
diff changeset
116
26
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
117 if (buf_get_pub_key(ses.payload, hostkey, &type) != DROPBEAR_SUCCESS) {
165
0cfba3034be5 Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents: 106
diff changeset
118 TRACE(("failed getting pubkey"))
26
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
119 dropbear_exit("Bad KEX packet");
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
120 }
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
121
848
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
122 switch (ses.newkeys->algo_kex->mode) {
1294
56aba7dedbea options for disabling "normal" DH
Matt Johnston <matt@ucc.asn.au>
parents: 1257
diff changeset
123 #if DROPBEAR_NORMAL_DH
848
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
124 case DROPBEAR_KEX_NORMAL_DH:
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
125 {
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
126 DEF_MP_INT(dh_f);
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
127 m_mp_init(&dh_f);
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
128 if (buf_getmpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) {
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
129 TRACE(("failed getting mpint"))
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
130 dropbear_exit("Bad KEX packet");
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
131 }
26
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
132
848
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
133 kexdh_comb_key(cli_ses.dh_param, &dh_f, hostkey);
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
134 mp_clear(&dh_f);
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
135 }
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
136 break;
1294
56aba7dedbea options for disabling "normal" DH
Matt Johnston <matt@ucc.asn.au>
parents: 1257
diff changeset
137 #endif
1295
750ec4ec4cbe Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents: 1294
diff changeset
138 #if DROPBEAR_ECDH
848
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
139 case DROPBEAR_KEX_ECDH:
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
140 {
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
141 buffer *ecdh_qs = buf_getstringbuf(ses.payload);
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
142 kexecdh_comb_key(cli_ses.ecdh_param, ecdh_qs, hostkey);
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
143 buf_free(ecdh_qs);
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
144 }
1294
56aba7dedbea options for disabling "normal" DH
Matt Johnston <matt@ucc.asn.au>
parents: 1257
diff changeset
145 break;
755
b07eb3dc23ec refactor kexdh code a bit, start working on ecdh etc
Matt Johnston <matt@ucc.asn.au>
parents: 723
diff changeset
146 #endif
1295
750ec4ec4cbe Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents: 1294
diff changeset
147 #if DROPBEAR_CURVE25519
848
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
148 case DROPBEAR_KEX_CURVE25519:
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
149 {
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
150 buffer *ecdh_qs = buf_getstringbuf(ses.payload);
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
151 kexcurve25519_comb_key(cli_ses.curve25519_param, ecdh_qs, hostkey);
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
152 buf_free(ecdh_qs);
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
153 }
1294
56aba7dedbea options for disabling "normal" DH
Matt Johnston <matt@ucc.asn.au>
parents: 1257
diff changeset
154 break;
848
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
155 #endif
26
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
156 }
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
157
801
7dcb46da72d9 merge in HEAD
Matt Johnston <matt@ucc.asn.au>
parents: 765 775
diff changeset
158 if (cli_ses.dh_param) {
7dcb46da72d9 merge in HEAD
Matt Johnston <matt@ucc.asn.au>
parents: 765 775
diff changeset
159 free_kexdh_param(cli_ses.dh_param);
7dcb46da72d9 merge in HEAD
Matt Johnston <matt@ucc.asn.au>
parents: 765 775
diff changeset
160 cli_ses.dh_param = NULL;
7dcb46da72d9 merge in HEAD
Matt Johnston <matt@ucc.asn.au>
parents: 765 775
diff changeset
161 }
1295
750ec4ec4cbe Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents: 1294
diff changeset
162 #if DROPBEAR_ECDH
801
7dcb46da72d9 merge in HEAD
Matt Johnston <matt@ucc.asn.au>
parents: 765 775
diff changeset
163 if (cli_ses.ecdh_param) {
7dcb46da72d9 merge in HEAD
Matt Johnston <matt@ucc.asn.au>
parents: 765 775
diff changeset
164 free_kexecdh_param(cli_ses.ecdh_param);
7dcb46da72d9 merge in HEAD
Matt Johnston <matt@ucc.asn.au>
parents: 765 775
diff changeset
165 cli_ses.ecdh_param = NULL;
7dcb46da72d9 merge in HEAD
Matt Johnston <matt@ucc.asn.au>
parents: 765 775
diff changeset
166 }
7dcb46da72d9 merge in HEAD
Matt Johnston <matt@ucc.asn.au>
parents: 765 775
diff changeset
167 #endif
1295
750ec4ec4cbe Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents: 1294
diff changeset
168 #if DROPBEAR_CURVE25519
848
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
169 if (cli_ses.curve25519_param) {
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
170 free_kexcurve25519_param(cli_ses.curve25519_param);
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
171 cli_ses.curve25519_param = NULL;
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
172 }
6c69e7df3621 curve25519
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
173 #endif
26
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
174
801
7dcb46da72d9 merge in HEAD
Matt Johnston <matt@ucc.asn.au>
parents: 765 775
diff changeset
175 cli_ses.param_kex_algo = NULL;
7dcb46da72d9 merge in HEAD
Matt Johnston <matt@ucc.asn.au>
parents: 765 775
diff changeset
176 if (buf_verify(ses.payload, hostkey, ses.hash) != DROPBEAR_SUCCESS) {
26
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
177 dropbear_exit("Bad hostkey signature");
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
178 }
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
179
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
180 sign_key_free(hostkey);
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
181 hostkey = NULL;
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
182
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
183 send_msg_newkeys();
886
cbc73a5aefb0 requirenext doesn't need two values
Matt Johnston <matt@ucc.asn.au>
parents: 885
diff changeset
184 ses.requirenext = SSH_MSG_NEWKEYS;
165
0cfba3034be5 Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents: 106
diff changeset
185 TRACE(("leave recv_msg_kexdh_init"))
26
0969767bca0d snapshot of stuff
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
186 }
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
187
1459
06d52bcb8094 Pointer parameter could be declared as pointing to const
Francois Perrad <francois.perrad@gadz.org>
parents: 1295
diff changeset
188 static void ask_to_confirm(const unsigned char* keyblob, unsigned int keybloblen,
847
f4bb964c8678 Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
189 const char* algoname) {
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
190
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
191 char* fp = NULL;
170
a62cb364f615 Read "y/n" response for fingerprints from /dev/tty directly so that dbclient
Matt Johnston <matt@ucc.asn.au>
parents: 165
diff changeset
192 FILE *tty = NULL;
1257
8291fc87273e Fix truncated type for getc() at confirmation prompt
Matt Johnston <matt@ucc.asn.au>
parents: 1213
diff changeset
193 int response = 'z';
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
194
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
195 fp = sign_key_fingerprint(keyblob, keybloblen);
418
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
196 if (cli_opts.always_accept_key) {
1213
7fd1211a1f63 Use dropbear_log instead of some fprintf's in client code.
Konstantin Tokarev <ktokarev@smartlabs.tv>
parents: 1124
diff changeset
197 dropbear_log(LOG_INFO, "\nHost '%s' key accepted unconditionally.\n(%s fingerprint %s)\n",
418
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
198 cli_opts.remotehost,
847
f4bb964c8678 Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
199 algoname,
418
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
200 fp);
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
201 m_free(fp);
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
202 return;
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
203 }
847
f4bb964c8678 Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
204 fprintf(stderr, "\nHost '%s' is not in the trusted hosts file.\n(%s fingerprint %s)\nDo you want to continue connecting? (y/n) ",
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
205 cli_opts.remotehost,
847
f4bb964c8678 Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
206 algoname,
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
207 fp);
340
454a34b2dfd1 Fixes from Erik Hovland:
Matt Johnston <matt@ucc.asn.au>
parents: 322
diff changeset
208 m_free(fp);
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
209
170
a62cb364f615 Read "y/n" response for fingerprints from /dev/tty directly so that dbclient
Matt Johnston <matt@ucc.asn.au>
parents: 165
diff changeset
210 tty = fopen(_PATH_TTY, "r");
a62cb364f615 Read "y/n" response for fingerprints from /dev/tty directly so that dbclient
Matt Johnston <matt@ucc.asn.au>
parents: 165
diff changeset
211 if (tty) {
a62cb364f615 Read "y/n" response for fingerprints from /dev/tty directly so that dbclient
Matt Johnston <matt@ucc.asn.au>
parents: 165
diff changeset
212 response = getc(tty);
a62cb364f615 Read "y/n" response for fingerprints from /dev/tty directly so that dbclient
Matt Johnston <matt@ucc.asn.au>
parents: 165
diff changeset
213 fclose(tty);
a62cb364f615 Read "y/n" response for fingerprints from /dev/tty directly so that dbclient
Matt Johnston <matt@ucc.asn.au>
parents: 165
diff changeset
214 } else {
a62cb364f615 Read "y/n" response for fingerprints from /dev/tty directly so that dbclient
Matt Johnston <matt@ucc.asn.au>
parents: 165
diff changeset
215 response = getc(stdin);
a62cb364f615 Read "y/n" response for fingerprints from /dev/tty directly so that dbclient
Matt Johnston <matt@ucc.asn.au>
parents: 165
diff changeset
216 }
a62cb364f615 Read "y/n" response for fingerprints from /dev/tty directly so that dbclient
Matt Johnston <matt@ucc.asn.au>
parents: 165
diff changeset
217
a62cb364f615 Read "y/n" response for fingerprints from /dev/tty directly so that dbclient
Matt Johnston <matt@ucc.asn.au>
parents: 165
diff changeset
218 if (response == 'y') {
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
219 return;
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
220 }
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
221
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
222 dropbear_exit("Didn't validate host key");
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
223 }
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
224
436
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
225 static FILE* open_known_hosts_file(int * readonly)
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
226 {
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
227 FILE * hostsfile = NULL;
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
228 char * filename = NULL;
318
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
229 char * homedir = NULL;
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
230
322
84aa4e60bd3c Look at HOME before /etc/passwd when looking for ~/.ssh/known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 318
diff changeset
231 homedir = getenv("HOME");
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
232
322
84aa4e60bd3c Look at HOME before /etc/passwd when looking for ~/.ssh/known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 318
diff changeset
233 if (!homedir) {
436
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
234 struct passwd * pw = NULL;
322
84aa4e60bd3c Look at HOME before /etc/passwd when looking for ~/.ssh/known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 318
diff changeset
235 pw = getpwuid(getuid());
84aa4e60bd3c Look at HOME before /etc/passwd when looking for ~/.ssh/known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 318
diff changeset
236 if (pw) {
84aa4e60bd3c Look at HOME before /etc/passwd when looking for ~/.ssh/known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 318
diff changeset
237 homedir = pw->pw_dir;
84aa4e60bd3c Look at HOME before /etc/passwd when looking for ~/.ssh/known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 318
diff changeset
238 }
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
239 }
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
240
318
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
241 if (homedir) {
436
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
242 unsigned int len;
318
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
243 len = strlen(homedir);
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
244 filename = m_malloc(len + 18); /* "/.ssh/known_hosts" and null-terminator*/
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
245
318
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
246 snprintf(filename, len+18, "%s/.ssh", homedir);
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
247 /* Check that ~/.ssh exists - easiest way is just to mkdir */
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
248 if (mkdir(filename, S_IRWXU) != 0) {
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
249 if (errno != EEXIST) {
322
84aa4e60bd3c Look at HOME before /etc/passwd when looking for ~/.ssh/known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 318
diff changeset
250 dropbear_log(LOG_INFO, "Warning: failed creating %s/.ssh: %s",
84aa4e60bd3c Look at HOME before /etc/passwd when looking for ~/.ssh/known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 318
diff changeset
251 homedir, strerror(errno));
318
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
252 TRACE(("mkdir didn't work: %s", strerror(errno)))
436
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
253 goto out;
318
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
254 }
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
255 }
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
256
318
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
257 snprintf(filename, len+18, "%s/.ssh/known_hosts", homedir);
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
258 hostsfile = fopen(filename, "a+");
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
259
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
260 if (hostsfile != NULL) {
436
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
261 *readonly = 0;
318
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
262 fseek(hostsfile, 0, SEEK_SET);
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
263 } else {
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
264 /* We mightn't have been able to open it if it was read-only */
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
265 if (errno == EACCES || errno == EROFS) {
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
266 TRACE(("trying readonly: %s", strerror(errno)))
436
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
267 *readonly = 1;
318
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
268 hostsfile = fopen(filename, "r");
9916350d7d8b don't fail fatally if the client can't get homedir from getpwuid(), fallback
Matt Johnston <matt@ucc.asn.au>
parents: 170
diff changeset
269 }
106
e13f8a712a1c Fix if the first write fails
Matt Johnston <matt@ucc.asn.au>
parents: 84
diff changeset
270 }
59
bdc97a5719f4 add new entries to known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 51
diff changeset
271 }
bdc97a5719f4 add new entries to known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 51
diff changeset
272
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
273 if (hostsfile == NULL) {
165
0cfba3034be5 Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents: 106
diff changeset
274 TRACE(("hostsfile didn't open: %s", strerror(errno)))
322
84aa4e60bd3c Look at HOME before /etc/passwd when looking for ~/.ssh/known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 318
diff changeset
275 dropbear_log(LOG_WARNING, "Failed to open %s/.ssh/known_hosts",
84aa4e60bd3c Look at HOME before /etc/passwd when looking for ~/.ssh/known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 318
diff changeset
276 homedir);
436
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
277 goto out;
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
278 }
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
279
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
280 out:
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
281 m_free(filename);
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
282 return hostsfile;
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
283 }
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
284
1459
06d52bcb8094 Pointer parameter could be declared as pointing to const
Francois Perrad <francois.perrad@gadz.org>
parents: 1295
diff changeset
285 static void checkhostkey(const unsigned char* keyblob, unsigned int keybloblen) {
436
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
286
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
287 FILE *hostsfile = NULL;
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
288 int readonly = 0;
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
289 unsigned int hostlen, algolen;
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
290 unsigned long len;
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
291 const char *algoname = NULL;
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
292 char * fingerprint = NULL;
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
293 buffer * line = NULL;
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
294 int ret;
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
295
772
7fc0aeada79c -y -y to disable hostkey checking
Matt Johnston <matt@ucc.asn.au>
parents: 568
diff changeset
296 if (cli_opts.no_hostkey_check) {
1213
7fd1211a1f63 Use dropbear_log instead of some fprintf's in client code.
Konstantin Tokarev <ktokarev@smartlabs.tv>
parents: 1124
diff changeset
297 dropbear_log(LOG_INFO, "Caution, skipping hostkey check for %s\n", cli_opts.remotehost);
772
7fc0aeada79c -y -y to disable hostkey checking
Matt Johnston <matt@ucc.asn.au>
parents: 568
diff changeset
298 return;
7fc0aeada79c -y -y to disable hostkey checking
Matt Johnston <matt@ucc.asn.au>
parents: 568
diff changeset
299 }
7fc0aeada79c -y -y to disable hostkey checking
Matt Johnston <matt@ucc.asn.au>
parents: 568
diff changeset
300
847
f4bb964c8678 Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
301 algoname = signkey_name_from_type(ses.newkeys->algo_hostkey, &algolen);
f4bb964c8678 Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
302
436
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
303 hostsfile = open_known_hosts_file(&readonly);
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
304 if (!hostsfile) {
847
f4bb964c8678 Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
305 ask_to_confirm(keyblob, keybloblen, algoname);
436
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
306 /* ask_to_confirm will exit upon failure */
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
307 return;
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
308 }
436
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
309
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
310 line = buf_new(MAX_KNOWNHOSTS_LINE);
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
311 hostlen = strlen(cli_opts.remotehost);
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
312
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
313 do {
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
314 if (buf_getline(line, hostsfile) == DROPBEAR_FAILURE) {
165
0cfba3034be5 Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents: 106
diff changeset
315 TRACE(("failed reading line: prob EOF"))
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
316 break;
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
317 }
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
318
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
319 /* The line is too short to be sensible */
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
320 /* "30" is 'enough to hold ssh-dss plus the spaces, ie so we don't
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
321 * buf_getfoo() past the end and die horribly - the base64 parsing
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
322 * code is what tiptoes up to the end nicely */
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
323 if (line->len < (hostlen+30) ) {
165
0cfba3034be5 Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents: 106
diff changeset
324 TRACE(("line is too short to be sensible"))
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
325 continue;
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
326 }
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
327
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
328 /* Compare hostnames */
1094
c45d65392c1a Fix pointer differ in signess warnings [-Werror=pointer-sign]
Gaël PORTAY <gael.portay@gmail.com>
parents: 886
diff changeset
329 if (strncmp(cli_opts.remotehost, (const char *) buf_getptr(line, hostlen),
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
330 hostlen) != 0) {
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
331 continue;
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
332 }
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
333
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
334 buf_incrpos(line, hostlen);
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
335 if (buf_getbyte(line) != ' ') {
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
336 /* there wasn't a space after the hostname, something dodgy */
165
0cfba3034be5 Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents: 106
diff changeset
337 TRACE(("missing space afte matching hostname"))
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
338 continue;
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
339 }
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
340
1094
c45d65392c1a Fix pointer differ in signess warnings [-Werror=pointer-sign]
Gaël PORTAY <gael.portay@gmail.com>
parents: 886
diff changeset
341 if (strncmp((const char *) buf_getptr(line, algolen), algoname, algolen) != 0) {
165
0cfba3034be5 Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents: 106
diff changeset
342 TRACE(("algo doesn't match"))
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
343 continue;
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
344 }
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
345
59
bdc97a5719f4 add new entries to known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 51
diff changeset
346 buf_incrpos(line, algolen);
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
347 if (buf_getbyte(line) != ' ') {
165
0cfba3034be5 Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents: 106
diff changeset
348 TRACE(("missing space after algo"))
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
349 continue;
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
350 }
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
351
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
352 /* Now we're at the interesting hostkey */
1094
c45d65392c1a Fix pointer differ in signess warnings [-Werror=pointer-sign]
Gaël PORTAY <gael.portay@gmail.com>
parents: 886
diff changeset
353 ret = cmp_base64_key(keyblob, keybloblen, (const unsigned char *) algoname, algolen,
436
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
354 line, &fingerprint);
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
355
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
356 if (ret == DROPBEAR_SUCCESS) {
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
357 /* Good matching key */
165
0cfba3034be5 Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents: 106
diff changeset
358 TRACE(("good matching key"))
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
359 goto out;
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
360 }
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
361
436
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
362 /* The keys didn't match. eep. Note that we're "leaking"
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
363 the fingerprint strings here, but we're exiting anyway */
847
f4bb964c8678 Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
364 dropbear_exit("\n\n%s host key mismatch for %s !\n"
436
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
365 "Fingerprint is %s\n"
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
366 "Expected %s\n"
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
367 "If you know that the host key is correct you can\nremove the bad entry from ~/.ssh/known_hosts",
847
f4bb964c8678 Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
368 algoname,
436
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
369 cli_opts.remotehost,
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
370 sign_key_fingerprint(keyblob, keybloblen),
7282370416a0 Improve known_hosts checking.
Matt Johnston <matt@ucc.asn.au>
parents: 418
diff changeset
371 fingerprint ? fingerprint : "UNKNOWN");
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
372 } while (1); /* keep going 'til something happens */
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
373
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
374 /* Key doesn't exist yet */
847
f4bb964c8678 Add '-R' for delayed hostkey option
Matt Johnston <matt@ucc.asn.au>
parents: 801
diff changeset
375 ask_to_confirm(keyblob, keybloblen, algoname);
59
bdc97a5719f4 add new entries to known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 51
diff changeset
376
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
377 /* If we get here, they said yes */
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
378
59
bdc97a5719f4 add new entries to known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 51
diff changeset
379 if (readonly) {
165
0cfba3034be5 Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents: 106
diff changeset
380 TRACE(("readonly"))
59
bdc97a5719f4 add new entries to known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 51
diff changeset
381 goto out;
bdc97a5719f4 add new entries to known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 51
diff changeset
382 }
bdc97a5719f4 add new entries to known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 51
diff changeset
383
418
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
384 if (!cli_opts.always_accept_key) {
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
385 /* put the new entry in the file */
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
386 fseek(hostsfile, 0, SEEK_END); /* In case it wasn't opened append */
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
387 buf_setpos(line, 0);
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
388 buf_setlen(line, 0);
1094
c45d65392c1a Fix pointer differ in signess warnings [-Werror=pointer-sign]
Gaël PORTAY <gael.portay@gmail.com>
parents: 886
diff changeset
389 buf_putbytes(line, (const unsigned char *) cli_opts.remotehost, hostlen);
418
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
390 buf_putbyte(line, ' ');
1094
c45d65392c1a Fix pointer differ in signess warnings [-Werror=pointer-sign]
Gaël PORTAY <gael.portay@gmail.com>
parents: 886
diff changeset
391 buf_putbytes(line, (const unsigned char *) algoname, algolen);
418
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
392 buf_putbyte(line, ' ');
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
393 len = line->size - line->pos;
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
394 /* The only failure with base64 is buffer_overflow, but buf_getwriteptr
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
395 * will die horribly in the case anyway */
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
396 base64_encode(keyblob, keybloblen, buf_getwriteptr(line, len), &len);
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
397 buf_incrwritepos(line, len);
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
398 buf_putbyte(line, '\n');
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
399 buf_setpos(line, 0);
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
400 fwrite(buf_getptr(line, line->len), line->len, 1, hostsfile);
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
401 /* We ignore errors, since there's not much we can do about them */
ab57ba0cb667 Add '-y' option to dbclient to accept the host key without checking
Matt Johnston <matt@ucc.asn.au>
parents: 340
diff changeset
402 }
59
bdc97a5719f4 add new entries to known_hosts
Matt Johnston <matt@ucc.asn.au>
parents: 51
diff changeset
403
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
404 out:
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
405 if (hostsfile != NULL) {
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
406 fclose(hostsfile);
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
407 }
79
5a55bd66707f - don't crash when trying to add to known_hosts if it doesn't exist
Matt Johnston <matt@ucc.asn.au>
parents: 74
diff changeset
408 if (line != NULL) {
5a55bd66707f - don't crash when trying to add to known_hosts if it doesn't exist
Matt Johnston <matt@ucc.asn.au>
parents: 74
diff changeset
409 buf_free(line);
5a55bd66707f - don't crash when trying to add to known_hosts if it doesn't exist
Matt Johnston <matt@ucc.asn.au>
parents: 74
diff changeset
410 }
544
9e51707cd6f2 - Make -i and -W pass through multihop arguments
Matt Johnston <matt@ucc.asn.au>
parents: 440
diff changeset
411 m_free(fingerprint);
51
095d689fed16 - Hostkey checking is mostly there, just aren't appending yet.
Matt Johnston <matt@ucc.asn.au>
parents: 34
diff changeset
412 }