Quaker,

I don't have so many comments, most of them are nits.

=============================================================================
wpa/wpa2 code review comments

Code Review Comments Records

RE              Quaker Fang
CODE REVIEWER   Cecilia Hu
WEBREV
    webrev: http://cr.grommit.com/~zf162725/cr_0308/
    workspace & cscope: /net/greatwall.prc/workspace/wifi-wpa-cr/usr/src
REVIEW FILES
        usr/src/cmd/cmd-inet/usr.lib/wpad/wpa.c
        usr/src/cmd/cmd-inet/usr.lib/wpad/wpa_impl.h
        usr/src/cmd/cmd-inet/usr.lib/wpad/wpa_supplicant.c
REVIEW DUE DAY
        2007/03/23

I. General
=============================================================================
#1.  indent
   I'm not quite sure it's webrev issue or source code issue. please make
   sure the indent correctly.

#2. comments
   More comments are always welcome. Current code is difficult to
   understand by someone else the experts on security.

#3. copy/license
   WPA supplicant license mentioned that README and COPYING files for
   more details. Do we have these two files in source tree?

#4. code convention
   Please make sure it's Sun coding style. I saw some places port from
   BSD code look strange. Please make sure run cstyle checking.

II. comments on wpa_impl.h
=============================================================================
#1. why don't put all data structures in one pack(1)

#2.
  216         enum {
  217                 WPA_DISCONNECTED, WPA_SCANNING, WPA_ASSOCIATING,
  218                 WPA_ASSOCIATED, WPA_4WAY_HANDSHAKE, 
WPA_GROUP_HANDSHAKE,
  219                 WPA_COMPLETED
  220         } wpa_state;

it's better to keep one entry one line;

#3.
  284 void wpa_supplicant_req_scan(struct wpa_supplicant *, int, int);
  285
  286 void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *, int, 
int);

Possibly, you want to keep them in same style, like:
        wpa_supplicant_req_scan();
        wpa_supplicant_req_timeout();
/* I didn't see anyother timeout then auth */

III. comments on wpa.c
=============================================================================
#1.
   49 static const uint8_t
   50 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[]        = { 0x00, 0x50, 0xf2, 1 };
   51 static const uint8_t
   52 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[]      = { 0x00, 0x50, 0xf2, 2 };
  ...
   88 static const uint8_t
   89 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[]        = { 0x00, 0x0f, 0xac, 1 };
   90 static const uint8_t
   91 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[]      = { 0x00, 0x0f, 0xac, 2 };
  ...
  313         pos += snprintf(pos, buf + len - pos,
  314                         "Index / AA / PMKID / expiration (in 
seconds)\n");

wrong indent.

#2.
  173 static int
  174 wpa_selector_to_bitfield(uint8_t *s)
  175 {
  176         if (memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN) == 0)
  177                 return (WPA_CIPHER_NONE);
  178         if (memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN) == 0)
  179                 return (WPA_CIPHER_WEP40);
  180         if (memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN) == 0)
  181                 return (WPA_CIPHER_TKIP);
  182         if (memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN) == 0)
  183                 return (WPA_CIPHER_CCMP);
  184         if (memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN) == 0)
  185                 return (WPA_CIPHER_WEP104);
  186         return (0);
  187 }

If cipher, by some reasons, set to the value you don't support, so far,
treat it as WPA_CIPHER_NONE, but never be checked by
wpa_parse_wpa_ie_wpa(). Or, do you need to add one value meaning
"not support"?

Other xxx_to_bitfield() functions are also have the same question.

