diff options
author | George Hazan <ghazan@miranda.im> | 2023-04-17 20:07:16 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2023-04-17 20:07:16 +0300 |
commit | f43396cbff99cc7cc9410f12e55783ad12d1d2f7 (patch) | |
tree | b2beeabe2b7df2d4ceeae92e20287d08b0675409 | |
parent | e0df536066a9299127ffe1f22530eaf7b401d0dc (diff) |
Jabber:
- option autoloadoob removed due to offline files support;
- added support for encrypted offline files
-rw-r--r-- | include/m_database.h | 1 | ||||
-rw-r--r-- | include/m_protosvc.h | 1 | ||||
-rw-r--r-- | protocols/JabberG/src/jabber_file.cpp | 64 | ||||
-rw-r--r-- | protocols/JabberG/src/jabber_omemo.cpp | 36 | ||||
-rw-r--r-- | protocols/JabberG/src/jabber_opt.cpp | 1 | ||||
-rw-r--r-- | protocols/JabberG/src/jabber_proto.cpp | 1 | ||||
-rw-r--r-- | protocols/JabberG/src/jabber_proto.h | 1 | ||||
-rw-r--r-- | protocols/JabberG/src/jabber_thread.cpp | 2 | ||||
-rw-r--r-- | src/mir_app/src/srmm_log_rtf.cpp | 13 |
9 files changed, 96 insertions, 24 deletions
diff --git a/include/m_database.h b/include/m_database.h index e927084bed..b55c1abedc 100644 --- a/include/m_database.h +++ b/include/m_database.h @@ -177,6 +177,7 @@ struct DBVARIANT #define DBEF_UTF 0x0010 // event contains a text in utf-8
#define DBEF_ENCRYPTED 0x0020 // event is encrypted (never reported outside a driver)
#define DBEF_HAS_ID 0x0040 // event has unique server id
+#define DBEF_SECURE 0x0080 // event is encrypted
struct DBEVENTINFO
{
diff --git a/include/m_protosvc.h b/include/m_protosvc.h index a49788f6e6..11963877d0 100644 --- a/include/m_protosvc.h +++ b/include/m_protosvc.h @@ -721,6 +721,7 @@ struct PROTOFILERESUME #define PREF_CREATEREAD 1 // create the database event with the 'read' flag set
#define PREF_RTL 4 // 0.5+ addition: support for right-to-left messages
#define PREF_SENT 16 // message will be created with the DBEF_SENT flag
+#define PREF_ENCRYPTED 32 // message is encrypted
struct PROTORECVEVENT
{
diff --git a/protocols/JabberG/src/jabber_file.cpp b/protocols/JabberG/src/jabber_file.cpp index c96f6ae92c..0b2767de8d 100644 --- a/protocols/JabberG/src/jabber_file.cpp +++ b/protocols/JabberG/src/jabber_file.cpp @@ -34,9 +34,25 @@ INT_PTR __cdecl CJabberProto::OnOfflineFile(WPARAM param, LPARAM) void __cdecl CJabberProto::OfflineFileThread(OFDTHREAD *param)
{
DB::EventInfo dbei(param->hDbEvent);
- if (dbei && !strcmp(dbei.szModule, m_szModuleName) && dbei.eventType == EVENTTYPE_FILE) {
+ if (m_bJabberOnline && dbei && !strcmp(dbei.szModule, m_szModuleName) && dbei.eventType == EVENTTYPE_FILE) {
DB::FILE_BLOB blob(dbei);
- if (blob.isOffline()) {
+ if (const char *url = blob.getUrl()) {
+ bool encrypted = false;
+ // OMEMO encryped file?
+ char protocol[7], hexkey[100], suburl[5001], newurl[5001];
+ int ret = sscanf(url, "%6[^:]://%5000[^#]#%88s", protocol, suburl, hexkey);
+ protocol[6] = hexkey[88] = 0;
+ if (ret == 3 && !strcmp(protocol, "aesgcm") && strlen(hexkey) == 88) {
+ mir_snprintf(newurl, "https://%s", suburl);
+ url = newurl;
+ encrypted = true;
+ }
+ else if (ret != 2 || (strcmp(protocol, "https") && strcmp(protocol, "http"))) {
+ debugLogA("Wrong url");
+ delete param;
+ return;
+ }
+
// initialize the netlib request
NETLIBHTTPREQUEST nlhr = {};
nlhr.cbSize = sizeof(nlhr);
@@ -48,16 +64,44 @@ void __cdecl CJabberProto::OfflineFileThread(OFDTHREAD *param) NLHR_PTR nlhrReply(Netlib_HttpTransaction(m_hNetlibUser, &nlhr));
if (nlhrReply && nlhrReply->resultCode == 200) {
FILE *f = _wfopen(param->wszPath, L"wb");
- fwrite(nlhrReply->pData, 1, nlhrReply->dataLength, f);
- fclose(f);
+ size_t written = 0;
+ if (f) {
+ if (encrypted) {
+ int payload_len = nlhrReply->dataLength - 16;
+ if (payload_len > 0) {
+ uint8_t ivkey[44];
+ hex2bin(hexkey, ivkey, 44);
+ EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL);
+ EVP_DecryptInit(ctx, EVP_aes_256_gcm(), ivkey + 12, ivkey);
+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, nlhrReply->pData + payload_len);
+
+ int outl = 0, round_len = 0;
+ uint8_t *out = (uint8_t *)mir_alloc(payload_len);
+ EVP_DecryptUpdate(ctx, out, &outl, (uint8_t *)nlhrReply->pData, (int)payload_len);
+ int dec_success = EVP_DecryptFinal(ctx, out + outl, &round_len);
+ outl += round_len;
+ EVP_CIPHER_CTX_free(ctx);
+ if (dec_success && outl == payload_len)
+ if (fwrite(out, 1, payload_len, f) == payload_len)
+ written = payload_len;
+ mir_free(out);
+ }
+ }
+ else if (fwrite(nlhrReply->pData, 1, nlhrReply->dataLength, f) == nlhrReply->dataLength)
+ written = nlhrReply->dataLength;
+ fclose(f);
+ }
- DBVARIANT dbv = { DBVT_DWORD };
- dbv.dVal = nlhrReply->dataLength;
- db_event_setJson(param->hDbEvent, "ft", &dbv);
- db_event_setJson(param->hDbEvent, "fs", &dbv);
+ if (written) {
+ DBVARIANT dbv = { DBVT_DWORD };
+ dbv.dVal = nlhrReply->dataLength;
+ db_event_setJson(param->hDbEvent, "ft", &dbv);
+ db_event_setJson(param->hDbEvent, "fs", &dbv);
- if (param->bOpen)
- ShellExecute(nullptr, L"open", param->wszPath, nullptr, nullptr, SW_SHOWDEFAULT);
+ if (param->bOpen)
+ ShellExecuteW(nullptr, L"open", param->wszPath, nullptr, nullptr, SW_SHOWDEFAULT);
+ }
}
}
}
diff --git a/protocols/JabberG/src/jabber_omemo.cpp b/protocols/JabberG/src/jabber_omemo.cpp index 9666eec9e7..06ebb64647 100644 --- a/protocols/JabberG/src/jabber_omemo.cpp +++ b/protocols/JabberG/src/jabber_omemo.cpp @@ -1431,10 +1431,38 @@ bool CJabberProto::OmemoHandleMessage(const TiXmlElement *node, const char *jid, if (!msgTime || m_bFixIncorrectTimestamps && (msgTime > now || (msgTime < (time_t)JabberGetLastContactMessageTime(hContact))))
msgTime = now;
- PROTORECVEVENT recv = {};
- recv.timestamp = (uint32_t)msgTime;
- recv.szMessage = result.GetBuffer();
- ProtoChainRecvMsg(hContact, &recv);
+ 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;
+ dbei.flags = DBEF_SECURE;
+
+ std::string text = root.write();
+ dbei.cbBlob = (int)text.size() + 1;
+ dbei.pBlob = (uint8_t *)text.c_str();
+ db_event_add(hContact, &dbei);
+ }
+ else {
+ PROTORECVEVENT recv = {};
+ recv.timestamp = (uint32_t)msgTime;
+ recv.szMessage = result.GetBuffer();
+ recv.flags = PREF_ENCRYPTED;
+ ProtoChainRecvMsg(hContact, &recv);
+ }
return true;
}
diff --git a/protocols/JabberG/src/jabber_opt.cpp b/protocols/JabberG/src/jabber_opt.cpp index 180f57c74a..4df55c6998 100644 --- a/protocols/JabberG/src/jabber_opt.cpp +++ b/protocols/JabberG/src/jabber_opt.cpp @@ -717,7 +717,6 @@ public: m_options.AddOption(LPGENW("Other"), LPGENW("Show transport agents on contact list"), m_proto->m_bShowTransport);
m_options.AddOption(LPGENW("Other"), LPGENW("Automatically add contact when accept authorization"), m_proto->m_bAutoAdd);
m_options.AddOption(LPGENW("Other"), LPGENW("Automatically accept authorization requests"), m_proto->m_bAutoAcceptAuthorization);
- m_options.AddOption(LPGENW("Other"), LPGENW("Automatically download files passed via HTTP File Upload"), m_proto->m_bAutoLoadOOB);
m_options.AddOption(LPGENW("Other"), LPGENW("Fix incorrect timestamps in incoming messages"), m_proto->m_bFixIncorrectTimestamps);
m_options.AddOption(LPGENW("Other"), LPGENW("Enable XMPP link processing (requires AssocMgr)"), m_proto->m_bProcessXMPPLinks);
m_options.AddOption(LPGENW("Other"), LPGENW("Embrace picture URLs with [img]"), m_proto->m_bEmbraceUrls);
diff --git a/protocols/JabberG/src/jabber_proto.cpp b/protocols/JabberG/src/jabber_proto.cpp index acc141e114..6ffe603acb 100644 --- a/protocols/JabberG/src/jabber_proto.cpp +++ b/protocols/JabberG/src/jabber_proto.cpp @@ -86,7 +86,6 @@ CJabberProto::CJabberProto(const char *aProtoName, const wchar_t *aUserName) : m_bAutoJoinBookmarks(this, "AutoJoinBookmarks", true),
m_bAutoJoinConferences(this, "AutoJoinConferences", false),
m_bAutoJoinHidden(this, "AutoJoinHidden", true),
- m_bAutoLoadOOB(this, "AutoLoadOOB", true),
m_bAutosaveNotes(this, "AutosaveNotes", false),
m_bBsDirect(this, "BsDirect", true),
m_bBsDirectManual(this, "BsDirectManual", false),
diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h index 019ea10d35..52e8b98c91 100644 --- a/protocols/JabberG/src/jabber_proto.h +++ b/protocols/JabberG/src/jabber_proto.h @@ -195,7 +195,6 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface CMOption<bool> m_bAutoJoinBookmarks;
CMOption<bool> m_bAutoJoinConferences;
CMOption<bool> m_bAutoJoinHidden;
- CMOption<bool> m_bAutoLoadOOB;
CMOption<bool> m_bAutosaveNotes;
CMOption<bool> m_bBsDirect;
CMOption<bool> m_bBsDirectManual;
diff --git a/protocols/JabberG/src/jabber_thread.cpp b/protocols/JabberG/src/jabber_thread.cpp index 1475657ecb..5e4fae32b9 100644 --- a/protocols/JabberG/src/jabber_thread.cpp +++ b/protocols/JabberG/src/jabber_thread.cpp @@ -1324,7 +1324,7 @@ void CJabberProto::OnProcessMessage(const TiXmlElement *node, ThreadData *info) szMessage += tempstring;
}
}
- else if (!mir_strcmp(pszXmlns, JABBER_FEAT_OOB2) && m_bAutoLoadOOB) {
+ else if (!mir_strcmp(pszXmlns, JABBER_FEAT_OOB2)) {
if (auto *url = XmlGetChildText(xNode, "url")) {
// create incoming file transfer instead of writing message
CMStringA szName;
diff --git a/src/mir_app/src/srmm_log_rtf.cpp b/src/mir_app/src/srmm_log_rtf.cpp index b38eb0f4eb..512f4d3344 100644 --- a/src/mir_app/src/srmm_log_rtf.cpp +++ b/src/mir_app/src/srmm_log_rtf.cpp @@ -143,7 +143,13 @@ void CRtfLogWindow::InsertFileLink(CMStringA &buf, MEVENT hEvent, const DB::FILE buf.AppendFormat("ofile:%ul", hEvent);
buf.Append("\"}{\\fldrslt{\\ul ");
AppendUnicodeString(buf, blob.getName());
- buf.AppendFormat("}}} | %uKB", blob.getSize() / 1024);
+ buf.AppendFormat("}}}");
+
+ if (blob.getSize() > 0 && blob.getSize() == blob.getTransferred())
+ buf.Append(" \\u10004? ");
+
+ if (uint32_t size = blob.getSize())
+ buf.AppendFormat(" %uKB", size < 1024 ? 1 : blob.getSize() / 1024);
CMStringA szHost;
if (const char *b = strstr(blob.getUrl(), "://"))
@@ -152,11 +158,6 @@ void CRtfLogWindow::InsertFileLink(CMStringA &buf, MEVENT hEvent, const DB::FILE if (!szHost.IsEmpty())
buf.AppendFormat(" on %s", szHost.c_str());
-
- if (blob.getSize() > 0 && blob.getSize() == blob.getTransferred()) {
- buf.AppendChar(' ');
- AppendUnicodeString(buf, TranslateT("Completed"));
- }
}
/////////////////////////////////////////////////////////////////////////////////////////
|