Utility.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / infocard / Service / managed / Microsoft / InfoCards / Utility.cs / 2 / Utility.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
//
// Presharp uses the c# pragma mechanism to supress its warnings. 
// These are not recognised by the base compiler so we need to explictly
// disable the following warnings. See http://winweb/cse/Tools/PREsharp/userguide/default.asp 
// for details. 
//
#pragma warning disable 1634, 1691      // unknown message, unknown pragma 



namespace Microsoft.InfoCards 
{
    using Microsoft.Win32.SafeHandles; 
    using System; 
    using System.Xml;
    using System.ComponentModel; 
    using System.Diagnostics;
    using System.Security.Principal;
    using System.Security.Cryptography;
    using System.ServiceModel; 
    using System.ServiceModel.Description;
    using System.ServiceModel.Channels; 
    using System.ServiceModel.Security.Tokens; 
    using System.Threading;
    using System.Runtime.InteropServices; 
    using IDT = Microsoft.InfoCards.Diagnostics.InfoCardTrace;
    using System.IO;
    using System.Text;
    using System.Collections; 
    using System.Collections.Generic;
    using System.Collections.Specialized; 
    using System.Security.Cryptography.X509Certificates; 
    using System.IdentityModel.Tokens;
    using System.Runtime.CompilerServices; 
    using System.Net;
    using System.Collections.ObjectModel;

 
    //
    // Summary: 
    // This class contains basic utility routines that don't seem to go anywhere else but are useful to 
    // multiple classes.
    // 
    internal static class Utility
    {
        //
        // Summary: 
        // Given an RPC binding handle returns the WindowsIdentity of the caller.
        // 
        // Parameters: 
        // rpcBindingHandle    - The RPC binding handle from which the WindowsIdentity should be derived.
        // 
        static public WindowsIdentity GetWindowsIdentity( IntPtr rpcBindingHandle )
        {
            uint err;
            WindowsIdentity id; 
            IDT.ThrowInvalidArgumentConditional( IntPtr.Zero == rpcBindingHandle, "rpcBindingHandle" );
 
            err = NativeMethods.RpcImpersonateClient( rpcBindingHandle ); 
            if( 0 != err )
            { 
                throw IDT.ThrowHelperError(
                                new CommunicationException( SR.GetString( SR.ServiceInvalidCallerToken ),
                                                            new Win32Exception( (int)err ) ) );
            } 

            try 
            { 
                id = WindowsIdentity.GetCurrent( true );
            } 
            finally
            {
                err = NativeMethods.RpcRevertToSelfEx( rpcBindingHandle );
                IDT.Assert( 0 == err, "rpcIdentity" ); 
            }
 
 
            return id;
        } 
        //
        // Summary:
        // Given an RPC binding handle, returns the pid of the calling process.
        // 
        // Parameters:
        // rpcBindingHandle    - The RPC binding handle from which the pid should be obtained. 
        // 
        static public uint GetRpcClientPid( IntPtr rpcBindingHandle )
        { 
            uint pid;
            uint err;

            err = NativeMethods.I_RpcBindingInqLocalClientPID( rpcBindingHandle, out pid ); 
            if( 0 != err )
            { 
                throw IDT.ThrowHelperError( new Win32Exception( ( int )err ) ); 
            }
 
            return pid;
        }

        // 
        // Summary:
        // A managed version of ZeroMemory for zeroing native buffers. 
        // 
        // Parameters:
        // ptr   - A pointer to a buffer to zero. 
        // count - The length of the buffer in bytes.
        //
        public unsafe static void ClearUnsafeMemory( IntPtr ptr, int count )
        { 
            IDT.DebugAssert( IntPtr.Zero != ptr, "attempt to =zero a null pointer" );
            IDT.DebugAssert( count > 0, "attempt to zero 0 bytes" ); 
 
            //
            // Presharp: ZeroMemory does not give us any indication of whether an error has occured 
            //
#pragma warning suppress 56523
            NativeMethods.ZeroMemory( ptr, count );
        } 

        // 
        // Summary: 
        // Checks if the process associated with the native handle passed in has exited and throws an exception if so.
        // 
        // Parameters:
        // processHandle  - The handle of the process to check.
        //
        static public void ThrowIfProcessExited( SafeWaitHandle processHandle ) 
        {
 
            using( AutoResetEvent autoevent = new AutoResetEvent( false ) ) 
            {
                autoevent.SafeWaitHandle = processHandle; 
                bool signaled = autoevent.WaitOne( 0, false );
                if( signaled )
                {
                    // 
                    // The handle was signaled.
                    // 
                    throw IDT.ThrowHelperError( new InvalidOperationException( SR.GetString( SR.ServiceProcessHasExited ) ) ); 
                }
            } 
        }

        static public void SerializeString( System.IO.BinaryWriter writer, string str )
        { 
            Int32 length = 0;
 
            if( String.IsNullOrEmpty( str ) ) 
            {
                writer.Write( length ); 
            }
            else
            {
                writer.Write( ( Int32 )str.Length ); 
                writer.Write( str.ToCharArray() );
            } 
        } 

        static public void SerializeUri( System.IO.BinaryWriter writer, Uri uri ) 
        {
            if( null == uri )
            {
                SerializeString( writer, null ); 
            }
            else 
            { 
                SerializeString( writer, uri.ToString() );
            } 
        }

        static public void SerializeBytes( System.IO.BinaryWriter writer, byte[ ] bytes )
        { 
            int length = 0;
            if( null != bytes ) 
            { 
                length = bytes.Length;
            } 
            SerializeBytes( writer, bytes, 0, length );
        }

        static public void SerializeBytes( System.IO.BinaryWriter writer, byte[ ] bytes, int startOffset, int count ) 
        {
            Int32 length = 0; 
            if( null == bytes ) 
            {
                writer.Write( ( Int32 )length ); 
            }
            else
            {
                writer.Write( count ); 
                writer.Write( bytes, startOffset, count );
            } 
        } 

        static public string DeserializeString( System.IO.BinaryReader reader ) 
        {
            return new String( reader.ReadChars( reader.ReadInt32() ) );
        }
 
        static public Uri DeserializeUri( System.IO.BinaryReader reader )
        { 
            return new System.Uri( DeserializeString( reader ) ); 
        }
 
        static public bool CompareUri( string first, string second )
        {

            try 
            {
                return CompareUri( new Uri( first ), new Uri( second ) ); 
            } 
            catch( UriFormatException e )
            { 
                throw IDT.ThrowHelperError(
                    new InfoCardArgumentException( SR.GetString( SR.InvalidUriFormat ), e ) );
            }
        } 

 
        static public bool CompareUri( Uri first, Uri second ) 
        {
            return ( first == second ); 

        }

 
        //
        // Summary: 
        //   Return true if array is null or empty. 
        //   In our serailization, a null array is read back (deserialized)
        //   as an array with 0 count. I.e. not null. This method can be used to 
        //   identify cases where we do not expect a zero length array
        //
        static public bool ArrayIsNullOrEmpty( Array inArray )
        { 
            if ( null == inArray || 0 == inArray.Length )
            { 
                return true; 
            }
            else 
            {
                return false;
            }
        } 

 
        // 
        // Summary:
        //  This method retrieves the local handle from the remote handle.  This is a private method used by public 
        //  methods that return a particular type of safe handle.
        //
        // Parameters:
        //  hRemote - The remote handle 
        //  remotePid - PID of the remote process
        // 
        // Returns: 
        //  A locally valid Handle in the form of an IntPtr.
        // 
        static public SafeWaitHandle GetLocalHandleFromRemoteHandle( SafeWaitHandle hRemote, int remotePid )
        {
            SafeWaitHandle hLocal;
 
            using( SystemIdentity lsa = new SystemIdentity( false ) )
            { 
                using( SafeNativeHandle hProc = NativeMethods.OpenProcess( 
                    NativeMethods.PROCESS_DUP_HANDLE,
                    false, 
                    remotePid ) )
                {

                    if( null == hProc || hProc.IsInvalid ) 
                    {
                        throw IDT.ThrowHelperError( new Win32Exception( Marshal.GetLastWin32Error() ) ); 
                    } 

                    if( !NativeMethods.DuplicateHandle( 
                        hProc,
                        hRemote,
                        new SafeNativeHandle( NativeMethods.GetCurrentProcess(), false),
                        out hLocal, 
                        NativeMethods.EVENT_MODIFY_STATE,
                        false, 
                        0 ) ) 
                    {
                        int error = Marshal.GetLastWin32Error(); 
                        IDT.CloseInvalidOutSafeHandle(hLocal);
                        throw IDT.ThrowHelperError( new Win32Exception( error ) );
                    }
                } 
            }
 
            return hLocal; 
        }
 
