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.

186 lines
5.4 KiB

  1. #include <wininetp.h>
  2. #include <splugin.hxx>
  3. #include "htuu.h"
  4. /*---------------------------------------------------------------------------
  5. BASIC_CTX
  6. ---------------------------------------------------------------------------*/
  7. /*---------------------------------------------------------------------------
  8. Constructor
  9. ---------------------------------------------------------------------------*/
  10. BASIC_CTX::BASIC_CTX(HTTP_REQUEST_HANDLE_OBJECT *pRequest, BOOL fIsProxy,
  11. SPMData* pSPM, AUTH_CREDS* pCreds)
  12. : AUTHCTX(pSPM, pCreds)
  13. {
  14. _fIsProxy = fIsProxy;
  15. _pRequest = pRequest;
  16. }
  17. /*---------------------------------------------------------------------------
  18. Destructor
  19. ---------------------------------------------------------------------------*/
  20. BASIC_CTX::~BASIC_CTX()
  21. {}
  22. /*---------------------------------------------------------------------------
  23. PreAuthUser
  24. ---------------------------------------------------------------------------*/
  25. DWORD BASIC_CTX::PreAuthUser(IN LPSTR pBuf, IN OUT LPDWORD pcbBuf)
  26. {
  27. DWORD dwRetVal = ERROR_WINHTTP_INTERNAL_ERROR;
  28. LPSTR pszUserPass = NULL;
  29. DWORD cbUserPass;
  30. LPSTR lpszPass = NULL;
  31. if (!_pCreds->lpszUser || !(lpszPass = _pCreds->GetPass()))
  32. {
  33. dwRetVal = ERROR_INVALID_PARAMETER;
  34. goto done;
  35. }
  36. // Prefix the header value with the auth type.
  37. const static BYTE szBasic[] = "Basic ";
  38. const DWORD BASIC_LEN = sizeof(szBasic) - 1;
  39. if (*pcbBuf < BASIC_LEN)
  40. {
  41. dwRetVal = ERROR_INSUFFICIENT_BUFFER;
  42. goto done;
  43. }
  44. memcpy (pBuf, szBasic, BASIC_LEN);
  45. pBuf += BASIC_LEN;
  46. // Generate rest of header value by uuencoding user:pass.
  47. DWORD cbMaxUserPathLen = strlen(_pCreds->lpszUser) + 1
  48. + strlen(lpszPass) + 1
  49. + 10;
  50. // HTUU_encode() parse the buffer 3 bytes at a time;
  51. // In the worst case we will be two bytes short, so add at least 2 here.
  52. // longer buffer doesn't matter, HTUU_encode will adjust appropreiately.
  53. pszUserPass = New CHAR[cbMaxUserPathLen];
  54. if (pszUserPass == NULL)
  55. {
  56. dwRetVal = ERROR_NOT_ENOUGH_MEMORY;
  57. goto done;
  58. }
  59. cbUserPass = wsprintf(pszUserPass, "%s:%s", _pCreds->lpszUser, lpszPass);
  60. INET_ASSERT (cbUserPass < cbMaxUserPathLen);
  61. if( -1 == HTUU_encode ((PBYTE) pszUserPass, cbUserPass, pBuf, *pcbBuf - BASIC_LEN))
  62. goto done;
  63. *pcbBuf = BASIC_LEN + lstrlen (pBuf);
  64. _pvContext = (LPVOID) 1;
  65. dwRetVal = ERROR_SUCCESS;
  66. done:
  67. if (pszUserPass != NULL)
  68. delete [] pszUserPass;
  69. if (lpszPass)
  70. {
  71. SecureZeroMemory(lpszPass, strlen(lpszPass));
  72. FREE_MEMORY(lpszPass);
  73. }
  74. return dwRetVal;
  75. }
  76. /*---------------------------------------------------------------------------
  77. UpdateFromHeaders
  78. ---------------------------------------------------------------------------*/
  79. DWORD BASIC_CTX::UpdateFromHeaders(HTTP_REQUEST_HANDLE_OBJECT *pRequest, BOOL fIsProxy)
  80. {
  81. DWORD dwAuthIdx, cbRealm, dwError;
  82. LPSTR szRealm = NULL;
  83. // Get the associated header.
  84. if ((dwError = FindHdrIdxFromScheme(&dwAuthIdx)) != ERROR_SUCCESS)
  85. goto exit;
  86. // Get any realm.
  87. dwError = GetAuthHeaderData(pRequest, fIsProxy, "Realm",
  88. &szRealm, &cbRealm, ALLOCATE_BUFFER, dwAuthIdx);
  89. // No realm is OK.
  90. if (dwError != ERROR_SUCCESS)
  91. szRealm = NULL;
  92. // If we already have a Creds, ensure that the realm matches. If not,
  93. // find or create a new one and set it in the auth context.
  94. if (_pCreds)
  95. {
  96. INET_ASSERT(_pCreds->lpszRealm);
  97. if (/*_pCreds->lpszRealm && */szRealm && lstrcmp(_pCreds->lpszRealm, szRealm))
  98. {
  99. // Realms don't match - create a new Creds entry, release the old.
  100. delete _pCreds;
  101. _pCreds = CreateCreds(pRequest, fIsProxy, _pSPMData, szRealm);
  102. INET_ASSERT(_pCreds->pSPM == _pSPMData);
  103. }
  104. }
  105. // If no password cache is set in the auth context,
  106. // find or create one and set it in the auth context.
  107. else
  108. {
  109. // Find or create a password cache entry.
  110. _pCreds = CreateCreds(pRequest, fIsProxy, _pSPMData, szRealm);
  111. if (!_pCreds)
  112. {
  113. dwError = ERROR_WINHTTP_INTERNAL_ERROR;
  114. goto exit;
  115. }
  116. INET_ASSERT(_pCreds->pSPM == _pSPMData);
  117. // _pCreds->nLockCount++;
  118. }
  119. if (!_pCreds)
  120. {
  121. INET_ASSERT(FALSE);
  122. dwError = ERROR_WINHTTP_INTERNAL_ERROR;
  123. goto exit;
  124. }
  125. dwError = ERROR_SUCCESS;
  126. exit:
  127. if (szRealm)
  128. delete []szRealm;
  129. return dwError;
  130. }
  131. /*---------------------------------------------------------------------------
  132. PostAuthUser
  133. ---------------------------------------------------------------------------*/
  134. DWORD BASIC_CTX::PostAuthUser()
  135. {
  136. DWORD dwRet;
  137. if (! _pvContext && !_pRequest->GetCreds()
  138. && _pCreds->lpszUser && _pCreds->xszPass.GetPtr())
  139. dwRet = ERROR_WINHTTP_FORCE_RETRY;
  140. else
  141. dwRet = ERROR_WINHTTP_INCORRECT_PASSWORD;
  142. _pRequest->SetCreds(NULL);
  143. _pvContext = (LPVOID) 1;
  144. return dwRet;
  145. }