/// <summary>
        /// It is called when SQL batch request arrives
        /// </summary>
        public virtual TDSMessageCollection OnSQLBatchRequest(ITDSServerSession session, TDSMessage message)
        {
            // Delegate to the query engine
            TDSMessageCollection responseMessage = Engine.ExecuteBatch(session, message);

            // Check if session packet size is different than the engine packet size
            if (session.PacketSize != Arguments.PacketSize)
            {
                // Get the first message
                TDSMessage firstMessage = responseMessage[0];

                // Find DONE token in it
                int indexOfDone = firstMessage.IndexOf(firstMessage.Where(t => t is TDSDoneToken).First());

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

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

                // Insert env change before done token
                firstMessage.Insert(indexOfDone, envChange);

                // Update session with the new packet size
                session.PacketSize = (uint)Arguments.PacketSize;
            }

            return(responseMessage);
        }
        /// <summary>
        /// Handler for pre-login request
        /// </summary>
        public override TDSMessageCollection OnPreLoginRequest(ITDSServerSession session, TDSMessage request)
        {
            // Delegate to the base class
            TDSMessageCollection response = base.OnPreLoginRequest(session, request);

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

                // Check if routing is configured during login
                if (serverArguments.RouteOnPacket == TDSMessageType.TDS7Login)
                {
                    // Check if pre-login response is contained inside the first message
                    if (response.Count > 0 && response[0].Any(t => t is TDSPreLoginToken))
                    {
                        // Find the first prelogin token
                        TDSPreLoginToken preLoginResponse = (TDSPreLoginToken)response[0].Where(t => t is TDSPreLoginToken).First();

                        // Inflate pre-login request from the message
                        TDSPreLoginToken preLoginRequest = request[0] as TDSPreLoginToken;

                        // Update MARS with the requested value
                        preLoginResponse.IsMARS = preLoginRequest.IsMARS;
                    }
                }
            }

            return(response);
        }
Exemple #3
0
        /// <summary>
        /// Handler for pre-login request
        /// </summary>
        public override TDSMessageCollection OnPreLoginRequest(ITDSServerSession session, TDSMessage request)
        {
            // Delegate to the base class
            TDSMessageCollection response = base.OnPreLoginRequest(session, request);

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

                // Check if routing is configured during login
                if (serverArguments.RouteOnPacket == TDSMessageType.TDS7Login)
                {
                    // Check if pre-login response is contained inside the first message
                    if (response.Count > 0 && response[0].Any(t => t is TDSPreLoginToken))
                    {
                        // Find the first prelogin token
                        TDSPreLoginToken preLoginResponse = (TDSPreLoginToken)response[0].Where(t => t is TDSPreLoginToken).First();

                        // Inflate pre-login request from the message
                        TDSPreLoginToken preLoginRequest = request[0] as TDSPreLoginToken;

                        // Update MARS with the requested value
                        preLoginResponse.IsMARS = preLoginRequest.IsMARS;
                    }
                }
            }

            return response;
        }
        public virtual TDSMessageCollection OnFederatedAuthenticationTokenMessage(ITDSServerSession session, TDSMessage message)
        {
            // Get the FedAuthToken
            TDSFedAuthToken fedauthToken = message[0] as TDSFedAuthToken;

            // Log
            TDSUtilities.Log(Arguments.Log, "Request", fedauthToken);

            return(OnFederatedAuthenticationCompleted(session, fedauthToken.Token));
        }
        /// <summary>
        /// Handler for SSPI request
        /// </summary>
        public virtual TDSMessageCollection OnSSPIRequest(ITDSServerSession session, TDSMessage request)
        {
            // Get the SSPI token
            TDSSSPIClientToken sspiRequest = request[0] as TDSSSPIClientToken;

            // Log request
            TDSUtilities.Log(Arguments.Log, "Request", sspiRequest.Payload);

            // Delegate to SSPI routine
            return(ContinueSSPIAuthentication(session, sspiRequest.Payload));
        }
Exemple #6
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));
        }
        /// <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));
        }
        /// <summary>
        /// Handler for pre-login request
        /// </summary>
        public virtual TDSMessageCollection OnPreLoginRequest(ITDSServerSession session, TDSMessage request)
        {
            // Inflate pre-login request from the message
            TDSPreLoginToken preLoginRequest = request[0] as TDSPreLoginToken;

            // Log request
            TDSUtilities.Log(Arguments.Log, "Request", preLoginRequest);

            // Generate server response for encryption
            TDSPreLoginTokenEncryptionType serverResponse = TDSUtilities.GetEncryptionResponse(preLoginRequest.Encryption, Arguments.Encryption);

            // Update client state with encryption resolution
            session.Encryption = TDSUtilities.ResolveEncryption(preLoginRequest.Encryption, serverResponse);

            // Create TDS prelogin packet
            TDSPreLoginToken preLoginToken = new TDSPreLoginToken(Arguments.ServerVersion, serverResponse, false); // TDS server doesn't support MARS

            // Cache the recieved Nonce into the session
            (session as GenericTDSServerSession).ClientNonce = preLoginRequest.Nonce;

            // Check if the server has been started up as requiring FedAuth when choosing between SSPI and FedAuth
            if (Arguments.FedAuthRequiredPreLoginOption == TdsPreLoginFedAuthRequiredOption.FedAuthRequired)
            {
                if (preLoginRequest.FedAuthRequired == TdsPreLoginFedAuthRequiredOption.FedAuthRequired)
                {
                    // Set the FedAuthRequired option
                    preLoginToken.FedAuthRequired = TdsPreLoginFedAuthRequiredOption.FedAuthRequired;
                }

                // Keep the federated authentication required flag in the server session
                (session as GenericTDSServerSession).FedAuthRequiredPreLoginServerResponse = preLoginToken.FedAuthRequired;

                if (preLoginRequest.Nonce != null)
                {
                    // Generate Server Nonce
                    preLoginToken.Nonce = _GenerateRandomBytes(32);
                }
            }

            // Cache the server Nonce in a session
            (session as GenericTDSServerSession).ServerNonce = preLoginToken.Nonce;

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

            // Reset authentication information
            session.SQLUserID = null;
            session.NTUserAuthenticationContext = null;

            // Respond with a single message that contains only one token
            return(new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, preLoginToken)));
        }
