eap_user_db.c 7.3 KB

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