        //
        // Summary:
        //  This method retrieves the remote handle from the local handle.  This is a private method used by public
        //  methods that return a particular type of safe handle. 
        //
        // Parameters: 
        //  hRemote - The remote handle 
        //  remotePid - PID of the remote process
        // 
        // Returns:
        //  A locally valid Handle in the form of an IntPtr.
        //
        static public SafeWaitHandle GetRemoteHandleFromLocalHandle( SafeWaitHandle hLocal, Process remoteProcess ) 
        {
            SafeWaitHandle hRemote = null; 
            using( SystemIdentity lsa = new SystemIdentity( false ) ) 
            {
                try 
                {
                    if( !NativeMethods.DuplicateHandle(
                        new SafeNativeHandle( NativeMethods.GetCurrentProcess(), false),
                        hLocal, 
                        new SafeNativeHandle( remoteProcess.Handle, false ),
                        out hRemote, 
                        NativeMethods.EVENT_MODIFY_STATE | NativeMethods.SYNCHRONIZE, 
                        false,
                        0 ) ) 
                    {
                        throw IDT.ThrowHelperError( new Win32Exception( Marshal.GetLastWin32Error() ) );
                    }
 
                    //
                    // NOTE: We must ADDREF the remote handle to prevent the finalizer from 
                    //  attempting to close this handle. 
                    //
                    bool rel = false; 
                    hRemote.DangerousAddRef( ref rel );
                }
                catch( Exception e )
                { 
                    if( IDT.IsFatal( e ) )
                    { 
                        throw; 
                    }
                } 
            }
            return hRemote;

        } 

 
 
        //
        // Summary: 
        //  This method creates a job object with a security descriptor. The trusted
        // user is allowed access to the job.
        //
        // Parameters: 
        //  trustedUserSid - string of trusted user.
        // 
        // Returns: 
        //  A SafeJobHandle object representing the job handle.
        // 
        static public SafeJobHandle CreateJobObjectWithSdHelper( string trustedUserSid )
        {
            SafeJobHandle jobHandle = new SafeJobHandle();
            RuntimeHelpers.PrepareConstrainedRegions(); 
            try
            { 
            } 
            finally
            { 
                IntPtr ptrHandle = IntPtr.Zero;
                uint error = NativeMcppMethods.CreateJobObjectWithSD( ref ptrHandle, trustedUserSid );

                if( 0 == error ) 
                {
                    jobHandle.UpdateHandle( ptrHandle ); 
                } 
                else
                { 
                    throw IDT.ThrowHelperError( new Win32Exception( (int) error ) );
                }
            }
            return jobHandle; 
        }
 
        // 
        // Summary:
        //  This method reads a handle from a BinaryReader 
        //
        // Parameters:
        //  br - The BinaryReader to read from.
        // 
        public static IntPtr ReadHandle( BinaryReader br )
        { 
            IntPtr handleToReturn = IntPtr.Zero; 

            if( 4 == IntPtr.Size ) 
            {
                handleToReturn = ( IntPtr )br.ReadInt32();
            }
            else 
            {
                IDT.DebugAssert( 8 == IntPtr.Size, "Only 32-bit and 64-bit supported currently" ); 
                handleToReturn = ( IntPtr )br.ReadInt64(); 
            }
 
            return handleToReturn;
        }

 
        //
        // Summary 
        //   Create a hash 
        //
        // Parameters 
        //   firstArray - The first array input for the hash
        //   cardId     - The cardId of the InfoCard
        //
        // Returns 
        //  The hash value
        // 
        public static byte[ ] CreateHash( byte[ ] firstArray, Uri cardId ) 
        {
            using( SHA256 sha = new SHA256Managed() ) 
            {
                byte[ ] secondArray = sha.ComputeHash( Encoding.Unicode.GetBytes( cardId.ToString() ) );

                byte[ ] bytesToBeHashed = new byte[ firstArray.Length + secondArray.Length ]; 
                Array.Copy( firstArray, 0, bytesToBeHashed, 0, firstArray.Length );
                Array.Copy( secondArray, 0, bytesToBeHashed, firstArray.Length, secondArray.Length ); 
 
                return sha.ComputeHash( bytesToBeHashed );
            } 
        }

