Пример #1
0
        public virtual NTStatus AcceptSecurityContext(ref GSSContext context, byte[] inputToken, out byte[] outputToken)
        {
            outputToken = null;
            SimpleProtectedNegotiationToken spnegoToken = null;

            try
            {
                spnegoToken = SimpleProtectedNegotiationToken.ReadToken(inputToken, 0);
            }
            catch
            {
            }

            if (spnegoToken != null)
            {
                if (spnegoToken is SimpleProtectedNegotiationTokenInit)
                {
                    SimpleProtectedNegotiationTokenInit tokenInit = (SimpleProtectedNegotiationTokenInit)spnegoToken;
                    if (tokenInit.MechanismTypeList.Count == 0)
                    {
                        return(NTStatus.SEC_E_INVALID_TOKEN);
                    }

                    // RFC 4178: Note that in order to avoid an extra round trip, the first context establishment token
                    // of the initiator's preferred mechanism SHOULD be embedded in the initial negotiation message.
                    byte[]        preferredMechanism   = tokenInit.MechanismTypeList[0];
                    IGSSMechanism mechanism            = FindMechanism(preferredMechanism);
                    bool          isPreferredMechanism = (mechanism != null);
                    if (!isPreferredMechanism)
                    {
                        mechanism = FindMechanism(tokenInit.MechanismTypeList);
                    }

                    if (mechanism != null)
                    {
                        NTStatus status;
                        context = new GSSContext(mechanism, null);
                        if (isPreferredMechanism)
                        {
                            byte[] mechanismOutput;
                            status      = mechanism.AcceptSecurityContext(ref context.MechanismContext, tokenInit.MechanismToken, out mechanismOutput);
                            outputToken = GetSPNEGOTokenResponseBytes(mechanismOutput, status, mechanism.Identifier);
                        }
                        else
                        {
                            status      = NTStatus.SEC_I_CONTINUE_NEEDED;
                            outputToken = GetSPNEGOTokenResponseBytes(null, status, mechanism.Identifier);
                        }
                        return(status);
                    }
                    return(NTStatus.SEC_E_SECPKG_NOT_FOUND);
                }
                else // SimpleProtectedNegotiationTokenResponse
                {
                    if (context == null)
                    {
                        return(NTStatus.SEC_E_INVALID_TOKEN);
                    }
                    IGSSMechanism mechanism = context.Mechanism;
                    SimpleProtectedNegotiationTokenResponse tokenResponse = (SimpleProtectedNegotiationTokenResponse)spnegoToken;
                    byte[]   mechanismOutput;
                    NTStatus status = mechanism.AcceptSecurityContext(ref context.MechanismContext, tokenResponse.ResponseToken, out mechanismOutput);
                    outputToken = GetSPNEGOTokenResponseBytes(mechanismOutput, status, null);
                    return(status);
                }
            }
            else
            {
                // [MS-SMB] The Windows GSS implementation supports raw Kerberos / NTLM messages in the SecurityBlob.
                // [MS-SMB2] Windows [..] will also accept raw Kerberos messages and implicit NTLM messages as part of GSS authentication.
                if (AuthenticationMessageUtils.IsSignatureValid(inputToken))
                {
                    MessageTypeName messageType = AuthenticationMessageUtils.GetMessageType(inputToken);
                    IGSSMechanism   ntlmAuthenticationProvider = FindMechanism(NTLMSSPIdentifier);
                    if (ntlmAuthenticationProvider != null)
                    {
                        if (messageType == MessageTypeName.Negotiate)
                        {
                            context = new GSSContext(ntlmAuthenticationProvider, null);
                        }

                        if (context == null)
                        {
                            return(NTStatus.SEC_E_INVALID_TOKEN);
                        }

                        NTStatus status = ntlmAuthenticationProvider.AcceptSecurityContext(ref context.MechanismContext, inputToken, out outputToken);
                        return(status);
                    }
                    else
                    {
                        return(NTStatus.SEC_E_SECPKG_NOT_FOUND);
                    }
                }
            }
            return(NTStatus.SEC_E_INVALID_TOKEN);
        }
Пример #2
0
        public NTStatus AcceptSecurityContext(ref object context, byte[] inputToken, out byte[] outputToken)
        {
            outputToken = null;
            SimpleProtectedNegotiationToken spnegoToken = SimpleProtectedNegotiationToken.ReadToken(inputToken, 0);

            if (spnegoToken != null)
            {
                if (spnegoToken is SimpleProtectedNegotiationTokenInit)
                {
                    SimpleProtectedNegotiationTokenInit tokenInit = (SimpleProtectedNegotiationTokenInit)spnegoToken;
                    IGSSMechanism mechanism = FindMechanism(tokenInit.MechanismTypeList);
                    if (mechanism != null)
                    {
                        byte[]   mechanismOutput;
                        NTStatus status = mechanism.AcceptSecurityContext(ref context, tokenInit.MechanismToken, out mechanismOutput);
                        outputToken = GetSPNEGOTokenResponseBytes(mechanismOutput, status, mechanism.Identifier);
                        m_contextToMechanism[context] = mechanism;
                        return(status);
                    }
                    return(NTStatus.SEC_E_SECPKG_NOT_FOUND);
                }
                else // SimpleProtectedNegotiationTokenResponse
                {
                    IGSSMechanism mechanism;
                    if (!m_contextToMechanism.TryGetValue(context, out mechanism))
                    {
                        // We assume that the problem is not with our implementation and that the client has sent
                        // SimpleProtectedNegotiationTokenResponse without first sending SimpleProtectedNegotiationTokenInit.
                        return(NTStatus.SEC_E_INVALID_TOKEN);
                    }
                    SimpleProtectedNegotiationTokenResponse tokenResponse = (SimpleProtectedNegotiationTokenResponse)spnegoToken;
                    byte[]   mechanismOutput;
                    NTStatus status = mechanism.AcceptSecurityContext(ref context, tokenResponse.ResponseToken, out mechanismOutput);
                    outputToken = GetSPNEGOTokenResponseBytes(mechanismOutput, status, null);
                    return(status);
                }
            }
            else
            {
                // [MS-SMB] The Windows GSS implementation supports raw Kerberos / NTLM messages in the SecurityBlob.
                // [MS-SMB2] Windows [..] will also accept raw Kerberos messages and implicit NTLM messages as part of GSS authentication.
                if (AuthenticationMessageUtils.IsSignatureValid(inputToken))
                {
                    MessageTypeName messageType = AuthenticationMessageUtils.GetMessageType(inputToken);
                    IGSSMechanism   ntlmAuthenticationProvider = FindMechanism(NTLMSSPIdentifier);
                    if (ntlmAuthenticationProvider != null)
                    {
                        NTStatus status = ntlmAuthenticationProvider.AcceptSecurityContext(ref context, inputToken, out outputToken);
                        if (messageType == MessageTypeName.Negotiate)
                        {
                            m_contextToMechanism[context] = ntlmAuthenticationProvider;
                        }
                        return(status);
                    }
                    else
                    {
                        return(NTStatus.SEC_E_SECPKG_NOT_FOUND);
                    }
                }
            }
            return(NTStatus.SEC_E_INVALID_TOKEN);
        }