コード例 #1
0
        internal HttpListenerRequest(HttpListenerContext httpContext, RequestContextBase memoryBlob)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(this, $"httpContext:${httpContext} memoryBlob {((IntPtr)memoryBlob.RequestBlob)}");
                NetEventSource.Associate(this, httpContext);
            }
            _httpContext  = httpContext;
            _memoryBlob   = memoryBlob;
            _boundaryType = BoundaryType.None;

            // Set up some of these now to avoid refcounting on memory blob later.
            _requestId    = memoryBlob.RequestBlob->RequestId;
            _connectionId = memoryBlob.RequestBlob->ConnectionId;
            _sslStatus    = memoryBlob.RequestBlob->pSslInfo == null ? SslStatus.Insecure :
                            memoryBlob.RequestBlob->pSslInfo->SslClientCertNegotiated == 0 ? SslStatus.NoClientCert :
                            SslStatus.ClientCert;
            if (memoryBlob.RequestBlob->pRawUrl != null && memoryBlob.RequestBlob->RawUrlLength > 0)
            {
                _rawUrl = Marshal.PtrToStringAnsi((IntPtr)memoryBlob.RequestBlob->pRawUrl, memoryBlob.RequestBlob->RawUrlLength);
            }

            Interop.HttpApi.HTTP_COOKED_URL cookedUrl = memoryBlob.RequestBlob->CookedUrl;
            if (cookedUrl.pHost != null && cookedUrl.HostLength > 0)
            {
                _cookedUrlHost = Marshal.PtrToStringUni((IntPtr)cookedUrl.pHost, cookedUrl.HostLength / 2);
            }
            if (cookedUrl.pAbsPath != null && cookedUrl.AbsPathLength > 0)
            {
                _cookedUrlPath = Marshal.PtrToStringUni((IntPtr)cookedUrl.pAbsPath, cookedUrl.AbsPathLength / 2);
            }
            if (cookedUrl.pQueryString != null && cookedUrl.QueryStringLength > 0)
            {
                _cookedUrlQuery = Marshal.PtrToStringUni((IntPtr)cookedUrl.pQueryString, cookedUrl.QueryStringLength / 2);
            }
            _version         = new Version(memoryBlob.RequestBlob->Version.MajorVersion, memoryBlob.RequestBlob->Version.MinorVersion);
            _clientCertState = ListenerClientCertState.NotInitialized;
            _keepAlive       = null;
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(this, $"RequestId:{RequestId} ConnectionId:{_connectionId} RawConnectionId:{memoryBlob.RequestBlob->RawConnectionId} UrlContext:{memoryBlob.RequestBlob->UrlContext} RawUrl:{_rawUrl} Version:{_version} Secure:{_sslStatus}");
                NetEventSource.Info(this, $"httpContext:${httpContext} RequestUri:{RequestUri} Content-Length:{ContentLength64} HTTP Method:{HttpMethod}");
            }
            // Log headers
            if (NetEventSource.IsEnabled)
            {
                StringBuilder sb = new StringBuilder("HttpListenerRequest Headers:\n");
                for (int i = 0; i < Headers.Count; i++)
                {
                    sb.Append("\t");
                    sb.Append(Headers.GetKey(i));
                    sb.Append(" : ");
                    sb.Append(Headers.Get(i));
                    sb.Append("\n");
                }
                NetEventSource.Info(this, sb.ToString());
            }
        }
 internal unsafe HttpListenerRequest(System.Net.HttpListenerContext httpContext, RequestContextBase memoryBlob)
 {
     if (Logging.On)
     {
         Logging.PrintInfo(Logging.HttpListener, this, ".ctor", "httpContext#" + ValidationHelper.HashString(httpContext) + " memoryBlob# " + ValidationHelper.HashString((IntPtr) memoryBlob.RequestBlob));
     }
     if (Logging.On)
     {
         Logging.Associate(Logging.HttpListener, this, httpContext);
     }
     this.m_HttpContext = httpContext;
     this.m_MemoryBlob = memoryBlob;
     this.m_BoundaryType = BoundaryType.None;
     this.m_RequestId = memoryBlob.RequestBlob.RequestId;
     this.m_ConnectionId = memoryBlob.RequestBlob.ConnectionId;
     this.m_SslStatus = (memoryBlob.RequestBlob.pSslInfo == null) ? SslStatus.Insecure : ((memoryBlob.RequestBlob.pSslInfo.SslClientCertNegotiated == 0) ? SslStatus.NoClientCert : SslStatus.ClientCert);
     if ((memoryBlob.RequestBlob.pRawUrl != null) && (memoryBlob.RequestBlob.RawUrlLength > 0))
     {
         this.m_RawUrl = Marshal.PtrToStringAnsi((IntPtr) memoryBlob.RequestBlob.pRawUrl, memoryBlob.RequestBlob.RawUrlLength);
     }
     UnsafeNclNativeMethods.HttpApi.HTTP_COOKED_URL cookedUrl = memoryBlob.RequestBlob.CookedUrl;
     if ((cookedUrl.pHost != null) && (cookedUrl.HostLength > 0))
     {
         this.m_CookedUrlHost = Marshal.PtrToStringUni((IntPtr) cookedUrl.pHost, cookedUrl.HostLength / 2);
     }
     if ((cookedUrl.pAbsPath != null) && (cookedUrl.AbsPathLength > 0))
     {
         this.m_CookedUrlPath = Marshal.PtrToStringUni((IntPtr) cookedUrl.pAbsPath, cookedUrl.AbsPathLength / 2);
     }
     if ((cookedUrl.pQueryString != null) && (cookedUrl.QueryStringLength > 0))
     {
         this.m_CookedUrlQuery = Marshal.PtrToStringUni((IntPtr) cookedUrl.pQueryString, cookedUrl.QueryStringLength / 2);
     }
     this.m_Version = new Version(memoryBlob.RequestBlob.Version.MajorVersion, memoryBlob.RequestBlob.Version.MinorVersion);
     this.m_ClientCertState = ListenerClientCertState.NotInitialized;
     this.m_KeepAlive = TriState.Unspecified;
     if (Logging.On)
     {
         Logging.PrintInfo(Logging.HttpListener, this, ".ctor", "httpContext#" + ValidationHelper.HashString(httpContext) + " RequestUri:" + ValidationHelper.ToString(this.RequestUri) + " Content-Length:" + ValidationHelper.ToString(this.ContentLength64) + " HTTP Method:" + ValidationHelper.ToString(this.HttpMethod));
     }
     if (Logging.On)
     {
         StringBuilder builder = new StringBuilder("HttpListenerRequest Headers:\n");
         for (int i = 0; i < this.Headers.Count; i++)
         {
             builder.Append("\t");
             builder.Append(this.Headers.GetKey(i));
             builder.Append(" : ");
             builder.Append(this.Headers.Get(i));
             builder.Append("\n");
         }
         Logging.PrintInfo(Logging.HttpListener, this, ".ctor", builder.ToString());
     }
 }
