2 * Host AP (software wireless LAN access point) user space daemon for
3 * Host AP kernel driver / Configuration file
4 * Copyright (c) 2003-2006, 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>
31 #include "radius_client.h"
32 #include "ieee802_1x.h"
35 static struct hostapd_config *hostapd_config_defaults(void)
37 struct hostapd_config *conf;
39 conf = malloc(sizeof(*conf) + sizeof(struct hostapd_radius_servers));
41 printf("Failed to allocate memory for configuration data.\n");
44 memset(conf, 0, sizeof(*conf) + sizeof(struct hostapd_radius_servers));
45 conf->radius = (struct hostapd_radius_servers *) (conf + 1);
47 /* set default driver based on configuration */
48 conf->driver = driver_lookup("default");
49 if (conf->driver == NULL) {
50 printf("No default driver registered!\n");
55 conf->wep_rekeying_period = 300;
56 conf->eap_reauth_period = 3600;
58 conf->logger_syslog_level = HOSTAPD_LEVEL_INFO;
59 conf->logger_stdout_level = HOSTAPD_LEVEL_INFO;
60 conf->logger_syslog = (unsigned int) -1;
61 conf->logger_stdout = (unsigned int) -1;
63 conf->auth_algs = HOSTAPD_AUTH_OPEN | HOSTAPD_AUTH_SHARED_KEY;
64 conf->eapol_version = EAPOL_VERSION;
66 conf->wpa_group_rekey = 600;
67 conf->wpa_gmk_rekey = 86400;
68 conf->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
69 conf->wpa_pairwise = WPA_CIPHER_TKIP;
70 conf->wpa_group = WPA_CIPHER_TKIP;
72 conf->radius_server_auth_port = 1812;
78 static int hostapd_parse_ip_addr(const char *txt, struct hostapd_ip_addr *addr)
80 if (inet_aton(txt, &addr->u.v4)) {
86 if (inet_pton(AF_INET6, txt, &addr->u.v6) > 0) {
90 #endif /* CONFIG_IPV6 */
96 static int mac_comp(const void *a, const void *b)
98 return memcmp(a, b, sizeof(macaddr));
102 static int hostapd_config_read_maclist(const char *fname, macaddr **acl,
114 f = fopen(fname, "r");
116 printf("MAC list file '%s' not found.\n", fname);
120 while (fgets(buf, sizeof(buf), f)) {
126 while (*pos != '\0') {
136 if (hwaddr_aton(buf, addr)) {
137 printf("Invalid MAC address '%s' at line %d in '%s'\n",
143 newacl = (macaddr *) realloc(*acl, (*num + 1) * ETH_ALEN);
144 if (newacl == NULL) {
145 printf("MAC list reallocation failed\n");
151 memcpy((*acl)[*num], addr, ETH_ALEN);
157 qsort(*acl, *num, sizeof(macaddr), mac_comp);
163 static int hostapd_config_read_wpa_psk(const char *fname,
164 struct hostapd_config *conf)
168 int line = 0, ret = 0, len, ok;
170 struct hostapd_wpa_psk *psk;
175 f = fopen(fname, "r");
177 printf("WPA PSK file '%s' not found.\n", fname);
181 while (fgets(buf, sizeof(buf), f)) {
187 while (*pos != '\0') {
197 if (hwaddr_aton(buf, addr)) {
198 printf("Invalid MAC address '%s' on line %d in '%s'\n",
204 psk = malloc(sizeof(*psk));
206 printf("WPA PSK allocation failed\n");
210 memset(psk, 0, sizeof(*psk));
211 if (memcmp(addr, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
214 memcpy(psk->addr, addr, ETH_ALEN);
218 printf("No PSK on line %d in '%s'\n", line, fname);
227 if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0)
229 else if (len >= 8 && len < 64) {
230 pbkdf2_sha1(pos, conf->ssid, conf->ssid_len,
231 4096, psk->psk, PMK_LEN);
235 printf("Invalid PSK '%s' on line %d in '%s'\n",
242 psk->next = conf->wpa_psk;
252 int hostapd_setup_wpa_psk(struct hostapd_config *conf)
254 if (conf->wpa_passphrase != NULL) {
255 if (conf->wpa_psk != NULL) {
256 printf("Warning: both WPA PSK and passphrase set. "
257 "Using passphrase.\n");
260 conf->wpa_psk = malloc(sizeof(struct hostapd_wpa_psk));
261 if (conf->wpa_psk == NULL) {
262 printf("Unable to alloc space for PSK\n");
265 wpa_hexdump_ascii(MSG_DEBUG, "SSID",
266 (u8 *) conf->ssid, conf->ssid_len);
267 wpa_hexdump_ascii(MSG_DEBUG, "PSK (ASCII passphrase)",
268 (u8 *) conf->wpa_passphrase,
269 strlen(conf->wpa_passphrase));
270 memset(conf->wpa_psk, 0, sizeof(struct hostapd_wpa_psk));
271 pbkdf2_sha1(conf->wpa_passphrase,
272 conf->ssid, conf->ssid_len,
273 4096, conf->wpa_psk->psk, PMK_LEN);
274 wpa_hexdump(MSG_DEBUG, "PSK (from passphrase)",
275 conf->wpa_psk->psk, PMK_LEN);
276 conf->wpa_psk->group = 1;
278 memset(conf->wpa_passphrase, 0, strlen(conf->wpa_passphrase));
279 free(conf->wpa_passphrase);
280 conf->wpa_passphrase = 0;
283 if (conf->wpa_psk_file) {
284 if (hostapd_config_read_wpa_psk(conf->wpa_psk_file, conf))
286 free(conf->wpa_psk_file);
287 conf->wpa_psk_file = NULL;
295 static int hostapd_config_read_eap_user(const char *fname,
296 struct hostapd_config *conf)
299 char buf[512], *pos, *start, *pos2;
300 int line = 0, ret = 0, num_methods;
301 struct hostapd_eap_user *user, *tail = NULL;
306 f = fopen(fname, "r");
308 printf("EAP user file '%s' not found.\n", fname);
312 /* Lines: "user" METHOD,METHOD2 "password" (password optional) */
313 while (fgets(buf, sizeof(buf), f)) {
319 while (*pos != '\0') {
331 if (buf[0] != '"' && buf[0] != '*') {
332 printf("Invalid EAP identity (no \" in start) on "
333 "line %d in '%s'\n", line, fname);
337 user = malloc(sizeof(*user));
339 printf("EAP user allocation failed\n");
342 memset(user, 0, sizeof(*user));
343 user->force_version = -1;
350 while (*pos != '"' && *pos != '\0')
353 printf("Invalid EAP identity (no \" in end) on"
354 " line %d in '%s'\n", line, fname);
358 user->identity = malloc(pos - start);
359 if (user->identity == NULL) {
360 printf("Failed to allocate memory for EAP "
364 memcpy(user->identity, start, pos - start);
365 user->identity_len = pos - start;
368 while (*pos == ' ' || *pos == '\t')
372 printf("No EAP method on line %d in '%s'\n",
378 while (*pos != ' ' && *pos != '\t' && *pos != '\0')
388 char *pos2 = strchr(start, ',');
392 user->methods[num_methods] = eap_get_type(start);
393 if (user->methods[num_methods] == EAP_TYPE_NONE) {
394 printf("Unsupported EAP type '%s' on line %d "
395 "in '%s'\n", start, line, fname);
400 if (num_methods >= EAP_USER_MAX_METHODS)
406 if (num_methods == 0) {
407 printf("No EAP types configured on line %d in '%s'\n",
415 while (*pos == ' ' || *pos == '\t')
420 if (strncmp(pos, "[ver=0]", 7) == 0) {
421 user->force_version = 0;
425 if (strncmp(pos, "[ver=1]", 7) == 0) {
426 user->force_version = 1;
430 if (strncmp(pos, "[2]", 3) == 0) {
438 while (*pos != '"' && *pos != '\0')
441 printf("Invalid EAP password (no \" in end) "
442 "on line %d in '%s'\n", line, fname);
446 user->password = malloc(pos - start);
447 if (user->password == NULL) {
448 printf("Failed to allocate memory for EAP "
452 memcpy(user->password, start, pos - start);
453 user->password_len = pos - start;
458 while (*pos2 != '\0' && *pos2 != ' ' &&
459 *pos2 != '\t' && *pos2 != '#')
461 if ((pos2 - pos) & 1) {
462 printf("Invalid hex password on line %d in "
463 "'%s'\n", line, fname);
466 user->password = malloc((pos2 - pos) / 2);
467 if (user->password == NULL) {
468 printf("Failed to allocate memory for EAP "
472 if (hexstr2bin(pos, user->password,
473 (pos2 - pos) / 2) < 0) {
474 printf("Invalid hex password on line %d in "
475 "'%s'\n", line, fname);
478 user->password_len = (pos2 - pos) / 2;
482 while (*pos == ' ' || *pos == '\t')
484 if (strncmp(pos, "[2]", 3) == 0) {
490 tail = conf->eap_user = user;
499 free(user->identity);
510 #endif /* EAP_SERVER */
514 hostapd_config_read_radius_addr(struct hostapd_radius_server **server,
515 int *num_server, const char *val, int def_port,
516 struct hostapd_radius_server **curr_serv)
518 struct hostapd_radius_server *nserv;
520 static int server_index = 1;
522 nserv = realloc(*server, (*num_server + 1) * sizeof(*nserv));
527 nserv = &nserv[*num_server];
529 (*curr_serv) = nserv;
531 memset(nserv, 0, sizeof(*nserv));
532 nserv->port = def_port;
533 ret = hostapd_parse_ip_addr(val, &nserv->addr);
534 nserv->index = server_index++;
540 static int hostapd_config_parse_key_mgmt(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, "WPA-PSK") == 0)
561 val |= WPA_KEY_MGMT_PSK;
562 else if (strcmp(start, "WPA-EAP") == 0)
563 val |= WPA_KEY_MGMT_IEEE8021X;
565 printf("Line %d: invalid key_mgmt '%s'", line, start);
577 printf("Line %d: no key_mgmt values configured.", line);
585 static int hostapd_config_parse_cipher(int line, const char *value)
588 char *start, *end, *buf;
595 while (start != '\0') {
596 while (*start == ' ' || *start == '\t')
601 while (*end != ' ' && *end != '\t' && *end != '\0')
605 if (strcmp(start, "CCMP") == 0)
606 val |= WPA_CIPHER_CCMP;
607 else if (strcmp(start, "TKIP") == 0)
608 val |= WPA_CIPHER_TKIP;
609 else if (strcmp(start, "WEP104") == 0)
610 val |= WPA_CIPHER_WEP104;
611 else if (strcmp(start, "WEP40") == 0)
612 val |= WPA_CIPHER_WEP40;
613 else if (strcmp(start, "NONE") == 0)
614 val |= WPA_CIPHER_NONE;
616 printf("Line %d: invalid cipher '%s'.", line, start);
628 printf("Line %d: no cipher values configured.", line);
635 static int hostapd_config_check(struct hostapd_config *conf)
637 if (conf->ieee802_1x && !conf->eap_server &&
638 !conf->radius->auth_servers) {
639 printf("Invalid IEEE 802.1X configuration (no EAP "
640 "authenticator configured).\n");
644 if (conf->wpa && (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) &&
645 conf->wpa_psk == NULL && conf->wpa_passphrase == NULL &&
646 conf->wpa_psk_file == NULL) {
647 printf("WPA-PSK enabled, but PSK or passphrase is not "
656 struct hostapd_config * hostapd_config_read(const char *fname)
658 struct hostapd_config *conf;
663 char *accept_mac_file = NULL, *deny_mac_file = NULL;
665 char *eap_user_file = NULL;
666 #endif /* EAP_SERVER */
668 f = fopen(fname, "r");
670 printf("Could not open configuration file '%s' for reading.\n",
675 conf = hostapd_config_defaults();
681 while (fgets(buf, sizeof(buf), f)) {
687 while (*pos != '\0') {
697 pos = strchr(buf, '=');
699 printf("Line %d: invalid line '%s'\n", line, buf);
706 if (strcmp(buf, "interface") == 0) {
707 snprintf(conf->iface, sizeof(conf->iface), "%s", pos);
708 } else if (strcmp(buf, "bridge") == 0) {
709 snprintf(conf->bridge, sizeof(conf->bridge), "%s",
711 } else if (strcmp(buf, "driver") == 0) {
712 conf->driver = driver_lookup(pos);
713 if (conf->driver == NULL) {
714 printf("Line %d: invalid/unknown driver "
715 "'%s'\n", line, pos);
718 } else if (strcmp(buf, "debug") == 0) {
719 conf->debug = atoi(pos);
720 } else if (strcmp(buf, "logger_syslog_level") == 0) {
721 conf->logger_syslog_level = atoi(pos);
722 } else if (strcmp(buf, "logger_stdout_level") == 0) {
723 conf->logger_stdout_level = atoi(pos);
724 } else if (strcmp(buf, "logger_syslog") == 0) {
725 conf->logger_syslog = atoi(pos);
726 } else if (strcmp(buf, "logger_stdout") == 0) {
727 conf->logger_stdout = atoi(pos);
728 } else if (strcmp(buf, "dump_file") == 0) {
729 conf->dump_log_name = strdup(pos);
730 } else if (strcmp(buf, "ssid") == 0) {
731 conf->ssid_len = strlen(pos);
732 if (conf->ssid_len >= HOSTAPD_SSID_LEN ||
733 conf->ssid_len < 1) {
734 printf("Line %d: invalid SSID '%s'\n", line,
738 memcpy(conf->ssid, pos, conf->ssid_len);
739 conf->ssid[conf->ssid_len] = '\0';
741 } else if (strcmp(buf, "macaddr_acl") == 0) {
742 conf->macaddr_acl = atoi(pos);
743 if (conf->macaddr_acl != ACCEPT_UNLESS_DENIED &&
744 conf->macaddr_acl != DENY_UNLESS_ACCEPTED &&
745 conf->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {
746 printf("Line %d: unknown macaddr_acl %d\n",
747 line, conf->macaddr_acl);
749 } else if (strcmp(buf, "accept_mac_file") == 0) {
750 accept_mac_file = strdup(pos);
751 if (!accept_mac_file) {
752 printf("Line %d: allocation failed\n", line);
755 } else if (strcmp(buf, "deny_mac_file") == 0) {
756 deny_mac_file = strdup(pos);
757 if (!deny_mac_file) {
758 printf("Line %d: allocation failed\n", line);
761 } else if (strcmp(buf, "assoc_ap_addr") == 0) {
762 if (hwaddr_aton(pos, conf->assoc_ap_addr)) {
763 printf("Line %d: invalid MAC address '%s'\n",
768 } else if (strcmp(buf, "ieee8021x") == 0) {
769 conf->ieee802_1x = atoi(pos);
770 } else if (strcmp(buf, "eapol_version") == 0) {
771 conf->eapol_version = atoi(pos);
772 if (conf->eapol_version < 1 ||
773 conf->eapol_version > 2) {
774 printf("Line %d: invalid EAPOL "
775 "version (%d): '%s'.\n",
776 line, conf->eapol_version, pos);
779 wpa_printf(MSG_DEBUG, "eapol_version=%d",
780 conf->eapol_version);
782 } else if (strcmp(buf, "eap_authenticator") == 0) {
783 conf->eap_server = atoi(pos);
784 printf("Line %d: obsolete eap_authenticator used; "
785 "this has been renamed to eap_server\n", line);
786 } else if (strcmp(buf, "eap_server") == 0) {
787 conf->eap_server = atoi(pos);
788 } else if (strcmp(buf, "eap_user_file") == 0) {
790 eap_user_file = strdup(pos);
791 if (!eap_user_file) {
792 printf("Line %d: allocation failed\n", line);
795 } else if (strcmp(buf, "ca_cert") == 0) {
797 conf->ca_cert = strdup(pos);
798 } else if (strcmp(buf, "server_cert") == 0) {
799 free(conf->server_cert);
800 conf->server_cert = strdup(pos);
801 } else if (strcmp(buf, "private_key") == 0) {
802 free(conf->private_key);
803 conf->private_key = strdup(pos);
804 } else if (strcmp(buf, "private_key_passwd") == 0) {
805 free(conf->private_key_passwd);
806 conf->private_key_passwd = strdup(pos);
807 } else if (strcmp(buf, "check_crl") == 0) {
808 conf->check_crl = atoi(pos);
810 } else if (strcmp(buf, "eap_sim_db") == 0) {
811 free(conf->eap_sim_db);
812 conf->eap_sim_db = strdup(pos);
814 #endif /* EAP_SERVER */
815 } else if (strcmp(buf, "eap_message") == 0) {
817 conf->eap_req_id_text = strdup(pos);
818 if (conf->eap_req_id_text == NULL) {
819 printf("Line %d: Failed to allocate memory "
820 "for eap_req_id_text\n", line);
824 conf->eap_req_id_text_len =
825 strlen(conf->eap_req_id_text);
826 term = strstr(conf->eap_req_id_text, "\\0");
829 memmove(term, term + 1,
830 conf->eap_req_id_text_len -
831 (term - conf->eap_req_id_text) - 1);
832 conf->eap_req_id_text_len--;
834 } else if (strcmp(buf, "wep_key_len_broadcast") == 0) {
835 conf->default_wep_key_len = atoi(pos);
836 if (conf->default_wep_key_len > 13) {
837 printf("Line %d: invalid WEP key len %lu "
838 "(= %lu bits)\n", line,
840 conf->default_wep_key_len,
842 conf->default_wep_key_len * 8);
845 } else if (strcmp(buf, "wep_key_len_unicast") == 0) {
846 conf->individual_wep_key_len = atoi(pos);
847 if (conf->individual_wep_key_len < 0 ||
848 conf->individual_wep_key_len > 13) {
849 printf("Line %d: invalid WEP key len %d "
850 "(= %d bits)\n", line,
851 conf->individual_wep_key_len,
852 conf->individual_wep_key_len * 8);
855 } else if (strcmp(buf, "wep_rekey_period") == 0) {
856 conf->wep_rekeying_period = atoi(pos);
857 if (conf->wep_rekeying_period < 0) {
858 printf("Line %d: invalid period %d\n",
859 line, conf->wep_rekeying_period);
862 } else if (strcmp(buf, "eap_reauth_period") == 0) {
863 conf->eap_reauth_period = atoi(pos);
864 if (conf->eap_reauth_period < 0) {
865 printf("Line %d: invalid period %d\n",
866 line, conf->eap_reauth_period);
869 } else if (strcmp(buf, "eapol_key_index_workaround") == 0) {
870 conf->eapol_key_index_workaround = atoi(pos);
872 } else if (strcmp(buf, "iapp_interface") == 0) {
873 conf->ieee802_11f = 1;
874 snprintf(conf->iapp_iface, sizeof(conf->iapp_iface),
876 #endif /* CONFIG_IAPP */
877 } else if (strcmp(buf, "own_ip_addr") == 0) {
878 if (hostapd_parse_ip_addr(pos, &conf->own_ip_addr)) {
879 printf("Line %d: invalid IP address '%s'\n",
883 } else if (strcmp(buf, "nas_identifier") == 0) {
884 conf->nas_identifier = strdup(pos);
885 } else if (strcmp(buf, "auth_server_addr") == 0) {
886 if (hostapd_config_read_radius_addr(
887 &conf->radius->auth_servers,
888 &conf->radius->num_auth_servers, pos, 1812,
889 &conf->radius->auth_server)) {
890 printf("Line %d: invalid IP address '%s'\n",
894 } else if (conf->radius->auth_server &&
895 strcmp(buf, "auth_server_port") == 0) {
896 conf->radius->auth_server->port = atoi(pos);
897 } else if (conf->radius->auth_server &&
898 strcmp(buf, "auth_server_shared_secret") == 0) {
899 int len = strlen(pos);
901 /* RFC 2865, Ch. 3 */
902 printf("Line %d: empty shared secret is not "
906 conf->radius->auth_server->shared_secret =
908 conf->radius->auth_server->shared_secret_len = len;
909 } else if (strcmp(buf, "acct_server_addr") == 0) {
910 if (hostapd_config_read_radius_addr(
911 &conf->radius->acct_servers,
912 &conf->radius->num_acct_servers, pos, 1813,
913 &conf->radius->acct_server)) {
914 printf("Line %d: invalid IP address '%s'\n",
918 } else if (conf->radius->acct_server &&
919 strcmp(buf, "acct_server_port") == 0) {
920 conf->radius->acct_server->port = atoi(pos);
921 } else if (conf->radius->acct_server &&
922 strcmp(buf, "acct_server_shared_secret") == 0) {
923 int len = strlen(pos);
925 /* RFC 2865, Ch. 3 */
926 printf("Line %d: empty shared secret is not "
930 conf->radius->acct_server->shared_secret =
932 conf->radius->acct_server->shared_secret_len = len;
933 } else if (strcmp(buf, "radius_retry_primary_interval") == 0) {
934 conf->radius->retry_primary_interval = atoi(pos);
935 } else if (strcmp(buf, "radius_acct_interim_interval") == 0) {
936 conf->radius->acct_interim_interval = atoi(pos);
937 } else if (strcmp(buf, "auth_algs") == 0) {
938 conf->auth_algs = atoi(pos);
939 if (conf->auth_algs == 0) {
940 printf("Line %d: no authentication algorithms "
945 } else if (strcmp(buf, "wpa") == 0) {
946 conf->wpa = atoi(pos);
947 } else if (strcmp(buf, "wpa_group_rekey") == 0) {
948 conf->wpa_group_rekey = atoi(pos);
949 } else if (strcmp(buf, "wpa_strict_rekey") == 0) {
950 conf->wpa_strict_rekey = atoi(pos);
951 } else if (strcmp(buf, "wpa_gmk_rekey") == 0) {
952 conf->wpa_gmk_rekey = atoi(pos);
953 } else if (strcmp(buf, "wpa_passphrase") == 0) {
954 int len = strlen(pos);
955 if (len < 8 || len > 63) {
956 printf("Line %d: invalid WPA passphrase length"
957 " %d (expected 8..63)\n", line, len);
960 free(conf->wpa_passphrase);
961 conf->wpa_passphrase = strdup(pos);
963 } else if (strcmp(buf, "wpa_psk") == 0) {
965 conf->wpa_psk = malloc(sizeof(struct hostapd_wpa_psk));
967 memset(conf->wpa_psk, 0,
968 sizeof(struct hostapd_wpa_psk));
970 if (conf->wpa_psk == NULL)
972 else if (hexstr2bin(pos, conf->wpa_psk->psk, PMK_LEN)
973 || pos[PMK_LEN * 2] != '\0') {
974 printf("Line %d: Invalid PSK '%s'.\n", line,
978 conf->wpa_psk->group = 1;
980 } else if (strcmp(buf, "wpa_psk_file") == 0) {
981 free(conf->wpa_psk_file);
982 conf->wpa_psk_file = strdup(pos);
983 if (!conf->wpa_psk_file) {
984 printf("Line %d: allocation failed\n", line);
987 } else if (strcmp(buf, "wpa_key_mgmt") == 0) {
989 hostapd_config_parse_key_mgmt(line, pos);
990 if (conf->wpa_key_mgmt == -1)
992 } else if (strcmp(buf, "wpa_pairwise") == 0) {
994 hostapd_config_parse_cipher(line, pos);
995 if (conf->wpa_pairwise == -1 ||
996 conf->wpa_pairwise == 0)
998 else if (conf->wpa_pairwise &
999 (WPA_CIPHER_NONE | WPA_CIPHER_WEP40 |
1000 WPA_CIPHER_WEP104)) {
1001 printf("Line %d: unsupported pairwise "
1002 "cipher suite '%s'\n",
1003 conf->wpa_pairwise, pos);
1006 if (conf->wpa_pairwise & WPA_CIPHER_TKIP)
1007 conf->wpa_group = WPA_CIPHER_TKIP;
1009 conf->wpa_group = WPA_CIPHER_CCMP;
1011 #ifdef CONFIG_RSN_PREAUTH
1012 } else if (strcmp(buf, "rsn_preauth") == 0) {
1013 conf->rsn_preauth = atoi(pos);
1014 } else if (strcmp(buf, "rsn_preauth_interfaces") == 0) {
1015 conf->rsn_preauth_interfaces = strdup(pos);
1016 #endif /* CONFIG_RSN_PREAUTH */
1017 } else if (strcmp(buf, "ctrl_interface") == 0) {
1018 free(conf->ctrl_interface);
1019 conf->ctrl_interface = strdup(pos);
1020 } else if (strcmp(buf, "ctrl_interface_group") == 0) {
1023 const char *group = pos;
1025 grp = getgrnam(group);
1027 conf->ctrl_interface_gid = grp->gr_gid;
1028 conf->ctrl_interface_gid_set = 1;
1029 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
1030 " (from group name '%s')",
1031 conf->ctrl_interface_gid, group);
1035 /* Group name not found - try to parse this as gid */
1036 conf->ctrl_interface_gid = strtol(group, &endp, 10);
1037 if (*group == '\0' || *endp != '\0') {
1038 wpa_printf(MSG_DEBUG, "Line %d: Invalid group "
1039 "'%s'", line, group);
1043 conf->ctrl_interface_gid_set = 1;
1044 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
1045 conf->ctrl_interface_gid);
1046 #ifdef RADIUS_SERVER
1047 } else if (strcmp(buf, "radius_server_clients") == 0) {
1048 free(conf->radius_server_clients);
1049 conf->radius_server_clients = strdup(pos);
1050 } else if (strcmp(buf, "radius_server_auth_port") == 0) {
1051 conf->radius_server_auth_port = atoi(pos);
1052 } else if (strcmp(buf, "radius_server_ipv6") == 0) {
1053 conf->radius_server_ipv6 = atoi(pos);
1054 #endif /* RADIUS_SERVER */
1055 } else if (strcmp(buf, "test_socket") == 0) {
1056 free(conf->test_socket);
1057 conf->test_socket = strdup(pos);
1058 } else if (strcmp(buf, "use_pae_group_addr") == 0) {
1059 conf->use_pae_group_addr = atoi(pos);
1061 printf("Line %d: unknown configuration item '%s'\n",
1069 if (hostapd_config_read_maclist(accept_mac_file, &conf->accept_mac,
1070 &conf->num_accept_mac))
1072 free(accept_mac_file);
1073 if (hostapd_config_read_maclist(deny_mac_file, &conf->deny_mac,
1074 &conf->num_deny_mac))
1076 free(deny_mac_file);
1079 if (hostapd_config_read_eap_user(eap_user_file, conf))
1081 free(eap_user_file);
1082 #endif /* EAP_SERVER */
1084 conf->radius->auth_server = conf->radius->auth_servers;
1085 conf->radius->acct_server = conf->radius->acct_servers;
1087 if (hostapd_config_check(conf))
1091 printf("%d errors found in configuration file '%s'\n",
1093 hostapd_config_free(conf);
1101 static void hostapd_config_free_radius(struct hostapd_radius_server *servers,
1106 for (i = 0; i < num_servers; i++) {
1107 free(servers[i].shared_secret);
1113 static void hostapd_config_free_eap_user(struct hostapd_eap_user *user)
1115 free(user->identity);
1116 free(user->password);
1121 void hostapd_config_free(struct hostapd_config *conf)
1123 struct hostapd_wpa_psk *psk, *prev;
1124 struct hostapd_eap_user *user, *prev_user;
1129 psk = conf->wpa_psk;
1136 free(conf->wpa_passphrase);
1137 free(conf->wpa_psk_file);
1139 user = conf->eap_user;
1143 hostapd_config_free_eap_user(prev_user);
1146 free(conf->dump_log_name);
1147 free(conf->eap_req_id_text);
1148 free(conf->accept_mac);
1149 free(conf->deny_mac);
1150 free(conf->nas_identifier);
1151 hostapd_config_free_radius(conf->radius->auth_servers,
1152 conf->radius->num_auth_servers);
1153 hostapd_config_free_radius(conf->radius->acct_servers,
1154 conf->radius->num_acct_servers);
1155 free(conf->rsn_preauth_interfaces);
1156 free(conf->ctrl_interface);
1157 free(conf->ca_cert);
1158 free(conf->server_cert);
1159 free(conf->private_key);
1160 free(conf->private_key_passwd);
1161 free(conf->eap_sim_db);
1162 free(conf->radius_server_clients);
1163 free(conf->test_socket);
1168 /* Perform a binary search for given MAC address from a pre-sorted list.
1169 * Returns 1 if address is in the list or 0 if not. */
1170 int hostapd_maclist_found(macaddr *list, int num_entries, u8 *addr)
1172 int start, end, middle, res;
1175 end = num_entries - 1;
1177 while (start <= end) {
1178 middle = (start + end) / 2;
1179 res = memcmp(list[middle], addr, ETH_ALEN);
1192 const u8 * hostapd_get_psk(const struct hostapd_config *conf, const u8 *addr,
1195 struct hostapd_wpa_psk *psk;
1196 int next_ok = prev_psk == NULL;
1198 for (psk = conf->wpa_psk; psk != NULL; psk = psk->next) {
1200 (psk->group || memcmp(psk->addr, addr, ETH_ALEN) == 0))
1203 if (psk->psk == prev_psk)
1211 const struct hostapd_eap_user *
1212 hostapd_get_eap_user(const struct hostapd_config *conf, const u8 *identity,
1213 size_t identity_len, int phase2)
1215 struct hostapd_eap_user *user = conf->eap_user;
1218 if (!phase2 && user->identity == NULL) {
1219 /* Wildcard match */
1222 if (user->phase2 == !!phase2 &&
1223 user->identity_len == identity_len &&
1224 memcmp(user->identity, identity, identity_len) == 0)