Exemple #10
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);
        }
Exemple #11
0
        /// <summary>
        /// Server TDS parser initialization constructor
        /// </summary>
        public TDSServerParser(ITDSServer server, ITDSServerSession session, Stream stream) :
            base(stream)
        {
            // Save TDS server
            Server = server;

            // Save session
            Session = session;

            // Configure TDS server
            Transport.PacketSize = session.PacketSize;
            Transport.OutgoingSessionID = (ushort)session.SessionID;
        }
        /// <summary>
        /// Server TDS parser initialization constructor
        /// </summary>
        public TDSServerParser(ITDSServer server, ITDSServerSession session, Stream stream) :
            base(stream)
        {
            // Save TDS server
            Server = server;

            // Save session
            Session = session;

            // Configure TDS server
            Transport.PacketSize        = session.PacketSize;
            Transport.OutgoingSessionID = (ushort)session.SessionID;
        }
        /// <summary>
        /// Handler for login request
        /// </summary>
        public override TDSMessageCollection OnLogin7Request(ITDSServerSession session, TDSMessage request)
        {
            // Get the collection from the normal behavior On Login7 Request
            TDSMessageCollection login7Collection = base.OnLogin7Request(session, request);

            // Check if arguments are of the Federated Authentication server
            if (Arguments is FederatedAuthenticationNegativeTDSServerArguments)
            {
                // Cast to federated authentication server arguments
                FederatedAuthenticationNegativeTDSServerArguments ServerArguments = Arguments as FederatedAuthenticationNegativeTDSServerArguments;

                // Get the Federated Authentication ExtAck from Login 7
                TDSFeatureExtAckFederatedAuthenticationOption fedAutExtAct = GetFeatureExtAckFederatedAuthenticationOptionFromLogin7(login7Collection);

                // If not found, return the base collection intact
                if (fedAutExtAct != null)
                {
                    switch (ServerArguments.Scenario)
                    {
                    case FederatedAuthenticationNegativeTDSScenarioType.NonceMissingInFedAuthFEATUREXTACK:
                    {
                        // Delete the nonce from the Token
                        fedAutExtAct.ClientNonce = null;

                        break;
                    }

                    case FederatedAuthenticationNegativeTDSScenarioType.FedAuthMissingInFEATUREEXTACK:
                    {
                        // Remove the Fed Auth Ext Ack from the options list in the FeatureExtAckToken
                        GetFeatureExtAckTokenFromLogin7(login7Collection).Options.Remove(fedAutExtAct);

                        break;
                    }

                    case FederatedAuthenticationNegativeTDSScenarioType.SignatureMissingInFedAuthFEATUREXTACK:
                    {
                        // Delete the signature from the Token
                        fedAutExtAct.Signature = null;

                        break;
                    }
                    }
                }
            }

            // Return the collection
            return(login7Collection);
        }
Exemple #14
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, 1, "Divide by zero error encountered.");
                TDSMessage    responseMessage = new TDSMessage(TDSMessageType.Response, errorToken);
                return(new TDSMessageCollection(responseMessage));
            }
            else
            {
                return(base.CreateQueryResponse(session, batchRequest));
            }
        }
        /// <summary>
        /// It is called when SQL batch request arrives
        /// </summary>
        /// <param name="message">TDS message recieved</param>
        /// <returns>TDS message to respond with</returns>
        public override TDSMessageCollection OnSQLBatchRequest(ITDSServerSession session, TDSMessage request)
        {
            // Delegate to the base class to produce the response first
            TDSMessageCollection batchResponse = base.OnSQLBatchRequest(session, request);

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

                // Check routing condition
                if (ServerArguments.RouteOnPacket == TDSMessageType.SQLBatch)
                {
                    // Construct routing token
                    TDSPacketToken routingToken = CreateRoutingToken();

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

                    // Insert the routing token at the beginning of the response
                    batchResponse[0].Insert(0, routingToken);
                }
                else
                {
                    // Get the first response message
                    TDSMessage responseMessage = batchResponse[0];

                    // Reset the content of the first message
                    responseMessage.Clear();

                    // Prepare ERROR token with the denial details
                    responseMessage.Add(new TDSErrorToken(11111, 1, 14, "Client should have been routed by now", Arguments.ServerName));

                    // Log response
                    TDSUtilities.Log(Arguments.Log, "Response", responseMessage[0]);

                    // Prepare DONE token
                    responseMessage.Add(new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error));

                    // Log response
                    TDSUtilities.Log(Arguments.Log, "Response", responseMessage[1]);
                }
            }

            // Register only one message with the collection
            return(batchResponse);
        }
        /// <summary>
        /// Handler for login request
        /// </summary>
        public override TDSMessageCollection OnLogin7Request(ITDSServerSession session, TDSMessage request)
        {
            // Get the collection from the normal behavior On Login7 Request
            TDSMessageCollection login7Collection = base.OnLogin7Request(session, request);

            // Check if arguments are of the Federated Authentication server
            if (Arguments is FederatedAuthenticationNegativeTDSServerArguments)
            {
                // Cast to federated authentication server arguments
                FederatedAuthenticationNegativeTDSServerArguments ServerArguments = Arguments as FederatedAuthenticationNegativeTDSServerArguments;

                // Get the Federated Authentication ExtAck from Login 7
                TDSFeatureExtAckFederatedAuthenticationOption fedAutExtAct = GetFeatureExtAckFederatedAuthenticationOptionFromLogin7(login7Collection);

                // If not found, return the base collection intact
                if (fedAutExtAct != null)
                {
                    switch (ServerArguments.Scenario)
                    {
                        case FederatedAuthenticationNegativeTDSScenarioType.NonceMissingInFedAuthFEATUREXTACK:
                            {
                                // Delete the nonce from the Token
                                fedAutExtAct.ClientNonce = null;

                                break;
                            }
                        case FederatedAuthenticationNegativeTDSScenarioType.FedAuthMissingInFEATUREEXTACK:
                            {
                                // Remove the Fed Auth Ext Ack from the options list in the FeatureExtAckToken
                                GetFeatureExtAckTokenFromLogin7(login7Collection).Options.Remove(fedAutExtAct);

                                break;
                            }
                        case FederatedAuthenticationNegativeTDSScenarioType.SignatureMissingInFedAuthFEATUREXTACK:
                            {
                                // Delete the signature from the Token
                                fedAutExtAct.Signature = null;

                                break;
                            }
                    }
                }
            }

            // Return the collection
            return login7Collection;
        }
        /// <summary>
        /// Handler for login request
        /// </summary>
        public override TDSMessageCollection OnPreLoginRequest(ITDSServerSession session, TDSMessage request)
        {
            // Get the collection from a valid On PreLogin Request
            TDSMessageCollection preLoginCollection = base.OnPreLoginRequest(session, request);

            // Check if arguments are of the Federated Authentication server
            if (Arguments is FederatedAuthenticationNegativeTDSServerArguments)
            {
                // Cast to federated authentication server arguments
                FederatedAuthenticationNegativeTDSServerArguments ServerArguments = Arguments as FederatedAuthenticationNegativeTDSServerArguments;

                // Find the is token carrying on TDSPreLoginToken
                TDSPreLoginToken preLoginToken = preLoginCollection.Find(message => message.Exists(packetToken => packetToken is TDSPreLoginToken)).
                                                 Find(packetToken => packetToken is TDSPreLoginToken) as TDSPreLoginToken;

                switch (ServerArguments.Scenario)
                {
                case FederatedAuthenticationNegativeTDSScenarioType.NonceMissingInFedAuthPreLogin:
                {
                    // If we have the prelogin token
                    if (preLoginToken != null && preLoginToken.Nonce != null)
                    {
                        // Nullify the nonce from the Token
                        preLoginToken.Nonce = null;
                    }

                    break;
                }

                case FederatedAuthenticationNegativeTDSScenarioType.InvalidB_FEDAUTHREQUIREDResponse:
                {
                    // If we have the prelogin token
                    if (preLoginToken != null)
                    {
                        // Set an illegal value for B_FEDAUTHREQURED
                        preLoginToken.FedAuthRequired = TdsPreLoginFedAuthRequiredOption.Illegal;
                    }

                    break;
                }
                }
            }

            // Return the collection
            return(preLoginCollection);
        }
        /// <summary>
        /// Handler for login request
        /// </summary>
        public override TDSMessageCollection OnPreLoginRequest(ITDSServerSession session, TDSMessage request)
        {
            // Get the collection from a valid On PreLogin Request
            TDSMessageCollection preLoginCollection = base.OnPreLoginRequest(session, request);

            // Check if arguments are of the Federated Authentication server
            if (Arguments is FederatedAuthenticationNegativeTDSServerArguments)
            {
                // Cast to federated authentication server arguments
                FederatedAuthenticationNegativeTDSServerArguments ServerArguments = Arguments as FederatedAuthenticationNegativeTDSServerArguments;

                // Find the is token carrying on TDSPreLoginToken
                TDSPreLoginToken preLoginToken = preLoginCollection.Find(message => message.Exists(packetToken => packetToken is TDSPreLoginToken)).
                    Find(packetToken => packetToken is TDSPreLoginToken) as TDSPreLoginToken;

                switch (ServerArguments.Scenario)
                {
                    case FederatedAuthenticationNegativeTDSScenarioType.NonceMissingInFedAuthPreLogin:
                        {
                            // If we have the prelogin token
                            if (preLoginToken != null && preLoginToken.Nonce != null)
                            {
                                // Nullify the nonce from the Token
                                preLoginToken.Nonce = null;
                            }

                            break;
                        }

                    case FederatedAuthenticationNegativeTDSScenarioType.InvalidB_FEDAUTHREQUIREDResponse:
                        {
                            // If we have the prelogin token
                            if (preLoginToken != null)
                            {
                                // Set an illegal value for B_FEDAUTHREQURED
                                preLoginToken.FedAuthRequired = TdsPreLoginFedAuthRequiredOption.Illegal;
                            }

                            break;
                        }
                }
            }

            // Return the collection
            return preLoginCollection;
        }
        /// <summary>
        /// Complete login sequence
        /// </summary>
        protected override TDSMessageCollection OnAuthenticationCompleted(ITDSServerSession session)
        {
            // Delegate to the base class
            TDSMessageCollection responseMessageCollection = base.OnAuthenticationCompleted(session);

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

                // Check routing condition
                if (serverArguments.RouteOnPacket == TDSMessageType.TDS7Login)
                {
                    // Construct routing token
                    TDSPacketToken routingToken = CreateRoutingToken();

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

                    // Get the first message
                    TDSMessage targetMessage = responseMessageCollection[0];

                    // Index at which to insert the routing token
                    int insertIndex = targetMessage.Count - 1;

                    // VSTS# 1021027 - Read-Only Routing yields TDS protocol error
                    // Resolution: Send TDS FeatureExtAct token before TDS ENVCHANGE token with routing information
                    TDSPacketToken featureExtAckToken = targetMessage.Find(t => t is TDSFeatureExtAckToken);

                    // Check if found
                    if (featureExtAckToken != null)
                    {
                        // Find token position
                        insertIndex = targetMessage.IndexOf(featureExtAckToken);
                    }

                    // Insert right before the done token
                    targetMessage.Insert(insertIndex, routingToken);
                }
            }

            return(responseMessageCollection);
        }
        protected virtual TDSMessageCollection OnFederatedAuthenticationInfoRequest(ITDSServerSession session)
        {
            TDSFedAuthInfoToken infoToken = new TDSFedAuthInfoToken();

            // Make fake info options
            TDSFedAuthInfoOptionSPN    spn    = new TDSFedAuthInfoOptionSPN(Arguments.ServerPrincipalName);
            TDSFedAuthInfoOptionSTSURL stsurl = new TDSFedAuthInfoOptionSTSURL(Arguments.StsUrl);

            infoToken.Options.Add(0, spn);
            infoToken.Options.Add(1, stsurl);

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

            TDSMessage infoMessage = new TDSMessage(TDSMessageType.FederatedAuthenticationInfo, infoToken);

            return(new TDSMessageCollection(infoMessage));
        }
        /// <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 #22
0
        /// <summary>
        /// Prepare response for server instance name query
        /// </summary>
        private TDSMessage _PrepareInstanceNameResponse(ITDSServerSession session)
        {
            // Prepare result metadata
            TDSColMetadataToken metadataToken = new TDSColMetadataToken();

            // Start first column
            TDSColumnData column = new TDSColumnData();
            column.DataType = TDSDataType.NVarChar;
            column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(256, new TDSColumnDataCollation(13632521, 52));
            column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly;

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

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

            // Prepare result data
            TDSRowToken rowToken = new TDSRowToken(metadataToken);

            // Start with server name
            string value = ServerArguments.ServerName;

            // Check if server name contains a slash
            if (value.Contains("\\"))
            {
                // Take everything after the slash
                value = value.Substring(value.IndexOf('\\') + 1);
            }
            else
            {
                // Instance is unnamed
                value = null;
            }

            // Add row
            rowToken.Data.Add(value);

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

            // Create DONE token
            TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1);

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

            // Serialize tokens into the message
            return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken);
        }
        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));
        }
 /// <summary>
 /// It is called when attention arrives
 /// </summary>
 public virtual TDSMessageCollection OnAttention(ITDSServerSession session, TDSMessage message)
 {
     // Delegate into the query engine
     return(Engine.ExecuteAttention(session, message));
 }
Exemple #25
0
        /// <summary>
        /// Prepare response for query whether this is a SQL Azure instance
        /// </summary>
        private TDSMessage _PrepareIsAzure(ITDSServerSession session)
        {
            // Prepare result metadata
            TDSColMetadataToken metadataToken = new TDSColMetadataToken();

            // Start a new column
            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);

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

            // Prepare result data
            TDSRowToken rowToken = new TDSRowToken(metadataToken);

            // Per http://msdn.microsoft.com/en-us/library/ms174396.aspx
            // 4 = Express (This is returned for Express, Express with Advanced Services, and Windows Embedded SQL.)
            rowToken.Data.Add(4);

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

            // Create DONE token
            TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1);

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

            // Serialize tokens into the message
            return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken);
        }
        /// <summary>
        /// Handler for login request
        /// </summary>
        public virtual TDSMessageCollection OnLogin7Request(ITDSServerSession session, TDSMessage request)
        {
            // Inflate login7 request from the message
            TDSLogin7Token loginRequest = request[0] as TDSLogin7Token;

            // Log request
            TDSUtilities.Log(Arguments.Log, "Request", loginRequest);

            // Update server context
            session.Database = string.IsNullOrEmpty(loginRequest.Database) ? "master" : loginRequest.Database;

            // Resolve TDS version
            session.TDSVersion = TDSVersion.Resolve(TDSVersion.GetTDSVersion(Arguments.ServerVersion), loginRequest.TDSVersion);

            // Check for the TDS version
            TDSMessageCollection collection = CheckTDSVersion(session);

            // Check if any errors are posted
            if (collection != null)
            {
                // Version check needs to send own message hence we can't proceed
                return(collection);
            }

            // Indicates federated authentication
            bool bIsFedAuthConnection = false;

            // Federated authentication option to be used later
            TDSLogin7FedAuthOptionToken federatedAuthenticationOption = null;

            // Check if feature extension block is available
            if (loginRequest.FeatureExt != null)
            {
                // Go over the feature extension data
                foreach (TDSLogin7FeatureOptionToken option in loginRequest.FeatureExt)
                {
                    // Check option type
                    switch (option.FeatureID)
                    {
                    case TDSFeatureID.SessionRecovery:
                    {
                        // Enable session recovery
                        session.IsSessionRecoveryEnabled = true;

                        // Cast to session state options
                        TDSLogin7SessionRecoveryOptionToken sessionStateOption = option as TDSLogin7SessionRecoveryOptionToken;

                        // Inflate session state
                        (session as GenericTDSServerSession).Inflate(sessionStateOption.Initial, sessionStateOption.Current);

                        break;
                    }

                    case TDSFeatureID.FederatedAuthentication:
                    {
                        // Cast to federated authentication option
                        federatedAuthenticationOption = option as TDSLogin7FedAuthOptionToken;

                        // Mark authentication as federated
                        bIsFedAuthConnection = true;

                        // Validate federated authentication option
                        collection = CheckFederatedAuthenticationOption(session, option as TDSLogin7FedAuthOptionToken);

                        if (collection != null)
                        {
                            // Version error happened.
                            return(collection);
                        }

                        // Save the fed auth library to be used
                        (session as GenericTDSServerSession).FederatedAuthenticationLibrary = federatedAuthenticationOption.Library;

                        break;
                    }

                    default:
                    {
                        // Do nothing
                        break;
                    }
                    }
                }
            }

            // Check if SSPI authentication is requested
            if (loginRequest.OptionalFlags2.IntegratedSecurity == TDSLogin7OptionalFlags2IntSecurity.On)
            {
                // Delegate to SSPI authentication
                return(ContinueSSPIAuthentication(session, loginRequest.SSPI));
            }

            // If it is not a FedAuth connection or the server has been started up as not supporting FedAuth, just ignore the FeatureExtension
            // Yes unfortunately for the fake server, supporting FedAuth = Requiring FedAuth
            if (!bIsFedAuthConnection ||
                Arguments.FedAuthRequiredPreLoginOption == TdsPreLoginFedAuthRequiredOption.FedAuthNotRequired)
            {
                // We use SQL authentication
                session.SQLUserID = loginRequest.UserID;

                // Process with the SQL login.
                return(OnSqlAuthenticationCompleted(session));
            }
            else
            {
                // Fedauth feature extension is present and server has been started up as Requiring (or Supporting) FedAuth
                if (federatedAuthenticationOption.IsRequestingAuthenticationInfo)
                {
                    // Must provide client with more info before completing authentication
                    return(OnFederatedAuthenticationInfoRequest(session));
                }
                else
                {
                    return(OnFederatedAuthenticationCompleted(session, federatedAuthenticationOption.Token));
                }
            }
        }
 /// <summary>
 /// Notify server of the session termination
 /// </summary>
 public virtual void CloseSession(ITDSServerSession session)
 {
     // Do nothing
 }
Exemple #28
0
        protected virtual TDSMessageCollection OnFederatedAuthenticationInfoRequest(ITDSServerSession session)
        {
            TDSFedAuthInfoToken infoToken = new TDSFedAuthInfoToken();

            // Make fake info options
            TDSFedAuthInfoOptionSPN spn = new TDSFedAuthInfoOptionSPN(Arguments.ServerPrincipalName);
            TDSFedAuthInfoOptionSTSURL stsurl = new TDSFedAuthInfoOptionSTSURL(Arguments.StsUrl);
            infoToken.Options.Add(0, spn);
            infoToken.Options.Add(1, stsurl);

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

            TDSMessage infoMessage = new TDSMessage(TDSMessageType.FederatedAuthenticationInfo, infoToken);
            return new TDSMessageCollection(infoMessage);
        }
Exemple #29
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)));
        }
        /// <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 #31
0
 /// <summary>
 /// Notify server of the session termination
 /// </summary>
 public virtual void CloseSession(ITDSServerSession session)
 {
     // Do nothing
 }
Exemple #32
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 #33
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 #34
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 #35
0
        /// <summary>
        /// Prepare response to server ping
        /// </summary>
        private TDSMessage _PreparePingResponse(ITDSServerSession session)
        {
            // Prepare result metadata
            TDSColMetadataToken metadataToken = new TDSColMetadataToken();

            // Start the first column
            TDSColumnData column = new TDSColumnData();
            column.DataType = TDSDataType.IntN;
            column.DataTypeSpecific = (byte)4;
            column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly;
            column.Flags.IsNullable = true;  // TODO: Must be nullable, otherwise something is wrong with SqlClient
            column.Flags.IsComputed = true;

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

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

            // Prepare result data
            TDSRowToken rowToken = new TDSRowToken(metadataToken);

            // Add row
            rowToken.Data.Add((int)1);

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

            // Create DONE token
            TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1);

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

            // Serialize tokens into the message
            return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken);
        }
Exemple #36
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 acknowledgnment 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);
        }
Exemple #37
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));
        }
Exemple #38
0
        /// <summary>
        /// Handler for pre-login request
        /// </summary>
        public virtual TDSMessageCollection OnPreLoginRequest(ITDSServerSession session, TDSMessage request)
        {
            // Inflate pre-login request from the message
            TDSPreLoginToken preLoginRequest = request[0] as TDSPreLoginToken;

            // Log request
            TDSUtilities.Log(Arguments.Log, "Request", preLoginRequest);

            // Generate server response for encryption
            TDSPreLoginTokenEncryptionType serverResponse = TDSUtilities.GetEncryptionResponse(preLoginRequest.Encryption, Arguments.Encryption);

            // Update client state with encryption resolution
            session.Encryption = TDSUtilities.ResolveEncryption(preLoginRequest.Encryption, serverResponse);

            // Create TDS prelogin packet
            TDSPreLoginToken preLoginToken = new TDSPreLoginToken(Arguments.ServerVersion, serverResponse, false); // TDS server doesn't support MARS

            // Cache the recieved Nonce into the session
            (session as GenericTDSServerSession).ClientNonce = preLoginRequest.Nonce;

            // Check if the server has been started up as requiring FedAuth when choosing between SSPI and FedAuth
            if (Arguments.FedAuthRequiredPreLoginOption == TdsPreLoginFedAuthRequiredOption.FedAuthRequired)
            {
                if (preLoginRequest.FedAuthRequired == TdsPreLoginFedAuthRequiredOption.FedAuthRequired)
                {
                    // Set the FedAuthRequired option
                    preLoginToken.FedAuthRequired = TdsPreLoginFedAuthRequiredOption.FedAuthRequired;
                }

                // Keep the federated authentication required flag in the server session
                (session as GenericTDSServerSession).FedAuthRequiredPreLoginServerResponse = preLoginToken.FedAuthRequired;

                if (preLoginRequest.Nonce != null)
                {
                    // Generate Server Nonce
                    preLoginToken.Nonce = _GenerateRandomBytes(32);
                }
            }

            // Cache the server Nonce in a session
            (session as GenericTDSServerSession).ServerNonce = preLoginToken.Nonce;

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

            // Reset authentication information
            session.SQLUserID = null;
            session.NTUserAuthenticationContext = null;

            // Respond with a single message that contains only one token
            return new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, preLoginToken));
        }