        // Summary
        //   Create a hash using the concatenation of three byte arrays 
        //
        // Parameters 
        //   firstArray - The first array input for the hash 
        //   secondArray - The second array input for the hash
        //   thirdArray - The third array input the hash 
        //
        // Returns
        //  The hash value
        // 
        public static byte[ ] CreateHash( byte[ ] firstArray, byte[ ] secondArray, byte[ ] thirdArray )
        { 
            byte[ ] bytesToBeHashed = new byte[ firstArray.Length + secondArray.Length + thirdArray.Length ]; 
            Array.Copy( firstArray, 0, bytesToBeHashed, 0, firstArray.Length );
            Array.Copy( secondArray, 0, bytesToBeHashed, firstArray.Length, secondArray.Length ); 
            Array.Copy( thirdArray, 0, bytesToBeHashed, firstArray.Length + secondArray.Length, thirdArray.Length );
            using( SHA256 sha = SHA256.Create() )
            {
                return sha.ComputeHash( bytesToBeHashed ); 
            }
        } 
 

 
        //
        // Compare two byte arrays
        //  arr1 - The first byte array
        //  arr2 - The second byte array 
        //
        // Returns 
        //   True if the byte arrays are equal, false otherwise. 
        //
        public static bool CompareByteArrays( byte[ ] arr1, byte[ ] arr2 ) 
        {
            bool result = true;

            if ( ( null == arr1 ) && ( null == arr2 ) ) 
            {
                return true; 
            } 

            if( ( null == arr1 ) || ( null == arr2 ) || ( arr1.Length != arr2.Length ) ) 
            {
                return false;
            }
 
            for( int i = 0; i < arr2.Length; i++ )
            { 
                if( arr1[ i ] != arr2[ i ] ) 
                {
                    result = false; 
                    break;
                }
            }
 
            return result;
 
        } 

        // 
        // Summary:
        //  Find the InfoCard key that was used to create the PPID.
        //
        // Arguments: 
        //  input:      The incoming PPID.
        //  issuerIdentiferAsBytes:  The identifier of the issuer used to generated the incoming PPID 
        //  connection: Connection to the store. To be used to search for the self issued card 
        //              identified by the PPID.
        // 
        public static string ResolvePPID( string input, byte[ ] issuerIdentiferAsBytes, StoreConnection connection )
        {
            string cardId = String.Empty;
 
            byte[ ] PPID = Convert.FromBase64String( input );
 
            // 
            // Retrive a list of all self issued cards
            // 
            List param = new List();
            param.Add( new QueryParameter(
                                 SecondaryIndexDefinition.ObjectTypeIndex,
                                 (Int32)StorableObjectType.InfoCard ) ); 
            param.Add( new QueryParameter(
                                SecondaryIndexDefinition.ProductionServiceIndex, 
                                XmlNames.WSIdentity.SelfIssuerUri ) ); 

            ICollection list = (ICollection)connection.Query( 
                    QueryDetails.FullRow, param.ToArray() );

            if( null != list && list.Count > 0 )
            { 
                foreach( DataRow row in list )
                { 
                    byte[ ] rawForm = row.GetDataField(); 
                    try
                    { 
                        using( MemoryStream stream = new MemoryStream( rawForm ) )
                        {
                            InfoCard card = new InfoCard( stream );
                            byte[] rowPPID = Utility.CreateHash( issuerIdentiferAsBytes, card.Id ); 
                            if( Utility.CompareByteArrays( rowPPID, PPID ) )
                            { 
                                cardId = card.Id.ToString(); 
                                break;
                            } 
                        }
                    }
                    finally
                    { 
                        Array.Clear( rawForm, 0, rawForm.Length );
                    } 
                } 
            }
            return cardId; 
        }


