1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-26 19:39:53 +03:00

Merge PR #1008: Adding RADIUS and L3 MAC address fixing function, with small bug-fixes

This commit is contained in:
Davide Beatrici 2019-10-19 19:37:21 +02:00 committed by GitHub
commit 2aeec323f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 246 additions and 61 deletions

View File

@ -1272,3 +1272,49 @@ int CompareUserName(void *p1, void *p2)
return StrCmpi(u1->Name, u2->Name); return StrCmpi(u1->Name, u2->Name);
} }
// Get the MAC address from the user's note string
bool GetUserMacAddressFromUserNote(UCHAR *mac, wchar_t *note)
{
bool ret = false;
UINT i;
Zero(mac, 6);
if (mac == NULL || note == NULL)
{
return false;
}
i = UniSearchStrEx(note, USER_MAC_STR_PREFIX, 0, false);
if (i != INFINITE)
{
wchar_t *macstr_start = &note[i + UniStrLen(USER_MAC_STR_PREFIX)];
wchar_t macstr2[MAX_SIZE];
UNI_TOKEN_LIST *tokens;
UniStrCpy(macstr2, sizeof(macstr2), macstr_start);
UniTrim(macstr2);
tokens = UniParseToken(macstr2, L" ,/()[].");
if (tokens != NULL)
{
if (tokens->NumTokens >= 1)
{
wchar_t *macstr = tokens->Token[0];
if (UniIsEmptyStr(macstr) == false)
{
char macstr_a[MAX_SIZE];
UniToStr(macstr_a, sizeof(macstr_a), macstr);
ret = StrToMac(mac, macstr_a);
}
}
UniFreeToken(tokens);
}
}
return ret;
}

View File