Exemple #39
0
        /// <summary>
        /// It is called when SQL batch request arrives
        /// </summary>
        /// <param name="message">TDS message recieved</param>
        /// <returns>TDS message to respond with</returns>
        public override TDSMessageCollection OnSQLBatchRequest(ITDSServerSession session, TDSMessage request)
        {
            // Delegate to the base class to produce the response first
            TDSMessageCollection batchResponse = base.OnSQLBatchRequest(session, request);

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

                // Check routing condition
                if (ServerArguments.RouteOnPacket == TDSMessageType.SQLBatch)
                {
                    // Construct routing token
                    TDSPacketToken routingToken = CreateRoutingToken();

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

                    // Insert the routing token at the beginning of the response
                    batchResponse[0].Insert(0, routingToken);
                }
                else
                {
                    // Get the first response message
                    TDSMessage responseMessage = batchResponse[0];

                    // Reset the content of the first message
                    responseMessage.Clear();

                    // Prepare ERROR token with the denial details
                    responseMessage.Add(new TDSErrorToken(11111, 1, 14, "Client should have been routed by now", Arguments.ServerName));

                    // Log response
                    TDSUtilities.Log(Arguments.Log, "Response", responseMessage[0]);

                    // Prepare DONE token
                    responseMessage.Add(new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error));

                    // Log response
                    TDSUtilities.Log(Arguments.Log, "Response", responseMessage[1]);
                }
            }

            // Register only one message with the collection
            return batchResponse;
        }
Exemple #40
0
        /// <summary>
        /// Prepare response for query of class of the SQL Server instance
        /// </summary>
        private TDSMessage _PrepareTestSQLServerClassResponse(ITDSServerSession session)
        {
            // Prepare result metadata
            TDSColMetadataToken metadataToken = new TDSColMetadataToken();

            // Start first column
            TDSColumnData column = new TDSColumnData();
            column.DataType = TDSDataType.NVarChar;
            column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(256, new TDSColumnDataCollation(13632521, 52));
            column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly;

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

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

            // Prepare result data
            TDSRowToken rowToken = new TDSRowToken(metadataToken);

            // Get the server class
            rowToken.Data.Add(session.Server.GetType().FullName);

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

            // Create DONE token
            TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1);

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

            // Serialize tokens into the message
            return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken);
        }
Exemple #41
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;
        }
Exemple #42
0
        /// <summary>
        /// Prepare response for user nane query that OLE DB stack dispatches upon connection
        /// </summary>
        private TDSMessage _PrepareOleDbReadOnlyUserName(ITDSServerSession session)
        {
            // Prepare result metadata
            TDSColMetadataToken metadataToken = new TDSColMetadataToken();

            // Start first column
            TDSColumnData column = new TDSColumnData();
            column.DataType = TDSDataType.BigVarChar;
            column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(1, new TDSColumnDataCollation(13632521, 52));
            column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly;

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

            // Start second column
            column = new TDSColumnData();
            column.DataType = TDSDataType.NVarChar;
            column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(128, new TDSColumnDataCollation(13632521, 52));
            column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly;

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

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

            // Prepare result data
            TDSRowToken rowToken = new TDSRowToken(metadataToken);

            // Add row
            rowToken.Data.Add("N");
            rowToken.Data.Add("dbo");

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

            // Create DONE token
            TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1);

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

            // Serialize tokens into the message
            return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken);
        }
Exemple #43
0
        /// <summary>
        /// Prepare response to the query about connection encryption
        /// </summary>
        private TDSMessage _PrepareEncryptionInfoResponse(ITDSServerSession session)
        {
            // Prepare result metadata
            TDSColMetadataToken metadataToken = new TDSColMetadataToken();

            // Start the first column
            TDSColumnData column = new TDSColumnData();
            column.DataType = TDSDataType.NVarChar;
            column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(40, new TDSColumnDataCollation(13632521, 52));
            column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly;
            column.Name = "encrypt_option";

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

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

            // Prepare result data
            TDSRowToken rowToken = new TDSRowToken(metadataToken);

            // Check if encryption is enabled
            if (session.Encryption == TDSEncryptionType.Full)
            {
                // Add row
                rowToken.Data.Add("TRUE");
            }
            else
            {
                // Add row
                rowToken.Data.Add("FALSE");
            }

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

            // Create DONE token
            TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1);

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

            // Serialize tokens into the message
            return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken);
        }
        /// <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);
        }
Exemple #45
0
 /// <summary>
 /// It is called when attention arrives
 /// </summary>
 public virtual TDSMessageCollection OnAttention(ITDSServerSession session, TDSMessage message)
 {
     // Delegate into the query engine
     return Engine.ExecuteAttention(session, message);
 }
 /// <summary>
 /// Called by OnLogin7Request when client is using SQL auth. Overridden by subclasses to easily detect when SQL auth is used.
 /// </summary>
 protected virtual TDSMessageCollection OnSqlAuthenticationCompleted(ITDSServerSession session)
 {
     return(OnAuthenticationCompleted(session));
 }
Exemple #47
0
        /// <summary>
        /// It is called when SQL batch request arrives
        /// </summary>
        public virtual TDSMessageCollection OnSQLBatchRequest(ITDSServerSession session, TDSMessage message)
        {
            // Delegate to the query engine
            TDSMessageCollection responseMessage = Engine.ExecuteBatch(session, message);

            // Check if session packet size is different than the engine packet size
            if (session.PacketSize != Arguments.PacketSize)
            {
                // Get the first message
                TDSMessage firstMessage = responseMessage[0];

                // Find DONE token in it
                int indexOfDone = firstMessage.IndexOf(firstMessage.Where(t => t is TDSDoneToken).First());

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

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

                // Insert env change before done token
                firstMessage.Insert(indexOfDone, envChange);

                // Update session with the new packet size
                session.PacketSize = (uint)Arguments.PacketSize;
            }

            return responseMessage;
        }
        /// <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);
        }
