📄 winhttpdohttp.c
字号:
/* Copyright 2003-2005, Voltage Security, all rights reserved.
*/
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "vsdistrict.h"
#include "derhelp.h"
#include "oidlist.h"
#include "ibe.h"
#include "vtime.h"
#include "errorctx.h"
#include "volti18n.h"
#if VOLT_OS == VOLT_WINDOWS_32
#include <windows.h>
#include <tchar.h>
#include <winhttp.h>
#include <stdio.h>
#include <process.h>
int winHttpDoHTTP (
VoltHttpRequestInfo *requestInfo,
char **response,
int *responseCode,
unsigned char *url,
int allowBadCert,
unsigned char *trustStore,
unsigned long timeOut,
void *appData
)
{
int status, sysRet;
BOOL bStatus;
int actualTimeOut;
unsigned int headerLen, postDataLen, urlLen, offset;
unsigned int purpose, usernameLen, passwordLen, releaseFlag;
DWORD dwSize, bytesRead, totalSize, currentPos, respCode;
DWORD reqFlag, supportedSchemes, firstScheme, authTarget, logonLevel;
LPWSTR wideUrl = (LPWSTR)0;
LPWSTR scheme = (LPWSTR)0;
URL_COMPONENTS urlComponents;
LPWSTR host = (LPWSTR)0;
LPWSTR path = (LPWSTR)0;
HINTERNET hSession = (HINTERNET)0;
HINTERNET hConnect = (HINTERNET)0;
HINTERNET hRequest = (HINTERNET)0;
LPWSTR header = (LPWSTR)0;
char *buffer = (char *)0;
char *temp = (char *)0;
unsigned char *postData = (unsigned char *)0;
unsigned char *userPass = (unsigned char *)0;
VoltLibCtx *libCtx = (VoltLibCtx *)0;
VoltTransportCtx *transCtx = (VoltTransportCtx *)0;
VoltHttpRequestInfoPost *postInfo = (VoltHttpRequestInfoPost *)0;
VoltIdentityObject *idObj = (VoltIdentityObject *)0;
HWND uiOwner = (HWND)0;
unsigned char *username = (unsigned char *)0;
unsigned char *password = (unsigned char *)0;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
*responseCode = 0;
*response = (char *)0;
/* First check the type of request and set some variables accordingly
*/
if (requestInfo->requestType == VOLT_REQUEST_TYPE_GET)
{
libCtx = (VoltLibCtx *)requestInfo->requestData;
scheme = L"GET";
headerLen = 0;
postDataLen = 0;
}
else
{
scheme = L"POST";
postInfo = (VoltHttpRequestInfoPost *)requestInfo->requestData;
transCtx = postInfo->transCtx;
idObj = postInfo->idObj;
libCtx = (VoltLibCtx *)(transCtx->voltObject.libraryCtx);
header = L"Content-Type: application/x-www-form-urlencoded";
headerLen = -1L;
postData = postInfo->postData;
postDataLen = Z2Strlen (postData);
}
/* Get the user specified values from the app data.
*/
if (appData != (void *)0)
uiOwner = (HANDLE)appData;
sysRet = 0;
reqFlag = WINHTTP_FLAG_ESCAPE_PERCENT;
releaseFlag = 0;
purpose = VT_USER_PASS_COLLECTOR_PURPOSE_COLLECT;
logonLevel = WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH;
do
{
urlLen = Z2Strlen (url);
/* Convert the url to unicode.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltConvertMultiByteToWideAlloc (url, CP_UTF8, &wideUrl, libCtx);
if (status != 0)
break;
/* Allocate a buffer to hold the "converted" values. We're going to
* call CrackURL. It will break the URL into components. We want to
* get ride of "escape" characters (url encoding, e.g., "#" converted
* to "%23"). The Crack function will need a buffer into which it
* will place the converted value. The urlLen is measured in bytes,
* the lengths the Crack routine wants is in shorts (16-bit
* characters). For 8 characters, allocate 16 bytes. For the
* hostName and urlPath, we don't need the full URL length, but
* to make life simpler, rather than compute the needed length,
* just use the URL length.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
temp = (char *)Z2Malloc ((urlLen * 4) + 16, 0);
if (temp == (char *)0)
break;
Z2Memset (temp, 0, (urlLen * 4) + 16);
/* Parse the URL into its components.
* The Scheme will most likely be 5 characters, set aside 8 so
* we're nicely aligned. Remember, for this routine we're using
* "wide chars", so 8 characters is 16 bytes, and urlLen characters
* is 2 * urlLen bytes.
*/
Z2Memset (&urlComponents, 0, sizeof (urlComponents));
urlComponents.dwStructSize = sizeof (urlComponents);
urlComponents.lpszScheme = (LPWSTR)temp;
urlComponents.dwSchemeLength = (DWORD)8;
offset = 16;
urlComponents.lpszHostName = (LPWSTR)(temp + offset);
urlComponents.dwHostNameLength = (DWORD)urlLen;
offset += (2 * urlLen);
urlComponents.lpszUrlPath = (LPWSTR)(temp + offset);
urlComponents.dwUrlPathLength = (DWORD)urlLen;
bStatus = WinHttpCrackUrl (wideUrl, 0, ICU_DECODE, &urlComponents);
if (bStatus == FALSE)
{
VOLT_SET_ERROR_TYPE (
errorType, VT_ERROR_TYPE_PRIMARY | VT_ERROR_TYPE_SYSTEM)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_URL;
sysRet = GetLastError ();
break;
}
/* If the URL is for HTTPS specify that in the reqFlag.
*/
if (urlComponents.nScheme == INTERNET_SCHEME_HTTPS)
reqFlag |= WINHTTP_FLAG_SECURE ;
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
host = (LPWSTR)Z2Malloc
(sizeof (WCHAR) * (urlComponents.dwHostNameLength + 1), 0);
if (host == (LPWSTR)0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
path = (LPWSTR) Z2Malloc
(sizeof (WCHAR) * (urlComponents.dwUrlPathLength + 1), 0);
if (path == (LPWSTR)0)
break;
/* Compute the host and the relative path from the URL.
*/
Z2Memcpy (
host, urlComponents.lpszHostName,
urlComponents.dwHostNameLength * sizeof (WCHAR));
host[urlComponents.dwHostNameLength] = L'\0';
Z2Memcpy (
path, urlComponents.lpszUrlPath,
urlComponents.dwUrlPathLength * sizeof (WCHAR));
path[urlComponents.dwUrlPathLength] = L'\0';
/* Create an HTTP session.
*/
hSession = WinHttpOpen(
L"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
if (hSession == NULL)
{
VOLT_SET_ERROR_TYPE (
errorType, VT_ERROR_TYPE_PRIMARY | VT_ERROR_TYPE_SYSTEM)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NETWORK_CONNECT;
sysRet = GetLastError ();
break;
}
/* Set the connection timeout on the session. An input timeout
* value of 0 means timeout quickly, but when passing timeout to
* WinHTTP, a value of 0 means infinity, so convert 0 to 1, a small
* enough value close to zero.
*/
actualTimeOut = 1;
if (timeOut != 0)
actualTimeOut = (int)timeOut;
bStatus = WinHttpSetTimeouts (
hSession, 30000, actualTimeOut, 30000, 30000);
if (bStatus == FALSE)
{
VOLT_SET_ERROR_TYPE (
errorType, VT_ERROR_TYPE_PRIMARY | VT_ERROR_TYPE_SYSTEM)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NETWORK_CONNECT;
sysRet = GetLastError ();
break;
}
/* Connect to the specified server on the given port.
*/
hConnect = WinHttpConnect (hSession, host, urlComponents.nPort, 0);
if (hConnect == NULL)
{
VOLT_SET_ERROR_TYPE (
errorType, VT_ERROR_TYPE_PRIMARY | VT_ERROR_TYPE_SYSTEM)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NETWORK_CONNECT;
sysRet = GetLastError ();
break;
}
hRequest = WinHttpOpenRequest(
hConnect, scheme, path, NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES, reqFlag);
if (hRequest == NULL)
{
VOLT_SET_ERROR_TYPE (
errorType, VT_ERROR_TYPE_PRIMARY | VT_ERROR_TYPE_SYSTEM)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NETWORK_CONNECT;
sysRet = GetLastError ();
break;
}
status = 0;
do
{
/* Send the request.
*/
bStatus = WinHttpSendRequest (
hRequest, header, headerLen, (LPVOID)postData, (DWORD)postDataLen,
(DWORD)postDataLen, (DWORD_PTR)0);
if (bStatus == FALSE)
{
VOLT_SET_ERROR_TYPE (
errorType, VT_ERROR_TYPE_PRIMARY | VT_ERROR_TYPE_SYSTEM)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NETWORK_CONNECT;
sysRet = GetLastError ();
break;
}
/* Receive the response.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -