diff --git a/ipb-profile-key.patch b/ipb-profile-key.patch new file mode 100644 index 0000000..f4e987e --- /dev/null +++ b/ipb-profile-key.patch @@ -0,0 +1,112 @@ +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)) + { diff --git a/package.nix b/package.nix index 5d4bec9..13aec17 100644 --- a/package.nix +++ b/package.nix @@ -22,6 +22,8 @@ stdenv.mkDerivation (finalAttrs: { fetchSubmodules = true; }; + patches = [ ./ipb-profile-key.patch ]; + nativeBuildInputs = with pkgs; [ cmake pkg-config