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)
|
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -153,7 +153,7 @@ main(int argc, char *argv[])
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
p = pt(HMAC(EVP_md5(),
|
p = pt(HMAC(EVP_md5(),
|
||||||
test[i].key, test[i].key_len,
|
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);
|
MD5_DIGEST_LENGTH);
|
||||||
|
|
||||||
if (strcmp(p, (char *)test[i].digest) != 0) {
|
if (strcmp(p, (char *)test[i].digest) != 0) {
|
||||||
|
|
|
@ -29,13 +29,13 @@
|
||||||
extern ServerOptions options;
|
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
|
* 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
|
* checking in the sshd listener process without pulling all the auth code in
|
||||||
* too.
|
* 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;
|
int none_enabled = 1;
|
||||||
struct authmethod_cfg methodcfg_none = {
|
struct authmethod_cfg methodcfg_none = {
|
||||||
"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.
|
* non-zero, then also require that the methods are enabled.
|
||||||
* Returns 0 on success or -1 if the methods list is invalid.
|
* 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>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* 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
|
* be freed. NB. this will usually trigger a DNS query. Return value is on
|
||||||
* heap and no caching is performed.
|
* heap and no caching is performed.
|
||||||
* This function does additional checks on the hostname to mitigate some
|
* 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.
|
* 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) 2000, 2001, 2002 Markus Friedl. All rights reserved.
|
||||||
* Copyright (c) 2002 Niels Provos. All rights reserved.
|
* Copyright (c) 2002 Niels Provos. All rights reserved.
|
||||||
|
@ -923,7 +923,7 @@ main(int ac, char **av)
|
||||||
inetd_flag = 1;
|
inetd_flag = 1;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
/* ignored */
|
logit("-r option is deprecated");
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
fatal("-R not supported here");
|
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>
|
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
|
||||||
|
@ -102,6 +102,7 @@ struct ra_iface {
|
||||||
TAILQ_ENTRY(ra_iface) entry;
|
TAILQ_ENTRY(ra_iface) entry;
|
||||||
struct icmp6_ev *icmp6ev;
|
struct icmp6_ev *icmp6ev;
|
||||||
struct ra_prefix_conf_head prefixes;
|
struct ra_prefix_conf_head prefixes;
|
||||||
|
struct ether_addr hw_addr;
|
||||||
char name[IF_NAMESIZE];
|
char name[IF_NAMESIZE];
|
||||||
char conf_name[IF_NAMESIZE];
|
char conf_name[IF_NAMESIZE];
|
||||||
uint32_t if_index;
|
uint32_t if_index;
|
||||||
|
@ -109,6 +110,7 @@ struct ra_iface {
|
||||||
int removed;
|
int removed;
|
||||||
int link_state;
|
int link_state;
|
||||||
int prefix_count;
|
int prefix_count;
|
||||||
|
int ltime_decaying;
|
||||||
size_t datalen;
|
size_t datalen;
|
||||||
uint8_t data[RA_MAX_SIZE];
|
uint8_t data[RA_MAX_SIZE];
|
||||||
};
|
};
|
||||||
|
@ -135,9 +137,8 @@ void frontend_startup(void);
|
||||||
void icmp6_receive(int, short, void *);
|
void icmp6_receive(int, short, void *);
|
||||||
void join_all_routers_mcast_group(struct ra_iface *);
|
void join_all_routers_mcast_group(struct ra_iface *);
|
||||||
void leave_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 *);
|
int get_ifrdomain(char *);
|
||||||
void merge_ra_interface(char *, char *);
|
void merge_ra_interface(char *, char *, struct ifaddrs *);
|
||||||
void merge_ra_interfaces(void);
|
void merge_ra_interfaces(void);
|
||||||
struct ra_iface *find_ra_iface_by_id(uint32_t);
|
struct ra_iface *find_ra_iface_by_id(uint32_t);
|
||||||
struct ra_iface *find_ra_iface_by_name(char *);
|
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 unref_icmp6ev(struct ra_iface *);
|
||||||
void set_icmp6sock(int, int);
|
void set_icmp6sock(int, int);
|
||||||
void add_new_prefix_to_ra_iface(struct ra_iface *r,
|
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 *);
|
void free_ra_iface(struct ra_iface *);
|
||||||
int in6_mask2prefixlen(struct in6_addr *);
|
int in6_mask2prefixlen(struct in6_addr *);
|
||||||
void get_interface_prefixes(struct ra_iface *,
|
void get_interface_prefixes(struct ra_iface *,
|
||||||
struct ra_prefix_conf *);
|
struct ra_prefix_conf *, struct ifaddrs *);
|
||||||
int interface_has_linklocal_address(char *);
|
int build_packet(struct ra_iface *);
|
||||||
void build_packet(struct ra_iface *);
|
|
||||||
void build_leaving_packet(struct ra_iface *);
|
void build_leaving_packet(struct ra_iface *);
|
||||||
void ra_output(struct ra_iface *, struct sockaddr_in6 *);
|
void ra_output(struct ra_iface *, struct sockaddr_in6 *);
|
||||||
void get_rtaddrs(int, struct sockaddr *,
|
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);
|
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
|
int
|
||||||
get_ifrdomain(char *if_name)
|
get_ifrdomain(char *if_name)
|
||||||
{
|
{
|
||||||
|
@ -774,27 +751,75 @@ get_ifrdomain(char *if_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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 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;
|
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);
|
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
|
||||||
has_linklocal = interface_has_linklocal_address(name);
|
if (ifa->ifa_addr == NULL)
|
||||||
ifrdomain = get_ifrdomain(name);
|
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;
|
ra_iface->link_state = link_state;
|
||||||
if (!LINK_STATE_IS_UP(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;
|
ra_iface->removed = 1;
|
||||||
} else if (!has_linklocal) {
|
} else if (!has_linklocal) {
|
||||||
log_debug("%s has no IPv6 link-local address, "
|
log_debug("%s has no IPv6 link-local address, "
|
||||||
"removing", name);
|
"removing", if_name);
|
||||||
ra_iface->removed = 1;
|
ra_iface->removed = 1;
|
||||||
} else if (ifrdomain == -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;
|
ra_iface->removed = 1;
|
||||||
} else if (ra_iface->rdomain != ifrdomain) {
|
} else if (ra_iface->rdomain != ifrdomain) {
|
||||||
leave_all_routers_mcast_group(ra_iface);
|
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);
|
join_all_routers_mcast_group(ra_iface);
|
||||||
ra_iface->removed = 0;
|
ra_iface->removed = 0;
|
||||||
} else {
|
} else {
|
||||||
log_debug("keeping interface %s", name);
|
log_debug("keeping interface %s", if_name);
|
||||||
ra_iface->removed = 0;
|
ra_iface->removed = 0;
|
||||||
}
|
}
|
||||||
|
memcpy(&ra_iface->hw_addr, &hw_addr, sizeof(hw_addr));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!LINK_STATE_IS_UP(link_state)) {
|
if (!LINK_STATE_IS_UP(link_state)) {
|
||||||
log_debug("%s down, ignoring", name);
|
log_debug("%s down, ignoring", if_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_linklocal) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug("new interface %s", name);
|
if (ifrdomain == -1) {
|
||||||
if ((if_index = if_nametoindex(name)) == 0)
|
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;
|
return;
|
||||||
|
|
||||||
log_debug("adding interface %s", name);
|
log_debug("adding interface %s", if_name);
|
||||||
if ((ra_iface = calloc(1, sizeof(*ra_iface))) == NULL)
|
if ((ra_iface = calloc(1, sizeof(*ra_iface))) == NULL)
|
||||||
fatal("%s", __func__);
|
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,
|
strlcpy(ra_iface->conf_name, conf_name,
|
||||||
sizeof(ra_iface->conf_name));
|
sizeof(ra_iface->conf_name));
|
||||||
|
|
||||||
ra_iface->if_index = if_index;
|
ra_iface->if_index = if_index;
|
||||||
ra_iface->rdomain = ifrdomain;
|
ra_iface->rdomain = ifrdomain;
|
||||||
|
memcpy(&ra_iface->hw_addr, &hw_addr, sizeof(hw_addr));
|
||||||
SIMPLEQ_INIT(&ra_iface->prefixes);
|
SIMPLEQ_INIT(&ra_iface->prefixes);
|
||||||
|
|
||||||
ra_iface->icmp6ev = get_icmp6ev_by_rdomain(ifrdomain);
|
ra_iface->icmp6ev = get_icmp6ev_by_rdomain(ifrdomain);
|
||||||
|
@ -850,9 +887,15 @@ merge_ra_interfaces(void)
|
||||||
struct ra_iface *ra_iface;
|
struct ra_iface *ra_iface;
|
||||||
struct ifgroupreq ifgr;
|
struct ifgroupreq ifgr;
|
||||||
struct ifg_req *ifg;
|
struct ifg_req *ifg;
|
||||||
|
struct ifaddrs *ifap;
|
||||||
char *conf_name;
|
char *conf_name;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
|
||||||
|
if (getifaddrs(&ifap) != 0) {
|
||||||
|
log_warn("getifaddrs");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TAILQ_FOREACH(ra_iface, &ra_interfaces, entry)
|
TAILQ_FOREACH(ra_iface, &ra_interfaces, entry)
|
||||||
ra_iface->removed = 1;
|
ra_iface->removed = 1;
|
||||||
|
|
||||||
|
@ -861,7 +904,7 @@ merge_ra_interfaces(void)
|
||||||
|
|
||||||
/* check if network interface or group */
|
/* check if network interface or group */
|
||||||
if (isdigit((unsigned char)conf_name[strlen(conf_name) - 1])) {
|
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 {
|
} else {
|
||||||
log_debug("interface group %s", conf_name);
|
log_debug("interface group %s", conf_name);
|
||||||
|
|
||||||
|
@ -888,7 +931,7 @@ merge_ra_interfaces(void)
|
||||||
ifg++) {
|
ifg++) {
|
||||||
len -= sizeof(struct ifg_req);
|
len -= sizeof(struct ifg_req);
|
||||||
merge_ra_interface(ifg->ifgrq_member,
|
merge_ra_interface(ifg->ifgrq_member,
|
||||||
conf_name);
|
conf_name, ifap);
|
||||||
}
|
}
|
||||||
free(ifgr.ifgr_groups);
|
free(ifgr.ifgr_groups);
|
||||||
}
|
}
|
||||||
|
@ -920,15 +963,23 @@ merge_ra_interfaces(void)
|
||||||
entry) {
|
entry) {
|
||||||
add_new_prefix_to_ra_iface(ra_iface,
|
add_new_prefix_to_ra_iface(ra_iface,
|
||||||
&ra_prefix_conf->prefix,
|
&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)
|
if (ra_iface_conf->autoprefix)
|
||||||
get_interface_prefixes(ra_iface,
|
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
|
void
|
||||||
|
@ -972,69 +1023,24 @@ in6_mask2prefixlen(struct in6_addr *in6)
|
||||||
return (plen);
|
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
|
void
|
||||||
get_interface_prefixes(struct ra_iface *ra_iface, struct ra_prefix_conf
|
get_interface_prefixes(struct ra_iface *ra_iface, struct ra_prefix_conf
|
||||||
*autoprefix)
|
*autoprefix_conf, struct ifaddrs *ifap)
|
||||||
{
|
{
|
||||||
struct in6_ifreq ifr6;
|
struct in6_ifreq ifr6;
|
||||||
struct ifaddrs *ifap, *ifa;
|
struct ifaddrs *ifa;
|
||||||
struct sockaddr_in6 *sin6;
|
struct sockaddr_in6 *sin6;
|
||||||
|
uint32_t decaying_vltime, decaying_pltime;
|
||||||
int prefixlen;
|
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) {
|
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
|
||||||
if (strcmp(ra_iface->name, ifa->ifa_name) != 0)
|
|
||||||
continue;
|
|
||||||
if (ifa->ifa_addr == NULL ||
|
if (ifa->ifa_addr == NULL ||
|
||||||
ifa->ifa_addr->sa_family != AF_INET6)
|
ifa->ifa_addr->sa_family != AF_INET6)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(ra_iface->name, ifa->ifa_name) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
|
sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
|
||||||
|
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_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));
|
strlcpy(ifr6.ifr_name, ra_iface->name, sizeof(ifr6.ifr_name));
|
||||||
memcpy(&ifr6.ifr_addr, sin6, sizeof(ifr6.ifr_addr));
|
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)
|
if (ioctl(ioctlsock, SIOCGIFNETMASK_IN6, (caddr_t)&ifr6) == -1)
|
||||||
continue; /* addr got deleted while we were looking */
|
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);
|
mask_prefix(&sin6->sin6_addr, prefixlen);
|
||||||
|
|
||||||
add_new_prefix_to_ra_iface(ra_iface, &sin6->sin6_addr,
|
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*
|
struct ra_prefix_conf*
|
||||||
|
@ -1078,13 +1102,41 @@ find_ra_prefix_conf(struct ra_prefix_conf_head* head, struct in6_addr *prefix,
|
||||||
|
|
||||||
void
|
void
|
||||||
add_new_prefix_to_ra_iface(struct ra_iface *ra_iface, struct in6_addr *addr,
|
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;
|
struct ra_prefix_conf *new_ra_prefix_conf;
|
||||||
|
|
||||||
if (find_ra_prefix_conf(&ra_iface->prefixes, addr, prefixlen)) {
|
if ((new_ra_prefix_conf = find_ra_prefix_conf(&ra_iface->prefixes, addr,
|
||||||
log_debug("ignoring duplicate %s/%d prefix",
|
prefixlen)) != NULL) {
|
||||||
in6_to_str(addr), prefixlen);
|
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;
|
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->prefixlen = prefixlen;
|
||||||
new_ra_prefix_conf->vltime = ra_prefix_conf->vltime;
|
new_ra_prefix_conf->vltime = ra_prefix_conf->vltime;
|
||||||
new_ra_prefix_conf->pltime = ra_prefix_conf->pltime;
|
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->aflag = ra_prefix_conf->aflag;
|
||||||
new_ra_prefix_conf->lflag = ra_prefix_conf->lflag;
|
new_ra_prefix_conf->lflag = ra_prefix_conf->lflag;
|
||||||
SIMPLEQ_INSERT_TAIL(&ra_iface->prefixes, new_ra_prefix_conf, entry);
|
SIMPLEQ_INSERT_TAIL(&ra_iface->prefixes, new_ra_prefix_conf, entry);
|
||||||
ra_iface->prefix_count++;
|
ra_iface->prefix_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
build_packet(struct ra_iface *ra_iface)
|
build_packet(struct ra_iface *ra_iface)
|
||||||
{
|
{
|
||||||
struct nd_router_advert *ra;
|
struct nd_router_advert *ra;
|
||||||
|
@ -1118,16 +1182,16 @@ build_packet(struct ra_iface *ra_iface)
|
||||||
struct ra_rdnss_conf *ra_rdnss;
|
struct ra_rdnss_conf *ra_rdnss;
|
||||||
struct ra_dnssl_conf *ra_dnssl;
|
struct ra_dnssl_conf *ra_dnssl;
|
||||||
struct ra_pref64_conf *pref64;
|
struct ra_pref64_conf *pref64;
|
||||||
struct ifaddrs *ifap, *ifa;
|
|
||||||
struct sockaddr_dl *sdl;
|
|
||||||
size_t len, label_len;
|
size_t len, label_len;
|
||||||
|
time_t t;
|
||||||
|
uint32_t vltime, pltime;
|
||||||
uint8_t *p, buf[RA_MAX_SIZE];
|
uint8_t *p, buf[RA_MAX_SIZE];
|
||||||
char *label_start, *label_end;
|
char *label_start, *label_end;
|
||||||
|
|
||||||
ra_iface_conf = find_ra_iface_conf(&frontend_conf->ra_iface_list,
|
ra_iface_conf = find_ra_iface_conf(&frontend_conf->ra_iface_list,
|
||||||
ra_iface->conf_name);
|
ra_iface->conf_name);
|
||||||
ra_options_conf = &ra_iface_conf->ra_options;
|
ra_options_conf = &ra_iface_conf->ra_options;
|
||||||
|
t = time(NULL);
|
||||||
len = sizeof(*ra);
|
len = sizeof(*ra);
|
||||||
if (ra_iface_conf->ra_options.source_link_addr)
|
if (ra_iface_conf->ra_options.source_link_addr)
|
||||||
len += sizeof(*ndopt_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 =
|
ndopt_source_link_addr->nd_opt_source_link_addr_type =
|
||||||
ND_OPT_SOURCE_LINKADDR;
|
ND_OPT_SOURCE_LINKADDR;
|
||||||
ndopt_source_link_addr->nd_opt_source_link_addr_len = 1;
|
ndopt_source_link_addr->nd_opt_source_link_addr_len = 1;
|
||||||
if (getifaddrs(&ifap) != 0) {
|
memcpy(&ndopt_source_link_addr->nd_opt_source_link_addr_hw_addr,
|
||||||
ifap = NULL;
|
&ra_iface->hw_addr, ETHER_ADDR_LEN);
|
||||||
log_warn("getifaddrs");
|
p += sizeof(*ndopt_source_link_addr);
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ra_options_conf->mtu > 0) {
|
if (ra_options_conf->mtu > 0) {
|
||||||
|
@ -1234,9 +1277,20 @@ build_packet(struct ra_iface *ra_iface)
|
||||||
if (ra_prefix_conf->aflag)
|
if (ra_prefix_conf->aflag)
|
||||||
ndopt_pi->nd_opt_pi_flags_reserved |=
|
ndopt_pi->nd_opt_pi_flags_reserved |=
|
||||||
ND_OPT_PI_FLAG_AUTO;
|
ND_OPT_PI_FLAG_AUTO;
|
||||||
ndopt_pi->nd_opt_pi_valid_time = htonl(ra_prefix_conf->vltime);
|
|
||||||
ndopt_pi->nd_opt_pi_preferred_time =
|
if (ra_prefix_conf->ltime_decaying & VLTIME_DECAYING)
|
||||||
htonl(ra_prefix_conf->pltime);
|
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;
|
ndopt_pi->nd_opt_pi_prefix = ra_prefix_conf->prefix;
|
||||||
|
|
||||||
p += sizeof(*ndopt_pi);
|
p += sizeof(*ndopt_pi);
|
||||||
|
@ -1330,11 +1384,9 @@ build_packet(struct ra_iface *ra_iface)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
memcpy(ra_iface->data, buf, len);
|
memcpy(ra_iface->data, buf, len);
|
||||||
ra_iface->datalen = len;
|
ra_iface->datalen = len;
|
||||||
/* packet changed; tell engine to send new advertisements */
|
return 1;
|
||||||
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 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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))
|
if (!LINK_STATE_IS_UP(ra_iface->link_state))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (ra_iface->ltime_decaying)
|
||||||
|
/* update vltime & pltime */
|
||||||
|
build_packet(ra_iface);
|
||||||
|
|
||||||
sndmhdr.msg_name = to;
|
sndmhdr.msg_name = to;
|
||||||
sndmhdr.msg_iov[0].iov_base = ra_iface->data;
|
sndmhdr.msg_iov[0].iov_base = ra_iface->data;
|
||||||
sndmhdr.msg_iov[0].iov_len = ra_iface->datalen;
|
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) 2018 Florian Obser <florian@openbsd.org>
|
||||||
.\" Copyright (c) 2005 Esben Norby <norby@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
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" 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
|
.Dt RAD.CONF 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -167,10 +167,14 @@ The default is yes.
|
||||||
The preferred lifetime (pltime) in seconds for addresses generated from this
|
The preferred lifetime (pltime) in seconds for addresses generated from this
|
||||||
prefix.
|
prefix.
|
||||||
The default is 2700.
|
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
|
.It Ic valid lifetime Ar seconds
|
||||||
The valid lifetime (vltime) in seconds for addresses generated from this
|
The valid lifetime (vltime) in seconds for addresses generated from this
|
||||||
prefix.
|
prefix.
|
||||||
The default is 5400.
|
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
|
.El
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width /etc/examples/rad.conf -compact
|
.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>
|
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
|
||||||
|
@ -35,6 +35,8 @@
|
||||||
#define MIN_DELAY_BETWEEN_RAS 3 /* 3 seconds */
|
#define MIN_DELAY_BETWEEN_RAS 3 /* 3 seconds */
|
||||||
#define MAX_SEARCH 1025 /* MAXDNAME in arpa/nameser.h */
|
#define MAX_SEARCH 1025 /* MAXDNAME in arpa/nameser.h */
|
||||||
#define DEFAULT_RDNS_LIFETIME 600 * 1.5
|
#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)
|
#define IMSG_DATA_SIZE(imsg) ((imsg).hdr.len - IMSG_HEADER_SIZE)
|
||||||
|
|
||||||
|
@ -114,6 +116,7 @@ struct ra_prefix_conf {
|
||||||
int prefixlen; /* prefix length */
|
int prefixlen; /* prefix length */
|
||||||
uint32_t vltime; /* valid lifetime */
|
uint32_t vltime; /* valid lifetime */
|
||||||
uint32_t pltime; /* preferred lifetime */
|
uint32_t pltime; /* preferred lifetime */
|
||||||
|
int ltime_decaying;
|
||||||
int lflag; /* on-link flag*/
|
int lflag; /* on-link flag*/
|
||||||
int aflag; /* autonom. addr 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) 2022 Theo Buehler <tb@openbsd.org>
|
||||||
* Copyright (c) 2021 Job Snijders <job@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;
|
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.
|
* Lightweight version of cert_parse_pre() for EE certs.
|
||||||
* Parses the two RFC 3779 extensions, and performs some sanity checks.
|
* 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;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!x509_valid_subject(fn, x))
|
if (!cert_check_subject_and_issuer(fn, x))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (X509_get_key_usage(x) != KU_DIGITAL_SIGNATURE) {
|
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;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!x509_valid_subject(fn, x))
|
if (!cert_check_subject_and_issuer(fn, x))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Look for X509v3 extensions. */
|
/* 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>
|
* 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;
|
const unsigned char *oder;
|
||||||
struct crl *crl;
|
struct crl *crl;
|
||||||
const X509_ALGOR *palg;
|
const X509_ALGOR *palg;
|
||||||
|
const X509_NAME *name;
|
||||||
const ASN1_OBJECT *cobj;
|
const ASN1_OBJECT *cobj;
|
||||||
const ASN1_TIME *at;
|
const ASN1_TIME *at;
|
||||||
int count, nid, rc = 0;
|
int count, nid, rc = 0;
|
||||||
|
@ -192,6 +193,13 @@ crl_parse(const char *fn, const unsigned char *der, size_t len)
|
||||||
goto out;
|
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);
|
X509_CRL_get0_signature(crl->x509_crl, NULL, &palg);
|
||||||
if (palg == NULL) {
|
if (palg == NULL) {
|
||||||
warnx("%s: X509_CRL_get0_signature", fn);
|
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>
|
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||||
*
|
*
|
||||||
|
@ -917,7 +917,7 @@ int x509_location(const char *, const char *, const char *,
|
||||||
GENERAL_NAME *, char **);
|
GENERAL_NAME *, char **);
|
||||||
int x509_inherits(X509 *);
|
int x509_inherits(X509 *);
|
||||||
int x509_any_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 *);
|
time_t x509_find_expires(time_t, struct auth *, struct crl_tree *);
|
||||||
|
|
||||||
/* printers */
|
/* 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) 2022 Theo Buehler <tb@openbsd.org>
|
||||||
* Copyright (c) 2021 Claudio Jeker <claudio@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.
|
* Return 0 on failure.
|
||||||
*/
|
*/
|
||||||
int
|
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 X509_NAME_ENTRY *ne;
|
||||||
const ASN1_OBJECT *ao;
|
const ASN1_OBJECT *ao;
|
||||||
const ASN1_STRING *as;
|
const ASN1_STRING *as;
|
||||||
int cn = 0, sn = 0;
|
int cn = 0, sn = 0;
|
||||||
int i, nid;
|
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++) {
|
for (i = 0; i < X509_NAME_entry_count(xn); i++) {
|
||||||
if ((ne = X509_NAME_get_entry(xn, i)) == NULL) {
|
if ((ne = X509_NAME_get_entry(xn, i)) == NULL) {
|
||||||
warnx("%s: X509_NAME_get_entry", fn);
|
warnx("%s: X509_NAME_get_entry", fn);
|
||||||
|
@ -874,8 +868,8 @@ x509_valid_subject(const char *fn, const X509 *x)
|
||||||
switch (nid) {
|
switch (nid) {
|
||||||
case NID_commonName:
|
case NID_commonName:
|
||||||
if (cn++ > 0) {
|
if (cn++ > 0) {
|
||||||
warnx("%s: duplicate commonName in subject",
|
warnx("%s: duplicate commonName in %s",
|
||||||
fn);
|
fn, descr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((as = X509_NAME_ENTRY_get_data(ne)) == NULL) {
|
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
|
* https://lists.afrinic.net/pipermail/dbwg/2023-March/000436.html
|
||||||
*/
|
*/
|
||||||
#if 0
|
#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) {
|
if (ASN1_STRING_type(as) != V_ASN1_PRINTABLESTRING) {
|
||||||
warnx("%s: RFC 6487 section 4.5: commonName is"
|
warnx("%s: RFC 6487 section 4.5: commonName is"
|
||||||
" not PrintableString", fn);
|
" not PrintableString", fn);
|
||||||
|
@ -897,8 +895,8 @@ x509_valid_subject(const char *fn, const X509 *x)
|
||||||
break;
|
break;
|
||||||
case NID_serialNumber:
|
case NID_serialNumber:
|
||||||
if (sn++ > 0) {
|
if (sn++ > 0) {
|
||||||
warnx("%s: duplicate serialNumber in subject",
|
warnx("%s: duplicate serialNumber in %s",
|
||||||
fn);
|
fn, descr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -907,14 +905,14 @@ x509_valid_subject(const char *fn, const X509 *x)
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
warnx("%s: RFC 6487 section 4.5: unexpected attribute"
|
warnx("%s: RFC 6487 section 4.5: unexpected attribute"
|
||||||
" %s", fn, nid2str(nid));
|
" %s in %s", fn, nid2str(nid), descr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cn == 0) {
|
if (cn == 0) {
|
||||||
warnx("%s: RFC 6487 section 4.5: subject missing commonName",
|
warnx("%s: RFC 6487 section 4.5: %s missing commonName",
|
||||||
fn);
|
fn, descr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue