Note that there are some explanatory texts on larger screens.

plurals
  1. POSecurityIdentifiers in Cassini-dev's NTLM authentication
    text
    copied!<p>In this block of code in Cassini-dev's NTLM authentication class, calls made to SECUR32.DLL (via <strong>Interop</strong>) are made to authenticate the base64 encoded data in an HTTP request's <code>Authorization</code> headers. This makes sense, when both <strong>AcceptSecurityContext()</strong> and <strong>QuerySecurityContextToken()</strong> return <code>0</code>, the client has been authorized. At the end, the security context token has a <code>SecurityIdentifier</code> extracted from it (the <strong>_sid</strong> variable). (A bit about <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa379649%28v=VS.85%29.aspx" rel="nofollow">common Security IDs</a> )</p> <p>Here is the relevant section of the <a href="http://cassinidev.codeplex.com/SourceControl/changeset/view/60871#1365123" rel="nofollow">NtlmAuth Class</a></p> <pre><code>int num = Interop.AcceptSecurityContext(ref _credentialsHandle, zero, ref _inputBufferDesc, 20, 0, ref _securityContext, ref _outputBufferDesc, ref _securityContextAttributes, ref _timestamp); if (num == 0x90312) { securityContextAcquired = true; _blob = Convert.ToBase64String(inArray, 0, (int) _outputBuffer.cbBuffer); } else { if (num != 0) { return false; } IntPtr phToken = IntPtr.Zero; if (Interop.QuerySecurityContextToken(ref _securityContext, ref phToken) != 0) { return false; } try { using (WindowsIdentity identity = new WindowsIdentity(phToken)) { _sid = identity.User; } } finally { Interop.CloseHandle(phToken); } _completed = true; </code></pre> <p>In the <a href="http://cassinidev.codeplex.com/SourceControl/changeset/view/60871#1365119" rel="nofollow">Request Class</a>, in the <code>TryNtlmAuthenticate()</code> method where NtlmAuth is being used, after successfully completing the 3 steps of the NTLM authentication, before returning either a final <em>403</em> or fulfilling the request, one final check is being made:</p> <pre><code>if (_host.GetProcessSid() != auth.SID) { _connection.WriteErrorAndClose(0x193); return false; } </code></pre> <p>Here, the <strong>_host.GetProcessSid()</strong> is the <code>SecurityIndentifier</code> of the owner of the Cassini process (me) and <strong>auth.SID</strong> is the <code>SecurityIdentifier</code> of the user that was authenticated (<strong>_sid</strong> from the NtlmAuth class above). If these 2 SID's are not the same, a 403 is returned and authentication stops, otherwise the request is served to the browser.</p> <hr> <p>My questions are:</p> <ol> <li>Why would you need to compare the SecurityIndentifiers of 2 different users? This fails (returns a 403) when I attempt to NTLM authenticate with a user/password that <em>isn't</em> the user that owns the Cassini process.</li> <li>If this really is the intended behavior, if Cassini is to run as a Windows service, nobody would be able to log in because the host SID would be <strong>S-1-5-18</strong> (or maybe something similar depending on the OS version) and nobody can log in as the operating system. Is this just part of Cassini's NTLM authentication implementation and I'm not using Cassini correctly?</li> <li>If this is clearly not the intended behavior, what role does SecurityIndentifiers play in this context? Does extra checks need to be made to ensure host SID's need to be of a certain class or group in order to accept client SID's of certain class/group? Are there OS version (XP/Vista/7) implications when dealing with host/client SID's?</li> <li>Or are there no applicable uses of SecurityIdentifiers here since they are not being stored nor passed around, nor are they being used to further identify the user/client?</li> </ol> <hr> <p><strong>Update:</strong> It seems that someone at the cassinidev forums <a href="http://cassinidev.codeplex.com/sourcecontrol/list/patches?ViewAll=true&amp;ProjectName=cassinidev" rel="nofollow">proposed a patch which removes this SID check</a> (patch #6604) back in 2010 but it's still being evaluated.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload