Authenticate() public static method

public static Authenticate ( string challenge, System request, ICredentials credentials ) : Authorization
challenge string
request System
credentials ICredentials
return Authorization
示例#1
0
		bool CheckAuthorization (WebResponse response, HttpStatusCode code)
		{
			authCompleted = false;
			if (code == HttpStatusCode.Unauthorized && credentials == null)
				return false;

			bool isProxy = (code == HttpStatusCode.ProxyAuthenticationRequired);
			if (isProxy && (proxy == null || proxy.Credentials == null))
				return false;

			string [] authHeaders = response.Headers.GetValues ( (isProxy) ? "Proxy-Authenticate" : "WWW-Authenticate");
			if (authHeaders == null || authHeaders.Length == 0)
				return false;

			ICredentials creds = (!isProxy) ? credentials : proxy.Credentials;
			Authorization auth = null;
			foreach (string authHeader in authHeaders) {
				auth = AuthenticationManager.Authenticate (authHeader, this, creds);
				if (auth != null)
					break;
			}
			if (auth == null)
				return false;
			webHeaders [(isProxy) ? "Proxy-Authorization" : "Authorization"] = auth.Message;
			authCompleted = auth.Complete;
			bool is_ntlm = (auth.Module.AuthenticationType == "NTLM");
			if (is_ntlm)
				ntlm_auth_state = (NtlmAuthState)((int) ntlm_auth_state + 1);
			return true;
		}
示例#2
0
        bool CheckAuthorization(WebResponse response, HttpStatusCode code)
        {
            authCompleted = false;
            if (code == HttpStatusCode.Unauthorized && credentials == null)
            {
                return(false);
            }

            bool isProxy = (code == HttpStatusCode.ProxyAuthenticationRequired);

            if (isProxy && (proxy == null || proxy.Credentials == null))
            {
                return(false);
            }

            string authHeader = response.Headers [(isProxy) ? "Proxy-Authenticate" : "WWW-Authenticate"];

            if (authHeader == null)
            {
                return(false);
            }

            ICredentials  creds = (!isProxy) ? credentials : proxy.Credentials;
            Authorization auth  = AuthenticationManager.Authenticate(authHeader, this, creds);

            if (auth == null)
            {
                return(false);
            }

            webHeaders [(isProxy) ? "Proxy-Authorization" : "Authorization"] = auth.Message;
            authCompleted = auth.Complete;
            return(true);
        }
        internal bool AttemptAuthenticate(HttpWebRequest httpWebRequest, ICredentials authInfo)
        {
            if ((this.Authorization != null) && this.Authorization.Complete)
            {
                if (this.IsProxyAuth)
                {
                    this.ClearAuthReq(httpWebRequest);
                }
                return(false);
            }
            if (authInfo == null)
            {
                return(false);
            }
            string challenge = httpWebRequest.AuthHeader(this.AuthenticateHeader);

            if (challenge == null)
            {
                if ((!this.IsProxyAuth && (this.Authorization != null)) && (httpWebRequest.ProxyAuthenticationState.Authorization != null))
                {
                    httpWebRequest.Headers.Set(this.AuthorizationHeader, this.Authorization.Message);
                }
                return(false);
            }
            this.PrepareState(httpWebRequest);
            try
            {
                this.Authorization = AuthenticationManager.Authenticate(challenge, httpWebRequest, authInfo);
            }
            catch (Exception)
            {
                this.Authorization = null;
                this.ClearSession(httpWebRequest);
                throw;
            }
            if (this.Authorization == null)
            {
                return(false);
            }
            if (this.Authorization.Message == null)
            {
                this.Authorization = null;
                return(false);
            }
            this.UniqueGroupId = this.Authorization.ConnectionGroupId;
            try
            {
                httpWebRequest.Headers.Set(this.AuthorizationHeader, this.Authorization.Message);
            }
            catch
            {
                this.Authorization = null;
                this.ClearSession(httpWebRequest);
                throw;
            }
            return(true);
        }
