Пример #1
0
        private byte[] GetOutgoingBlob(byte[]?incomingBlob, out BlobErrorType status, out Exception?error)
        {
            try
            {
                // byte[] GetOutgoingBlob(byte[] incomingBlob, bool throwOnError, out SecurityStatusPal statusCode)
                var parameters = new object?[] { incomingBlob, false, null };
                var blob       = (byte[])_getOutgoingBlob.Invoke(_instance, parameters) !;

                var securityStatus = parameters[2];
                // TODO: Update after corefx changes
                error = (Exception?)(_statusException.GetValue(securityStatus)
                                     ?? _getException.Invoke(null, new[] { securityStatus }));
                var errorCode = (SecurityStatusPalErrorCode)_statusCode.GetValue(securityStatus) !;

                // TODO: Remove after corefx changes
                // The linux implementation always uses InternalError;
                if (errorCode == SecurityStatusPalErrorCode.InternalError &&
                    !OperatingSystem.IsWindows() &&
                    _gssExceptionType !.IsInstanceOfType(error))
                {
                    var majorStatus = (uint)error.HResult;
                    var minorStatus = (uint)_gssMinorStatus !.GetValue(error) !;

                    // Remap specific errors
                    if (majorStatus == GSS_S_NO_CRED && minorStatus == 0)
                    {
                        errorCode = SecurityStatusPalErrorCode.UnknownCredentials;
                    }

                    error = new Exception($"An authentication exception occurred (0x{majorStatus:X}/0x{minorStatus:X}).", error);
                }

                if (errorCode == SecurityStatusPalErrorCode.OK ||
                    errorCode == SecurityStatusPalErrorCode.ContinueNeeded ||
                    errorCode == SecurityStatusPalErrorCode.CompleteNeeded)
                {
                    status = BlobErrorType.None;
                }
                else if (IsCredentialError(errorCode))
                {
                    status = BlobErrorType.CredentialError;
                }
                else if (IsClientError(errorCode))
                {
                    status = BlobErrorType.ClientError;
                }
                else
                {
                    status = BlobErrorType.Other;
                }

                return(blob);
            }
            catch (TargetInvocationException tex)
            {
                // Unwrap
                ExceptionDispatchInfo.Capture(tex.InnerException !).Throw();
                throw;
            }
        }
Пример #2
0
        public byte[] GetOutgoingBlob(byte[] incomingBlob, out BlobErrorType status, out Exception error)
        {
            try
            {
                // byte[] GetOutgoingBlob(byte[] incomingBlob, bool throwOnError, out SecurityStatusPal statusCode)
                object[] parameters = new object[] { incomingBlob, false, null };
                byte[]   blob       = (byte[])s_getOutgoingBlob.Invoke(_instance, parameters);

                object securityStatus = parameters[2];
                // TODO: Update after corefx changes
                error = (Exception)(s_statusException.GetValue(securityStatus)
                                    ?? GetException.Invoke(null, new[] { securityStatus }));
                var errorCode = (NegotiateInternalSecurityStatusErrorCode)s_statusCode.GetValue(securityStatus);

                // TODO: Remove after corefx changes
                // The linux implementation always uses InternalError;
                if (errorCode == NegotiateInternalSecurityStatusErrorCode.InternalError &&
                    !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
                    s_gssExceptionType.IsInstanceOfType(error))
                {
                    uint majorStatus = (uint)error.HResult;
                    uint minorStatus = (uint)s_gssMinorStatus.GetValue(error);

                    // Remap specific errors
                    if (majorStatus == GSS_S_NO_CRED && minorStatus == 0)
                    {
                        errorCode = NegotiateInternalSecurityStatusErrorCode.UnknownCredentials;
                    }

                    error = new Exception($"An authentication exception occurred (0x{majorStatus:X}/0x{minorStatus:X}).", error);
                }

                if (errorCode == NegotiateInternalSecurityStatusErrorCode.OK ||
                    errorCode == NegotiateInternalSecurityStatusErrorCode.ContinueNeeded ||
                    errorCode == NegotiateInternalSecurityStatusErrorCode.CompleteNeeded)
                {
                    status = BlobErrorType.None;
                }
                else if (IsCredentialError(errorCode))
                {
                    status = BlobErrorType.CredentialError;
                }
                else if (IsClientError(errorCode))
                {
                    status = BlobErrorType.ClientError;
                }
                else
                {
                    status = BlobErrorType.Other;
                }

                return(blob);
            }
            catch (TargetInvocationException tex)
            {
                // Unwrap
                ExceptionDispatchInfo.Capture(tex.InnerException).Throw();
                throw;
            }
        }
