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.
 
 
 
 
 
 

363 lines
9.2 KiB

//+-----------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) Microsoft Corporation
//
// File: kthttp.cxx
//
// Contents: Kerberos Tunneller, http communication routines
//
// History: 28-Jun-2001 t-ryanj Created
//
//------------------------------------------------------------------------
#include "ktdebug.h"
#include "kthttp.h"
#include "ktcontrol.h"
#include "ktkerb.h"
#if 0 /* Unneeded for now since http is running sync */
VOID CALLBACK KtHttpCallback(
IN HINTERNET hInternet,
IN DWORD_PTR dwContext,
IN DWORD dwInternetStatus,
IN LPVOID lpvStatusInformation,
IN DWORD dwStatusInformationLength
);
#endif
//#define KT_HTTP_AGENT_STRING TEXT("Kerbtunnel")
//#define KT_KERBPROXY_LOCATION TEXT("/kerberos-KDC/kerbproxy.dll")
TCHAR KT_HTTP_AGENT_STRING[] = TEXT("Kerbtunnel");
TCHAR KT_KERBPROXY_LOCATION[] = TEXT("/kerberos-KDC/kerbproxy.dll");
LPCTSTR KT_MIMETYPES_ACCEPTED[] = { TEXT("*/*"), NULL };
HINTERNET KtInternet = NULL;
//+-------------------------------------------------------------------------
//
// Function: KtInitHttp
//
// Synopsis: Performs necessary initialization for use of http
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns: Success value. If FALSE, GetLastError() for details.
//
// Notes:
//
//--------------------------------------------------------------------------
BOOL
KtInitHttp(
VOID
)
{
BOOL fSuccess = TRUE;
DsysAssert(KtInternet == NULL );
KtInternet = InternetOpen( KT_HTTP_AGENT_STRING,
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
0 );
if( KtInternet == NULL )
{
DebugLog( DEB_ERROR, "%s(%d): Error initializing internet routines: 0x%x.\n", __FILE__, __LINE__, GetLastError() );
goto Error;
}
Cleanup:
return fSuccess;
Error:
KtCleanupHttp();
fSuccess = FALSE;
goto Cleanup;
}
//+-------------------------------------------------------------------------
//
// Function: KtCleanupHttp
//
// Synopsis: Performs necessary cleanup after use of http
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//--------------------------------------------------------------------------
VOID
KtCleanupHttp(
VOID
)
{
if( KtInternet )
{
InternetCloseHandle(KtInternet);
KtInternet = NULL;
}
}
//+-------------------------------------------------------------------------
//
// Function: KtHttpWrite
//
// Synopsis: Opens a connection to the kerbproxy server, creates a POST
// request, and writes the contents of the context buffer as
// the request body.
//
// Effects:
//
// Arguments: pContext - A context.
//
// Requires:
//
// Returns: Success value. If FALSE, GetLastError() for details.
//
// Notes:
//
//--------------------------------------------------------------------------
BOOL
KtHttpWrite(
PKTCONTEXT pContext
)
{
HINTERNET hConnect = NULL;
HINTERNET hRequest = NULL;
BOOL SendSuccess;
BOOL IocpSuccess;
BOOL fRet = TRUE;
INTERNET_PORT InternetPort = INTERNET_DEFAULT_HTTP_PORT;
DebugLog( DEB_TRACE, "%s(%d): Sending %d bytes over http.\n", __FILE__, __LINE__, pContext->buffers->bytesused );
#if 0
//
// Use SSL for AS-REQUEST
//
if( KtIsAsRequest( pContext ) )
InternetPort = INTERNET_DEFAULT_HTTPS_PORT;
#endif
//
// TODO: Add logic so that it tries all the servers in the list.
//
//
// Open a connection to the kerbproxy server and store it in the context.
//
hConnect = InternetConnect( KtInternet,
(LPCWSTR)pContext->pbProxies,
InternetPort,
NULL,
NULL,
INTERNET_SERVICE_HTTP,
0,
INTERNET_FLAG_ASYNC );
if( !hConnect )
{
DebugLog( DEB_ERROR, "%s(%d): Error connecting to server: 0x%x.\n", __FILE__, __LINE__, GetLastError() );
goto Error;
}
pContext->hConnect = hConnect;
hConnect = NULL;
//
// Open a POST request to the kerbproxy object and store it in the context.
//
hRequest = HttpOpenRequest( pContext->hConnect,
TEXT("POST"),
KT_KERBPROXY_LOCATION,
NULL, /* version */
NULL, /* referrer */
KT_MIMETYPES_ACCEPTED,
0,
0 );
if( !hRequest )
{
DebugLog(DEB_ERROR, "%s(%d): Error opening %ws%ws: 0x%x.\n", __FILE__, __LINE__, pContext->pbProxies, KT_KERBPROXY_LOCATION, GetLastError() );
goto Error;
}
pContext->hRequest = hRequest;
hRequest = NULL;
//
// Send the results from reading off the user socket as the request body.
//
#if 0 /* unnecessary, as synchronous ops are being used now. */
InternetSetStatusCallback( hConnect,
KtHttpCallback );
#endif
pContext->Status = KT_HTTP_WRITE;
SendSuccess = HttpSendRequest( pContext->hRequest,
NULL,
0,
pContext->buffers->buffer,
pContext->buffers->bytesused );
if( !SendSuccess /*&& (GetLastError() != ERROR_IO_PENDING)*/ )
{
DebugLog(DEB_ERROR, "%s(%d): Error from sendrequest: 0x%x.\n", __FILE__, __LINE__, GetLastError() );
goto Error;
}
//
// Since this is being done synchronously right now, we need to post to
// the iocp in order to progress to the next step.
//
IocpSuccess = PostQueuedCompletionStatus( KtIocp,
0,
KTCK_CHECK_CONTEXT,
&(pContext->ol) );
if( !IocpSuccess )
{
DebugLog(DEB_ERROR, "%s(%d): Error posting to completion port: 0x%x.\n", __FILE__, __LINE__, GetLastError() );
goto Error;
}
Cleanup:
return fRet;
Error:
fRet = FALSE;
goto Cleanup;
}
//+-------------------------------------------------------------------------
//
// Function: KtHttpRead
//
// Synopsis: Reads the response to the request sent by KtHttpWrite into
// the context buffer.
//
// Effects:
//
// Arguments: pContext - A context.
//
// Requires:
//
// Returns: Success value. If FALSE, GetLastError() for details.
//
// Notes:
//
//--------------------------------------------------------------------------
BOOL
KtHttpRead(
PKTCONTEXT pContext
)
{
BOOL EndSuccess;
BOOL ReadSuccess;
BOOL fRet = TRUE;
BOOL IocpSuccess;
DebugLog( DEB_PEDANTIC, "%s(%d): Reading up to %d bytes from http.\n", __FILE__, __LINE__, pContext->emptybuf->buflen );
//
// Read the response from the kerbproxy server.
//
pContext->Status = KT_HTTP_READ;
ReadSuccess = InternetReadFile( pContext->hRequest,
pContext->emptybuf->buffer,
pContext->emptybuf->buflen,
&(pContext->emptybuf->bytesused) );
if( !ReadSuccess )
{
DebugLog(DEB_ERROR, "%s(%d): Error from readfile: 0x%x.\n", __FILE__, __LINE__, GetLastError() );
goto Error;
}
//
// Since we're doing this synchronously, we need to post to the iocp
// manually to move on.
//
IocpSuccess = PostQueuedCompletionStatus( KtIocp,
0,
KTCK_CHECK_CONTEXT,
&(pContext->ol) );
if( !IocpSuccess )
{
DebugLog( DEB_ERROR, "%s(%d): Error for PQCS: 0x%x\n", __FILE__, __LINE__, GetLastError() );
goto Error;
}
Cleanup:
return fRet;
Error:
fRet = FALSE;
goto Cleanup;
}
#if 0 /* Unneccessary because using synchronous calls for now */
//+-------------------------------------------------------------------------
//
// Function: KtHttpCallback
//
// Synopsis: Callback function for asynchronous http functions.
//
// Effects:
//
// Arguments: hInternet - connection appropriate to this callback
// pContext - context supplied at the time of the async call
// dwInternetStatus - why the callback was called
// lpvStatusInformation - more detailed info
// dwStatusInformationLength - length of *lpvStatusInformation
//
// Requires:
//
// Returns:
//
// Notes: Not being used right now, as synchronous wininet calls are
// being used, since it is not entirely clear how to do the
// asynchronous calls in all cases.
//
//--------------------------------------------------------------------------
VOID CALLBACK KtHttpCallback(
IN HINTERNET hInternet,
IN DWORD_PTR pContext,
IN DWORD dwInternetStatus,
IN LPVOID lpvStatusInformation,
IN DWORD dwStatusInformationLength
)
{
BOOL IocpSuccess;
if( dwInternetStatus == INTERNET_STATUS_REQUEST_COMPLETE )
{
IocpSuccess = PostQueuedCompletionStatus( KtIocp,
0,
KTCK_CHECK_CONTEXT,
&(((PKPCONTEXT)pContext)->ol) );
if( !IocpSuccess )
{
DebugLog( DEB_ERROR, "%s(%d): Error in PQCS: 0x%x.\n", __FILE__, __LINE__, GetLastError() );
KtReleaseContext( (PKTCONTEXT)pContext );
}
}
else
{
DebugLog( DEB_TRACE, "This httpcallback status: 0x%x.\n", dwInternetStatus );
}
}
#endif