LCOV - code coverage report
Current view: top level - src/eap_peer - eap_md5.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1401264779 Lines: 40 53 75.5 %
Date: 2014-05-28 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :  * EAP peer method: EAP-MD5 (RFC 3748 and RFC 1994)
       3             :  * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "includes.h"
      10             : 
      11             : #include "common.h"
      12             : #include "eap_i.h"
      13             : #include "eap_common/chap.h"
      14             : 
      15             : 
      16           2 : static void * eap_md5_init(struct eap_sm *sm)
      17             : {
      18             :         /* No need for private data. However, must return non-NULL to indicate
      19             :          * success. */
      20           2 :         return (void *) 1;
      21             : }
      22             : 
      23             : 
      24           2 : static void eap_md5_deinit(struct eap_sm *sm, void *priv)
      25             : {
      26           2 : }
      27             : 
      28             : 
      29           4 : static struct wpabuf * eap_md5_process(struct eap_sm *sm, void *priv,
      30             :                                        struct eap_method_ret *ret,
      31             :                                        const struct wpabuf *reqData)
      32             : {
      33             :         struct wpabuf *resp;
      34             :         const u8 *pos, *challenge, *password;
      35             :         u8 *rpos, id;
      36             :         size_t len, challenge_len, password_len;
      37             : 
      38           4 :         password = eap_get_config_password(sm, &password_len);
      39           4 :         if (password == NULL) {
      40           1 :                 wpa_printf(MSG_INFO, "EAP-MD5: Password not configured");
      41           1 :                 eap_sm_request_password(sm);
      42           1 :                 ret->ignore = TRUE;
      43           1 :                 return NULL;
      44             :         }
      45             : 
      46           3 :         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MD5, reqData, &len);
      47           3 :         if (pos == NULL || len == 0) {
      48           0 :                 wpa_printf(MSG_INFO, "EAP-MD5: Invalid frame (pos=%p len=%lu)",
      49             :                            pos, (unsigned long) len);
      50           0 :                 ret->ignore = TRUE;
      51           0 :                 return NULL;
      52             :         }
      53             : 
      54             :         /*
      55             :          * CHAP Challenge:
      56             :          * Value-Size (1 octet) | Value(Challenge) | Name(optional)
      57             :          */
      58           3 :         challenge_len = *pos++;
      59           3 :         if (challenge_len == 0 || challenge_len > len - 1) {
      60           0 :                 wpa_printf(MSG_INFO, "EAP-MD5: Invalid challenge "
      61             :                            "(challenge_len=%lu len=%lu)",
      62             :                            (unsigned long) challenge_len, (unsigned long) len);
      63           0 :                 ret->ignore = TRUE;
      64           0 :                 return NULL;
      65             :         }
      66           3 :         ret->ignore = FALSE;
      67           3 :         challenge = pos;
      68           3 :         wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge",
      69             :                     challenge, challenge_len);
      70             : 
      71           3 :         wpa_printf(MSG_DEBUG, "EAP-MD5: Generating Challenge Response");
      72           3 :         ret->methodState = METHOD_DONE;
      73           3 :         ret->decision = DECISION_COND_SUCC;
      74           3 :         ret->allowNotifications = TRUE;
      75             : 
      76           3 :         resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MD5, 1 + CHAP_MD5_LEN,
      77           3 :                              EAP_CODE_RESPONSE, eap_get_id(reqData));
      78           3 :         if (resp == NULL)
      79           0 :                 return NULL;
      80             : 
      81             :         /*
      82             :          * CHAP Response:
      83             :          * Value-Size (1 octet) | Value(Response) | Name(optional)
      84             :          */
      85           3 :         wpabuf_put_u8(resp, CHAP_MD5_LEN);
      86             : 
      87           3 :         id = eap_get_id(resp);
      88           3 :         rpos = wpabuf_put(resp, CHAP_MD5_LEN);
      89           3 :         if (chap_md5(id, password, password_len, challenge, challenge_len,
      90             :                      rpos)) {
      91           0 :                 wpa_printf(MSG_INFO, "EAP-MD5: CHAP MD5 operation failed");
      92           0 :                 ret->ignore = TRUE;
      93           0 :                 wpabuf_free(resp);
      94           0 :                 return NULL;
      95             :         }
      96           3 :         wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Response", rpos, CHAP_MD5_LEN);
      97             : 
      98           3 :         return resp;
      99             : }
     100             : 
     101             : 
     102           4 : int eap_peer_md5_register(void)
     103             : {
     104             :         struct eap_method *eap;
     105             :         int ret;
     106             : 
     107           4 :         eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
     108             :                                     EAP_VENDOR_IETF, EAP_TYPE_MD5, "MD5");
     109           4 :         if (eap == NULL)
     110           0 :                 return -1;
     111             : 
     112           4 :         eap->init = eap_md5_init;
     113           4 :         eap->deinit = eap_md5_deinit;
     114           4 :         eap->process = eap_md5_process;
     115             : 
     116           4 :         ret = eap_peer_method_register(eap);
     117           4 :         if (ret)
     118           0 :                 eap_peer_method_free(eap);
     119           4 :         return ret;
     120             : }

Generated by: LCOV version 1.10