RADIUS server: Allow EAP methods to log into SQLite DB
[mech_eap.git] / 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 "radius_server.h"
21
22 /**
23  * RADIUS_SESSION_TIMEOUT - Session timeout in seconds
24  */
25 #define RADIUS_SESSION_TIMEOUT 60
26
27 /**
28  * RADIUS_MAX_SESSION - Maximum number of active sessions
29  */
30 #define RADIUS_MAX_SESSION 100
31
32 /**
33  * RADIUS_MAX_MSG_LEN - Maximum message length for incoming RADIUS messages
34  */
35 #define RADIUS_MAX_MSG_LEN 3000
36
37 static struct eapol_callbacks radius_server_eapol_cb;
38
39 struct radius_client;
40 struct radius_server_data;
41
42 /**
43  * struct radius_server_counters - RADIUS server statistics counters
44  */
45 struct radius_server_counters {
46         u32 access_requests;
47         u32 invalid_requests;
48         u32 dup_access_requests;
49         u32 access_accepts;
50         u32 access_rejects;
51         u32 access_challenges;
52         u32 malformed_access_requests;
53         u32 bad_authenticators;
54         u32 packets_dropped;
55         u32 unknown_types;
56
57         u32 acct_requests;
58         u32 invalid_acct_requests;
59         u32 acct_responses;
60         u32 malformed_acct_requests;
61         u32 acct_bad_authenticators;
62         u32 unknown_acct_types;
63 };
64
65 /**
66  * struct radius_session - Internal RADIUS server data for a session
67  */
68 struct radius_session {
69         struct radius_session *next;
70         struct radius_client *client;
71         struct radius_server_data *server;
72         unsigned int sess_id;
73         struct eap_sm *eap;
74         struct eap_eapol_interface *eap_if;
75         char *username; /* from User-Name attribute */
76         char *nas_ip;
77
78         struct radius_msg *last_msg;
79         char *last_from_addr;
80         int last_from_port;
81         struct sockaddr_storage last_from;
82         socklen_t last_fromlen;
83         u8 last_identifier;
84         struct radius_msg *last_reply;
85         u8 last_authenticator[16];
86
87         unsigned int remediation:1;
88
89         struct hostapd_radius_attr *accept_attr;
90 };
91
92 /**
93  * struct radius_client - Internal RADIUS server data for a client
94  */
95 struct radius_client {
96         struct radius_client *next;
97         struct in_addr addr;
98         struct in_addr mask;
99 #ifdef CONFIG_IPV6
100         struct in6_addr addr6;
101         struct in6_addr mask6;
102 #endif /* CONFIG_IPV6 */
103         char *shared_secret;
104         int shared_secret_len;
105         struct radius_session *sessions;
106         struct radius_server_counters counters;
107 };
108
109 /**
110  * struct radius_server_data - Internal RADIUS server data
111  */
112 struct radius_server_data {
113         /**
114          * auth_sock - Socket for RADIUS authentication messages
115          */
116         int auth_sock;
117
118         /**
119          * acct_sock - Socket for RADIUS accounting messages
120          */
121         int acct_sock;
122
123         /**
124          * clients - List of authorized RADIUS clients
125          */
126         struct radius_client *clients;
127
128         /**
129          * next_sess_id - Next session identifier
130          */
131         unsigned int next_sess_id;
132
133         /**
134          * conf_ctx - Context pointer for callbacks
135          *
136          * This is used as the ctx argument in get_eap_user() calls.
137          */
138         void *conf_ctx;
139
140         /**
141          * num_sess - Number of active sessions
142          */
143         int num_sess;
144
145         /**
146          * eap_sim_db_priv - EAP-SIM/AKA database context
147          *
148          * This is passed to the EAP-SIM/AKA server implementation as a
149          * callback context.
150          */
151         void *eap_sim_db_priv;
152
153         /**
154          * ssl_ctx - TLS context
155          *
156          * This is passed to the EAP server implementation as a callback
157          * context for TLS operations.
158          */
159         void *ssl_ctx;
160
161         /**
162          * pac_opaque_encr_key - PAC-Opaque encryption key for EAP-FAST
163          *
164          * This parameter is used to set a key for EAP-FAST to encrypt the
165          * PAC-Opaque data. It can be set to %NULL if EAP-FAST is not used. If
166          * set, must point to a 16-octet key.
167          */
168         u8 *pac_opaque_encr_key;
169
170         /**
171          * eap_fast_a_id - EAP-FAST authority identity (A-ID)
172          *
173          * If EAP-FAST is not used, this can be set to %NULL. In theory, this
174          * is a variable length field, but due to some existing implementations
175          * requiring A-ID to be 16 octets in length, it is recommended to use
176          * that length for the field to provide interoperability with deployed
177          * peer implementations.
178          */
179         u8 *eap_fast_a_id;
180
181         /**
182          * eap_fast_a_id_len - Length of eap_fast_a_id buffer in octets
183          */
184         size_t eap_fast_a_id_len;
185
186         /**
187          * eap_fast_a_id_info - EAP-FAST authority identifier information
188          *
189          * This A-ID-Info contains a user-friendly name for the A-ID. For
190          * example, this could be the enterprise and server names in
191          * human-readable format. This field is encoded as UTF-8. If EAP-FAST
192          * is not used, this can be set to %NULL.
193          */
194         char *eap_fast_a_id_info;
195
196         /**
197          * eap_fast_prov - EAP-FAST provisioning modes
198          *
199          * 0 = provisioning disabled, 1 = only anonymous provisioning allowed,
200          * 2 = only authenticated provisioning allowed, 3 = both provisioning
201          * modes allowed.
202          */
203         int eap_fast_prov;
204
205         /**
206          * pac_key_lifetime - EAP-FAST PAC-Key lifetime in seconds
207          *
208          * This is the hard limit on how long a provisioned PAC-Key can be
209          * used.
210          */
211         int pac_key_lifetime;
212
213         /**
214          * pac_key_refresh_time - EAP-FAST PAC-Key refresh time in seconds
215          *
216          * This is a soft limit on the PAC-Key. The server will automatically
217          * generate a new PAC-Key when this number of seconds (or fewer) of the
218          * lifetime remains.
219          */
220         int pac_key_refresh_time;
221
222         /**
223          * eap_sim_aka_result_ind - EAP-SIM/AKA protected success indication
224          *
225          * This controls whether the protected success/failure indication
226          * (AT_RESULT_IND) is used with EAP-SIM and EAP-AKA.
227          */
228         int eap_sim_aka_result_ind;
229
230         /**
231          * tnc - Trusted Network Connect (TNC)
232          *
233          * This controls whether TNC is enabled and will be required before the
234          * peer is allowed to connect. Note: This is only used with EAP-TTLS
235          * and EAP-FAST. If any other EAP method is enabled, the peer will be
236          * allowed to connect without TNC.
237          */
238         int tnc;
239
240         /**
241          * pwd_group - The D-H group assigned for EAP-pwd
242          *
243          * If EAP-pwd is not used it can be set to zero.
244          */
245         u16 pwd_group;
246
247         /**
248          * server_id - Server identity
249          */
250         const char *server_id;
251
252         /**
253          * wps - Wi-Fi Protected Setup context
254          *
255          * If WPS is used with an external RADIUS server (which is quite
256          * unlikely configuration), this is used to provide a pointer to WPS
257          * context data. Normally, this can be set to %NULL.
258          */
259         struct wps_context *wps;
260
261         /**
262          * ipv6 - Whether to enable IPv6 support in the RADIUS server
263          */
264         int ipv6;
265
266         /**
267          * start_time - Timestamp of server start
268          */
269         struct os_reltime start_time;
270
271         /**
272          * counters - Statistics counters for server operations
273          *
274          * These counters are the sum over all clients.
275          */
276         struct radius_server_counters counters;
277
278         /**
279          * get_eap_user - Callback for fetching EAP user information
280          * @ctx: Context data from conf_ctx
281          * @identity: User identity
282          * @identity_len: identity buffer length in octets
283          * @phase2: Whether this is for Phase 2 identity
284          * @user: Data structure for filling in the user information
285          * Returns: 0 on success, -1 on failure
286          *
287          * This is used to fetch information from user database. The callback
288          * will fill in information about allowed EAP methods and the user
289          * password. The password field will be an allocated copy of the
290          * password data and RADIUS server will free it after use.
291          */
292         int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
293                             int phase2, struct eap_user *user);
294
295         /**
296          * eap_req_id_text - Optional data for EAP-Request/Identity
297          *
298          * This can be used to configure an optional, displayable message that
299          * will be sent in EAP-Request/Identity. This string can contain an
300          * ASCII-0 character (nul) to separate network infromation per RFC
301          * 4284. The actual string length is explicit provided in
302          * eap_req_id_text_len since nul character will not be used as a string
303          * terminator.
304          */
305         char *eap_req_id_text;
306
307         /**
308          * eap_req_id_text_len - Length of eap_req_id_text buffer in octets
309          */
310         size_t eap_req_id_text_len;
311
312         /*
313          * msg_ctx - Context data for wpa_msg() calls
314          */
315         void *msg_ctx;
316
317 #ifdef CONFIG_RADIUS_TEST
318         char *dump_msk_file;
319 #endif /* CONFIG_RADIUS_TEST */
320
321         char *subscr_remediation_url;
322         u8 subscr_remediation_method;
323
324 #ifdef CONFIG_SQLITE
325         sqlite3 *db;
326 #endif /* CONFIG_SQLITE */
327 };
328
329
330 #define RADIUS_DEBUG(args...) \
331 wpa_printf(MSG_DEBUG, "RADIUS SRV: " args)
332 #define RADIUS_ERROR(args...) \
333 wpa_printf(MSG_ERROR, "RADIUS SRV: " args)
334 #define RADIUS_DUMP(args...) \
335 wpa_hexdump(MSG_MSGDUMP, "RADIUS SRV: " args)
336 #define RADIUS_DUMP_ASCII(args...) \
337 wpa_hexdump_ascii(MSG_MSGDUMP, "RADIUS SRV: " args)
338
339
340 static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx);
341 static void radius_server_session_remove_timeout(void *eloop_ctx,
342                                                  void *timeout_ctx);
343
344 void srv_log(struct radius_session *sess, const char *fmt, ...)
345 PRINTF_FORMAT(2, 3);
346
347 void srv_log(struct radius_session *sess, const char *fmt, ...)
348 {
349         va_list ap;
350         char *buf;
351         int buflen;
352
353         va_start(ap, fmt);
354         buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
355         va_end(ap);
356
357         buf = os_malloc(buflen);
358         if (buf == NULL)
359                 return;
360         va_start(ap, fmt);
361         vsnprintf(buf, buflen, fmt, ap);
362         va_end(ap);
363
364         RADIUS_DEBUG("[0x%x %s] %s", sess->sess_id, sess->nas_ip, buf);
365
366 #ifdef CONFIG_SQLITE
367         if (sess->server->db) {
368                 char *sql;
369                 sql = sqlite3_mprintf("INSERT INTO authlog"
370                                       "(timestamp,session,nas_ip,username,note)"
371                                       " VALUES ("
372                                       "strftime('%%Y-%%m-%%d %%H:%%M:%%f',"
373                                       "'now'),%u,%Q,%Q,%Q)",
374                                       sess->sess_id, sess->nas_ip,
375                                       sess->username, buf);
376                 if (sql) {
377                         if (sqlite3_exec(sess->server->db, sql, NULL, NULL,
378                                          NULL) != SQLITE_OK) {
379                                 RADIUS_ERROR("Failed to add authlog entry into sqlite database: %s",
380                                              sqlite3_errmsg(sess->server->db));
381                         }
382                         sqlite3_free(sql);
383                 }
384         }
385 #endif /* CONFIG_SQLITE */
386
387         os_free(buf);
388 }
389
390
391 static struct radius_client *
392 radius_server_get_client(struct radius_server_data *data, struct in_addr *addr,
393                          int ipv6)
394 {
395         struct radius_client *client = data->clients;
396
397         while (client) {
398 #ifdef CONFIG_IPV6
399                 if (ipv6) {
400                         struct in6_addr *addr6;
401                         int i;
402
403                         addr6 = (struct in6_addr *) addr;
404                         for (i = 0; i < 16; i++) {
405                                 if ((addr6->s6_addr[i] &
406                                      client->mask6.s6_addr[i]) !=
407                                     (client->addr6.s6_addr[i] &
408                                      client->mask6.s6_addr[i])) {
409                                         i = 17;
410                                         break;
411                                 }
412                         }
413                         if (i == 16) {
414                                 break;
415                         }
416                 }
417 #endif /* CONFIG_IPV6 */
418                 if (!ipv6 && (client->addr.s_addr & client->mask.s_addr) ==
419                     (addr->s_addr & client->mask.s_addr)) {
420                         break;
421                 }
422
423                 client = client->next;
424         }
425
426         return client;
427 }
428
429
430 static struct radius_session *
431 radius_server_get_session(struct radius_client *client, unsigned int sess_id)
432 {
433         struct radius_session *sess = client->sessions;
434
435         while (sess) {
436                 if (sess->sess_id == sess_id) {
437                         break;
438                 }
439                 sess = sess->next;
440         }
441
442         return sess;
443 }
444
445
446 static void radius_server_session_free(struct radius_server_data *data,
447                                        struct radius_session *sess)
448 {
449         eloop_cancel_timeout(radius_server_session_timeout, data, sess);
450         eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess);
451         eap_server_sm_deinit(sess->eap);
452         radius_msg_free(sess->last_msg);
453         os_free(sess->last_from_addr);
454         radius_msg_free(sess->last_reply);
455         os_free(sess->username);
456         os_free(sess->nas_ip);
457         os_free(sess);
458         data->num_sess--;
459 }
460
461
462 static void radius_server_session_remove(struct radius_server_data *data,
463                                          struct radius_session *sess)
464 {
465         struct radius_client *client = sess->client;
466         struct radius_session *session, *prev;
467
468         eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess);
469
470         prev = NULL;
471         session = client->sessions;
472         while (session) {
473                 if (session == sess) {
474                         if (prev == NULL) {
475                                 client->sessions = sess->next;
476                         } else {
477                                 prev->next = sess->next;
478                         }
479                         radius_server_session_free(data, sess);
480                         break;
481                 }
482                 prev = session;
483                 session = session->next;
484         }
485 }
486
487
488 static void radius_server_session_remove_timeout(void *eloop_ctx,
489                                                  void *timeout_ctx)
490 {
491         struct radius_server_data *data = eloop_ctx;
492         struct radius_session *sess = timeout_ctx;
493         RADIUS_DEBUG("Removing completed session 0x%x", sess->sess_id);
494         radius_server_session_remove(data, sess);
495 }
496
497
498 static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx)
499 {
500         struct radius_server_data *data = eloop_ctx;
501         struct radius_session *sess = timeout_ctx;
502
503         RADIUS_DEBUG("Timing out authentication session 0x%x", sess->sess_id);
504         radius_server_session_remove(data, sess);
505 }
506
507
508 static struct radius_session *
509 radius_server_new_session(struct radius_server_data *data,
510                           struct radius_client *client)
511 {
512         struct radius_session *sess;
513
514         if (data->num_sess >= RADIUS_MAX_SESSION) {
515                 RADIUS_DEBUG("Maximum number of existing session - no room "
516                              "for a new session");
517                 return NULL;
518         }
519
520         sess = os_zalloc(sizeof(*sess));
521         if (sess == NULL)
522                 return NULL;
523
524         sess->server = data;
525         sess->client = client;
526         sess->sess_id = data->next_sess_id++;
527         sess->next = client->sessions;
528         client->sessions = sess;
529         eloop_register_timeout(RADIUS_SESSION_TIMEOUT, 0,
530                                radius_server_session_timeout, data, sess);
531         data->num_sess++;
532         return sess;
533 }
534
535
536 static struct radius_session *
537 radius_server_get_new_session(struct radius_server_data *data,
538                               struct radius_client *client,
539                               struct radius_msg *msg, const char *from_addr)
540 {
541         u8 *user;
542         size_t user_len;
543         int res;
544         struct radius_session *sess;
545         struct eap_config eap_conf;
546         struct eap_user tmp;
547
548         RADIUS_DEBUG("Creating a new session");
549
550         if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &user,
551                                     &user_len, NULL) < 0) {
552                 RADIUS_DEBUG("Could not get User-Name");
553                 return NULL;
554         }
555         RADIUS_DUMP_ASCII("User-Name", user, user_len);
556
557         os_memset(&tmp, 0, sizeof(tmp));
558         res = data->get_eap_user(data->conf_ctx, user, user_len, 0, &tmp);
559         os_free(tmp.password);
560
561         if (res != 0) {
562                 RADIUS_DEBUG("User-Name not found from user database");
563                 return NULL;
564         }
565
566         RADIUS_DEBUG("Matching user entry found");
567         sess = radius_server_new_session(data, client);
568         if (sess == NULL) {
569                 RADIUS_DEBUG("Failed to create a new session");
570                 return NULL;
571         }
572         sess->accept_attr = tmp.accept_attr;
573
574         sess->username = os_malloc(user_len * 2 + 1);
575         if (sess->username == NULL) {
576                 radius_server_session_free(data, sess);
577                 return NULL;
578         }
579         printf_encode(sess->username, user_len * 2 + 1, user, user_len);
580
581         sess->nas_ip = os_strdup(from_addr);
582         if (sess->nas_ip == NULL) {
583                 radius_server_session_free(data, sess);
584                 return NULL;
585         }
586
587         srv_log(sess, "New session created");
588
589         os_memset(&eap_conf, 0, sizeof(eap_conf));
590         eap_conf.ssl_ctx = data->ssl_ctx;
591         eap_conf.msg_ctx = data->msg_ctx;
592         eap_conf.eap_sim_db_priv = data->eap_sim_db_priv;
593         eap_conf.backend_auth = TRUE;
594         eap_conf.eap_server = 1;
595         eap_conf.pac_opaque_encr_key = data->pac_opaque_encr_key;
596         eap_conf.eap_fast_a_id = data->eap_fast_a_id;
597         eap_conf.eap_fast_a_id_len = data->eap_fast_a_id_len;
598         eap_conf.eap_fast_a_id_info = data->eap_fast_a_id_info;
599         eap_conf.eap_fast_prov = data->eap_fast_prov;
600         eap_conf.pac_key_lifetime = data->pac_key_lifetime;
601         eap_conf.pac_key_refresh_time = data->pac_key_refresh_time;
602         eap_conf.eap_sim_aka_result_ind = data->eap_sim_aka_result_ind;
603         eap_conf.tnc = data->tnc;
604         eap_conf.wps = data->wps;
605         eap_conf.pwd_group = data->pwd_group;
606         eap_conf.server_id = (const u8 *) data->server_id;
607         eap_conf.server_id_len = os_strlen(data->server_id);
608         sess->eap = eap_server_sm_init(sess, &radius_server_eapol_cb,
609                                        &eap_conf);
610         if (sess->eap == NULL) {
611                 RADIUS_DEBUG("Failed to initialize EAP state machine for the "
612                              "new session");
613                 radius_server_session_free(data, sess);
614                 return NULL;
615         }
616         sess->eap_if = eap_get_interface(sess->eap);
617         sess->eap_if->eapRestart = TRUE;
618         sess->eap_if->portEnabled = TRUE;
619
620         RADIUS_DEBUG("New session 0x%x initialized", sess->sess_id);
621
622         return sess;
623 }
624
625
626 static struct radius_msg *
627 radius_server_encapsulate_eap(struct radius_server_data *data,
628                               struct radius_client *client,
629                               struct radius_session *sess,
630                               struct radius_msg *request)
631 {
632         struct radius_msg *msg;
633         int code;
634         unsigned int sess_id;
635         struct radius_hdr *hdr = radius_msg_get_hdr(request);
636
637         if (sess->eap_if->eapFail) {
638                 sess->eap_if->eapFail = FALSE;
639                 code = RADIUS_CODE_ACCESS_REJECT;
640         } else if (sess->eap_if->eapSuccess) {
641                 sess->eap_if->eapSuccess = FALSE;
642                 code = RADIUS_CODE_ACCESS_ACCEPT;
643         } else {
644                 sess->eap_if->eapReq = FALSE;
645                 code = RADIUS_CODE_ACCESS_CHALLENGE;
646         }
647
648         msg = radius_msg_new(code, hdr->identifier);
649         if (msg == NULL) {
650                 RADIUS_DEBUG("Failed to allocate reply message");
651                 return NULL;
652         }
653
654         sess_id = htonl(sess->sess_id);
655         if (code == RADIUS_CODE_ACCESS_CHALLENGE &&
656             !radius_msg_add_attr(msg, RADIUS_ATTR_STATE,
657                                  (u8 *) &sess_id, sizeof(sess_id))) {
658                 RADIUS_DEBUG("Failed to add State attribute");
659         }
660
661         if (sess->eap_if->eapReqData &&
662             !radius_msg_add_eap(msg, wpabuf_head(sess->eap_if->eapReqData),
663                                 wpabuf_len(sess->eap_if->eapReqData))) {
664                 RADIUS_DEBUG("Failed to add EAP-Message attribute");
665         }
666
667         if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->eap_if->eapKeyData) {
668                 int len;
669 #ifdef CONFIG_RADIUS_TEST
670                 if (data->dump_msk_file) {
671                         FILE *f;
672                         char buf[2 * 64 + 1];
673                         f = fopen(data->dump_msk_file, "a");
674                         if (f) {
675                                 len = sess->eap_if->eapKeyDataLen;
676                                 if (len > 64)
677                                         len = 64;
678                                 len = wpa_snprintf_hex(
679                                         buf, sizeof(buf),
680                                         sess->eap_if->eapKeyData, len);
681                                 buf[len] = '\0';
682                                 fprintf(f, "%s\n", buf);
683                                 fclose(f);
684                         }
685                 }
686 #endif /* CONFIG_RADIUS_TEST */
687                 if (sess->eap_if->eapKeyDataLen > 64) {
688                         len = 32;
689                 } else {
690                         len = sess->eap_if->eapKeyDataLen / 2;
691                 }
692                 if (!radius_msg_add_mppe_keys(msg, hdr->authenticator,
693                                               (u8 *) client->shared_secret,
694                                               client->shared_secret_len,
695                                               sess->eap_if->eapKeyData + len,
696                                               len, sess->eap_if->eapKeyData,
697                                               len)) {
698                         RADIUS_DEBUG("Failed to add MPPE key attributes");
699                 }
700         }
701
702 #ifdef CONFIG_HS20
703         if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->remediation &&
704             data->subscr_remediation_url) {
705                 u8 *buf;
706                 size_t url_len = os_strlen(data->subscr_remediation_url);
707                 buf = os_malloc(1 + url_len);
708                 if (buf == NULL) {
709                         radius_msg_free(msg);
710                         return NULL;
711                 }
712                 buf[0] = data->subscr_remediation_method;
713                 os_memcpy(&buf[1], data->subscr_remediation_url, url_len);
714                 if (!radius_msg_add_wfa(
715                             msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION,
716                             buf, 1 + url_len)) {
717                         RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem");
718                 }
719                 os_free(buf);
720         } else if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->remediation) {
721                 u8 buf[1];
722                 if (!radius_msg_add_wfa(
723                             msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION,
724                             buf, 0)) {
725                         RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem");
726                 }
727         }
728 #endif /* CONFIG_HS20 */
729
730         if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
731                 RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
732                 radius_msg_free(msg);
733                 return NULL;
734         }
735
736         if (code == RADIUS_CODE_ACCESS_ACCEPT) {
737                 struct hostapd_radius_attr *attr;
738                 for (attr = sess->accept_attr; attr; attr = attr->next) {
739                         if (!radius_msg_add_attr(msg, attr->type,
740                                                  wpabuf_head(attr->val),
741                                                  wpabuf_len(attr->val))) {
742                                 wpa_printf(MSG_ERROR, "Could not add RADIUS attribute");
743                                 radius_msg_free(msg);
744                                 return NULL;
745                         }
746                 }
747         }
748
749         if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
750                                   client->shared_secret_len,
751                                   hdr->authenticator) < 0) {
752                 RADIUS_DEBUG("Failed to add Message-Authenticator attribute");
753         }
754
755         return msg;
756 }
757
758
759 static int radius_server_reject(struct radius_server_data *data,
760                                 struct radius_client *client,
761                                 struct radius_msg *request,
762                                 struct sockaddr *from, socklen_t fromlen,
763                                 const char *from_addr, int from_port)
764 {
765         struct radius_msg *msg;
766         int ret = 0;
767         struct eap_hdr eapfail;
768         struct wpabuf *buf;
769         struct radius_hdr *hdr = radius_msg_get_hdr(request);
770
771         RADIUS_DEBUG("Reject invalid request from %s:%d",
772                      from_addr, from_port);
773
774         msg = radius_msg_new(RADIUS_CODE_ACCESS_REJECT, hdr->identifier);
775         if (msg == NULL) {
776                 return -1;
777         }
778
779         os_memset(&eapfail, 0, sizeof(eapfail));
780         eapfail.code = EAP_CODE_FAILURE;
781         eapfail.identifier = 0;
782         eapfail.length = host_to_be16(sizeof(eapfail));
783
784         if (!radius_msg_add_eap(msg, (u8 *) &eapfail, sizeof(eapfail))) {
785                 RADIUS_DEBUG("Failed to add EAP-Message attribute");
786         }
787
788         if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
789                 RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
790                 radius_msg_free(msg);
791                 return -1;
792         }
793
794         if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
795                                   client->shared_secret_len,
796                                   hdr->authenticator) <
797             0) {
798                 RADIUS_DEBUG("Failed to add Message-Authenticator attribute");
799         }
800
801         if (wpa_debug_level <= MSG_MSGDUMP) {
802                 radius_msg_dump(msg);
803         }
804
805         data->counters.access_rejects++;
806         client->counters.access_rejects++;
807         buf = radius_msg_get_buf(msg);
808         if (sendto(data->auth_sock, wpabuf_head(buf), wpabuf_len(buf), 0,
809                    (struct sockaddr *) from, sizeof(*from)) < 0) {
810                 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", strerror(errno));
811                 ret = -1;
812         }
813
814         radius_msg_free(msg);
815
816         return ret;
817 }
818
819
820 static int radius_server_request(struct radius_server_data *data,
821                                  struct radius_msg *msg,
822                                  struct sockaddr *from, socklen_t fromlen,
823                                  struct radius_client *client,
824                                  const char *from_addr, int from_port,
825                                  struct radius_session *force_sess)
826 {
827         struct wpabuf *eap = NULL;
828         int res, state_included = 0;
829         u8 statebuf[4];
830         unsigned int state;
831         struct radius_session *sess;
832         struct radius_msg *reply;
833         int is_complete = 0;
834
835         if (force_sess)
836                 sess = force_sess;
837         else {
838                 res = radius_msg_get_attr(msg, RADIUS_ATTR_STATE, statebuf,
839                                           sizeof(statebuf));
840                 state_included = res >= 0;
841                 if (res == sizeof(statebuf)) {
842                         state = WPA_GET_BE32(statebuf);
843                         sess = radius_server_get_session(client, state);
844                 } else {
845                         sess = NULL;
846                 }
847         }
848
849         if (sess) {
850                 RADIUS_DEBUG("Request for session 0x%x", sess->sess_id);
851         } else if (state_included) {
852                 RADIUS_DEBUG("State attribute included but no session found");
853                 radius_server_reject(data, client, msg, from, fromlen,
854                                      from_addr, from_port);
855                 return -1;
856         } else {
857                 sess = radius_server_get_new_session(data, client, msg,
858                                                      from_addr);
859                 if (sess == NULL) {
860                         RADIUS_DEBUG("Could not create a new session");
861                         radius_server_reject(data, client, msg, from, fromlen,
862                                              from_addr, from_port);
863                         return -1;
864                 }
865         }
866
867         if (sess->last_from_port == from_port &&
868             sess->last_identifier == radius_msg_get_hdr(msg)->identifier &&
869             os_memcmp(sess->last_authenticator,
870                       radius_msg_get_hdr(msg)->authenticator, 16) == 0) {
871                 RADIUS_DEBUG("Duplicate message from %s", from_addr);
872                 data->counters.dup_access_requests++;
873                 client->counters.dup_access_requests++;
874
875                 if (sess->last_reply) {
876                         struct wpabuf *buf;
877                         buf = radius_msg_get_buf(sess->last_reply);
878                         res = sendto(data->auth_sock, wpabuf_head(buf),
879                                      wpabuf_len(buf), 0,
880                                      (struct sockaddr *) from, fromlen);
881                         if (res < 0) {
882                                 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
883                                            strerror(errno));
884                         }
885                         return 0;
886                 }
887
888                 RADIUS_DEBUG("No previous reply available for duplicate "
889                              "message");
890                 return -1;
891         }
892                       
893         eap = radius_msg_get_eap(msg);
894         if (eap == NULL) {
895                 RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s",
896                              from_addr);
897                 data->counters.packets_dropped++;
898                 client->counters.packets_dropped++;
899                 return -1;
900         }
901
902         RADIUS_DUMP("Received EAP data", wpabuf_head(eap), wpabuf_len(eap));
903
904         /* FIX: if Code is Request, Success, or Failure, send Access-Reject;
905          * RFC3579 Sect. 2.6.2.
906          * Include EAP-Response/Nak with no preferred method if
907          * code == request.
908          * If code is not 1-4, discard the packet silently.
909          * Or is this already done by the EAP state machine? */
910
911         wpabuf_free(sess->eap_if->eapRespData);
912         sess->eap_if->eapRespData = eap;
913         sess->eap_if->eapResp = TRUE;
914         eap_server_sm_step(sess->eap);
915
916         if ((sess->eap_if->eapReq || sess->eap_if->eapSuccess ||
917              sess->eap_if->eapFail) && sess->eap_if->eapReqData) {
918                 RADIUS_DUMP("EAP data from the state machine",
919                             wpabuf_head(sess->eap_if->eapReqData),
920                             wpabuf_len(sess->eap_if->eapReqData));
921         } else if (sess->eap_if->eapFail) {
922                 RADIUS_DEBUG("No EAP data from the state machine, but eapFail "
923                              "set");
924         } else if (eap_sm_method_pending(sess->eap)) {
925                 radius_msg_free(sess->last_msg);
926                 sess->last_msg = msg;
927                 sess->last_from_port = from_port;
928                 os_free(sess->last_from_addr);
929                 sess->last_from_addr = os_strdup(from_addr);
930                 sess->last_fromlen = fromlen;
931                 os_memcpy(&sess->last_from, from, fromlen);
932                 return -2;
933         } else {
934                 RADIUS_DEBUG("No EAP data from the state machine - ignore this"
935                              " Access-Request silently (assuming it was a "
936                              "duplicate)");
937                 data->counters.packets_dropped++;
938                 client->counters.packets_dropped++;
939                 return -1;
940         }
941
942         if (sess->eap_if->eapSuccess || sess->eap_if->eapFail)
943                 is_complete = 1;
944         if (sess->eap_if->eapFail)
945                 srv_log(sess, "EAP authentication failed");
946         else if (sess->eap_if->eapSuccess)
947                 srv_log(sess, "EAP authentication succeeded");
948
949         reply = radius_server_encapsulate_eap(data, client, sess, msg);
950
951         if (reply) {
952                 struct wpabuf *buf;
953                 struct radius_hdr *hdr;
954
955                 RADIUS_DEBUG("Reply to %s:%d", from_addr, from_port);
956                 if (wpa_debug_level <= MSG_MSGDUMP) {
957                         radius_msg_dump(reply);
958                 }
959
960                 switch (radius_msg_get_hdr(reply)->code) {
961                 case RADIUS_CODE_ACCESS_ACCEPT:
962                         srv_log(sess, "Sending Access-Accept");
963                         data->counters.access_accepts++;
964                         client->counters.access_accepts++;
965                         break;
966                 case RADIUS_CODE_ACCESS_REJECT:
967                         srv_log(sess, "Sending Access-Reject");
968                         data->counters.access_rejects++;
969                         client->counters.access_rejects++;
970                         break;
971                 case RADIUS_CODE_ACCESS_CHALLENGE:
972                         data->counters.access_challenges++;
973                         client->counters.access_challenges++;
974                         break;
975                 }
976                 buf = radius_msg_get_buf(reply);
977                 res = sendto(data->auth_sock, wpabuf_head(buf),
978                              wpabuf_len(buf), 0,
979                              (struct sockaddr *) from, fromlen);
980                 if (res < 0) {
981                         wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
982                                    strerror(errno));
983                 }
984                 radius_msg_free(sess->last_reply);
985                 sess->last_reply = reply;
986                 sess->last_from_port = from_port;
987                 hdr = radius_msg_get_hdr(msg);
988                 sess->last_identifier = hdr->identifier;
989                 os_memcpy(sess->last_authenticator, hdr->authenticator, 16);
990         } else {
991                 data->counters.packets_dropped++;
992                 client->counters.packets_dropped++;
993         }
994
995         if (is_complete) {
996                 RADIUS_DEBUG("Removing completed session 0x%x after timeout",
997                              sess->sess_id);
998                 eloop_cancel_timeout(radius_server_session_remove_timeout,
999                                      data, sess);
1000                 eloop_register_timeout(10, 0,
1001                                        radius_server_session_remove_timeout,
1002                                        data, sess);
1003         }
1004
1005         return 0;
1006 }
1007
1008
1009 static void radius_server_receive_auth(int sock, void *eloop_ctx,
1010                                        void *sock_ctx)
1011 {
1012         struct radius_server_data *data = eloop_ctx;
1013         u8 *buf = NULL;
1014         union {
1015                 struct sockaddr_storage ss;
1016                 struct sockaddr_in sin;
1017 #ifdef CONFIG_IPV6
1018                 struct sockaddr_in6 sin6;
1019 #endif /* CONFIG_IPV6 */
1020         } from;
1021         socklen_t fromlen;
1022         int len;
1023         struct radius_client *client = NULL;
1024         struct radius_msg *msg = NULL;
1025         char abuf[50];
1026         int from_port = 0;
1027
1028         buf = os_malloc(RADIUS_MAX_MSG_LEN);
1029         if (buf == NULL) {
1030                 goto fail;
1031         }
1032
1033         fromlen = sizeof(from);
1034         len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0,
1035                        (struct sockaddr *) &from.ss, &fromlen);
1036         if (len < 0) {
1037                 wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s",
1038                            strerror(errno));
1039                 goto fail;
1040         }
1041
1042 #ifdef CONFIG_IPV6
1043         if (data->ipv6) {
1044                 if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf,
1045                               sizeof(abuf)) == NULL)
1046                         abuf[0] = '\0';
1047                 from_port = ntohs(from.sin6.sin6_port);
1048                 RADIUS_DEBUG("Received %d bytes from %s:%d",
1049                              len, abuf, from_port);
1050
1051                 client = radius_server_get_client(data,
1052                                                   (struct in_addr *)
1053                                                   &from.sin6.sin6_addr, 1);
1054         }
1055 #endif /* CONFIG_IPV6 */
1056
1057         if (!data->ipv6) {
1058                 os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
1059                 from_port = ntohs(from.sin.sin_port);
1060                 RADIUS_DEBUG("Received %d bytes from %s:%d",
1061                              len, abuf, from_port);
1062
1063                 client = radius_server_get_client(data, &from.sin.sin_addr, 0);
1064         }
1065
1066         RADIUS_DUMP("Received data", buf, len);
1067
1068         if (client == NULL) {
1069                 RADIUS_DEBUG("Unknown client %s - packet ignored", abuf);
1070                 data->counters.invalid_requests++;
1071                 goto fail;
1072         }
1073
1074         msg = radius_msg_parse(buf, len);
1075         if (msg == NULL) {
1076                 RADIUS_DEBUG("Parsing incoming RADIUS frame failed");
1077                 data->counters.malformed_access_requests++;
1078                 client->counters.malformed_access_requests++;
1079                 goto fail;
1080         }
1081
1082         os_free(buf);
1083         buf = NULL;
1084
1085         if (wpa_debug_level <= MSG_MSGDUMP) {
1086                 radius_msg_dump(msg);
1087         }
1088
1089         if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCESS_REQUEST) {
1090                 RADIUS_DEBUG("Unexpected RADIUS code %d",
1091                              radius_msg_get_hdr(msg)->code);
1092                 data->counters.unknown_types++;
1093                 client->counters.unknown_types++;
1094                 goto fail;
1095         }
1096
1097         data->counters.access_requests++;
1098         client->counters.access_requests++;
1099
1100         if (radius_msg_verify_msg_auth(msg, (u8 *) client->shared_secret,
1101                                        client->shared_secret_len, NULL)) {
1102                 RADIUS_DEBUG("Invalid Message-Authenticator from %s", abuf);
1103                 data->counters.bad_authenticators++;
1104                 client->counters.bad_authenticators++;
1105                 goto fail;
1106         }
1107
1108         if (radius_server_request(data, msg, (struct sockaddr *) &from,
1109                                   fromlen, client, abuf, from_port, NULL) ==
1110             -2)
1111                 return; /* msg was stored with the session */
1112
1113 fail:
1114         radius_msg_free(msg);
1115         os_free(buf);
1116 }
1117
1118
1119 static void radius_server_receive_acct(int sock, void *eloop_ctx,
1120                                        void *sock_ctx)
1121 {
1122         struct radius_server_data *data = eloop_ctx;
1123         u8 *buf = NULL;
1124         union {
1125                 struct sockaddr_storage ss;
1126                 struct sockaddr_in sin;
1127 #ifdef CONFIG_IPV6
1128                 struct sockaddr_in6 sin6;
1129 #endif /* CONFIG_IPV6 */
1130         } from;
1131         socklen_t fromlen;
1132         int len, res;
1133         struct radius_client *client = NULL;
1134         struct radius_msg *msg = NULL, *resp = NULL;
1135         char abuf[50];
1136         int from_port = 0;
1137         struct radius_hdr *hdr;
1138         struct wpabuf *rbuf;
1139
1140         buf = os_malloc(RADIUS_MAX_MSG_LEN);
1141         if (buf == NULL) {
1142                 goto fail;
1143         }
1144
1145         fromlen = sizeof(from);
1146         len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0,
1147                        (struct sockaddr *) &from.ss, &fromlen);
1148         if (len < 0) {
1149                 wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s",
1150                            strerror(errno));
1151                 goto fail;
1152         }
1153
1154 #ifdef CONFIG_IPV6
1155         if (data->ipv6) {
1156                 if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf,
1157                               sizeof(abuf)) == NULL)
1158                         abuf[0] = '\0';
1159                 from_port = ntohs(from.sin6.sin6_port);
1160                 RADIUS_DEBUG("Received %d bytes from %s:%d",
1161                              len, abuf, from_port);
1162
1163                 client = radius_server_get_client(data,
1164                                                   (struct in_addr *)
1165                                                   &from.sin6.sin6_addr, 1);
1166         }
1167 #endif /* CONFIG_IPV6 */
1168
1169         if (!data->ipv6) {
1170                 os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
1171                 from_port = ntohs(from.sin.sin_port);
1172                 RADIUS_DEBUG("Received %d bytes from %s:%d",
1173                              len, abuf, from_port);
1174
1175                 client = radius_server_get_client(data, &from.sin.sin_addr, 0);
1176         }
1177
1178         RADIUS_DUMP("Received data", buf, len);
1179
1180         if (client == NULL) {
1181                 RADIUS_DEBUG("Unknown client %s - packet ignored", abuf);
1182                 data->counters.invalid_acct_requests++;
1183                 goto fail;
1184         }
1185
1186         msg = radius_msg_parse(buf, len);
1187         if (msg == NULL) {
1188                 RADIUS_DEBUG("Parsing incoming RADIUS frame failed");
1189                 data->counters.malformed_acct_requests++;
1190                 client->counters.malformed_acct_requests++;
1191                 goto fail;
1192         }
1193
1194         os_free(buf);
1195         buf = NULL;
1196
1197         if (wpa_debug_level <= MSG_MSGDUMP) {
1198                 radius_msg_dump(msg);
1199         }
1200
1201         if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCOUNTING_REQUEST) {
1202                 RADIUS_DEBUG("Unexpected RADIUS code %d",
1203                              radius_msg_get_hdr(msg)->code);
1204                 data->counters.unknown_acct_types++;
1205                 client->counters.unknown_acct_types++;
1206                 goto fail;
1207         }
1208
1209         data->counters.acct_requests++;
1210         client->counters.acct_requests++;
1211
1212         if (radius_msg_verify_acct_req(msg, (u8 *) client->shared_secret,
1213                                        client->shared_secret_len)) {
1214                 RADIUS_DEBUG("Invalid Authenticator from %s", abuf);
1215                 data->counters.acct_bad_authenticators++;
1216                 client->counters.acct_bad_authenticators++;
1217                 goto fail;
1218         }
1219
1220         /* TODO: Write accounting information to a file or database */
1221
1222         hdr = radius_msg_get_hdr(msg);
1223
1224         resp = radius_msg_new(RADIUS_CODE_ACCOUNTING_RESPONSE, hdr->identifier);
1225         if (resp == NULL)
1226                 goto fail;
1227
1228         radius_msg_finish_acct_resp(resp, (u8 *) client->shared_secret,
1229                                     client->shared_secret_len,
1230                                     hdr->authenticator);
1231
1232         RADIUS_DEBUG("Reply to %s:%d", abuf, from_port);
1233         if (wpa_debug_level <= MSG_MSGDUMP) {
1234                 radius_msg_dump(resp);
1235         }
1236         rbuf = radius_msg_get_buf(resp);
1237         data->counters.acct_responses++;
1238         client->counters.acct_responses++;
1239         res = sendto(data->acct_sock, wpabuf_head(rbuf), wpabuf_len(rbuf), 0,
1240                      (struct sockaddr *) &from.ss, fromlen);
1241         if (res < 0) {
1242                 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
1243                            strerror(errno));
1244         }
1245
1246 fail:
1247         radius_msg_free(resp);
1248         radius_msg_free(msg);
1249         os_free(buf);
1250 }
1251
1252
1253 static int radius_server_disable_pmtu_discovery(int s)
1254 {
1255         int r = -1;
1256 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
1257         /* Turn off Path MTU discovery on IPv4/UDP sockets. */
1258         int action = IP_PMTUDISC_DONT;
1259         r = setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action,
1260                        sizeof(action));
1261         if (r == -1)
1262                 wpa_printf(MSG_ERROR, "Failed to set IP_MTU_DISCOVER: "
1263                            "%s", strerror(errno));
1264 #endif
1265         return r;
1266 }
1267
1268
1269 static int radius_server_open_socket(int port)
1270 {
1271         int s;
1272         struct sockaddr_in addr;
1273
1274         s = socket(PF_INET, SOCK_DGRAM, 0);
1275         if (s < 0) {
1276                 wpa_printf(MSG_INFO, "RADIUS: socket: %s", strerror(errno));
1277                 return -1;
1278         }
1279
1280         radius_server_disable_pmtu_discovery(s);
1281
1282         os_memset(&addr, 0, sizeof(addr));
1283         addr.sin_family = AF_INET;
1284         addr.sin_port = htons(port);
1285         if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1286                 wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno));
1287                 close(s);
1288                 return -1;
1289         }
1290
1291         return s;
1292 }
1293
1294
1295 #ifdef CONFIG_IPV6
1296 static int radius_server_open_socket6(int port)
1297 {
1298         int s;
1299         struct sockaddr_in6 addr;
1300
1301         s = socket(PF_INET6, SOCK_DGRAM, 0);
1302         if (s < 0) {
1303                 wpa_printf(MSG_INFO, "RADIUS: socket[IPv6]: %s",
1304                            strerror(errno));
1305                 return -1;
1306         }
1307
1308         os_memset(&addr, 0, sizeof(addr));
1309         addr.sin6_family = AF_INET6;
1310         os_memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any));
1311         addr.sin6_port = htons(port);
1312         if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1313                 wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno));
1314                 close(s);
1315                 return -1;
1316         }
1317
1318         return s;
1319 }
1320 #endif /* CONFIG_IPV6 */
1321
1322
1323 static void radius_server_free_sessions(struct radius_server_data *data,
1324                                         struct radius_session *sessions)
1325 {
1326         struct radius_session *session, *prev;
1327
1328         session = sessions;
1329         while (session) {
1330                 prev = session;
1331                 session = session->next;
1332                 radius_server_session_free(data, prev);
1333         }
1334 }
1335
1336
1337 static void radius_server_free_clients(struct radius_server_data *data,
1338                                        struct radius_client *clients)
1339 {
1340         struct radius_client *client, *prev;
1341
1342         client = clients;
1343         while (client) {
1344                 prev = client;
1345                 client = client->next;
1346
1347                 radius_server_free_sessions(data, prev->sessions);
1348                 os_free(prev->shared_secret);
1349                 os_free(prev);
1350         }
1351 }
1352
1353
1354 static struct radius_client *
1355 radius_server_read_clients(const char *client_file, int ipv6)
1356 {
1357         FILE *f;
1358         const int buf_size = 1024;
1359         char *buf, *pos;
1360         struct radius_client *clients, *tail, *entry;
1361         int line = 0, mask, failed = 0, i;
1362         struct in_addr addr;
1363 #ifdef CONFIG_IPV6
1364         struct in6_addr addr6;
1365 #endif /* CONFIG_IPV6 */
1366         unsigned int val;
1367
1368         f = fopen(client_file, "r");
1369         if (f == NULL) {
1370                 RADIUS_ERROR("Could not open client file '%s'", client_file);
1371                 return NULL;
1372         }
1373
1374         buf = os_malloc(buf_size);
1375         if (buf == NULL) {
1376                 fclose(f);
1377                 return NULL;
1378         }
1379
1380         clients = tail = NULL;
1381         while (fgets(buf, buf_size, f)) {
1382                 /* Configuration file format:
1383                  * 192.168.1.0/24 secret
1384                  * 192.168.1.2 secret
1385                  * fe80::211:22ff:fe33:4455/64 secretipv6
1386                  */
1387                 line++;
1388                 buf[buf_size - 1] = '\0';
1389                 pos = buf;
1390                 while (*pos != '\0' && *pos != '\n')
1391                         pos++;
1392                 if (*pos == '\n')
1393                         *pos = '\0';
1394                 if (*buf == '\0' || *buf == '#')
1395                         continue;
1396
1397                 pos = buf;
1398                 while ((*pos >= '0' && *pos <= '9') || *pos == '.' ||
1399                        (*pos >= 'a' && *pos <= 'f') || *pos == ':' ||
1400                        (*pos >= 'A' && *pos <= 'F')) {
1401                         pos++;
1402                 }
1403
1404                 if (*pos == '\0') {
1405                         failed = 1;
1406                         break;
1407                 }
1408
1409                 if (*pos == '/') {
1410                         char *end;
1411                         *pos++ = '\0';
1412                         mask = strtol(pos, &end, 10);
1413                         if ((pos == end) ||
1414                             (mask < 0 || mask > (ipv6 ? 128 : 32))) {
1415                                 failed = 1;
1416                                 break;
1417                         }
1418                         pos = end;
1419                 } else {
1420                         mask = ipv6 ? 128 : 32;
1421                         *pos++ = '\0';
1422                 }
1423
1424                 if (!ipv6 && inet_aton(buf, &addr) == 0) {
1425                         failed = 1;
1426                         break;
1427                 }
1428 #ifdef CONFIG_IPV6
1429                 if (ipv6 && inet_pton(AF_INET6, buf, &addr6) <= 0) {
1430                         if (inet_pton(AF_INET, buf, &addr) <= 0) {
1431                                 failed = 1;
1432                                 break;
1433                         }
1434                         /* Convert IPv4 address to IPv6 */
1435                         if (mask <= 32)
1436                                 mask += (128 - 32);
1437                         os_memset(addr6.s6_addr, 0, 10);
1438                         addr6.s6_addr[10] = 0xff;
1439                         addr6.s6_addr[11] = 0xff;
1440                         os_memcpy(addr6.s6_addr + 12, (char *) &addr.s_addr,
1441                                   4);
1442                 }
1443 #endif /* CONFIG_IPV6 */
1444
1445                 while (*pos == ' ' || *pos == '\t') {
1446                         pos++;
1447                 }
1448
1449                 if (*pos == '\0') {
1450                         failed = 1;
1451                         break;
1452                 }
1453
1454                 entry = os_zalloc(sizeof(*entry));
1455                 if (entry == NULL) {
1456                         failed = 1;
1457                         break;
1458                 }
1459                 entry->shared_secret = os_strdup(pos);
1460                 if (entry->shared_secret == NULL) {
1461                         failed = 1;
1462                         os_free(entry);
1463                         break;
1464                 }
1465                 entry->shared_secret_len = os_strlen(entry->shared_secret);
1466                 if (!ipv6) {
1467                         entry->addr.s_addr = addr.s_addr;
1468                         val = 0;
1469                         for (i = 0; i < mask; i++)
1470                                 val |= 1 << (31 - i);
1471                         entry->mask.s_addr = htonl(val);
1472                 }
1473 #ifdef CONFIG_IPV6
1474                 if (ipv6) {
1475                         int offset = mask / 8;
1476
1477                         os_memcpy(entry->addr6.s6_addr, addr6.s6_addr, 16);
1478                         os_memset(entry->mask6.s6_addr, 0xff, offset);
1479                         val = 0;
1480                         for (i = 0; i < (mask % 8); i++)
1481                                 val |= 1 << (7 - i);
1482                         if (offset < 16)
1483                                 entry->mask6.s6_addr[offset] = val;
1484                 }
1485 #endif /* CONFIG_IPV6 */
1486
1487                 if (tail == NULL) {
1488                         clients = tail = entry;
1489                 } else {
1490                         tail->next = entry;
1491                         tail = entry;
1492                 }
1493         }
1494
1495         if (failed) {
1496                 RADIUS_ERROR("Invalid line %d in '%s'", line, client_file);
1497                 radius_server_free_clients(NULL, clients);
1498                 clients = NULL;
1499         }
1500
1501         os_free(buf);
1502         fclose(f);
1503
1504         return clients;
1505 }
1506
1507
1508 /**
1509  * radius_server_init - Initialize RADIUS server
1510  * @conf: Configuration for the RADIUS server
1511  * Returns: Pointer to private RADIUS server context or %NULL on failure
1512  *
1513  * This initializes a RADIUS server instance and returns a context pointer that
1514  * will be used in other calls to the RADIUS server module. The server can be
1515  * deinitialize by calling radius_server_deinit().
1516  */
1517 struct radius_server_data *
1518 radius_server_init(struct radius_server_conf *conf)
1519 {
1520         struct radius_server_data *data;
1521
1522 #ifndef CONFIG_IPV6
1523         if (conf->ipv6) {
1524                 wpa_printf(MSG_ERROR, "RADIUS server compiled without IPv6 support");
1525                 return NULL;
1526         }
1527 #endif /* CONFIG_IPV6 */
1528
1529         data = os_zalloc(sizeof(*data));
1530         if (data == NULL)
1531                 return NULL;
1532
1533         os_get_reltime(&data->start_time);
1534         data->conf_ctx = conf->conf_ctx;
1535         data->eap_sim_db_priv = conf->eap_sim_db_priv;
1536         data->ssl_ctx = conf->ssl_ctx;
1537         data->msg_ctx = conf->msg_ctx;
1538         data->ipv6 = conf->ipv6;
1539         if (conf->pac_opaque_encr_key) {
1540                 data->pac_opaque_encr_key = os_malloc(16);
1541                 os_memcpy(data->pac_opaque_encr_key, conf->pac_opaque_encr_key,
1542                           16);
1543         }
1544         if (conf->eap_fast_a_id) {
1545                 data->eap_fast_a_id = os_malloc(conf->eap_fast_a_id_len);
1546                 if (data->eap_fast_a_id) {
1547                         os_memcpy(data->eap_fast_a_id, conf->eap_fast_a_id,
1548                                   conf->eap_fast_a_id_len);
1549                         data->eap_fast_a_id_len = conf->eap_fast_a_id_len;
1550                 }
1551         }
1552         if (conf->eap_fast_a_id_info)
1553                 data->eap_fast_a_id_info = os_strdup(conf->eap_fast_a_id_info);
1554         data->eap_fast_prov = conf->eap_fast_prov;
1555         data->pac_key_lifetime = conf->pac_key_lifetime;
1556         data->pac_key_refresh_time = conf->pac_key_refresh_time;
1557         data->get_eap_user = conf->get_eap_user;
1558         data->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
1559         data->tnc = conf->tnc;
1560         data->wps = conf->wps;
1561         data->pwd_group = conf->pwd_group;
1562         data->server_id = conf->server_id;
1563         if (conf->eap_req_id_text) {
1564                 data->eap_req_id_text = os_malloc(conf->eap_req_id_text_len);
1565                 if (data->eap_req_id_text) {
1566                         os_memcpy(data->eap_req_id_text, conf->eap_req_id_text,
1567                                   conf->eap_req_id_text_len);
1568                         data->eap_req_id_text_len = conf->eap_req_id_text_len;
1569                 }
1570         }
1571
1572         if (conf->subscr_remediation_url) {
1573                 data->subscr_remediation_url =
1574                         os_strdup(conf->subscr_remediation_url);
1575         }
1576
1577 #ifdef CONFIG_SQLITE
1578         if (conf->sqlite_file) {
1579                 if (sqlite3_open(conf->sqlite_file, &data->db)) {
1580                         RADIUS_ERROR("Could not open SQLite file '%s'",
1581                                      conf->sqlite_file);
1582                         radius_server_deinit(data);
1583                         return NULL;
1584                 }
1585         }
1586 #endif /* CONFIG_SQLITE */
1587
1588 #ifdef CONFIG_RADIUS_TEST
1589         if (conf->dump_msk_file)
1590                 data->dump_msk_file = os_strdup(conf->dump_msk_file);
1591 #endif /* CONFIG_RADIUS_TEST */
1592
1593         data->clients = radius_server_read_clients(conf->client_file,
1594                                                    conf->ipv6);
1595         if (data->clients == NULL) {
1596                 wpa_printf(MSG_ERROR, "No RADIUS clients configured");
1597                 radius_server_deinit(data);
1598                 return NULL;
1599         }
1600
1601 #ifdef CONFIG_IPV6
1602         if (conf->ipv6)
1603                 data->auth_sock = radius_server_open_socket6(conf->auth_port);
1604         else
1605 #endif /* CONFIG_IPV6 */
1606         data->auth_sock = radius_server_open_socket(conf->auth_port);
1607         if (data->auth_sock < 0) {
1608                 wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS authentication server");
1609                 radius_server_deinit(data);
1610                 return NULL;
1611         }
1612         if (eloop_register_read_sock(data->auth_sock,
1613                                      radius_server_receive_auth,
1614                                      data, NULL)) {
1615                 radius_server_deinit(data);
1616                 return NULL;
1617         }
1618
1619         if (conf->acct_port) {
1620 #ifdef CONFIG_IPV6
1621                 if (conf->ipv6)
1622                         data->acct_sock = radius_server_open_socket6(
1623                                 conf->acct_port);
1624                 else
1625 #endif /* CONFIG_IPV6 */
1626                 data->acct_sock = radius_server_open_socket(conf->acct_port);
1627                 if (data->acct_sock < 0) {
1628                         wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS accounting server");
1629                         radius_server_deinit(data);
1630                         return NULL;
1631                 }
1632                 if (eloop_register_read_sock(data->acct_sock,
1633                                              radius_server_receive_acct,
1634                                              data, NULL)) {
1635                         radius_server_deinit(data);
1636                         return NULL;
1637                 }
1638         } else {
1639                 data->acct_sock = -1;
1640         }
1641
1642         return data;
1643 }
1644
1645
1646 /**
1647  * radius_server_deinit - Deinitialize RADIUS server
1648  * @data: RADIUS server context from radius_server_init()
1649  */
1650 void radius_server_deinit(struct radius_server_data *data)
1651 {
1652         if (data == NULL)
1653                 return;
1654
1655         if (data->auth_sock >= 0) {
1656                 eloop_unregister_read_sock(data->auth_sock);
1657                 close(data->auth_sock);
1658         }
1659
1660         if (data->acct_sock >= 0) {
1661                 eloop_unregister_read_sock(data->acct_sock);
1662                 close(data->acct_sock);
1663         }
1664
1665         radius_server_free_clients(data, data->clients);
1666
1667         os_free(data->pac_opaque_encr_key);
1668         os_free(data->eap_fast_a_id);
1669         os_free(data->eap_fast_a_id_info);
1670         os_free(data->eap_req_id_text);
1671 #ifdef CONFIG_RADIUS_TEST
1672         os_free(data->dump_msk_file);
1673 #endif /* CONFIG_RADIUS_TEST */
1674         os_free(data->subscr_remediation_url);
1675
1676 #ifdef CONFIG_SQLITE
1677         if (data->db)
1678                 sqlite3_close(data->db);
1679 #endif /* CONFIG_SQLITE */
1680
1681         os_free(data);
1682 }
1683
1684
1685 /**
1686  * radius_server_get_mib - Get RADIUS server MIB information
1687  * @data: RADIUS server context from radius_server_init()
1688  * @buf: Buffer for returning the MIB data in text format
1689  * @buflen: buf length in octets
1690  * Returns: Number of octets written into buf
1691  */
1692 int radius_server_get_mib(struct radius_server_data *data, char *buf,
1693                           size_t buflen)
1694 {
1695         int ret, uptime;
1696         unsigned int idx;
1697         char *end, *pos;
1698         struct os_reltime now;
1699         struct radius_client *cli;
1700
1701         /* RFC 2619 - RADIUS Authentication Server MIB */
1702
1703         if (data == NULL || buflen == 0)
1704                 return 0;
1705
1706         pos = buf;
1707         end = buf + buflen;
1708
1709         os_get_reltime(&now);
1710         uptime = (now.sec - data->start_time.sec) * 100 +
1711                 ((now.usec - data->start_time.usec) / 10000) % 100;
1712         ret = os_snprintf(pos, end - pos,
1713                           "RADIUS-AUTH-SERVER-MIB\n"
1714                           "radiusAuthServIdent=hostapd\n"
1715                           "radiusAuthServUpTime=%d\n"
1716                           "radiusAuthServResetTime=0\n"
1717                           "radiusAuthServConfigReset=4\n",
1718                           uptime);
1719         if (ret < 0 || ret >= end - pos) {
1720                 *pos = '\0';
1721                 return pos - buf;
1722         }
1723         pos += ret;
1724
1725         ret = os_snprintf(pos, end - pos,
1726                           "radiusAuthServTotalAccessRequests=%u\n"
1727                           "radiusAuthServTotalInvalidRequests=%u\n"
1728                           "radiusAuthServTotalDupAccessRequests=%u\n"
1729                           "radiusAuthServTotalAccessAccepts=%u\n"
1730                           "radiusAuthServTotalAccessRejects=%u\n"
1731                           "radiusAuthServTotalAccessChallenges=%u\n"
1732                           "radiusAuthServTotalMalformedAccessRequests=%u\n"
1733                           "radiusAuthServTotalBadAuthenticators=%u\n"
1734                           "radiusAuthServTotalPacketsDropped=%u\n"
1735                           "radiusAuthServTotalUnknownTypes=%u\n"
1736                           "radiusAccServTotalRequests=%u\n"
1737                           "radiusAccServTotalInvalidRequests=%u\n"
1738                           "radiusAccServTotalResponses=%u\n"
1739                           "radiusAccServTotalMalformedRequests=%u\n"
1740                           "radiusAccServTotalBadAuthenticators=%u\n"
1741                           "radiusAccServTotalUnknownTypes=%u\n",
1742                           data->counters.access_requests,
1743                           data->counters.invalid_requests,
1744                           data->counters.dup_access_requests,
1745                           data->counters.access_accepts,
1746                           data->counters.access_rejects,
1747                           data->counters.access_challenges,
1748                           data->counters.malformed_access_requests,
1749                           data->counters.bad_authenticators,
1750                           data->counters.packets_dropped,
1751                           data->counters.unknown_types,
1752                           data->counters.acct_requests,
1753                           data->counters.invalid_acct_requests,
1754                           data->counters.acct_responses,
1755                           data->counters.malformed_acct_requests,
1756                           data->counters.acct_bad_authenticators,
1757                           data->counters.unknown_acct_types);
1758         if (ret < 0 || ret >= end - pos) {
1759                 *pos = '\0';
1760                 return pos - buf;
1761         }
1762         pos += ret;
1763
1764         for (cli = data->clients, idx = 0; cli; cli = cli->next, idx++) {
1765                 char abuf[50], mbuf[50];
1766 #ifdef CONFIG_IPV6
1767                 if (data->ipv6) {
1768                         if (inet_ntop(AF_INET6, &cli->addr6, abuf,
1769                                       sizeof(abuf)) == NULL)
1770                                 abuf[0] = '\0';
1771                         if (inet_ntop(AF_INET6, &cli->mask6, abuf,
1772                                       sizeof(mbuf)) == NULL)
1773                                 mbuf[0] = '\0';
1774                 }
1775 #endif /* CONFIG_IPV6 */
1776                 if (!data->ipv6) {
1777                         os_strlcpy(abuf, inet_ntoa(cli->addr), sizeof(abuf));
1778                         os_strlcpy(mbuf, inet_ntoa(cli->mask), sizeof(mbuf));
1779                 }
1780
1781                 ret = os_snprintf(pos, end - pos,
1782                                   "radiusAuthClientIndex=%u\n"
1783                                   "radiusAuthClientAddress=%s/%s\n"
1784                                   "radiusAuthServAccessRequests=%u\n"
1785                                   "radiusAuthServDupAccessRequests=%u\n"
1786                                   "radiusAuthServAccessAccepts=%u\n"
1787                                   "radiusAuthServAccessRejects=%u\n"
1788                                   "radiusAuthServAccessChallenges=%u\n"
1789                                   "radiusAuthServMalformedAccessRequests=%u\n"
1790                                   "radiusAuthServBadAuthenticators=%u\n"
1791                                   "radiusAuthServPacketsDropped=%u\n"
1792                                   "radiusAuthServUnknownTypes=%u\n"
1793                                   "radiusAccServTotalRequests=%u\n"
1794                                   "radiusAccServTotalInvalidRequests=%u\n"
1795                                   "radiusAccServTotalResponses=%u\n"
1796                                   "radiusAccServTotalMalformedRequests=%u\n"
1797                                   "radiusAccServTotalBadAuthenticators=%u\n"
1798                                   "radiusAccServTotalUnknownTypes=%u\n",
1799                                   idx,
1800                                   abuf, mbuf,
1801                                   cli->counters.access_requests,
1802                                   cli->counters.dup_access_requests,
1803                                   cli->counters.access_accepts,
1804                                   cli->counters.access_rejects,
1805                                   cli->counters.access_challenges,
1806                                   cli->counters.malformed_access_requests,
1807                                   cli->counters.bad_authenticators,
1808                                   cli->counters.packets_dropped,
1809                                   cli->counters.unknown_types,
1810                                   cli->counters.acct_requests,
1811                                   cli->counters.invalid_acct_requests,
1812                                   cli->counters.acct_responses,
1813                                   cli->counters.malformed_acct_requests,
1814                                   cli->counters.acct_bad_authenticators,
1815                                   cli->counters.unknown_acct_types);
1816                 if (ret < 0 || ret >= end - pos) {
1817                         *pos = '\0';
1818                         return pos - buf;
1819                 }
1820                 pos += ret;
1821         }
1822
1823         return pos - buf;
1824 }
1825
1826
1827 static int radius_server_get_eap_user(void *ctx, const u8 *identity,
1828                                       size_t identity_len, int phase2,
1829                                       struct eap_user *user)
1830 {
1831         struct radius_session *sess = ctx;
1832         struct radius_server_data *data = sess->server;
1833         int ret;
1834
1835         ret = data->get_eap_user(data->conf_ctx, identity, identity_len,
1836                                  phase2, user);
1837         if (ret == 0 && user) {
1838                 sess->accept_attr = user->accept_attr;
1839                 sess->remediation = user->remediation;
1840         }
1841         return ret;
1842 }
1843
1844
1845 static const char * radius_server_get_eap_req_id_text(void *ctx, size_t *len)
1846 {
1847         struct radius_session *sess = ctx;
1848         struct radius_server_data *data = sess->server;
1849         *len = data->eap_req_id_text_len;
1850         return data->eap_req_id_text;
1851 }
1852
1853
1854 static void radius_server_log_msg(void *ctx, const char *msg)
1855 {
1856         struct radius_session *sess = ctx;
1857         srv_log(sess, "EAP: %s", msg);
1858 }
1859
1860
1861 static struct eapol_callbacks radius_server_eapol_cb =
1862 {
1863         .get_eap_user = radius_server_get_eap_user,
1864         .get_eap_req_id_text = radius_server_get_eap_req_id_text,
1865         .log_msg = radius_server_log_msg,
1866 };
1867
1868
1869 /**
1870  * radius_server_eap_pending_cb - Pending EAP data notification
1871  * @data: RADIUS server context from radius_server_init()
1872  * @ctx: Pending EAP context pointer
1873  *
1874  * This function is used to notify EAP server module that a pending operation
1875  * has been completed and processing of the EAP session can proceed.
1876  */
1877 void radius_server_eap_pending_cb(struct radius_server_data *data, void *ctx)
1878 {
1879         struct radius_client *cli;
1880         struct radius_session *s, *sess = NULL;
1881         struct radius_msg *msg;
1882
1883         if (data == NULL)
1884                 return;
1885
1886         for (cli = data->clients; cli; cli = cli->next) {
1887                 for (s = cli->sessions; s; s = s->next) {
1888                         if (s->eap == ctx && s->last_msg) {
1889                                 sess = s;
1890                                 break;
1891                         }
1892                         if (sess)
1893                                 break;
1894                 }
1895                 if (sess)
1896                         break;
1897         }
1898
1899         if (sess == NULL) {
1900                 RADIUS_DEBUG("No session matched callback ctx");
1901                 return;
1902         }
1903
1904         msg = sess->last_msg;
1905         sess->last_msg = NULL;
1906         eap_sm_pending_cb(sess->eap);
1907         if (radius_server_request(data, msg,
1908                                   (struct sockaddr *) &sess->last_from,
1909                                   sess->last_fromlen, cli,
1910                                   sess->last_from_addr,
1911                                   sess->last_from_port, sess) == -2)
1912                 return; /* msg was stored with the session */
1913
1914         radius_msg_free(msg);
1915 }