예제 #1
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");
            }
        }
예제 #2
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;
            }
        }
예제 #3
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!");
            }
        }