X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/cdc95d6e00ba6c81f14da1cc712f65206ce6b4ce..25616c132251df1782c4edcb873f8acba345fc97:/ssh-keyscan.c diff --git a/ssh-keyscan.c b/ssh-keyscan.c index 80eab269..266b23cb 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -7,14 +7,9 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-keyscan.c,v 1.33 2001/12/10 20:34:31 markus Exp $"); +RCSID("$OpenBSD: ssh-keyscan.c,v 1.47 2004/03/08 09:38:05 djm Exp $"); -#if defined(HAVE_SYS_QUEUE_H) && !defined(HAVE_BOGUS_SYS_QUEUE_H) -#include -#else -#include "openbsd-compat/fake-queue.h" -#endif -#include +#include "openbsd-compat/sys-queue.h" #include @@ -36,11 +31,7 @@ RCSID("$OpenBSD: ssh-keyscan.c,v 1.33 2001/12/10 20:34:31 markus Exp $"); /* Flag indicating whether IPv4 or IPv6. This can be set on the command line. Default value is AF_UNSPEC means both IPv4 and IPv6. */ -#ifdef IPV4_DEFAULT -int IPv4or6 = AF_INET; -#else int IPv4or6 = AF_UNSPEC; -#endif int ssh_port = SSH_DEFAULT_PORT; @@ -121,7 +112,8 @@ Linebuf_alloc(const char *filename, void (*errfun) (const char *,...)) if (!(lb = malloc(sizeof(*lb)))) { if (errfun) - (*errfun) ("linebuf (%s): malloc failed\n", lb->filename); + (*errfun) ("linebuf (%s): malloc failed\n", + filename ? filename : "(stdin)"); return (NULL); } if (filename) { @@ -176,13 +168,14 @@ static char * Linebuf_getline(Linebuf * lb) { int n = 0; + void *p; lb->lineno++; for (;;) { /* Read a line */ if (!fgets(&lb->buf[n], lb->size - n, lb->stream)) { if (ferror(lb->stream) && lb->errfun) - (*lb->errfun) ("%s: %s\n", lb->filename, + (*lb->errfun)("%s: %s\n", lb->filename, strerror(errno)); return (NULL); } @@ -195,17 +188,20 @@ Linebuf_getline(Linebuf * lb) } if (n != lb->size - 1) { if (lb->errfun) - (*lb->errfun) ("%s: skipping incomplete last line\n", + (*lb->errfun)("%s: skipping incomplete last line\n", lb->filename); return (NULL); } /* Double the buffer if we need more space */ - if (!(lb->buf = realloc(lb->buf, (lb->size *= 2)))) { + lb->size *= 2; + if ((p = realloc(lb->buf, lb->size)) == NULL) { + lb->size /= 2; if (lb->errfun) - (*lb->errfun) ("linebuf (%s): realloc failed\n", + (*lb->errfun)("linebuf (%s): realloc failed\n", lb->filename); return (NULL); } + lb->buf = p; } } @@ -218,13 +214,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 } @@ -234,6 +228,7 @@ fdlim_set(int lim) #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) struct rlimit rlfd; #endif + if (lim <= 0) return (-1); #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) @@ -353,6 +348,8 @@ keygrab_ssh2(con *c) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA? "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_GEX_SHA1] = kexgex_client; c->c_kex->verify_host_key = hostjump; if (!(j = setjmp(kexjmp))) { @@ -394,7 +391,7 @@ tcpconnect(char *host) if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) fatal("getaddrinfo %s: %s", host, gai_strerror(gaierr)); for (ai = aitop; ai; ai = ai->ai_next) { - s = socket(ai->ai_family, SOCK_STREAM, 0); + s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (s < 0) { error("socket: %s", strerror(errno)); continue; @@ -416,8 +413,8 @@ tcpconnect(char *host) static int conalloc(char *iname, char *oname, int keytype) { - int s; char *namebase, *name, *namelist; + int s; namebase = namelist = xstrdup(iname); @@ -481,8 +478,8 @@ contouch(int s) static int conrecycle(int s) { - int ret; con *c = &fdcon[s]; + int ret; ret = conalloc(c->c_namelist, c->c_output_name, c->c_keytype); confree(s); @@ -492,10 +489,10 @@ conrecycle(int s) static void congreet(int s) { + int remote_major = 0, remote_minor = 0, n = 0; char buf[256], *cp; char remote_version[sizeof buf]; size_t bufsiz; - int remote_major, remote_minor, n = 0; con *c = &fdcon[s]; bufsiz = sizeof(buf); @@ -511,6 +508,11 @@ congreet(int s) conrecycle(s); return; } + if (n == 0) { + error("%s: Connection closed by remote host", c->c_name); + conrecycle(s); + return; + } if (*cp != '\n' && *cp != '\r') { error("%s: bad greeting", c->c_name); confree(s); @@ -537,7 +539,7 @@ 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(write, s, buf, n) != n) { + if (atomicio(vwrite, s, buf, n) != n) { error("write (%s): %s", c->c_name, strerror(errno)); confree(s); return; @@ -554,8 +556,8 @@ congreet(int s) static void conread(int s) { - int n; con *c = &fdcon[s]; + int n; if (c->c_status == CS_CON) { congreet(s); @@ -594,13 +596,13 @@ conread(int s) static void conloop(void) { - fd_set *r, *e; struct timeval seltime, now; - int i; + fd_set *r, *e; con *c; + int i; gettimeofday(&now, NULL); - c = tq.tqh_first; + c = TAILQ_FIRST(&tq); if (c && (c->c_tv.tv_sec > now.tv_sec || (c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec > now.tv_usec))) { @@ -633,12 +635,12 @@ conloop(void) xfree(r); xfree(e); - c = tq.tqh_first; + c = TAILQ_FIRST(&tq); while (c && (c->c_tv.tv_sec < now.tv_sec || (c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec < now.tv_usec))) { int s = c->c_fd; - c = c->c_link.tqe_next; + c = TAILQ_NEXT(c, c_link); conrecycle(s); } } @@ -660,26 +662,26 @@ do_host(char *host) } } -static void -fatal_callback(void *arg) +void +fatal(const char *fmt,...) { + va_list args; + + va_start(args, fmt); + do_log(SYSLOG_LEVEL_FATAL, fmt, args); + va_end(args); if (nonfatal_fatal) longjmp(kexjmp, -1); + else + exit(255); } static void usage(void) { - fprintf(stderr, "Usage: %s [options] host ...\n", + fprintf(stderr, "usage: %s [-v46] [-p port] [-T timeout] [-t type] [-f file]\n" + "\t\t [host | addrlist namelist] [...]\n", __progname); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -f file Read hosts or addresses from file.\n"); - fprintf(stderr, " -p port Connect to the specified port.\n"); - fprintf(stderr, " -t keytype Specify the host key type.\n"); - fprintf(stderr, " -T timeout Set connection timeout.\n"); - fprintf(stderr, " -v Verbose; display verbose debugging messages.\n"); - fprintf(stderr, " -4 Use IPv4 only.\n"); - fprintf(stderr, " -6 Use IPv6 only.\n"); exit(1); } @@ -693,7 +695,7 @@ main(int argc, char **argv) extern int optind; extern char *optarg; - __progname = get_progname(argv[0]); + __progname = ssh_get_progname(argv[0]); init_rng(); seed_rng(); TAILQ_INIT(&tq); @@ -711,9 +713,11 @@ main(int argc, char **argv) } break; case 'T': - timeout = atoi(optarg); - if (timeout <= 0) + timeout = convtime(optarg); + if (timeout == -1 || timeout == 0) { + fprintf(stderr, "Bad timeout '%s'\n", optarg); usage(); + } break; case 'v': if (!debug_flag) { @@ -766,7 +770,6 @@ main(int argc, char **argv) usage(); log_init("ssh-keyscan", log_level, SYSLOG_FACILITY_USER, 1); - fatal_add_cleanup(fatal_callback, NULL); maxfd = fdlim_get(1); if (maxfd < 0)