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;
        }
Example #4
0
 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();
             }
         }
     }
 }
Example #5
0
        /*++
         *  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);
        }
Example #6
0
 public override string ToString()
 {
     return("Status=" + Status.ToString() + ", data size=" + Size);
 }