Environment change token "ERROR"
Inheritance: TDSPacketToken
Exemple #1
0
        /// <summary>
        /// Handler for login request
        /// </summary>
        public override TDSMessageCollection OnLogin7Request(ITDSServerSession session, TDSMessage request)
        {
            // Inflate login7 request from the message
            TDSLogin7Token loginRequest = request[0] as TDSLogin7Token;

            // Check if arguments are of the routing server
            if (Arguments is RoutingTDSServerArguments)
            {
                // Cast to routing server arguments
                RoutingTDSServerArguments ServerArguments = Arguments as RoutingTDSServerArguments;

                // Check filter
                if (ServerArguments.RequireReadOnly && (loginRequest.TypeFlags.ReadOnlyIntent != TDSLogin7TypeFlagsReadOnlyIntent.ReadOnly))
                {
                    // Log request
                    TDSUtilities.Log(Arguments.Log, "Request", loginRequest);

                    // Prepare ERROR token with the denial details
                    TDSErrorToken errorToken = new TDSErrorToken(18456, 1, 14, "Received application intent: " + loginRequest.TypeFlags.ReadOnlyIntent.ToString(), Arguments.ServerName);

                    // Log response
                    TDSUtilities.Log(Arguments.Log, "Response", errorToken);

                    // Serialize the error token into the response packet
                    TDSMessage responseMessage = new TDSMessage(TDSMessageType.Response, errorToken);

                    // Prepare ERROR token for the final decision
                    errorToken = new TDSErrorToken(18456, 1, 14, "Read-Only application intent is required for routing", Arguments.ServerName);

                    // Log response
                    TDSUtilities.Log(Arguments.Log, "Response", errorToken);

                    // Serialize the error token into the response packet
                    responseMessage.Add(errorToken);

                    // Create DONE token
                    TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error);

                    // Log response
                    TDSUtilities.Log(Arguments.Log, "Response", doneToken);

                    // Serialize DONE token into the response packet
                    responseMessage.Add(doneToken);

                    // Return a single message in the collection
                    return new TDSMessageCollection(responseMessage);
                }
            }

            // Delegate to the base class
            return base.OnLogin7Request(session, request);
        }
        /// <summary>
        /// Handler for login request
        /// </summary>
        public override TDSMessageCollection OnLogin7Request(ITDSServerSession session, TDSMessage request)
        {
            // Inflate login7 request from the message
            TDSLogin7Token loginRequest = request[0] as TDSLogin7Token;

            // Check if arguments are of the authenticating TDS server
            if (Arguments is AuthenticatingTDSServerArguments)
            {
                // Cast to authenticating TDS server arguments
                AuthenticatingTDSServerArguments ServerArguments = Arguments as AuthenticatingTDSServerArguments;

                // Check if we're still processing normal login
                if (ServerArguments.ApplicationIntentFilter != ApplicationIntentFilterType.All)
                {
                    // Check filter
                    if ((ServerArguments.ApplicationIntentFilter == ApplicationIntentFilterType.ReadOnly && loginRequest.TypeFlags.ReadOnlyIntent != TDSLogin7TypeFlagsReadOnlyIntent.ReadOnly)
                        || (ServerArguments.ApplicationIntentFilter == ApplicationIntentFilterType.None))
                    {
                        // Log request to which we're about to send a failure
                        TDSUtilities.Log(Arguments.Log, "Request", loginRequest);

                        // Prepare ERROR token with the denial details
                        TDSErrorToken errorToken = new TDSErrorToken(18456, 1, 14, "Received application intent: " + loginRequest.TypeFlags.ReadOnlyIntent.ToString(), Arguments.ServerName);

                        // Log response
                        TDSUtilities.Log(Arguments.Log, "Response", errorToken);

                        // Serialize the error token into the response packet
                        TDSMessage responseMessage = new TDSMessage(TDSMessageType.Response, errorToken);

                        // Prepare ERROR token for the final decision
                        errorToken = new TDSErrorToken(18456, 1, 14, "Connection is denied by application intent filter", Arguments.ServerName);

                        // Log response
                        TDSUtilities.Log(Arguments.Log, "Response", errorToken);

                        // Serialize the error token into the response packet
                        responseMessage.Add(errorToken);

                        // Create DONE token
                        TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error);

                        // Log response
                        TDSUtilities.Log(Arguments.Log, "Response", doneToken);

                        // Serialize DONE token into the response packet
                        responseMessage.Add(doneToken);

                        // Put a single message into the collection and return it
                        return new TDSMessageCollection(responseMessage);
                    }
                }

                // Check if we're still processing normal login and there's a filter to check
                if (ServerArguments.ServerNameFilterType != ServerNameFilterType.None)
                {
                    // Check each algorithm
                    if ((ServerArguments.ServerNameFilterType == ServerNameFilterType.Equals && string.Compare(ServerArguments.ServerNameFilter, loginRequest.ServerName, true) != 0)
                        || (ServerArguments.ServerNameFilterType == ServerNameFilterType.StartsWith && !loginRequest.ServerName.StartsWith(ServerArguments.ServerNameFilter))
                        || (ServerArguments.ServerNameFilterType == ServerNameFilterType.EndsWith && !loginRequest.ServerName.EndsWith(ServerArguments.ServerNameFilter))
                        || (ServerArguments.ServerNameFilterType == ServerNameFilterType.Contains && !loginRequest.ServerName.Contains(ServerArguments.ServerNameFilter)))
                    {
                        // Log request to which we're about to send a failure
                        TDSUtilities.Log(Arguments.Log, "Request", loginRequest);

                        // Prepare ERROR token with the reason
                        TDSErrorToken errorToken = new TDSErrorToken(18456, 1, 14, string.Format("Received server name \"{0}\", expected \"{1}\" using \"{2}\" algorithm", loginRequest.ServerName, ServerArguments.ServerNameFilter, ServerArguments.ServerNameFilterType), Arguments.ServerName);

                        // Log response
                        TDSUtilities.Log(Arguments.Log, "Response", errorToken);

                        // Serialize the errorToken token into the response packet
                        TDSMessage responseMessage = new TDSMessage(TDSMessageType.Response, errorToken);

                        // Prepare ERROR token with the final errorToken
                        errorToken = new TDSErrorToken(18456, 1, 14, "Connection is denied by server name filter", Arguments.ServerName);

                        // Log response
                        TDSUtilities.Log(Arguments.Log, "Response", errorToken);

                        // Serialize the errorToken token into the response packet
                        responseMessage.Add(errorToken);

                        // Create DONE token
                        TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error);

                        // Log response
                        TDSUtilities.Log(Arguments.Log, "Response", doneToken);

                        // Serialize DONE token into the response packet
                        responseMessage.Add(doneToken);

                        // Return only a single message with the collection
                        return new TDSMessageCollection(responseMessage);
                    }
                }

                // Check if packet size filter is applied
                if (ServerArguments.PacketSizeFilter != null)
                {
                    // Check if requested packet size is the same as the filter specified
                    if (loginRequest.PacketSize != ServerArguments.PacketSizeFilter.Value)
                    {
                        // Log request to which we're about to send a failure
                        TDSUtilities.Log(Arguments.Log, "Request", loginRequest);

                        // Prepare ERROR token with the reason
                        TDSErrorToken errorToken = new TDSErrorToken(1919, 1, 14, string.Format("Received packet size \"{0}\", expected \"{1}\"", loginRequest.PacketSize, ServerArguments.PacketSizeFilter.Value), Arguments.ServerName);

                        // Log response
                        TDSUtilities.Log(Arguments.Log, "Response", errorToken);

                        // Serialize the errorToken token into the response packet
                        TDSMessage responseMessage = new TDSMessage(TDSMessageType.Response, errorToken);

                        // Prepare ERROR token with the final errorToken
                        errorToken = new TDSErrorToken(1919, 1, 14, "Connection is denied by packet size filter", Arguments.ServerName);

                        // Log response
                        TDSUtilities.Log(Arguments.Log, "Response", errorToken);

                        // Serialize the errorToken token into the response packet
                        responseMessage.Add(errorToken);

                        // Create DONE token
                        TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error);

                        // Log response
                        TDSUtilities.Log(Arguments.Log, "Response", doneToken);

                        // Serialize DONE token into the response packet
                        responseMessage.Add(doneToken);

                        // Return only a single message with the collection
                        return new TDSMessageCollection(responseMessage);
                    }
                }

                // If we have an application name filter
                if (ServerArguments.ApplicationNameFilter != null)
                {
                    // If we are supposed to block this connection attempt
                    if (loginRequest.ApplicationName.Equals(ServerArguments.ApplicationNameFilter, System.StringComparison.OrdinalIgnoreCase))
                    {
                        // Log request to which we're about to send a failure
                        TDSUtilities.Log(Arguments.Log, "Request", loginRequest);

                        // Prepare ERROR token with the denial details
                        TDSErrorToken errorToken = new TDSErrorToken(18456, 1, 14, "Received application name: " + loginRequest.ApplicationName, Arguments.ServerName);

                        // Log response
                        TDSUtilities.Log(Arguments.Log, "Response", errorToken);

                        // Serialize the error token into the response packet
                        TDSMessage responseMessage = new TDSMessage(TDSMessageType.Response, errorToken);

                        // Prepare ERROR token for the final decision
                        errorToken = new TDSErrorToken(18456, 1, 14, "Connection is denied by application name filter", Arguments.ServerName);

                        // Log response
                        TDSUtilities.Log(Arguments.Log, "Response", errorToken);

                        // Serialize the error token into the response packet
                        responseMessage.Add(errorToken);

                        // Create DONE token
                        TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error);

                        // Log response
                        TDSUtilities.Log(Arguments.Log, "Response", doneToken);

                        // Serialize DONE token into the response packet
                        responseMessage.Add(doneToken);

                        // Put a single message into the collection and return it
                        return new TDSMessageCollection(responseMessage);
                    }
                }
            }

            // Return login response from the base class
            return base.OnLogin7Request(session, request);
        }
Exemple #3
0
        /// <summary>
        /// Checks the TDS version
        /// </summary>
        /// <param name="session">Server session</param>
        /// <returns>Null if the TDS version is supported, errorToken message otherwise</returns>
        protected virtual TDSMessageCollection CheckTDSVersion(ITDSServerSession session)
        {
            // Check if version is supported
            if (TDSVersion.IsSupported(session.TDSVersion))
            {
                return null;
            }

            // Prepare ERROR token
            TDSErrorToken errorToken = new TDSErrorToken(12345, 1, 16, "Unsupported TDS client version", Arguments.ServerName);

            // Log response
            TDSUtilities.Log(Arguments.Log, "Response", errorToken);

            // Create DONE token
            TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error);

            // Log response
            TDSUtilities.Log(Arguments.Log, "Response", doneToken);

            // Wrap with message collection
            return new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, errorToken, doneToken));
        }
Exemple #4
0
        /// <summary>
        /// Ensure that federated authentication option is valid
        /// </summary>
        protected virtual TDSMessageCollection CheckFederatedAuthenticationOption(ITDSServerSession session, TDSLogin7FedAuthOptionToken federatedAuthenticationOption)
        {
            // Check if server's prelogin response for FedAuthRequired prelogin option is echoed back correctly in FedAuth Feature Extenion Echo
            if (federatedAuthenticationOption.Echo != (session as GenericTDSServerSession).FedAuthRequiredPreLoginServerResponse)
            {
                // Create Error message
                string message =
                    string.Format("FEDAUTHREQUIRED option in the prelogin response is not echoed back correctly: in prelogin response, it is {0} and in login, it is {1}: ",
                    (session as GenericTDSServerSession).FedAuthRequiredPreLoginServerResponse,
                    federatedAuthenticationOption.Echo);

                // Create errorToken token
                TDSErrorToken errorToken = new TDSErrorToken(3456, 34, 23, message);

                // Log response
                TDSUtilities.Log(Arguments.Log, "Response", errorToken);

                // Create DONE token
                TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error);

                // Log response
                TDSUtilities.Log(Arguments.Log, "Response", doneToken);

                // Build a collection with a single message of two tokens
                return new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, errorToken, doneToken));
            }

            // Check if the nonce exists
            if ((federatedAuthenticationOption.Nonce == null && federatedAuthenticationOption.Library == TDSFedAuthLibraryType.IDCRL)
                || !AreEqual((session as GenericTDSServerSession).ServerNonce, federatedAuthenticationOption.Nonce))
            {
                // Error message
                string message = string.Format("Unexpected NONCEOPT specified in the Federated authentication feature extension");

                // Create errorToken token
                TDSErrorToken errorToken = new TDSErrorToken(5672, 32, 87, message);

                // Log response
                TDSUtilities.Log(Arguments.Log, "Response", errorToken);

                // Create DONE token
                TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error);

                // Log response
                TDSUtilities.Log(Arguments.Log, "Response", doneToken);

                // Build a collection with a single message of two tokens
                return new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, errorToken, doneToken));
            }

            // We're good
            return null;
        }
