示例#1
0
 static extern int InitializeSecurityContext(
     ref SecHandle phCredential,
     ref SecHandle phContext,
     string pszTargetName,
     int fContextReq,
     int Reserved1,
     int TargetDataRep,
     ref SecBufferDesc pInput,
     int Reserved2,
     out SecHandle phNewContext,
     out SecBufferDesc pOutput,
     out int pfContextAttr,
     out SecHandle ptsExpiry);
		/// <summary>
		/// Creates client security context and returns "client token"
		/// </summary>
		/// <returns>Client authentication data to be sent to server</returns>
		public byte[] InitializeClientSecurity()
		{
			if (_disposed)
				throw new ObjectDisposedException("SSPIHelper");
			CloseClientContext();
			SecInteger expiry = new SecInteger(0);
			uint contextAttributes;
			SecBufferDesc clientTokenBuf = new SecBufferDesc(MAX_TOKEN_SIZE);
			try
			{
				int resCode = InitializeSecurityContext(
					ref _clientCredentials,
					IntPtr.Zero,
					_remotePrincipal,// null string pszTargetName,
					STANDARD_CONTEXT_ATTRIBUTES,
					0,//int Reserved1,
					SECURITY_NATIVE_DREP,//int TargetDataRep
					IntPtr.Zero,    //Always zero first time around...
					0, //int Reserved2,
					out _clientContext, //pHandle CtxtHandle = SecHandle
					ref clientTokenBuf,//ref SecBufferDesc pOutput, //PSecBufferDesc
					out contextAttributes,//ref int pfContextAttr,
					out expiry); //ref IntPtr ptsExpiry ); //PTimeStamp
				if (resCode != SEC_E_OK && resCode != SEC_I_CONTINUE_NEEDED)
					throw new Exception("InitializeSecurityContext failed");
				return clientTokenBuf.GetSecBufferBytes();
			}
			finally
			{
				clientTokenBuf.Dispose();
			}
		}
示例#3
0
 internal static unsafe partial int ApplyControlToken(
     void *inContextPtr,
     ref SecBufferDesc inputBuffers);
示例#4
0
 internal static extern unsafe int DecryptMessage(
     [In] ref CredHandle contextHandle,
     [In, Out] ref SecBufferDesc inputOutput,
     [In] uint sequenceNumber,
     uint *qualityOfProtection
     );
示例#5
0
 public static extern int AcceptSecurityContext(ref SECURITY_HANDLE phCredential,
                                         IntPtr phContext,
                                         ref SecBufferDesc pInput,
                                         uint fContextReq,
                                         uint TargetDataRep,
                                         out SECURITY_HANDLE phNewContext,
                                         out SecBufferDesc pOutput,
                                         out uint pfContextAttr,    //managed ulong == 64 bits!!!
                                         out SECURITY_INTEGER ptsTimeStamp);
示例#6
0
 internal static unsafe partial int DecryptMessage(
     ref CredHandle contextHandle,
     ref SecBufferDesc inputOutput,
     uint sequenceNumber,
     uint *qualityOfProtection);
