summaryrefslogtreecommitdiffstats
path: root/contrib/wpa_supplicant/radius_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/wpa_supplicant/radius_client.c')
-rw-r--r--contrib/wpa_supplicant/radius_client.c427
1 files changed, 258 insertions, 169 deletions
diff --git a/contrib/wpa_supplicant/radius_client.c b/contrib/wpa_supplicant/radius_client.c
index abc28bd..5b00bbe 100644
--- a/contrib/wpa_supplicant/radius_client.c
+++ b/contrib/wpa_supplicant/radius_client.c
@@ -1,7 +1,6 @@
/*
- * Host AP (software wireless LAN access point) user space daemon for
- * Host AP kernel driver / RADIUS client
- * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ * hostapd / RADIUS client
+ * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -13,19 +12,7 @@
* See README and COPYING for more details.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <errno.h>
-#ifndef CONFIG_NATIVE_WINDOWS
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#endif /* CONFIG_NATIVE_WINDOWS */
+#include "includes.h"
#include "hostapd.h"
#include "radius.h"
@@ -60,11 +47,11 @@ struct radius_msg_list {
* for the same STA. */
struct radius_msg *msg;
RadiusType msg_type;
- time_t first_try;
- time_t next_try;
+ os_time_t first_try;
+ os_time_t next_try;
int attempts;
int next_wait;
- struct timeval last_attempt;
+ struct os_time last_attempt;
u8 *shared_secret;
size_t shared_secret_len;
@@ -110,8 +97,8 @@ static int radius_client_init_auth(struct radius_client_data *radius);
static void radius_client_msg_free(struct radius_msg_list *req)
{
radius_msg_free(req->msg);
- free(req->msg);
- free(req);
+ os_free(req->msg);
+ os_free(req);
}
@@ -135,9 +122,8 @@ int radius_client_register(struct radius_client_data *radius,
num = &radius->num_auth_handlers;
}
- newh = (struct radius_rx_handler *)
- realloc(*handlers,
- (*num + 1) * sizeof(struct radius_rx_handler));
+ newh = os_realloc(*handlers,
+ (*num + 1) * sizeof(struct radius_rx_handler));
if (newh == NULL)
return -1;
@@ -173,7 +159,8 @@ static void radius_client_handle_send_error(struct radius_client_data *radius,
static int radius_client_retransmit(struct radius_client_data *radius,
- struct radius_msg_list *entry, time_t now)
+ struct radius_msg_list *entry,
+ os_time_t now)
{
struct hostapd_radius_servers *conf = radius->conf;
int s;
@@ -203,7 +190,7 @@ static int radius_client_retransmit(struct radius_client_data *radius,
HOSTAPD_LEVEL_DEBUG, "Resending RADIUS message (id=%d)",
entry->msg->hdr->identifier);
- gettimeofday(&entry->last_attempt, NULL);
+ os_get_time(&entry->last_attempt);
if (send(s, entry->msg->buf, entry->msg->buf_used, 0) < 0)
radius_client_handle_send_error(radius, s, entry->msg_type);
@@ -225,7 +212,8 @@ static void radius_client_timer(void *eloop_ctx, void *timeout_ctx)
{
struct radius_client_data *radius = eloop_ctx;
struct hostapd_radius_servers *conf = radius->conf;
- time_t now, first;
+ struct os_time now;
+ os_time_t first;
struct radius_msg_list *entry, *prev, *tmp;
int auth_failover = 0, acct_failover = 0;
char abuf[50];
@@ -234,13 +222,13 @@ static void radius_client_timer(void *eloop_ctx, void *timeout_ctx)
if (!entry)
return;
- time(&now);
+ os_get_time(&now);
first = 0;
prev = NULL;
while (entry) {
- if (now >= entry->next_try &&
- radius_client_retransmit(radius, entry, now)) {
+ if (now.sec >= entry->next_try &&
+ radius_client_retransmit(radius, entry, now.sec)) {
if (prev)
prev->next = entry->next;
else
@@ -269,14 +257,14 @@ static void radius_client_timer(void *eloop_ctx, void *timeout_ctx)
}
if (radius->msgs) {
- if (first < now)
- first = now;
- eloop_register_timeout(first - now, 0,
+ if (first < now.sec)
+ first = now.sec;
+ eloop_register_timeout(first - now.sec, 0,
radius_client_timer, radius, NULL);
hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_DEBUG, "Next RADIUS client "
"retransmit in %ld seconds",
- (long int) (first - now));
+ (long int) (first - now.sec));
}
if (auth_failover && conf->num_auth_servers > 1) {
@@ -332,7 +320,8 @@ static void radius_client_timer(void *eloop_ctx, void *timeout_ctx)
static void radius_client_update_timeout(struct radius_client_data *radius)
{
- time_t now, first;
+ struct os_time now;
+ os_time_t first;
struct radius_msg_list *entry;
eloop_cancel_timeout(radius_client_timer, radius, NULL);
@@ -347,21 +336,21 @@ static void radius_client_update_timeout(struct radius_client_data *radius)
first = entry->next_try;
}
- time(&now);
- if (first < now)
- first = now;
- eloop_register_timeout(first - now, 0, radius_client_timer, radius,
+ os_get_time(&now);
+ if (first < now.sec)
+ first = now.sec;
+ eloop_register_timeout(first - now.sec, 0, radius_client_timer, radius,
NULL);
hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_DEBUG, "Next RADIUS client retransmit in"
- " %ld seconds\n", (long int) (first - now));
+ " %ld seconds\n", (long int) (first - now.sec));
}
static void radius_client_list_add(struct radius_client_data *radius,
struct radius_msg *msg,
RadiusType msg_type, u8 *shared_secret,
- size_t shared_secret_len, u8 *addr)
+ size_t shared_secret_len, const u8 *addr)
{
struct radius_msg_list *entry, *prev;
@@ -369,29 +358,28 @@ static void radius_client_list_add(struct radius_client_data *radius,
/* No point in adding entries to retransmit queue since event
* loop has already been terminated. */
radius_msg_free(msg);
- free(msg);
+ os_free(msg);
return;
}
- entry = malloc(sizeof(*entry));
+ entry = wpa_zalloc(sizeof(*entry));
if (entry == NULL) {
printf("Failed to add RADIUS packet into retransmit list\n");
radius_msg_free(msg);
- free(msg);
+ os_free(msg);
return;
}
- memset(entry, 0, sizeof(*entry));
if (addr)
- memcpy(entry->addr, addr, ETH_ALEN);
+ os_memcpy(entry->addr, addr, ETH_ALEN);
entry->msg = msg;
entry->msg_type = msg_type;
entry->shared_secret = shared_secret;
entry->shared_secret_len = shared_secret_len;
- time(&entry->first_try);
+ os_get_time(&entry->last_attempt);
+ entry->first_try = entry->last_attempt.sec;
entry->next_try = entry->first_try + RADIUS_CLIENT_FIRST_WAIT;
entry->attempts = 1;
- gettimeofday(&entry->last_attempt, NULL);
entry->next_wait = RADIUS_CLIENT_FIRST_WAIT * 2;
entry->next = radius->msgs;
radius->msgs = entry;
@@ -415,7 +403,7 @@ static void radius_client_list_add(struct radius_client_data *radius,
static void radius_client_list_del(struct radius_client_data *radius,
- RadiusType msg_type, u8 *addr)
+ RadiusType msg_type, const u8 *addr)
{
struct radius_msg_list *entry, *prev, *tmp;
@@ -426,7 +414,7 @@ static void radius_client_list_del(struct radius_client_data *radius,
prev = NULL;
while (entry) {
if (entry->msg_type == msg_type &&
- memcmp(entry->addr, addr, ETH_ALEN) == 0) {
+ os_memcmp(entry->addr, addr, ETH_ALEN) == 0) {
if (prev)
prev->next = entry->next;
else
@@ -448,7 +436,8 @@ static void radius_client_list_del(struct radius_client_data *radius,
int radius_client_send(struct radius_client_data *radius,
- struct radius_msg *msg, RadiusType msg_type, u8 *addr)
+ struct radius_msg *msg, RadiusType msg_type,
+ const u8 *addr)
{
struct hostapd_radius_servers *conf = radius->conf;
u8 *shared_secret;
@@ -499,13 +488,13 @@ static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx)
struct radius_client_data *radius = eloop_ctx;
struct hostapd_radius_servers *conf = radius->conf;
RadiusType msg_type = (RadiusType) sock_ctx;
- int len, i, roundtrip;
+ int len, roundtrip;
unsigned char buf[3000];
struct radius_msg *msg;
struct radius_rx_handler *handlers;
- size_t num_handlers;
+ size_t num_handlers, i;
struct radius_msg_list *req, *prev_req;
- struct timeval tv;
+ struct os_time now;
struct hostapd_radius_server *rconf;
int invalid_authenticator = 0;
@@ -584,9 +573,9 @@ static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx)
goto fail;
}
- gettimeofday(&tv, NULL);
- roundtrip = (tv.tv_sec - req->last_attempt.tv_sec) * 100 +
- (tv.tv_usec - req->last_attempt.tv_usec) / 10000;
+ os_get_time(&now);
+ roundtrip = (now.sec - req->last_attempt.sec) * 100 +
+ (now.usec - req->last_attempt.usec) / 10000;
hostapd_logger(radius->ctx, req->addr, HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_DEBUG,
"Received RADIUS packet matched with a pending "
@@ -609,7 +598,7 @@ static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx)
switch (res) {
case RADIUS_RX_PROCESSED:
radius_msg_free(msg);
- free(msg);
+ os_free(msg);
/* continue */
case RADIUS_RX_QUEUED:
radius_client_msg_free(req);
@@ -637,13 +626,13 @@ static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx)
fail:
radius_msg_free(msg);
- free(msg);
+ os_free(msg);
}
u8 radius_client_get_id(struct radius_client_data *radius)
{
- struct radius_msg_list *entry, *prev, *remove;
+ struct radius_msg_list *entry, *prev, *_remove;
u8 id = radius->next_radius_identifier++;
/* remove entries with matching id from retransmit list to avoid
@@ -661,36 +650,69 @@ u8 radius_client_get_id(struct radius_client_data *radius)
prev->next = entry->next;
else
radius->msgs = entry->next;
- remove = entry;
- } else
- remove = NULL;
- prev = entry;
+ _remove = entry;
+ } else {
+ _remove = NULL;
+ prev = entry;
+ }
entry = entry->next;
- if (remove)
- radius_client_msg_free(remove);
+ if (_remove)
+ radius_client_msg_free(_remove);
}
return id;
}
-void radius_client_flush(struct radius_client_data *radius)
+void radius_client_flush(struct radius_client_data *radius, int only_auth)
{
- struct radius_msg_list *entry, *prev;
+ struct radius_msg_list *entry, *prev, *tmp;
if (!radius)
return;
- eloop_cancel_timeout(radius_client_timer, radius, NULL);
-
+ prev = NULL;
entry = radius->msgs;
- radius->msgs = NULL;
- radius->num_msgs = 0;
+
while (entry) {
- prev = entry;
- entry = entry->next;
- radius_client_msg_free(prev);
+ if (!only_auth || entry->msg_type == RADIUS_AUTH) {
+ if (prev)
+ prev->next = entry->next;
+ else
+ radius->msgs = entry->next;
+
+ tmp = entry;
+ entry = entry->next;
+ radius_client_msg_free(tmp);
+ radius->num_msgs--;
+ } else {
+ prev = entry;
+ entry = entry->next;
+ }
+ }
+
+ if (radius->msgs == NULL)
+ eloop_cancel_timeout(radius_client_timer, radius, NULL);
+}
+
+
+void radius_client_update_acct_msgs(struct radius_client_data *radius,
+ u8 *shared_secret,
+ size_t shared_secret_len)
+{
+ struct radius_msg_list *entry;
+
+ if (!radius)
+ return;
+
+ for (entry = radius->msgs; entry; entry = entry->next) {
+ if (entry->msg_type == RADIUS_ACCT) {
+ entry->shared_secret = shared_secret;
+ entry->shared_secret_len = shared_secret_len;
+ radius_msg_finish_acct(entry->msg, shared_secret,
+ shared_secret_len);
+ }
}
}
@@ -709,6 +731,7 @@ radius_change_server(struct radius_client_data *radius,
socklen_t addrlen;
char abuf[50];
int sel_sock;
+ struct radius_msg_list *entry;
hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_INFO,
@@ -718,37 +741,43 @@ radius_change_server(struct radius_client_data *radius,
nserv->port);
if (!oserv || nserv->shared_secret_len != oserv->shared_secret_len ||
- memcmp(nserv->shared_secret, oserv->shared_secret,
- nserv->shared_secret_len) != 0) {
- /* Pending RADIUS packets used different shared
- * secret, so they would need to be modified. Could
- * update all message authenticators and
- * User-Passwords, etc. and retry with new server. For
- * now, just drop all pending packets. */
- radius_client_flush(radius);
- } else {
- /* Reset retry counters for the new server */
- struct radius_msg_list *entry;
- entry = radius->msgs;
- while (entry) {
- entry->next_try = entry->first_try +
- RADIUS_CLIENT_FIRST_WAIT;
- entry->attempts = 0;
- entry->next_wait = RADIUS_CLIENT_FIRST_WAIT * 2;
- entry = entry->next;
- }
- if (radius->msgs) {
- eloop_cancel_timeout(radius_client_timer, radius,
- NULL);
- eloop_register_timeout(RADIUS_CLIENT_FIRST_WAIT, 0,
- radius_client_timer, radius,
- NULL);
+ os_memcmp(nserv->shared_secret, oserv->shared_secret,
+ nserv->shared_secret_len) != 0) {
+ /* Pending RADIUS packets used different shared secret, so
+ * they need to be modified. Update accounting message
+ * authenticators here. Authentication messages are removed
+ * since they would require more changes and the new RADIUS
+ * server may not be prepared to receive them anyway due to
+ * missing state information. Client will likely retry
+ * authentication, so this should not be an issue. */
+ if (auth)
+ radius_client_flush(radius, 1);
+ else {
+ radius_client_update_acct_msgs(
+ radius, nserv->shared_secret,
+ nserv->shared_secret_len);
}
}
+ /* Reset retry counters for the new server */
+ for (entry = radius->msgs; entry; entry = entry->next) {
+ if ((auth && entry->msg_type != RADIUS_AUTH) ||
+ (!auth && entry->msg_type != RADIUS_ACCT))
+ continue;
+ entry->next_try = entry->first_try + RADIUS_CLIENT_FIRST_WAIT;
+ entry->attempts = 0;
+ entry->next_wait = RADIUS_CLIENT_FIRST_WAIT * 2;
+ }
+
+ if (radius->msgs) {
+ eloop_cancel_timeout(radius_client_timer, radius, NULL);
+ eloop_register_timeout(RADIUS_CLIENT_FIRST_WAIT, 0,
+ radius_client_timer, radius, NULL);
+ }
+
switch (nserv->addr.af) {
case AF_INET:
- memset(&serv, 0, sizeof(serv));
+ os_memset(&serv, 0, sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_addr.s_addr = nserv->addr.u.v4.s_addr;
serv.sin_port = htons(nserv->port);
@@ -758,10 +787,10 @@ radius_change_server(struct radius_client_data *radius,
break;
#ifdef CONFIG_IPV6
case AF_INET6:
- memset(&serv6, 0, sizeof(serv6));
+ os_memset(&serv6, 0, sizeof(serv6));
serv6.sin6_family = AF_INET6;
- memcpy(&serv6.sin6_addr, &nserv->addr.u.v6,
- sizeof(struct in6_addr));
+ os_memcpy(&serv6.sin6_addr, &nserv->addr.u.v6,
+ sizeof(struct in6_addr));
serv6.sin6_port = htons(nserv->port);
addr = (struct sockaddr *) &serv6;
addrlen = sizeof(serv6);
@@ -878,6 +907,17 @@ static int radius_client_init_acct(struct radius_client_data *radius)
else
ok++;
+#ifdef CONFIG_IPV6
+ radius->acct_serv_sock6 = socket(PF_INET6, SOCK_DGRAM, 0);
+ if (radius->acct_serv_sock6 < 0)
+ perror("socket[PF_INET6,SOCK_DGRAM]");
+ else
+ ok++;
+#endif /* CONFIG_IPV6 */
+
+ if (ok == 0)
+ return -1;
+
radius_change_server(radius, conf->acct_server, NULL,
radius->acct_serv_sock, radius->acct_serv_sock6,
0);
@@ -911,11 +951,10 @@ radius_client_init(void *ctx, struct hostapd_radius_servers *conf)
{
struct radius_client_data *radius;
- radius = malloc(sizeof(struct radius_client_data));
+ radius = wpa_zalloc(sizeof(struct radius_client_data));
if (radius == NULL)
return NULL;
- memset(radius, 0, sizeof(struct radius_client_data));
radius->ctx = ctx;
radius->conf = conf;
radius->auth_serv_sock = radius->acct_serv_sock =
@@ -946,12 +985,17 @@ void radius_client_deinit(struct radius_client_data *radius)
if (!radius)
return;
+ if (radius->auth_serv_sock >= 0)
+ eloop_unregister_read_sock(radius->auth_serv_sock);
+ if (radius->acct_serv_sock >= 0)
+ eloop_unregister_read_sock(radius->acct_serv_sock);
+
eloop_cancel_timeout(radius_retry_primary_timer, radius, NULL);
- radius_client_flush(radius);
- free(radius->auth_handlers);
- free(radius->acct_handlers);
- free(radius);
+ radius_client_flush(radius, 0);
+ os_free(radius->auth_handlers);
+ os_free(radius->acct_handlers);
+ os_free(radius);
}
@@ -963,7 +1007,7 @@ void radius_client_flush_auth(struct radius_client_data *radius, u8 *addr)
entry = radius->msgs;
while (entry) {
if (entry->msg_type == RADIUS_AUTH &&
- memcmp(entry->addr, addr, ETH_ALEN) == 0) {
+ os_memcmp(entry->addr, addr, ETH_ALEN) == 0) {
hostapd_logger(radius->ctx, addr,
HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_DEBUG,
@@ -1003,37 +1047,37 @@ static int radius_client_dump_auth_server(char *buf, size_t buflen,
}
}
- return snprintf(buf, buflen,
- "radiusAuthServerIndex=%d\n"
- "radiusAuthServerAddress=%s\n"
- "radiusAuthClientServerPortNumber=%d\n"
- "radiusAuthClientRoundTripTime=%d\n"
- "radiusAuthClientAccessRequests=%u\n"
- "radiusAuthClientAccessRetransmissions=%u\n"
- "radiusAuthClientAccessAccepts=%u\n"
- "radiusAuthClientAccessRejects=%u\n"
- "radiusAuthClientAccessChallenges=%u\n"
- "radiusAuthClientMalformedAccessResponses=%u\n"
- "radiusAuthClientBadAuthenticators=%u\n"
- "radiusAuthClientPendingRequests=%u\n"
- "radiusAuthClientTimeouts=%u\n"
- "radiusAuthClientUnknownTypes=%u\n"
- "radiusAuthClientPacketsDropped=%u\n",
- serv->index,
- hostapd_ip_txt(&serv->addr, abuf, sizeof(abuf)),
- serv->port,
- serv->round_trip_time,
- serv->requests,
- serv->retransmissions,
- serv->access_accepts,
- serv->access_rejects,
- serv->access_challenges,
- serv->malformed_responses,
- serv->bad_authenticators,
- pending,
- serv->timeouts,
- serv->unknown_types,
- serv->packets_dropped);
+ return os_snprintf(buf, buflen,
+ "radiusAuthServerIndex=%d\n"
+ "radiusAuthServerAddress=%s\n"
+ "radiusAuthClientServerPortNumber=%d\n"
+ "radiusAuthClientRoundTripTime=%d\n"
+ "radiusAuthClientAccessRequests=%u\n"
+ "radiusAuthClientAccessRetransmissions=%u\n"
+ "radiusAuthClientAccessAccepts=%u\n"
+ "radiusAuthClientAccessRejects=%u\n"
+ "radiusAuthClientAccessChallenges=%u\n"
+ "radiusAuthClientMalformedAccessResponses=%u\n"
+ "radiusAuthClientBadAuthenticators=%u\n"
+ "radiusAuthClientPendingRequests=%u\n"
+ "radiusAuthClientTimeouts=%u\n"
+ "radiusAuthClientUnknownTypes=%u\n"
+ "radiusAuthClientPacketsDropped=%u\n",
+ serv->index,
+ hostapd_ip_txt(&serv->addr, abuf, sizeof(abuf)),
+ serv->port,
+ serv->round_trip_time,
+ serv->requests,
+ serv->retransmissions,
+ serv->access_accepts,
+ serv->access_rejects,
+ serv->access_challenges,
+ serv->malformed_responses,
+ serv->bad_authenticators,
+ pending,
+ serv->timeouts,
+ serv->unknown_types,
+ serv->packets_dropped);
}
@@ -1053,33 +1097,33 @@ static int radius_client_dump_acct_server(char *buf, size_t buflen,
}
}
- return snprintf(buf, buflen,
- "radiusAccServerIndex=%d\n"
- "radiusAccServerAddress=%s\n"
- "radiusAccClientServerPortNumber=%d\n"
- "radiusAccClientRoundTripTime=%d\n"
- "radiusAccClientRequests=%u\n"
- "radiusAccClientRetransmissions=%u\n"
- "radiusAccClientResponses=%u\n"
- "radiusAccClientMalformedResponses=%u\n"
- "radiusAccClientBadAuthenticators=%u\n"
- "radiusAccClientPendingRequests=%u\n"
- "radiusAccClientTimeouts=%u\n"
- "radiusAccClientUnknownTypes=%u\n"
- "radiusAccClientPacketsDropped=%u\n",
- serv->index,
- hostapd_ip_txt(&serv->addr, abuf, sizeof(abuf)),
- serv->port,
- serv->round_trip_time,
- serv->requests,
- serv->retransmissions,
- serv->responses,
- serv->malformed_responses,
- serv->bad_authenticators,
- pending,
- serv->timeouts,
- serv->unknown_types,
- serv->packets_dropped);
+ return os_snprintf(buf, buflen,
+ "radiusAccServerIndex=%d\n"
+ "radiusAccServerAddress=%s\n"
+ "radiusAccClientServerPortNumber=%d\n"
+ "radiusAccClientRoundTripTime=%d\n"
+ "radiusAccClientRequests=%u\n"
+ "radiusAccClientRetransmissions=%u\n"
+ "radiusAccClientResponses=%u\n"
+ "radiusAccClientMalformedResponses=%u\n"
+ "radiusAccClientBadAuthenticators=%u\n"
+ "radiusAccClientPendingRequests=%u\n"
+ "radiusAccClientTimeouts=%u\n"
+ "radiusAccClientUnknownTypes=%u\n"
+ "radiusAccClientPacketsDropped=%u\n",
+ serv->index,
+ hostapd_ip_txt(&serv->addr, abuf, sizeof(abuf)),
+ serv->port,
+ serv->round_trip_time,
+ serv->requests,
+ serv->retransmissions,
+ serv->responses,
+ serv->malformed_responses,
+ serv->bad_authenticators,
+ pending,
+ serv->timeouts,
+ serv->unknown_types,
+ serv->packets_dropped);
}
@@ -1113,3 +1157,48 @@ int radius_client_get_mib(struct radius_client_data *radius, char *buf,
return count;
}
+
+
+static int radius_servers_diff(struct hostapd_radius_server *nserv,
+ struct hostapd_radius_server *oserv,
+ int num)
+{
+ int i;
+
+ for (i = 0; i < num; i++) {
+ if (hostapd_ip_diff(&nserv[i].addr, &oserv[i].addr) ||
+ nserv[i].port != oserv[i].port ||
+ nserv[i].shared_secret_len != oserv[i].shared_secret_len ||
+ memcmp(nserv[i].shared_secret, oserv[i].shared_secret,
+ nserv[i].shared_secret_len) != 0)
+ return 1;
+ }
+
+ return 0;
+}
+
+
+struct radius_client_data *
+radius_client_reconfig(struct radius_client_data *old, void *ctx,
+ struct hostapd_radius_servers *oldconf,
+ struct hostapd_radius_servers *newconf)
+{
+ radius_client_flush(old, 0);
+
+ if (newconf->retry_primary_interval !=
+ oldconf->retry_primary_interval ||
+ newconf->num_auth_servers != oldconf->num_auth_servers ||
+ newconf->num_acct_servers != oldconf->num_acct_servers ||
+ radius_servers_diff(newconf->auth_servers, oldconf->auth_servers,
+ newconf->num_auth_servers) ||
+ radius_servers_diff(newconf->acct_servers, oldconf->acct_servers,
+ newconf->num_acct_servers)) {
+ hostapd_logger(ctx, NULL, HOSTAPD_MODULE_RADIUS,
+ HOSTAPD_LEVEL_DEBUG,
+ "Reconfiguring RADIUS client");
+ radius_client_deinit(old);
+ return radius_client_init(ctx, newconf);
+ }
+
+ return old;
+}
OpenPOWER on IntegriCloud