@ -8,6 +8,8 @@
#ifndef ACCOUNT_H #ifndef ACCOUNT_H
#define ACCOUNT_H #define ACCOUNT_H
#define USER_MAC_STR_PREFIX L"MAC:"
// Policy item // Policy item
struct POLICY_ITEM struct POLICY_ITEM
{ {
@ -202,6 +204,7 @@ char *PolicyIdToStr(UINT i);
POLICY_ITEM *GetPolicyItem(UINT id); POLICY_ITEM *GetPolicyItem(UINT id);
void GetPolicyValueRangeStr(wchar_t *str, UINT size, UINT id); void GetPolicyValueRangeStr(wchar_t *str, UINT size, UINT id);
void FormatPolicyValue(wchar_t *str, UINT size, UINT id, UINT value); void FormatPolicyValue(wchar_t *str, UINT size, UINT id, UINT value);
bool GetUserMacAddressFromUserNote(UCHAR *mac, wchar_t *note);
#endif // ACCOUNT_H #endif // ACCOUNT_H

View File

@ -207,6 +207,7 @@ struct CONNECTION
void *hWndForUI; // Parent window void *hWndForUI; // Parent window
bool IsInProc; // In-process bool IsInProc; // In-process
char InProcPrefix[64]; // Prefix char InProcPrefix[64]; // Prefix
UINT InProcLayer; // InProc layer
UINT AdditionalConnectionFailedCounter; // Additional connection failure counter UINT AdditionalConnectionFailedCounter; // Additional connection failure counter
UINT64 LastCounterResetTick; // Time the counter was reset finally UINT64 LastCounterResetTick; // Time the counter was reset finally
bool WasSstp; // Processed the SSTP bool WasSstp; // Processed the SSTP

View File

@ -62,7 +62,7 @@ UINT num_admin_options = sizeof(admin_options) / sizeof(ADMIN_OPTION);
// Create an EAP client for the specified Virtual Hub // Create an EAP client for the specified Virtual Hub
EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username) EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username, char *vpn_protocol_state_str)
{ {
HUB *hub = NULL; HUB *hub = NULL;
EAP_CLIENT *ret = NULL; EAP_CLIENT *ret = NULL;
@ -112,6 +112,11 @@ EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, ch
if (eap != NULL) if (eap != NULL)
{ {
if (IsEmptyStr(vpn_protocol_state_str) == false)
{
StrCpy(eap->In_VpnProtocolState, sizeof(eap->In_VpnProtocolState), vpn_protocol_state_str);
}
if (use_peap == false) if (use_peap == false)
{ {
// EAP // EAP

View File

@ -532,7 +532,7 @@ bool IsUserMatchInUserList(LIST *o, char *filename, UINT64 user_hash);
bool IsUserMatchInUserListWithCacheExpires(LIST *o, char *filename, UINT64 user_hash, UINT64 lifetime); bool IsUserMatchInUserListWithCacheExpires(LIST *o, char *filename, UINT64 user_hash, UINT64 lifetime);
bool IsUserMatchInUserListWithCacheExpiresAcl(LIST *o, char *name_in_acl, UINT64 user_hash, UINT64 lifetime); bool IsUserMatchInUserListWithCacheExpiresAcl(LIST *o, char *name_in_acl, UINT64 user_hash, UINT64 lifetime);
bool CheckMaxLoggedPacketsPerMinute(SESSION *s, UINT max_packets, UINT64 now); bool CheckMaxLoggedPacketsPerMinute(SESSION *s, UINT max_packets, UINT64 now);
EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username); EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username, char *vpn_protocol_state_str);
#endif // HUB_H #endif // HUB_H

View File

@ -217,7 +217,7 @@ IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code)
param->UserName, param->Password, error_code, &param->ClientIp, param->UserName, param->Password, error_code, &param->ClientIp,
param->ClientPort, &param->ServerIp, param->ServerPort, param->ClientPort, &param->ServerIp, param->ServerPort,
param->ClientHostname, param->CryptName, param->ClientHostname, param->CryptName,
param->BridgeMode, param->Mss, NULL, param->ClientCertificate); param->BridgeMode, param->Mss, NULL, param->ClientCertificate, param->Layer);
return ipc; return ipc;
} }
@ -226,7 +226,8 @@ IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code)
IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password, IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password,
UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port, UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port,
char *client_hostname, char *crypt_name, char *client_hostname, char *crypt_name,
bool bridge_mode, UINT mss, EAP_CLIENT *eap_client, X *client_certificate) bool bridge_mode, UINT mss, EAP_CLIENT *eap_client, X *client_certificate,
UINT layer)
{ {
IPC *ipc; IPC *ipc;
UINT dummy_int = 0; UINT dummy_int = 0;
@ -274,6 +275,12 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
ipc->Cedar = cedar; ipc->Cedar = cedar;
AddRef(cedar->ref); AddRef(cedar->ref);
ipc->Layer = layer;
if (ipc->Layer == 0)
{
ipc->Layer = IPC_LAYER_2;
}
ipc->FlushList = NewTubeFlushList(); ipc->FlushList = NewTubeFlushList();
StrCpy(ipc->ClientHostname, sizeof(ipc->ClientHostname), client_hostname); StrCpy(ipc->ClientHostname, sizeof(ipc->ClientHostname), client_hostname);
@ -368,6 +375,7 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
PackAddStr(p, "inproc_postfix", postfix); PackAddStr(p, "inproc_postfix", postfix);
PackAddStr(p, "inproc_cryptname", crypt_name); PackAddStr(p, "inproc_cryptname", crypt_name);
PackAddInt(p, "inproc_layer", ipc->Layer);
// Node information // Node information
Zero(&info, sizeof(info)); Zero(&info, sizeof(info));

View File

@ -21,6 +21,9 @@
#define IPC_PASSWORD_MSCHAPV2_TAG "xH7DiNlurDhcYV4a:" #define IPC_PASSWORD_MSCHAPV2_TAG "xH7DiNlurDhcYV4a:"
#define IPC_LAYER_2 2
#define IPC_LAYER_3 3
// ARP table entry // ARP table entry
struct IPC_ARP struct IPC_ARP
{ {
@ -58,6 +61,7 @@ struct IPC_PARAM
UINT Mss; UINT Mss;
bool IsL3Mode; bool IsL3Mode;
X *ClientCertificate; X *ClientCertificate;
UINT Layer;
}; };
// IPC_ASYNC object // IPC_ASYNC object
@ -102,6 +106,7 @@ struct IPC
TUBE_FLUSH_LIST *FlushList; // Tube Flush List TUBE_FLUSH_LIST *FlushList; // Tube Flush List
UCHAR MsChapV2_ServerResponse[20]; // Server response UCHAR MsChapV2_ServerResponse[20]; // Server response
DHCP_CLASSLESS_ROUTE_TABLE ClasslessRoute; // Classless routing table DHCP_CLASSLESS_ROUTE_TABLE ClasslessRoute; // Classless routing table
UINT Layer;
}; };
// MS-CHAPv2 authentication information // MS-CHAPv2 authentication information
@ -117,7 +122,8 @@ struct IPC_MSCHAP_V2_AUTHINFO
IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password, IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password,
UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port, UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port,
char *client_hostname, char *crypt_name, char *client_hostname, char *crypt_name,
bool bridge_mode, UINT mss, EAP_CLIENT *eap_client, X *client_certificate); bool bridge_mode, UINT mss, EAP_CLIENT *eap_client, X *client_certificate,
UINT layer);
IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code); IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code);
IPC *NewIPCBySock(CEDAR *cedar, SOCK *s, void *mac_address); IPC *NewIPCBySock(CEDAR *cedar, SOCK *s, void *mac_address);
void FreeIPC(IPC *ipc); void FreeIPC(IPC *ipc);

View File

@ -64,7 +64,7 @@ void EtherIPIpcConnectThread(THREAD *t, void *p)
&s->ClientIP, s->ClientPort, &s->ClientIP, s->ClientPort,
&s->ServerIP, s->ServerPort, &s->ServerIP, s->ServerPort,
tmp, tmp,
s->CryptName, true, mss, NULL, NULL); s->CryptName, true, mss, NULL, NULL, IPC_LAYER_2);
if (ipc != NULL) if (ipc != NULL)
{ {

View File

@ -1071,6 +1071,8 @@ void OvsBeginIPCAsyncConnectionIfEmpty(OPENVPN_SERVER *s, OPENVPN_SESSION *se, O
} }
} }
p.Layer = (se->Mode == OPENVPN_MODE_L2) ? IPC_LAYER_2 : IPC_LAYER_3;
// Calculate the MSS // Calculate the MSS
p.Mss = OvsCalcTcpMss(s, se, c); p.Mss = OvsCalcTcpMss(s, se, c);
Debug("MSS=%u\n", p.Mss); Debug("MSS=%u\n", p.Mss);

