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); } }
public NegotiateMessage() { Signature = AuthenticateMessage.ValidSignature; MessageType = MessageTypeName.Negotiate; DomainName = String.Empty; Workstation = String.Empty; }
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]; }
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); } }
public override int GetHashCode() { int hash = 1; if (MessageTypeName.Length != 0) { hash ^= MessageTypeName.GetHashCode(); } if (EncodedMessage.Length != 0) { hash ^= EncodedMessage.GetHashCode(); } return(hash); }
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); } }
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); } }
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); }
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); }
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)); }
public ChallengeMessage() { Signature = AuthenticateMessage.ValidSignature; MessageType = MessageTypeName.Challenge; }
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); }