コード例 #3
0
 internal unsafe HttpListenerRequest(System.Net.HttpListenerContext httpContext, RequestContextBase memoryBlob)
 {
     if (Logging.On)
     {
         Logging.PrintInfo(Logging.HttpListener, this, ".ctor", "httpContext#" + ValidationHelper.HashString(httpContext) + " memoryBlob# " + ValidationHelper.HashString((IntPtr)memoryBlob.RequestBlob));
     }
     if (Logging.On)
     {
         Logging.Associate(Logging.HttpListener, this, httpContext);
     }
     this.m_HttpContext  = httpContext;
     this.m_MemoryBlob   = memoryBlob;
     this.m_BoundaryType = BoundaryType.None;
     this.m_RequestId    = memoryBlob.RequestBlob.RequestId;
     this.m_ConnectionId = memoryBlob.RequestBlob.ConnectionId;
     this.m_SslStatus    = (memoryBlob.RequestBlob.pSslInfo == null) ? SslStatus.Insecure : ((memoryBlob.RequestBlob.pSslInfo.SslClientCertNegotiated == 0) ? SslStatus.NoClientCert : SslStatus.ClientCert);
     if ((memoryBlob.RequestBlob.pRawUrl != null) && (memoryBlob.RequestBlob.RawUrlLength > 0))
     {
         this.m_RawUrl = Marshal.PtrToStringAnsi((IntPtr)memoryBlob.RequestBlob.pRawUrl, memoryBlob.RequestBlob.RawUrlLength);
     }
     UnsafeNclNativeMethods.HttpApi.HTTP_COOKED_URL cookedUrl = memoryBlob.RequestBlob.CookedUrl;
     if ((cookedUrl.pHost != null) && (cookedUrl.HostLength > 0))
     {
         this.m_CookedUrlHost = Marshal.PtrToStringUni((IntPtr)cookedUrl.pHost, cookedUrl.HostLength / 2);
     }
     if ((cookedUrl.pAbsPath != null) && (cookedUrl.AbsPathLength > 0))
     {
         this.m_CookedUrlPath = Marshal.PtrToStringUni((IntPtr)cookedUrl.pAbsPath, cookedUrl.AbsPathLength / 2);
     }
     if ((cookedUrl.pQueryString != null) && (cookedUrl.QueryStringLength > 0))
     {
         this.m_CookedUrlQuery = Marshal.PtrToStringUni((IntPtr)cookedUrl.pQueryString, cookedUrl.QueryStringLength / 2);
     }
     this.m_Version         = new Version(memoryBlob.RequestBlob.Version.MajorVersion, memoryBlob.RequestBlob.Version.MinorVersion);
     this.m_ClientCertState = ListenerClientCertState.NotInitialized;
     this.m_KeepAlive       = TriState.Unspecified;
     if (Logging.On)
     {
         Logging.PrintInfo(Logging.HttpListener, this, ".ctor", "httpContext#" + ValidationHelper.HashString(httpContext) + " RequestUri:" + ValidationHelper.ToString(this.RequestUri) + " Content-Length:" + ValidationHelper.ToString(this.ContentLength64) + " HTTP Method:" + ValidationHelper.ToString(this.HttpMethod));
     }
     if (Logging.On)
     {
         StringBuilder builder = new StringBuilder("HttpListenerRequest Headers:\n");
         for (int i = 0; i < this.Headers.Count; i++)
         {
             builder.Append("\t");
             builder.Append(this.Headers.GetKey(i));
             builder.Append(" : ");
             builder.Append(this.Headers.Get(i));
             builder.Append("\n");
         }
         Logging.PrintInfo(Logging.HttpListener, this, ".ctor", builder.ToString());
     }
 }
コード例 #4
0
        private unsafe void ProcessClientCertificate()
        {
            byte[] buffer;
            if (this.m_ClientCertState == ListenerClientCertState.InProgress)
            {
                throw new InvalidOperationException(SR.GetString("net_listener_callinprogress", new object[] { "GetClientCertificate()/BeginGetClientCertificate()" }));
            }
            this.m_ClientCertState = ListenerClientCertState.InProgress;
            if (this.m_SslStatus == SslStatus.Insecure)
            {
                goto Label_00FD;
            }
            uint sslClientCertInfoSize = 0x5dc;

Label_0044:
            buffer = new byte[sslClientCertInfoSize];
            fixed(byte *numRef = buffer)
            {
                UnsafeNclNativeMethods.HttpApi.HTTP_SSL_CLIENT_CERT_INFO *pSslClientCertInfo = (UnsafeNclNativeMethods.HttpApi.HTTP_SSL_CLIENT_CERT_INFO *)numRef;
                uint pBytesReceived = 0;
                uint num3           = UnsafeNclNativeMethods.HttpApi.HttpReceiveClientCertificate(this.HttpListenerContext.RequestQueueHandle, this.m_ConnectionId, 0, pSslClientCertInfo, sslClientCertInfoSize, &pBytesReceived, null);

                if (num3 == 0xea)
                {
                    sslClientCertInfoSize = pBytesReceived + pSslClientCertInfo->CertEncodedSize;
                    goto Label_0044;
                }
                if ((num3 == 0) && (pSslClientCertInfo != null))
                {
                    if (pSslClientCertInfo->pCertEncoded != null)
                    {
                        try
                        {
                            byte[] destination = new byte[pSslClientCertInfo->CertEncodedSize];
                            Marshal.Copy((IntPtr)pSslClientCertInfo->pCertEncoded, destination, 0, destination.Length);
                            this.m_ClientCertificate = new X509Certificate2(destination);
                        }
                        catch (CryptographicException)
                        {
                        }
                        catch (SecurityException)
                        {
                        }
                    }
                    this.m_ClientCertificateError = (int)pSslClientCertInfo->CertFlags;
                }
            }

Label_00FD:
            this.m_ClientCertState = ListenerClientCertState.Completed;
        }
コード例 #5
0
        private unsafe ListenerClientCertAsyncResult AsyncProcessClientCertificate(AsyncCallback requestCallback, object state)
        {
            if (this.m_ClientCertState == ListenerClientCertState.InProgress)
            {
                throw new InvalidOperationException(SR.GetString("net_listener_callinprogress", new object[] { "GetClientCertificate()/BeginGetClientCertificate()" }));
            }
            this.m_ClientCertState = ListenerClientCertState.InProgress;
            this.HttpListenerContext.EnsureBoundHandle();
            ListenerClientCertAsyncResult result = null;

            if (this.m_SslStatus != SslStatus.Insecure)
            {
                uint size = 0x5dc;
                result = new ListenerClientCertAsyncResult(this, state, requestCallback, size);
                try
                {
                    uint num2;
Label_0058:
                    num2 = 0;
                    uint num3 = UnsafeNclNativeMethods.HttpApi.HttpReceiveClientCertificate(this.HttpListenerContext.RequestQueueHandle, this.m_ConnectionId, 0, result.RequestBlob, size, &num2, result.NativeOverlapped);
                    if (num3 == 0xea)
                    {
                        UnsafeNclNativeMethods.HttpApi.HTTP_SSL_CLIENT_CERT_INFO *requestBlob = result.RequestBlob;
                        size = num2 + requestBlob->CertEncodedSize;
                        result.Reset(size);
                        goto Label_0058;
                    }
                    if ((num3 != 0) && (num3 != 0x3e5))
                    {
                        throw new HttpListenerException((int)num3);
                    }
                    return(result);
                }
                catch
                {
                    if (result != null)
                    {
                        result.InternalCleanup();
                    }
                    throw;
                }
            }
            result = new ListenerClientCertAsyncResult(this, state, requestCallback, 0);
            result.InvokeCallback();
            return(result);
        }