View File

@ -202,7 +202,7 @@ void PPPThread(THREAD *thread, void *param)
IPToStr(client_ip_tmp, sizeof(client_ip_tmp), &p->ClientIP); IPToStr(client_ip_tmp, sizeof(client_ip_tmp), &p->ClientIP);
eap = HubNewEapClient(p->Cedar, hub, client_ip_tmp, id); eap = HubNewEapClient(p->Cedar, hub, client_ip_tmp, id, "L3:PPP");
if (eap) if (eap)
{ {
@ -913,7 +913,8 @@ PPP_PACKET *PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *req)
// Attempt to connect with IPC // Attempt to connect with IPC
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password, ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password,
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort, &error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
p->ClientHostname, p->CryptName, false, p->AdjustMss, p->EapClient, NULL); p->ClientHostname, p->CryptName, false, p->AdjustMss, p->EapClient, NULL,
IPC_LAYER_3);
if (ipc != NULL) if (ipc != NULL)
{ {
@ -1046,7 +1047,8 @@ PPP_PACKET *PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *req)
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password, ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password,
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort, &error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
p->ClientHostname, p->CryptName, false, p->AdjustMss, NULL, NULL); p->ClientHostname, p->CryptName, false, p->AdjustMss, NULL, NULL,
IPC_LAYER_3);
if (ipc != NULL) if (ipc != NULL)
{ {

View File

@ -1788,6 +1788,7 @@ bool ServerAccept(CONNECTION *c)
UINT authtype; UINT authtype;
POLICY *policy; POLICY *policy;
UINT assigned_vlan_id = 0; UINT assigned_vlan_id = 0;
UCHAR assigned_ipc_mac_address[6];
HUB *hub; HUB *hub;
SESSION *s = NULL; SESSION *s = NULL;
UINT64 user_expires = 0; UINT64 user_expires = 0;
@ -1856,6 +1857,8 @@ bool ServerAccept(CONNECTION *c)
Zero(ctoken_hash_str, sizeof(ctoken_hash_str)); Zero(ctoken_hash_str, sizeof(ctoken_hash_str));
Zero(assigned_ipc_mac_address, sizeof(assigned_ipc_mac_address));
Zero(mschap_v2_server_response_20, sizeof(mschap_v2_server_response_20)); Zero(mschap_v2_server_response_20, sizeof(mschap_v2_server_response_20));
Zero(&udp_acceleration_client_ip, sizeof(udp_acceleration_client_ip)); Zero(&udp_acceleration_client_ip, sizeof(udp_acceleration_client_ip));
@ -2190,6 +2193,7 @@ bool ServerAccept(CONNECTION *c)
PackGetStr(p, "inproc_postfix", c->InProcPrefix, sizeof(c->InProcPrefix)); PackGetStr(p, "inproc_postfix", c->InProcPrefix, sizeof(c->InProcPrefix));
Zero(tmp, sizeof(tmp)); Zero(tmp, sizeof(tmp));
PackGetStr(p, "inproc_cryptname", tmp, sizeof(tmp)); PackGetStr(p, "inproc_cryptname", tmp, sizeof(tmp));
c->InProcLayer = PackGetInt(p, "inproc_layer");
if (c->FirstSock != NULL) if (c->FirstSock != NULL)
{ {
@ -2214,6 +2218,9 @@ bool ServerAccept(CONNECTION *c)
} }
use_udp_acceleration_client = false; use_udp_acceleration_client = false;
Format(radius_login_opt.In_VpnProtocolState, sizeof(radius_login_opt.In_VpnProtocolState),
"L%u:%s", c->InProcLayer, c->InProcPrefix);
} }
else else
{ {
@ -2227,6 +2234,9 @@ bool ServerAccept(CONNECTION *c)
{ {
c->CipherName = CopyStr(c->FirstSock->CipherName); c->CipherName = CopyStr(c->FirstSock->CipherName);
} }
Format(radius_login_opt.In_VpnProtocolState, sizeof(radius_login_opt.In_VpnProtocolState),
"L%u:%s", IPC_LAYER_2, "SEVPN");
} }
if (support_bulk_on_rudp && c->FirstSock != NULL && c->FirstSock->IsRUDPSocket && if (support_bulk_on_rudp && c->FirstSock != NULL && c->FirstSock->IsRUDPSocket &&
@ -2784,11 +2794,19 @@ bool ServerAccept(CONNECTION *c)
} }
} }
// Check the assigned MAC Address
if (radius_login_opt.Out_IsRadiusLogin)
{
Copy(assigned_ipc_mac_address, radius_login_opt.Out_VirtualMacAddress, 6);
}
if (StrCmpi(username, ADMINISTRATOR_USERNAME) != 0) if (StrCmpi(username, ADMINISTRATOR_USERNAME) != 0)
{ {
// Get the policy // Get the policy
if (farm_member == false) if (farm_member == false)
{ {
bool is_asterisk_user = false;
// In the case of not a farm member // In the case of not a farm member
user = AcGetUser(hub, username); user = AcGetUser(hub, username);
if (user == NULL) if (user == NULL)
@ -2803,12 +2821,29 @@ bool ServerAccept(CONNECTION *c)
error_detail = "AcGetUser"; error_detail = "AcGetUser";
goto CLEANUP; goto CLEANUP;
} }
is_asterisk_user = true;
} }
policy = NULL; policy = NULL;
Lock(user->lock); Lock(user->lock);
{ {
if (is_asterisk_user == false)
{
UCHAR associated_mac_address[6];
// Get the associated virtual MAC address
if (GetUserMacAddressFromUserNote(associated_mac_address, user->Note))
{
if (IsZero(assigned_ipc_mac_address, 6))
{
WHERE;
Copy(assigned_ipc_mac_address, associated_mac_address, 6);
}
}
}
// Get the expiration date // Get the expiration date
user_expires = user->ExpireTime; user_expires = user->ExpireTime;
@ -3478,7 +3513,8 @@ bool ServerAccept(CONNECTION *c)
// Create a Session // Create a Session
StrLower(username); StrLower(username);
s = NewServerSessionEx(c->Cedar, c, hub, username, policy, c->IsInProc); s = NewServerSessionEx(c->Cedar, c, hub, username, policy, c->IsInProc,
(c->IsInProc && IsZero(assigned_ipc_mac_address, 6) == false) ? assigned_ipc_mac_address : NULL);
s->EnableUdpRecovery = enable_udp_recovery; s->EnableUdpRecovery = enable_udp_recovery;
s->LocalHostSession = local_host_session; s->LocalHostSession = local_host_session;

View File

@ -217,11 +217,11 @@ bool SendPeapRawPacket(EAP_CLIENT *e, UCHAR *peap_data, UINT peap_size)
fragments = NewListFast(NULL); fragments = NewListFast(NULL);
for (num = 0;;num++) for (num = 0;;num++)
{ {
UCHAR tmp[1024]; UCHAR tmp[200];
EAP_PEAP *send_peap_message; EAP_PEAP *send_peap_message;
UINT sz; UINT sz;
sz = ReadBuf(buf, tmp, 1024); sz = ReadBuf(buf, tmp, 200);
if (sz == 0) if (sz == 0)
{ {
@ -593,6 +593,11 @@ void EapSetRadiusGeneralAttributes(RADIUS_PACKET *r, EAP_CLIENT *e)
Add(r->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_NAS_ID, 0, 0, CEDAR_SERVER_STR, StrLen(CEDAR_SERVER_STR))); Add(r->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_NAS_ID, 0, 0, CEDAR_SERVER_STR, StrLen(CEDAR_SERVER_STR)));
if (IsEmptyStr(e->In_VpnProtocolState) == false)
{
Add(r->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_PROXY_STATE, 0, 0, e->In_VpnProtocolState, StrLen(e->In_VpnProtocolState)));
}
ui = Endian32(2); ui = Endian32(2);
Add(r->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, Add(r->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT,
RADIUS_MS_NETWORK_ACCESS_SERVER_TYPE, &ui, sizeof(UINT))); RADIUS_MS_NETWORK_ACCESS_SERVER_TYPE, &ui, sizeof(UINT)));
@ -914,11 +919,27 @@ RADIUS_PACKET *EapSendPacketAndRecvResponse(EAP_CLIENT *e, RADIUS_PACKET *r)
{ {
RADIUS_AVP *eap_msg = GetRadiusAvp(rp, RADIUS_ATTRIBUTE_EAP_MESSAGE); RADIUS_AVP *eap_msg = GetRadiusAvp(rp, RADIUS_ATTRIBUTE_EAP_MESSAGE);
RADIUS_AVP *vlan_avp = GetRadiusAvp(rp, RADIUS_ATTRIBUTE_VLAN_ID); RADIUS_AVP *vlan_avp = GetRadiusAvp(rp, RADIUS_ATTRIBUTE_VLAN_ID);
RADIUS_AVP *framed_interface_id_avp = GetRadiusAvp(rp, RADIUS_ATTRIBUTE_FRAMED_INTERFACE_ID);
if (eap_msg != NULL) if (eap_msg != NULL)
{ {
e->LastRecvEapId = ((EAP_MESSAGE *)(eap_msg->Data))->Id; e->LastRecvEapId = ((EAP_MESSAGE *)(eap_msg->Data))->Id;
} }
if (framed_interface_id_avp != NULL)
{
// FRAMED_INTERFACE_ID
char tmp_str[64];
UCHAR mac_address[6];
Zero(tmp_str, sizeof(tmp_str));
Copy(tmp_str, framed_interface_id_avp->Data, MIN(framed_interface_id_avp->DataSize, sizeof(tmp_str) - 1));
if (StrToMac(mac_address, tmp_str))
{
Copy(e->LastRecvVirtualMacAddress, mac_address, 6);
}
}
if (vlan_avp != NULL) if (vlan_avp != NULL)
{ {
// VLAN ID // VLAN ID
@ -1642,6 +1663,11 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec
// Try the EAP authentication for RADIUS first // Try the EAP authentication for RADIUS first
EAP_CLIENT *eap = mschap.MsChapV2_EapClient; EAP_CLIENT *eap = mschap.MsChapV2_EapClient;
if (IsEmptyStr(opt->In_VpnProtocolState) == false)
{
StrCpy(eap->In_VpnProtocolState, sizeof(eap->In_VpnProtocolState), opt->In_VpnProtocolState);
}
if (eap->PeapMode == false) if (eap->PeapMode == false)
{ {
ret = EapClientSendMsChapv2AuthClientResponse(eap, mschap.MsChapV2_ClientResponse, ret = EapClientSendMsChapv2AuthClientResponse(eap, mschap.MsChapV2_ClientResponse,
@ -1662,6 +1688,8 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec
opt->Out_VLanId = eap->LastRecvVLanId; opt->Out_VLanId = eap->LastRecvVLanId;
} }
Copy(opt->Out_VirtualMacAddress, eap->LastRecvVirtualMacAddress, 6);
return true; return true;
} }
else else
@ -1776,31 +1804,31 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec
// Service-Type // Service-Type
ui = Endian32(2); ui = Endian32(2);
RadiusAddValue(p, 6, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_SERVICE_TYPE, 0, 0, &ui, sizeof(ui));
// NAS-Port-Type // NAS-Port-Type
ui = Endian32(5); ui = Endian32(5);
RadiusAddValue(p, 61, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_NAS_PORT_TYPE, 0, 0, &ui, sizeof(ui));
// Tunnel-Type // Tunnel-Type
ui = Endian32(1); ui = Endian32(1);
RadiusAddValue(p, 64, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_TYPE, 0, 0, &ui, sizeof(ui));
// Tunnel-Medium-Type // Tunnel-Medium-Type
ui = Endian32(1); ui = Endian32(1);
RadiusAddValue(p, 65, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_MEDIUM_TYPE, 0, 0, &ui, sizeof(ui));
// Called-Station-ID - VPN Hub Name // Called-Station-ID - VPN Hub Name
if (IsEmptyStr(hubname) == false) if (IsEmptyStr(hubname) == false)
{ {
RadiusAddValue(p, 30, 0, 0, hubname, StrLen(hubname)); RadiusAddValue(p, RADIUS_ATTRIBUTE_CALLED_STATION_ID, 0, 0, hubname, StrLen(hubname));
} }
// Calling-Station-Id // Calling-Station-Id
RadiusAddValue(p, 31, 0, 0, client_ip_str, StrLen(client_ip_str)); RadiusAddValue(p, RADIUS_ATTRIBUTE_CALLING_STATION_ID, 0, 0, client_ip_str, StrLen(client_ip_str));
// Tunnel-Client-Endpoint // Tunnel-Client-Endpoint
RadiusAddValue(p, 66, 0, 0, client_ip_str, StrLen(client_ip_str)); RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_CLIENT_ENDPOINT, 0, 0, client_ip_str, StrLen(client_ip_str));
} }
else else
{ {
@ -1814,69 +1842,74 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec
// Acct-Session-Id // Acct-Session-Id
us = Endian16(session_id % 254 + 1); us = Endian16(session_id % 254 + 1);
session_id++; session_id++;
RadiusAddValue(p, 44, 0, 0, &us, sizeof(us)); RadiusAddValue(p, RADIUS_ATTRIBUTE_ACCT_SESSION_ID, 0, 0, &us, sizeof(us));
// NAS-IP-Address // NAS-IP-Address
if (c != NULL && c->FirstSock != NULL && c->FirstSock->IPv6 == false) if (c != NULL && c->FirstSock != NULL && c->FirstSock->IPv6 == false)
{ {
ui = IPToUINT(&c->FirstSock->LocalIP); ui = IPToUINT(&c->FirstSock->LocalIP);
RadiusAddValue(p, 4, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_NAS_IP, 0, 0, &ui, sizeof(ui));
} }
// Service-Type // Service-Type
ui = Endian32(2); ui = Endian32(2);
RadiusAddValue(p, 6, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_SERVICE_TYPE, 0, 0, &ui, sizeof(ui));
// MS-RAS-Vendor // MS-RAS-Vendor
ui = Endian32(311); RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_VERSION, ms_ras_version, StrLen(ms_ras_version));
RadiusAddValue(p, 26, 311, 9, &ui, sizeof(ui));
// MS-RAS-Version // MS-RAS-Version
RadiusAddValue(p, 26, 311, 18, ms_ras_version, StrLen(ms_ras_version)); RadiusAddValue(p, 26, 311, 18, ms_ras_version, StrLen(ms_ras_version));
// NAS-Port-Type // NAS-Port-Type
ui = Endian32(5); ui = Endian32(5);
RadiusAddValue(p, 61, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_NAS_PORT_TYPE, 0, 0, &ui, sizeof(ui));
// Tunnel-Type // Tunnel-Type
ui = Endian32(1); ui = Endian32(1);
RadiusAddValue(p, 64, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_TYPE, 0, 0, &ui, sizeof(ui));
// Tunnel-Medium-Type // Tunnel-Medium-Type
ui = Endian32(1); ui = Endian32(1);
RadiusAddValue(p, 65, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_MEDIUM_TYPE, 0, 0, &ui, sizeof(ui));
// Called-Station-ID - VPN Hub Name // Called-Station-ID - VPN Hub Name
if (IsEmptyStr(hubname) == false) if (IsEmptyStr(hubname) == false)
{ {
RadiusAddValue(p, 30, 0, 0, hubname, StrLen(hubname)); RadiusAddValue(p, RADIUS_ATTRIBUTE_CALLED_STATION_ID, 0, 0, hubname, StrLen(hubname));
} }
// Calling-Station-Id // Calling-Station-Id
RadiusAddValue(p, 31, 0, 0, client_ip_str, StrLen(client_ip_str)); RadiusAddValue(p, RADIUS_ATTRIBUTE_CALLING_STATION_ID, 0, 0, client_ip_str, StrLen(client_ip_str));
// Tunnel-Client-Endpoint // Tunnel-Client-Endpoint
RadiusAddValue(p, 66, 0, 0, client_ip_str, StrLen(client_ip_str)); RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_CLIENT_ENDPOINT, 0, 0, client_ip_str, StrLen(client_ip_str));
// MS-RAS-Client-Version // MS-RAS-Client-Version
RadiusAddValue(p, 26, 311, 35, ms_ras_version, StrLen(ms_ras_version)); RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_RAS_CLIENT_VERSION, ms_ras_version, StrLen(ms_ras_version));
// MS-RAS-Client-Name // MS-RAS-Client-Name
RadiusAddValue(p, 26, 311, 34, client_ip_str, StrLen(client_ip_str)); RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_RAS_CLIENT_NAME, client_ip_str, StrLen(client_ip_str));
// MS-CHAP-Challenge // MS-CHAP-Challenge
RadiusAddValue(p, 26, 311, 11, mschap.MsChapV2_ServerChallenge, sizeof(mschap.MsChapV2_ServerChallenge)); RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_CHAP_CHALLENGE, mschap.MsChapV2_ServerChallenge, sizeof(mschap.MsChapV2_ServerChallenge));
// MS-CHAP2-Response // MS-CHAP2-Response
Zero(ms_chapv2_response, sizeof(ms_chapv2_response)); Zero(ms_chapv2_response, sizeof(ms_chapv2_response));
Copy(ms_chapv2_response + 2, mschap.MsChapV2_ClientChallenge, 16); Copy(ms_chapv2_response + 2, mschap.MsChapV2_ClientChallenge, 16);
Copy(ms_chapv2_response + 2 + 16 + 8, mschap.MsChapV2_ClientResponse, 24); Copy(ms_chapv2_response + 2 + 16 + 8, mschap.MsChapV2_ClientResponse, 24);
RadiusAddValue(p, 26, 311, 25, ms_chapv2_response, sizeof(ms_chapv2_response)); RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_CHAP2_RESPONSE, ms_chapv2_response, sizeof(ms_chapv2_response));
// NAS-ID // NAS-ID
WriteBuf(p, nas_id->Buf, nas_id->Size); WriteBuf(p, nas_id->Buf, nas_id->Size);
} }
if (IsEmptyStr(opt->In_VpnProtocolState) == false)
{
// Proxy state as protocol details
RadiusAddValue(p, RADIUS_ATTRIBUTE_PROXY_STATE, 0, 0, opt->In_VpnProtocolState, StrLen(opt->In_VpnProtocolState));
}
SeekBuf(p, 0, 0); SeekBuf(p, 0, 0);
WRITE_USHORT(((UCHAR *)p->Buf) + 2, (USHORT)p->Size); WRITE_USHORT(((UCHAR *)p->Buf) + 2, (USHORT)p->Size);
@ -1967,6 +2000,9 @@ RECV_RETRY:
// Success // Success
if (recv_buf[0] == 2) if (recv_buf[0] == 2)
{ {
LIST *o;
BUF *buf = NewBufFromMemory(recv_buf, recv_size);
ret = true; ret = true;
if (is_mschap && mschap_v2_server_response_20 != NULL) if (is_mschap && mschap_v2_server_response_20 != NULL)
@ -2004,12 +2040,26 @@ RECV_RETRY:
} }
} }
if (opt->In_CheckVLanId) o = RadiusParseOptions(buf);
if (o != NULL)
{ {
BUF *buf = NewBufFromMemory(recv_buf, recv_size); DHCP_OPTION *framed_interface_id_option = GetDhcpOption(o, RADIUS_ATTRIBUTE_FRAMED_INTERFACE_ID);
LIST *o = RadiusParseOptions(buf);
if (o != NULL) if (framed_interface_id_option != NULL)
{
char tmp_str[64];
UCHAR mac_address[6];
Zero(tmp_str, sizeof(tmp_str));
Copy(tmp_str, framed_interface_id_option->Data, MIN(framed_interface_id_option->Size, sizeof(tmp_str) - 1));
if (StrToMac(mac_address, tmp_str))
{
Copy(opt->Out_VirtualMacAddress, mac_address, 6);
}
}
if (opt->In_CheckVLanId)
{ {
DHCP_OPTION *vlan_option = GetDhcpOption(o, RADIUS_ATTRIBUTE_VLAN_ID); DHCP_OPTION *vlan_option = GetDhcpOption(o, RADIUS_ATTRIBUTE_VLAN_ID);
@ -2028,9 +2078,10 @@ RECV_RETRY:
} }
} }
FreeBuf(buf);
FreeDhcpOptions(o); FreeDhcpOptions(o);
} }
FreeBuf(buf);
} }
break; break;
} }

