]> andersk Git - openssh.git/blobdiff - ssh-keyscan.c
- (tim) [contrib/caldera/openssh.spec] add Requires line for Caldera 3.1
[openssh.git] / ssh-keyscan.c
index 68593fe750f0000d7746423b7fb085dc02eaf500..3f6c23136356437785f234858b73bcb9a1b9e993 100644 (file)
@@ -8,44 +8,45 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-keyscan.c,v 1.6 2000/12/19 23:17:58 markus Exp $");
+RCSID("$OpenBSD: ssh-keyscan.c,v 1.22 2001/03/06 06:11:18 deraadt Exp $");
 
-#if defined(HAVE_SYS_QUEUE_H)  &&  !defined(HAVE_BOGUS_SYS_QUEUE_H)
+#if defined(HAVE_SYS_QUEUE_H) && !defined(HAVE_BOGUS_SYS_QUEUE_H)
 #include <sys/queue.h>
 #else
-#include "bsd-queue.h"
+#include "openbsd-compat/fake-queue.h"
 #endif
 #include <errno.h>
 
 #include <openssl/bn.h>
-#include <openssl/rsa.h>
-#include <openssl/dsa.h>
 
 #include "xmalloc.h"
 #include "ssh.h"
+#include "ssh1.h"
 #include "key.h"
 #include "buffer.h"
 #include "bufaux.h"
+#include "log.h"
+#include "atomicio.h"
 
 static int argno = 1;          /* Number of argument currently being parsed */
 
 int family = AF_UNSPEC;                /* IPv4, IPv6 or both */
 
-#define PORT 22
 #define MAXMAXFD 256
 
 /* The number of seconds after which to give up on a TCP connection */
 int timeout = 5;
 
 int maxfd;
-#define maxcon (maxfd - 10)
+#define MAXCON (maxfd - 10)
 
 #ifdef HAVE___PROGNAME
 extern char *__progname;
 #else
 char *__progname;
 #endif
-fd_set read_wait;
+fd_set *read_wait;
+size_t read_wait_size;
 int ncon;
 
 /*
@@ -90,7 +91,7 @@ typedef struct {
        void (*errfun) (const char *,...);
 } Linebuf;
 
-static inline Linebuf *
+Linebuf *
 Linebuf_alloc(const char *filename, void (*errfun) (const char *,...))
 {
        Linebuf *lb;
@@ -103,7 +104,7 @@ Linebuf_alloc(const char *filename, void (*errfun) (const char *,...))
        if (filename) {
                lb->filename = filename;
                if (!(lb->stream = fopen(filename, "r"))) {
-                       free(lb);
+                       xfree(lb);
                        if (errfun)
                                (*errfun) ("%s: %s\n", filename, strerror(errno));
                        return (NULL);
@@ -116,7 +117,7 @@ Linebuf_alloc(const char *filename, void (*errfun) (const char *,...))
        if (!(lb->buf = malloc(lb->size = LINEBUF_SIZE))) {
                if (errfun)
                        (*errfun) ("linebuf (%s): malloc failed\n", lb->filename);
-               free(lb);
+               xfree(lb);
                return (NULL);
        }
        lb->errfun = errfun;
@@ -124,15 +125,15 @@ Linebuf_alloc(const char *filename, void (*errfun) (const char *,...))
        return (lb);
 }
 
-static inline void
+void
 Linebuf_free(Linebuf * lb)
 {
        fclose(lb->stream);
-       free(lb->buf);
-       free(lb);
+       xfree(lb->buf);
+       xfree(lb);
 }
 
-static inline void
+void
 Linebuf_restart(Linebuf * lb)
 {
        clearerr(lb->stream);
@@ -140,14 +141,14 @@ Linebuf_restart(Linebuf * lb)
        lb->lineno = 0;
 }
 
-static inline int
+int
 Linebuf_lineno(Linebuf * lb)
 {
        return (lb->lineno);
 }
 
-static inline char *
-getline(Linebuf * lb)
+char *
+Linebuf_getline(Linebuf * lb)
 {
        int n = 0;
 
@@ -156,7 +157,8 @@ getline(Linebuf * lb)
                /* 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, strerror(errno));
+                               (*lb->errfun) ("%s: %s\n", lb->filename,
+                                   strerror(errno));
                        return (NULL);
                }
                n = strlen(lb->buf);
@@ -168,23 +170,26 @@ getline(Linebuf * lb)
                }
                if (n != lb->size - 1) {
                        if (lb->errfun)
-                               (*lb->errfun) ("%s: skipping incomplete last line\n", lb->filename);
+                               (*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)))) {
                        if (lb->errfun)
-                               (*lb->errfun) ("linebuf (%s): realloc failed\n", lb->filename);
+                               (*lb->errfun) ("linebuf (%s): realloc failed\n",
+                                   lb->filename);
                        return (NULL);
                }
        }
 }
 
-static int
+int
 fdlim_get(int hard)
 {
 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
        struct rlimit rlfd;
+
        if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0)
                return (-1);
        if ((hard ? rlfd.rlim_max : rlfd.rlim_cur) == RLIM_INFINITY)
@@ -198,7 +203,7 @@ fdlim_get(int hard)
 #endif
 }
 
-static int
+int
 fdlim_set(int lim)
 {
 #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
@@ -213,7 +218,7 @@ fdlim_set(int lim)
        if (setrlimit(RLIMIT_NOFILE, &rlfd) < 0)
                return (-1);
 #elif defined (HAVE_SETDTABLESIZE)
-       setdtablesize (lim);
+       setdtablesize(lim);
 #endif
        return (0);
 }
@@ -223,7 +228,7 @@ fdlim_set(int lim)
  * separators.  This is the same as the 4.4BSD strsep, but different from the
  * one in the GNU libc.
  */
-inline char *
+char *
 xstrsep(char **str, const char *delim)
 {
        char *s, *e;
@@ -298,7 +303,7 @@ tcpconnect(char *host)
        char strport[NI_MAXSERV];
        int gaierr, s = -1;
 
-       snprintf(strport, sizeof strport, "%d", PORT);
+       snprintf(strport, sizeof strport, "%d", SSH_DEFAULT_PORT);
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = family;
        hints.ai_socktype = SOCK_STREAM;
@@ -310,7 +315,7 @@ tcpconnect(char *host)
                        error("socket: %s", strerror(errno));
                        continue;
                }
-               if (fcntl(s, F_SETFL, O_NDELAY) < 0)
+               if (fcntl(s, F_SETFL, O_NONBLOCK) < 0)
                        fatal("F_SETFL: %s", strerror(errno));
                if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0 &&
                    errno != EINPROGRESS)
@@ -335,7 +340,7 @@ conalloc(char *iname, char *oname)
        do {
                name = xstrsep(&namelist, ",");
                if (!name) {
-                       free(namebase);
+                       xfree(namebase);
                        return (-1);
                }
        } while ((s = tcpconnect(name)) < 0);
@@ -357,7 +362,7 @@ conalloc(char *iname, char *oname)
        gettimeofday(&fdcon[s].c_tv, NULL);
        fdcon[s].c_tv.tv_sec += timeout;
        TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link);
-       FD_SET(s, &read_wait);
+       FD_SET(s, read_wait);
        ncon++;
        return (s);
 }
@@ -365,16 +370,16 @@ conalloc(char *iname, char *oname)
 void
 confree(int s)
 {
-       close(s);
        if (s >= maxfd || fdcon[s].c_status == CS_UNUSED)
                fatal("confree: attempt to free bad fdno %d", s);
-       free(fdcon[s].c_namebase);
-       free(fdcon[s].c_output_name);
+       close(s);
+       xfree(fdcon[s].c_namebase);
+       xfree(fdcon[s].c_output_name);
        if (fdcon[s].c_status == CS_KEYS)
-               free(fdcon[s].c_data);
+               xfree(fdcon[s].c_data);
        fdcon[s].c_status = CS_UNUSED;
        TAILQ_REMOVE(&tq, &fdcon[s], c_link);
-       FD_CLR(s, &read_wait);
+       FD_CLR(s, read_wait);
        ncon--;
 }
 
@@ -395,37 +400,41 @@ conrecycle(int s)
        char *iname, *oname;
 
        iname = xstrdup(c->c_namelist);
-       oname = c->c_output_name;
-       c->c_output_name = NULL;/* prevent it from being freed */
+       oname = xstrdup(c->c_output_name);
        confree(s);
        ret = conalloc(iname, oname);
