// Copyright © 2010 sss // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "commonheaders.h" int RecvMsgSvc(WPARAM w, LPARAM l) { CCSDATA *ccs = (CCSDATA*)l; if (!ccs) return CallService(MS_PROTO_CHAINRECV, w, l); PROTORECVEVENT *pre = (PROTORECVEVENT*)(ccs->lParam); if (!pre) return CallService(MS_PROTO_CHAINRECV, w, l); char *msg = pre->szMessage; if (!msg) return CallService(MS_PROTO_CHAINRECV, w, l); bool unicode = (bool)(pre->flags&PREF_UNICODE); { //check for gpg related data wchar_t *tmp = mir_utf8decodeW(msg); wstring str = tmp; mir_free(tmp); wstring::size_type s1, s2; s2 = str.find(_T("-----END PGP PUBLIC KEY BLOCK-----")); s1 = str.find(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----")); if((s2 != wstring::npos) && (s1 != wstring::npos)) { //this is public key if(!DBGetContactSettingByte(ccs->hContact, szModuleName, "GPGEncryption", 0)) ;// s1 = 0; while((s1 = str.find(_T("\r"), s1)) != wstring::npos) { str.erase(s1, 1); } s2 = str.find(_T("-----END PGP PUBLIC KEY BLOCK-----")); s1 = str.find(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----")); s2 += _tcslen(_T("-----END PGP PUBLIC KEY BLOCK-----")); DBWriteContactSettingTString(ccs->hContact, szModuleName, "GPGPubKey", str.substr(s1,s2-s1).c_str()); { //gpg execute block wstring cmd; TCHAR tmp2[MAX_PATH] = {0}; TCHAR *ptmp; string output; DWORD exitcode; { ptmp = UniGetContactSettingUtf(NULL, szModuleName, "szHomePath", _T("")); _tcscpy(tmp2, ptmp); mir_free(ptmp); _tcscat(tmp2, _T("\\")); _tcscat(tmp2, _T("temporary_exported.asc")); wfstream f(tmp2, std::ios::out); ptmp = UniGetContactSettingUtf(ccs->hContact, szModuleName, "GPGPubKey", _T("")); wstring str = ptmp; mir_free(ptmp); f<hContact, szModuleName, "GPGEncryption", 0)) ;// { wstring::size_type p = 0; while((p = str.find(_T("\r"), p)) != wstring::npos) str.erase(p, 1); } s2 += _tcslen(_T("-----END PGP MESSAGE-----")); char *tmp = mir_t2a(str.substr(s1,s2-s1).c_str()); TCHAR *tmp2 = UniGetContactSettingUtf(NULL, szModuleName, "szHomePath", _T("")); wstring path = tmp2; path.append(_T("\\encrypted_data.asc")); wfstream f(path.c_str(), std::ios::out); f< 0) { cmd += _T("--passphrase \""); cmd += tmp; cmd += _T("\" "); } mir_free(tmp); } cmd += _T("--output \""); cmd += tmp2; cmd += _T("\\decrypted_data\""); cmd += _T(" -d -a \""); cmd += path; cmd += _T("\""); //MessageBox(0, cmd.c_str(), _T("in"), MB_OK); if(pxExecute(&cmd, "", &out, &code) == pxNotFound) { MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); DeleteFile(path.c_str()); return CallService(MS_PROTO_CHAINRECV, w, l); } //MessageBoxA(0, out.c_str(), "out", MB_OK); { wstring tmp = tmp2; tmp += _T("\\decrypted_data"); if(_waccess(tmp.c_str(), 0) == -1) { if(errno == ENOENT) { mir_free((void**)pre->szMessage); pre->szMessage = "Failed to decrypt GPG encrypted message"; return CallService(MS_PROTO_CHAINRECV, w, (LPARAM)ccs); } } } str.clear(); { wstring path = tmp2; mir_free(tmp2); path += _T("\\decrypted_data"); fstream f(path.c_str(), std::ios::in); while(!f.eof() && f.is_open()) { char tmp[256]; f.getline(tmp, 256); TCHAR *tmp2; // if(unicode) tmp2 = mir_utf8decodeW(tmp); // else // tmp2 = mir_a2t(tmp); str.append(tmp2).append(_T("\n")); mir_free(tmp2); } f.close(); DeleteFile(path.c_str()); str.erase(str.find_last_of(_T("\n")), 1); if(!str.length()) { mir_free((void**)pre->szMessage); pre->szMessage = "Failed to decrypt GPG encrypted message"; return CallService(MS_PROTO_CHAINRECV, w, (LPARAM)ccs); } else { mir_free((void**)pre->szMessage); if(bAppendTags) { str.insert(0, inopentag); str.append(inclosetag); } char *utf = mir_utf8encodeW(str.c_str()); pre->szMessage = utf; return CallService(MS_PROTO_CHAINRECV, w, (LPARAM)ccs); } } } } } return CallService(MS_PROTO_CHAINRECV, w, l); } int SendMsgSvc(WPARAM w, LPARAM l) { CCSDATA *ccs = (CCSDATA*)l; if (!ccs) return CallService(MS_PROTO_CHAINSEND, w, l); if(!DBGetContactSettingByte(ccs->hContact, szModuleName, "GPGEncryption", 0)) return CallService(MS_PROTO_CHAINSEND, w, l); char *msg = (char*)(ccs->lParam); if (!msg) return CallService(MS_PROTO_CHAINSEND, w, l); bool unicode = (bool)(ccs->wParam&PREF_UNICODE); { //encrypt data here wchar_t *tmp = mir_utf8decodeW(msg); wstring str = tmp; mir_free(tmp); wstring::size_type s1, s2; { //not xmpp, just replace whole message string out; DWORD code; wstring cmd; wstring path; char *tmp = UniGetContactSettingUtf(ccs->hContact, szModuleName, "KeyFingerprint", ""); if(strlen(tmp) < 2) { mir_free(tmp); return CallService(MS_PROTO_CHAINSEND, w, l); } cmd += _T("--trust-model always "); cmd += _T("--batch --yes -e -a -r "); TCHAR *tmp2 = mir_a2t(tmp); mir_free(tmp); cmd += tmp2; mir_free(tmp2); cmd += _T(" \""); tmp2 = UniGetContactSettingUtf(NULL, szModuleName, "szHomePath", _T("")); path.append(tmp2); cmd += tmp2; mir_free(tmp2); cmd += _T("\\exported_data"); path.append(_T("\\exported_data")); cmd += _T("\""); { char *tmp; // if(unicode) tmp = mir_utf8encodeW(str.c_str()); // else // tmp = mir_t2a(str.c_str()); wfstream f(path.c_str(), std::ios::out); f<hContact, "Failed to encrypt message with GPG", EVENTTYPE_MESSAGE, DBEF_SENT); return CallService(MS_PROTO_CHAINRECV, w, (LPARAM)ccs); } mir_free((void**)ccs->lParam); char *utf = mir_utf8encodeW(str.c_str()); ccs->lParam = (LPARAM)utf; if(bAppendTags) DBWriteContactSettingByte(ccs->hContact, szModuleName, "MsgsForTagging", DBGetContactSettingByte(ccs->hContact, szModuleName, "MsgsForTagging", 0) + 1); } } return CallService(MS_PROTO_CHAINSEND, w, l); } int HookSendMsg(WPARAM w, LPARAM l) { HANDLE hContact = (HANDLE)w; if(!DBGetContactSettingByte(hContact, szModuleName, "GPGEncryption", 0)) return 0; if(bAppendTags) { if(!l) return 0; BYTE Msgs = DBGetContactSettingByte(hContact, szModuleName, "MsgsForTagging", 0); if(!Msgs) return 0; DBEVENTINFO * dbei = (DBEVENTINFO*)l; if((dbei->eventType == EVENTTYPE_MESSAGE) && (dbei->flags & DBEF_SENT)) { char *msg = (char*)dbei->pBlob; TCHAR *tmp = mir_utf8decodeW(msg); wstring str = tmp; mir_free(tmp); str.insert(0, outopentag); str.append(outclosetag); char *msg2 = mir_utf8encodeW(str.c_str()); mir_free(dbei->pBlob); dbei->pBlob = (PBYTE)msg2; dbei->cbBlob = strlen(msg2)+1; DBWriteContactSettingByte(hContact, szModuleName, "MsgsForTagging", Msgs - 1); } } return 0; }