Exemple #49
0
        /// <summary>
        /// Handler for SSPI request
        /// </summary>
        public virtual TDSMessageCollection OnSSPIRequest(ITDSServerSession session, TDSMessage request)
        {
            // Get the SSPI token
            TDSSSPIClientToken sspiRequest = request[0] as TDSSSPIClientToken;

            // Log request
            TDSUtilities.Log(Arguments.Log, "Request", sspiRequest.Payload);

            // Delegate to SSPI routine
            return ContinueSSPIAuthentication(session, sspiRequest.Payload);
        }
Exemple #50
0
        public virtual TDSMessageCollection OnFederatedAuthenticationTokenMessage(ITDSServerSession session, TDSMessage message)
        {
            // Get the FedAuthToken
            TDSFedAuthToken fedauthToken = message[0] as TDSFedAuthToken;

            // Log
            TDSUtilities.Log(Arguments.Log, "Request", fedauthToken);

            return OnFederatedAuthenticationCompleted(session, fedauthToken.Token);
        }
Exemple #51
0
        /// <summary>
        /// Handler for login request
        /// </summary>
        public virtual TDSMessageCollection OnLogin7Request(ITDSServerSession session, TDSMessage request)
        {
            // Inflate login7 request from the message
            TDSLogin7Token loginRequest = request[0] as TDSLogin7Token;

            // Log request
            TDSUtilities.Log(Arguments.Log, "Request", loginRequest);

            // Update server context
            session.Database = string.IsNullOrEmpty(loginRequest.Database) ? "master" : loginRequest.Database;

            // Resolve TDS version
            session.TDSVersion = TDSVersion.Resolve(TDSVersion.GetTDSVersion(Arguments.ServerVersion), loginRequest.TDSVersion);

            // Check for the TDS version
            TDSMessageCollection collection = CheckTDSVersion(session);

            // Check if any errors are posted
            if (collection != null)
            {
                // Version check needs to send own message hence we can't proceed
                return collection;
            }

            // Indicates federated authentication
            bool bIsFedAuthConnection = false;

            // Federated authentication option to be used later
            TDSLogin7FedAuthOptionToken federatedAuthenticationOption = null;

            // Check if feature extension block is available
            if (loginRequest.FeatureExt != null)
            {
                // Go over the feature extension data
                foreach (TDSLogin7FeatureOptionToken option in loginRequest.FeatureExt)
                {
                    // Check option type
                    switch (option.FeatureID)
                    {
                        case TDSFeatureID.SessionRecovery:
                            {
                                // Enable session recovery
                                session.IsSessionRecoveryEnabled = true;

                                // Cast to session state options
                                TDSLogin7SessionRecoveryOptionToken sessionStateOption = option as TDSLogin7SessionRecoveryOptionToken;

                                // Inflate session state
                                (session as GenericTDSServerSession).Inflate(sessionStateOption.Initial, sessionStateOption.Current);

                                break;
                            }
                        case TDSFeatureID.FederatedAuthentication:
                            {
                                // Cast to federated authentication option
                                federatedAuthenticationOption = option as TDSLogin7FedAuthOptionToken;

                                // Mark authentication as federated
                                bIsFedAuthConnection = true;

                                // Validate federated authentication option
                                collection = CheckFederatedAuthenticationOption(session, option as TDSLogin7FedAuthOptionToken);

                                if (collection != null)
                                {
                                    // Version error happened.
                                    return collection;
                                }

                                // Save the fed auth library to be used
                                (session as GenericTDSServerSession).FederatedAuthenticationLibrary = federatedAuthenticationOption.Library;

                                break;
                            }
                        default:
                            {
                                // Do nothing
                                break;
                            }
                    }
                }
            }

            // Check if SSPI authentication is requested
            if (loginRequest.OptionalFlags2.IntegratedSecurity == TDSLogin7OptionalFlags2IntSecurity.On)
            {
                // Delegate to SSPI authentication
                return ContinueSSPIAuthentication(session, loginRequest.SSPI);
            }

            // If it is not a FedAuth connection or the server has been started up as not supporting FedAuth, just ignore the FeatureExtension
            // Yes unfortunately for the fake server, supporting FedAuth = Requiring FedAuth
            if (!bIsFedAuthConnection
                || Arguments.FedAuthRequiredPreLoginOption == TdsPreLoginFedAuthRequiredOption.FedAuthNotRequired)
            {
                // We use SQL authentication
                session.SQLUserID = loginRequest.UserID;

                // Process with the SQL login.
                return OnSqlAuthenticationCompleted(session);
            }
            else
            {
                // Fedauth feature extension is present and server has been started up as Requiring (or Supporting) FedAuth
                if (federatedAuthenticationOption.IsRequestingAuthenticationInfo)
                {
                    // Must provide client with more info before completing authentication
                    return OnFederatedAuthenticationInfoRequest(session);
                }
                else
                {
                    return OnFederatedAuthenticationCompleted(session, federatedAuthenticationOption.Token);
                }
            }
        }
Exemple #52
0
        /// <summary>
        /// Complete login sequence
        /// </summary>
        protected override TDSMessageCollection OnAuthenticationCompleted(ITDSServerSession session)
        {
            // Delegate to the base class
            TDSMessageCollection responseMessageCollection = base.OnAuthenticationCompleted(session);

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

                // Check routing condition
                if (serverArguments.RouteOnPacket == TDSMessageType.TDS7Login)
                {
                    // Construct routing token
                    TDSPacketToken routingToken = CreateRoutingToken();

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

                    // Get the first message
                    TDSMessage targetMessage = responseMessageCollection[0];

                    // Index at which to insert the routing token
                    int insertIndex = targetMessage.Count - 1;

                    // VSTS# 1021027 - Read-Only Routing yields TDS protocol error
                    // Resolution: Send TDS FeatureExtAct token before TDS ENVCHANGE token with routing information
                    TDSPacketToken featureExtAckToken = targetMessage.Find(t => t is TDSFeatureExtAckToken);

                    // Check if found
                    if (featureExtAckToken != null)
                    {
                        // Find token position
                        insertIndex = targetMessage.IndexOf(featureExtAckToken);
                    }

                    // Insert right before the done token
                    targetMessage.Insert(insertIndex, routingToken);
                }
            }

            return responseMessageCollection;
        }
