Beispiel #1
0
        private void SpngNegotiationInitial(byte[] inToken)
        {
            byte[]       securityToken  = null;
            MechTypeList serverMechList = null;

            if ((inToken == null) || (inToken.Length == 0)) // Client Initiation Mode
            {
                InitializeSecurityContext(this.client.Config.MechList.Elements[0], securityToken);
                this.client.Context.NegotiationState = SpngNegotiationState.AcceptIncomplete;
            }
            else // Server Initiation Mode
            {
                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 (Exception ex)
                {
                    if (securityMechContext is NlmpClientSecurityContext)
                    {
                        throw ex;
                    }
                    SwitchToNTLMSSP(securityToken); // try use NTLM
                }
            }
            else
            {
                securityMechContext.Initialize(null);
            }

            UpdateNegotiationToken(securityToken);
        }
Beispiel #2
0
        /// <summary>
        /// Generate a NegotiationToken byte array, and insert the internal security token
        /// </summary>
        /// <param name="payloadType">the internal payload type</param>
        /// <param name="inToken">the internal security token</param>
        /// <returns>the generated NegotiationToken byte array</returns>
        private byte[] WrapNegotiationToken(SpngPayloadType payloadType, byte[] inToken)
        {
            byte[] mechListMic = null;

            if (this.needMechListMic &&
                securityMechContext != null && !securityMechContext.NeedContinueProcessing)
            {
                mechListMic = this.client.GenerateMechListMIC(securityMechContext);
            }

            SpngNegotiationToken negToken = client.CreateNegotiationToken(payloadType,
                                                                          new NegState(NegState.accept_incomplete),
                                                                          inToken,
                                                                          mechListMic);

            return(negToken.ToBytes());
        }
Beispiel #3
0
        /// <summary>
        /// Retrieve the internal security token from NegotiationToken
        /// </summary>
        /// <param name="inToken">NegotiationToken byte array</param>
        /// <param name="mechListMic">the byte-array formatted MechListMIC that contains in the inner payload</param>
        /// <returns>the internal security token</returns>
        private byte[] UnwrapNegotiationToken(byte[] inToken, out byte[] mechListMic)
        {
            mechListMic = null;

            SpngNegotiationToken negToken = new SpngNegotiationToken();

            negToken.FromBytes(inToken);

            if (negToken != null)
            {
                mechListMic = negToken.MechListMIC;
            }

            if (negToken.MechToken == null || negToken.MechToken.Length == 0)
            {
                return(null);
            }

            return(negToken.MechToken);
        }
Beispiel #4
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!");
            }
        }