Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/SoftEtherVPN/SoftEtherVPN_Stable.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/Cedar/Sam.c')
-rw-r--r--src/Cedar/Sam.c262
1 files changed, 259 insertions, 3 deletions
diff --git a/src/Cedar/Sam.c b/src/Cedar/Sam.c
index b12a97f9..7520e40a 100644
--- a/src/Cedar/Sam.c
+++ b/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