private unsafe void AcquireCredentials()
        {
            CredentialHandle creds = _credential.Structify();

            TrackUnmanaged(creds);
            IntPtr authIdPtr = IntPtr.Zero;

            if (_logonId != 0)
            {
#if NET45
                authIdPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(long)));
#else
                authIdPtr = Marshal.AllocHGlobal(Marshal.SizeOf <long>());
#endif
                Marshal.StructureToPtr(_logonId, authIdPtr, false);
            }

            SecStatus result = NativeMethods.AcquireCredentialsHandle(
                null,
                Package,
                SECPKG_CRED_BOTH,
                authIdPtr,
                (void *)creds.DangerousGetHandle(),
                IntPtr.Zero,
                IntPtr.Zero,
                ref _credentialsHandle,
                IntPtr.Zero);

            if (result != SecStatus.SEC_E_OK)
            {
                throw new Win32Exception((int)result);
            }

            TrackUnmanaged(_credentialsHandle);
        }
示例#2
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
                {
                    InitContextFlag contextFlags;

                    clientToken = new SecBufferDesc(tokenSize);

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

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

                            result = InitializeSecurityContext_1(
                                ref this.credentialsHandle,
                                ref this.securityContext,
                                targetNameNormalized,
                                this.clientFlags,
                                0,
                                SECURITY_NETWORK_DREP,
                                ref pInputBuffer,
                                0,
                                ref this.securityContext,
                                ref clientToken,
                                out 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();
            }
        }
        public ContextStatus InitializeSecurityContext(string targetName, out byte[] clientRequest)
        {
            var targetNameNormalized = targetName.ToLowerInvariant();

            clientRequest = null;

            SecStatus result    = 0;
            int       tokenSize = 0;

            NativeMethods.SecBufferDesc clientToken = default;

            try
            {
                do
                {
                    InitContextFlag contextFlags;

                    clientToken = new NativeMethods.SecBufferDesc(tokenSize);

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

                    result = NativeMethods.InitializeSecurityContext_0(
                        ref _credentialsHandle,
                        IntPtr.Zero,
                        targetNameNormalized,
                        _clientFlags,
                        0,
                        SECURITY_NETWORK_DREP,
                        IntPtr.Zero,
                        0,
                        ref _securityContext,
                        ref clientToken,
                        out contextFlags,
                        IntPtr.Zero);

                    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();
            }
        }