Bugzilla – Attachment 3602 Details for
Bug 976
ssh-keyscan should accept cidr ranges
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
expand CIDR ranges in ssh-keyscan
bz976.diff (text/plain), 5.91 KB, created by
Damien Miller
on 2022-07-01 14:31:06 AEST
(
hide
)
Description:
expand CIDR ranges in ssh-keyscan
Filename:
MIME Type:
Creator:
Damien Miller
Created:
2022-07-01 14:31:06 AEST
Size:
5.91 KB
patch
obsolete
>diff --git a/addr.c b/addr.c >index 8774764..ed1b805 100644 >--- a/addr.c >+++ b/addr.c >@@ -223,6 +223,28 @@ addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b) > } > } > >+int >+addr_or(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b) >+{ >+ int i; >+ >+ if (dst == NULL || a == NULL || b == NULL || a->af != b->af) >+ return (-1); >+ >+ memcpy(dst, a, sizeof(*dst)); >+ switch (a->af) { >+ case AF_INET: >+ dst->v4.s_addr |= b->v4.s_addr; >+ return (0); >+ case AF_INET6: >+ for (i = 0; i < 4; i++) >+ dst->addr32[i] |= b->addr32[i]; >+ return (0); >+ default: >+ return (-1); >+ } >+} >+ > int > addr_cmp(const struct xaddr *a, const struct xaddr *b) > { >@@ -274,6 +296,29 @@ addr_is_all0s(const struct xaddr *a) > } > } > >+/* Increment the specified address. Note, does not overflow checking */ >+void >+addr_increment(struct xaddr *a) >+{ >+ int i; >+ uint32_t n; >+ >+ switch (a->af) { >+ case AF_INET: >+ a->v4.s_addr = htonl(ntohl(a->v4.s_addr) + 1); >+ break; >+ case AF_INET6: >+ for (i = 0; i < 4; i++) { >+ /* Increment with carry */ >+ n = ntohl(a->addr32[3 - i]) + 1; >+ a->addr32[3 - i] = htonl(n); >+ if (n != 0) >+ break; >+ } >+ break; >+ } >+} >+ > /* > * Test whether host portion of address 'a', as determined by 'masklen' > * is all zeros. >@@ -293,6 +338,30 @@ addr_host_is_all0s(const struct xaddr *a, u_int masklen) > return addr_is_all0s(&tmp_result); > } > >+int >+addr_host_to_all0s(struct xaddr *a, u_int masklen) >+{ >+ struct xaddr tmp_mask; >+ >+ if (addr_netmask(a->af, masklen, &tmp_mask) == -1) >+ return (-1); >+ if (addr_and(a, a, &tmp_mask) == -1) >+ return (-1); >+ return (0); >+} >+ >+int >+addr_host_to_all1s(struct xaddr *a, u_int masklen) >+{ >+ struct xaddr tmp_mask; >+ >+ if (addr_hostmask(a->af, masklen, &tmp_mask) == -1) >+ return (-1); >+ if (addr_or(a, a, &tmp_mask) == -1) >+ return (-1); >+ return (0); >+} >+ > /* > * Parse string address 'p' into 'n'. > * Returns 0 on success, -1 on failure. >diff --git a/addr.h b/addr.h >index 5eff026..180e9fd 100644 >--- a/addr.h >+++ b/addr.h >@@ -52,9 +52,13 @@ int addr_sa_pton(const char *h, const char *s, struct sockaddr *sa, > int addr_pton_cidr(const char *p, struct xaddr *n, u_int *l); > int addr_ntop(const struct xaddr *n, char *p, size_t len); > int addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b); >+int addr_or(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b); > int addr_cmp(const struct xaddr *a, const struct xaddr *b); > int addr_is_all0s(const struct xaddr *n); > int addr_host_is_all0s(const struct xaddr *n, u_int masklen); >+int addr_host_to_all0s(struct xaddr *a, u_int masklen); >+int addr_host_to_all1s(struct xaddr *a, u_int masklen); > int addr_netmatch(const struct xaddr *host, const struct xaddr *net, > u_int masklen); >+void addr_increment(struct xaddr *a); > #endif /* _ADDR_H */ >diff --git a/ssh-keyscan.1 b/ssh-keyscan.1 >index 4eb0bea..5dd7a9c 100644 >--- a/ssh-keyscan.1 >+++ b/ssh-keyscan.1 >@@ -44,6 +44,11 @@ For scanning, one does not need > login access to the machines that are being scanned, nor does the > scanning process involve any encryption. > .Pp >+Hosts to be scanned may be specified by hostname, address or by CIDR >+network range (e.g. 192.168.16/28). >+If a network range is specified, then all addresses in that range will >+be scanned. >+.Pp > The options are as follows: > .Bl -tag -width Ds > .It Fl 4 >@@ -73,9 +78,16 @@ If > is supplied instead of a filename, > .Nm > will read from the standard input. >-Input is expected in the format: >+Names read from a file must start with an address, hostname or CIDR network >+range to be scanned. >+Addresses and hostnames may optionally be followed by comma-separated name >+or address aliases that will be copied to the output. >+For example: > .Bd -literal >-1.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4 >+192.168.11.0/24 >+10.20.1.1 >+happy.example.org >+10.0.0.1,sad.example.org > .Ed > .It Fl H > Hash all hostnames and addresses in the output. >@@ -138,6 +150,10 @@ Print the RSA host key for machine > .Pp > .Dl $ ssh-keyscan -t rsa hostname > .Pp >+Search a network range, printing all supported key types: >+.Pp >+.Dl $ ssh-keyscan 192.168.0.64/25 >+.Pp > Find all hosts from the file > .Pa ssh_hosts > which have new or different keys from those in the sorted file >diff --git a/ssh-keyscan.c b/ssh-keyscan.c >index 1b75bbe..a5b4471 100644 >--- a/ssh-keyscan.c >+++ b/ssh-keyscan.c >@@ -44,6 +44,7 @@ > #include "ssherr.h" > #include "ssh_api.h" > #include "dns.h" >+#include "addr.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. */ >@@ -364,7 +365,7 @@ tcpconnect(char *host) > } > > static int >-conalloc(char *iname, char *oname, int keytype) >+conalloc(const char *iname, const char *oname, int keytype) > { > char *namebase, *name, *namelist; > int s; >@@ -595,7 +596,7 @@ conloop(void) > } > > static void >-do_host(char *host) >+do_one_host(char *host) > { > char *name = strnnsep(&host, " \t\n"); > int j; >@@ -611,6 +612,43 @@ do_host(char *host) > } > } > >+static void >+do_host(char *host) >+{ >+ char daddr[128]; >+ struct xaddr addr, start_addr, end_addr; >+ u_int masklen; >+ >+ if (host == NULL) >+ return; >+ if (addr_pton_cidr(host, &addr, &masklen) != 0) { >+ /* Assume argument is a hostname */ >+ do_one_host(host); >+ } else { >+ /* Argument is a CIDR range */ >+ debug("CIDR range %s", host); >+ start_addr = end_addr = addr; >+ if (addr_host_to_all0s(&start_addr, masklen) != 0 || >+ addr_host_to_all1s(&end_addr, masklen) != 0) >+ goto badaddr; >+ /* >+ * Note: we deliberately include the all-zero/ones addresses. >+ */ >+ for (;;) { >+ if (addr_ntop(&addr, daddr, sizeof(daddr)) != 0) { >+ badaddr: >+ error("Invalid address %s", host); >+ return; >+ } >+ debug("CIDR expand: address %s", daddr); >+ do_one_host(daddr); >+ if (addr_cmp(&addr, &end_addr) == 0) >+ break; >+ addr_increment(&addr); >+ }; >+ } >+} >+ > void > sshfatal(const char *file, const char *func, int line, int showfunc, > LogLevel level, const char *suffix, const char *fmt, ...)
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 976
: 3602