private void setNTLMToken() { initNTLMClientAuth(); if (NTLMChallangeToken != "") { serverToken = Convert.FromBase64String(NTLMChallangeToken); Debug.WriteLine("NTLM Challange token detected. Setting server token: " + NTLMChallangeToken); } //while (true) //{ NSSPIclientStatus = NSSPIclient.Init(serverToken, out NTLMClientToken); Debug.WriteLine("NSSPI ClientStatus: " + NSSPIclientStatus.ToString()); //if (clientStatus != SecurityStatus.ContinueNeeded) { break; } //} // this.NTLMToken = Convert.ToBase64String(NTLMClientToken); Debug.WriteLine("NTLMToken: " + this.NTLMToken); }
// for Server side (IIS 6.0) see: \\netindex\Sources\inetsrv\iis\iisrearc\iisplus\ulw3\digestprovider.cxx // for Client side (HTTP.SYS) see: \\netindex\Sources\net\http\sys\ucauth.c internal string GetOutgoingDigestBlob(string incomingBlob, string requestMethod, string requestedUri, string realm, bool isClientPreAuth, bool throwOnError, out SecurityStatus statusCode) { GlobalLog.Enter("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob", incomingBlob); // second time call with 3 incoming buffers to select HTTP client. // we should get back a SecurityStatus.OK and a non null outgoingBlob. SecurityBuffer[] inSecurityBuffers = null; SecurityBuffer outSecurityBuffer = new SecurityBuffer(m_TokenSize, isClientPreAuth ? BufferType.Parameters : BufferType.Token); bool firstTime = m_SecurityContext == null; try { if (!m_IsServer) { // client session if (!isClientPreAuth) { if (incomingBlob != null) { List<SecurityBuffer> list = new List<SecurityBuffer>(5); list.Add(new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(incomingBlob), BufferType.Token)); list.Add(new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(requestMethod), BufferType.Parameters)); list.Add(new SecurityBuffer(null, BufferType.Parameters)); list.Add(new SecurityBuffer(Encoding.Unicode.GetBytes(m_Spn), BufferType.TargetHost)); if (m_ChannelBinding != null) { list.Add(new SecurityBuffer(m_ChannelBinding)); } inSecurityBuffers = list.ToArray(); } statusCode = (SecurityStatus) SSPIWrapper.InitializeSecurityContext( GlobalSSPI.SSPIAuth, m_CredentialsHandle, ref m_SecurityContext, requestedUri, // this must match the Uri in the HTTP status line for the current request m_RequestedContextFlags, Endianness.Network, inSecurityBuffers, outSecurityBuffer, ref m_ContextFlags ); GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob() SSPIWrapper.InitializeSecurityContext() returns statusCode:0x" + ((int) statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); } else { #if WDIGEST_PREAUTH inSecurityBuffers = new SecurityBuffer[] { new SecurityBuffer(null, BufferType.Token), new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(requestMethod), BufferType.Parameters), new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(requestedUri), BufferType.Parameters), new SecurityBuffer(null, BufferType.Parameters), outSecurityBuffer, }; statusCode = (SecurityStatus) SSPIWrapper.MakeSignature(GlobalSSPI.SSPIAuth, m_SecurityContext, inSecurityBuffers, 0); GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob() SSPIWrapper.MakeSignature() returns statusCode:0x" + ((int) statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); #else statusCode = SecurityStatus.OK; GlobalLog.Assert("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob()", "Invalid code path."); #endif } } else { // server session List<SecurityBuffer> list = new List<SecurityBuffer>(6); list.Add(incomingBlob == null ? new SecurityBuffer(0, BufferType.Token) : new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(incomingBlob), BufferType.Token)); list.Add(requestMethod == null ? new SecurityBuffer(0, BufferType.Parameters) : new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(requestMethod), BufferType.Parameters)); list.Add(requestedUri == null ? new SecurityBuffer(0, BufferType.Parameters) : new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(requestedUri), BufferType.Parameters)); list.Add(new SecurityBuffer(0, BufferType.Parameters)); list.Add(realm == null ? new SecurityBuffer(0, BufferType.Parameters) : new SecurityBuffer(Encoding.Unicode.GetBytes(realm), BufferType.Parameters)); if (m_ChannelBinding != null) { list.Add(new SecurityBuffer(m_ChannelBinding)); } inSecurityBuffers = list.ToArray(); statusCode = (SecurityStatus) SSPIWrapper.AcceptSecurityContext( GlobalSSPI.SSPIAuth, m_CredentialsHandle, ref m_SecurityContext, m_RequestedContextFlags, Endianness.Network, inSecurityBuffers, outSecurityBuffer, ref m_ContextFlags ); GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob() SSPIWrapper.AcceptSecurityContext() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); if (statusCode == SecurityStatus.CompleteNeeded) { inSecurityBuffers[4] = outSecurityBuffer; statusCode = (SecurityStatus) SSPIWrapper.CompleteAuthToken( GlobalSSPI.SSPIAuth, ref m_SecurityContext, inSecurityBuffers ); GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob() SSPIWrapper.CompleteAuthToken() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); outSecurityBuffer.token = null; } } } finally { // // Assuming the ISC or ASC has referenced the credential on the first successful call, // we want to decrement the effective ref count by "disposing" it. // The real dispose will happen when the security context is closed. // Note if the first call was not successfull the handle is physically destroyed here // if (firstTime && m_CredentialsHandle != null) m_CredentialsHandle.Close(); } if (((int) statusCode & unchecked((int) 0x80000000)) != 0) { CloseContext(); if (throwOnError) { Win32Exception exception = new Win32Exception((int) statusCode); GlobalLog.Leave("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob", "Win32Exception:" + exception); throw exception; } GlobalLog.Leave("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob", "null statusCode:0x" + ((int) statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); return null; } else if (firstTime && m_CredentialsHandle != null) { // cache until it is pushed out by newly incoming handles SSPIHandleCache.CacheCredential(m_CredentialsHandle); } // the return value from SSPI will tell us correctly if the // handshake is over or not: http://msdn.microsoft.com/library/psdk/secspi/sspiref_67p0.htm if (statusCode == SecurityStatus.OK) { // we're done, cleanup m_IsCompleted = true; } else { // we need to continue GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob() need continue statusCode:[0x" + ((int) statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + "] (" + statusCode.ToString() + ") m_SecurityContext#" + ValidationHelper.HashString(m_SecurityContext) + "::Handle:" + ValidationHelper.ToString(m_SecurityContext) + "]"); } GlobalLog.Print("out token = " + outSecurityBuffer.ToString()); GlobalLog.Dump(outSecurityBuffer.token); GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob() IsCompleted:" + IsCompleted.ToString()); byte[] decodedOutgoingBlob = outSecurityBuffer.token; string outgoingBlob = null; if (decodedOutgoingBlob!=null && decodedOutgoingBlob.Length>0) { outgoingBlob = WebHeaderCollection.HeaderEncoding.GetString(decodedOutgoingBlob, 0, outSecurityBuffer.size); } GlobalLog.Leave("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob", outgoingBlob); return outgoingBlob; }
// NTAuth::GetOutgoingBlob() // Created: 12-01-1999: L.M. // Description: // Accepts an incoming binary security blob and returns // an outgoing binary security blob internal byte[] GetOutgoingBlob(byte[] incomingBlob, bool throwOnError, out SecurityStatus statusCode) { GlobalLog.Enter("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob", ((incomingBlob == null) ? "0" : incomingBlob.Length.ToString(NumberFormatInfo.InvariantInfo)) + " bytes"); List<SecurityBuffer> list = new List<SecurityBuffer>(2); if (incomingBlob != null) { list.Add(new SecurityBuffer(incomingBlob, BufferType.Token)); } if (m_ChannelBinding != null) { list.Add(new SecurityBuffer(m_ChannelBinding)); } SecurityBuffer[] inSecurityBufferArray = null; if (list.Count > 0) { inSecurityBufferArray = list.ToArray(); } SecurityBuffer outSecurityBuffer = new SecurityBuffer(m_TokenSize, BufferType.Token); bool firstTime = m_SecurityContext == null; try { if (!m_IsServer) { // client session statusCode = (SecurityStatus)SSPIWrapper.InitializeSecurityContext( GlobalSSPI.SSPIAuth, m_CredentialsHandle, ref m_SecurityContext, m_Spn, m_RequestedContextFlags, Endianness.Network, inSecurityBufferArray, outSecurityBuffer, ref m_ContextFlags); GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob() SSPIWrapper.InitializeSecurityContext() returns statusCode:0x" + ((int) statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); if (statusCode == SecurityStatus.CompleteNeeded) { SecurityBuffer[] inSecurityBuffers = new SecurityBuffer[1]; inSecurityBuffers[0] = outSecurityBuffer; statusCode = (SecurityStatus) SSPIWrapper.CompleteAuthToken( GlobalSSPI.SSPIAuth, ref m_SecurityContext, inSecurityBuffers ); GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob() SSPIWrapper.CompleteAuthToken() returns statusCode:0x" + ((int) statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); outSecurityBuffer.token = null; } } else { // server session statusCode = (SecurityStatus)SSPIWrapper.AcceptSecurityContext( GlobalSSPI.SSPIAuth, m_CredentialsHandle, ref m_SecurityContext, m_RequestedContextFlags, Endianness.Network, inSecurityBufferArray, outSecurityBuffer, ref m_ContextFlags); GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob() SSPIWrapper.AcceptSecurityContext() returns statusCode:0x" + ((int) statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); } } finally { // // Assuming the ISC or ASC has referenced the credential on the first successful call, // we want to decrement the effective ref count by "disposing" it. // The real dispose will happen when the security context is closed. // Note if the first call was not successfull the handle is physically destroyed here // if (firstTime && m_CredentialsHandle != null) m_CredentialsHandle.Close(); } if (((int) statusCode & unchecked((int) 0x80000000)) != 0) { CloseContext(); m_IsCompleted = true; if (throwOnError) { Win32Exception exception = new Win32Exception((int) statusCode); GlobalLog.Leave("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob", "Win32Exception:" + exception); throw exception; } GlobalLog.Leave("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob", "null statusCode:0x" + ((int) statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")"); return null; } else if (firstTime && m_CredentialsHandle != null) { // cache until it is pushed out by newly incoming handles SSPIHandleCache.CacheCredential(m_CredentialsHandle); } // the return value from SSPI will tell us correctly if the // handshake is over or not: http://msdn.microsoft.com/library/psdk/secspi/sspiref_67p0.htm // we also have to consider the case in which SSPI formed a new context, in this case we're done as well. if (statusCode == SecurityStatus.OK) { // we're sucessfully done GlobalLog.Assert(statusCode == SecurityStatus.OK, "NTAuthentication#{0}::GetOutgoingBlob()|statusCode:[0x{1:x8}] ({2}) m_SecurityContext#{3}::Handle:[{4}] [STATUS != OK]", ValidationHelper.HashString(this), (int)statusCode, statusCode, ValidationHelper.HashString(m_SecurityContext), ValidationHelper.ToString(m_SecurityContext)); m_IsCompleted = true; } else { // we need to continue GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob() need continue statusCode:[0x" + ((int) statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + "] (" + statusCode.ToString() + ") m_SecurityContext#" + ValidationHelper.HashString(m_SecurityContext) + "::Handle:" + ValidationHelper.ToString(m_SecurityContext) + "]"); } // GlobalLog.Print("out token = " + outSecurityBuffer.ToString()); // GlobalLog.Dump(outSecurityBuffer.token); GlobalLog.Leave("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob", "IsCompleted:" + IsCompleted.ToString()); return outSecurityBuffer.token; }
protected sealed override void InternalValidate() { if (this.Instance.IsModified(ADObjectSchema.Name)) { base.WriteError(new InvalidOperationException(Strings.ErrorServerNameModified), ErrorCategory.InvalidOperation, this.Identity); } base.InternalValidate(); if (base.Fields.IsModified("AutoDiscoverServiceInternalUri") && this.AutoDiscoverServiceInternalUri != null && (!this.AutoDiscoverServiceInternalUri.IsWellFormedOriginalString() || !Uri.IsWellFormedUriString(this.AutoDiscoverServiceInternalUri.ToString(), UriKind.Absolute))) { base.WriteError(new ArgumentException(Strings.AutoDiscoverUrlIsBad, "AutoDiscoverServiceInternalUri"), ErrorCategory.InvalidArgument, this.DataObject.Identity); return; } if (base.ParameterSetName == "AlternateServiceAccount") { if (this.CleanUpInvalidAlternateServiceAccountCredentials.ToBool() && this.RemoveAlternateServiceAccountCredentials.ToBool()) { base.WriteError(new InvalidOperationException(Strings.ErrorCleanUpAndRemoveAlternateServiceAccountsAreMutuallyExclusive), ErrorCategory.SyntaxError, this.DataObject.Identity); } if (this.CleanUpInvalidAlternateServiceAccountCredentials.ToBool()) { AlternateServiceAccountCredential[] array = this.alternateServiceAccountConfiguration.AllCredentials.ToArray <AlternateServiceAccountCredential>(); ICollection <string> collection = new HashSet <string>(Microsoft.Exchange.Data.Directory.Management.AlternateServiceAccountCredential.UserNameComparer); foreach (AlternateServiceAccountCredential alternateServiceAccountCredential in array) { if (base.Stopping) { break; } bool flag = !collection.Contains(alternateServiceAccountCredential.QualifiedUserName); if (flag) { SecurityStatus securityStatus = SecurityStatus.DecryptFailure; flag &= alternateServiceAccountCredential.IsValid; if (flag) { base.WriteVerbose(Strings.VerboseValidatingAlternateServiceAccountCredential(alternateServiceAccountCredential.QualifiedUserName, alternateServiceAccountCredential.WhenAdded.Value)); flag &= alternateServiceAccountCredential.TryAuthenticate(out securityStatus); } if (!flag) { base.WriteVerbose(Strings.VerboseFoundInvalidAlternateServiceAccountCredential(alternateServiceAccountCredential.QualifiedUserName, alternateServiceAccountCredential.WhenAdded ?? DateTime.MinValue, securityStatus.ToString())); } } if (flag) { base.WriteVerbose(Strings.VerboseFoundValidAlternateServiceAccountCredential(alternateServiceAccountCredential.QualifiedUserName, alternateServiceAccountCredential.WhenAdded.Value)); collection.Add(alternateServiceAccountCredential.QualifiedUserName); } else { this.alternateServiceAccountCredentialsToRemove.Add(alternateServiceAccountCredential); } } if (array.Length > 0 && array.Length == this.alternateServiceAccountCredentialsToRemove.Count) { this.WriteWarning(Strings.AllAlternateServiceAccountCredentialsAreInvalidOnCleanup(this.DataObject.Fqdn)); this.alternateServiceAccountCredentialsToRemove.Clear(); } } } }
/*++ * Encrypt - Encrypts our bytes before we send them over the wire * * PERF: make more efficient, this does an extra copy when the offset * is non-zero. * * Input: * buffer - bytes for sending * offset - * size - * output - Encrypted bytes * --*/ internal SecurityStatus Encrypt(byte[] buffer, int offset, int size, ref byte[] output, out int resultSize) { GlobalLog.Enter("SecureChannel#" + Logging.HashString(this) + "::Encrypt"); GlobalLog.Print("SecureChannel#" + Logging.HashString(this) + "::Encrypt() - offset: " + offset.ToString() + " size: " + size.ToString() + " buffersize: " + buffer.Length.ToString()); GlobalLog.Print("SecureChannel#" + Logging.HashString(this) + "::Encrypt() buffer:"); GlobalLog.Dump(buffer, Math.Min(buffer.Length, 128)); byte[] writeBuffer; try { if (offset < 0 || offset > (buffer == null ? 0 : buffer.Length)) { throw new ArgumentOutOfRangeException("offset"); } if (size < 0 || size > (buffer == null ? 0 : buffer.Length - offset)) { throw new ArgumentOutOfRangeException("size"); } resultSize = 0; int bufferSizeNeeded = checked (size + _headerSize + _trailerSize); if (output != null && bufferSizeNeeded <= output.Length) { writeBuffer = output; } else { writeBuffer = new byte[bufferSizeNeeded]; } Buffer.BlockCopy(buffer, offset, writeBuffer, _headerSize, size); } catch (Exception e) { if (!ExceptionCheck.IsFatal(e)) { GlobalLog.Assert(false, "SecureChannel#" + Logging.HashString(this) + "::Encrypt", "Arguments out of range."); } throw; } SecurityStatus secStatus = SSPIWrapper.EncryptMessage(GlobalSSPI.SSPISecureChannel, _securityContext, writeBuffer, size, _headerSize, _trailerSize, out resultSize); if (secStatus != SecurityStatus.OK) { GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::Encrypt ERROR", secStatus.ToString("x")); } else { output = writeBuffer; GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::Encrypt OK", "data size:" + resultSize.ToString()); } return(secStatus); }
public override string ToString() { return("Status=" + Status.ToString() + ", data size=" + Size); }