Exemple #5
0
        /// <summary>
        /// Complete the Federated Login
        /// </summary>
        /// <param name="session">Server session</param>
        /// <returns>Federated Login message collection</returns>
        protected virtual TDSMessageCollection OnFederatedAuthenticationCompleted(ITDSServerSession session, byte[] ticket)
        {
            // Delegate to successful authentication routine
            TDSMessageCollection responseMessageCollection = OnAuthenticationCompleted(session);

            // Get the last message
            TDSMessage targetMessage = responseMessageCollection.Last();

            IFederatedAuthenticationTicket decryptedTicket = null;

            try
            {
                // Get the Federated Authentication ticket using RPS
                decryptedTicket = FederatedAuthenticationTicketService.DecryptTicket((session as GenericTDSServerSession).FederatedAuthenticationLibrary, ticket);

                if (decryptedTicket is RpsTicket)
                {
                    TDSUtilities.Log(Arguments.Log, "RPS ticket session key: ", (decryptedTicket as RpsTicket).sessionKey);
                }
                else if (decryptedTicket is JwtTicket)
                {
                    TDSUtilities.Log(Arguments.Log, "JWT Ticket Received", null);
                }
            }
            catch (Exception ex)
            {
                // Prepare ERROR token
                TDSErrorToken errorToken = new TDSErrorToken(54879, 1, 20, "Authentication error in Federated Authentication Ticket Service: " + ex.Message, Arguments.ServerName);

                // Log response
                TDSUtilities.Log(Arguments.Log, "Response", errorToken);

                // Create DONE token
                TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error);

                // Log response
                TDSUtilities.Log(Arguments.Log, "Response", doneToken);

                // Return the message and stop processing request
                return new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, errorToken, doneToken));
            }

            // Create federated authentication extension option
            TDSFeatureExtAckFederatedAuthenticationOption federatedAuthenticationOption;
            if ((session as GenericTDSServerSession).FederatedAuthenticationLibrary == TDSFedAuthLibraryType.ADAL)
            {
                // For the time being, fake fedauth tokens are used for ADAL, so decryptedTicket is null.
                federatedAuthenticationOption =
                    new TDSFeatureExtAckFederatedAuthenticationOption((session as GenericTDSServerSession).ClientNonce, null);
            }
            else
            {
                federatedAuthenticationOption =
                    new TDSFeatureExtAckFederatedAuthenticationOption((session as GenericTDSServerSession).ClientNonce,
                                                                       decryptedTicket.GetSignature((session as GenericTDSServerSession).ClientNonce));
            }

            // Look for feature extension token
            TDSFeatureExtAckToken featureExtActToken = (TDSFeatureExtAckToken)targetMessage.Where(t => t is TDSFeatureExtAckToken).FirstOrDefault();

            // Check if response already contains federated authentication
            if (featureExtActToken == null)
            {
                // Create Feature extension Ack token
                featureExtActToken = new TDSFeatureExtAckToken(federatedAuthenticationOption);

                // Serialize feature extension token into the response
                // The last token is Done token, so we should put feautureextack token before done token
                targetMessage.Insert(targetMessage.Count - 1, featureExtActToken);
            }
            else
            {
                // Update
                featureExtActToken.Options.Add(federatedAuthenticationOption);
            }

            // Log response
            TDSUtilities.Log(Arguments.Log, "Response", federatedAuthenticationOption);

            // Wrap a message with a collection
            return responseMessageCollection;
        }
