summaryrefslogtreecommitdiff
path: root/ssh-keyscan.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-keyscan.c')
-rw-r--r--ssh-keyscan.c129
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
55int ssh_port = SSH_DEFAULT_PORT; 54int 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
63int get_cert = 0; 64int get_cert = 0;
64int get_keytypes = KT_RSA|KT_ECDSA|KT_ED25519; 65int 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
191static struct sshkey *
192keygrab_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
237static int 192static int
238key_print_wrapper(struct sshkey *hostkey, struct ssh *ssh) 193key_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
323static void 277static 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
561static void 505static 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;