diff options
author | Colin Watson <cjwatson@debian.org> | 2017-10-04 11:23:58 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2017-10-04 11:23:58 +0100 |
commit | 62f54f20bf351468e0124f63cc2902ee40d9b0e9 (patch) | |
tree | 3e090f2711b94ca5029d3fa3e8047b1ed1448b1f /ssh-keyscan.c | |
parent | 6fabaf6fd9b07cc8bc6a17c9c4a5b76849cfc874 (diff) | |
parent | 66bf74a92131b7effe49fb0eefe5225151869dc5 (diff) |
Import openssh_7.6p1.orig.tar.gz
Diffstat (limited to 'ssh-keyscan.c')
-rw-r--r-- | ssh-keyscan.c | 129 |
1 files changed, 31 insertions, 98 deletions
diff --git a/ssh-keyscan.c b/ssh-keyscan.c index 1f95239a3..258123ae8 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keyscan.c,v 1.109 2017/03/10 04:26:06 djm Exp $ */ | 1 | /* $OpenBSD: ssh-keyscan.c,v 1.115 2017/06/30 04:17:23 dtucker Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. | 3 | * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. |
4 | * | 4 | * |
@@ -32,7 +32,6 @@ | |||
32 | 32 | ||
33 | #include "xmalloc.h" | 33 | #include "xmalloc.h" |
34 | #include "ssh.h" | 34 | #include "ssh.h" |
35 | #include "ssh1.h" | ||
36 | #include "sshbuf.h" | 35 | #include "sshbuf.h" |
37 | #include "sshkey.h" | 36 | #include "sshkey.h" |
38 | #include "cipher.h" | 37 | #include "cipher.h" |
@@ -54,11 +53,13 @@ int IPv4or6 = AF_UNSPEC; | |||
54 | 53 | ||
55 | int ssh_port = SSH_DEFAULT_PORT; | 54 | int ssh_port = SSH_DEFAULT_PORT; |
56 | 55 | ||
57 | #define KT_RSA1 1 | 56 | #define KT_DSA (1) |
58 | #define KT_DSA 2 | 57 | #define KT_RSA (1<<1) |
59 | #define KT_RSA 4 | 58 | #define KT_ECDSA (1<<2) |
60 | #define KT_ECDSA 8 | 59 | #define KT_ED25519 (1<<3) |
61 | #define KT_ED25519 16 | 60 | |
61 | #define KT_MIN KT_DSA | ||
62 | #define KT_MAX KT_ED25519 | ||
62 | 63 | ||
63 | int get_cert = 0; | 64 | int get_cert = 0; |
64 | int get_keytypes = KT_RSA|KT_ECDSA|KT_ED25519; | 65 | int get_keytypes = KT_RSA|KT_ECDSA|KT_ED25519; |
@@ -94,7 +95,7 @@ typedef struct Connection { | |||
94 | int c_plen; /* Packet length field for ssh packet */ | 95 | int c_plen; /* Packet length field for ssh packet */ |
95 | int c_len; /* Total bytes which must be read. */ | 96 | int c_len; /* Total bytes which must be read. */ |
96 | int c_off; /* Length of data read so far. */ | 97 | int c_off; /* Length of data read so far. */ |
97 | int c_keytype; /* Only one of KT_RSA1, KT_DSA, or KT_RSA */ | 98 | int c_keytype; /* Only one of KT_* */ |
98 | sig_atomic_t c_done; /* SSH2 done */ | 99 | sig_atomic_t c_done; /* SSH2 done */ |
99 | char *c_namebase; /* Address to free for c_name and c_namelist */ | 100 | char *c_namebase; /* Address to free for c_name and c_namelist */ |
100 | char *c_name; /* Hostname of connection for errors */ | 101 | char *c_name; /* Hostname of connection for errors */ |
@@ -187,52 +188,6 @@ strnnsep(char **stringp, char *delim) | |||
187 | return (tok); | 188 | return (tok); |
188 | } | 189 | } |
189 | 190 | ||
190 | #ifdef WITH_SSH1 | ||
191 | static struct sshkey * | ||
192 | keygrab_ssh1(con *c) | ||
193 | { | ||
194 | static struct sshkey *rsa; | ||
195 | static struct sshbuf *msg; | ||
196 | int r; | ||
197 | u_char type; | ||
198 | |||
199 | if (rsa == NULL) { | ||
200 | if ((rsa = sshkey_new(KEY_RSA1)) == NULL) { | ||
201 | error("%s: sshkey_new failed", __func__); | ||
202 | return NULL; | ||
203 | } | ||
204 | if ((msg = sshbuf_new()) == NULL) | ||
205 | fatal("%s: sshbuf_new failed", __func__); | ||
206 | } | ||
207 | if ((r = sshbuf_put(msg, c->c_data, c->c_plen)) != 0 || | ||
208 | (r = sshbuf_consume(msg, 8 - (c->c_plen & 7))) != 0 || /* padding */ | ||
209 | (r = sshbuf_get_u8(msg, &type)) != 0) | ||
210 | goto buf_err; | ||
211 | if (type != (int) SSH_SMSG_PUBLIC_KEY) { | ||
212 | error("%s: invalid packet type", c->c_name); | ||
213 | sshbuf_reset(msg); | ||
214 | return NULL; | ||
215 | } | ||
216 | if ((r = sshbuf_consume(msg, 8)) != 0 || /* cookie */ | ||
217 | /* server key */ | ||
218 | (r = sshbuf_get_u32(msg, NULL)) != 0 || | ||
219 | (r = sshbuf_get_bignum1(msg, NULL)) != 0 || | ||
220 | (r = sshbuf_get_bignum1(msg, NULL)) != 0 || | ||
221 | /* host key */ | ||
222 | (r = sshbuf_get_u32(msg, NULL)) != 0 || | ||
223 | (r = sshbuf_get_bignum1(msg, rsa->rsa->e)) != 0 || | ||
224 | (r = sshbuf_get_bignum1(msg, rsa->rsa->n)) != 0) { | ||
225 | buf_err: | ||
226 | error("%s: buffer error: %s", __func__, ssh_err(r)); | ||
227 | sshbuf_reset(msg); | ||
228 | return NULL; | ||
229 | } | ||
230 | |||
231 | sshbuf_reset(msg); | ||
232 | |||
233 | return (rsa); | ||
234 | } | ||
235 | #endif | ||
236 | 191 | ||
237 | static int | 192 | static int |
238 | key_print_wrapper(struct sshkey *hostkey, struct ssh *ssh) | 193 | key_print_wrapper(struct sshkey *hostkey, struct ssh *ssh) |
@@ -267,7 +222,6 @@ keygrab_ssh2(con *c) | |||
267 | char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; | 222 | char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; |
268 | int r; | 223 | int r; |
269 | 224 | ||
270 | enable_compat20(); | ||
271 | switch (c->c_keytype) { | 225 | switch (c->c_keytype) { |
272 | case KT_DSA: | 226 | case KT_DSA: |
273 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? | 227 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? |
@@ -317,7 +271,7 @@ keygrab_ssh2(con *c) | |||
317 | * do the key-exchange until an error occurs or until | 271 | * do the key-exchange until an error occurs or until |
318 | * the key_print_wrapper() callback sets c_done. | 272 | * the key_print_wrapper() callback sets c_done. |
319 | */ | 273 | */ |
320 | ssh_dispatch_run(c->c_ssh, DISPATCH_BLOCK, &c->c_done, c->c_ssh); | 274 | ssh_dispatch_run(c->c_ssh, DISPATCH_BLOCK, &c->c_done); |
321 | } | 275 | } |
322 | 276 | ||
323 | static void | 277 | static void |
@@ -436,7 +390,6 @@ confree(int s) | |||
436 | { | 390 | { |
437 | if (s >= maxfd || fdcon[s].c_status == CS_UNUSED) | 391 | if (s >= maxfd || fdcon[s].c_status == CS_UNUSED) |
438 | fatal("confree: attempt to free bad fdno %d", s); | 392 | fatal("confree: attempt to free bad fdno %d", s); |
439 | close(s); | ||
440 | free(fdcon[s].c_namebase); | 393 | free(fdcon[s].c_namebase); |
441 | free(fdcon[s].c_output_name); | 394 | free(fdcon[s].c_output_name); |
442 | if (fdcon[s].c_status == CS_KEYS) | 395 | if (fdcon[s].c_status == CS_KEYS) |
@@ -447,7 +400,8 @@ confree(int s) | |||
447 | ssh_packet_close(fdcon[s].c_ssh); | 400 | ssh_packet_close(fdcon[s].c_ssh); |
448 | free(fdcon[s].c_ssh); | 401 | free(fdcon[s].c_ssh); |
449 | fdcon[s].c_ssh = NULL; | 402 | fdcon[s].c_ssh = NULL; |
450 | } | 403 | } else |
404 | close(s); | ||
451 | TAILQ_REMOVE(&tq, &fdcon[s], c_link); | 405 | TAILQ_REMOVE(&tq, &fdcon[s], c_link); |
452 | FD_CLR(s, read_wait); | 406 | FD_CLR(s, read_wait); |
453 | ncon--; | 407 | ncon--; |
@@ -482,6 +436,20 @@ congreet(int s) | |||
482 | size_t bufsiz; | 436 | size_t bufsiz; |
483 | con *c = &fdcon[s]; | 437 | con *c = &fdcon[s]; |
484 | 438 | ||
439 | /* send client banner */ | ||
440 | n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n", | ||
441 | PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2); | ||
442 | if (n < 0 || (size_t)n >= sizeof(buf)) { | ||
443 | error("snprintf: buffer too small"); | ||
444 | confree(s); | ||
445 | return; | ||
446 | } | ||
447 | if (atomicio(vwrite, s, buf, n) != (size_t)n) { | ||
448 | error("write (%s): %s", c->c_name, strerror(errno)); | ||
449 | confree(s); | ||
450 | return; | ||
451 | } | ||
452 | |||
485 | for (;;) { | 453 | for (;;) { |
486 | memset(buf, '\0', sizeof(buf)); | 454 | memset(buf, '\0', sizeof(buf)); |
487 | bufsiz = sizeof(buf); | 455 | bufsiz = sizeof(buf); |
@@ -524,38 +492,14 @@ congreet(int s) | |||
524 | c->c_ssh->compat = compat_datafellows(remote_version); | 492 | c->c_ssh->compat = compat_datafellows(remote_version); |
525 | else | 493 | else |
526 | c->c_ssh->compat = 0; | 494 | c->c_ssh->compat = 0; |
527 | if (c->c_keytype != KT_RSA1) { | 495 | if (!ssh2_capable(remote_major, remote_minor)) { |
528 | if (!ssh2_capable(remote_major, remote_minor)) { | 496 | debug("%s doesn't support ssh2", c->c_name); |
529 | debug("%s doesn't support ssh2", c->c_name); | ||
530 | confree(s); | ||
531 | return; | ||
532 | } | ||
533 | } else if (remote_major != 1) { | ||
534 | debug("%s doesn't support ssh1", c->c_name); | ||
535 | confree(s); | 497 | confree(s); |
536 | return; | 498 | return; |
537 | } | 499 | } |
538 | fprintf(stderr, "# %s:%d %s\n", c->c_name, ssh_port, chop(buf)); | 500 | fprintf(stderr, "# %s:%d %s\n", c->c_name, ssh_port, chop(buf)); |
539 | n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n", | 501 | keygrab_ssh2(c); |
540 | c->c_keytype == KT_RSA1? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2, | 502 | confree(s); |
541 | c->c_keytype == KT_RSA1? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2); | ||
542 | if (n < 0 || (size_t)n >= sizeof(buf)) { | ||
543 | error("snprintf: buffer too small"); | ||
544 | confree(s); | ||
545 | return; | ||
546 | } | ||
547 | if (atomicio(vwrite, s, buf, n) != (size_t)n) { | ||
548 | error("write (%s): %s", c->c_name, strerror(errno)); | ||
549 | confree(s); | ||
550 | return; | ||
551 | } | ||
552 | if (c->c_keytype != KT_RSA1) { | ||
553 | keygrab_ssh2(c); | ||
554 | confree(s); | ||
555 | return; | ||
556 | } | ||
557 | c->c_status = CS_SIZE; | ||
558 | contouch(s); | ||
559 | } | 503 | } |
560 | 504 | ||
561 | static void | 505 | static void |
@@ -585,12 +529,6 @@ conread(int s) | |||
585 | c->c_data = xmalloc(c->c_len); | 529 | c->c_data = xmalloc(c->c_len); |
586 | c->c_status = CS_KEYS; | 530 | c->c_status = CS_KEYS; |
587 | break; | 531 | break; |
588 | #ifdef WITH_SSH1 | ||
589 | case CS_KEYS: | ||
590 | keyprint(c, keygrab_ssh1(c)); | ||
591 | confree(s); | ||
592 | return; | ||
593 | #endif | ||
594 | default: | 532 | default: |
595 | fatal("conread: invalid status %d", c->c_status); | 533 | fatal("conread: invalid status %d", c->c_status); |
596 | break; | 534 | break; |
@@ -659,7 +597,7 @@ do_host(char *host) | |||
659 | 597 | ||
660 | if (name == NULL) | 598 | if (name == NULL) |
661 | return; | 599 | return; |
662 | for (j = KT_RSA1; j <= KT_ED25519; j *= 2) { | 600 | for (j = KT_MIN; j <= KT_MAX; j *= 2) { |
663 | if (get_keytypes & j) { | 601 | if (get_keytypes & j) { |
664 | while (ncon >= MAXCON) | 602 | while (ncon >= MAXCON) |
665 | conloop(); | 603 | conloop(); |
@@ -756,11 +694,6 @@ main(int argc, char **argv) | |||
756 | int type = sshkey_type_from_name(tname); | 694 | int type = sshkey_type_from_name(tname); |
757 | 695 | ||
758 | switch (type) { | 696 | switch (type) { |
759 | #ifdef WITH_SSH1 | ||
760 | case KEY_RSA1: | ||
761 | get_keytypes |= KT_RSA1; | ||
762 | break; | ||
763 | #endif | ||
764 | case KEY_DSA: | 697 | case KEY_DSA: |
765 | get_keytypes |= KT_DSA; | 698 | get_keytypes |= KT_DSA; |
766 | break; | 699 | break; |