示例#7
0
        public ContextStatus InitializeSecurityContext(string targetName, byte[] serverResponse, out byte[] clientRequest)
        {
            var targetNameNormalized = targetName.ToLowerInvariant();

            clientRequest = null;

            // 1. acquire
            // 2. initialize
            // 3. ??

            SecStatus result = 0;

            int tokenSize = 0;

            SecBufferDesc clientToken = default;

            try
            {
                do
                {
                    clientToken = new SecBufferDesc(tokenSize);

                    if (!credentialsHandle.IsSet || result == SecStatus.SEC_I_CONTINUE_NEEDED)
                    {
                        AcquireCredentials();
                    }

                    if (serverResponse == null)
                    {
                        result = InitializeSecurityContext_0(
                            ref credentialsHandle,
                            IntPtr.Zero,
                            targetNameNormalized,
                            clientFlags,
                            0,
                            SECURITY_NETWORK_DREP,
                            IntPtr.Zero,
                            0,
                            ref securityContext,
                            ref clientToken,
                            out ContextFlag ContextFlags,
                            IntPtr.Zero
                            );
                    }
                    else
                    {
                        var pInputBuffer = new SecBufferDesc(serverResponse);
                        {
                            IntPtr pExpiry = IntPtr.Zero;

                            result = InitializeSecurityContext_1(
                                ref credentialsHandle,
                                ref securityContext,
                                targetNameNormalized,
                                clientFlags,
                                0,
                                SECURITY_NETWORK_DREP,
                                ref pInputBuffer,
                                0,
                                ref securityContext,
                                ref clientToken,
                                out ContextFlag ContextFlags,
                                ref pExpiry
                                );
                        }
                    }

                    if (result == SecStatus.SEC_E_INSUFFICENT_MEMORY)
                    {
                        if (tokenSize > MaxTokenSize)
                        {
                            break;
                        }

                        tokenSize += 1000;
                    }
                }while (result == SecStatus.SEC_I_INCOMPLETE_CREDENTIALS || result == SecStatus.SEC_E_INSUFFICENT_MEMORY);

                if (result > SecStatus.SEC_E_ERROR)
                {
                    throw new Win32Exception((int)result);
                }

                clientRequest = clientToken.ReadBytes();

                if (result == SecStatus.SEC_I_CONTINUE_NEEDED)
                {
                    return(ContextStatus.RequiresContinuation);
                }

                return(ContextStatus.Accepted);
            }
            finally
            {
                clientToken.Dispose();
            }
        }
示例#8
0
 public static extern int MakeSignature(ref SECURITY_HANDLE phContext,          // Context to use
                                         uint fQOP,         // Quality of Protection
                                         ref SecBufferDesc pMessage,        // Message to sign
                                         uint MessageSeqNo);
示例#9
0
 public static extern int CompleteAuthToken(
     [In] ref SecHandle phNewContext,
     [In] ref SecBufferDesc pOutput
     );
示例#10
0
        public ContextStatus AcceptSecurityContext(byte[] clientRequest, out byte[] serverResponse)
        {
            serverResponse = null;

            if (!credentialsHandle.IsSet)
            {
                AcquireCredentials();
            }

            var pInput = new SecBufferDesc(clientRequest);

            var           tokenSize = 0;
            SecBufferDesc pOutput   = default;

            try
            {
                SecStatus result;

                do
                {
                    pOutput = new SecBufferDesc(tokenSize);

                    if (!securityContext.IsSet)
                    {
                        result = AcceptSecurityContext_0(
                            ref credentialsHandle,
                            IntPtr.Zero,
                            ref pInput,
                            serverFlags,
                            SECURITY_NETWORK_DREP,
                            ref securityContext,
                            out pOutput,
                            out ContextFlag pfContextAttr,
                            out SECURITY_INTEGER ptsTimeStamp
                            );
                    }
                    else
                    {
                        result = AcceptSecurityContext_1(
                            ref credentialsHandle,
                            ref securityContext,
                            ref pInput,
                            serverFlags,
                            SECURITY_NETWORK_DREP,
                            ref securityContext,
                            out pOutput,
                            out ContextFlag pfContextAttr,
                            out SECURITY_INTEGER ptsTimeStamp
                            );
                    }

                    if (result == SecStatus.SEC_E_INSUFFICENT_MEMORY)
                    {
                        if (tokenSize > MaxTokenSize)
                        {
                            break;
                        }

                        tokenSize += 1000;
                    }
                }while (result == SecStatus.SEC_I_INCOMPLETE_CREDENTIALS || result == SecStatus.SEC_E_INSUFFICENT_MEMORY);

                TrackUnmanaged(securityContext);

                if (result > SecStatus.SEC_E_ERROR)
                {
                    throw new Win32Exception((int)result);
                }

                serverResponse = pOutput.ReadBytes();

                if (result == SecStatus.SEC_I_CONTINUE_NEEDED)
                {
                    return(ContextStatus.RequiresContinuation);
                }

                return(ContextStatus.Accepted);
            }
            finally
            {
                pInput.Dispose();
                pOutput.Dispose();
            }
        }
