If an SSID uses the maximum allowed length, ifconfig overwrites the last byte with \0 when hashing the WPA key. This leads to a wrong WPA key being installed in the kernel:
iwm0: SCAN -> AUTH iwm0: sending auth to xx:xx:xx:xx:xx:xx on channel 1 mode 11g iwm0: AUTH -> ASSOC iwm0: sending assoc_req to xx:xx:xx:xx:xx:xx on channel 1 mode 11g iwm0: ASSOC -> RUN iwm0: associated with xx:xx:xx:xx:xx:xx ssid "FRITZ!Box7430 Internetmanufaktur" channel 1 start MCS 0 short preamble short slot time protection enabled HT enabled iwm0: missed beacon threshold set to 30 beacons, beacon interval is 100 TU iwm0: received msg 1/4 of the 4-way handshake from xx:xx:xx:xx:xx:xx iwm0: sending msg 2/4 of the 4-way handshake to xx:xx:xx:xx:xx:xx iwm0: received msg 1/4 of the 4-way handshake from xx:xx:xx:xx:xx:xx iwm0: sending msg 2/4 of the 4-way handshake to xx:xx:xx:xx:xx:xx iwm0: received msg 1/4 of the 4-way handshake from xx:xx:xx:xx:xx:xx iwm0: sending msg 2/4 of the 4-way handshake to xx:xx:xx:xx:xx:xx iwm0: received msg 1/4 of the 4-way handshake from xx:xx:xx:xx:xx:xx iwm0: sending msg 2/4 of the 4-way handshake to xx:xx:xx:xx:xx:xx The diff below fixes this. Using strlcpy is incorrect for SSIDs. We need to manually track the length instead and treat the SSID as an opaque byte string which might not be NUL-terminated. iwm0: SCAN -> AUTH iwm0: sending auth to xx:xx:xx:xx:xx:xx on channel 1 mode 11g iwm0: AUTH -> ASSOC iwm0: sending assoc_req to xx:xx:xx:xx:xx:xx on channel 1 mode 11g iwm0: ASSOC -> RUN iwm0: associated with xx:xx:xx:xx:xx:xx ssid "FRITZ!Box7430 Internetmanufaktur" channel 1 start MCS 0 short preamble short slot time protection enabled HT enabled iwm0: missed beacon threshold set to 30 beacons, beacon interval is 100 TU iwm0: received msg 1/4 of the 4-way handshake from xx:xx:xx:xx:xx:xx iwm0: sending msg 2/4 of the 4-way handshake to xx:xx:xx:xx:xx:xx iwm0: received msg 3/4 of the 4-way handshake from xx:xx:xx:xx:xx:xx iwm0: sending msg 4/4 of the 4-way handshake to xx:xx:xx:xx:xx:xx ok? diff 5181eb992cbbf64c135f177197957b0e0b427e21 /usr/src blob - 0ee441181c9f85d12056accc352833cf31c41895 file + sbin/ifconfig/ifconfig.c --- sbin/ifconfig/ifconfig.c +++ sbin/ifconfig/ifconfig.c @@ -714,7 +714,9 @@ const struct afswtch { const struct afswtch *afp; /*the address family being set or asked about*/ char joinname[IEEE80211_NWID_LEN]; +size_t joinlen; char nwidname[IEEE80211_NWID_LEN]; +size_t nwidlen; int ifaliases = 0; int aflag = 0; @@ -1735,11 +1737,11 @@ setifnwid(const char *val, int d) struct ieee80211_nwid nwid; int len; - if (strlen(joinname) != 0) { + if (joinlen != 0) { errx(1, "nwid and join may not be used at the same time"); } - if (strlen(nwidname) != 0) { + if (nwidlen != 0) { errx(1, "nwid may not be specified twice"); } @@ -1752,9 +1754,9 @@ setifnwid(const char *val, int d) if (get_string(val, NULL, nwid.i_nwid, &len) == NULL) return; } - nwid.i_len = len; + nwidlen = nwid.i_len = len; (void)strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - (void)strlcpy(nwidname, nwid.i_nwid, sizeof(nwidname)); + memcpy(nwidname, nwid.i_nwid, len); ifr.ifr_data = (caddr_t)&nwid; if (ioctl(sock, SIOCS80211NWID, (caddr_t)&ifr) == -1) warn("SIOCS80211NWID"); @@ -1777,11 +1779,11 @@ setifjoin(const char *val, int d) { int len; - if (strlen(nwidname) != 0) { + if (nwidlen != 0) { errx(1, "nwid and join may not be used at the same time"); } - if (strlen(joinname) != 0) { + if (joinlen != 0) { errx(1, "join may not be specified twice"); } @@ -1796,9 +1798,9 @@ setifjoin(const char *val, int d) if (len == 0) join.i_flags |= IEEE80211_JOIN_ANY; } - join.i_len = len; + joinlen = join.i_len = len; (void)strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - (void)strlcpy(joinname, join.i_nwid, sizeof(joinname)); + memcpy(joinname, join.i_nwid, len); actions |= A_JOIN; } @@ -2181,12 +2183,12 @@ setifwpakey(const char *val, int d) strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); /* Use the value specified in 'join' or 'nwid' */ - if (strlen(joinname) != 0) { - strlcpy(nwid.i_nwid, joinname, sizeof(nwid.i_nwid)); - nwid.i_len = strlen(joinname); - } else if (strlen(nwidname) != 0) { - strlcpy(nwid.i_nwid, nwidname, sizeof(nwid.i_nwid)); - nwid.i_len = strlen(nwidname); + if (joinlen != 0) { + memcpy(nwid.i_nwid, joinname, joinlen); + nwid.i_len = joinlen; + } else if (nwidlen != 0) { + memcpy(nwid.i_nwid, nwidname, nwidlen); + nwid.i_len = nwidlen; } else { warnx("no nwid or join command, guessing nwid to use");