コード例 #1
0
        public NTStatus AcceptSecurityContext(ref object context, byte[] inputToken, out byte[] outputToken)
        {
            outputToken = null;
            if (!AuthenticationMessageUtils.IsSignatureValid(inputToken))
            {
                return(NTStatus.SEC_E_INVALID_TOKEN);
            }

            MessageTypeName messageType = AuthenticationMessageUtils.GetMessageType(inputToken);

            if (messageType == MessageTypeName.Negotiate)
            {
                NegotiateMessage input = new NegotiateMessage(inputToken);
                ChallengeMessage output;
                NTStatus         status = GetChallengeMessage(out context, input, out output);
                outputToken = output.GetBytes();
                return(status);
            }
            else if (messageType == MessageTypeName.Authenticate)
            {
                AuthenticateMessage message = new AuthenticateMessage(inputToken);
                return(Authenticate(context, message));
            }
            else
            {
                return(NTStatus.SEC_E_INVALID_TOKEN);
            }
        }
コード例 #2
0
 public NegotiateMessage()
 {
     Signature   = AuthenticateMessage.ValidSignature;
     MessageType = MessageTypeName.Negotiate;
     DomainName  = String.Empty;
     Workstation = String.Empty;
 }
コード例 #3
0
        public byte[]? MIC; // 16-byte MIC field is omitted for Windows NT / 2000 / XP / Server 2003

        public AuthenticateMessage()
        {
            Signature   = ValidSignature;
            MessageType = MessageTypeName.Authenticate;
            DomainName  = string.Empty;
            UserName    = string.Empty;
            WorkStation = string.Empty;
            EncryptedRandomSessionKey = new byte[0];
        }
コード例 #4
0
 public NegotiateMessage(byte[] buffer)
 {
     Signature      = ByteReader.ReadAnsiString(buffer, 0, 8);
     MessageType    = (MessageTypeName)LittleEndianConverter.ToUInt32(buffer, 8);
     NegotiateFlags = (NegotiateFlags)LittleEndianConverter.ToUInt32(buffer, 12);
     DomainName     = AuthenticationMessageUtils.ReadAnsiStringBufferPointer(buffer, 16);
     Workstation    = AuthenticationMessageUtils.ReadAnsiStringBufferPointer(buffer, 24);
     if ((NegotiateFlags & NegotiateFlags.Version) > 0)
     {
         Version = new NTLMVersion(buffer, 32);
     }
 }
コード例 #5
0
        public override int GetHashCode()
        {
            int hash = 1;

            if (MessageTypeName.Length != 0)
            {
                hash ^= MessageTypeName.GetHashCode();
            }
            if (EncodedMessage.Length != 0)
            {
                hash ^= EncodedMessage.GetHashCode();
            }
            return(hash);
        }
コード例 #6
0
 public ChallengeMessage(byte[] buffer)
 {
     Signature       = ByteReader.ReadAnsiString(buffer, 0, 8);
     MessageType     = (MessageTypeName)LittleEndianConverter.ToUInt32(buffer, 8);
     TargetName      = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 12);
     NegotiateFlags  = (NegotiateFlags)LittleEndianConverter.ToUInt32(buffer, 20);
     ServerChallenge = ByteReader.ReadBytes(buffer, 24, 8);
     // Reserved
     TargetInfo = AuthenticationMessageUtils.ReadBufferPointer(buffer, 40);
     if ((NegotiateFlags & NegotiateFlags.Version) > 0)
     {
         Version = new NTLMVersion(buffer, 48);
     }
 }
コード例 #7
0
 public AuthenticateMessage(byte[] buffer)
 {
     Signature                 = ByteReader.ReadAnsiString(buffer, 0, 8);
     MessageType               = (MessageTypeName)LittleEndianConverter.ToUInt32(buffer, 8);
     LmChallengeResponse       = AuthenticationMessageUtils.ReadBufferPointer(buffer, 12);
     NtChallengeResponse       = AuthenticationMessageUtils.ReadBufferPointer(buffer, 20);
     DomainName                = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 28);
     UserName                  = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 36);
     WorkStation               = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 44);
     EncryptedRandomSessionKey = AuthenticationMessageUtils.ReadBufferPointer(buffer, 52);
     NegotiateFlags            = (NegotiateFlags)LittleEndianConverter.ToUInt32(buffer, 60);
     if ((NegotiateFlags & NegotiateFlags.Version) > 0)
     {
         Version = new NTLMVersion(buffer, 64);
     }
 }
コード例 #8
0
 private static ChallengeMessage GetChallengeMessage(byte[] messageBytes)
 {
     if (AuthenticationMessageUtils.IsSignatureValid(messageBytes))
     {
         MessageTypeName messageType = AuthenticationMessageUtils.GetMessageType(messageBytes);
         if (messageType == MessageTypeName.Challenge)
         {
             try
             {
                 return(new ChallengeMessage(messageBytes));
             }
             catch
             {
                 return(null);
             }
         }
     }
     return(null);
 }
コード例 #9
0
        public NTStatus AcceptSecurityContext(ref object context, byte[] inputToken, out byte[]?outputToken)
        {
            outputToken = null;
            if (!AuthenticationMessageUtils.IsSignatureValid(inputToken))
            {
                return(NTStatus.SEC_E_INVALID_TOKEN);
            }

            MessageTypeName messageType = AuthenticationMessageUtils.GetMessageType(inputToken);

            if (messageType != MessageTypeName.Negotiate)
            {
                return(messageType == MessageTypeName.Authenticate ? Authenticate(context, inputToken) : NTStatus.SEC_E_INVALID_TOKEN);
            }

            NTStatus status = GetChallengeMessage(out context, inputToken, out outputToken);

            return(status);
        }
コード例 #10
0
        public virtual NTStatus AcceptSecurityContext(ref GssContext?context, byte[] inputToken, out byte[]?outputToken)
        {
            outputToken = null;
            SimpleProtectedNegotiationToken?spnegoToken = null;

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

            if (spnegoToken != null)
            {
                if (spnegoToken is SimpleProtectedNegotiationTokenInit tokenInit)
                {
                    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)
                    {
                        return(NTStatus.SEC_E_SECPKG_NOT_FOUND);
                    }
                    NTStatus status;
                    context = new GssContext(mechanism, null);
                    if (isPreferredMechanism)
                    {
                        status      = mechanism.AcceptSecurityContext(ref context.MechanismContext, tokenInit.MechanismToken, out byte[] mechanismOutput);
                        outputToken = GetSpnegoTokenResponseBytes(mechanismOutput, status, mechanism.Identifier);
                    }
                    else
                    {
                        status      = NTStatus.SEC_I_CONTINUE_NEEDED;
                        outputToken = GetSpnegoTokenResponseBytes(null, status, mechanism.Identifier);
                    }
                    return(status);
                }
                else // SimpleProtectedNegotiationTokenResponse
                {
                    if (context == null)
                    {
                        return(NTStatus.SEC_E_INVALID_TOKEN);
                    }
                    IGssMechanism mechanism = context.Mechanism;
                    SimpleProtectedNegotiationTokenResponse tokenResponse = (SimpleProtectedNegotiationTokenResponse)spnegoToken;
                    NTStatus status = mechanism.AcceptSecurityContext(ref context.MechanismContext, tokenResponse.ResponseToken, out byte[] mechanismOutput);
                    outputToken = GetSpnegoTokenResponseBytes(mechanismOutput, status, null);
                    return(status);
                }
            }

            // [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))
            {
                return(NTStatus.SEC_E_INVALID_TOKEN);
            }

            MessageTypeName messageType = AuthenticationMessageUtils.GetMessageType(inputToken);
            IGssMechanism?  ntlmAuthenticationProvider = FindMechanism(NtlmSspIdentifier);

            if (ntlmAuthenticationProvider == null)
            {
                return(NTStatus.SEC_E_SECPKG_NOT_FOUND);
            }

            if (messageType == MessageTypeName.Negotiate)
            {
                context = new GssContext(ntlmAuthenticationProvider, null);
            }

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

            return(ntlmAuthenticationProvider.AcceptSecurityContext(ref context.MechanismContext, inputToken, out outputToken));
        }
コード例 #11
0
ファイル: ChallengeMessage.cs プロジェクト: SonnyX/SMB-Client
 public ChallengeMessage()
 {
     Signature   = AuthenticateMessage.ValidSignature;
     MessageType = MessageTypeName.Challenge;
 }
コード例 #12
0
ファイル: GSSProvider.cs プロジェクト: ciamberlini/SMBLibrary
        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);
        }