View File

@ -36,6 +36,7 @@
#define RADIUS_ATTRIBUTE_EAP_MESSAGE 79 #define RADIUS_ATTRIBUTE_EAP_MESSAGE 79
#define RADIUS_ATTRIBUTE_EAP_AUTHENTICATOR 80 #define RADIUS_ATTRIBUTE_EAP_AUTHENTICATOR 80
#define RADIUS_ATTRIBUTE_VLAN_ID 81 #define RADIUS_ATTRIBUTE_VLAN_ID 81
#define RADIUS_ATTRIBUTE_FRAMED_INTERFACE_ID 96
#define RADIUS_MAX_NAS_ID_LEN 253 #define RADIUS_MAX_NAS_ID_LEN 253
// RADIUS codes // RADIUS codes
@ -230,6 +231,9 @@ struct EAP_CLIENT
UCHAR RecvLastCode; UCHAR RecvLastCode;
UINT LastRecvVLanId; UINT LastRecvVLanId;
UCHAR LastRecvVirtualMacAddress[6];
char In_VpnProtocolState[64];
}; };
void FreeRadiusPacket(RADIUS_PACKET *p); void FreeRadiusPacket(RADIUS_PACKET *p);
@ -268,6 +272,8 @@ struct RADIUS_LOGIN_OPTION
UINT Out_VLanId; UINT Out_VLanId;
bool Out_IsRadiusLogin; bool Out_IsRadiusLogin;
char NasId[RADIUS_MAX_NAS_ID_LEN + 1]; // NAS-Identifier char NasId[RADIUS_MAX_NAS_ID_LEN + 1]; // NAS-Identifier
char Out_VirtualMacAddress[6];
char In_VpnProtocolState[64];
}; };
// Function prototype // Function prototype

