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