示例#4
0
        internal bool AddProxyAuthHeaders(String challenge)
        {
            ICredentials  cred;
            String        challengeType = "Basic"; /* default */
            Authorization auth;

            if (proxy == null)
            {
                return(false);
            }

            if (proxy.Credentials == null)
            {
                return(false);
            }

            if (challenge == null)
            {
                throw new ArgumentNullException("challenge");
            }
            else
            {
                int len = challenge.IndexOf(' ');
                challengeType = (len == -1) ? challenge :
                                challenge.Substring(0, len);
            }

            cred = proxy.Credentials.GetCredential(this.Address, challengeType);

            if (cred == null)
            {
                return(false);        /* TODO : throw an exception here ? */
            }

            /* I would have added a PreAuthenticate option for this as well
             * But MS or ECMA doesn't . So I won't -- Gopal */

            auth = AuthenticationManager.Authenticate(challenge,
                                                      this, cred);
            if (auth == null)
            {
                return(false);        /* TODO : throw an exception here ? */
            }

            this.Headers["Proxy-Authorization"] = auth.Message;
            return(true);
        }
示例#5
0
        internal bool AddHttpAuthHeaders(String challenge)
        {
            ICredentials  cred;
            String        challengeType = "Basic"; /* default */
            Authorization auth;

            if (credentials == null)
            {
                return(false);
            }
            if (challenge == null && !preAuthenticate)
            {
                return(false);        /* TODO : throw an exception here ? */
            }
            else if (challenge != null)
            {
                int len = challenge.IndexOf(' ');
                challengeType = (len == -1) ? challenge :
                                challenge.Substring(0, len);
            }
            cred = credentials.GetCredential(this.Address, challengeType);
            if (cred == null)
            {
                return(false);        /* TODO : throw an exception here ? */
            }

            if (preAuthenticate)
            {
                auth = AuthenticationManager.PreAuthenticate(this,
                                                             cred);
            }
            else
            {
                auth = AuthenticationManager.Authenticate(challenge,
                                                          this, cred);
            }

            if (auth == null)
            {
                return(false);        /* TODO : throw an exception here ? */
            }
            this.Headers["Authorization"] = auth.Message;
            return(true);
        }
示例#6
0
        private bool CreateTunnel(HttpWebRequest request, Stream stream, out byte[] buffer)
        {
            StringBuilder stringBuilder = new StringBuilder();

            stringBuilder.Append("CONNECT ");
            stringBuilder.Append(request.Address.Host);
            stringBuilder.Append(':');
            stringBuilder.Append(request.Address.Port);
            stringBuilder.Append(" HTTP/");
            if (request.ServicePoint.ProtocolVersion == HttpVersion.Version11)
            {
                stringBuilder.Append("1.1");
            }
            else
            {
                stringBuilder.Append("1.0");
            }
            stringBuilder.Append("\r\nHost: ");
            stringBuilder.Append(request.Address.Authority);
            string challenge = Data.Challenge;

            Data.Challenge = null;
            bool flag = request.Headers["Proxy-Authorization"] != null;

            if (flag)
            {
                stringBuilder.Append("\r\nProxy-Authorization: ");
                stringBuilder.Append(request.Headers["Proxy-Authorization"]);
            }
            else if (challenge != null && Data.StatusCode == 407)
            {
                flag = true;
                ICredentials  credentials   = request.Proxy.Credentials;
                Authorization authorization = AuthenticationManager.Authenticate(challenge, request, credentials);
                if (authorization != null)
                {
                    stringBuilder.Append("\r\nProxy-Authorization: ");
                    stringBuilder.Append(authorization.Message);
                }
            }
            stringBuilder.Append("\r\n\r\n");
            Data.StatusCode = 0;
            byte[] bytes = Encoding.Default.GetBytes(stringBuilder.ToString());
            stream.Write(bytes, 0, bytes.Length);
            int num;
            WebHeaderCollection webHeaderCollection = ReadHeaders(request, stream, out buffer, out num);

            if (!flag && webHeaderCollection != null && num == 407)
            {
                Data.StatusCode = num;
                Data.Challenge  = webHeaderCollection["Proxy-Authenticate"];
                return(false);
            }
            if (num != 200)
            {
                string where = $"The remote server returned a {num} status code.";
                HandleError(WebExceptionStatus.SecureChannelFailure, null, where);
                return(false);
            }
            return(webHeaderCollection != null);
        }
