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/                 

Reply via email to