Exemple #53
0
 /// <summary>
 /// Called by OnLogin7Request when client is using SQL auth. Overridden by subclasses to easily detect when SQL auth is used.
 /// </summary>
 protected virtual TDSMessageCollection OnSqlAuthenticationCompleted(ITDSServerSession session)
 {
     return OnAuthenticationCompleted(session);
 }
Exemple #54
0
        /// <summary>
        /// Prepare response for session user name query
        /// </summary>
        private TDSMessage _PrepareSessionUserResponse(ITDSServerSession session)
        {
            // Prepare result metadata
            TDSColMetadataToken metadataToken = new TDSColMetadataToken();

            // Prepare column type-specific data
            TDSShilohVarCharColumnSpecific nVarChar = new TDSShilohVarCharColumnSpecific(256, new TDSColumnDataCollation(13632521, 52));

            // Prepare the first column
            TDSColumnData column = new TDSColumnData();
            column.DataType = TDSDataType.NVarChar;
            column.Flags.Updatable = TDSColumnDataUpdatableFlag.Unknown;
            column.Flags.IsNullable = true;
            column.DataTypeSpecific = nVarChar;
            column.Name = "nt_user_name";

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

            // Prepare the second column
            column = new TDSColumnData();
            column.DataType = TDSDataType.NVarChar;
            column.Flags.Updatable = TDSColumnDataUpdatableFlag.Unknown;
            column.Flags.IsNullable = true;
            column.DataTypeSpecific = nVarChar;
            column.Name = "nt_domain";

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

            // Prepare the third column
            column = new TDSColumnData();
            column.DataType = TDSDataType.NVarChar;
            column.Flags.Updatable = TDSColumnDataUpdatableFlag.Unknown;
            column.DataTypeSpecific = nVarChar;
            column.Name = "login_name";

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

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

            // Prepare result data
            TDSRowToken rowToken = new TDSRowToken(metadataToken);

            // Check user type
            if (session.SQLUserID != null)
            {
                // Add row
                rowToken.Data.Add(null);  // nt_user_name
                rowToken.Data.Add(null);  // nt_domain
                rowToken.Data.Add(session.SQLUserID);  // login_name
            }
            else if (session.NTUserAuthenticationContext != null)
            {
                // Get user identifier
                string userID = session.NTUserAuthenticationContext.GetRemoteIdentity().Name;

                // Look for traditional separator for form "<domain>\<user>"
                int indexOfSeparator = userID.IndexOf('\\');

                string domain = null;
                string user = null;

                // Parse domain and user out of the entry
                if (indexOfSeparator != -1)
                {
                    // Extract parts
                    domain = userID.Substring(0, indexOfSeparator);
                    user = userID.Substring(indexOfSeparator + 1);
                }
                else
                {
                    // Look for a different type of separator for form "<user>@<domain>"
                    indexOfSeparator = userID.IndexOf('@');

                    // Check if found
                    if (indexOfSeparator != -1)
                    {
                        // Extract parts
                        domain = userID.Substring(indexOfSeparator + 1);
                        user = userID.Substring(0, indexOfSeparator);
                    }
                    else
                    {
                        // We don't recognize this user so don't parse it
                        domain = null;
                        user = userID;
                    }
                }

                // Add row
                rowToken.Data.Add(user);  // nt_user_name
                rowToken.Data.Add(domain);  // nt_domain
                rowToken.Data.Add(userID);  // login_name
            }
            else
            {
                // We don't have a user, which is very strange since we're in query engine already
                rowToken.Data.Add(null);  // nt_user_name
                rowToken.Data.Add(null);  // nt_domain
                rowToken.Data.Add(null);  // login_name
            }

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

            // Create DONE token
            TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1);

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

            // Serialize tokens into the message
            return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken);
        }
Exemple #55
0
        /// <summary>
        /// Prepare response to the query about connection end-point
        /// </summary>
        private TDSMessage _PrepareConnectionInfoResponse(ITDSServerSession session)
        {
            // Prepare result metadata
            TDSColMetadataToken metadataToken = new TDSColMetadataToken();

            // Start the first column
            TDSColumnData column = new TDSColumnData();
            column.DataType = TDSDataType.NVarChar;
            column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(40, new TDSColumnDataCollation(13632521, 52));
            column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly;
            column.Name = "net_transport";

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

            // Start the second column
            column = new TDSColumnData();
            column.DataType = TDSDataType.BigVarChar;
            column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(48, new TDSColumnDataCollation(13632521, 52));
            column.Flags.IsNullable = true;
            column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly;
            column.Name = "local_net_address";

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

            // Start the third column
            column = new TDSColumnData();
            column.DataType = TDSDataType.IntN;
            column.DataTypeSpecific = (byte)4;
            column.Flags.IsNullable = true;
            column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly;
            column.Name = "local_tcp_port";

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

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

            // Prepare result data
            TDSRowToken rowToken = new TDSRowToken(metadataToken);

            // Add row
            rowToken.Data.Add(session.ServerEndPointInfo.Transport.ToString());
            rowToken.Data.Add(session.ServerEndPointInfo.Address.ToString());
            rowToken.Data.Add(session.ServerEndPointInfo.Port);

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

            // Create DONE token
            TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1);

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

            // Serialize tokens into the message
            return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken);
        }