コード例 #6
0
        private void ProcessClientCertificate()
        {
            if (_clientCertState == ListenerClientCertState.InProgress)
            {
                throw new InvalidOperationException(SR.Format(SR.net_listener_callinprogress, "GetClientCertificate()/BeginGetClientCertificate()"));
            }
            _clientCertState = ListenerClientCertState.InProgress;
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(this);
            }
            //--------------------------------------------------------------------
            //When you configure the HTTP.SYS with a flag value 2
            //which means require client certificates, when the client makes the
            //initial SSL connection, server (HTTP.SYS) demands the client certificate
            //
            //Some apps may not want to demand the client cert at the beginning
            //perhaps server the default.htm. In this case the HTTP.SYS is configured
            //with a flag value other than 2, whcih means that the client certificate is
            //optional.So initially when SSL is established HTTP.SYS won't ask for client
            //certificate. This works fine for the default.htm in the case above
            //However, if the app wants to demand a client certficate at a later time
            //perhaps showing "YOUR ORDERS" page, then the server wans to demand
            //Client certs. this will inturn makes HTTP.SYS to do the
            //SEC_I_RENOGOTIATE through which the client cert demand is made
            //
            //THE BUG HERE IS THAT PRIOR TO QFE 4796, we call
            //GET Client certificate native API ONLY WHEN THE HTTP.SYS is configured with
            //flag = 2. Which means that apps using HTTPListener will not be able to
            //demand a client cert at a later point
            //
            //The fix here is to demand the client cert when the channel is NOT INSECURE
            //which means whether the client certs are requried at the beginning or not,
            //if this is an SSL connection, Call HttpReceiveClientCertificate, thus
            //starting the cert negotiation at that point
            //
            //NOTE: WHEN CALLING THE HttpReceiveClientCertificate, you can get
            //ERROR_NOT_FOUND - which means the client did not provide the cert
            //If this is important, the server should respond with 403 forbidden
            //HTTP.SYS will not do this for you automatically ***
            //--------------------------------------------------------------------
            if (_sslStatus != SslStatus.Insecure)
            {
                // at this point we know that DefaultFlags has the 2 bit set (Negotiate Client certificate)
                // the cert, though might or might not be there. try to retrieve it
                // this number is the same that IIS decided to use
                uint size = CertBoblSize;
                while (true)
                {
                    byte[] clientCertInfoBlob = new byte[checked ((int)size)];
                    fixed(byte *pClientCertInfoBlob = &clientCertInfoBlob[0])
                    {
                        Interop.HttpApi.HTTP_SSL_CLIENT_CERT_INFO *pClientCertInfo = (Interop.HttpApi.HTTP_SSL_CLIENT_CERT_INFO *)pClientCertInfoBlob;

                        if (NetEventSource.IsEnabled)
                        {
                            NetEventSource.Info(this, "Calling Interop.HttpApi.HttpReceiveClientCertificate size:" + size);
                        }
                        uint bytesReceived = 0;

                        uint statusCode =
                            Interop.HttpApi.HttpReceiveClientCertificate(
                                HttpListenerContext.RequestQueueHandle,
                                _connectionId,
                                (uint)Interop.HttpApi.HTTP_FLAGS.NONE,
                                pClientCertInfo,
                                size,
                                &bytesReceived,
                                null);

                        if (NetEventSource.IsEnabled)
                        {
                            NetEventSource.Info(this, "Call to Interop.HttpApi.HttpReceiveClientCertificate returned:" + statusCode + " bytesReceived:" + bytesReceived);
                        }
                        if (statusCode == Interop.HttpApi.ERROR_MORE_DATA)
                        {
                            size = bytesReceived + pClientCertInfo->CertEncodedSize;
                            continue;
                        }
                        else if (statusCode == Interop.HttpApi.ERROR_SUCCESS)
                        {
                            if (pClientCertInfo != null)
                            {
                                if (NetEventSource.IsEnabled)
                                {
                                    NetEventSource.Info(this, $"pClientCertInfo:{(IntPtr)pClientCertInfo} pClientCertInfo->CertFlags: {pClientCertInfo->CertFlags} pClientCertInfo->CertEncodedSize: {pClientCertInfo->CertEncodedSize} pClientCertInfo->pCertEncoded: {(IntPtr)pClientCertInfo->pCertEncoded} pClientCertInfo->Token: {(IntPtr)pClientCertInfo->Token} pClientCertInfo->CertDeniedByMapper: {pClientCertInfo->CertDeniedByMapper}");
                                }

                                if (pClientCertInfo->pCertEncoded != null)
                                {
                                    try
                                    {
                                        byte[] certEncoded = new byte[pClientCertInfo->CertEncodedSize];
                                        Marshal.Copy((IntPtr)pClientCertInfo->pCertEncoded, certEncoded, 0, certEncoded.Length);
                                        _clientCertificate = new X509Certificate2(certEncoded);
                                    }
                                    catch (CryptographicException exception)
                                    {
                                        if (NetEventSource.IsEnabled)
                                        {
                                            NetEventSource.Info(this, $"CryptographicException={exception}");
                                        }
                                    }
                                    catch (SecurityException exception)
                                    {
                                        if (NetEventSource.IsEnabled)
                                        {
                                            NetEventSource.Info(this, $"SecurityException={exception}");
                                        }
                                    }
                                }
                                _clientCertificateError = (int)pClientCertInfo->CertFlags;
                            }
                        }
                        else
                        {
                            Debug.Assert(statusCode == Interop.HttpApi.ERROR_NOT_FOUND,
                                         $"Call to Interop.HttpApi.HttpReceiveClientCertificate() failed with statusCode {statusCode}.");
                        }
                    }

                    break;
                }
            }
            _clientCertState = ListenerClientCertState.Completed;
        }
