summaryrefslogtreecommitdiff
path: root/protocols/JabberG
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/JabberG')
-rwxr-xr-xprotocols/JabberG/src/jabber_omemo.cpp136
-rwxr-xr-xprotocols/JabberG/src/jabber_proto.cpp33
-rwxr-xr-xprotocols/JabberG/src/jabber_proto.h4
-rwxr-xr-xprotocols/JabberG/src/jabber_thread.cpp3
4 files changed, 163 insertions, 13 deletions
diff --git a/protocols/JabberG/src/jabber_omemo.cpp b/protocols/JabberG/src/jabber_omemo.cpp
index be4f9ce400..fbf43f0183 100755
--- a/protocols/JabberG/src/jabber_omemo.cpp
+++ b/protocols/JabberG/src/jabber_omemo.cpp
@@ -552,6 +552,13 @@ void CJabberProto::OmemoInitDevice()
void CJabberProto::OmemoHandleMessage(HXML /*node*/)
{
//TODO: handle "encrypted" node here
+
+/* PROTORECVEVENT recv = { 0 };
+ recv.timestamp = (DWORD)msgTime;
+ recv.szMessage = buf;
+ recv.lParam = (LPARAM)((pFromResource != NULL && m_options.EnableRemoteControl) ? pFromResource->m_tszResourceName : 0);
+ ProtoChainRecvMsg(hContact, &recv); */
+
}
void CJabberProto::OmemoHandleDeviceList(HXML node)
@@ -580,7 +587,8 @@ void CJabberProto::OmemoHandleDeviceList(HXML node)
DWORD own_id = omemo::GetOwnDeviceId(this);
char setting_name[64];
HXML list_item;
- for (int p = 1, i = 0; (list_item = XmlGetNthChild(node, L"device", p)) != NULL; p++, i++)
+ int i = 0;
+ for (int p = 1; (list_item = XmlGetNthChild(node, L"device", p)) != NULL; p++, i++)
{
current_id_str = xmlGetAttrValue(list_item, L"id");
current_id = _wtoi(current_id_str);
@@ -589,23 +597,45 @@ void CJabberProto::OmemoHandleDeviceList(HXML node)
mir_snprintf(setting_name, "OmemoDeviceId%d", i);
setDword(setting_name, current_id);
}
+ i++;
+ DWORD val = 0;
+ mir_snprintf(setting_name, "OmemoDeviceId%d", i);
+ val = getDword(setting_name, 0);
+ while (val)
+ {
+ delSetting(setting_name);
+ i++;
+ mir_snprintf(setting_name, "OmemoDeviceId%d", i);
+ val = getDword(setting_name, 0);
+ }
if (!own_device_listed)
OmemoAnnounceDevice();
- //TODO: remove all settings higher than 'i' from db
}
else
{
//store device id's
char setting_name[64];
HXML list_item;
- for (int p = 1, i = 0; (list_item = XmlGetNthChild(node, L"device", p)) != NULL; p++, i++)
+ int i = 0;
+ for (int p = 1; (list_item = XmlGetNthChild(node, L"device", p)) != NULL; p++, i++)
{
current_id_str = xmlGetAttrValue(list_item, L"id");
current_id = _wtoi(current_id_str);
mir_snprintf(setting_name, "OmemoDeviceId%d", i);
setDword(hContact, setting_name, current_id);
}
- //TODO: remove all settings higher than 'i' from db
+ i++;
+ DWORD val = 0;
+ mir_snprintf(setting_name, "OmemoDeviceId%d", i);
+ val = getDword(hContact, setting_name, 0);
+ while (val)
+ {
+ delSetting(hContact, setting_name);
+ i++;
+ mir_snprintf(setting_name, "OmemoDeviceId%d", i);
+ val = getDword(hContact, setting_name, 0);
+ }
+
}
}
@@ -700,3 +730,101 @@ void CJabberProto::OmemoPublishNodes()
OmemoAnnounceDevice();
OmemoSendBundle();
}
+
+bool CJabberProto::OmemoCheckSession(MCONTACT hContact)
+{
+ if (getBool(hContact, "OmemoSessionChecked"))
+ return true;
+ bool pending_check = false;
+
+ char setting_name[64], setting_name2[64];
+ DWORD id = 0;
+ bool checked = false;
+ int i = 0;
+
+ mir_snprintf(setting_name, "OmemoDeviceId%d", i);
+ mir_snprintf(setting_name2, "%sChecked", setting_name);
+ id = getDword(hContact, setting_name, 0);
+ checked = getBool(hContact, setting_name2);
+ while (id)
+ {
+ if (!checked)
+ {
+ pending_check = true;
+ wchar_t szBareJid[JABBER_MAX_JID_LEN];
+ XmlNodeIq iq(AddIQ(&CJabberProto::OmemoOnIqResultGetBundle, JABBER_IQ_TYPE_GET));
+ iq << XATTR(L"from", JabberStripJid(m_ThreadInfo->fullJID, szBareJid, _countof_portable(szBareJid)));
+ wchar_t *jid = ContactToJID(hContact);
+ iq << XATTR(L"to", jid);
+ HXML items = iq << XCHILDNS(L"pubsub", L"http://jabber.org/protocol/pubsub") << XCHILD(L"items");
+ wchar_t bundle[64];
+ mir_snwprintf(bundle, 63, L"%s%s%d", JABBER_FEAT_OMEMO, L".bundles:", id);
+ XmlAddAttr(items, L"node", bundle);
+ m_ThreadInfo->send(iq);
+ mir_free(jid);
+ }
+ i++;
+ mir_snprintf(setting_name, "OmemoDeviceId%d", i);
+ mir_snprintf(setting_name2, "%sChecked", setting_name);
+ id = getDword(hContact, setting_name, 0);
+ checked = getBool(hContact, setting_name2);
+ }
+
+ if (!pending_check)
+ return true;
+ return false;
+}
+
+void CJabberProto::OmemoOnIqResultGetBundle(HXML iqNode, CJabberIqInfo * /*pInfo*/)
+{
+ if (iqNode == NULL)
+ return;
+
+ const wchar_t *type = XmlGetAttrValue(iqNode, L"type");
+ if (mir_wstrcmp(type, L"result"))
+ return;
+
+ LPCTSTR jid = XmlGetAttrValue(iqNode, L"from");
+
+ HXML pubsub = XmlGetChildByTag(iqNode, L"pubsub", L"xmlns", L"http://jabber.org/protocol/pubsub");
+ if (!pubsub)
+ return;
+ HXML items = XmlGetChild(pubsub, L"items");
+ LPCTSTR items_node_val = XmlGetAttrValue(items, L"node");
+ LPCTSTR device_id = items_node_val;
+ device_id += mir_wstrlen(JABBER_FEAT_OMEMO L".bundles:");
+ HXML bundle = XmlGetChild(XmlGetChild(items, L"item"), L"bundle");
+ if (!bundle)
+ return;
+ LPCTSTR signedPreKeyPublic = XmlGetText(XmlGetChild(bundle, L"signedPreKeyPublic"));
+ LPCTSTR signedPreKeySignature = XmlGetText(XmlGetChild(bundle, L"signedPreKeySignature"));
+ LPCTSTR identityKey = XmlGetText(XmlGetChild(bundle, L"identityKey"));
+ HXML prekeys = XmlGetChild(bundle, L"prekeys");
+ if (!prekeys)
+ return;
+
+ HXML list_item;
+ char key_num = 0;
+ while(key_num == 0)
+ Utils_GetRandom(&key_num, 1);
+ key_num = key_num % 101;
+
+ wchar_t key_num_str[4];
+ mir_snwprintf(key_num_str, 3, L"%d", key_num);
+
+ LPCTSTR preKeyPublic = XmlGetText(XmlGetChildByTag(prekeys, L"preKeyPublic", L"preKeyId", key_num_str));
+ if (!preKeyPublic)
+ return;
+ //TODO: we have all required data, we need to create session with device here
+
+}
+
+void CJabberProto::OmemoEncryptMessage(XmlNode &msg, const wchar_t *msg_text)
+{
+ //TODO:
+}
+bool CJabberProto::OmemoIsEnabled(MCONTACT hContact)
+{
+ //TODO:
+ return false;
+}
diff --git a/protocols/JabberG/src/jabber_proto.cpp b/protocols/JabberG/src/jabber_proto.cpp
index 8960a70166..b5bb2108ed 100755
--- a/protocols/JabberG/src/jabber_proto.cpp
+++ b/protocols/JabberG/src/jabber_proto.cpp
@@ -919,6 +919,16 @@ int __cdecl CJabberProto::SendMsg(MCONTACT hContact, int, const char* pszSrc)
return 1;
}
+ if (m_options.UseOMEMO)
+ {
+ if (!OmemoCheckSession(hContact)) //check omemo session state and build new session if necessary
+ {
+ TFakeAckParams *param = new TFakeAckParams(hContact, Translate("Protocol is offline or no JID"));
+ ForkThread(&CJabberProto::SendMessageAckThread, param);
+ return 1;
+ }
+ }
+
int isEncrypted, id = SerialNext();
if (!strncmp(pszSrc, PGP_PROLOG, mir_strlen(PGP_PROLOG))) {
const char *szEnd = strstr(pszSrc, PGP_EPILOG);
@@ -941,15 +951,24 @@ int __cdecl CJabberProto::SendMsg(MCONTACT hContact, int, const char* pszSrc)
msgType = L"groupchat";
else
msgType = L"chat";
+ XmlNode m(L"message");
- XmlNode m(L"message"); XmlAddAttr(m, L"type", msgType);
- if (!isEncrypted)
- m << XCHILD(L"body", msg);
- else {
- m << XCHILD(L"body", L"[This message is encrypted.]");
- m << XCHILD(L"x", msg) << XATTR(L"xmlns", L"jabber:x:encrypted");
+ if(m_options.UseOMEMO && OmemoIsEnabled(hContact) && !mir_wstrcmp(msgType, L"chat")) //omemo enabled in options, omemo enabled for contact
+ {
+ OmemoEncryptMessage(m, msg);
+ }
+ else
+ {
+
+ XmlAddAttr(m, L"type", msgType);
+ if (!isEncrypted)
+ m << XCHILD(L"body", msg);
+ else {
+ m << XCHILD(L"body", L"[This message is encrypted.]");
+ m << XCHILD(L"x", msg) << XATTR(L"xmlns", L"jabber:x:encrypted");
+ }
+ mir_free(msg);
}
- mir_free(msg);
pResourceStatus r(ResourceInfoFromJID(szClientJid));
if (r)
diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h
index bbcc472262..04414012fc 100755
--- a/protocols/JabberG/src/jabber_proto.h
+++ b/protocols/JabberG/src/jabber_proto.h
@@ -343,6 +343,10 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
void OmemoAnnounceDevice();
void OmemoSendBundle();
void OmemoPublishNodes();
+ bool OmemoCheckSession(MCONTACT hContact);
+ void OmemoEncryptMessage(XmlNode &msg, const wchar_t *msg_text);
+ bool OmemoIsEnabled(MCONTACT hContact);
+ void OmemoOnIqResultGetBundle(HXML iqNode, CJabberIqInfo *pInfo);
//---- jabber_console.cpp ------------------------------------------------------------
diff --git a/protocols/JabberG/src/jabber_thread.cpp b/protocols/JabberG/src/jabber_thread.cpp
index f9ece29019..0c2aa34d16 100755
--- a/protocols/JabberG/src/jabber_thread.cpp
+++ b/protocols/JabberG/src/jabber_thread.cpp
@@ -1195,8 +1195,7 @@ void CJabberProto::OnProcessMessage(HXML node, ThreadData *info)
for (int i = 0; (xNode = XmlGetChild(node, i)) != NULL; i++) {
if (m_options.UseOMEMO)
{
- //TODO: handle incomming omemo message/key
- if ((xNode = XmlGetNthChild(node, L"encrypted", i + 1)) == NULL)
+ if ((xNode = XmlGetNthChild(node, L"encrypted", i + 1)) != NULL)
{
const wchar_t *ptszXmlns = XmlGetAttrValue(xNode, L"xmlns");
if (ptszXmlns == NULL)