summaryrefslogtreecommitdiff
path: root/protocols/JabberG
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/JabberG')
-rw-r--r--protocols/JabberG/jabber.vcxproj4
-rw-r--r--protocols/JabberG/jabber.vcxproj.filters12
-rw-r--r--protocols/JabberG/src/jabber.cpp4
-rw-r--r--protocols/JabberG/src/jabber_adhoc.cpp4
-rw-r--r--protocols/JabberG/src/jabber_agent.cpp2
-rw-r--r--protocols/JabberG/src/jabber_api.cpp2
-rw-r--r--protocols/JabberG/src/jabber_archive.cpp10
-rw-r--r--protocols/JabberG/src/jabber_auth.cpp443
-rw-r--r--protocols/JabberG/src/jabber_bookmarks.cpp6
-rw-r--r--protocols/JabberG/src/jabber_byte.cpp2
-rw-r--r--protocols/JabberG/src/jabber_byte.h2
-rw-r--r--protocols/JabberG/src/jabber_caps.cpp2
-rw-r--r--protocols/JabberG/src/jabber_caps.h2
-rw-r--r--protocols/JabberG/src/jabber_captcha.cpp2
-rw-r--r--protocols/JabberG/src/jabber_chat.cpp48
-rw-r--r--protocols/JabberG/src/jabber_console.cpp2
-rw-r--r--protocols/JabberG/src/jabber_disco.cpp4
-rw-r--r--protocols/JabberG/src/jabber_disco.h2
-rw-r--r--protocols/JabberG/src/jabber_events.cpp2
-rw-r--r--protocols/JabberG/src/jabber_file.cpp36
-rw-r--r--protocols/JabberG/src/jabber_form.cpp2
-rw-r--r--protocols/JabberG/src/jabber_ft.cpp6
-rw-r--r--protocols/JabberG/src/jabber_groupchat.cpp2
-rw-r--r--protocols/JabberG/src/jabber_ibb.cpp2
-rw-r--r--protocols/JabberG/src/jabber_ibb.h2
-rw-r--r--protocols/JabberG/src/jabber_icolib.cpp12
-rw-r--r--protocols/JabberG/src/jabber_icolib.h2
-rw-r--r--protocols/JabberG/src/jabber_iq.cpp2
-rw-r--r--protocols/JabberG/src/jabber_iq.h2
-rw-r--r--protocols/JabberG/src/jabber_iq_handlers.cpp4
-rw-r--r--protocols/JabberG/src/jabber_iqid.cpp16
-rw-r--r--protocols/JabberG/src/jabber_iqid_muc.cpp2
-rw-r--r--protocols/JabberG/src/jabber_libstr.cpp2
-rw-r--r--protocols/JabberG/src/jabber_list.cpp2
-rw-r--r--protocols/JabberG/src/jabber_list.h2
-rw-r--r--protocols/JabberG/src/jabber_mam.cpp2
-rw-r--r--protocols/JabberG/src/jabber_menu.cpp48
-rw-r--r--protocols/JabberG/src/jabber_message_handlers.cpp2
-rw-r--r--protocols/JabberG/src/jabber_message_manager.cpp2
-rw-r--r--protocols/JabberG/src/jabber_message_manager.h2
-rw-r--r--protocols/JabberG/src/jabber_misc.cpp8
-rw-r--r--protocols/JabberG/src/jabber_notes.cpp2
-rw-r--r--protocols/JabberG/src/jabber_notes.h2
-rw-r--r--protocols/JabberG/src/jabber_omemo.cpp44
-rw-r--r--protocols/JabberG/src/jabber_omemo.h2
-rw-r--r--protocols/JabberG/src/jabber_opt.cpp2
-rw-r--r--protocols/JabberG/src/jabber_password.cpp2
-rw-r--r--protocols/JabberG/src/jabber_presence_manager.cpp2
-rw-r--r--protocols/JabberG/src/jabber_presence_manager.h2
-rw-r--r--protocols/JabberG/src/jabber_privacy.cpp2
-rw-r--r--protocols/JabberG/src/jabber_privacy.h2
-rw-r--r--protocols/JabberG/src/jabber_proto.cpp20
-rw-r--r--protocols/JabberG/src/jabber_proto.h92
-rw-r--r--protocols/JabberG/src/jabber_rc.cpp6
-rw-r--r--protocols/JabberG/src/jabber_rc.h2
-rw-r--r--protocols/JabberG/src/jabber_roster.cpp2
-rw-r--r--protocols/JabberG/src/jabber_sasl2.cpp129
-rw-r--r--protocols/JabberG/src/jabber_search.cpp2
-rw-r--r--protocols/JabberG/src/jabber_search.h2
-rw-r--r--protocols/JabberG/src/jabber_secur.cpp442
-rw-r--r--protocols/JabberG/src/jabber_secur.h123
-rw-r--r--protocols/JabberG/src/jabber_send_manager.cpp2
-rw-r--r--protocols/JabberG/src/jabber_send_manager.h2
-rw-r--r--protocols/JabberG/src/jabber_strm_mgmt.cpp2
-rw-r--r--protocols/JabberG/src/jabber_strm_mgmt.h2
-rw-r--r--protocols/JabberG/src/jabber_svc.cpp2
-rw-r--r--protocols/JabberG/src/jabber_thread.cpp106
-rw-r--r--protocols/JabberG/src/jabber_treelist.cpp2
-rw-r--r--protocols/JabberG/src/jabber_userinfo.cpp2
-rw-r--r--protocols/JabberG/src/jabber_util.cpp57
-rw-r--r--protocols/JabberG/src/jabber_vcard.cpp2
-rw-r--r--protocols/JabberG/src/jabber_xml.cpp2
-rw-r--r--protocols/JabberG/src/jabber_xml.h2
-rw-r--r--protocols/JabberG/src/jabber_xstatus.cpp2
-rw-r--r--protocols/JabberG/src/jabber_xstatus.h2
-rw-r--r--protocols/JabberG/src/jabber_zstream.cpp2
-rw-r--r--protocols/JabberG/src/stdafx.cxx2
-rw-r--r--protocols/JabberG/src/stdafx.h8
-rw-r--r--protocols/JabberG/src/version.h2
79 files changed, 894 insertions, 904 deletions
diff --git a/protocols/JabberG/jabber.vcxproj b/protocols/JabberG/jabber.vcxproj
index ea5a4e6cd3..c624c1bfa4 100644
--- a/protocols/JabberG/jabber.vcxproj
+++ b/protocols/JabberG/jabber.vcxproj
@@ -34,6 +34,7 @@
<ClCompile Include="src\jabber_agent.cpp" />
<ClCompile Include="src\jabber_api.cpp" />
<ClCompile Include="src\jabber_archive.cpp" />
+ <ClCompile Include="src\jabber_auth.cpp" />
<ClCompile Include="src\jabber_bookmarks.cpp" />
<ClCompile Include="src\jabber_byte.cpp" />
<ClCompile Include="src\jabber_caps.cpp" />
@@ -68,8 +69,8 @@
<ClCompile Include="src\jabber_proto.cpp" />
<ClCompile Include="src\jabber_rc.cpp" />
<ClCompile Include="src\jabber_roster.cpp" />
+ <ClCompile Include="src\jabber_sasl2.cpp" />
<ClCompile Include="src\jabber_search.cpp" />
- <ClCompile Include="src\jabber_secur.cpp" />
<ClCompile Include="src\jabber_send_manager.cpp" />
<ClCompile Include="src\jabber_strm_mgmt.cpp" />
<ClCompile Include="src\jabber_svc.cpp" />
@@ -100,7 +101,6 @@
<ClInclude Include="src\jabber_proto.h" />
<ClInclude Include="src\jabber_rc.h" />
<ClInclude Include="src\jabber_search.h" />
- <ClInclude Include="src\jabber_secur.h" />
<ClInclude Include="src\jabber_send_manager.h" />
<ClInclude Include="src\jabber_strm_mgmt.h" />
<ClInclude Include="src\jabber_xml.h" />
diff --git a/protocols/JabberG/jabber.vcxproj.filters b/protocols/JabberG/jabber.vcxproj.filters
index 4bed895b71..b87ab85845 100644
--- a/protocols/JabberG/jabber.vcxproj.filters
+++ b/protocols/JabberG/jabber.vcxproj.filters
@@ -119,9 +119,6 @@
<ClCompile Include="src\jabber_search.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="src\jabber_secur.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="src\jabber_send_manager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -164,6 +161,12 @@
<ClCompile Include="..\..\utils\mir_signal.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\jabber_sasl2.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\jabber_auth.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\jabber_byte.h">
@@ -211,9 +214,6 @@
<ClInclude Include="src\jabber_search.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="src\jabber_secur.h">
- <Filter>Header Files</Filter>
- </ClInclude>
<ClInclude Include="src\jabber_send_manager.h">
<Filter>Header Files</Filter>
</ClInclude>
diff --git a/protocols/JabberG/src/jabber.cpp b/protocols/JabberG/src/jabber.cpp
index dad476efb6..3302d6e95d 100644
--- a/protocols/JabberG/src/jabber.cpp
+++ b/protocols/JabberG/src/jabber.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
@@ -141,7 +141,7 @@ int CMPlugin::Load()
// Init extra icons
hExtraActivity = ExtraIcon_RegisterIcolib("activity", LPGEN("Jabber Activity"), "jabber_dancing");
hExtraMood = ExtraIcon_RegisterIcolib("mood", LPGEN("Jabber Mood"), "jabber_contemplative");
- g_MenuInit();
+ CJabberProto::GlobalMenuInit();
HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded);
JabberUserInfoInit();
diff --git a/protocols/JabberG/src/jabber_adhoc.cpp b/protocols/JabberG/src/jabber_adhoc.cpp
index e1ab9548ae..6aa603c045 100644
--- a/protocols/JabberG/src/jabber_adhoc.cpp
+++ b/protocols/JabberG/src/jabber_adhoc.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Artem Shpynov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 Miranda NG team
Module implements an XMPP protocol extension for reporting and executing ad-hoc,
human-oriented commands according to XEP-0050: Ad-Hoc Commands
@@ -488,7 +488,7 @@ static INT_PTR CALLBACK JabberAdHoc_CommandDlgProc(HWND hwndDlg, UINT msg, WPARA
return FALSE;
}
-int __cdecl CJabberProto::ContactMenuRunCommands(WPARAM hContact, LPARAM lParam)
+INT_PTR __cdecl CJabberProto::ContactMenuRunCommands(WPARAM hContact, LPARAM lParam)
{
int res = -1;
diff --git a/protocols/JabberG/src/jabber_agent.cpp b/protocols/JabberG/src/jabber_agent.cpp
index 2bb08292e1..c87eec69cf 100644
--- a/protocols/JabberG/src/jabber_agent.cpp
+++ b/protocols/JabberG/src/jabber_agent.cpp
@@ -4,7 +4,7 @@ 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
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_api.cpp b/protocols/JabberG/src/jabber_api.cpp
index 1183e2c9e3..13b742eab7 100644
--- a/protocols/JabberG/src/jabber_api.cpp
+++ b/protocols/JabberG/src/jabber_api.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_archive.cpp b/protocols/JabberG/src/jabber_archive.cpp
index 8da5128406..dde2369d4e 100644
--- a/protocols/JabberG/src/jabber_archive.cpp
+++ b/protocols/JabberG/src/jabber_archive.cpp
@@ -4,7 +4,7 @@ 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
+Copyright (C) 2012-25 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
@@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
bool operator==(const DBEVENTINFO &ev1, const DBEVENTINFO &ev2)
{
- return ev1.timestamp == ev2.timestamp && ev1.eventType == ev2.eventType && ev1.cbBlob == ev2.cbBlob && (ev1.flags & DBEF_SENT) == (ev2.flags & DBEF_SENT);
+ return ev1.iTimestamp == ev2.iTimestamp && ev1.eventType == ev2.eventType && ev1.cbBlob == ev2.cbBlob && ev1.bSent == ev2.bSent;
}
void CJabberProto::EnableArchive(bool bEnable)
@@ -117,9 +117,9 @@ void CJabberProto::OnIqResultGetCollection(const TiXmlElement *iqNode, CJabberIq
msg.process();
- tmStart = msg.dbei.timestamp;
- if (msg.dbei.timestamp > tmLast)
- tmLast = msg.dbei.timestamp;
+ tmStart = msg.dbei.getUnixtime();
+ if (msg.dbei.getUnixtime() > tmLast)
+ tmLast = msg.dbei.getUnixtime();
}
if (tmLast != 0)
diff --git a/protocols/JabberG/src/jabber_auth.cpp b/protocols/JabberG/src/jabber_auth.cpp
new file mode 100644
index 0000000000..c76ccc700a
--- /dev/null
+++ b/protocols/JabberG/src/jabber_auth.cpp
@@ -0,0 +1,443 @@
+/*
+
+Jabber Protocol Plugin for Miranda NG
+
+Copyright (c) 2002-04 Santithorn Bunchua
+Copyright (c) 2005-12 George Hazan
+Copyright (C) 2012-25 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"
+
+class TPlainAuth : public TJabberAuth
+{
+ typedef TJabberAuth CSuper;
+
+ bool bOld;
+
+public:
+ TPlainAuth(ThreadData *info, bool old) :
+ TJabberAuth(info, "PLAIN"),
+ bOld(old)
+ {
+ priority = (old) ? 100 : 101;
+ }
+
+ char* getInitialRequest() override
+ {
+ 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());
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// ntlm auth - LanServer based authorization
+
+class TNtlmAuth : public TJabberAuth
+{
+ typedef TJabberAuth CSuper;
+
+ HANDLE hProvider = 0;
+ ptrA szInitRequest;
+
+public:
+ 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()
+ {
+ if (hProvider != nullptr)
+ Netlib_DestroySecurityProvider(hProvider);
+ }
+
+ char *getInitialRequest() override
+ {
+ return szInitRequest.detach();
+ }
+
+ char *getChallenge(const char *challenge) override
+ {
+ 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);
+ }
+
+ bool 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;
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// md5 auth - digest-based authorization
+
+class TMD5Auth : public TJabberAuth
+{
+ typedef TJabberAuth CSuper;
+
+ int iCallCount = 0;
+
+public:
+ TMD5Auth(ThreadData *info) :
+ TJabberAuth(info, "DIGEST-MD5")
+ {
+ priority = 301;
+ }
+
+ char *getChallenge(const char *challenge) override
+ {
+ 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
+
+void Hi(const EVP_MD *hashMethod, uint8_t *res, char *passw, size_t passwLen, char *salt, size_t saltLen, int iterations)
+{
+ 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 < iterations; 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];
+ }
+}
+
+class TScramAuth : public TJabberAuth
+{
+ typedef TJabberAuth CSuper;
+
+ char *bindFlag, *cnonce = 0, *msg1 = 0, *serverSignature = 0;
+ MBinBuffer bindData;
+ const EVP_MD *hashMethod;
+
+public:
+ TScramAuth(ThreadData *info, const char *pszMech, const EVP_MD *pMethod, int iPriority) :
+ TJabberAuth(info, pszMech),
+ hashMethod(pMethod)
+ {
+ priority = iPriority;
+ }
+
+ ~TScramAuth()
+ {
+ mir_free(cnonce);
+ mir_free(msg1);
+ mir_free(serverSignature);
+ }
+
+ char* getInitialRequest() override
+ {
+ 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* getChallenge(const char *challenge) override
+ {
+ size_t chlLen, saltLen = 0;
+ ptrA snonce, salt;
+ int iterations = -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] == '=')
+ iterations = atoi(p + 2);
+ }
+
+ if (snonce == nullptr || salt == nullptr || iterations == -1)
+ return nullptr;
+
+ int hashSize = EVP_MD_size(hashMethod);
+
+ uint8_t saltedPassw[EVP_MAX_MD_SIZE];
+ Hi(hashMethod, saltedPassw, info->conn.password, mir_strlen(info->conn.password), salt, saltLen, iterations);
+
+ 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 validateLogin(const char *challenge) override
+ {
+ size_t chlLen;
+ ptrA chl((char *)mir_base64_decode(challenge, &chlLen));
+ return chl && strncmp((char *)chl + 2, serverSignature, chlLen - 2) == 0;
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// module entry point
+
+bool CJabberProto::OnProcessMechanism(const TiXmlElement *n, ThreadData *info)
+{
+ if (!mir_strcmp(n->Name(), "mechanism")) {
+ TJabberAuth *pAuth = nullptr;
+ auto *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;
+}
diff --git a/protocols/JabberG/src/jabber_bookmarks.cpp b/protocols/JabberG/src/jabber_bookmarks.cpp
index 04b2fe46bc..931953910f 100644
--- a/protocols/JabberG/src/jabber_bookmarks.cpp
+++ b/protocols/JabberG/src/jabber_bookmarks.cpp
@@ -3,7 +3,7 @@
Jabber Protocol Plugin for Miranda NG
Copyright (c) 2007 Michael Stepura, George Hazan
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
@@ -422,13 +422,13 @@ INT_PTR __cdecl CJabberProto::OnMenuHandleBookmarks(WPARAM, LPARAM)
/////////////////////////////////////////////////////////////////////////////////////////
// Launches the Bookmark details window, lParam is JABBER_BOOKMARK_ITEM*
-int CJabberProto::AddEditBookmark(JABBER_LIST_ITEM *item)
+int CJabberProto::AddEditBookmark(JABBER_LIST_ITEM *item, MWindow hwndParent)
{
if (m_bJabberOnline) {
JabberAddBookmarkDlgParam param;
param.ppro = this;
param.m_item = item;//(JABBER_LIST_ITEM*)lParam;
- DialogBoxParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_BOOKMARK_ADD), nullptr, JabberAddBookmarkDlgProc, (LPARAM)&param);
+ DialogBoxParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_BOOKMARK_ADD), hwndParent, JabberAddBookmarkDlgProc, (LPARAM)&param);
}
return 0;
}
diff --git a/protocols/JabberG/src/jabber_byte.cpp b/protocols/JabberG/src/jabber_byte.cpp
index 1cb98c1da1..e19d5e6741 100644
--- a/protocols/JabberG/src/jabber_byte.cpp
+++ b/protocols/JabberG/src/jabber_byte.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_byte.h b/protocols/JabberG/src/jabber_byte.h
index aae8fe57ad..ed4a61e1b1 100644
--- a/protocols/JabberG/src/jabber_byte.h
+++ b/protocols/JabberG/src/jabber_byte.h
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_caps.cpp b/protocols/JabberG/src/jabber_caps.cpp
index efdd143703..ae6912c3fd 100644
--- a/protocols/JabberG/src/jabber_caps.cpp
+++ b/protocols/JabberG/src/jabber_caps.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_caps.h b/protocols/JabberG/src/jabber_caps.h
index 50da211ac5..b05ad8d893 100644
--- a/protocols/JabberG/src/jabber_caps.h
+++ b/protocols/JabberG/src/jabber_caps.h
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_captcha.cpp b/protocols/JabberG/src/jabber_captcha.cpp
index 147f2c9255..6f9048d219 100644
--- a/protocols/JabberG/src/jabber_captcha.cpp
+++ b/protocols/JabberG/src/jabber_captcha.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_chat.cpp b/protocols/JabberG/src/jabber_chat.cpp
index b68edc5c81..17b824d84b 100644
--- a/protocols/JabberG/src/jabber_chat.cpp
+++ b/protocols/JabberG/src/jabber_chat.cpp
@@ -4,7 +4,7 @@ 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
+Copyright (C) 2012-25 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
@@ -130,14 +130,11 @@ SESSION_INFO* CJabberProto::GcInit(JABBER_LIST_ITEM *item)
}
}
- ptrA tszNick(getUStringA(si->hContact, "MyNick"));
- if (tszNick != nullptr) {
- if (!mir_strcmp(tszNick, szNick))
- delSetting(si->hContact, "MyNick");
- else
- setUString(si->hContact, "MyNick", item->nick);
- }
- else setUString(si->hContact, "MyNick", item->nick);
+ ptrA szMyNick(getUStringA(si->hContact, "MyNick"));
+ if (szMyNick && getMStringU("Nick") == szMyNick)
+ delSetting(si->hContact, "MyNick");
+ else
+ setUString(si->hContact, "MyNick", item->nick);
ptrA passw(getUStringA(si->hContact, "Password"));
if (mir_strcmp(passw, item->password)) {
@@ -1166,30 +1163,31 @@ static void sttLogListHook(CJabberProto *ppro, JABBER_LIST_ITEM *item, GCHOOK *g
{
CMStringW szBuffer, szTitle;
T2Utf roomJid(gch->si->ptszID);
+ auto *pDlg = gch->si->pDlg;
switch (gch->dwData) {
case IDM_LST_PARTICIPANT:
- ppro->AdminGet(roomJid, JABBER_FEAT_MUC_ADMIN, "role", "participant", &CJabberProto::OnIqResultMucGetVoiceList, gch->si->pDlg);
+ ppro->AdminGet(roomJid, JABBER_FEAT_MUC_ADMIN, "role", "participant", &CJabberProto::OnIqResultMucGetVoiceList, pDlg);
break;
case IDM_LST_MEMBER:
- ppro->AdminGet(roomJid, JABBER_FEAT_MUC_ADMIN, "affiliation", "member", &CJabberProto::OnIqResultMucGetMemberList, gch->si->pDlg);
+ ppro->AdminGet(roomJid, JABBER_FEAT_MUC_ADMIN, "affiliation", "member", &CJabberProto::OnIqResultMucGetMemberList, pDlg);
break;
case IDM_LST_MODERATOR:
- ppro->AdminGet(roomJid, JABBER_FEAT_MUC_ADMIN, "role", "moderator", &CJabberProto::OnIqResultMucGetModeratorList, gch->si->pDlg);
+ ppro->AdminGet(roomJid, JABBER_FEAT_MUC_ADMIN, "role", "moderator", &CJabberProto::OnIqResultMucGetModeratorList, pDlg);
break;
case IDM_LST_BAN:
- ppro->AdminGet(roomJid, JABBER_FEAT_MUC_ADMIN, "affiliation", "outcast", &CJabberProto::OnIqResultMucGetBanList, gch->si->pDlg);
+ ppro->AdminGet(roomJid, JABBER_FEAT_MUC_ADMIN, "affiliation", "outcast", &CJabberProto::OnIqResultMucGetBanList, pDlg);
break;
case IDM_LST_ADMIN:
- ppro->AdminGet(roomJid, JABBER_FEAT_MUC_ADMIN, "affiliation", "admin", &CJabberProto::OnIqResultMucGetAdminList, gch->si->pDlg);
+ ppro->AdminGet(roomJid, JABBER_FEAT_MUC_ADMIN, "affiliation", "admin", &CJabberProto::OnIqResultMucGetAdminList, pDlg);
break;
case IDM_LST_OWNER:
- ppro->AdminGet(roomJid, JABBER_FEAT_MUC_ADMIN, "affiliation", "owner", &CJabberProto::OnIqResultMucGetOwnerList, gch->si->pDlg);
+ ppro->AdminGet(roomJid, JABBER_FEAT_MUC_ADMIN, "affiliation", "owner", &CJabberProto::OnIqResultMucGetOwnerList, pDlg);
break;
case IDM_AVATAR:
@@ -1226,11 +1224,10 @@ static void sttLogListHook(CJabberProto *ppro, JABBER_LIST_ITEM *item, GCHOOK *g
break;
case IDM_INVITE:
- {
- auto *pDlg = new CGroupchatInviteDlg(ppro, roomJid);
- if (gch->si->pDlg)
- pDlg->SetParent(gch->si->pDlg->GetHwnd());
- pDlg->Show();
+ if (auto *pInviteDlg = new CGroupchatInviteDlg(ppro, roomJid)) {
+ if (pDlg)
+ pInviteDlg->SetParent(pDlg->GetHwnd());
+ pInviteDlg->Show();
}
break;
@@ -1246,9 +1243,14 @@ static void sttLogListHook(CJabberProto *ppro, JABBER_LIST_ITEM *item, GCHOOK *g
item = ppro->ListGetItemPtr(LIST_CHATROOM, roomJid);
if (item != nullptr) {
replaceStr(item->type, "conference");
- MCONTACT hContact = ppro->HContactFromJID(item->jid);
- item->name = Clist_GetContactDisplayName(hContact);
- ppro->AddEditBookmark(item);
+ if (MCONTACT hContact = ppro->HContactFromJID(item->jid))
+ replaceStrW(item->name, Clist_GetContactDisplayName(hContact));
+ else {
+ ptrA szNick(JabberNickFromJID(roomJid));
+ if (szNick)
+ replaceStrW(item->name, Utf2T(szNick));
+ }
+ ppro->AddEditBookmark(item, pDlg ? pDlg->GetHwnd() : 0);
}
}
break;
diff --git a/protocols/JabberG/src/jabber_console.cpp b/protocols/JabberG/src/jabber_console.cpp
index b25aeb1410..e2380745d7 100644
--- a/protocols/JabberG/src/jabber_console.cpp
+++ b/protocols/JabberG/src/jabber_console.cpp
@@ -6,7 +6,7 @@ Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
Copyright (c) 2007 Victor Pavlychko
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_disco.cpp b/protocols/JabberG/src/jabber_disco.cpp
index 7ce1ec6a6a..779cc0447c 100644
--- a/protocols/JabberG/src/jabber_disco.cpp
+++ b/protocols/JabberG/src/jabber_disco.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
@@ -1143,7 +1143,7 @@ public:
}
replaceStr(item->type, "conference");
- m_proto->AddEditBookmark(item);
+ m_proto->AddEditBookmark(item, m_hwnd);
}
}
break;
diff --git a/protocols/JabberG/src/jabber_disco.h b/protocols/JabberG/src/jabber_disco.h
index 6914336b54..585a93082c 100644
--- a/protocols/JabberG/src/jabber_disco.h
+++ b/protocols/JabberG/src/jabber_disco.h
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2005-07 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_events.cpp b/protocols/JabberG/src/jabber_events.cpp
index 58d09eee16..47404ef200 100644
--- a/protocols/JabberG/src/jabber_events.cpp
+++ b/protocols/JabberG/src/jabber_events.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_file.cpp b/protocols/JabberG/src/jabber_file.cpp
index ddd2a5bdf2..317e67ad52 100644
--- a/protocols/JabberG/src/jabber_file.cpp
+++ b/protocols/JabberG/src/jabber_file.cpp
@@ -4,7 +4,7 @@ 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
+Copyright (C) 2012-25 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
@@ -148,37 +148,29 @@ void __cdecl CJabberProto::FileReceiveHttpThread(filetransfer *ft)
delete ft;
}
-void CJabberProto::FileProcessHttpDownload(MCONTACT hContact, const char *jid, const char *pszUrl, const char *pszDescr)
+void CJabberProto::FileProcessHttpDownload(DB::EventInfo &dbei, const char *pszUrl, const char *pszDescr)
{
// create incoming file transfer instead of a writing message
+ dbei.eventType = EVENTTYPE_FILE;
+
CMStringA szName;
const char *b = strrchr(pszUrl, '/') + 1;
while (*b != 0 && *b != '#' && *b != '?')
szName.AppendChar(*b++);
mir_urlDecode(szName.GetBuffer());
- MHttpRequest req(REQUEST_HEAD);
- req.m_szUrl = pszUrl;
-
- filetransfer *ft = new filetransfer(this, 0);
- ft->jid = mir_strdup(jid);
- ft->std.hContact = hContact;
- ft->type = FT_HTTP;
- ft->httpPath = mir_strdup(pszUrl);
- ft->std.totalFiles = 1;
- ft->std.szCurrentFile.w = mir_utf8decodeW(szName);
-
- NLHR_PTR pResp(Netlib_HttpTransaction(m_hNetlibUser, &req));
- if (pResp && pResp->resultCode == 200) {
- auto *p = (*pResp)["Content-Length"];
- if (p)
- ft->dwExpectedRecvFileSize = ft->std.currentFileSize = atoi(p);
+ DB::FILE_BLOB blob(nullptr, szName, pszDescr);
+ blob.setUrl(pszUrl);
+ if (File::bOfflineAuto) {
+ MHttpRequest req(REQUEST_HEAD);
+ req.m_szUrl = pszUrl;
+ NLHR_PTR pResp(Netlib_HttpTransaction(m_hNetlibUser, &req));
+ if (pResp && pResp->resultCode == 200)
+ if (auto *p = pResp->FindHeader("Content-Length"))
+ blob.setSize(_atoi64(p));
}
- DB::EventInfo dbei;
- dbei.flags = DBEF_TEMPORARY;
- dbei.timestamp = time(0);
- ProtoChainRecvFile(ft->std.hContact, DB::FILE_BLOB(ft, szName, pszDescr), dbei);
+ blob.write(dbei);
}
/////////////////////////////////////////////////////////////////////////////////////////
diff --git a/protocols/JabberG/src/jabber_form.cpp b/protocols/JabberG/src/jabber_form.cpp
index 7bfa69186b..6aee7f65b5 100644
--- a/protocols/JabberG/src/jabber_form.cpp
+++ b/protocols/JabberG/src/jabber_form.cpp
@@ -4,7 +4,7 @@ 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
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_ft.cpp b/protocols/JabberG/src/jabber_ft.cpp
index 481e049a1f..97299e6b5d 100644
--- a/protocols/JabberG/src/jabber_ft.cpp
+++ b/protocols/JabberG/src/jabber_ft.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
@@ -467,7 +467,7 @@ void CJabberProto::FtHandleSiRequest(const TiXmlElement *iqNode)
ft->std.totalBytes = ft->std.currentFileSize = filesize;
DB::EventInfo dbei;
- dbei.timestamp = time(0);
+ dbei.iTimestamp = time(0);
ProtoChainRecvFile(ft->std.hContact, DB::FILE_BLOB(ft, filename, XmlGetChildText(fileNode, "desc")), dbei);
return;
}
@@ -874,7 +874,7 @@ bool CJabberProto::FtTryInlineFile(filetransfer *ft)
DB::EventInfo dbei;
dbei.flags = DBEF_READ | DBEF_SENT;
dbei.pBlob = szMsg.GetBuffer();
- dbei.timestamp = time(0);
+ dbei.iTimestamp = time(0);
ProtoChainRecvMsg(ft->std.hContact, dbei);
return true;
}
diff --git a/protocols/JabberG/src/jabber_groupchat.cpp b/protocols/JabberG/src/jabber_groupchat.cpp
index 47ee405834..50106f78bd 100644
--- a/protocols/JabberG/src/jabber_groupchat.cpp
+++ b/protocols/JabberG/src/jabber_groupchat.cpp
@@ -4,7 +4,7 @@ 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
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_ibb.cpp b/protocols/JabberG/src/jabber_ibb.cpp
index 7113e21d39..786af813ac 100644
--- a/protocols/JabberG/src/jabber_ibb.cpp
+++ b/protocols/JabberG/src/jabber_ibb.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_ibb.h b/protocols/JabberG/src/jabber_ibb.h
index 3d64e8bf50..9ef9baa3b9 100644
--- a/protocols/JabberG/src/jabber_ibb.h
+++ b/protocols/JabberG/src/jabber_ibb.h
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_icolib.cpp b/protocols/JabberG/src/jabber_icolib.cpp
index d49a86bf37..583d49bbeb 100644
--- a/protocols/JabberG/src/jabber_icolib.cpp
+++ b/protocols/JabberG/src/jabber_icolib.cpp
@@ -4,7 +4,7 @@ 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
+Copyright (C) 2012-25 Miranda NG team
Idea & portions of code by Artem Shpynov
@@ -39,20 +39,15 @@ HIMAGELIST hAdvancedStatusIcon = nullptr;
struct
{
- char *mask;
- char* proto;
+ char *mask, *proto;
}
static TransportProtoTable[] =
{
- { "|*icq*|jit*", "ICQ" },
- { "mrim*", "MRA" },
-
- //request #3094
+ // request #3094
{ "|gg*|gadu*", "GaduGadu" },
{ "tv*", "TV" },
{ "dict*", "Dictionary" },
{ "weather*", "Weather" },
- { "skype*", "Skype" },
{ "sms*", "SMS" },
{ "smtp*", "SMTP" },
@@ -64,7 +59,6 @@ static TransportProtoTable[] =
{ "disk*", "Jabber Disk" },
{ "irc*", "IRC" },
{ "rss*", "RSS" },
- { "tlen*", "Tlen" },
// German social networks
{ "studivz*", "StudiVZ" },
diff --git a/protocols/JabberG/src/jabber_icolib.h b/protocols/JabberG/src/jabber_icolib.h
index 46988dac29..d2d661a0df 100644
--- a/protocols/JabberG/src/jabber_icolib.h
+++ b/protocols/JabberG/src/jabber_icolib.h
@@ -6,7 +6,7 @@ Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007-09 Maxim Mluhov
Copyright (c) 2007-09 Victor Pavlychko
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_iq.cpp b/protocols/JabberG/src/jabber_iq.cpp
index 7f46247e2c..4f92829261 100644
--- a/protocols/JabberG/src/jabber_iq.cpp
+++ b/protocols/JabberG/src/jabber_iq.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_iq.h b/protocols/JabberG/src/jabber_iq.h
index d4ede7b06d..2e2c7bfd6e 100644
--- a/protocols/JabberG/src/jabber_iq.h
+++ b/protocols/JabberG/src/jabber_iq.h
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_iq_handlers.cpp b/protocols/JabberG/src/jabber_iq_handlers.cpp
index eb73be3a35..ede6e546a1 100644
--- a/protocols/JabberG/src/jabber_iq_handlers.cpp
+++ b/protocols/JabberG/src/jabber_iq_handlers.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
@@ -324,7 +324,7 @@ bool CJabberProto::OnIqRequestOOB(const TiXmlElement*, CJabberIqInfo *pInfo)
str2 = ft->httpPath;
DB::EventInfo dbei;
- dbei.timestamp = time(0);
+ dbei.iTimestamp = time(0);
ProtoChainRecvFile(ft->std.hContact, DB::FILE_BLOB(ft, str2, desc), dbei);
}
else { // reject
diff --git a/protocols/JabberG/src/jabber_iqid.cpp b/protocols/JabberG/src/jabber_iqid.cpp
index 2839a73e30..8480bcacce 100644
--- a/protocols/JabberG/src/jabber_iqid.cpp
+++ b/protocols/JabberG/src/jabber_iqid.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
@@ -467,7 +467,7 @@ void CJabberProto::OnIqResultGetRoster(const TiXmlElement *iqNode, CJabberIqInfo
continue;
MCONTACT hContact = HContactFromJID(jid);
- if (hContact == 0) // Received roster has a new JID.
+ if (hContact == 0 && !IsMyOwnJID(jid)) // Received roster has a new JID.
hContact = DBCreateContact(jid, nick, false, false); // Add the jid (with empty resource) to a Miranda's contact list.
JABBER_LIST_ITEM *item = ListAdd(LIST_ROSTER, jid, hContact);
@@ -760,17 +760,7 @@ void CJabberProto::OnIqResultGetVcard(const TiXmlElement *iqNode, CJabberIqInfo*
if (hContact != 0) {
if (sscanf(n->GetText(), "%d-%d-%d", &nYear, &nMonth, &nDay) == 3) {
hasBday = true;
- setWord(hContact, "BirthYear", (uint16_t)nYear);
- setByte(hContact, "BirthMonth", (uint8_t)nMonth);
- setByte(hContact, "BirthDay", (uint8_t)nDay);
-
- SYSTEMTIME sToday = { 0 };
- GetLocalTime(&sToday);
- int nAge = sToday.wYear - nYear;
- if (sToday.wMonth < nMonth || (sToday.wMonth == nMonth && sToday.wDay < nDay))
- nAge--;
- if (nAge)
- setWord(hContact, "Age", (uint16_t)nAge);
+ Contact::SetBirthday(hContact, nDay, nMonth, nYear);
}
}
else {
diff --git a/protocols/JabberG/src/jabber_iqid_muc.cpp b/protocols/JabberG/src/jabber_iqid_muc.cpp
index c5fffd013b..56ef2eceee 100644
--- a/protocols/JabberG/src/jabber_iqid_muc.cpp
+++ b/protocols/JabberG/src/jabber_iqid_muc.cpp
@@ -4,7 +4,7 @@ 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
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_libstr.cpp b/protocols/JabberG/src/jabber_libstr.cpp
index 02156776ea..d80c361d42 100644
--- a/protocols/JabberG/src/jabber_libstr.cpp
+++ b/protocols/JabberG/src/jabber_libstr.cpp
@@ -4,7 +4,7 @@ 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
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_list.cpp b/protocols/JabberG/src/jabber_list.cpp
index 7c2292106e..d12d51cb78 100644
--- a/protocols/JabberG/src/jabber_list.cpp
+++ b/protocols/JabberG/src/jabber_list.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_list.h b/protocols/JabberG/src/jabber_list.h
index 69e4e21fe5..187ce12bd6 100644
--- a/protocols/JabberG/src/jabber_list.h
+++ b/protocols/JabberG/src/jabber_list.h
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_mam.cpp b/protocols/JabberG/src/jabber_mam.cpp
index dd31bf93ff..2a42a0a4a8 100644
--- a/protocols/JabberG/src/jabber_mam.cpp
+++ b/protocols/JabberG/src/jabber_mam.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_menu.cpp b/protocols/JabberG/src/jabber_menu.cpp
index 37fbfdee45..622ce74f29 100644
--- a/protocols/JabberG/src/jabber_menu.cpp
+++ b/protocols/JabberG/src/jabber_menu.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
@@ -70,36 +70,6 @@ static INT_PTR JabberMenuChooseService(WPARAM wParam, LPARAM lParam)
return 0;
}
-static INT_PTR JabberMenuBookmarkAdd(WPARAM hContact, LPARAM lParam)
-{
- CJabberProto *ppro = CMPlugin::getInstance(hContact);
- return(ppro) ? ppro->OnMenuBookmarkAdd(hContact, lParam) : 0;
-}
-
-static INT_PTR JabberMenuTransportLogin(WPARAM hContact, LPARAM lParam)
-{
- CJabberProto *ppro = CMPlugin::getInstance(hContact);
- return(ppro) ? ppro->OnMenuTransportLogin(hContact, lParam) : 0;
-}
-
-static INT_PTR JabberMenuTransportResolve(WPARAM hContact, LPARAM lParam)
-{
- CJabberProto *ppro = CMPlugin::getInstance(hContact);
- return(ppro) ? ppro->OnMenuTransportResolve(hContact, lParam) : 0;
-}
-
-static INT_PTR JabberContactMenuRunCommands(WPARAM hContact, LPARAM lParam)
-{
- CJabberProto *ppro = CMPlugin::getInstance(hContact);
- return(ppro) ? ppro->ContactMenuRunCommands(hContact, lParam) : 0;
-}
-
-static INT_PTR JabberMenuSendNote(WPARAM hContact, LPARAM lParam)
-{
- CJabberProto *ppro = CMPlugin::getInstance(hContact);
- return(ppro) ? ppro->OnMenuSendNote(hContact, lParam) : 0;
-}
-
static INT_PTR JabberMenuHandleResource(WPARAM hContact, LPARAM lParam, LPARAM lRes)
{
CJabberProto *ppro = CMPlugin::getInstance(hContact);
@@ -126,7 +96,7 @@ static int JabberPrebuildContactMenu(WPARAM hContact, LPARAM lParam)
return(ppro) ? ppro->OnPrebuildContactMenu(hContact, lParam) : 0;
}
-void g_MenuInit(void)
+void CJabberProto::GlobalMenuInit()
{
hStatusMenuInit = CreateHookableEvent(ME_JABBER_MENUINIT);
@@ -155,7 +125,7 @@ void g_MenuInit(void)
mi.position = -1999901006;
mi.hIcolibItem = g_plugin.getIconHandle(IDI_BOOKMARKS);
g_hMenuAddBookmark = Menu_AddContactMenuItem(&mi);
- CreateServiceFunction(mi.pszService, JabberMenuBookmarkAdd);
+ CreateServiceFunction(mi.pszService, GlobalService<&CJabberProto::OnMenuBookmarkAdd>);
// Login/logout
SET_UID(mi, 0x7674d540, 0x2638, 0x4958, 0x99, 0xda, 0x8, 0x3f, 0xad, 0x66, 0x8f, 0xed);
@@ -164,7 +134,7 @@ void g_MenuInit(void)
mi.position = -1999901007;
mi.hIcolibItem = g_plugin.getIconHandle(IDI_LOGIN);
g_hMenuLogin = Menu_AddContactMenuItem(&mi);
- CreateServiceFunction(mi.pszService, JabberMenuTransportLogin);
+ CreateServiceFunction(mi.pszService, GlobalService<&CJabberProto::OnMenuTransportLogin>);
// Retrieve nicks
SET_UID(mi, 0x6adf70d9, 0x6e92, 0x4a4f, 0x90, 0x71, 0x67, 0xa7, 0xaa, 0x1a, 0x19, 0x7a);
@@ -173,7 +143,7 @@ void g_MenuInit(void)
mi.position = -1999901008;
mi.hIcolibItem = g_plugin.getIconHandle(IDI_REFRESH);
g_hMenuRefresh = Menu_AddContactMenuItem(&mi);
- CreateServiceFunction(mi.pszService, JabberMenuTransportResolve);
+ CreateServiceFunction(mi.pszService, GlobalService<&CJabberProto::OnMenuTransportResolve>);
// Run Commands
SET_UID(mi, 0x25546e26, 0xc82, 0x4715, 0xb8, 0xca, 0xe5, 0xf7, 0x2a, 0x58, 0x9, 0x2);
@@ -182,7 +152,7 @@ void g_MenuInit(void)
mi.position = -1999901009;
mi.hIcolibItem = g_plugin.getIconHandle(IDI_COMMAND);
g_hMenuCommands = Menu_AddContactMenuItem(&mi);
- CreateServiceFunction(mi.pszService, JabberContactMenuRunCommands);
+ CreateServiceFunction(mi.pszService, GlobalService<&CJabberProto::ContactMenuRunCommands>);
// Send Note
SET_UID(mi, 0xf4b0cc51, 0xab9, 0x4cf0, 0x96, 0xaa, 0x22, 0xa0, 0x33, 0x9b, 0x56, 0xc5);
@@ -191,7 +161,7 @@ void g_MenuInit(void)
mi.position = -1999901010;
mi.hIcolibItem = g_plugin.getIconHandle(IDI_SEND_NOTE);
g_hMenuSendNote = Menu_AddContactMenuItem(&mi);
- CreateServiceFunction(mi.pszService, JabberMenuSendNote);
+ CreateServiceFunction(mi.pszService, GlobalService<&CJabberProto::OnMenuSendNote>);
//////////////////////////////////////////////////////////////////////////////////////
// Direct Presence
@@ -640,7 +610,7 @@ void CJabberProto::UpdatePriorityMenu(int priority)
/////////////////////////////////////////////////////////////////////////////////////////
-void CJabberProto::GlobalMenuInit()
+void CJabberProto::MenuInit()
{
//////////////////////////////////////////////////////////////////////////////////////
// Account chooser menu
@@ -730,7 +700,7 @@ int g_OnToolbarInit(WPARAM, LPARAM)
return 0;
}
-void CJabberProto::GlobalMenuUninit()
+void CJabberProto::MenuUninit()
{
if (m_phMenuResourceItems) {
for (int i = 0; i < m_nMenuResourceItems; i++)
diff --git a/protocols/JabberG/src/jabber_message_handlers.cpp b/protocols/JabberG/src/jabber_message_handlers.cpp
index 46bb59d5ed..56e8826a9e 100644
--- a/protocols/JabberG/src/jabber_message_handlers.cpp
+++ b/protocols/JabberG/src/jabber_message_handlers.cpp
@@ -6,7 +6,7 @@ Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-08 George Hazan
Copyright (c) 2007 Maxim Mluhov
Copyright (c) 2008-09 Dmitriy Chervov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_message_manager.cpp b/protocols/JabberG/src/jabber_message_manager.cpp
index 431ceda20c..8f89c2cc06 100644
--- a/protocols/JabberG/src/jabber_message_manager.cpp
+++ b/protocols/JabberG/src/jabber_message_manager.cpp
@@ -6,7 +6,7 @@ Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-08 George Hazan
Copyright (c) 2007 Maxim Mluhov
Copyright (c) 2008-09 Dmitriy Chervov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_message_manager.h b/protocols/JabberG/src/jabber_message_manager.h
index 7f338557ee..2313837109 100644
--- a/protocols/JabberG/src/jabber_message_manager.h
+++ b/protocols/JabberG/src/jabber_message_manager.h
@@ -6,7 +6,7 @@ Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-08 George Hazan
Copyright (c) 2007 Maxim Mluhov
Copyright (c) 2008-09 Dmitriy Chervov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_misc.cpp b/protocols/JabberG/src/jabber_misc.cpp
index 23f8c9ecea..b50829a943 100644
--- a/protocols/JabberG/src/jabber_misc.cpp
+++ b/protocols/JabberG/src/jabber_misc.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
@@ -53,7 +53,7 @@ void CJabberProto::DBAddAuthRequest(const char *jid, const char *nick)
DB::AUTH_BLOB blob(hContact, nick, nullptr, nullptr, jid, nullptr);
DB::EventInfo dbei;
- dbei.timestamp = (uint32_t)time(0);
+ dbei.iTimestamp = (uint32_t)time(0);
dbei.cbBlob = blob.size();
dbei.pBlob = blob;
ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&dbei);
@@ -126,7 +126,7 @@ bool CJabberProto::AddDbPresenceEvent(MCONTACT hContact, uint8_t btEventType)
dbei.cbBlob = sizeof(btEventType);
dbei.eventType = EVENTTYPE_JABBER_PRESENCE;
dbei.flags = DBEF_READ;
- dbei.timestamp = time(0);
+ dbei.iTimestamp = time(0);
dbei.szModule = m_szModuleName;
db_event_add(hContact, &dbei);
return true;
@@ -500,7 +500,7 @@ void CJabberProto::OnGetBob(const TiXmlElement *node, CJabberIqInfo *pReq)
wszFileName.Insert(0, L"[img]"); wszFileName.Append(L"[/img]");
T2Utf szMsg(wszFileName);
DB::EventInfo dbei;
- dbei.timestamp = time(0);
+ dbei.iTimestamp = time(0);
dbei.pBlob = szMsg;
ProtoChainRecvMsg(pReq->GetHContact(), dbei);
}
diff --git a/protocols/JabberG/src/jabber_notes.cpp b/protocols/JabberG/src/jabber_notes.cpp
index 4a70562c23..05df01d1dc 100644
--- a/protocols/JabberG/src/jabber_notes.cpp
+++ b/protocols/JabberG/src/jabber_notes.cpp
@@ -6,7 +6,7 @@ Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007-09 Maxim Mluhov
Copyright (c) 2007-09 Victor Pavlychko
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_notes.h b/protocols/JabberG/src/jabber_notes.h
index 832f0d97ae..6203b2d6a5 100644
--- a/protocols/JabberG/src/jabber_notes.h
+++ b/protocols/JabberG/src/jabber_notes.h
@@ -6,7 +6,7 @@ Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007-09 Maxim Mluhov
Copyright (c) 2007-09 Victor Pavlychko
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_omemo.cpp b/protocols/JabberG/src/jabber_omemo.cpp
index b28f32ccb0..28026fe7c0 100644
--- a/protocols/JabberG/src/jabber_omemo.cpp
+++ b/protocols/JabberG/src/jabber_omemo.cpp
@@ -2,7 +2,7 @@
Jabber Protocol Plugin for Miranda NG
-Copyright (c) 2017-24 Miranda NG team
+Copyright (c) 2017-25 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
@@ -1392,40 +1392,16 @@ bool CJabberProto::OmemoHandleMessage(XmppMsg *msg, const TiXmlElement *node, co
char protocol[7], hexkey[89], suburl[5001];
int ret = sscanf(result.GetBuffer(), "%6[^:]://%5000[^#]#%88s", protocol, suburl, hexkey);
protocol[6] = hexkey[88] = suburl[5000] = 0;
- if (ret == 3 && !strcmp(protocol, "aesgcm") && strlen(hexkey) == 88) {
- CMStringA szName;
- const char *b = strrchr(suburl, '/') + 1;
- while (*b != 0 && *b != '#' && *b != '?')
- szName.AppendChar(*b++);
-
- ptrW pwszName(mir_utf8decodeW(szName.c_str()));
-
- JSONNode root;
- root << WCHAR_PARAM("f", pwszName) << CHAR_PARAM("u", result.GetBuffer());
-
- DBEVENTINFO dbei = {};
- dbei.szModule = Proto_GetBaseAccountName(hContact);
- dbei.timestamp = msgTime;
- dbei.eventType = EVENTTYPE_FILE;
- if (trusted)
- dbei.flags = DBEF_SECURE;
- if (isCarbon)
- dbei.flags = DBEF_SENT;
-
- std::string text = root.write();
- dbei.cbBlob = (int)text.size() + 1;
- dbei.pBlob = (char *)text.c_str();
- db_event_add(hContact, &dbei);
- }
- else {
- msg->msgTime = msgTime;
+
+ if (trusted == FP_TOFU)
+ msg->dbei.flags |= DBEF_SECURE;
+ if (trusted == FP_VERIFIED)
+ msg->dbei.flags |= DBEF_STRONG;
+
+ if (ret == 3 && !strcmp(protocol, "aesgcm") && strlen(hexkey) == 88)
+ FileProcessHttpDownload(msg->dbei, result, nullptr);
+ else
msg->szMessage = result;
-
- if (trusted)
- msg->dbei.flags = DBEF_STRONG;
- if (isCarbon)
- msg->dbei.flags = DBEF_SENT;
- }
return true;
}
diff --git a/protocols/JabberG/src/jabber_omemo.h b/protocols/JabberG/src/jabber_omemo.h
index f6216891a5..66f2ea9445 100644
--- a/protocols/JabberG/src/jabber_omemo.h
+++ b/protocols/JabberG/src/jabber_omemo.h
@@ -2,7 +2,7 @@
Jabber Protocol Plugin for Miranda NG
-Copyright (c) 2017-24 Miranda NG team
+Copyright (c) 2017-25 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
diff --git a/protocols/JabberG/src/jabber_opt.cpp b/protocols/JabberG/src/jabber_opt.cpp
index 5254d9ea10..5e03d105c3 100644
--- a/protocols/JabberG/src/jabber_opt.cpp
+++ b/protocols/JabberG/src/jabber_opt.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_password.cpp b/protocols/JabberG/src/jabber_password.cpp
index d7d34ddeb5..551797f2eb 100644
--- a/protocols/JabberG/src/jabber_password.cpp
+++ b/protocols/JabberG/src/jabber_password.cpp
@@ -4,7 +4,7 @@ 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
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_presence_manager.cpp b/protocols/JabberG/src/jabber_presence_manager.cpp
index 05938ce077..bd9f55745f 100644
--- a/protocols/JabberG/src/jabber_presence_manager.cpp
+++ b/protocols/JabberG/src/jabber_presence_manager.cpp
@@ -6,7 +6,7 @@ Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-08 George Hazan
Copyright (c) 2007 Maxim Mluhov
Copyright (c) 2008-09 Dmitriy Chervov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_presence_manager.h b/protocols/JabberG/src/jabber_presence_manager.h
index 3916317570..3c3ca2c3d5 100644
--- a/protocols/JabberG/src/jabber_presence_manager.h
+++ b/protocols/JabberG/src/jabber_presence_manager.h
@@ -6,7 +6,7 @@ Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-08 George Hazan
Copyright (c) 2007 Maxim Mluhov
Copyright (c) 2008-09 Dmitriy Chervov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_privacy.cpp b/protocols/JabberG/src/jabber_privacy.cpp
index 0eb0b4a12e..2efb1fac48 100644
--- a/protocols/JabberG/src/jabber_privacy.cpp
+++ b/protocols/JabberG/src/jabber_privacy.cpp
@@ -6,7 +6,7 @@ Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007-09 Maxim Mluhov
Copyright (c) 2007-09 Victor Pavlychko
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_privacy.h b/protocols/JabberG/src/jabber_privacy.h
index 317543dfb9..2ce2daffab 100644
--- a/protocols/JabberG/src/jabber_privacy.h
+++ b/protocols/JabberG/src/jabber_privacy.h
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_proto.cpp b/protocols/JabberG/src/jabber_proto.cpp
index fbb772ac56..aa6c0e5d45 100644
--- a/protocols/JabberG/src/jabber_proto.cpp
+++ b/protocols/JabberG/src/jabber_proto.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
@@ -27,7 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "jabber_iq.h"
#include "jabber_caps.h"
#include "jabber_disco.h"
-#include "jabber_secur.h"
#pragma warning(disable:4355)
@@ -53,12 +52,23 @@ static int compareListItems(const JABBER_LIST_ITEM *p1, const JABBER_LIST_ITEM *
return mir_strcmpi(szp1, szp2);
}
+static int compareAuth(const TJabberAuth *p1, const TJabberAuth *p2)
+{
+ return p2->getPriority() - p1->getPriority(); // reverse sorting order
+}
+
+static int compareTasks(const TUpgradeTask *p1, const TUpgradeTask *p2)
+{
+ return p2->getPriority() - p1->getPriority(); // reverse sorting order
+}
+
CJabberProto::CJabberProto(const char *aProtoName, const wchar_t *aUserName) :
PROTO<CJabberProto>(aProtoName, aUserName),
m_impl(*this),
m_omemo(this),
m_arChatMarks(50, NumericKeySortT),
- m_arAuthMechs(1, &TJabberAuth::compare),
+ m_arAuthMechs(1, compareAuth),
+ m_arSaslUpgrade(1, compareTasks),
m_lstTransports(50, compareTransports),
m_lstRoster(50, compareListItems),
m_iqManager(this),
@@ -247,7 +257,7 @@ CJabberProto::CJabberProto(const char *aProtoName, const wchar_t *aUserName) :
CJabberProto::~CJabberProto()
{
ConsoleUninit();
- GlobalMenuUninit();
+ MenuUninit();
if (m_hPopupClass)
Popup_UnregisterClass(m_hPopupClass);
@@ -286,7 +296,7 @@ void CJabberProto::OnModulesLoaded()
m_pepServices.InitGui();
InitPopups();
- GlobalMenuInit();
+ MenuInit();
UpdateFeatHash();
StatusIconData sid = {};
diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h
index 83d13b8797..3c6000f8d9 100644
--- a/protocols/JabberG/src/jabber_proto.h
+++ b/protocols/JabberG/src/jabber_proto.h
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
@@ -74,7 +74,73 @@ struct CChatMark
CMStringA szId, szFrom;
};
+// basic class - provides interface for various Jabber auth
+class TJabberAuth : public MZeroedObject
+{
+protected: bool bIsValid = true;
+ ptrA szName;
+ unsigned complete;
+ int priority;
+ ThreadData *info;
+public:
+ TJabberAuth(ThreadData *pInfo, const char *pszMech) :
+ info(pInfo),
+ szName(mir_strdup(pszMech))
+ {}
+
+ virtual ~TJabberAuth() {}
+
+ virtual char* getInitialRequest() { return nullptr; }
+ virtual char* getChallenge(const char*) { return nullptr; }
+ virtual bool validateLogin(const char*) { return true; }
+
+ __forceinline int getPriority() const {
+ return priority;
+ }
+
+ __forceinline const char *getName() const {
+ return szName;
+ }
+
+ __forceinline bool isValid() const {
+ return bIsValid;
+ }
+};
+
+class TUpgradeTask : public MZeroedObject
+{
+protected:
+ ptrA szName, szInitData;
+ ThreadData *info;
+ int priority;
+
+public:
+ TUpgradeTask(ThreadData *pInfo, const char *pszMech) :
+ info(pInfo),
+ szName(mir_strdup(pszMech))
+ {}
+
+ virtual ~TUpgradeTask() {}
+
+ __forceinline const char *getInitData() const {
+ return szInitData;
+ }
+
+ __forceinline const char *getName() const {
+ return szName;
+ }
+
+ __forceinline int getPriority() const {
+ return priority;
+ }
+
+ void setInitData(const char *pszData) {
+ szInitData = mir_strdup(pszData);
+ }
+
+ virtual bool perform(const TiXmlElement *src, TiXmlElement *dest) = 0;
+};
struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
{
@@ -385,7 +451,7 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
//---- jabber_adhoc.cpp --------------------------------------------------------------
- int __cdecl ContactMenuRunCommands(WPARAM wParam, LPARAM lParam);
+ INT_PTR __cdecl ContactMenuRunCommands(WPARAM wParam, LPARAM lParam);
HWND GetWindowFromIq(CJabberIqInfo *pInfo);
bool HandleAdhocCommandRequest(const TiXmlElement *iqNode, CJabberIqInfo *pInfo);
@@ -430,7 +496,7 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
INT_PTR __cdecl OnMenuHandleBookmarks(WPARAM wParam, LPARAM lParam);
- int AddEditBookmark(JABBER_LIST_ITEM *item);
+ int AddEditBookmark(JABBER_LIST_ITEM *item, MWindow hwndParent = 0);
//---- jabber_notes.c -----------------------------------------------------------------
@@ -533,7 +599,7 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
//---- jabber_file.cpp ---------------------------------------------------------------
- void FileProcessHttpDownload(MCONTACT, const char *jid, const char *pszUrl, const char *pszDescr);
+ void FileProcessHttpDownload(DB::EventInfo &dbei, const char *pszUrl, const char *pszDescr);
int FileReceiveParse(filetransfer *ft, char* buffer, int datalen);
int FileSendParse(HNETLIBCONN s, filetransfer *ft, char* buffer, int datalen);
@@ -726,8 +792,9 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
INT_PTR __cdecl OnMenuTransportLogin(WPARAM wParam, LPARAM lParam);
INT_PTR __cdecl OnMenuTransportResolve(WPARAM wParam, LPARAM lParam);
- void GlobalMenuInit(void);
- void GlobalMenuUninit(void);
+ static void GlobalMenuInit();
+ void MenuInit(void);
+ void MenuUninit(void);
void MenuUpdateSrmmIcon(JABBER_LIST_ITEM *item);
@@ -827,6 +894,15 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
void SearchDeleteFromRecent(const char *szAddr, bool deleteLastFromDB);
void SearchAddToRecent(const char *szAddr, HWND hwndDialog = nullptr);
+ //---- jabber_auth.cpp ---------------------------------------------------------------
+
+ OBJLIST<TJabberAuth> m_arAuthMechs;
+
+ OBJLIST<TUpgradeTask> m_arSaslUpgrade;
+ void OnProcessChannelBinding(const TiXmlElement *node);
+ bool OnProcessMechanism(const TiXmlElement *node, ThreadData *info);
+ void OnProcessUpgrade(const TiXmlElement *node, ThreadData *info);
+
//---- jabber_svc.c ------------------------------------------------------------------
void CheckMenuItems();
@@ -856,7 +932,6 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
ptrA m_szGroupDelimiter;
ptrW m_savedPassword;
- OBJLIST<class TJabberAuth> m_arAuthMechs;
bool m_hasSession, m_hasAuth, m_hasSasl2;
void __cdecl ServerThread(JABBER_CONN_DATA *info);
@@ -868,6 +943,8 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
void OnProcessError(const TiXmlElement *node, ThreadData *info);
void OnProcessSuccess(const TiXmlElement *node, ThreadData *info);
void OnProcessChallenge(const TiXmlElement *node, ThreadData *info);
+ void OnProcessContinue(const TiXmlElement *node, ThreadData *info);
+ void OnProcessTaskData(const TiXmlElement *node, ThreadData *info);
void OnProcessProceed(const TiXmlElement *node, ThreadData *info);
void OnProcessCompressed(const TiXmlElement *node, ThreadData *info);
//message processing helpers
@@ -884,7 +961,6 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
void PerformRegistration(ThreadData *info);
void PerformIqAuth(ThreadData *info);
void PerformAuthentication(ThreadData *info);
- bool OnProcessMechanism(const TiXmlElement *node, ThreadData *info);
void OnProcessFeatures(const TiXmlElement *node, ThreadData *info);
void xmlStreamInitialize(char *which);
diff --git a/protocols/JabberG/src/jabber_rc.cpp b/protocols/JabberG/src/jabber_rc.cpp
index 3a67ea5f23..e273d169fe 100644
--- a/protocols/JabberG/src/jabber_rc.cpp
+++ b/protocols/JabberG/src/jabber_rc.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 Miranda NG team
XEP-0146 support for Miranda IM
@@ -450,7 +450,7 @@ int CJabberProto::RcGetUnreadEventsCount()
for (MEVENT hDbEvent = db_event_firstUnread(hContact); hDbEvent; hDbEvent = db_event_next(hContact, hDbEvent)) {
DB::EventInfo dbei(hDbEvent);
- if (dbei && dbei.eventType == EVENTTYPE_MESSAGE && !(dbei.flags & DBEF_READ) && !(dbei.flags & DBEF_SENT)) {
+ if (dbei && dbei.eventType == EVENTTYPE_MESSAGE && !dbei.bRead && !dbei.bSent) {
ptrW szEventText(dbei.getText());
if (szEventText)
nEventsSent++;
@@ -549,7 +549,7 @@ int CJabberProto::AdhocForwardHandler(const TiXmlElement*, CJabberIqInfo *pInfo,
addressesNode << XCHILD("address") << XATTR("type", "ofrom") << XATTR("jid", szOFrom);
addressesNode << XCHILD("address") << XATTR("type", "oto") << XATTR("jid", m_ThreadInfo->fullJID);
- time_t ltime = (time_t)dbei.timestamp;
+ time_t ltime = dbei.getUnixtime();
struct tm *gmt = gmtime(&ltime);
char stime[512];
mir_snprintf(stime, "%.4i-%.2i-%.2iT%.2i:%.2i:%.2iZ", gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday,
diff --git a/protocols/JabberG/src/jabber_rc.h b/protocols/JabberG/src/jabber_rc.h
index a425a142fe..198a770eb4 100644
--- a/protocols/JabberG/src/jabber_rc.h
+++ b/protocols/JabberG/src/jabber_rc.h
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 Miranda NG team
XEP-0146 support for Miranda IM
diff --git a/protocols/JabberG/src/jabber_roster.cpp b/protocols/JabberG/src/jabber_roster.cpp
index 883f61c261..416a725147 100644
--- a/protocols/JabberG/src/jabber_roster.cpp
+++ b/protocols/JabberG/src/jabber_roster.cpp
@@ -4,7 +4,7 @@ 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
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_sasl2.cpp b/protocols/JabberG/src/jabber_sasl2.cpp
new file mode 100644
index 0000000000..3b27a66719
--- /dev/null
+++ b/protocols/JabberG/src/jabber_sasl2.cpp
@@ -0,0 +1,129 @@
+/*
+Copyright (C) 2012-25 Miranda NG team (https://miranda-ng.org)
+
+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 version 2
+of the License.
+
+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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stdafx.h"
+
+void Hi(const EVP_MD *hashMethod, uint8_t *res, char *passw, size_t passwLen, char *salt, size_t saltLen, int iterations);
+
+struct TScramTask : public TUpgradeTask
+{
+ const EVP_MD *hashMethod;
+
+ TScramTask(ThreadData *info, const char *pszMech, const EVP_MD *pMethod, int iPriority) :
+ TUpgradeTask(info, pszMech),
+ hashMethod(pMethod)
+ {
+ priority = iPriority;
+ }
+
+ ~TScramTask() {}
+
+ bool perform(const TiXmlElement *src, TiXmlElement *dest) override
+ {
+ auto *salt = XmlGetChildByTag(src, "salt", "xmlns", "urn:xmpp:scram-upgrade:0");
+ if (!salt || !mir_strlen(szInitData))
+ return false;
+
+ int iterations = salt->IntAttribute("iterations");
+ auto *pszSalt = salt->GetText();
+ if (!mir_strlen(pszSalt) || !iterations)
+ return false;
+
+ size_t cbNonce, cbSalt;
+ ptrA szInit((char *)mir_base64_decode(szInitData, &cbNonce));
+ ptrA szNonce((char*)mir_base64_decode(szInit.get() + 2, &cbNonce));
+ ptrA szSalt((char *)mir_base64_decode(pszSalt, &cbSalt));
+
+ int hashSize = EVP_MD_size(hashMethod);
+
+ uint8_t saltedPassw[EVP_MAX_MD_SIZE];
+ Hi(hashMethod, saltedPassw, info->conn.password, mir_strlen(info->conn.password), szSalt, cbSalt, iterations);
+
+ ptrA szEncoded(mir_base64_encode(saltedPassw, hashSize));
+ auto *pHash = dest << XCHILD("hash", szEncoded);
+ pHash << XATTR("xmlns", "urn:xmpp:scram-upgrade:0");
+ return true;
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// SASL2: common tasks processing methods
+
+void CJabberProto::OnProcessUpgrade(const TiXmlElement *n, ThreadData *info)
+{
+ TUpgradeTask *pTask;
+ auto *szMechanism = n->GetText();
+ if (!mir_strcmp(szMechanism, "UPGR-SCRAM-SHA-1"))
+ pTask = new TScramTask(info, szMechanism, EVP_sha1(), 500);
+ else if (!mir_strcmp(szMechanism, "UPGR-SCRAM-SHA-256"))
+ pTask = new TScramTask(info, szMechanism, EVP_sha256(), 520);
+ else if (!mir_strcmp(szMechanism, "UPGR-SCRAM-SHA-384"))
+ pTask = new TScramTask(info, szMechanism, EVP_sha384(), 530);
+ // uncomment those lines when ejabberd will support SHA-512 normally
+ // else if (!mir_strcmp(szMechanism, "UPGR-SCRAM-SHA-512"))
+ // pTask = new TScramTask(info, szMechanism, EVP_sha512(), 540);
+ else {
+ debugLogA("Unsupported mechanism for upgrade: %s, skipping", szMechanism);
+ return;
+ }
+
+ m_arSaslUpgrade.insert(pTask);
+}
+
+void CJabberProto::OnProcessContinue(const TiXmlElement *node, ThreadData *info)
+{
+ if (!node->Attribute("xmlns", JABBER_FEAT_SASL2)) {
+ debugLogA("Missing xmlns for continue, ignoring");
+ return;
+ }
+
+ TUpgradeTask *pTask = nullptr;
+ for (auto *task : TiXmlFilter(node->FirstChildElement("tasks"), "task"))
+ for (auto &it : m_arSaslUpgrade)
+ if (!mir_strcmp(it->getName(), task->GetText())) {
+ pTask = it;
+ break;
+ }
+
+ if (!pTask) {
+ debugLogA("Unsupported task type, ignoring");
+ info->send("</stream:stream>"); // bye-bye
+ return;
+ }
+
+ info->m_saslUpgrade = pTask;
+
+ if (auto *pszInitData = XmlGetChildText(node, "additional-data"))
+ pTask->setInitData(pszInitData);
+
+ XmlNode next("next");
+ next << XATTR("xmlns", JABBER_FEAT_SASL2) << XATTR("task", pTask->getName());
+ info->send(next);
+}
+
+void CJabberProto::OnProcessTaskData(const TiXmlElement *node, ThreadData *info)
+{
+ if (!info->m_saslUpgrade)
+ return;
+
+ XmlNode reply("task-data");
+ reply << XATTR("xmlns", JABBER_FEAT_SASL2);
+ if (info->m_saslUpgrade->perform(node, reply))
+ info->send(reply);
+ else
+ info->send("</stream:stream>"); // bye-bye
+}
diff --git a/protocols/JabberG/src/jabber_search.cpp b/protocols/JabberG/src/jabber_search.cpp
index 849189355e..94ffd55453 100644
--- a/protocols/JabberG/src/jabber_search.cpp
+++ b/protocols/JabberG/src/jabber_search.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Artem Shpynov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 Miranda NG team
Module implements a search according to XEP-0055: Jabber Search
http://www.xmpp.org/extensions/xep-0055.html
diff --git a/protocols/JabberG/src/jabber_search.h b/protocols/JabberG/src/jabber_search.h
index b181f3e5c4..44bd757d27 100644
--- a/protocols/JabberG/src/jabber_search.h
+++ b/protocols/JabberG/src/jabber_search.h
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Artem Shpynov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 Miranda NG team
Module implements a search according to XEP-0055: Jabber Search
http://www.xmpp.org/extensions/xep-0055.html
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;
-}
diff --git a/protocols/JabberG/src/jabber_secur.h b/protocols/JabberG/src/jabber_secur.h
deleted file mode 100644
index 0a9a8f843c..0000000000
--- a/protocols/JabberG/src/jabber_secur.h
+++ /dev/null
@@ -1,123 +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.
-
-*/
-
-#pragma once
-
-#include "stdafx.h"
-
-// basic class - provides interface for various Jabber auth
-
-class TJabberAuth : public MZeroedObject
-{
-protected: bool bIsValid = true;
- ptrA szName;
- unsigned complete;
- int priority;
- ThreadData *info;
-public:
- TJabberAuth(ThreadData *pInfo, const char *pszMech);
- virtual ~TJabberAuth();
-
- virtual char* getInitialRequest();
- virtual char* getChallenge(const char *challenge);
- virtual bool validateLogin(const char *challenge);
-
- static int compare(const TJabberAuth *p1, const TJabberAuth *p2)
- { return p2->priority - p1->priority; // reverse sorting order
- }
-
- inline const char* getName() const
- { return szName;
- }
-
- inline bool isValid() const
- { return bIsValid;
- }
-};
-
-// plain auth - the most simple one
-
-class TPlainAuth : public TJabberAuth
-{
- typedef TJabberAuth CSuper;
-
- bool bOld;
-
-public:
- TPlainAuth(ThreadData*, bool);
-
- char* getInitialRequest() override;
-};
-
-// md5 auth - digest-based authorization
-
-class TMD5Auth : public TJabberAuth
-{
- typedef TJabberAuth CSuper;
-
- int iCallCount;
-public:
- TMD5Auth(ThreadData*);
- ~TMD5Auth();
-
- char* getChallenge(const char *challenge) override;
-};
-
-class TScramAuth : public TJabberAuth
-{
- typedef TJabberAuth CSuper;
-
- char *bindFlag, *cnonce = 0, *msg1 = 0, *serverSignature = 0;
- MBinBuffer bindData;
- const EVP_MD *hashMethod;
-
-public:
- TScramAuth(ThreadData *pInfo, const char *pszMech, const EVP_MD *pMethod, int priority);
- ~TScramAuth();
-
- char* getInitialRequest() override;
- char* getChallenge(const char *challenge) override;
- bool validateLogin(const char *challenge) override;
-
- void Hi(uint8_t* res , char* passw, size_t passwLen, char* salt, size_t saltLen, int ind);
-};
-
-// ntlm auth - LanServer based authorization
-
-class TNtlmAuth : public TJabberAuth
-{
- typedef TJabberAuth CSuper;
-
- HANDLE hProvider;
- ptrA szInitRequest;
-
-public:
- TNtlmAuth(ThreadData*, const char* mechanism);
- ~TNtlmAuth();
-
- char* getInitialRequest() override;
- char* getChallenge(const char *challenge) override;
-
- bool getSpn(wchar_t* szSpn, size_t dwSpnLen);
-};
diff --git a/protocols/JabberG/src/jabber_send_manager.cpp b/protocols/JabberG/src/jabber_send_manager.cpp
index 217c5f1129..4f5a4775ff 100644
--- a/protocols/JabberG/src/jabber_send_manager.cpp
+++ b/protocols/JabberG/src/jabber_send_manager.cpp
@@ -6,7 +6,7 @@ Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-08 George Hazan
Copyright (c) 2007 Maxim Mluhov
Copyright (c) 2008-09 Dmitriy Chervov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_send_manager.h b/protocols/JabberG/src/jabber_send_manager.h
index ce29cdaaee..d7e6262cda 100644
--- a/protocols/JabberG/src/jabber_send_manager.h
+++ b/protocols/JabberG/src/jabber_send_manager.h
@@ -6,7 +6,7 @@ Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-08 George Hazan
Copyright (c) 2007 Maxim Mluhov
Copyright (c) 2008-09 Dmitriy Chervov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_strm_mgmt.cpp b/protocols/JabberG/src/jabber_strm_mgmt.cpp
index 9e8a238c2d..516910e511 100644
--- a/protocols/JabberG/src/jabber_strm_mgmt.cpp
+++ b/protocols/JabberG/src/jabber_strm_mgmt.cpp
@@ -2,7 +2,7 @@
Jabber Protocol Plugin for Miranda NG
-Copyright (c) 2018-24 Miranda NG team
+Copyright (c) 2018-25 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
diff --git a/protocols/JabberG/src/jabber_strm_mgmt.h b/protocols/JabberG/src/jabber_strm_mgmt.h
index 17e93e2041..642d1107e7 100644
--- a/protocols/JabberG/src/jabber_strm_mgmt.h
+++ b/protocols/JabberG/src/jabber_strm_mgmt.h
@@ -2,7 +2,7 @@
Jabber Protocol Plugin for Miranda NG
-Copyright (c) 2018-24 Miranda NG team
+Copyright (c) 2018-25 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
diff --git a/protocols/JabberG/src/jabber_svc.cpp b/protocols/JabberG/src/jabber_svc.cpp
index ba276b38af..7a6556f8ab 100644
--- a/protocols/JabberG/src/jabber_svc.cpp
+++ b/protocols/JabberG/src/jabber_svc.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_thread.cpp b/protocols/JabberG/src/jabber_thread.cpp
index b43afa84c0..fa0bd377e7 100644
--- a/protocols/JabberG/src/jabber_thread.cpp
+++ b/protocols/JabberG/src/jabber_thread.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
@@ -29,7 +29,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "jabber_list.h"
#include "jabber_iq.h"
-#include "jabber_secur.h"
#include "jabber_caps.h"
#include "jabber_privacy.h"
#include "jabber_rc.h"
@@ -639,6 +638,8 @@ void CJabberProto::PerformAuthentication(ThreadData *info)
if (m_hasSasl2) {
XmlNode node("authenticate");
+ for (auto &it : m_arSaslUpgrade)
+ node << XCHILD("upgrade", it->getName()) << XATTR("xmlns", "urn:xmpp:sasl:upgrade:0");
node << XATTR("xmlns", JABBER_FEAT_SASL2) << XATTR("mechanism", auth.getName()) << XCHILD("initial-response", auth.getInitialRequest());
info->send(node);
}
@@ -647,6 +648,18 @@ void CJabberProto::PerformAuthentication(ThreadData *info)
/////////////////////////////////////////////////////////////////////////////////////////
+void CJabberProto::OnProcessChannelBinding(const TiXmlElement *node)
+{
+ for (auto *it : TiXmlFilter(node, "channel-binding")) {
+ if (auto *pszType = it->Attribute("type")) {
+ if (!mir_strcmp(pszType, "tls-exporter"))
+ m_bTlsExporter = true;
+ else if (!mir_strcmp(pszType, "tls-server-end-point"))
+ m_bTlsServerEndpoint = true;
+ }
+ }
+}
+
void CJabberProto::OnProcessFeatures(const TiXmlElement *node, ThreadData *info)
{
info->jabberServerCaps = JABBER_RESOURCE_CAPS_NONE;
@@ -693,6 +706,7 @@ void CJabberProto::OnProcessFeatures(const TiXmlElement *node, ThreadData *info)
else if (!mir_strcmp(pszName, "authentication") && !mir_strcmp(xmlns, JABBER_FEAT_SASL2) && m_bEnableSasl2) {
m_hasSasl2 = areMechanismsDefined = true;
m_arAuthMechs.destroy();
+ m_arSaslUpgrade.destroy();
replaceStr(info->gssapiHostName, nullptr);
for (auto *c : TiXmlEnum(n)) {
@@ -703,10 +717,14 @@ void CJabberProto::OnProcessFeatures(const TiXmlElement *node, ThreadData *info)
if (auto *sm = XmlGetChildByTag(c, "sm", "xmlns", JABBER_FEAT_SM))
m_StrmMgmt.CheckStreamFeatures(sm);
- if (auto *bind = XmlGetChildByTag(c, "sm", "xmlns", "urn:xmpp:bind:0")) {
+ if (auto *bind = XmlGetChildByTag(c, "bind", "xmlns", "urn:xmpp:bind:0")) {
// dunno why we need to handle that
}
}
+ else if (!mir_strcmp(c->Name(), "upgrade") && c->Attribute("xmlns", "urn:xmpp:sasl:upgrade:0"))
+ OnProcessUpgrade(c, info);
+ else if (!mir_strcmp(pszName, "sasl-channel-binding") && c->Attribute("xmlns", JABBER_FEAT_CHANNEL_BINDING))
+ OnProcessChannelBinding(c);
}
}
else if (!mir_strcmp(pszName, "session"))
@@ -724,16 +742,8 @@ void CJabberProto::OnProcessFeatures(const TiXmlElement *node, ThreadData *info)
}
else info->jabberServerCaps |= pCaps->GetCaps();
}
- else if (!mir_strcmp(pszName, "sasl-channel-binding") && !mir_strcmp(xmlns, JABBER_FEAT_CHANNEL_BINDING)) {
- for (auto *it : TiXmlFilter(n, "channel-binding")) {
- if (auto *pszType = it->Attribute("type")) {
- if (!mir_strcmp(pszType, "tls-exporter"))
- m_bTlsExporter = true;
- else if (!mir_strcmp(pszType, "tls-server-end-point"))
- m_bTlsServerEndpoint = true;
- }
- }
- }
+ else if (!mir_strcmp(pszName, "sasl-channel-binding") && !mir_strcmp(xmlns, JABBER_FEAT_CHANNEL_BINDING))
+ OnProcessChannelBinding(n);
}
if (areMechanismsDefined) {
@@ -829,7 +839,10 @@ void CJabberProto::OnProcessSuccess(const TiXmlElement *node, ThreadData *info)
return;
}
- if (!pszFinal || !m_arAuthMechs[0].validateLogin(pszFinal)) {
+ if (m_hasSasl2 && !pszFinal && info->m_saslUpgrade)
+ pszFinal = info->m_saslUpgrade->getInitData();
+
+ if (!m_arAuthMechs[0].validateLogin(pszFinal)) {
info->send("</stream:stream>");
return;
}
@@ -867,40 +880,45 @@ void CJabberProto::OnProcessProtocol(const TiXmlElement *node, ThreadData *info)
if (m_StrmMgmt.HandleIncommingNode(node))
return;
- if (!mir_strcmp(node->Name(), "proceed"))
+ auto *pszName = node->Name();
+ if (!mir_strcmp(pszName, "proceed"))
OnProcessProceed(node, info);
- else if (!mir_strcmp(node->Name(), "compressed"))
+ else if (!mir_strcmp(pszName, "compressed"))
OnProcessCompressed(node, info);
- else if (!mir_strcmp(node->Name(), "stream:features"))
+ else if (!mir_strcmp(pszName, "stream:features"))
OnProcessFeatures(node, info);
- else if (!mir_strcmp(node->Name(), "stream:stream"))
+ else if (!mir_strcmp(pszName, "stream:stream"))
OnProcessStreamOpening(node, info);
- else if (!mir_strcmp(node->Name(), "success"))
+ else if (!mir_strcmp(pszName, "success"))
OnProcessSuccess(node, info);
- else if (!mir_strcmp(node->Name(), "failure"))
+ else if (!mir_strcmp(pszName, "failure"))
OnProcessFailure(node, info);
- else if (!mir_strcmp(node->Name(), "stream:error"))
+ else if (!mir_strcmp(pszName, "continue"))
+ OnProcessContinue(node, info);
+ else if (!mir_strcmp(pszName, "task-data"))
+ OnProcessTaskData(node, info);
+ else if (!mir_strcmp(pszName, "stream:error"))
OnProcessError(node, info);
- else if (!mir_strcmp(node->Name(), "challenge"))
+ else if (!mir_strcmp(pszName, "challenge"))
OnProcessChallenge(node, info);
else if (!info->bIsReg) {
- if (!mir_strcmp(node->Name(), "message"))
+ if (!mir_strcmp(pszName, "message"))
OnProcessMessage(node, info);
- else if (!mir_strcmp(node->Name(), "presence"))
+ else if (!mir_strcmp(pszName, "presence"))
OnProcessPresence(node, info);
- else if (!mir_strcmp(node->Name(), "iq"))
+ else if (!mir_strcmp(pszName, "iq"))
OnProcessIq(node);
- else if (!mir_strcmp(node->Name(), "failed"))
+ else if (!mir_strcmp(pszName, "failed"))
OnProcessFailed(node, info);
- else if (!mir_strcmp(node->Name(), "enabled"))
+ else if (!mir_strcmp(pszName, "enabled"))
OnProcessEnabled(node, info);
- else if (m_bEnableStreamMgmt && !mir_strcmp(node->Name(), "resumed"))
+ else if (m_bEnableStreamMgmt && !mir_strcmp(pszName, "resumed"))
m_StrmMgmt.OnProcessResumed(node, info);
else
debugLogA("Invalid top-level tag (only <message/> <presence/> and <iq/> allowed)");
}
else {
- if (!mir_strcmp(node->Name(), "iq"))
+ if (!mir_strcmp(pszName, "iq"))
OnProcessRegIq(node, info);
else
debugLogA("Invalid top-level tag (only <iq/> allowed)");
@@ -1003,7 +1021,7 @@ uint32_t JabberGetLastContactMessageTime(MCONTACT hContact)
return 0;
DB::EventInfo dbei(hDbEvent, false);
- return (dbei) ? dbei.timestamp : 0;
+ return (dbei) ? dbei.getUnixtime() : 0;
}
MCONTACT CJabberProto::CreateTemporaryContact(const char *szJid, JABBER_LIST_ITEM *chatItem)
@@ -1157,7 +1175,7 @@ void CJabberProto::XmppMsg::handle_chatstates()
_dbei.cbBlob = 1;
_dbei.eventType = EVENTTYPE_JABBER_CHATSTATES;
_dbei.flags = DBEF_READ;
- _dbei.timestamp = time(0);
+ _dbei.iTimestamp = time(0);
_dbei.szModule = m_proto->m_szModuleName;
db_event_add(hContact, &_dbei);
}
@@ -1349,12 +1367,10 @@ void CJabberProto::XmppMsg::process()
}
}
else if (!mir_strcmp(pszXmlns, JABBER_FEAT_OOB2)) {
- if (auto* url = XmlGetChildText(xNode, "url")) {
- m_proto->FileProcessHttpDownload(hContact, from, url, XmlGetChildText(xNode, "desc"));
- return;
- }
-
- m_proto->debugLogA("No URL in OOB file transfer, ignoring");
+ if (auto* url = XmlGetChildText(xNode, "url"))
+ m_proto->FileProcessHttpDownload(dbei, url, XmlGetChildText(xNode, "desc"));
+ else
+ m_proto->debugLogA("No URL in OOB file transfer, ignoring");
}
else if (!mir_strcmp(pszXmlns, JABBER_FEAT_MUC_USER)) {
auto* inviteNode = XmlFirstChild(xNode, "invite");
@@ -1402,7 +1418,7 @@ void CJabberProto::XmppMsg::process()
szMessage += m_proto->ExtractImage(node);
// all service info was already processed
- if (szMessage.IsEmpty()) {
+ if (dbei.eventType == EVENTTYPE_MESSAGE && szMessage.IsEmpty()) {
m_proto->debugLogA("empty message, returning");
return;
}
@@ -1445,11 +1461,19 @@ void CJabberProto::XmppMsg::add_to_db()
if (bWasSent)
dbei.flags |= DBEF_SENT;
- dbei.timestamp = (uint32_t)msgTime;
- dbei.pBlob = szMessage.GetBuffer();
+ dbei.iTimestamp = (uint32_t)msgTime;
dbei.szId = szMamMsgId;
- MEVENT hDbEVent = (MEVENT)ProtoChainRecvMsg(hContact, dbei);
+ MEVENT hDbEVent;
+ if (dbei.eventType == EVENTTYPE_FILE) {
+ dbei.flags |= DBEF_TEMPORARY;
+ hDbEVent = (MEVENT)ProtoChainRecvFile(hContact, DB::FILE_BLOB(dbei), dbei);
+ }
+ else {
+ dbei.pBlob = szMessage.GetBuffer();
+ hDbEVent = (MEVENT)ProtoChainRecvMsg(hContact, dbei);
+ }
+
if (idStr)
m_proto->m_arChatMarks.insert(new CChatMark(hDbEVent, idStr, from));
diff --git a/protocols/JabberG/src/jabber_treelist.cpp b/protocols/JabberG/src/jabber_treelist.cpp
index c6c3f627ce..d239792e1d 100644
--- a/protocols/JabberG/src/jabber_treelist.cpp
+++ b/protocols/JabberG/src/jabber_treelist.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Victor Pavlychko
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_userinfo.cpp b/protocols/JabberG/src/jabber_userinfo.cpp
index a2509128ba..70c183a96e 100644
--- a/protocols/JabberG/src/jabber_userinfo.cpp
+++ b/protocols/JabberG/src/jabber_userinfo.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_util.cpp b/protocols/JabberG/src/jabber_util.cpp
index 1c2b2936b6..b486219753 100644
--- a/protocols/JabberG/src/jabber_util.cpp
+++ b/protocols/JabberG/src/jabber_util.cpp
@@ -4,7 +4,7 @@ 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
+Copyright (C) 2012-25 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
@@ -390,57 +390,6 @@ void CJabberProto::SendVisibleInvisiblePresence(bool invisible)
}
}
-time_t JabberIsoToUnixTime(const char *stamp)
-{
- wchar_t date[9];
- int i, y;
-
- if (stamp == nullptr)
- return 0;
-
- auto *p = stamp;
-
- // Get the date part
- for (i = 0; *p != '\0' && i < 8 && isdigit(*p); p++, i++)
- date[i] = *p;
-
- // Parse year
- if (i == 6) {
- // 2-digit year (1970-2069)
- y = (date[0] - '0') * 10 + (date[1] - '0');
- if (y < 70) y += 100;
- }
- else if (i == 8) {
- // 4-digit year
- y = (date[0] - '0') * 1000 + (date[1] - '0') * 100 + (date[2] - '0') * 10 + date[3] - '0';
- y -= 1900;
- }
- else return 0;
-
- struct tm timestamp;
- timestamp.tm_year = y;
-
- // Parse month
- timestamp.tm_mon = (date[i - 4] - '0') * 10 + date[i - 3] - '0' - 1;
-
- // Parse date
- timestamp.tm_mday = (date[i - 2] - '0') * 10 + date[i - 1] - '0';
-
- // Skip any date/time delimiter
- for (; *p != '\0' && !isdigit(*p); p++);
-
- // Parse time
- if (sscanf(p, "%d:%d:%d", &timestamp.tm_hour, &timestamp.tm_min, &timestamp.tm_sec) != 3)
- return (time_t)0;
-
- timestamp.tm_isdst = 0; // DST is already present in _timezone below
- time_t t = mktime(&timestamp);
-
- _tzset();
- t -= _timezone;
- return (t >= 0) ? t : 0;
-}
-
void CJabberProto::SendPresenceTo(int status, const char *to, const TiXmlElement *extra, const char *msg)
{
if (!m_bJabberOnline) return;
@@ -826,13 +775,13 @@ const TiXmlElement* JabberProcessDelay(const TiXmlElement *node, time_t &msgTime
else if (!(szStamp[sj++] = szStamp[si++]))
break;
};
- msgTime = JabberIsoToUnixTime(szStamp);
+ msgTime = Utils_IsoToUnixTime(szStamp);
return (msgTime != 0) ? n : nullptr;
}
if (auto *n = XmlGetChildByTag(node, "x", "xmlns", JABBER_FEAT_DELAY))
if (auto *pszTimeStamp = XmlGetAttr(n, "stamp")) {
- msgTime = JabberIsoToUnixTime(pszTimeStamp);
+ msgTime = Utils_IsoToUnixTime(pszTimeStamp);
return (msgTime != 0) ? n : nullptr;
}
diff --git a/protocols/JabberG/src/jabber_vcard.cpp b/protocols/JabberG/src/jabber_vcard.cpp
index 8149bb15be..9daaeeaddd 100644
--- a/protocols/JabberG/src/jabber_vcard.cpp
+++ b/protocols/JabberG/src/jabber_vcard.cpp
@@ -4,7 +4,7 @@ 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
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_xml.cpp b/protocols/JabberG/src/jabber_xml.cpp
index 620dee32d2..0ee1971e1a 100644
--- a/protocols/JabberG/src/jabber_xml.cpp
+++ b/protocols/JabberG/src/jabber_xml.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_xml.h b/protocols/JabberG/src/jabber_xml.h
index e6c0790d98..32eb2f48a1 100644
--- a/protocols/JabberG/src/jabber_xml.h
+++ b/protocols/JabberG/src/jabber_xml.h
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_xstatus.cpp b/protocols/JabberG/src/jabber_xstatus.cpp
index f604534548..0ba3eb1ce9 100644
--- a/protocols/JabberG/src/jabber_xstatus.cpp
+++ b/protocols/JabberG/src/jabber_xstatus.cpp
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_xstatus.h b/protocols/JabberG/src/jabber_xstatus.h
index ec093be570..9f0600a9e0 100644
--- a/protocols/JabberG/src/jabber_xstatus.h
+++ b/protocols/JabberG/src/jabber_xstatus.h
@@ -6,7 +6,7 @@ Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007-09 Maxim Mluhov
Copyright (c) 2007-09 Victor Pavlychko
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/jabber_zstream.cpp b/protocols/JabberG/src/jabber_zstream.cpp
index e7f2fa0c41..726972451c 100644
--- a/protocols/JabberG/src/jabber_zstream.cpp
+++ b/protocols/JabberG/src/jabber_zstream.cpp
@@ -6,7 +6,7 @@ XEP-0138 (Stream Compression) implementation
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Kostya Chukavin, Taras Zackrepa
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
diff --git a/protocols/JabberG/src/stdafx.cxx b/protocols/JabberG/src/stdafx.cxx
index 13f28e1314..f111565f38 100644
--- a/protocols/JabberG/src/stdafx.cxx
+++ b/protocols/JabberG/src/stdafx.cxx
@@ -1,5 +1,5 @@
/*
-Copyright (C) 2012-24 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-25 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/protocols/JabberG/src/stdafx.h b/protocols/JabberG/src/stdafx.h
index e3d575442d..ae3958750e 100644
--- a/protocols/JabberG/src/stdafx.h
+++ b/protocols/JabberG/src/stdafx.h
@@ -5,7 +5,7 @@ Jabber Protocol Plugin for Miranda NG
Copyright (c) 2002-04 Santithorn Bunchua
Copyright (c) 2005-12 George Hazan
Copyright (c) 2007 Maxim Mluhov
-Copyright (C) 2012-24 Miranda NG team
+Copyright (C) 2012-25 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
@@ -381,7 +381,9 @@ struct ThreadData
char fullJID[JABBER_MAX_JID_LEN];
ptrA tszNewPassword;
- char *gssapiHostName;
+ char* gssapiHostName;
+
+ class TUpgradeTask *m_saslUpgrade;
CJabberIqInfo *pPendingQuery;
JabberCapsBits jabberServerCaps;
@@ -615,7 +617,6 @@ int lstrcmp_null(const wchar_t *s1, const wchar_t *s2);
//---- jabber_menu.c ------------------------------------------------
-void g_MenuInit();
void g_MenuUninit();
int g_OnToolbarInit(WPARAM, LPARAM);
@@ -681,7 +682,6 @@ char* JabberPrepareJid(const char *jid);
char* JabberSha1(const char *str, JabberShaStrBuf buf);
void JabberHttpUrlDecode(wchar_t *str);
int JabberCombineStatus(int status1, int status2);
-time_t JabberIsoToUnixTime(const char *stamp);
char* JabberStripJid(const char *jid, char *dest, size_t destLen);
int JabberGetPacketID(const char*);
char* JabberId2string(int id);
diff --git a/protocols/JabberG/src/version.h b/protocols/JabberG/src/version.h
index 132d06287e..eabd01f2ec 100644
--- a/protocols/JabberG/src/version.h
+++ b/protocols/JabberG/src/version.h
@@ -9,5 +9,5 @@
#define __FILENAME "Jabber.dll"
#define __DESCRIPTION "Jabber (XMPP) protocol support for Miranda NG."
#define __AUTHOR "George Hazan, Maxim Mluhov, Victor Pavlychko, Artem Shpynov, Michael Stepura"
-#define __COPYRIGHT "© 2005-24 George Hazan, Maxim Mluhov, Victor Pavlychko, Artem Shpynov, Michael Stepura"
+#define __COPYRIGHT "© 2005-25 George Hazan, Maxim Mluhov, Victor Pavlychko, Artem Shpynov, Michael Stepura"
#define __AUTHORWEB "https://miranda-ng.org/p/Jabber"