mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-22 17:39:53 +03:00
Support EAP auth with RADIUS server for SEVPN
This commit is contained in:
parent
e20fa9ec2e
commit
e81ecbb0ec
@ -413,6 +413,7 @@ bool PPPParseUsername(CEDAR *cedar, char *src, ETHERIP_ID *dst);
|
||||
void GenerateNtPasswordHash(UCHAR *dst, char *password);
|
||||
void GenerateNtPasswordHashHash(UCHAR *dst_hash, UCHAR *src_hash);
|
||||
void MsChapV2Server_GenerateChallenge(UCHAR *dst);
|
||||
void MsChapV2Client_GenerateChallenge(UCHAR *dst);
|
||||
void MsChapV2_GenerateChallenge8(UCHAR *dst, UCHAR *client_challenge, UCHAR *server_challenge, char *username);
|
||||
void MsChapV2Client_GenerateResponse(UCHAR *dst, UCHAR *challenge8, UCHAR *nt_password_hash);
|
||||
void MsChapV2Server_GenerateResponse(UCHAR *dst, UCHAR *nt_password_hash_hash, UCHAR *client_response, UCHAR *challenge8);
|
||||
|
@ -1914,7 +1914,7 @@ bool ServerAccept(CONNECTION *c)
|
||||
|
||||
if (auth_ret == false)
|
||||
{
|
||||
// Attempt external authentication registered users
|
||||
// Attempt external authentication
|
||||
bool fail_ext_user_auth = false;
|
||||
if (GetGlobalServerFlag(GSF_DISABLE_RADIUS_AUTH) != 0)
|
||||
{
|
||||
@ -1923,7 +1923,7 @@ bool ServerAccept(CONNECTION *c)
|
||||
|
||||
if (fail_ext_user_auth == false)
|
||||
{
|
||||
auth_ret = SamAuthUserByPlainPassword(c, hub, username, plain_password, false, mschap_v2_server_response_20, &radius_login_opt);
|
||||
auth_ret = SamAuthUserByPlainPassword(c, hub, username, plain_password, true, mschap_v2_server_response_20, &radius_login_opt);
|
||||
}
|
||||
|
||||
if (auth_ret && pol == NULL)
|
||||
@ -1932,37 +1932,6 @@ bool ServerAccept(CONNECTION *c)
|
||||
}
|
||||
}
|
||||
|
||||
if (auth_ret == false)
|
||||
{
|
||||
// Attempt external authentication asterisk user
|
||||
bool b = false;
|
||||
bool fail_ext_user_auth = false;
|
||||
|
||||
if (GetGlobalServerFlag(GSF_DISABLE_RADIUS_AUTH) != 0)
|
||||
{
|
||||
fail_ext_user_auth = true;
|
||||
}
|
||||
|
||||
if (fail_ext_user_auth == false)
|
||||
{
|
||||
AcLock(hub);
|
||||
{
|
||||
b = AcIsUser(hub, "*");
|
||||
}
|
||||
AcUnlock(hub);
|
||||
|
||||
// If there is asterisk user, log on as the user
|
||||
if (b)
|
||||
{
|
||||
auth_ret = SamAuthUserByPlainPassword(c, hub, username, plain_password, true, mschap_v2_server_response_20, &radius_login_opt);
|
||||
if (auth_ret && pol == NULL)
|
||||
{
|
||||
pol = SamGetUserPolicy(hub, "*");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pol != NULL)
|
||||
{
|
||||
no_save_password = pol->NoSavePassword;
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "Account.h"
|
||||
#include "Cedar.h"
|
||||
#include "Connection.h"
|
||||
#include "Hub.h"
|
||||
#include "IPC.h"
|
||||
#include "Proto_PPP.h"
|
||||
@ -420,7 +421,7 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
||||
bool auth_by_nt = false;
|
||||
HUB *h;
|
||||
// Validate arguments
|
||||
if (hub == NULL || c == NULL || username == NULL)
|
||||
if (hub == NULL || c == NULL || username == NULL || password == NULL || opt == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -438,7 +439,14 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
||||
AcLock(hub);
|
||||
{
|
||||
USER *u;
|
||||
u = AcGetUser(hub, ast == false ? username : "*");
|
||||
|
||||
// Find exact user first
|
||||
u = AcGetUser(hub, username);
|
||||
if (u == NULL && ast)
|
||||
{
|
||||
u = AcGetUser(hub, "*");
|
||||
}
|
||||
|
||||
if (u)
|
||||
{
|
||||
Lock(u->lock);
|
||||
@ -447,7 +455,7 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
||||
{
|
||||
// Radius authentication
|
||||
AUTHRADIUS *auth = (AUTHRADIUS *)u->AuthData;
|
||||
if (ast || auth->RadiusUsername == NULL || UniStrLen(auth->RadiusUsername) == 0)
|
||||
if (auth->RadiusUsername == NULL || UniStrLen(auth->RadiusUsername) == 0)
|
||||
{
|
||||
if( IsEmptyStr(h->RadiusRealm) == false )
|
||||
{
|
||||
@ -472,7 +480,7 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
||||
{
|
||||
// NT authentication
|
||||
AUTHNT *auth = (AUTHNT *)u->AuthData;
|
||||
if (ast || auth->NtUsername == NULL || UniStrLen(auth->NtUsername) == 0)
|
||||
if (auth->NtUsername == NULL || UniStrLen(auth->NtUsername) == 0)
|
||||
{
|
||||
name = CopyStrToUni(username);
|
||||
}
|
||||
@ -508,10 +516,75 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
||||
char suffix_filter[MAX_SIZE];
|
||||
wchar_t suffix_filter_w[MAX_SIZE];
|
||||
UINT interval;
|
||||
EAP_CLIENT *eap = NULL;
|
||||
char password1[MAX_SIZE];
|
||||
UCHAR client_challenge[16];
|
||||
UCHAR server_challenge[16];
|
||||
UCHAR challenge8[8];
|
||||
UCHAR client_response[24];
|
||||
UCHAR ntlm_hash[MD5_SIZE];
|
||||
|
||||
Zero(suffix_filter, sizeof(suffix_filter));
|
||||
Zero(suffix_filter_w, sizeof(suffix_filter_w));
|
||||
|
||||
// MSCHAPv2 / EAP wrapper for SEVPN
|
||||
if (c->IsInProc == false && StartWith(password, IPC_PASSWORD_MSCHAPV2_TAG) == false)
|
||||
{
|
||||
char client_ip_str[MAX_SIZE];
|
||||
char utf8[MAX_SIZE];
|
||||
|
||||
// Convert the user name to a Unicode string
|
||||
UniToStr(utf8, sizeof(utf8), name);
|
||||
utf8[MAX_SIZE-1] = 0;
|
||||
|
||||
Zero(client_ip_str, sizeof(client_ip_str));
|
||||
if (c != NULL && c->FirstSock != NULL)
|
||||
{
|
||||
IPToStr(client_ip_str, sizeof(client_ip_str), &c->FirstSock->RemoteIP);
|
||||
}
|
||||
|
||||
if (hub->RadiusConvertAllMsChapv2AuthRequestToEap)
|
||||
{
|
||||
// Do EAP or PEAP
|
||||
eap = HubNewEapClient(hub->Cedar, hub->Name, client_ip_str, utf8, opt->In_VpnProtocolState);
|
||||
|
||||
// Prepare MSCHAP response and replace plain password
|
||||
if (eap != NULL)
|
||||
{
|
||||
char server_challenge_hex[MAX_SIZE];
|
||||
char client_challenge_hex[MAX_SIZE];
|
||||
char client_response_hex[MAX_SIZE];
|
||||
char eap_client_hex[64];
|
||||
|
||||
MsChapV2Client_GenerateChallenge(client_challenge);
|
||||
GenerateNtPasswordHash(ntlm_hash, password);
|
||||
Copy(server_challenge, eap->MsChapV2Challenge.Chap_ChallengeValue, 16);
|
||||
MsChapV2_GenerateChallenge8(challenge8, client_challenge, server_challenge, utf8);
|
||||
MsChapV2Client_GenerateResponse(client_response, challenge8, ntlm_hash);
|
||||
|
||||
BinToStr(server_challenge_hex, sizeof(server_challenge_hex),
|
||||
server_challenge, sizeof(server_challenge));
|
||||
BinToStr(client_challenge_hex, sizeof(client_challenge_hex),
|
||||
client_challenge, sizeof(client_challenge));
|
||||
BinToStr(client_response_hex, sizeof(client_response_hex),
|
||||
client_response, sizeof(client_response));
|
||||
BinToStr(eap_client_hex, sizeof(eap_client_hex), &eap, 8);
|
||||
Format(password1, sizeof(password1), "%s%s:%s:%s:%s:%s",
|
||||
IPC_PASSWORD_MSCHAPV2_TAG,
|
||||
utf8,
|
||||
server_challenge_hex,
|
||||
client_challenge_hex,
|
||||
client_response_hex,
|
||||
eap_client_hex);
|
||||
password = password1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Todo: Do MSCHAPv2
|
||||
}
|
||||
}
|
||||
|
||||
// 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)))
|
||||
{
|
||||
@ -527,13 +600,10 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
||||
name, password, interval, mschap_v2_server_response_20, opt, hub->Name);
|
||||
|
||||
if (b)
|
||||
{
|
||||
if (opt != NULL)
|
||||
{
|
||||
opt->Out_IsRadiusLogin = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Lock(hub->lock);
|
||||
}
|
||||
@ -541,6 +611,11 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
||||
{
|
||||
HLog(hub, "LH_NO_RADIUS_SETTING", name);
|
||||
}
|
||||
|
||||
if (eap != NULL)
|
||||
{
|
||||
ReleaseEapClient(eap);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user