radius_client.c (209158) | radius_client.c (214734) |
---|---|
1/* | 1/* |
2 * hostapd / RADIUS client 3 * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi> | 2 * RADIUS client 3 * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> |
4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15#include "includes.h" 16 17#include "common.h" 18#include "radius.h" 19#include "radius_client.h" 20#include "eloop.h" 21 22/* Defaults for RADIUS retransmit values (exponential backoff) */ | 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15#include "includes.h" 16 17#include "common.h" 18#include "radius.h" 19#include "radius_client.h" 20#include "eloop.h" 21 22/* Defaults for RADIUS retransmit values (exponential backoff) */ |
23#define RADIUS_CLIENT_FIRST_WAIT 3 /* seconds */ 24#define RADIUS_CLIENT_MAX_WAIT 120 /* seconds */ 25#define RADIUS_CLIENT_MAX_RETRIES 10 /* maximum number of retransmit attempts 26 * before entry is removed from retransmit 27 * list */ 28#define RADIUS_CLIENT_MAX_ENTRIES 30 /* maximum number of entries in retransmit 29 * list (oldest will be removed, if this 30 * limit is exceeded) */ 31#define RADIUS_CLIENT_NUM_FAILOVER 4 /* try to change RADIUS server after this 32 * many failed retry attempts */ | |
33 | 23 |
24/** 25 * RADIUS_CLIENT_FIRST_WAIT - RADIUS client timeout for first retry in seconds 26 */ 27#define RADIUS_CLIENT_FIRST_WAIT 3 |
|
34 | 28 |
29/** 30 * RADIUS_CLIENT_MAX_WAIT - RADIUS client maximum retry timeout in seconds 31 */ 32#define RADIUS_CLIENT_MAX_WAIT 120 33 34/** 35 * RADIUS_CLIENT_MAX_RETRIES - RADIUS client maximum retries 36 * 37 * Maximum number of retransmit attempts before the entry is removed from 38 * retransmit list. 39 */ 40#define RADIUS_CLIENT_MAX_RETRIES 10 41 42/** 43 * RADIUS_CLIENT_MAX_ENTRIES - RADIUS client maximum pending messages 44 * 45 * Maximum number of entries in retransmit list (oldest entries will be 46 * removed, if this limit is exceeded). 47 */ 48#define RADIUS_CLIENT_MAX_ENTRIES 30 49 50/** 51 * RADIUS_CLIENT_NUM_FAILOVER - RADIUS client failover point 52 * 53 * The number of failed retry attempts after which the RADIUS server will be 54 * changed (if one of more backup servers are configured). 55 */ 56#define RADIUS_CLIENT_NUM_FAILOVER 4 57 58 59/** 60 * struct radius_rx_handler - RADIUS client RX handler 61 * 62 * This data structure is used internally inside the RADIUS client module to 63 * store registered RX handlers. These handlers are registered by calls to 64 * radius_client_register() and unregistered when the RADIUS client is 65 * deinitialized with a call to radius_client_deinit(). 66 */ |
|
35struct radius_rx_handler { | 67struct radius_rx_handler { |
68 /** 69 * handler - Received RADIUS message handler 70 */ |
|
36 RadiusRxResult (*handler)(struct radius_msg *msg, 37 struct radius_msg *req, 38 const u8 *shared_secret, 39 size_t shared_secret_len, 40 void *data); | 71 RadiusRxResult (*handler)(struct radius_msg *msg, 72 struct radius_msg *req, 73 const u8 *shared_secret, 74 size_t shared_secret_len, 75 void *data); |
76 77 /** 78 * data - Context data for the handler 79 */ |
|
41 void *data; 42}; 43 44 | 80 void *data; 81}; 82 83 |
45/* RADIUS message retransmit list */ | 84/** 85 * struct radius_msg_list - RADIUS client message retransmit list 86 * 87 * This data structure is used internally inside the RADIUS client module to 88 * store pending RADIUS requests that may still need to be retransmitted. 89 */ |
46struct radius_msg_list { | 90struct radius_msg_list { |
47 u8 addr[ETH_ALEN]; /* STA/client address; used to find RADIUS messages 48 * for the same STA. */ | 91 /** 92 * addr - STA/client address 93 * 94 * This is used to find RADIUS messages for the same STA. 95 */ 96 u8 addr[ETH_ALEN]; 97 98 /** 99 * msg - RADIUS message 100 */ |
49 struct radius_msg *msg; | 101 struct radius_msg *msg; |
102 103 /** 104 * msg_type - Message type 105 */ |
|
50 RadiusType msg_type; | 106 RadiusType msg_type; |
107 108 /** 109 * first_try - Time of the first transmission attempt 110 */ |
|
51 os_time_t first_try; | 111 os_time_t first_try; |
112 113 /** 114 * next_try - Time for the next transmission attempt 115 */ |
|
52 os_time_t next_try; | 116 os_time_t next_try; |
117 118 /** 119 * attempts - Number of transmission attempts 120 */ |
|
53 int attempts; | 121 int attempts; |
122 123 /** 124 * next_wait - Next retransmission wait time in seconds 125 */ |
|
54 int next_wait; | 126 int next_wait; |
127 128 /** 129 * last_attempt - Time of the last transmission attempt 130 */ |
|
55 struct os_time last_attempt; 56 | 131 struct os_time last_attempt; 132 |
57 u8 *shared_secret; | 133 /** 134 * shared_secret - Shared secret with the target RADIUS server 135 */ 136 const u8 *shared_secret; 137 138 /** 139 * shared_secret_len - shared_secret length in octets 140 */ |
58 size_t shared_secret_len; 59 60 /* TODO: server config with failover to backup server(s) */ 61 | 141 size_t shared_secret_len; 142 143 /* TODO: server config with failover to backup server(s) */ 144 |
145 /** 146 * next - Next message in the list 147 */ |
|
62 struct radius_msg_list *next; 63}; 64 65 | 148 struct radius_msg_list *next; 149}; 150 151 |
152/** 153 * struct radius_client_data - Internal RADIUS client data 154 * 155 * This data structure is used internally inside the RADIUS client module. 156 * External users allocate this by calling radius_client_init() and free it by 157 * calling radius_client_deinit(). The pointer to this opaque data is used in 158 * calls to other functions as an identifier for the RADIUS client instance. 159 */ |
|
66struct radius_client_data { | 160struct radius_client_data { |
161 /** 162 * ctx - Context pointer for hostapd_logger() callbacks 163 */ |
|
67 void *ctx; | 164 void *ctx; |
165 166 /** 167 * conf - RADIUS client configuration (list of RADIUS servers to use) 168 */ |
|
68 struct hostapd_radius_servers *conf; 69 | 169 struct hostapd_radius_servers *conf; 170 |
70 int auth_serv_sock; /* socket for authentication RADIUS messages */ 71 int acct_serv_sock; /* socket for accounting RADIUS messages */ | 171 /** 172 * auth_serv_sock - IPv4 socket for RADIUS authentication messages 173 */ 174 int auth_serv_sock; 175 176 /** 177 * acct_serv_sock - IPv4 socket for RADIUS accounting messages 178 */ 179 int acct_serv_sock; 180 181 /** 182 * auth_serv_sock6 - IPv6 socket for RADIUS authentication messages 183 */ |
72 int auth_serv_sock6; | 184 int auth_serv_sock6; |
185 186 /** 187 * acct_serv_sock6 - IPv6 socket for RADIUS accounting messages 188 */ |
|
73 int acct_serv_sock6; | 189 int acct_serv_sock6; |
74 int auth_sock; /* currently used socket */ 75 int acct_sock; /* currently used socket */ | |
76 | 190 |
191 /** 192 * auth_sock - Currently used socket for RADIUS authentication server 193 */ 194 int auth_sock; 195 196 /** 197 * acct_sock - Currently used socket for RADIUS accounting server 198 */ 199 int acct_sock; 200 201 /** 202 * auth_handlers - Authentication message handlers 203 */ |
|
77 struct radius_rx_handler *auth_handlers; | 204 struct radius_rx_handler *auth_handlers; |
205 206 /** 207 * num_auth_handlers - Number of handlers in auth_handlers 208 */ |
|
78 size_t num_auth_handlers; | 209 size_t num_auth_handlers; |
210 211 /** 212 * acct_handlers - Accounting message handlers 213 */ |
|
79 struct radius_rx_handler *acct_handlers; | 214 struct radius_rx_handler *acct_handlers; |
215 216 /** 217 * num_acct_handlers - Number of handlers in acct_handlers 218 */ |
|
80 size_t num_acct_handlers; 81 | 219 size_t num_acct_handlers; 220 |
221 /** 222 * msgs - Pending outgoing RADIUS messages 223 */ |
|
82 struct radius_msg_list *msgs; | 224 struct radius_msg_list *msgs; |
225 226 /** 227 * num_msgs - Number of pending messages in the msgs list 228 */ |
|
83 size_t num_msgs; 84 | 229 size_t num_msgs; 230 |
231 /** 232 * next_radius_identifier - Next RADIUS message identifier to use 233 */ |
|
85 u8 next_radius_identifier; 86}; 87 88 89static int 90radius_change_server(struct radius_client_data *radius, 91 struct hostapd_radius_server *nserv, 92 struct hostapd_radius_server *oserv, 93 int sock, int sock6, int auth); 94static int radius_client_init_acct(struct radius_client_data *radius); 95static int radius_client_init_auth(struct radius_client_data *radius); 96 97 98static void radius_client_msg_free(struct radius_msg_list *req) 99{ 100 radius_msg_free(req->msg); | 234 u8 next_radius_identifier; 235}; 236 237 238static int 239radius_change_server(struct radius_client_data *radius, 240 struct hostapd_radius_server *nserv, 241 struct hostapd_radius_server *oserv, 242 int sock, int sock6, int auth); 243static int radius_client_init_acct(struct radius_client_data *radius); 244static int radius_client_init_auth(struct radius_client_data *radius); 245 246 247static void radius_client_msg_free(struct radius_msg_list *req) 248{ 249 radius_msg_free(req->msg); |
101 os_free(req->msg); | |
102 os_free(req); 103} 104 105 | 250 os_free(req); 251} 252 253 |
254/** 255 * radius_client_register - Register a RADIUS client RX handler 256 * @radius: RADIUS client context from radius_client_init() 257 * @msg_type: RADIUS client type (RADIUS_AUTH or RADIUS_ACCT) 258 * @handler: Handler for received RADIUS messages 259 * @data: Context pointer for handler callbacks 260 * Returns: 0 on success, -1 on failure 261 * 262 * This function is used to register a handler for processing received RADIUS 263 * authentication and accounting messages. The handler() callback function will 264 * be called whenever a RADIUS message is received from the active server. 265 * 266 * There can be multiple registered RADIUS message handlers. The handlers will 267 * be called in order until one of them indicates that it has processed or 268 * queued the message. 269 */ |
|
106int radius_client_register(struct radius_client_data *radius, 107 RadiusType msg_type, 108 RadiusRxResult (*handler)(struct radius_msg *msg, 109 struct radius_msg *req, 110 const u8 *shared_secret, 111 size_t shared_secret_len, 112 void *data), 113 void *data) --- 47 unchanged lines hidden (view full) --- 161 162 163static int radius_client_retransmit(struct radius_client_data *radius, 164 struct radius_msg_list *entry, 165 os_time_t now) 166{ 167 struct hostapd_radius_servers *conf = radius->conf; 168 int s; | 270int radius_client_register(struct radius_client_data *radius, 271 RadiusType msg_type, 272 RadiusRxResult (*handler)(struct radius_msg *msg, 273 struct radius_msg *req, 274 const u8 *shared_secret, 275 size_t shared_secret_len, 276 void *data), 277 void *data) --- 47 unchanged lines hidden (view full) --- 325 326 327static int radius_client_retransmit(struct radius_client_data *radius, 328 struct radius_msg_list *entry, 329 os_time_t now) 330{ 331 struct hostapd_radius_servers *conf = radius->conf; 332 int s; |
333 struct wpabuf *buf; |
|
169 170 if (entry->msg_type == RADIUS_ACCT || 171 entry->msg_type == RADIUS_ACCT_INTERIM) { 172 s = radius->acct_sock; 173 if (entry->attempts == 0) 174 conf->acct_server->requests++; 175 else { 176 conf->acct_server->timeouts++; --- 8 unchanged lines hidden (view full) --- 185 conf->auth_server->retransmissions++; 186 } 187 } 188 189 /* retransmit; remove entry if too many attempts */ 190 entry->attempts++; 191 hostapd_logger(radius->ctx, entry->addr, HOSTAPD_MODULE_RADIUS, 192 HOSTAPD_LEVEL_DEBUG, "Resending RADIUS message (id=%d)", | 334 335 if (entry->msg_type == RADIUS_ACCT || 336 entry->msg_type == RADIUS_ACCT_INTERIM) { 337 s = radius->acct_sock; 338 if (entry->attempts == 0) 339 conf->acct_server->requests++; 340 else { 341 conf->acct_server->timeouts++; --- 8 unchanged lines hidden (view full) --- 350 conf->auth_server->retransmissions++; 351 } 352 } 353 354 /* retransmit; remove entry if too many attempts */ 355 entry->attempts++; 356 hostapd_logger(radius->ctx, entry->addr, HOSTAPD_MODULE_RADIUS, 357 HOSTAPD_LEVEL_DEBUG, "Resending RADIUS message (id=%d)", |
193 entry->msg->hdr->identifier); | 358 radius_msg_get_hdr(entry->msg)->identifier); |
194 195 os_get_time(&entry->last_attempt); | 359 360 os_get_time(&entry->last_attempt); |
196 if (send(s, entry->msg->buf, entry->msg->buf_used, 0) < 0) | 361 buf = radius_msg_get_buf(entry->msg); 362 if (send(s, wpabuf_head(buf), wpabuf_len(buf), 0) < 0) |
197 radius_client_handle_send_error(radius, s, entry->msg_type); 198 199 entry->next_try = now + entry->next_wait; 200 entry->next_wait *= 2; 201 if (entry->next_wait > RADIUS_CLIENT_MAX_WAIT) 202 entry->next_wait = RADIUS_CLIENT_MAX_WAIT; 203 if (entry->attempts >= RADIUS_CLIENT_MAX_RETRIES) { 204 printf("Removing un-ACKed RADIUS message due to too many " --- 141 unchanged lines hidden (view full) --- 346 hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, 347 HOSTAPD_LEVEL_DEBUG, "Next RADIUS client retransmit in" 348 " %ld seconds\n", (long int) (first - now.sec)); 349} 350 351 352static void radius_client_list_add(struct radius_client_data *radius, 353 struct radius_msg *msg, | 363 radius_client_handle_send_error(radius, s, entry->msg_type); 364 365 entry->next_try = now + entry->next_wait; 366 entry->next_wait *= 2; 367 if (entry->next_wait > RADIUS_CLIENT_MAX_WAIT) 368 entry->next_wait = RADIUS_CLIENT_MAX_WAIT; 369 if (entry->attempts >= RADIUS_CLIENT_MAX_RETRIES) { 370 printf("Removing un-ACKed RADIUS message due to too many " --- 141 unchanged lines hidden (view full) --- 512 hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, 513 HOSTAPD_LEVEL_DEBUG, "Next RADIUS client retransmit in" 514 " %ld seconds\n", (long int) (first - now.sec)); 515} 516 517 518static void radius_client_list_add(struct radius_client_data *radius, 519 struct radius_msg *msg, |
354 RadiusType msg_type, u8 *shared_secret, | 520 RadiusType msg_type, 521 const u8 *shared_secret, |
355 size_t shared_secret_len, const u8 *addr) 356{ 357 struct radius_msg_list *entry, *prev; 358 359 if (eloop_terminated()) { 360 /* No point in adding entries to retransmit queue since event 361 * loop has already been terminated. */ 362 radius_msg_free(msg); | 522 size_t shared_secret_len, const u8 *addr) 523{ 524 struct radius_msg_list *entry, *prev; 525 526 if (eloop_terminated()) { 527 /* No point in adding entries to retransmit queue since event 528 * loop has already been terminated. */ 529 radius_msg_free(msg); |
363 os_free(msg); | |
364 return; 365 } 366 367 entry = os_zalloc(sizeof(*entry)); 368 if (entry == NULL) { 369 printf("Failed to add RADIUS packet into retransmit list\n"); 370 radius_msg_free(msg); | 530 return; 531 } 532 533 entry = os_zalloc(sizeof(*entry)); 534 if (entry == NULL) { 535 printf("Failed to add RADIUS packet into retransmit list\n"); 536 radius_msg_free(msg); |
371 os_free(msg); | |
372 return; 373 } 374 375 if (addr) 376 os_memcpy(entry->addr, addr, ETH_ALEN); 377 entry->msg = msg; 378 entry->msg_type = msg_type; 379 entry->shared_secret = shared_secret; --- 52 unchanged lines hidden (view full) --- 432 continue; 433 } 434 prev = entry; 435 entry = entry->next; 436 } 437} 438 439 | 537 return; 538 } 539 540 if (addr) 541 os_memcpy(entry->addr, addr, ETH_ALEN); 542 entry->msg = msg; 543 entry->msg_type = msg_type; 544 entry->shared_secret = shared_secret; --- 52 unchanged lines hidden (view full) --- 597 continue; 598 } 599 prev = entry; 600 entry = entry->next; 601 } 602} 603 604 |
605/** 606 * radius_client_send - Send a RADIUS request 607 * @radius: RADIUS client context from radius_client_init() 608 * @msg: RADIUS message to be sent 609 * @msg_type: Message type (RADIUS_AUTH, RADIUS_ACCT, RADIUS_ACCT_INTERIM) 610 * @addr: MAC address of the device related to this message or %NULL 611 * Returns: 0 on success, -1 on failure 612 * 613 * This function is used to transmit a RADIUS authentication (RADIUS_AUTH) or 614 * accounting request (RADIUS_ACCT or RADIUS_ACCT_INTERIM). The only difference 615 * between accounting and interim accounting messages is that the interim 616 * message will override any pending interim accounting updates while a new 617 * accounting message does not remove any pending messages. 618 * 619 * The message is added on the retransmission queue and will be retransmitted 620 * automatically until a response is received or maximum number of retries 621 * (RADIUS_CLIENT_MAX_RETRIES) is reached. 622 * 623 * The related device MAC address can be used to identify pending messages that 624 * can be removed with radius_client_flush_auth() or with interim accounting 625 * updates. 626 */ |
|
440int radius_client_send(struct radius_client_data *radius, 441 struct radius_msg *msg, RadiusType msg_type, 442 const u8 *addr) 443{ 444 struct hostapd_radius_servers *conf = radius->conf; | 627int radius_client_send(struct radius_client_data *radius, 628 struct radius_msg *msg, RadiusType msg_type, 629 const u8 *addr) 630{ 631 struct hostapd_radius_servers *conf = radius->conf; |
445 u8 *shared_secret; | 632 const u8 *shared_secret; |
446 size_t shared_secret_len; 447 char *name; 448 int s, res; | 633 size_t shared_secret_len; 634 char *name; 635 int s, res; |
636 struct wpabuf *buf; |
|
449 450 if (msg_type == RADIUS_ACCT_INTERIM) { 451 /* Remove any pending interim acct update for the same STA. */ 452 radius_client_list_del(radius, msg_type, addr); 453 } 454 455 if (msg_type == RADIUS_ACCT || msg_type == RADIUS_ACCT_INTERIM) { 456 if (conf->acct_server == NULL) { --- 26 unchanged lines hidden (view full) --- 483 } 484 485 hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, 486 HOSTAPD_LEVEL_DEBUG, "Sending RADIUS message to %s " 487 "server", name); 488 if (conf->msg_dumps) 489 radius_msg_dump(msg); 490 | 637 638 if (msg_type == RADIUS_ACCT_INTERIM) { 639 /* Remove any pending interim acct update for the same STA. */ 640 radius_client_list_del(radius, msg_type, addr); 641 } 642 643 if (msg_type == RADIUS_ACCT || msg_type == RADIUS_ACCT_INTERIM) { 644 if (conf->acct_server == NULL) { --- 26 unchanged lines hidden (view full) --- 671 } 672 673 hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, 674 HOSTAPD_LEVEL_DEBUG, "Sending RADIUS message to %s " 675 "server", name); 676 if (conf->msg_dumps) 677 radius_msg_dump(msg); 678 |
491 res = send(s, msg->buf, msg->buf_used, 0); | 679 buf = radius_msg_get_buf(msg); 680 res = send(s, wpabuf_head(buf), wpabuf_len(buf), 0); |
492 if (res < 0) 493 radius_client_handle_send_error(radius, s, msg_type); 494 495 radius_client_list_add(radius, msg, msg_type, shared_secret, 496 shared_secret_len, addr); 497 498 return res; 499} 500 501 502static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx) 503{ 504 struct radius_client_data *radius = eloop_ctx; 505 struct hostapd_radius_servers *conf = radius->conf; 506 RadiusType msg_type = (RadiusType) sock_ctx; 507 int len, roundtrip; 508 unsigned char buf[3000]; 509 struct radius_msg *msg; | 681 if (res < 0) 682 radius_client_handle_send_error(radius, s, msg_type); 683 684 radius_client_list_add(radius, msg, msg_type, shared_secret, 685 shared_secret_len, addr); 686 687 return res; 688} 689 690 691static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx) 692{ 693 struct radius_client_data *radius = eloop_ctx; 694 struct hostapd_radius_servers *conf = radius->conf; 695 RadiusType msg_type = (RadiusType) sock_ctx; 696 int len, roundtrip; 697 unsigned char buf[3000]; 698 struct radius_msg *msg; |
699 struct radius_hdr *hdr; |
|
510 struct radius_rx_handler *handlers; 511 size_t num_handlers, i; 512 struct radius_msg_list *req, *prev_req; 513 struct os_time now; 514 struct hostapd_radius_server *rconf; 515 int invalid_authenticator = 0; 516 517 if (msg_type == RADIUS_ACCT) { --- 21 unchanged lines hidden (view full) --- 539 } 540 541 msg = radius_msg_parse(buf, len); 542 if (msg == NULL) { 543 printf("Parsing incoming RADIUS frame failed\n"); 544 rconf->malformed_responses++; 545 return; 546 } | 700 struct radius_rx_handler *handlers; 701 size_t num_handlers, i; 702 struct radius_msg_list *req, *prev_req; 703 struct os_time now; 704 struct hostapd_radius_server *rconf; 705 int invalid_authenticator = 0; 706 707 if (msg_type == RADIUS_ACCT) { --- 21 unchanged lines hidden (view full) --- 729 } 730 731 msg = radius_msg_parse(buf, len); 732 if (msg == NULL) { 733 printf("Parsing incoming RADIUS frame failed\n"); 734 rconf->malformed_responses++; 735 return; 736 } |
737 hdr = radius_msg_get_hdr(msg); |
|
547 548 hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, 549 HOSTAPD_LEVEL_DEBUG, "Received RADIUS message"); 550 if (conf->msg_dumps) 551 radius_msg_dump(msg); 552 | 738 739 hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, 740 HOSTAPD_LEVEL_DEBUG, "Received RADIUS message"); 741 if (conf->msg_dumps) 742 radius_msg_dump(msg); 743 |
553 switch (msg->hdr->code) { | 744 switch (hdr->code) { |
554 case RADIUS_CODE_ACCESS_ACCEPT: 555 rconf->access_accepts++; 556 break; 557 case RADIUS_CODE_ACCESS_REJECT: 558 rconf->access_rejects++; 559 break; 560 case RADIUS_CODE_ACCESS_CHALLENGE: 561 rconf->access_challenges++; --- 6 unchanged lines hidden (view full) --- 568 prev_req = NULL; 569 req = radius->msgs; 570 while (req) { 571 /* TODO: also match by src addr:port of the packet when using 572 * alternative RADIUS servers (?) */ 573 if ((req->msg_type == msg_type || 574 (req->msg_type == RADIUS_ACCT_INTERIM && 575 msg_type == RADIUS_ACCT)) && | 745 case RADIUS_CODE_ACCESS_ACCEPT: 746 rconf->access_accepts++; 747 break; 748 case RADIUS_CODE_ACCESS_REJECT: 749 rconf->access_rejects++; 750 break; 751 case RADIUS_CODE_ACCESS_CHALLENGE: 752 rconf->access_challenges++; --- 6 unchanged lines hidden (view full) --- 759 prev_req = NULL; 760 req = radius->msgs; 761 while (req) { 762 /* TODO: also match by src addr:port of the packet when using 763 * alternative RADIUS servers (?) */ 764 if ((req->msg_type == msg_type || 765 (req->msg_type == RADIUS_ACCT_INTERIM && 766 msg_type == RADIUS_ACCT)) && |
576 req->msg->hdr->identifier == msg->hdr->identifier) | 767 radius_msg_get_hdr(req->msg)->identifier == 768 hdr->identifier) |
577 break; 578 579 prev_req = req; 580 req = req->next; 581 } 582 583 if (req == NULL) { 584 hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, 585 HOSTAPD_LEVEL_DEBUG, 586 "No matching RADIUS request found (type=%d " 587 "id=%d) - dropping packet", | 769 break; 770 771 prev_req = req; 772 req = req->next; 773 } 774 775 if (req == NULL) { 776 hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, 777 HOSTAPD_LEVEL_DEBUG, 778 "No matching RADIUS request found (type=%d " 779 "id=%d) - dropping packet", |
588 msg_type, msg->hdr->identifier); | 780 msg_type, hdr->identifier); |
589 goto fail; 590 } 591 592 os_get_time(&now); 593 roundtrip = (now.sec - req->last_attempt.sec) * 100 + 594 (now.usec - req->last_attempt.usec) / 10000; 595 hostapd_logger(radius->ctx, req->addr, HOSTAPD_MODULE_RADIUS, 596 HOSTAPD_LEVEL_DEBUG, --- 12 unchanged lines hidden (view full) --- 609 for (i = 0; i < num_handlers; i++) { 610 RadiusRxResult res; 611 res = handlers[i].handler(msg, req->msg, req->shared_secret, 612 req->shared_secret_len, 613 handlers[i].data); 614 switch (res) { 615 case RADIUS_RX_PROCESSED: 616 radius_msg_free(msg); | 781 goto fail; 782 } 783 784 os_get_time(&now); 785 roundtrip = (now.sec - req->last_attempt.sec) * 100 + 786 (now.usec - req->last_attempt.usec) / 10000; 787 hostapd_logger(radius->ctx, req->addr, HOSTAPD_MODULE_RADIUS, 788 HOSTAPD_LEVEL_DEBUG, --- 12 unchanged lines hidden (view full) --- 801 for (i = 0; i < num_handlers; i++) { 802 RadiusRxResult res; 803 res = handlers[i].handler(msg, req->msg, req->shared_secret, 804 req->shared_secret_len, 805 handlers[i].data); 806 switch (res) { 807 case RADIUS_RX_PROCESSED: 808 radius_msg_free(msg); |
617 os_free(msg); | |
618 /* continue */ 619 case RADIUS_RX_QUEUED: 620 radius_client_msg_free(req); 621 return; 622 case RADIUS_RX_INVALID_AUTHENTICATOR: 623 invalid_authenticator++; 624 /* continue */ 625 case RADIUS_RX_UNKNOWN: --- 4 unchanged lines hidden (view full) --- 630 631 if (invalid_authenticator) 632 rconf->bad_authenticators++; 633 else 634 rconf->unknown_types++; 635 hostapd_logger(radius->ctx, req->addr, HOSTAPD_MODULE_RADIUS, 636 HOSTAPD_LEVEL_DEBUG, "No RADIUS RX handler found " 637 "(type=%d code=%d id=%d)%s - dropping packet", | 809 /* continue */ 810 case RADIUS_RX_QUEUED: 811 radius_client_msg_free(req); 812 return; 813 case RADIUS_RX_INVALID_AUTHENTICATOR: 814 invalid_authenticator++; 815 /* continue */ 816 case RADIUS_RX_UNKNOWN: --- 4 unchanged lines hidden (view full) --- 821 822 if (invalid_authenticator) 823 rconf->bad_authenticators++; 824 else 825 rconf->unknown_types++; 826 hostapd_logger(radius->ctx, req->addr, HOSTAPD_MODULE_RADIUS, 827 HOSTAPD_LEVEL_DEBUG, "No RADIUS RX handler found " 828 "(type=%d code=%d id=%d)%s - dropping packet", |
638 msg_type, msg->hdr->code, msg->hdr->identifier, | 829 msg_type, hdr->code, hdr->identifier, |
639 invalid_authenticator ? " [INVALID AUTHENTICATOR]" : 640 ""); 641 radius_client_msg_free(req); 642 643 fail: 644 radius_msg_free(msg); | 830 invalid_authenticator ? " [INVALID AUTHENTICATOR]" : 831 ""); 832 radius_client_msg_free(req); 833 834 fail: 835 radius_msg_free(msg); |
645 os_free(msg); | |
646} 647 648 | 836} 837 838 |
839/** 840 * radius_client_get_id - Get an identifier for a new RADIUS message 841 * @radius: RADIUS client context from radius_client_init() 842 * Returns: Allocated identifier 843 * 844 * This function is used to fetch a unique (among pending requests) identifier 845 * for a new RADIUS message. 846 */ |
|
649u8 radius_client_get_id(struct radius_client_data *radius) 650{ 651 struct radius_msg_list *entry, *prev, *_remove; 652 u8 id = radius->next_radius_identifier++; 653 654 /* remove entries with matching id from retransmit list to avoid 655 * using new reply from the RADIUS server with an old request */ 656 entry = radius->msgs; 657 prev = NULL; 658 while (entry) { | 847u8 radius_client_get_id(struct radius_client_data *radius) 848{ 849 struct radius_msg_list *entry, *prev, *_remove; 850 u8 id = radius->next_radius_identifier++; 851 852 /* remove entries with matching id from retransmit list to avoid 853 * using new reply from the RADIUS server with an old request */ 854 entry = radius->msgs; 855 prev = NULL; 856 while (entry) { |
659 if (entry->msg->hdr->identifier == id) { | 857 if (radius_msg_get_hdr(entry->msg)->identifier == id) { |
660 hostapd_logger(radius->ctx, entry->addr, 661 HOSTAPD_MODULE_RADIUS, 662 HOSTAPD_LEVEL_DEBUG, 663 "Removing pending RADIUS message, " 664 "since its id (%d) is reused", id); 665 if (prev) 666 prev->next = entry->next; 667 else --- 8 unchanged lines hidden (view full) --- 676 if (_remove) 677 radius_client_msg_free(_remove); 678 } 679 680 return id; 681} 682 683 | 858 hostapd_logger(radius->ctx, entry->addr, 859 HOSTAPD_MODULE_RADIUS, 860 HOSTAPD_LEVEL_DEBUG, 861 "Removing pending RADIUS message, " 862 "since its id (%d) is reused", id); 863 if (prev) 864 prev->next = entry->next; 865 else --- 8 unchanged lines hidden (view full) --- 874 if (_remove) 875 radius_client_msg_free(_remove); 876 } 877 878 return id; 879} 880 881 |
882/** 883 * radius_client_flush - Flush all pending RADIUS client messages 884 * @radius: RADIUS client context from radius_client_init() 885 * @only_auth: Whether only authentication messages are removed 886 */ |
|
684void radius_client_flush(struct radius_client_data *radius, int only_auth) 685{ 686 struct radius_msg_list *entry, *prev, *tmp; 687 688 if (!radius) 689 return; 690 691 prev = NULL; --- 17 unchanged lines hidden (view full) --- 709 } 710 711 if (radius->msgs == NULL) 712 eloop_cancel_timeout(radius_client_timer, radius, NULL); 713} 714 715 716static void radius_client_update_acct_msgs(struct radius_client_data *radius, | 887void radius_client_flush(struct radius_client_data *radius, int only_auth) 888{ 889 struct radius_msg_list *entry, *prev, *tmp; 890 891 if (!radius) 892 return; 893 894 prev = NULL; --- 17 unchanged lines hidden (view full) --- 912 } 913 914 if (radius->msgs == NULL) 915 eloop_cancel_timeout(radius_client_timer, radius, NULL); 916} 917 918 919static void radius_client_update_acct_msgs(struct radius_client_data *radius, |
717 u8 *shared_secret, | 920 const u8 *shared_secret, |
718 size_t shared_secret_len) 719{ 720 struct radius_msg_list *entry; 721 722 if (!radius) 723 return; 724 725 for (entry = radius->msgs; entry; entry = entry->next) { --- 306 unchanged lines hidden (view full) --- 1032 return -1; 1033 } 1034#endif /* CONFIG_IPV6 */ 1035 1036 return 0; 1037} 1038 1039 | 921 size_t shared_secret_len) 922{ 923 struct radius_msg_list *entry; 924 925 if (!radius) 926 return; 927 928 for (entry = radius->msgs; entry; entry = entry->next) { --- 306 unchanged lines hidden (view full) --- 1235 return -1; 1236 } 1237#endif /* CONFIG_IPV6 */ 1238 1239 return 0; 1240} 1241 1242 |
1243/** 1244 * radius_client_init - Initialize RADIUS client 1245 * @ctx: Callback context to be used in hostapd_logger() calls 1246 * @conf: RADIUS client configuration (RADIUS servers) 1247 * Returns: Pointer to private RADIUS client context or %NULL on failure 1248 * 1249 * The caller is responsible for keeping the configuration data available for 1250 * the lifetime of the RADIUS client, i.e., until radius_client_deinit() is 1251 * called for the returned context pointer. 1252 */ |
|
1040struct radius_client_data * 1041radius_client_init(void *ctx, struct hostapd_radius_servers *conf) 1042{ 1043 struct radius_client_data *radius; 1044 1045 radius = os_zalloc(sizeof(struct radius_client_data)); 1046 if (radius == NULL) 1047 return NULL; --- 18 unchanged lines hidden (view full) --- 1066 eloop_register_timeout(conf->retry_primary_interval, 0, 1067 radius_retry_primary_timer, radius, 1068 NULL); 1069 1070 return radius; 1071} 1072 1073 | 1253struct radius_client_data * 1254radius_client_init(void *ctx, struct hostapd_radius_servers *conf) 1255{ 1256 struct radius_client_data *radius; 1257 1258 radius = os_zalloc(sizeof(struct radius_client_data)); 1259 if (radius == NULL) 1260 return NULL; --- 18 unchanged lines hidden (view full) --- 1279 eloop_register_timeout(conf->retry_primary_interval, 0, 1280 radius_retry_primary_timer, radius, 1281 NULL); 1282 1283 return radius; 1284} 1285 1286 |
1287/** 1288 * radius_client_deinit - Deinitialize RADIUS client 1289 * @radius: RADIUS client context from radius_client_init() 1290 */ |
|
1074void radius_client_deinit(struct radius_client_data *radius) 1075{ 1076 if (!radius) 1077 return; 1078 1079 if (radius->auth_serv_sock >= 0) 1080 eloop_unregister_read_sock(radius->auth_serv_sock); 1081 if (radius->acct_serv_sock >= 0) --- 9 unchanged lines hidden (view full) --- 1091 1092 radius_client_flush(radius, 0); 1093 os_free(radius->auth_handlers); 1094 os_free(radius->acct_handlers); 1095 os_free(radius); 1096} 1097 1098 | 1291void radius_client_deinit(struct radius_client_data *radius) 1292{ 1293 if (!radius) 1294 return; 1295 1296 if (radius->auth_serv_sock >= 0) 1297 eloop_unregister_read_sock(radius->auth_serv_sock); 1298 if (radius->acct_serv_sock >= 0) --- 9 unchanged lines hidden (view full) --- 1308 1309 radius_client_flush(radius, 0); 1310 os_free(radius->auth_handlers); 1311 os_free(radius->acct_handlers); 1312 os_free(radius); 1313} 1314 1315 |
1099void radius_client_flush_auth(struct radius_client_data *radius, u8 *addr) | 1316/** 1317 * radius_client_flush_auth - Flush pending RADIUS messages for an address 1318 * @radius: RADIUS client context from radius_client_init() 1319 * @addr: MAC address of the related device 1320 * 1321 * This function can be used to remove pending RADIUS authentication messages 1322 * that are related to a specific device. The addr parameter is matched with 1323 * the one used in radius_client_send() call that was used to transmit the 1324 * authentication request. 1325 */ 1326void radius_client_flush_auth(struct radius_client_data *radius, 1327 const u8 *addr) |
1100{ 1101 struct radius_msg_list *entry, *prev, *tmp; 1102 1103 prev = NULL; 1104 entry = radius->msgs; 1105 while (entry) { 1106 if (entry->msg_type == RADIUS_AUTH && 1107 os_memcmp(entry->addr, addr, ETH_ALEN) == 0) { --- 111 unchanged lines hidden (view full) --- 1219 serv->bad_authenticators, 1220 pending, 1221 serv->timeouts, 1222 serv->unknown_types, 1223 serv->packets_dropped); 1224} 1225 1226 | 1328{ 1329 struct radius_msg_list *entry, *prev, *tmp; 1330 1331 prev = NULL; 1332 entry = radius->msgs; 1333 while (entry) { 1334 if (entry->msg_type == RADIUS_AUTH && 1335 os_memcmp(entry->addr, addr, ETH_ALEN) == 0) { --- 111 unchanged lines hidden (view full) --- 1447 serv->bad_authenticators, 1448 pending, 1449 serv->timeouts, 1450 serv->unknown_types, 1451 serv->packets_dropped); 1452} 1453 1454 |
1455/** 1456 * radius_client_get_mib - Get RADIUS client MIB information 1457 * @radius: RADIUS client context from radius_client_init() 1458 * @buf: Buffer for returning MIB data in text format 1459 * @buflen: Maximum buf length in octets 1460 * Returns: Number of octets written into the buffer 1461 */ |
|
1227int radius_client_get_mib(struct radius_client_data *radius, char *buf, 1228 size_t buflen) 1229{ 1230 struct hostapd_radius_servers *conf = radius->conf; 1231 int i; 1232 struct hostapd_radius_server *serv; 1233 int count = 0; 1234 --- 14 unchanged lines hidden (view full) --- 1249 buf + count, buflen - count, serv, 1250 serv == conf->acct_server ? 1251 radius : NULL); 1252 } 1253 } 1254 1255 return count; 1256} | 1462int radius_client_get_mib(struct radius_client_data *radius, char *buf, 1463 size_t buflen) 1464{ 1465 struct hostapd_radius_servers *conf = radius->conf; 1466 int i; 1467 struct hostapd_radius_server *serv; 1468 int count = 0; 1469 --- 14 unchanged lines hidden (view full) --- 1484 buf + count, buflen - count, serv, 1485 serv == conf->acct_server ? 1486 radius : NULL); 1487 } 1488 } 1489 1490 return count; 1491} |
1257 1258 1259static int radius_servers_diff(struct hostapd_radius_server *nserv, 1260 struct hostapd_radius_server *oserv, 1261 int num) 1262{ 1263 int i; 1264 1265 for (i = 0; i < num; i++) { 1266 if (hostapd_ip_diff(&nserv[i].addr, &oserv[i].addr) || 1267 nserv[i].port != oserv[i].port || 1268 nserv[i].shared_secret_len != oserv[i].shared_secret_len || 1269 os_memcmp(nserv[i].shared_secret, oserv[i].shared_secret, 1270 nserv[i].shared_secret_len) != 0) 1271 return 1; 1272 } 1273 1274 return 0; 1275} 1276 1277 1278struct radius_client_data * 1279radius_client_reconfig(struct radius_client_data *old, void *ctx, 1280 struct hostapd_radius_servers *oldconf, 1281 struct hostapd_radius_servers *newconf) 1282{ 1283 radius_client_flush(old, 0); 1284 1285 if (newconf->retry_primary_interval != 1286 oldconf->retry_primary_interval || 1287 newconf->num_auth_servers != oldconf->num_auth_servers || 1288 newconf->num_acct_servers != oldconf->num_acct_servers || 1289 radius_servers_diff(newconf->auth_servers, oldconf->auth_servers, 1290 newconf->num_auth_servers) || 1291 radius_servers_diff(newconf->acct_servers, oldconf->acct_servers, 1292 newconf->num_acct_servers)) { 1293 hostapd_logger(ctx, NULL, HOSTAPD_MODULE_RADIUS, 1294 HOSTAPD_LEVEL_DEBUG, 1295 "Reconfiguring RADIUS client"); 1296 radius_client_deinit(old); 1297 return radius_client_init(ctx, newconf); 1298 } 1299 1300 return old; 1301} | |