#3.
  227 static void
  228 pmksa_cache_free_entry(struct wpa_supplicant *wpa_s,
  229         struct rsn_pmksa_cache *entry)
  230 {
  231         free(entry);
  232         wpa_s->pmksa_count--;
  233         if (wpa_s->cur_pmksa == entry) {
  234                 wpa_printf(MSG_DEBUG, "RSN: removed current PMKSA 
entry");
  235                 wpa_s->cur_pmksa = NULL;
  236         }
  237 }

entry is freed firstly, and then used to compare with wpa_s->cur_pmksa. 
When some "streesing" testing, is it a potential problem?

#4.
  265         sec = wpa_s->pmksa->expiration - time(NULL);
  266         if (sec < 0)
  267                 sec = 0;
  268         (void) eloop_register_timeout(sec + 1, 0, pmksa_cache_expire,
  269             wpa_s, NULL);

the minal timeout is 1s, is it too short?

#5.
  386         if (left >= WPA_SELECTOR_LEN) {
  387                 data->group_cipher = wpa_selector_to_bitfield(pos);
  388                 pos += WPA_SELECTOR_LEN;
  389                 left -= WPA_SELECTOR_LEN;
  390         } else if (left > 0) {
  391                 wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u 
too much",
  392                     "wpa_parse_wpa_ie_wpa", left);
  393                 return (-1);
  394         }

don't you need to check the return 0 of wpa_selector_to_bitfield() which
means "not support" or "wpa_none"?
see above #2.

#6.
wpa_parse_wpa_ie_wpa()
{
  ...
  412         } else if (left == 1) {
  413                 wpa_printf(MSG_DEBUG, "%s: ie too short (for key 
mgmt)",
  414                     "wpa_parse_wpa_ie_wpa");
  415                 return (-1);
  416         }
  ...
  434         } else if (left == 1) {
  435                 wpa_printf(MSG_DEBUG, "%s: ie too short (for 
capabilities)",
  436                     "wpa_parse_wpa_ie_wpa");
  437                 return (-1);
  438         }
}

Question: how about left == 0. If it's acceptable case, that means "key
mgmt" and "capabilities" are both optional. is it?
same question to wpa_parse_wpa_ie_rsn().

#7.
  664                 return (-1);

wrong indent.

