diff options
| author | Dmitry Shmidt <dimitrysh@google.com> | 2014-06-02 13:50:35 -0700 |
|---|---|---|
| committer | Dmitry Shmidt <dimitrysh@google.com> | 2014-06-02 13:50:35 -0700 |
| commit | 717574375e969e8272c6d1a26137286eac158abb (patch) | |
| tree | cd44844dacf9673caeedbad792d6f89f39fdf49c /src/radius | |
| parent | 76cd2cc44b62e858f1897ce58f4ce7d0174e8839 (diff) | |
| download | android_external_wpa_supplicant_8-717574375e969e8272c6d1a26137286eac158abb.tar.gz android_external_wpa_supplicant_8-717574375e969e8272c6d1a26137286eac158abb.tar.bz2 android_external_wpa_supplicant_8-717574375e969e8272c6d1a26137286eac158abb.zip | |
Cumulative patch from commit 801e117376e13d5b3c50f1627b93a949529fdf99
801e117 Fix validation of RSN EAPOL-Key version for GCMP with PMF
3d4d234 FT: Fix GTK rekeying after FT protocol
d3d0483 nl80211: Work around error case prints for nl_recvmsgs on Android
8a387a2 P2P NFC: Fix use of freed memory
df48efc Fix external radio work stopping to not read freed memory
13c3303 SAE: Fix memory leak in random number generation
d92bdf9 hostapd: Make sure hapd->drv_priv gets cleared on driver deinit
438e133 hostapd: Use helper function to avoid duplicate deinit calls
ac1a224 hostapd: Clean up if interface setup fails
81c4fca hostapd: Reset hapd->interface_add properly
3fbd036 hostapd: Prevent double interface disabling from segfaulting
ea39367 nl80211: Fix wpa_driver_nl80211_if_add() failure paths
b77aeae Interworking: Re-trigger scan if no connect attempt is done
b523973 RADIUS client: Trigger failover more quickly if socket is not valid
09844c0 RADIUS client: Do not flush pending messages if server did not change
5d67bf1 hostapd: Fix configuration of multiple RADIUS servers with SET
70d4084 RADIUS client: Fix socket close/re-open on server change
d045cc8 RADIUS client: Fix crash issue in radius_client_timer()
c1fb75a RADIUS client: Handle ENETUNREACH similarly to other failure cases
9ed4076 RADIUS client: Do not try to send message without socket
cc0b7cb hostapd_cli: Fix segmentation fault with interface command
114153b P2P: Debug print channel lists for invitation processing
4eb3b76 OpenSSL: Fix OCSP certificate debug print to use wpa_printf
f6fb192 HS 2.0R2: Fix subscr_remediation_method for RADIUS server
74879f3 Remove extra newline from a debug print
Change-Id: I82d4f00501fabb8b325e4461178b45e7b2c0178e
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'src/radius')
| -rw-r--r-- | src/radius/radius_client.c | 117 | ||||
| -rw-r--r-- | src/radius/radius_server.c | 1 |
2 files changed, 92 insertions, 26 deletions
diff --git a/src/radius/radius_client.c b/src/radius/radius_client.c index 76259966..10056a64 100644 --- a/src/radius/radius_client.c +++ b/src/radius/radius_client.c @@ -295,26 +295,34 @@ int radius_client_register(struct radius_client_data *radius, } -static void radius_client_handle_send_error(struct radius_client_data *radius, - int s, RadiusType msg_type) +/* + * Returns >0 if message queue was flushed (i.e., the message that triggered + * the error is not available anymore) + */ +static int radius_client_handle_send_error(struct radius_client_data *radius, + int s, RadiusType msg_type) { #ifndef CONFIG_NATIVE_WINDOWS int _errno = errno; wpa_printf(MSG_INFO, "send[RADIUS]: %s", strerror(errno)); if (_errno == ENOTCONN || _errno == EDESTADDRREQ || _errno == EINVAL || - _errno == EBADF) { + _errno == EBADF || _errno == ENETUNREACH) { hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO, "Send failed - maybe interface status changed -" " try to connect again"); - eloop_unregister_read_sock(s); - close(s); - if (msg_type == RADIUS_ACCT || msg_type == RADIUS_ACCT_INTERIM) + if (msg_type == RADIUS_ACCT || + msg_type == RADIUS_ACCT_INTERIM) { radius_client_init_acct(radius); - else + return 0; + } else { radius_client_init_auth(radius); + return 1; + } } #endif /* CONFIG_NATIVE_WINDOWS */ + + return 0; } @@ -353,8 +361,11 @@ static int radius_client_retransmit(struct radius_client_data *radius, os_get_reltime(&entry->last_attempt); buf = radius_msg_get_buf(entry->msg); - if (send(s, wpabuf_head(buf), wpabuf_len(buf), 0) < 0) - radius_client_handle_send_error(radius, s, entry->msg_type); + if (send(s, wpabuf_head(buf), wpabuf_len(buf), 0) < 0) { + if (radius_client_handle_send_error(radius, s, entry->msg_type) + > 0) + return 0; + } entry->next_try = now + entry->next_wait; entry->next_wait *= 2; @@ -378,6 +389,8 @@ static void radius_client_timer(void *eloop_ctx, void *timeout_ctx) struct radius_msg_list *entry, *prev, *tmp; int auth_failover = 0, acct_failover = 0; char abuf[50]; + size_t prev_num_msgs; + int s; entry = radius->msgs; if (!entry) @@ -388,6 +401,7 @@ static void radius_client_timer(void *eloop_ctx, void *timeout_ctx) prev = NULL; while (entry) { + prev_num_msgs = radius->num_msgs; if (now.sec >= entry->next_try && radius_client_retransmit(radius, entry, now.sec)) { if (prev) @@ -402,7 +416,18 @@ static void radius_client_timer(void *eloop_ctx, void *timeout_ctx) continue; } - if (entry->attempts > RADIUS_CLIENT_NUM_FAILOVER) { + if (prev_num_msgs != radius->num_msgs) { + wpa_printf(MSG_DEBUG, + "RADIUS: Message removed from queue - restart from beginning"); + entry = radius->msgs; + prev = NULL; + continue; + } + + s = entry->msg_type == RADIUS_AUTH ? radius->auth_sock : + radius->acct_sock; + if (entry->attempts > RADIUS_CLIENT_NUM_FAILOVER || + (s < 0 && entry->attempts > 0)) { if (entry->msg_type == RADIUS_ACCT || entry->msg_type == RADIUS_ACCT_INTERIM) acct_failover++; @@ -633,7 +658,7 @@ int radius_client_send(struct radius_client_data *radius, } if (msg_type == RADIUS_ACCT || msg_type == RADIUS_ACCT_INTERIM) { - if (conf->acct_server == NULL) { + if (conf->acct_server == NULL || radius->acct_sock < 0) { hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO, @@ -647,7 +672,7 @@ int radius_client_send(struct radius_client_data *radius, s = radius->acct_sock; conf->acct_server->requests++; } else { - if (conf->auth_server == NULL) { + if (conf->auth_server == NULL || radius->auth_sock < 0) { hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO, @@ -951,9 +976,10 @@ radius_change_server(struct radius_client_data *radius, hostapd_ip_txt(&nserv->addr, abuf, sizeof(abuf)), nserv->port); - if (!oserv || nserv->shared_secret_len != oserv->shared_secret_len || - os_memcmp(nserv->shared_secret, oserv->shared_secret, - nserv->shared_secret_len) != 0) { + if (oserv && oserv != nserv && + (nserv->shared_secret_len != oserv->shared_secret_len || + 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 @@ -971,7 +997,8 @@ radius_change_server(struct radius_client_data *radius, } /* Reset retry counters for the new server */ - for (entry = radius->msgs; entry; entry = entry->next) { + for (entry = radius->msgs; oserv && oserv != nserv && entry; + entry = entry->next) { if ((auth && entry->msg_type != RADIUS_AUTH) || (!auth && entry->msg_type != RADIUS_ACCT)) continue; @@ -1128,11 +1155,51 @@ static int radius_client_disable_pmtu_discovery(int s) } +static void radius_close_auth_sockets(struct radius_client_data *radius) +{ + radius->auth_sock = -1; + + if (radius->auth_serv_sock >= 0) { + eloop_unregister_read_sock(radius->auth_serv_sock); + close(radius->auth_serv_sock); + radius->auth_serv_sock = -1; + } +#ifdef CONFIG_IPV6 + if (radius->auth_serv_sock6 >= 0) { + eloop_unregister_read_sock(radius->auth_serv_sock6); + close(radius->auth_serv_sock6); + radius->auth_serv_sock6 = -1; + } +#endif /* CONFIG_IPV6 */ +} + + +static void radius_close_acct_sockets(struct radius_client_data *radius) +{ + radius->acct_sock = -1; + + if (radius->acct_serv_sock >= 0) { + eloop_unregister_read_sock(radius->acct_serv_sock); + close(radius->acct_serv_sock); + radius->acct_serv_sock = -1; + } +#ifdef CONFIG_IPV6 + if (radius->acct_serv_sock6 >= 0) { + eloop_unregister_read_sock(radius->acct_serv_sock6); + close(radius->acct_serv_sock6); + radius->acct_serv_sock6 = -1; + } +#endif /* CONFIG_IPV6 */ +} + + static int radius_client_init_auth(struct radius_client_data *radius) { struct hostapd_radius_servers *conf = radius->conf; int ok = 0; + radius_close_auth_sockets(radius); + radius->auth_serv_sock = socket(PF_INET, SOCK_DGRAM, 0); if (radius->auth_serv_sock < 0) wpa_printf(MSG_INFO, "RADIUS: socket[PF_INET,SOCK_DGRAM]: %s", @@ -1163,6 +1230,7 @@ static int radius_client_init_auth(struct radius_client_data *radius) radius_client_receive, radius, (void *) RADIUS_AUTH)) { wpa_printf(MSG_INFO, "RADIUS: Could not register read socket for authentication server"); + radius_close_auth_sockets(radius); return -1; } @@ -1172,6 +1240,7 @@ static int radius_client_init_auth(struct radius_client_data *radius) radius_client_receive, radius, (void *) RADIUS_AUTH)) { wpa_printf(MSG_INFO, "RADIUS: Could not register read socket for authentication server"); + radius_close_auth_sockets(radius); return -1; } #endif /* CONFIG_IPV6 */ @@ -1185,6 +1254,8 @@ static int radius_client_init_acct(struct radius_client_data *radius) struct hostapd_radius_servers *conf = radius->conf; int ok = 0; + radius_close_acct_sockets(radius); + radius->acct_serv_sock = socket(PF_INET, SOCK_DGRAM, 0); if (radius->acct_serv_sock < 0) wpa_printf(MSG_INFO, "RADIUS: socket[PF_INET,SOCK_DGRAM]: %s", @@ -1215,6 +1286,7 @@ static int radius_client_init_acct(struct radius_client_data *radius) radius_client_receive, radius, (void *) RADIUS_ACCT)) { wpa_printf(MSG_INFO, "RADIUS: Could not register read socket for accounting server"); + radius_close_acct_sockets(radius); return -1; } @@ -1224,6 +1296,7 @@ static int radius_client_init_acct(struct radius_client_data *radius) radius_client_receive, radius, (void *) RADIUS_ACCT)) { wpa_printf(MSG_INFO, "RADIUS: Could not register read socket for accounting server"); + radius_close_acct_sockets(radius); return -1; } #endif /* CONFIG_IPV6 */ @@ -1285,16 +1358,8 @@ 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); -#ifdef CONFIG_IPV6 - if (radius->auth_serv_sock6 >= 0) - eloop_unregister_read_sock(radius->auth_serv_sock6); - if (radius->acct_serv_sock6 >= 0) - eloop_unregister_read_sock(radius->acct_serv_sock6); -#endif /* CONFIG_IPV6 */ + radius_close_auth_sockets(radius); + radius_close_acct_sockets(radius); eloop_cancel_timeout(radius_retry_primary_timer, radius, NULL); diff --git a/src/radius/radius_server.c b/src/radius/radius_server.c index bd358ae9..78c99614 100644 --- a/src/radius/radius_server.c +++ b/src/radius/radius_server.c @@ -1730,6 +1730,7 @@ radius_server_init(struct radius_server_conf *conf) data->subscr_remediation_url = os_strdup(conf->subscr_remediation_url); } + data->subscr_remediation_method = conf->subscr_remediation_method; #ifdef CONFIG_SQLITE if (conf->sqlite_file) { |
