X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/blobdiff_plain/12a403af2e464fc8b8d95db93167b0b6d4cb15e7..944e4e582be802144f889cadee3077f1a2b8b950:/openssh/ssh-keyscan.c diff --git a/openssh/ssh-keyscan.c b/openssh/ssh-keyscan.c index 266b23c..6915102 100644 --- a/openssh/ssh-keyscan.c +++ b/openssh/ssh-keyscan.c @@ -7,7 +7,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-keyscan.c,v 1.47 2004/03/08 09:38:05 djm Exp $"); +RCSID("$OpenBSD: ssh-keyscan.c,v 1.57 2005/10/30 04:01:03 djm Exp $"); #include "openbsd-compat/sys-queue.h" @@ -28,6 +28,7 @@ RCSID("$OpenBSD: ssh-keyscan.c,v 1.47 2004/03/08 09:38:05 djm Exp $"); #include "log.h" #include "atomicio.h" #include "misc.h" +#include "hostfile.h" /* Flag indicating whether IPv4 or IPv6. This can be set on the command line. Default value is AF_UNSPEC means both IPv4 and IPv6. */ @@ -41,6 +42,8 @@ int ssh_port = SSH_DEFAULT_PORT; int get_keytypes = KT_RSA1; /* Get only RSA1 keys by default */ +int hash_hosts = 0; /* Hash hostname on output */ + #define MAXMAXFD 256 /* The number of seconds after which to give up on a TCP connection */ @@ -49,11 +52,7 @@ int timeout = 5; int maxfd; #define MAXCON (maxfd - 10) -#ifdef HAVE___PROGNAME extern char *__progname; -#else -char *__progname; -#endif fd_set *read_wait; size_t read_wait_size; int ncon; @@ -167,7 +166,7 @@ Linebuf_lineno(Linebuf * lb) static char * Linebuf_getline(Linebuf * lb) { - int n = 0; + size_t n = 0; void *p; lb->lineno++; @@ -349,6 +348,7 @@ keygrab_ssh2(con *c) "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_GRP14_SHA1] = kexdh_client; c->c_kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; c->c_kex->verify_host_key = hostjump; @@ -369,10 +369,14 @@ keygrab_ssh2(con *c) static void keyprint(con *c, Key *key) { + char *host = c->c_output_name ? c->c_output_name : c->c_name; + if (!key) return; + if (hash_hosts && (host = host_hash(host, NULL, 0)) == NULL) + fatal("host_hash failed"); - fprintf(stdout, "%s ", c->c_output_name ? c->c_output_name : c->c_name); + fprintf(stdout, "%s ", host); key_write(key, stdout); fputs("\n", stdout); } @@ -396,8 +400,8 @@ tcpconnect(char *host) error("socket: %s", strerror(errno)); continue; } - if (fcntl(s, F_SETFL, O_NONBLOCK) < 0) - fatal("F_SETFL: %s", strerror(errno)); + if (set_nonblock(s) == -1) + fatal("%s: set_nonblock(%d)", __func__, s); if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0 && errno != EINPROGRESS) error("connect (`%s'): %s", host, strerror(errno)); @@ -489,27 +493,36 @@ conrecycle(int s) static void congreet(int s) { - int remote_major = 0, remote_minor = 0, n = 0; + int n = 0, remote_major = 0, remote_minor = 0; char buf[256], *cp; char remote_version[sizeof buf]; size_t bufsiz; con *c = &fdcon[s]; - bufsiz = sizeof(buf); - cp = buf; - while (bufsiz-- && (n = read(s, cp, 1)) == 1 && *cp != '\n') { - if (*cp == '\r') - *cp = '\n'; - cp++; - } - if (n < 0) { - if (errno != ECONNREFUSED) - error("read (%s): %s", c->c_name, strerror(errno)); - conrecycle(s); - return; + for (;;) { + memset(buf, '\0', sizeof(buf)); + bufsiz = sizeof(buf); + cp = buf; + while (bufsiz-- && + (n = atomicio(read, s, cp, 1)) == 1 && *cp != '\n') { + if (*cp == '\r') + *cp = '\n'; + cp++; + } + if (n != 1 || strncmp(buf, "SSH-", 4) == 0) + break; } if (n == 0) { - error("%s: Connection closed by remote host", c->c_name); + switch (errno) { + case EPIPE: + error("%s: Connection closed by remote host", c->c_name); + break; + case ECONNREFUSED: + break; + default: + error("read (%s): %s", c->c_name, strerror(errno)); + break; + } conrecycle(s); return; } @@ -539,7 +552,12 @@ congreet(int s) n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n", c->c_keytype == KT_RSA1? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2, c->c_keytype == KT_RSA1? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2); - if (atomicio(vwrite, s, buf, n) != n) { + if (n < 0 || (size_t)n >= sizeof(buf)) { + error("snprintf: buffer too small"); + confree(s); + return; + } + if (atomicio(vwrite, s, buf, n) != (size_t)n) { error("write (%s): %s", c->c_name, strerror(errno)); confree(s); return; @@ -557,14 +575,14 @@ static void conread(int s) { con *c = &fdcon[s]; - int n; + size_t n; if (c->c_status == CS_CON) { congreet(s); return; } - n = read(s, c->c_data + c->c_off, c->c_len - c->c_off); - if (n < 0) { + n = atomicio(read, s, c->c_data + c->c_off, c->c_len - c->c_off); + if (n == 0) { error("read (%s): %s", c->c_name, strerror(errno)); confree(s); return; @@ -679,7 +697,7 @@ fatal(const char *fmt,...) static void usage(void) { - fprintf(stderr, "usage: %s [-v46] [-p port] [-T timeout] [-t type] [-f file]\n" + fprintf(stderr, "usage: %s [-46Hv] [-f file] [-p port] [-T timeout] [-t type]\n" "\t\t [host | addrlist namelist] [...]\n", __progname); exit(1); @@ -700,11 +718,17 @@ main(int argc, char **argv) seed_rng(); TAILQ_INIT(&tq); + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ + sanitise_stdfd(); + if (argc <= 1) usage(); - while ((opt = getopt(argc, argv, "v46p:T:t:f:")) != -1) { + while ((opt = getopt(argc, argv, "Hv46p:T:t:f:")) != -1) { switch (opt) { + case 'H': + hash_hosts = 1; + break; case 'p': ssh_port = a2port(optarg); if (ssh_port == 0) {