        // 
        // Summary: Created from SSL_HIGHASSURANCE_* constants defined in native service code
        // 
        [Flags] 
        public enum SubjectAtrributeHAFlags
        { 
            NotEnabled = 0x0,
            Enabled = 0x1,
            OrganizationHA = 0x2,	/* SSS_WARNINGS_OFF */
            LocStateCountryHA = 0x4,	/* SSS_WARNINGS_ON */ 
            LogoHA = 0x8
        }; 
 

        // 
        // Summary:
        //  Determine if this X509 Certificate is high assurance or not.
        //
        // Arguments: 
        //  certificate: Certificate being checked for high assurance fields.
        //  supportingCertificates - intermediate certs that may be needed for chain building 
        //                   (if they are not already on the box) 
        //  certFlags: Reference to SubjectAtrributeHAFlags, contains the flags if cert has HA
        //             fields. 
        //
        // Returns:
        //  TRUE if certificate is high assurance, FALSE otherwise.
        // 
        static public bool GetCertHAFlags(
                               X509Certificate2 certificate, 
                               X509Certificate2Collection supportingCertificates, 
                               ref SubjectAtrributeHAFlags certFlags )
        { 
            int certFlagsInt = 0;
            X509Chain chain;

            // 
            // The cert chain should be validated before we look for the HA
            // flags. The HA flags are valid only if the chain is valid. 
            // 
            try
            { 
                //
                // NB: ValidateChain essentially does chain.Build,
                // so there is not much saving if we do chain.Build instead.
                // 
                InfoCardX509Validator.ValidateChain( certificate, supportingCertificates,  out chain );
            } 
            catch ( SecurityTokenValidationException e ) 
            {
                // 
                // Not a valid chain, then it cannot be HA.
                //
                IDT.TraceAndLogException( e );
                return false; 
            }
 
            IDT.Assert( null != chain, "Should have been populated by ValidateChain" ); 

            bool isCertHA = NativeMcppMethods.GetHighAssuranceFlags( 
                             chain.ChainContext,
                             ref certFlagsInt );

            certFlags = ( SubjectAtrributeHAFlags ) certFlagsInt; 

            // 
            // Some verification on the flags we get back 
            //
            if( isCertHA ) 
            {
                if( !IsSubjectAtrributeHAFlagsSet( certFlags, SubjectAtrributeHAFlags.Enabled ) )
                {
 
                    throw IDT.ThrowHelperError(
                                new UntrustedRecipientException( 
                                SR.GetString( SR.InvalidHACertificateStructure ) ) ); 
                }
 
            }

            return isCertHA;
 
        }
 
        // 
        // Summary: Perform bitwise operations on the flag
        // 
        public static bool IsSubjectAtrributeHAFlagsSet(
            SubjectAtrributeHAFlags currentValue,
            SubjectAtrributeHAFlags testFlag )
        { 
            if ( ( testFlag & currentValue ) == testFlag )
            { 
                return true; 
            }
            else 
            {
                return false;
            }
        } 

        // 
        // Summary: Returns length of array that is to be newly allocated 
        // based on the following arguments:
        // 
        // oldSize - oldSize of the array
        // alignToByteBoundary - the length is aligned to this byte boundary
        // percentIncrease - indicates the amount to grow the array by
        // 
        public static int CalculateIncreaseByPercent(int oldSize, int alignToByteBoundary, int percentIncrease)
        { 
            uint boundry = Convert.ToUInt32( alignToByteBoundary ); 
            double newPercentage = 1.0 + ((double)percentIncrease / 100.0);
            uint newSize = Convert.ToUInt32(newPercentage * oldSize); 
            if (0 == newSize)
            {
                newSize = boundry;
            } 
            else if ((newSize % boundry) > 0)
            { 
                newSize += boundry - (newSize % boundry); 
            }
            return Convert.ToInt32(newSize); 
        }


