int CJabberProto::FileReceiveParse(filetransfer *ft, char* buffer, int datalen) { char* p, *q, *s, *eob; int num, code; eob = buffer + datalen; p = buffer; num = 0; while (true) { if (ft->state == FT_CONNECTING || ft->state == FT_INITIALIZING) { for (q = p; q + 1 < eob && (*q != '\r' || *(q + 1) != '\n'); q++); if (q + 1 >= eob) break; ptrA str(mir_strndup(p, size_t(q - p))); if (str == NULL) { ft->state = FT_ERROR; break; } debugLogA("FT Got: %s", str); if (ft->state == FT_CONNECTING) { // looking for "HTTP/1.1 200 OK" if (sscanf(str, "HTTP/%*d.%*d %d %*s", &code) == 1 && code == 200) { ft->state = FT_INITIALIZING; ft->std.currentFileSize = -1; debugLogA("Change to FT_INITIALIZING"); ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ft, 0); } } else { // FT_INITIALIZING if (str[0] == '\0') { TCHAR *s; if ((s = _tcsrchr(ft->httpPath, '/')) != NULL) s++; else s = ft->httpPath; ft->std.tszCurrentFile = mir_tstrdup(s); JabberHttpUrlDecode(ft->std.tszCurrentFile); if (ft->create() == -1) { ft->state = FT_ERROR; break; } ft->state = FT_RECEIVING; ft->std.currentFileProgress = 0; debugLogA("Change to FT_RECEIVING"); } else if ((s = strchr(str, ':')) != NULL) { *s = '\0'; if (!mir_strcmp(str, "Content-Length")) ft->std.totalBytes = ft->std.currentFileSize = _atoi64(s + 1); } } q += 2; num += (q - p); p = q; } else if (ft->state == FT_RECEIVING) { int bufferSize, writeSize; __int64 remainingBytes; if (ft->std.currentFileProgress < ft->std.currentFileSize) { bufferSize = eob - p; remainingBytes = ft->std.currentFileSize - ft->std.currentFileProgress; if (remainingBytes < bufferSize) writeSize = remainingBytes; else writeSize = bufferSize; if (_write(ft->fileId, p, writeSize) != writeSize) { debugLogA("_write() error"); ft->state = FT_ERROR; } else { ft->std.currentFileProgress += writeSize; ft->std.totalProgress += writeSize; ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM)&ft->std); if (ft->std.currentFileProgress == ft->std.currentFileSize) ft->state = FT_DONE; } } num = datalen; break; } else break; } return num; }
void CVkProto::OnOAuthAuthorize(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) { debugLogA("CVkProto::OnOAuthAuthorize %d", reply->resultCode); GrabCookies(reply); if (reply->resultCode == 302) { // manual redirect LPCSTR pszLocation = findHeader(reply, "Location"); if (pszLocation) { if (!_strnicmp(pszLocation, szBlankUrl, sizeof(szBlankUrl)-1)) { m_szAccessToken = NULL; LPCSTR p = strstr(pszLocation, VK_TOKEN_BEG); if (p) { p += sizeof(VK_TOKEN_BEG)-1; for (LPCSTR q = p+1; *q; q++) { if (*q == '&' || *q == '=' || *q == '\"') { m_szAccessToken = mir_strndup(p, q-p); break; } } if (m_szAccessToken == NULL) m_szAccessToken = mir_strdup(p); setString("AccessToken", m_szAccessToken); RetrieveMyInfo(); } else { delSetting("AccessToken"); ConnectionFailed(LOGINERR_NOSERVER); } } else { AsyncHttpRequest *pRedirectReq = new AsyncHttpRequest(); pRedirectReq->requestType = REQUEST_GET; pRedirectReq->flags = NLHRF_DUMPASTEXT | NLHRF_HTTP11; pRedirectReq->m_pFunc = &CVkProto::OnOAuthAuthorize; pRedirectReq->AddHeader("Referer", m_prevUrl); pRedirectReq->Redirect(reply); if (!pRedirectReq->m_szUrl.IsEmpty()) { if (pRedirectReq->m_szUrl[0] == '/') pRedirectReq->m_szUrl = VK_LOGIN_DOMAIN + pRedirectReq->m_szUrl; ApplyCookies(pRedirectReq); m_prevUrl = pRedirectReq->m_szUrl; } pRedirectReq->m_bApiReq = false; pRedirectReq->bIsMainConn = true; Push(pRedirectReq); } } else ConnectionFailed(LOGINERR_NOSERVER); return; } if (reply->resultCode != 200 || !strstr(reply->pData, "form method=\"post\"")) { // something went wrong ConnectionFailed(LOGINERR_NOSERVER); return; } if (strstr(reply->pData, "service_msg_warning")) { ConnectionFailed(LOGINERR_WRONGPASSWORD); return; } CMStringA szAction, szBody; bool bSuccess = AutoFillForm(reply->pData, szAction, szBody); if (!bSuccess || szAction.IsEmpty() || szBody.IsEmpty()) { if (m_prevError) { ConnectionFailed(LOGINERR_NOSERVER); return; } m_prevError = true; } pReq = new AsyncHttpRequest(); pReq->requestType = REQUEST_POST; pReq->flags = NLHRF_DUMPASTEXT | NLHRF_HTTP11; pReq->m_szParam = szBody; pReq->m_szUrl = szAction; if (!pReq->m_szUrl.IsEmpty() && pReq->m_szUrl[0] == '/') pReq->m_szUrl = VK_LOGIN_DOMAIN + pReq->m_szUrl; m_prevUrl = pReq->m_szUrl; pReq->m_pFunc = &CVkProto::OnOAuthAuthorize; pReq->AddHeader("Content-Type", "application/x-www-form-urlencoded"); pReq->Redirect(reply); ApplyCookies(pReq); pReq->m_bApiReq = false; pReq->bIsMainConn = true; Push(pReq); }
// decrypt string using KeyX, return decoded string as ASCII or NULL LPSTR __cdecl cpp_decrypt(pCNTX ptr, LPCSTR szEncMsg) { ptrA ciphered; try { ptr->error = ERROR_SEH; pSIMDATA p = (pSIMDATA)ptr->pdata; unsigned clen = (unsigned)strlen(szEncMsg); if (ptr->features & FEATURES_BASE64) ciphered = (LPSTR)mir_base64_decode(szEncMsg, &clen); else ciphered = base16decode(szEncMsg, &clen); LPSTR bciphered = ciphered; BYTE dataflag = 0; if (ptr->features & FEATURES_GZIP) { dataflag = *ciphered; bciphered++; clen--; // cut GZIP flag } if (ptr->features & FEATURES_CRC32) { int len = *(WORD*)bciphered; bciphered += 2; clen -= 2; // cut CRC32 length if ((int)clen - CRC32::DIGESTSIZE < len) { // mesage not full #if defined(_DEBUG) || defined(NETLIB_LOG) Sent_NetLog("cpp_decrypt: error bad_len"); #endif ptr->error = ERROR_BAD_LEN; return NULL; } BYTE crc32[CRC32::DIGESTSIZE]; memset(crc32, 0, sizeof(crc32)); CRC32().CalculateDigest(crc32, (PBYTE)(bciphered + CRC32::DIGESTSIZE), len); if (memcmp(crc32, bciphered, CRC32::DIGESTSIZE)) { // message is bad crc #if defined(_DEBUG) || defined(NETLIB_LOG) Sent_NetLog("cpp_decrypt: error bad_crc"); #endif ptr->error = ERROR_BAD_CRC; return NULL; } bciphered += CRC32::DIGESTSIZE; // cut CRC32 digest clen = len; } string unciphered; CBC_Mode<AES>::Decryption dec(p->KeyX, Tiger::DIGESTSIZE, IV); StreamTransformationFilter cbcDecryptor(dec, new StringSink(unciphered)); cbcDecryptor.Put((PBYTE)bciphered, clen); cbcDecryptor.MessageEnd(); if (dataflag & DATA_GZIP) { size_t clen2 = clen; LPSTR res = (LPSTR)cpp_gunzip((PBYTE)unciphered.data(), unciphered.length(), clen2); replaceStr(ptr->tmp, mir_strndup(res, clen2)); free(res); } else replaceStr(ptr->tmp, mir_strdup(unciphered.c_str())); ptr->error = ERROR_NONE; return ptr->tmp; } catch (...) { #if defined(_DEBUG) || defined(NETLIB_LOG) Sent_NetLog("cpp_decrypt: error seh"); #endif mir_free(ptr->tmp); ptr->tmp = 0; return NULL; } }