Fix to consider explicitly configured hosts to be probled for servers. Add -S

This commit is contained in:
Richard Frith-Macdonald 2020-02-17 15:30:21 +00:00
parent c8cfcec652
commit 31f277d751
4 changed files with 183 additions and 12 deletions

View file

@ -1,3 +1,11 @@
2020-02-17 Richard Frith-Macdonald <rfm@gnu.org>
* Tools/gdomap.c: When building the list of hosts to be probed to see
if they have gdomap servers, fix code to include those explicitly
defined in the config file. Add -S option to list the addresses of
the known gdomap servers.
* Tools/gdomap.8: Document the new command line option.
2020-02-11 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/Foundation/NSXPCConnection.h: remove unistd.h since

View file

@ -859,9 +859,9 @@ typedef enum {
host = [NSHost hostWithAddress: addr];
return (NSPort*)[NSSocketPort portWithNumber: portNum
onHost: host
forceAddress: addr
listener: NO];
onHost: host
forceAddress: addr
listener: NO];
}
else
{

View file

@ -23,6 +23,7 @@ gdomap \- GNUstep Distributed Objects name server
.IR number ]
.RB [ -R
.IR name ]
.RB [ -S ]
.RB [ -T
.IR type ]
.RB [ -U
@ -117,6 +118,9 @@ port number required for
option.
.IP "\fB-R \fIname"
register name locally then quit.
.B -S
.IP "\fB-S"
list the addresses of all gdomap servers known to host
.IP "\fB-T \fItype"
port type for
.B -L

View file

@ -412,6 +412,27 @@ is_local_host(struct in_addr a)
return 0;
}
static int
is_probe_host(struct in_addr a)
{
if (plist)
{
plentry *p;
/* Hosts explicitly configured to be probed are ones we treat
* as being part of our LAN and therefore trusted.
*/
for (p = plist; p != 0; p = p->next)
{
if (a.s_addr == p->addr.s_addr)
{
return 1;
}
}
}
return 0;
}
static int
is_local_net(struct in_addr a)
{
@ -930,7 +951,7 @@ prb_add(struct in_addr *p)
{
return;
}
if (is_local_net(*p) == 0)
if (is_local_net(*p) == 0 && is_probe_host(*p) == 0)
{
return;
}
@ -3100,12 +3121,11 @@ handle_request(int desc)
unsigned int i;
unsigned int j;
/*
* See if this is a request from a local process.
/* See if this is a request from a local process.
*
* This request is only useful locally. Do not allow remote
* requests for the server list. Our response can be large,
* so it would make a great UDP amplification attack.
* This request is only useful locally. Do not allow remote
* requests for the server list. Our response can be large,
* so it would make a great UDP amplification attack.
*/
if (is_local_host(ri->addr.sin_addr) == 0)
{
@ -4403,6 +4423,135 @@ donames(const char *host)
free(b);
}
static void
doservers(const char *host)
{
struct sockaddr_in sin;
unsigned short p;
unsigned short num = 0;
int rval;
uptr b;
char *first_dot = 0;
if (host == 0 || *host == '\0')
{
/*
* If no host name is given, we use the name of the local host.
*/
first_dot = strchr(local_hostname, '.');
if (first_dot)
{
*first_dot = '\0';
}
host = local_hostname;
}
memset((char*)&sin, '\0', sizeof(sin));
sin.sin_family = AF_INET;
#if GDOMAP_PORT_OVERRIDE
p = htons(GDOMAP_PORT_OVERRIDE);
#else
{
struct servent *sp;
/*
* Ensure we have port number to connect to name server.
* The TCP service name 'gdomap' overrides the default port.
*/
if ((sp = getservbyname("gdomap", "tcp")) != 0)
{
p = sp->s_port; /* Network byte order. */
}
else
{
p = htons(GDOMAP_PORT);
}
}
#endif
sin.sin_port = p;
#if HAVE_GETADDRINFO
{
struct addrinfo hints;
struct addrinfo *info;
int err;
memset(&hints, '\0', sizeof(hints));
hints.ai_family = AF_INET;
if ((err = getaddrinfo(host, NULL, &hints, &info) != 0) && first_dot != 0)
{
*first_dot = '.';
err = getaddrinfo(host, NULL, &hints, &info);
}
if (err != 0)
{
snprintf(ebuf, sizeof(ebuf),
"getaddrinfo('%s') failed: %s", host, gai_strerror(err));
gdomap_log(LOG_ERR);
return;
}
sin.sin_addr = ((struct sockaddr_in *)info->ai_addr)->sin_addr;
freeaddrinfo(info);
}
#else
{
struct hostent *hp;
if ((hp = gethostbyname(host)) == 0 && first_dot != 0)
{
*first_dot = '.';
hp = gethostbyname(host);
}
if (hp == 0)
{
snprintf(ebuf, sizeof(ebuf),
"gethostbyname('%s') failed: %s", host, strerror(errno));
gdomap_log(LOG_ERR);
return;
}
if (hp->h_addrtype != AF_INET)
{
snprintf(ebuf, sizeof(ebuf),
"non-internet network not supported for %s", host);
gdomap_log(LOG_ERR);
return;
}
memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
}
#endif
rval = tryHost(GDO_SERVERS, 0, 0, 0, &sin, &num, (uptr*)&b);
if (rval != 0)
{
snprintf(ebuf, sizeof(ebuf), "failed to contact gdomap on %s(%s) - %s",
local_hostname, inet_ntoa(sin.sin_addr), strerror(errno));
gdomap_log(LOG_ERR);
return;
}
if (num == 0)
{
snprintf(ebuf, sizeof(ebuf), "No servers currently known to gdomap");
gdomap_log(LOG_INFO);
}
else
{
struct in_addr *p = (struct in_addr*)(b + 4);
snprintf(ebuf, sizeof(ebuf), "Known servers are -");
gdomap_log(LOG_INFO);
while (num-- > 0)
{
snprintf(ebuf, sizeof(ebuf), " %s", inet_ntoa(*p));
gdomap_log(LOG_INFO);
p++;
}
}
free(b);
}
static void
doregister(const char *name, int port, int ptype)
{
@ -4478,6 +4627,7 @@ static void do_help(int argc, char **argv, char *options)
printf("-N list all names registered on host\n");
printf("-P number port number required for R option.\n");
printf("-R name register name locally then quit.\n");
printf("-S list all gdomap servers known to host\n");
printf("-T type port type for L, R and U options -\n");
printf(" tcp_gdo, udp_gdo,\n");
printf(" tcp_foreign, udp_foreign.\n");
@ -4594,9 +4744,9 @@ main(int argc, char** argv)
{
extern char *optarg;
#if defined(__MINGW__)
char *options = "-CHI:L:M:NP:R:T:U:a:bc:dfi:p";
char *options = "-CHI:L:M:NP:R:ST:U:a:bc:dfi:p";
#else
char *options = "-CHI:L:M:NP:R:T:U:a:bc:dfi:j:p";
char *options = "-CHI:L:M:NP:R:ST:U:a:bc:dfi:j:p";
const char *jail = 0;
#endif
int c;
@ -4605,6 +4755,7 @@ main(int argc, char** argv)
const char *machine = 0;
const char *lookupf = 0;
int donamesf = 0;
int doserversf = 0;
#if defined(__MINGW__)
WORD wVersionRequested;
@ -4726,6 +4877,10 @@ printf(
doregister(optarg, port, ptype);
exit(EXIT_SUCCESS);
case 'S':
doserversf = 1;
break;
case 'T':
if (strcmp(optarg, "tcp_gdo") == 0)
{
@ -4938,12 +5093,16 @@ printf(
exit(EXIT_SUCCESS);
}
}
if (donamesf || lookupf)
if (donamesf || doserversf || lookupf)
{
if (donamesf)
{
donames(machine);
}
if (doserversf)
{
doservers(machine);
}
if (lookupf)
{
lookup(lookupf, machine, ptype);