From 304364719cc2de16146d84e2a7ff424cab9afbc4 Mon Sep 17 00:00:00 2001 From: Siddharth Narayan Date: Sun, 21 Dec 2025 21:07:55 -0500 Subject: [PATCH 1/3] Add radius retry timeout in configuration --- src/Cedar/Admin.c | 6 ++++-- src/Cedar/Admin.h | 1 + src/Cedar/Hub.c | 34 +++++++++++++++++++++++----------- src/Cedar/Hub.h | 7 ++++--- src/Cedar/Server.c | 9 ++++++++- src/Mayaqua/Network.h | 2 -- 6 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/Cedar/Admin.c b/src/Cedar/Admin.c index eeb99201..dda7fa62 100644 --- a/src/Cedar/Admin.c +++ b/src/Cedar/Admin.c @@ -8739,7 +8739,7 @@ UINT StSetHubRadius(ADMIN *a, RPC_RADIUS *t) } //SetRadiusServer(h, t->RadiusServerName, t->RadiusPort, t->RadiusSecret); - SetRadiusServerEx(h, t->RadiusServerName, t->RadiusPort, t->RadiusSecret, t->RadiusRetryInterval); + SetRadiusServerEx(h, t->RadiusServerName, t->RadiusPort, t->RadiusSecret, t->RadiusRetryInterval, t->RadiusRetryTimeout); ALog(a, h, "LA_SET_HUB_RADIUS"); @@ -8779,7 +8779,7 @@ UINT StGetHubRadius(ADMIN *a, RPC_RADIUS *t) //GetRadiusServer(h, t->RadiusServerName, sizeof(t->RadiusServerName), // &t->RadiusPort, t->RadiusSecret, sizeof(t->RadiusSecret)); GetRadiusServerEx(h, t->RadiusServerName, sizeof(t->RadiusServerName), - &t->RadiusPort, t->RadiusSecret, sizeof(t->RadiusSecret), &t->RadiusRetryInterval); + &t->RadiusPort, t->RadiusSecret, sizeof(t->RadiusSecret), &t->RadiusRetryInterval, &t->RadiusRetryTimeout); ReleaseHub(h); @@ -13031,6 +13031,7 @@ void InRpcRadius(RPC_RADIUS *t, PACK *p) PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName)); PackGetStr(p, "RadiusSecret", t->RadiusSecret, sizeof(t->RadiusSecret)); t->RadiusRetryInterval = PackGetInt(p, "RadiusRetryInterval"); + t->RadiusRetryTimeout = PackGetInt(p, "RadiusRetryTimeout"); } void OutRpcRadius(PACK *p, RPC_RADIUS *t) { @@ -13045,6 +13046,7 @@ void OutRpcRadius(PACK *p, RPC_RADIUS *t) PackAddStr(p, "HubName", t->HubName); PackAddStr(p, "RadiusSecret", t->RadiusSecret); PackAddInt(p, "RadiusRetryInterval", t->RadiusRetryInterval); + PackAddInt(p, "RadiusRetryTimeout", t->RadiusRetryTimeout); } // RPC_HUB diff --git a/src/Cedar/Admin.h b/src/Cedar/Admin.h index e6e5faaf..4e951a41 100644 --- a/src/Cedar/Admin.h +++ b/src/Cedar/Admin.h @@ -259,6 +259,7 @@ struct RPC_RADIUS UINT RadiusPort; // Radius port number char RadiusSecret[MAX_PASSWORD_LEN + 1]; // Secret key UINT RadiusRetryInterval; // Radius retry interval + UINT RadiusRetryTimeout; // Radius retry timeout }; // Specify the HUB diff --git a/src/Cedar/Hub.c b/src/Cedar/Hub.c index 1677d605..8cbcd536 100644 --- a/src/Cedar/Hub.c +++ b/src/Cedar/Hub.c @@ -99,6 +99,7 @@ EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, ch char radius_servers[MAX_PATH] = {0}; UINT radius_port = 0; UINT radius_retry_interval = 0; + UINT radius_retry_timeout = 0; char radius_secret[MAX_PATH] = {0}; char radius_suffix_filter[MAX_PATH] = {0}; if (cedar == NULL || hubname == NULL || client_ip_str == NULL || username == NULL) @@ -116,7 +117,7 @@ EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, ch if (hub != NULL) { if (GetRadiusServerEx2(hub, radius_servers, sizeof(radius_servers), &radius_port, radius_secret, - sizeof(radius_secret), &radius_retry_interval, radius_suffix_filter, sizeof(radius_suffix_filter))) + sizeof(radius_secret), &radius_retry_interval, &radius_retry_timeout, radius_suffix_filter, sizeof(radius_suffix_filter))) { bool use_peap = hub->RadiusUsePeapInsteadOfEap; @@ -6415,17 +6416,18 @@ void ReleaseHub(HUB *h) bool GetRadiusServer(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size) { UINT interval; - return GetRadiusServerEx(hub, name, size, port, secret, secret_size, &interval); + UINT timeout; + return GetRadiusServerEx(hub, name, size, port, secret, secret_size, &interval, &timeout); } -bool GetRadiusServerEx(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval) +bool GetRadiusServerEx(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, UINT *timeout) { - return GetRadiusServerEx2(hub, name, size, port, secret, secret_size, interval, NULL, 0); + return GetRadiusServerEx2(hub, name, size, port, secret, secret_size, interval, timeout, NULL, 0); } -bool GetRadiusServerEx2(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, char *suffix_filter, UINT suffix_filter_size) +bool GetRadiusServerEx2(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, UINT *timeout, char *suffix_filter, UINT suffix_filter_size) { bool ret = false; // Validate arguments - if (hub == NULL || name == NULL || port == NULL || secret == NULL || interval == NULL) + if (hub == NULL || name == NULL || port == NULL || secret == NULL || interval == NULL || timeout == NULL) { return false; } @@ -6439,6 +6441,7 @@ bool GetRadiusServerEx2(HUB *hub, char *name, UINT size, UINT *port, char *secre StrCpy(name, size, hub->RadiusServerName); *port = hub->RadiusServerPort; *interval = hub->RadiusRetryInterval; + *timeout = hub->RadiusRetryTimeout; tmp_size = hub->RadiusSecret->Size + 1; tmp = ZeroMalloc(tmp_size); @@ -6462,9 +6465,9 @@ bool GetRadiusServerEx2(HUB *hub, char *name, UINT size, UINT *port, char *secre // Set the Radius server information void SetRadiusServer(HUB *hub, char *name, UINT port, char *secret) { - SetRadiusServerEx(hub, name, port, secret, RADIUS_RETRY_INTERVAL); + SetRadiusServerEx(hub, name, port, secret, RADIUS_RETRY_INTERVAL, RADIUS_RETRY_TIMEOUT); } -void SetRadiusServerEx(HUB *hub, char *name, UINT port, char *secret, UINT interval) +void SetRadiusServerEx(HUB *hub, char *name, UINT port, char *secret, UINT interval, UINT timeout) { // Validate arguments if (hub == NULL) @@ -6484,19 +6487,28 @@ void SetRadiusServerEx(HUB *hub, char *name, UINT port, char *secret, UINT inter hub->RadiusServerName = NULL; hub->RadiusServerPort = 0; hub->RadiusRetryInterval = RADIUS_RETRY_INTERVAL; + hub->RadiusRetryTimeout = RADIUS_RETRY_TIMEOUT; + FreeBuf(hub->RadiusSecret); } else { hub->RadiusServerName = CopyStr(name); hub->RadiusServerPort = port; + + if (timeout == 0) { + timeout = RADIUS_RETRY_TIMEOUT; + } + hub->RadiusRetryTimeout = timeout; + if (interval == 0) { - hub->RadiusRetryInterval = RADIUS_RETRY_INTERVAL; + hub->RadiusRetryInterval = RADIUS_RETRY_INTERVAL; ///What happens here is that RADIUS_RETRY_TIMEOUT is not configurable, and RADIUS_RETRY_INTERVAL is set to the timeout if it's larger. } - else if (interval > RADIUS_RETRY_TIMEOUT) + + if (interval > timeout) { - hub->RadiusRetryInterval = RADIUS_RETRY_TIMEOUT; + hub->RadiusRetryInterval = timeout; } else { diff --git a/src/Cedar/Hub.h b/src/Cedar/Hub.h index a47984f6..61f234d7 100644 --- a/src/Cedar/Hub.h +++ b/src/Cedar/Hub.h @@ -341,6 +341,7 @@ struct HUB char *RadiusServerName; // Radius server name UINT RadiusServerPort; // Radius server port number UINT RadiusRetryInterval; // Radius retry interval + UINT RadiusRetryTimeout; // Radius timeout, it will no longer retry BUF *RadiusSecret; // Radius shared key char RadiusSuffixFilter[MAX_SIZE]; // Radius suffix filter char RadiusRealm[MAX_SIZE]; // Radius realm (optional) @@ -481,10 +482,10 @@ bool IsPacketMaskedByAccessList(SESSION *s, PKT *p, ACCESS *a, UINT64 dest_usern void GetAccessListStr(char *str, UINT size, ACCESS *a); void DeleteOldIpTableEntry(LIST *o); void SetRadiusServer(HUB *hub, char *name, UINT port, char *secret); -void SetRadiusServerEx(HUB *hub, char *name, UINT port, char *secret, UINT interval); +void SetRadiusServerEx(HUB *hub, char *name, UINT port, char *secret, UINT interval, UINT timeout); bool GetRadiusServer(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size); -bool GetRadiusServerEx(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval); -bool GetRadiusServerEx2(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, char *suffix_filter, UINT suffix_filter_size); +bool GetRadiusServerEx(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, UINT *timeout); +bool GetRadiusServerEx2(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, UINT *timeout, char *suffix_filter, UINT suffix_filter_size); int CompareCert(void *p1, void *p2); void GetHubLogSetting(HUB *h, HUB_LOG *setting); void SetHubLogSetting(HUB *h, HUB_LOG *setting); diff --git a/src/Cedar/Server.c b/src/Cedar/Server.c index 08b8345b..59ddef72 100644 --- a/src/Cedar/Server.c +++ b/src/Cedar/Server.c @@ -4855,6 +4855,7 @@ void SiWriteHubCfg(FOLDER *f, HUB *h) } CfgAddInt(f, "RadiusServerPort", h->RadiusServerPort); CfgAddInt(f, "RadiusRetryInterval", h->RadiusRetryInterval); + CfgAddInt(f, "RadiusRetryTimeout", h->RadiusRetryTimeout); CfgAddStr(f, "RadiusSuffixFilter", h->RadiusSuffixFilter); CfgAddStr(f, "RadiusRealm", h->RadiusRealm); @@ -5020,9 +5021,11 @@ void SiLoadHubCfg(SERVER *s, FOLDER *f, char *name) BUF *secret; UINT port; UINT interval; + UINT timeout; port = CfgGetInt(f, "RadiusServerPort"); interval = CfgGetInt(f, "RadiusRetryInterval"); + timeout = CfgGetInt(f, "RadiusRetryTimeout"); CfgGetStr(f, "RadiusSuffixFilter", h->RadiusSuffixFilter, sizeof(h->RadiusSuffixFilter)); CfgGetStr(f, "RadiusRealm", h->RadiusRealm, sizeof(h->RadiusRealm)); @@ -5035,6 +5038,10 @@ void SiLoadHubCfg(SERVER *s, FOLDER *f, char *name) interval = RADIUS_RETRY_INTERVAL; } + if (timeout == 0) { + timeout = RADIUS_RETRY_TIMEOUT; + } + if (port != 0 && CfgGetStr(f, "RadiusServerName", name, sizeof(name))) { secret = CfgGetBuf(f, "RadiusSecret"); @@ -5048,7 +5055,7 @@ void SiLoadHubCfg(SERVER *s, FOLDER *f, char *name) } secret_str[sizeof(secret_str) - 1] = 0; //SetRadiusServer(h, name, port, secret_str); - SetRadiusServerEx(h, name, port, secret_str, interval); + SetRadiusServerEx(h, name, port, secret_str, interval, timeout); FreeBuf(secret); } } diff --git a/src/Mayaqua/Network.h b/src/Mayaqua/Network.h index 2aa8d1f7..5d1aece2 100644 --- a/src/Mayaqua/Network.h +++ b/src/Mayaqua/Network.h @@ -881,8 +881,6 @@ struct SSL_VERIFY_OPTION X *SavedCert; // Saved server certificate }; -#define SSL_DEFAULT_CONNECT_TIMEOUT (15 * 1000) // SSL default timeout - // Header for TCP Pair struct TCP_PAIR_HEADER { From c32184495b34999930d5a0a832adffe3c36146c3 Mon Sep 17 00:00:00 2001 From: Siddharth Narayan Date: Sun, 21 Dec 2025 21:10:32 -0500 Subject: [PATCH 2/3] Add server-side NOOP upload for connection keepalive --- src/Cedar/Protocol.c | 20 +++++++++++++++++++- src/Cedar/Protocol.h | 1 + src/Mayaqua/HTTP.c | 28 ++++++++++++++++++++++++++-- src/Mayaqua/Pack.h | 2 ++ 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/Cedar/Protocol.c b/src/Cedar/Protocol.c index b61abc1e..7efd3397 100644 --- a/src/Cedar/Protocol.c +++ b/src/Cedar/Protocol.c @@ -5429,7 +5429,7 @@ void ClientUploadNoop(CONNECTION *c) } p = PackError(0); - PackAddInt(p, "noop", 1); + PackAddInt(p, "noop", NOOP); (void)HttpClientSend(c->FirstSock, p); FreePack(p); @@ -5440,6 +5440,24 @@ void ClientUploadNoop(CONNECTION *c) } } +void ServerUploadNoop(CONNECTION *c) +{ + PACK *p; + // Validate arguments + if (c == NULL) + { + return; + } + + p = PackError(0); + PackAddInt(p, "noop", NOOP_IGNORE); + (void)HttpServerSend(c->FirstSock, p); + FreePack(p); + + // Client can't re-respond to an HTTP "response" + // so we don't wait for it on the server side +} + // Add client version information to the PACK void PackAddClientVersion(PACK *p, CONNECTION *c) { diff --git a/src/Cedar/Protocol.h b/src/Cedar/Protocol.h index 112b365a..ac982767 100644 --- a/src/Cedar/Protocol.h +++ b/src/Cedar/Protocol.h @@ -169,6 +169,7 @@ bool GetSessionKeyFromPack(PACK *p, UCHAR *session_key, UINT *session_key_32); void CreateNodeInfo(NODE_INFO *info, CONNECTION *c); UINT SecureSign(SECURE_SIGN *sign, UINT device_id, char *pin); void ClientUploadNoop(CONNECTION *c); +void ServerUploadNoop(CONNECTION *c); bool ClientCheckServerCert(CONNECTION *c, bool *expired); void ClientCheckServerCertThread(THREAD *thread, void *param); bool ClientSecureSign(CONNECTION *c, UCHAR *sign, UCHAR *random, X **x); diff --git a/src/Mayaqua/HTTP.c b/src/Mayaqua/HTTP.c index 22ace11b..ba6dcc23 100644 --- a/src/Mayaqua/HTTP.c +++ b/src/Mayaqua/HTTP.c @@ -1207,12 +1207,14 @@ PACK *HttpClientRecv(SOCK *s) UINT size; UCHAR *tmp; HTTP_VALUE *v; + UINT num_noop = 0; // Validate arguments if (s == NULL) { return NULL; } +START: h = RecvHttpHeader(s); if (h == NULL) { @@ -1257,6 +1259,22 @@ PACK *HttpClientRecv(SOCK *s) p = BufToPack(b); FreeBuf(b); + // Client shouldn't receive a noop other than NOOP_IGNORE + // because it can't respond without a full new HTTP request + UINT noop = PackGetInt(p, "noop"); + if (noop == NOOP_IGNORE) { + Debug("recv: noop ignore\n"); + FreePack(p); + + num_noop++; + + if (num_noop > MAX_NOOP_PER_SESSION) + { + return NULL; + } + + goto START; + } return p; } @@ -1365,13 +1383,14 @@ START: FreeBuf(b); // Determine whether it's a NOOP - if (PackGetInt(p, "noop") != 0) + UINT noop = PackGetInt(p, "noop"); + if (noop == NOOP) { Debug("recv: noop\n"); FreePack(p); p = PackError(0); - PackAddInt(p, "noop", 1); + PackAddInt(p, "noop", NOOP_IGNORE); if (HttpServerSend(s, p) == false) { FreePack(p); @@ -1387,6 +1406,11 @@ START: return NULL; } + goto START; + } else if (noop == NOOP_IGNORE) { + Debug("recv: noop ignore\n"); + FreePack(p); + goto START; } diff --git a/src/Mayaqua/Pack.h b/src/Mayaqua/Pack.h index 1f93cd58..ef3cffe1 100644 --- a/src/Mayaqua/Pack.h +++ b/src/Mayaqua/Pack.h @@ -38,6 +38,8 @@ // The number of allowable NOOP #define MAX_NOOP_PER_SESSION 30 +#define NOOP 1 +#define NOOP_IGNORE 2 // A noop, but don't send a response noop // VALUE object struct VALUE From bbda0c298d1500e6acd1c0f7046b549f843c1290 Mon Sep 17 00:00:00 2001 From: Siddharth Narayan Date: Wed, 18 Feb 2026 00:44:18 -0600 Subject: [PATCH 3/3] Implement extended-timeout radius login --- src/Cedar/Admin.c | 4 ++-- src/Cedar/Command.c | 7 +++++++ src/Cedar/Hub.c | 23 ++++++++++++++++------- src/Cedar/Hub.h | 8 +++++--- src/Cedar/Radius.c | 19 +++++++++++++++---- src/Cedar/Radius.h | 2 +- src/Cedar/Sam.c | 5 +++-- src/Cedar/Server.c | 2 +- 8 files changed, 50 insertions(+), 20 deletions(-) diff --git a/src/Cedar/Admin.c b/src/Cedar/Admin.c index dda7fa62..a6c59f48 100644 --- a/src/Cedar/Admin.c +++ b/src/Cedar/Admin.c @@ -8739,7 +8739,7 @@ UINT StSetHubRadius(ADMIN *a, RPC_RADIUS *t) } //SetRadiusServer(h, t->RadiusServerName, t->RadiusPort, t->RadiusSecret); - SetRadiusServerEx(h, t->RadiusServerName, t->RadiusPort, t->RadiusSecret, t->RadiusRetryInterval, t->RadiusRetryTimeout); + SetRadiusServerEx2(h, t->RadiusServerName, t->RadiusPort, t->RadiusSecret, t->RadiusRetryInterval, t->RadiusRetryTimeout); ALog(a, h, "LA_SET_HUB_RADIUS"); @@ -8778,7 +8778,7 @@ UINT StGetHubRadius(ADMIN *a, RPC_RADIUS *t) Zero(t, sizeof(RPC_RADIUS)); //GetRadiusServer(h, t->RadiusServerName, sizeof(t->RadiusServerName), // &t->RadiusPort, t->RadiusSecret, sizeof(t->RadiusSecret)); - GetRadiusServerEx(h, t->RadiusServerName, sizeof(t->RadiusServerName), + GetRadiusServerEx2(h, t->RadiusServerName, sizeof(t->RadiusServerName), &t->RadiusPort, t->RadiusSecret, sizeof(t->RadiusSecret), &t->RadiusRetryInterval, &t->RadiusRetryTimeout); ReleaseHub(h); diff --git a/src/Cedar/Command.c b/src/Cedar/Command.c index dce502bb..848d620e 100644 --- a/src/Cedar/Command.c +++ b/src/Cedar/Command.c @@ -11789,6 +11789,9 @@ UINT PsRadiusServerSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param) {"[server_name:port]", CmdPrompt, _UU("CMD_RadiusServerSet_Prompt_Host"), CmdEvalNotEmpty, NULL}, {"SECRET", CmdPromptChoosePassword, _UU("CMD_RadiusServerSet_Prompt_Secret"), NULL, NULL}, {"RETRY_INTERVAL", CmdPrompt, _UU("CMD_RadiusServerSet_Prompt_RetryInterval"), CmdEvalMinMax, &minmax}, + + // Support for setting timeout through commandline not added + // {"RETRY_TIMEOUT", CmdPrompt, _UU("CMD_RadiusServerSet_Prompt_RetryTimeout"), CmdEvalMinMax, &minmax}, }; // If virtual HUB is not selected, it's an error @@ -11813,6 +11816,7 @@ UINT PsRadiusServerSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param) StrCpy(t.RadiusServerName, sizeof(t.RadiusServerName), host); StrCpy(t.RadiusSecret, sizeof(t.RadiusSecret), GetParamStr(o, "SECRET")); t.RadiusRetryInterval = GetParamInt(o, "RETRY_INTERVAL"); + // t.RadiusRetryTimeout = GetParamInt(o, "RETRY_TIMEOUT"); Free(host); @@ -11936,6 +11940,9 @@ UINT PsRadiusServerGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param) UniToStri(tmp, t.RadiusRetryInterval); CtInsert(ct, _UU("CMD_RadiusServerGet_RetryInterval"), tmp); + + UniToStri(tmp, t.RadiusRetryTimeout); + CtInsert(ct, _UU("CMD_RadiusServerGet_RetryTimeout"), tmp); } CtFree(ct, c); diff --git a/src/Cedar/Hub.c b/src/Cedar/Hub.c index 8cbcd536..774da34d 100644 --- a/src/Cedar/Hub.c +++ b/src/Cedar/Hub.c @@ -116,7 +116,7 @@ EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, ch if (hub != NULL) { - if (GetRadiusServerEx2(hub, radius_servers, sizeof(radius_servers), &radius_port, radius_secret, + if (GetRadiusServerEx3(hub, radius_servers, sizeof(radius_servers), &radius_port, radius_secret, sizeof(radius_secret), &radius_retry_interval, &radius_retry_timeout, radius_suffix_filter, sizeof(radius_suffix_filter))) { bool use_peap = hub->RadiusUsePeapInsteadOfEap; @@ -6416,14 +6416,19 @@ void ReleaseHub(HUB *h) bool GetRadiusServer(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size) { UINT interval; + + return GetRadiusServerEx(hub, name, size, port, secret, secret_size, &interval); +} +bool GetRadiusServerEx(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval) { UINT timeout; - return GetRadiusServerEx(hub, name, size, port, secret, secret_size, &interval, &timeout); + + return GetRadiusServerEx2(hub, name, size, port, secret, secret_size, interval, timeout); } -bool GetRadiusServerEx(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, UINT *timeout) +bool GetRadiusServerEx2(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, UINT *timeout) { - return GetRadiusServerEx2(hub, name, size, port, secret, secret_size, interval, timeout, NULL, 0); + return GetRadiusServerEx3(hub, name, size, port, secret, secret_size, interval, timeout, NULL, 0); } -bool GetRadiusServerEx2(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, UINT *timeout, char *suffix_filter, UINT suffix_filter_size) +bool GetRadiusServerEx3(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, UINT *timeout, char *suffix_filter, UINT suffix_filter_size) { bool ret = false; // Validate arguments @@ -6465,9 +6470,13 @@ bool GetRadiusServerEx2(HUB *hub, char *name, UINT size, UINT *port, char *secre // Set the Radius server information void SetRadiusServer(HUB *hub, char *name, UINT port, char *secret) { - SetRadiusServerEx(hub, name, port, secret, RADIUS_RETRY_INTERVAL, RADIUS_RETRY_TIMEOUT); + SetRadiusServerEx(hub, name, port, secret, RADIUS_RETRY_INTERVAL); } -void SetRadiusServerEx(HUB *hub, char *name, UINT port, char *secret, UINT interval, UINT timeout) +void SetRadiusServerEx(HUB *hub, char *name, UINT port, char *secret, UINT interval) +{ + SetRadiusServerEx2(hub, name, port, secret, interval, RADIUS_RETRY_TIMEOUT); +} +void SetRadiusServerEx2(HUB *hub, char *name, UINT port, char *secret, UINT interval, UINT timeout) { // Validate arguments if (hub == NULL) diff --git a/src/Cedar/Hub.h b/src/Cedar/Hub.h index 61f234d7..0c740700 100644 --- a/src/Cedar/Hub.h +++ b/src/Cedar/Hub.h @@ -482,10 +482,12 @@ bool IsPacketMaskedByAccessList(SESSION *s, PKT *p, ACCESS *a, UINT64 dest_usern void GetAccessListStr(char *str, UINT size, ACCESS *a); void DeleteOldIpTableEntry(LIST *o); void SetRadiusServer(HUB *hub, char *name, UINT port, char *secret); -void SetRadiusServerEx(HUB *hub, char *name, UINT port, char *secret, UINT interval, UINT timeout); +void SetRadiusServerEx(HUB *hub, char *name, UINT port, char *secret, UINT interval); +void SetRadiusServerEx2(HUB *hub, char *name, UINT port, char *secret, UINT interval, UINT timeout); bool GetRadiusServer(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size); -bool GetRadiusServerEx(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, UINT *timeout); -bool GetRadiusServerEx2(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, UINT *timeout, char *suffix_filter, UINT suffix_filter_size); +bool GetRadiusServerEx(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval); +bool GetRadiusServerEx2(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, UINT *timeout); +bool GetRadiusServerEx3(HUB *hub, char *name, UINT size, UINT *port, char *secret, UINT secret_size, UINT *interval, UINT *timeout, char *suffix_filter, UINT suffix_filter_size); int CompareCert(void *p1, void *p2); void GetHubLogSetting(HUB *h, HUB_LOG *setting); void SetHubLogSetting(HUB *h, HUB_LOG *setting); diff --git a/src/Cedar/Radius.c b/src/Cedar/Radius.c index c17c5b42..08e6727b 100644 --- a/src/Cedar/Radius.c +++ b/src/Cedar/Radius.c @@ -7,6 +7,7 @@ #include "Radius.h" +#include "Protocol.h" #include "Connection.h" #include "IPC.h" #include "Server.h" @@ -1767,7 +1768,7 @@ LABEL_ERROR: ////////// Classical implementation // Attempts Radius authentication (with specifying retry interval and multiple server) -bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT secret_size, wchar_t *username, char *password, UINT interval, UCHAR *mschap_v2_server_response_20, +bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT secret_size, wchar_t *username, char *password, UINT interval, UINT timeout, UCHAR *mschap_v2_server_response_20, RADIUS_LOGIN_OPTION *opt, char *hubname) { UCHAR random[MD5_SIZE]; @@ -2072,14 +2073,22 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec // Transmission process start start = Tick64(); + + // Limit timeout to be larger than hardcoded timeout + // Limit interval to be larger than the hardcoded interval and less than timeout + if (timeout < RADIUS_RETRY_TIMEOUT) { + timeout = RADIUS_RETRY_TIMEOUT; + } + if(interval < RADIUS_RETRY_INTERVAL) { interval = RADIUS_RETRY_INTERVAL; } - else if(interval > RADIUS_RETRY_TIMEOUT) + else if(interval > timeout) { - interval = RADIUS_RETRY_TIMEOUT; + interval = timeout; } + next_send_time = start + (UINT64)interval; while (true) @@ -2099,6 +2108,8 @@ SEND_RETRY: next_send_time = Tick64() + (UINT64)interval; RECV_RETRY: + ServerUploadNoop(c); + now = Tick64(); if (next_send_time <= now) { @@ -2109,7 +2120,7 @@ RECV_RETRY: goto SEND_RETRY; } - if ((start + RADIUS_RETRY_TIMEOUT) < now) + if ((start + timeout) < now) { // Time-out break; diff --git a/src/Cedar/Radius.h b/src/Cedar/Radius.h index ccae30c9..8d3b880d 100644 --- a/src/Cedar/Radius.h +++ b/src/Cedar/Radius.h @@ -283,7 +283,7 @@ struct RADIUS_LOGIN_OPTION }; // Function prototype -bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT secret_size, wchar_t *username, char *password, UINT interval, UCHAR *mschap_v2_server_response_20, +bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT secret_size, wchar_t *username, char *password, UINT interval, UINT timeout, UCHAR *mschap_v2_server_response_20, RADIUS_LOGIN_OPTION *opt, char *hubname); BUF *RadiusEncryptPassword(char *password, UCHAR *random, UCHAR *secret, UINT secret_size); BUF *RadiusCreateUserName(wchar_t *username); diff --git a/src/Cedar/Sam.c b/src/Cedar/Sam.c index 4a223d64..511d5e9d 100644 --- a/src/Cedar/Sam.c +++ b/src/Cedar/Sam.c @@ -516,6 +516,7 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p char suffix_filter[MAX_SIZE]; wchar_t suffix_filter_w[MAX_SIZE]; UINT interval; + UINT timeout; EAP_CLIENT *eap = NULL; char password1[MAX_SIZE]; UCHAR client_challenge[16]; @@ -586,7 +587,7 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p } // Get the Radius server information - if (GetRadiusServerEx2(hub, radius_server_addr, sizeof(radius_server_addr), &radius_server_port, radius_secret, sizeof(radius_secret), &interval, suffix_filter, sizeof(suffix_filter))) + if (GetRadiusServerEx3(hub, radius_server_addr, sizeof(radius_server_addr), &radius_server_port, radius_secret, sizeof(radius_secret), &interval, &timeout, suffix_filter, sizeof(suffix_filter))) { Unlock(hub->lock); @@ -597,7 +598,7 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p // Attempt to login b = RadiusLogin(c, radius_server_addr, radius_server_port, radius_secret, StrLen(radius_secret), - name, password, interval, mschap_v2_server_response_20, opt, hub->Name); + name, password, interval, timeout, mschap_v2_server_response_20, opt, hub->Name); if (b) { diff --git a/src/Cedar/Server.c b/src/Cedar/Server.c index 59ddef72..f23399b0 100644 --- a/src/Cedar/Server.c +++ b/src/Cedar/Server.c @@ -5055,7 +5055,7 @@ void SiLoadHubCfg(SERVER *s, FOLDER *f, char *name) } secret_str[sizeof(secret_str) - 1] = 0; //SetRadiusServer(h, name, port, secret_str); - SetRadiusServerEx(h, name, port, secret_str, interval, timeout); + SetRadiusServerEx2(h, name, port, secret_str, interval, timeout); FreeBuf(secret); } }