示例#7
0
        bool CreateTunnel(HttpWebRequest request, Stream stream, out byte [] buffer)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("CONNECT ");
            sb.Append(request.Address.Host);
            sb.Append(':');
            sb.Append(request.Address.Port);
            sb.Append(" HTTP/");
            if (request.ServicePoint.ProtocolVersion == HttpVersion.Version11)
            {
                sb.Append("1.1");
            }
            else
            {
                sb.Append("1.0");
            }

            sb.Append("\r\nHost: ");
            sb.Append(request.Address.Authority);
            string challenge = Data.Challenge;

            Data.Challenge = null;
            bool have_auth = (request.Headers ["Proxy-Authorization"] != null);

            if (have_auth)
            {
                sb.Append("\r\nProxy-Authorization: ");
                sb.Append(request.Headers ["Proxy-Authorization"]);
            }
            else if (challenge != null && Data.StatusCode == 407)
            {
                have_auth = true;
                ICredentials  creds = request.Proxy.Credentials;
                Authorization auth  = AuthenticationManager.Authenticate(challenge, request, creds);
                if (auth != null)
                {
                    sb.Append("\r\nProxy-Authorization: ");
                    sb.Append(auth.Message);
                }
            }
            sb.Append("\r\n\r\n");

            Data.StatusCode = 0;
            byte [] connectBytes = Encoding.Default.GetBytes(sb.ToString());
            stream.Write(connectBytes, 0, connectBytes.Length);

            int status;
            WebHeaderCollection result = ReadHeaders(request, stream, out buffer, out status);

            if (!have_auth && result != null && status == 407)               // Needs proxy auth
            {
                Data.StatusCode = status;
                Data.Challenge  = result ["Proxy-Authenticate"];
                return(false);
            }
            else if (status != 200)
            {
                string msg = String.Format("The remote server returned a {0} status code.", status);
                HandleError(WebExceptionStatus.SecureChannelFailure, null, msg);
                return(false);
            }

            return(result != null);
        }
示例#8
0
        bool CreateTunnel(HttpWebRequest request, Uri connectUri,
                          Stream stream, out byte[] buffer)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("CONNECT ");
            sb.Append(request.Address.Host);
            sb.Append(':');
            sb.Append(request.Address.Port);
            sb.Append(" HTTP/");
            if (request.ServicePoint.ProtocolVersion == HttpVersion.Version11)
            {
                sb.Append("1.1");
            }
            else
            {
                sb.Append("1.0");
            }

            sb.Append("\r\nHost: ");
            sb.Append(request.Address.Authority);

            bool ntlm      = false;
            var  challenge = Data.Challenge;

            Data.Challenge = null;
            var  auth_header = request.Headers ["Proxy-Authorization"];
            bool have_auth   = auth_header != null;

            if (have_auth)
            {
                sb.Append("\r\nProxy-Authorization: ");
                sb.Append(auth_header);
                ntlm = auth_header.ToUpper().Contains("NTLM");
            }
            else if (challenge != null && Data.StatusCode == 407)
            {
                ICredentials creds = request.Proxy.Credentials;
                have_auth = true;

                if (connect_request == null)
                {
                    // create a CONNECT request to use with Authenticate
                    connect_request = (HttpWebRequest)WebRequest.Create(
                        connectUri.Scheme + "://" + connectUri.Host + ":" + connectUri.Port + "/");
                    connect_request.Method      = "CONNECT";
                    connect_request.Credentials = creds;
                }

                for (int i = 0; i < challenge.Length; i++)
                {
                    var auth = AuthenticationManager.Authenticate(challenge [i], connect_request, creds);
                    if (auth == null)
                    {
                        continue;
                    }
                    ntlm = (auth.Module.AuthenticationType == "NTLM");
                    sb.Append("\r\nProxy-Authorization: ");
                    sb.Append(auth.Message);
                    break;
                }
            }

            if (ntlm)
            {
                sb.Append("\r\nProxy-Connection: keep-alive");
                connect_ntlm_auth_state++;
            }

            sb.Append("\r\n\r\n");

            Data.StatusCode = 0;
            byte [] connectBytes = Encoding.Default.GetBytes(sb.ToString());
            stream.Write(connectBytes, 0, connectBytes.Length);

            int status;
            WebHeaderCollection result = ReadHeaders(stream, out buffer, out status);

            if ((!have_auth || connect_ntlm_auth_state == NtlmAuthState.Challenge) &&
                result != null && status == 407)               // Needs proxy auth
            {
                var connectionHeader = result ["Connection"];
                if (socket != null && !string.IsNullOrEmpty(connectionHeader) &&
                    connectionHeader.ToLower() == "close")
                {
                    // The server is requesting that this connection be closed
                    socket.Close();
                    socket = null;
                }

                Data.StatusCode = status;
                Data.Challenge  = result.GetValues_internal("Proxy-Authenticate", false);
                return(false);
            }
            else if (status != 200)
            {
                string msg = String.Format("The remote server returned a {0} status code.", status);
                HandleError(WebExceptionStatus.SecureChannelFailure, null, msg);
                return(false);
            }

            return(result != null);
        }
