]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/wpa/src/radius/radius_server.c
MFV r341618:
[FreeBSD/FreeBSD.git] / contrib / wpa / src / radius / radius_server.c
1 /*
2  * RADIUS authentication server
3  * Copyright (c) 2005-2009, 2011-2014, 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
9 #include "includes.h"
10 #include <net/if.h>
11 #ifdef CONFIG_SQLITE
12 #include <sqlite3.h>
13 #endif /* CONFIG_SQLITE */
14
15 #include "common.h"
16 #include "radius.h"
17 #include "eloop.h"
18 #include "eap_server/eap.h"
19 #include "ap/ap_config.h"
20 #include "crypto/tls.h"
21 #include "radius_server.h"
22
23 /**
24  * RADIUS_SESSION_TIMEOUT - Session timeout in seconds
25  */
26 #define RADIUS_SESSION_TIMEOUT 60
27
28 /**
29  * RADIUS_SESSION_MAINTAIN - Completed session expiration timeout in seconds
30  */
31 #define RADIUS_SESSION_MAINTAIN 5
32
33 /**
34  * RADIUS_MAX_SESSION - Maximum number of active sessions
35  */
36 #define RADIUS_MAX_SESSION 1000
37
38 /**
39  * RADIUS_MAX_MSG_LEN - Maximum message length for incoming RADIUS messages
40  */
41 #define RADIUS_MAX_MSG_LEN 3000
42
43 static const struct eapol_callbacks radius_server_eapol_cb;
44
45 struct radius_client;
46 struct radius_server_data;
47
48 /**
49  * struct radius_server_counters - RADIUS server statistics counters
50  */
51 struct radius_server_counters {
52         u32 access_requests;
53         u32 invalid_requests;
54         u32 dup_access_requests;
55         u32 access_accepts;
56         u32 access_rejects;
57         u32 access_challenges;
58         u32 malformed_access_requests;
59         u32 bad_authenticators;
60         u32 packets_dropped;
61         u32 unknown_types;
62
63         u32 acct_requests;
64         u32 invalid_acct_requests;
65         u32 acct_responses;
66         u32 malformed_acct_requests;
67         u32 acct_bad_authenticators;
68         u32 unknown_acct_types;
69 };
70
71 /**
72  * struct radius_session - Internal RADIUS server data for a session
73  */
74 struct radius_session {
75         struct radius_session *next;
76         struct radius_client *client;
77         struct radius_server_data *server;
78         unsigned int sess_id;
79         struct eap_sm *eap;
80         struct eap_eapol_interface *eap_if;
81         char *username; /* from User-Name attribute */
82         char *nas_ip;
83         u8 mac_addr[ETH_ALEN]; /* from Calling-Station-Id attribute */
84
85         struct radius_msg *last_msg;
86         char *last_from_addr;
87         int last_from_port;
88         struct sockaddr_storage last_from;
89         socklen_t last_fromlen;
90         u8 last_identifier;
91         struct radius_msg *last_reply;
92         u8 last_authenticator[16];
93
94         unsigned int remediation:1;
95         unsigned int macacl:1;
96         unsigned int t_c_filtering:1;
97
98         struct hostapd_radius_attr *accept_attr;
99
100         u32 t_c_timestamp; /* Last read T&C timestamp from user DB */
101 };
102
103 /**
104  * struct radius_client - Internal RADIUS server data for a client
105  */
106 struct radius_client {
107         struct radius_client *next;
108         struct in_addr addr;
109         struct in_addr mask;
110 #ifdef CONFIG_IPV6
111         struct in6_addr addr6;
112         struct in6_addr mask6;
113 #endif /* CONFIG_IPV6 */
114         char *shared_secret;
115         int shared_secret_len;
116         struct radius_session *sessions;
117         struct radius_server_counters counters;
118
119         u8 next_dac_identifier;
120         struct radius_msg *pending_dac_coa_req;
121         u8 pending_dac_coa_id;
122         u8 pending_dac_coa_addr[ETH_ALEN];
123         struct radius_msg *pending_dac_disconnect_req;
124         u8 pending_dac_disconnect_id;
125         u8 pending_dac_disconnect_addr[ETH_ALEN];
126 };
127
128 /**
129  * struct radius_server_data - Internal RADIUS server data
130  */
131 struct radius_server_data {
132         /**
133          * auth_sock - Socket for RADIUS authentication messages
134          */
135         int auth_sock;
136
137         /**
138          * acct_sock - Socket for RADIUS accounting messages
139          */
140         int acct_sock;
141
142         /**
143          * clients - List of authorized RADIUS clients
144          */
145         struct radius_client *clients;
146
147         /**
148          * next_sess_id - Next session identifier
149          */
150         unsigned int next_sess_id;
151
152         /**
153          * conf_ctx - Context pointer for callbacks
154          *
155          * This is used as the ctx argument in get_eap_user() calls.
156          */
157         void *conf_ctx;
158
159         /**
160          * num_sess - Number of active sessions
161          */
162         int num_sess;
163
164         /**
165          * eap_sim_db_priv - EAP-SIM/AKA database context
166          *
167          * This is passed to the EAP-SIM/AKA server implementation as a
168          * callback context.
169          */
170         void *eap_sim_db_priv;
171
172         /**
173          * ssl_ctx - TLS context
174          *
175          * This is passed to the EAP server implementation as a callback
176          * context for TLS operations.
177          */
178         void *ssl_ctx;
179
180         /**
181          * pac_opaque_encr_key - PAC-Opaque encryption key for EAP-FAST
182          *
183          * This parameter is used to set a key for EAP-FAST to encrypt the
184          * PAC-Opaque data. It can be set to %NULL if EAP-FAST is not used. If
185          * set, must point to a 16-octet key.
186          */
187         u8 *pac_opaque_encr_key;
188
189         /**
190          * eap_fast_a_id - EAP-FAST authority identity (A-ID)
191          *
192          * If EAP-FAST is not used, this can be set to %NULL. In theory, this
193          * is a variable length field, but due to some existing implementations
194          * requiring A-ID to be 16 octets in length, it is recommended to use
195          * that length for the field to provide interoperability with deployed
196          * peer implementations.
197          */
198         u8 *eap_fast_a_id;
199
200         /**
201          * eap_fast_a_id_len - Length of eap_fast_a_id buffer in octets
202          */
203         size_t eap_fast_a_id_len;
204
205         /**
206          * eap_fast_a_id_info - EAP-FAST authority identifier information
207          *
208          * This A-ID-Info contains a user-friendly name for the A-ID. For
209          * example, this could be the enterprise and server names in
210          * human-readable format. This field is encoded as UTF-8. If EAP-FAST
211          * is not used, this can be set to %NULL.
212          */
213         char *eap_fast_a_id_info;
214
215         /**
216          * eap_fast_prov - EAP-FAST provisioning modes
217          *
218          * 0 = provisioning disabled, 1 = only anonymous provisioning allowed,
219          * 2 = only authenticated provisioning allowed, 3 = both provisioning
220          * modes allowed.
221          */
222         int eap_fast_prov;
223
224         /**
225          * pac_key_lifetime - EAP-FAST PAC-Key lifetime in seconds
226          *
227          * This is the hard limit on how long a provisioned PAC-Key can be
228          * used.
229          */
230         int pac_key_lifetime;
231
232         /**
233          * pac_key_refresh_time - EAP-FAST PAC-Key refresh time in seconds
234          *
235          * This is a soft limit on the PAC-Key. The server will automatically
236          * generate a new PAC-Key when this number of seconds (or fewer) of the
237          * lifetime remains.
238          */
239         int pac_key_refresh_time;
240
241         /**
242          * eap_sim_aka_result_ind - EAP-SIM/AKA protected success indication
243          *
244          * This controls whether the protected success/failure indication
245          * (AT_RESULT_IND) is used with EAP-SIM and EAP-AKA.
246          */
247         int eap_sim_aka_result_ind;
248
249         /**
250          * tnc - Trusted Network Connect (TNC)
251          *
252          * This controls whether TNC is enabled and will be required before the
253          * peer is allowed to connect. Note: This is only used with EAP-TTLS
254          * and EAP-FAST. If any other EAP method is enabled, the peer will be
255          * allowed to connect without TNC.
256          */
257         int tnc;
258
259         /**
260          * pwd_group - The D-H group assigned for EAP-pwd
261          *
262          * If EAP-pwd is not used it can be set to zero.
263          */
264         u16 pwd_group;
265
266         /**
267          * server_id - Server identity
268          */
269         const char *server_id;
270
271         /**
272          * erp - Whether EAP Re-authentication Protocol (ERP) is enabled
273          *
274          * This controls whether the authentication server derives ERP key
275          * hierarchy (rRK and rIK) from full EAP authentication and allows
276          * these keys to be used to perform ERP to derive rMSK instead of full
277          * EAP authentication to derive MSK.
278          */
279         int erp;
280
281         const char *erp_domain;
282
283         struct dl_list erp_keys; /* struct eap_server_erp_key */
284
285         unsigned int tls_session_lifetime;
286
287         unsigned int tls_flags;
288
289         /**
290          * wps - Wi-Fi Protected Setup context
291          *
292          * If WPS is used with an external RADIUS server (which is quite
293          * unlikely configuration), this is used to provide a pointer to WPS
294          * context data. Normally, this can be set to %NULL.
295          */
296         struct wps_context *wps;
297
298         /**
299          * ipv6 - Whether to enable IPv6 support in the RADIUS server
300          */
301         int ipv6;
302
303         /**
304          * start_time - Timestamp of server start
305          */
306         struct os_reltime start_time;
307
308         /**
309          * counters - Statistics counters for server operations
310          *
311          * These counters are the sum over all clients.
312          */
313         struct radius_server_counters counters;
314
315         /**
316          * get_eap_user - Callback for fetching EAP user information
317          * @ctx: Context data from conf_ctx
318          * @identity: User identity
319          * @identity_len: identity buffer length in octets
320          * @phase2: Whether this is for Phase 2 identity
321          * @user: Data structure for filling in the user information
322          * Returns: 0 on success, -1 on failure
323          *
324          * This is used to fetch information from user database. The callback
325          * will fill in information about allowed EAP methods and the user
326          * password. The password field will be an allocated copy of the
327          * password data and RADIUS server will free it after use.
328          */
329         int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
330                             int phase2, struct eap_user *user);
331
332         /**
333          * eap_req_id_text - Optional data for EAP-Request/Identity
334          *
335          * This can be used to configure an optional, displayable message that
336          * will be sent in EAP-Request/Identity. This string can contain an
337          * ASCII-0 character (nul) to separate network infromation per RFC
338          * 4284. The actual string length is explicit provided in
339          * eap_req_id_text_len since nul character will not be used as a string
340          * terminator.
341          */
342         char *eap_req_id_text;
343
344         /**
345          * eap_req_id_text_len - Length of eap_req_id_text buffer in octets
346          */
347         size_t eap_req_id_text_len;
348
349         /*
350          * msg_ctx - Context data for wpa_msg() calls
351          */
352         void *msg_ctx;
353
354 #ifdef CONFIG_RADIUS_TEST
355         char *dump_msk_file;
356 #endif /* CONFIG_RADIUS_TEST */
357
358         char *subscr_remediation_url;
359         u8 subscr_remediation_method;
360
361         char *t_c_server_url;
362
363 #ifdef CONFIG_SQLITE
364         sqlite3 *db;
365 #endif /* CONFIG_SQLITE */
366 };
367
368
369 #define RADIUS_DEBUG(args...) \
370 wpa_printf(MSG_DEBUG, "RADIUS SRV: " args)
371 #define RADIUS_ERROR(args...) \
372 wpa_printf(MSG_ERROR, "RADIUS SRV: " args)
373 #define RADIUS_DUMP(args...) \
374 wpa_hexdump(MSG_MSGDUMP, "RADIUS SRV: " args)
375 #define RADIUS_DUMP_ASCII(args...) \
376 wpa_hexdump_ascii(MSG_MSGDUMP, "RADIUS SRV: " args)
377
378
379 static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx);
380 static void radius_server_session_remove_timeout(void *eloop_ctx,
381                                                  void *timeout_ctx);
382
383 void srv_log(struct radius_session *sess, const char *fmt, ...)
384 PRINTF_FORMAT(2, 3);
385
386 void srv_log(struct radius_session *sess, const char *fmt, ...)
387 {
388         va_list ap;
389         char *buf;
390         int buflen;
391
392         va_start(ap, fmt);
393         buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
394         va_end(ap);
395
396         buf = os_malloc(buflen);
397         if (buf == NULL)
398                 return;
399         va_start(ap, fmt);
400         vsnprintf(buf, buflen, fmt, ap);
401         va_end(ap);
402
403         RADIUS_DEBUG("[0x%x %s] %s", sess->sess_id, sess->nas_ip, buf);
404
405 #ifdef CONFIG_SQLITE
406         if (sess->server->db) {
407                 char *sql;
408                 sql = sqlite3_mprintf("INSERT INTO authlog"
409                                       "(timestamp,session,nas_ip,username,note)"
410                                       " VALUES ("
411                                       "strftime('%%Y-%%m-%%d %%H:%%M:%%f',"
412                                       "'now'),%u,%Q,%Q,%Q)",
413                                       sess->sess_id, sess->nas_ip,
414                                       sess->username, buf);
415                 if (sql) {
416                         if (sqlite3_exec(sess->server->db, sql, NULL, NULL,
417                                          NULL) != SQLITE_OK) {
418                                 RADIUS_ERROR("Failed to add authlog entry into sqlite database: %s",
419                                              sqlite3_errmsg(sess->server->db));
420                         }
421                         sqlite3_free(sql);
422                 }
423         }
424 #endif /* CONFIG_SQLITE */
425
426         os_free(buf);
427 }
428
429
430 static struct radius_client *
431 radius_server_get_client(struct radius_server_data *data, struct in_addr *addr,
432                          int ipv6)
433 {
434         struct radius_client *client = data->clients;
435
436         while (client) {
437 #ifdef CONFIG_IPV6
438                 if (ipv6) {
439                         struct in6_addr *addr6;
440                         int i;
441
442                         addr6 = (struct in6_addr *) addr;
443                         for (i = 0; i < 16; i++) {
444                                 if ((addr6->s6_addr[i] &
445                                      client->mask6.s6_addr[i]) !=
446                                     (client->addr6.s6_addr[i] &
447                                      client->mask6.s6_addr[i])) {
448                                         i = 17;
449                                         break;
450                                 }
451                         }
452                         if (i == 16) {
453                                 break;
454                         }
455                 }
456 #endif /* CONFIG_IPV6 */
457                 if (!ipv6 && (client->addr.s_addr & client->mask.s_addr) ==
458                     (addr->s_addr & client->mask.s_addr)) {
459                         break;
460                 }
461
462                 client = client->next;
463         }
464
465         return client;
466 }
467
468
469 static struct radius_session *
470 radius_server_get_session(struct radius_client *client, unsigned int sess_id)
471 {
472         struct radius_session *sess = client->sessions;
473
474         while (sess) {
475                 if (sess->sess_id == sess_id) {
476                         break;
477                 }
478                 sess = sess->next;
479         }
480
481         return sess;
482 }
483
484
485 static void radius_server_session_free(struct radius_server_data *data,
486                                        struct radius_session *sess)
487 {
488         eloop_cancel_timeout(radius_server_session_timeout, data, sess);
489         eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess);
490         eap_server_sm_deinit(sess->eap);
491         radius_msg_free(sess->last_msg);
492         os_free(sess->last_from_addr);
493         radius_msg_free(sess->last_reply);
494         os_free(sess->username);
495         os_free(sess->nas_ip);
496         os_free(sess);
497         data->num_sess--;
498 }
499
500
501 static void radius_server_session_remove(struct radius_server_data *data,
502                                          struct radius_session *sess)
503 {
504         struct radius_client *client = sess->client;
505         struct radius_session *session, *prev;
506
507         eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess);
508
509         prev = NULL;
510         session = client->sessions;
511         while (session) {
512                 if (session == sess) {
513                         if (prev == NULL) {
514                                 client->sessions = sess->next;
515                         } else {
516                                 prev->next = sess->next;
517                         }
518                         radius_server_session_free(data, sess);
519                         break;
520                 }
521                 prev = session;
522                 session = session->next;
523         }
524 }
525
526
527 static void radius_server_session_remove_timeout(void *eloop_ctx,
528                                                  void *timeout_ctx)
529 {
530         struct radius_server_data *data = eloop_ctx;
531         struct radius_session *sess = timeout_ctx;
532         RADIUS_DEBUG("Removing completed session 0x%x", sess->sess_id);
533         radius_server_session_remove(data, sess);
534 }
535
536
537 static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx)
538 {
539         struct radius_server_data *data = eloop_ctx;
540         struct radius_session *sess = timeout_ctx;
541
542         RADIUS_DEBUG("Timing out authentication session 0x%x", sess->sess_id);
543         radius_server_session_remove(data, sess);
544 }
545
546
547 static struct radius_session *
548 radius_server_new_session(struct radius_server_data *data,
549                           struct radius_client *client)
550 {
551         struct radius_session *sess;
552
553         if (data->num_sess >= RADIUS_MAX_SESSION) {
554                 RADIUS_DEBUG("Maximum number of existing session - no room "
555                              "for a new session");
556                 return NULL;
557         }
558
559         sess = os_zalloc(sizeof(*sess));
560         if (sess == NULL)
561                 return NULL;
562
563         sess->server = data;
564         sess->client = client;
565         sess->sess_id = data->next_sess_id++;
566         sess->next = client->sessions;
567         client->sessions = sess;
568         eloop_register_timeout(RADIUS_SESSION_TIMEOUT, 0,
569                                radius_server_session_timeout, data, sess);
570         data->num_sess++;
571         return sess;
572 }
573
574
575 #ifdef CONFIG_TESTING_OPTIONS
576 static void radius_server_testing_options_tls(struct radius_session *sess,
577                                               const char *tls,
578                                               struct eap_config *eap_conf)
579 {
580         int test = atoi(tls);
581
582         switch (test) {
583         case 1:
584                 srv_log(sess, "TLS test - break VerifyData");
585                 eap_conf->tls_test_flags = TLS_BREAK_VERIFY_DATA;
586                 break;
587         case 2:
588                 srv_log(sess, "TLS test - break ServerKeyExchange ServerParams hash");
589                 eap_conf->tls_test_flags = TLS_BREAK_SRV_KEY_X_HASH;
590                 break;
591         case 3:
592                 srv_log(sess, "TLS test - break ServerKeyExchange ServerParams Signature");
593                 eap_conf->tls_test_flags = TLS_BREAK_SRV_KEY_X_SIGNATURE;
594                 break;
595         case 4:
596                 srv_log(sess, "TLS test - RSA-DHE using a short 511-bit prime");
597                 eap_conf->tls_test_flags = TLS_DHE_PRIME_511B;
598                 break;
599         case 5:
600                 srv_log(sess, "TLS test - RSA-DHE using a short 767-bit prime");
601                 eap_conf->tls_test_flags = TLS_DHE_PRIME_767B;
602                 break;
603         case 6:
604                 srv_log(sess, "TLS test - RSA-DHE using a bogus 15 \"prime\"");
605                 eap_conf->tls_test_flags = TLS_DHE_PRIME_15;
606                 break;
607         case 7:
608                 srv_log(sess, "TLS test - RSA-DHE using a short 58-bit prime in long container");
609                 eap_conf->tls_test_flags = TLS_DHE_PRIME_58B;
610                 break;
611         case 8:
612                 srv_log(sess, "TLS test - RSA-DHE using a non-prime");
613                 eap_conf->tls_test_flags = TLS_DHE_NON_PRIME;
614                 break;
615         default:
616                 srv_log(sess, "Unrecognized TLS test");
617                 break;
618         }
619 }
620 #endif /* CONFIG_TESTING_OPTIONS */
621
622 static void radius_server_testing_options(struct radius_session *sess,
623                                           struct eap_config *eap_conf)
624 {
625 #ifdef CONFIG_TESTING_OPTIONS
626         const char *pos;
627
628         pos = os_strstr(sess->username, "@test-");
629         if (pos == NULL)
630                 return;
631         pos += 6;
632         if (os_strncmp(pos, "tls-", 4) == 0)
633                 radius_server_testing_options_tls(sess, pos + 4, eap_conf);
634         else
635                 srv_log(sess, "Unrecognized test: %s", pos);
636 #endif /* CONFIG_TESTING_OPTIONS */
637 }
638
639
640 static struct radius_session *
641 radius_server_get_new_session(struct radius_server_data *data,
642                               struct radius_client *client,
643                               struct radius_msg *msg, const char *from_addr)
644 {
645         u8 *user, *id;
646         size_t user_len, id_len;
647         int res;
648         struct radius_session *sess;
649         struct eap_config eap_conf;
650         struct eap_user tmp;
651
652         RADIUS_DEBUG("Creating a new session");
653
654         if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &user,
655                                     &user_len, NULL) < 0) {
656                 RADIUS_DEBUG("Could not get User-Name");
657                 return NULL;
658         }
659         RADIUS_DUMP_ASCII("User-Name", user, user_len);
660
661         os_memset(&tmp, 0, sizeof(tmp));
662         res = data->get_eap_user(data->conf_ctx, user, user_len, 0, &tmp);
663         bin_clear_free(tmp.password, tmp.password_len);
664
665         if (res != 0) {
666                 RADIUS_DEBUG("User-Name not found from user database");
667                 return NULL;
668         }
669
670         RADIUS_DEBUG("Matching user entry found");
671         sess = radius_server_new_session(data, client);
672         if (sess == NULL) {
673                 RADIUS_DEBUG("Failed to create a new session");
674                 return NULL;
675         }
676         sess->accept_attr = tmp.accept_attr;
677         sess->macacl = tmp.macacl;
678
679         sess->username = os_malloc(user_len * 4 + 1);
680         if (sess->username == NULL) {
681                 radius_server_session_remove(data, sess);
682                 return NULL;
683         }
684         printf_encode(sess->username, user_len * 4 + 1, user, user_len);
685
686         sess->nas_ip = os_strdup(from_addr);
687         if (sess->nas_ip == NULL) {
688                 radius_server_session_remove(data, sess);
689                 return NULL;
690         }
691
692         if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CALLING_STATION_ID, &id,
693                                     &id_len, NULL) == 0) {
694                 char buf[3 * ETH_ALEN];
695
696                 os_memset(buf, 0, sizeof(buf));
697                 if (id_len >= sizeof(buf))
698                         id_len = sizeof(buf) - 1;
699                 os_memcpy(buf, id, id_len);
700                 if (hwaddr_aton2(buf, sess->mac_addr) < 0)
701                         os_memset(sess->mac_addr, 0, ETH_ALEN);
702                 else
703                         RADIUS_DEBUG("Calling-Station-Id: " MACSTR,
704                                      MAC2STR(sess->mac_addr));
705         }
706
707         srv_log(sess, "New session created");
708
709         os_memset(&eap_conf, 0, sizeof(eap_conf));
710         eap_conf.ssl_ctx = data->ssl_ctx;
711         eap_conf.msg_ctx = data->msg_ctx;
712         eap_conf.eap_sim_db_priv = data->eap_sim_db_priv;
713         eap_conf.backend_auth = TRUE;
714         eap_conf.eap_server = 1;
715         eap_conf.pac_opaque_encr_key = data->pac_opaque_encr_key;
716         eap_conf.eap_fast_a_id = data->eap_fast_a_id;
717         eap_conf.eap_fast_a_id_len = data->eap_fast_a_id_len;
718         eap_conf.eap_fast_a_id_info = data->eap_fast_a_id_info;
719         eap_conf.eap_fast_prov = data->eap_fast_prov;
720         eap_conf.pac_key_lifetime = data->pac_key_lifetime;
721         eap_conf.pac_key_refresh_time = data->pac_key_refresh_time;
722         eap_conf.eap_sim_aka_result_ind = data->eap_sim_aka_result_ind;
723         eap_conf.tnc = data->tnc;
724         eap_conf.wps = data->wps;
725         eap_conf.pwd_group = data->pwd_group;
726         eap_conf.server_id = (const u8 *) data->server_id;
727         eap_conf.server_id_len = os_strlen(data->server_id);
728         eap_conf.erp = data->erp;
729         eap_conf.tls_session_lifetime = data->tls_session_lifetime;
730         eap_conf.tls_flags = data->tls_flags;
731         radius_server_testing_options(sess, &eap_conf);
732         sess->eap = eap_server_sm_init(sess, &radius_server_eapol_cb,
733                                        &eap_conf);
734         if (sess->eap == NULL) {
735                 RADIUS_DEBUG("Failed to initialize EAP state machine for the "
736                              "new session");
737                 radius_server_session_remove(data, sess);
738                 return NULL;
739         }
740         sess->eap_if = eap_get_interface(sess->eap);
741         sess->eap_if->eapRestart = TRUE;
742         sess->eap_if->portEnabled = TRUE;
743
744         RADIUS_DEBUG("New session 0x%x initialized", sess->sess_id);
745
746         return sess;
747 }
748
749
750 #ifdef CONFIG_HS20
751 static void radius_srv_hs20_t_c_pending(struct radius_session *sess)
752 {
753 #ifdef CONFIG_SQLITE
754         char *sql;
755         char addr[3 * ETH_ALEN], *id_str;
756         const u8 *id;
757         size_t id_len;
758
759         if (!sess->server->db || !sess->eap ||
760             is_zero_ether_addr(sess->mac_addr))
761                 return;
762
763         os_snprintf(addr, sizeof(addr), MACSTR, MAC2STR(sess->mac_addr));
764
765         id = eap_get_identity(sess->eap, &id_len);
766         if (!id)
767                 return;
768         id_str = os_malloc(id_len + 1);
769         if (!id_str)
770                 return;
771         os_memcpy(id_str, id, id_len);
772         id_str[id_len] = '\0';
773
774         sql = sqlite3_mprintf("INSERT OR REPLACE INTO pending_tc (mac_addr,identity) VALUES (%Q,%Q)",
775                               addr, id_str);
776         os_free(id_str);
777         if (!sql)
778                 return;
779
780         if (sqlite3_exec(sess->server->db, sql, NULL, NULL, NULL) !=
781             SQLITE_OK) {
782                 RADIUS_ERROR("Failed to add pending_tc entry into sqlite database: %s",
783                              sqlite3_errmsg(sess->server->db));
784         }
785         sqlite3_free(sql);
786 #endif /* CONFIG_SQLITE */
787 }
788 #endif /* CONFIG_HS20 */
789
790
791 static void radius_server_add_session(struct radius_session *sess)
792 {
793 #ifdef CONFIG_SQLITE
794         char *sql;
795         char addr_txt[ETH_ALEN * 3];
796         struct os_time now;
797
798         if (!sess->server->db)
799                 return;
800
801
802         os_snprintf(addr_txt, sizeof(addr_txt), MACSTR,
803                     MAC2STR(sess->mac_addr));
804
805         os_get_time(&now);
806         sql = sqlite3_mprintf("INSERT OR REPLACE INTO current_sessions(mac_addr,identity,start_time,nas,hs20_t_c_filtering) VALUES (%Q,%Q,%d,%Q,%u)",
807                               addr_txt, sess->username, now.sec,
808                               sess->nas_ip, sess->t_c_filtering);
809         if (sql) {
810                         if (sqlite3_exec(sess->server->db, sql, NULL, NULL,
811                                          NULL) != SQLITE_OK) {
812                                 RADIUS_ERROR("Failed to add current_sessions entry into sqlite database: %s",
813                                              sqlite3_errmsg(sess->server->db));
814                         }
815                         sqlite3_free(sql);
816         }
817 #endif /* CONFIG_SQLITE */
818 }
819
820
821 static void db_update_last_msk(struct radius_session *sess, const char *msk)
822 {
823 #ifdef CONFIG_RADIUS_TEST
824 #ifdef CONFIG_SQLITE
825         char *sql = NULL;
826         char *id_str = NULL;
827         const u8 *id;
828         size_t id_len;
829         const char *serial_num;
830
831         if (!sess->server->db)
832                 return;
833
834         serial_num = eap_get_serial_num(sess->eap);
835         if (serial_num) {
836                 id_len = 5 + os_strlen(serial_num) + 1;
837                 id_str = os_malloc(id_len);
838                 if (!id_str)
839                         return;
840                 os_snprintf(id_str, id_len, "cert-%s", serial_num);
841         } else {
842                 id = eap_get_identity(sess->eap, &id_len);
843                 if (!id)
844                         return;
845                 id_str = os_malloc(id_len + 1);
846                 if (!id_str)
847                         return;
848                 os_memcpy(id_str, id, id_len);
849                 id_str[id_len] = '\0';
850         }
851
852         sql = sqlite3_mprintf("UPDATE users SET last_msk=%Q WHERE identity=%Q",
853                               msk, id_str);
854         os_free(id_str);
855         if (!sql)
856                 return;
857
858         if (sqlite3_exec(sess->server->db, sql, NULL, NULL, NULL) !=
859             SQLITE_OK) {
860                 RADIUS_DEBUG("Failed to update last_msk: %s",
861                              sqlite3_errmsg(sess->server->db));
862         }
863         sqlite3_free(sql);
864 #endif /* CONFIG_SQLITE */
865 #endif /* CONFIG_RADIUS_TEST */
866 }
867
868
869 static struct radius_msg *
870 radius_server_encapsulate_eap(struct radius_server_data *data,
871                               struct radius_client *client,
872                               struct radius_session *sess,
873                               struct radius_msg *request)
874 {
875         struct radius_msg *msg;
876         int code;
877         unsigned int sess_id;
878         struct radius_hdr *hdr = radius_msg_get_hdr(request);
879         u16 reason = WLAN_REASON_IEEE_802_1X_AUTH_FAILED;
880
881         if (sess->eap_if->eapFail) {
882                 sess->eap_if->eapFail = FALSE;
883                 code = RADIUS_CODE_ACCESS_REJECT;
884         } else if (sess->eap_if->eapSuccess) {
885                 sess->eap_if->eapSuccess = FALSE;
886                 code = RADIUS_CODE_ACCESS_ACCEPT;
887         } else {
888                 sess->eap_if->eapReq = FALSE;
889                 code = RADIUS_CODE_ACCESS_CHALLENGE;
890         }
891
892         msg = radius_msg_new(code, hdr->identifier);
893         if (msg == NULL) {
894                 RADIUS_DEBUG("Failed to allocate reply message");
895                 return NULL;
896         }
897
898         sess_id = htonl(sess->sess_id);
899         if (code == RADIUS_CODE_ACCESS_CHALLENGE &&
900             !radius_msg_add_attr(msg, RADIUS_ATTR_STATE,
901                                  (u8 *) &sess_id, sizeof(sess_id))) {
902                 RADIUS_DEBUG("Failed to add State attribute");
903         }
904
905         if (sess->eap_if->eapReqData &&
906             !radius_msg_add_eap(msg, wpabuf_head(sess->eap_if->eapReqData),
907                                 wpabuf_len(sess->eap_if->eapReqData))) {
908                 RADIUS_DEBUG("Failed to add EAP-Message attribute");
909         }
910
911         if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->eap_if->eapKeyData) {
912                 int len;
913 #ifdef CONFIG_RADIUS_TEST
914                 char buf[2 * 64 + 1];
915
916                 len = sess->eap_if->eapKeyDataLen;
917                 if (len > 64)
918                         len = 64;
919                 len = wpa_snprintf_hex(buf, sizeof(buf),
920                                        sess->eap_if->eapKeyData, len);
921                 buf[len] = '\0';
922
923                 if (data->dump_msk_file) {
924                         FILE *f;
925
926                         f = fopen(data->dump_msk_file, "a");
927                         if (f) {
928                                 len = sess->eap_if->eapKeyDataLen;
929                                 if (len > 64)
930                                         len = 64;
931                                 len = wpa_snprintf_hex(
932                                         buf, sizeof(buf),
933                                         sess->eap_if->eapKeyData, len);
934                                 buf[len] = '\0';
935                                 fprintf(f, "%s\n", buf);
936                                 fclose(f);
937                         }
938                 }
939
940                 db_update_last_msk(sess, buf);
941 #endif /* CONFIG_RADIUS_TEST */
942                 if (sess->eap_if->eapKeyDataLen > 64) {
943                         len = 32;
944                 } else {
945                         len = sess->eap_if->eapKeyDataLen / 2;
946                 }
947                 if (!radius_msg_add_mppe_keys(msg, hdr->authenticator,
948                                               (u8 *) client->shared_secret,
949                                               client->shared_secret_len,
950                                               sess->eap_if->eapKeyData + len,
951                                               len, sess->eap_if->eapKeyData,
952                                               len)) {
953                         RADIUS_DEBUG("Failed to add MPPE key attributes");
954                 }
955         }
956
957 #ifdef CONFIG_HS20
958         if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->remediation &&
959             data->subscr_remediation_url) {
960                 u8 *buf;
961                 size_t url_len = os_strlen(data->subscr_remediation_url);
962                 buf = os_malloc(1 + url_len);
963                 if (buf == NULL) {
964                         radius_msg_free(msg);
965                         return NULL;
966                 }
967                 buf[0] = data->subscr_remediation_method;
968                 os_memcpy(&buf[1], data->subscr_remediation_url, url_len);
969                 if (!radius_msg_add_wfa(
970                             msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION,
971                             buf, 1 + url_len)) {
972                         RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem");
973                 }
974                 os_free(buf);
975         } else if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->remediation) {
976                 u8 buf[1];
977                 if (!radius_msg_add_wfa(
978                             msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION,
979                             buf, 0)) {
980                         RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem");
981                 }
982         }
983
984         if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->t_c_filtering) {
985                 u8 buf[4] = { 0x01, 0x00, 0x00, 0x00 }; /* E=1 */
986                 const char *url = data->t_c_server_url, *pos;
987                 char *url2, *end2, *pos2;
988                 size_t url_len;
989
990                 if (!radius_msg_add_wfa(
991                             msg, RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILTERING,
992                             buf, sizeof(buf))) {
993                         RADIUS_DEBUG("Failed to add WFA-HS20-T-C-Filtering");
994                         radius_msg_free(msg);
995                         return NULL;
996                 }
997
998                 if (!url) {
999                         RADIUS_DEBUG("No t_c_server_url configured");
1000                         radius_msg_free(msg);
1001                         return NULL;
1002                 }
1003
1004                 pos = os_strstr(url, "@1@");
1005                 if (!pos) {
1006                         RADIUS_DEBUG("No @1@ macro in t_c_server_url");
1007                         radius_msg_free(msg);
1008                         return NULL;
1009                 }
1010
1011                 url_len = os_strlen(url) + ETH_ALEN * 3 - 1 - 3;
1012                 url2 = os_malloc(url_len + 1);
1013                 if (!url2) {
1014                         RADIUS_DEBUG("Failed to allocate room for T&C Server URL");
1015                         os_free(url2);
1016                         radius_msg_free(msg);
1017                         return NULL;
1018                 }
1019                 pos2 = url2;
1020                 end2 = url2 + url_len + 1;
1021                 os_memcpy(pos2, url, pos - url);
1022                 pos2 += pos - url;
1023                 os_snprintf(pos2, end2 - pos2, MACSTR, MAC2STR(sess->mac_addr));
1024                 pos2 += ETH_ALEN * 3 - 1;
1025                 os_memcpy(pos2, pos + 3, os_strlen(pos + 3));
1026                 if (!radius_msg_add_wfa(msg,
1027                                         RADIUS_VENDOR_ATTR_WFA_HS20_T_C_URL,
1028                                         (const u8 *) url2, url_len)) {
1029                         RADIUS_DEBUG("Failed to add WFA-HS20-T-C-URL");
1030                         os_free(url2);
1031                         radius_msg_free(msg);
1032                         return NULL;
1033                 }
1034                 os_free(url2);
1035
1036                 radius_srv_hs20_t_c_pending(sess);
1037         }
1038 #endif /* CONFIG_HS20 */
1039
1040         if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
1041                 RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
1042                 radius_msg_free(msg);
1043                 return NULL;
1044         }
1045
1046         if (code == RADIUS_CODE_ACCESS_ACCEPT) {
1047                 struct hostapd_radius_attr *attr;
1048                 for (attr = sess->accept_attr; attr; attr = attr->next) {
1049                         if (!radius_msg_add_attr(msg, attr->type,
1050                                                  wpabuf_head(attr->val),
1051                                                  wpabuf_len(attr->val))) {
1052                                 wpa_printf(MSG_ERROR, "Could not add RADIUS attribute");
1053                                 radius_msg_free(msg);
1054                                 return NULL;
1055                         }
1056                 }
1057         }
1058
1059         if (code == RADIUS_CODE_ACCESS_REJECT) {
1060                 if (radius_msg_add_attr_int32(msg, RADIUS_ATTR_WLAN_REASON_CODE,
1061                                               reason) < 0) {
1062                         RADIUS_DEBUG("Failed to add WLAN-Reason-Code attribute");
1063                         radius_msg_free(msg);
1064                         return NULL;
1065                 }
1066         }
1067
1068         if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
1069                                   client->shared_secret_len,
1070                                   hdr->authenticator) < 0) {
1071                 RADIUS_DEBUG("Failed to add Message-Authenticator attribute");
1072         }
1073
1074         if (code == RADIUS_CODE_ACCESS_ACCEPT)
1075                 radius_server_add_session(sess);
1076
1077         return msg;
1078 }
1079
1080
1081 static struct radius_msg *
1082 radius_server_macacl(struct radius_server_data *data,
1083                      struct radius_client *client,
1084                      struct radius_session *sess,
1085                      struct radius_msg *request)
1086 {
1087         struct radius_msg *msg;
1088         int code;
1089         struct radius_hdr *hdr = radius_msg_get_hdr(request);
1090         u8 *pw;
1091         size_t pw_len;
1092
1093         code = RADIUS_CODE_ACCESS_ACCEPT;
1094
1095         if (radius_msg_get_attr_ptr(request, RADIUS_ATTR_USER_PASSWORD, &pw,
1096                                     &pw_len, NULL) < 0) {
1097                 RADIUS_DEBUG("Could not get User-Password");
1098                 code = RADIUS_CODE_ACCESS_REJECT;
1099         } else {
1100                 int res;
1101                 struct eap_user tmp;
1102
1103                 os_memset(&tmp, 0, sizeof(tmp));
1104                 res = data->get_eap_user(data->conf_ctx, (u8 *) sess->username,
1105                                          os_strlen(sess->username), 0, &tmp);
1106                 if (res || !tmp.macacl || tmp.password == NULL) {
1107                         RADIUS_DEBUG("No MAC ACL user entry");
1108                         bin_clear_free(tmp.password, tmp.password_len);
1109                         code = RADIUS_CODE_ACCESS_REJECT;
1110                 } else {
1111                         u8 buf[128];
1112                         res = radius_user_password_hide(
1113                                 request, tmp.password, tmp.password_len,
1114                                 (u8 *) client->shared_secret,
1115                                 client->shared_secret_len,
1116                                 buf, sizeof(buf));
1117                         bin_clear_free(tmp.password, tmp.password_len);
1118
1119                         if (res < 0 || pw_len != (size_t) res ||
1120                             os_memcmp_const(pw, buf, res) != 0) {
1121                                 RADIUS_DEBUG("Incorrect User-Password");
1122                                 code = RADIUS_CODE_ACCESS_REJECT;
1123                         }
1124                 }
1125         }
1126
1127         msg = radius_msg_new(code, hdr->identifier);
1128         if (msg == NULL) {
1129                 RADIUS_DEBUG("Failed to allocate reply message");
1130                 return NULL;
1131         }
1132
1133         if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
1134                 RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
1135                 radius_msg_free(msg);
1136                 return NULL;
1137         }
1138
1139         if (code == RADIUS_CODE_ACCESS_ACCEPT) {
1140                 struct hostapd_radius_attr *attr;
1141                 for (attr = sess->accept_attr; attr; attr = attr->next) {
1142                         if (!radius_msg_add_attr(msg, attr->type,
1143                                                  wpabuf_head(attr->val),
1144                                                  wpabuf_len(attr->val))) {
1145                                 wpa_printf(MSG_ERROR, "Could not add RADIUS attribute");
1146                                 radius_msg_free(msg);
1147                                 return NULL;
1148                         }
1149                 }
1150         }
1151
1152         if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
1153                                   client->shared_secret_len,
1154                                   hdr->authenticator) < 0) {
1155                 RADIUS_DEBUG("Failed to add Message-Authenticator attribute");
1156         }
1157
1158         return msg;
1159 }
1160
1161
1162 static int radius_server_reject(struct radius_server_data *data,
1163                                 struct radius_client *client,
1164                                 struct radius_msg *request,
1165                                 struct sockaddr *from, socklen_t fromlen,
1166                                 const char *from_addr, int from_port)
1167 {
1168         struct radius_msg *msg;
1169         int ret = 0;
1170         struct eap_hdr eapfail;
1171         struct wpabuf *buf;
1172         struct radius_hdr *hdr = radius_msg_get_hdr(request);
1173
1174         RADIUS_DEBUG("Reject invalid request from %s:%d",
1175                      from_addr, from_port);
1176
1177         msg = radius_msg_new(RADIUS_CODE_ACCESS_REJECT, hdr->identifier);
1178         if (msg == NULL) {
1179                 return -1;
1180         }
1181
1182         os_memset(&eapfail, 0, sizeof(eapfail));
1183         eapfail.code = EAP_CODE_FAILURE;
1184         eapfail.identifier = 0;
1185         eapfail.length = host_to_be16(sizeof(eapfail));
1186
1187         if (!radius_msg_add_eap(msg, (u8 *) &eapfail, sizeof(eapfail))) {
1188                 RADIUS_DEBUG("Failed to add EAP-Message attribute");
1189         }
1190
1191         if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
1192                 RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
1193                 radius_msg_free(msg);
1194                 return -1;
1195         }
1196
1197         if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
1198                                   client->shared_secret_len,
1199                                   hdr->authenticator) <
1200             0) {
1201                 RADIUS_DEBUG("Failed to add Message-Authenticator attribute");
1202         }
1203
1204         if (wpa_debug_level <= MSG_MSGDUMP) {
1205                 radius_msg_dump(msg);
1206         }
1207
1208         data->counters.access_rejects++;
1209         client->counters.access_rejects++;
1210         buf = radius_msg_get_buf(msg);
1211         if (sendto(data->auth_sock, wpabuf_head(buf), wpabuf_len(buf), 0,
1212                    (struct sockaddr *) from, sizeof(*from)) < 0) {
1213                 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", strerror(errno));
1214                 ret = -1;
1215         }
1216
1217         radius_msg_free(msg);
1218
1219         return ret;
1220 }
1221
1222
1223 static void radius_server_hs20_t_c_check(struct radius_session *sess,
1224                                          struct radius_msg *msg)
1225 {
1226 #ifdef CONFIG_HS20
1227         u8 *buf, *pos, *end, type, sublen, *timestamp = NULL;
1228         size_t len;
1229
1230         buf = NULL;
1231         for (;;) {
1232                 if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_VENDOR_SPECIFIC,
1233                                             &buf, &len, buf) < 0)
1234                         break;
1235                 if (len < 6)
1236                         continue;
1237                 pos = buf;
1238                 end = buf + len;
1239                 if (WPA_GET_BE32(pos) != RADIUS_VENDOR_ID_WFA)
1240                         continue;
1241                 pos += 4;
1242
1243                 type = *pos++;
1244                 sublen = *pos++;
1245                 if (sublen < 2)
1246                         continue; /* invalid length */
1247                 sublen -= 2; /* skip header */
1248                 if (pos + sublen > end)
1249                         continue; /* invalid WFA VSA */
1250
1251                 if (type == RADIUS_VENDOR_ATTR_WFA_HS20_TIMESTAMP && len >= 4) {
1252                         timestamp = pos;
1253                         break;
1254                 }
1255         }
1256
1257         if (!timestamp)
1258                 return;
1259         RADIUS_DEBUG("HS20-Timestamp: %u", WPA_GET_BE32(timestamp));
1260         if (sess->t_c_timestamp != WPA_GET_BE32(timestamp)) {
1261                 RADIUS_DEBUG("Last read T&C timestamp does not match HS20-Timestamp --> require filtering");
1262                 sess->t_c_filtering = 1;
1263         }
1264 #endif /* CONFIG_HS20 */
1265 }
1266
1267
1268 static int radius_server_request(struct radius_server_data *data,
1269                                  struct radius_msg *msg,
1270                                  struct sockaddr *from, socklen_t fromlen,
1271                                  struct radius_client *client,
1272                                  const char *from_addr, int from_port,
1273                                  struct radius_session *force_sess)
1274 {
1275         struct wpabuf *eap = NULL;
1276         int res, state_included = 0;
1277         u8 statebuf[4];
1278         unsigned int state;
1279         struct radius_session *sess;
1280         struct radius_msg *reply;
1281         int is_complete = 0;
1282
1283         if (force_sess)
1284                 sess = force_sess;
1285         else {
1286                 res = radius_msg_get_attr(msg, RADIUS_ATTR_STATE, statebuf,
1287                                           sizeof(statebuf));
1288                 state_included = res >= 0;
1289                 if (res == sizeof(statebuf)) {
1290                         state = WPA_GET_BE32(statebuf);
1291                         sess = radius_server_get_session(client, state);
1292                 } else {
1293                         sess = NULL;
1294                 }
1295         }
1296
1297         if (sess) {
1298                 RADIUS_DEBUG("Request for session 0x%x", sess->sess_id);
1299         } else if (state_included) {
1300                 RADIUS_DEBUG("State attribute included but no session found");
1301                 radius_server_reject(data, client, msg, from, fromlen,
1302                                      from_addr, from_port);
1303                 return -1;
1304         } else {
1305                 sess = radius_server_get_new_session(data, client, msg,
1306                                                      from_addr);
1307                 if (sess == NULL) {
1308                         RADIUS_DEBUG("Could not create a new session");
1309                         radius_server_reject(data, client, msg, from, fromlen,
1310                                              from_addr, from_port);
1311                         return -1;
1312                 }
1313         }
1314
1315         if (sess->last_from_port == from_port &&
1316             sess->last_identifier == radius_msg_get_hdr(msg)->identifier &&
1317             os_memcmp(sess->last_authenticator,
1318                       radius_msg_get_hdr(msg)->authenticator, 16) == 0) {
1319                 RADIUS_DEBUG("Duplicate message from %s", from_addr);
1320                 data->counters.dup_access_requests++;
1321                 client->counters.dup_access_requests++;
1322
1323                 if (sess->last_reply) {
1324                         struct wpabuf *buf;
1325                         buf = radius_msg_get_buf(sess->last_reply);
1326                         res = sendto(data->auth_sock, wpabuf_head(buf),
1327                                      wpabuf_len(buf), 0,
1328                                      (struct sockaddr *) from, fromlen);
1329                         if (res < 0) {
1330                                 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
1331                                            strerror(errno));
1332                         }
1333                         return 0;
1334                 }
1335
1336                 RADIUS_DEBUG("No previous reply available for duplicate "
1337                              "message");
1338                 return -1;
1339         }
1340
1341         eap = radius_msg_get_eap(msg);
1342         if (eap == NULL && sess->macacl) {
1343                 reply = radius_server_macacl(data, client, sess, msg);
1344                 if (reply == NULL)
1345                         return -1;
1346                 goto send_reply;
1347         }
1348         if (eap == NULL) {
1349                 RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s",
1350                              from_addr);
1351                 data->counters.packets_dropped++;
1352                 client->counters.packets_dropped++;
1353                 return -1;
1354         }
1355
1356         RADIUS_DUMP("Received EAP data", wpabuf_head(eap), wpabuf_len(eap));
1357
1358         /* FIX: if Code is Request, Success, or Failure, send Access-Reject;
1359          * RFC3579 Sect. 2.6.2.
1360          * Include EAP-Response/Nak with no preferred method if
1361          * code == request.
1362          * If code is not 1-4, discard the packet silently.
1363          * Or is this already done by the EAP state machine? */
1364
1365         wpabuf_free(sess->eap_if->eapRespData);
1366         sess->eap_if->eapRespData = eap;
1367         sess->eap_if->eapResp = TRUE;
1368         eap_server_sm_step(sess->eap);
1369
1370         if ((sess->eap_if->eapReq || sess->eap_if->eapSuccess ||
1371              sess->eap_if->eapFail) && sess->eap_if->eapReqData) {
1372                 RADIUS_DUMP("EAP data from the state machine",
1373                             wpabuf_head(sess->eap_if->eapReqData),
1374                             wpabuf_len(sess->eap_if->eapReqData));
1375         } else if (sess->eap_if->eapFail) {
1376                 RADIUS_DEBUG("No EAP data from the state machine, but eapFail "
1377                              "set");
1378         } else if (eap_sm_method_pending(sess->eap)) {
1379                 radius_msg_free(sess->last_msg);
1380                 sess->last_msg = msg;
1381                 sess->last_from_port = from_port;
1382                 os_free(sess->last_from_addr);
1383                 sess->last_from_addr = os_strdup(from_addr);
1384                 sess->last_fromlen = fromlen;
1385                 os_memcpy(&sess->last_from, from, fromlen);
1386                 return -2;
1387         } else {
1388                 RADIUS_DEBUG("No EAP data from the state machine - ignore this"
1389                              " Access-Request silently (assuming it was a "
1390                              "duplicate)");
1391                 data->counters.packets_dropped++;
1392                 client->counters.packets_dropped++;
1393                 return -1;
1394         }
1395
1396         if (sess->eap_if->eapSuccess || sess->eap_if->eapFail)
1397                 is_complete = 1;
1398         if (sess->eap_if->eapFail) {
1399                 srv_log(sess, "EAP authentication failed");
1400                 db_update_last_msk(sess, "FAIL");
1401         } else if (sess->eap_if->eapSuccess) {
1402                 srv_log(sess, "EAP authentication succeeded");
1403         }
1404
1405         if (sess->eap_if->eapSuccess)
1406                 radius_server_hs20_t_c_check(sess, msg);
1407
1408         reply = radius_server_encapsulate_eap(data, client, sess, msg);
1409
1410 send_reply:
1411         if (reply) {
1412                 struct wpabuf *buf;
1413                 struct radius_hdr *hdr;
1414
1415                 RADIUS_DEBUG("Reply to %s:%d", from_addr, from_port);
1416                 if (wpa_debug_level <= MSG_MSGDUMP) {
1417                         radius_msg_dump(reply);
1418                 }
1419
1420                 switch (radius_msg_get_hdr(reply)->code) {
1421                 case RADIUS_CODE_ACCESS_ACCEPT:
1422                         srv_log(sess, "Sending Access-Accept");
1423                         data->counters.access_accepts++;
1424                         client->counters.access_accepts++;
1425                         break;
1426                 case RADIUS_CODE_ACCESS_REJECT:
1427                         srv_log(sess, "Sending Access-Reject");
1428                         data->counters.access_rejects++;
1429                         client->counters.access_rejects++;
1430                         break;
1431                 case RADIUS_CODE_ACCESS_CHALLENGE:
1432                         data->counters.access_challenges++;
1433                         client->counters.access_challenges++;
1434                         break;
1435                 }
1436                 buf = radius_msg_get_buf(reply);
1437                 res = sendto(data->auth_sock, wpabuf_head(buf),
1438                              wpabuf_len(buf), 0,
1439                              (struct sockaddr *) from, fromlen);
1440                 if (res < 0) {
1441                         wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
1442                                    strerror(errno));
1443                 }
1444                 radius_msg_free(sess->last_reply);
1445                 sess->last_reply = reply;
1446                 sess->last_from_port = from_port;
1447                 hdr = radius_msg_get_hdr(msg);
1448                 sess->last_identifier = hdr->identifier;
1449                 os_memcpy(sess->last_authenticator, hdr->authenticator, 16);
1450         } else {
1451                 data->counters.packets_dropped++;
1452                 client->counters.packets_dropped++;
1453         }
1454
1455         if (is_complete) {
1456                 RADIUS_DEBUG("Removing completed session 0x%x after timeout",
1457                              sess->sess_id);
1458                 eloop_cancel_timeout(radius_server_session_remove_timeout,
1459                                      data, sess);
1460                 eloop_register_timeout(RADIUS_SESSION_MAINTAIN, 0,
1461                                        radius_server_session_remove_timeout,
1462                                        data, sess);
1463         }
1464
1465         return 0;
1466 }
1467
1468
1469 static void
1470 radius_server_receive_disconnect_resp(struct radius_server_data *data,
1471                                       struct radius_client *client,
1472                                       struct radius_msg *msg, int ack)
1473 {
1474         struct radius_hdr *hdr;
1475
1476         if (!client->pending_dac_disconnect_req) {
1477                 RADIUS_DEBUG("Ignore unexpected Disconnect response");
1478                 radius_msg_free(msg);
1479                 return;
1480         }
1481
1482         hdr = radius_msg_get_hdr(msg);
1483         if (hdr->identifier != client->pending_dac_disconnect_id) {
1484                 RADIUS_DEBUG("Ignore unexpected Disconnect response with unexpected identifier %u (expected %u)",
1485                              hdr->identifier,
1486                              client->pending_dac_disconnect_id);
1487                 radius_msg_free(msg);
1488                 return;
1489         }
1490
1491         if (radius_msg_verify(msg, (const u8 *) client->shared_secret,
1492                               client->shared_secret_len,
1493                               client->pending_dac_disconnect_req, 0)) {
1494                 RADIUS_DEBUG("Ignore Disconnect response with invalid authenticator");
1495                 radius_msg_free(msg);
1496                 return;
1497         }
1498
1499         RADIUS_DEBUG("Disconnect-%s received for " MACSTR,
1500                      ack ? "ACK" : "NAK",
1501                      MAC2STR(client->pending_dac_disconnect_addr));
1502
1503         radius_msg_free(msg);
1504         radius_msg_free(client->pending_dac_disconnect_req);
1505         client->pending_dac_disconnect_req = NULL;
1506 }
1507
1508
1509 static void radius_server_receive_coa_resp(struct radius_server_data *data,
1510                                            struct radius_client *client,
1511                                            struct radius_msg *msg, int ack)
1512 {
1513         struct radius_hdr *hdr;
1514 #ifdef CONFIG_SQLITE
1515         char addrtxt[3 * ETH_ALEN];
1516         char *sql;
1517         int res;
1518 #endif /* CONFIG_SQLITE */
1519
1520         if (!client->pending_dac_coa_req) {
1521                 RADIUS_DEBUG("Ignore unexpected CoA response");
1522                 radius_msg_free(msg);
1523                 return;
1524         }
1525
1526         hdr = radius_msg_get_hdr(msg);
1527         if (hdr->identifier != client->pending_dac_coa_id) {
1528                 RADIUS_DEBUG("Ignore unexpected CoA response with unexpected identifier %u (expected %u)",
1529                              hdr->identifier,
1530                              client->pending_dac_coa_id);
1531                 radius_msg_free(msg);
1532                 return;
1533         }
1534
1535         if (radius_msg_verify(msg, (const u8 *) client->shared_secret,
1536                               client->shared_secret_len,
1537                               client->pending_dac_coa_req, 0)) {
1538                 RADIUS_DEBUG("Ignore CoA response with invalid authenticator");
1539                 radius_msg_free(msg);
1540                 return;
1541         }
1542
1543         RADIUS_DEBUG("CoA-%s received for " MACSTR,
1544                      ack ? "ACK" : "NAK",
1545                      MAC2STR(client->pending_dac_coa_addr));
1546
1547         radius_msg_free(msg);
1548         radius_msg_free(client->pending_dac_coa_req);
1549         client->pending_dac_coa_req = NULL;
1550
1551 #ifdef CONFIG_SQLITE
1552         if (!data->db)
1553                 return;
1554
1555         os_snprintf(addrtxt, sizeof(addrtxt), MACSTR,
1556                     MAC2STR(client->pending_dac_coa_addr));
1557
1558         if (ack) {
1559                 sql = sqlite3_mprintf("UPDATE current_sessions SET hs20_t_c_filtering=0, waiting_coa_ack=0, coa_ack_received=1 WHERE mac_addr=%Q",
1560                                       addrtxt);
1561         } else {
1562                 sql = sqlite3_mprintf("UPDATE current_sessions SET waiting_coa_ack=0 WHERE mac_addr=%Q",
1563                                       addrtxt);
1564         }
1565         if (!sql)
1566                 return;
1567
1568         res = sqlite3_exec(data->db, sql, NULL, NULL, NULL);
1569         sqlite3_free(sql);
1570         if (res != SQLITE_OK) {
1571                 RADIUS_ERROR("Failed to update current_sessions entry: %s",
1572                              sqlite3_errmsg(data->db));
1573                 return;
1574         }
1575 #endif /* CONFIG_SQLITE */
1576 }
1577
1578
1579 static void radius_server_receive_auth(int sock, void *eloop_ctx,
1580                                        void *sock_ctx)
1581 {
1582         struct radius_server_data *data = eloop_ctx;
1583         u8 *buf = NULL;
1584         union {
1585                 struct sockaddr_storage ss;
1586                 struct sockaddr_in sin;
1587 #ifdef CONFIG_IPV6
1588                 struct sockaddr_in6 sin6;
1589 #endif /* CONFIG_IPV6 */
1590         } from;
1591         socklen_t fromlen;
1592         int len;
1593         struct radius_client *client = NULL;
1594         struct radius_msg *msg = NULL;
1595         char abuf[50];
1596         int from_port = 0;
1597
1598         buf = os_malloc(RADIUS_MAX_MSG_LEN);
1599         if (buf == NULL) {
1600                 goto fail;
1601         }
1602
1603         fromlen = sizeof(from);
1604         len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0,
1605                        (struct sockaddr *) &from.ss, &fromlen);
1606         if (len < 0) {
1607                 wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s",
1608                            strerror(errno));
1609                 goto fail;
1610         }
1611
1612 #ifdef CONFIG_IPV6
1613         if (data->ipv6) {
1614                 if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf,
1615                               sizeof(abuf)) == NULL)
1616                         abuf[0] = '\0';
1617                 from_port = ntohs(from.sin6.sin6_port);
1618                 RADIUS_DEBUG("Received %d bytes from %s:%d",
1619                              len, abuf, from_port);
1620
1621                 client = radius_server_get_client(data,
1622                                                   (struct in_addr *)
1623                                                   &from.sin6.sin6_addr, 1);
1624         }
1625 #endif /* CONFIG_IPV6 */
1626
1627         if (!data->ipv6) {
1628                 os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
1629                 from_port = ntohs(from.sin.sin_port);
1630                 RADIUS_DEBUG("Received %d bytes from %s:%d",
1631                              len, abuf, from_port);
1632
1633                 client = radius_server_get_client(data, &from.sin.sin_addr, 0);
1634         }
1635
1636         RADIUS_DUMP("Received data", buf, len);
1637
1638         if (client == NULL) {
1639                 RADIUS_DEBUG("Unknown client %s - packet ignored", abuf);
1640                 data->counters.invalid_requests++;
1641                 goto fail;
1642         }
1643
1644         msg = radius_msg_parse(buf, len);
1645         if (msg == NULL) {
1646                 RADIUS_DEBUG("Parsing incoming RADIUS frame failed");
1647                 data->counters.malformed_access_requests++;
1648                 client->counters.malformed_access_requests++;
1649                 goto fail;
1650         }
1651
1652         os_free(buf);
1653         buf = NULL;
1654
1655         if (wpa_debug_level <= MSG_MSGDUMP) {
1656                 radius_msg_dump(msg);
1657         }
1658
1659         if (radius_msg_get_hdr(msg)->code == RADIUS_CODE_DISCONNECT_ACK) {
1660                 radius_server_receive_disconnect_resp(data, client, msg, 1);
1661                 return;
1662         }
1663
1664         if (radius_msg_get_hdr(msg)->code == RADIUS_CODE_DISCONNECT_NAK) {
1665                 radius_server_receive_disconnect_resp(data, client, msg, 0);
1666                 return;
1667         }
1668
1669         if (radius_msg_get_hdr(msg)->code == RADIUS_CODE_COA_ACK) {
1670                 radius_server_receive_coa_resp(data, client, msg, 1);
1671                 return;
1672         }
1673
1674         if (radius_msg_get_hdr(msg)->code == RADIUS_CODE_COA_NAK) {
1675                 radius_server_receive_coa_resp(data, client, msg, 0);
1676                 return;
1677         }
1678
1679         if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCESS_REQUEST) {
1680                 RADIUS_DEBUG("Unexpected RADIUS code %d",
1681                              radius_msg_get_hdr(msg)->code);
1682                 data->counters.unknown_types++;
1683                 client->counters.unknown_types++;
1684                 goto fail;
1685         }
1686
1687         data->counters.access_requests++;
1688         client->counters.access_requests++;
1689
1690         if (radius_msg_verify_msg_auth(msg, (u8 *) client->shared_secret,
1691                                        client->shared_secret_len, NULL)) {
1692                 RADIUS_DEBUG("Invalid Message-Authenticator from %s", abuf);
1693                 data->counters.bad_authenticators++;
1694                 client->counters.bad_authenticators++;
1695                 goto fail;
1696         }
1697
1698         if (radius_server_request(data, msg, (struct sockaddr *) &from,
1699                                   fromlen, client, abuf, from_port, NULL) ==
1700             -2)
1701                 return; /* msg was stored with the session */
1702
1703 fail:
1704         radius_msg_free(msg);
1705         os_free(buf);
1706 }
1707
1708
1709 static void radius_server_receive_acct(int sock, void *eloop_ctx,
1710                                        void *sock_ctx)
1711 {
1712         struct radius_server_data *data = eloop_ctx;
1713         u8 *buf = NULL;
1714         union {
1715                 struct sockaddr_storage ss;
1716                 struct sockaddr_in sin;
1717 #ifdef CONFIG_IPV6
1718                 struct sockaddr_in6 sin6;
1719 #endif /* CONFIG_IPV6 */
1720         } from;
1721         socklen_t fromlen;
1722         int len, res;
1723         struct radius_client *client = NULL;
1724         struct radius_msg *msg = NULL, *resp = NULL;
1725         char abuf[50];
1726         int from_port = 0;
1727         struct radius_hdr *hdr;
1728         struct wpabuf *rbuf;
1729
1730         buf = os_malloc(RADIUS_MAX_MSG_LEN);
1731         if (buf == NULL) {
1732                 goto fail;
1733         }
1734
1735         fromlen = sizeof(from);
1736         len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0,
1737                        (struct sockaddr *) &from.ss, &fromlen);
1738         if (len < 0) {
1739                 wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s",
1740                            strerror(errno));
1741                 goto fail;
1742         }
1743
1744 #ifdef CONFIG_IPV6
1745         if (data->ipv6) {
1746                 if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf,
1747                               sizeof(abuf)) == NULL)
1748                         abuf[0] = '\0';
1749                 from_port = ntohs(from.sin6.sin6_port);
1750                 RADIUS_DEBUG("Received %d bytes from %s:%d",
1751                              len, abuf, from_port);
1752
1753                 client = radius_server_get_client(data,
1754                                                   (struct in_addr *)
1755                                                   &from.sin6.sin6_addr, 1);
1756         }
1757 #endif /* CONFIG_IPV6 */
1758
1759         if (!data->ipv6) {
1760                 os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
1761                 from_port = ntohs(from.sin.sin_port);
1762                 RADIUS_DEBUG("Received %d bytes from %s:%d",
1763                              len, abuf, from_port);
1764
1765                 client = radius_server_get_client(data, &from.sin.sin_addr, 0);
1766         }
1767
1768         RADIUS_DUMP("Received data", buf, len);
1769
1770         if (client == NULL) {
1771                 RADIUS_DEBUG("Unknown client %s - packet ignored", abuf);
1772                 data->counters.invalid_acct_requests++;
1773                 goto fail;
1774         }
1775
1776         msg = radius_msg_parse(buf, len);
1777         if (msg == NULL) {
1778                 RADIUS_DEBUG("Parsing incoming RADIUS frame failed");
1779                 data->counters.malformed_acct_requests++;
1780                 client->counters.malformed_acct_requests++;
1781                 goto fail;
1782         }
1783
1784         os_free(buf);
1785         buf = NULL;
1786
1787         if (wpa_debug_level <= MSG_MSGDUMP) {
1788                 radius_msg_dump(msg);
1789         }
1790
1791         if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCOUNTING_REQUEST) {
1792                 RADIUS_DEBUG("Unexpected RADIUS code %d",
1793                              radius_msg_get_hdr(msg)->code);
1794                 data->counters.unknown_acct_types++;
1795                 client->counters.unknown_acct_types++;
1796                 goto fail;
1797         }
1798
1799         data->counters.acct_requests++;
1800         client->counters.acct_requests++;
1801
1802         if (radius_msg_verify_acct_req(msg, (u8 *) client->shared_secret,
1803                                        client->shared_secret_len)) {
1804                 RADIUS_DEBUG("Invalid Authenticator from %s", abuf);
1805                 data->counters.acct_bad_authenticators++;
1806                 client->counters.acct_bad_authenticators++;
1807                 goto fail;
1808         }
1809
1810         /* TODO: Write accounting information to a file or database */
1811
1812         hdr = radius_msg_get_hdr(msg);
1813
1814         resp = radius_msg_new(RADIUS_CODE_ACCOUNTING_RESPONSE, hdr->identifier);
1815         if (resp == NULL)
1816                 goto fail;
1817
1818         radius_msg_finish_acct_resp(resp, (u8 *) client->shared_secret,
1819                                     client->shared_secret_len,
1820                                     hdr->authenticator);
1821
1822         RADIUS_DEBUG("Reply to %s:%d", abuf, from_port);
1823         if (wpa_debug_level <= MSG_MSGDUMP) {
1824                 radius_msg_dump(resp);
1825         }
1826         rbuf = radius_msg_get_buf(resp);
1827         data->counters.acct_responses++;
1828         client->counters.acct_responses++;
1829         res = sendto(data->acct_sock, wpabuf_head(rbuf), wpabuf_len(rbuf), 0,
1830                      (struct sockaddr *) &from.ss, fromlen);
1831         if (res < 0) {
1832                 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
1833                            strerror(errno));
1834         }
1835
1836 fail:
1837         radius_msg_free(resp);
1838         radius_msg_free(msg);
1839         os_free(buf);
1840 }
1841
1842
1843 static int radius_server_disable_pmtu_discovery(int s)
1844 {
1845         int r = -1;
1846 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
1847         /* Turn off Path MTU discovery on IPv4/UDP sockets. */
1848         int action = IP_PMTUDISC_DONT;
1849         r = setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action,
1850                        sizeof(action));
1851         if (r == -1)
1852                 wpa_printf(MSG_ERROR, "Failed to set IP_MTU_DISCOVER: "
1853                            "%s", strerror(errno));
1854 #endif
1855         return r;
1856 }
1857
1858
1859 static int radius_server_open_socket(int port)
1860 {
1861         int s;
1862         struct sockaddr_in addr;
1863
1864         s = socket(PF_INET, SOCK_DGRAM, 0);
1865         if (s < 0) {
1866                 wpa_printf(MSG_INFO, "RADIUS: socket: %s", strerror(errno));
1867                 return -1;
1868         }
1869
1870         radius_server_disable_pmtu_discovery(s);
1871
1872         os_memset(&addr, 0, sizeof(addr));
1873         addr.sin_family = AF_INET;
1874         addr.sin_port = htons(port);
1875         if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1876                 wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno));
1877                 close(s);
1878                 return -1;
1879         }
1880
1881         return s;
1882 }
1883
1884
1885 #ifdef CONFIG_IPV6
1886 static int radius_server_open_socket6(int port)
1887 {
1888         int s;
1889         struct sockaddr_in6 addr;
1890
1891         s = socket(PF_INET6, SOCK_DGRAM, 0);
1892         if (s < 0) {
1893                 wpa_printf(MSG_INFO, "RADIUS: socket[IPv6]: %s",
1894                            strerror(errno));
1895                 return -1;
1896         }
1897
1898         os_memset(&addr, 0, sizeof(addr));
1899         addr.sin6_family = AF_INET6;
1900         os_memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any));
1901         addr.sin6_port = htons(port);
1902         if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1903                 wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno));
1904                 close(s);
1905                 return -1;
1906         }
1907
1908         return s;
1909 }
1910 #endif /* CONFIG_IPV6 */
1911
1912
1913 static void radius_server_free_sessions(struct radius_server_data *data,
1914                                         struct radius_session *sessions)
1915 {
1916         struct radius_session *session, *prev;
1917
1918         session = sessions;
1919         while (session) {
1920                 prev = session;
1921                 session = session->next;
1922                 radius_server_session_free(data, prev);
1923         }
1924 }
1925
1926
1927 static void radius_server_free_clients(struct radius_server_data *data,
1928                                        struct radius_client *clients)
1929 {
1930         struct radius_client *client, *prev;
1931
1932         client = clients;
1933         while (client) {
1934                 prev = client;
1935                 client = client->next;
1936
1937                 radius_server_free_sessions(data, prev->sessions);
1938                 os_free(prev->shared_secret);
1939                 radius_msg_free(prev->pending_dac_coa_req);
1940                 radius_msg_free(prev->pending_dac_disconnect_req);
1941                 os_free(prev);
1942         }
1943 }
1944
1945
1946 static struct radius_client *
1947 radius_server_read_clients(const char *client_file, int ipv6)
1948 {
1949         FILE *f;
1950         const int buf_size = 1024;
1951         char *buf, *pos;
1952         struct radius_client *clients, *tail, *entry;
1953         int line = 0, mask, failed = 0, i;
1954         struct in_addr addr;
1955 #ifdef CONFIG_IPV6
1956         struct in6_addr addr6;
1957 #endif /* CONFIG_IPV6 */
1958         unsigned int val;
1959
1960         f = fopen(client_file, "r");
1961         if (f == NULL) {
1962                 RADIUS_ERROR("Could not open client file '%s'", client_file);
1963                 return NULL;
1964         }
1965
1966         buf = os_malloc(buf_size);
1967         if (buf == NULL) {
1968                 fclose(f);
1969                 return NULL;
1970         }
1971
1972         clients = tail = NULL;
1973         while (fgets(buf, buf_size, f)) {
1974                 /* Configuration file format:
1975                  * 192.168.1.0/24 secret
1976                  * 192.168.1.2 secret
1977                  * fe80::211:22ff:fe33:4455/64 secretipv6
1978                  */
1979                 line++;
1980                 buf[buf_size - 1] = '\0';
1981                 pos = buf;
1982                 while (*pos != '\0' && *pos != '\n')
1983                         pos++;
1984                 if (*pos == '\n')
1985                         *pos = '\0';
1986                 if (*buf == '\0' || *buf == '#')
1987                         continue;
1988
1989                 pos = buf;
1990                 while ((*pos >= '0' && *pos <= '9') || *pos == '.' ||
1991                        (*pos >= 'a' && *pos <= 'f') || *pos == ':' ||
1992                        (*pos >= 'A' && *pos <= 'F')) {
1993                         pos++;
1994                 }
1995
1996                 if (*pos == '\0') {
1997                         failed = 1;
1998                         break;
1999                 }
2000
2001                 if (*pos == '/') {
2002                         char *end;
2003                         *pos++ = '\0';
2004                         mask = strtol(pos, &end, 10);
2005                         if ((pos == end) ||
2006                             (mask < 0 || mask > (ipv6 ? 128 : 32))) {
2007                                 failed = 1;
2008                                 break;
2009                         }
2010                         pos = end;
2011                 } else {
2012                         mask = ipv6 ? 128 : 32;
2013                         *pos++ = '\0';
2014                 }
2015
2016                 if (!ipv6 && inet_aton(buf, &addr) == 0) {
2017                         failed = 1;
2018                         break;
2019                 }
2020 #ifdef CONFIG_IPV6
2021                 if (ipv6 && inet_pton(AF_INET6, buf, &addr6) <= 0) {
2022                         if (inet_pton(AF_INET, buf, &addr) <= 0) {
2023                                 failed = 1;
2024                                 break;
2025                         }
2026                         /* Convert IPv4 address to IPv6 */
2027                         if (mask <= 32)
2028                                 mask += (128 - 32);
2029                         os_memset(addr6.s6_addr, 0, 10);
2030                         addr6.s6_addr[10] = 0xff;
2031                         addr6.s6_addr[11] = 0xff;
2032                         os_memcpy(addr6.s6_addr + 12, (char *) &addr.s_addr,
2033                                   4);
2034                 }
2035 #endif /* CONFIG_IPV6 */
2036
2037                 while (*pos == ' ' || *pos == '\t') {
2038                         pos++;
2039                 }
2040
2041                 if (*pos == '\0') {
2042                         failed = 1;
2043                         break;
2044                 }
2045
2046                 entry = os_zalloc(sizeof(*entry));
2047                 if (entry == NULL) {
2048                         failed = 1;
2049                         break;
2050                 }
2051                 entry->shared_secret = os_strdup(pos);
2052                 if (entry->shared_secret == NULL) {
2053                         failed = 1;
2054                         os_free(entry);
2055                         break;
2056                 }
2057                 entry->shared_secret_len = os_strlen(entry->shared_secret);
2058                 if (!ipv6) {
2059                         entry->addr.s_addr = addr.s_addr;
2060                         val = 0;
2061                         for (i = 0; i < mask; i++)
2062                                 val |= 1 << (31 - i);
2063                         entry->mask.s_addr = htonl(val);
2064                 }
2065 #ifdef CONFIG_IPV6
2066                 if (ipv6) {
2067                         int offset = mask / 8;
2068
2069                         os_memcpy(entry->addr6.s6_addr, addr6.s6_addr, 16);
2070                         os_memset(entry->mask6.s6_addr, 0xff, offset);
2071                         val = 0;
2072                         for (i = 0; i < (mask % 8); i++)
2073                                 val |= 1 << (7 - i);
2074                         if (offset < 16)
2075                                 entry->mask6.s6_addr[offset] = val;
2076                 }
2077 #endif /* CONFIG_IPV6 */
2078
2079                 if (tail == NULL) {
2080                         clients = tail = entry;
2081                 } else {
2082                         tail->next = entry;
2083                         tail = entry;
2084                 }
2085         }
2086
2087         if (failed) {
2088                 RADIUS_ERROR("Invalid line %d in '%s'", line, client_file);
2089                 radius_server_free_clients(NULL, clients);
2090                 clients = NULL;
2091         }
2092
2093         os_free(buf);
2094         fclose(f);
2095
2096         return clients;
2097 }
2098
2099
2100 /**
2101  * radius_server_init - Initialize RADIUS server
2102  * @conf: Configuration for the RADIUS server
2103  * Returns: Pointer to private RADIUS server context or %NULL on failure
2104  *
2105  * This initializes a RADIUS server instance and returns a context pointer that
2106  * will be used in other calls to the RADIUS server module. The server can be
2107  * deinitialize by calling radius_server_deinit().
2108  */
2109 struct radius_server_data *
2110 radius_server_init(struct radius_server_conf *conf)
2111 {
2112         struct radius_server_data *data;
2113
2114 #ifndef CONFIG_IPV6
2115         if (conf->ipv6) {
2116                 wpa_printf(MSG_ERROR, "RADIUS server compiled without IPv6 support");
2117                 return NULL;
2118         }
2119 #endif /* CONFIG_IPV6 */
2120
2121         data = os_zalloc(sizeof(*data));
2122         if (data == NULL)
2123                 return NULL;
2124
2125         dl_list_init(&data->erp_keys);
2126         os_get_reltime(&data->start_time);
2127         data->conf_ctx = conf->conf_ctx;
2128         data->eap_sim_db_priv = conf->eap_sim_db_priv;
2129         data->ssl_ctx = conf->ssl_ctx;
2130         data->msg_ctx = conf->msg_ctx;
2131         data->ipv6 = conf->ipv6;
2132         if (conf->pac_opaque_encr_key) {
2133                 data->pac_opaque_encr_key = os_malloc(16);
2134                 if (data->pac_opaque_encr_key) {
2135                         os_memcpy(data->pac_opaque_encr_key,
2136                                   conf->pac_opaque_encr_key, 16);
2137                 }
2138         }
2139         if (conf->eap_fast_a_id) {
2140                 data->eap_fast_a_id = os_malloc(conf->eap_fast_a_id_len);
2141                 if (data->eap_fast_a_id) {
2142                         os_memcpy(data->eap_fast_a_id, conf->eap_fast_a_id,
2143                                   conf->eap_fast_a_id_len);
2144                         data->eap_fast_a_id_len = conf->eap_fast_a_id_len;
2145                 }
2146         }
2147         if (conf->eap_fast_a_id_info)
2148                 data->eap_fast_a_id_info = os_strdup(conf->eap_fast_a_id_info);
2149         data->eap_fast_prov = conf->eap_fast_prov;
2150         data->pac_key_lifetime = conf->pac_key_lifetime;
2151         data->pac_key_refresh_time = conf->pac_key_refresh_time;
2152         data->get_eap_user = conf->get_eap_user;
2153         data->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
2154         data->tnc = conf->tnc;
2155         data->wps = conf->wps;
2156         data->pwd_group = conf->pwd_group;
2157         data->server_id = conf->server_id;
2158         if (conf->eap_req_id_text) {
2159                 data->eap_req_id_text = os_malloc(conf->eap_req_id_text_len);
2160                 if (data->eap_req_id_text) {
2161                         os_memcpy(data->eap_req_id_text, conf->eap_req_id_text,
2162                                   conf->eap_req_id_text_len);
2163                         data->eap_req_id_text_len = conf->eap_req_id_text_len;
2164                 }
2165         }
2166         data->erp = conf->erp;
2167         data->erp_domain = conf->erp_domain;
2168         data->tls_session_lifetime = conf->tls_session_lifetime;
2169         data->tls_flags = conf->tls_flags;
2170
2171         if (conf->subscr_remediation_url) {
2172                 data->subscr_remediation_url =
2173                         os_strdup(conf->subscr_remediation_url);
2174         }
2175         data->subscr_remediation_method = conf->subscr_remediation_method;
2176
2177         if (conf->t_c_server_url)
2178                 data->t_c_server_url = os_strdup(conf->t_c_server_url);
2179
2180 #ifdef CONFIG_SQLITE
2181         if (conf->sqlite_file) {
2182                 if (sqlite3_open(conf->sqlite_file, &data->db)) {
2183                         RADIUS_ERROR("Could not open SQLite file '%s'",
2184                                      conf->sqlite_file);
2185                         radius_server_deinit(data);
2186                         return NULL;
2187                 }
2188         }
2189 #endif /* CONFIG_SQLITE */
2190
2191 #ifdef CONFIG_RADIUS_TEST
2192         if (conf->dump_msk_file)
2193                 data->dump_msk_file = os_strdup(conf->dump_msk_file);
2194 #endif /* CONFIG_RADIUS_TEST */
2195
2196         data->clients = radius_server_read_clients(conf->client_file,
2197                                                    conf->ipv6);
2198         if (data->clients == NULL) {
2199                 wpa_printf(MSG_ERROR, "No RADIUS clients configured");
2200                 radius_server_deinit(data);
2201                 return NULL;
2202         }
2203
2204 #ifdef CONFIG_IPV6
2205         if (conf->ipv6)
2206                 data->auth_sock = radius_server_open_socket6(conf->auth_port);
2207         else
2208 #endif /* CONFIG_IPV6 */
2209         data->auth_sock = radius_server_open_socket(conf->auth_port);
2210         if (data->auth_sock < 0) {
2211                 wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS authentication server");
2212                 radius_server_deinit(data);
2213                 return NULL;
2214         }
2215         if (eloop_register_read_sock(data->auth_sock,
2216                                      radius_server_receive_auth,
2217                                      data, NULL)) {
2218                 radius_server_deinit(data);
2219                 return NULL;
2220         }
2221
2222         if (conf->acct_port) {
2223 #ifdef CONFIG_IPV6
2224                 if (conf->ipv6)
2225                         data->acct_sock = radius_server_open_socket6(
2226                                 conf->acct_port);
2227                 else
2228 #endif /* CONFIG_IPV6 */
2229                 data->acct_sock = radius_server_open_socket(conf->acct_port);
2230                 if (data->acct_sock < 0) {
2231                         wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS accounting server");
2232                         radius_server_deinit(data);
2233                         return NULL;
2234                 }
2235                 if (eloop_register_read_sock(data->acct_sock,
2236                                              radius_server_receive_acct,
2237                                              data, NULL)) {
2238                         radius_server_deinit(data);
2239                         return NULL;
2240                 }
2241         } else {
2242                 data->acct_sock = -1;
2243         }
2244
2245         return data;
2246 }
2247
2248
2249 /**
2250  * radius_server_erp_flush - Flush all ERP keys
2251  * @data: RADIUS server context from radius_server_init()
2252  */
2253 void radius_server_erp_flush(struct radius_server_data *data)
2254 {
2255         struct eap_server_erp_key *erp;
2256
2257         if (data == NULL)
2258                 return;
2259         while ((erp = dl_list_first(&data->erp_keys, struct eap_server_erp_key,
2260                                     list)) != NULL) {
2261                 dl_list_del(&erp->list);
2262                 bin_clear_free(erp, sizeof(*erp));
2263         }
2264 }
2265
2266
2267 /**
2268  * radius_server_deinit - Deinitialize RADIUS server
2269  * @data: RADIUS server context from radius_server_init()
2270  */
2271 void radius_server_deinit(struct radius_server_data *data)
2272 {
2273         if (data == NULL)
2274                 return;
2275
2276         if (data->auth_sock >= 0) {
2277                 eloop_unregister_read_sock(data->auth_sock);
2278                 close(data->auth_sock);
2279         }
2280
2281         if (data->acct_sock >= 0) {
2282                 eloop_unregister_read_sock(data->acct_sock);
2283                 close(data->acct_sock);
2284         }
2285
2286         radius_server_free_clients(data, data->clients);
2287
2288         os_free(data->pac_opaque_encr_key);
2289         os_free(data->eap_fast_a_id);
2290         os_free(data->eap_fast_a_id_info);
2291         os_free(data->eap_req_id_text);
2292 #ifdef CONFIG_RADIUS_TEST
2293         os_free(data->dump_msk_file);
2294 #endif /* CONFIG_RADIUS_TEST */
2295         os_free(data->subscr_remediation_url);
2296         os_free(data->t_c_server_url);
2297
2298 #ifdef CONFIG_SQLITE
2299         if (data->db)
2300                 sqlite3_close(data->db);
2301 #endif /* CONFIG_SQLITE */
2302
2303         radius_server_erp_flush(data);
2304
2305         os_free(data);
2306 }
2307
2308
2309 /**
2310  * radius_server_get_mib - Get RADIUS server MIB information
2311  * @data: RADIUS server context from radius_server_init()
2312  * @buf: Buffer for returning the MIB data in text format
2313  * @buflen: buf length in octets
2314  * Returns: Number of octets written into buf
2315  */
2316 int radius_server_get_mib(struct radius_server_data *data, char *buf,
2317                           size_t buflen)
2318 {
2319         int ret, uptime;
2320         unsigned int idx;
2321         char *end, *pos;
2322         struct os_reltime now;
2323         struct radius_client *cli;
2324
2325         /* RFC 2619 - RADIUS Authentication Server MIB */
2326
2327         if (data == NULL || buflen == 0)
2328                 return 0;
2329
2330         pos = buf;
2331         end = buf + buflen;
2332
2333         os_get_reltime(&now);
2334         uptime = (now.sec - data->start_time.sec) * 100 +
2335                 ((now.usec - data->start_time.usec) / 10000) % 100;
2336         ret = os_snprintf(pos, end - pos,
2337                           "RADIUS-AUTH-SERVER-MIB\n"
2338                           "radiusAuthServIdent=hostapd\n"
2339                           "radiusAuthServUpTime=%d\n"
2340                           "radiusAuthServResetTime=0\n"
2341                           "radiusAuthServConfigReset=4\n",
2342                           uptime);
2343         if (os_snprintf_error(end - pos, ret)) {
2344                 *pos = '\0';
2345                 return pos - buf;
2346         }
2347         pos += ret;
2348
2349         ret = os_snprintf(pos, end - pos,
2350                           "radiusAuthServTotalAccessRequests=%u\n"
2351                           "radiusAuthServTotalInvalidRequests=%u\n"
2352                           "radiusAuthServTotalDupAccessRequests=%u\n"
2353                           "radiusAuthServTotalAccessAccepts=%u\n"
2354                           "radiusAuthServTotalAccessRejects=%u\n"
2355                           "radiusAuthServTotalAccessChallenges=%u\n"
2356                           "radiusAuthServTotalMalformedAccessRequests=%u\n"
2357                           "radiusAuthServTotalBadAuthenticators=%u\n"
2358                           "radiusAuthServTotalPacketsDropped=%u\n"
2359                           "radiusAuthServTotalUnknownTypes=%u\n"
2360                           "radiusAccServTotalRequests=%u\n"
2361                           "radiusAccServTotalInvalidRequests=%u\n"
2362                           "radiusAccServTotalResponses=%u\n"
2363                           "radiusAccServTotalMalformedRequests=%u\n"
2364                           "radiusAccServTotalBadAuthenticators=%u\n"
2365                           "radiusAccServTotalUnknownTypes=%u\n",
2366                           data->counters.access_requests,
2367                           data->counters.invalid_requests,
2368                           data->counters.dup_access_requests,
2369                           data->counters.access_accepts,
2370                           data->counters.access_rejects,
2371                           data->counters.access_challenges,
2372                           data->counters.malformed_access_requests,
2373                           data->counters.bad_authenticators,
2374                           data->counters.packets_dropped,
2375                           data->counters.unknown_types,
2376                           data->counters.acct_requests,
2377                           data->counters.invalid_acct_requests,
2378                           data->counters.acct_responses,
2379                           data->counters.malformed_acct_requests,
2380                           data->counters.acct_bad_authenticators,
2381                           data->counters.unknown_acct_types);
2382         if (os_snprintf_error(end - pos, ret)) {
2383                 *pos = '\0';
2384                 return pos - buf;
2385         }
2386         pos += ret;
2387
2388         for (cli = data->clients, idx = 0; cli; cli = cli->next, idx++) {
2389                 char abuf[50], mbuf[50];
2390 #ifdef CONFIG_IPV6
2391                 if (data->ipv6) {
2392                         if (inet_ntop(AF_INET6, &cli->addr6, abuf,
2393                                       sizeof(abuf)) == NULL)
2394                                 abuf[0] = '\0';
2395                         if (inet_ntop(AF_INET6, &cli->mask6, mbuf,
2396                                       sizeof(mbuf)) == NULL)
2397                                 mbuf[0] = '\0';
2398                 }
2399 #endif /* CONFIG_IPV6 */
2400                 if (!data->ipv6) {
2401                         os_strlcpy(abuf, inet_ntoa(cli->addr), sizeof(abuf));
2402                         os_strlcpy(mbuf, inet_ntoa(cli->mask), sizeof(mbuf));
2403                 }
2404
2405                 ret = os_snprintf(pos, end - pos,
2406                                   "radiusAuthClientIndex=%u\n"
2407                                   "radiusAuthClientAddress=%s/%s\n"
2408                                   "radiusAuthServAccessRequests=%u\n"
2409                                   "radiusAuthServDupAccessRequests=%u\n"
2410                                   "radiusAuthServAccessAccepts=%u\n"
2411                                   "radiusAuthServAccessRejects=%u\n"
2412                                   "radiusAuthServAccessChallenges=%u\n"
2413                                   "radiusAuthServMalformedAccessRequests=%u\n"
2414                                   "radiusAuthServBadAuthenticators=%u\n"
2415                                   "radiusAuthServPacketsDropped=%u\n"
2416                                   "radiusAuthServUnknownTypes=%u\n"
2417                                   "radiusAccServTotalRequests=%u\n"
2418                                   "radiusAccServTotalInvalidRequests=%u\n"
2419                                   "radiusAccServTotalResponses=%u\n"
2420                                   "radiusAccServTotalMalformedRequests=%u\n"
2421                                   "radiusAccServTotalBadAuthenticators=%u\n"
2422                                   "radiusAccServTotalUnknownTypes=%u\n",
2423                                   idx,
2424                                   abuf, mbuf,
2425                                   cli->counters.access_requests,
2426                                   cli->counters.dup_access_requests,
2427                                   cli->counters.access_accepts,
2428                                   cli->counters.access_rejects,
2429                                   cli->counters.access_challenges,
2430                                   cli->counters.malformed_access_requests,
2431                                   cli->counters.bad_authenticators,
2432                                   cli->counters.packets_dropped,
2433                                   cli->counters.unknown_types,
2434                                   cli->counters.acct_requests,
2435                                   cli->counters.invalid_acct_requests,
2436                                   cli->counters.acct_responses,
2437                                   cli->counters.malformed_acct_requests,
2438                                   cli->counters.acct_bad_authenticators,
2439                                   cli->counters.unknown_acct_types);
2440                 if (os_snprintf_error(end - pos, ret)) {
2441                         *pos = '\0';
2442                         return pos - buf;
2443                 }
2444                 pos += ret;
2445         }
2446
2447         return pos - buf;
2448 }
2449
2450
2451 static int radius_server_get_eap_user(void *ctx, const u8 *identity,
2452                                       size_t identity_len, int phase2,
2453                                       struct eap_user *user)
2454 {
2455         struct radius_session *sess = ctx;
2456         struct radius_server_data *data = sess->server;
2457         int ret;
2458
2459         ret = data->get_eap_user(data->conf_ctx, identity, identity_len,
2460                                  phase2, user);
2461         if (ret == 0 && user) {
2462                 sess->accept_attr = user->accept_attr;
2463                 sess->remediation = user->remediation;
2464                 sess->macacl = user->macacl;
2465                 sess->t_c_timestamp = user->t_c_timestamp;
2466         }
2467
2468         if (ret) {
2469                 RADIUS_DEBUG("%s: User-Name not found from user database",
2470                              __func__);
2471         }
2472
2473         return ret;
2474 }
2475
2476
2477 static const char * radius_server_get_eap_req_id_text(void *ctx, size_t *len)
2478 {
2479         struct radius_session *sess = ctx;
2480         struct radius_server_data *data = sess->server;
2481         *len = data->eap_req_id_text_len;
2482         return data->eap_req_id_text;
2483 }
2484
2485
2486 static void radius_server_log_msg(void *ctx, const char *msg)
2487 {
2488         struct radius_session *sess = ctx;
2489         srv_log(sess, "EAP: %s", msg);
2490 }
2491
2492
2493 #ifdef CONFIG_ERP
2494
2495 static const char * radius_server_get_erp_domain(void *ctx)
2496 {
2497         struct radius_session *sess = ctx;
2498         struct radius_server_data *data = sess->server;
2499
2500         return data->erp_domain;
2501 }
2502
2503
2504 static struct eap_server_erp_key *
2505 radius_server_erp_get_key(void *ctx, const char *keyname)
2506 {
2507         struct radius_session *sess = ctx;
2508         struct radius_server_data *data = sess->server;
2509         struct eap_server_erp_key *erp;
2510
2511         dl_list_for_each(erp, &data->erp_keys, struct eap_server_erp_key,
2512                          list) {
2513                 if (os_strcmp(erp->keyname_nai, keyname) == 0)
2514                         return erp;
2515         }
2516
2517         return NULL;
2518 }
2519
2520
2521 static int radius_server_erp_add_key(void *ctx, struct eap_server_erp_key *erp)
2522 {
2523         struct radius_session *sess = ctx;
2524         struct radius_server_data *data = sess->server;
2525
2526         dl_list_add(&data->erp_keys, &erp->list);
2527         return 0;
2528 }
2529
2530 #endif /* CONFIG_ERP */
2531
2532
2533 static const struct eapol_callbacks radius_server_eapol_cb =
2534 {
2535         .get_eap_user = radius_server_get_eap_user,
2536         .get_eap_req_id_text = radius_server_get_eap_req_id_text,
2537         .log_msg = radius_server_log_msg,
2538 #ifdef CONFIG_ERP
2539         .get_erp_send_reauth_start = NULL,
2540         .get_erp_domain = radius_server_get_erp_domain,
2541         .erp_get_key = radius_server_erp_get_key,
2542         .erp_add_key = radius_server_erp_add_key,
2543 #endif /* CONFIG_ERP */
2544 };
2545
2546
2547 /**
2548  * radius_server_eap_pending_cb - Pending EAP data notification
2549  * @data: RADIUS server context from radius_server_init()
2550  * @ctx: Pending EAP context pointer
2551  *
2552  * This function is used to notify EAP server module that a pending operation
2553  * has been completed and processing of the EAP session can proceed.
2554  */
2555 void radius_server_eap_pending_cb(struct radius_server_data *data, void *ctx)
2556 {
2557         struct radius_client *cli;
2558         struct radius_session *s, *sess = NULL;
2559         struct radius_msg *msg;
2560
2561         if (data == NULL)
2562                 return;
2563
2564         for (cli = data->clients; cli; cli = cli->next) {
2565                 for (s = cli->sessions; s; s = s->next) {
2566                         if (s->eap == ctx && s->last_msg) {
2567                                 sess = s;
2568                                 break;
2569                         }
2570                 }
2571                 if (sess)
2572                         break;
2573         }
2574
2575         if (sess == NULL) {
2576                 RADIUS_DEBUG("No session matched callback ctx");
2577                 return;
2578         }
2579
2580         msg = sess->last_msg;
2581         sess->last_msg = NULL;
2582         eap_sm_pending_cb(sess->eap);
2583         if (radius_server_request(data, msg,
2584                                   (struct sockaddr *) &sess->last_from,
2585                                   sess->last_fromlen, cli,
2586                                   sess->last_from_addr,
2587                                   sess->last_from_port, sess) == -2)
2588                 return; /* msg was stored with the session */
2589
2590         radius_msg_free(msg);
2591 }
2592
2593
2594 #ifdef CONFIG_SQLITE
2595
2596 struct db_session_fields {
2597         char *identity;
2598         char *nas;
2599         int hs20_t_c_filtering;
2600         int waiting_coa_ack;
2601         int coa_ack_received;
2602 };
2603
2604
2605 static int get_db_session_fields(void *ctx, int argc, char *argv[], char *col[])
2606 {
2607         struct db_session_fields *fields = ctx;
2608         int i;
2609
2610         for (i = 0; i < argc; i++) {
2611                 if (!argv[i])
2612                         continue;
2613
2614                 RADIUS_DEBUG("Session DB: %s=%s", col[i], argv[i]);
2615
2616                 if (os_strcmp(col[i], "identity") == 0) {
2617                         os_free(fields->identity);
2618                         fields->identity = os_strdup(argv[i]);
2619                 } else if (os_strcmp(col[i], "nas") == 0) {
2620                         os_free(fields->nas);
2621                         fields->nas = os_strdup(argv[i]);
2622                 } else if (os_strcmp(col[i], "hs20_t_c_filtering") == 0) {
2623                         fields->hs20_t_c_filtering = atoi(argv[i]);
2624                 } else if (os_strcmp(col[i], "waiting_coa_ack") == 0) {
2625                         fields->waiting_coa_ack = atoi(argv[i]);
2626                 } else if (os_strcmp(col[i], "coa_ack_received") == 0) {
2627                         fields->coa_ack_received = atoi(argv[i]);
2628                 }
2629         }
2630
2631         return 0;
2632 }
2633
2634
2635 static void free_db_session_fields(struct db_session_fields *fields)
2636 {
2637         os_free(fields->identity);
2638         fields->identity = NULL;
2639         os_free(fields->nas);
2640         fields->nas = NULL;
2641 }
2642
2643 #endif /* CONFIG_SQLITE */
2644
2645
2646 int radius_server_dac_request(struct radius_server_data *data, const char *req)
2647 {
2648 #ifdef CONFIG_SQLITE
2649         char *sql;
2650         int res;
2651         int disconnect;
2652         const char *pos = req;
2653         u8 addr[ETH_ALEN];
2654         char addrtxt[3 * ETH_ALEN];
2655         int t_c_clear = 0;
2656         struct db_session_fields fields;
2657         struct sockaddr_in das;
2658         struct radius_client *client;
2659         struct radius_msg *msg;
2660         struct wpabuf *buf;
2661         u8 identifier;
2662         struct os_time now;
2663
2664         if (!data)
2665                 return -1;
2666
2667         /* req: <disconnect|coa> <MAC Address> [t_c_clear] */
2668
2669         if (os_strncmp(pos, "disconnect ", 11) == 0) {
2670                 disconnect = 1;
2671                 pos += 11;
2672         } else if (os_strncmp(req, "coa ", 4) == 0) {
2673                 disconnect = 0;
2674                 pos += 4;
2675         } else {
2676                 return -1;
2677         }
2678
2679         if (hwaddr_aton(pos, addr))
2680                 return -1;
2681         pos = os_strchr(pos, ' ');
2682         if (pos) {
2683                 if (os_strstr(pos, "t_c_clear"))
2684                         t_c_clear = 1;
2685         }
2686
2687         if (!disconnect && !t_c_clear) {
2688                 RADIUS_ERROR("DAC request for CoA without any authorization change");
2689                 return -1;
2690         }
2691
2692         if (!data->db) {
2693                 RADIUS_ERROR("SQLite database not in use");
2694                 return -1;
2695         }
2696
2697         os_snprintf(addrtxt, sizeof(addrtxt), MACSTR, MAC2STR(addr));
2698
2699         sql = sqlite3_mprintf("SELECT * FROM current_sessions WHERE mac_addr=%Q",
2700                               addrtxt);
2701         if (!sql)
2702                 return -1;
2703
2704         os_memset(&fields, 0, sizeof(fields));
2705         res = sqlite3_exec(data->db, sql, get_db_session_fields, &fields, NULL);
2706         sqlite3_free(sql);
2707         if (res != SQLITE_OK) {
2708                 RADIUS_ERROR("Failed to find matching current_sessions entry from sqlite database: %s",
2709                              sqlite3_errmsg(data->db));
2710                 free_db_session_fields(&fields);
2711                 return -1;
2712         }
2713
2714         if (!fields.nas) {
2715                 RADIUS_ERROR("No NAS information found from current_sessions");
2716                 free_db_session_fields(&fields);
2717                 return -1;
2718         }
2719
2720         os_memset(&das, 0, sizeof(das));
2721         das.sin_family = AF_INET;
2722         das.sin_addr.s_addr = inet_addr(fields.nas);
2723         das.sin_port = htons(3799);
2724
2725         free_db_session_fields(&fields);
2726
2727         client = radius_server_get_client(data, &das.sin_addr, 0);
2728         if (!client) {
2729                 RADIUS_ERROR("No NAS information available to protect the packet");
2730                 return -1;
2731         }
2732
2733         identifier = client->next_dac_identifier++;
2734
2735         msg = radius_msg_new(disconnect ? RADIUS_CODE_DISCONNECT_REQUEST :
2736                              RADIUS_CODE_COA_REQUEST, identifier);
2737         if (!msg)
2738                 return -1;
2739
2740         os_snprintf(addrtxt, sizeof(addrtxt), RADIUS_802_1X_ADDR_FORMAT,
2741                     MAC2STR(addr));
2742         if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID,
2743                                  (u8 *) addrtxt, os_strlen(addrtxt))) {
2744                 RADIUS_ERROR("Could not add Calling-Station-Id");
2745                 radius_msg_free(msg);
2746                 return -1;
2747         }
2748
2749         if (!disconnect && t_c_clear) {
2750                 u8 val[4] = { 0x00, 0x00, 0x00, 0x00 }; /* E=0 */
2751
2752                 if (!radius_msg_add_wfa(
2753                             msg, RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILTERING,
2754                             val, sizeof(val))) {
2755                         RADIUS_DEBUG("Failed to add WFA-HS20-T-C-Filtering");
2756                         radius_msg_free(msg);
2757                         return -1;
2758                 }
2759         }
2760
2761         os_get_time(&now);
2762         if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_EVENT_TIMESTAMP,
2763                                        now.sec)) {
2764                 RADIUS_ERROR("Failed to add Event-Timestamp attribute");
2765                 radius_msg_free(msg);
2766                 return -1;
2767         }
2768
2769         radius_msg_finish_acct(msg, (u8 *) client->shared_secret,
2770                                client->shared_secret_len);
2771
2772         if (wpa_debug_level <= MSG_MSGDUMP)
2773                 radius_msg_dump(msg);
2774
2775         buf = radius_msg_get_buf(msg);
2776         if (sendto(data->auth_sock, wpabuf_head(buf), wpabuf_len(buf), 0,
2777                    (struct sockaddr *) &das, sizeof(das)) < 0) {
2778                 RADIUS_ERROR("Failed to send packet - sendto: %s",
2779                              strerror(errno));
2780                 radius_msg_free(msg);
2781                 return -1;
2782         }
2783
2784         if (disconnect) {
2785                 radius_msg_free(client->pending_dac_disconnect_req);
2786                 client->pending_dac_disconnect_req = msg;
2787                 client->pending_dac_disconnect_id = identifier;
2788                 os_memcpy(client->pending_dac_disconnect_addr, addr, ETH_ALEN);
2789         } else {
2790                 radius_msg_free(client->pending_dac_coa_req);
2791                 client->pending_dac_coa_req = msg;
2792                 client->pending_dac_coa_id = identifier;
2793                 os_memcpy(client->pending_dac_coa_addr, addr, ETH_ALEN);
2794         }
2795
2796         return 0;
2797 #else /* CONFIG_SQLITE */
2798         return -1;
2799 #endif /* CONFIG_SQLITE */
2800 }