Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

523 lines
15 KiB

// ===========================================================================
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright 1996 Microsoft Corporation. All Rights Reserved.
// ===========================================================================
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <io.h>
#include <wininet.h>
BOOL g_fAllowCustomUI;
DWORD g_dwConnectFlags;
BOOL g_fPreload;
BOOL g_fMonolithicUpload = TRUE;
LPSTR g_szVerb = NULL;
//==============================================================================
BOOL NeedAuth (HINTERNET hRequest, DWORD *pdwStatus)
{
// Get status code.
DWORD dwStatus;
DWORD cbStatus = sizeof(dwStatus);
HttpQueryInfo
(
hRequest,
HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE,
&dwStatus,
&cbStatus,
NULL
);
fprintf (stderr, "Status: %d\n", dwStatus);
*pdwStatus = dwStatus;
// Look for 401 or 407.
DWORD dwFlags;
switch (dwStatus)
{
case HTTP_STATUS_DENIED:
dwFlags = HTTP_QUERY_WWW_AUTHENTICATE;
break;
case HTTP_STATUS_PROXY_AUTH_REQ:
dwFlags = HTTP_QUERY_PROXY_AUTHENTICATE;
break;
default:
return FALSE;
}
// Enumerate the authentication types.
BOOL fRet;
char szScheme[64];
DWORD dwIndex = 0;
do
{
DWORD cbScheme = sizeof(szScheme);
fRet = HttpQueryInfo
(hRequest, dwFlags, szScheme, &cbScheme, &dwIndex);
if (fRet)
fprintf (stderr, "Found auth scheme: %s\n", szScheme);
}
while (fRet);
return TRUE;
}
//==============================================================================
DWORD DoCustomUI (HINTERNET hRequest, BOOL fProxy)
{
// Prompt for username and password.
char szUser[64], szPass[64];
fprintf (stderr, "Enter Username: ");
if (!fscanf (stdin, "%s", szUser))
return ERROR_INTERNET_LOGIN_FAILURE;
fprintf (stderr, "Enter Password: ");
if (!fscanf (stdin, "%s", szPass))
return ERROR_INTERNET_LOGIN_FAILURE;
// Set the values in the handle.
if (fProxy)
{
InternetSetOption
(hRequest, INTERNET_OPTION_PROXY_USERNAME, szUser, sizeof(szUser));
InternetSetOption
(hRequest, INTERNET_OPTION_PROXY_PASSWORD, szPass, sizeof(szPass));
}
else
{
InternetSetOption
(hRequest, INTERNET_OPTION_USERNAME, szUser, sizeof(szUser));
InternetSetOption
(hRequest, INTERNET_OPTION_PASSWORD, szPass, sizeof(szPass));
}
return ERROR_INTERNET_FORCE_RETRY;
}
//==============================================================================
int RequestLoop (int argc, char **argv)
{
HINTERNET hInternet = NULL;
HINTERNET hConnect = NULL;
HINTERNET hRequest = NULL;
PSTR pPostData = NULL;
DWORD cbPostData = 0;
PSTR pszErr = NULL;
BOOL fRet;
#define CHECK_ERROR(cond, err) if (!(cond)) {pszErr=(err); goto done;}
// Parse host:port
PSTR pszHost = argv[0];
DWORD dwPort;
PSTR pszColon = strchr(pszHost, ':');
if (!pszColon)
dwPort = INTERNET_INVALID_PORT_NUMBER;
else
{
*pszColon++ = 0;
dwPort = atol (pszColon);
}
PSTR pszObject = argc >= 2 ? argv[1] : "/";
PSTR pszUser = argc >= 3 ? argv[2] : NULL;
PSTR pszPass = argc >= 4 ? argv[3] : NULL;
PSTR pszPostFile = argc >= 5 ? argv[4] : NULL;
if (pszPostFile)
g_dwConnectFlags |= INTERNET_FLAG_RELOAD;
//#ifdef MONOLITHIC_UPLOAD
if(g_fMonolithicUpload)
{
// Read any POST data into a buffer.
if (pszPostFile)
{
HANDLE hf =
CreateFile
(
pszPostFile,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
NULL
);
if (hf != INVALID_HANDLE_VALUE)
{
cbPostData = GetFileSize (hf, NULL);
pPostData = (PSTR) LocalAlloc (LMEM_FIXED, cbPostData + 1);
if (pPostData)
ReadFile (hf, pPostData, cbPostData, &cbPostData, NULL);
pPostData[cbPostData] = 0;
CloseHandle (hf);
}
}
} // g_fMonolithicUpload
//#endif
// Initialize wininet.
hInternet = InternetOpen
(
//"HttpAuth Sample", // user agent
"Mozilla/4.0 (compatible; MSIE 4.0b2; Windows 95",
INTERNET_OPEN_TYPE_PRECONFIG, // access type
NULL, // proxy server
0, // proxy port
0 // flags
);
CHECK_ERROR (hInternet, "InternetOpen");
// Connect to host.
hConnect = InternetConnect
(
hInternet, // wininet handle,
pszHost, // host
(INTERNET_PORT)dwPort, // port
pszUser, // user
NULL, // password
INTERNET_SERVICE_HTTP, // service
g_dwConnectFlags, // flags
0 // context
);
CHECK_ERROR (hConnect, "InternetConnect");
// Use SetOption to set the password since it handles empty strings.
if (pszPass)
{
InternetSetOption
(hConnect, INTERNET_OPTION_PASSWORD, pszPass, lstrlen(pszPass)+1);
}
if(!g_szVerb)
{
if (pszPostFile)
g_szVerb = "PUT";
else
g_szVerb = "GET";
}
// Create request.
hRequest = HttpOpenRequest
(
hConnect, // connect handle
g_szVerb, // pszPostFile? "PUT" : "GET", // request method
pszObject, // object name
NULL, // version
NULL, // referer
NULL, // accept types
g_dwConnectFlags // flags
| INTERNET_FLAG_KEEP_CONNECTION
| SECURITY_INTERNET_MASK, // ignore SSL warnings
0 // context
);
CHECK_ERROR (hRequest, "HttpOpenRequest");
resend:
// if (!pszPostFile || pPostData)
if (g_fMonolithicUpload)
{
// Send request.
fRet = HttpSendRequest
(
hRequest, // request handle
"", // header string
0, // header length
pPostData, // post data
cbPostData // post length
);
}
else
{
HANDLE hf = CreateFile
(
pszPostFile,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
NULL
);
if (hf != INVALID_HANDLE_VALUE)
{
cbPostData = GetFileSize (hf, NULL);
INTERNET_BUFFERS BufferIn;
BufferIn.dwStructSize = sizeof( INTERNET_BUFFERSA );
BufferIn.Next = NULL;
BufferIn.lpcszHeader = NULL;
BufferIn.dwHeadersLength = 0;
BufferIn.dwHeadersTotal = 0;
BufferIn.lpvBuffer = NULL;
BufferIn.dwBufferLength = 0;
BufferIn.dwBufferTotal = cbPostData;
BufferIn.dwOffsetLow = 0;
BufferIn.dwOffsetHigh = 0;
fRet = HttpSendRequestEx (hRequest, &BufferIn, NULL, 0, 0);
CHECK_ERROR (fRet, "HttpSendRequestEx");
while (1)
{
CHAR szTemp[512];
DWORD cbRead;
fRet = ReadFile (hf, szTemp, sizeof(szTemp), &cbRead, 0);
CHECK_ERROR (fRet, "ReadFile");
if (!fRet || !cbRead)
break;
DWORD cbRead2;
fRet = InternetWriteFile (hRequest, szTemp, cbRead, &cbRead2);
CHECK_ERROR (fRet, "InternetWriteFile");
}
CloseHandle (hf);
fRet = HttpEndRequest (hRequest, NULL, 0, 0);
if (!fRet && GetLastError() == ERROR_INTERNET_FORCE_RETRY)
goto resend;
}
}
DWORD dwStatus;
// Check if the status code is 401 or 407
if (NeedAuth (hRequest, &dwStatus) && (g_fAllowCustomUI))
{
// Prompt for username and password.
if (DoCustomUI (hRequest, dwStatus != HTTP_STATUS_DENIED))
goto resend;
}
else
{
DWORD dwSendErr = fRet? ERROR_SUCCESS : GetLastError();
DWORD dwDlgErr = InternetErrorDlg(
GetDesktopWindow(),
hRequest,
dwSendErr,
FLAGS_ERROR_UI_FILTER_FOR_ERRORS |
FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS |
FLAGS_ERROR_UI_FLAGS_GENERATE_DATA,
NULL
);
switch (dwSendErr)
{
case ERROR_SUCCESS:
case ERROR_INTERNET_NAME_NOT_RESOLVED:
case ERROR_INTERNET_CANNOT_CONNECT:
if (dwDlgErr == ERROR_INTERNET_FORCE_RETRY)
goto resend;
else
break;
case ERROR_HTTP_REDIRECT_NEEDS_CONFIRMATION:
default:
if (dwDlgErr == ERROR_SUCCESS)
goto resend;
else
break;
}
}
// Dump some bytes.
BYTE bBuf[1024];
DWORD cbBuf;
DWORD cbRead;
cbBuf = sizeof(bBuf);
_setmode( _fileno( stdout ), _O_BINARY );
while (InternetReadFile (hRequest, bBuf, cbBuf, &cbRead) && cbRead)
fwrite (bBuf, 1, cbRead, stdout);
done: // Clean up.
if (pszErr)
fprintf (stderr, "Failed on %s, last error %d\n", pszErr, GetLastError());
if (hRequest)
InternetCloseHandle (hRequest);
if (hConnect)
InternetCloseHandle (hConnect);
if (hInternet)
InternetCloseHandle (hInternet);
if (pPostData)
LocalFree (pPostData);
return 0;
}
//==============================================================================
void ParseArguments
(
LPSTR InBuffer,
LPSTR* CArgv,
DWORD* CArgc
)
{
LPSTR CurrentPtr = InBuffer;
DWORD i = 0;
DWORD Cnt = 0;
for ( ;; ) {
//
// skip blanks.
//
while( *CurrentPtr == ' ' ) {
CurrentPtr++;
}
if( *CurrentPtr == '\0' ) {
break;
}
CArgv[i++] = CurrentPtr;
//
// go to next space.
//
while( (*CurrentPtr != '\0') &&
(*CurrentPtr != '\n') ) {
if( *CurrentPtr == '"' ) { // Deal with simple quoted args
if( Cnt == 0 )
CArgv[i-1] = ++CurrentPtr; // Set arg to after quote
else
*CurrentPtr = '\0'; // Remove end quote
Cnt = !Cnt;
}
if( (Cnt == 0) && (*CurrentPtr == ' ') || // If we hit a space and no quotes yet we are done with this arg
(*CurrentPtr == '\0') )
break;
CurrentPtr++;
}
if( *CurrentPtr == '\0' ) {
break;
}
*CurrentPtr++ = '\0';
}
*CArgc = i;
return;
}
//==============================================================================
int __cdecl main (int argc, char **argv)
{
g_fAllowCustomUI = 0; //FALSE;
g_dwConnectFlags = 0;
HMODULE hmodShlwapi = NULL;
char * port ;
// Discard program arg.
argv++;
argc--;
// Parse options.
while (argc && argv[0][0] == '-')
{
switch (tolower(argv[0][1]))
{
case 'c':
g_fAllowCustomUI = TRUE;
break;
case 's':
g_dwConnectFlags = INTERNET_FLAG_SECURE;
break;
case 'p':
g_fPreload = TRUE;
break;
case 'v':
port = *argv;
port +=2;
fprintf(stderr,"Verb: %s\n", port);
if(port)
g_szVerb = port;
break;
case 'm':
g_fMonolithicUpload = TRUE;
break;
default:
fprintf (stderr, "\nUsage: httpauth [-c] [-s] <server> [<object> [<user> [<pass> [<POST-file>]]]]");
fprintf (stderr, "\n -c: Custom UI to prompt for user/pass");
fprintf (stderr, "\n -s: Secure connection (ssl or pct)");
fprintf (stderr, "\n -m: Monolithic upload");
fprintf (stderr, "\n -o<port#> : Port Number");
exit (1);
}
argv++;
argc--;
}
if (g_fPreload)
{
//Get the current directory in case the user selects -p to preload shlwapi from current dir
char buf[256];
GetCurrentDirectory((DWORD)256, buf);
strcat(buf,"\\shlwapi.dll");
fprintf(stderr, "\nPreloading shlwapi.dll from %s", buf);
if (!(hmodShlwapi=LoadLibrary(buf))) fprintf(stderr, "\nPreload of shlwapi.dll failed");
}
if (argc)
RequestLoop (argc, argv);
else // Enter command prompt loop
{
fprintf (stderr, "\nUsage: <server> [<object> [<user> [<pass> [<POST-file>]]]]");
fprintf (stderr, "\n quit - exit the command loop");
fprintf (stderr, "\n flush - flush pwd cache and authenticated sockets");
while (1)
{
char szIn[1024];
DWORD argcIn;
LPSTR argvIn[10];
fprintf (stderr, "\nhttpauth> ");
gets (szIn);
if (!lstrcmpi (szIn, "quit"))
break;
else if (!lstrcmpi (szIn, "flush"))
{
InternetSetOption
(NULL, INTERNET_OPTION_END_BROWSER_SESSION, NULL, 0);
continue;
}
argcIn = 0;
ParseArguments (szIn, argvIn, &argcIn);
if (!argcIn)
break;
RequestLoop (argcIn, argvIn);
}
}
//unload shlwapi if loaded
if (hmodShlwapi) FreeLibrary(hmodShlwapi);
}