From 3a02afffa431d57c9f31a542fa95710dcf3fc3d5 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 15 Mar 2023 17:33:11 +0300 Subject: Jabber: fixe for OMEMO UI --- protocols/JabberG/res/jabber.rc | 3 +- protocols/JabberG/src/jabber_omemo.cpp | 45 ++++++++++- protocols/JabberG/src/jabber_omemo.h | 7 +- protocols/JabberG/src/jabber_userinfo.cpp | 119 +++++++++++++++++++++--------- protocols/JabberG/src/resource.h | 3 +- 5 files changed, 138 insertions(+), 39 deletions(-) diff --git a/protocols/JabberG/res/jabber.rc b/protocols/JabberG/res/jabber.rc index 125cf58d12..a13d37d15a 100644 --- a/protocols/JabberG/res/jabber.rc +++ b/protocols/JabberG/res/jabber.rc @@ -326,7 +326,8 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - CONTROL "",IDC_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,0,0,221,143 + CONTROL "",IDC_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,0,18,221,125 + CONTROL "Enable OMEMO",IDC_CHECK_ENOMEMO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,0,65,10 END IDD_VCARD_PHOTO DIALOGEX 0, 0, 222, 132 diff --git a/protocols/JabberG/src/jabber_omemo.cpp b/protocols/JabberG/src/jabber_omemo.cpp index 6477aca0d3..6dc9fa2d8d 100644 --- a/protocols/JabberG/src/jabber_omemo.cpp +++ b/protocols/JabberG/src/jabber_omemo.cpp @@ -474,9 +474,9 @@ complete: return false; } - unsigned long omemo_impl::GetOwnDeviceId() + int omemo_impl::GetOwnDeviceId() { - unsigned long own_id = proto->getDword("OmemoDeviceId", 0); + int own_id = proto->getDword("OmemoDeviceId", 0); if (own_id == 0) { proto->OmemoInitDevice(); own_id = proto->getDword("OmemoDeviceId", 0); @@ -1328,8 +1328,47 @@ complete: return buf; } -}; + // Some DB helpers + int omemo_impl::dbGetDeviceId(MCONTACT hContact, uint32_t number) + { + CMStringA szSetting(FORMAT, "%s%u", DevicePrefix, number); + return proto->getDword(hContact, szSetting, 0); + } + + CMStringA omemo_impl::dbGetSuffix(MCONTACT hContact, int device_id) + { + ptrA jid(proto->getStringA(hContact, "jid")); + if (!jid) + return CMStringA(); + + return dbGetSuffix(jid, device_id); + } + + CMStringA omemo_impl::dbGetSuffix(char *jid, int device_id) + { + if (!jid || device_id <= 0) + return CMStringA(); + + size_t len = strlen(jid); + char *jiddev = (char *)mir_alloc(len + sizeof(int32_t)); + memcpy(jiddev, jid, len); + memcpy(jiddev + len, &device_id, sizeof(int32_t)); + ptrA suffix(mir_base64_encode(jiddev, len + sizeof(int32_t))); + mir_free(jiddev); + + return CMStringA(suffix); + } + + CMStringA hex_string(const uint8_t *pData, const size_t length) + { + CMStringA hexstr; + hexstr.Truncate((int)length * 2); + bin2hex(pData, length, hexstr.GetBuffer()); + + return hexstr; + } +}; void CJabberProto::OmemoInitDevice() { diff --git a/protocols/JabberG/src/jabber_omemo.h b/protocols/JabberG/src/jabber_omemo.h index 94b9fd8dbb..8bcc5cea93 100644 --- a/protocols/JabberG/src/jabber_omemo.h +++ b/protocols/JabberG/src/jabber_omemo.h @@ -36,6 +36,7 @@ namespace omemo const char DevicePrefix[] = "OmemoDeviceId"; CMStringW FormatFingerprint(const char* pszHexString); + CMStringA hex_string(const uint8_t* pData, const size_t length); struct omemo_device; @@ -47,7 +48,7 @@ namespace omemo void init(); void deinit(); bool IsFirstRun(); - unsigned long GetOwnDeviceId(); + int GetOwnDeviceId(); void RefreshDevice(); omemo_device* create_device(); bool create_session_store(MCONTACT hContact, const char *device_id); @@ -62,6 +63,10 @@ namespace omemo std::list incoming_messages; std::list outgoing_messages; + int dbGetDeviceId(MCONTACT hContact, uint32_t number); + CMStringA dbGetSuffix(MCONTACT hContact, int device_id); + CMStringA dbGetSuffix(char* jid, int device_id); + TiXmlDocument doc; private: diff --git a/protocols/JabberG/src/jabber_userinfo.cpp b/protocols/JabberG/src/jabber_userinfo.cpp index 0f9271481a..ead3d33009 100644 --- a/protocols/JabberG/src/jabber_userinfo.cpp +++ b/protocols/JabberG/src/jabber_userinfo.cpp @@ -738,6 +738,7 @@ static int EnumOmemoSessions(const char *szSetting, void *param) class JabberUserOmemoDlg : public JabberBaseUserInfoDlg { CCtrlListView m_list; + CCtrlCheck m_ChkEnabled; void AddListItem(const CMStringA &pszStr1, const wchar_t *pszStr2, const CMStringA &pszStr3) { @@ -756,8 +757,11 @@ class JabberUserOmemoDlg : public JabberBaseUserInfoDlg public: JabberUserOmemoDlg(CJabberProto *_ppro) : JabberBaseUserInfoDlg(_ppro, IDD_INFO_OMEMO), - m_list(this, IDC_LIST) + m_list(this, IDC_LIST), + m_ChkEnabled(this, IDC_CHECK_ENOMEMO) { +// m_ChkEnabled.OnChange = Callback(this, &JabberUserOmemoDlg::onEnCheck); + m_list.OnBuildMenu = Callback(this, &JabberUserOmemoDlg::onMenu_List); } bool OnInitDialog() override @@ -777,14 +781,30 @@ public: lvc.pszText = TranslateT("Fingerprint"); m_list.InsertColumn(3, &lvc); - if (m_hContact == 0) + if (m_hContact == 0) { OnRefresh(); + m_ChkEnabled.Disable(); + m_ChkEnabled.SetState(1); + } + else { + if (ppro->isChatRoom(m_hContact)) { + m_ChkEnabled.Disable(); + m_ChkEnabled.SetState(0); + } + else + m_ChkEnabled.SetState(!ppro->getByte(m_hContact, "bDisableOmemo")); + } return true; } - int Resizer(UTILRESIZECONTROL*) override + int Resizer(UTILRESIZECONTROL* ctrl) override { - return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; + switch (ctrl->wId) { + case IDC_CHECK_ENOMEMO: + return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; + default: + return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; + } } bool OnRefresh() override @@ -795,48 +815,81 @@ public: // GetOwnDeviceId() creates own keys if they don't exist CMStringA str1(FORMAT, "%d", ppro->m_omemo.GetOwnDeviceId()); CMStringA str2(ppro->getMStringA("OmemoFingerprintOwn")); - AddListItem(str1, TranslateT("Own device"), str2); + AddListItem(str1, TranslateT("This device"), str2); } for (int i = 0;; i++) { - CMStringA szSetting(FORMAT, "%s%d", omemo::DevicePrefix, i); - uint32_t device_id = ppro->getDword(m_hContact, szSetting, 0); + int device_id = ppro->m_omemo.dbGetDeviceId(m_hContact, i); if (device_id == 0) break; - char *jiddev = ppro->getStringA(m_hContact, "jid"); - if (jiddev == 0) - continue; + CMStringA suffix(ppro->m_omemo.dbGetSuffix(m_hContact, device_id)); + MBinBuffer fp(ppro->getBlob(m_hContact, CMStringA(omemo::IdentityPrefix) + suffix)); - size_t len = strlen(jiddev); - jiddev = (char *)mir_realloc(jiddev, len + sizeof(int32_t)); - memcpy(jiddev + len, &device_id, sizeof(int32_t)); - - szSetting = omemo::IdentityPrefix; - szSetting.Append(ptrA(mir_base64_encode(jiddev, len + sizeof(int32_t)))); - mir_free(jiddev); - - const wchar_t *pwszStatus = L""; + CMStringW wsStatus; CMStringA fp_hex; - DBVARIANT dbv = { 0 }; - dbv.type = DBVT_BLOB; - db_get(m_hContact, ppro->m_szModuleName, szSetting, &dbv); - if (dbv.cpbVal == 33) { - fp_hex.Truncate(33 * 2); - bin2hex(dbv.pbVal, 33, fp_hex.GetBuffer()); - uint8_t trusted = ppro->getByte(m_hContact, "OmemoFingerprintTrusted_" + fp_hex); - pwszStatus = trusted ? TranslateT("Trusted") : TranslateT("UNTRUSTED"); - //TODO: 3 states Trusted, Untrusted, TOFU + if (!fp.isEmpty()) { + fp_hex = omemo::hex_string(fp.data(), fp.length()); + int8_t trusted = ppro->getByte(m_hContact, "OmemoFingerprintTrusted_" + fp_hex); + wsStatus = trusted ? TranslateT("Trusted") : TranslateT("UNTRUSTED"); } - else if (dbv.cpbVal) - pwszStatus = TranslateT("Unknown"); - - db_free(&dbv); + MBinBuffer session(ppro->getBlob(m_hContact, "OmemoSignalSession_" + suffix)); - AddListItem(CMStringA(FORMAT, "%d", device_id), pwszStatus, fp_hex); + CMStringA device(FORMAT, "%d", device_id); + if (!session.isEmpty()) + device.AppendChar('*'); + AddListItem(device, wsStatus, fp_hex); } return false; } + + void onMenu_List(CContextMenuPos *pos) + { + if (pos->iCurr < 0) + return; + + wchar_t wszText[16]; + m_list.GetItemText(pos->iCurr, 0, wszText, _countof(wszText)); + int device_id = wcstol(wszText, NULL, 10); + if (device_id == ppro->m_omemo.GetOwnDeviceId()) + return; + + CMStringA suffix(ppro->m_omemo.dbGetSuffix(m_hContact, device_id)); + MBinBuffer fp(ppro->getBlob(m_hContact, CMStringA(omemo::IdentityPrefix) + suffix)); + CMStringA TrustSettingName("OmemoFingerprintTrusted_"); + TrustSettingName.Append(omemo::hex_string(fp.data(), fp.length())); + + int8_t trusted = ppro->getByte(m_hContact, TrustSettingName); + bool ses = !ppro->getBlob(m_hContact, "OmemoSignalSession_" + suffix).isEmpty(); + + HMENU hMenu = CreatePopupMenu(); + AppendMenu(hMenu, MF_STRING, (UINT_PTR)1, trusted ? TranslateT("Untrust") : TranslateT("Trust")); + AppendMenu(hMenu, MF_STRING | (ses ? 0 : MF_GRAYED), (UINT_PTR)2, TranslateT("Kill session")); + int nReturnCmd = TrackPopupMenu(hMenu, TPM_RETURNCMD, pos->pt.x, pos->pt.y, 0, m_hwnd, nullptr); + if (nReturnCmd == 1) { + ppro->setByte(m_hContact, TrustSettingName, !trusted); + OnRefresh(); + } + else if (nReturnCmd == 2) { + // TODO Purge session in ram + CMStringA SettingName(FORMAT, "OmemoDeviceId%dChecked", pos->iCurr); + ppro->delSetting(m_hContact, SettingName); + ppro->delSetting(m_hContact, "OmemoSignalSession_" + suffix); + + OnRefresh(); + } + DestroyMenu(hMenu); + } + + bool OnApply() override + { + if (m_ChkEnabled.GetState()) + ppro->delSetting(m_hContact, "bDisableOmemo"); + else + ppro->setByte(m_hContact, "bDisableOmemo", true); + + return true; + } }; ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/protocols/JabberG/src/resource.h b/protocols/JabberG/src/resource.h index 9ea9e91990..e8f695d078 100644 --- a/protocols/JabberG/src/resource.h +++ b/protocols/JabberG/src/resource.h @@ -294,6 +294,7 @@ #define IDC_TXT_ALTNICK 1323 #define IDC_SAVE_PERM 1324 #define IDC_LIST1 1326 +#define IDC_CHECK_ENOMEMO 1330 #define IDC_BM_LIST 3002 #define IDC_ADD 3004 #define IDC_REMOVE 3005 @@ -317,7 +318,7 @@ #define _APS_NO_MFC 1 #define _APS_NEXT_RESOURCE_VALUE 235 #define _APS_NEXT_COMMAND_VALUE 40017 -#define _APS_NEXT_CONTROL_VALUE 1327 +#define _APS_NEXT_CONTROL_VALUE 1331 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif -- cgit v1.2.3