On Sat, May 20, 2023 at 05:33:11PM +0200, Florian Obser wrote: | In case this turns out to be useful for unlocking work in the kernel. | | It's a minimum diff, if we want to go this way we probably want to move | init_soiikey() to the engine process and stop bouncing through the main | process when an interface changes. | | This changes behaviour: in -current we can change the sysctl and down/up | an interface to read the new value, with this diff that no longer | works. slaacd will (and can) only read the file on startup. | | This has consequences for the installer: slaacd starts before | /mnt/etc/soii.key is available in the upgrade case. Which in turn means | that we get a different IPv6 address in the installer than in the | running system. I don't know how big of an issue that is.
Can't speak for others, but my use case for soii-addresses is for incoming connections - outgoing ones should use the temporary privacy addressed. So for the installer it doesn't matter. My guess is that this goes for many (most? all?) users of soii-addresses, so it should be safe to not have those in the installer during upgrades. Paul | diff --git distrib/miniroot/install.sub distrib/miniroot/install.sub | index d3d944bf2ca..aa84e4808f2 100644 | --- distrib/miniroot/install.sub | +++ distrib/miniroot/install.sub | @@ -2620,9 +2620,6 @@ enable_network() { | echo "127.0.0.1\tlocalhost" >/tmp/i/hosts | echo "::1\t\tlocalhost" >>/tmp/i/hosts | | - _f=/mnt/etc/soii.key | - [[ -f $_f ]] && sysctl "net.inet6.ip6.soiikey=$(<$_f)" | - | enable_ifs | } | | diff --git distrib/special/sysctl/sysctl.c distrib/special/sysctl/sysctl.c | index 9156d5f455c..7aedb6dd55b 100644 | --- distrib/special/sysctl/sysctl.c | +++ distrib/special/sysctl/sysctl.c | @@ -99,39 +99,6 @@ pstring(struct var *v) | return (1); | } | | -int | -parse_hex_char(char ch) | -{ | - if (ch >= '0' && ch <= '9') | - return (ch - '0'); | - | - ch = tolower((unsigned char)ch); | - if (ch >= 'a' && ch <= 'f') | - return (ch - 'a' + 10); | - | - return (-1); | -} | - | -int | -set_soii_key(char *src) | -{ | - uint8_t key[SOIIKEY_LEN]; | - int mib[4] = {CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_SOIIKEY}; | - int i, c; | - | - for(i = 0; i < SOIIKEY_LEN; i++) { | - if ((c = parse_hex_char(src[2 * i])) == -1) | - return (-1); | - key[i] = c << 4; | - if ((c = parse_hex_char(src[2 * i + 1])) == -1) | - return (-1); | - key[i] |= c; | - } | - | - return sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, NULL, key, | - SOIIKEY_LEN); | -} | - | int | main(int argc, char *argv[]) | { | @@ -159,17 +126,6 @@ main(int argc, char *argv[]) | | while (argc--) { | name = *argv++; | - /* | - * strlen("net.inet6.ip6.soiikey=" | - * "00000000000000000000000000000000") == 54 | - * strlen("net.inet6.ip6.soiikey=") == 22 | - */ | - if (strlen(name) == 54 && strncmp(name, | - "net.inet6.ip6.soiikey=", 22) == 0) { | - set_soii_key(name + 22); | - continue; | - } | - | for (i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) { | if (strcmp(name, vars[i].name) == 0) { | (vars[i].print)(&vars[i]); | diff --git etc/netstart etc/netstart | index af4866f909e..105d5a977cf 100644 | --- etc/netstart | +++ etc/netstart | @@ -360,13 +360,6 @@ if ifconfig lo0 inet6 >/dev/null 2>&1; then | IP6KERNEL=true | fi | | -# Load key material for the generation of IPv6 Semantically Opaque Interface | -# Identifiers (SOII) used for SLAAC addresses. | -if $IP6KERNEL && ! $PRINT_ONLY; then | - [[ -f /etc/soii.key ]] && | - sysctl -q "net.inet6.ip6.soiikey=$(</etc/soii.key)" | -fi | - | # If we were invoked with a list of interface names, just reconfigure these | # interfaces (or bridges), add default routes and return. | # Create virtual interfaces upfront to make ifconfig commands depending on | diff --git etc/rc etc/rc | index ea30a76aec4..78d82c81cd5 100644 | --- etc/rc | +++ etc/rc | @@ -164,11 +164,6 @@ make_keys() { | | ssh-keygen -A | | - if [[ ! -f /etc/soii.key ]]; then | - openssl rand -hex 16 > /etc/soii.key && | - chmod 600 /etc/soii.key && sysctl -q \ | - "net.inet6.ip6.soiikey=$(</etc/soii.key)" | - fi | } | | # Re-link libraries, placing the objects in a random order. | diff --git sbin/slaacd/slaacd.c sbin/slaacd/slaacd.c | index 4d1786361f7..3187af8740b 100644 | --- sbin/slaacd/slaacd.c | +++ sbin/slaacd/slaacd.c | @@ -22,8 +22,8 @@ | #include <sys/ioctl.h> | #include <sys/queue.h> | #include <sys/socket.h> | +#include <sys/stat.h> | #include <sys/syslog.h> | -#include <sys/sysctl.h> | #include <sys/uio.h> | #include <sys/wait.h> | | @@ -34,6 +34,7 @@ | #include <netinet6/in6_var.h> | #include <netinet/icmp6.h> | | +#include <ctype.h> | #include <err.h> | #include <errno.h> | #include <fcntl.h> | @@ -76,7 +77,8 @@ void configure_gateway(struct imsg_configure_dfr *, uint8_t); | void add_gateway(struct imsg_configure_dfr *); | void delete_gateway(struct imsg_configure_dfr *); | void send_rdns_proposal(struct imsg_propose_rdns *); | -int get_soiikey(uint8_t *); | +int parse_hex_char(char); | +void init_soiikey(void); | | static int main_imsg_send_ipc_sockets(struct imsgbuf *, struct imsgbuf *); | int main_imsg_compose_frontend(int, int, void *, uint16_t); | @@ -89,6 +91,7 @@ pid_t frontend_pid; | pid_t engine_pid; | | int routesock, ioctl_sock, rtm_seq = 0; | +uint8_t soiikey[SLAACD_SOIIKEY_LEN]; | | void | main_sig_handler(int sig, short event, void *arg) | @@ -189,6 +192,10 @@ main(int argc, char *argv[]) | if (getpwnam(SLAACD_USER) == NULL) | errx(1, "unknown user %s", SLAACD_USER); | | +#ifndef SMALL | + init_soiikey(); | +#endif /* SMALL */ | + | log_init(debug, LOG_DAEMON); | log_setverbose(verbose); | | @@ -431,11 +438,9 @@ main_dispatch_frontend(int fd, short event, void *bula) | fatalx("%s: IMSG_UPDATE_IF wrong length: %lu", | __func__, IMSG_DATA_SIZE(imsg)); | memcpy(&imsg_ifinfo, imsg.data, sizeof(imsg_ifinfo)); | - if (get_soiikey(imsg_ifinfo.soiikey) == -1) | - log_warn("get_soiikey"); | - else | - main_imsg_compose_engine(IMSG_UPDATE_IF, 0, | - &imsg_ifinfo, sizeof(imsg_ifinfo)); | + memcpy(imsg_ifinfo.soiikey, soiikey, sizeof(soiikey)); | + main_imsg_compose_engine(IMSG_UPDATE_IF, 0, | + &imsg_ifinfo, sizeof(imsg_ifinfo)); | break; | default: | log_debug("%s: error handling imsg %d", __func__, | @@ -856,16 +861,56 @@ sin6_to_str(struct sockaddr_in6 *sin6) | } | return hbuf; | } | -#endif /* SMALL */ | | int | -get_soiikey(uint8_t *key) | +parse_hex_char(char ch) | { | - int mib[4] = {CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_SOIIKEY}; | - size_t size = SLAACD_SOIIKEY_LEN; | + if (ch >= '0' && ch <= '9') | + return (ch - '0'); | + | + ch = tolower((unsigned char)ch); | + if (ch >= 'a' && ch <= 'f') | + return (ch - 'a' + 10); | + | + return (-1); | +} | | - return sysctl(mib, sizeof(mib) / sizeof(mib[0]), key, &size, NULL, 0); | +void | +init_soiikey(void) | +{ | + int fd, i; | + char buf[SLAACD_SOIIKEY_LEN * 2 + 1]; | + | + memset(buf, 0, sizeof(buf)); | + if ((fd = open(_PATH_SOIIKEY, O_RDONLY)) == -1) { | + arc4random_buf(soiikey, SLAACD_SOIIKEY_LEN); | + for (i = 0; i < SLAACD_SOIIKEY_LEN; i++) | + snprintf(&buf[2 * i], sizeof(buf) - 2 * i, "%02x", | + soiikey[i]); | + buf[sizeof(buf) - 1] = '\n'; | + if ((fd = open(_PATH_SOIIKEY, O_WRONLY | O_CREAT, | + S_IRUSR | S_IWUSR)) != -1) { | + write(fd, buf, sizeof(buf)); | + close(fd); | + } | + } else { | + if (read(fd, buf, sizeof(buf)) == -1) | + arc4random_buf(soiikey, SLAACD_SOIIKEY_LEN); | + else { | + for (i = 0; i < SLAACD_SOIIKEY_LEN; i++) { | + int c; | + if ((c = parse_hex_char(buf[2 * i])) == -1) | + break; | + soiikey[i] = c << 4; | + if ((c = parse_hex_char(buf[2 * i + 1])) == -1) | + break; | + soiikey[i] |= c; | + } | + } | + close(fd); | + } | } | +#endif /* SMALL */ | | void | open_icmp6sock(int rdomain) | diff --git sbin/slaacd/slaacd.h sbin/slaacd/slaacd.h | index 2844f4a63b7..9ee028247a8 100644 | --- sbin/slaacd/slaacd.h | +++ sbin/slaacd/slaacd.h | @@ -20,6 +20,7 @@ | | #define _PATH_LOCKFILE "/dev/slaacd.lock" | #define _PATH_SLAACD_SOCKET "/dev/slaacd.sock" | +#define _PATH_SOIIKEY "/etc/soii.key" | #define SLAACD_USER "_slaacd" | #define SLAACD_RTA_LABEL "slaacd" | | | -- | In my defence, I have been left unsupervised. | -- >++++++++[<++++++++++>-]<+++++++.>+++[<------>-]<.>+++[<+ +++++++++++>-]<.>++[<------------>-]<+.--------------.[-] http://www.weirdnet.nl/