Exemple #6
0
        /// <summary>
        /// Advances one step in SSPI authentication sequence
        /// </summary>
        protected virtual TDSMessageCollection ContinueSSPIAuthentication(ITDSServerSession session, byte[] payload)
        {
            // Response to send to the client
            SSPIResponse response;

            try
            {
                // Check if we have an SSPI context
                if (session.NTUserAuthenticationContext == null)
                {
                    // This is the first step so we need to create a server context and initialize it
                    session.NTUserAuthenticationContext = SSPIContext.CreateServer();

                    // Run the first step of authentication
                    response = session.NTUserAuthenticationContext.StartServerAuthentication(payload);
                }
                else
                {
                    // Process SSPI request from the client
                    response = session.NTUserAuthenticationContext.ContinueServerAuthentication(payload);
                }
            }
            catch (Exception e)
            {
                // Prepare ERROR token with the reason
                TDSErrorToken errorToken = new TDSErrorToken(12345, 1, 15, "Failed to accept security SSPI context", Arguments.ServerName);

                // Log response
                TDSUtilities.Log(Arguments.Log, "Response", errorToken);

                // Serialize the error token into the response packet
                TDSMessage responseErrorMessage = new TDSMessage(TDSMessageType.Response, errorToken);

                // Prepare ERROR token with the final errorToken
                errorToken = new TDSErrorToken(12345, 1, 15, e.Message, Arguments.ServerName);

                // Log response
                TDSUtilities.Log(Arguments.Log, "Response", errorToken);

                // Serialize the error token into the response packet
                responseErrorMessage.Add(errorToken);

                // Create DONE token
                TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error);

                // Log response
                TDSUtilities.Log(Arguments.Log, "Response", doneToken);

                // Serialize DONE token into the response packet
                responseErrorMessage.Add(doneToken);

                // Respond with a single message
                return new TDSMessageCollection(responseErrorMessage);
            }

            // Message collection to respond with
            TDSMessageCollection responseMessages = new TDSMessageCollection();

            // Check if there's a response
            if (response != null)
            {
                // Check if there's a payload
                if (response.Payload != null)
                {
                    // Create SSPI token
                    TDSSSPIToken sspiToken = new TDSSSPIToken(response.Payload);

                    // Log response
                    TDSUtilities.Log(Arguments.Log, "Response", sspiToken);

                    // Prepare response message with a single response token
                    responseMessages.Add(new TDSMessage(TDSMessageType.Response, sspiToken));

                    // Check if we can complete login
                    if (!response.IsFinal)
                    {
                        // Send the message to the client
                        return responseMessages;
                    }
                }
            }

            // Reset SQL user identifier since we're using NT authentication
            session.SQLUserID = null;

            // Append successfully authentication response
            responseMessages.AddRange(OnAuthenticationCompleted(session));

            // Return the message with SSPI token
            return responseMessages;
        }