Mercurial > dropbear
comparison cli-kex.c @ 165:0cfba3034be5
Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 02 Jan 2005 20:25:56 +0000 |
parents | e13f8a712a1c |
children | a62cb364f615 |
comparison
equal
deleted
inserted
replaced
161:b9d3f725e00b | 165:0cfba3034be5 |
---|---|
63 sign_key *hostkey = NULL; | 63 sign_key *hostkey = NULL; |
64 unsigned int type, keybloblen; | 64 unsigned int type, keybloblen; |
65 unsigned char* keyblob = NULL; | 65 unsigned char* keyblob = NULL; |
66 | 66 |
67 | 67 |
68 TRACE(("enter recv_msg_kexdh_reply")); | 68 TRACE(("enter recv_msg_kexdh_reply")) |
69 | 69 |
70 if (cli_ses.kex_state != KEXDH_INIT_SENT) { | 70 if (cli_ses.kex_state != KEXDH_INIT_SENT) { |
71 dropbear_exit("Received out-of-order kexdhreply"); | 71 dropbear_exit("Received out-of-order kexdhreply"); |
72 } | 72 } |
73 m_mp_init(&dh_f); | 73 m_mp_init(&dh_f); |
74 type = ses.newkeys->algo_hostkey; | 74 type = ses.newkeys->algo_hostkey; |
75 TRACE(("type is %d", type)); | 75 TRACE(("type is %d", type)) |
76 | 76 |
77 hostkey = new_sign_key(); | 77 hostkey = new_sign_key(); |
78 keybloblen = buf_getint(ses.payload); | 78 keybloblen = buf_getint(ses.payload); |
79 | 79 |
80 keyblob = buf_getptr(ses.payload, keybloblen); | 80 keyblob = buf_getptr(ses.payload, keybloblen); |
82 /* Only makes sense the first time */ | 82 /* Only makes sense the first time */ |
83 checkhostkey(keyblob, keybloblen); | 83 checkhostkey(keyblob, keybloblen); |
84 } | 84 } |
85 | 85 |
86 if (buf_get_pub_key(ses.payload, hostkey, &type) != DROPBEAR_SUCCESS) { | 86 if (buf_get_pub_key(ses.payload, hostkey, &type) != DROPBEAR_SUCCESS) { |
87 TRACE(("failed getting pubkey")); | 87 TRACE(("failed getting pubkey")) |
88 dropbear_exit("Bad KEX packet"); | 88 dropbear_exit("Bad KEX packet"); |
89 } | 89 } |
90 | 90 |
91 if (buf_getmpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) { | 91 if (buf_getmpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) { |
92 TRACE(("failed getting mpint")); | 92 TRACE(("failed getting mpint")) |
93 dropbear_exit("Bad KEX packet"); | 93 dropbear_exit("Bad KEX packet"); |
94 } | 94 } |
95 | 95 |
96 kexdh_comb_key(cli_ses.dh_e, cli_ses.dh_x, &dh_f, hostkey); | 96 kexdh_comb_key(cli_ses.dh_e, cli_ses.dh_x, &dh_f, hostkey); |
97 mp_clear(&dh_f); | 97 mp_clear(&dh_f); |
107 sign_key_free(hostkey); | 107 sign_key_free(hostkey); |
108 hostkey = NULL; | 108 hostkey = NULL; |
109 | 109 |
110 send_msg_newkeys(); | 110 send_msg_newkeys(); |
111 ses.requirenext = SSH_MSG_NEWKEYS; | 111 ses.requirenext = SSH_MSG_NEWKEYS; |
112 TRACE(("leave recv_msg_kexdh_init")); | 112 TRACE(("leave recv_msg_kexdh_init")) |
113 } | 113 } |
114 | 114 |
115 static void ask_to_confirm(unsigned char* keyblob, unsigned int keybloblen) { | 115 static void ask_to_confirm(unsigned char* keyblob, unsigned int keybloblen) { |
116 | 116 |
117 char* fp = NULL; | 117 char* fp = NULL; |
154 /* Check that ~/.ssh exists - easiest way is just to mkdir */ | 154 /* Check that ~/.ssh exists - easiest way is just to mkdir */ |
155 if (mkdir(filename, S_IRWXU) != 0) { | 155 if (mkdir(filename, S_IRWXU) != 0) { |
156 if (errno != EEXIST) { | 156 if (errno != EEXIST) { |
157 dropbear_log(LOG_INFO, "Warning: failed creating ~/.ssh: %s", | 157 dropbear_log(LOG_INFO, "Warning: failed creating ~/.ssh: %s", |
158 strerror(errno)); | 158 strerror(errno)); |
159 TRACE(("mkdir didn't work: %s", strerror(errno))); | 159 TRACE(("mkdir didn't work: %s", strerror(errno))) |
160 ask_to_confirm(keyblob, keybloblen); | 160 ask_to_confirm(keyblob, keybloblen); |
161 goto out; /* only get here on success */ | 161 goto out; /* only get here on success */ |
162 } | 162 } |
163 } | 163 } |
164 | 164 |
168 if (hostsfile != NULL) { | 168 if (hostsfile != NULL) { |
169 fseek(hostsfile, 0, SEEK_SET); | 169 fseek(hostsfile, 0, SEEK_SET); |
170 } else { | 170 } else { |
171 /* We mightn't have been able to open it if it was read-only */ | 171 /* We mightn't have been able to open it if it was read-only */ |
172 if (errno == EACCES || errno == EROFS) { | 172 if (errno == EACCES || errno == EROFS) { |
173 TRACE(("trying readonly: %s", strerror(errno))); | 173 TRACE(("trying readonly: %s", strerror(errno))) |
174 readonly = 1; | 174 readonly = 1; |
175 hostsfile = fopen(filename, "r"); | 175 hostsfile = fopen(filename, "r"); |
176 } | 176 } |
177 } | 177 } |
178 | 178 |
179 if (hostsfile == NULL) { | 179 if (hostsfile == NULL) { |
180 TRACE(("hostsfile didn't open: %s", strerror(errno))); | 180 TRACE(("hostsfile didn't open: %s", strerror(errno))) |
181 ask_to_confirm(keyblob, keybloblen); | 181 ask_to_confirm(keyblob, keybloblen); |
182 goto out; /* We only get here on success */ | 182 goto out; /* We only get here on success */ |
183 } | 183 } |
184 | 184 |
185 line = buf_new(MAX_KNOWNHOSTS_LINE); | 185 line = buf_new(MAX_KNOWNHOSTS_LINE); |
186 hostlen = strlen(cli_opts.remotehost); | 186 hostlen = strlen(cli_opts.remotehost); |
187 algoname = signkey_name_from_type(ses.newkeys->algo_hostkey, &algolen); | 187 algoname = signkey_name_from_type(ses.newkeys->algo_hostkey, &algolen); |
188 | 188 |
189 do { | 189 do { |
190 if (buf_getline(line, hostsfile) == DROPBEAR_FAILURE) { | 190 if (buf_getline(line, hostsfile) == DROPBEAR_FAILURE) { |
191 TRACE(("failed reading line: prob EOF")); | 191 TRACE(("failed reading line: prob EOF")) |
192 break; | 192 break; |
193 } | 193 } |
194 | 194 |
195 /* The line is too short to be sensible */ | 195 /* The line is too short to be sensible */ |
196 /* "30" is 'enough to hold ssh-dss plus the spaces, ie so we don't | 196 /* "30" is 'enough to hold ssh-dss plus the spaces, ie so we don't |
197 * buf_getfoo() past the end and die horribly - the base64 parsing | 197 * buf_getfoo() past the end and die horribly - the base64 parsing |
198 * code is what tiptoes up to the end nicely */ | 198 * code is what tiptoes up to the end nicely */ |
199 if (line->len < (hostlen+30) ) { | 199 if (line->len < (hostlen+30) ) { |
200 TRACE(("line is too short to be sensible")); | 200 TRACE(("line is too short to be sensible")) |
201 continue; | 201 continue; |
202 } | 202 } |
203 | 203 |
204 /* Compare hostnames */ | 204 /* Compare hostnames */ |
205 if (strncmp(cli_opts.remotehost, buf_getptr(line, hostlen), | 205 if (strncmp(cli_opts.remotehost, buf_getptr(line, hostlen), |
206 hostlen) != 0) { | 206 hostlen) != 0) { |
207 TRACE(("hosts don't match")); | 207 TRACE(("hosts don't match")) |
208 continue; | 208 continue; |
209 } | 209 } |
210 | 210 |
211 buf_incrpos(line, hostlen); | 211 buf_incrpos(line, hostlen); |
212 if (buf_getbyte(line) != ' ') { | 212 if (buf_getbyte(line) != ' ') { |
213 /* there wasn't a space after the hostname, something dodgy */ | 213 /* there wasn't a space after the hostname, something dodgy */ |
214 TRACE(("missing space afte matching hostname")); | 214 TRACE(("missing space afte matching hostname")) |
215 continue; | 215 continue; |
216 } | 216 } |
217 | 217 |
218 if ( strncmp(buf_getptr(line, algolen), algoname, algolen) != 0) { | 218 if ( strncmp(buf_getptr(line, algolen), algoname, algolen) != 0) { |
219 TRACE(("algo doesn't match")); | 219 TRACE(("algo doesn't match")) |
220 continue; | 220 continue; |
221 } | 221 } |
222 | 222 |
223 buf_incrpos(line, algolen); | 223 buf_incrpos(line, algolen); |
224 if (buf_getbyte(line) != ' ') { | 224 if (buf_getbyte(line) != ' ') { |
225 TRACE(("missing space after algo")); | 225 TRACE(("missing space after algo")) |
226 continue; | 226 continue; |
227 } | 227 } |
228 | 228 |
229 /* Now we're at the interesting hostkey */ | 229 /* Now we're at the interesting hostkey */ |
230 ret = cmp_base64_key(keyblob, keybloblen, algoname, algolen, line); | 230 ret = cmp_base64_key(keyblob, keybloblen, algoname, algolen, line); |
231 | 231 |
232 if (ret == DROPBEAR_SUCCESS) { | 232 if (ret == DROPBEAR_SUCCESS) { |
233 /* Good matching key */ | 233 /* Good matching key */ |
234 TRACE(("good matching key")); | 234 TRACE(("good matching key")) |
235 goto out; | 235 goto out; |
236 } | 236 } |
237 | 237 |
238 /* The keys didn't match. eep. */ | 238 /* The keys didn't match. eep. */ |
239 } while (1); /* keep going 'til something happens */ | 239 } while (1); /* keep going 'til something happens */ |
242 ask_to_confirm(keyblob, keybloblen); | 242 ask_to_confirm(keyblob, keybloblen); |
243 | 243 |
244 /* If we get here, they said yes */ | 244 /* If we get here, they said yes */ |
245 | 245 |
246 if (readonly) { | 246 if (readonly) { |
247 TRACE(("readonly")); | 247 TRACE(("readonly")) |
248 goto out; | 248 goto out; |
249 } | 249 } |
250 | 250 |
251 /* put the new entry in the file */ | 251 /* put the new entry in the file */ |
252 fseek(hostsfile, 0, SEEK_END); /* In case it wasn't opened append */ | 252 fseek(hostsfile, 0, SEEK_END); /* In case it wasn't opened append */ |
255 buf_putbytes(line, ses.remotehost, hostlen); | 255 buf_putbytes(line, ses.remotehost, hostlen); |
256 buf_putbyte(line, ' '); | 256 buf_putbyte(line, ' '); |
257 buf_putbytes(line, algoname, algolen); | 257 buf_putbytes(line, algoname, algolen); |
258 buf_putbyte(line, ' '); | 258 buf_putbyte(line, ' '); |
259 len = line->size - line->pos; | 259 len = line->size - line->pos; |
260 TRACE(("keybloblen %d, len %d", keybloblen, len)); | 260 TRACE(("keybloblen %d, len %d", keybloblen, len)) |
261 /* The only failure with base64 is buffer_overflow, but buf_getwriteptr | 261 /* The only failure with base64 is buffer_overflow, but buf_getwriteptr |
262 * will die horribly in the case anyway */ | 262 * will die horribly in the case anyway */ |
263 base64_encode(keyblob, keybloblen, buf_getwriteptr(line, len), &len); | 263 base64_encode(keyblob, keybloblen, buf_getwriteptr(line, len), &len); |
264 buf_incrwritepos(line, len); | 264 buf_incrwritepos(line, len); |
265 buf_putbyte(line, '\n'); | 265 buf_putbyte(line, '\n'); |