X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/fda04d7d7e5544d24e3bb0bc25c8f04a342136d2..495795e1042da83d07e68e13e0b570c8cc619d24:/ssh-keyscan.c diff --git a/ssh-keyscan.c b/ssh-keyscan.c index 9fa8aaeb..7dffb851 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -7,7 +7,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-keyscan.c,v 1.44 2003/06/28 16:23:06 deraadt Exp $"); +RCSID("$OpenBSD: ssh-keyscan.c,v 1.54 2005/05/24 17:32:44 avsm Exp $"); #include "openbsd-compat/sys-queue.h" @@ -28,6 +28,7 @@ RCSID("$OpenBSD: ssh-keyscan.c,v 1.44 2003/06/28 16:23:06 deraadt 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; @@ -214,13 +213,11 @@ fdlim_get(int hard) if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0) return (-1); if ((hard ? rlfd.rlim_max : rlfd.rlim_cur) == RLIM_INFINITY) - return 10000; + return SSH_SYSFDMAX; else return hard ? rlfd.rlim_max : rlfd.rlim_cur; -#elif defined (HAVE_SYSCONF) - return sysconf (_SC_OPEN_MAX); #else - return 10000; + return SSH_SYSFDMAX; #endif } @@ -351,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; @@ -371,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); } @@ -398,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)); @@ -491,27 +493,30 @@ conrecycle(int s) static void congreet(int s) { - int remote_major, remote_minor, n = 0; + int remote_major = 0, remote_minor = 0; char buf[256], *cp; char remote_version[sizeof buf]; - size_t bufsiz; + size_t bufsiz, n = 0; con *c = &fdcon[s]; bufsiz = sizeof(buf); cp = buf; - while (bufsiz-- && (n = read(s, cp, 1)) == 1 && *cp != '\n') { + while (bufsiz-- && (n = atomicio(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; - } 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; } @@ -541,6 +546,11 @@ 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 (n == -1 || n >= sizeof buf) { + error("snprintf: buffer too small"); + confree(s); + return; + } if (atomicio(vwrite, s, buf, n) != n) { error("write (%s): %s", c->c_name, strerror(errno)); confree(s); @@ -559,14 +569,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; @@ -675,13 +685,13 @@ fatal(const char *fmt,...) if (nonfatal_fatal) longjmp(kexjmp, -1); else - fatal_cleanup(); + exit(255); } 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); @@ -705,8 +715,11 @@ main(int argc, char **argv) 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) {