コード例 #7
0
        private ListenerClientCertAsyncResult AsyncProcessClientCertificate(AsyncCallback requestCallback, object state)
        {
            if (_clientCertState == ListenerClientCertState.InProgress)
            {
                throw new InvalidOperationException(SR.Format(SR.net_listener_callinprogress, "GetClientCertificate()/BeginGetClientCertificate()"));
            }
            _clientCertState = ListenerClientCertState.InProgress;

            ListenerClientCertAsyncResult asyncResult = null;

            //--------------------------------------------------------------------
            //When you configure the HTTP.SYS with a flag value 2
            //which means require client certificates, when the client makes the
            //initial SSL connection, server (HTTP.SYS) demands the client certificate
            //
            //Some apps may not want to demand the client cert at the beginning
            //perhaps server the default.htm. In this case the HTTP.SYS is configured
            //with a flag value other than 2, whcih means that the client certificate is
            //optional.So initially when SSL is established HTTP.SYS won't ask for client
            //certificate. This works fine for the default.htm in the case above
            //However, if the app wants to demand a client certficate at a later time
            //perhaps showing "YOUR ORDERS" page, then the server wans to demand
            //Client certs. this will inturn makes HTTP.SYS to do the
            //SEC_I_RENOGOTIATE through which the client cert demand is made
            //
            //THE BUG HERE IS THAT PRIOR TO QFE 4796, we call
            //GET Client certificate native API ONLY WHEN THE HTTP.SYS is configured with
            //flag = 2. Which means that apps using HTTPListener will not be able to
            //demand a client cert at a later point
            //
            //The fix here is to demand the client cert when the channel is NOT INSECURE
            //which means whether the client certs are requried at the beginning or not,
            //if this is an SSL connection, Call HttpReceiveClientCertificate, thus
            //starting the cert negotiation at that point
            //
            //NOTE: WHEN CALLING THE HttpReceiveClientCertificate, you can get
            //ERROR_NOT_FOUND - which means the client did not provide the cert
            //If this is important, the server should respond with 403 forbidden
            //HTTP.SYS will not do this for you automatically ***
            //--------------------------------------------------------------------
            if (_sslStatus != SslStatus.Insecure)
            {
                // at this point we know that DefaultFlags has the 2 bit set (Negotiate Client certificate)
                // the cert, though might or might not be there. try to retrieve it
                // this number is the same that IIS decided to use
                uint size = CertBoblSize;
                asyncResult = new ListenerClientCertAsyncResult(HttpListenerContext.RequestQueueBoundHandle, this, state, requestCallback, size);
                try
                {
                    while (true)
                    {
                        if (NetEventSource.IsEnabled)
                        {
                            NetEventSource.Info(this, "Calling Interop.HttpApi.HttpReceiveClientCertificate size:" + size);
                        }
                        uint bytesReceived = 0;

                        uint statusCode =
                            Interop.HttpApi.HttpReceiveClientCertificate(
                                HttpListenerContext.RequestQueueHandle,
                                _connectionId,
                                (uint)Interop.HttpApi.HTTP_FLAGS.NONE,
                                asyncResult.RequestBlob,
                                size,
                                &bytesReceived,
                                asyncResult.NativeOverlapped);

                        if (NetEventSource.IsEnabled)
                        {
                            NetEventSource.Info(this, "Call to Interop.HttpApi.HttpReceiveClientCertificate returned:" + statusCode + " bytesReceived:" + bytesReceived);
                        }
                        if (statusCode == Interop.HttpApi.ERROR_MORE_DATA)
                        {
                            Interop.HttpApi.HTTP_SSL_CLIENT_CERT_INFO *pClientCertInfo = asyncResult.RequestBlob;
                            size = bytesReceived + pClientCertInfo->CertEncodedSize;
                            asyncResult.Reset(size);
                            continue;
                        }
                        if (statusCode != Interop.HttpApi.ERROR_SUCCESS &&
                            statusCode != Interop.HttpApi.ERROR_IO_PENDING)
                        {
                            // someother bad error, possible return values are:
                            // ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED
                            // Also ERROR_BAD_DATA if we got it twice or it reported smaller size buffer required.
                            throw new HttpListenerException((int)statusCode);
                        }

                        if (statusCode == Interop.HttpApi.ERROR_SUCCESS &&
                            HttpListener.SkipIOCPCallbackOnSuccess)
                        {
                            asyncResult.IOCompleted(statusCode, bytesReceived);
                        }
                        break;
                    }
                }
                catch
                {
                    asyncResult?.InternalCleanup();
                    throw;
                }
            }
            else
            {
                asyncResult = new ListenerClientCertAsyncResult(HttpListenerContext.RequestQueueBoundHandle, this, state, requestCallback, 0);
                asyncResult.InvokeCallback();
            }
            return(asyncResult);
        }
コード例 #8
0
        private void ProcessClientCertificate()
        {
            if (_clientCertState == ListenerClientCertState.InProgress)
                throw new InvalidOperationException(SR.Format(SR.net_listener_callinprogress, "GetClientCertificate()/BeginGetClientCertificate()"));
            _clientCertState = ListenerClientCertState.InProgress;
            if (NetEventSource.IsEnabled) NetEventSource.Info(this);
            //--------------------------------------------------------------------
            //When you configure the HTTP.SYS with a flag value 2
            //which means require client certificates, when the client makes the
            //initial SSL connection, server (HTTP.SYS) demands the client certificate
            //
            //Some apps may not want to demand the client cert at the beginning
            //perhaps server the default.htm. In this case the HTTP.SYS is configured
            //with a flag value other than 2, whcih means that the client certificate is
            //optional.So intially when SSL is established HTTP.SYS won't ask for client
            //certificate. This works fine for the default.htm in the case above
            //However, if the app wants to demand a client certficate at a later time
            //perhaps showing "YOUR ORDERS" page, then the server wans to demand
            //Client certs. this will inturn makes HTTP.SYS to do the
            //SEC_I_RENOGOTIATE through which the client cert demand is made
            //
            //THE BUG HERE IS THAT PRIOR TO QFE 4796, we call
            //GET Client certificate native API ONLY WHEN THE HTTP.SYS is configured with
            //flag = 2. Which means that apps using HTTPListener will not be able to
            //demand a client cert at a later point
            //
            //The fix here is to demand the client cert when the channel is NOT INSECURE
            //which means whether the client certs are requried at the beginning or not,
            //if this is an SSL connection, Call HttpReceiveClientCertificate, thus
            //starting the cert negotiation at that point
            //
            //NOTE: WHEN CALLING THE HttpReceiveClientCertificate, you can get
            //ERROR_NOT_FOUND - which means the client did not provide the cert
            //If this is important, the server should respond with 403 forbidden
            //HTTP.SYS will not do this for you automatically ***
            //--------------------------------------------------------------------
            if (_sslStatus != SslStatus.Insecure)
            {
                // at this point we know that DefaultFlags has the 2 bit set (Negotiate Client certificate)
                // the cert, though might or might not be there. try to retrieve it
                // this number is the same that IIS decided to use
                uint size = CertBoblSize;
                while (true)
                {
                    byte[] clientCertInfoBlob = new byte[checked((int)size)];
                    fixed (byte* pClientCertInfoBlob = clientCertInfoBlob)
                    {
                        Interop.HttpApi.HTTP_SSL_CLIENT_CERT_INFO* pClientCertInfo = (Interop.HttpApi.HTTP_SSL_CLIENT_CERT_INFO*)pClientCertInfoBlob;

                        if (NetEventSource.IsEnabled) NetEventSource.Info(this, "Calling Interop.HttpApi.HttpReceiveClientCertificate size:" + size);
                        uint bytesReceived = 0;

                        uint statusCode =
                            Interop.HttpApi.HttpReceiveClientCertificate(
                                HttpListenerContext.RequestQueueHandle,
                                _connectionId,
                                (uint)Interop.HttpApi.HTTP_FLAGS.NONE,
                                pClientCertInfo,
                                size,
                                &bytesReceived,
                                null);

                        if (NetEventSource.IsEnabled) NetEventSource.Info(this,
                            "Call to Interop.HttpApi.HttpReceiveClientCertificate returned:" + statusCode + " bytesReceived:" + bytesReceived);
                        if (statusCode == Interop.HttpApi.ERROR_MORE_DATA)
                        {
                            size = bytesReceived + pClientCertInfo->CertEncodedSize;
                            continue;
                        }
                        else if (statusCode == Interop.HttpApi.ERROR_SUCCESS)
                        {
                            if (pClientCertInfo != null)
                            {
                                if (NetEventSource.IsEnabled) NetEventSource.Info(this,
                                    $"pClientCertInfo:{(IntPtr)pClientCertInfo} pClientCertInfo->CertFlags: {pClientCertInfo->CertFlags} pClientCertInfo->CertEncodedSize: {pClientCertInfo->CertEncodedSize} pClientCertInfo->pCertEncoded: {(IntPtr)pClientCertInfo->pCertEncoded} pClientCertInfo->Token: {(IntPtr)pClientCertInfo->Token} pClientCertInfo->CertDeniedByMapper: {pClientCertInfo->CertDeniedByMapper}");

                                if (pClientCertInfo->pCertEncoded != null)
                                {
                                    try
                                    {
                                        byte[] certEncoded = new byte[pClientCertInfo->CertEncodedSize];
                                        Marshal.Copy((IntPtr)pClientCertInfo->pCertEncoded, certEncoded, 0, certEncoded.Length);
                                        _clientCertificate = new X509Certificate2(certEncoded);
                                    }
                                    catch (CryptographicException exception)
                                    {
                                        if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"CryptographicException={exception}");
                                    }
                                    catch (SecurityException exception)
                                    {
                                        if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"SecurityException={exception}");
                                    }
                                }
                                _clientCertificateError = (int)pClientCertInfo->CertFlags;
                            }
                        }
                        else
                        {
                            Debug.Assert(statusCode == Interop.HttpApi.ERROR_NOT_FOUND,
                                $"Call to Interop.HttpApi.HttpReceiveClientCertificate() failed with statusCode {statusCode}.");
                        }
                    }
                    break;
                }
            }
            _clientCertState = ListenerClientCertState.Completed;
        }
コード例 #9
0
        private ListenerClientCertAsyncResult AsyncProcessClientCertificate(AsyncCallback requestCallback, object state)
        {
            if (_clientCertState == ListenerClientCertState.InProgress)
                throw new InvalidOperationException(SR.Format(SR.net_listener_callinprogress, "GetClientCertificate()/BeginGetClientCertificate()"));
            _clientCertState = ListenerClientCertState.InProgress;

            ListenerClientCertAsyncResult asyncResult = null;
            //--------------------------------------------------------------------
            //When you configure the HTTP.SYS with a flag value 2
            //which means require client certificates, when the client makes the
            //initial SSL connection, server (HTTP.SYS) demands the client certificate
            //
            //Some apps may not want to demand the client cert at the beginning
            //perhaps server the default.htm. In this case the HTTP.SYS is configured
            //with a flag value other than 2, whcih means that the client certificate is
            //optional.So intially when SSL is established HTTP.SYS won't ask for client
            //certificate. This works fine for the default.htm in the case above
            //However, if the app wants to demand a client certficate at a later time
            //perhaps showing "YOUR ORDERS" page, then the server wans to demand
            //Client certs. this will inturn makes HTTP.SYS to do the
            //SEC_I_RENOGOTIATE through which the client cert demand is made
            //
            //THE BUG HERE IS THAT PRIOR TO QFE 4796, we call
            //GET Client certificate native API ONLY WHEN THE HTTP.SYS is configured with
            //flag = 2. Which means that apps using HTTPListener will not be able to
            //demand a client cert at a later point
            //
            //The fix here is to demand the client cert when the channel is NOT INSECURE
            //which means whether the client certs are requried at the beginning or not,
            //if this is an SSL connection, Call HttpReceiveClientCertificate, thus
            //starting the cert negotiation at that point
            //
            //NOTE: WHEN CALLING THE HttpReceiveClientCertificate, you can get
            //ERROR_NOT_FOUND - which means the client did not provide the cert
            //If this is important, the server should respond with 403 forbidden
            //HTTP.SYS will not do this for you automatically ***
            //--------------------------------------------------------------------
            if (_sslStatus != SslStatus.Insecure)
            {
                // at this point we know that DefaultFlags has the 2 bit set (Negotiate Client certificate)
                // the cert, though might or might not be there. try to retrieve it
                // this number is the same that IIS decided to use
                uint size = CertBoblSize;
                asyncResult = new ListenerClientCertAsyncResult(HttpListenerContext.RequestQueueBoundHandle, this, state, requestCallback, size);
                try
                {
                    while (true)
                    {
                        if (NetEventSource.IsEnabled) NetEventSource.Info(this, "Calling Interop.HttpApi.HttpReceiveClientCertificate size:" + size);
                        uint bytesReceived = 0;

                        uint statusCode =
                            Interop.HttpApi.HttpReceiveClientCertificate(
                                HttpListenerContext.RequestQueueHandle,
                                _connectionId,
                                (uint)Interop.HttpApi.HTTP_FLAGS.NONE,
                                asyncResult.RequestBlob,
                                size,
                                &bytesReceived,
                                asyncResult.NativeOverlapped);

                        if (NetEventSource.IsEnabled) NetEventSource.Info(this,
                            "Call to Interop.HttpApi.HttpReceiveClientCertificate returned:" + statusCode + " bytesReceived:" + bytesReceived);
                        if (statusCode == Interop.HttpApi.ERROR_MORE_DATA)
                        {
                            Interop.HttpApi.HTTP_SSL_CLIENT_CERT_INFO* pClientCertInfo = asyncResult.RequestBlob;
                            size = bytesReceived + pClientCertInfo->CertEncodedSize;
                            asyncResult.Reset(size);
                            continue;
                        }
                        if (statusCode != Interop.HttpApi.ERROR_SUCCESS &&
                            statusCode != Interop.HttpApi.ERROR_IO_PENDING)
                        {
                            // someother bad error, possible return values are:
                            // ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED
                            // Also ERROR_BAD_DATA if we got it twice or it reported smaller size buffer required.
                            throw new HttpListenerException((int)statusCode);
                        }

                        if (statusCode == Interop.HttpApi.ERROR_SUCCESS &&
                            HttpListener.SkipIOCPCallbackOnSuccess)
                        {
                            asyncResult.IOCompleted(statusCode, bytesReceived);
                        }
                        break;
                    }
                }
                catch
                {
                    asyncResult?.InternalCleanup();
                    throw;
                }
            }
            else
            {
                asyncResult = new ListenerClientCertAsyncResult(HttpListenerContext.RequestQueueBoundHandle, this, state, requestCallback, 0);
                asyncResult.InvokeCallback();
            }
            return asyncResult;
        }
コード例 #10
0
        internal HttpListenerRequest(HttpListenerContext httpContext, RequestContextBase memoryBlob)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(this, $"httpContext:${httpContext} memoryBlob {((IntPtr)memoryBlob.RequestBlob)}");
                NetEventSource.Associate(this, httpContext);
            }
            _httpContext = httpContext;
            _memoryBlob = memoryBlob;
            _boundaryType = BoundaryType.None;

            // Set up some of these now to avoid refcounting on memory blob later.
            _requestId = memoryBlob.RequestBlob->RequestId;
            _connectionId = memoryBlob.RequestBlob->ConnectionId;
            _sslStatus = memoryBlob.RequestBlob->pSslInfo == null ? SslStatus.Insecure :
                memoryBlob.RequestBlob->pSslInfo->SslClientCertNegotiated == 0 ? SslStatus.NoClientCert :
                SslStatus.ClientCert;
            if (memoryBlob.RequestBlob->pRawUrl != null && memoryBlob.RequestBlob->RawUrlLength > 0)
            {
                _rawUrl = Marshal.PtrToStringAnsi((IntPtr)memoryBlob.RequestBlob->pRawUrl, memoryBlob.RequestBlob->RawUrlLength);
            }

            Interop.HttpApi.HTTP_COOKED_URL cookedUrl = memoryBlob.RequestBlob->CookedUrl;
            if (cookedUrl.pHost != null && cookedUrl.HostLength > 0)
            {
                _cookedUrlHost = Marshal.PtrToStringUni((IntPtr)cookedUrl.pHost, cookedUrl.HostLength / 2);
            }
            if (cookedUrl.pAbsPath != null && cookedUrl.AbsPathLength > 0)
            {
                _cookedUrlPath = Marshal.PtrToStringUni((IntPtr)cookedUrl.pAbsPath, cookedUrl.AbsPathLength / 2);
            }
            if (cookedUrl.pQueryString != null && cookedUrl.QueryStringLength > 0)
            {
                _cookedUrlQuery = Marshal.PtrToStringUni((IntPtr)cookedUrl.pQueryString, cookedUrl.QueryStringLength / 2);
            }
            _version = new Version(memoryBlob.RequestBlob->Version.MajorVersion, memoryBlob.RequestBlob->Version.MinorVersion);
            _clientCertState = ListenerClientCertState.NotInitialized;
            _keepAlive = null;
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(this, $"RequestId:{RequestId} ConnectionId:{_connectionId} RawConnectionId:{memoryBlob.RequestBlob->RawConnectionId} UrlContext:{memoryBlob.RequestBlob->UrlContext} RawUrl:{_rawUrl} Version:{_version} Secure:{_sslStatus}");
                NetEventSource.Info(this, $"httpContext:${httpContext} RequestUri:{RequestUri} Content-Length:{ContentLength64} HTTP Method:{HttpMethod}");
            }
            // Log headers
            if (NetEventSource.IsEnabled)
            {
                StringBuilder sb = new StringBuilder("HttpListenerRequest Headers:\n");
                for (int i = 0; i < Headers.Count; i++)
                {
                    sb.Append("\t");
                    sb.Append(Headers.GetKey(i));
                    sb.Append(" : ");
                    sb.Append(Headers.Get(i));
                    sb.Append("\n");
                }
                NetEventSource.Info(this, sb.ToString());
            }
        }
 private unsafe ListenerClientCertAsyncResult AsyncProcessClientCertificate(AsyncCallback requestCallback, object state)
 {
     if (this.m_ClientCertState == ListenerClientCertState.InProgress)
     {
         throw new InvalidOperationException(SR.GetString("net_listener_callinprogress", new object[] { "GetClientCertificate()/BeginGetClientCertificate()" }));
     }
     this.m_ClientCertState = ListenerClientCertState.InProgress;
     this.HttpListenerContext.EnsureBoundHandle();
     ListenerClientCertAsyncResult result = null;
     if (this.m_SslStatus != SslStatus.Insecure)
     {
         uint size = 0x5dc;
         result = new ListenerClientCertAsyncResult(this, state, requestCallback, size);
         try
         {
             uint num2;
         Label_0058:
             num2 = 0;
             uint num3 = UnsafeNclNativeMethods.HttpApi.HttpReceiveClientCertificate(this.HttpListenerContext.RequestQueueHandle, this.m_ConnectionId, 0, result.RequestBlob, size, &num2, result.NativeOverlapped);
             if (num3 == 0xea)
             {
                 UnsafeNclNativeMethods.HttpApi.HTTP_SSL_CLIENT_CERT_INFO* requestBlob = result.RequestBlob;
                 size = num2 + requestBlob->CertEncodedSize;
                 result.Reset(size);
                 goto Label_0058;
             }
             if ((num3 != 0) && (num3 != 0x3e5))
             {
                 throw new HttpListenerException((int) num3);
             }
             return result;
         }
         catch
         {
             if (result != null)
             {
                 result.InternalCleanup();
             }
             throw;
         }
     }
     result = new ListenerClientCertAsyncResult(this, state, requestCallback, 0);
     result.InvokeCallback();
     return result;
 }
 private unsafe void ProcessClientCertificate()
 {
     byte[] buffer;
     if (this.m_ClientCertState == ListenerClientCertState.InProgress)
     {
         throw new InvalidOperationException(SR.GetString("net_listener_callinprogress", new object[] { "GetClientCertificate()/BeginGetClientCertificate()" }));
     }
     this.m_ClientCertState = ListenerClientCertState.InProgress;
     if (this.m_SslStatus == SslStatus.Insecure)
     {
         goto Label_00FD;
     }
     uint sslClientCertInfoSize = 0x5dc;
 Label_0044:
     buffer = new byte[sslClientCertInfoSize];
     fixed (byte* numRef = buffer)
     {
         UnsafeNclNativeMethods.HttpApi.HTTP_SSL_CLIENT_CERT_INFO* pSslClientCertInfo = (UnsafeNclNativeMethods.HttpApi.HTTP_SSL_CLIENT_CERT_INFO*) numRef;
         uint pBytesReceived = 0;
         uint num3 = UnsafeNclNativeMethods.HttpApi.HttpReceiveClientCertificate(this.HttpListenerContext.RequestQueueHandle, this.m_ConnectionId, 0, pSslClientCertInfo, sslClientCertInfoSize, &pBytesReceived, null);
         if (num3 == 0xea)
         {
             sslClientCertInfoSize = pBytesReceived + pSslClientCertInfo->CertEncodedSize;
             goto Label_0044;
         }
         if ((num3 == 0) && (pSslClientCertInfo != null))
         {
             if (pSslClientCertInfo->pCertEncoded != null)
             {
                 try
                 {
                     byte[] destination = new byte[pSslClientCertInfo->CertEncodedSize];
                     Marshal.Copy((IntPtr) pSslClientCertInfo->pCertEncoded, destination, 0, destination.Length);
                     this.m_ClientCertificate = new X509Certificate2(destination);
                 }
                 catch (CryptographicException)
                 {
                 }
                 catch (SecurityException)
                 {
                 }
             }
             this.m_ClientCertificateError = (int) pSslClientCertInfo->CertFlags;
         }
     }
 Label_00FD:
     this.m_ClientCertState = ListenerClientCertState.Completed;
 }
