Esempio n. 1
0
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;
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
// 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;
	}
}