LCOV - code coverage report
Current view: top level - src/ap - eap_user_db.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1401264779 Lines: 135 154 87.7 %
Date: 2014-05-28 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :  * hostapd / EAP user database
       3             :  * Copyright (c) 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             : #ifdef CONFIG_SQLITE
      11             : #include <sqlite3.h>
      12             : #endif /* CONFIG_SQLITE */
      13             : 
      14             : #include "common.h"
      15             : #include "eap_common/eap_wsc_common.h"
      16             : #include "eap_server/eap_methods.h"
      17             : #include "eap_server/eap.h"
      18             : #include "ap_config.h"
      19             : #include "hostapd.h"
      20             : 
      21             : #ifdef CONFIG_SQLITE
      22             : 
      23          11 : static void set_user_methods(struct hostapd_eap_user *user, const char *methods)
      24             : {
      25             :         char *buf, *start;
      26             :         int num_methods;
      27             : 
      28          11 :         buf = os_strdup(methods);
      29          11 :         if (buf == NULL)
      30           0 :                 return;
      31             : 
      32          11 :         os_memset(&user->methods, 0, sizeof(user->methods));
      33          11 :         num_methods = 0;
      34          11 :         start = buf;
      35          28 :         while (*start) {
      36          17 :                 char *pos3 = os_strchr(start, ',');
      37          17 :                 if (pos3)
      38           6 :                         *pos3++ = '\0';
      39          17 :                 user->methods[num_methods].method =
      40          17 :                         eap_server_get_type(start,
      41             :                                             &user->methods[num_methods].vendor);
      42          34 :                 if (user->methods[num_methods].vendor == EAP_VENDOR_IETF &&
      43          17 :                     user->methods[num_methods].method == EAP_TYPE_NONE) {
      44           5 :                         if (os_strcmp(start, "TTLS-PAP") == 0) {
      45           1 :                                 user->ttls_auth |= EAP_TTLS_AUTH_PAP;
      46           1 :                                 goto skip_eap;
      47             :                         }
      48           4 :                         if (os_strcmp(start, "TTLS-CHAP") == 0) {
      49           1 :                                 user->ttls_auth |= EAP_TTLS_AUTH_CHAP;
      50           1 :                                 goto skip_eap;
      51             :                         }
      52           3 :                         if (os_strcmp(start, "TTLS-MSCHAP") == 0) {
      53           1 :                                 user->ttls_auth |= EAP_TTLS_AUTH_MSCHAP;
      54           1 :                                 goto skip_eap;
      55             :                         }
      56           2 :                         if (os_strcmp(start, "TTLS-MSCHAPV2") == 0) {
      57           2 :                                 user->ttls_auth |= EAP_TTLS_AUTH_MSCHAPV2;
      58           2 :                                 goto skip_eap;
      59             :                         }
      60           0 :                         wpa_printf(MSG_INFO, "DB: Unsupported EAP type '%s'",
      61             :                                    start);
      62           0 :                         os_free(buf);
      63           0 :                         return;
      64             :                 }
      65             : 
      66          12 :                 num_methods++;
      67          12 :                 if (num_methods >= EAP_MAX_METHODS)
      68           0 :                         break;
      69             :         skip_eap:
      70          17 :                 if (pos3 == NULL)
      71          11 :                         break;
      72           6 :                 start = pos3;
      73             :         }
      74             : 
      75          11 :         os_free(buf);
      76             : }
      77             : 
      78             : 
      79           5 : static int get_user_cb(void *ctx, int argc, char *argv[], char *col[])
      80             : {
      81           5 :         struct hostapd_eap_user *user = ctx;
      82             :         int i;
      83             : 
      84          30 :         for (i = 0; i < argc; i++) {
      85          25 :                 if (os_strcmp(col[i], "password") == 0 && argv[i]) {
      86           5 :                         os_free(user->password);
      87           5 :                         user->password_len = os_strlen(argv[i]);
      88           5 :                         user->password = (u8 *) os_strdup(argv[i]);
      89           5 :                         user->next = (void *) 1;
      90          20 :                 } else if (os_strcmp(col[i], "methods") == 0 && argv[i]) {
      91           5 :                         set_user_methods(user, argv[i]);
      92          15 :                 } else if (os_strcmp(col[i], "remediation") == 0 && argv[i]) {
      93           1 :                         user->remediation = strlen(argv[i]) > 0;
      94             :                 }
      95             :         }
      96             : 
      97           5 :         return 0;
      98             : }
      99             : 
     100             : 
     101           6 : static int get_wildcard_cb(void *ctx, int argc, char *argv[], char *col[])
     102             : {
     103           6 :         struct hostapd_eap_user *user = ctx;
     104           6 :         int i, id = -1, methods = -1;
     105             :         size_t len;
     106             : 
     107          18 :         for (i = 0; i < argc; i++) {
     108          12 :                 if (os_strcmp(col[i], "identity") == 0 && argv[i])
     109           6 :                         id = i;
     110           6 :                 else if (os_strcmp(col[i], "methods") == 0 && argv[i])
     111           6 :                         methods = i;
     112             :         }
     113             : 
     114           6 :         if (id < 0 || methods < 0)
     115           0 :                 return 0;
     116             : 
     117           6 :         len = os_strlen(argv[id]);
     118          12 :         if (len <= user->identity_len &&
     119          12 :             os_memcmp(argv[id], user->identity, len) == 0 &&
     120           6 :             (user->password == NULL || len > user->password_len)) {
     121           6 :                 os_free(user->password);
     122           6 :                 user->password_len = os_strlen(argv[id]);
     123           6 :                 user->password = (u8 *) os_strdup(argv[id]);
     124           6 :                 user->next = (void *) 1;
     125           6 :                 set_user_methods(user, argv[methods]);
     126             :         }
     127             : 
     128           6 :         return 0;
     129             : }
     130             : 
     131             : 
     132             : static const struct hostapd_eap_user *
     133          11 : eap_user_sqlite_get(struct hostapd_data *hapd, const u8 *identity,
     134             :                     size_t identity_len, int phase2)
     135             : {
     136             :         sqlite3 *db;
     137          11 :         struct hostapd_eap_user *user = NULL;
     138             :         char id_str[256], cmd[300];
     139             :         size_t i;
     140             : 
     141          11 :         if (identity_len >= sizeof(id_str))
     142           0 :                 return NULL;
     143          11 :         os_memcpy(id_str, identity, identity_len);
     144          11 :         id_str[identity_len] = '\0';
     145         123 :         for (i = 0; i < identity_len; i++) {
     146         112 :                 if (id_str[i] >= 'a' && id_str[i] <= 'z')
     147         101 :                         continue;
     148          11 :                 if (id_str[i] >= 'A' && id_str[i] <= 'Z')
     149           0 :                         continue;
     150          11 :                 if (id_str[i] >= '0' && id_str[i] <= '9')
     151           2 :                         continue;
     152          11 :                 if (id_str[i] == '-' || id_str[i] == '_' || id_str[i] == '.' ||
     153           4 :                     id_str[i] == ',' || id_str[i] == '@' || id_str[i] == '\\' ||
     154           0 :                     id_str[i] == '!' || id_str[i] == '#' || id_str[i] == '%' ||
     155           0 :                     id_str[i] == '=' || id_str[i] == ' ')
     156           9 :                         continue;
     157           0 :                 wpa_printf(MSG_INFO, "DB: Unsupported character in identity");
     158           0 :                 return NULL;
     159             :         }
     160             : 
     161          11 :         os_free(hapd->tmp_eap_user.identity);
     162          11 :         os_free(hapd->tmp_eap_user.password);
     163          11 :         os_memset(&hapd->tmp_eap_user, 0, sizeof(hapd->tmp_eap_user));
     164          11 :         hapd->tmp_eap_user.phase2 = phase2;
     165          11 :         hapd->tmp_eap_user.identity = os_zalloc(identity_len + 1);
     166          11 :         if (hapd->tmp_eap_user.identity == NULL)
     167           0 :                 return NULL;
     168          11 :         os_memcpy(hapd->tmp_eap_user.identity, identity, identity_len);
     169             : 
     170          11 :         if (sqlite3_open(hapd->conf->eap_user_sqlite, &db)) {
     171           0 :                 wpa_printf(MSG_INFO, "DB: Failed to open database %s: %s",
     172           0 :                            hapd->conf->eap_user_sqlite, sqlite3_errmsg(db));
     173           0 :                 sqlite3_close(db);
     174           0 :                 return NULL;
     175             :         }
     176             : 
     177          11 :         os_snprintf(cmd, sizeof(cmd),
     178             :                     "SELECT * FROM users WHERE identity='%s' AND phase2=%d;",
     179             :                     id_str, phase2);
     180          11 :         wpa_printf(MSG_DEBUG, "DB: %s", cmd);
     181          11 :         if (sqlite3_exec(db, cmd, get_user_cb, &hapd->tmp_eap_user, NULL) !=
     182             :             SQLITE_OK) {
     183           0 :                 wpa_printf(MSG_DEBUG, "DB: Failed to complete SQL operation");
     184          11 :         } else if (hapd->tmp_eap_user.next)
     185           5 :                 user = &hapd->tmp_eap_user;
     186             : 
     187          11 :         if (user == NULL && !phase2) {
     188           6 :                 os_snprintf(cmd, sizeof(cmd),
     189             :                             "SELECT identity,methods FROM wildcards;");
     190           6 :                 wpa_printf(MSG_DEBUG, "DB: %s", cmd);
     191           6 :                 if (sqlite3_exec(db, cmd, get_wildcard_cb, &hapd->tmp_eap_user,
     192             :                                  NULL) != SQLITE_OK) {
     193           0 :                         wpa_printf(MSG_DEBUG, "DB: Failed to complete SQL "
     194             :                                    "operation");
     195           6 :                 } else if (hapd->tmp_eap_user.next) {
     196           6 :                         user = &hapd->tmp_eap_user;
     197           6 :                         os_free(user->identity);
     198           6 :                         user->identity = user->password;
     199           6 :                         user->identity_len = user->password_len;
     200           6 :                         user->password = NULL;
     201           6 :                         user->password_len = 0;
     202             :                 }
     203             :         }
     204             : 
     205          11 :         sqlite3_close(db);
     206             : 
     207          11 :         return user;
     208             : }
     209             : 
     210             : #endif /* CONFIG_SQLITE */
     211             : 
     212             : 
     213             : const struct hostapd_eap_user *
     214        1052 : hostapd_get_eap_user(struct hostapd_data *hapd, const u8 *identity,
     215             :                      size_t identity_len, int phase2)
     216             : {
     217        1052 :         const struct hostapd_bss_config *conf = hapd->conf;
     218        1052 :         struct hostapd_eap_user *user = conf->eap_user;
     219             : 
     220             : #ifdef CONFIG_WPS
     221        1214 :         if (conf->wps_state && identity_len == WSC_ID_ENROLLEE_LEN &&
     222         162 :             os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) {
     223             :                 static struct hostapd_eap_user wsc_enrollee;
     224         162 :                 os_memset(&wsc_enrollee, 0, sizeof(wsc_enrollee));
     225         162 :                 wsc_enrollee.methods[0].method = eap_server_get_type(
     226             :                         "WSC", &wsc_enrollee.methods[0].vendor);
     227         162 :                 return &wsc_enrollee;
     228             :         }
     229             : 
     230         928 :         if (conf->wps_state && identity_len == WSC_ID_REGISTRAR_LEN &&
     231          38 :             os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) {
     232             :                 static struct hostapd_eap_user wsc_registrar;
     233          38 :                 os_memset(&wsc_registrar, 0, sizeof(wsc_registrar));
     234          38 :                 wsc_registrar.methods[0].method = eap_server_get_type(
     235             :                         "WSC", &wsc_registrar.methods[0].vendor);
     236          38 :                 wsc_registrar.password = (u8 *) conf->ap_pin;
     237          76 :                 wsc_registrar.password_len = conf->ap_pin ?
     238          38 :                         os_strlen(conf->ap_pin) : 0;
     239          38 :                 return &wsc_registrar;
     240             :         }
     241             : #endif /* CONFIG_WPS */
     242             : 
     243       22426 :         while (user) {
     244       21562 :                 if (!phase2 && user->identity == NULL) {
     245             :                         /* Wildcard match */
     246         335 :                         break;
     247             :                 }
     248             : 
     249       26137 :                 if (user->phase2 == !!phase2 && user->wildcard_prefix &&
     250        9820 :                     identity_len >= user->identity_len &&
     251        4910 :                     os_memcmp(user->identity, identity, user->identity_len) ==
     252             :                     0) {
     253             :                         /* Wildcard prefix match */
     254         126 :                         break;
     255             :                 }
     256             : 
     257       37612 :                 if (user->phase2 == !!phase2 &&
     258       17881 :                     user->identity_len == identity_len &&
     259        1370 :                     os_memcmp(user->identity, identity, identity_len) == 0)
     260         379 :                         break;
     261       20722 :                 user = user->next;
     262             :         }
     263             : 
     264             : #ifdef CONFIG_SQLITE
     265         852 :         if (user == NULL && conf->eap_user_sqlite) {
     266          11 :                 return eap_user_sqlite_get(hapd, identity, identity_len,
     267             :                                            phase2);
     268             :         }
     269             : #endif /* CONFIG_SQLITE */
     270             : 
     271         841 :         return user;
     272             : }

Generated by: LCOV version 1.10