Пример #3
0
        // Copied rather than reflected to remove the IsCompleted -> CloseContext check.
        // The client doesn't need the context once auth is complete, but the server does.
        // I'm not sure why it auto-closes for the client given that the client closes it just a few lines later.
        // https://github.com/dotnet/corefx/blob/a3ab91e10045bb298f48c1d1f9bd5b0782a8ac46/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs#L134
        public string?GetOutgoingBlob(string incomingBlob, out BlobErrorType status, out Exception?error)
        {
            byte[]? decodedIncomingBlob = null;
            if (incomingBlob != null && incomingBlob.Length > 0)
            {
                decodedIncomingBlob = Convert.FromBase64String(incomingBlob);
            }

            byte[] decodedOutgoingBlob = GetOutgoingBlob(decodedIncomingBlob, out status, out error);

            string?outgoingBlob = null;

            if (decodedOutgoingBlob != null && decodedOutgoingBlob.Length > 0)
            {
                outgoingBlob = Convert.ToBase64String(decodedOutgoingBlob);
            }

            return(outgoingBlob);
        }
            public string GetOutgoingBlob(string incomingBlob, out BlobErrorType errorType, out Exception ex)
            {
                if (IsDisposed)
                {
                    throw new ObjectDisposedException(nameof(TestNegotiateState));
                }
                if (IsCompleted)
                {
                    throw new InvalidOperationException("Authentication is already complete.");
                }

                errorType = BlobErrorType.None;
                ex        = null;

                switch (incomingBlob)
                {
                case "ClientNtlmBlob1":
                    Assert.False(Stage1Complete, nameof(Stage1Complete));
                    Stage1Complete = true;
                    _protocol      = "NTLM";
                    return("ServerNtlmBlob1");

                case "ClientNtlmBlob2":
                    Assert.True(Stage1Complete, nameof(Stage1Complete));
                    Assert.Equal("NTLM", _protocol);
                    IsCompleted = true;
                    return("ServerNtlmBlob2");

                // Kerberos can require one or two stages
                case "ClientKerberosBlob":
                    Assert.False(Stage1Complete, nameof(Stage1Complete));
                    _protocol      = "Kerberos";
                    Stage1Complete = true;
                    IsCompleted    = true;
                    return("ServerKerberosBlob");

                case "ClientKerberosBlob1":
                    Assert.False(Stage1Complete, nameof(Stage1Complete));
                    _protocol      = "Kerberos";
                    Stage1Complete = true;
                    return("ServerKerberosBlob1");

                case "ClientKerberosBlob2":
                    Assert.True(Stage1Complete, nameof(Stage1Complete));
                    Assert.Equal("Kerberos", _protocol);
                    IsCompleted = true;
                    return("ServerKerberosBlob2");

                case "CredentialError":
                    errorType = BlobErrorType.CredentialError;
                    ex        = new Exception("A test credential error occurred");
                    return(null);

                case "ClientError":
                    errorType = BlobErrorType.ClientError;
                    ex        = new Exception("A test client error occurred");
                    return(null);

                case "OtherError":
                    errorType = BlobErrorType.Other;
                    ex        = new Exception("A test other error occurred");
                    return(null);

                default:
                    errorType = BlobErrorType.Other;
                    ex        = new InvalidOperationException(incomingBlob);
                    return(null);
                }
            }