View File

@ -10099,12 +10099,17 @@ void SiFarmServMain(SERVER *server, SOCK *sock, FARM_MEMBER *f)
} }
// Receive // Receive
p = HttpServerRecv(sock); p = HttpServerRecvEx(sock, FIRM_SERV_RECV_PACK_MAX_SIZE);
t->Response = p; t->Response = p;
Set(t->CompleteEvent); Set(t->CompleteEvent);
send_noop = false; if (p == NULL)
{
// Avoid infinite loop
Disconnect(sock);
goto DISCONNECTED;
}
} }
} }
while (t != NULL); while (t != NULL);

View File

@ -52,6 +52,7 @@ extern char *SERVER_CONFIG_FILE_NAME;
#define MEMBER_SELECTOR_CONNECT_TIMEOUT 2000 #define MEMBER_SELECTOR_CONNECT_TIMEOUT 2000
#define MEMBER_SELECTOR_DATA_TIMEOUT 5000 #define MEMBER_SELECTOR_DATA_TIMEOUT 5000
#define FIRM_SERV_RECV_PACK_MAX_SIZE (100 * 1024 * 1024)
// Virtual HUB list hosted by each farm member // Virtual HUB list hosted by each farm member
struct HUB_LIST struct HUB_LIST

View File

@ -2047,9 +2047,9 @@ void if_free(SESSION *s);
// Create a server session // Create a server session
SESSION *NewServerSession(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy) SESSION *NewServerSession(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy)
{ {
return NewServerSessionEx(cedar, c, h, username, policy, false); return NewServerSessionEx(cedar, c, h, username, policy, false, NULL);
} }
SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy, bool inproc_mode) SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy, bool inproc_mode, UCHAR *ipc_mac_address)
{ {
SESSION *s; SESSION *s;
char name[MAX_SIZE]; char name[MAX_SIZE];
@ -2170,28 +2170,35 @@ SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username,
// Generate a MAC address for IPC // Generate a MAC address for IPC
if (s->InProcMode) if (s->InProcMode)
{ {
char tmp[MAX_SIZE]; if (ipc_mac_address != NULL)
char machine[MAX_SIZE]; {
UCHAR hash[SHA1_SIZE]; Copy(s->IpcMacAddress, ipc_mac_address, 6);
}
else
{
char tmp[MAX_SIZE];
char machine[MAX_SIZE];
UCHAR hash[SHA1_SIZE];
GetMachineName(machine, sizeof(machine)); GetMachineName(machine, sizeof(machine));
Format(tmp, sizeof(tmp), "%s@%s@%u", machine, h->Name, s->UniqueId); Format(tmp, sizeof(tmp), "%s@%s@%u", machine, h->Name, s->UniqueId);
StrUpper(tmp); StrUpper(tmp);
Trim(tmp); Trim(tmp);
Sha0(hash, tmp, StrLen(tmp)); Sha0(hash, tmp, StrLen(tmp));
s->IpcMacAddress[0] = 0xCA; s->IpcMacAddress[0] = 0xCA;
s->IpcMacAddress[1] = hash[1]; s->IpcMacAddress[1] = hash[1];
s->IpcMacAddress[2] = hash[2]; s->IpcMacAddress[2] = hash[2];
s->IpcMacAddress[3] = hash[3]; s->IpcMacAddress[3] = hash[3];
s->IpcMacAddress[4] = hash[4]; s->IpcMacAddress[4] = hash[4];
s->IpcMacAddress[5] = hash[5]; s->IpcMacAddress[5] = hash[5];
MacToStr(tmp, sizeof(tmp), s->IpcMacAddress); MacToStr(tmp, sizeof(tmp), s->IpcMacAddress);
Debug("MAC Address for IPC: %s\n", tmp); Debug("MAC Address for IPC: %s\n", tmp);
}
} }
return s; return s;

View File

@ -300,7 +300,7 @@ SESSION *NewRpcSession(CEDAR *cedar, CLIENT_OPTION *option);
SESSION *NewRpcSessionEx(CEDAR *cedar, CLIENT_OPTION *option, UINT *err, char *client_str); SESSION *NewRpcSessionEx(CEDAR *cedar, CLIENT_OPTION *option, UINT *err, char *client_str);
SESSION *NewRpcSessionEx2(CEDAR *cedar, CLIENT_OPTION *option, UINT *err, char *client_str, void *hWnd); SESSION *NewRpcSessionEx2(CEDAR *cedar, CLIENT_OPTION *option, UINT *err, char *client_str, void *hWnd);
SESSION *NewServerSession(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy); SESSION *NewServerSession(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy);
SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy, bool inproc_mode); SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy, bool inproc_mode, UCHAR *ipc_mac_address);
void ClientThread(THREAD *t, void *param); void ClientThread(THREAD *t, void *param);
void ReleaseSession(SESSION *s); void ReleaseSession(SESSION *s);
void CleanupSession(SESSION *s); void CleanupSession(SESSION *s);

