2 * Host AP (software wireless LAN access point) user space daemon for
3 * Host AP kernel driver / Configuration file
4 * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * Alternatively, this software may be distributed under the terms of BSD
13 * See README and COPYING for more details.
19 #include <netinet/in.h>
21 #include <sys/socket.h>
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
33 static struct hostapd_config *hostapd_config_defaults(void)
35 struct hostapd_config *conf;
37 conf = malloc(sizeof(*conf));
39 printf("Failed to allocate memory for configuration data.\n");
42 memset(conf, 0, sizeof(*conf));
44 /* set default driver based on configuration */
45 conf->driver = driver_lookup("default");
46 if (conf->driver == NULL) {
47 printf("No default driver registered!\n");
52 conf->wep_rekeying_period = 300;
53 conf->eap_reauth_period = 3600;
55 conf->logger_syslog_level = HOSTAPD_LEVEL_INFO;
56 conf->logger_stdout_level = HOSTAPD_LEVEL_INFO;
57 conf->logger_syslog = (unsigned int) -1;
58 conf->logger_stdout = (unsigned int) -1;
60 conf->auth_algs = HOSTAPD_AUTH_OPEN | HOSTAPD_AUTH_SHARED_KEY;
62 conf->wpa_group_rekey = 600;
63 conf->wpa_gmk_rekey = 86400;
64 conf->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
65 conf->wpa_pairwise = WPA_CIPHER_TKIP;
66 conf->wpa_group = WPA_CIPHER_TKIP;
68 conf->radius_server_auth_port = 1812;
74 static int mac_comp(const void *a, const void *b)
76 return memcmp(a, b, sizeof(macaddr));
80 static int hostapd_config_read_maclist(const char *fname, macaddr **acl,
92 f = fopen(fname, "r");
94 printf("MAC list file '%s' not found.\n", fname);
98 while (fgets(buf, sizeof(buf), f)) {
104 while (*pos != '\0') {
114 if (hwaddr_aton(buf, addr)) {
115 printf("Invalid MAC address '%s' at line %d in '%s'\n",
121 newacl = (macaddr *) realloc(*acl, (*num + 1) * ETH_ALEN);
122 if (newacl == NULL) {
123 printf("MAC list reallocation failed\n");
129 memcpy((*acl)[*num], addr, ETH_ALEN);
135 qsort(*acl, *num, sizeof(macaddr), mac_comp);
141 static int hostapd_config_read_wpa_psk(const char *fname,
142 struct hostapd_config *conf)
146 int line = 0, ret = 0, len, ok;
148 struct hostapd_wpa_psk *psk;
153 f = fopen(fname, "r");
155 printf("WPA PSK file '%s' not found.\n", fname);
159 while (fgets(buf, sizeof(buf), f)) {
165 while (*pos != '\0') {
175 if (hwaddr_aton(buf, addr)) {
176 printf("Invalid MAC address '%s' on line %d in '%s'\n",
182 psk = malloc(sizeof(*psk));
184 printf("WPA PSK allocation failed\n");
188 memset(psk, 0, sizeof(*psk));
189 if (memcmp(addr, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
192 memcpy(psk->addr, addr, ETH_ALEN);
196 printf("No PSK on line %d in '%s'\n", line, fname);
205 if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0)
207 else if (len >= 8 && len < 64) {
208 pbkdf2_sha1(pos, conf->ssid, conf->ssid_len,
209 4096, psk->psk, PMK_LEN);
213 printf("Invalid PSK '%s' on line %d in '%s'\n",
220 psk->next = conf->wpa_psk;
230 int hostapd_setup_wpa_psk(struct hostapd_config *conf)
232 if (conf->wpa_passphrase != NULL) {
233 if (conf->wpa_psk != NULL) {
234 printf("Warning: both WPA PSK and passphrase set. "
235 "Using passphrase.\n");
238 conf->wpa_psk = malloc(sizeof(struct hostapd_wpa_psk));
239 if (conf->wpa_psk == NULL) {
240 printf("Unable to alloc space for PSK\n");
243 wpa_hexdump_ascii(MSG_DEBUG, "SSID",
244 (u8 *) conf->ssid, conf->ssid_len);
245 wpa_hexdump_ascii(MSG_DEBUG, "PSK (ASCII passphrase)",
246 (u8 *) conf->wpa_passphrase,
247 strlen(conf->wpa_passphrase));
248 memset(conf->wpa_psk, 0, sizeof(struct hostapd_wpa_psk));
249 pbkdf2_sha1(conf->wpa_passphrase,
250 conf->ssid, conf->ssid_len,
251 4096, conf->wpa_psk->psk, PMK_LEN);
252 wpa_hexdump(MSG_DEBUG, "PSK (from passphrase)",
253 conf->wpa_psk->psk, PMK_LEN);
254 conf->wpa_psk->group = 1;
256 memset(conf->wpa_passphrase, 0, strlen(conf->wpa_passphrase));
257 free(conf->wpa_passphrase);
258 conf->wpa_passphrase = 0;
261 if (conf->wpa_psk_file) {
262 if (hostapd_config_read_wpa_psk(conf->wpa_psk_file, conf))
264 free(conf->wpa_psk_file);
265 conf->wpa_psk_file = NULL;
272 #ifdef EAP_AUTHENTICATOR
273 static int hostapd_config_read_eap_user(const char *fname,
274 struct hostapd_config *conf)
277 char buf[512], *pos, *start;
278 int line = 0, ret = 0, num_methods;
279 struct hostapd_eap_user *user, *tail = NULL;
284 f = fopen(fname, "r");
286 printf("EAP user file '%s' not found.\n", fname);
290 /* Lines: "user" METHOD,METHOD2 "password" (password optional) */
291 while (fgets(buf, sizeof(buf), f)) {
297 while (*pos != '\0') {
309 if (buf[0] != '"' && buf[0] != '*') {
310 printf("Invalid EAP identity (no \" in start) on "
311 "line %d in '%s'\n", line, fname);
315 user = malloc(sizeof(*user));
317 printf("EAP user allocation failed\n");
320 memset(user, 0, sizeof(*user));
321 user->force_version = -1;
328 while (*pos != '"' && *pos != '\0')
331 printf("Invalid EAP identity (no \" in end) on"
332 " line %d in '%s'\n", line, fname);
336 user->identity = malloc(pos - start);
337 if (user->identity == NULL) {
338 printf("Failed to allocate memory for EAP "
342 memcpy(user->identity, start, pos - start);
343 user->identity_len = pos - start;
346 while (*pos == ' ' || *pos == '\t')
350 printf("No EAP method on line %d in '%s'\n",
356 while (*pos != ' ' && *pos != '\t' && *pos != '\0')
366 char *pos2 = strchr(start, ',');
370 user->methods[num_methods] = eap_get_type(start);
371 if (user->methods[num_methods] == EAP_TYPE_NONE) {
372 printf("Unsupported EAP type '%s' on line %d "
373 "in '%s'\n", start, line, fname);
378 if (num_methods >= EAP_USER_MAX_METHODS)
384 if (num_methods == 0) {
385 printf("No EAP types configured on line %d in '%s'\n",
393 while (*pos == ' ' || *pos == '\t')
398 if (strncmp(pos, "[ver=0]", 7) == 0) {
399 user->force_version = 0;
403 if (strncmp(pos, "[ver=1]", 7) == 0) {
404 user->force_version = 1;
408 if (strncmp(pos, "[2]", 3) == 0) {
414 printf("Invalid EAP password (no \" in start) on "
415 "line %d in '%s'\n", line, fname);
420 while (*pos != '"' && *pos != '\0')
423 printf("Invalid EAP password (no \" in end) on "
424 "line %d in '%s'\n", line, fname);
428 user->password = malloc(pos - start);
429 if (user->password == NULL) {
430 printf("Failed to allocate memory for EAP password\n");
433 memcpy(user->password, start, pos - start);
434 user->password_len = pos - start;
437 while (*pos == ' ' || *pos == '\t')
439 if (strncmp(pos, "[2]", 3) == 0) {
445 tail = conf->eap_user = user;
454 free(user->identity);
465 #endif /* EAP_AUTHENTICATOR */
469 hostapd_config_read_radius_addr(struct hostapd_radius_server **server,
470 int *num_server, const char *val, int def_port,
471 struct hostapd_radius_server **curr_serv)
473 struct hostapd_radius_server *nserv;
475 static int server_index = 1;
477 nserv = realloc(*server, (*num_server + 1) * sizeof(*nserv));
482 nserv = &nserv[*num_server];
484 (*curr_serv) = nserv;
486 memset(nserv, 0, sizeof(*nserv));
487 nserv->port = def_port;
488 ret = !inet_aton(val, &nserv->addr);
489 nserv->index = server_index++;
495 static int hostapd_config_parse_key_mgmt(int line, const char *value)
498 char *start, *end, *buf;
505 while (start != '\0') {
506 while (*start == ' ' || *start == '\t')
511 while (*end != ' ' && *end != '\t' && *end != '\0')
515 if (strcmp(start, "WPA-PSK") == 0)
516 val |= WPA_KEY_MGMT_PSK;
517 else if (strcmp(start, "WPA-EAP") == 0)
518 val |= WPA_KEY_MGMT_IEEE8021X;
520 printf("Line %d: invalid key_mgmt '%s'", line, start);
532 printf("Line %d: no key_mgmt values configured.", line);
540 static int hostapd_config_parse_cipher(int line, const char *value)
543 char *start, *end, *buf;
550 while (start != '\0') {
551 while (*start == ' ' || *start == '\t')
556 while (*end != ' ' && *end != '\t' && *end != '\0')
560 if (strcmp(start, "CCMP") == 0)
561 val |= WPA_CIPHER_CCMP;
562 else if (strcmp(start, "TKIP") == 0)
563 val |= WPA_CIPHER_TKIP;
564 else if (strcmp(start, "WEP104") == 0)
565 val |= WPA_CIPHER_WEP104;
566 else if (strcmp(start, "WEP40") == 0)
567 val |= WPA_CIPHER_WEP40;
568 else if (strcmp(start, "NONE") == 0)
569 val |= WPA_CIPHER_NONE;
571 printf("Line %d: invalid cipher '%s'.", line, start);
583 printf("Line %d: no cipher values configured.", line);
590 static int hostapd_config_check(struct hostapd_config *conf)
592 if (conf->ieee802_1x && !conf->eap_authenticator &&
593 !conf->auth_servers) {
594 printf("Invalid IEEE 802.1X configuration (no EAP "
595 "authenticator configured).\n");
599 if (conf->wpa && (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) &&
600 conf->wpa_psk == NULL && conf->wpa_passphrase == NULL &&
601 conf->wpa_psk_file == NULL) {
602 printf("WPA-PSK enabled, but PSK or passphrase is not "
611 struct hostapd_config * hostapd_config_read(const char *fname)
613 struct hostapd_config *conf;
618 char *accept_mac_file = NULL, *deny_mac_file = NULL;
619 #ifdef EAP_AUTHENTICATOR
620 char *eap_user_file = NULL;
621 #endif /* EAP_AUTHENTICATOR */
623 f = fopen(fname, "r");
625 printf("Could not open configuration file '%s' for reading.\n",
630 conf = hostapd_config_defaults();
636 while (fgets(buf, sizeof(buf), f)) {
642 while (*pos != '\0') {
652 pos = strchr(buf, '=');
654 printf("Line %d: invalid line '%s'\n", line, buf);
661 if (strcmp(buf, "interface") == 0) {
662 snprintf(conf->iface, sizeof(conf->iface), "%s", pos);
663 } else if (strcmp(buf, "bridge") == 0) {
664 snprintf(conf->bridge, sizeof(conf->bridge), "%s",
666 } else if (strcmp(buf, "driver") == 0) {
667 conf->driver = driver_lookup(pos);
668 if (conf->driver == NULL) {
669 printf("Line %d: invalid/unknown driver "
670 "'%s'\n", line, pos);
673 } else if (strcmp(buf, "debug") == 0) {
674 conf->debug = atoi(pos);
675 } else if (strcmp(buf, "logger_syslog_level") == 0) {
676 conf->logger_syslog_level = atoi(pos);
677 } else if (strcmp(buf, "logger_stdout_level") == 0) {
678 conf->logger_stdout_level = atoi(pos);
679 } else if (strcmp(buf, "logger_syslog") == 0) {
680 conf->logger_syslog = atoi(pos);
681 } else if (strcmp(buf, "logger_stdout") == 0) {
682 conf->logger_stdout = atoi(pos);
683 } else if (strcmp(buf, "dump_file") == 0) {
684 conf->dump_log_name = strdup(pos);
685 } else if (strcmp(buf, "ssid") == 0) {
686 conf->ssid_len = strlen(pos);
687 if (conf->ssid_len >= HOSTAPD_SSID_LEN ||
688 conf->ssid_len < 1) {
689 printf("Line %d: invalid SSID '%s'\n", line,
693 memcpy(conf->ssid, pos, conf->ssid_len);
694 conf->ssid[conf->ssid_len] = '\0';
696 } else if (strcmp(buf, "macaddr_acl") == 0) {
697 conf->macaddr_acl = atoi(pos);
698 if (conf->macaddr_acl != ACCEPT_UNLESS_DENIED &&
699 conf->macaddr_acl != DENY_UNLESS_ACCEPTED &&
700 conf->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {
701 printf("Line %d: unknown macaddr_acl %d\n",
702 line, conf->macaddr_acl);
704 } else if (strcmp(buf, "accept_mac_file") == 0) {
705 accept_mac_file = strdup(pos);
706 if (!accept_mac_file) {
707 printf("Line %d: allocation failed\n", line);
710 } else if (strcmp(buf, "deny_mac_file") == 0) {
711 deny_mac_file = strdup(pos);
712 if (!deny_mac_file) {
713 printf("Line %d: allocation failed\n", line);
716 } else if (strcmp(buf, "assoc_ap_addr") == 0) {
717 if (hwaddr_aton(pos, conf->assoc_ap_addr)) {
718 printf("Line %d: invalid MAC address '%s'\n",
723 } else if (strcmp(buf, "ieee8021x") == 0) {
724 conf->ieee802_1x = atoi(pos);
725 #ifdef EAP_AUTHENTICATOR
726 } else if (strcmp(buf, "eap_authenticator") == 0) {
727 conf->eap_authenticator = atoi(pos);
728 } else if (strcmp(buf, "eap_user_file") == 0) {
730 eap_user_file = strdup(pos);
731 if (!eap_user_file) {
732 printf("Line %d: allocation failed\n", line);
735 } else if (strcmp(buf, "ca_cert") == 0) {
737 conf->ca_cert = strdup(pos);
738 } else if (strcmp(buf, "server_cert") == 0) {
739 free(conf->server_cert);
740 conf->server_cert = strdup(pos);
741 } else if (strcmp(buf, "private_key") == 0) {
742 free(conf->private_key);
743 conf->private_key = strdup(pos);
744 } else if (strcmp(buf, "private_key_passwd") == 0) {
745 free(conf->private_key_passwd);
746 conf->private_key_passwd = strdup(pos);
748 } else if (strcmp(buf, "eap_sim_db") == 0) {
749 free(conf->eap_sim_db);
750 conf->eap_sim_db = strdup(pos);
752 #endif /* EAP_AUTHENTICATOR */
753 } else if (strcmp(buf, "eap_message") == 0) {
754 conf->eap_req_id_text = strdup(pos);
755 } else if (strcmp(buf, "wep_key_len_broadcast") == 0) {
756 conf->default_wep_key_len = atoi(pos);
757 if (conf->default_wep_key_len > 13) {
758 printf("Line %d: invalid WEP key len %lu "
759 "(= %lu bits)\n", line,
761 conf->default_wep_key_len,
763 conf->default_wep_key_len * 8);
766 } else if (strcmp(buf, "wep_key_len_unicast") == 0) {
767 conf->individual_wep_key_len = atoi(pos);
768 if (conf->individual_wep_key_len < 0 ||
769 conf->individual_wep_key_len > 13) {
770 printf("Line %d: invalid WEP key len %d "
771 "(= %d bits)\n", line,
772 conf->individual_wep_key_len,
773 conf->individual_wep_key_len * 8);
776 } else if (strcmp(buf, "wep_rekey_period") == 0) {
777 conf->wep_rekeying_period = atoi(pos);
778 if (conf->wep_rekeying_period < 0) {
779 printf("Line %d: invalid period %d\n",
780 line, conf->wep_rekeying_period);
783 } else if (strcmp(buf, "eap_reauth_period") == 0) {
784 conf->eap_reauth_period = atoi(pos);
785 if (conf->eap_reauth_period < 0) {
786 printf("Line %d: invalid period %d\n",
787 line, conf->eap_reauth_period);
790 } else if (strcmp(buf, "eapol_key_index_workaround") == 0) {
791 conf->eapol_key_index_workaround = atoi(pos);
793 } else if (strcmp(buf, "iapp_interface") == 0) {
794 conf->ieee802_11f = 1;
795 snprintf(conf->iapp_iface, sizeof(conf->iapp_iface),
797 #endif /* CONFIG_IAPP */
798 } else if (strcmp(buf, "own_ip_addr") == 0) {
799 if (!inet_aton(pos, &conf->own_ip_addr)) {
800 printf("Line %d: invalid IP address '%s'\n",
804 } else if (strcmp(buf, "nas_identifier") == 0) {
805 conf->nas_identifier = strdup(pos);
806 } else if (strcmp(buf, "auth_server_addr") == 0) {
807 if (hostapd_config_read_radius_addr(
809 &conf->num_auth_servers, pos, 1812,
810 &conf->auth_server)) {
811 printf("Line %d: invalid IP address '%s'\n",
815 } else if (conf->auth_server &&
816 strcmp(buf, "auth_server_port") == 0) {
817 conf->auth_server->port = atoi(pos);
818 } else if (conf->auth_server &&
819 strcmp(buf, "auth_server_shared_secret") == 0) {
820 int len = strlen(pos);
822 /* RFC 2865, Ch. 3 */
823 printf("Line %d: empty shared secret is not "
827 conf->auth_server->shared_secret = (u8 *) strdup(pos);
828 conf->auth_server->shared_secret_len = len;
829 } else if (strcmp(buf, "acct_server_addr") == 0) {
830 if (hostapd_config_read_radius_addr(
832 &conf->num_acct_servers, pos, 1813,
833 &conf->acct_server)) {
834 printf("Line %d: invalid IP address '%s'\n",
838 } else if (conf->acct_server &&
839 strcmp(buf, "acct_server_port") == 0) {
840 conf->acct_server->port = atoi(pos);
841 } else if (conf->acct_server &&
842 strcmp(buf, "acct_server_shared_secret") == 0) {
843 int len = strlen(pos);
845 /* RFC 2865, Ch. 3 */
846 printf("Line %d: empty shared secret is not "
850 conf->acct_server->shared_secret = (u8 *) strdup(pos);
851 conf->acct_server->shared_secret_len = len;
852 } else if (strcmp(buf, "radius_retry_primary_interval") == 0) {
853 conf->radius_retry_primary_interval = atoi(pos);
854 } else if (strcmp(buf, "radius_acct_interim_interval") == 0) {
855 conf->radius_acct_interim_interval = atoi(pos);
856 } else if (strcmp(buf, "auth_algs") == 0) {
857 conf->auth_algs = atoi(pos);
858 if (conf->auth_algs == 0) {
859 printf("Line %d: no authentication algorithms "
864 } else if (strcmp(buf, "wpa") == 0) {
865 conf->wpa = atoi(pos);
866 } else if (strcmp(buf, "wpa_group_rekey") == 0) {
867 conf->wpa_group_rekey = atoi(pos);
868 } else if (strcmp(buf, "wpa_strict_rekey") == 0) {
869 conf->wpa_strict_rekey = atoi(pos);
870 } else if (strcmp(buf, "wpa_gmk_rekey") == 0) {
871 conf->wpa_gmk_rekey = atoi(pos);
872 } else if (strcmp(buf, "wpa_passphrase") == 0) {
873 int len = strlen(pos);
874 if (len < 8 || len > 63) {
875 printf("Line %d: invalid WPA passphrase length"
876 " %d (expected 8..63)\n", line, len);
879 free(conf->wpa_passphrase);
880 conf->wpa_passphrase = strdup(pos);
882 } else if (strcmp(buf, "wpa_psk") == 0) {
884 conf->wpa_psk = malloc(sizeof(struct hostapd_wpa_psk));
886 memset(conf->wpa_psk, 0,
887 sizeof(struct hostapd_wpa_psk));
889 if (conf->wpa_psk == NULL)
891 else if (hexstr2bin(pos, conf->wpa_psk->psk, PMK_LEN)
892 || pos[PMK_LEN * 2] != '\0') {
893 printf("Line %d: Invalid PSK '%s'.\n", line,
897 conf->wpa_psk->group = 1;
899 } else if (strcmp(buf, "wpa_psk_file") == 0) {
900 free(conf->wpa_psk_file);
901 conf->wpa_psk_file = strdup(pos);
902 if (!conf->wpa_psk_file) {
903 printf("Line %d: allocation failed\n", line);
906 } else if (strcmp(buf, "wpa_key_mgmt") == 0) {
908 hostapd_config_parse_key_mgmt(line, pos);
909 if (conf->wpa_key_mgmt == -1)
911 } else if (strcmp(buf, "wpa_pairwise") == 0) {
913 hostapd_config_parse_cipher(line, pos);
914 if (conf->wpa_pairwise == -1 ||
915 conf->wpa_pairwise == 0)
917 else if (conf->wpa_pairwise &
918 (WPA_CIPHER_NONE | WPA_CIPHER_WEP40 |
919 WPA_CIPHER_WEP104)) {
920 printf("Line %d: unsupported pairwise "
921 "cipher suite '%s'\n",
922 conf->wpa_pairwise, pos);
925 if (conf->wpa_pairwise & WPA_CIPHER_TKIP)
926 conf->wpa_group = WPA_CIPHER_TKIP;
928 conf->wpa_group = WPA_CIPHER_CCMP;
930 #ifdef CONFIG_RSN_PREAUTH
931 } else if (strcmp(buf, "rsn_preauth") == 0) {
932 conf->rsn_preauth = atoi(pos);
933 } else if (strcmp(buf, "rsn_preauth_interfaces") == 0) {
934 conf->rsn_preauth_interfaces = strdup(pos);
935 #endif /* CONFIG_RSN_PREAUTH */
936 } else if (strcmp(buf, "ctrl_interface") == 0) {
937 free(conf->ctrl_interface);
938 conf->ctrl_interface = strdup(pos);
939 } else if (strcmp(buf, "ctrl_interface_group") == 0) {
942 const char *group = pos;
944 grp = getgrnam(group);
946 conf->ctrl_interface_gid = grp->gr_gid;
947 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
948 " (from group name '%s')",
949 conf->ctrl_interface_gid, group);
953 /* Group name not found - try to parse this as gid */
954 conf->ctrl_interface_gid = strtol(group, &endp, 10);
955 if (*group == '\0' || *endp != '\0') {
956 wpa_printf(MSG_DEBUG, "Line %d: Invalid group "
957 "'%s'", line, group);
961 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
962 conf->ctrl_interface_gid);
964 } else if (strcmp(buf, "radius_server_clients") == 0) {
965 free(conf->radius_server_clients);
966 conf->radius_server_clients = strdup(pos);
967 } else if (strcmp(buf, "radius_server_auth_port") == 0) {
968 conf->radius_server_auth_port = atoi(pos);
969 #endif /* RADIUS_SERVER */
971 printf("Line %d: unknown configuration item '%s'\n",
979 if (hostapd_config_read_maclist(accept_mac_file, &conf->accept_mac,
980 &conf->num_accept_mac))
982 free(accept_mac_file);
983 if (hostapd_config_read_maclist(deny_mac_file, &conf->deny_mac,
984 &conf->num_deny_mac))
988 #ifdef EAP_AUTHENTICATOR
989 if (hostapd_config_read_eap_user(eap_user_file, conf))
992 #endif /* EAP_AUTHENTICATOR */
994 conf->auth_server = conf->auth_servers;
995 conf->acct_server = conf->acct_servers;
997 if (hostapd_config_check(conf))
1001 printf("%d errors found in configuration file '%s'\n",
1003 hostapd_config_free(conf);
1011 static void hostapd_config_free_radius(struct hostapd_radius_server *servers,
1016 for (i = 0; i < num_servers; i++) {
1017 free(servers[i].shared_secret);
1023 static void hostapd_config_free_eap_user(struct hostapd_eap_user *user)
1025 free(user->identity);
1026 free(user->password);
1031 void hostapd_config_free(struct hostapd_config *conf)
1033 struct hostapd_wpa_psk *psk, *prev;
1034 struct hostapd_eap_user *user, *prev_user;
1039 psk = conf->wpa_psk;
1046 free(conf->wpa_passphrase);
1047 free(conf->wpa_psk_file);
1049 user = conf->eap_user;
1053 hostapd_config_free_eap_user(prev_user);
1056 free(conf->dump_log_name);
1057 free(conf->eap_req_id_text);
1058 free(conf->accept_mac);
1059 free(conf->deny_mac);
1060 free(conf->nas_identifier);
1061 hostapd_config_free_radius(conf->auth_servers, conf->num_auth_servers);
1062 hostapd_config_free_radius(conf->acct_servers, conf->num_acct_servers);
1063 free(conf->rsn_preauth_interfaces);
1064 free(conf->ctrl_interface);
1065 free(conf->ca_cert);
1066 free(conf->server_cert);
1067 free(conf->private_key);
1068 free(conf->private_key_passwd);
1069 free(conf->eap_sim_db);
1070 free(conf->radius_server_clients);
1075 /* Perform a binary search for given MAC address from a pre-sorted list.
1076 * Returns 1 if address is in the list or 0 if not. */
1077 int hostapd_maclist_found(macaddr *list, int num_entries, u8 *addr)
1079 int start, end, middle, res;
1082 end = num_entries - 1;
1084 while (start <= end) {
1085 middle = (start + end) / 2;
1086 res = memcmp(list[middle], addr, ETH_ALEN);
1099 const u8 * hostapd_get_psk(const struct hostapd_config *conf, const u8 *addr,
1102 struct hostapd_wpa_psk *psk;
1103 int next_ok = prev_psk == NULL;
1105 for (psk = conf->wpa_psk; psk != NULL; psk = psk->next) {
1107 (psk->group || memcmp(psk->addr, addr, ETH_ALEN) == 0))
1110 if (psk->psk == prev_psk)
1118 const struct hostapd_eap_user *
1119 hostapd_get_eap_user(const struct hostapd_config *conf, const u8 *identity,
1120 size_t identity_len, int phase2)
1122 struct hostapd_eap_user *user = conf->eap_user;
1125 if (!phase2 && user->identity == NULL) {
1126 /* Wildcard match */
1129 if (user->phase2 == !!phase2 &&
1130 user->identity_len == identity_len &&
1131 memcmp(user->identity, identity, identity_len) == 0)