#8.
  726 wpa_pmk_to_ptk(uint8_t *pmk, uint8_t *addr1, uint8_t *addr2,
  727     uint8_t *nonce1, uint8_t *nonce2, uint8_t *ptk, size_t ptk_len)
  728 {
  729         uint8_t data[2 * IEEE80211_ADDR_LEN + 2 * 32];

32 is used many times in this subroutine. What's that mean? If there is
defination for it, maybe you want to define a macro.

#9.
  904                 /* RSN: msg 1/4 should contain PMKID for the 
selected PMK */
  905                 uint8_t *pos = (uint8_t *)(key + 1);
  906                 uint8_t *end = pos + BE_16(key->key_data_length);

define them at the beginning of this subroutine.

#10.
  982         if (wpa_s->renew_snonce) {
  983                 if (random_get_pseudo_bytes(wpa_s->snonce, 
WPA_NONCE_LEN)) {
  984                         wpa_printf(MSG_WARNING, "WPA: Failed to get "
  985                             "random data for SNonce");
  986                         return;
  987                 }

need the free(rbuf) here.

#11.
1018 static void
1019 wpa_supplicant_process_3_of_4_gtk(struct wpa_supplicant *wpa_s,
1020     unsigned char *src_addr, struct wpa_eapol_key *key,
1021     uint8_t *gtk, int gtk_len)

The meaning of 16/32/13/5 can be eaily understood as the len for
different CIPHER, suppose they should be defined as macro somewhere in
.h file.

IV. comments on wpa_supplicant.c
=============================================================================
#1.
46 static const char *wpa_supplicant_version =
47 "wpa_supplicant v0.1";

Please make sure it's the normal policy to version a new service from v0.1.

#2.
112  * Note: new line '\n' is added to the end of the text when printing 
to stdout.

This comment is not, obviously, what this subroutine actually does.

#3.
  180         for (pos = ssid_txt; *pos != '\0'; pos ++) {
  181                 if ((uint8_t)*pos < 32 || (uint8_t)*pos >= 127)
  182                         *pos = '_';
  183         }

you may want to add comments to explain 32/127 for ASCII.

#4.
  218         (void) eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
  219         (void) eloop_register_timeout(sec, usec, wpa_supplicant_scan,
  220             wpa_s, NULL);

for eloop_cancel_timeout(); don't need cast it to (void);
for eloop_register_timeout(); is it not necessary to check the return 
result?

#5.
  314         if (bss->wpa_ie_len && bss->wpa_ie[0] == RSN_INFO_ELEM &&
  315                 (ssid->proto & WPA_PROTO_RSN)) {
  316                 wpa_printf(MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
  317                 proto = WPA_PROTO_RSN;

wrong indent.

#6.
  333         free(wpa_s->ap_wpa_ie);
  334         wpa_s->ap_wpa_ie = malloc(ap_ie_len);

Question: I'm not quite understand the logical. can ap_ie_len change?

#7.
  380         free(wpa_s->assoc_wpa_ie);
  381         wpa_s->assoc_wpa_ie = NULL;
  382         wpa_s->assoc_wpa_ie_len = 0;

Question: I didn't find when assoc_wpa_ie was malloc?

#8.
  486                 if (ssid->bssid_set &&
  487                     memcmp(bss->bssid, ssid->bssid, 
IEEE80211_ADDR_LEN) != 0) {
  488                         wpa_printf(MSG_DEBUG, "   skip - BSSID 
mismatch");
  489                 }
  490                 if (!((ssid->proto & (WPA_PROTO_RSN | 
WPA_PROTO_WPA)) &&
  491                     wpa_parse_wpa_ie(wpa_s, bss->wpa_ie,
  492                     bss->wpa_ie_len, &ie) == 0)) {
  493                         wpa_printf(MSG_DEBUG, "   skip - "
  494                             "could not parse WPA/RSN IE");
  495                 }
  496                 if (!(ie.proto & ssid->proto)) {
  497                         wpa_printf(MSG_DEBUG, "   skip - proto 
mismatch");
  498                 }

If these three conditions will not continue the loop - means find next
bss, then it's not necessary to check them at all.

#9.
  529         num = wpa_s->driver->get_scan_results(wpa_s->ifname, results,
  530                                         MAX_SCANRESULTS);

wrong indent

#10.
  554                 wpa_supplicant_req_scan(wpa_s, 5, 0);

why the arguments are 5 and 0? there are someother places use these kind
of numbers, maybe need some comments...

#11.
  625 static void
  626 wpa_supplicant_fd_workaround(void)
  627 {
  628         int s, i;
  629         /*
  630          * When started from pcmcia-cs scripts, wpa_supplicant 
might start with
  631          * fd 0, 1, and 2 closed. This will cause some issues 
because many
  632          * places in wpa_supplicant are still printing out to 
stdout. As a
  633          * workaround, make sure that fd's 0, 1, and 2 are not 
used for other
  634          * sockets.
  635          */
  636         for (i = 0; i < 3; i++) {
  637                 s = open("/dev/null", O_RDWR);
  638                 if (s > 2) {
  639                         (void) close(s);
  640                         break;
  641                 }
  642         }
  643 }

Seems this workaround is copied from somehwere else, you may add
a clear comments or remove this one.

#12.
  697         door_id = door_create(event_handler, cookie,
  698             DOOR_UNREF | DOOR_REFUSE_DESC | DOOR_NO_CANCEL);

Question: according to the define of DOOR_NO_CANCEL. is it what the wpad 
wants?
      DOOR_NO_CANCEL    Clients which abort calls  to  door_call()
                        on  this door will not cause the cancella-
                        tion of the  server  thread  handling  the
                        request.  See cancellation(5).

#13.
  705         if (stat(doorname, &stbuf) < 0) {
  706                 int newfd;
  707                 ...
  715         }
  716

Define variable at the function beginning

#14.
  750 static int
  751 wpa_config_parse_ssid(struct wpa_ssid *ssid, int line, const char 
*value)
  752 {

the return value of this function is never be checked. why don't define
it "void"?

#15.
  816         if ((ssid->key_mgmt & WPA_KEY_MGMT_PSK) && !ssid->psk_set) {
  817                 wpa_printf(MSG_ERROR, "WPA-PSK accepted for key "
  818                     "management, but no PSK configured.");
  819                 errors++;
  820         }
  821
  822         if (errors) {
  823                 free(ssid);
  824                 ssid = NULL;
  825         }

it's not necessary to define errors, or you need to check other previous
return value.

#16.
  847         if (ssid == NULL)
  848                 errors ++;
  849
  850         config->ssid = ssid;
  851
  852         if (errors) {
  853                 wpa_config_free(config);
  854                 config = NULL;
  855         }
  856
  857         return (config);

it's not necessary to define errors.


  #17.
  958                 case 'D':
  959                         debug_mode = 1;
  960                         break;

-D option is not in usage output;


BR,
-Cecilia

Quaker Fang :
> Wireless WPA Supplicant (PSARC/2006/046) is now ready for code review.
> This work consists of a new wpa SMF service, along with WPA-related
> changes to dladm(1M), libdladm, and the mac_wifi, ath, and net80211
> kernel modules.
> 
> This project consists of almost 10,000 changed or new lines of code.
> To make the review more manageable, we are splitting it into two parts.
> 
> This is the first part, and consists of everything but[1] the net80211
> kernel module, ath driver and mac_wifi plugin changes.
> The second part will be sent out for review later.
> 
>    webrev: http://cr.grommit.com/~zf162725/cr_0308/
>    workspace & cscope: /net/greatwall.prc/workspace/wifi-wpa-cr/usr/src
> 
> Please provide feedback to this list.  The review timer is set for two
> weeks (03/22/2007).
> 
> Several Sun employees have graciously agreed to do the review
> (assignments are listed below), but we welcome comments from the
> community at-large.
> 
> For part 1, there are 38 files to be reviewed, split into six areas:
> 
>    1. WPA protocol:        3 files,  ~3100 lines new
>       wpa.c, wpa_supplicant, wpa_impl.h
> 
>    2. DLPI related:        3 files,  ~260  lines new
>       l2_packet.[ch], ethernet.h
> 
>    3. Misc:                6 files,  ~1200 lines new
>       eloop.[ch], wpa_enc.[ch], driver.h, driver_wifi.c
> 
>    4. Packaging/Build:    17 files,  ~600 lines changed
>       Makefile, wpa.xml, svc-wpa, pkgdefs.
> 
>    5. GLDv3 Userland:      7 files,   ~600 lines changed
>       libwladm.[ch], mapfile-vers, Makefile.com, secobj.c,
>       libdladm.h, dladm.c
> 
>    6. GLDv3 Kernel:        2 files,   ~10  lines changed
>       dld_drv.c, dld.h
> 
> In the webrev, each file has been placed into one of the above areas.
> My proposed assignments are:
> 
>    Darren J Moffat and Cecilia Hu:             1. WPA Protocol
>    Sagun Shakya:                               2. DLPI related
>    David Chieu:                                3. Misc
>    David Bustos or a team member of SMF team:  4. Packaging/Build, and
>                                                   libwladm.c (smf)
>    Peter Memishian, Eric Cheng, Cathy Zhou:    5. GLDv3 Userland
>    Peter Memishian:                            6. GLDv3 Kernel
> 
> *Thanks* for your assistance, and let us know if you have questions.
> Have fun!  :-)
> 
> -----
> 
> [1] To provide more context when reviewing other kernel files, the
> net80211, ath, mac-wifi plugin files have been left in webrev/cscope.
> 
> [2] In particular, there are some small changes between 2006/046 and
> the provided materials; we will return to the ARC after code review.
> 

-- 

Cecilia.Hu at Sun.COM
Solaris x86 Engineering, Sun Microsystems
+86-10-82618200 ext. 82947 / 62673947

Reply via email to