示例#11
0
 internal static void UpdateBuffers(this IEnumerable <SecurityBuffer> buffers, SecBufferDesc desc)
 {
     UpdateBuffers(buffers.ToArray(), desc);
 }
示例#12
0
 internal static extern SEC_RESULT AcceptSecurityContext(SecurityHandle phCredential, ref SecurityHandle phContext,
                                                         ref SecBufferDesc pInput, ASC_REQ fContextReq, Data_Rep TargetDataRep, out SecurityHandle phNewContext,
                                                         ref SecBufferDesc pOutput, out uint pfContextAttr, out SecurityInteger ptsTimeStamp);
示例#13
0
        public unsafe string AcceptSecurityToken(byte[] token)
        {
            fixed(byte *bufferPtr = token)
            {
                var buffer = stackalloc SecBuffer[1];

                buffer[0].BufferType = SecurityBufferType.SECBUFFER_TOKEN;
                buffer[0].cbBuffer   = (uint)token.Length;
                buffer[0].pvBuffer   = (IntPtr)bufferPtr;

                var outBufferPtr = stackalloc byte[512];
                var outBuffer    = stackalloc SecBuffer[1];

                outBuffer[0].BufferType = SecurityBufferType.SECBUFFER_TOKEN;
                outBuffer[0].cbBuffer   = 512;
                outBuffer[0].pvBuffer   = (IntPtr)outBufferPtr;

                var bufferDesc = new SecBufferDesc()
                {
                    cBuffers  = 1,
                    pBuffers  = (IntPtr)buffer,
                    ulVersion = 0
                };

                var outBufferDesc = new SecBufferDesc()
                {
                    cBuffers  = 1,
                    pBuffers  = (IntPtr)outBuffer,
                    ulVersion = 0
                };
                uint            contextAttribute;
                SecurityInteger timeStamp;
                SEC_RESULT      result;

                if (_context.HighPart == _context.LowPart && _context.HighPart == IntPtr.Zero)
                {
                    result = AcceptSecurityContext(_ntlmHandle, IntPtr.Zero, ref bufferDesc, _requestType, Data_Rep.SECURITY_NATIVE_DREP,
                                                   out _context, ref outBufferDesc, out contextAttribute, out timeStamp);
                }
                else
                {
                    result = AcceptSecurityContext(_ntlmHandle, ref _context, ref bufferDesc, _requestType, Data_Rep.SECURITY_NATIVE_DREP,
                                                   out _context, ref outBufferDesc, out contextAttribute, out timeStamp);
                }
                string returnToken = null;

                if (result == SEC_RESULT.SEC_I_CONTINUE_NEEDED)
                {
                    var byteSpan = new byte[(int)outBuffer[0].cbBuffer];
                    Marshal.Copy((IntPtr)outBufferPtr, byteSpan, 0, byteSpan.Length);
                    returnToken = "Negotiate " + Convert.ToBase64String(byteSpan);
                    return(returnToken);
                }

                if (result == SEC_RESULT.SEC_E_OK)
                {
                    IntPtr handle;
                    if (outBuffer[0].cbBuffer > 0)
                    {
                        var byteSpan = new byte[(int)outBuffer[0].cbBuffer];
                        Marshal.Copy((IntPtr)outBufferPtr, byteSpan, 0, byteSpan.Length);
                        returnToken = "Negotiate " + Convert.ToBase64String(byteSpan);
                    }
                    result    = QuerySecurityContextToken(ref _context, out handle);
                    _identity = new WindowsIdentity(handle);
                    Interop.Kernel32.CloseHandle(handle);
                    return(returnToken);
                }
                throw new InvalidOperationException();
            }
        }
