Bugzilla – Attachment 2018 Details for
Bug 1213
ssh-keyscan exits in mid-way
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Add 'L' option to usage message
difs5.8 (text/plain), 11.96 KB, created by
aab
on 2011-03-19 16:38:46 AEDT
(
hide
)
Description:
Add 'L' option to usage message
Filename:
MIME Type:
Creator:
aab
Created:
2011-03-19 16:38:46 AEDT
Size:
11.96 KB
patch
obsolete
>diff -u openssh-5.8p1/kex.c.orig openssh-5.8p1/kex.c >--- openssh-5.8p1/kex.c.orig 2010-09-24 08:11:14.000000000 -0400 >+++ openssh-5.8p1/kex.c 2011-03-18 01:54:24.314007000 -0400 >@@ -49,6 +49,7 @@ > #include "dispatch.h" > #include "monitor.h" > #include "roaming.h" >+#include "canohost.h" > > #if OPENSSL_VERSION_NUMBER >= 0x00907000L > # if defined(HAVE_EVP_SHA256) >@@ -366,11 +367,19 @@ > choose_hostkeyalg(Kex *k, char *client, char *server) > { > char *hostkeyalg = match_list(client, server, NULL); >- if (hostkeyalg == NULL) >- fatal("no hostkey alg"); >+ if (hostkeyalg == NULL) { >+ if (k->server) >+ fatal("bad '%.100s' hostkey alg request from %.200s", client, get_remote_ipaddr()); >+ else >+ fatal("no '%.100s' hostkey alg(s) for %.200s", client, get_remote_ipaddr()); >+ } >+/* >+ * Note that if KEY_UNSPEC is returned, both the client and the server >+ * have the bad key string. >+ */ > k->hostkey_type = key_type_from_name(hostkeyalg); > if (k->hostkey_type == KEY_UNSPEC) >- fatal("bad hostkey alg '%s'", hostkeyalg); >+ fatal("unknown hostkey alg '%s'", hostkeyalg); > xfree(hostkeyalg); > } > >diff -u openssh-5.8p1/packet.c.orig openssh-5.8p1/packet.c >--- openssh-5.8p1/packet.c.orig 2010-11-23 18:46:37.000000000 -0500 >+++ openssh-5.8p1/packet.c 2011-02-08 20:06:41.478474000 -0500 >@@ -1025,6 +1025,10 @@ > * be used during the interactive session. > */ > >+int connclosed = 0; /* = 1 if connection closed by remote server */ >+ /* prior to necessary data being read */ >+ /* currently used in ssh-keyscan.c */ >+ > int > packet_read_seqnr(u_int32_t *seqnr_p) > { >@@ -1035,6 +1039,8 @@ > > DBG(debug("packet_read()")); > >+ connclosed = 0; >+ > setp = (fd_set *)xcalloc(howmany(active_state->connection_in + 1, > NFDBITS), sizeof(fd_mask)); > >@@ -1100,11 +1106,12 @@ > sizeof(buf), &cont); > } while (len == 0 && cont); > if (len == 0) { >+ connclosed = 1; /* if anybody wants to know */ > logit("Connection closed by %.200s", get_remote_ipaddr()); > cleanup_exit(255); > } > if (len < 0) >- fatal("Read from socket failed: %.100s", strerror(errno)); >+ fatal("Read from %.200s failed: %.100s", get_remote_ipaddr(), strerror(errno)); > /* Append it to the buffer. */ > packet_process_incoming(buf, len); > } >diff -u openssh-5.8p1/ssh-keyscan.1.orig openssh-5.8p1/ssh-keyscan.1 >--- openssh-5.8p1/ssh-keyscan.1.orig 2010-08-31 08:41:14.000000000 -0400 >+++ openssh-5.8p1/ssh-keyscan.1 2011-02-26 20:59:47.656753000 -0500 >@@ -15,7 +15,7 @@ > .Sh SYNOPSIS > .Nm ssh-keyscan > .Bk -words >-.Op Fl 46Hv >+.Op Fl 46HLv > .Op Fl f Ar file > .Op Fl p Ar port > .Op Fl T Ar timeout >@@ -73,6 +73,8 @@ > .Nm sshd , > but they do not reveal identifying information should the file's contents > be disclosed. >+.It Fl L >+If specified, all hosts for which no key is acquired will be logged. > .It Fl p Ar port > Port to connect to on the remote host. > .It Fl T Ar timeout >diff -u openssh-5.8p1/ssh-keyscan.c.orig openssh-5.8p1/ssh-keyscan.c >--- openssh-5.8p1/ssh-keyscan.c.orig 2011-01-06 06:44:45.000000000 -0500 >+++ openssh-5.8p1/ssh-keyscan.c 2011-03-19 01:35:59.017072000 -0400 >@@ -45,6 +45,7 @@ > #include "atomicio.h" > #include "misc.h" > #include "hostfile.h" >+#include "canohost.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. */ >@@ -61,6 +62,8 @@ > > int hash_hosts = 0; /* Hash hostname on output */ > >+int log_all_failures = 0; /* list all hosts checked */ >+ > #define MAXMAXFD 256 > > /* The number of seconds after which to give up on a TCP connection */ >@@ -70,6 +73,7 @@ > #define MAXCON (maxfd - 10) > > extern char *__progname; >+extern int connclosed; > fd_set *read_wait; > size_t read_wait_nfdset; > int ncon; >@@ -92,6 +96,7 @@ > int c_len; /* Total bytes which must be read. */ > int c_off; /* Length of data read so far. */ > int c_keytype; /* Only one of KT_RSA1, KT_DSA, or KT_RSA */ >+ int c_connclosed; /* = 1 if previous closed connection */ > char *c_namebase; /* Address to free for c_name and c_namelist */ > char *c_name; /* Hostname of connection for errors */ > char *c_namelist; /* Pointer to other possible addresses */ >@@ -243,6 +248,15 @@ > { > int j; > >+/* >+ * New fd and socket. Clear the possibly cached IP-address of the >+ * remote host (kex.c:canonical_host_ip) of the previous socket. Also >+ * ensure that the packet_read_seqnr():Connection closed ..." flag is >+ * clear (called by dispatch_run()). >+ */ >+ clear_cached_addr(); >+ connclosed = 0; >+ > packet_set_connection(c->c_fd, c->c_fd); > enable_compat20(); > myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA? >@@ -296,8 +310,11 @@ > memset(&hints, 0, sizeof(hints)); > hints.ai_family = IPv4or6; > hints.ai_socktype = SOCK_STREAM; >- if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) >- fatal("getaddrinfo %s: %s", host, ssh_gai_strerror(gaierr)); >+ if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) { >+ error("getaddrinfo %s: %s", host, ssh_gai_strerror(gaierr)); >+ s = -1; >+ return s; >+ } > for (ai = aitop; ai; ai = ai->ai_next) { > s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); > if (s < 0) { >@@ -349,6 +366,7 @@ > fdcon[s].c_len = 4; > fdcon[s].c_off = 0; > fdcon[s].c_keytype = keytype; >+ fdcon[s].c_connclosed = 0; > gettimeofday(&fdcon[s].c_tv, NULL); > fdcon[s].c_tv.tv_sec += timeout; > TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link); >@@ -388,8 +406,20 @@ > { > con *c = &fdcon[s]; > int ret; >+ char *name; > >- ret = conalloc(c->c_namelist, c->c_output_name, c->c_keytype); >+/* >+ * If "connclosed" isn't set, do the next host from c->c_namelist. Else, >+ * restore the original string in c->c_namebase and redo the current >+ * host. >+ */ >+ name = c->c_namelist; /* do next in list ?? */ >+ if (connclosed != 0) { >+ if (name && *name != '\0') /* restore separator, if any */ >+ *(name - 1) = ','; >+ name = c->c_namebase; /* redo current */ >+ } >+ ret = conalloc(name, c->c_output_name, c->c_keytype); > confree(s); > return (ret); > } >@@ -422,6 +452,8 @@ > error("%s: Connection closed by remote host", c->c_name); > break; > case ECONNREFUSED: >+ if (log_all_failures) >+ error("%s: Connection refused by remote host", c->c_name); > break; > default: > error("read (%s): %s", c->c_name, strerror(errno)); >@@ -443,14 +475,20 @@ > datafellows = 0; > if (c->c_keytype != KT_RSA1) { > if (!ssh2_capable(remote_major, remote_minor)) { >+ if (log_all_failures) >+ logit("%s doesn't support ssh2", c->c_name); >+ else > debug("%s doesn't support ssh2", c->c_name); >- confree(s); >- return; >+ confree(s); >+ return; > } > } else if (remote_major != 1) { >+ if (log_all_failures) >+ logit("%s doesn't support ssh1", c->c_name); >+ else > debug("%s doesn't support ssh1", c->c_name); >- confree(s); >- return; >+ 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", >@@ -466,13 +504,42 @@ > confree(s); > return; > } >- if (c->c_keytype != KT_RSA1) { >- keyprint(c, keygrab_ssh2(c)); >- confree(s); >+ if (c->c_keytype == KT_RSA1) { >+ c->c_status = CS_SIZE; >+ contouch(s); > return; > } >- c->c_status = CS_SIZE; >- contouch(s); >+/* >+ * Read and print one of the ssh2 keys for this host. >+ */ >+ keyprint(c, keygrab_ssh2(c)); >+ >+/* >+ * We're done with this host if the `packet.c:packet_read_seqnr()' >+ * function was able to complete its data read. >+ */ >+ if (connclosed == 0) { >+ confree(s); >+ } >+/* >+ * We're also done with this host if the `packet.c:packet_read_seqnr()' >+ * function received an EOF while attempting to read data (probably >+ * caused by the LoginGraceTime being exceeded on the host) and if this >+ * is the second time this has occurred for this host. >+ */ >+ else if (c->c_connclosed) { >+ confree(s); >+ connclosed = -1; /* conrecycle other active sockets */ >+ } >+/* >+ * Else, give this host one and only one more chance with this key. We >+ * don't know if this timeout was caused because of slow responses by >+ * previous hosts or the host itself (or both (:@{)). This host and all >+ * other hosts that currently have open sockets will be `conrecycled()'. >+ */ >+ else { >+ connclosed = s; >+ } > } > > static void >@@ -550,20 +617,90 @@ > 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); >+/* >+ * Break if the read attempt in the `packet.c:packet_read_seqnr()' >+ * function failed because the remote host closed the connection before >+ * the packet data read was complete. The closure probably occurred >+ * because the LoginGraceTime was exceeded on the remote `sshd' server. >+ * All hosts that currently have a viable "fdcon[s]" entry will be >+ * recycled below to negate the time used waiting for the current >+ * "fdcon[i]"th host to respond. This is a very kludgy way to do this. >+ */ >+ if (connclosed) >+ break; >+ } > } > xfree(r); > xfree(e); > >+/* >+ * If we have the "connclosed" condition, the "fdcon[connclosed]" entry >+ * has to be freed now since the socket has already been closed by the >+ * `packet.c:packet_close()' function. We will use the new fd as a >+ * termination condition in the while loop below. >+ */ >+ i = -1; >+ if (connclosed > 0) { >+ char *iname, *oname; >+ int keytype; >+ >+ c = &fdcon[connclosed]; >+ iname = c->c_namelist; >+ if (iname && *iname != '\0') >+ *(iname - 1) = ','; >+ iname = xstrdup (c->c_namebase); >+ oname = xstrdup (c->c_output_name); >+ keytype = c->c_keytype; >+ confree (connclosed); >+ i = conalloc (iname, oname, keytype); >+/* >+ * Flag this entry as having caused a "connclosed" condition - once. >+ */ >+ if (i >= 0) >+ fdcon[i].c_connclosed = 1; >+ xfree (iname); >+ xfree (oname); >+ } >+ >+/* >+ * Loop through the remaining TAILQ entries. If we have a "connclosed" >+ * condition, recycle all of them using the current host name. Else, >+ * if they have timed out, recycle them using the next name in the list. >+ */ > 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))) { >+ while (c && (connclosed || >+ (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; >+/* >+ * If i >= 0, fdcon[i] should be the first of any new allocations that >+ * were made as a result of the call(s) to conrecycle() below or to >+ * conalloc() above. >+ */ >+ if (s == i) >+ break; >+ >+/* >+ * If requested and if not recycling because of "connclosed", list this >+ * host as a connection time out. >+ */ >+ if (log_all_failures && connclosed == 0) >+ logit("%s: Connection timed out.", c->c_name); >+ >+/* >+ * Save fd of first new allocation. If we encounter it again, we'll >+ * know that we've cycled through all of the original queue. >+ */ >+ s = conrecycle(s); >+ if (i < 0) >+ i = s; > > c = TAILQ_NEXT(c, c_link); >- conrecycle(s); > } >+ connclosed = 0; > } > > static void >@@ -583,6 +720,19 @@ > } > } > >+/* >+ * Convert general remote aborts to continues while the `dispatch_run()' >+ * function is being executed. >+ */ >+void >+cleanup_exit(int i) >+{ >+ if (nonfatal_fatal) >+ longjmp(kexjmp, -1); >+ else >+ exit(i); >+} >+ > void > fatal(const char *fmt,...) > { >@@ -601,7 +751,7 @@ > usage(void) > { > fprintf(stderr, >- "usage: %s [-46Hv] [-f file] [-p port] [-T timeout] [-t type]\n" >+ "usage: %s [-46HLv] [-f file] [-p port] [-T timeout] [-t type]\n" > "\t\t [host | addrlist namelist] ...\n", > __progname); > exit(1); >@@ -630,11 +780,14 @@ > if (argc <= 1) > usage(); > >- while ((opt = getopt(argc, argv, "Hv46p:T:t:f:")) != -1) { >+ while ((opt = getopt(argc, argv, "HLv46p:T:t:f:")) != -1) { > switch (opt) { > case 'H': > hash_hosts = 1; > break; >+ case 'L': >+ log_all_failures = 1; >+ break; > case 'p': > ssh_port = a2port(optarg); > if (ssh_port <= 0) { >@@ -715,7 +868,7 @@ > fdlim_set(maxfd); > fdcon = xcalloc(maxfd, sizeof(con)); > >- read_wait_nfdset = howmany(maxfd, NFDBITS); >+ read_wait_nfdset = howmany(maxfd + 1, NFDBITS); > read_wait = xcalloc(read_wait_nfdset, sizeof(fd_mask)); > > for (j = 0; j < fopt_count; j++) {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1213
:
1961
|
1969
|
2000
|
2005
|
2008
|
2016
|
2018
|
2021
|
2057
|
2197
|
2533
|
2536
|
2537
|
2540