diff options
author | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2017-04-05 22:54:45 +0300 |
---|---|---|
committer | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2017-04-05 23:04:05 +0300 |
commit | 379c01d539737afbe1c32e09a492a240400774e4 (patch) | |
tree | 425f021ed16c7f6947a4808854821125b505336d | |
parent | dc38d017dab888de1e2d530b916c94989489af94 (diff) |
jabber: omemo: working on 4.4
started implementation of omemo session setup (4.4)
currently trying to setup session on outgoing message send attempt for simplicity, this must be changed in future
fixed bug in incomming message handler (4.7)
-rwxr-xr-x | protocols/JabberG/src/jabber_omemo.cpp | 136 | ||||
-rwxr-xr-x | protocols/JabberG/src/jabber_proto.cpp | 33 | ||||
-rwxr-xr-x | protocols/JabberG/src/jabber_proto.h | 4 | ||||
-rwxr-xr-x | protocols/JabberG/src/jabber_thread.cpp | 3 |
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)
|