mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2025-12-08 03:01:31 +03:00
v4.06-9430-beta
This commit is contained in:
262
src/Cedar/Sam.c
262
src/Cedar/Sam.c
@ -14,7 +14,6 @@
|
||||
// Author: Daiyuu Nobori
|
||||
// Comments: Tetsuo Sugiyama, Ph.D.
|
||||
//
|
||||
//
|
||||
// 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 published by the Free Software Foundation.
|
||||
@ -85,6 +84,13 @@
|
||||
// http://www.softether.org/ and ask your question on the users forum.
|
||||
//
|
||||
// Thank you for your cooperation.
|
||||
//
|
||||
//
|
||||
// NO MEMORY OR RESOURCE LEAKS
|
||||
// ---------------------------
|
||||
//
|
||||
// The memory-leaks and resource-leaks verification under the stress
|
||||
// test has been passed before release this source code.
|
||||
|
||||
|
||||
// Sam.c
|
||||
@ -156,13 +162,263 @@ bool SamAuthUserByAnonymous(HUB *h, char *username)
|
||||
// Plaintext password authentication of user
|
||||
bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *password, bool ast, UCHAR *mschap_v2_server_response_20)
|
||||
{
|
||||
return false;
|
||||
bool b = false;
|
||||
wchar_t *name = NULL;
|
||||
bool auth_by_nt = false;
|
||||
HUB *h;
|
||||
// Validate arguments
|
||||
if (hub == NULL || c == NULL || username == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetGlobalServerFlag(GSF_DISABLE_RADIUS_AUTH) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
h = hub;
|
||||
|
||||
AddRef(h->ref);
|
||||
|
||||
// Get the user name on authentication system
|
||||
AcLock(hub);
|
||||
{
|
||||
USER *u;
|
||||
u = AcGetUser(hub, ast == false ? username : "*");
|
||||
if (u)
|
||||
{
|
||||
Lock(u->lock);
|
||||
{
|
||||
if (u->AuthType == AUTHTYPE_RADIUS)
|
||||
{
|
||||
// Radius authentication
|
||||
AUTHRADIUS *auth = (AUTHRADIUS *)u->AuthData;
|
||||
if (ast || auth->RadiusUsername == NULL || UniStrLen(auth->RadiusUsername) == 0)
|
||||
{
|
||||
name = CopyStrToUni(username);
|
||||
}
|
||||
else
|
||||
{
|
||||
name = CopyUniStr(auth->RadiusUsername);
|
||||
}
|
||||
auth_by_nt = false;
|
||||
}
|
||||
else if (u->AuthType == AUTHTYPE_NT)
|
||||
{
|
||||
// NT authentication
|
||||
AUTHNT *auth = (AUTHNT *)u->AuthData;
|
||||
if (ast || auth->NtUsername == NULL || UniStrLen(auth->NtUsername) == 0)
|
||||
{
|
||||
name = CopyStrToUni(username);
|
||||
}
|
||||
else
|
||||
{
|
||||
name = CopyUniStr(auth->NtUsername);
|
||||
}
|
||||
auth_by_nt = true;
|
||||
}
|
||||
}
|
||||
Unlock(u->lock);
|
||||
ReleaseUser(u);
|
||||
}
|
||||
}
|
||||
AcUnlock(hub);
|
||||
|
||||
if (name != NULL)
|
||||
{
|
||||
if (auth_by_nt == false)
|
||||
{
|
||||
// Radius authentication
|
||||
char radius_server_addr[MAX_SIZE];
|
||||
UINT radius_server_port;
|
||||
char radius_secret[MAX_SIZE];
|
||||
char suffix_filter[MAX_SIZE];
|
||||
wchar_t suffix_filter_w[MAX_SIZE];
|
||||
UINT interval;
|
||||
|
||||
Zero(suffix_filter, sizeof(suffix_filter));
|
||||
Zero(suffix_filter_w, sizeof(suffix_filter_w));
|
||||
|
||||
// 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)))
|
||||
{
|
||||
Unlock(hub->lock);
|
||||
|
||||
StrToUni(suffix_filter_w, sizeof(suffix_filter_w), suffix_filter);
|
||||
|
||||
if (UniIsEmptyStr(suffix_filter_w) || UniEndWith(name, suffix_filter_w))
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
Lock(hub->lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
HLog(hub, "LH_NO_RADIUS_SETTING", name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// NT authentication (Not available for non-Win32)
|
||||
#ifdef OS_WIN32
|
||||
IPC_MSCHAP_V2_AUTHINFO mschap;
|
||||
Unlock(hub->lock);
|
||||
|
||||
if (ParseAndExtractMsChapV2InfoFromPassword(&mschap, password) == false)
|
||||
{
|
||||
// Plaintext password authentication
|
||||
b = MsCheckLogon(name, password);
|
||||
}
|
||||
else
|
||||
{
|
||||
UCHAR challenge8[8];
|
||||
UCHAR nt_pw_hash_hash[16];
|
||||
char nt_name[MAX_SIZE];
|
||||
|
||||
UniToStr(nt_name, sizeof(nt_name), name);
|
||||
|
||||
// MS-CHAPv2 authentication
|
||||
MsChapV2_GenerateChallenge8(challenge8, mschap.MsChapV2_ClientChallenge,
|
||||
mschap.MsChapV2_ServerChallenge,
|
||||
mschap.MsChapV2_PPPUsername);
|
||||
|
||||
Debug("MsChapV2_PPPUsername = %s, nt_name = %s\n", mschap.MsChapV2_PPPUsername, nt_name);
|
||||
|
||||
b = MsPerformMsChapV2AuthByLsa(nt_name, challenge8, mschap.MsChapV2_ClientResponse, nt_pw_hash_hash);
|
||||
|
||||
if (b)
|
||||
{
|
||||
if (mschap_v2_server_response_20 != NULL)
|
||||
{
|
||||
MsChapV2Server_GenerateResponse(mschap_v2_server_response_20, nt_pw_hash_hash,
|
||||
mschap.MsChapV2_ClientResponse, challenge8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Lock(hub->lock);
|
||||
#else // OS_WIN32
|
||||
// Nothing to do other than Win32
|
||||
#endif // OS_WIN32
|
||||
}
|
||||
|
||||
// Memory release
|
||||
Free(name);
|
||||
}
|
||||
|
||||
ReleaseHub(h);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
// Certificate authentication of user
|
||||
bool SamAuthUserByCert(HUB *h, char *username, X *x)
|
||||
{
|
||||
return false;
|
||||
bool b = false;
|
||||
// Validate arguments
|
||||
if (h == NULL || username == NULL || x == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetGlobalServerFlag(GSF_DISABLE_CERT_AUTH) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check expiration date
|
||||
if (CheckXDateNow(x) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the Certification Revocation List
|
||||
if (IsValidCertInHub(h, x) == false)
|
||||
{
|
||||
// Bad
|
||||
wchar_t tmp[MAX_SIZE * 2];
|
||||
|
||||
// Log the contents of the certificate
|
||||
GetAllNameFromX(tmp, sizeof(tmp), x);
|
||||
|
||||
HLog(h, "LH_AUTH_NG_CERT", username, tmp);
|
||||
return false;
|
||||
}
|
||||
|
||||
AcLock(h);
|
||||
{
|
||||
USER *u;
|
||||
u = AcGetUser(h, username);
|
||||
if (u)
|
||||
{
|
||||
Lock(u->lock);
|
||||
{
|
||||
if (u->AuthType == AUTHTYPE_USERCERT)
|
||||
{
|
||||
// Check whether to matche with the registered certificate
|
||||
AUTHUSERCERT *auth = (AUTHUSERCERT *)u->AuthData;
|
||||
if (CompareX(auth->UserX, x))
|
||||
{
|
||||
b = true;
|
||||
}
|
||||
}
|
||||
else if (u->AuthType == AUTHTYPE_ROOTCERT)
|
||||
{
|
||||
// Check whether the certificate has been signed by the root certificate
|
||||
AUTHROOTCERT *auth = (AUTHROOTCERT *)u->AuthData;
|
||||
if (h->HubDb != NULL)
|
||||
{
|
||||
LockList(h->HubDb->RootCertList);
|
||||
{
|
||||
X *root_cert;
|
||||
root_cert = GetIssuerFromList(h->HubDb->RootCertList, x);
|
||||
if (root_cert != NULL)
|
||||
{
|
||||
b = true;
|
||||
if (auth->CommonName != NULL && UniIsEmptyStr(auth->CommonName) == false)
|
||||
{
|
||||
// Compare the CN
|
||||
if (UniStrCmpi(x->subject_name->CommonName, auth->CommonName) != 0)
|
||||
{
|
||||
b = false;
|
||||
}
|
||||
}
|
||||
if (auth->Serial != NULL && auth->Serial->size >= 1)
|
||||
{
|
||||
// Compare the serial number
|
||||
if (CompareXSerial(x->serial, auth->Serial) == false)
|
||||
{
|
||||
b = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
UnlockList(h->HubDb->RootCertList);
|
||||
}
|
||||
}
|
||||
}
|
||||
Unlock(u->lock);
|
||||
ReleaseUser(u);
|
||||
}
|
||||
}
|
||||
AcUnlock(h);
|
||||
|
||||
if (b)
|
||||
{
|
||||
wchar_t tmp[MAX_SIZE * 2];
|
||||
|
||||
// Log the contents of the certificate
|
||||
GetAllNameFromX(tmp, sizeof(tmp), x);
|
||||
|
||||
HLog(h, "LH_AUTH_OK_CERT", username, tmp);
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
// Get the root certificate that signed the specified certificate from the list
|
||||
|
||||
Reference in New Issue
Block a user