public void InitializeClient(out byte[] clientToken, byte[] serverToken, out bool continueProcessing) { clientToken = null; continueProcessing = true; WindowsAPI.SECURITY_INTEGER clientLifeTime = new WindowsAPI.SECURITY_INTEGER(0); int resultCode = -1; if (!_gotClientCredentials) { if (_networkCredential == null) { resultCode = WindowsAPI.AcquireCredentialsHandle(IntPtr.Zero, "Kerberos", WindowsAPI.SECPKG_CRED_OUTBOUND, IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero, ref _outboundCredHandle, ref clientLifeTime); } else { WindowsAPI.AuthIdentityEx authIdentity = new WindowsAPI.AuthIdentityEx(_networkCredential.UserName, _networkCredential.Password, _networkCredential.Domain, "!ntlm,"); if (_principal == null) { resultCode = WindowsAPI.AcquireCredentialsHandle(IntPtr.Zero, "Kerberos", WindowsAPI.SECPKG_CRED_OUTBOUND, IntPtr.Zero, ref authIdentity, 0, IntPtr.Zero, ref _outboundCredHandle, ref clientLifeTime); } else { resultCode = WindowsAPI.AcquireCredentialsHandle(_principal, "Kerberos", WindowsAPI.SECPKG_CRED_OUTBOUND, IntPtr.Zero, ref authIdentity, 0, IntPtr.Zero, ref _outboundCredHandle, ref clientLifeTime); } } if (resultCode != WindowsAPI.SEC_E_OK) { throw WindowsAPI.CreateException(resultCode, "Couldn't acquire client credentials"); } _gotClientCredentials = true; } WindowsAPI.SecBufferDesc clientTokenBuf = new WindowsAPI.SecBufferDesc(WindowsAPI.MAX_TOKEN_SIZE); try { var reqContextAttributes = WindowsAPI.ISC_REQ_ALLOCATE_MEMORY | WindowsAPI.ISC_REQ_REPLAY_DETECT | WindowsAPI.ISC_REQ_MUTUAL_AUTH | WindowsAPI.ISC_REQ_IDENTIFY; uint contextAttributes = 0; WindowsAPI.SECURITY_HANDLE _retContext; if (serverToken == null) { resultCode = WindowsAPI.InitializeSecurityContext(ref _outboundCredHandle, IntPtr.Zero, _hostname, // null string pszTargetName, reqContextAttributes, 0, //int Reserved1, WindowsAPI.SECURITY_NATIVE_DREP, //int TargetDataRep IntPtr.Zero, //Always zero first time around... 0, //int Reserved2, out _clientContextHandle, //pHandle CtxtHandle = SecHandle out clientTokenBuf, //ref SecBufferDesc pOutput, //PSecBufferDesc out contextAttributes, //ref int pfContextAttr, out clientLifeTime); //ref IntPtr ptsExpiry ); //PTimeStamp } else { WindowsAPI.SecBufferDesc serverTokenBuf = new WindowsAPI.SecBufferDesc(serverToken); try { resultCode = WindowsAPI.InitializeSecurityContext(ref _outboundCredHandle, ref _clientContextHandle, _hostname, // null string pszTargetName, reqContextAttributes, 0, //int Reserved1, WindowsAPI.SECURITY_NATIVE_DREP, //int TargetDataRep ref serverTokenBuf, //Always zero first time around... 0, //int Reserved2, out _retContext, //pHandle CtxtHandle = SecHandle out clientTokenBuf, //ref SecBufferDesc pOutput, //PSecBufferDesc out contextAttributes, //ref int pfContextAttr, out clientLifeTime); //ref IntPtr ptsExpiry ); //PTimeStamp } finally { serverTokenBuf.Dispose(); } _clientContextHandle = _retContext; } if (resultCode != WindowsAPI.SEC_E_OK && resultCode != WindowsAPI.SEC_I_CONTINUE_NEEDED) { throw WindowsAPI.CreateException(resultCode, "InitializeSecurityContext() failed!!!"); } clientToken = clientTokenBuf.GetSecBufferByteArray(); } finally { clientTokenBuf.Dispose(); } continueProcessing = resultCode != WindowsAPI.SEC_E_OK; }