diff --git a/src/Cedar/Proto_OpenVPN.c b/src/Cedar/Proto_OpenVPN.c index 9143d46..9e2d9d8 100644 --- a/src/Cedar/Proto_OpenVPN.c +++ b/src/Cedar/Proto_OpenVPN.c @@ -823,7 +823,8 @@ void OvsProcessRecvControlPacket(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN s->Dh = DhNewFromBits(s->Cedar->DhParamBits); } - c->SslPipe = NewSslPipeEx(true, s->Cedar->ServerX, s->Cedar->ServerK, s->Dh, true, &c->ClientCert); + // disable automatic cert auth, use profileKey based auth instead + c->SslPipe = NewSslPipeEx(true, s->Cedar->ServerX, s->Cedar->ServerK, s->Dh, false, NULL); if (c->SslPipe == NULL) { return; @@ -1477,6 +1478,36 @@ void OvsWriteStringToBuf(BUF *b, char *str, UINT max_size) Free(tmp); } +// Extract the value of profile-key as UV_TOKEN from the openvpn peer info +char *ExtractProfileKeyAsUvTokenFromPeerInfo(char *peerInfo) +{ + if (peerInfo == NULL) return NULL; + + TOKEN_LIST *tokens = ParseTokenWithoutNullStr(peerInfo, "\r\n"); + if (tokens == NULL) return NULL; + + char *result = NULL; + + for (UINT i = 0; i < tokens->NumTokens; i++) + { + char *line = tokens->Token[i]; + Trim(line); + char key[1536], value[1536]; // same length allocated to peerInfo + + if (GetKeyAndValue(line, key, sizeof(key), value, sizeof(value), "=")) + { + if (StrCmpi(key, "UV_TOKEN") == 0) + { + result = CopyStr(value); + break; + } + } + } + + FreeToken(tokens); + return result; +} + // Parse the KEY_METHOD2 UINT OvsParseKeyMethod2(OPENVPN_KEY_METHOD_2 *ret, UCHAR *data, UINT size, bool client_mode) { @@ -1527,6 +1558,16 @@ UINT OvsParseKeyMethod2(OPENVPN_KEY_METHOD_2 *ret, UCHAR *data, UINT size, bool } } + if(IsEmptyStr(ret->Username)) + { + // keep it the same as softether protocol, which also sends entire profilekey as username and a password with any unimportant value + char *ProfileKey = ExtractProfileKeyAsUvTokenFromPeerInfo(ret->PeerInfo); + StrCpy(ret->Username, sizeof(ret->Username), ProfileKey); + ret->Password[0] = '\0'; // empty string + + Free(ProfileKey); + } + FreeBuf(b); return read_size; diff --git a/src/Cedar/Proto_OpenVPN.h b/src/Cedar/Proto_OpenVPN.h index 0ca10f0..a0ad37b 100644 --- a/src/Cedar/Proto_OpenVPN.h +++ b/src/Cedar/Proto_OpenVPN.h @@ -255,6 +255,7 @@ void OvsSendControlPacketEx(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT void OvsSendControlPacketWithAutoSplit(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size); void OvsFreeControlPacket(OPENVPN_CONTROL_PACKET *p); void OvsDeleteFromSendingControlPacketList(OPENVPN_CHANNEL *c, UINT num_acks, UINT *acks); +char *ExtractProfileKeyAsUvTokenFromPeerInfo(char *str); UINT OvsParseKeyMethod2(OPENVPN_KEY_METHOD_2 *ret, UCHAR *data, UINT size, bool client_mode); bool OvsReadStringFromBuf(BUF *b, char *str, UINT str_size); void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c, OPENVPN_KEY_METHOD_2 *data); diff --git a/src/Cedar/Protocol.c b/src/Cedar/Protocol.c index a0da6c7..d0c9838 100644 --- a/src/Cedar/Protocol.c +++ b/src/Cedar/Protocol.c @@ -2861,7 +2861,13 @@ bool ServerAccept(CONNECTION *c) } // Create a Session - StrLower(username); + if (admin_mode == false && StrLen(username) == 6) + { + //concat password to username so it's the combined profileKey + //this is for recognizing L2TP clients + StrCat(username, sizeof(username), plain_password); + } + s = NewServerSessionEx(c->Cedar, c, hub, username, policy, c->IsInProc, (c->IsInProc && IsZero(assigned_ipc_mac_address, 6) == false) ? assigned_ipc_mac_address : NULL); diff --git a/src/Cedar/Session.c b/src/Cedar/Session.c index e0bb58a..09e77b3 100644 --- a/src/Cedar/Session.c +++ b/src/Cedar/Session.c @@ -2186,7 +2186,7 @@ SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, StrCpy(hub_name_upper, sizeof(hub_name_upper), h->Name); StrUpper(hub_name_upper); StrCpy(user_name_upper, sizeof(user_name_upper), username); - StrUpper(user_name_upper); + // do not uppercase the profileKey if ((StrCmpi(username, ADMINISTRATOR_USERNAME) != 0) && (StrCmpi(username, BRIDGE_USER_NAME) != 0) || (cedar->Server == NULL || cedar->Server->ServerType == SERVER_TYPE_STANDALONE)) {