예제 #1
0
        protected override TDSMessageCollection CreateQueryResponse(ITDSServerSession session,
                                                                    TDSSQLBatchToken batchRequest)
        {
            string lowerBatchText = batchRequest.Text.ToLowerInvariant().Trim();

            var result = TryGet(lowerBatchText, null);

            if (null != result)
            {
                List <TDSPacketToken> tokens        = new List <TDSPacketToken>();
                TDSColMetadataToken   metadataToken = new TDSColMetadataToken();
                tokens.Add(metadataToken);

                if (String.IsNullOrWhiteSpace(result.Table))
                {
                    TDSColumnData column = new TDSColumnData();
                    column.DataType         = TDSDataType.IntN;
                    column.DataTypeSpecific = (byte)4;
                    column.Flags.Updatable  = TDSColumnDataUpdatableFlag.ReadOnly;
                    column.Flags.IsComputed = true;
                    column.Flags.IsNullable =
                        true; // TODO: Must be nullable, otherwise something is wrong with SqlClient

                    // Add a column to the response
                    metadataToken.Columns.Add(column);

                    TDSRowToken rowToken = new TDSRowToken(metadataToken);
                    rowToken.Data.Add(result.Scalar);

                    tokens.Add(rowToken);

                    TDSDoneToken doneToken =
                        new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count,
                                         TDSDoneTokenCommandType.Select, 1);
                    tokens.Add(doneToken);
                }
                else
                {
                    tokens.AddRange(ReturnTable(result));
                    // Create DONE token
                    TDSDoneToken doneToken = new TDSDoneToken(
                        TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count,
                        TDSDoneTokenCommandType.Select, (ulong)result.GetRecords().Count());
                    tokens.Add(doneToken);
                }

                return(new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, tokens.ToArray())));
            }
            else
            {
                PrintMissignQuery(lowerBatchText, null);
            }
            return(base.CreateQueryResponse(session, batchRequest));
        }
예제 #2
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);
        }
        /// <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));
        }
예제 #4
0
        protected override TDSMessageCollection CreateQueryResponse(ITDSServerSession session, TDSSQLBatchToken batchRequest)
        {
            string lowerBatchText = batchRequest.Text.ToLowerInvariant();

            if (lowerBatchText.Contains("1 / 0")) // SELECT 1/0
            {
                TDSErrorToken errorToken      = new TDSErrorToken(8134, 1, 16, "Divide by zero error encountered.");
                TDSDoneToken  doneToken       = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1);
                TDSMessage    responseMessage = new TDSMessage(TDSMessageType.Response, errorToken, doneToken);
                return(new TDSMessageCollection(responseMessage));
            }
            else
            {
                return(base.CreateQueryResponse(session, batchRequest));
            }
        }
예제 #5
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)));
        }
예제 #6
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.MSAL)
            {
                // 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);
        }
예제 #7
0
        protected virtual TDSMessageCollection OnAuthenticationCompleted(ITDSServerSession session)
        {
            // Create new database environment change token
            TDSEnvChangeToken envChange = new TDSEnvChangeToken(TDSEnvChangeTokenType.Database, session.Database, "master");

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

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

            // Create information token on the change
            TDSInfoToken infoToken = new TDSInfoToken(5701, 2, 0, string.Format("Changed database context to '{0}'", envChange.NewValue), Arguments.ServerName);

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

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

            // Create new collation change token
            envChange = new TDSEnvChangeToken(TDSEnvChangeTokenType.SQLCollation, (session as GenericTDSServerSession).Collation);

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

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

            // Create new language change token
            envChange = new TDSEnvChangeToken(TDSEnvChangeTokenType.Language, LanguageString.ToString((session as GenericTDSServerSession).Language));

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

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

            // Create information token on the change
            infoToken = new TDSInfoToken(5703, 1, 0, string.Format("Changed language setting to {0}", envChange.NewValue), Arguments.ServerName);

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

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

            // Create new packet size environment change token
            envChange = new TDSEnvChangeToken(TDSEnvChangeTokenType.PacketSize, Arguments.PacketSize.ToString(), Arguments.PacketSize.ToString());

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

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

            // Update session packet size
            session.PacketSize = (uint)Arguments.PacketSize;

            // Create login acknowledgement packet
            TDSLoginAckToken loginResponseToken = new TDSLoginAckToken(Arguments.ServerVersion, session.TDSVersion, TDSLogin7TypeFlagsSQL.SQL, "Microsoft SQL Server");  // Otherwise SNAC yields E_FAIL

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

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

            // Check if session recovery is enabled
            if (session.IsSessionRecoveryEnabled)
            {
                // Create Feature extension Ack token
                TDSFeatureExtAckToken featureExtActToken = new TDSFeatureExtAckToken(new TDSFeatureExtAckSessionStateOption((session as GenericTDSServerSession).Deflate()));

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

                // Serialize feature extnesion token into the response
                responseMessage.Add(featureExtActToken);
            }

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

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

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

            // Wrap a single message in a collection
            return(new TDSMessageCollection(responseMessage));
        }
