From 48540940b6c28bb4378abfeb500ec45a625b37b6 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 May 2012 10:38:20 +0000 Subject: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/crshdmp/upload.cpp | 292 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 plugins/crshdmp/upload.cpp (limited to 'plugins/crshdmp/upload.cpp') diff --git a/plugins/crshdmp/upload.cpp b/plugins/crshdmp/upload.cpp new file mode 100644 index 0000000000..498b5cb2f6 --- /dev/null +++ b/plugins/crshdmp/upload.cpp @@ -0,0 +1,292 @@ +/* +Miranda Crash Dumper Plugin +Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved + +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 version 2 +of the License. + +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, see . +*/ + +#include "utils.h" +#include + +HANDLE hNetlibUser; + +static void arrayToHex(BYTE* data, size_t datasz, char* res) +{ + char* resptr = res; + for (unsigned i=0; i> 4); + *resptr++ = (char)((ch0 <= 9) ? ('0' + ch0) : (('a' - 10) + ch0)); + + const char ch1 = (char)(ch & 0xF); + *resptr++ = (char)((ch1 <= 9) ? ('0' + ch1) : (('a' - 10) + ch1)); + } + *resptr = '\0'; +} + +void GetLoginStr(char* user, size_t szuser, char* pass) +{ + DBVARIANT dbv; + + if (DBGetContactSettingString(NULL, PluginName, "Username", &dbv) == 0) + { + mir_snprintf(user, szuser, "%s", dbv.pszVal); + DBFreeVariant(&dbv); + } + else + user[0] = 0; + + if (DBGetContactSettingString(NULL, PluginName, "Password", &dbv) == 0) + { + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM)dbv.pszVal); + + mir_md5_byte_t hash[16]; + mir_md5_state_t context; + + mir_md5_init(&context); + mir_md5_append(&context, (BYTE*)dbv.pszVal, (int)strlen(dbv.pszVal)); + mir_md5_finish(&context, hash); + + arrayToHex(hash, sizeof(hash), pass); + + DBFreeVariant(&dbv); + } + else + pass[0] = 0; +} + +void OpenAuthUrl(const char* url) +{ + char user[64], pass[40]; + GetLoginStr(user, sizeof(user), pass); + + if (user[0] && pass[0]) + { + char str[256]; + + mir_snprintf(str, sizeof(str), url, user); + char* eurl = (char*)CallService(MS_NETLIB_URLENCODE, 0, (LPARAM)str); + + mir_snprintf(str, sizeof(str), "http://www.miranda-vi.org/cdlogin?name=%s&pass=%s&redir=%s", user, pass, eurl); + CallService(MS_UTILS_OPENURL, 1, (LPARAM)str); + HeapFree(GetProcessHeap(), 0, eurl); + } + else + CallService(MS_UTILS_OPENURL, 1, (LPARAM)"http://www.miranda-vi.org/"); +} + +void CreateAuthString(char* auth) +{ + char user[64], pass[40]; + GetLoginStr(user, sizeof(user), pass); + + char str[110]; + int len = mir_snprintf(str, sizeof(str), "%s:%s", user, pass); + + strcpy(auth, "Basic "); + NETLIBBASE64 nlb = { auth+6, 250, (PBYTE)str, len }; + CallService(MS_NETLIB_BASE64ENCODE, 0, LPARAM(&nlb)); +} + + +bool InternetDownloadFile(const char *szUrl, VerTrnsfr* szReq) +{ + int result = 0xBADBAD; + char* szRedirUrl = NULL; + NETLIBHTTPREQUEST nlhr = {0}; + + // initialize the netlib request + nlhr.cbSize = sizeof(nlhr); + nlhr.requestType = REQUEST_POST; + nlhr.flags = NLHRF_HTTP11 | NLHRF_NODUMP; + nlhr.szUrl = (char*)szUrl; + + nlhr.headersCount = 6; + nlhr.headers=(NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER)*nlhr.headersCount); + nlhr.headers[0].szName = "Connection"; + nlhr.headers[0].szValue = "close"; + nlhr.headers[1].szName = "Cache-Control"; + nlhr.headers[1].szValue = "no-cache"; + nlhr.headers[2].szName = "Pragma"; + nlhr.headers[2].szValue = "no-cache"; + nlhr.headers[3].szName = "Content-Type"; + nlhr.headers[3].szValue = "text/plain; charset=utf-8"; + nlhr.headers[4].szName = "AutoUpload"; + nlhr.headers[4].szValue = (char*)(szReq->autot ? "1" : "0"); + nlhr.headers[5].szName = "Authorization"; + + char auth[256]; + CreateAuthString(auth); + nlhr.headers[5].szValue = auth; + + nlhr.pData = szReq->buf; + nlhr.dataLength = (int)strlen(szReq->buf); + + while (result == 0xBADBAD) + { + // download the page + NETLIBHTTPREQUEST *nlhrReply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, + (WPARAM)hNetlibUser,(LPARAM)&nlhr); + + if (nlhrReply) + { + int i; + + // if the recieved code is 200 OK + switch(nlhrReply->resultCode) + { + case 200: + if (DBGetContactSettingByte(NULL, PluginName, "UploadChanged", 0)) + ProcessVIHash(true); + + for (i=nlhrReply->headersCount; i--; ) + { + if (_stricmp(nlhrReply->headers[i].szName, "OldPlugins") == 0) + { + i = atoi(nlhrReply->headers[i].szValue); + break; + } + } + + ShowMessage(1, TranslateT("VersionInfo upload successful,\n %d old plugins"), i); + result = 0; + break; + + case 401: + ShowMessage(0, TranslateT("Cannot upload VersionInfo. Incorrect username or password")); + result = 1; + break; + + case 510: + ShowMessage(0, TranslateT("Cannot upload VersionInfo. User is banned")); + result = 1; + break; + + case 511: + ShowMessage(0, TranslateT("Cannot upload VersionInfo. Daily upload limit exceeded")); + result = 1; + break; + + case 301: + case 302: + case 307: + // get the url for the new location and save it to szInfo + // look for the reply header "Location" + for (i=0; iheadersCount; i++) + { + if (!strcmp(nlhrReply->headers[i].szName, "Location")) + { + size_t rlen = 0; + if (nlhrReply->headers[i].szValue[0] == '/') + { + const char* szPath; + const char* szPref = strstr(szUrl, "://"); + szPref = szPref ? szPref + 3 : szUrl; + szPath = strchr(szPref, '/'); + rlen = szPath != NULL ? szPath - szUrl : strlen(szUrl); + } + + szRedirUrl = (char*)mir_realloc(szRedirUrl, + rlen + strlen(nlhrReply->headers[i].szValue)*3 + 1); + + strncpy(szRedirUrl, szUrl, rlen); + strcpy(szRedirUrl+rlen, nlhrReply->headers[i].szValue); + + nlhr.szUrl = szRedirUrl; + break; + } + } + break; + + default: + result = 1; + ShowMessage(0, TranslateT("Cannot upload VersionInfo. Unknown error")); + } + } + else + { + result = 1; + ShowMessage(0, TranslateT("Cannot upload VersionInfo. Host unreachable.")); + } + + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)nlhrReply); + } + + mir_free(szRedirUrl); + mir_free(nlhr.headers); + + return result == 0; +} + +void __cdecl VersionInfoUploadThread(void* arg) +{ + VerTrnsfr* trn = (VerTrnsfr*)arg; + InternetDownloadFile("http://www.miranda-vi.org/uploadpost", trn); + mir_free(trn->buf); + mir_free(trn); +} + + +void UploadInit(void) +{ + NETLIBUSER nlu = {0}; + nlu.cbSize = sizeof(nlu); + nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_NOHTTPSOPTION | NUF_TCHAR; + nlu.szSettingsModule = (char*)PluginName; + nlu.ptszDescriptiveName = TranslateT("Crash Dumper HTTP connections"); + hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); +} + +void UploadClose(void) +{ + Netlib_CloseHandle(hNetlibUser); +} + +bool ProcessVIHash(bool store) +{ + bkstring buffer; + buffer.reserve(0x1800); + PrintVersionInfo(buffer, 0); + + mir_md5_byte_t hash[16]; + mir_md5_state_t context; + + mir_md5_init(&context); + mir_md5_append(&context, (PBYTE)buffer.c_str(), (int)buffer.sizebytes()); + mir_md5_finish(&context, hash); + + char hashstr[40]; + arrayToHex(hash, sizeof(hash), hashstr); + + bool result; + if (store) + { + DBWriteContactSettingString(NULL, PluginName, "VIHash", hashstr); + result = true; + } + else + { + DBVARIANT dbv; + if (DBGetContactSettingString(NULL, PluginName, "VIHash", &dbv) == 0) + { + result = strcmp(hashstr, dbv.pszVal) == 0; + DBFreeVariant(&dbv); + } + else + result = false; + } + return result; +} -- cgit v1.2.3