mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2025-07-07 16:25:01 +03:00
OpenVPN client certificate authentication (Individual Certificate Authentication) (#327)
* Implement OpenVPN certificate authentication, fixes #55 * fixup! Implement OpenVPN certificate authentication, fixes #55
This commit is contained in:
committed by
Moataz Elmasry
parent
863f87fac1
commit
83295bb736
@ -1795,6 +1795,9 @@ bool ServerAccept(CONNECTION *c)
|
||||
case AUTHTYPE_TICKET:
|
||||
authtype_str = _UU("LH_AUTH_TICKET");
|
||||
break;
|
||||
case AUTHTYPE_OPENVPN_CERT:
|
||||
authtype_str = _UU("LH_AUTH_OPENVPN_CERT");
|
||||
break;
|
||||
}
|
||||
IPToStr(ip1, sizeof(ip1), &c->FirstSock->RemoteIP);
|
||||
IPToStr(ip2, sizeof(ip2), &c->FirstSock->LocalIP);
|
||||
@ -2128,6 +2131,50 @@ bool ServerAccept(CONNECTION *c)
|
||||
}
|
||||
break;
|
||||
|
||||
case AUTHTYPE_OPENVPN_CERT:
|
||||
// For OpenVPN; mostly same as CLIENT_AUTHTYPE_CERT, but without
|
||||
// signature verification, because it was already performed during TLS handshake.
|
||||
if (c->IsInProc)
|
||||
{
|
||||
// Certificate authentication
|
||||
cert_size = PackGetDataSize(p, "cert");
|
||||
if (cert_size >= 1 && cert_size <= 100000)
|
||||
{
|
||||
cert_buf = ZeroMalloc(cert_size);
|
||||
if (PackGetData(p, "cert", cert_buf))
|
||||
{
|
||||
BUF *b = NewBuf();
|
||||
X *x;
|
||||
WriteBuf(b, cert_buf, cert_size);
|
||||
x = BufToX(b, false);
|
||||
if (x != NULL && x->is_compatible_bit)
|
||||
{
|
||||
Debug("Got to SamAuthUserByCert %s\n", username); // XXX
|
||||
// Check whether the certificate is valid.
|
||||
auth_ret = SamAuthUserByCert(hub, username, x);
|
||||
if (auth_ret)
|
||||
{
|
||||
// Copy the certificate
|
||||
c->ClientX = CloneX(x);
|
||||
}
|
||||
}
|
||||
FreeX(x);
|
||||
FreeBuf(b);
|
||||
}
|
||||
Free(cert_buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// OpenVPN certificate authentication cannot be used directly by external clients
|
||||
Unlock(hub->lock);
|
||||
ReleaseHub(hub);
|
||||
FreePack(p);
|
||||
c->Err = ERR_AUTHTYPE_NOT_SUPPORTED;
|
||||
goto CLEANUP;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Unknown authentication method
|
||||
Unlock(hub->lock);
|
||||
@ -7247,6 +7294,45 @@ PACK *PackLoginWithPlainPassword(char *hubname, char *username, void *plain_pass
|
||||
return p;
|
||||
}
|
||||
|
||||
// Generate a packet of OpenVPN certificate login
|
||||
PACK *PackLoginWithOpenVPNCertificate(char *hubname, char *username, X *x)
|
||||
{
|
||||
PACK *p;
|
||||
// Validate arguments
|
||||
if (hubname == NULL || username == NULL || x == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = NewPack();
|
||||
PackAddStr(p, "method", "login");
|
||||
PackAddStr(p, "hubname", hubname);
|
||||
|
||||
char cn_username[128];
|
||||
if (IsEmptyStr(username))
|
||||
{
|
||||
if (x->subject_name == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
wcstombs(cn_username, x->subject_name->CommonName, 127);
|
||||
cn_username[127] = '\0';
|
||||
PackAddStr(p, "username", cn_username);
|
||||
}
|
||||
else
|
||||
{
|
||||
PackAddStr(p, "username", username);
|
||||
}
|
||||
|
||||
PackAddInt(p, "authtype", AUTHTYPE_OPENVPN_CERT);
|
||||
|
||||
BUF *cert_buf = XToBuf(x, false);
|
||||
PackAddBuf(p, "cert", cert_buf);
|
||||
FreeBuf(cert_buf);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
// Create a packet of password authentication login
|
||||
PACK *PackLoginWithPassword(char *hubname, char *username, void *secure_password)
|
||||
{
|
||||
|
Reference in New Issue
Block a user