コード例 #13
0
        private void ProcessClientCertificate() {
            if (m_ClientCertState == ListenerClientCertState.InProgress)
                throw new InvalidOperationException(SR.GetString(SR.net_listener_callinprogress, "GetClientCertificate()/BeginGetClientCertificate()"));
            m_ClientCertState = ListenerClientCertState.InProgress;
            GlobalLog.Print("HttpListenerRequest#" + ValidationHelper.HashString(this) + "::ProcessClientCertificate()");
			//--------------------------------------------------------------------
			//When you configure the HTTP.SYS with a flag value 2
			//which means require client certificates, when the client makes the
			//initial SSL connection, server (HTTP.SYS) demands the client certificate
			//
			//Some apps may not want to demand the client cert at the beginning
			//perhaps server the default.htm. In this case the HTTP.SYS is configured
			//with a flag value other than 2, whcih means that the client certificate is
			//optional.So intially when SSL is established HTTP.SYS won't ask for client
			//certificate. This works fine for the default.htm in the case above
			//However, if the app wants to demand a client certficate at a later time
			//perhaps showing "YOUR ORDERS" page, then the server wans to demand
			//Client certs. this will inturn makes HTTP.SYS to do the
			//SEC_I_RENOGOTIATE through which the client cert demand is made
			//
			//THE 














            if (m_SslStatus != SslStatus.Insecure)
            {
                // at this point we know that DefaultFlags has the 2 bit set (Negotiate Client certificate)
                // the cert, though might or might not be there. try to retrieve it
                // this number is the same that IIS decided to use
                uint size = CertBoblSize;
                while (true)
                {
                    byte[] clientCertInfoBlob = new byte[checked((int) size)];
                    fixed (byte* pClientCertInfoBlob = clientCertInfoBlob)
                    {
                        UnsafeNclNativeMethods.HttpApi.HTTP_SSL_CLIENT_CERT_INFO* pClientCertInfo = (UnsafeNclNativeMethods.HttpApi.HTTP_SSL_CLIENT_CERT_INFO*) pClientCertInfoBlob;

                        GlobalLog.Print("HttpListenerRequest#" + ValidationHelper.HashString(this) + "::ProcessClientCertificate() calling UnsafeNclNativeMethods.HttpApi.HttpReceiveClientCertificate size:" + size);
                        uint bytesReceived = 0;

                        uint statusCode =
                            UnsafeNclNativeMethods.HttpApi.HttpReceiveClientCertificate(
                                HttpListenerContext.RequestQueueHandle,
                                m_ConnectionId,
                                (uint)UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE,
                                pClientCertInfo,
                                size,
                                &bytesReceived,
                                null);

                        GlobalLog.Print("HttpListenerRequest#" + ValidationHelper.HashString(this) + "::ProcessClientCertificate() call to UnsafeNclNativeMethods.HttpApi.HttpReceiveClientCertificate returned:" + statusCode + " bytesReceived:" + bytesReceived);
                        if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA) {
                            size = bytesReceived + pClientCertInfo->CertEncodedSize;
                            continue;
                        }
                        else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) {
                            if (pClientCertInfo!=null) {
                                GlobalLog.Print("HttpListenerRequest#" + ValidationHelper.HashString(this) + "::ProcessClientCertificate() pClientCertInfo:" + ValidationHelper.ToString((IntPtr)pClientCertInfo)
                                    + " pClientCertInfo->CertFlags:" + ValidationHelper.ToString(pClientCertInfo->CertFlags)
                                    + " pClientCertInfo->CertEncodedSize:" + ValidationHelper.ToString(pClientCertInfo->CertEncodedSize)
                                    + " pClientCertInfo->pCertEncoded:" + ValidationHelper.ToString((IntPtr)pClientCertInfo->pCertEncoded)
                                    + " pClientCertInfo->Token:" + ValidationHelper.ToString((IntPtr)pClientCertInfo->Token)
                                    + " pClientCertInfo->CertDeniedByMapper:" + ValidationHelper.ToString(pClientCertInfo->CertDeniedByMapper));
                                if (pClientCertInfo->pCertEncoded!=null) {
                                    try {
                                        byte[] certEncoded = new byte[pClientCertInfo->CertEncodedSize];
                                        Marshal.Copy((IntPtr)pClientCertInfo->pCertEncoded, certEncoded, 0, certEncoded.Length);
                                        m_ClientCertificate = new X509Certificate2(certEncoded);
                                    }
                                    catch (CryptographicException exception) {
                                        GlobalLog.Print("HttpListenerRequest#" + ValidationHelper.HashString(this) + "::ProcessClientCertificate() caught CryptographicException in X509Certificate2..ctor():" + ValidationHelper.ToString(exception));
                                    }
                                    catch (SecurityException exception) {
                                        GlobalLog.Print("HttpListenerRequest#" + ValidationHelper.HashString(this) + "::ProcessClientCertificate() caught SecurityException in X509Certificate2..ctor():" + ValidationHelper.ToString(exception));
                                    }
                                }
                                m_ClientCertificateError = (int)pClientCertInfo->CertFlags;
                            }
                        }
                        else {
                            GlobalLog.Assert(statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_NOT_FOUND, "HttpListenerRequest#{0}::ProcessClientCertificate()|Call to UnsafeNclNativeMethods.HttpApi.HttpReceiveClientCertificate() failed with statusCode {1}.", ValidationHelper.HashString(this), statusCode);
                        }
                    }
                    break;
                }
            }
            m_ClientCertState = ListenerClientCertState.Completed;
        }
