Source code of Windows XP (NT5)
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.

1863 lines
53 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name :
  4. basereq.hxx
  5. Abstract:
  6. This file declares the class for http base request, that is used
  7. by the w3 information service.
  8. Author:
  9. Murali R. Krishnan ( MuraliK ) 16-Oct-1995
  10. Environment:
  11. Win32 -- User Mode
  12. Project:
  13. W3 Server DLL
  14. Revision History:
  15. Murali R. Krishnan (MuraliK) 22-Jan-1996
  16. make impersonation/revert function virtual
  17. --*/
  18. # ifndef _BASEREQ_HXX_
  19. # define _BASEREQ_HXX_
  20. /************************************************************
  21. * Include Headers
  22. ************************************************************/
  23. # include "string.hxx"
  24. # include "httphdr.hxx"
  25. # include "tssec.hxx"
  26. # include "w3type.hxx"
  27. # include "filter.hxx"
  28. # include "redirect.hxx"
  29. extern BOOL ReadEntireFile(
  30. CHAR *pszFileName,
  31. TSVC_CACHE &Cache,
  32. HANDLE User,
  33. BUFFER *pBuf,
  34. DWORD *pdwBytesRead
  35. );
  36. // Forward References
  37. class CLIENT_CONN;
  38. class HTTP_FILTER;
  39. class HTTP_FILTER_DLL;
  40. class W3_SERVER_INSTANCE;
  41. /************************************************************
  42. * Symbolic Constants
  43. ************************************************************/
  44. //
  45. // HTTP Server response status codes
  46. //
  47. #define HT_OK 200
  48. #define HT_CREATED 201
  49. //#define HT_ACCEPTED 202
  50. //#define HT_PARTIAL 203
  51. #define HT_NO_CONTENT 204
  52. #define HT_RANGE 206
  53. //#define HT_MULT_CHOICE 300
  54. #define HT_MOVED 301
  55. #define HT_REDIRECT 302
  56. #define HT_REDIRECT_METHOD 303
  57. #define HT_NOT_MODIFIED 304
  58. #define HT_BAD_REQUEST 400
  59. #define HT_DENIED 401
  60. //#define HT_PAYMENT_REQ 402
  61. #define HT_FORBIDDEN 403
  62. #define HT_NOT_FOUND 404
  63. #define HT_METHOD_NOT_ALLOWED 405
  64. #define HT_NONE_ACCEPTABLE 406
  65. #define HT_PROXY_AUTH_REQ 407
  66. //#define HT_REQUEST_TIMEOUT 408
  67. //#define HT_CONFLICT 409
  68. //#define HT_GONE 410
  69. #define HT_LENGTH_REQUIRED 411
  70. #define HT_PRECOND_FAILED 412
  71. #define HT_URL_TOO_LONG 414
  72. #define HT_RANGE_NOT_SATISFIABLE 416
  73. #define HT_SERVER_ERROR 500
  74. #define HT_NOT_SUPPORTED 501
  75. #define HT_BAD_GATEWAY 502
  76. #define HT_SVC_UNAVAILABLE 503
  77. #define HT_GATEWAY_TIMOUT 504
  78. //
  79. // Special invalid HTTP response code used to indicate a request should not
  80. // be logged
  81. //
  82. #define HT_DONT_LOG 000
  83. //
  84. // The versioning string for responses
  85. //
  86. #define HTTP_VERSION_STR PSZ_HTTP_VERSION_STR
  87. //
  88. // Flags for network communications over this request
  89. //
  90. #define IO_FLAG_ASYNC 0x00000010 // Call is async
  91. #define IO_FLAG_SYNC 0x00000020 // Call is synchronous
  92. #define IO_FLAG_SEND 0x00000040 // Call is a send
  93. #define IO_FLAG_RECV 0x00000080 // Call is a recv
  94. #define IO_FLAG_NO_FILTER 0x00000100 // Don't go through filters
  95. #define IO_FLAG_AND_RECV 0x00000400 // Add recv operation to IO
  96. #define IO_FLAG_NO_RECV 0x00000800 // Don't do auto-recv after TransmitFile
  97. #define IO_FLAG_NO_DELAY 0x00001000 // Disable Nagling on the socket
  98. // Flags for header generation
  99. #define HTTPH_SEND_GLOBAL_EXPIRE 0x00000001
  100. #define HTTPH_NO_DATE 0x00000002
  101. #define HTTPH_NO_CONNECTION 0x00000004
  102. #define HTTPH_NO_CUSTOM 0x00000008
  103. #define MIN_BUFFER_SIZE_FOR_HEADERS 384
  104. #define MAX_CUSTOM_ERROR_FILE_SIZE (48 * 1024)
  105. #define MD_AUTH_ALL (MD_AUTH_ANONYMOUS|MD_AUTH_BASIC|MD_AUTH_MD5|MD_AUTH_MAPBASIC)
  106. #define MAX_CERT_FIELD_SIZE 4096
  107. #define MAX_ALLOW_SIZE (sizeof("Allow: OPTIONS, TRACE, PUT, DELETE, HEAD, GET\r\n") - 1)
  108. #define MAX_URI_LENGTH 255
  109. //
  110. // Back trace configuration
  111. //
  112. #define MAX_BACKTRACE_FRAMES 10
  113. /************************************************************
  114. * Type Definitions
  115. ************************************************************/
  116. enum HTTP_VERB
  117. {
  118. HTV_GET = 0,
  119. HTV_HEAD,
  120. HTV_TRACE,
  121. HTV_PUT,
  122. HTV_DELETE,
  123. HTV_TRACECK,
  124. HTV_POST,
  125. HTV_OPTIONS,
  126. HTV_UNKNOWN
  127. };
  128. //
  129. // Class of a custom error entry.
  130. //
  131. class CUSTOM_ERROR_ENTRY
  132. {
  133. public:
  134. CUSTOM_ERROR_ENTRY( DWORD dwErr,
  135. DWORD dwSubError,
  136. BOOL bWildcard,
  137. CHAR *pszPath,
  138. BOOL bFileError
  139. )
  140. {
  141. m_dwErr = dwErr;
  142. m_dwSubError = dwSubError;
  143. m_bIsFileError = bFileError;
  144. m_bIsWildcard = bWildcard;
  145. if (bFileError)
  146. {
  147. m_pszNames.ErrorFileName = pszPath;
  148. }
  149. else
  150. {
  151. m_pszNames.ErrorURL = pszPath;
  152. }
  153. }
  154. ~CUSTOM_ERROR_ENTRY( VOID )
  155. {
  156. CHAR *pszTemp;
  157. if (m_bIsFileError)
  158. {
  159. pszTemp = m_pszNames.ErrorFileName;
  160. }
  161. else
  162. {
  163. pszTemp = m_pszNames.ErrorURL;
  164. }
  165. if (pszTemp != NULL)
  166. {
  167. TCP_FREE(pszTemp);
  168. }
  169. }
  170. BOOL IsFileError( VOID )
  171. { return m_bIsFileError; }
  172. CHAR *QueryErrorFileName( VOID )
  173. { return m_pszNames.ErrorFileName; }
  174. CHAR *QueryErrorURL( VOID )
  175. { return m_pszNames.ErrorURL; }
  176. DWORD QueryError( VOID )
  177. { return m_dwErr; }
  178. DWORD QuerySubError( VOID )
  179. { return m_dwSubError; }
  180. DWORD QueryWildcard( VOID )
  181. { return m_bIsWildcard; }
  182. LIST_ENTRY _ListEntry;
  183. private:
  184. BOOL m_bIsFileError;
  185. BOOL m_bIsWildcard;
  186. DWORD m_dwErr;
  187. DWORD m_dwSubError;
  188. union
  189. {
  190. CHAR *ErrorFileName;
  191. CHAR *ErrorURL;
  192. } m_pszNames;
  193. };
  194. typedef CUSTOM_ERROR_ENTRY *PCUSTOM_ERROR_ENTRY;
  195. //
  196. // The structure of the server's pre-digested meta data.
  197. //
  198. #define W3MD_CREATE_PROCESS_AS_USER 0x00000001
  199. #define W3MD_CREATE_PROCESS_NEW_CONSOLE 0x00000002
  200. #define EXPIRE_MODE_NONE 0
  201. #define EXPIRE_MODE_STATIC 1
  202. #define EXPIRE_MODE_DYNAMIC 2
  203. #define EXPIRE_MODE_OFF 3
  204. class W3_METADATA : public COMMON_METADATA {
  205. public:
  206. //
  207. // Hmmm, since most of these values aren't getting initialized, if
  208. // somebody went and deleted all the metadata items from the tree, then
  209. // bad things could happen. We should initialize with defaults things
  210. // that might mess us
  211. //
  212. W3_METADATA(VOID) :
  213. m_dwAuthentication ( MD_AUTH_ANONYMOUS ),
  214. m_dwAuthenticationPersistence( MD_AUTH_SINGLEREQUESTIFPROXY ),
  215. m_fAnyExtAllowedOnReadDir( FALSE ),
  216. m_pRBlob ( NULL ),
  217. m_dwFooterLength ( 0 ),
  218. m_pszFooter ( NULL ),
  219. m_bFooterEnabled ( TRUE ),
  220. m_bHaveNoCache ( FALSE ),
  221. m_bHaveMaxAge ( FALSE ),
  222. m_bSSIExecDisabled ( FALSE ),
  223. m_dwCGIScriptTimeout ( DEFAULT_SCRIPT_TIMEOUT ),
  224. m_csecPoolIDCTimeout ( 0 ),
  225. m_dwCreateProcessFlags( W3MD_CREATE_PROCESS_AS_USER ),
  226. m_fAllowKeepAlives ( TRUE ),
  227. m_fCacheISAPIApps ( TRUE ),
  228. m_fDoReverseDns ( FALSE ),
  229. m_dwExpireMaxLength ( 0 ),
  230. m_dwExpireMode ( EXPIRE_MODE_NONE ),
  231. m_pWildcardMapping ( NULL ),
  232. m_dwNotifyExAuth ( 0 ),
  233. m_pszCCPointer ( NULL ),
  234. m_dwUploadReadAhead (DEFAULT_W3_UPLOAD_READ_AHEAD),
  235. m_dwPutReadSize (8192),
  236. #if defined(CAL_ENABLED)
  237. m_dwCalHnd ( INVALID_CAL_EXEMPT_HANDLE ),
  238. #endif
  239. m_dwDirBrowseFlags ( MD_DIRBROW_LOADDEFAULT ),
  240. m_fJobCGIEnabled ( FALSE ),
  241. m_fIgnoreTranslate ( FALSE ),
  242. m_fUseDigestSSP ( FALSE ),
  243. m_dwMaxExtLen (0)
  244. {
  245. InitializeListHead( &m_ExtMapHead );
  246. InitializeListHead( &m_CustomErrorHead );
  247. memset( m_apszNTProviders, 0, sizeof(m_apszNTProviders) );
  248. if ( g_fIsWindows95 )
  249. {
  250. m_dwCreateProcessFlags &= ~W3MD_CREATE_PROCESS_AS_USER;
  251. }
  252. }
  253. ~W3_METADATA(VOID)
  254. {
  255. DWORD i = 0;
  256. DestroyCustomErrorTable();
  257. TerminateExtMap();
  258. if (m_pRBlob != NULL )
  259. {
  260. delete m_pRBlob;
  261. m_pRBlob = NULL;
  262. }
  263. while ( m_apszNTProviders[i] )
  264. {
  265. TCP_FREE( m_apszNTProviders[i++] );
  266. }
  267. #if defined(CAL_ENABLED)
  268. if ( m_dwCalHnd != INVALID_CAL_EXEMPT_HANDLE )
  269. {
  270. CalExemptRelease( m_dwCalHnd );
  271. }
  272. #endif
  273. }
  274. BOOL HandlePrivateProperty(
  275. LPSTR pszURL,
  276. PIIS_SERVER_INSTANCE pInstance,
  277. METADATA_GETALL_INTERNAL_RECORD *pMDRecord,
  278. LPVOID pDataPointer,
  279. BUFFER *pBuffer,
  280. DWORD *pdwBytesUsed,
  281. PMETADATA_ERROR_INFO pMDErrorInfo
  282. );
  283. BOOL FinishPrivateProperties(
  284. BUFFER *pBuffer,
  285. DWORD dwBytesUsed,
  286. BOOL bSucceeded
  287. );
  288. //
  289. // Query Methods
  290. //
  291. STR * QueryDefaultDocs( VOID )
  292. { return &m_strDefaultDocs; }
  293. STR * QueryHeaders( VOID )
  294. { return &m_strHeaders; }
  295. BUFFER * QueryMimeMap( VOID )
  296. { return &m_bufMimeMap; }
  297. DWORD QueryAuthentication( VOID ) const
  298. { return m_dwAuthentication; }
  299. DWORD QueryAuthenticationPersistence( VOID ) const
  300. { return m_dwAuthenticationPersistence; }
  301. DWORD QueryScriptTimeout( VOID ) const
  302. { return m_dwCGIScriptTimeout; }
  303. DWORD QueryDirBrowseFlags( VOID ) const
  304. { return m_dwDirBrowseFlags; }
  305. BOOL LookupExtMap(
  306. IN const CHAR * pchExt,
  307. IN BOOL fNoWildcards,
  308. OUT STR * pstrGatewayImage,
  309. OUT GATEWAY_TYPE * pGatewayType,
  310. OUT DWORD * pcchExt,
  311. OUT BOOL * pfImageInURL,
  312. OUT BOOL * pfVerbExcluded,
  313. OUT DWORD * pdwFlags,
  314. IN const CHAR *pszVerb,
  315. IN enum HTTP_VERB Verb,
  316. IN OUT PVOID * ppvExtMapInfo
  317. );
  318. PTCP_AUTHENT_INFO QueryAuthentInfo(VOID) const
  319. { return (const PTCP_AUTHENT_INFO) &m_TCPAuthentInfo; }
  320. BOOL
  321. BuildProviderList(
  322. CHAR *pszProviders
  323. );
  324. BOOL
  325. CheckSSPPackage(
  326. IN LPCSTR pszAuthString
  327. );
  328. PCHAR QueryRealm(VOID) const
  329. { return (m_strRealm.IsEmpty() ? NULL : m_strRealm.QueryStr()); }
  330. DWORD QueryCreateProcessAsUser(VOID) const
  331. { return (m_dwCreateProcessFlags & W3MD_CREATE_PROCESS_AS_USER); }
  332. DWORD QueryCreateProcessNewConsole(VOID) const
  333. { return (m_dwCreateProcessFlags & W3MD_CREATE_PROCESS_NEW_CONSOLE); }
  334. BOOL QueryAnyExtAllowedOnReadDir() const
  335. { return m_fAnyExtAllowedOnReadDir; }
  336. PREDIRECTION_BLOB QueryRedirectionBlob(VOID) const
  337. { return m_pRBlob; }
  338. dllexp
  339. PCUSTOM_ERROR_ENTRY LookupCustomError( DWORD dwErr, DWORD dwSubError )
  340. {
  341. LIST_ENTRY *pEntry;
  342. PCUSTOM_ERROR_ENTRY pCustomErrorItem;
  343. PCUSTOM_ERROR_ENTRY pCustomErrorWildcard = NULL;
  344. for ( pEntry = m_CustomErrorHead.Flink;
  345. pEntry != &m_CustomErrorHead;
  346. pEntry = pEntry->Flink )
  347. {
  348. pCustomErrorItem = CONTAINING_RECORD( pEntry,
  349. CUSTOM_ERROR_ENTRY,
  350. _ListEntry );
  351. if ( pCustomErrorItem->QueryError() == dwErr )
  352. {
  353. if ( pCustomErrorItem->QuerySubError() == dwSubError )
  354. {
  355. return pCustomErrorItem;
  356. }
  357. else if ( pCustomErrorItem->QueryWildcard() )
  358. {
  359. pCustomErrorWildcard = pCustomErrorItem;
  360. }
  361. }
  362. }
  363. return pCustomErrorWildcard;
  364. }
  365. DWORD QueryFooterLength(VOID) const
  366. { return m_dwFooterLength; }
  367. CHAR *QueryFooter(VOID) const
  368. { return m_pszFooter; }
  369. BOOL FooterEnabled(VOID) const
  370. { return m_bFooterEnabled; }
  371. BOOL SSIExecDisabled(VOID) const
  372. { return m_bSSIExecDisabled; }
  373. DWORD QueryPoolIDCTimeout( VOID ) const
  374. { return m_csecPoolIDCTimeout; }
  375. const LPSTR * QueryNTProviders( VOID ) const
  376. { return m_apszNTProviders; }
  377. BOOL QueryKeepAlives( VOID ) const
  378. { return m_fAllowKeepAlives; }
  379. BOOL QueryCacheISAPIApps( VOID ) const
  380. { return m_fCacheISAPIApps; }
  381. BOOL QueryDoReverseDns(VOID) const
  382. { return m_fDoReverseDns; }
  383. DWORD QueryExpireMaxLength(VOID) const
  384. { return m_dwExpireMaxLength;}
  385. DWORD QueryExpireDelta(VOID) const
  386. { return m_dwExpireDelta;}
  387. DWORD QueryExpireMode(VOID) const
  388. { return m_dwExpireMode;}
  389. LPSTR QueryExpireHeader(VOID) const
  390. { return m_strExpireHeader.QueryStr();}
  391. DWORD QueryExpireHeaderLength(VOID) const
  392. { return m_strExpireHeader.QueryCCH();}
  393. LARGE_INTEGER QueryExpireTime(VOID) const
  394. { return m_liExpireTime;}
  395. PVOID QueryWildcardMapping(VOID) const
  396. { return m_pWildcardMapping; }
  397. DWORD QueryNotifyExAuth(VOID) const
  398. { return m_dwNotifyExAuth; }
  399. BOOL QueryConfigNoCache(VOID) const
  400. { return m_bHaveNoCache; }
  401. BOOL QueryHaveMaxAge(VOID) const
  402. { return m_bHaveMaxAge; }
  403. LPSTR QueryCacheControlHeader(VOID) const
  404. { return m_strCacheControlHeader.QueryStr(); }
  405. DWORD QueryCacheControlHeaderLength(VOID) const
  406. { return m_strCacheControlHeader.QueryCB(); }
  407. STR * QueryRedirectHeaders( VOID )
  408. { return &m_strRedirectHeaders; }
  409. DWORD QueryUploadReadAhead(VOID) const
  410. { return m_dwUploadReadAhead; }
  411. DWORD QueryPutReadSize(VOID) const
  412. { return m_dwPutReadSize; }
  413. BOOL QueryJobCGIEnabled()
  414. { return m_fJobCGIEnabled; }
  415. BOOL QueryIgnoreTranslate() const
  416. { return m_fIgnoreTranslate; }
  417. BOOL QueryUseDigestSSP() const
  418. { return m_fUseDigestSSP; }
  419. //
  420. // Set Methods
  421. //
  422. BOOL SetAnonUserName(PCHAR AnonUserName)
  423. { return m_TCPAuthentInfo.strAnonUserName.Copy( AnonUserName ); }
  424. BOOL SetAnonUserPassword(PCHAR AnonUserPassword)
  425. { return m_TCPAuthentInfo.strAnonUserPassword.Copy( AnonUserPassword ); }
  426. BOOL SetDefaultLogonDomain(PCHAR DefLogonDom)
  427. { return m_TCPAuthentInfo.strDefaultLogonDomain.Copy( DefLogonDom ); }
  428. VOID SetLogonMethod(DWORD dwLogonMethod)
  429. { m_TCPAuthentInfo.dwLogonMethod = dwLogonMethod; }
  430. VOID SetUseAnonSubAuth( BOOL fUseAnonSubAuth )
  431. { m_TCPAuthentInfo.fDontUseAnonSubAuth = !fUseAnonSubAuth; }
  432. VOID SetAuthentication( DWORD dwFlags )
  433. {
  434. if (g_fIsWindows95)
  435. {
  436. dwFlags &= INET_INFO_AUTH_W95_MASK;
  437. }
  438. m_dwAuthentication = dwFlags;
  439. }
  440. VOID SetAuthenticationPersistence( DWORD dwFlags )
  441. {
  442. m_dwAuthenticationPersistence = dwFlags;
  443. }
  444. VOID SetCGIScriptTimeout( DWORD dwScriptTimeout )
  445. { m_dwCGIScriptTimeout = dwScriptTimeout; }
  446. VOID SetDirBrowseFlags( DWORD dwDirBrowseFlags )
  447. { m_dwDirBrowseFlags = dwDirBrowseFlags; }
  448. BOOL BuildExtMap(CHAR *pszExtMapString);
  449. BOOL SetRealm(PCHAR pszRealm)
  450. { return m_strRealm.Copy( pszRealm ); }
  451. VOID SetCreateProcessAsUser(BOOL fValue)
  452. {
  453. if ( fValue )
  454. {
  455. if ( !g_fIsWindows95 ) {
  456. m_dwCreateProcessFlags |= W3MD_CREATE_PROCESS_AS_USER;
  457. }
  458. }
  459. else
  460. {
  461. m_dwCreateProcessFlags &= ~W3MD_CREATE_PROCESS_AS_USER;
  462. }
  463. }
  464. VOID SetCreateProcessNewConsole(BOOL fValue)
  465. {
  466. if ( fValue )
  467. {
  468. m_dwCreateProcessFlags |= W3MD_CREATE_PROCESS_NEW_CONSOLE;
  469. }
  470. else
  471. {
  472. m_dwCreateProcessFlags &= ~W3MD_CREATE_PROCESS_NEW_CONSOLE;
  473. }
  474. }
  475. BOOL SetRedirectionBlob( STR & strSource,
  476. STR & strDestination )
  477. {
  478. //
  479. // If the redirection is nullified, don't allocate a blob
  480. // and just return success.
  481. //
  482. if ( *( strDestination.QueryStr() ) == '!' )
  483. {
  484. return TRUE;
  485. }
  486. m_pRBlob = new REDIRECTION_BLOB( strSource, strDestination );
  487. if (m_pRBlob == NULL)
  488. {
  489. return FALSE;
  490. }
  491. return m_pRBlob->IsValid();
  492. }
  493. BOOL BuildCustomErrorTable( CHAR *pszErrorList,
  494. PMETADATA_ERROR_INFO pMDErrorInfo
  495. );
  496. VOID DestroyCustomErrorTable( VOID );
  497. BOOL ReadCustomFooter( CHAR *pszFooterString,
  498. TSVC_CACHE &Cache,
  499. HANDLE User,
  500. PMETADATA_ERROR_INFO pMDErrorInfo
  501. );
  502. VOID SetFooter(DWORD dwLength, CHAR *pszFooter)
  503. { m_dwFooterLength = dwLength; m_pszFooter = pszFooter; }
  504. VOID SetFooterEnabled(BOOL bEnabled)
  505. { m_bFooterEnabled = bEnabled; }
  506. VOID SetSSIExecDisabled( BOOL bDisabled )
  507. { m_bSSIExecDisabled = bDisabled; }
  508. VOID SetPoolIDCTimeout( DWORD csecPoolIDCTimeout )
  509. { m_csecPoolIDCTimeout = csecPoolIDCTimeout; }
  510. VOID SetAllowKeepAlives( BOOL fAllowKeepAlives )
  511. { m_fAllowKeepAlives = fAllowKeepAlives; }
  512. VOID SetCacheISAPIApps( BOOL fCacheISAPIApps )
  513. { m_fCacheISAPIApps = fCacheISAPIApps; }
  514. BOOL SetExpire( CHAR* pszExpire,
  515. PMETADATA_ERROR_INFO pMDErrorInfo
  516. );
  517. VOID SetWildcardMapping(PVOID pMapping)
  518. { m_pWildcardMapping = pMapping; }
  519. VOID SetConfigNoCache(VOID)
  520. { m_bHaveNoCache = TRUE; }
  521. VOID SetHaveMaxAge(VOID)
  522. { m_bHaveMaxAge = TRUE; }
  523. VOID ClearConfigNoCache(VOID)
  524. { m_bHaveNoCache = FALSE; }
  525. VOID ClearHaveMaxAge(VOID)
  526. { m_bHaveMaxAge = FALSE; }
  527. BOOL
  528. SetCCHeader( BOOL bNoCache,
  529. BOOL bMaxAge,
  530. DWORD dwMaxAge
  531. );
  532. VOID SetUploadReadAhead(DWORD dwUploadSize)
  533. { m_dwUploadReadAhead = dwUploadSize; }
  534. VOID SetPutReadSize(DWORD dwSize)
  535. { m_dwPutReadSize = dwSize; }
  536. //
  537. // Disable job objects on IIS5.1, original code would read the
  538. // property from metabase
  539. //
  540. VOID SetJobCGIEnabled( BOOL f ) { m_fJobCGIEnabled = FALSE; }
  541. VOID SetIgnoreTranslate( BOOL f ) { m_fIgnoreTranslate = f; }
  542. VOID SetUseDigestSSP( BOOL f ) { m_fUseDigestSSP = f; }
  543. private:
  544. VOID TerminateExtMap( VOID );
  545. TCP_AUTHENT_INFO m_TCPAuthentInfo;
  546. STR m_strDefaultDocs;
  547. STR m_strHeaders;
  548. BUFFER m_bufMimeMap;
  549. STR m_strRealm;
  550. DWORD m_dwAuthentication;
  551. DWORD m_dwAuthenticationPersistence;
  552. DWORD m_dwCGIScriptTimeout;
  553. DWORD m_dwDirBrowseFlags;
  554. DWORD m_dwCreateProcessFlags;
  555. LIST_ENTRY m_ExtMapHead;
  556. LIST_ENTRY m_CustomErrorHead;
  557. PREDIRECTION_BLOB m_pRBlob;
  558. DWORD m_dwFooterLength;
  559. CHAR *m_pszFooter;
  560. BUFFER m_bufFooter;
  561. BOOL m_fAnyExtAllowedOnReadDir:1;
  562. BOOL m_bFooterEnabled:1;
  563. BOOL m_bHaveNoCache:1;
  564. BOOL m_bHaveMaxAge:1;
  565. BOOL m_bSSIExecDisabled:1;
  566. BOOL m_fAllowKeepAlives:1;
  567. BOOL m_fCacheISAPIApps:1;
  568. BOOL m_fDoReverseDns:1;
  569. DWORD m_csecPoolIDCTimeout;
  570. LPSTR m_apszNTProviders[MAX_SSPI_PROVIDERS];
  571. STR m_strExpireHeader;
  572. STR m_strCacheControlHeader;
  573. DWORD m_dwExpireMaxLength;
  574. DWORD m_dwExpireMode;
  575. DWORD m_dwExpireDelta;
  576. LARGE_INTEGER m_liExpireTime;
  577. PVOID m_pWildcardMapping;
  578. DWORD m_dwNotifyExAuth;
  579. LPSTR m_pszCCPointer;
  580. STR m_strRedirectHeaders;
  581. DWORD m_dwUploadReadAhead;
  582. DWORD m_dwPutReadSize;
  583. BOOL m_fJobCGIEnabled;
  584. #if defined(CAL_ENABLED)
  585. DWORD m_dwCalHnd;
  586. #endif
  587. DWORD m_dwMaxExtLen;
  588. BOOL m_fIgnoreTranslate;
  589. BOOL m_fUseDigestSSP;
  590. };
  591. typedef W3_METADATA *PW3_METADATA;
  592. typedef struct _W3_METADATA_INFO
  593. {
  594. DWORD dwMaxAge;
  595. } W3_METADATA_INFO, *PW3_METADATA_INFO;
  596. //
  597. // Various states the HTTP Request goes through
  598. //
  599. enum HTR_STATE
  600. {
  601. //
  602. // We're still gathering the client request header
  603. //
  604. HTR_READING_CLIENT_REQUEST = 0,
  605. //
  606. // The client is supplying some gateway data, deal with it
  607. //
  608. HTR_READING_GATEWAY_DATA,
  609. //
  610. // We need to take apart the client request and figure out what they
  611. // want
  612. //
  613. HTR_PARSE,
  614. //
  615. // We're executing the verb or handing the request off to a gateway
  616. //
  617. HTR_DOVERB,
  618. //
  619. // The ISAPI application has submitted async IO operation
  620. //
  621. HTR_GATEWAY_ASYNC_IO,
  622. //
  623. // The client requested a file so send them the file
  624. //
  625. HTR_SEND_FILE,
  626. //
  627. // The proxy server is forwarding the request on to the remote server
  628. //
  629. HTR_PROXY_SENDING_REQUEST,
  630. //
  631. // The proxy server is waiting for a response from the remote server
  632. //
  633. HTR_PROXY_READING_RESPONSE,
  634. //
  635. // We're processing a CGI request so we need to ignore any IO
  636. // completions that may occur as the CGIThread forwards the
  637. // program's output
  638. //
  639. HTR_CGI,
  640. //
  641. // Processing a range request
  642. //
  643. HTR_RANGE,
  644. //
  645. // resume processing with clear text logon
  646. //
  647. HTR_RESTART_REQUEST,
  648. //
  649. // We're in the process of writing data from a client PUT request to
  650. // disk
  651. //
  652. HTR_WRITING_FILE,
  653. //
  654. // We're renegotiating a certificate with the client
  655. //
  656. HTR_CERT_RENEGOTIATE,
  657. //
  658. // We're reading the entity body before doing redirect
  659. //
  660. HTR_REDIRECT,
  661. //
  662. // We're reading the entity body before sending access denial
  663. //
  664. HTR_ACCESS_DENIED,
  665. //
  666. // We've completely handled the client's request
  667. //
  668. HTR_DONE
  669. };
  670. enum CHUNK_STATE
  671. {
  672. READ_CHUNK_SIZE = 0,
  673. READ_CHUNK_PARAMS,
  674. READ_CHUNK,
  675. READ_CHUNK_FOOTER,
  676. READ_CHUNK_CRLF,
  677. READ_CHUNK_DONE
  678. };
  679. #if 0 // This routine is no longer used /SAB
  680. #define IS_WRITE_VERB(__verb__) ( (__verb__) == HTV_PUT || \
  681. (__verb__) == HTV_DELETE)
  682. #endif 0
  683. #define CHUNK_READ_SIZE 80 // Important to keep this small, to
  684. // avoid getting two chunks into the
  685. // same buffer in one read.
  686. #define CRLF_SIZE 2
  687. #define SSLNEGO_MAP 0x00000001
  688. /*******************************************************************
  689. CLASS: HTTP_REQ_BASE
  690. SYNOPSIS: Basic HTTP request object
  691. HISTORY:
  692. Johnl 24-Aug-1994 Created
  693. ********************************************************************/
  694. class HTTP_REQ_BASE
  695. {
  696. public:
  697. //
  698. // Constructor/Destructor
  699. //
  700. HTTP_REQ_BASE( CLIENT_CONN * pClientConn,
  701. PVOID pvInitialBuff,
  702. DWORD cbInitialBuff );
  703. virtual ~HTTP_REQ_BASE( VOID );
  704. //
  705. // This is the work entry point that is driven by the completion of the
  706. // async IO.
  707. //
  708. virtual BOOL DoWork( BOOL * pfFinished ) = 0;
  709. //
  710. // Parses the client's HTTP request
  711. //
  712. virtual BOOL Parse( const CHAR* pchRequest,
  713. DWORD cbData,
  714. DWORD * pcbExtraData,
  715. BOOL * pfHandled,
  716. BOOL * pfFinished ) = 0;
  717. // Following function can be overridden by individual derived object.
  718. virtual dllexp BOOL GetInfo( const TCHAR * pszValName,
  719. STR * pstr,
  720. BOOL * pfFound = NULL )
  721. { if ( pfFound )
  722. {
  723. *pfFound = FALSE;
  724. }
  725. return (TRUE);
  726. }
  727. //
  728. // Kicks off the read for a client request header
  729. //
  730. BOOL StartNewRequest( PVOID pvInitialBuff,
  731. DWORD cbInitialBuff,
  732. BOOL fFirst,
  733. BOOL *pfDoAgain);
  734. BOOL OnFillClientReq( BOOL * pfCompleteRequest,
  735. BOOL * pfFinished,
  736. BOOL * pfHandled );
  737. BOOL OnCompleteRequest( TCHAR * pchRequest,
  738. DWORD cbData,
  739. BOOL * pfFinished,
  740. BOOL * pfHandled );
  741. BOOL OnRestartRequest( TCHAR * pchRequest,
  742. DWORD cbData,
  743. BOOL * pfFinished,
  744. BOOL * pfHandled);
  745. BOOL HandleCertRenegotiation( BOOL * pfFinished,
  746. BOOL * pfHandled,
  747. DWORD cbData );
  748. BOOL DenyAccess( BOOL * pfFinished,
  749. BOOL * pfDisconnected );
  750. BOOL VrootAccessCheck( PW3_METADATA pMetaData,
  751. DWORD dwDesiredAccess );
  752. BOOL DoChange( LPBOOL );
  753. BOOL UnWrapRequest( BOOL * pfCompleteRequest,
  754. BOOL * pfFinished,
  755. BOOL * pfHandled );
  756. //
  757. // Attempts to logon with the user information gleaned from the Parse
  758. // we just did
  759. //
  760. BOOL LogonUser( BOOL * pfFinished );
  761. BOOL LogonAsSystem( VOID );
  762. //
  763. // Common header parsing functions.
  764. //
  765. BOOL OnContentLength ( CHAR * pszValue );
  766. BOOL OnIfModifiedSince( CHAR * pszValue );
  767. BOOL OnIfUnmodifiedSince( CHAR * pszValue );
  768. BOOL OnIfMatch( CHAR * pszValue );
  769. BOOL OnIfNoneMatch( CHAR * pszValue );
  770. BOOL OnIfRange( CHAR * pszValue );
  771. BOOL OnUnlessModifiedSince( CHAR * pszValue );
  772. BOOL ProcessAuthorization ( CHAR * pszValue );
  773. BOOL OnProxyAuthorization ( CHAR * pszValue );
  774. BOOL OnHost ( CHAR * pszValue );
  775. BOOL OnRange ( CHAR * pszValue );
  776. //BOOL OnAuthorization ( CHAR * pszValue );
  777. BOOL ParseAuthorization( CHAR * pszValue );
  778. //
  779. // Builds and optionally sends an HTTP server response back to the client
  780. //
  781. static BOOL BuildStatusLine( BUFFER * pstrResp,
  782. DWORD dwHTTPError,
  783. DWORD dwError2,
  784. LPSTR pszError2 = NULL,
  785. STR *pstrErrorStr = NULL
  786. );
  787. //
  788. // Builds a complete HTTP reply with extended explanation text
  789. //
  790. static BOOL BuildExtendedStatus(
  791. STR * pstrResp,
  792. DWORD dwHTTPError,
  793. DWORD dwError2 = NO_ERROR,
  794. DWORD dwExplanation = 0,
  795. LPSTR pszError2 = NULL
  796. );
  797. //
  798. // Sets the http status code and win32 error that should be used for
  799. // this request when it gets written to the logfile
  800. //
  801. VOID SetLogStatus( DWORD LogHttpResponse, DWORD LogWinError )
  802. {
  803. _dwLogHttpResponse = LogHttpResponse;
  804. _dwLogWinError = LogWinError;
  805. }
  806. DWORD QueryLogHttpResponse( VOID ) const
  807. { return _dwLogHttpResponse; }
  808. DWORD QueryLogWinError( VOID ) const
  809. { return _dwLogWinError; }
  810. //
  811. // Builds a server header for responding back to the client
  812. //
  813. BOOL BuildBaseResponseHeader(
  814. BUFFER * pbufResponse,
  815. BOOL * pfFinished,
  816. STR * pstrStatus = NULL, // Full status string
  817. DWORD dwOptions = 0 );
  818. BOOL BuildHttpHeader( OUT BOOL * pfFinished,
  819. IN CHAR * pchStatus = NULL,
  820. IN CHAR * pchAdditionalHeaders = NULL,
  821. IN DWORD dwOptions = 0);
  822. dllexp
  823. BOOL SendHeader( IN CHAR * pchStatus OPTIONAL,
  824. IN CHAR * pchAdditionalHeaders OPTIONAL,
  825. IN DWORD IOFlags,
  826. OUT BOOL * pfFinished,
  827. IN DWORD dwOptions = 0,
  828. IN BOOL fWriteHeader = TRUE );
  829. BOOL SendHeader( IN CHAR * pchHeaders,
  830. IN DWORD cbHeaders,
  831. IN DWORD IOFlags,
  832. OUT BOOL * pfFinished );
  833. //
  834. // Builds a 301 or 302 URL Moved message
  835. //
  836. dllexp
  837. BOOL BuildURLMovedResponse( BUFFER * pbufResp,
  838. STR * pstrURL,
  839. DWORD dwServerCode,
  840. BOOL fIncludeParams = FALSE );
  841. dllexp
  842. BOOL WriteLogRecord( VOID );
  843. BOOL AppendLogParameter( CHAR * pszParam );
  844. //
  845. // Sends an access denied message with the forms of authorization
  846. // we support
  847. //
  848. BOOL SendAuthNeededResp( BOOL * pfFinished );
  849. BOOL SetUserNameAndPassword( TCHAR * pszUserName, TCHAR * pszPassword )
  850. { return _strUserName.Copy( pszUserName ) && _strPassword.Copy( pszPassword ); }
  851. STR * QueryDenialHeaders( VOID )
  852. { return &_strDenialHdrs; }
  853. STR * QueryAdditionalRespHeaders( VOID )
  854. { return &_strRespHdrs; }
  855. DWORD QueryAuthentication( VOID ) const
  856. { return _pMetaData->QueryAuthentication(); }
  857. DWORD QueryNotifyExAuth( VOID ) const
  858. { return _pMetaData->QueryNotifyExAuth(); }
  859. DWORD QueryDirBrowseFlags( VOID ) const
  860. { return _pMetaData->QueryDirBrowseFlags(); }
  861. BOOL IsIpDnsAccessCheckPresent( VOID ) const
  862. { return _pMetaData->IsIpDnsAccessCheckPresent(); }
  863. PW3_METADATA QueryMetaData( VOID ) const
  864. { return _pMetaData; }
  865. //
  866. // Retrieves various bits of request information
  867. //
  868. enum HTR_STATE QueryState( VOID ) const
  869. { return _htrState; }
  870. BOOL IsKeepConnSet( VOID ) const
  871. { return _fKeepConn; }
  872. BOOL IsProcessByteRange( VOID ) const
  873. { return _fProcessByteRange; }
  874. BOOL IsAuthenticationRequested( VOID ) const
  875. { return _fAuthenticationRequested; }
  876. BOOL IsAuthenticated( VOID ) const
  877. { return !_strUserName.IsEmpty(); }
  878. DWORD IsChunked( VOID ) const
  879. { return _fChunked; }
  880. VOID SetChunked( VOID )
  881. { _fChunked = TRUE; }
  882. VOID ClearChunked( VOID )
  883. { _fChunked = FALSE; }
  884. VOID SetKeepConn( BOOL fKeepConn )
  885. { _fKeepConn = fKeepConn; }
  886. VOID SetAuthenticationRequested( BOOL fAuthenticationRequested )
  887. { _fAuthenticationRequested = fAuthenticationRequested; }
  888. BOOL IsLoggedOn( VOID ) const
  889. { return _fLoggedOn; }
  890. BOOL IsClearTextPassword( VOID ) const
  891. { return _fClearTextPass; };
  892. BOOL IsNTLMImpersonation( VOID ) const
  893. { return !_fClearTextPass && !_fAnonymous && !UseVrAccessToken(); }
  894. BOOL IsSecurePort( VOID ) const
  895. { return _fSecurePort; }
  896. BOOL IsProxyRequest( VOID ) const
  897. { return _fProxyRequest; }
  898. VOID SetProxyRequest( BOOL fIsProxyRequest )
  899. { _fProxyRequest = fIsProxyRequest; }
  900. BOOL IsClientProxy( VOID );
  901. CLIENT_CONN * QueryClientConn( VOID ) const
  902. { return _pClientConn; }
  903. W3_SERVER_INSTANCE * QueryW3Instance( VOID ) const
  904. { return _pW3Instance; }
  905. W3_SERVER_INSTANCE * QueryW3InstanceAggressively( VOID ) const;
  906. VOID SetW3Instance( IN W3_SERVER_INSTANCE* pInstance )
  907. { DBG_ASSERT(_pW3Instance == NULL); _pW3Instance = pInstance; }
  908. W3_SERVER_STATISTICS * QueryW3StatsObj( VOID ) const
  909. { return _pW3Stats; }
  910. VOID SetW3StatsObj( IN LPW3_SERVER_STATISTICS pW3Stats )
  911. { _pW3Stats = pW3Stats; }
  912. BOOL IsPointNine( VOID ) const
  913. { return (_VersionMajor < 1); }
  914. BOOL IsAtLeastOneOne( VOID ) const
  915. { return ((_VersionMajor == 1 && _VersionMinor >= 1) ||
  916. (_VersionMajor >= 2)); }
  917. BOOL IsOneOne( VOID ) const
  918. { return ((_VersionMajor == 1) && (_VersionMinor == 1)); }
  919. BOOL IsAuthenticating( VOID ) const
  920. { return _fAuthenticating; }
  921. DWORD QueryClientContentLength( VOID ) const
  922. { return _cbContentLength; }
  923. DWORD QueryTotalRequestLength( VOID ) const
  924. { return _cbContentLength + _cbClientRequest; }
  925. BYTE * QueryClientRequest( VOID ) const
  926. { return (BYTE *) _bufClientRequest.QueryPtr(); }
  927. BUFFER * QueryClientReqBuff( VOID )
  928. { return &_bufClientRequest; }
  929. CHAR * QueryURL( VOID ) const
  930. { return _strURL.QueryStr(); }
  931. CHAR * QueryURLParams( VOID ) const
  932. { return _strURLParams.QueryStr(); }
  933. HTTP_HEADERS * QueryHeaderList( VOID )
  934. { return &_HeaderList; }
  935. BUFFER * QueryRespBuf( VOID )
  936. { return &_bufServerResp; }
  937. CHAR * QueryRespBufPtr( VOID )
  938. { return (CHAR *) _bufServerResp.QueryPtr(); }
  939. DWORD QueryRespBufCB( VOID )
  940. { return strlen( (CHAR *)_bufServerResp.QueryPtr()); }
  941. VOID SetDeniedFlags( DWORD dwDeniedFlags )
  942. { _Filter.SetDeniedFlags( dwDeniedFlags ); }
  943. CHAR * QueryHostAddr( VOID );
  944. //
  945. // If the client supplied additional data in their request, we store
  946. // the byte count and data here.
  947. //
  948. DWORD QueryEntityBodyCB( VOID ) const
  949. { return _cbEntityBody; }
  950. DWORD QueryTotalEntityBodyCB( VOID ) const
  951. { return _cbTotalEntityBody; }
  952. VOID AddTotalEntityBodyCB( DWORD cbAdditionalEntityBody )
  953. { _cbTotalEntityBody += cbAdditionalEntityBody; }
  954. BYTE * QueryEntityBody( VOID ) const
  955. { return (BYTE *) _bufClientRequest.QueryPtr() + _cbClientRequest; }
  956. BOOL ReadMoreEntityBody(DWORD cbOffset,
  957. DWORD cbSize);
  958. BOOL ReadEntityBody( BOOL *pfDone,
  959. BOOL fFirstRead = FALSE,
  960. DWORD dwMaxAmountToRead = 0,
  961. BOOL *pfDisconnected = NULL );
  962. BOOL DecodeChunkedBytes( LPBYTE lpBuffer,
  963. LPDWORD pnBytes );
  964. BOOL IsChunkedReadComplete( ) {
  965. return ( _ChunkState == READ_CHUNK_DONE );
  966. }
  967. //
  968. // IO Status stuff
  969. //
  970. VOID SetLastCompletionStatus( DWORD BytesWritten,
  971. DWORD CompletionStatus )
  972. {
  973. _cbBytesWritten = BytesWritten;
  974. _status = CompletionStatus;
  975. //
  976. // Do accounting for async sends so that the total bytes matches
  977. // the number actually sent to they client.
  978. //
  979. // TODO: If the client disconnects then the io completion may
  980. // complete with an error even the data was successfully sent.
  981. // This appears to be an issue with TCP, but requires further
  982. // investigation. (taylorw)
  983. //
  984. if ( _fAsyncSendPosted )
  985. {
  986. _cbBytesSent += BytesWritten;
  987. _fAsyncSendPosted = FALSE;
  988. }
  989. }
  990. DWORD QueryIOStatus( VOID ) const
  991. { return _status; }
  992. DWORD QueryBytesWritten( VOID ) const
  993. { return _cbBytesWritten; }
  994. DWORD QueryBytesReceived( VOID ) const
  995. { return _cbBytesReceived; }
  996. //
  997. // Impersonation related stuff
  998. //
  999. BOOL UseVrAccessToken() const
  1000. { return _pMetaData->QueryVrAccessToken() &&
  1001. (!_pMetaData->QueryVrPassThrough() || !_tcpauth.IsForwardable()); }
  1002. BOOL ImpersonateUser( VOID )
  1003. { return (!UseVrAccessToken() ?
  1004. _tcpauth.Impersonate() :
  1005. _pMetaData->ImpersonateVrAccessToken()
  1006. ); }
  1007. VOID RevertUser( VOID )
  1008. { (!UseVrAccessToken() ?
  1009. _tcpauth.RevertToSelf():
  1010. ::RevertToSelf()
  1011. ); }
  1012. HANDLE QueryPrimaryToken( HANDLE * phDelete );
  1013. HANDLE QueryImpersonationHandle( BOOL fUnused = FALSE )
  1014. { return (UseVrAccessToken() ?
  1015. _pMetaData->QueryVrAccessToken() :
  1016. _tcpauth.QueryImpersonationToken() ); }
  1017. HANDLE QueryUserImpersonationHandle( VOID )
  1018. { return _tcpauth.QueryImpersonationToken(); }
  1019. HANDLE QueryVrootImpersonateHandle(VOID) const
  1020. { return UseVrAccessToken() ? _pMetaData->QueryVrAccessToken() : NULL; }
  1021. TCP_AUTHENT * QueryAuthenticationObj( VOID )
  1022. { return &_tcpauth; }
  1023. BOOL IsValid( VOID ) const
  1024. { return _fValid; }
  1025. //
  1026. // Forwards request to the client connection object
  1027. //
  1028. VOID Disconnect( DWORD htResp = 0,
  1029. DWORD dwError2 = NO_ERROR,
  1030. BOOL fShutdown= FALSE,
  1031. LPBOOL pfFinished = NULL );
  1032. dllexp
  1033. BOOL ReadFile( LPVOID lpBuffer,
  1034. DWORD nBytesToRead,
  1035. DWORD * pcbBytesRead, // Only for sync reads
  1036. DWORD dwFlags = IO_FLAG_ASYNC );
  1037. dllexp
  1038. BOOL WriteFile( LPVOID lpBuffer,
  1039. DWORD nBytesToRead,
  1040. DWORD * pcbBytesWritten, // Only for sync writes
  1041. DWORD dwFlags = IO_FLAG_ASYNC );
  1042. dllexp
  1043. BOOL TestConnection( VOID );
  1044. BOOL TransmitFile( TS_OPEN_FILE_INFO * pOpenFile,
  1045. HANDLE hFile,
  1046. DWORD Offset,
  1047. DWORD BytesToWrite,
  1048. DWORD dwFlags = IO_FLAG_ASYNC,
  1049. PVOID pHead = NULL,
  1050. DWORD HeadLength = 0,
  1051. PVOID pTail = NULL,
  1052. DWORD TailLength = 0);
  1053. BOOL TransmitFileTs( TS_OPEN_FILE_INFO * pOpenFile,
  1054. DWORD Offset,
  1055. DWORD BytesToWrite,
  1056. DWORD dwFlags = IO_FLAG_ASYNC,
  1057. PVOID pHead = NULL,
  1058. DWORD HeadLength = 0,
  1059. PVOID pTail = NULL,
  1060. DWORD TailLength = 0);
  1061. BOOL SyncWsaSend( WSABUF * rgWsaBuffers,
  1062. DWORD cWsaBuffers,
  1063. LPDWORD pcbWritten );
  1064. BOOL PostCompletionStatus( DWORD cbBytesTransferred );
  1065. DWORD Reference( VOID );
  1066. DWORD Dereference( VOID );
  1067. DWORD QueryRefCount( VOID );
  1068. //
  1069. // Reset is called at the beginning of every request
  1070. //
  1071. virtual BOOL Reset( BOOL fResetPipelineInfo );
  1072. virtual VOID ReleaseCacheInfo( VOID );
  1073. //
  1074. // Called to reset Authentication status
  1075. //
  1076. BOOL ResetAuth( BOOL fSessionTerminated = TRUE );
  1077. // added these methods for exposing them to the Server extension processor
  1078. dllexp
  1079. const STR & QueryContentTypeStr( void) const { return ( _strContentType); }
  1080. dllexp
  1081. const STR & QueryMethodStr( void) const { return ( _strMethod); }
  1082. dllexp
  1083. const STR & QueryURLStr(void) const { return ( _strURL); }
  1084. dllexp
  1085. const STR & QueryPhysicalPathStr( void) const { return ( _strPhysicalPath); }
  1086. dllexp
  1087. const LPSTR QueryExpireHeader( void ) const
  1088. { return ( _pMetaData->QueryExpireHeader() ); }
  1089. //
  1090. // Called at the beginning and end of a TCP session
  1091. //
  1092. VOID InitializeSession( CLIENT_CONN * pConn,
  1093. PVOID pvInitialBuff,
  1094. DWORD cbInitialBuff );
  1095. virtual VOID EndOfRequest( VOID ) = 0;
  1096. virtual VOID SessionTerminated( VOID );
  1097. //
  1098. // Generally when the state is set to HTR_DONE
  1099. //
  1100. VOID SetState( enum HTR_STATE htrstate,
  1101. DWORD dwLogHttpResponse = HT_DONT_LOG,
  1102. DWORD dwLogWinError = NO_ERROR )
  1103. { _htrState = htrstate;
  1104. _dwLogHttpResponse = dwLogHttpResponse;
  1105. _dwLogWinError = dwLogWinError;
  1106. }
  1107. BOOL SetCertificateInfo( PHTTP_FILTER_CERTIFICATE_INFO pData,
  1108. CtxtHandle* pCtxt,
  1109. HANDLE hImpersonationToken,
  1110. HTTP_FILTER_DLL* pFilter );
  1111. BOOL CheckValidSSPILogin( VOID );
  1112. BOOL NotifyRequestSecurityContextClose( CtxtHandle *pH )
  1113. { return _pAuthFilter ? _Filter.NotifyRequestSecurityContextClose( _pAuthFilter,
  1114. pH ) : TRUE; }
  1115. dllexp
  1116. BOOL CheckForBasicAuthenticationHeader( LPSTR pszHeaders );
  1117. BOOL IsAnonymous( VOID ) const
  1118. { return _fAnonymous; }
  1119. HTTP_FILTER * QueryFilter( VOID )
  1120. { return &_Filter; }
  1121. BOOL CheckCustomError(BUFFER *pBuf, DWORD dwErr, DWORD dwSubError,
  1122. BOOL *pfFinished, DWORD *pdwMsgSize, BOOL bCheckURL = TRUE);
  1123. VOID SetNoCache( VOID )
  1124. { _bForceNoCache = 1; }
  1125. VOID ClearNoCache( VOID )
  1126. { _bForceNoCache = 0; }
  1127. DWORD QueryNoCache( VOID)
  1128. { return _bForceNoCache; }
  1129. VOID SetSendVary( VOID )
  1130. { _bSendVary = 1; }
  1131. VOID ClearSendVary( VOID )
  1132. { _bSendVary = 0; }
  1133. VOID ToggleSendCL( VOID )
  1134. { _bSendContentLocation ^= 1; }
  1135. VOID SetSendCL( VOID )
  1136. { _bSendContentLocation = 1; }
  1137. VOID ClearSendCL( VOID )
  1138. { _bSendContentLocation = 0; }
  1139. BOOL IsCGIRequest( VOID ) const
  1140. { return _GatewayType == GATEWAY_CGI; }
  1141. //
  1142. // The request looks like a gateway request (but may just be a poorly named
  1143. // directory)
  1144. //
  1145. BOOL IsProbablyGatewayRequest( VOID ) const
  1146. { return (_GatewayType & GT_GATEWAY_REQUEST); }
  1147. enum HTTP_VERB QueryVerb( VOID ) const
  1148. { return _verb; }
  1149. virtual DWORD BuildAllowHeader(CHAR *pszURL, CHAR *pszTail) = 0;
  1150. //
  1151. // Set the time for start of processing
  1152. //
  1153. VOID SetRequestStartTime( VOID )
  1154. { if (!_fStartTimeValid) { _msStartRequest= GetCurrentTime(); _fStartTimeValid= TRUE;}}
  1155. HANDLE GetFileHandle( TS_OPEN_FILE_INFO * pOpenFile )
  1156. {
  1157. HANDLE hHandle = INVALID_HANDLE_VALUE;
  1158. if ( pOpenFile )
  1159. {
  1160. if ( ImpersonateUser() )
  1161. {
  1162. hHandle = pOpenFile->QueryFileHandle();
  1163. RevertUser();
  1164. }
  1165. }
  1166. return hHandle;
  1167. }
  1168. VOID IncrementBytesSeenByRawReadFilter( DWORD cbBytesSeen )
  1169. {
  1170. _cbOldData += cbBytesSeen;
  1171. }
  1172. protected:
  1173. //
  1174. // Breaks out the simple authorization info
  1175. //
  1176. BOOL ExtractClearNameAndPswd( CHAR * pch,
  1177. STR * pstrUserName,
  1178. STR * pstrPassword,
  1179. BOOL fUUEncoded );
  1180. //
  1181. // Appends the forms of authentication the server supports to the
  1182. // server response string
  1183. //
  1184. BOOL AppendAuthenticationHdrs( STR * pstrAuthHdrs,
  1185. BOOL * pfFinished );
  1186. //
  1187. // Data members
  1188. //
  1189. //
  1190. // Points to connection object we are communicating on
  1191. //
  1192. CLIENT_CONN * _pClientConn;
  1193. // Meta data info for this request.
  1194. PW3_METADATA _pMetaData;
  1195. // URI related info (file and metadata) for this request.
  1196. PW3_URI_INFO _pURIInfo;
  1197. //
  1198. // Points to the w3 instance
  1199. //
  1200. W3_SERVER_INSTANCE * _pW3Instance;
  1201. //
  1202. // Points to server instance's statistics object.
  1203. //
  1204. W3_SERVER_STATISTICS * _pW3Stats;
  1205. //
  1206. // Action the client is requesting
  1207. //
  1208. enum HTTP_VERB _verb;
  1209. //
  1210. // Statistics trackers
  1211. //
  1212. DWORD _cFilesSent;
  1213. DWORD _cFilesReceived;
  1214. DWORD _cbBytesSent; // Total for this request
  1215. DWORD _cbBytesReceived;
  1216. DWORD _cbTotalBytesSent; // Total for all requests using this
  1217. DWORD _cbTotalBytesReceived; // object
  1218. //
  1219. // Flags
  1220. //
  1221. BOOL _fValid:1; // TRUE if this object constructed successfully
  1222. BOOL _fKeepConn:1; // Pragma: Keep-connection was specified
  1223. BOOL _fAuthenticationRequested:1; // request client authentication
  1224. BOOL _fLoggedOn:1; // A user was successfully logged on
  1225. BOOL _fAnonymous:1; // The user is using the Anonymous user token
  1226. BOOL _fSecurePort; // This request is coming over an encrypted port
  1227. BOOL _fMappedAcct:1; // The user is using a mapped account
  1228. BOOL _fClearTextPass:1; // The user supplied a clear text password
  1229. BOOL _fAuthenticating:1; // We're in an NT authentication conversation
  1230. BOOL _fBasicRealm:1; // TRUE if realm specified
  1231. BOOL _fAuthSystem:1;
  1232. BOOL _fAuthCert:1;
  1233. BOOL _fInvalidAccessToken:1;
  1234. BOOL _fAsyncSendPosted:1; // TRUE when we send data to the client asychronously
  1235. BOOL _fChunked:1; // TRUE iff the entity body is in the chunked
  1236. // transfer-encoding
  1237. BOOL _fDiscNoError:1; // TRUE if we're to disconnect w/o an error.
  1238. BOOL _fNoDisconnectOnError:1; // TRUE if we're not to disconnect on an early error.
  1239. BOOL _fProxyRequest:1; // This is request is a proxy request
  1240. // Accept range variables
  1241. BOOL _fAcceptRange:1; // TRUE if the referenced file accept byte ranges
  1242. BOOL _fProcessByteRange:1; // TRUE while processing a byte range request
  1243. BOOL _fUnsatisfiableByteRange:1; // TRUE if an unsatisfiable byte range was encountered
  1244. BOOL _fMimeMultipart:1; // TRUE if generating a MIME multipart message
  1245. BOOL _fIfModifier:1; // TRUE if we've seen an If-Match, etc.
  1246. BOOL _fHaveContentLength:1;// Set to TRUE if we've seen a content length
  1247. // on this requests.
  1248. BOOL _fLogRecordWritten:1; // TRUE if we've written a log record
  1249. DWORD _iRangeIdx; // index in strRange string
  1250. DWORD _dwRgNxOffset; // next range offset
  1251. DWORD _dwRgNxSizeToSend; // next range size
  1252. DWORD _cbMimeMultipart; // length of a MIME multipart message body
  1253. //
  1254. // The state of the HTTP request
  1255. //
  1256. enum HTR_STATE _htrState;
  1257. enum GATEWAY_TYPE _GatewayType; // BGI vs CGI vs BAT
  1258. //
  1259. // List of raw headers passed by client
  1260. //
  1261. HTTP_HEADERS _HeaderList;
  1262. //
  1263. // Client protocol version information
  1264. //
  1265. BYTE _VersionMajor;
  1266. BYTE _VersionMinor;
  1267. //
  1268. // If the client is passing data to a gateway, they will specify
  1269. // the length and type in a Content-length/type header that is stored
  1270. // here
  1271. //
  1272. STR _strContentType;
  1273. UINT _cbContentLength;
  1274. //
  1275. // The URL the client is requesting
  1276. //
  1277. STR _strURL; // Just the URL
  1278. STR _strURLPathInfo; // Combined URL and script path info
  1279. STR _strURLParams; // Just the params (w/o '?')
  1280. STR _strLogParams; // Copy of _strURLParams for logging
  1281. STR _strPathInfo; // Additional script path info
  1282. STR _strRawURL; // Combined URL and params
  1283. STR _strOriginalURL; // URL before being passed to filters
  1284. //
  1285. // Various other pieces of data in the HTTP request we care about
  1286. //
  1287. STR _strMethod; // GET, HEAD, POST etc.
  1288. STR _strAuthType; // "user", "kerberos", "nt" etc.
  1289. STR _strAuthInfo; // Current SSP authorization blob
  1290. STR _strUserName; // The user name (empty if Guest)
  1291. STR _strPassword; // Temporarily holds the password
  1292. STR _strUnmappedUserName; // User before filter mappings
  1293. STR _strUnmappedPassword; // Password before filter mappings
  1294. STR _strPhysicalPath; // Physical path of URL (maybe empty)
  1295. STR _strUnmappedPhysicalPath; // unmapped Physical path of URL (maybe empty)
  1296. STR _strRespHdrs; // Optional headers from filters
  1297. STR _strDenialHdrs; // Optional headers from filters
  1298. // to add if request is denied
  1299. STR _strHostAddr; // Host address as a domain name
  1300. STR _strRange;
  1301. BOOL _fAuthTypeDigest; // is auth type Digest/NT-Digest
  1302. LARGE_INTEGER _liModifiedSince; // Contains If-Modified-Since time
  1303. LARGE_INTEGER _liUnlessModifiedSince; // Contains Unless-Modified-Since time
  1304. LARGE_INTEGER _liUnmodifiedSince; // Contains If-Unmodified-Since time
  1305. DWORD _dwExpireInDay; // # of days before pwd expiration
  1306. // or 0x7fffffff if n/a
  1307. DWORD _dwModifiedSinceLength; // Length parameter passed in with IMS.
  1308. BOOL _bProcessingCustomError:1; // TRUE if we're processing a custom error.
  1309. BOOL _bForceNoCache:1; // Set to TRUE if must force no-cache.
  1310. BOOL _bSendContentLocation:1; // Set to TRUE if we need to send C-L:
  1311. BOOL _bSendVary:1; // Set to TRUE if we need to send Vary: *.
  1312. //
  1313. // Encapsulates authentication and impersonation code
  1314. //
  1315. BOOL _fSingleRequestAuth:1;
  1316. TCP_AUTHENT _tcpauth;
  1317. //
  1318. // Used to calculate the time of this request
  1319. //
  1320. BOOL _fStartTimeValid:1;
  1321. DWORD _msStartRequest;
  1322. //
  1323. // Filter context information
  1324. //
  1325. HTTP_FILTER _Filter;
  1326. HTTP_FILTER_DLL * _pAuthFilter;
  1327. //
  1328. // Contains the HTTP client request buffer
  1329. // _cbClientRequest indicates the number of bytes in the HTTP request
  1330. // (excluding gateway data)
  1331. // _cbOldData - Number of bytes in buffer raw read filters have already
  1332. // seen
  1333. // _cbEntityBody - Number of bytes of entity body currently in buffer
  1334. // _cbTotalEntityBody - Number of bytes expected in entity body.
  1335. // _cbChunkHeader - Number of bytes in chunk header processed.
  1336. // _cbChunkBytesRead - Number of bytes in the current transfer-encoded
  1337. // chunk we've read.
  1338. // _cbExtraData - Number of 'extra' bytes in buffer.
  1339. // _pchExtraData - Pointer to start of 'extra' bytes.
  1340. //
  1341. BUFFER _bufClientRequest;
  1342. DWORD _cbClientRequest;
  1343. DWORD _cbOldData;
  1344. DWORD _cbEntityBody;
  1345. DWORD _cbTotalEntityBody;
  1346. DWORD _cbChunkHeader;
  1347. DWORD _cbChunkBytesRead;
  1348. DWORD _cbExtraData;
  1349. CHAR *_pchExtraData;
  1350. //
  1351. // Contains the server response buffer, generally only used for response
  1352. // headers
  1353. //
  1354. BUFFER _bufServerResp;
  1355. //
  1356. // Stores the results of the last IO request
  1357. //
  1358. APIERR _status;
  1359. DWORD _cbBytesWritten;
  1360. DWORD _cbRestartBytesWritten;
  1361. DWORD _dwRenegotiated;
  1362. DWORD _dwSslNegoFlags;
  1363. AC_RESULT _acIpAccess;
  1364. BOOL _fNeedDnsCheck;
  1365. //
  1366. // Stores the request codes to write to the request log
  1367. //
  1368. DWORD _dwLogHttpResponse;
  1369. DWORD _dwLogWinError;
  1370. // Information used for decoding chunked requests.
  1371. enum CHUNK_STATE _ChunkState;
  1372. DWORD _dwChunkSize; // reset value is -1 => chunk size not sent.
  1373. BYTE _CRCount;
  1374. BYTE _LFCount;
  1375. BUFFER _bufLastAnonAcctDesc;
  1376. DWORD _cbLastAnonAcctDesc;
  1377. #if defined(CAL_ENABLED)
  1378. LPVOID m_pCalAuthCtxt;
  1379. LPVOID m_pCalSslCtxt;
  1380. #endif
  1381. VOID * m_ppvFrames[ MAX_BACKTRACE_FRAMES ];
  1382. };
  1383. #define CERT_NEGO_SUCCESS 1
  1384. #define CERT_NEGO_FAILURE 2
  1385. //
  1386. // Macro to check for both normal and localhost access
  1387. //
  1388. #define IS_ACCESS_ALLOWED(op) ( \
  1389. ((GetFilePerms() & VROOT_MASK_## op) != 0) && \
  1390. (((GetFilePerms() & VROOT_MASK_NO_REMOTE_## op) == 0) || \
  1391. IsIPAddressLocal( \
  1392. QueryClientConn()->QueryLocalIPAddress(), \
  1393. QueryClientConn()->QueryRemoteIPAddress()) ) )
  1394. #define IS_ACCESS_ALLOWED2(_pExec, op) ( \
  1395. ((_pExec->_pMetaData->QueryAccessPerms() & VROOT_MASK_## op) != 0) && \
  1396. (((_pExec->_pMetaData->QueryAccessPerms() & VROOT_MASK_NO_REMOTE_## op) == 0) || \
  1397. IsIPAddressLocal( \
  1398. QueryClientConn()->QueryLocalIPAddress(), \
  1399. QueryClientConn()->QueryRemoteIPAddress()) ) )
  1400. # endif // _BASEREQ_HXX_