예제 #8
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);
        }
예제 #9
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 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));
        }
예제 #10
0
        public override TDSMessageCollection ExecuteRPC(ITDSServerSession session, TDSMessage message)
        {
            TDSRPCRequestToken rpc  = message[0] as TDSRPCRequestToken;
            TDSDoneToken       done = new TDSDoneToken(TDSDoneTokenStatusType.Final, TDSDoneTokenCommandType.Done, 0);

            if (String.IsNullOrEmpty(rpc.ProcName))
            {
                if (rpc.ProcID == TDSRPCRequestTokenProcID.Sp_ExecuteSql)
                {
                    var sqlQuery = rpc.Parameters.First();
                    if (sqlQuery.DataType == TDSDataType.NVarChar)
                    {
                        var sql    = sqlQuery.Value.ToString();
                        var result = TryGet(sql, rpc.Parameters);
                        if (null != result)
                        {
                            if (result.GetRecords().Any())
                            {
                                var tokens = ReturnTable(result);

                                // Create DONE token
                                TDSDoneToken doneToken =
                                    new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count,
                                                     TDSDoneTokenCommandType.Select, (ulong)result.GetRecords().Count());
                                tokens.Add(doneToken);

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

                                // Serialize tokens into the message
                                return(new TDSMessageCollection(new TDSMessage(TDSMessageType.Response,
                                                                               tokens.ToArray())));
                            }
                            else if (result.ReturnValue.HasValue)
                            {
                                var retVal = new TDSReturnValueToken();
                                retVal.Flags.Updatable  = TDSColumnDataUpdatableFlag.ReadOnly;
                                retVal.DataType         = TDSDataType.IntN;
                                retVal.DataTypeSpecific = (byte)4;
                                retVal.Flags.IsComputed = true;
                                retVal.Flags.IsNullable =
                                    true; // TODO: Must be nullable, otherwise something is wrong with SqlClient
                                retVal.ParamName = "@RETURN_VALUE";
                                retVal.Value     = (int)result.ReturnValue.Value;
                                retVal.Status    = TDSReturnValueStatus.Output;

                                TDSDoneInProcToken doneInRpc =
                                    new TDSDoneInProcToken(TDSDoneTokenStatusType.Count,
                                                           TDSDoneTokenCommandType.DoneInProc, 1);

                                return(new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, retVal, doneInRpc)));
                            }
                            else
                            {
                                TDSDoneInProcToken doneInRpc =
                                    new TDSDoneInProcToken(TDSDoneTokenStatusType.Count,
                                                           TDSDoneTokenCommandType.DoneInProc,
                                                           result.Scalar);

                                return(new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, doneInRpc)));
                            }
                        }
                        else
                        {
                            PrintMissignQuery(sql, rpc.Parameters);
                        }
                    }
                }
            }
            else
            {
                var text   = rpc.ProcName.ToLowerInvariant();
                var result = TryGet(text, rpc.Parameters);
                if (null != result)
                {
                    if (result.GetRecords().Any())
                    {
                        var tokens = ReturnTable(result);

                        // Create DONE token
                        TDSDoneToken doneToken =
                            new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count,
                                             TDSDoneTokenCommandType.Select, (ulong)result.GetRecords().Count());
                        tokens.Add(doneToken);

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

                        // Serialize tokens into the message
                        return(new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, tokens.ToArray())));
                    }
                    else
                    {
                        TDSDoneInProcToken doneIn =
                            new TDSDoneInProcToken(TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.DoneInProc,
                                                   result.Scalar);

                        return(new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, doneIn)));
                    }
                }
                else
                {
                    PrintMissignQuery(text, rpc.Parameters);
                }
            }
            return(new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, done)));
        }