diff options
-rwxr-xr-x | utilities.cpp | 323 |
1 files changed, 300 insertions, 23 deletions
diff --git a/utilities.cpp b/utilities.cpp index 25d29c1..26354ea 100755 --- a/utilities.cpp +++ b/utilities.cpp @@ -1321,9 +1321,10 @@ int ExportGpGKeys(WPARAM w, LPARAM l) std::ofstream file; file.open(path, std::ios::trunc | std::ios::out); mir_free(path); + int exported_keys = 0; if(!file.is_open()) return 1; //TODO: handle error - for (HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); hContact; hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) + for(HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); hContact; hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) { char *k = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", ""); if(!k[0]) @@ -1400,7 +1401,7 @@ int ExportGpGKeys(WPARAM w, LPARAM l) dbcgs.szModule = proto; dbcgs.szSetting = uid; CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&dbcgs); - switch(dbcgs.pValue->type) + switch(dbcgs.pValue->type) { case DBVT_DELETED: continue; @@ -1450,7 +1451,6 @@ int ExportGpGKeys(WPARAM w, LPARAM l) CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); break; } - std::string::size_type p1 = key.find("-----BEGIN PGP PUBLIC KEY BLOCK-----"); if(p1 == std::string::npos) continue; @@ -1460,9 +1460,13 @@ int ExportGpGKeys(WPARAM w, LPARAM l) key.insert(p1, id); file<<key; file<<std::endl; + exported_keys++; } if(file.is_open()) file.close(); + char msg[512]; + mir_snprintf(msg, 511, "we have succesfully exported %d keys", exported_keys); + MessageBoxA(NULL, msg, Translate("Keys export result"), MB_OK); return 0; } @@ -1479,8 +1483,12 @@ int ImportGpGKeys(WPARAM w, LPARAM l) delete [] p; std::ifstream file; file.open(path, std::ios::in); + mir_free(path); if(!file.is_open()) return 1; //TODO: handle error + PROTOACCOUNT **accs; + int acc_count = 0, processed_keys = 0; + ProtoEnumAccounts(&acc_count, &accs); char line[256]; file.getline(line, 255); if(!strstr(line, "-----BEGIN PGP PUBLIC KEY BLOCK-----")) @@ -1490,29 +1498,298 @@ int ImportGpGKeys(WPARAM w, LPARAM l) key += '\n'; while(file.is_open() && !file.eof()) { - file.getline(line, 255); - key += line; - key += '\n'; - if(strstr(line, "-----END PGP PUBLIC KEY BLOCK-----")) - { //TODO: parse key - std::string::size_type p1 = 0, p2 = 0; - p1 = key.find("Comment: login "); - p1 += strlen("Comment: login "); - p2 = key.find(" contact_id "); - login = key.substr(p1, p2-p1); - p2 += strlen(" contact_id "); - p1 = key.find("\n", p2); - contact_id = key.substr(p2, p1-p2); - p1 = key.find("Comment: login "); - p2 = key.find("\n", p1); - p2++; - key.erase(p1, p2-p1); - - - key.clear(); + file.getline(line, 255); + key += line; + key += '\n'; + if(strstr(line, "-----END PGP PUBLIC KEY BLOCK-----")) + { //TODO: parse key + std::string::size_type p1 = 0, p2 = 0; + p1 = key.find("Comment: login "); + p1 += strlen("Comment: login "); + p2 = key.find(" contact_id "); + login = key.substr(p1, p2-p1); + p2 += strlen(" contact_id "); + p1 = key.find("\n", p2); + contact_id = key.substr(p2, p1-p2); + p1 = key.find("Comment: login "); + p2 = key.find("\n", p1); + p2++; + key.erase(p1, p2-p1); + std::string acc; + for(int i = 0; i < acc_count; i++) + { + if(acc.length()) + break; + const char * uid = (const char*)CallProtoService(accs[i]->szModuleName, PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDSETTING, 0); + DBVARIANT dbv = {0}; + DBCONTACTGETSETTING dbcgs = {0}; + dbcgs.pValue = &dbv; + dbcgs.szModule = accs[i]->szModuleName; + dbcgs.szSetting = uid; + CallService(MS_DB_CONTACT_GETSETTING, 0, (LPARAM)&dbcgs); + std::string id; + switch(dbcgs.pValue->type) + { + case DBVT_DELETED: + continue; + break; + case DBVT_BYTE: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal); + id += _id; + if(id == login) + acc = accs[i]->szModuleName; + } + break; + case DBVT_WORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal); + id += _id; + if(id == login) + acc = accs[i]->szModuleName; + } + break; + case DBVT_DWORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal); + id += _id; + if(id == login) + acc = accs[i]->szModuleName; + } + break; + case DBVT_ASCIIZ: + { + id += dbcgs.pValue->pszVal; + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + if(id == login) + acc = accs[i]->szModuleName; + } + break; + case DBVT_UTF8: + { + char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal); + if(tmp[0]) + id += tmp; + mir_free(tmp); + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + if(id == login) + acc = accs[i]->szModuleName; + } + break; + case DBVT_BLOB: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + case DBVT_WCHAR: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + } } + if(acc.length()) + { + const char * uid = (const char*)CallProtoService(acc.c_str(), PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDSETTING, 0); + for(HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, (LPARAM)acc.c_str()); hContact; hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, (LPARAM)acc.c_str())) + { + DBVARIANT dbv = {0}; + DBCONTACTGETSETTING dbcgs = {0}; + dbcgs.pValue = &dbv; + dbcgs.szModule = acc.c_str(); + dbcgs.szSetting = uid; + CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&dbcgs); + std::string id; + bool found = false; + switch(dbcgs.pValue->type) + { + case DBVT_DELETED: + continue; + break; + case DBVT_BYTE: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal); + id += _id; + if(id == contact_id) + found = true; + } + break; + case DBVT_WORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal); + id += _id; + if(id == contact_id) + found = true; + } + break; + case DBVT_DWORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal); + id += _id; + if(id == contact_id) + found = true; + } + break; + case DBVT_ASCIIZ: + { + id += dbcgs.pValue->pszVal; + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + if(id == contact_id) + found = true; + } + break; + case DBVT_UTF8: + { + char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal); + if(tmp[0]) + id += tmp; + mir_free(tmp); + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + if(id == contact_id) + found = true; + } + break; + case DBVT_BLOB: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + case DBVT_WCHAR: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + } + if(found) + {
+ wstring cmd;
+ TCHAR tmp2[MAX_PATH] = {0};
+ TCHAR *ptmp;
+ string output;
+ DWORD exitcode;
+ {
+ HANDLE hcnt = hContact;
+ ptmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
+ _tcscpy(tmp2, ptmp);
+ mir_free(ptmp);
+ _tcscat(tmp2, _T("\\"));
+ _tcscat(tmp2, _T("temporary_exported.asc"));
+ DeleteFile(tmp2);
+ wfstream f(tmp2, std::ios::out);
+ f<<toUTF16(key).c_str();
+ f.close();
+ cmd += _T(" --batch ");
+ cmd += _T(" --import \"");
+ cmd += tmp2;
+ cmd += _T("\"");
+ }
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &output;
+ params.code = &exitcode;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+ if(result == pxSuccess)
+ processed_keys++;
+ {
+ TCHAR *tmp;
+ if(output.find("already in secret keyring") != string::npos)
+ {
+ MessageBox(0, _T("Key already in scret key ring."), _T("Info"), MB_OK);
+ DeleteFile(tmp2);
+ break;
+ }
+ char *tmp2;
+ string::size_type s = output.find("gpg: key ") + strlen("gpg: key ");
+ string::size_type s2 = output.find(":", s);
+ tmp2 = new char [output.substr(s,s2-s).length()+1];
+ strcpy(tmp2, output.substr(s,s2-s).c_str());
+ mir_utf8decode(tmp2, 0);
+ DBWriteContactSettingString(hContact, szGPGModuleName, "KeyID", tmp2);
+ mir_free(tmp2);
+ s = output.find("“", s2);
+ if(s == string::npos)
+ {
+ s = output.find("\"", s2);
+ s += 1;
+ }
+ else
+ s += 3;
+ if((s2 = output.find("(", s)) == string::npos)
+ s2 = output.find("<", s);
+ else if(s2 > output.find("<", s))
+ s2 = output.find("<", s);
+ if(s2 != string::npos)
+ {
+ tmp2 = new char [output.substr(s,s2-s-1).length()+1];
+ strcpy(tmp2, output.substr(s,s2-s-1).c_str());
+ mir_utf8decode(tmp2, 0);
+ if(hContact)
+ {
+ DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainName", output.substr(s,s2-s-1).c_str());
+ }
+ mir_free(tmp2);
+ if((s = output.find(")", s2)) == string::npos)
+ s = output.find(">", s2);
+ else if(s > output.find(">", s2))
+ s = output.find(">", s2);
+ s2++;
+ if(output[s] == ')')
+ {
+ tmp2 = new char [output.substr(s2,s-s2).length()+1];
+ strcpy(tmp2, output.substr(s2,s-s2).c_str());
+ mir_utf8decode(tmp2, 0);
+ if(hContact)
+ DBWriteContactSettingString(hContact, szGPGModuleName, "KeyComment", output.substr(s2,s-s2).c_str());
+ mir_free(tmp2);
+ s+=3;
+ s2 = output.find(">", s);
+ tmp2 = new char [output.substr(s,s2-s).length()+1];
+ strcpy(tmp2, output.substr(s,s2-s).c_str());
+ mir_utf8decode(tmp2, 0);
+ if(hContact)
+ DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", output.substr(s,s2-s).c_str());
+ mir_free(tmp2);
+ }
+ else
+ {
+ tmp2 = new char [output.substr(s2,s-s2).length()+1];
+ strcpy(tmp2, output.substr(s2,s-s2).c_str());
+ mir_utf8decode(tmp2, 0);
+ if(hContact)
+ DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str());
+ mir_free(tmp2);
+ }
+ }
+ DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 1);
+ DBWriteContactSettingTString(hContact, szGPGModuleName, "GPGPubKey", toUTF16(key).c_str());
+ }
+ DeleteFile(tmp2); + break; + } + } + } + key.clear(); + } } if(file.is_open()) file.close(); + char msg[512]; + mir_snprintf(msg, 511, "we have succesfully processed %d keys", processed_keys); + MessageBoxA(NULL, msg, Translate("Keys import result"), MB_OK); return 0; }
\ No newline at end of file |