        public static string CreatePpid( byte[] certIdentifierAsBytes, Uri cardId ) 
        {
            byte[] ppid = Utility.CreateHash( certIdentifierAsBytes, 
                                              cardId ); 

            string ppidStr = Convert.ToBase64String( ppid ); 

            return ppidStr;

        } 

        public static EndpointAddress DeriveMexAddress( EndpointAddress epr ) 
        { 
            EndpointAddress mex = null;
 
            try
            {
                XmlReader metadataReader = epr.GetReaderAtMetadata();
 
                if( null != metadataReader )
                { 
                    MetadataSet metadataSet = MetadataSet.ReadFrom( epr.GetReaderAtMetadata() ); 
                    foreach( MetadataSection section in metadataSet.MetadataSections )
                    { 
                        //
                        // We pick the first mex in the list
                        //
                        if( section.Metadata is MetadataReference ) 
                        {
                            // 
                            // Only if the address is an https address 
                            //
                            if( null != ( (MetadataReference)section.Metadata ).Address && 
                                0 == String.Compare( ( (MetadataReference)section.Metadata ).Address.Uri.Scheme, "https", StringComparison.OrdinalIgnoreCase ) )
                            {
                                mex = ( (MetadataReference)section.Metadata ).Address;
                                break; 
                            }
                        } 
                    } 
                }
            } 
            catch( Exception e )
            {
                if( IDT.IsFatal( e ) )
                { 
                    throw;
                } 
            } 

            return mex; 
        }


        // 
        // Summary
        // Creates an xml reader with the appropriate quotas over the given root element. 
        // Parameters 
        // root - the root element of the xml we are creating a reader over.
        // 
        public static XmlDictionaryReader CreateReaderWithQuotas( string root )
        {
            UTF8Encoding utf8 = new UTF8Encoding();
            byte[] rootbytes = utf8.GetBytes( root ); 
            return XmlDictionaryReader.CreateTextReader(    rootbytes
                                                            , 0 
                                                            , rootbytes.GetLength(0) 
                                                            , null
                                                            ,InfoCardConstants.DefaultQuotas, 
                                                            null);
        }

        // 
        // Summary
        // Creates an xml reader with the appropriate quotas over the given stream 
        // Parameters 
        // input - the stream that ww wish to create the reader over
        // 
        public static XmlDictionaryReader CreateReaderWithQuotas( Stream input )
        {
            return XmlDictionaryReader.CreateTextReader(    input,
                                                            null, 
                                                            InfoCardConstants.DefaultQuotas,
                                                            null ); 
        } 

 
        //
        // Sumamry:
        // Reads an incoming base64 string into a byte array.
        // Parameters: 
        // reader - the xml dictionary reader that wraps the stream
        // 
        public static MemoryStream ReadByteStreamFromBase64( XmlReader reader ) 
        {
            MemoryStream output = new MemoryStream(); 
            if( !reader.IsEmptyElement && reader.Read() )
            {
                if( reader.NodeType != XmlNodeType.EndElement )
                { 
                    byte[] block = new byte[1024];
                    int bytesRead = 0; 
 
                    while( (bytesRead = reader.ReadContentAsBase64(block, 0, block.Length) ) > 0 )
                    { 
                        output.Write( block, 0, bytesRead );
                    }
                    output.Flush();
                    output.Seek( 0, SeekOrigin.Begin ); 
                }
            } 
            return output; 
        }
 

        //
        // Summary:
        // This function is invoked for ALL bindings (both during Mex and during RST/RSTR) 
        // with ANY STS that CardSpace interacts with.
        // This function has several purposes: 
        // (a) Update proxy for http transport binding element (if present) 
        // (b) Set the maximum message size default against an indigo binding
        // (b) Throw if transports binding elements other than TcpTransportBindingElement 
        //     or HttpProxyTransportBindingElement are present
        //
        // Parameters:
        // source - the binding to wrap & restrict 
        // proxy - web proxy
        // turnOffClientAuthOnTransport - bool to determine whether auth on the transport binding should be turned off 
        // 
        // Remarks:
        // This function is invoked for BOTH Mex bindings and RST/RSTR bindings 
        //
        //

 