示例#9
0
        //
        // attempts to authenticate the request:
        // returns true only if it succesfully called into the AuthenticationManager
        // and got back a valid Authorization and succesfully set the appropriate auth headers
        //
        internal bool AttemptAuthenticate(HttpWebRequest httpWebRequest, ICredentials authInfo)
        {
            //
            // Check for previous authentication attempts or the presence of credentials
            //
            GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() httpWebRequest#" + ValidationHelper.HashString(httpWebRequest) + " AuthorizationHeader:" + AuthorizationHeader.ToString());

            if (Authorization != null && Authorization.Complete)
            {
                //
                // here the design gets "dirty".
                // if this is proxy auth, we might have been challenged by an external
                // server as well. in this case we will have to clear our previous proxy
                // auth state before we go any further. this will be broken if the handshake
                // requires more than one dropped connection (which NTLM is a border case for,
                // since it droppes the connection on the 1st challenge but not on the second)
                //
                GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() Authorization!=null Authorization.Complete:" + Authorization.Complete.ToString());
                if (IsProxyAuth)
                {
                    //
                    // so, we got passed a 407 but now we got a 401, the proxy probably
                    // dropped the connection on us so we need to reset our proxy handshake
                    // Consider: this should have been taken care by Update()
                    //
                    GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() ProxyAuth cleaning up auth status");
                    ClearAuthReq(httpWebRequest);
                }
                return(false);
            }

            if (authInfo == null)
            {
                GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() authInfo==null Authorization#" + ValidationHelper.HashString(Authorization));
                return(false);
            }

            string challenge = httpWebRequest.AuthHeader(AuthenticateHeader);

            if (challenge == null)
            {
                //
                // the server sent no challenge, but this might be the case
                // in which we're succeeding an authorization handshake to
                // a proxy while a handshake with the server is still in progress.
                // if the handshake with the proxy is complete and we actually have
                // a handshake with the server in progress we can send the authorization header for the server as well.
                //
                if (!IsProxyAuth && Authorization != null && httpWebRequest.ProxyAuthenticationState.Authorization != null)
                {
                    httpWebRequest.Headers.Set(AuthorizationHeader, Authorization.Message);
                }
                GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() challenge==null Authorization#" + ValidationHelper.HashString(Authorization));
                return(false);
            }

            //
            // if the AuthenticationManager throws on Authenticate,
            // bubble up that Exception to the user
            //
            GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() challenge:" + challenge);

            PrepareState(httpWebRequest);
            try {
                Authorization = AuthenticationManager.Authenticate(challenge, httpWebRequest, authInfo);
            }
            catch (Exception exception) {
                Authorization = null;
                GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::PreAuthIfNeeded() PreAuthenticate() returned exception:" + exception.Message);
                ClearSession(httpWebRequest);
                throw;
            }


            if (Authorization == null)
            {
                GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() Authorization==null");
                return(false);
            }
            if (Authorization.Message == null)
            {
                GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() Authorization.Message==null");
                Authorization = null;
                return(false);
            }

            UniqueGroupId = Authorization.ConnectionGroupId;
            GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() AuthorizationHeader:" + AuthorizationHeader + " blob: " + Authorization.Message.Length + "bytes Complete:" + Authorization.Complete.ToString());

            try {
                //
                // a "bad" module could try sending bad characters in the HTTP headers.
                // catch the exception from WebHeaderCollection.CheckBadChars()
                // fail the auth process
                // and return the exception to the user as InnerException
                //
                httpWebRequest.Headers.Set(AuthorizationHeader, Authorization.Message);
            }
            catch {
                Authorization = null;
                ClearSession(httpWebRequest);
                throw;
            }

            return(true);
        }
        //
        // attempts to authenticate the request:
        // returns true only if it succesfully called into the AuthenticationManager
        // and got back a valid Authorization and succesfully set the appropriate auth headers
        //
        internal bool AttemptAuthenticate(HttpWebRequest httpWebRequest, ICredentials authInfo)
        {
            //
            // Check for previous authentication attempts or the presence of credentials
            //
            GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() httpWebRequest#" + ValidationHelper.HashString(httpWebRequest) + " AuthorizationHeader:" + AuthorizationHeader.ToString());

            if (Authorization != null && Authorization.Complete)
            {
                GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() Authorization!=null Authorization.Complete:" + Authorization.Complete.ToString());
                if (IsProxyAuth)
                {
                    GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() ProxyAuth cleaning up auth status");
                    ClearAuthReq(httpWebRequest);
                }
                return(false);
            }

            if (authInfo == null)
            {
                GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() authInfo==null Authorization#" + ValidationHelper.HashString(Authorization));
                return(false);
            }

            string challenge = httpWebRequest.AuthHeader(AuthenticateHeader);

            if (challenge == null)
            {
                //
                // the server sent no challenge, but this might be the case
                // in which we're succeeding an authorization handshake to
                // a proxy while a handshake with the server is still in progress.
                // if the handshake with the proxy is complete and we actually have
                // a handshake with the server in progress we can send the authorization header for the server as well.
                //
                if (!IsProxyAuth && Authorization != null && httpWebRequest.ProxyAuthenticationState.Authorization != null)
                {
                    httpWebRequest.Headers.Set(AuthorizationHeader, Authorization.Message);
                }
                GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() challenge==null Authorization#" + ValidationHelper.HashString(Authorization));
                return(false);
            }

            //
            // if the AuthenticationManager throws on Authenticate,
            // bubble up that Exception to the user
            //
            GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() challenge:" + challenge);

            PrepareState(httpWebRequest);
            try {
                Authorization = AuthenticationManager.Authenticate(challenge, httpWebRequest, authInfo);
            }
            catch (Exception exception) {
                Authorization = null;
                GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::PreAuthIfNeeded() PreAuthenticate() returned exception:" + exception.Message);
                ClearSession(httpWebRequest);
                throw;
            }
            catch {
                Authorization = null;
                GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::PreAuthIfNeeded() PreAuthenticate() returned exception: Non-CLS Compliant Exception");
                ClearSession(httpWebRequest);
                throw;
            }


            if (Authorization == null)
            {
                GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() Authorization==null");
                return(false);
            }
            if (Authorization.Message == null)
            {
                GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() Authorization.Message==null");
                Authorization = null;
                return(false);
            }

            UniqueGroupId = Authorization.ConnectionGroupId;
            GlobalLog.Print("AuthenticationState#" + ValidationHelper.HashString(this) + "::AttemptAuthenticate() AuthorizationHeader:" + AuthorizationHeader + " blob: " + Authorization.Message.Length + "bytes Complete:" + Authorization.Complete.ToString());

            try {
                //
                // a "bad" module could try sending bad characters in the HTTP headers.
                // catch the exception from WebHeaderCollection.CheckBadChars()
                // fail the auth process
                // and return the exception to the user as InnerException
                //
                httpWebRequest.Headers.Set(AuthorizationHeader, Authorization.Message);
            }
            catch {
                Authorization = null;
                ClearSession(httpWebRequest);
                throw;
            }

            return(true);
        }
