Beispiel #1
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="attributes">the attributes for server</param>
 /// <param name="nlmpConfig">
 /// the config for nlmp client, this param maybe null. if null, spng does not support nlmp.
 /// </param>
 /// <param name="kileConfig">
 /// the config for kile client, this param maybe null. if null, spng does not support Kerberos.
 /// </param>
 /// <exception cref="ArgumentException">at least one of nlmpConfig and kileConfig must not be null</exception>
 public SpngClientSecurityContext(
     ClientSecurityContextAttribute attributes,
     NlmpClientSecurityConfig nlmpConfig,
     KerberosClientSecurityConfig kileConfig)
 {
     InitializeClientSecurityContext(attributes, nlmpConfig, kileConfig, null);
 }
Beispiel #2
0
        /// <summary>
        /// initialize the client security context.
        /// </summary>
        /// <param name="attributes">the attributes for server</param>
        /// <param name="nlmpConfig">
        /// the config for nlmp client, this param maybe null. if null, spng does not support nlmp.
        /// </param>
        /// <param name="kileConfig">
        /// the config for kile client, this param maybe null. if null, spng does not support Kerberos.
        /// </param>
        /// <param name="sspiConfig">
        /// the config for sspi client, this param maybe null. if null, spng does not support sspi.
        /// </param>
        /// <exception cref="ArgumentException">
        /// at least one of nlmpConfig, kileConfig and sspiConfig must not be null
        /// </exception>
        private void InitializeClientSecurityContext(
            ClientSecurityContextAttribute attributes,
            NlmpClientSecurityConfig nlmpConfig,
            KerberosClientSecurityConfig kileConfig,
            SspiClientSecurityConfig sspiConfig)
        {
            if (nlmpConfig == null && kileConfig == null && sspiConfig == null)
            {
                throw new ArgumentException("at least one of nlmpConfig, kileConfig and sspiConfig must not be null");
            }

            List <SecurityConfig> configList = new List <SecurityConfig>();

            // build the mech types
            List <MechType> mechTypes = new List <MechType>();

            if (kileConfig != null)
            {
                configList.Add(kileConfig);
                mechTypes.Add(new MechType(Consts.KerbOidInt));
            }
            if (nlmpConfig != null)
            {
                configList.Add(nlmpConfig);
                mechTypes.Add(new MechType(Consts.NlmpOidInt));
            }
            if (sspiConfig != null)
            {
                configList.Add(sspiConfig);
                switch (sspiConfig.SecurityType)
                {
                case SecurityPackageType.Ntlm:
                    mechTypes.Add(new MechType(Consts.NlmpOidInt));
                    break;

                case SecurityPackageType.Kerberos:
                    mechTypes.Add(new MechType(Consts.KerbOidInt));
                    break;

                default:
                    mechTypes.Add(new MechType(Consts.UnknownOidInt));
                    break;
                }
            }

            // build a spng config
            SpngClientSecurityConfig spngConfig =
                new SpngClientSecurityConfig(attributes, new MechTypeList(mechTypes.ToArray()));

            // add spng config to config list.
            configList.Insert(0, spngConfig);

            // initialize the spng client
            this.client = new SpngClient(spngConfig);
            this.needContinueProcessing = true;
            this.packageType            = SecurityPackageType.Negotiate;
            this.securityConfigList     = configList.ToArray();
        }
Beispiel #3
0
        /// <summary>
        /// Initialize the securityMechContext based on the security package type
        /// </summary>
        /// <param name="mechType">security mechanism type</param>
        /// <param name="inToken">the input security token</param>
        /// <exception cref="InvalidOperationException">Thrown if could not find the configuration.</exception>
        /// <exception cref="InvalidOperationException">Thrown when security configuration is unknown</exception>
        private void InitializeSecurityContext(MechType mechType, byte[] inToken)
        {
            SpngClientContext   clientContext = this.client.Context as SpngClientContext;
            SecurityPackageType authType      = SpngUtility.ConvertMechType(mechType);

            CurrentSecurityConfig = SpngUtility.GetSecurityConfig(this.securityConfigList, authType);

            if (CurrentSecurityConfig == null)
            {
                throw new InvalidOperationException("Missing configuration for " + authType.ToString());
            }

            if (securityMechContext != null)
            {
                // re-enter. Nothing need to do
                return;
            }

            if (CurrentSecurityConfig.GetType() == typeof(KerberosClientSecurityConfig))
            {
                KerberosClientSecurityConfig kileConfig = CurrentSecurityConfig as KerberosClientSecurityConfig;

                securityMechContext = new KerberosClientSecurityContext(
                    kileConfig.ServiceName,
                    kileConfig.ClientCredential,
                    KerberosAccountType.User,
                    kileConfig.KdcIpAddress,
                    kileConfig.KdcPort,
                    kileConfig.TransportType,
                    kileConfig.SecurityAttributes);
            }
            else if (CurrentSecurityConfig.GetType() == typeof(NlmpClientSecurityConfig))
            {
                NlmpClientSecurityConfig nlmpConfig = CurrentSecurityConfig as NlmpClientSecurityConfig;

                NlmpClientCredential cred = new NlmpClientCredential(
                    nlmpConfig.TargetName,
                    nlmpConfig.DomainName,
                    nlmpConfig.AccountName,
                    nlmpConfig.Password);
                securityMechContext = new NlmpClientSecurityContext(cred, nlmpConfig.SecurityAttributes);
            }
            else if (CurrentSecurityConfig.GetType() == typeof(SspiClientSecurityConfig))
            {
                throw new InvalidOperationException("Only support Kerberos security config and NTLM security config");
            }
            else
            {
                throw new InvalidOperationException("unknown security config");
            }
        }
Beispiel #4
0
        private void SpngNegotiationAcceptIncomplete(byte[] inToken)
        {
            byte[] securityToken = null;
            bool   isNeedWrap    = true;

            if ((inToken == null) || (inToken.Length == 0))
            {
                throw new ArgumentNullException("inToken");
            }

            byte[] mechListMic = null;
            if (CurrentSecurityConfig.GetType() == typeof(NlmpClientSecurityConfig))
            {
                NlmpClientSecurityConfig nlmpConfig = CurrentSecurityConfig as NlmpClientSecurityConfig;
                if ((nlmpConfig.SecurityAttributes & ClientSecurityContextAttribute.DceStyle) == ClientSecurityContextAttribute.DceStyle)
                {
                    isNeedWrap = false;
                }
            }

            securityToken = isNeedWrap ? UnwrapNegotiationToken(inToken, out mechListMic) : inToken;

            if (!securityMechContext.NeedContinueProcessing)
            {
                this.needContinueProcessing          = false;
                this.client.Context.NegotiationState = SpngNegotiationState.AcceptCompleted;
                this.token = null;

                if (isNeedWrap && mechListMic != null && !this.client.VerifyMechListMIC(securityMechContext, mechListMic))
                {
                    throw new InvalidOperationException("Invalid MechListMic");
                }
            }
            else
            {
                securityMechContext.Initialize(securityToken);
                if (!securityMechContext.NeedContinueProcessing)
                {
                    this.needMechListMic = true;
                }
                this.token = isNeedWrap ? WrapNegotiationToken(SpngPayloadType.NegResp, securityMechContext.Token) : securityMechContext.Token;
            }
        }
Beispiel #5
0
 private void UpdateNegotiationToken(byte[] securityToken)
 {
     if (this.client.Context.NegotiationState == SpngNegotiationState.SspiNegotiation)
     {
         //SSPI negotiation already has an SPNG wrapper.
         this.token = securityToken;
     }
     else
     {
         bool isNeedWrap = true;
         if (CurrentSecurityConfig.GetType() == typeof(NlmpClientSecurityConfig))
         {
             NlmpClientSecurityConfig nlmpConfig = CurrentSecurityConfig as NlmpClientSecurityConfig;
             if ((nlmpConfig.SecurityAttributes & ClientSecurityContextAttribute.DceStyle) == ClientSecurityContextAttribute.DceStyle)
             {
                 isNeedWrap = false;
             }
         }
         this.token = isNeedWrap ? WrapInitialNegToken(securityMechContext.Token) : securityMechContext.Token;
     }
 }
        /// <summary>
        /// AcquireCredentialsHandle
        /// </summary>
        /// <param name="accountCredential"></param>
        protected void AcquireCredentialsHandle <T>(T accountCredential)
        {
            if (!string.IsNullOrEmpty(this.serverPrincipalName))
            {
                this.serverPrincipalName = GetServicePrincipalName(this.serverPrincipalName);
            }

            switch (packageType)
            {
            case SecurityPackageType.Ntlm:
            {
                if (accountCredential is AccountCredential)
                {
                    var credential = accountCredential as AccountCredential;
                    this.Context = new NlmpClientSecurityContext(
                        new NlmpClientCredential(
                            this.serverPrincipalName,
                            credential.DomainName,
                            credential.AccountName,
                            credential.Password)
                        );
                }
                else
                {
                    throw new NotSupportedException("NTLM only support AccountCredential, Please provide an AccountCredential and try again.");
                }
                return;
            }

            case SecurityPackageType.Kerberos:
            {
                if (accountCredential is AccountCredential)
                {
                    var       credential   = accountCredential as AccountCredential;
                    IPAddress kdcIpAddress = (string.IsNullOrEmpty(KerberosContext.KDCComputerName) ? credential.DomainName : KerberosContext.KDCComputerName).ParseIPAddress();
                    this.Context = KerberosClientSecurityContext.CreateClientSecurityContext(
                        this.serverPrincipalName,
                        credential,
                        KerberosAccountType.User,
                        kdcIpAddress,
                        KerberosContext.KDCPort,
                        TransportType.TCP,
                        this.securityContextAttributes
                        );
                }
                else
                {
                    throw new NotSupportedException("Kerberos only support AccountCredential, Please provide an AccountCredential and try again.");
                }
                return;
            }

            case SecurityPackageType.Negotiate:
            {
                if (accountCredential is AccountCredential)
                {
                    if (this.securityContextAttributes == ClientSecurityContextAttribute.None)
                    {
                        this.securityContextAttributes = ClientSecurityContextAttribute.MutualAuth;         // MS-SPNG 3.3.3 The client MUST request Mutual Authentication services
                    }

                    var credential = accountCredential as AccountCredential;
                    NlmpClientSecurityConfig nlmpSecurityConfig = new NlmpClientSecurityConfig(credential, this.serverPrincipalName, this.securityContextAttributes);

                    IPAddress kdcIpAddress = (string.IsNullOrEmpty(KerberosContext.KDCComputerName) ? credential.DomainName : KerberosContext.KDCComputerName).ParseIPAddress();
                    KerberosClientSecurityConfig kerberosSecurityConfig = new KerberosClientSecurityConfig(
                        credential,
                        credential.AccountName,
                        this.serverPrincipalName,
                        kdcIpAddress,
                        KerberosContext.KDCPort,
                        this.securityContextAttributes,
                        TransportType.TCP
                        );

                    this.Context = new SpngClientSecurityContext(this.securityContextAttributes, nlmpSecurityConfig, kerberosSecurityConfig);
                }
                else
                {
                    throw new NotSupportedException("Negotiate SSP only support AccountCredential, Please provide an AccountCredential and try again.");
                }
                return;
            }
                //case SecurityPackageType.Schannel:
                //    throw new NotImplementedException();
                //case SecurityPackageType.CredSsp:
                //    throw new NotImplementedException();
                //default:
                //    throw new NotImplementedException();
            }

            this.UseNativeSSP(accountCredential);
        }
Beispiel #7
0
        /// <summary>
        /// Initialize the context from a token, and generate a new token.
        /// </summary>
        /// <param name="inToken">the token from server. "inToken" must be null when invoked first time.</param>
        /// <exception cref="ArgumentNullException">Except invoked at the first time, the "inToken" MUST not be null
        /// when invoking Initialize.</exception>
        /// <exception cref="InvalidOperationException">The internal state is invalid when invoking Initialize.</exception>
        /// <exception cref="InvalidOperationException">Invalid MechListMic</exception>
        public override void Initialize(byte[] inToken)
        {
            byte[]       securityToken  = null;
            MechTypeList serverMechList = null;
            bool         isNeedWrap     = true;

            switch (this.client.Context.NegotiationState)
            {
            case SpngNegotiationState.Initial:
                if ((inToken == null) || (inToken.Length == 0))     // Client Initiation Mode
                {
                    InitializeSecurityContext(this.client.Config.MechList.Elements[0], securityToken);
                    this.client.Context.NegotiationState = SpngNegotiationState.AcceptIncomplete;
                }
                else
                {
                    try
                    {
                        securityToken = UnwrapInitialNegToken2(inToken, out serverMechList);
                        this.client.NegotiateMechType(serverMechList);
                        if (this.client.Context.NegotiationState == SpngNegotiationState.Reject)
                        {
                            //Negotiation failed. Do not need to throw exception in this case.
                            return;
                        }
                    }
                    catch
                    {
                        // check if reauth token
                        SpngNegotiationToken negToken = new SpngNegotiationToken();
                        negToken.FromBytes(inToken);
                        this.client.Context.NegotiatedMechType = negToken.SupportedMechType;        // try use preview MechType to do Re-Initialize
                        securityToken = null;
                    }

                    InitializeSecurityContext(this.client.Context.NegotiatedMechType, securityToken);
                }

                if (this.client.Context.NegotiationState == SpngNegotiationState.AcceptIncomplete)     // server prefered mechtype can find from local support mechtype list.
                {
                    try
                    {
                        securityMechContext.Initialize(securityToken);
                    }
                    catch
                    {
                        securityMechContext = null;     // try use NTLM
                        InitializeSecurityContext(this.client.Config.MechList.Elements[1], securityToken);
                        this.client.Context.NegotiationState = SpngNegotiationState.AcceptIncomplete;
                        securityMechContext.Initialize(securityToken);
                    }
                }
                else
                {
                    securityMechContext.Initialize(null);
                }

                if (this.client.Context.NegotiationState == SpngNegotiationState.SspiNegotiation)
                {
                    //SSPI negotiation already has an SPNG wrapper.
                    this.token = securityToken;
                }
                else
                {
                    if (CurrentSecurityConfig.GetType() == typeof(NlmpClientSecurityConfig))
                    {
                        NlmpClientSecurityConfig nlmpConfig = CurrentSecurityConfig as NlmpClientSecurityConfig;
                        if ((nlmpConfig.SecurityAttributes & ClientSecurityContextAttribute.DceStyle) == ClientSecurityContextAttribute.DceStyle)
                        {
                            isNeedWrap = false;
                        }
                    }

                    if (isNeedWrap)
                    {
                        this.token = WrapInitialNegToken(securityMechContext.Token);
                    }
                    else
                    {
                        this.token = securityMechContext.Token;
                    }
                }
                break;

            case SpngNegotiationState.RequestMic:
                if ((inToken == null) || (inToken.Length == 0))
                {
                    throw new ArgumentNullException("inToken");
                }
                securityToken        = UnwrapNegotiationToken(inToken);
                this.needMechListMic = true;
                this.client.Context.NegotiationState = SpngNegotiationState.AcceptIncomplete;

                securityMechContext.Initialize(securityToken);
                if (securityMechContext.Token != null)
                {
                    this.token = WrapNegotiationToken(SpngPayloadType.NegResp, securityMechContext.Token);
                }
                break;

            case SpngNegotiationState.AcceptIncomplete:
                if ((inToken == null) || (inToken.Length == 0))
                {
                    throw new ArgumentNullException("inToken");
                }

                byte[] mechListMic = null;
                if (CurrentSecurityConfig.GetType() == typeof(NlmpClientSecurityConfig))
                {
                    NlmpClientSecurityConfig nlmpConfig = CurrentSecurityConfig as NlmpClientSecurityConfig;
                    if ((nlmpConfig.SecurityAttributes & ClientSecurityContextAttribute.DceStyle) == ClientSecurityContextAttribute.DceStyle)
                    {
                        isNeedWrap = false;
                    }
                }

                if (isNeedWrap)
                {
                    securityToken = UnwrapNegotiationToken(inToken, out mechListMic);
                    if (!securityMechContext.NeedContinueProcessing)
                    {
                        this.needContinueProcessing          = false;
                        this.client.Context.NegotiationState = SpngNegotiationState.AcceptCompleted;
                        this.token = null;
                        if (mechListMic != null && !this.client.VerifyMechListMIC(securityMechContext, mechListMic))
                        {
                            throw new InvalidOperationException("Invalid MechListMic");
                        }
                    }
                    else
                    {
                        securityMechContext.Initialize(securityToken);
                        if (!securityMechContext.NeedContinueProcessing)
                        {
                            this.needMechListMic = true;
                        }

                        this.token = WrapNegotiationToken(SpngPayloadType.NegResp, securityMechContext.Token);
                    }
                }
                else
                {
                    this.needContinueProcessing = false;

                    if (!securityMechContext.NeedContinueProcessing)
                    {
                        this.client.Context.NegotiationState = SpngNegotiationState.AcceptCompleted;
                        this.token = null;
                    }
                    else
                    {
                        securityToken = inToken;
                        securityMechContext.Initialize(securityToken);
                        this.token = securityMechContext.Token;
                    }
                }

                break;

            case SpngNegotiationState.AcceptCompleted:
                throw new InvalidOperationException("Authentication completed!");

            case SpngNegotiationState.SspiNegotiation:
                if (securityMechContext != null)
                {
                    securityMechContext.Initialize(inToken);
                }
                break;

            default:     // MUST be SpngNegotiationState.Reject
                throw new InvalidOperationException("Authentication rejected!");
            }
        }