From baa06aeb963965b4b6a8a8051ec15b72372080dd Mon Sep 17 00:00:00 2001 From: Stephen Early Date: Wed, 26 Sep 2001 00:19:00 +0100 Subject: [PATCH] Import release 0.1.0 --- INSTALL | 2 + Makefile.in | 2 +- NOTES | 15 +++-- TODO | 7 +- netlink.c | 181 ++++++++++++++++++++++++++++++---------------------- rsa.c | 12 +++- secnet.c | 17 ++++- secnet.h | 17 +++-- site.c | 3 +- udp.c | 58 +++++++++-------- util.c | 31 ++++++++- 11 files changed, 225 insertions(+), 120 deletions(-) diff --git a/INSTALL b/INSTALL index db1fabf..af48a93 100644 --- a/INSTALL +++ b/INSTALL @@ -7,6 +7,8 @@ VERSIONS. PROTOCOL COMPATIBILITY WAS BROKEN BETWEEN secnet-0.06, secnet-0.07 AND secnet-0.08 FOR ENDIANNESS FIXES. +THERE WILL BE ANOTHER CHANGE IN PROTOCOL IN THE secnet-0.1.x SERIES + * Preparation ** System software support diff --git a/Makefile.in b/Makefile.in index 5465a36..a06fcae 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,7 +18,7 @@ .PHONY: all clean realclean dist install PACKAGE:=secnet -VERSION:=0.09 +VERSION:=0.1.0 @SET_MAKE@ diff --git a/NOTES b/NOTES index a815905..8e53ac7 100644 --- a/NOTES +++ b/NOTES @@ -77,14 +77,14 @@ is always fresh. Messages: -1) A->B: *,iA,msg1,A,B,nA +1) A->B: *,iA,msg1,A,B,protorange-A,nA -2) B->A: iA,iB,msg2,B,A,nB,nA +2) B->A: iA,iB,msg2,B,A,chosen-protocol,nB,nA (The order of B and A reverses in alternate messages so that the same code can be used to construct them...) -3) A->B: {iB,iA,msg3,A,B,nA,nB,g^x mod m}_PK_A^-1 +3) A->B: {iB,iA,msg3,A,B,protorange-A,chosen-protocol,nA,nB,g^x mod m}_PK_A^-1 If message 1 was a replay then A will not generate message 3, because it doesn't recognise nA. @@ -92,11 +92,18 @@ it doesn't recognise nA. If message 2 was from an attacker then B will not generate message 4, because it doesn't recognise nB. -4) B->A: {iA,iB,msg4,B,A,nB,nA,g^y mod m}_PK_B^-1 +If an attacker is trying to manipulate the chosen protocol, B can spot +this when it sees A's message 3. + +4) B->A: {iA,iB,msg4,B,A,protorange-B,chosen-protocol,nB,nA,g^y mod m}_PK_B^-1 At this point, A and B share a key, k. B must keep retransmitting message 4 until it receives a packet encrypted using key k. +A can abandon the exchange if the chosen protocol is not the one that +it would have chosen knowing the acceptable protocol ranges of A and +B. + 5) A: iB,iA,msg5,(ping/msg5)_k 6) B: iA,iB,msg6,(pong/msg6)_k diff --git a/TODO b/TODO index 3f5f028..071a716 100644 --- a/TODO +++ b/TODO @@ -20,11 +20,10 @@ secnet.c: done site.c: the site_incoming() routing could be implemented much more cleanly using a table. There's still quite a lot of redundancy in this -file. Abandon key exchanges when a bad packet is received. Tell -netlink link is down if it's down and we don't have address for other -end. +file. Abandon key exchanges when a bad packet is received. Modify +protocol to include version fields, as described in the NOTES file. -transform.c: done. Needs checking for endianness problems. +transform.c: done. JDA reports endianness problems are fixed. udp.c: done diff --git a/netlink.c b/netlink.c index 3fbc3cf..0cbb27d 100644 --- a/netlink.c +++ b/netlink.c @@ -1,18 +1,19 @@ /* User-kernel network link */ -/* We will eventually support a variety of methods for extracting - packets from the kernel: userv-ipif, ipif on its own (when we run - as root), the kernel TUN driver, SLIP to a pty, an external netlink - daemon. There is a performance/security tradeoff. */ +/* We support a variety of methods for extracting packets from the + kernel: userv-ipif, ipif on its own (when we run as root), the + kernel TUN driver. Possible future methods: SLIP to a pty, an + external netlink daemon. There is a performance/security + tradeoff. */ /* When dealing with SLIP (to a pty, or ipif) we have separate rx, tx - and client buffers. When receiving we may read() any amount, not - just whole packets. When transmitting we need to bytestuff anyway, + and client buffers. When receiving we may read() any amount, not + just whole packets. When transmitting we need to bytestuff anyway, and may be part-way through receiving. */ -/* Each netlink device is actually a router, with its own IP - address. We do things like decreasing the TTL and recalculating the - header checksum, generating ICMP, responding to pings, etc. */ +/* Each netlink device is actually a router, with its own IP address. + We do things like decreasing the TTL and recalculating the header + checksum, generating ICMP, responding to pings, etc. */ /* This is where we have the anti-spoofing paranoia - before sending a packet to the kernel we check that the tunnel it came over could @@ -31,7 +32,7 @@ #include #endif -/* XXX where do we find if_tun on other architectures? */ +/* XXX where do we find if_tun on other platforms? */ #define DEFAULT_BUFSIZE 2048 #define DEFAULT_MTU 1000 @@ -63,6 +64,7 @@ struct netlink { uint32_t max_start_pad; uint32_t max_end_pad; struct subnet_list networks; + struct subnet_list exclude_remote_networks; uint32_t local_address; /* host interface address */ uint32_t secnet_address; /* our own address */ uint32_t mtu; @@ -534,6 +536,20 @@ static void *netlink_regnets(void *sst, struct subnet_list *nets, "max_start_pad=%d, max_end_pad=%d\n", nets->entries,max_start_pad,max_end_pad); + /* Check that nets does not intersect with st->networks or + st->exclude_remote_networks; refuse to register if it does. */ + if (subnet_lists_intersect(&st->networks,nets)) { + Message(M_ERROR,"%s: site %s specifies networks that " + "intersect with our local networks\n",st->name,client_name); + return False; + } + if (subnet_lists_intersect(&st->exclude_remote_networks,nets)) { + Message(M_ERROR,"%s: site %s specifies networks that " + "intersect with the explicitly excluded remote networks\n", + st->name,client_name); + return False; + } + c=safe_malloc(sizeof(*c),"netlink_regnets"); c->networks=nets; c->deliver=deliver; @@ -571,13 +587,15 @@ static netlink_deliver_fn *netlink_init(struct netlink *st, if (!st->name) st->name=description; dict_read_subnet_list(dict, "networks", True, "netlink", loc, &st->networks); + dict_read_subnet_list(dict, "exclude-remote-networks", False, "netlink", + loc, &st->exclude_remote_networks); + /* local-address and secnet-address do not have to be in local-networks; + however, they should be advertised in the 'sites' file for the + local site. */ st->local_address=string_to_ipaddr( dict_find_item(dict,"local-address", True, "netlink", loc),"netlink"); st->secnet_address=string_to_ipaddr( dict_find_item(dict,"secnet-address", True, "netlink", loc),"netlink"); - if (!subnet_match(&st->networks,st->local_address)) { - cfgfatal(loc,"netlink","local-address must be in local networks\n"); - } st->mtu=dict_read_number(dict, "mtu", False, "netlink", loc, DEFAULT_MTU); buffer_new(&st->icmp,ICMP_BUFSIZE); @@ -842,6 +860,8 @@ struct tun { string_t interface_name; string_t ifconfig_path; string_t route_path; + bool_t tun_old; + bool_t search_for_if; /* Applies to tun-old only */ struct buffer_if *buff; /* We receive packets into here and send them to the netlink code. */ netlink_deliver_fn *netlink_to_tunnel; @@ -906,6 +926,65 @@ static void tun_phase_hook(void *sst, uint32_t newphase) struct netlink_client *c; int i; + if (st->tun_old) { + if (st->search_for_if) { + string_t dname; + int i; + + /* ASSERT st->interface_name */ + dname=safe_malloc(strlen(st->device_path)+4,"tun_old_apply"); + st->interface_name=safe_malloc(8,"tun_phase_hook"); + + for (i=0; i<255; i++) { + sprintf(dname,"%s%d",st->device_path,i); + if ((st->fd=open(dname,O_RDWR))>0) { + sprintf(st->interface_name,"tun%d",i); + Message(M_INFO,"%s: allocated network interface %s " + "through %s\n",st->nl.name,st->interface_name, + dname); + break; + } + } + if (st->fd==-1) { + fatal("%s: unable to open any TUN device (%s...)\n", + st->nl.name,st->device_path); + } + } else { + st->fd=open(st->device_path,O_RDWR); + if (st->fd==-1) { + fatal_perror("%s: unable to open TUN device file %s", + st->nl.name,st->device_path); + } + } + } else { +#ifdef HAVE_LINUX_IF_H + struct ifreq ifr; + + /* New TUN interface: open the device, then do ioctl TUNSETIFF + to set or find out the network interface name. */ + st->fd=open(st->device_path,O_RDWR); + if (st->fd==-1) { + fatal_perror("%s: can't open device file %s",st->nl.name, + st->device_path); + } + memset(&ifr,0,sizeof(ifr)); + ifr.ifr_flags = IFF_TUN | IFF_NO_PI; /* Just send/receive IP packets, + no extra headers */ + if (st->interface_name) + strncpy(ifr.ifr_name,st->interface_name,IFNAMSIZ); + if (ioctl(st->fd,TUNSETIFF,&ifr)<0) { + fatal_perror("%s: ioctl(TUNSETIFF)",st->nl.name); + } + if (!st->interface_name) { + st->interface_name=safe_malloc(strlen(ifr.ifr_name)+1,"tun_apply"); + strcpy(st->interface_name,ifr.ifr_name); + Message(M_INFO,"%s: allocated network interface %s\n",st->nl.name, + st->interface_name); + } +#else + fatal("netlink.c:tun_phase_hook:!tun_old unexpected\n"); +#endif /* HAVE_LINUX_IF_H */ + } /* All the networks we'll be using have been registered. Invoke ifconfig to set the TUN device's address, and route to add routes to all our networks. */ @@ -939,7 +1018,6 @@ static list_t *tun_apply(closure_t *self, struct cloc loc, dict_t *context, struct tun *st; item_t *item; dict_t *dict; - struct ifreq ifr; st=safe_malloc(sizeof(*st),"tun_apply"); @@ -954,6 +1032,7 @@ static list_t *tun_apply(closure_t *self, struct cloc loc, dict_t *context, netlink_init(&st->nl,st,loc,dict, "netlink-tun",tun_deliver_to_kernel); + st->tun_old=False; st->device_path=dict_read_string(dict,"device",False,"tun-netlink",loc); st->interface_name=dict_read_string(dict,"interface",False, "tun-netlink",loc); @@ -967,29 +1046,7 @@ static list_t *tun_apply(closure_t *self, struct cloc loc, dict_t *context, if (!st->route_path) st->route_path="route"; st->buff=find_cl_if(dict,"buffer",CL_BUFFER,True,"tun-netlink",loc); - /* New TUN interface: open the device, then do ioctl TUNSETIFF - to set or find out the network interface name. */ - st->fd=open(st->device_path,O_RDWR); - if (st->fd==-1) { - fatal_perror("%s: can't open device file %s",st->nl.name, - st->device_path); - } - memset(&ifr,0,sizeof(ifr)); - ifr.ifr_flags = IFF_TUN | IFF_NO_PI; /* Just send/receive IP packets, - no extra headers */ - if (st->interface_name) - strncpy(ifr.ifr_name,st->interface_name,IFNAMSIZ); - if (ioctl(st->fd,TUNSETIFF,&ifr)<0) { - fatal_perror("%s: ioctl(TUNSETIFF)",st->nl.name); - } - if (!st->interface_name) { - st->interface_name=safe_malloc(strlen(ifr.ifr_name)+1,"tun_apply"); - strcpy(st->interface_name,ifr.ifr_name); - Message(M_INFO,"%s: allocated network interface %s\n",st->nl.name, - st->interface_name); - } - - add_hook(PHASE_DROPPRIV,tun_phase_hook,st); + add_hook(PHASE_GETRESOURCES,tun_phase_hook,st); return new_closure(&st->nl.cl); } @@ -1001,7 +1058,6 @@ static list_t *tun_old_apply(closure_t *self, struct cloc loc, dict_t *context, struct tun *st; item_t *item; dict_t *dict; - bool_t search_for_if; st=safe_malloc(sizeof(*st),"tun_old_apply"); @@ -1019,11 +1075,12 @@ static list_t *tun_old_apply(closure_t *self, struct cloc loc, dict_t *context, netlink_init(&st->nl,st,loc,dict, "netlink-tun",tun_deliver_to_kernel); + st->tun_old=True; st->device_path=dict_read_string(dict,"device",False,"tun-netlink",loc); st->interface_name=dict_read_string(dict,"interface",False, "tun-netlink",loc); - search_for_if=dict_read_bool(dict,"interface-search",False,"tun-netlink", - loc,st->device_path==NULL); + st->search_for_if=dict_read_bool(dict,"interface-search",False, + "tun-netlink",loc,st->device_path==NULL); st->ifconfig_path=dict_read_string(dict,"ifconfig-path",False, "tun-netlink",loc); st->route_path=dict_read_string(dict,"route-path",False,"tun-netlink",loc); @@ -1038,43 +1095,17 @@ static list_t *tun_old_apply(closure_t *self, struct cloc loc, dict_t *context, 'device' as the prefix and try numbers from 0--255. If it's set to false, treat 'device' as the whole name, and require than an appropriate interface name be specified. */ - if (search_for_if) { - string_t dname; - int i; - - if (st->interface_name) { - cfgfatal(loc,"tun-old","you may not specify an interface name " - "in interface-search mode\n"); - } - dname=safe_malloc(strlen(st->device_path)+4,"tun_old_apply"); - st->interface_name=safe_malloc(8,"tun_old_apply"); - - for (i=0; i<255; i++) { - sprintf(dname,"%s%d",st->device_path,i); - if ((st->fd=open(dname,O_RDWR))>0) { - sprintf(st->interface_name,"tun%d",i); - Message(M_INFO,"%s: allocated network interface %s " - "through %s\n",st->nl.name,st->interface_name,dname); - break; - } - } - if (st->fd==-1) { - fatal("%s: unable to open any TUN device (%s...)\n", - st->nl.name,st->device_path); - } - } else { - if (!st->interface_name) { - cfgfatal(loc,"tun-old","you must specify an interface name " - "when you explicitly specify a TUN device file\n"); - } - st->fd=open(st->device_path,O_RDWR); - if (st->fd==-1) { - fatal_perror("%s: unable to open TUN device file %s", - st->nl.name,st->device_path); - } + if (st->search_for_if && st->interface_name) { + cfgfatal(loc,"tun-old","you may not specify an interface name " + "in interface-search mode\n"); } + if (!st->search_for_if && !st->interface_name) { + cfgfatal(loc,"tun-old","you must specify an interface name " + "when you explicitly specify a TUN device file\n"); + } + - add_hook(PHASE_DROPPRIV,tun_phase_hook,st); + add_hook(PHASE_GETRESOURCES,tun_phase_hook,st); return new_closure(&st->nl.cl); } diff --git a/rsa.c b/rsa.c index d1107a9..0b6f147 100644 --- a/rsa.c +++ b/rsa.c @@ -228,8 +228,15 @@ static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context, f=fopen(filename,"rb"); if (!f) { - fatal_perror("rsa-private (%s:%d): cannot open file \"%s\"", - loc.file,loc.line,filename); + if (just_check_config) { + Message(M_WARNING,"rsa-private (%s:%d): cannot open keyfile " + "\"%s\"; assuming it's valid while we check the " + "rest of the configuration\n",loc.file,loc.line,filename); + goto assume_valid; + } else { + fatal_perror("rsa-private (%s:%d): cannot open file \"%s\"", + loc.file,loc.line,filename); + } } /* Check that the ID string is correct */ @@ -327,6 +334,7 @@ static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context, free(c); mpz_clear(&e); +assume_valid: return new_closure(&st->cl); } diff --git a/secnet.c b/secnet.c index e70fbe1..be94f95 100644 --- a/secnet.c +++ b/secnet.c @@ -21,6 +21,7 @@ extern char version[]; /* Command-line options (possibly config-file options too) */ static char *configfile="/etc/secnet/secnet.conf"; +bool_t just_check_config=False; static char *userid=NULL; static uid_t uid=0; static bool_t background=True; @@ -58,10 +59,11 @@ static void parse_options(int argc, char **argv) {"quiet", 0, 0, 'f'}, {"debug", 1, 0, 'd'}, {"config", 1, 0, 'c'}, + {"just-check-config", 0, 0, 'j'}, {0,0,0,0} }; - c=getopt_long(argc, argv, "vwdnc:ft:", + c=getopt_long(argc, argv, "vwdnjc:ft:", long_options, &option_index); if (c==-1) break; @@ -75,6 +77,7 @@ static void parse_options(int argc, char **argv) " -w, --nowarnings suppress warnings\n" " -v, --verbose output extra diagnostics\n" " -c, --config=filename specify a configuration file\n" + " -j, --just-check-config stop after reading configfile\n" " -n, --nodetach do not run in background\n" " -d, --debug=item,... set debug options\n" " --help display this help and exit\n" @@ -112,6 +115,10 @@ static void parse_options(int argc, char **argv) fatal("secnet: no config filename specified"); break; + case 'j': + just_check_config=True; + break; + case '?': break; @@ -339,6 +346,14 @@ int main(int argc, char **argv) enter_phase(PHASE_SETUP); setup(config); + + if (just_check_config) { + Message(M_INFO,"configuration file check complete\n"); + exit(0); + } + + enter_phase(PHASE_GETRESOURCES); + /* Appropriate phase hooks will have been run */ enter_phase(PHASE_DROPPRIV); droppriv(); diff --git a/secnet.h b/secnet.h index 35e06d1..f0f3a3e 100644 --- a/secnet.h +++ b/secnet.h @@ -34,11 +34,19 @@ struct subnet_list { /* Match an address (in HOST byte order) with a subnet list. Returns True if matched. */ extern bool_t subnet_match(struct subnet_list *list, uint32_t address); +extern bool_t subnets_intersect(struct subnet a, struct subnet b); +extern bool_t subnet_intersects_with_list(struct subnet a, + struct subnet_list *b); +extern bool_t subnet_lists_intersect(struct subnet_list *a, + struct subnet_list *b); /***** END of shared types *****/ /***** CONFIGURATION support *****/ +extern bool_t just_check_config; /* If True then we're going to exit after + reading the configuration file */ + typedef struct dict dict_t; /* Configuration dictionary */ typedef struct closure closure_t; typedef struct item item_t; @@ -179,10 +187,11 @@ extern void register_for_poll(void *st, beforepoll_fn *before, #define PHASE_GETOPTS 1 /* Process command-line arguments */ #define PHASE_READCONFIG 2 /* Parse and process configuration file */ #define PHASE_SETUP 3 /* Process information in configuration */ -#define PHASE_DROPPRIV 4 /* Last chance for privileged operations */ -#define PHASE_RUN 5 -#define PHASE_SHUTDOWN 6 /* About to die; delete key material, etc. */ -#define NR_PHASES 7 +#define PHASE_GETRESOURCES 4 /* Obtain all external resources */ +#define PHASE_DROPPRIV 5 /* Last chance for privileged operations */ +#define PHASE_RUN 6 +#define PHASE_SHUTDOWN 7 /* About to die; delete key material, etc. */ +#define NR_PHASES 8 typedef void hook_fn(void *self, uint32_t newphase); bool_t add_hook(uint32_t phase, hook_fn *f, void *state); diff --git a/site.c b/site.c index 22f1575..efa1ebb 100644 --- a/site.c +++ b/site.c @@ -1096,7 +1096,8 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context, site() closures for all sites including our own): refuse to talk to ourselves */ if (strcmp(st->localname,st->remotename)==0) { - Message(M_INFO,"site %s: talking to ourselves!\n",st->localname); + Message(M_INFO,"site %s: local-name==name -> ignoring this site\n", + st->localname); free(st); return NULL; } diff --git a/udp.c b/udp.c index f055962..ba9f9d6 100644 --- a/udp.c +++ b/udp.c @@ -41,6 +41,7 @@ struct udp { closure_t cl; struct comm_if ops; struct cloc loc; + uint16_t port; int fd; struct buffer_if *rbuf; struct notify_list *notify; @@ -145,14 +146,40 @@ static bool_t udp_sendmsg(void *commst, struct buffer_if *buf, return True; } +static void udp_phase_hook(void *sst, uint32_t new_phase) +{ + struct udp *st=sst; + struct sockaddr_in addr; + + st->fd=socket(AF_INET, SOCK_DGRAM, 0); + if (st->fd<0) { + fatal_perror("udp (%s:%d): socket",st->loc.file,st->loc.line); + } + if (fcntl(st->fd, F_SETFL, fcntl(st->fd, F_GETFL)|O_NONBLOCK)==-1) { + fatal_perror("udp (%s:%d): fcntl(set O_NONBLOCK)", + st->loc.file,st->loc.line); + } + if (fcntl(st->fd, F_SETFD, FD_CLOEXEC)==-1) { + fatal_perror("udp (%s:%d): fcntl(set FD_CLOEXEC)", + st->loc.file,st->loc.line); + } + + memset(&addr, 0, sizeof(addr)); + addr.sin_family=AF_INET; + addr.sin_port=htons(st->port); + if (bind(st->fd, (struct sockaddr *)&addr, sizeof(addr))!=0) { + fatal_perror("udp (%s:%d): bind",st->loc.file,st->loc.line); + } + + register_for_poll(st,udp_beforepoll,udp_afterpoll,1,"udp"); +} + static list_t *udp_apply(closure_t *self, struct cloc loc, dict_t *context, list_t *args) { struct udp *st; item_t *i; dict_t *d; - uint16_t local_port=0; - struct sockaddr_in addr; st=safe_malloc(sizeof(*st),"udp_apply(st)"); st->loc=loc; @@ -164,6 +191,7 @@ static list_t *udp_apply(closure_t *self, struct cloc loc, dict_t *context, st->ops.request_notify=request_notify; st->ops.release_notify=release_notify; st->ops.sendmsg=udp_sendmsg; + st->port=0; i=list_elem(args,0); if (!i || i->type!=t_dict) { @@ -171,32 +199,10 @@ static list_t *udp_apply(closure_t *self, struct cloc loc, dict_t *context, } d=i->data.dict; - local_port=dict_read_number(d,"port",False,"udp",st->loc,0); + st->port=dict_read_number(d,"port",True,"udp",st->loc,0); st->rbuf=find_cl_if(d,"buffer",CL_BUFFER,True,"udp",st->loc); - st->fd=socket(AF_INET, SOCK_DGRAM, 0); - if (st->fd<0) { - fatal_perror("udp_apply (%s:%d): socket",loc.file,loc.line); - } - if (fcntl(st->fd, F_SETFL, fcntl(st->fd, F_GETFL)|O_NONBLOCK)==-1) { - fatal_perror("udp_apply (%s:%d): fcntl(set O_NONBLOCK)", - loc.file,loc.line); - } - if (fcntl(st->fd, F_SETFD, FD_CLOEXEC)==-1) { - fatal_perror("udp_apply (%s:%d): fcntl(set FD_CLOEXEC)", - loc.file,loc.line); - } - - memset(&addr, 0, sizeof(addr)); - addr.sin_family=AF_INET; - if (local_port) { - addr.sin_port=htons(local_port); - } - if (bind(st->fd, (struct sockaddr *)&addr, sizeof(addr))!=0) { - fatal_perror("udp_apply (%s:%d): bind",loc.file,loc.line); - } - - register_for_poll(st,udp_beforepoll,udp_afterpoll,1,"udp"); + add_hook(PHASE_GETRESOURCES,udp_phase_hook,st); return new_closure(&st->cl); } diff --git a/util.c b/util.c index 053e81e..0ffdcdd 100644 --- a/util.c +++ b/util.c @@ -248,6 +248,31 @@ bool_t subnet_match(struct subnet_list *list, uint32_t address) return False; } +bool_t subnets_intersect(struct subnet a, struct subnet b) +{ + uint32_t mask=a.mask&b.mask; + return ((a.prefix&mask)==(b.prefix&mask)); +} + +bool_t subnet_intersects_with_list(struct subnet a, struct subnet_list *b) +{ + uint32_t i; + + for (i=0; ientries; i++) { + if (subnets_intersect(a,b->list[i])) return True; + } + return False; +} + +bool_t subnet_lists_intersect(struct subnet_list *a, struct subnet_list *b) +{ + uint32_t i; + for (i=0; ientries; i++) { + if (subnet_intersects_with_list(a->list[i],b)) return True; + } + return False; +} + /* The string buffer must be at least 16 bytes long */ string_t ipaddr_to_string(uint32_t addr) { @@ -415,6 +440,7 @@ static char *phases[NR_PHASES]={ "PHASE_GETOPTS", "PHASE_READCONFIG", "PHASE_SETUP", + "PHASE_GETRESOURCES", "PHASE_DROPPRIV", "PHASE_RUN", "PHASE_SHUTDOWN" @@ -424,12 +450,13 @@ void enter_phase(uint32_t new_phase) { struct phase_hook *i; - Message(M_DEBUG_PHASE,"entering %s... ", phases[new_phase]); + if (hooks[new_phase]) + Message(M_DEBUG_PHASE,"Running hooks for %s...\n", phases[new_phase]); current_phase=new_phase; for (i=hooks[new_phase]; i; i=i->next) i->fn(i->state, new_phase); - Message(M_DEBUG_PHASE,"now in %s\n",phases[new_phase]); + Message(M_DEBUG_PHASE,"Now in %s\n",phases[new_phase]); } bool_t add_hook(uint32_t phase, hook_fn *fn, void *state) -- 2.30.2