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 1443382998 Lines: 135 157 86.0 %
Date: 2015-09-27 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 :                         bin_clear_free(user->password, user->password_len);
      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 :                 bin_clear_free(user->password, user->password_len);
     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 :                 wpa_printf(MSG_DEBUG, "%s: identity len too big: %d >= %d",
     143             :                            __func__, (int) identity_len,
     144             :                            (int) (sizeof(id_str)));
     145           0 :                 return NULL;
     146             :         }
     147          11 :         os_memcpy(id_str, identity, identity_len);
     148          11 :         id_str[identity_len] = '\0';
     149         123 :         for (i = 0; i < identity_len; i++) {
     150         112 :                 if (id_str[i] >= 'a' && id_str[i] <= 'z')
     151         101 :                         continue;
     152          11 :                 if (id_str[i] >= 'A' && id_str[i] <= 'Z')
     153           0 :                         continue;
     154          11 :                 if (id_str[i] >= '0' && id_str[i] <= '9')
     155           2 :                         continue;
     156          11 :                 if (id_str[i] == '-' || id_str[i] == '_' || id_str[i] == '.' ||
     157           4 :                     id_str[i] == ',' || id_str[i] == '@' || id_str[i] == '\\' ||
     158           0 :                     id_str[i] == '!' || id_str[i] == '#' || id_str[i] == '%' ||
     159           0 :                     id_str[i] == '=' || id_str[i] == ' ')
     160           9 :                         continue;
     161           0 :                 wpa_printf(MSG_INFO, "DB: Unsupported character in identity");
     162           0 :                 return NULL;
     163             :         }
     164             : 
     165          11 :         bin_clear_free(hapd->tmp_eap_user.identity,
     166             :                        hapd->tmp_eap_user.identity_len);
     167          11 :         bin_clear_free(hapd->tmp_eap_user.password,
     168             :                        hapd->tmp_eap_user.password_len);
     169          11 :         os_memset(&hapd->tmp_eap_user, 0, sizeof(hapd->tmp_eap_user));
     170          11 :         hapd->tmp_eap_user.phase2 = phase2;
     171          11 :         hapd->tmp_eap_user.identity = os_zalloc(identity_len + 1);
     172          11 :         if (hapd->tmp_eap_user.identity == NULL)
     173           0 :                 return NULL;
     174          11 :         os_memcpy(hapd->tmp_eap_user.identity, identity, identity_len);
     175             : 
     176          11 :         if (sqlite3_open(hapd->conf->eap_user_sqlite, &db)) {
     177           0 :                 wpa_printf(MSG_INFO, "DB: Failed to open database %s: %s",
     178           0 :                            hapd->conf->eap_user_sqlite, sqlite3_errmsg(db));
     179           0 :                 sqlite3_close(db);
     180           0 :                 return NULL;
     181             :         }
     182             : 
     183          11 :         os_snprintf(cmd, sizeof(cmd),
     184             :                     "SELECT * FROM users WHERE identity='%s' AND phase2=%d;",
     185             :                     id_str, phase2);
     186          11 :         wpa_printf(MSG_DEBUG, "DB: %s", cmd);
     187          11 :         if (sqlite3_exec(db, cmd, get_user_cb, &hapd->tmp_eap_user, NULL) !=
     188             :             SQLITE_OK) {
     189           0 :                 wpa_printf(MSG_DEBUG,
     190             :                            "DB: Failed to complete SQL operation: %s  db: %s",
     191           0 :                            sqlite3_errmsg(db), hapd->conf->eap_user_sqlite);
     192          11 :         } else if (hapd->tmp_eap_user.next)
     193           5 :                 user = &hapd->tmp_eap_user;
     194             : 
     195          11 :         if (user == NULL && !phase2) {
     196           6 :                 os_snprintf(cmd, sizeof(cmd),
     197             :                             "SELECT identity,methods FROM wildcards;");
     198           6 :                 wpa_printf(MSG_DEBUG, "DB: %s", cmd);
     199           6 :                 if (sqlite3_exec(db, cmd, get_wildcard_cb, &hapd->tmp_eap_user,
     200             :                                  NULL) != SQLITE_OK) {
     201           0 :                         wpa_printf(MSG_DEBUG,
     202             :                                    "DB: Failed to complete SQL operation: %s  db: %s",
     203             :                                    sqlite3_errmsg(db),
     204           0 :                                    hapd->conf->eap_user_sqlite);
     205           6 :                 } else if (hapd->tmp_eap_user.next) {
     206           6 :                         user = &hapd->tmp_eap_user;
     207           6 :                         os_free(user->identity);
     208           6 :                         user->identity = user->password;
     209           6 :                         user->identity_len = user->password_len;
     210           6 :                         user->password = NULL;
     211           6 :                         user->password_len = 0;
     212             :                 }
     213             :         }
     214             : 
     215          11 :         sqlite3_close(db);
     216             : 
     217          11 :         return user;
     218             : }
     219             : 
     220             : #endif /* CONFIG_SQLITE */
     221             : 
     222             : 
     223             : const struct hostapd_eap_user *
     224        2665 : hostapd_get_eap_user(struct hostapd_data *hapd, const u8 *identity,
     225             :                      size_t identity_len, int phase2)
     226             : {
     227        2665 :         const struct hostapd_bss_config *conf = hapd->conf;
     228        2665 :         struct hostapd_eap_user *user = conf->eap_user;
     229             : 
     230             : #ifdef CONFIG_WPS
     231        3063 :         if (conf->wps_state && identity_len == WSC_ID_ENROLLEE_LEN &&
     232         398 :             os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) {
     233             :                 static struct hostapd_eap_user wsc_enrollee;
     234         398 :                 os_memset(&wsc_enrollee, 0, sizeof(wsc_enrollee));
     235         398 :                 wsc_enrollee.methods[0].method = eap_server_get_type(
     236             :                         "WSC", &wsc_enrollee.methods[0].vendor);
     237         398 :                 return &wsc_enrollee;
     238             :         }
     239             : 
     240        2329 :         if (conf->wps_state && identity_len == WSC_ID_REGISTRAR_LEN &&
     241          62 :             os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) {
     242             :                 static struct hostapd_eap_user wsc_registrar;
     243          62 :                 os_memset(&wsc_registrar, 0, sizeof(wsc_registrar));
     244          62 :                 wsc_registrar.methods[0].method = eap_server_get_type(
     245             :                         "WSC", &wsc_registrar.methods[0].vendor);
     246          62 :                 wsc_registrar.password = (u8 *) conf->ap_pin;
     247         124 :                 wsc_registrar.password_len = conf->ap_pin ?
     248          62 :                         os_strlen(conf->ap_pin) : 0;
     249          62 :                 return &wsc_registrar;
     250             :         }
     251             : #endif /* CONFIG_WPS */
     252             : 
     253       62304 :         while (user) {
     254       60086 :                 if (!phase2 && user->identity == NULL) {
     255             :                         /* Wildcard match */
     256         585 :                         break;
     257             :                 }
     258             : 
     259       67629 :                 if (user->phase2 == !!phase2 && user->wildcard_prefix &&
     260       16256 :                     identity_len >= user->identity_len &&
     261        8128 :                     os_memcmp(user->identity, identity, user->identity_len) ==
     262             :                     0) {
     263             :                         /* Wildcard prefix match */
     264         213 :                         break;
     265             :                 }
     266             : 
     267      105187 :                 if (user->phase2 == !!phase2 &&
     268       49473 :                     user->identity_len == identity_len &&
     269        3574 :                     os_memcmp(user->identity, identity, identity_len) == 0)
     270        1394 :                         break;
     271       57894 :                 user = user->next;
     272             :         }
     273             : 
     274             : #ifdef CONFIG_SQLITE
     275        2205 :         if (user == NULL && conf->eap_user_sqlite) {
     276          11 :                 return eap_user_sqlite_get(hapd, identity, identity_len,
     277             :                                            phase2);
     278             :         }
     279             : #endif /* CONFIG_SQLITE */
     280             : 
     281        2194 :         return user;
     282             : }

Generated by: LCOV version 1.10