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 1393793999 Lines: 29 29 100.0 %
Date: 2014-03-02 Functions: 1 1 100.0 %
Branches: 29 34 85.3 %

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

Generated by: LCOV version 1.9