From f0bca208f1d668f0ad3d51afdafbb9d30ec8555b Mon Sep 17 00:00:00 2001 From: Gluzskiy Alexandr Date: Mon, 11 Oct 2010 23:37:54 +0300 Subject: encrypted filetransfers //two paralell threads of more than one file will fail, miranda api lack of documentation, and ghaza does not remember how to edentify thread ) --- commonheaders.h | 2 +- gpg_wrapper.cpp | 1 + init.cpp | 21 +++++-- main.cpp | 4 +- utilities.cpp | 168 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 5 files changed, 164 insertions(+), 32 deletions(-) diff --git a/commonheaders.h b/commonheaders.h index 1faf221..f3a16f7 100644 --- a/commonheaders.h +++ b/commonheaders.h @@ -44,7 +44,7 @@ using std::fstream; //boost #include #include -//#include +#include //miranda #include diff --git a/gpg_wrapper.cpp b/gpg_wrapper.cpp index 007a192..e549af7 100644 --- a/gpg_wrapper.cpp +++ b/gpg_wrapper.cpp @@ -91,6 +91,7 @@ pxResult pxExecute(wstring *acommandline, char *ainput, string *aoutput, LPDWORD commandline += home_dir; commandline += _T("\" "); commandline += _T("--display-charset utf-8 "); + commandline += _T("-z 9 "); commandline += *acommandline; mir_free(bin_path); mir_free(home_dir); diff --git a/init.cpp b/init.cpp index 1530f82..768736c 100644 --- a/init.cpp +++ b/init.cpp @@ -136,6 +136,10 @@ int AddContact(WPARAM w, LPARAM l) return 0; } +void temp_cleaner_thread(); +boost::thread cleaner(boost::bind(temp_cleaner_thread)); + + static int OnModulesLoaded(WPARAM wParam,LPARAM lParam) { @@ -152,6 +156,7 @@ static int OnModulesLoaded(WPARAM wParam,LPARAM lParam) int onExtraImageListRebuilding(WPARAM, LPARAM); int onExtraImageApplying(WPARAM wParam, LPARAM); int onProtoAck(WPARAM, LPARAM); + int onSendFile(WPARAM, LPARAM); void InitIconLib(); void InitCheck(); @@ -192,7 +197,7 @@ static int OnModulesLoaded(WPARAM wParam,LPARAM lParam) if(bJabberAPI && bIsMiranda09) HookEvent(ME_PROTO_ACCLISTCHANGED, GetJabberInterface); -// HookEvent(ME_PROTO_ACK, onProtoAck); //filetransfer unimplemented now + HookEvent(ME_PROTO_ACK, onProtoAck); //filetransfer unimplemented now HookEvent(ME_CLIST_PREBUILDCONTACTMENU, OnPreBuildContactMenu); @@ -210,10 +215,13 @@ static int OnModulesLoaded(WPARAM wParam,LPARAM lParam) pd.type=PROTOTYPE_ENCRYPTION; CallService(MS_PROTO_REGISTERMODULE,0,(LPARAM)&pd); - CreateProtoServiceFunction(szGPGModuleName,PSR_MESSAGE,RecvMsgSvc); - CreateProtoServiceFunction(szGPGModuleName,PSS_MESSAGE,SendMsgSvc); - CreateProtoServiceFunction(szGPGModuleName,PSR_MESSAGE"W",RecvMsgSvc); - CreateProtoServiceFunction(szGPGModuleName,PSS_MESSAGE"W",SendMsgSvc); + CreateProtoServiceFunction(szGPGModuleName, PSR_MESSAGE, RecvMsgSvc); + CreateProtoServiceFunction(szGPGModuleName, PSS_MESSAGE, SendMsgSvc); + CreateProtoServiceFunction(szGPGModuleName, PSR_MESSAGE"W", RecvMsgSvc); + CreateProtoServiceFunction(szGPGModuleName, PSS_MESSAGE"W", SendMsgSvc); + + CreateProtoServiceFunction(szGPGModuleName, PSS_FILE, onSendFile); + CreateProtoServiceFunction(szGPGModuleName, PSS_FILE"W", onSendFile); for (HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); hContact; hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) if (!CallService(MS_PROTO_ISPROTOONCONTACT, (WPARAM)hContact, (LPARAM)szGPGModuleName)) @@ -221,6 +229,8 @@ static int OnModulesLoaded(WPARAM wParam,LPARAM lParam) HookEvent(ME_DB_CONTACT_ADDED,AddContact); + cleaner.detach(); + return 0; @@ -237,5 +247,6 @@ extern "C" int __declspec(dllexport) Unload(void) mir_free(outclosetag); if(password) delete [] password; + cleaner.~thread(); return 0; } diff --git a/main.cpp b/main.cpp index 1cefa44..4b0f46a 100644 --- a/main.cpp +++ b/main.cpp @@ -845,7 +845,7 @@ static BOOL CALLBACK DlgProcKeyGenDialog(HWND hwndDlg, UINT msg, WPARAM wParam, f<<"\n"; tmp = new TCHAR [64]; //i hope this is enough for password GetDlgItemText(hwndDlg, IDC_KEY_PASSWD, tmp, 64); - if(!tmp[0]) + if(tmp[0]) { f<<"Passphrase: "; tmp2 = mir_utf8encodeW(tmp); @@ -864,7 +864,7 @@ static BOOL CALLBACK DlgProcKeyGenDialog(HWND hwndDlg, UINT msg, WPARAM wParam, f<<"\n"; tmp = new TCHAR [512]; GetDlgItemText(hwndDlg, IDC_KEY_COMMENT, tmp, 512); - if(!tmp[0]) + if(tmp[0]) { tmp2 = mir_utf8encodeW(tmp); f<<"Name-Comment: "; diff --git a/utilities.cpp b/utilities.cpp index ebe38dc..0d51010 100644 --- a/utilities.cpp +++ b/utilities.cpp @@ -270,18 +270,21 @@ int OnPreBuildContactMenu(WPARAM w, LPARAM l) return 0; } +struct file_in_transfer +{ + wstring file; + CCSDATA *thread; +}; + +list transfers; + int onProtoAck(WPARAM w, LPARAM l) { - extern bool bFileTransfers; - bool isContactHaveKey(HANDLE); ACKDATA *ack=(ACKDATA*)l; + CCSDATA *ccs=(CCSDATA*)ack->lParam; if (ack->type!=ACKTYPE_FILE) return 0; - if(!isContactHaveKey(ack->hContact)) - return 0; PROTOFILETRANSFERSTATUS *f = (PROTOFILETRANSFERSTATUS*) ack->lParam; - if (f && (f->flags & PFTS_SENDING) && !bFileTransfers) - return 0; if(!f) f = (PROTOFILETRANSFERSTATUS*) ack->hProcess; @@ -289,29 +292,65 @@ int onProtoAck(WPARAM w, LPARAM l) { case ACKRESULT_DENIED: case ACKRESULT_FAILED: { - if(!f->tszWorkingDir) - return 0; - if(_tcsstr(f->tszCurrentFile, _T(".gpg"))) - ; - } - break; - case ACKRESULT_NEXTFILE: case ACKRESULT_FILERESUME: //works only on receiving (than it useless ...) - { - wstring str = _T("Next:\n"); - str.append(f->tszCurrentFile).append(_T("\n")); - MessageBox(0, str.c_str(), _T(""), MB_OK); + TCHAR *temp = _wgetenv(_T("TEMP")); + if(_tcsstr(f->tszCurrentFile, temp) && _tcsstr(f->tszCurrentFile, _T(".gpg"))) //ok, succesfuly sent, delete temporary file + DeleteFile(f->tszCurrentFile); + return 0; } break; case ACKRESULT_SUCCESS: { - if(!f->tszWorkingDir) + TCHAR *temp = _wgetenv(_T("TEMP")); + if(_tcsstr(f->tszCurrentFile, temp)) + { + if(!transfers.empty()) + { + for(list::iterator i = transfers.begin(); i != transfers.end(); i++) //bad solution +// if((*i)->thread == ccs) + DeleteFile((*i)->file.c_str()); + transfers.clear(); + } +// if(_tcsstr(f->tszCurrentFile, _T(".gpg"))) //ok, succesfuly sent, delete temporary file +// DeleteFile(f->tszCurrentFile); return 0; - if(_tcsstr(f->tszCurrentFile, _T(".gpg"))) + } + else if(_tcsstr(f->tszCurrentFile, _T(".gpg"))) //decrypt it { //process encrypted file - if(f->flags & PFTS_SENDING) - DeleteFile(f->tszCurrentFile); - if(f->flags & PFTS_RECEIVING) - ; + if(_waccess(f->tszCurrentFile, 0) == -1) + { + if(errno == ENOENT) + return 0; + } + string out; + DWORD code; + pxResult result; + wstring cmd = _T("-o "); + wstring file = f->tszCurrentFile; + wstring::size_type p1 = file.find(_T(".gpg")); + file.erase(p1, _tcslen(_T(".gpg"))); + file.insert(0, _T("\"")); + file.insert(file.length(), _T("\" ")); + cmd += file; + cmd += _T(" -d \""); + cmd += f->tszCurrentFile; + cmd += _T("\""); + gpg_execution_params params; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + boost::thread *gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread->timed_join(boost::posix_time::seconds(10))) + { + delete gpg_thread; + MessageBox(0, _T("GPG execution timed out, aborted"), _T(""), MB_OK); + } + if(result == pxNotFound) + { + MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); + } + DeleteFile(f->tszCurrentFile); } } break; @@ -319,6 +358,85 @@ int onProtoAck(WPARAM w, LPARAM l) return 0; } + +//from secureim partially +int onSendFile(WPARAM w, LPARAM l) +{ + CCSDATA *ccs=(CCSDATA*)l; + if(isContactSecured(ccs->hContact)) + { + TCHAR **file=(TCHAR **)ccs->lParam; + int i; + for(i = 0; file[i]; i++) + { + if (_tcsstr(file[i],_T(".gpg"))) + continue; + TCHAR *name = _tcsrchr(file[i],_T('\\')); + if( !name ) + name = file[i]; + else + name++; + TCHAR *file_out = (TCHAR*) mir_alloc(_tcslen(name)+20); + mir_sntprintf(file_out, _tcslen(name)+7, _T("%s.gpg"), name); + string out; + DWORD code; + pxResult result; + char *keyid = UniGetContactSettingUtf(ccs->hContact, szGPGModuleName, "KeyID", ""); + wstring cmd = _T("-r "); + cmd += boost::lexical_cast(keyid); + mir_free(keyid); + cmd += _T(" -o \""); + TCHAR *temp = _wgetenv(_T("TEMP")); + cmd += temp; + cmd += _T("\\"); + cmd += file_out; + wstring path_out = temp; + path_out += _T("\\"); + path_out += file_out; + DeleteFile(path_out.c_str()); + cmd += _T("\" "); + mir_free(temp); + cmd += _T(" -e \""); + cmd += file[i]; + cmd += _T("\" "); + gpg_execution_params params; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + boost::thread *gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread->timed_join(boost::posix_time::seconds(10))) + { + delete gpg_thread; + MessageBox(0, _T("GPG execution timed out, aborted"), _T(""), MB_OK); + } + if(result == pxNotFound) + { + MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); + } + mir_free(file[i]); + file[i]=mir_wstrdup(path_out.c_str()); + mir_free(file_out); + file_in_transfer *file_transfer = new file_in_transfer; + file_transfer->file = path_out; + file_transfer->thread = ccs; + transfers.push_back(file_transfer); + } + } + + return CallService(PSS_FILE, w, l); +} + +void temp_cleaner_thread() +{ + while(true) + { + list::iterator> elements_to_del; + Sleep(10000); + } +} + void storeOutput(HANDLE ahandle, string *output) { BOOL success; @@ -503,9 +621,11 @@ static JABBER_HANDLER_FUNC SendHandler(IJabberInterface *ji, HXML node, void *pU mir_free(pass); mir_free(inkeyid); } - cmd += _T("--default-key "); + cmd += _T("--local-user "); path_c = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", _T("")); cmd += path_c; + cmd += _T(" --default-key "); + cmd += path_c; mir_free(path_c); cmd += _T(" --batch --yes -a -s \""); cmd += path_out; -- cgit v1.2.3