示例#11
0
        internal async Task Initialize(Stream stream, CancellationToken cancellationToken)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("CONNECT ");
            sb.Append(Request.Address.Host);
            sb.Append(':');
            sb.Append(Request.Address.Port);
            sb.Append(" HTTP/");
            if (Request.ProtocolVersion == HttpVersion.Version11)
            {
                sb.Append("1.1");
            }
            else
            {
                sb.Append("1.0");
            }

            sb.Append("\r\nHost: ");
            sb.Append(Request.Address.Authority);

            bool ntlm      = false;
            var  challenge = Challenge;

            Challenge = null;
            var  auth_header = Request.Headers["Proxy-Authorization"];
            bool have_auth   = auth_header != null;

            if (have_auth)
            {
                sb.Append("\r\nProxy-Authorization: ");
                sb.Append(auth_header);
                ntlm = auth_header.ToUpper().Contains("NTLM");
            }
            else if (challenge != null && StatusCode == 407)
            {
                ICredentials creds = Request.Proxy.Credentials;
                have_auth = true;

                if (connectRequest == null)
                {
                    // create a CONNECT request to use with Authenticate
                    connectRequest = (HttpWebRequest)WebRequest.Create(
                        ConnectUri.Scheme + "://" + ConnectUri.Host + ":" + ConnectUri.Port + "/");
                    connectRequest.Method      = "CONNECT";
                    connectRequest.Credentials = creds;
                }

                if (creds != null)
                {
                    for (int i = 0; i < challenge.Length; i++)
                    {
                        var auth = AuthenticationManager.Authenticate(challenge[i], connectRequest, creds);
                        if (auth == null)
                        {
                            continue;
                        }
                        ntlm = (auth.ModuleAuthenticationType == "NTLM");
                        sb.Append("\r\nProxy-Authorization: ");
                        sb.Append(auth.Message);
                        break;
                    }
                }
            }

            if (ntlm)
            {
                sb.Append("\r\nProxy-Connection: keep-alive");
                ntlmAuthState++;
            }

            sb.Append("\r\n\r\n");

            StatusCode = 0;
            byte[] connectBytes = Encoding.Default.GetBytes(sb.ToString());
            await stream.WriteAsync(connectBytes, 0, connectBytes.Length, cancellationToken).ConfigureAwait(false);

            (Headers, Data, StatusCode) = await ReadHeaders(stream, cancellationToken).ConfigureAwait(false);

            if ((!have_auth || ntlmAuthState == NtlmAuthState.Challenge) && Headers != null && StatusCode == 407)               // Needs proxy auth
            {
                var connectionHeader = Headers["Connection"];
                if (!string.IsNullOrEmpty(connectionHeader) && connectionHeader.ToLower() == "close")
                {
                    // The server is requesting that this connection be closed
                    CloseConnection = true;
                }

                Challenge = Headers.GetValues("Proxy-Authenticate");
                Success   = false;
            }
            else
            {
                Success = StatusCode == 200 && Headers != null;
            }

            if (Challenge == null && (StatusCode == 401 || StatusCode == 407))
            {
                var response = new HttpWebResponse(ConnectUri, "CONNECT", (HttpStatusCode)StatusCode, Headers);
                throw new WebException(
                          StatusCode == 407 ? "(407) Proxy Authentication Required" : "(401) Unauthorized",
                          null, WebExceptionStatus.ProtocolError, response);
            }
        }