diff --git a/regress/lib/libcrypto/hmac/hmactest.c b/regress/lib/libcrypto/hmac/hmactest.c index f61a177e1..99b936f93 100644 --- a/regress/lib/libcrypto/hmac/hmactest.c +++ b/regress/lib/libcrypto/hmac/hmactest.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hmactest.c,v 1.7 2021/11/18 20:11:55 tb Exp $ */ +/* $OpenBSD: hmactest.c,v 1.8 2024/05/30 17:01:38 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -153,7 +153,7 @@ main(int argc, char *argv[]) for (i = 0; i < 4; i++) { p = pt(HMAC(EVP_md5(), test[i].key, test[i].key_len, - test[i].data, test[i].data_len, NULL, NULL), + test[i].data, test[i].data_len, buf, NULL), MD5_DIGEST_LENGTH); if (strcmp(p, (char *)test[i].digest) != 0) { diff --git a/usr.bin/ssh/auth2-methods.c b/usr.bin/ssh/auth2-methods.c index 4043b0958..6ceff6e12 100644 --- a/usr.bin/ssh/auth2-methods.c +++ b/usr.bin/ssh/auth2-methods.c @@ -29,13 +29,13 @@ extern ServerOptions options; /* - * Configuration of enabled authentication methods. Separate to the rest of + * Configuration of enabled authentication methods. Separate from the rest of * auth2-*.c because we want to query it during server configuration validity * checking in the sshd listener process without pulling all the auth code in * too. */ -/* "none" is allowed only one time and it cleared by userauth_none() later */ +/* "none" is allowed only one time and it is cleared by userauth_none() later */ int none_enabled = 1; struct authmethod_cfg methodcfg_none = { "none", @@ -83,7 +83,7 @@ static struct authmethod_cfg *authmethod_cfgs[] = { }; /* - * Check a comma-separated list of methods for validity. Is need_enable is + * Check a comma-separated list of methods for validity. If need_enable is * non-zero, then also require that the methods are enabled. * Returns 0 on success or -1 if the methods list is invalid. */ diff --git a/usr.bin/ssh/packet.c b/usr.bin/ssh/packet.c index 33e821c23..70c98dd0f 100644 --- a/usr.bin/ssh/packet.c +++ b/usr.bin/ssh/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.314 2024/05/17 00:30:24 djm Exp $ */ +/* $OpenBSD: packet.c,v 1.315 2024/05/31 08:49:35 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -519,7 +519,7 @@ ssh_remote_ipaddr(struct ssh *ssh) * be freed. NB. this will usually trigger a DNS query. Return value is on * heap and no caching is performed. * This function does additional checks on the hostname to mitigate some - * attacks on based on conflation of hostnames and addresses and will + * attacks based on conflation of hostnames and addresses and will * fall back to returning an address on error. */ diff --git a/usr.bin/ssh/sshd.c b/usr.bin/ssh/sshd.c index 683b0b885..c14f5966e 100644 --- a/usr.bin/ssh/sshd.c +++ b/usr.bin/ssh/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.603 2024/05/17 00:30:24 djm Exp $ */ +/* $OpenBSD: sshd.c,v 1.604 2024/05/31 09:01:08 djm Exp $ */ /* * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved. * Copyright (c) 2002 Niels Provos. All rights reserved. @@ -923,7 +923,7 @@ main(int ac, char **av) inetd_flag = 1; break; case 'r': - /* ignored */ + logit("-r option is deprecated"); break; case 'R': fatal("-R not supported here"); diff --git a/usr.sbin/rad/frontend.c b/usr.sbin/rad/frontend.c index ca8719a4a..e0beb3352 100644 --- a/usr.sbin/rad/frontend.c +++ b/usr.sbin/rad/frontend.c @@ -1,4 +1,4 @@ -/* $OpenBSD: frontend.c,v 1.46 2024/05/17 06:50:14 florian Exp $ */ +/* $OpenBSD: frontend.c,v 1.48 2024/05/31 16:10:42 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser @@ -102,6 +102,7 @@ struct ra_iface { TAILQ_ENTRY(ra_iface) entry; struct icmp6_ev *icmp6ev; struct ra_prefix_conf_head prefixes; + struct ether_addr hw_addr; char name[IF_NAMESIZE]; char conf_name[IF_NAMESIZE]; uint32_t if_index; @@ -109,6 +110,7 @@ struct ra_iface { int removed; int link_state; int prefix_count; + int ltime_decaying; size_t datalen; uint8_t data[RA_MAX_SIZE]; }; @@ -135,9 +137,8 @@ void frontend_startup(void); void icmp6_receive(int, short, void *); void join_all_routers_mcast_group(struct ra_iface *); void leave_all_routers_mcast_group(struct ra_iface *); -int get_link_state(char *); int get_ifrdomain(char *); -void merge_ra_interface(char *, char *); +void merge_ra_interface(char *, char *, struct ifaddrs *); void merge_ra_interfaces(void); struct ra_iface *find_ra_iface_by_id(uint32_t); struct ra_iface *find_ra_iface_by_name(char *); @@ -149,13 +150,13 @@ struct icmp6_ev *get_icmp6ev_by_rdomain(int); void unref_icmp6ev(struct ra_iface *); void set_icmp6sock(int, int); void add_new_prefix_to_ra_iface(struct ra_iface *r, - struct in6_addr *, int, struct ra_prefix_conf *); + struct in6_addr *, int, struct ra_prefix_conf *, + uint32_t, uint32_t); void free_ra_iface(struct ra_iface *); int in6_mask2prefixlen(struct in6_addr *); void get_interface_prefixes(struct ra_iface *, - struct ra_prefix_conf *); -int interface_has_linklocal_address(char *); -void build_packet(struct ra_iface *); + struct ra_prefix_conf *, struct ifaddrs *); +int build_packet(struct ra_iface *); void build_leaving_packet(struct ra_iface *); void ra_output(struct ra_iface *, struct sockaddr_in6 *); void get_rtaddrs(int, struct sockaddr *, @@ -736,30 +737,6 @@ find_ra_iface_conf(struct ra_iface_conf_head *head, char *if_name) return (NULL); } -int -get_link_state(char *if_name) -{ - struct ifaddrs *ifap, *ifa; - int ls = LINK_STATE_UNKNOWN; - - if (getifaddrs(&ifap) != 0) { - log_warn("getifaddrs"); - return LINK_STATE_UNKNOWN; - } - for (ifa = ifap; ifa; ifa = ifa->ifa_next) { - if (ifa->ifa_addr == NULL || - ifa->ifa_addr->sa_family != AF_LINK) - continue; - if (strcmp(if_name, ifa->ifa_name) != 0) - continue; - - ls = ((struct if_data*)ifa->ifa_data)->ifi_link_state; - break; - } - freeifaddrs(ifap); - return ls; -} - int get_ifrdomain(char *if_name) { @@ -774,27 +751,75 @@ get_ifrdomain(char *if_name) } void -merge_ra_interface(char *name, char *conf_name) +merge_ra_interface(char *if_name, char *conf_name, struct ifaddrs *ifap) { struct ra_iface *ra_iface; + struct ifaddrs *ifa; + struct sockaddr_in6 *sin6; + struct in6_ifreq ifr6; + struct sockaddr_dl *sdl; + struct ether_addr hw_addr; uint32_t if_index; - int link_state, has_linklocal, ifrdomain; + int link_state = LINK_STATE_UNKNOWN; + int has_linklocal = 0, ifrdomain; + int has_hw_addr = 0; - link_state = get_link_state(name); - has_linklocal = interface_has_linklocal_address(name); - ifrdomain = get_ifrdomain(name); + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) + continue; + if (ifa->ifa_addr->sa_family != AF_LINK && + ifa->ifa_addr->sa_family != AF_INET6) + continue; + if (strcmp(if_name, ifa->ifa_name) != 0) + continue; - if ((ra_iface = find_ra_iface_by_name(name)) != NULL) { + if (ifa->ifa_addr->sa_family == AF_LINK) { + link_state = + ((struct if_data*)ifa->ifa_data)->ifi_link_state; + sdl = (struct sockaddr_dl *)ifa->ifa_addr; + if (sdl->sdl_type == IFT_ETHER && + sdl->sdl_alen == ETHER_ADDR_LEN) { + has_hw_addr = 1; + memcpy(&hw_addr, LLADDR(sdl), ETHER_ADDR_LEN); + } + } else if (ifa->ifa_addr->sa_family == AF_INET6) { + sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; + + if (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) + continue; + + memset(&ifr6, 0, sizeof(ifr6)); + strlcpy(ifr6.ifr_name, if_name, sizeof(ifr6.ifr_name)); + memcpy(&ifr6.ifr_addr, sin6, sizeof(ifr6.ifr_addr)); + if (ioctl(ioctlsock, SIOCGIFAFLAG_IN6, + (caddr_t)&ifr6) == -1) { + log_warn("SIOCGIFAFLAG_IN6"); + continue; + } + + if (ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_TENTATIVE | + IN6_IFF_DUPLICATED)) + continue; + has_linklocal = 1; + } + } + + ifrdomain = get_ifrdomain(if_name); + + if ((ra_iface = find_ra_iface_by_name(if_name)) != NULL) { ra_iface->link_state = link_state; if (!LINK_STATE_IS_UP(link_state)) { - log_debug("%s down, removing", name); + log_debug("%s down, removing", if_name); ra_iface->removed = 1; } else if (!has_linklocal) { log_debug("%s has no IPv6 link-local address, " - "removing", name); + "removing", if_name); ra_iface->removed = 1; } else if (ifrdomain == -1) { - log_debug("can't get rdomain for %s, removing", name); + log_debug("can't get rdomain for %s, removing", if_name); + ra_iface->removed = 1; + } else if (!has_hw_addr) { + log_debug("%s has no mac address, removing", if_name); ra_iface->removed = 1; } else if (ra_iface->rdomain != ifrdomain) { leave_all_routers_mcast_group(ra_iface); @@ -804,37 +829,49 @@ merge_ra_interface(char *name, char *conf_name) join_all_routers_mcast_group(ra_iface); ra_iface->removed = 0; } else { - log_debug("keeping interface %s", name); + log_debug("keeping interface %s", if_name); ra_iface->removed = 0; } + memcpy(&ra_iface->hw_addr, &hw_addr, sizeof(hw_addr)); return; } if (!LINK_STATE_IS_UP(link_state)) { - log_debug("%s down, ignoring", name); + log_debug("%s down, ignoring", if_name); return; } if (!has_linklocal) { - log_debug("%s has no IPv6 link-local address, ignoring", name); + log_debug("%s has no IPv6 link-local address, ignoring", + if_name); return; } - log_debug("new interface %s", name); - if ((if_index = if_nametoindex(name)) == 0) + if (ifrdomain == -1) { + log_debug("can't get rdomain for %s, ignoring", if_name); + return; + } + + if (!has_hw_addr) { + log_debug("%s has no mac address, ignoring", if_name); + return; + } + + log_debug("new interface %s", if_name); + if ((if_index = if_nametoindex(if_name)) == 0) return; - log_debug("adding interface %s", name); + log_debug("adding interface %s", if_name); if ((ra_iface = calloc(1, sizeof(*ra_iface))) == NULL) fatal("%s", __func__); - strlcpy(ra_iface->name, name, sizeof(ra_iface->name)); + strlcpy(ra_iface->name, if_name, sizeof(ra_iface->name)); strlcpy(ra_iface->conf_name, conf_name, sizeof(ra_iface->conf_name)); ra_iface->if_index = if_index; ra_iface->rdomain = ifrdomain; - + memcpy(&ra_iface->hw_addr, &hw_addr, sizeof(hw_addr)); SIMPLEQ_INIT(&ra_iface->prefixes); ra_iface->icmp6ev = get_icmp6ev_by_rdomain(ifrdomain); @@ -850,9 +887,15 @@ merge_ra_interfaces(void) struct ra_iface *ra_iface; struct ifgroupreq ifgr; struct ifg_req *ifg; + struct ifaddrs *ifap; char *conf_name; unsigned int len; + if (getifaddrs(&ifap) != 0) { + log_warn("getifaddrs"); + return; + } + TAILQ_FOREACH(ra_iface, &ra_interfaces, entry) ra_iface->removed = 1; @@ -861,7 +904,7 @@ merge_ra_interfaces(void) /* check if network interface or group */ if (isdigit((unsigned char)conf_name[strlen(conf_name) - 1])) { - merge_ra_interface(conf_name, conf_name); + merge_ra_interface(conf_name, conf_name, ifap); } else { log_debug("interface group %s", conf_name); @@ -888,7 +931,7 @@ merge_ra_interfaces(void) ifg++) { len -= sizeof(struct ifg_req); merge_ra_interface(ifg->ifgrq_member, - conf_name); + conf_name, ifap); } free(ifgr.ifgr_groups); } @@ -920,15 +963,23 @@ merge_ra_interfaces(void) entry) { add_new_prefix_to_ra_iface(ra_iface, &ra_prefix_conf->prefix, - ra_prefix_conf->prefixlen, ra_prefix_conf); + ra_prefix_conf->prefixlen, ra_prefix_conf, + ND6_INFINITE_LIFETIME, ND6_INFINITE_LIFETIME); } if (ra_iface_conf->autoprefix) get_interface_prefixes(ra_iface, - ra_iface_conf->autoprefix); + ra_iface_conf->autoprefix, ifap); - build_packet(ra_iface); + if (build_packet(ra_iface)) { + /* packet changed; send new advertisements */ + if (event_initialized(&ra_iface->icmp6ev->ev)) + frontend_imsg_compose_engine(IMSG_UPDATE_IF, 0, + &ra_iface->if_index, + sizeof(ra_iface->if_index)); + } } + freeifaddrs(ifap); } void @@ -972,69 +1023,24 @@ in6_mask2prefixlen(struct in6_addr *in6) return (plen); } -int -interface_has_linklocal_address(char *name) -{ - struct ifaddrs *ifap, *ifa; - struct sockaddr_in6 *sin6; - struct in6_ifreq ifr6; - int ret = 0; - - if (getifaddrs(&ifap) != 0) - fatal("getifaddrs"); - - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { - if (strcmp(name, ifa->ifa_name) != 0) - continue; - if (ifa->ifa_addr == NULL || - ifa->ifa_addr->sa_family != AF_INET6) - continue; - - sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; - - if (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) - continue; - - memset(&ifr6, 0, sizeof(ifr6)); - strlcpy(ifr6.ifr_name, name, sizeof(ifr6.ifr_name)); - memcpy(&ifr6.ifr_addr, sin6, sizeof(ifr6.ifr_addr)); - if (ioctl(ioctlsock, SIOCGIFAFLAG_IN6, (caddr_t)&ifr6) == -1) { - log_warn("SIOCGIFAFLAG_IN6"); - continue; - } - - if (ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_TENTATIVE | - IN6_IFF_DUPLICATED)) - continue; - - ret = 1; - break; - } - freeifaddrs(ifap); - return (ret); -} - void get_interface_prefixes(struct ra_iface *ra_iface, struct ra_prefix_conf - *autoprefix) + *autoprefix_conf, struct ifaddrs *ifap) { struct in6_ifreq ifr6; - struct ifaddrs *ifap, *ifa; + struct ifaddrs *ifa; struct sockaddr_in6 *sin6; + uint32_t decaying_vltime, decaying_pltime; int prefixlen; - log_debug("%s: %s", __func__, ra_iface->name); - - if (getifaddrs(&ifap) != 0) - fatal("getifaddrs"); - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { - if (strcmp(ra_iface->name, ifa->ifa_name) != 0) - continue; if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET6) continue; + if (strcmp(ra_iface->name, ifa->ifa_name) != 0) + continue; + sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) @@ -1044,6 +1050,24 @@ get_interface_prefixes(struct ra_iface *ra_iface, struct ra_prefix_conf strlcpy(ifr6.ifr_name, ra_iface->name, sizeof(ifr6.ifr_name)); memcpy(&ifr6.ifr_addr, sin6, sizeof(ifr6.ifr_addr)); + decaying_vltime = ND6_INFINITE_LIFETIME; + decaying_pltime = ND6_INFINITE_LIFETIME; + + if (ioctl(ioctlsock, SIOCGIFALIFETIME_IN6, + (caddr_t)&ifr6) != -1) { + struct in6_addrlifetime *lifetime; + + lifetime = &ifr6.ifr_ifru.ifru_lifetime; + if (lifetime->ia6t_preferred) + decaying_pltime = lifetime->ia6t_preferred; + if (lifetime->ia6t_expire) + decaying_vltime = lifetime->ia6t_expire; + } + + memset(&ifr6, 0, sizeof(ifr6)); + strlcpy(ifr6.ifr_name, ra_iface->name, sizeof(ifr6.ifr_name)); + memcpy(&ifr6.ifr_addr, sin6, sizeof(ifr6.ifr_addr)); + if (ioctl(ioctlsock, SIOCGIFNETMASK_IN6, (caddr_t)&ifr6) == -1) continue; /* addr got deleted while we were looking */ @@ -1056,9 +1080,9 @@ get_interface_prefixes(struct ra_iface *ra_iface, struct ra_prefix_conf mask_prefix(&sin6->sin6_addr, prefixlen); add_new_prefix_to_ra_iface(ra_iface, &sin6->sin6_addr, - prefixlen, autoprefix); + prefixlen, autoprefix_conf, decaying_vltime, + decaying_pltime); } - freeifaddrs(ifap); } struct ra_prefix_conf* @@ -1078,13 +1102,41 @@ find_ra_prefix_conf(struct ra_prefix_conf_head* head, struct in6_addr *prefix, void add_new_prefix_to_ra_iface(struct ra_iface *ra_iface, struct in6_addr *addr, - int prefixlen, struct ra_prefix_conf *ra_prefix_conf) + int prefixlen, struct ra_prefix_conf *ra_prefix_conf, + uint32_t decaying_vltime, uint32_t decaying_pltime) { struct ra_prefix_conf *new_ra_prefix_conf; - if (find_ra_prefix_conf(&ra_iface->prefixes, addr, prefixlen)) { - log_debug("ignoring duplicate %s/%d prefix", - in6_to_str(addr), prefixlen); + if ((new_ra_prefix_conf = find_ra_prefix_conf(&ra_iface->prefixes, addr, + prefixlen)) != NULL) { + if (decaying_vltime != ND6_INFINITE_LIFETIME || + decaying_pltime != ND6_INFINITE_LIFETIME) { + ra_iface->ltime_decaying = 1; + new_ra_prefix_conf->ltime_decaying = 0; + if (decaying_vltime != ND6_INFINITE_LIFETIME) { + new_ra_prefix_conf->vltime = decaying_vltime; + new_ra_prefix_conf->ltime_decaying |= + VLTIME_DECAYING; + } + if (decaying_pltime != ND6_INFINITE_LIFETIME) { + new_ra_prefix_conf->pltime = decaying_pltime; + new_ra_prefix_conf->ltime_decaying |= + PLTIME_DECAYING; + } + } else if (new_ra_prefix_conf->ltime_decaying) { + struct ra_prefix_conf *pc; + + new_ra_prefix_conf->ltime_decaying = 0; + ra_iface->ltime_decaying = 0; + SIMPLEQ_FOREACH(pc, &ra_iface->prefixes, entry) { + if (pc->ltime_decaying) { + ra_iface->ltime_decaying = 1; + break; + } + } + } else + log_debug("ignoring duplicate %s/%d prefix", + in6_to_str(addr), prefixlen); return; } @@ -1096,13 +1148,25 @@ add_new_prefix_to_ra_iface(struct ra_iface *ra_iface, struct in6_addr *addr, new_ra_prefix_conf->prefixlen = prefixlen; new_ra_prefix_conf->vltime = ra_prefix_conf->vltime; new_ra_prefix_conf->pltime = ra_prefix_conf->pltime; + if (decaying_vltime != ND6_INFINITE_LIFETIME || + decaying_pltime != ND6_INFINITE_LIFETIME) { + ra_iface->ltime_decaying = 1; + if (decaying_vltime != ND6_INFINITE_LIFETIME) { + new_ra_prefix_conf->vltime = decaying_vltime; + new_ra_prefix_conf->ltime_decaying |= VLTIME_DECAYING; + } + if (decaying_pltime != ND6_INFINITE_LIFETIME) { + new_ra_prefix_conf->pltime = decaying_pltime; + new_ra_prefix_conf->ltime_decaying |= PLTIME_DECAYING; + } + } new_ra_prefix_conf->aflag = ra_prefix_conf->aflag; new_ra_prefix_conf->lflag = ra_prefix_conf->lflag; SIMPLEQ_INSERT_TAIL(&ra_iface->prefixes, new_ra_prefix_conf, entry); ra_iface->prefix_count++; } -void +int build_packet(struct ra_iface *ra_iface) { struct nd_router_advert *ra; @@ -1118,16 +1182,16 @@ build_packet(struct ra_iface *ra_iface) struct ra_rdnss_conf *ra_rdnss; struct ra_dnssl_conf *ra_dnssl; struct ra_pref64_conf *pref64; - struct ifaddrs *ifap, *ifa; - struct sockaddr_dl *sdl; size_t len, label_len; + time_t t; + uint32_t vltime, pltime; uint8_t *p, buf[RA_MAX_SIZE]; char *label_start, *label_end; ra_iface_conf = find_ra_iface_conf(&frontend_conf->ra_iface_list, ra_iface->conf_name); ra_options_conf = &ra_iface_conf->ra_options; - + t = time(NULL); len = sizeof(*ra); if (ra_iface_conf->ra_options.source_link_addr) len += sizeof(*ndopt_source_link_addr); @@ -1187,30 +1251,9 @@ build_packet(struct ra_iface *ra_iface) ndopt_source_link_addr->nd_opt_source_link_addr_type = ND_OPT_SOURCE_LINKADDR; ndopt_source_link_addr->nd_opt_source_link_addr_len = 1; - if (getifaddrs(&ifap) != 0) { - ifap = NULL; - log_warn("getifaddrs"); - } - for (ifa = ifap; ifa; ifa = ifa->ifa_next) { - if (ifa->ifa_addr == NULL || - ifa->ifa_addr->sa_family != AF_LINK) - continue; - if (strcmp(ra_iface->name, ifa->ifa_name) != 0) - continue; - sdl = (struct sockaddr_dl *)ifa->ifa_addr; - if (sdl->sdl_type != IFT_ETHER || - sdl->sdl_alen != ETHER_ADDR_LEN) - continue; - memcpy(&ndopt_source_link_addr-> - nd_opt_source_link_addr_hw_addr, - LLADDR(sdl), ETHER_ADDR_LEN); - break; - } - if (ifap != NULL) { - freeifaddrs(ifap); - p += sizeof(*ndopt_source_link_addr); - } else - len -= sizeof(*ndopt_source_link_addr); + memcpy(&ndopt_source_link_addr->nd_opt_source_link_addr_hw_addr, + &ra_iface->hw_addr, ETHER_ADDR_LEN); + p += sizeof(*ndopt_source_link_addr); } if (ra_options_conf->mtu > 0) { @@ -1234,9 +1277,20 @@ build_packet(struct ra_iface *ra_iface) if (ra_prefix_conf->aflag) ndopt_pi->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO; - ndopt_pi->nd_opt_pi_valid_time = htonl(ra_prefix_conf->vltime); - ndopt_pi->nd_opt_pi_preferred_time = - htonl(ra_prefix_conf->pltime); + + if (ra_prefix_conf->ltime_decaying & VLTIME_DECAYING) + vltime = ra_prefix_conf->vltime < t ? 0 : + ra_prefix_conf->vltime - t; + else + vltime = ra_prefix_conf->vltime; + if (ra_prefix_conf->ltime_decaying & PLTIME_DECAYING) + pltime = ra_prefix_conf->pltime < t ? 0 : + ra_prefix_conf->pltime - t; + else + pltime = ra_prefix_conf->pltime; + + ndopt_pi->nd_opt_pi_valid_time = htonl(vltime); + ndopt_pi->nd_opt_pi_preferred_time = htonl(pltime); ndopt_pi->nd_opt_pi_prefix = ra_prefix_conf->prefix; p += sizeof(*ndopt_pi); @@ -1330,11 +1384,9 @@ build_packet(struct ra_iface *ra_iface) != 0) { memcpy(ra_iface->data, buf, len); ra_iface->datalen = len; - /* packet changed; tell engine to send new advertisements */ - if (event_initialized(&ra_iface->icmp6ev->ev)) - frontend_imsg_compose_engine(IMSG_UPDATE_IF, 0, - &ra_iface->if_index, sizeof(ra_iface->if_index)); + return 1; } + return 0; } void @@ -1362,6 +1414,10 @@ ra_output(struct ra_iface *ra_iface, struct sockaddr_in6 *to) if (!LINK_STATE_IS_UP(ra_iface->link_state)) return; + if (ra_iface->ltime_decaying) + /* update vltime & pltime */ + build_packet(ra_iface); + sndmhdr.msg_name = to; sndmhdr.msg_iov[0].iov_base = ra_iface->data; sndmhdr.msg_iov[0].iov_len = ra_iface->datalen; diff --git a/usr.sbin/rad/rad.conf.5 b/usr.sbin/rad/rad.conf.5 index 87c2b3286..7c95a8cce 100644 --- a/usr.sbin/rad/rad.conf.5 +++ b/usr.sbin/rad/rad.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: rad.conf.5,v 1.24 2024/05/17 06:50:14 florian Exp $ +.\" $OpenBSD: rad.conf.5,v 1.25 2024/05/31 16:19:53 florian Exp $ .\" .\" Copyright (c) 2018 Florian Obser .\" Copyright (c) 2005 Esben Norby @@ -18,7 +18,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: May 17 2024 $ +.Dd $Mdocdate: May 31 2024 $ .Dt RAD.CONF 5 .Os .Sh NAME @@ -167,10 +167,14 @@ The default is yes. The preferred lifetime (pltime) in seconds for addresses generated from this prefix. The default is 2700. +This option is ignored if the prefix is discovered from a network interface +and it has a preferred lifetime configured. .It Ic valid lifetime Ar seconds The valid lifetime (vltime) in seconds for addresses generated from this prefix. The default is 5400. +This option is ignored if the prefix is discovered from a network interface +and it has a valid lifetime configured. .El .Sh FILES .Bl -tag -width /etc/examples/rad.conf -compact diff --git a/usr.sbin/rad/rad.h b/usr.sbin/rad/rad.h index 442ff00fc..46cdc51ea 100644 --- a/usr.sbin/rad/rad.h +++ b/usr.sbin/rad/rad.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rad.h,v 1.27 2024/05/17 06:50:14 florian Exp $ */ +/* $OpenBSD: rad.h,v 1.28 2024/05/31 16:10:42 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser @@ -35,6 +35,8 @@ #define MIN_DELAY_BETWEEN_RAS 3 /* 3 seconds */ #define MAX_SEARCH 1025 /* MAXDNAME in arpa/nameser.h */ #define DEFAULT_RDNS_LIFETIME 600 * 1.5 +#define PLTIME_DECAYING 1 +#define VLTIME_DECAYING 2 #define IMSG_DATA_SIZE(imsg) ((imsg).hdr.len - IMSG_HEADER_SIZE) @@ -114,6 +116,7 @@ struct ra_prefix_conf { int prefixlen; /* prefix length */ uint32_t vltime; /* valid lifetime */ uint32_t pltime; /* preferred lifetime */ + int ltime_decaying; int lflag; /* on-link flag*/ int aflag; /* autonom. addr flag */ }; diff --git a/usr.sbin/rpki-client/cert.c b/usr.sbin/rpki-client/cert.c index 3eb769f95..d180c6817 100644 --- a/usr.sbin/rpki-client/cert.c +++ b/usr.sbin/rpki-client/cert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cert.c,v 1.131 2024/05/20 15:51:43 claudio Exp $ */ +/* $OpenBSD: cert.c,v 1.132 2024/05/31 02:45:15 tb Exp $ */ /* * Copyright (c) 2022 Theo Buehler * Copyright (c) 2021 Job Snijders @@ -651,6 +651,28 @@ certificate_policies(const char *fn, struct cert *cert, X509_EXTENSION *ext) return rc; } +static int +cert_check_subject_and_issuer(const char *fn, const X509 *x) +{ + const X509_NAME *name; + + if ((name = X509_get_subject_name(x)) == NULL) { + warnx("%s: X509_get_subject_name", fn); + return 0; + } + if (!x509_valid_name(fn, "subject", name)) + return 0; + + if ((name = X509_get_issuer_name(x)) == NULL) { + warnx("%s: X509_get_issuer_name", fn); + return 0; + } + if (!x509_valid_name(fn, "issuer", name)) + return 0; + + return 1; +} + /* * Lightweight version of cert_parse_pre() for EE certs. * Parses the two RFC 3779 extensions, and performs some sanity checks. @@ -671,7 +693,7 @@ cert_parse_ee_cert(const char *fn, int talid, X509 *x) goto out; } - if (!x509_valid_subject(fn, x)) + if (!cert_check_subject_and_issuer(fn, x)) goto out; if (X509_get_key_usage(x) != KU_DIGITAL_SIGNATURE) { @@ -791,7 +813,7 @@ cert_parse_pre(const char *fn, const unsigned char *der, size_t len) goto out; } - if (!x509_valid_subject(fn, x)) + if (!cert_check_subject_and_issuer(fn, x)) goto out; /* Look for X509v3 extensions. */ diff --git a/usr.sbin/rpki-client/crl.c b/usr.sbin/rpki-client/crl.c index 45eaa623c..6896b6f67 100644 --- a/usr.sbin/rpki-client/crl.c +++ b/usr.sbin/rpki-client/crl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: crl.c,v 1.35 2024/05/29 13:26:24 tb Exp $ */ +/* $OpenBSD: crl.c,v 1.36 2024/05/31 02:45:15 tb Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -166,6 +166,7 @@ crl_parse(const char *fn, const unsigned char *der, size_t len) const unsigned char *oder; struct crl *crl; const X509_ALGOR *palg; + const X509_NAME *name; const ASN1_OBJECT *cobj; const ASN1_TIME *at; int count, nid, rc = 0; @@ -192,6 +193,13 @@ crl_parse(const char *fn, const unsigned char *der, size_t len) goto out; } + if ((name = X509_CRL_get_issuer(crl->x509_crl)) == NULL) { + warnx("%s: X509_CRL_get_issuer", fn); + goto out; + } + if (!x509_valid_name(fn, "issuer", name)) + goto out; + X509_CRL_get0_signature(crl->x509_crl, NULL, &palg); if (palg == NULL) { warnx("%s: X509_CRL_get0_signature", fn); diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h index 6a871baad..46c64afc9 100644 --- a/usr.sbin/rpki-client/extern.h +++ b/usr.sbin/rpki-client/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.219 2024/05/29 13:26:24 tb Exp $ */ +/* $OpenBSD: extern.h,v 1.220 2024/05/31 02:45:15 tb Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -917,7 +917,7 @@ int x509_location(const char *, const char *, const char *, GENERAL_NAME *, char **); int x509_inherits(X509 *); int x509_any_inherits(X509 *); -int x509_valid_subject(const char *, const X509 *); +int x509_valid_name(const char *, const char *, const X509_NAME *); time_t x509_find_expires(time_t, struct auth *, struct crl_tree *); /* printers */ diff --git a/usr.sbin/rpki-client/x509.c b/usr.sbin/rpki-client/x509.c index d3d3a6c6a..0b28d6ee4 100644 --- a/usr.sbin/rpki-client/x509.c +++ b/usr.sbin/rpki-client/x509.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x509.c,v 1.88 2024/05/29 13:26:24 tb Exp $ */ +/* $OpenBSD: x509.c,v 1.90 2024/05/31 11:27:34 tb Exp $ */ /* * Copyright (c) 2022 Theo Buehler * Copyright (c) 2021 Claudio Jeker @@ -842,24 +842,18 @@ x509_location(const char *fn, const char *descr, const char *proto, } /* - * Check that the subject only contains commonName and serialNumber. + * Check that subject or issuer only contain commonName and serialNumber. * Return 0 on failure. */ int -x509_valid_subject(const char *fn, const X509 *x) +x509_valid_name(const char *fn, const char *descr, const X509_NAME *xn) { - const X509_NAME *xn; const X509_NAME_ENTRY *ne; const ASN1_OBJECT *ao; const ASN1_STRING *as; int cn = 0, sn = 0; int i, nid; - if ((xn = X509_get_subject_name(x)) == NULL) { - warnx("%s: X509_get_subject_name", fn); - return 0; - } - for (i = 0; i < X509_NAME_entry_count(xn); i++) { if ((ne = X509_NAME_get_entry(xn, i)) == NULL) { warnx("%s: X509_NAME_get_entry", fn); @@ -874,8 +868,8 @@ x509_valid_subject(const char *fn, const X509 *x) switch (nid) { case NID_commonName: if (cn++ > 0) { - warnx("%s: duplicate commonName in subject", - fn); + warnx("%s: duplicate commonName in %s", + fn, descr); return 0; } if ((as = X509_NAME_ENTRY_get_data(ne)) == NULL) { @@ -888,6 +882,10 @@ x509_valid_subject(const char *fn, const X509 *x) * https://lists.afrinic.net/pipermail/dbwg/2023-March/000436.html */ #if 0 + /* + * XXX - For some reason RFC 8209, section 3.1.1 decided + * to allow UTF8String for BGPsec Router Certificates. + */ if (ASN1_STRING_type(as) != V_ASN1_PRINTABLESTRING) { warnx("%s: RFC 6487 section 4.5: commonName is" " not PrintableString", fn); @@ -897,8 +895,8 @@ x509_valid_subject(const char *fn, const X509 *x) break; case NID_serialNumber: if (sn++ > 0) { - warnx("%s: duplicate serialNumber in subject", - fn); + warnx("%s: duplicate serialNumber in %s", + fn, descr); return 0; } break; @@ -907,14 +905,14 @@ x509_valid_subject(const char *fn, const X509 *x) return 0; default: warnx("%s: RFC 6487 section 4.5: unexpected attribute" - " %s", fn, nid2str(nid)); + " %s in %s", fn, nid2str(nid), descr); return 0; } } if (cn == 0) { - warnx("%s: RFC 6487 section 4.5: subject missing commonName", - fn); + warnx("%s: RFC 6487 section 4.5: %s missing commonName", + fn, descr); return 0; }