        public static BindingElementCollection UpdateProxyForHttpAndRestrictTransportBinding( 
            BindingElementCollection source, 
            IWebProxy proxy,
            bool turnOffClientAuthOnTransport ) 
        {
            IDT.Assert( null != source, "Do not expect a null bindingElementCollection" );

            if( null == source.Find() ) 
            {
                // 
                // Throw if no transport binding. If we ever reach this case, we will unable 
                // to be able to check constraints on our transport.
                // 
                throw IDT.ThrowHelperError( new UnsupportedPolicyOptionsException() );
            }

            // 
            // Update proxy for http transport binding element (if present)
            // 
            BindingElementCollection bindings = HttpProxyTransportBindingElement.ReplaceHttpTransportWithProxy( 
                source, proxy, turnOffClientAuthOnTransport );
 

            TransportBindingElement transport = bindings.Find();
            IDT.Assert( null != transport, "We ensured there is a TransportBindingElement at the start of this function" );
 

            // 
            // Set the maximum message size default against an indigo binding 
            //
            transport.MaxReceivedMessageSize = InfoCardConstants.MaximumMessageSize; 

            //
            // Allow only http(s) or netTcp transports
            // 
            if(  !( transport is TcpTransportBindingElement ) &&
                 !( transport is HttpProxyTransportBindingElement ) ) 
            { 
                IDT.Assert( null == ( transport as HttpTransportBindingElement ),
                        "Http(s)TransportBindingElement should have been replaced by HttpProxyTransportBindingElement above" ); 

                //
                // Block PeerTransportBindingElement, NamedPipeTransportBindingElement,
                // MsmqTransportBindingElement, MsmqIntegrationBindingElement, and 
                // any other customer written transports.
                // 
                throw IDT.ThrowHelperError( new UnsupportedPolicyOptionsException() ); 

            } 

            //
            // HttpTransportBinding element's AuthenticationScheme has been already set to Anonymous
            // when we wrapped with proxy. Just make sure we only allow SslStreamSecurityBindingElement if we 
            // want to turn off client auth. Note: SslStreamSecurityBindingElement is allowed because the underlying SslStream
            // doesn't do any authentication other than the cert validation 
            // 
            if( turnOffClientAuthOnTransport )
            { 
                Collection subes = bindings.FindAll();

                IDT.Assert(
                    ( null != subes ) && ( 1 >= subes.Count ), 
                    "Should not be null (even if empty) and there should be at most one StreamUpgradeBindingElement" );
 
                foreach( StreamUpgradeBindingElement sube in subes ) 
                {
                    // 
                    // Only SslStreamSecurityBindingElement is allowed. WindowsStreamSecurityBindingElement is NOT.
                    //
                    if( null == ( sube as SslStreamSecurityBindingElement ) )
                    { 
                        throw IDT.ThrowHelperError( new UnsupportedPolicyOptionsException() );
                    } 
                } 
            }
 
            return bindings;
        }

 

        // 
        // Sumamry: 
        // Kills the specified process and returns true if the operation was
        // successful, false if it was an exception that we can ignore. 
        // This can happen if the process is terminating when we call kill
        // or has already been terminated when we call kill.
        //
        // Parameters: 
        //     p - Process to kill.
        // 
        // Return true if we could kill the process or false if there was an 
        // expected exception.
        // 
        public static bool KillHelper( Process p )
        {
            bool fProcessKilledSuccessfully = false;;
 
            if ( false == p.HasExited )
            { 
                try 
                {
                    p.Kill(); 
                    fProcessKilledSuccessfully = true;
                }
                catch( InvalidOperationException )
                { 
                    //
                    // If the process has already terminated then, we can get 
                    // this exception. 
                    //
                    ; 
                }
                catch( Win32Exception e )
                {
                    // 
                    // We can get access denied if the process is currently terminating.
                    // 
                    if( NativeMethods.ERROR_ACCESS_DENIED != ( ( Win32Exception ) e ).NativeErrorCode ) 
                    {
                        throw e; 
                    }

                }
            } 

            return fProcessKilledSuccessfully; 
        } 
    }
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK