summaryrefslogtreecommitdiff
path: root/protocols/JabberG/src
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2017-04-02 16:16:36 +0300
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2017-04-02 16:21:26 +0300
commitd353887c8cde702539d8d0f3d339c158498648ed (patch)
tree9ae3d71ee095da94637d57f77b4c396749dd2ebe /protocols/JabberG/src
parent85f860270ed1c622e3e15ee49e741512305a5fe2 (diff)
jabber: omemo: working on 4.3
proper dynamic caps implementation for omemo caps/features and for miranda caps/features in general as required by xep-0115 removed my old attempt to implement dynamic omemo cap fixed few bugs in OmemoHandleDeviceList
Diffstat (limited to 'protocols/JabberG/src')
-rwxr-xr-xprotocols/JabberG/src/jabber_caps.cpp63
-rwxr-xr-xprotocols/JabberG/src/jabber_caps.h6
-rwxr-xr-x[-rw-r--r--]protocols/JabberG/src/jabber_misc.cpp3
-rwxr-xr-xprotocols/JabberG/src/jabber_omemo.cpp11
-rwxr-xr-xprotocols/JabberG/src/jabber_opt.cpp19
-rwxr-xr-xprotocols/JabberG/src/jabber_util.cpp7
6 files changed, 77 insertions, 32 deletions
diff --git a/protocols/JabberG/src/jabber_caps.cpp b/protocols/JabberG/src/jabber_caps.cpp
index f92bdc708b..a409a61dca 100755
--- a/protocols/JabberG/src/jabber_caps.cpp
+++ b/protocols/JabberG/src/jabber_caps.cpp
@@ -83,6 +83,7 @@ const JabberFeatCapPairExt g_JabberFeatCapPairsExt[] = {
{ JABBER_EXT_SECUREIM, JABBER_CAPS_SECUREIM, "SecureIM/IsContactSecured" },
{ JABBER_EXT_MIROTR, JABBER_CAPS_MIROTR, "MirOTRMenuCheckService" },
{ JABBER_EXT_NEWGPG, JABBER_CAPS_NEWGPG, "/ExportGPGKeys" },
+ { JABBER_EXT_OMEMO, JABBER_CAPS_OMEMO, },
{ JABBER_EXT_NUDGE, JABBER_CAPS_ATTENTION, "NUDGE/Send" },
{ JABBER_EXT_JINGLE, JABBER_CAPS_JINGLE, "Jingle/StartSession" },
{ JABBER_EXT_COMMANDS, JABBER_CAPS_COMMANDS },
@@ -518,16 +519,55 @@ BOOL CJabberClientCaps::SetPartialCaps(int nIqId, JabberCapsBits jcbCaps)
/////////////////////////////////////////////////////////////////////////////////////////
// CJabberClientCapsManager class
-CJabberClientCapsManager::CJabberClientCapsManager(CJabberProto *proto)
+CJabberClientCapsManager::CJabberClientCapsManager(CJabberProto *proto) : m_szFeaturesCrc(nullptr)
{
ppro = proto;
m_pClients = NULL;
+
+ UpdateFeatHash();
+
+}
+
+void CJabberClientCapsManager::UpdateFeatHash()
+{
+ if (m_szFeaturesCrc)
+ mir_free(m_szFeaturesCrc);
+ wchar_t feat_buf[2048];
+ mir_wstrcpy(feat_buf, L"");
+ JabberCapsBits jcb = JABBER_CAPS_MIRANDA_ALL;
+ for (int i = 0; i < ppro->m_lstJabberFeatCapPairsDynamic.getCount(); i++)
+ jcb |= ppro->m_lstJabberFeatCapPairsDynamic[i]->jcbCap;
+ if (!ppro->m_options.AllowVersionRequests)
+ jcb &= ~JABBER_CAPS_VERSION;
+
+ if (ppro->m_options.UseOMEMO)
+ jcb |= JABBER_CAPS_OMEMO_DEVICELIST_NOTIFY;
+
+
+ for (int i = 0; g_JabberFeatCapPairs[i].szFeature; i++)
+ if (jcb & g_JabberFeatCapPairs[i].jcbCap)
+ mir_wstrcat(feat_buf, g_JabberFeatCapPairs[i].szFeature);
+
+ for (int i = 0; i < ppro->m_lstJabberFeatCapPairsDynamic.getCount(); i++)
+ if (jcb & ppro->m_lstJabberFeatCapPairsDynamic[i]->jcbCap)
+ mir_wstrcat(feat_buf, ppro->m_lstJabberFeatCapPairsDynamic[i]->szFeature);
+ unsigned int hash = mir_hashstrW(feat_buf);
+ char *szHash = mir_base64_encode((BYTE*)&hash, sizeof(int));
+ m_szFeaturesCrc = mir_a2u(szHash);
+ mir_free(szHash);
+}
+
+const wchar_t* CJabberClientCapsManager::GetFeaturesCrc()
+{
+ return m_szFeaturesCrc;
}
CJabberClientCapsManager::~CJabberClientCapsManager()
{
if (m_pClients)
delete m_pClients;
+ if(m_szFeaturesCrc)
+ mir_free(m_szFeaturesCrc);
}
CJabberClientCaps * CJabberClientCapsManager::FindClient(const wchar_t *szNode)
@@ -546,7 +586,10 @@ CJabberClientCaps * CJabberClientCapsManager::FindClient(const wchar_t *szNode)
void CJabberClientCapsManager::AddDefaultCaps()
{
- SetClientCaps(JABBER_CAPS_MIRANDA_NODE, szCoreVersion, JABBER_CAPS_MIRANDA_ALL);
+ wchar_t szVerWHash[256];
+ mir_snwprintf(szVerWHash, 255, L"%s %s", szCoreVersion, m_szFeaturesCrc);
+
+ SetClientCaps(JABBER_CAPS_MIRANDA_NODE, szVerWHash, ppro->m_options.UseOMEMO ? (JABBER_CAPS_MIRANDA_ALL | JABBER_CAPS_OMEMO_DEVICELIST_NOTIFY) : JABBER_CAPS_MIRANDA_ALL);
for (int i=0; g_JabberFeatCapPairsExt[i].szFeature; i++)
if (g_JabberFeatCapPairsExt[i].Valid())
@@ -614,10 +657,11 @@ BOOL CJabberClientCapsManager::HandleInfoRequest(HXML, CJabberIqInfo *pInfo, con
for (i=0; g_JabberFeatCapPairsExt[i].szFeature; i++) {
if (!g_JabberFeatCapPairsExt[i].Valid())
continue;
-
- wchar_t szExtCap[ 512 ];
+ //TODO: something better here
+ wchar_t szExtCap[ 512 ], szExtCapWHash [560];
mir_snwprintf(szExtCap, L"%s#%s", JABBER_CAPS_MIRANDA_NODE, g_JabberFeatCapPairsExt[i].szFeature);
- if (!mir_wstrcmp(szNode, szExtCap)) {
+ mir_snwprintf(szExtCapWHash, L"%s %s", szExtCap, m_szFeaturesCrc);
+ if (!mir_wstrcmp(szNode, szExtCap) || !mir_wstrcmp(szNode, szExtCapWHash)) {
jcb = g_JabberFeatCapPairsExt[i].jcbCap;
break;
}
@@ -625,9 +669,11 @@ BOOL CJabberClientCapsManager::HandleInfoRequest(HXML, CJabberIqInfo *pInfo, con
// check features registered through IJabberNetInterface::RegisterFeature() and IJabberNetInterface::AddFeatures()
for (i=0; i < ppro->m_lstJabberFeatCapPairsDynamic.getCount(); i++) {
- wchar_t szExtCap[ 512 ];
+ //TODO: something better here
+ wchar_t szExtCap[ 512 ], szExtCapWHash[560];
mir_snwprintf(szExtCap, L"%s#%s", JABBER_CAPS_MIRANDA_NODE, ppro->m_lstJabberFeatCapPairsDynamic[i]->szExt);
- if (!mir_wstrcmp(szNode, szExtCap)) {
+ mir_snwprintf(szExtCapWHash, L"%s %s", szExtCap, m_szFeaturesCrc);
+ if (!mir_wstrcmp(szNode, szExtCap) || !mir_wstrcmp(szNode, szExtCapWHash)) {
jcb = ppro->m_lstJabberFeatCapPairsDynamic[i]->jcbCap;
break;
}
@@ -643,6 +689,9 @@ BOOL CJabberClientCapsManager::HandleInfoRequest(HXML, CJabberIqInfo *pInfo, con
jcb |= ppro->m_lstJabberFeatCapPairsDynamic[i]->jcbCap;
}
+ if (ppro->m_options.UseOMEMO)
+ jcb |= JABBER_CAPS_OMEMO_DEVICELIST_NOTIFY;
+
if (!ppro->m_options.AllowVersionRequests)
jcb &= ~JABBER_CAPS_VERSION;
diff --git a/protocols/JabberG/src/jabber_caps.h b/protocols/JabberG/src/jabber_caps.h
index 097108c608..16805680b5 100755
--- a/protocols/JabberG/src/jabber_caps.h
+++ b/protocols/JabberG/src/jabber_caps.h
@@ -167,7 +167,7 @@ typedef unsigned __int64 JabberCapsBits;
JABBER_CAPS_ROSTER_EXCHANGE | JABBER_CAPS_DIRECT_MUC_INVITE)
#define JABBER_CAPS_MIRANDA_ALL (JABBER_CAPS_MIRANDA_PARTIAL | JABBER_CAPS_COMMANDS | \
- JABBER_CAPS_USER_MOOD_NOTIFY | JABBER_CAPS_USER_TUNE_NOTIFY | JABBER_CAPS_USER_ACTIVITY_NOTIFY | JABBER_CAPS_OMEMO_DEVICELIST_NOTIFY \
+ JABBER_CAPS_USER_MOOD_NOTIFY | JABBER_CAPS_USER_TUNE_NOTIFY | JABBER_CAPS_USER_ACTIVITY_NOTIFY \
| JABBER_CAPS_PLATFORMX86 | JABBER_CAPS_PLATFORMX64)
@@ -175,6 +175,7 @@ typedef unsigned __int64 JabberCapsBits;
#define JABBER_EXT_MIROTR L"mirotr"
#define JABBER_EXT_JINGLE L"jingle"
#define JABBER_EXT_NEWGPG L"new_gpg"
+#define JABBER_EXT_OMEMO L"omemo"
#define JABBER_EXT_NUDGE L"nudge"
#define JABBER_EXT_COMMANDS L"cmds"
#define JABBER_EXT_USER_MOOD L"mood"
@@ -276,6 +277,7 @@ protected:
mir_cs m_cs;
CJabberClientCaps *m_pClients;
CJabberProto *ppro;
+ wchar_t *m_szFeaturesCrc;
protected:
CJabberClientCaps *FindClient(const wchar_t *szNode);
@@ -285,6 +287,8 @@ public:
~CJabberClientCapsManager();
void AddDefaultCaps();
+ const wchar_t* GetFeaturesCrc();
+ void UpdateFeatHash();
JabberCapsBits GetClientCaps(wchar_t *szNode, wchar_t *szVer);
BOOL SetClientCaps(const wchar_t *szNode, const wchar_t *szVer, JabberCapsBits jcbCaps, int nIqId = -1);
diff --git a/protocols/JabberG/src/jabber_misc.cpp b/protocols/JabberG/src/jabber_misc.cpp
index 4950875dd3..6b271d7fca 100644..100755
--- a/protocols/JabberG/src/jabber_misc.cpp
+++ b/protocols/JabberG/src/jabber_misc.cpp
@@ -330,6 +330,9 @@ void CJabberProto::FormatMirVer(pResourceStatus &resource, CMStringW &res)
if (resource->m_tszCapsExt && wcsstr(resource->m_tszCapsExt, JABBER_EXT_NEWGPG) && !wcsstr(res, L"(New_GPG)"))
res.Append(L" (New_GPG)");
+ if (resource->m_tszCapsExt && wcsstr(resource->m_tszCapsExt, JABBER_EXT_OMEMO) && !wcsstr(res, L"(omemo)"))
+ res.Append(L" (omemo)");
+
if (resource->m_tszResourceName && !wcsstr(res, resource->m_tszResourceName))
if (wcsstr(res, L"Miranda IM") || wcsstr(res, L"Miranda NG") || m_options.ShowForeignResourceInMirVer)
res.AppendFormat(L" [%s]", resource->m_tszResourceName);
diff --git a/protocols/JabberG/src/jabber_omemo.cpp b/protocols/JabberG/src/jabber_omemo.cpp
index a86e8e0805..be4f9ce400 100755
--- a/protocols/JabberG/src/jabber_omemo.cpp
+++ b/protocols/JabberG/src/jabber_omemo.cpp
@@ -559,7 +559,7 @@ void CJabberProto::OmemoHandleDeviceList(HXML node)
if (!node)
return;
HXML message = xmlGetParent(node);
- message = xmlGetParent(node);
+ message = xmlGetParent(message);
LPCTSTR jid = XmlGetAttrValue(message, L"from");
MCONTACT hContact = HContactFromJID(jid);
node = XmlGetChild(node, "item"); //get <item> node
@@ -578,9 +578,9 @@ void CJabberProto::OmemoHandleDeviceList(HXML node)
//check if our device exist
bool own_device_listed = false;
DWORD own_id = omemo::GetOwnDeviceId(this);
- int i = 0;
char setting_name[64];
- for (HXML list_item = xmlGetFirstChild(node); list_item; xmlGetNextNode(list_item))
+ HXML list_item;
+ for (int p = 1, i = 0; (list_item = XmlGetNthChild(node, L"device", p)) != NULL; p++, i++)
{
current_id_str = xmlGetAttrValue(list_item, L"id");
current_id = _wtoi(current_id_str);
@@ -591,13 +591,14 @@ void CJabberProto::OmemoHandleDeviceList(HXML node)
}
if (!own_device_listed)
OmemoAnnounceDevice();
+ //TODO: remove all settings higher than 'i' from db
}
else
{
//store device id's
- int i = 0;
char setting_name[64];
- for (HXML list_item = xmlGetFirstChild(node); list_item; xmlGetNextNode(list_item), i++)
+ HXML list_item;
+ for (int p = 1, i = 0; (list_item = XmlGetNthChild(node, L"device", p)) != NULL; p++, i++)
{
current_id_str = xmlGetAttrValue(list_item, L"id");
current_id = _wtoi(current_id_str);
diff --git a/protocols/JabberG/src/jabber_opt.cpp b/protocols/JabberG/src/jabber_opt.cpp
index 071c841546..8393b4b964 100755
--- a/protocols/JabberG/src/jabber_opt.cpp
+++ b/protocols/JabberG/src/jabber_opt.cpp
@@ -848,24 +848,7 @@ public:
}
}
}
- //dynamic caps
- {
- JabberCapsBits jcb = 0;
- // set all bits occupied by g_JabberFeatCapPairs
- for (int i = 0; g_JabberFeatCapPairs[i].szFeature; i++)
- jcb |= g_JabberFeatCapPairs[i].jcbCap;
-
- // set all bits already occupied by external plugins
- for (int i = 0; i < m_proto->m_lstJabberFeatCapPairsDynamic.getCount(); i++)
- jcb |= m_proto->m_lstJabberFeatCapPairsDynamic[i]->jcbCap;
- if(m_proto->m_options.UseOMEMO)
- jcb |= JABBER_CAPS_OMEMO_DEVICELIST_NOTIFY;
- else
- jcb &= ~JABBER_CAPS_OMEMO_DEVICELIST_NOTIFY;
-
- m_proto->m_clientCapsManager.SetClientCaps(JABBER_CAPS_MIRANDA_NODE, szCoreVersion, jcb);
- }
-
+ m_proto->m_clientCapsManager.UpdateFeatHash();
m_proto->SendPresence(m_proto->m_iStatus, true);
}
diff --git a/protocols/JabberG/src/jabber_util.cpp b/protocols/JabberG/src/jabber_util.cpp
index 19de86f090..c29725c02f 100755
--- a/protocols/JabberG/src/jabber_util.cpp
+++ b/protocols/JabberG/src/jabber_util.cpp
@@ -385,8 +385,10 @@ void CJabberProto::SendPresenceTo(int status, const wchar_t* to, HXML extra, con
// XEP-0115:Entity Capabilities
if (m_options.AllowVersionRequests) {
+ wchar_t szVersionWithFeatHash[256];
+ mir_snwprintf(szVersionWithFeatHash, 255, L"%s %s", szCoreVersion, m_clientCapsManager.GetFeaturesCrc());
HXML c = p << XCHILDNS(L"c", JABBER_FEAT_ENTITY_CAPS) << XATTR(L"node", JABBER_CAPS_MIRANDA_NODE)
- << XATTR(L"ver", szCoreVersion);
+ << XATTR(L"ver", szVersionWithFeatHash);
LIST<wchar_t> arrExtCaps(5);
if (bSecureIM)
@@ -398,6 +400,9 @@ void CJabberProto::SendPresenceTo(int status, const wchar_t* to, HXML extra, con
if (bNewGPG)
arrExtCaps.insert(JABBER_EXT_NEWGPG);
+ if(m_options.UseOMEMO)
+ arrExtCaps.insert(JABBER_EXT_OMEMO);
+
if (bPlatform)
arrExtCaps.insert(JABBER_EXT_PLATFORMX64);
else