WSSecurityPolicy12.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 / ServiceModel / System / ServiceModel / Security / WSSecurityPolicy12.cs / 1 / WSSecurityPolicy12.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.ServiceModel.Security 
{
    using System; 
    using System.Collections.Generic; 
    using System.Collections.ObjectModel;
    using System.Net; 
    using System.ServiceModel.Description;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Security.Tokens;
    using System.Text; 
    using System.Xml;
 
    class WSSecurityPolicy12 : WSSecurityPolicy 
    {
        public const string WsspNamespace = @"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"; 

        public const string SignedEncryptedSupportingTokensName = "SignedEncryptedSupportingTokens";
        public const string RequireImpliedDerivedKeysName = "RequireImpliedDerivedKeys";
        public const string RequireExplicitDerivedKeysName = "RequireExplicitDerivedKeys"; 

        public override string WsspNamespaceUri 
        { 
            get { return WSSecurityPolicy12.WsspNamespace; }
        } 

        public override bool IsSecurityVersionSupported(MessageSecurityVersion version)
        {
            return version == MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10 || 
                version == MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12 ||
                version == MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10; 
        } 

        public override MessageSecurityVersion GetSupportedMessageSecurityVersion(SecurityVersion version) 
        {
            return (version == SecurityVersion.WSSecurity10) ? MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10 : MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
        }
 
        public override TrustDriver TrustDriver
        { 
            get 
            {
                return new WSTrustDec2005.DriverDec2005(new SecurityStandardsManager(MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12, WSSecurityTokenSerializer.DefaultInstance)); 
            }
        }

        public override XmlElement CreateWsspHttpsTokenAssertion(MetadataExporter exporter, HttpsTransportBindingElement httpsBinding) 
        {
            XmlElement result = CreateWsspAssertion(WSSecurityPolicy.HttpsTokenName); 
            if (httpsBinding.RequireClientCertificate || 
                httpsBinding.AuthenticationScheme == AuthenticationSchemes.Basic ||
                httpsBinding.AuthenticationScheme == AuthenticationSchemes.Digest) 
            {
                XmlElement policy = CreateWspPolicyWrapper(exporter);
                if (httpsBinding.RequireClientCertificate)
                { 
                    policy.AppendChild(CreateWsspAssertion(WSSecurityPolicy.RequireClientCertificateName));
                } 
                if (httpsBinding.AuthenticationScheme == AuthenticationSchemes.Basic) 
                {
                    policy.AppendChild(CreateWsspAssertion(WSSecurityPolicy.HttpBasicAuthenticationName)); 
                }
                else if (httpsBinding.AuthenticationScheme == AuthenticationSchemes.Digest)
                {
                    policy.AppendChild(CreateWsspAssertion(WSSecurityPolicy.HttpDigestAuthenticationName)); 
                }
                result.AppendChild(policy); 
            } 
            return result;
        } 

        public override bool TryImportWsspHttpsTokenAssertion(MetadataImporter importer, ICollection assertions, HttpsTransportBindingElement httpsBinding)
        {
            if (assertions == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("assertions"); 
            } 

            bool result = true; 
            XmlElement assertion;

            if (TryImportWsspAssertion(assertions, HttpsTokenName, out assertion))
            { 
                XmlElement policyElement = null;
                foreach (XmlNode node in assertion.ChildNodes) 
                { 
                    if (node is XmlElement && node.LocalName == WSSecurityPolicy.PolicyName && (node.NamespaceURI == WSSecurityPolicy.WspNamespace || node.NamespaceURI == WSSecurityPolicy.Wsp15Namespace))
                    { 
                        policyElement = (XmlElement)node;
                        break;
                    }
                } 

                if (policyElement != null) 
                { 
                    foreach (XmlNode node in policyElement.ChildNodes)
                    { 
                        if (node is XmlElement && node.NamespaceURI == this.WsspNamespaceUri)
                        {
                            if (node.LocalName == WSSecurityPolicy.RequireClientCertificateName)
                            { 
                                httpsBinding.RequireClientCertificate = true;
                            } 
                            else if (node.LocalName == WSSecurityPolicy.HttpBasicAuthenticationName) 
                            {
                                httpsBinding.AuthenticationScheme = AuthenticationSchemes.Basic; 
                            }
                            else if (node.LocalName == WSSecurityPolicy.HttpDigestAuthenticationName)
                            {
                                httpsBinding.AuthenticationScheme = AuthenticationSchemes.Digest; 
                            }
                        } 
                    } 
                }
            } 
            else
            {
                result = false;
            } 

            return result; 
        } 

        public override Collection CreateWsspSupportingTokensAssertion(MetadataExporter exporter, Collection signed, Collection signedEncrypted, Collection endorsing, Collection signedEndorsing, Collection optionalSigned, Collection optionalSignedEncrypted, Collection optionalEndorsing, Collection optionalSignedEndorsing, AddressingVersion addressingVersion) 
        {
            Collection supportingTokenAssertions = new Collection();

            // Signed Supporting Tokens 
            XmlElement supportingTokenAssertion = CreateWsspSignedSupportingTokensAssertion(exporter, signed, optionalSigned);
            if (supportingTokenAssertion != null) 
                supportingTokenAssertions.Add(supportingTokenAssertion); 

            // Signed Encrypted Supporting Tokens 
            supportingTokenAssertion = CreateWsspSignedEncryptedSupportingTokensAssertion(exporter, signedEncrypted, optionalSignedEncrypted);
            if (supportingTokenAssertion != null)
                supportingTokenAssertions.Add(supportingTokenAssertion);
 
            // Endorsing Supporting Tokens.
            supportingTokenAssertion = CreateWsspEndorsingSupportingTokensAssertion(exporter, endorsing, optionalEndorsing, addressingVersion); 
            if (supportingTokenAssertion != null) 
                supportingTokenAssertions.Add(supportingTokenAssertion);
 
            // Signed Endorsing Supporting Tokens.
            supportingTokenAssertion = CreateWsspSignedEndorsingSupportingTokensAssertion(exporter, signedEndorsing, optionalSignedEndorsing, addressingVersion);
            if (supportingTokenAssertion != null)
                supportingTokenAssertions.Add(supportingTokenAssertion); 

            return supportingTokenAssertions; 
        } 

        public override XmlElement CreateWsspSpnegoContextTokenAssertion(MetadataExporter exporter, SspiSecurityTokenParameters parameters) 
        {
            XmlElement result = CreateWsspAssertion(SpnegoContextTokenName);
            SetIncludeTokenValue(result, parameters.InclusionMode);
            result.AppendChild( 
                CreateWspPolicyWrapper(
                    exporter, 
                    CreateWsspRequireDerivedKeysAssertion(parameters.RequireDerivedKeys), 
                    // Always emit  for spnego and sslnego
                    CreateWsspMustNotSendCancelAssertion(false), 
                    CreateWsspMustNotSendAmendAssertion(),
                    CreateWsspMustNotSendRenewAssertion()
            ));
            return result; 
        }
 
        public override XmlElement CreateMsspSslContextTokenAssertion(MetadataExporter exporter, SslSecurityTokenParameters parameters) 
        {
            XmlElement result = CreateMsspAssertion(SslContextTokenName); 
            SetIncludeTokenValue(result, parameters.InclusionMode);
            result.AppendChild(
                CreateWspPolicyWrapper(
                    exporter, 
                    CreateWsspRequireDerivedKeysAssertion(parameters.RequireDerivedKeys),
                    // Always emit  for spnego and sslnego 
                    CreateWsspMustNotSendCancelAssertion(false), 
                    CreateMsspRequireClientCertificateAssertion(parameters.RequireClientCertificate),
                    CreateWsspMustNotSendAmendAssertion(), 
                    CreateWsspMustNotSendRenewAssertion()
            ));
            return result;
        } 

        public override XmlElement CreateWsspSecureConversationTokenAssertion(MetadataExporter exporter, SecureConversationSecurityTokenParameters parameters) 
        { 
            XmlElement result = CreateWsspAssertion(SecureConversationTokenName);
            SetIncludeTokenValue(result, parameters.InclusionMode); 
            result.AppendChild(
                CreateWspPolicyWrapper(
                    exporter,
                    CreateWsspRequireDerivedKeysAssertion(parameters.RequireDerivedKeys), 
                    CreateWsspMustNotSendCancelAssertion(parameters.RequireCancellation),
                    CreateWsspBootstrapPolicyAssertion(exporter, parameters.BootstrapSecurityBindingElement), 
                    CreateWsspMustNotSendAmendAssertion(), 
                    parameters.RequireCancellation ? null : CreateWsspMustNotSendRenewAssertion()
            )); 
            return result;
        }

        XmlElement CreateWsspMustNotSendAmendAssertion() 
        {
            XmlElement result = CreateWsspAssertion(MustNotSendAmendName); 
            return result; 
        }
 
        XmlElement CreateWsspMustNotSendRenewAssertion()
        {
            XmlElement result = CreateWsspAssertion(MustNotSendRenewName);
            return result; 
        }
 
        public override bool TryImportWsspSpnegoContextTokenAssertion(MetadataImporter importer, XmlElement assertion, out SecurityTokenParameters parameters) 
        {
            parameters = null; 

            SecurityTokenInclusionMode inclusionMode;
            Collection> alternatives;
 
            if (IsWsspAssertion(assertion, SpnegoContextTokenName)
                && TryGetIncludeTokenValue(assertion, out inclusionMode)) 
            { 
                if (TryGetNestedPolicyAlternatives(importer, assertion, out alternatives))
                { 
                    foreach (Collection alternative in alternatives)
                    {
                        SspiSecurityTokenParameters sspi = new SspiSecurityTokenParameters();
                        parameters = sspi; 
                        bool requireCancellation;
                        if (TryImportWsspRequireDerivedKeysAssertion(alternative, sspi) 
                            && TryImportWsspMustNotSendCancelAssertion(alternative, out requireCancellation) 
                            && TryImportWsspMustNotSendAmendAssertion(alternative)
                            && TryImportWsspMustNotSendRenewAssertion(alternative) 
                            && alternative.Count == 0)
                        {
                            // Client always set this to true to match the standardbinding.
                            // This setting on client has no effect for spnego and sslnego. 
                            sspi.RequireCancellation = true;
                            sspi.InclusionMode = inclusionMode; 
                            break; 
                        }
                        else 
                        {
                            parameters = null;
                        }
                    } 
                }
                else 
                { 
                    parameters = new SspiSecurityTokenParameters();
                    parameters.RequireDerivedKeys = false; 
                    parameters.InclusionMode = inclusionMode;
                }
            }
 
            return parameters != null;
        } 
 
        public override bool TryImportMsspSslContextTokenAssertion(MetadataImporter importer, XmlElement assertion, out SecurityTokenParameters parameters)
        { 
            parameters = null;

            SecurityTokenInclusionMode inclusionMode;
            Collection> alternatives; 

            if (IsMsspAssertion(assertion, SslContextTokenName) 
                && TryGetIncludeTokenValue(assertion, out inclusionMode)) 
            {
                if (TryGetNestedPolicyAlternatives(importer, assertion, out alternatives)) 
                {
                    foreach (Collection alternative in alternatives)
                    {
                        SslSecurityTokenParameters ssl = new SslSecurityTokenParameters(); 
                        parameters = ssl;
                        bool requireCancellation; 
                        if (TryImportWsspRequireDerivedKeysAssertion(alternative, ssl) 
                            && TryImportWsspMustNotSendCancelAssertion(alternative, out requireCancellation)
                            && TryImportWsspMustNotSendAmendAssertion(alternative) 
                            && TryImportWsspMustNotSendRenewAssertion(alternative)
                            && TryImportMsspRequireClientCertificateAssertion(alternative, ssl)
                            && alternative.Count == 0)
                        { 
                            // Client always set this to true to match the standardbinding.
                            // This setting on client has no effect for spnego and sslnego. 
                            ssl.RequireCancellation = true; 
                            ssl.InclusionMode = inclusionMode;
                            break; 
                        }
                        else
                        {
                            parameters = null; 
                        }
                    } 
                } 
                else
                { 
                    parameters = new SslSecurityTokenParameters();
                    parameters.RequireDerivedKeys = false;
                    parameters.InclusionMode = inclusionMode;
                } 
            }
 
            return parameters != null; 
        }
 
        public override bool TryImportWsspSecureConversationTokenAssertion(MetadataImporter importer, XmlElement assertion, out SecurityTokenParameters parameters)
        {
            parameters = null;
 
            SecurityTokenInclusionMode inclusionMode;
            Collection> alternatives; 
 
            if (IsWsspAssertion(assertion, SecureConversationTokenName)
                && TryGetIncludeTokenValue(assertion, out inclusionMode)) 
            {
                if (TryGetNestedPolicyAlternatives(importer, assertion, out alternatives))
                {
                    foreach (Collection alternative in alternatives) 
                    {
                        SecureConversationSecurityTokenParameters sc = new SecureConversationSecurityTokenParameters(); 
                        parameters = sc; 
                        bool requireCancellation;
                        if (TryImportWsspRequireDerivedKeysAssertion(alternative, sc) 
                            && TryImportWsspMustNotSendCancelAssertion(alternative, out requireCancellation)
                            && TryImportWsspMustNotSendAmendAssertion(alternative)
                            // the  assertion, WCF client will tolerate
                            // whether or not this exist and will always send Renew regardless. 
                            && TryImportWsspMustNotSendRenewAssertion(alternative)
                            && TryImportWsspBootstrapPolicyAssertion(importer, alternative, sc) 
                            && alternative.Count == 0) 
                        {
                            sc.RequireCancellation = requireCancellation; 
                            sc.InclusionMode = inclusionMode;
                            break;
                        }
                        else 
                        {
                            parameters = null; 
                        } 
                    }
                } 
                else
                {
                    parameters = new SecureConversationSecurityTokenParameters();
                    parameters.InclusionMode = inclusionMode; 
                    parameters.RequireDerivedKeys = false;
                } 
            } 

            return parameters != null; 
        }

        public virtual bool TryImportWsspMustNotSendAmendAssertion(ICollection assertions)
        { 
            TryImportWsspAssertion(assertions, MustNotSendAmendName);
            return true; 
        } 

        public virtual bool TryImportWsspMustNotSendRenewAssertion(ICollection assertions) 
        {
            TryImportWsspAssertion(assertions, MustNotSendRenewName);
            return true;
        } 

        XmlElement CreateWsspSignedSupportingTokensAssertion(MetadataExporter exporter, Collection signed, Collection optionalSigned) 
        { 
            XmlElement result;
 
            if ((signed == null || signed.Count == 0)
                && (optionalSigned == null || optionalSigned.Count == 0))
            {
                result = null; 
            }
            else 
            { 
                XmlElement policy = CreateWspPolicyWrapper(exporter);
 
                if (signed != null)
                {
                    foreach (SecurityTokenParameters p in signed)
                    { 
                        policy.AppendChild(CreateTokenAssertion(exporter, p));
                    } 
                } 
                if (optionalSigned != null)
                { 
                    foreach (SecurityTokenParameters p in optionalSigned)
                    {
                        policy.AppendChild(CreateTokenAssertion(exporter, p, true));
                    } 
                }
 
                result = CreateWsspAssertion(SignedSupportingTokensName); 
                result.AppendChild(policy);
            } 

            return result;
        }
 
        XmlElement CreateWsspSignedEncryptedSupportingTokensAssertion(MetadataExporter exporter, Collection signedEncrypted, Collection optionalSignedEncrypted)
        { 
            XmlElement result; 

            if ((signedEncrypted == null || signedEncrypted.Count == 0) 
                && (optionalSignedEncrypted == null || optionalSignedEncrypted.Count == 0))
            {
                result = null;
            } 
            else
            { 
                XmlElement policy = CreateWspPolicyWrapper(exporter); 

                if (signedEncrypted != null) 
                {
                    foreach (SecurityTokenParameters p in signedEncrypted)
                    {
                        policy.AppendChild(CreateTokenAssertion(exporter, p)); 
                    }
                } 
                if (optionalSignedEncrypted != null) 
                {
                    foreach (SecurityTokenParameters p in optionalSignedEncrypted) 
                    {
                        policy.AppendChild(CreateTokenAssertion(exporter, p, true));
                    }
                } 

                result = CreateWsspAssertion(SignedEncryptedSupportingTokensName); 
                result.AppendChild(policy); 
            }
 
            return result;
        }

        public override bool TryImportWsspSupportingTokensAssertion(MetadataImporter importer, PolicyConversionContext policyContext, ICollection assertions, Collection signed, Collection signedEncrypted, Collection endorsing, Collection signedEndorsing, Collection optionalSigned, Collection optionalSignedEncrypted, Collection optionalEndorsing, Collection optionalSignedEndorsing) 
        {
            XmlElement assertion; 
 
            if (!TryImportWsspSignedSupportingTokensAssertion(
                importer, 
                policyContext,
                assertions,
                signed,
                optionalSigned, 
                out assertion)
                && assertion != null) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnsupportedSecurityPolicyAssertion, assertion.OuterXml)));
            } 

            if (!TryImportWsspSignedEncryptedSupportingTokensAssertion(
                importer,
                policyContext, 
                assertions,
                signedEncrypted, 
                optionalSignedEncrypted, 
                out assertion)
                && assertion != null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnsupportedSecurityPolicyAssertion, assertion.OuterXml)));
            }
 
            if (!TryImportWsspEndorsingSupportingTokensAssertion(
                importer, 
                policyContext, 
                assertions,
                endorsing, 
                optionalEndorsing,
                out assertion)
                && assertion != null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnsupportedSecurityPolicyAssertion, assertion.OuterXml)));
            } 
 
            if (!TryImportWsspSignedEndorsingSupportingTokensAssertion(
                importer, 
                policyContext,
                assertions,
                signedEndorsing,
                optionalSignedEndorsing, 
                out assertion)
                && assertion != null) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnsupportedSecurityPolicyAssertion, assertion.OuterXml)));
            } 

            return true;
        }
 
        bool TryImportWsspSignedSupportingTokensAssertion(MetadataImporter importer, PolicyConversionContext policyContext, ICollection assertions, Collection signed, Collection optionalSigned, out XmlElement assertion)
        { 
            if (signed == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("signed"); 
            }
            if (optionalSigned == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("optionalSigned"); 
            }
 
            bool result = true; 

            Collection> alternatives; 

            if (TryImportWsspAssertion(assertions, SignedSupportingTokensName, out assertion)
                && TryGetNestedPolicyAlternatives(importer, assertion, out alternatives))
            { 
                foreach (Collection alternative in alternatives)
                { 
                    SecurityTokenParameters parameters; 
                    bool isOptional;
                    while (alternative.Count > 0 && TryImportTokenAssertion(importer, policyContext, alternative, out parameters, out isOptional)) 
                    {
                        if (isOptional)
                        {
                            optionalSigned.Add(parameters); 
                        }
                        else 
                        { 
                            signed.Add(parameters);
                        } 
                    }
                    if (alternative.Count == 0)
                    {
                        result = true; 
                        break;
                    } 
                    else 
                    {
                        result = false; 
                    }
                }
            }
 
            return result;
        } 
 
        bool TryImportWsspSignedEncryptedSupportingTokensAssertion(MetadataImporter importer, PolicyConversionContext policyContext, ICollection assertions, Collection signedEncrypted, Collection optionalSignedEncrypted, out XmlElement assertion)
        { 
            if (signedEncrypted == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("signedEncrypted");
            } 
            if (optionalSignedEncrypted == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("optionalSignedEncrypted"); 
            }
 
            bool result = true;

            Collection> alternatives;
 
            if (TryImportWsspAssertion(assertions, SignedEncryptedSupportingTokensName, out assertion)
                && TryGetNestedPolicyAlternatives(importer, assertion, out alternatives)) 
            { 
                foreach (Collection alternative in alternatives)
                { 
                    SecurityTokenParameters parameters;
                    bool isOptional;
                    while (alternative.Count > 0 && TryImportTokenAssertion(importer, policyContext, alternative, out parameters, out isOptional))
                    { 
                        if (isOptional)
                        { 
                            optionalSignedEncrypted.Add(parameters); 
                        }
                        else 
                        {
                            signedEncrypted.Add(parameters);
                        }
                    } 
                    if (alternative.Count == 0)
                    { 
                        result = true; 
                        break;
                    } 
                    else
                    {
                        result = false;
                    } 
                }
            } 
 
            return result;
        } 

        public override bool TryImportWsspRequireDerivedKeysAssertion(ICollection assertions, SecurityTokenParameters parameters)
        {
            parameters.RequireDerivedKeys = TryImportWsspAssertion(assertions, WSSecurityPolicy.RequireDerivedKeysName); 

            if (!parameters.RequireDerivedKeys) 
            { 
                parameters.RequireDerivedKeys = TryImportWsspAssertion(assertions, WSSecurityPolicy12.RequireExplicitDerivedKeysName);
            } 

            if (!parameters.RequireDerivedKeys)
            {
                XmlElement assertion = null; 
                if (TryImportWsspAssertion(assertions, WSSecurityPolicy12.RequireImpliedDerivedKeysName, out assertion))
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnsupportedSecurityPolicyAssertion, assertion.OuterXml))); 
            } 

            return true; 
        }

        public override XmlElement CreateWsspTrustAssertion(MetadataExporter exporter, SecurityKeyEntropyMode keyEntropyMode)
        { 
            return CreateWsspTrustAssertion(Trust13Name, exporter, keyEntropyMode);
        } 
 
        public override bool TryImportWsspTrustAssertion(MetadataImporter importer, ICollection assertions, SecurityBindingElement binding, out XmlElement assertion)
        { 
            return TryImportWsspTrustAssertion(Trust13Name, importer, assertions, binding, out assertion);
        }

        public override XmlElement CreateWsspRsaTokenAssertion(RsaSecurityTokenParameters parameters) 
        {
            XmlElement result = CreateWsspAssertion(KeyValueTokenName); 
            SetIncludeTokenValue(result, parameters.InclusionMode); 
            return result;
        } 

        public override bool TryImportWsspRsaTokenAssertion(MetadataImporter importer, XmlElement assertion, out SecurityTokenParameters parameters)
        {
            parameters = null; 

            SecurityTokenInclusionMode inclusionMode; 
            Collection> alternatives; 

            if (IsWsspAssertion(assertion, KeyValueTokenName) 
                && TryGetIncludeTokenValue(assertion, out inclusionMode)
                && TryGetNestedPolicyAlternatives(importer, assertion, out alternatives) == false)
            {
                parameters = new RsaSecurityTokenParameters(); 
                parameters.InclusionMode = inclusionMode;
            } 
 
            return parameters != null;
        } 
    }
}

// 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