diff options
Diffstat (limited to 'protocols/JabberG/src/jabber_secur.cpp')
-rw-r--r-- | protocols/JabberG/src/jabber_secur.cpp | 442 |
1 files changed, 0 insertions, 442 deletions
diff --git a/protocols/JabberG/src/jabber_secur.cpp b/protocols/JabberG/src/jabber_secur.cpp deleted file mode 100644 index 2b52830960..0000000000 --- a/protocols/JabberG/src/jabber_secur.cpp +++ /dev/null @@ -1,442 +0,0 @@ -/*
-
-Jabber Protocol Plugin for Miranda NG
-
-Copyright (c) 2002-04 Santithorn Bunchua
-Copyright (c) 2005-12 George Hazan
-Copyright (C) 2012-24 Miranda NG team
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-*/
-
-#include "stdafx.h"
-#include "jabber_secur.h"
-
-bool CJabberProto::OnProcessMechanism(const TiXmlElement *n, ThreadData *info)
-{
- if (!mir_strcmp(n->Name(), "mechanism")) {
- TJabberAuth *pAuth = nullptr;
- const char *szMechanism = n->GetText();
- if (!mir_strcmp(szMechanism, "PLAIN")) {
- m_arAuthMechs.insert(new TPlainAuth(info, false));
- pAuth = new TPlainAuth(info, true);
- }
- else if (!mir_strcmp(szMechanism, "DIGEST-MD5"))
- pAuth = new TMD5Auth(info);
- else if (!mir_strcmp(szMechanism, "SCRAM-SHA-1"))
- pAuth = new TScramAuth(info, szMechanism, EVP_sha1(), 500);
- else if (!mir_strcmp(szMechanism, "SCRAM-SHA-1-PLUS"))
- pAuth = new TScramAuth(info, szMechanism, EVP_sha1(), 601);
- else if (!mir_strcmp(szMechanism, "SCRAM-SHA-224"))
- pAuth = new TScramAuth(info, szMechanism, EVP_sha224(), 510);
- else if (!mir_strcmp(szMechanism, "SCRAM-SHA-224-PLUS"))
- pAuth = new TScramAuth(info, szMechanism, EVP_sha224(), 611);
- else if (!mir_strcmp(szMechanism, "SCRAM-SHA-256"))
- pAuth = new TScramAuth(info, szMechanism, EVP_sha256(), 520);
- else if (!mir_strcmp(szMechanism, "SCRAM-SHA-256-PLUS"))
- pAuth = new TScramAuth(info, szMechanism, EVP_sha256(), 621);
- else if (!mir_strcmp(szMechanism, "SCRAM-SHA-384"))
- pAuth = new TScramAuth(info, szMechanism, EVP_sha384(), 530);
- else if (!mir_strcmp(szMechanism, "SCRAM-SHA-384-PLUS"))
- pAuth = new TScramAuth(info, szMechanism, EVP_sha384(), 631);
- else if (!mir_strcmp(szMechanism, "SCRAM-SHA-512"))
- pAuth = new TScramAuth(info, szMechanism, EVP_sha512(), 540);
- else if (!mir_strcmp(szMechanism, "SCRAM-SHA-512-PLUS"))
- pAuth = new TScramAuth(info, szMechanism, EVP_sha512(), 641);
- else if (!mir_strcmp(szMechanism, "NTLM") || !mir_strcmp(szMechanism, "GSS-SPNEGO") || !mir_strcmp(szMechanism, "GSSAPI"))
- pAuth = new TNtlmAuth(info, szMechanism);
- else {
- debugLogA("Unsupported auth mechanism: %s, skipping", szMechanism);
- return true;
- }
-
- if (!pAuth->isValid())
- delete pAuth;
- else
- m_arAuthMechs.insert(pAuth);
- return true;
- }
-
- if (!mir_strcmp(n->Name(), "hostname")) {
- const char *mech = XmlGetAttr(n, "mechanism");
- if (mech && mir_strcmpi(mech, "GSSAPI") == 0)
- info->gssapiHostName = mir_strdup(n->GetText());
- return true;
- }
-
- return false;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// ntlm auth - LanServer based authorization
-
-TNtlmAuth::TNtlmAuth(ThreadData *info, const char *mechanism) :
- TJabberAuth(info, mechanism)
-{
- bIsValid = false;
-
- const wchar_t *szProvider;
- if (!mir_strcmp(mechanism, "GSS-SPNEGO"))
- szProvider = L"Negotiate", priority = 703;
- else if (!mir_strcmp(mechanism, "GSSAPI"))
- szProvider = L"Kerberos", priority = 702;
- else if (!mir_strcmp(mechanism, "NTLM"))
- szProvider = L"NTLM", priority = 701;
- else
- return;
-
- wchar_t szSpn[1024]; szSpn[0] = 0;
- if (!mir_strcmp(mechanism, "GSSAPI"))
- if (!getSpn(szSpn, _countof(szSpn)))
- return;
-
- if ((hProvider = Netlib_InitSecurityProvider(szProvider, szSpn)) == nullptr)
- return;
-
- // This generates login method advertisement packet
- if (info->conn.password[0] != 0)
- szInitRequest = Netlib_NtlmCreateResponse(hProvider, "", Utf2T(info->conn.username), Utf2T(info->conn.password), complete);
- else
- szInitRequest = Netlib_NtlmCreateResponse(hProvider, "", nullptr, nullptr, complete);
- if (szInitRequest == nullptr)
- return;
-
- bIsValid = true;
-}
-
-TNtlmAuth::~TNtlmAuth()
-{
- if (hProvider != nullptr)
- Netlib_DestroySecurityProvider(hProvider);
-}
-
-bool TNtlmAuth::getSpn(wchar_t* szSpn, size_t dwSpnLen)
-{
- wchar_t szFullUserName[128] = L"";
- ULONG szFullUserNameLen = _countof(szFullUserName);
- if (!GetUserNameEx(NameDnsDomain, szFullUserName, &szFullUserNameLen)) {
- szFullUserName[0] = 0;
- szFullUserNameLen = _countof(szFullUserName);
- GetUserNameEx(NameSamCompatible, szFullUserName, &szFullUserNameLen);
- }
-
- wchar_t *name = wcsrchr(szFullUserName, '\\');
- if (name) *name = 0;
- else return false;
-
- if (info->gssapiHostName && info->gssapiHostName[0]) {
- wchar_t *szFullUserNameU = wcsupr(mir_wstrdup(szFullUserName));
- mir_snwprintf(szSpn, dwSpnLen, L"xmpp/%s/%s@%s", info->gssapiHostName, szFullUserName, szFullUserNameU);
- mir_free(szFullUserNameU);
- }
- else {
- const char* connectHost = info->conn.manualHost[0] ? info->conn.manualHost : info->conn.server;
-
- unsigned long ip = inet_addr(connectHost);
- PHOSTENT host = (ip == INADDR_NONE) ? nullptr : gethostbyaddr((char*)&ip, 4, AF_INET);
- if (host && host->h_name)
- connectHost = host->h_name;
-
- wchar_t *connectHostT = mir_a2u(connectHost);
- mir_snwprintf(szSpn, dwSpnLen, L"xmpp/%s@%s", connectHostT, wcsupr(szFullUserName));
- mir_free(connectHostT);
- }
-
- Netlib_Logf(nullptr, "SPN: %S", szSpn);
- return true;
-}
-
-char* TNtlmAuth::getInitialRequest()
-{
- return szInitRequest.detach();
-}
-
-char* TNtlmAuth::getChallenge(const char *challenge)
-{
- if (!hProvider)
- return nullptr;
-
- const char *text((!mir_strcmp(challenge, "=")) ? "" : challenge);
- if (info->conn.password[0] != 0)
- return Netlib_NtlmCreateResponse(hProvider, text, Utf2T(info->conn.username), Utf2T(info->conn.password), complete);
-
- return Netlib_NtlmCreateResponse(hProvider, text, nullptr, nullptr, complete);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// md5 auth - digest-based authorization
-
-TMD5Auth::TMD5Auth(ThreadData *info) :
- TJabberAuth(info, "DIGEST-MD5"),
- iCallCount(0)
-{
- priority = 301;
-}
-
-TMD5Auth::~TMD5Auth()
-{
-}
-
-char* TMD5Auth::getChallenge(const char *challenge)
-{
- if (iCallCount > 0)
- return nullptr;
-
- iCallCount++;
-
- size_t resultLen;
- ptrA text((char*)mir_base64_decode(challenge, &resultLen));
-
- TStringPairs pairs(text);
- const char *realm = pairs["realm"], *nonce = pairs["nonce"];
-
- char cnonce[40], tmpBuf[40];
- uint32_t digest[4], hash1[4], hash2[4];
- mir_md5_state_t ctx;
-
- Utils_GetRandom(digest, sizeof(digest));
- mir_snprintf(cnonce, "%08x%08x%08x%08x", htonl(digest[0]), htonl(digest[1]), htonl(digest[2]), htonl(digest[3]));
-
- ptrA serv(mir_utf8encode(info->conn.server));
-
- mir_md5_init(&ctx);
- mir_md5_append(&ctx, (uint8_t*)info->conn.username, (int)mir_strlen(info->conn.username));
- mir_md5_append(&ctx, (uint8_t*)":", 1);
- mir_md5_append(&ctx, (uint8_t*)realm, (int)mir_strlen(realm));
- mir_md5_append(&ctx, (uint8_t*)":", 1);
- mir_md5_append(&ctx, (uint8_t*)info->conn.password, (int)mir_strlen(info->conn.password));
- mir_md5_finish(&ctx, (uint8_t*)hash1);
-
- mir_md5_init(&ctx);
- mir_md5_append(&ctx, (uint8_t*)hash1, 16);
- mir_md5_append(&ctx, (uint8_t*)":", 1);
- mir_md5_append(&ctx, (uint8_t*)nonce, (int)mir_strlen(nonce));
- mir_md5_append(&ctx, (uint8_t*)":", 1);
- mir_md5_append(&ctx, (uint8_t*)cnonce, (int)mir_strlen(cnonce));
- mir_md5_finish(&ctx, (uint8_t*)hash1);
-
- mir_md5_init(&ctx);
- mir_md5_append(&ctx, (uint8_t*)"AUTHENTICATE:xmpp/", 18);
- mir_md5_append(&ctx, (uint8_t*)(char*)serv, (int)mir_strlen(serv));
- mir_md5_finish(&ctx, (uint8_t*)hash2);
-
- mir_md5_init(&ctx);
- mir_snprintf(tmpBuf, "%08x%08x%08x%08x", htonl(hash1[0]), htonl(hash1[1]), htonl(hash1[2]), htonl(hash1[3]));
- mir_md5_append(&ctx, (uint8_t*)tmpBuf, (int)mir_strlen(tmpBuf));
- mir_md5_append(&ctx, (uint8_t*)":", 1);
- mir_md5_append(&ctx, (uint8_t*)nonce, (int)mir_strlen(nonce));
- mir_snprintf(tmpBuf, ":%08d:", iCallCount);
- mir_md5_append(&ctx, (uint8_t*)tmpBuf, (int)mir_strlen(tmpBuf));
- mir_md5_append(&ctx, (uint8_t*)cnonce, (int)mir_strlen(cnonce));
- mir_md5_append(&ctx, (uint8_t*)":auth:", 6);
- mir_snprintf(tmpBuf, "%08x%08x%08x%08x", htonl(hash2[0]), htonl(hash2[1]), htonl(hash2[2]), htonl(hash2[3]));
- mir_md5_append(&ctx, (uint8_t*)tmpBuf, (int)mir_strlen(tmpBuf));
- mir_md5_finish(&ctx, (uint8_t*)digest);
-
- char *buf = (char*)alloca(8000);
- int cbLen = mir_snprintf(buf, 8000,
- "username=\"%s\",realm=\"%s\",nonce=\"%s\",cnonce=\"%s\",nc=%08d,"
- "qop=auth,digest-uri=\"xmpp/%s\",charset=utf-8,response=%08x%08x%08x%08x",
- info->conn.username, realm, nonce, cnonce, iCallCount, serv.get(),
- htonl(digest[0]), htonl(digest[1]), htonl(digest[2]), htonl(digest[3]));
-
- return mir_base64_encode(buf, cbLen);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// SCRAM-SHA-1 authorization
-
-TScramAuth::TScramAuth(ThreadData *info, const char *pszMech, const EVP_MD *pMethod, int iPriority) :
- TJabberAuth(info, pszMech),
- hashMethod(pMethod)
-{
- priority = iPriority;
-}
-
-TScramAuth::~TScramAuth()
-{
- mir_free(cnonce);
- mir_free(msg1);
- mir_free(serverSignature);
-}
-
-void TScramAuth::Hi(uint8_t *res, char *passw, size_t passwLen, char *salt, size_t saltLen, int ind)
-{
- size_t bufLen = saltLen + sizeof(UINT32);
- uint8_t *u = (uint8_t*)_alloca(max(bufLen, EVP_MAX_MD_SIZE));
- memcpy(u, salt, saltLen); *(UINT32*)(u + saltLen) = htonl(1);
-
- memset(res, 0, EVP_MAX_MD_SIZE);
-
- for (int i = 0; i < ind; i++) {
- unsigned int len;
- HMAC(hashMethod, (uint8_t*)passw, (unsigned)passwLen, u, (unsigned)bufLen, u, &len);
- bufLen = EVP_MD_size(hashMethod);
-
- for (size_t j = 0; j < bufLen; j++)
- res[j] ^= u[j];
- }
-}
-
-char* TScramAuth::getInitialRequest()
-{
- unsigned char nonce[24];
- Utils_GetRandom(nonce, sizeof(nonce));
- cnonce = mir_base64_encode(nonce, sizeof(nonce));
-
- bindFlag = "n,,";
- if ((priority % 10) == 1) {
- if (info->proto->m_bTlsExporter) {
- int cbLen, tlsVer = true;
- void *pData = Netlib_GetTlsUnique(info->s, cbLen, tlsVer);
- if (pData == nullptr)
- return nullptr;
-
- bindFlag = (tlsVer == 13) ? "p=tls-exporter,," : "p=tls-unique,,";
- bindData.append(pData, cbLen);
- }
- }
-
- CMStringA buf(FORMAT, "n=%s,r=%s", info->conn.username, cnonce);
- msg1 = mir_strdup(buf);
-
- buf.Insert(0, bindFlag);
- return mir_base64_encode(buf, buf.GetLength());
-}
-
-char* TScramAuth::getChallenge(const char *challenge)
-{
- size_t chlLen, saltLen = 0;
- ptrA snonce, salt;
- int ind = -1;
-
- ptrA chl((char *)mir_base64_decode(challenge, &chlLen)), cbd;
- if (bindData.isEmpty())
- cbd = mir_base64_encode(bindFlag, mir_strlen(bindFlag));
- else {
- bindData.appendBefore((void*)bindFlag, mir_strlen(bindFlag));
- cbd = mir_base64_encode(bindData.data(), bindData.length());
- }
-
- for (char *p = strtok(NEWSTR_ALLOCA(chl), ","); p != nullptr; p = strtok(nullptr, ",")) {
- if (*p == 'r' && p[1] == '=') { // snonce
- if (strncmp(cnonce, p + 2, mir_strlen(cnonce)))
- return nullptr;
- snonce = mir_strdup(p + 2);
- }
- else if (*p == 's' && p[1] == '=') // salt
- salt = (char*)mir_base64_decode(p + 2, &saltLen);
- else if (*p == 'i' && p[1] == '=')
- ind = atoi(p + 2);
- }
-
- if (snonce == nullptr || salt == nullptr || ind == -1)
- return nullptr;
-
- int hashSize = EVP_MD_size(hashMethod);
-
- uint8_t saltedPassw[EVP_MAX_MD_SIZE];
- Hi(saltedPassw, info->conn.password, mir_strlen(info->conn.password), salt, saltLen, ind);
-
- uint8_t clientKey[EVP_MAX_MD_SIZE];
- unsigned int len;
- HMAC(hashMethod, saltedPassw, hashSize, (uint8_t*)"Client Key", 10, clientKey, &len);
-
- uint8_t storedKey[EVP_MAX_MD_SIZE];
- {
- EVP_MD_CTX *pctx = EVP_MD_CTX_new();
- EVP_DigestInit(pctx, hashMethod);
- EVP_DigestUpdate(pctx, clientKey, hashSize);
- EVP_DigestFinal(pctx, storedKey, &len);
- EVP_MD_CTX_free(pctx);
- }
-
- uint8_t clientSig[EVP_MAX_MD_SIZE];
- CMStringA authmsg(FORMAT, "%s,%s,c=%s,r=%s", msg1, chl.get(), cbd.get(), snonce.get());
- HMAC(hashMethod, storedKey, hashSize, (uint8_t*)authmsg.c_str(), authmsg.GetLength(), clientSig, &len);
-
- uint8_t clientProof[EVP_MAX_MD_SIZE];
- for (int j = 0; j < hashSize; j++)
- clientProof[j] = clientKey[j] ^ clientSig[j];
-
- /* Calculate the server signature */
- uint8_t serverKey[EVP_MAX_MD_SIZE];
- HMAC(hashMethod, saltedPassw, hashSize, (uint8_t*)"Server Key", 10, serverKey, &len);
-
- uint8_t srvSig[EVP_MAX_MD_SIZE];
- HMAC(hashMethod, serverKey, hashSize, (uint8_t*)authmsg.c_str(), authmsg.GetLength(), srvSig, &len);
- serverSignature = mir_base64_encode(srvSig, hashSize);
-
- ptrA encproof(mir_base64_encode(clientProof, hashSize));
- CMStringA buf(FORMAT, "c=%s,r=%s,p=%s", cbd.get(), snonce.get(), encproof.get());
- return mir_base64_encode(buf, buf.GetLength());
-}
-
-bool TScramAuth::validateLogin(const char *challenge)
-{
- size_t chlLen;
- ptrA chl((char*)mir_base64_decode(challenge, &chlLen));
- return chl && strncmp((char*)chl + 2, serverSignature, chlLen - 2) == 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// plain auth - the most simple one
-
-TPlainAuth::TPlainAuth(ThreadData *info, bool old) :
- TJabberAuth(info, "PLAIN"),
- bOld(old)
-{
- priority = (old) ? 100 : 101;
-}
-
-char* TPlainAuth::getInitialRequest()
-{
- CMStringA buf;
- if (bOld)
- buf.Format("%s@%s%c%s%c%s", info->conn.username, info->conn.server, 0, info->conn.username, 0, info->conn.password);
- else
- buf.Format("%c%s%c%s", 0, info->conn.username, 0, info->conn.password);
-
- return mir_base64_encode(buf, buf.GetLength());
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// basic type
-
-TJabberAuth::TJabberAuth(ThreadData *pInfo, const char *pszMech) :
- info(pInfo),
- szName(mir_strdup(pszMech))
-{
-}
-
-TJabberAuth::~TJabberAuth()
-{
-}
-
-char* TJabberAuth::getInitialRequest()
-{
- return nullptr;
-}
-
-char* TJabberAuth::getChallenge(const char*)
-{
- return nullptr;
-}
-
-bool TJabberAuth::validateLogin(const char*)
-{
- return true;
-}
|