Ejemplo n.º 1
0
HANDLE FindNetUserHandle(LPCSTR acc)
{
    IJabberInterface *ji = getJabberApi(acc);
    if (!ji) return NULL;

    PBYTE m_psProto = *(PBYTE*)((PBYTE)ji + sizeof(*ji));	// see CJabberInterface	in jabber_proto.h

    PHANDLE pResult = (PHANDLE)(m_psProto +					// see CJabberProto in jabber_proto.h
                                sizeof(PVOID) +										// skip vtable ptr
                                sizeof(PVOID) +										// skip m_ThreadInfo
                                SIZE_OF_JABBER_OPTIONS);							// skip m_options

    //for (int i=0; i < 100; i++) {
    //	__try {
    //		if (GetNetlibHandleType(*pResult) == NLH_USER)
    //			MessageBox(0, L"1", L"1", 0);
    //	}
    //	__except (EXCEPTION_EXECUTE_HANDLER){
    //		AllocConsole();
    //	}
    //	pResult++;
    //}

    if (GetNetlibHandleType(*pResult) != NLH_USER)
        pResult += 4;

    if (GetNetlibHandleType(*pResult) != NLH_USER)
        pResult += 4;

    if (GetNetlibHandleType(*pResult) != NLH_USER)
        pResult += 4;

    assert(GetNetlibHandleType(*pResult) == NLH_USER);
    return *pResult;
}
Ejemplo n.º 2
0
INT_PTR NetlibShutdown(WPARAM wParam, LPARAM)
{
	if (wParam) 
	{
		WaitForSingleObject(hConnectionHeaderMutex,INFINITE);
		switch(GetNetlibHandleType(wParam)) {
			case NLH_CONNECTION:
				{
					struct NetlibConnection* nlc = (struct NetlibConnection*)wParam;
					if (nlc->hSsl) si.shutdown(nlc->hSsl);
					if (nlc->s != INVALID_SOCKET) shutdown(nlc->s, 2);
					if (nlc->s2 != INVALID_SOCKET) shutdown(nlc->s2, 2);
					nlc->termRequested = true;
				}
				break;
			case NLH_BOUNDPORT:
				{
					struct NetlibBoundPort* nlb = (struct NetlibBoundPort*)wParam;
					if (nlb->s != INVALID_SOCKET) shutdown(nlb->s, 2);
				}
				break;
		}
		ReleaseMutex(hConnectionHeaderMutex);

	}
	return 0;
}
Ejemplo n.º 3
0
static INT_PTR NetlibGetSocket(WPARAM wParam, LPARAM)
{
	SOCKET s;
	if(wParam==0) {
		s=INVALID_SOCKET;
		SetLastError(ERROR_INVALID_PARAMETER);
	}
	else {
		WaitForSingleObject(hConnectionHeaderMutex,INFINITE);
		switch(GetNetlibHandleType(wParam)) {
			case NLH_CONNECTION:
				s=((struct NetlibConnection*)wParam)->s;
				break;
			case NLH_BOUNDPORT:
				s=((struct NetlibBoundPort*)wParam)->s;
				break;
			default:
				s=INVALID_SOCKET;
				SetLastError(ERROR_INVALID_PARAMETER);
				break;
		}
		ReleaseMutex(hConnectionHeaderMutex);
	}
	return s;
}
Ejemplo n.º 4
0
INT_PTR NetlibHttpGatewaySetInfo(WPARAM wParam, LPARAM lParam)
{
	NETLIBHTTPPROXYINFO *nlhpi = (NETLIBHTTPPROXYINFO*)lParam;
	NetlibConnection *nlc = (struct NetlibConnection*)wParam;

	if (GetNetlibHandleType(nlc) != NLH_CONNECTION || nlhpi == NULL  ||
		nlhpi->cbSize < (sizeof(NETLIBHTTPPROXYINFO) - sizeof(int)) ||
		nlhpi->szHttpPostUrl == NULL)
	{
		SetLastError(ERROR_INVALID_PARAMETER);
		return 0;
	}

	mir_free(nlc->nlhpi.szHttpGetUrl);
	mir_free(nlc->nlhpi.szHttpPostUrl);

	nlc->nlhpi.combinePackets = 1;
	memcpy(&nlc->nlhpi, nlhpi, min(nlhpi->cbSize, sizeof(*nlhpi)));
	if (nlc->nlhpi.combinePackets == 0) nlc->nlhpi.combinePackets = 1;

	nlc->nlhpi.szHttpGetUrl = mir_strdup(nlc->nlhpi.szHttpGetUrl);
	nlc->nlhpi.szHttpPostUrl = mir_strdup(nlc->nlhpi.szHttpPostUrl);

	return 1;
}
Ejemplo n.º 5
0
INT_PTR NetlibHttpSetSticky(WPARAM wParam, LPARAM lParam)
{
	NetlibUser * nu = (NetlibUser*)wParam;
	if (GetNetlibHandleType(nu) != NLH_USER) return ERROR_INVALID_PARAMETER;
	replaceStr(nu->szStickyHeaders, (char*)lParam); // pointer is ours
	return 0;
}
Ejemplo n.º 6
0
INT_PTR NetlibHttpSetSticky(WPARAM wParam, LPARAM lParam)
{
	struct NetlibUser * nu = (struct NetlibUser*)wParam;
	if (GetNetlibHandleType(nu)!=NLH_USER) return ERROR_INVALID_PARAMETER;
	mir_free(nu->szStickyHeaders); 
	nu->szStickyHeaders = mir_strdup((char*)lParam); // pointer is ours
	return 0;
}
Ejemplo n.º 7
0
INT_PTR NetlibHttpSetPollingTimeout(WPARAM wParam, LPARAM lParam)
{
	int oldTimeout;
	NetlibConnection *nlc = (struct NetlibConnection*)wParam;
	if (GetNetlibHandleType(nlc) != NLH_CONNECTION) return -1;
	oldTimeout = nlc->pollingTimeout;
	nlc->pollingTimeout = lParam;
	return oldTimeout;
}
Ejemplo n.º 8
0
static INT_PTR NetlibSetUserSettings(WPARAM wParam,LPARAM lParam)
{
	NETLIBUSERSETTINGS *nlus=(NETLIBUSERSETTINGS*)lParam;
	struct NetlibUser *nlu=(struct NetlibUser*)wParam;

	if(GetNetlibHandleType(nlu)!=NLH_USER || nlus==NULL || nlus->cbSize!=sizeof(NETLIBUSERSETTINGS)) {
		SetLastError(ERROR_INVALID_PARAMETER);
		return 0;
	}
	NetlibSaveUserSettingsStruct(nlu->user.szSettingsModule,nlus);
	return 1;
}
Ejemplo n.º 9
0
INT_PTR NetlibOpenConnection(WPARAM wParam,LPARAM lParam)
{
	NETLIBOPENCONNECTION *nloc = (NETLIBOPENCONNECTION*)lParam;
	struct NetlibUser *nlu = (struct NetlibUser*)wParam;
	struct NetlibConnection *nlc;

	NetlibLogf(nlu,"Connection request to %s:%d (Flags %x)....", nloc->szHost, nloc->wPort, nloc->flags);

	if (GetNetlibHandleType(nlu) != NLH_USER || !(nlu->user.flags & NUF_OUTGOING) || nloc == NULL ||
		(nloc->cbSize != NETLIBOPENCONNECTION_V1_SIZE && nloc->cbSize != sizeof(NETLIBOPENCONNECTION)) || 
		nloc->szHost == NULL || nloc->wPort == 0)
	{
		SetLastError(ERROR_INVALID_PARAMETER);
		return 0;
	}
	nlc = (struct NetlibConnection*)mir_calloc(sizeof(struct NetlibConnection));
	nlc->handleType = NLH_CONNECTION;
	nlc->nlu = nlu;
	nlc->nloc = *nloc;
	nlc->nloc.szHost = mir_strdup(nloc->szHost);
	nlc->s = INVALID_SOCKET;
	nlc->s2 = INVALID_SOCKET;
	nlc->dnsThroughProxy = nlu->settings.dnsThroughProxy != 0;

	InitializeCriticalSection(&nlc->csHttpSequenceNums);
	nlc->hOkToCloseEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
	nlc->dontCloseNow = 0;
	NetlibInitializeNestedCS(&nlc->ncsSend);
	NetlibInitializeNestedCS(&nlc->ncsRecv);

	if (!NetlibDoConnect(nlc))
	{
		FreePartiallyInitedConnection(nlc);		
		return 0;
	}

	if (iUPnPCleanup == 0)
	{
		EnterCriticalSection(&csNetlibUser);
		if (iUPnPCleanup == 0) 
		{
			iUPnPCleanup = 1;
			forkthread(NetlibUPnPCleanup, 0, NULL);
		}
		LeaveCriticalSection(&csNetlibUser);
	}

	return (INT_PTR)nlc;
}
Ejemplo n.º 10
0
INT_PTR NetlibPacketRecverGetMore(WPARAM wParam, LPARAM lParam)
{
	struct NetlibPacketRecver *nlpr = (struct NetlibPacketRecver*)wParam;
	NETLIBPACKETRECVER *nlprParam = (NETLIBPACKETRECVER*)lParam;

	if (GetNetlibHandleType(nlpr) != NLH_PACKETRECVER || nlprParam == NULL || nlprParam->cbSize != sizeof(NETLIBPACKETRECVER) || nlprParam->bytesUsed > nlpr->packetRecver.bytesAvailable) {
		SetLastError(ERROR_INVALID_PARAMETER);
		return SOCKET_ERROR;
	}
	if (Miranda_Terminated()) { /* HACK: Lame, break while loops of protocols that can't kill their while loops, (cough, ICQ, cough) */
		SetLastError(ERROR_TIMEOUT);
		return SOCKET_ERROR;
	}
	nlpr->packetRecver.dwTimeout = nlprParam->dwTimeout;
	if (nlprParam->bytesUsed == 0) {
		if (nlpr->packetRecver.bytesAvailable == nlpr->packetRecver.bufferSize) {
			nlpr->packetRecver.bytesAvailable = 0;
			NetlibLogf(nlpr->nlc->nlu, "Packet recver: packet overflowed buffer, ditching");
		}
	}
	else {
		MoveMemory(nlpr->packetRecver.buffer, nlpr->packetRecver.buffer + nlprParam->bytesUsed, nlpr->packetRecver.bytesAvailable - nlprParam->bytesUsed);
		nlpr->packetRecver.bytesAvailable -= nlprParam->bytesUsed;
	}
	
	if (nlprParam->dwTimeout != INFINITE) {
		if (!si.pending(nlpr->nlc->hSsl) && WaitUntilReadable(nlpr->nlc->s, nlprParam->dwTimeout) <= 0) {
			*nlprParam = nlpr->packetRecver;
			return SOCKET_ERROR;
		}
	}
	
	INT_PTR recvResult = NLRecv(nlpr->nlc, (char*)nlpr->packetRecver.buffer + nlpr->packetRecver.bytesAvailable, nlpr->packetRecver.bufferSize - nlpr->packetRecver.bytesAvailable, 0);
	if (recvResult > 0)
		nlpr->packetRecver.bytesAvailable += recvResult;
	*nlprParam = nlpr->packetRecver;
	return recvResult;
}
Ejemplo n.º 11
0
INT_PTR NetlibPacketRecverCreate(WPARAM wParam, LPARAM lParam)
{
	NetlibConnection *nlc = (struct NetlibConnection*)wParam;
	struct NetlibPacketRecver *nlpr;

	if (GetNetlibHandleType(nlc) != NLH_CONNECTION || lParam == 0) {
		SetLastError(ERROR_INVALID_PARAMETER);
		return (INT_PTR)(struct NetlibPacketRecver*)NULL;
	}
	nlpr = (struct NetlibPacketRecver*)mir_calloc(sizeof(struct NetlibPacketRecver));
	if (nlpr == NULL) {
		SetLastError(ERROR_OUTOFMEMORY);
		return (INT_PTR)(struct NetlibPacketRecver*)NULL;
	}
	nlpr->handleType = NLH_PACKETRECVER;
	nlpr->nlc = nlc;
	nlpr->packetRecver.cbSize = sizeof(nlpr->packetRecver);
	nlpr->packetRecver.bufferSize = lParam;
	nlpr->packetRecver.buffer = (PBYTE)mir_alloc(nlpr->packetRecver.bufferSize);
	nlpr->packetRecver.bytesUsed = 0;
	nlpr->packetRecver.bytesAvailable = 0;
	return (INT_PTR)nlpr;
}
Ejemplo n.º 12
0
INT_PTR NetlibCloseHandle(WPARAM wParam, LPARAM)
{
	switch(GetNetlibHandleType(wParam)) {
		case NLH_USER:
		{	struct NetlibUser *nlu=(struct NetlibUser*)wParam;
			int i;
			
			EnterCriticalSection(&csNetlibUser);
			i = netlibUser.getIndex(nlu);
			if (i >= 0) netlibUser.remove(i);
			LeaveCriticalSection(&csNetlibUser);

			NetlibFreeUserSettingsStruct(&nlu->settings);
			mir_free(nlu->user.szSettingsModule);
			mir_free(nlu->user.szDescriptiveName);
			mir_free(nlu->user.szHttpGatewayHello);
			mir_free(nlu->user.szHttpGatewayUserAgent);
			mir_free(nlu->szStickyHeaders);
			break;
		}
		case NLH_CONNECTION:
		{	struct NetlibConnection *nlc=(struct NetlibConnection*)wParam;
			HANDLE waitHandles[4];
			DWORD waitResult;

			WaitForSingleObject(hConnectionHeaderMutex,INFINITE);
			if (nlc->usingHttpGateway)
			{
				HttpGatewayRemovePacket(nlc, -1);
			}
			else
			{
				if(nlc->s != INVALID_SOCKET) {
					NetlibDoClose(nlc);
				}
				if (nlc->s2 != INVALID_SOCKET) closesocket(nlc->s2);
				nlc->s2 = INVALID_SOCKET;
			}
			ReleaseMutex(hConnectionHeaderMutex);

			waitHandles[0]=hConnectionHeaderMutex;
			waitHandles[1]=nlc->hOkToCloseEvent;
			waitHandles[2]=nlc->ncsRecv.hMutex;
			waitHandles[3]=nlc->ncsSend.hMutex;
			waitResult=WaitForMultipleObjects( SIZEOF(waitHandles),waitHandles,TRUE,INFINITE);
			if(waitResult<WAIT_OBJECT_0 || waitResult >= WAIT_OBJECT_0 + SIZEOF(waitHandles)) {
				ReleaseMutex(hConnectionHeaderMutex);
				SetLastError(ERROR_INVALID_PARAMETER);	  //already been closed
				return 0;
			}
			nlc->handleType=0;
			mir_free(nlc->nlhpi.szHttpPostUrl);
			mir_free(nlc->nlhpi.szHttpGetUrl);
			mir_free(nlc->dataBuffer);
			mir_free((char*)nlc->nloc.szHost);
			mir_free(nlc->szNewUrl);
			mir_free(nlc->szProxyServer);
			NetlibDeleteNestedCS(&nlc->ncsRecv);
			NetlibDeleteNestedCS(&nlc->ncsSend);
			CloseHandle(nlc->hOkToCloseEvent);
			DeleteCriticalSection(&nlc->csHttpSequenceNums);
			ReleaseMutex(hConnectionHeaderMutex);
			NetlibLogf(nlc->nlu,"(%p:%u) Connection closed",nlc,nlc->s);
			break;
		}
		case NLH_BOUNDPORT:
			return NetlibFreeBoundPort((struct NetlibBoundPort*)wParam);
		case NLH_PACKETRECVER:
		{	struct NetlibPacketRecver *nlpr=(struct NetlibPacketRecver*)wParam;
			mir_free(nlpr->packetRecver.buffer);
			break;
		}
		default:
			SetLastError(ERROR_INVALID_PARAMETER);
			return 0;
	}
	mir_free((void*)wParam);
	return 1;
}
Ejemplo n.º 13
0
INT_PTR NetlibHttpTransaction(WPARAM wParam, LPARAM lParam)
{
	NetlibUser *nlu = (NetlibUser*)wParam;
	NETLIBHTTPREQUEST *nlhr = (NETLIBHTTPREQUEST*)lParam, *nlhrReply;

	if (GetNetlibHandleType(nlu) != NLH_USER || !(nlu->user.flags & NUF_OUTGOING) ||
		nlhr == NULL || nlhr->cbSize != sizeof(NETLIBHTTPREQUEST) ||
		nlhr->szUrl == NULL || nlhr->szUrl[0] == 0)
	{
		SetLastError(ERROR_INVALID_PARAMETER);
		return 0;
	}

	if (nlhr->nlc != NULL && GetNetlibHandleType(nlhr->nlc) != NLH_CONNECTION)
		nlhr->nlc = NULL;

	NetlibConnection *nlc = NetlibHttpProcessUrl(nlhr, nlu, (NetlibConnection*)nlhr->nlc);
	if (nlc == NULL)
		return 0;

	NETLIBHTTPREQUEST nlhrSend;
	char szUserAgent[64];

	nlhrSend = *nlhr;
	nlhrSend.flags &= ~NLHRF_REMOVEHOST;
	nlhrSend.flags |= NLHRF_GENERATEHOST | NLHRF_SMARTREMOVEHOST | NLHRF_SMARTAUTHHEADER;

	bool doneUserAgentHeader = NetlibHttpFindHeader(nlhr, "User-Agent") != NULL;
	bool doneAcceptEncoding = NetlibHttpFindHeader(nlhr, "Accept-Encoding") != NULL;

	if (!doneUserAgentHeader || !doneAcceptEncoding) {
		nlhrSend.headers = (NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER) * (nlhrSend.headersCount + 2));
		memcpy(nlhrSend.headers, nlhr->headers, sizeof(NETLIBHTTPHEADER) * nlhr->headersCount);
	}

	if (!doneUserAgentHeader) {
		nlhrSend.headers[nlhrSend.headersCount].szName = "User-Agent";
		nlhrSend.headers[nlhrSend.headersCount].szValue = szUserAgent;
		++nlhrSend.headersCount;

		char szMirandaVer[64];
		strncpy_s(szMirandaVer, MIRANDA_VERSION_STRING, _TRUNCATE);
		#if defined(_WIN64)
			strncat_s(szMirandaVer, " x64", _TRUNCATE);
		#endif

		char *pspace = strchr(szMirandaVer, ' ');
		if (pspace) {
			*pspace++ = '\0';
			mir_snprintf(szUserAgent, "Miranda/%s (%s)", szMirandaVer, pspace);
		}
		else mir_snprintf(szUserAgent, "Miranda/%s", szMirandaVer);
	}
	if (!doneAcceptEncoding) {
		nlhrSend.headers[nlhrSend.headersCount].szName = "Accept-Encoding";
		nlhrSend.headers[nlhrSend.headersCount].szValue = "deflate, gzip";
		++nlhrSend.headersCount;
	}
	if (NetlibHttpSendRequest((WPARAM)nlc, (LPARAM)&nlhrSend) == SOCKET_ERROR) {
		if (!doneUserAgentHeader || !doneAcceptEncoding) mir_free(nlhrSend.headers);
		nlhr->resultCode = nlhrSend.resultCode;
		NetlibCloseHandle((WPARAM)nlc, 0);
		return 0;
	}
	if (!doneUserAgentHeader || !doneAcceptEncoding)
		mir_free(nlhrSend.headers);

	DWORD dflags = (nlhr->flags & NLHRF_DUMPASTEXT ? MSG_DUMPASTEXT : 0) |
		(nlhr->flags & NLHRF_NODUMP ? MSG_NODUMP : (nlhr->flags & NLHRF_DUMPPROXY ? MSG_DUMPPROXY : 0)) |
		(nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0);

	DWORD hflags =
		(nlhr->flags & NLHRF_NODUMP ? MSG_NODUMP : (nlhr->flags & NLHRF_DUMPPROXY ? MSG_DUMPPROXY : 0)) |
		(nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0);

	if (nlhr->requestType == REQUEST_HEAD)
		nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, 0);
	else
		nlhrReply = NetlibHttpRecv(nlc, hflags, dflags);

	if (nlhrReply) {
		nlhrReply->szUrl = nlc->szNewUrl;
		nlc->szNewUrl = NULL;
	}

	if ((nlhr->flags & NLHRF_PERSISTENT) == 0 || nlhrReply == NULL) {
		NetlibCloseHandle((WPARAM)nlc, 0);
		if (nlhrReply)
			nlhrReply->nlc = NULL;
	}
	else nlhrReply->nlc = nlc;

	return (INT_PTR)nlhrReply;
}
Ejemplo n.º 14
0
INT_PTR NetlibHttpSendRequest(WPARAM wParam, LPARAM lParam)
{
	NetlibConnection *nlc = (struct NetlibConnection*)wParam;
	NETLIBHTTPREQUEST *nlhr = (NETLIBHTTPREQUEST*)lParam;
	NETLIBHTTPREQUEST *nlhrReply = NULL;
	HttpSecurityContext httpSecurity;

	struct ResizableCharBuffer httpRequest = { 0 };
	char *szHost = NULL, *szNewUrl = NULL;
	char *pszProxyAuthHdr = NULL, *pszAuthHdr = NULL;
	int i, doneHostHeader, doneContentLengthHeader, doneProxyAuthHeader, doneAuthHeader;
	int bytesSent = 0;
	bool lastFirstLineFail = false;

	if (nlhr == NULL || nlhr->cbSize != sizeof(NETLIBHTTPREQUEST) || nlhr->szUrl == NULL || nlhr->szUrl[0] == '\0') {
		SetLastError(ERROR_INVALID_PARAMETER);
		return SOCKET_ERROR;
	}

	NetlibUser *nlu = nlc->nlu;
	if (GetNetlibHandleType(nlu) != NLH_USER) {
		SetLastError(ERROR_INVALID_PARAMETER);
		return SOCKET_ERROR;
	}

	int hdrTimeout = (nlhr->timeout) ? nlhr->timeout : HTTPRECVHEADERSTIMEOUT;

	const char *pszRequest;
	switch (nlhr->requestType) {
	case REQUEST_GET:     pszRequest = "GET";     break;
	case REQUEST_POST:    pszRequest = "POST";    break;
	case REQUEST_CONNECT: pszRequest = "CONNECT"; break;
	case REQUEST_HEAD:    pszRequest = "HEAD";    break;
	case REQUEST_PUT:     pszRequest = "PUT";     break;
	case REQUEST_DELETE:  pszRequest = "DELETE";  break;
	default:
		SetLastError(ERROR_INVALID_PARAMETER);
		return SOCKET_ERROR;
	}

	if (!nlc->usingHttpGateway)
		if (!NetlibEnterNestedCS(nlc, NLNCS_SEND))
			return SOCKET_ERROR;

	const char *pszFullUrl = nlhr->szUrl;
	const char *pszUrl = NULL;

	unsigned complete = false;
	int count = 11;
	while (--count) {
		if (GetNetlibHandleType(nlc) != NLH_CONNECTION) {
			nlc = NULL;
			bytesSent = SOCKET_ERROR;
			break;
		}

		if (!NetlibReconnect(nlc)) {
			bytesSent = SOCKET_ERROR;
			break;
		}

		if (!pszUrl) {
			pszUrl = pszFullUrl;
			if (nlhr->flags & (NLHRF_SMARTREMOVEHOST | NLHRF_REMOVEHOST | NLHRF_GENERATEHOST)) {
				bool usingProxy = nlc->proxyType == PROXYTYPE_HTTP && !(nlhr->flags & NLHRF_SSL);

				mir_free(szHost);
				szHost = NULL;

				const char *ppath, *phost;
				phost = strstr(pszUrl, "://");
				if (phost == NULL) phost = pszUrl;
				else phost += 3;
				ppath = strchr(phost, '/');
				if (ppath == phost) phost = NULL;

				if (nlhr->flags & NLHRF_GENERATEHOST) {
					szHost = mir_strdup(phost);
					if (ppath && phost) szHost[ppath - phost] = 0;
				}

				if (nlhr->flags & NLHRF_REMOVEHOST || (nlhr->flags & NLHRF_SMARTREMOVEHOST && !usingProxy))
					pszUrl = ppath ? ppath : "/";

				if (usingProxy && phost && !nlc->dnsThroughProxy) {
					char* tszHost = mir_strdup(phost);
					if (ppath && phost) tszHost[ppath - phost] = 0;
					char* cln = strchr(tszHost, ':'); if (cln) *cln = 0;

					if (inet_addr(tszHost) == INADDR_NONE) {
						DWORD ip = DnsLookup(nlu, tszHost);
						if (ip && szHost) {
							mir_free(szHost);
							szHost = (char*)mir_alloc(64);
							if (cln) *cln = ':';
							mir_snprintf(szHost, 64, "%s%s", inet_ntoa(*(PIN_ADDR)&ip), cln ? cln : "");
						}
					}
					mir_free(tszHost);
				}
			}
		}

		if (nlc->proxyAuthNeeded && proxyAuthList.getCount()) {
			if (httpSecurity.m_szProvider == NULL && nlc->szProxyServer) {
				const char *szAuthMethodNlu = proxyAuthList.find(nlc->szProxyServer);
				if (szAuthMethodNlu) {
					mir_free(pszProxyAuthHdr);
					pszProxyAuthHdr = httpSecurity.Execute(nlc, nlc->szProxyServer, szAuthMethodNlu, "", complete);
				}
			}
		}
		nlc->proxyAuthNeeded = false;

		AppendToCharBuffer(&httpRequest, "%s %s HTTP/1.%d\r\n", pszRequest, pszUrl, (nlhr->flags & NLHRF_HTTP11) != 0);

		//HTTP headers
		doneHostHeader = doneContentLengthHeader = doneProxyAuthHeader = doneAuthHeader = 0;
		for (i=0; i < nlhr->headersCount; i++) {
			NETLIBHTTPHEADER &p = nlhr->headers[i];
			if (!mir_strcmpi(p.szName, "Host")) doneHostHeader = 1;
			else if (!mir_strcmpi(p.szName, "Content-Length")) doneContentLengthHeader = 1;
			else if (!mir_strcmpi(p.szName, "Proxy-Authorization")) doneProxyAuthHeader = 1;
			else if (!mir_strcmpi(p.szName, "Authorization")) doneAuthHeader = 1;
			else if (!mir_strcmpi(p.szName, "Connection")) continue;
			if (p.szValue == NULL) continue;
			AppendToCharBuffer(&httpRequest, "%s: %s\r\n", p.szName, p.szValue);
		}
		if (szHost && !doneHostHeader)
			AppendToCharBuffer(&httpRequest, "%s: %s\r\n", "Host", szHost);
		if (pszProxyAuthHdr && !doneProxyAuthHeader)
			AppendToCharBuffer(&httpRequest, "%s: %s\r\n", "Proxy-Authorization", pszProxyAuthHdr);
		if (pszAuthHdr && !doneAuthHeader)
			AppendToCharBuffer(&httpRequest, "%s: %s\r\n", "Authorization", pszAuthHdr);
		AppendToCharBuffer(&httpRequest, "%s: %s\r\n", "Connection", "Keep-Alive");
		AppendToCharBuffer(&httpRequest, "%s: %s\r\n", "Proxy-Connection", "Keep-Alive");

		// Add Sticky Headers
		if (nlu->szStickyHeaders != NULL)
			AppendToCharBuffer(&httpRequest, "%s\r\n", nlu->szStickyHeaders);

		//send it
		bytesSent = SendHttpRequestAndData(nlc, &httpRequest, nlhr, !doneContentLengthHeader);
		if (bytesSent == SOCKET_ERROR)
			break;

		//ntlm reply
		if (doneContentLengthHeader && nlhr->requestType != REQUEST_HEAD)
			break;

		DWORD fflags = MSG_PEEK | MSG_NODUMP | ((nlhr->flags & NLHRF_NOPROXY) ? MSG_RAW : 0);
		DWORD dwTimeOutTime = hdrTimeout < 0 ? -1 : GetTickCount() + hdrTimeout;
		if (!HttpPeekFirstResponseLine(nlc, dwTimeOutTime, fflags, &nlhr->resultCode, NULL, NULL)) {
			DWORD err = GetLastError();
			NetlibLogf(nlu, "%s %d: %s Failed (%u %u)", __FILE__, __LINE__, "HttpPeekFirstResponseLine", err, count);

			// connection died while we were waiting
			if (GetNetlibHandleType(nlc) != NLH_CONNECTION) {
				nlc = NULL;
				break;
			}

			if (err == ERROR_TIMEOUT || err == ERROR_BAD_FORMAT || err == ERROR_BUFFER_OVERFLOW || lastFirstLineFail || nlc->termRequested || nlhr->requestType == REQUEST_CONNECT) {
				bytesSent = SOCKET_ERROR;
				break;
			}

			lastFirstLineFail = true;
			continue;
		}

		int resultCode = nlhr->resultCode;
		lastFirstLineFail = false;

		DWORD hflags = (nlhr->flags & (NLHRF_NODUMP | NLHRF_NODUMPHEADERS | NLHRF_NODUMPSEND) ?
		MSG_NODUMP : (nlhr->flags & NLHRF_DUMPPROXY ? MSG_DUMPPROXY : 0)) |
						 (nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0);

		DWORD dflags = (nlhr->flags & (NLHRF_NODUMP | NLHRF_NODUMPSEND) ? MSG_NODUMP : MSG_DUMPASTEXT | MSG_DUMPPROXY) |
			(nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0) | MSG_NODUMP;

		if (resultCode == 100)
			nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, hflags);

		else if (resultCode == 307 || ((resultCode == 301 || resultCode == 302) && (nlhr->flags & NLHRF_REDIRECT))) { // redirect
			pszUrl = NULL;

			if (nlhr->requestType == REQUEST_HEAD)
				nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, hflags);
			else
				nlhrReply = NetlibHttpRecv(nlc, hflags, dflags);

			if (nlhrReply) {
				char* tmpUrl = NetlibHttpFindHeader(nlhrReply, "Location");
				if (tmpUrl) {
					size_t rlen = 0;
					if (tmpUrl[0] == '/') {
						const char *ppath, *phost;
						phost = strstr(pszFullUrl, "://");
						phost = phost ? phost + 3 : pszFullUrl;
						ppath = strchr(phost, '/');
						rlen = ppath ? ppath - pszFullUrl : mir_strlen(pszFullUrl);
					}

					nlc->szNewUrl = (char*)mir_realloc(nlc->szNewUrl, rlen + mir_strlen(tmpUrl) * 3 + 1);

					strncpy(nlc->szNewUrl, pszFullUrl, rlen);
					mir_strcpy(nlc->szNewUrl + rlen, tmpUrl);
					pszFullUrl = nlc->szNewUrl;
					pszUrl = NULL;

					if (NetlibHttpProcessUrl(nlhr, nlu, nlc, pszFullUrl) == NULL) {
						bytesSent = SOCKET_ERROR;
						break;
					}
				}
				else {
					NetlibHttpSetLastErrorUsingHttpResult(resultCode);
					bytesSent = SOCKET_ERROR;
					break;
				}
			}
			else {
				NetlibHttpSetLastErrorUsingHttpResult(resultCode);
				bytesSent = SOCKET_ERROR;
				break;
			}
		}
		else if (resultCode == 401 && !doneAuthHeader) { //auth required
			if (nlhr->requestType == REQUEST_HEAD)
				nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, hflags);
			else
				nlhrReply = NetlibHttpRecv(nlc, hflags, dflags);

			mir_free(pszAuthHdr); pszAuthHdr = NULL;
			if (nlhrReply) {
				char *szAuthStr = NULL;
				if (!complete) {
					szAuthStr = NetlibHttpFindAuthHeader(nlhrReply, "WWW-Authenticate", httpSecurity.m_szProvider);
					if (szAuthStr) {
						char *szChallenge = strchr(szAuthStr, ' ');
						if (!szChallenge || !*lrtrimp(szChallenge))
							complete = true;
					}
				}
				if (complete && httpSecurity.m_hNtlmSecurity)
					szAuthStr = httpSecurity.TryBasic() ? NetlibHttpFindAuthHeader(nlhrReply, "WWW-Authenticate", "Basic") : NULL;

				if (szAuthStr) {
					char *szChallenge = strchr(szAuthStr, ' ');
					if (szChallenge) { *szChallenge = 0; szChallenge = lrtrimp(szChallenge + 1); }

					pszAuthHdr = httpSecurity.Execute(nlc, szHost, szAuthStr, szChallenge, complete);
				}
			}
			if (pszAuthHdr == NULL) {
				proxyAuthList.add(szHost, NULL);
				NetlibHttpSetLastErrorUsingHttpResult(resultCode);
				bytesSent = SOCKET_ERROR;
				break;
			}
		}
		else if (resultCode == 407 && !doneProxyAuthHeader) { //proxy auth required
			if (nlhr->requestType == REQUEST_HEAD)
				nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, hflags);
			else
				nlhrReply = NetlibHttpRecv(nlc, hflags, dflags);

			mir_free(pszProxyAuthHdr); pszProxyAuthHdr = NULL;
			if (nlhrReply) {
				char *szAuthStr = NULL;
				if (!complete) {
					szAuthStr = NetlibHttpFindAuthHeader(nlhrReply, "Proxy-Authenticate", httpSecurity.m_szProvider);
					if (szAuthStr) {
						char *szChallenge = strchr(szAuthStr, ' ');
						if (!szChallenge || !*lrtrimp(szChallenge + 1))
							complete = true;
					}
				}
				if (complete && httpSecurity.m_hNtlmSecurity)
					szAuthStr = httpSecurity.TryBasic() ? NetlibHttpFindAuthHeader(nlhrReply, "Proxy-Authenticate", "Basic") : NULL;

				if (szAuthStr) {
					char *szChallenge = strchr(szAuthStr, ' ');
					if (szChallenge) { *szChallenge = 0; szChallenge = lrtrimp(szChallenge + 1); }

					pszProxyAuthHdr = httpSecurity.Execute(nlc, nlc->szProxyServer, szAuthStr, szChallenge, complete);
				}
			}
			if (pszProxyAuthHdr == NULL) {
				proxyAuthList.add(nlc->szProxyServer, NULL);
				NetlibHttpSetLastErrorUsingHttpResult(resultCode);
				bytesSent = SOCKET_ERROR;
				break;
			}
		}
		else break;

		if (pszProxyAuthHdr && resultCode != 407 && !doneProxyAuthHeader)
			replaceStr(pszProxyAuthHdr, NULL);

		if (pszAuthHdr && resultCode != 401 && !doneAuthHeader)
			replaceStr(pszAuthHdr, NULL);

		if (nlhrReply) {
			NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
			nlhrReply = NULL;
		}
	}

	if (count == 0) bytesSent = SOCKET_ERROR;
	if (nlhrReply)
		NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);

	//clean up
	mir_free(pszProxyAuthHdr);
	mir_free(pszAuthHdr);
	mir_free(szHost);
	mir_free(szNewUrl);

	if (nlc && !nlc->usingHttpGateway)
		NetlibLeaveNestedCS(&nlc->ncsSend);

	return bytesSent;
}
Ejemplo n.º 15
0
INT_PTR NetlibBindPort(WPARAM wParam,LPARAM lParam)
{
    NETLIBBIND *nlb = (NETLIBBIND*)lParam;
    struct NetlibUser *nlu = (struct NetlibUser*)wParam;
    struct NetlibBoundPort *nlbp;
    SOCKADDR_IN sin;
    int foundPort = 0;
    UINT dwThreadId;

    if (GetNetlibHandleType(nlu) != NLH_USER || !(nlu->user.flags & NUF_INCOMING) ||
            nlb == NULL || nlb->pfnNewConnection == NULL)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return 0;
    }
    if (nlb->cbSize != sizeof(NETLIBBIND)   &&
            nlb->cbSize != NETLIBBIND_SIZEOF_V2 &&
            nlb->cbSize != NETLIBBIND_SIZEOF_V1)
    {
        return 0;
    }
    nlbp = (NetlibBoundPort*)mir_calloc(sizeof(NetlibBoundPort));
    nlbp->handleType = NLH_BOUNDPORT;
    nlbp->nlu = nlu;
    nlbp->pfnNewConnectionV2 = nlb->pfnNewConnectionV2;
    nlbp->s = socket(AF_INET, SOCK_STREAM, 0);
    nlbp->pExtra = (nlb->cbSize != NETLIBBIND_SIZEOF_V1) ? nlb->pExtra : NULL;
    if (nlbp->s == INVALID_SOCKET)
    {
        NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"socket",WSAGetLastError());
        mir_free(nlbp);
        return 0;
    }
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = htonl(INADDR_ANY);
    sin.sin_port = 0;

    /* if the netlib user wanted a free port given in the range, then
    they better have given wPort==0, let's hope so */
    if (nlu->settings.specifyIncomingPorts && nlu->settings.szIncomingPorts && nlb->wPort == 0)
    {
        if (!BindSocketToPort(nlu->settings.szIncomingPorts, nlbp->s, &nlu->outportnum))
        {
            NetlibLogf(nlu, "Netlib bind: Not enough ports for incoming connections specified");
            SetLastError(WSAEADDRINUSE);
        }
        else
            foundPort = 1;
    }
    else
    {
        /* if ->wPort==0 then they'll get any free port, otherwise they'll
        be asking for whatever was in nlb->wPort*/
        if (nlb->wPort != 0)
        {
            NetlibLogf(nlu,"%s %d: trying to bind port %d, this 'feature' can be abused, please be sure you want to allow it.",__FILE__,__LINE__,nlb->wPort);
            sin.sin_port = htons(nlb->wPort);
        }
        if (bind(nlbp->s, (PSOCKADDR)&sin, sizeof(sin)) == 0)
            foundPort = 1;
    }
    if (!foundPort)
    {
        NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"bind",WSAGetLastError());
        closesocket(nlbp->s);
        mir_free(nlbp);
        return 0;
    }

    if (listen(nlbp->s, 5))
    {
        NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"listen",WSAGetLastError());
        closesocket(nlbp->s);
        mir_free(nlbp);
        return 0;
    }

    {   int len;
        DWORD extIP;

        ZeroMemory(&sin,sizeof(sin));
        len = sizeof(sin);
        if (getsockname(nlbp->s,(SOCKADDR *)&sin,&len))
        {
            NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"getsockname",WSAGetLastError());
            closesocket(nlbp->s);
            mir_free(nlbp);
            return 0;
        }
        nlb->wPort = ntohs(sin.sin_port);
        nlbp->wPort = nlb->wPort;
        nlb->dwInternalIP = ntohl(sin.sin_addr.S_un.S_addr);

        if (nlb->dwInternalIP == 0)
        {
            char hostname[64];
            struct hostent *he;

            gethostname(hostname, SIZEOF(hostname));
            he = gethostbyname(hostname);
            if (he && he->h_addr_list[0])
                nlb->dwInternalIP = ntohl(*(PDWORD)he->h_addr_list[0]);
        }
        if (nlu->settings.enableUPnP &&
                NetlibUPnPAddPortMapping(nlb->wPort, "TCP", &nlbp->wExPort, &extIP, nlb->cbSize > NETLIBBIND_SIZEOF_V2))
        {
            NetlibLogf(NULL, "UPnP port mapping succeeded. Internal Port: %u External Port: %u\n",
                       nlb->wPort, nlbp->wExPort);
            if (nlb->cbSize > NETLIBBIND_SIZEOF_V2)
            {
                nlb->wExPort = nlbp->wExPort;
                nlb->dwExternalIP = extIP;
            }
        }
        else
        {
            if (nlu->settings.enableUPnP)
                NetlibLogf(NULL, "UPnP port mapping failed. Internal Port: %u\n", nlb->wPort);
            else
                NetlibLogf(NULL, "UPnP disabled. Internal Port: %u\n", nlb->wPort);

            nlbp->wExPort = 0;
            if (nlb->cbSize > NETLIBBIND_SIZEOF_V2)
            {
                nlb->wExPort = nlb->wPort;
                nlb->dwExternalIP = nlb->dwInternalIP;
            }
        }
    }
    nlbp->hThread = (HANDLE)forkthreadex(NULL, 0, NetlibBindAcceptThread, 0, nlbp, &dwThreadId);
    return (INT_PTR)nlbp;
}
Ejemplo n.º 16
0
int NetlibHttpGatewayRecv(NetlibConnection *nlc, char *buf, int len, int flags)
{
	bool peek = (flags & MSG_PEEK) != 0;

	if (nlc->dataBufferLen != 0 && (!peek || nlc->dataBufferLen >= len))
		return HttpGatewayReadSetResult(nlc, buf, len, peek);

	NetlibUser *nlu = nlc->nlu;
	if (GetNetlibHandleType(nlu) != NLH_USER)
		return SOCKET_ERROR;

	for (int retryCount = 0; retryCount < NETLIBHTTP_RETRYCOUNT;) {
		if (nlc->nlhpi.szHttpGetUrl == NULL && retryCount == 0) {
			if (nlc->pollingTimeout == 0) nlc->pollingTimeout = 30;

			/* We Need to sleep/wait for the data to send before we do receive */
			for (int pollCount = nlc->pollingTimeout; pollCount--;) {
				if (nlc->pHttpProxyPacketQueue != NULL && GetTickCount() - nlc->lastPost > 1000)
					break;

				if (nlc->termRequested || (SleepEx(1000, TRUE) && Miranda_Terminated()))
					return SOCKET_ERROR;
			}

			nlc->lastPost = GetTickCount();
			if (nlc->pHttpProxyPacketQueue == NULL && nlu->user.pfnHttpGatewayWrapSend != NULL)
				if (nlu->user.pfnHttpGatewayWrapSend(nlc, (PBYTE)"", 0, MSG_NOHTTPGATEWAYWRAP, NetlibSend) == SOCKET_ERROR)
					return SOCKET_ERROR;
		}

		int numPackets = 0;
		if (nlc->nlhpi.szHttpGetUrl) {
			if (!NetlibHttpGatewaySend(nlc, reqOldGet, NULL, 0)) {
				if (GetLastError() == ERROR_ACCESS_DENIED || nlc->termRequested)
					break;

				++retryCount;
				continue;
			}
		}
		else {
			if (!NetlibHttpGatewayStdPost(nlc, numPackets)) {
				if (GetLastError() == ERROR_ACCESS_DENIED || nlc->termRequested)
					break;

				++retryCount;
				continue;
			}
		}
		NETLIBHTTPREQUEST *nlhrReply = NetlibHttpRecv(nlc, flags | MSG_RAW | MSG_DUMPPROXY, MSG_RAW | MSG_DUMPPROXY);
		if (nlhrReply == NULL)
			return SOCKET_ERROR;

		if (nlu->user.pfnHttpGatewayUnwrapRecv && !(flags & MSG_NOHTTPGATEWAYWRAP))
			nlhrReply->pData = (char*)nlu->user.pfnHttpGatewayUnwrapRecv(nlhrReply, (PBYTE)nlhrReply->pData, nlhrReply->dataLength, &nlhrReply->dataLength, mir_realloc);

		if (nlhrReply->resultCode >= 300) {
			int resultCode = nlhrReply->resultCode;
			NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);

			if (nlc->nlhpi.szHttpGetUrl && resultCode != 404) {
				NetlibLogf(nlu, "Error received from proxy, retrying");
				continue;
			}
			else {
				NetlibLogf(nlu, "Error received from proxy, retry attempts exceeded (%u)", retryCount);
				SetLastError(ERROR_GEN_FAILURE);
				return SOCKET_ERROR;
			}
		}
		else {
			retryCount = 0;
			HttpGatewayRemovePacket(nlc, numPackets);
		}

		if (nlhrReply->dataLength) {
			if (peek) {
				int rbytes = nlc->dataBufferLen + nlhrReply->dataLength;

				nlc->dataBuffer = (PBYTE)mir_realloc(nlc->dataBuffer, rbytes);
				memcpy(nlc->dataBuffer + nlc->dataBufferLen, nlhrReply->pData, nlhrReply->dataLength);
				nlc->dataBufferLen = rbytes;

				NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);

				return HttpGatewayReadSetResult(nlc, buf, len, peek);
			}
			else {
				int bytes = min(len, nlhrReply->dataLength);
				int rbytes = nlhrReply->dataLength - bytes;

				memcpy(buf, nlhrReply->pData, bytes);

				nlc->dataBuffer = (PBYTE)mir_realloc(nlc->dataBuffer, rbytes);
				if (rbytes) memcpy(nlc->dataBuffer, nlhrReply->pData + bytes, rbytes);
				nlc->dataBufferLen = rbytes;

				NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
				return bytes;
			}
		}
		else {
			if ((peek && nlc->dataBufferLen != 0) || nlhrReply->pData) {
				NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
				return HttpGatewayReadSetResult(nlc, buf, len, peek);
			}
		}
		NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
	}

	SetLastError(ERROR_GEN_FAILURE);
	return SOCKET_ERROR;
}