View File

@ -19947,6 +19947,10 @@ void FlushTubeFlushList(TUBE_FLUSH_LIST *f)
// The server receives a PACK from the client // The server receives a PACK from the client
PACK *HttpServerRecv(SOCK *s) PACK *HttpServerRecv(SOCK *s)
{
return HttpServerRecvEx(s, 0);
}
PACK *HttpServerRecvEx(SOCK *s, UINT max_data_size)
{ {
BUF *b; BUF *b;
PACK *p; PACK *p;
@ -19955,6 +19959,7 @@ PACK *HttpServerRecv(SOCK *s)
UCHAR *tmp; UCHAR *tmp;
HTTP_VALUE *v; HTTP_VALUE *v;
UINT num_noop = 0; UINT num_noop = 0;
if (max_data_size == 0) max_data_size = HTTP_PACK_MAX_SIZE;
// Validate arguments // Validate arguments
if (s == NULL) if (s == NULL)
{ {
@ -19985,7 +19990,7 @@ START:
} }
size = GetContentLength(h); size = GetContentLength(h);
if (size == 0 || size > HTTP_PACK_MAX_SIZE) if (size == 0 || (size > max_data_size))
{ {
FreeHttpHeader(h); FreeHttpHeader(h);
goto BAD_REQUEST; goto BAD_REQUEST;

View File

@ -969,6 +969,7 @@ bool HttpSendNotImplemented(SOCK *s, char *method, char *target, char *version);
bool HttpServerSend(SOCK *s, PACK *p); bool HttpServerSend(SOCK *s, PACK *p);
bool HttpClientSend(SOCK *s, PACK *p); bool HttpClientSend(SOCK *s, PACK *p);
PACK *HttpServerRecv(SOCK *s); PACK *HttpServerRecv(SOCK *s);
PACK *HttpServerRecvEx(SOCK *s, UINT max_data_size);
PACK *HttpClientRecv(SOCK *s); PACK *HttpClientRecv(SOCK *s);
bool GetIPViaDnsProxyForJapanFlets(IP *ip_ret, char *hostname, bool ipv6, UINT timeout, bool *cancel, char *dns_proxy_hostname); bool GetIPViaDnsProxyForJapanFlets(IP *ip_ret, char *hostname, bool ipv6, UINT timeout, bool *cancel, char *dns_proxy_hostname);