Browse Source

SMB2: implemented server-initiated SPNEGO authentication

Tal Aloni 8 years ago
parent
commit
092869efa1

+ 10 - 0
SMBLibrary/Authentication/GSSAPI/GSSAPIHelper.cs

@@ -48,6 +48,16 @@ namespace SMBLibrary.Authentication
             return null;
         }
 
+        public static byte[] GetGSSTokenInitNTLMSSPBytes()
+        {
+            SimpleProtectedNegotiationTokenInit token = new SimpleProtectedNegotiationTokenInit();
+            TokenInitEntry entry = new TokenInitEntry();
+            entry.MechanismTypeList = new List<byte[]>();
+            entry.MechanismTypeList.Add(NTLMSSPIdentifier);
+            token.Tokens.Add(entry);
+            return SimpleProtectedNegotiationToken.GetTokenBytes(token);
+        }
+
         public static byte[] GetGSSTokenResponseBytesFromNTLMSSPMessage(byte[] messageBytes)
         {
             SimpleProtectedNegotiationTokenResponse token = new SimpleProtectedNegotiationTokenResponse();

+ 28 - 0
SMBLibrary/Authentication/GSSAPI/SimpleProtectedNegotiationToken.cs

@@ -51,5 +51,33 @@ namespace SMBLibrary.Authentication
             }
             return null;
         }
+
+        /// <summary>
+        /// Will append the generic GSSAPI header.
+        /// </summary>
+        public static byte[] GetTokenBytes(SimpleProtectedNegotiationToken token)
+        {
+            if (token is SimpleProtectedNegotiationTokenInit)
+            {
+                byte[] tokenBytes = token.GetBytes();
+                int objectIdentifierFieldSize = DerEncodingHelper.GetLengthFieldSize(SPNEGOIdentifier.Length);
+                int tokenLength = 1 + objectIdentifierFieldSize + SPNEGOIdentifier.Length + tokenBytes.Length;
+                int tokenLengthFieldSize = DerEncodingHelper.GetLengthFieldSize(tokenLength);
+                int headerLength = 1 + tokenLengthFieldSize + 1 + objectIdentifierFieldSize + SPNEGOIdentifier.Length;
+                byte[] buffer = new byte[headerLength + tokenBytes.Length];
+                int offset = 0;
+                ByteWriter.WriteByte(buffer, ref offset, ApplicationTag);
+                DerEncodingHelper.WriteLength(buffer, ref offset, tokenLength);
+                ByteWriter.WriteByte(buffer, ref offset, (byte)DerEncodingTag.ObjectIdentifier);
+                DerEncodingHelper.WriteLength(buffer, ref offset, SPNEGOIdentifier.Length);
+                ByteWriter.WriteBytes(buffer, ref offset, SPNEGOIdentifier);
+                ByteWriter.WriteBytes(buffer, ref offset, tokenBytes);
+                return buffer;
+            }
+            else
+            {
+                return token.GetBytes();
+            }
+        }
     }
 }

+ 6 - 2
SMBLibrary/Authentication/GSSAPI/SimpleProtectedNegotiationTokenInit.cs

@@ -13,9 +13,9 @@ namespace SMBLibrary.Authentication
 {
     public class TokenInitEntry
     {
-        public List<byte[]> MechanismTypeList = new List<byte[]>(); // Optional
+        public List<byte[]> MechanismTypeList; // Optional
         // reqFlags - Optional, RECOMMENDED to be left out
-        public byte[] MechanismToken = new byte[0]; // Optional
+        public byte[] MechanismToken; // Optional
         public byte[] MechanismListMIC; // Optional
     }
 
@@ -32,6 +32,10 @@ namespace SMBLibrary.Authentication
 
         public List<TokenInitEntry> Tokens = new List<TokenInitEntry>();
 
+        public SimpleProtectedNegotiationTokenInit()
+        {
+        }
+
         /// <param name="offset">The offset following the NegTokenInit tag</param>
         public SimpleProtectedNegotiationTokenInit(byte[] buffer, int offset)
         {

+ 2 - 0
SMBLibrary/Server/SMB2/NegotiateHelper.cs

@@ -45,6 +45,7 @@ namespace SMBLibrary.Server.SMB2
             response.MaxWriteSize = 65536;
             response.SystemTime = DateTime.Now;
             response.ServerStartTime = DateTime.Today;
+            response.SecurityBuffer = GSSAPIHelper.GetGSSTokenInitNTLMSSPBytes();
             return response;
         }
 
@@ -71,6 +72,7 @@ namespace SMBLibrary.Server.SMB2
             response.MaxWriteSize = 65536;
             response.SystemTime = DateTime.Now;
             response.ServerStartTime = DateTime.Today;
+            response.SecurityBuffer = GSSAPIHelper.GetGSSTokenInitNTLMSSPBytes();
             return response;
         }