示例#14
0
        internal byte[] Continue([CanBeNull] byte[] authData)
        {
            if (authData == null && _isSSPICtxSet)
                throw new InvalidOperationException("The authData parameter con only be null at the first call to continue!");

            var outBuffer = new SecBuffer
            {
                pvBuffer = IntPtr.Zero,
                BufferType = SecbufferToken,
                cbBuffer = 0
            };

            var outbuf = new SecBufferDesc
            {
                cBuffers = 1,
                ulVersion = SecbufferVersion,
                pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(outBuffer))
            };

            try
            {
                int status;
                SecHandle newContext;
                SecHandle expire;
                int contextAttr;

                Marshal.StructureToPtr(outBuffer, outbuf.pBuffer, false);

                if (_isSSPICtxSet)
                {
                    Contract.Assert(authData != null);
                    var inbuf = new SecBufferDesc { pBuffer = IntPtr.Zero };
                    var inBuffer = new SecBuffer { pvBuffer = Marshal.AllocHGlobal(authData.Length) };
                    try
                    {
                        Marshal.Copy(authData, 0, inBuffer.pvBuffer, authData.Length);
                        inBuffer.cbBuffer = authData.Length;
                        inBuffer.BufferType = SecbufferToken;
                        inbuf.ulVersion = SecbufferVersion;
                        inbuf.cBuffers = 1;
                        inbuf.pBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(inBuffer));
                        Marshal.StructureToPtr(inBuffer, inbuf.pBuffer, false);
                        status = InitializeSecurityContext(
                            ref _sspiCred,
                            ref _sspiCtx,
                            _sspiTarget,
                            IscReqAllocateMemory,
                            0,
                            SecurityNetworkDrep,
                            ref inbuf,
                            0,
                            out newContext,
                            out outbuf,
                            out contextAttr,
                            out expire
                        );
                    }
                    finally
                    {
                        if (inBuffer.pvBuffer != IntPtr.Zero)
                            Marshal.FreeHGlobal(inBuffer.pvBuffer);
                        if (inbuf.pBuffer != IntPtr.Zero)
                            Marshal.FreeHGlobal(inbuf.pBuffer);
                    }
                }
                else
                {
                    status = InitializeSecurityContext(
                        ref _sspiCred,
                        IntPtr.Zero,
                        _sspiTarget,
                        IscReqAllocateMemory,
                        0,
                        SecurityNetworkDrep,
                        IntPtr.Zero,
                        0,
                        out newContext,
                        out outbuf,
                        out contextAttr,
                        out expire
                    );
                }

                if (status != SecEOk && status != SecIContinueNeeded)
                {
                    // This will automaticcaly fill in the message of the last Win32 error
                    throw new Win32Exception();
                }
                if (!_isSSPICtxSet)
                {
                    _sspiCtx.dwUpper = newContext.dwUpper;
                    _sspiCtx.dwLower = newContext.dwLower;
                    _isSSPICtxSet = true;
                }

                if (outbuf.cBuffers > 0)
                {
                    if (outbuf.cBuffers != 1)
                        throw new InvalidOperationException("SSPI returned invalid number of output buffers");
                    // attention: OutBuffer is still our initially created struct but outbuf.pBuffer doesn't point to
                    // it but to the copy of it we created on the unmanaged heap and passed to InitializeSecurityContext()
                    // we have to marshal it back to see the content change
#if NET45
                    outBuffer = (SecBuffer)Marshal.PtrToStructure(outbuf.pBuffer, typeof(SecBuffer));
#else
                    outBuffer = Marshal.PtrToStructure<SecBuffer>(outbuf.pBuffer);
#endif
                    if (outBuffer.cbBuffer > 0)
                    {
                        // we need the buffer with a terminating 0 so we
                        // make it one byte bigger
                        var buffer = new byte[outBuffer.cbBuffer];
                        Marshal.Copy(outBuffer.pvBuffer, buffer, 0, buffer.Length);
                        // The SSPI authentication data must be sent as password message

                        return buffer;
                        //stream.WriteByte((byte)'p');
                        //PGUtil.WriteInt32(stream, buffer.Length + 5);
                        //stream.Write(buffer, 0, buffer.Length);
                        //stream.Flush();
                    }
                }
                return PGUtil.EmptyBuffer;
            }
            finally
            {
                if (outBuffer.pvBuffer != IntPtr.Zero)
                    FreeContextBuffer(outBuffer.pvBuffer);
                if (outbuf.pBuffer != IntPtr.Zero)
                    Marshal.FreeHGlobal(outbuf.pBuffer);
            }
        }
示例#15
0
 public static extern int AcceptSecurityContext(ref SecHandle phCredential, IntPtr phContext,
                                                ref SecBufferDesc pInput, uint fContextReq, uint TargetDataRep,
                                                ref SecHandle phNewContext, ref SecBufferDesc pOutput,
                                                ref uint pfContextAttr, ref long ptsTimeStamp);
示例#16
0
        internal byte[] Continue([CanBeNull] byte[] authData)
        {
            if (authData == null && _isSSPICtxSet)
            {
                throw new InvalidOperationException("The authData parameter con only be null at the first call to continue!");
            }

            var outBuffer = new SecBuffer
            {
                pvBuffer   = IntPtr.Zero,
                BufferType = SecbufferToken,
                cbBuffer   = 0
            };

            var outbuf = new SecBufferDesc
            {
                cBuffers  = 1,
                ulVersion = SecbufferVersion,
                pBuffer   = Marshal.AllocHGlobal(Marshal.SizeOf(outBuffer))
            };

            try
            {
                int       status;
                SecHandle newContext;
                SecHandle expire;
                int       contextAttr;

                Marshal.StructureToPtr(outBuffer, outbuf.pBuffer, false);

                if (_isSSPICtxSet)
                {
                    Contract.Assert(authData != null);
                    var inbuf = new SecBufferDesc {
                        pBuffer = IntPtr.Zero
                    };
                    var inBuffer = new SecBuffer {
                        pvBuffer = Marshal.AllocHGlobal(authData.Length)
                    };
                    try
                    {
                        Marshal.Copy(authData, 0, inBuffer.pvBuffer, authData.Length);
                        inBuffer.cbBuffer   = authData.Length;
                        inBuffer.BufferType = SecbufferToken;
                        inbuf.ulVersion     = SecbufferVersion;
                        inbuf.cBuffers      = 1;
                        inbuf.pBuffer       = Marshal.AllocHGlobal(Marshal.SizeOf(inBuffer));
                        Marshal.StructureToPtr(inBuffer, inbuf.pBuffer, false);
                        status = InitializeSecurityContext(
                            ref _sspiCred,
                            ref _sspiCtx,
                            _sspiTarget,
                            IscReqAllocateMemory,
                            0,
                            SecurityNetworkDrep,
                            ref inbuf,
                            0,
                            out newContext,
                            out outbuf,
                            out contextAttr,
                            out expire
                            );
                    }
                    finally
                    {
                        if (inBuffer.pvBuffer != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(inBuffer.pvBuffer);
                        }
                        if (inbuf.pBuffer != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(inbuf.pBuffer);
                        }
                    }
                }
                else
                {
                    status = InitializeSecurityContext(
                        ref _sspiCred,
                        IntPtr.Zero,
                        _sspiTarget,
                        IscReqAllocateMemory,
                        0,
                        SecurityNetworkDrep,
                        IntPtr.Zero,
                        0,
                        out newContext,
                        out outbuf,
                        out contextAttr,
                        out expire
                        );
                }

                if (status != SecEOk && status != SecIContinueNeeded)
                {
                    // This will automaticcaly fill in the message of the last Win32 error
                    throw new Win32Exception();
                }
                if (!_isSSPICtxSet)
                {
                    _sspiCtx.dwUpper = newContext.dwUpper;
                    _sspiCtx.dwLower = newContext.dwLower;
                    _isSSPICtxSet    = true;
                }

                if (outbuf.cBuffers > 0)
                {
                    if (outbuf.cBuffers != 1)
                    {
                        throw new InvalidOperationException("SSPI returned invalid number of output buffers");
                    }
                    // attention: OutBuffer is still our initially created struct but outbuf.pBuffer doesn't point to
                    // it but to the copy of it we created on the unmanaged heap and passed to InitializeSecurityContext()
                    // we have to marshal it back to see the content change
#if NET45
                    outBuffer = (SecBuffer)Marshal.PtrToStructure(outbuf.pBuffer, typeof(SecBuffer));
#else
                    outBuffer = Marshal.PtrToStructure <SecBuffer>(outbuf.pBuffer);
#endif
                    if (outBuffer.cbBuffer > 0)
                    {
                        // we need the buffer with a terminating 0 so we
                        // make it one byte bigger
                        var buffer = new byte[outBuffer.cbBuffer];
                        Marshal.Copy(outBuffer.pvBuffer, buffer, 0, buffer.Length);
                        // The SSPI authentication data must be sent as password message

                        return(buffer);
                        //stream.WriteByte((byte)'p');
                        //PGUtil.WriteInt32(stream, buffer.Length + 5);
                        //stream.Write(buffer, 0, buffer.Length);
                        //stream.Flush();
                    }
                }
                return(PGUtil.EmptyBuffer);
            }
            finally
            {
                if (outBuffer.pvBuffer != IntPtr.Zero)
                {
                    FreeContextBuffer(outBuffer.pvBuffer);
                }
                if (outbuf.pBuffer != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(outbuf.pBuffer);
                }
            }
        }
示例#17
0
 public static extern int EncryptMessage(ref SECURITY_HANDLE phContext,
                                         uint fQOP,          //managed ulong == 64 bits!!!
                                         ref SecBufferDesc pMessage,
                                         uint MessageSeqNo); //managed ulong == 64 bits!!!
示例#18
0
 public static extern int VerifySignature(ref SECURITY_HANDLE phContext,          // Context to use
                                         ref SecBufferDesc pMessage,        // Message to sign
                                         uint MessageSeqNo,            // Message Sequence Num.
                                         out uint pfQOP);
示例#19
0
 public static extern int DecryptMessage(ref SECURITY_HANDLE phContext,
                                         ref SecBufferDesc pMessage,
                                         uint MessageSeqNo,
                                         out uint pfQOP);
示例#20
0
 internal static partial int EncryptMessage(
     ref CredHandle contextHandle,
     uint qualityOfProtection,
     ref SecBufferDesc inputOutput,
     uint sequenceNumber);
示例#21
0
 public static extern int MakeSignature(ref SECURITY_HANDLE phContext, // Context to use
                                        uint fQOP,                     // Quality of Protection
                                        ref SecBufferDesc pMessage,    // Message to sign
                                        uint MessageSeqNo);            // Message Sequence Num.
示例#22
0
 internal static unsafe partial int CompleteAuthToken(
     void *inContextPtr,
     ref SecBufferDesc inputBuffers);
示例#23
0
 public static extern int VerifySignature(ref SECURITY_HANDLE phContext, // Context to use
                                          ref SecBufferDesc pMessage,    // Message to sign
                                          uint MessageSeqNo,             // Message Sequence Num.
                                          out uint pfQOP);               // Quality of Protection
示例#24
0
 internal static extern int EncryptMessage(
     ref CredHandle contextHandle,
     [In] uint qualityOfProtection,
     [In, Out] ref SecBufferDesc inputOutput,
     [In] uint sequenceNumber
     );
 internal static extern unsafe int ApplyControlToken(
     [In] void *inContextPtr,
     [In, Out] ref SecBufferDesc inputBuffers
     );
示例#26
0
 internal static extern unsafe int CompleteAuthToken(
     [In] void *inContextPtr,
     [In, Out] ref SecBufferDesc inputBuffers
     );
示例#27
0
 public static extern int DecryptMessage(ref SECURITY_HANDLE phContext,
                                          ref SecBufferDesc pMessage,
                                          uint MessageSeqNo,
                                          out uint pfQOP);
		static extern int InitializeSecurityContext(
			ref SecHandle phCredential,//PCredHandle
			ref SecHandle phContext, //PCtxtHandle
			string pszTargetName,
			int fContextReq,
			int Reserved1,
			int TargetDataRep,
			ref SecBufferDesc SecBufferDesc, //PSecBufferDesc SecBufferDesc
			int Reserved2,
			out SecHandle phNewContext, //PCtxtHandle
			ref SecBufferDesc pOutput, //PSecBufferDesc SecBufferDesc
			out uint pfContextAttr, //managed ulong == 64 bits!!!
			out SecInteger ptsExpiry //PTimeStamp
		);
