*/
#include "includes.h"
-RCSID("$OpenBSD: ssh-keyscan.c,v 1.26 2001/08/05 23:18:20 markus Exp $");
+RCSID("$OpenBSD: ssh-keyscan.c,v 1.35 2002/03/04 18:30:23 stevesk Exp $");
-#if defined(HAVE_SYS_QUEUE_H) && !defined(HAVE_BOGUS_SYS_QUEUE_H)
-#include <sys/queue.h>
-#else
#include "openbsd-compat/fake-queue.h"
-#endif
-#include <errno.h>
#include <openssl/bn.h>
#endif
int ssh_port = SSH_DEFAULT_PORT;
-
-#define KT_RSA1 1
-#define KT_DSA 2
-#define KT_RSA 4
-
-int get_keytypes = KT_RSA1; /* Get only RSA1 keys by default */
+
+#define KT_RSA1 1
+#define KT_DSA 2
+#define KT_RSA 4
+
+int get_keytypes = KT_RSA1; /* Get only RSA1 keys by default */
#define MAXMAXFD 256
int ncon;
int nonfatal_fatal = 0;
jmp_buf kexjmp;
+Key *kexjmp_key;
/*
* Keep a connection structure for each file descriptor. The state
static int
hostjump(Key *hostkey)
{
- longjmp(kexjmp, (int)hostkey);
+ kexjmp_key = hostkey;
+ longjmp(kexjmp, 1);
}
static int
xfree(c->c_kex);
c->c_kex = NULL;
packet_close();
- if (j < 0)
- j = 0;
- return (Key*)(j);
+ return j < 0? NULL : kexjmp_key;
}
static void
congreet(int s)
{
char buf[256], *cp;
+ char remote_version[sizeof buf];
size_t bufsiz;
- int n = 0;
+ int remote_major, remote_minor, n = 0;
con *c = &fdcon[s];
bufsiz = sizeof(buf);
cp = buf;
- while (bufsiz-- && (n = read(s, cp, 1)) == 1 && *cp != '\n' && *cp != '\r')
+ 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;
}
+ 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);
return;
}
*cp = '\0';
- fprintf(stderr, "# %s %s\n", c->c_name, buf);
+ if (sscanf(buf, "SSH-%d.%d-%[^\n]\n",
+ &remote_major, &remote_minor, remote_version) == 3)
+ compat_datafellows(remote_version);
+ else
+ datafellows = 0;
if (c->c_keytype != KT_RSA1) {
- int remote_major, remote_minor;
- char remote_version[sizeof buf];
-
- if (sscanf(buf, "SSH-%d.%d-%[^\n]\n",
- &remote_major, &remote_minor, remote_version) == 3)
- compat_datafellows(remote_version);
- else
- datafellows = 0;
if (!ssh2_capable(remote_major, remote_minor)) {
debug("%s doesn't support ssh2", c->c_name);
confree(s);
return;
}
+ } else if (remote_major != 1) {
+ debug("%s doesn't support ssh1", c->c_name);
+ confree(s);
+ return;
}
+ fprintf(stderr, "# %s %s\n", c->c_name, chop(buf));
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);
char *name = strnnsep(&host, " \t\n");
int j;
+ if (name == NULL)
+ return;
for (j = KT_RSA1; j <= KT_RSA; j *= 2) {
if (get_keytypes & j) {
while (ncon >= MAXCON)
}
}
-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
+ fatal_cleanup();
}
static void
int debug_flag = 0, log_level = SYSLOG_LEVEL_INFO;
int opt, fopt_count = 0;
char *tname;
-
+
extern int optind;
extern char *optarg;
__progname = get_progname(argv[0]);
+ init_rng();
+ seed_rng();
TAILQ_INIT(&tq);
if (argc <= 1)
else
fatal("Too high debugging level.");
break;
- case 'f':
+ case 'f':
if (strcmp(optarg, "-") == 0)
optarg = NULL;
argv[fopt_count++] = optarg;
get_keytypes |= KT_RSA;
break;
case KEY_UNSPEC:
- fatal("unknown key type %s\n", tname);
+ fatal("unknown key type %s", tname);
}
tname = strtok(NULL, ",");
}
usage();
log_init("ssh-keyscan", log_level, SYSLOG_FACILITY_USER, 1);
- fatal_add_cleanup(fatal_callback, NULL);
-
maxfd = fdlim_get(1);
if (maxfd < 0)
for (j = 0; j < fopt_count; j++) {
lb = Linebuf_alloc(argv[j], error);
+ if (!lb)
+ continue;
while ((line = Linebuf_getline(lb)) != NULL)
do_host(line);
Linebuf_free(lb);