コード例 #14
0
        private ListenerClientCertAsyncResult AsyncProcessClientCertificate(AsyncCallback requestCallback, object state) {
            if (m_ClientCertState == ListenerClientCertState.InProgress)
                throw new InvalidOperationException(SR.GetString(SR.net_listener_callinprogress, "GetClientCertificate()/BeginGetClientCertificate()"));
            m_ClientCertState = ListenerClientCertState.InProgress;
            HttpListenerContext.EnsureBoundHandle();

            ListenerClientCertAsyncResult asyncResult = null;
			//--------------------------------------------------------------------
			//When you configure the HTTP.SYS with a flag value 2
			//which means require client certificates, when the client makes the
			//initial SSL connection, server (HTTP.SYS) demands the client certificate
			//
			//Some apps may not want to demand the client cert at the beginning
			//perhaps server the default.htm. In this case the HTTP.SYS is configured
			//with a flag value other than 2, whcih means that the client certificate is
			//optional.So intially when SSL is established HTTP.SYS won't ask for client
			//certificate. This works fine for the default.htm in the case above
			//However, if the app wants to demand a client certficate at a later time
			//perhaps showing "YOUR ORDERS" page, then the server wans to demand
			//Client certs. this will inturn makes HTTP.SYS to do the
			//SEC_I_RENOGOTIATE through which the client cert demand is made
			//
			//THE 














            if (m_SslStatus != SslStatus.Insecure)
            {
                // at this point we know that DefaultFlags has the 2 bit set (Negotiate Client certificate)
                // the cert, though might or might not be there. try to retrieve it
                // this number is the same that IIS decided to use
                uint size = CertBoblSize;
                asyncResult = new ListenerClientCertAsyncResult(this, state, requestCallback, size);
                try {
                    while (true)
                    {
                        GlobalLog.Print("HttpListenerRequest#" + ValidationHelper.HashString(this) + "::ProcessClientCertificate() calling UnsafeNclNativeMethods.HttpApi.HttpReceiveClientCertificate size:" + size);
                        uint bytesReceived = 0;

                        uint statusCode =
                            UnsafeNclNativeMethods.HttpApi.HttpReceiveClientCertificate(
                                HttpListenerContext.RequestQueueHandle,
                                m_ConnectionId,
                                (uint)UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE,
                                asyncResult.RequestBlob,
                                size,
                                &bytesReceived,
                                asyncResult.NativeOverlapped);

                        GlobalLog.Print("HttpListenerRequest#" + ValidationHelper.HashString(this) + "::ProcessClientCertificate() call to UnsafeNclNativeMethods.HttpApi.HttpReceiveClientCertificate returned:" + statusCode + " bytesReceived:" + bytesReceived);
                        if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA)
                        {
                            UnsafeNclNativeMethods.HttpApi.HTTP_SSL_CLIENT_CERT_INFO* pClientCertInfo = asyncResult.RequestBlob;
                            size = bytesReceived + pClientCertInfo->CertEncodedSize;
                            asyncResult.Reset(size);
                            continue;
                        }
                        if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
                            statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING) {
                            // someother bad error, possible(?) return values are:
                            // ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED
                            // Also ERROR_BAD_DATA if we got it twice or it reported smaller size buffer required.
                            throw new HttpListenerException((int)statusCode);
                        }

                        if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
                            HttpListener.SkipIOCPCallbackOnSuccess)
                        {
                            asyncResult.IOCompleted(statusCode, bytesReceived);
                        }
                        break;
                    }
                }
                catch {
                    if (asyncResult!=null) {
                        asyncResult.InternalCleanup();
                    }
                    throw;
                }
            } else {
                asyncResult = new ListenerClientCertAsyncResult(this, state, requestCallback, 0);
                asyncResult.InvokeCallback();
            }
            return asyncResult;
        }
コード例 #15
0
        internal HttpListenerRequest(HttpListenerContext httpContext, RequestContextBase memoryBlob)
        {
            if (Logging.On) Logging.PrintInfo(Logging.HttpListener, this, ".ctor", "httpContext#" + ValidationHelper.HashString(httpContext) + " memoryBlob# " + ValidationHelper.HashString((IntPtr) memoryBlob.RequestBlob));
            if(Logging.On)Logging.Associate(Logging.HttpListener, this, httpContext);
            m_HttpContext = httpContext;
            m_MemoryBlob = memoryBlob;
            m_BoundaryType = BoundaryType.None;

            // Set up some of these now to avoid refcounting on memory blob later.
            m_RequestId = memoryBlob.RequestBlob->RequestId;
            m_ConnectionId = memoryBlob.RequestBlob->ConnectionId;
            m_SslStatus = memoryBlob.RequestBlob->pSslInfo == null ? SslStatus.Insecure :
                memoryBlob.RequestBlob->pSslInfo->SslClientCertNegotiated == 0 ? SslStatus.NoClientCert :
                SslStatus.ClientCert;
            if (memoryBlob.RequestBlob->pRawUrl != null && memoryBlob.RequestBlob->RawUrlLength > 0) {
                m_RawUrl = Marshal.PtrToStringAnsi((IntPtr) memoryBlob.RequestBlob->pRawUrl, memoryBlob.RequestBlob->RawUrlLength);
            }
            
            UnsafeNclNativeMethods.HttpApi.HTTP_COOKED_URL cookedUrl = memoryBlob.RequestBlob->CookedUrl;
            if (cookedUrl.pHost != null && cookedUrl.HostLength > 0) {
                m_CookedUrlHost = Marshal.PtrToStringUni((IntPtr)cookedUrl.pHost, cookedUrl.HostLength / 2);
            }
            if (cookedUrl.pAbsPath != null && cookedUrl.AbsPathLength > 0) {
                m_CookedUrlPath = Marshal.PtrToStringUni((IntPtr)cookedUrl.pAbsPath, cookedUrl.AbsPathLength / 2);
            }
            if (cookedUrl.pQueryString != null && cookedUrl.QueryStringLength > 0) {
                m_CookedUrlQuery = Marshal.PtrToStringUni((IntPtr)cookedUrl.pQueryString, cookedUrl.QueryStringLength / 2);
            }
            m_Version = new Version(memoryBlob.RequestBlob->Version.MajorVersion, memoryBlob.RequestBlob->Version.MinorVersion);
            m_ClientCertState = ListenerClientCertState.NotInitialized;
            m_KeepAlive = TriState.Unspecified;
            GlobalLog.Print("HttpListenerContext#" + ValidationHelper.HashString(this) + "::.ctor() RequestId:" + RequestId + " ConnectionId:" + m_ConnectionId + " RawConnectionId:" + memoryBlob.RequestBlob->RawConnectionId + " UrlContext:" + memoryBlob.RequestBlob->UrlContext + " RawUrl:" + m_RawUrl + " Version:" + m_Version.ToString() + " Secure:" + m_SslStatus.ToString());
            if(Logging.On)Logging.PrintInfo(Logging.HttpListener, this, ".ctor", "httpContext#"+ ValidationHelper.HashString(httpContext)+ " RequestUri:" + ValidationHelper.ToString(RequestUri) + " Content-Length:" + ValidationHelper.ToString(ContentLength64) + " HTTP Method:" + ValidationHelper.ToString(HttpMethod));
            // Log headers
            if(Logging.On) {
                StringBuilder sb = new StringBuilder("HttpListenerRequest Headers:\n");
                for (int i=0; i<Headers.Count; i++) {
                    sb.Append("\t");
                    sb.Append(Headers.GetKey(i));
                    sb.Append(" : ");
                    sb.Append(Headers.Get(i));
                    sb.Append("\n");
                }
                Logging.PrintInfo(Logging.HttpListener, this, ".ctor", sb.ToString());
            }
        }