示例#29
0
 public static extern int EncryptMessage(ref SECURITY_HANDLE phContext,
                                         uint fQOP,        //managed ulong == 64 bits!!!
                                         ref SecBufferDesc pMessage,
                                         uint MessageSeqNo);
		/// <summary>
		/// Creates client authentication data based on already existing security context and
		/// authentication data sent by server
		/// This method must not be called before InitializeClientSecurity
		/// </summary>
		/// <param name="serverToken">Authentication data received from server</param>
		/// <returns>Client authentication data to be sent to server</returns>
		public byte[] GetClientSecurity(byte[] serverToken)
		{
			if (_disposed)
				throw new ObjectDisposedException("SSPIHelper");
			if (_clientContext.IsInvalid)
				throw new InvalidOperationException("InitializeClientSecurity not called");
			SecInteger expiry = new SecInteger();
			uint contextAttributes;
			SecBufferDesc clientTokenBuf = new SecBufferDesc(MAX_TOKEN_SIZE);
			try
			{
				SecBufferDesc serverTokenBuf = new SecBufferDesc(serverToken);
				try
				{
					int resCode = InitializeSecurityContext(
						ref _clientCredentials,
						ref _clientContext,
						_remotePrincipal,// null string pszTargetName,
						STANDARD_CONTEXT_ATTRIBUTES,
						0,//int Reserved1,
						SECURITY_NATIVE_DREP,//int TargetDataRep
						ref serverTokenBuf, // server token must be ref because it is struct
						0, //int Reserved2,
						out _clientContext, //pHandle CtxtHandle = SecHandle
						ref clientTokenBuf,//ref SecBufferDesc pOutput, //PSecBufferDesc
						out contextAttributes,//ref int pfContextAttr,
						out expiry); //ref IntPtr ptsExpiry ); //PTimeStamp
					if (resCode != SEC_E_OK && resCode != SEC_I_CONTINUE_NEEDED)
						throw new Exception("InitializeSecurityContext() failed");
					return clientTokenBuf.GetSecBufferBytes();
				}
				finally
				{
					serverTokenBuf.Dispose();
				}
			}
			finally
			{
				clientTokenBuf.Dispose();
			}
		}
示例#31
0
 public static extern int InitializeSecurityContext(ref SECURITY_HANDLE phCredential,//PCredHandle
     ref SECURITY_HANDLE phContext, //PCtxtHandle
     string pszTargetName,
     int fContextReq,
     int Reserved1,
     int TargetDataRep,
     ref SecBufferDesc SecBufferDesc, //PSecBufferDesc SecBufferDesc
     int Reserved2,
     out SECURITY_HANDLE phNewContext, //PCtxtHandle
     out SecBufferDesc pOutput, //PSecBufferDesc SecBufferDesc
     out uint pfContextAttr, //managed ulong == 64 bits!!!
     out SECURITY_INTEGER ptsExpiry);
