sync with OpenBSD -current
This commit is contained in:
parent
e0194c3e7d
commit
7c962f73cd
11 changed files with 270 additions and 179 deletions
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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 <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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 <florian@openbsd.org>
|
||||
|
@ -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;
|
||||
|
|
|
@ -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 <florian@openbsd.org>
|
||||
.\" Copyright (c) 2005 Esben Norby <norby@openbsd.org>
|
||||
|
@ -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
|
||||
|
|
|
@ -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 <florian@openbsd.org>
|
||||
|
@ -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 */
|
||||
};
|
||||
|
|
|
@ -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 <tb@openbsd.org>
|
||||
* Copyright (c) 2021 Job Snijders <job@openbsd.org>
|
||||
|
@ -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. */
|
||||
|
|
|
@ -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 <kristaps@bsd.lv>
|
||||
*
|
||||
|
@ -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);
|
||||
|
|
|
@ -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 <kristaps@bsd.lv>
|
||||
*
|
||||
|
@ -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 */
|
||||
|
|
|
@ -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 <tb@openbsd.org>
|
||||
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue