internal void ValidateCreateContext(
string package,
bool isServer,
NetworkCredential credential,
string servicePrincipalName,
ChannelBinding channelBinding,
ProtectionLevel protectionLevel,
TokenImpersonationLevel impersonationLevel)
{
if (_exception != null && !_canRetryAuthentication)
{
ExceptionDispatchInfo.Throw(_exception);
}
if (_context != null && _context.IsValidContext)
{
throw new InvalidOperationException(SR.net_auth_reauth);
}
if (credential == null)
{
throw new ArgumentNullException(nameof(credential));
}
if (servicePrincipalName == null)
{
throw new ArgumentNullException(nameof(servicePrincipalName));
}
NegotiateStreamPal.ValidateImpersonationLevel(impersonationLevel);
if (_context != null && IsServer != isServer)
{
throw new InvalidOperationException(SR.net_auth_client_server);
}
_exception = null;
_remoteOk = false;
_framer = new StreamFramer(_innerStream);
_framer.WriteHeader.MessageId = FrameHeader.HandshakeId;
_expectedProtectionLevel = protectionLevel;
_expectedImpersonationLevel = isServer ? impersonationLevel : TokenImpersonationLevel.None;
_writeSequenceNumber = 0;
_readSequenceNumber = 0;
ContextFlagsPal flags = ContextFlagsPal.Connection;
// A workaround for the client when talking to Win9x on the server side.
if (protectionLevel == ProtectionLevel.None && !isServer)
{
package = NegotiationInfoClass.NTLM;
}
else if (protectionLevel == ProtectionLevel.EncryptAndSign)
{
flags |= ContextFlagsPal.Confidentiality;
}
else if (protectionLevel == ProtectionLevel.Sign)
{
// Assuming user expects NT4 SP4 and above.
flags |= (ContextFlagsPal.ReplayDetect | ContextFlagsPal.SequenceDetect | ContextFlagsPal.InitIntegrity);
}
if (isServer)
{
if (_extendedProtectionPolicy.PolicyEnforcement == PolicyEnforcement.WhenSupported)
{
flags |= ContextFlagsPal.AllowMissingBindings;
}
if (_extendedProtectionPolicy.PolicyEnforcement != PolicyEnforcement.Never &&
_extendedProtectionPolicy.ProtectionScenario == ProtectionScenario.TrustedProxy)
{
flags |= ContextFlagsPal.ProxyBindings;
}
}
else
{
// Server side should not request any of these flags.
if (protectionLevel != ProtectionLevel.None)
{
flags |= ContextFlagsPal.MutualAuth;
}
if (impersonationLevel == TokenImpersonationLevel.Identification)
{
flags |= ContextFlagsPal.InitIdentify;
}
if (impersonationLevel == TokenImpersonationLevel.Delegation)
{
flags |= ContextFlagsPal.Delegate;
}
}
_canRetryAuthentication = false;
try
{
_context = new NTAuthentication(isServer, package, credential, servicePrincipalName, flags, channelBinding);
}
catch (Win32Exception e)
{
throw new AuthenticationException(SR.net_auth_SSPI, e);
}
}