示例#32
0
 public static extern int AcceptSecurityContext(ref SecHandle phCredential, IntPtr phContext,
     ref SecBufferDesc pInput, uint fContextReq, uint TargetDataRep,
     ref SecHandle phNewContext, ref SecBufferDesc pOutput,
     ref uint pfContextAttr, ref long ptsTimeStamp);
        private NtlmHashDTO?GetNtlmCreds(string challenge, bool DisableESS)
        {
            var clientToken    = new SecBufferDesc(MAX_TOKEN_SIZE);
            var newClientToken = new SecBufferDesc(MAX_TOKEN_SIZE);
            var serverToken    = new SecBufferDesc(MAX_TOKEN_SIZE);

            SECURITY_HANDLE cred;

            cred.LowPart = cred.HighPart = IntPtr.Zero;

            SECURITY_HANDLE clientContext;

            clientContext.LowPart = clientContext.HighPart = IntPtr.Zero;

            SECURITY_HANDLE newClientContext;

            newClientContext.LowPart = newClientContext.HighPart = IntPtr.Zero;

            SECURITY_HANDLE serverContext;

            serverContext.LowPart = serverContext.HighPart = IntPtr.Zero;

            SECURITY_INTEGER clientLifeTime;

            clientLifeTime.LowPart = clientLifeTime.HighPart = IntPtr.Zero;

            try
            {
                // Acquire credentials handle for current user
                var result = Secur32.AcquireCredentialsHandle(
                    IntPtr.Zero,
                    "NTLM",
                    3,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    0,
                    IntPtr.Zero,
                    ref cred,
                    ref clientLifeTime
                    );
                if (result != SEC_E_OK)
                {
                    throw new Exception($"AcquireCredentialsHandle failed. Error: 0x{result:x8}");
                }

                // Get a type-1 message from NTLM SSP
                result = Secur32.InitializeSecurityContext(
                    ref cred,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    0x00000800,       // SECPKG_FLAG_NEGOTIABLE
                    0,
                    0x10,             // SECURITY_NATIVE_DREP
                    IntPtr.Zero,
                    0,
                    out clientContext,
                    out clientToken,
                    out _,
                    out clientLifeTime
                    );
                if (result != SEC_E_OK && result != SEC_I_CONTINUE_NEEDED)
                {
                    throw new Exception($"InitializeSecurityContext failed. Error: 0x{result:x8}");
                }

                // Get a type-2 message from NTLM SSP (Server)
                result = AcceptSecurityContext(
                    ref cred,
                    IntPtr.Zero,
                    ref clientToken,
                    0x00000800,   // ASC_REQ_CONNECTION
                    0x10,         // SECURITY_NATIVE_DREP
                    out serverContext,
                    out serverToken,
                    out _,
                    out clientLifeTime
                    );
                if (result != SEC_E_OK && result != SEC_I_CONTINUE_NEEDED)
                {
                    throw new Exception($"AcceptSecurityContext failed. Error: 0x{result:x8}");
                }

                // Tamper with the CHALLENGE message
                var serverMessage  = serverToken.ToArray();
                var challengeBytes = StringToByteArray(challenge);
                if (DisableESS)
                {
                    serverMessage[22] = (byte)(serverMessage[22] & 0xF7);
                }

                //Replace Challenge
                Array.Copy(challengeBytes, 0, serverMessage, 24, 8);
                //Reset reserved bytes to avoid local authentication
                Array.Copy(new byte[16], 0, serverMessage, 32, 16);


                var newServerToken = new SecBufferDesc(serverMessage);
                result = InitializeSecurityContext(
                    ref cred,
                    ref clientContext,
                    IntPtr.Zero,
                    0x00000800,     // SECPKG_FLAG_NEGOTIABLE
                    0,
                    0x10,           // SECURITY_NATIVE_DREP
                    ref newServerToken,
                    0,
                    out newClientContext,
                    out newClientToken,
                    out _,
                    out clientLifeTime
                    );

                var clientTokenBytes = newClientToken.ToArray();
                newServerToken.Dispose();

                if (result == SEC_E_OK)
                {
                    return(ParseNTResponse(clientTokenBytes, challenge));
                }
                else if (result == SEC_E_NO_CREDENTIALS)
                {
                    WriteVerbose("The NTLM security package does not contain any credentials");
                    return(null);
                }
                else if (DisableESS)
                {
                    return(GetNtlmCreds(challenge, false));
                }
                else
                {
                    throw new Exception($"InitializeSecurityContext (client) failed. Error: 0x{result:x8}");
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                clientToken.Dispose();
                newClientToken.Dispose();
                serverToken.Dispose();

                if (cred.LowPart != IntPtr.Zero && cred.HighPart != IntPtr.Zero)
                {
                    FreeCredentialsHandle(ref cred);
                }

                if (clientContext.LowPart != IntPtr.Zero && clientContext.HighPart != IntPtr.Zero)
                {
                    DeleteSecurityContext(ref clientContext);
                }

                if (newClientContext.LowPart != IntPtr.Zero && newClientContext.HighPart != IntPtr.Zero)
                {
                    DeleteSecurityContext(ref newClientContext);
                }

                if (serverContext.LowPart != IntPtr.Zero && serverContext.HighPart != IntPtr.Zero)
                {
                    DeleteSecurityContext(ref serverContext);
                }
            }
        }