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>
31 #include "radius_client.h"
34 static struct hostapd_config *hostapd_config_defaults(void)
36 struct hostapd_config *conf;
38 conf = malloc(sizeof(*conf) + sizeof(struct hostapd_radius_servers));
40 printf("Failed to allocate memory for configuration data.\n");
43 memset(conf, 0, sizeof(*conf) + sizeof(struct hostapd_radius_servers));
44 conf->radius = (struct hostapd_radius_servers *) (conf + 1);
46 /* set default driver based on configuration */
47 conf->driver = driver_lookup("default");
48 if (conf->driver == NULL) {
49 printf("No default driver registered!\n");
54 conf->wep_rekeying_period = 300;
55 conf->eap_reauth_period = 3600;
57 conf->logger_syslog_level = HOSTAPD_LEVEL_INFO;
58 conf->logger_stdout_level = HOSTAPD_LEVEL_INFO;
59 conf->logger_syslog = (unsigned int) -1;
60 conf->logger_stdout = (unsigned int) -1;
62 conf->auth_algs = HOSTAPD_AUTH_OPEN | HOSTAPD_AUTH_SHARED_KEY;
64 conf->wpa_group_rekey = 600;
65 conf->wpa_gmk_rekey = 86400;
66 conf->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
67 conf->wpa_pairwise = WPA_CIPHER_TKIP;
68 conf->wpa_group = WPA_CIPHER_TKIP;
70 conf->radius_server_auth_port = 1812;
76 static int hostapd_parse_ip_addr(const char *txt, struct hostapd_ip_addr *addr)
78 if (inet_aton(txt, &addr->u.v4)) {
84 if (inet_pton(AF_INET6, txt, &addr->u.v6) > 0) {
88 #endif /* CONFIG_IPV6 */
94 static int mac_comp(const void *a, const void *b)
96 return memcmp(a, b, sizeof(macaddr));
100 static int hostapd_config_read_maclist(const char *fname, macaddr **acl,
112 f = fopen(fname, "r");
114 printf("MAC list file '%s' not found.\n", fname);
118 while (fgets(buf, sizeof(buf), f)) {
124 while (*pos != '\0') {
134 if (hwaddr_aton(buf, addr)) {
135 printf("Invalid MAC address '%s' at line %d in '%s'\n",
141 newacl = (macaddr *) realloc(*acl, (*num + 1) * ETH_ALEN);
142 if (newacl == NULL) {
143 printf("MAC list reallocation failed\n");
149 memcpy((*acl)[*num], addr, ETH_ALEN);
155 qsort(*acl, *num, sizeof(macaddr), mac_comp);
161 static int hostapd_config_read_wpa_psk(const char *fname,
162 struct hostapd_config *conf)
166 int line = 0, ret = 0, len, ok;
168 struct hostapd_wpa_psk *psk;
173 f = fopen(fname, "r");
175 printf("WPA PSK file '%s' not found.\n", fname);
179 while (fgets(buf, sizeof(buf), f)) {
185 while (*pos != '\0') {
195 if (hwaddr_aton(buf, addr)) {
196 printf("Invalid MAC address '%s' on line %d in '%s'\n",
202 psk = malloc(sizeof(*psk));
204 printf("WPA PSK allocation failed\n");
208 memset(psk, 0, sizeof(*psk));
209 if (memcmp(addr, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
212 memcpy(psk->addr, addr, ETH_ALEN);
216 printf("No PSK on line %d in '%s'\n", line, fname);
225 if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0)
227 else if (len >= 8 && len < 64) {
228 pbkdf2_sha1(pos, conf->ssid, conf->ssid_len,
229 4096, psk->psk, PMK_LEN);
233 printf("Invalid PSK '%s' on line %d in '%s'\n",
240 psk->next = conf->wpa_psk;
250 int hostapd_setup_wpa_psk(struct hostapd_config *conf)
252 if (conf->wpa_passphrase != NULL) {
253 if (conf->wpa_psk != NULL) {
254 printf("Warning: both WPA PSK and passphrase set. "
255 "Using passphrase.\n");
258 conf->wpa_psk = malloc(sizeof(struct hostapd_wpa_psk));
259 if (conf->wpa_psk == NULL) {
260 printf("Unable to alloc space for PSK\n");
263 wpa_hexdump_ascii(MSG_DEBUG, "SSID",
264 (u8 *) conf->ssid, conf->ssid_len);
265 wpa_hexdump_ascii(MSG_DEBUG, "PSK (ASCII passphrase)",
266 (u8 *) conf->wpa_passphrase,
267 strlen(conf->wpa_passphrase));
268 memset(conf->wpa_psk, 0, sizeof(struct hostapd_wpa_psk));
269 pbkdf2_sha1(conf->wpa_passphrase,
270 conf->ssid, conf->ssid_len,
271 4096, conf->wpa_psk->psk, PMK_LEN);
272 wpa_hexdump(MSG_DEBUG, "PSK (from passphrase)",
273 conf->wpa_psk->psk, PMK_LEN);
274 conf->wpa_psk->group = 1;
276 memset(conf->wpa_passphrase, 0, strlen(conf->wpa_passphrase));
277 free(conf->wpa_passphrase);
278 conf->wpa_passphrase = 0;
281 if (conf->wpa_psk_file) {
282 if (hostapd_config_read_wpa_psk(conf->wpa_psk_file, conf))
284 free(conf->wpa_psk_file);
285 conf->wpa_psk_file = NULL;
293 static int hostapd_config_read_eap_user(const char *fname,
294 struct hostapd_config *conf)
297 char buf[512], *pos, *start, *pos2;
298 int line = 0, ret = 0, num_methods;
299 struct hostapd_eap_user *user, *tail = NULL;
304 f = fopen(fname, "r");
306 printf("EAP user file '%s' not found.\n", fname);
310 /* Lines: "user" METHOD,METHOD2 "password" (password optional) */
311 while (fgets(buf, sizeof(buf), f)) {
317 while (*pos != '\0') {
329 if (buf[0] != '"' && buf[0] != '*') {
330 printf("Invalid EAP identity (no \" in start) on "
331 "line %d in '%s'\n", line, fname);
335 user = malloc(sizeof(*user));
337 printf("EAP user allocation failed\n");
340 memset(user, 0, sizeof(*user));
341 user->force_version = -1;
348 while (*pos != '"' && *pos != '\0')
351 printf("Invalid EAP identity (no \" in end) on"
352 " line %d in '%s'\n", line, fname);
356 user->identity = malloc(pos - start);
357 if (user->identity == NULL) {
358 printf("Failed to allocate memory for EAP "
362 memcpy(user->identity, start, pos - start);
363 user->identity_len = pos - start;
366 while (*pos == ' ' || *pos == '\t')
370 printf("No EAP method on line %d in '%s'\n",
376 while (*pos != ' ' && *pos != '\t' && *pos != '\0')
386 char *pos2 = strchr(start, ',');
390 user->methods[num_methods] = eap_get_type(start);
391 if (user->methods[num_methods] == EAP_TYPE_NONE) {
392 printf("Unsupported EAP type '%s' on line %d "
393 "in '%s'\n", start, line, fname);
398 if (num_methods >= EAP_USER_MAX_METHODS)
404 if (num_methods == 0) {
405 printf("No EAP types configured on line %d in '%s'\n",
413 while (*pos == ' ' || *pos == '\t')
418 if (strncmp(pos, "[ver=0]", 7) == 0) {
419 user->force_version = 0;
423 if (strncmp(pos, "[ver=1]", 7) == 0) {
424 user->force_version = 1;
428 if (strncmp(pos, "[2]", 3) == 0) {
436 while (*pos != '"' && *pos != '\0')
439 printf("Invalid EAP password (no \" in end) "
440 "on line %d in '%s'\n", line, fname);
444 user->password = malloc(pos - start);
445 if (user->password == NULL) {
446 printf("Failed to allocate memory for EAP "
450 memcpy(user->password, start, pos - start);
451 user->password_len = pos - start;
456 while (*pos2 != '\0' && *pos2 != ' ' &&
457 *pos2 != '\t' && *pos2 != '#')
459 if ((pos2 - pos) & 1) {
460 printf("Invalid hex password on line %d in "
461 "'%s'\n", line, fname);
464 user->password = malloc((pos2 - pos) / 2);
465 if (user->password == NULL) {
466 printf("Failed to allocate memory for EAP "
470 if (hexstr2bin(pos, user->password,
471 (pos2 - pos) / 2) < 0) {
472 printf("Invalid hex password on line %d in "
473 "'%s'\n", line, fname);
476 user->password_len = (pos2 - pos) / 2;
480 while (*pos == ' ' || *pos == '\t')
482 if (strncmp(pos, "[2]", 3) == 0) {
488 tail = conf->eap_user = user;
497 free(user->identity);
508 #endif /* EAP_SERVER */
512 hostapd_config_read_radius_addr(struct hostapd_radius_server **server,
513 int *num_server, const char *val, int def_port,
514 struct hostapd_radius_server **curr_serv)
516 struct hostapd_radius_server *nserv;
518 static int server_index = 1;
520 nserv = realloc(*server, (*num_server + 1) * sizeof(*nserv));
525 nserv = &nserv[*num_server];
527 (*curr_serv) = nserv;
529 memset(nserv, 0, sizeof(*nserv));
530 nserv->port = def_port;
531 ret = hostapd_parse_ip_addr(val, &nserv->addr);
532 nserv->index = server_index++;
538 static int hostapd_config_parse_key_mgmt(int line, const char *value)
541 char *start, *end, *buf;
548 while (start != '\0') {
549 while (*start == ' ' || *start == '\t')
554 while (*end != ' ' && *end != '\t' && *end != '\0')
558 if (strcmp(start, "WPA-PSK") == 0)
559 val |= WPA_KEY_MGMT_PSK;
560 else if (strcmp(start, "WPA-EAP") == 0)
561 val |= WPA_KEY_MGMT_IEEE8021X;
563 printf("Line %d: invalid key_mgmt '%s'", line, start);
575 printf("Line %d: no key_mgmt values configured.", line);
583 static int hostapd_config_parse_cipher(int line, const char *value)
586 char *start, *end, *buf;
593 while (start != '\0') {
594 while (*start == ' ' || *start == '\t')
599 while (*end != ' ' && *end != '\t' && *end != '\0')
603 if (strcmp(start, "CCMP") == 0)
604 val |= WPA_CIPHER_CCMP;
605 else if (strcmp(start, "TKIP") == 0)
606 val |= WPA_CIPHER_TKIP;
607 else if (strcmp(start, "WEP104") == 0)
608 val |= WPA_CIPHER_WEP104;
609 else if (strcmp(start, "WEP40") == 0)
610 val |= WPA_CIPHER_WEP40;
611 else if (strcmp(start, "NONE") == 0)
612 val |= WPA_CIPHER_NONE;
614 printf("Line %d: invalid cipher '%s'.", line, start);
626 printf("Line %d: no cipher values configured.", line);
633 static int hostapd_config_check(struct hostapd_config *conf)
635 if (conf->ieee802_1x && !conf->eap_server &&
636 !conf->radius->auth_servers) {
637 printf("Invalid IEEE 802.1X configuration (no EAP "
638 "authenticator configured).\n");
642 if (conf->wpa && (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) &&
643 conf->wpa_psk == NULL && conf->wpa_passphrase == NULL &&
644 conf->wpa_psk_file == NULL) {
645 printf("WPA-PSK enabled, but PSK or passphrase is not "
654 struct hostapd_config * hostapd_config_read(const char *fname)
656 struct hostapd_config *conf;
661 char *accept_mac_file = NULL, *deny_mac_file = NULL;
663 char *eap_user_file = NULL;
664 #endif /* EAP_SERVER */
666 f = fopen(fname, "r");
668 printf("Could not open configuration file '%s' for reading.\n",
673 conf = hostapd_config_defaults();
679 while (fgets(buf, sizeof(buf), f)) {
685 while (*pos != '\0') {
695 pos = strchr(buf, '=');
697 printf("Line %d: invalid line '%s'\n", line, buf);
704 if (strcmp(buf, "interface") == 0) {
705 snprintf(conf->iface, sizeof(conf->iface), "%s", pos);
706 } else if (strcmp(buf, "bridge") == 0) {
707 snprintf(conf->bridge, sizeof(conf->bridge), "%s",
709 } else if (strcmp(buf, "driver") == 0) {
710 conf->driver = driver_lookup(pos);
711 if (conf->driver == NULL) {
712 printf("Line %d: invalid/unknown driver "
713 "'%s'\n", line, pos);
716 } else if (strcmp(buf, "debug") == 0) {
717 conf->debug = atoi(pos);
718 } else if (strcmp(buf, "logger_syslog_level") == 0) {
719 conf->logger_syslog_level = atoi(pos);
720 } else if (strcmp(buf, "logger_stdout_level") == 0) {
721 conf->logger_stdout_level = atoi(pos);
722 } else if (strcmp(buf, "logger_syslog") == 0) {
723 conf->logger_syslog = atoi(pos);
724 } else if (strcmp(buf, "logger_stdout") == 0) {
725 conf->logger_stdout = atoi(pos);
726 } else if (strcmp(buf, "dump_file") == 0) {
727 conf->dump_log_name = strdup(pos);
728 } else if (strcmp(buf, "ssid") == 0) {
729 conf->ssid_len = strlen(pos);
730 if (conf->ssid_len >= HOSTAPD_SSID_LEN ||
731 conf->ssid_len < 1) {
732 printf("Line %d: invalid SSID '%s'\n", line,
736 memcpy(conf->ssid, pos, conf->ssid_len);
737 conf->ssid[conf->ssid_len] = '\0';
739 } else if (strcmp(buf, "macaddr_acl") == 0) {
740 conf->macaddr_acl = atoi(pos);
741 if (conf->macaddr_acl != ACCEPT_UNLESS_DENIED &&
742 conf->macaddr_acl != DENY_UNLESS_ACCEPTED &&
743 conf->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {
744 printf("Line %d: unknown macaddr_acl %d\n",
745 line, conf->macaddr_acl);
747 } else if (strcmp(buf, "accept_mac_file") == 0) {
748 accept_mac_file = strdup(pos);
749 if (!accept_mac_file) {
750 printf("Line %d: allocation failed\n", line);
753 } else if (strcmp(buf, "deny_mac_file") == 0) {
754 deny_mac_file = strdup(pos);
755 if (!deny_mac_file) {
756 printf("Line %d: allocation failed\n", line);
759 } else if (strcmp(buf, "assoc_ap_addr") == 0) {
760 if (hwaddr_aton(pos, conf->assoc_ap_addr)) {
761 printf("Line %d: invalid MAC address '%s'\n",
766 } else if (strcmp(buf, "ieee8021x") == 0) {
767 conf->ieee802_1x = atoi(pos);
769 } else if (strcmp(buf, "eap_authenticator") == 0) {
770 conf->eap_server = atoi(pos);
771 printf("Line %d: obsolete eap_authenticator used; "
772 "this has been renamed to eap_server\n", line);
773 } else if (strcmp(buf, "eap_server") == 0) {
774 conf->eap_server = atoi(pos);
775 } else if (strcmp(buf, "eap_user_file") == 0) {
777 eap_user_file = strdup(pos);
778 if (!eap_user_file) {
779 printf("Line %d: allocation failed\n", line);
782 } else if (strcmp(buf, "ca_cert") == 0) {
784 conf->ca_cert = strdup(pos);
785 } else if (strcmp(buf, "server_cert") == 0) {
786 free(conf->server_cert);
787 conf->server_cert = strdup(pos);
788 } else if (strcmp(buf, "private_key") == 0) {
789 free(conf->private_key);
790 conf->private_key = strdup(pos);
791 } else if (strcmp(buf, "private_key_passwd") == 0) {
792 free(conf->private_key_passwd);
793 conf->private_key_passwd = strdup(pos);
794 } else if (strcmp(buf, "check_crl") == 0) {
795 conf->check_crl = atoi(pos);
797 } else if (strcmp(buf, "eap_sim_db") == 0) {
798 free(conf->eap_sim_db);
799 conf->eap_sim_db = strdup(pos);
801 #endif /* EAP_SERVER */
802 } else if (strcmp(buf, "eap_message") == 0) {
804 conf->eap_req_id_text = strdup(pos);
805 if (conf->eap_req_id_text == NULL) {
806 printf("Line %d: Failed to allocate memory "
807 "for eap_req_id_text\n", line);
811 conf->eap_req_id_text_len =
812 strlen(conf->eap_req_id_text);
813 term = strstr(conf->eap_req_id_text, "\\0");
816 memmove(term, term + 1,
817 conf->eap_req_id_text_len -
818 (term - conf->eap_req_id_text) - 1);
819 conf->eap_req_id_text_len--;
821 } else if (strcmp(buf, "wep_key_len_broadcast") == 0) {
822 conf->default_wep_key_len = atoi(pos);
823 if (conf->default_wep_key_len > 13) {
824 printf("Line %d: invalid WEP key len %lu "
825 "(= %lu bits)\n", line,
827 conf->default_wep_key_len,
829 conf->default_wep_key_len * 8);
832 } else if (strcmp(buf, "wep_key_len_unicast") == 0) {
833 conf->individual_wep_key_len = atoi(pos);
834 if (conf->individual_wep_key_len < 0 ||
835 conf->individual_wep_key_len > 13) {
836 printf("Line %d: invalid WEP key len %d "
837 "(= %d bits)\n", line,
838 conf->individual_wep_key_len,
839 conf->individual_wep_key_len * 8);
842 } else if (strcmp(buf, "wep_rekey_period") == 0) {
843 conf->wep_rekeying_period = atoi(pos);
844 if (conf->wep_rekeying_period < 0) {
845 printf("Line %d: invalid period %d\n",
846 line, conf->wep_rekeying_period);
849 } else if (strcmp(buf, "eap_reauth_period") == 0) {
850 conf->eap_reauth_period = atoi(pos);
851 if (conf->eap_reauth_period < 0) {
852 printf("Line %d: invalid period %d\n",
853 line, conf->eap_reauth_period);
856 } else if (strcmp(buf, "eapol_key_index_workaround") == 0) {
857 conf->eapol_key_index_workaround = atoi(pos);
859 } else if (strcmp(buf, "iapp_interface") == 0) {
860 conf->ieee802_11f = 1;
861 snprintf(conf->iapp_iface, sizeof(conf->iapp_iface),
863 #endif /* CONFIG_IAPP */
864 } else if (strcmp(buf, "own_ip_addr") == 0) {
865 if (hostapd_parse_ip_addr(pos, &conf->own_ip_addr)) {
866 printf("Line %d: invalid IP address '%s'\n",
870 } else if (strcmp(buf, "nas_identifier") == 0) {
871 conf->nas_identifier = strdup(pos);
872 } else if (strcmp(buf, "auth_server_addr") == 0) {
873 if (hostapd_config_read_radius_addr(
874 &conf->radius->auth_servers,
875 &conf->radius->num_auth_servers, pos, 1812,
876 &conf->radius->auth_server)) {
877 printf("Line %d: invalid IP address '%s'\n",
881 } else if (conf->radius->auth_server &&
882 strcmp(buf, "auth_server_port") == 0) {
883 conf->radius->auth_server->port = atoi(pos);
884 } else if (conf->radius->auth_server &&
885 strcmp(buf, "auth_server_shared_secret") == 0) {
886 int len = strlen(pos);
888 /* RFC 2865, Ch. 3 */
889 printf("Line %d: empty shared secret is not "
893 conf->radius->auth_server->shared_secret =
895 conf->radius->auth_server->shared_secret_len = len;
896 } else if (strcmp(buf, "acct_server_addr") == 0) {
897 if (hostapd_config_read_radius_addr(
898 &conf->radius->acct_servers,
899 &conf->radius->num_acct_servers, pos, 1813,
900 &conf->radius->acct_server)) {
901 printf("Line %d: invalid IP address '%s'\n",
905 } else if (conf->radius->acct_server &&
906 strcmp(buf, "acct_server_port") == 0) {
907 conf->radius->acct_server->port = atoi(pos);
908 } else if (conf->radius->acct_server &&
909 strcmp(buf, "acct_server_shared_secret") == 0) {
910 int len = strlen(pos);
912 /* RFC 2865, Ch. 3 */
913 printf("Line %d: empty shared secret is not "
917 conf->radius->acct_server->shared_secret =
919 conf->radius->acct_server->shared_secret_len = len;
920 } else if (strcmp(buf, "radius_retry_primary_interval") == 0) {
921 conf->radius->retry_primary_interval = atoi(pos);
922 } else if (strcmp(buf, "radius_acct_interim_interval") == 0) {
923 conf->radius->acct_interim_interval = atoi(pos);
924 } else if (strcmp(buf, "auth_algs") == 0) {
925 conf->auth_algs = atoi(pos);
926 if (conf->auth_algs == 0) {
927 printf("Line %d: no authentication algorithms "
932 } else if (strcmp(buf, "wpa") == 0) {
933 conf->wpa = atoi(pos);
934 } else if (strcmp(buf, "wpa_group_rekey") == 0) {
935 conf->wpa_group_rekey = atoi(pos);
936 } else if (strcmp(buf, "wpa_strict_rekey") == 0) {
937 conf->wpa_strict_rekey = atoi(pos);
938 } else if (strcmp(buf, "wpa_gmk_rekey") == 0) {
939 conf->wpa_gmk_rekey = atoi(pos);
940 } else if (strcmp(buf, "wpa_passphrase") == 0) {
941 int len = strlen(pos);
942 if (len < 8 || len > 63) {
943 printf("Line %d: invalid WPA passphrase length"
944 " %d (expected 8..63)\n", line, len);
947 free(conf->wpa_passphrase);
948 conf->wpa_passphrase = strdup(pos);
950 } else if (strcmp(buf, "wpa_psk") == 0) {
952 conf->wpa_psk = malloc(sizeof(struct hostapd_wpa_psk));
954 memset(conf->wpa_psk, 0,
955 sizeof(struct hostapd_wpa_psk));
957 if (conf->wpa_psk == NULL)
959 else if (hexstr2bin(pos, conf->wpa_psk->psk, PMK_LEN)
960 || pos[PMK_LEN * 2] != '\0') {
961 printf("Line %d: Invalid PSK '%s'.\n", line,
965 conf->wpa_psk->group = 1;
967 } else if (strcmp(buf, "wpa_psk_file") == 0) {
968 free(conf->wpa_psk_file);
969 conf->wpa_psk_file = strdup(pos);
970 if (!conf->wpa_psk_file) {
971 printf("Line %d: allocation failed\n", line);
974 } else if (strcmp(buf, "wpa_key_mgmt") == 0) {
976 hostapd_config_parse_key_mgmt(line, pos);
977 if (conf->wpa_key_mgmt == -1)
979 } else if (strcmp(buf, "wpa_pairwise") == 0) {
981 hostapd_config_parse_cipher(line, pos);
982 if (conf->wpa_pairwise == -1 ||
983 conf->wpa_pairwise == 0)
985 else if (conf->wpa_pairwise &
986 (WPA_CIPHER_NONE | WPA_CIPHER_WEP40 |
987 WPA_CIPHER_WEP104)) {
988 printf("Line %d: unsupported pairwise "
989 "cipher suite '%s'\n",
990 conf->wpa_pairwise, pos);
993 if (conf->wpa_pairwise & WPA_CIPHER_TKIP)
994 conf->wpa_group = WPA_CIPHER_TKIP;
996 conf->wpa_group = WPA_CIPHER_CCMP;
998 #ifdef CONFIG_RSN_PREAUTH
999 } else if (strcmp(buf, "rsn_preauth") == 0) {
1000 conf->rsn_preauth = atoi(pos);
1001 } else if (strcmp(buf, "rsn_preauth_interfaces") == 0) {
1002 conf->rsn_preauth_interfaces = strdup(pos);
1003 #endif /* CONFIG_RSN_PREAUTH */
1004 } else if (strcmp(buf, "ctrl_interface") == 0) {
1005 free(conf->ctrl_interface);
1006 conf->ctrl_interface = strdup(pos);
1007 } else if (strcmp(buf, "ctrl_interface_group") == 0) {
1010 const char *group = pos;
1012 grp = getgrnam(group);
1014 conf->ctrl_interface_gid = grp->gr_gid;
1015 conf->ctrl_interface_gid_set = 1;
1016 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
1017 " (from group name '%s')",
1018 conf->ctrl_interface_gid, group);
1022 /* Group name not found - try to parse this as gid */
1023 conf->ctrl_interface_gid = strtol(group, &endp, 10);
1024 if (*group == '\0' || *endp != '\0') {
1025 wpa_printf(MSG_DEBUG, "Line %d: Invalid group "
1026 "'%s'", line, group);
1030 conf->ctrl_interface_gid_set = 1;
1031 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
1032 conf->ctrl_interface_gid);
1033 #ifdef RADIUS_SERVER
1034 } else if (strcmp(buf, "radius_server_clients") == 0) {
1035 free(conf->radius_server_clients);
1036 conf->radius_server_clients = strdup(pos);
1037 } else if (strcmp(buf, "radius_server_auth_port") == 0) {
1038 conf->radius_server_auth_port = atoi(pos);
1039 } else if (strcmp(buf, "radius_server_ipv6") == 0) {
1040 conf->radius_server_ipv6 = atoi(pos);
1041 #endif /* RADIUS_SERVER */
1042 } else if (strcmp(buf, "test_socket") == 0) {
1043 free(conf->test_socket);
1044 conf->test_socket = strdup(pos);
1045 } else if (strcmp(buf, "use_pae_group_addr") == 0) {
1046 conf->use_pae_group_addr = atoi(pos);
1048 printf("Line %d: unknown configuration item '%s'\n",
1056 if (hostapd_config_read_maclist(accept_mac_file, &conf->accept_mac,
1057 &conf->num_accept_mac))
1059 free(accept_mac_file);
1060 if (hostapd_config_read_maclist(deny_mac_file, &conf->deny_mac,
1061 &conf->num_deny_mac))
1063 free(deny_mac_file);
1066 if (hostapd_config_read_eap_user(eap_user_file, conf))
1068 free(eap_user_file);
1069 #endif /* EAP_SERVER */
1071 conf->radius->auth_server = conf->radius->auth_servers;
1072 conf->radius->acct_server = conf->radius->acct_servers;
1074 if (hostapd_config_check(conf))
1078 printf("%d errors found in configuration file '%s'\n",
1080 hostapd_config_free(conf);
1088 static void hostapd_config_free_radius(struct hostapd_radius_server *servers,
1093 for (i = 0; i < num_servers; i++) {
1094 free(servers[i].shared_secret);
1100 static void hostapd_config_free_eap_user(struct hostapd_eap_user *user)
1102 free(user->identity);
1103 free(user->password);
1108 void hostapd_config_free(struct hostapd_config *conf)
1110 struct hostapd_wpa_psk *psk, *prev;
1111 struct hostapd_eap_user *user, *prev_user;
1116 psk = conf->wpa_psk;
1123 free(conf->wpa_passphrase);
1124 free(conf->wpa_psk_file);
1126 user = conf->eap_user;
1130 hostapd_config_free_eap_user(prev_user);
1133 free(conf->dump_log_name);
1134 free(conf->eap_req_id_text);
1135 free(conf->accept_mac);
1136 free(conf->deny_mac);
1137 free(conf->nas_identifier);
1138 hostapd_config_free_radius(conf->radius->auth_servers,
1139 conf->radius->num_auth_servers);
1140 hostapd_config_free_radius(conf->radius->acct_servers,
1141 conf->radius->num_acct_servers);
1142 free(conf->rsn_preauth_interfaces);
1143 free(conf->ctrl_interface);
1144 free(conf->ca_cert);
1145 free(conf->server_cert);
1146 free(conf->private_key);
1147 free(conf->private_key_passwd);
1148 free(conf->eap_sim_db);
1149 free(conf->radius_server_clients);
1150 free(conf->test_socket);
1155 /* Perform a binary search for given MAC address from a pre-sorted list.
1156 * Returns 1 if address is in the list or 0 if not. */
1157 int hostapd_maclist_found(macaddr *list, int num_entries, u8 *addr)
1159 int start, end, middle, res;
1162 end = num_entries - 1;
1164 while (start <= end) {
1165 middle = (start + end) / 2;
1166 res = memcmp(list[middle], addr, ETH_ALEN);
1179 const u8 * hostapd_get_psk(const struct hostapd_config *conf, const u8 *addr,
1182 struct hostapd_wpa_psk *psk;
1183 int next_ok = prev_psk == NULL;
1185 for (psk = conf->wpa_psk; psk != NULL; psk = psk->next) {
1187 (psk->group || memcmp(psk->addr, addr, ETH_ALEN) == 0))
1190 if (psk->psk == prev_psk)
1198 const struct hostapd_eap_user *
1199 hostapd_get_eap_user(const struct hostapd_config *conf, const u8 *identity,
1200 size_t identity_len, int phase2)
1202 struct hostapd_eap_user *user = conf->eap_user;
1205 if (!phase2 && user->identity == NULL) {
1206 /* Wildcard match */
1209 if (user->phase2 == !!phase2 &&
1210 user->identity_len == identity_len &&
1211 memcmp(user->identity, identity, identity_len) == 0)