-       free(iname);
+       xfree(iname);
+       xfree(oname);
        return (ret);
 }
 
 void
 congreet(int s)
 {
-       char buf[80];
-       int n;
+       char buf[80], *cp;
+       size_t bufsiz;
+       int n = 0;
        con *c = &fdcon[s];
 
-       n = read(s, buf, sizeof(buf));
+       bufsiz = sizeof(buf);
+       cp = buf;
+       while (bufsiz-- && (n = read(s, cp, 1)) == 1 && *cp != '\n' && *cp != '\r')
+               cp++;
        if (n < 0) {
                if (errno != ECONNREFUSED)
                        error("read (%s): %s", c->c_name, strerror(errno));
                conrecycle(s);
                return;
        }
-       if (buf[n - 1] != '\n') {
+       if (*cp != '\n' && *cp != '\r') {
                error("%s: bad greeting", c->c_name);
                confree(s);
                return;
        }
-       buf[n - 1] = '\0';
+       *cp = '\0';
        fprintf(stderr, "# %s %s\n", c->c_name, buf);
        n = snprintf(buf, sizeof buf, "SSH-1.5-OpenSSH-keyscan\r\n");
-       if (write(s, buf, n) != n) {
+       if (atomicio(write, s, buf, n) != n) {
                error("write (%s): %s", c->c_name, strerror(errno));
                confree(s);
                return;
@@ -477,7 +486,7 @@ conread(int s)
 void
 conloop(void)
 {
-       fd_set r, e;
+       fd_set *r, *e;
        struct timeval seltime, now;
        int i;
        con *c;
@@ -485,33 +494,42 @@ conloop(void)
        gettimeofday(&now, NULL);
        c = tq.tqh_first;
 
-       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))) {
+       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))) {
                seltime = c->c_tv;
                seltime.tv_sec -= now.tv_sec;
                seltime.tv_usec -= now.tv_usec;
-               if ((int) seltime.tv_usec < 0) {
+               if (seltime.tv_usec < 0) {
                        seltime.tv_usec += 1000000;
                        seltime.tv_sec--;
                }
        } else
                seltime.tv_sec = seltime.tv_usec = 0;
 
-       r = e = read_wait;
-       select(maxfd, &r, NULL, &e, &seltime);
-       for (i = 0; i < maxfd; i++)
-               if (FD_ISSET(i, &e)) {
+       r = xmalloc(read_wait_size);
+       memcpy(r, read_wait, read_wait_size);
+       e = xmalloc(read_wait_size);
+       memcpy(e, read_wait, read_wait_size);
+
+       while (select(maxfd, r, NULL, e, &seltime) == -1 &&
+           (errno == EAGAIN || errno == EINTR))
+               ;
+
+       for (i = 0; i < maxfd; i++) {
+               if (FD_ISSET(i, e)) {
                        error("%s: exception!", fdcon[i].c_name);
                        confree(i);
-               } else if (FD_ISSET(i, &r))
+               } else if (FD_ISSET(i, r))
                        conread(i);
+       }
+       xfree(r);
+       xfree(e);
 
        c = tq.tqh_first;
-       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))) {
+       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;
                conrecycle(s);
        }
@@ -534,6 +552,7 @@ nexthost(int argc, char **argv)
                                return (argv[argno++]);
                        } else if (!strncmp(argv[argno], "-f", 2)) {
                                char *fname;
+
                                if (argv[argno][2])
                                        fname = &argv[argno++][2];
                                else if (++argno >= argc) {
@@ -545,10 +564,12 @@ nexthost(int argc, char **argv)
                                        fname = NULL;
                                lb = Linebuf_alloc(fname, error);
                        } else
-                               error("ignoring invalid/misplaced option `%s'", argv[argno++]);
+                               error("ignoring invalid/misplaced option `%s'",
+                                   argv[argno++]);
                } else {
                        char *line;
-                       line = getline(lb);
+
+                       line = Linebuf_getline(lb);
                        if (line)
                                return (line);
                        Linebuf_free(lb);
@@ -557,7 +578,7 @@ nexthost(int argc, char **argv)
        }
 }
 
-static void
+void
 usage(void)
 {
        fatal("usage: %s [-t timeout] { [--] host | -f file } ...", __progname);
@@ -595,14 +616,19 @@ main(int argc, char **argv)
                fatal("%s: fdlim_get: bad value", __progname);
        if (maxfd > MAXMAXFD)
                maxfd = MAXMAXFD;
-       if (maxcon <= 0)
+       if (MAXCON <= 0)
                fatal("%s: not enough file descriptors", __progname);
        if (maxfd > fdlim_get(0))
                fdlim_set(maxfd);
        fdcon = xmalloc(maxfd * sizeof(con));
+       memset(fdcon, 0, maxfd * sizeof(con));
+
+       read_wait_size = howmany(maxfd, NFDBITS) * sizeof(fd_mask);
+       read_wait = xmalloc(read_wait_size);
+       memset(read_wait, 0, read_wait_size);
 
        do {
-               while (ncon < maxcon) {
+               while (ncon < MAXCON) {
                        char *name;
 
                        host = nexthost(argc, argv);
This page took 0.587185 seconds and 4 git commands to generate.