/// <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))); }
/// <summary> /// Generate an encryption response based on the client request and server setting /// </summary> /// <param name="client">A value received from the client</param> /// <param name="server">Configuration of the server</param> public static TDSPreLoginTokenEncryptionType GetEncryptionResponse(TDSPreLoginTokenEncryptionType client, TDSPreLoginTokenEncryptionType server) { // Check each equivalence class if (client == TDSPreLoginTokenEncryptionType.NotSupported) { // Check server response if (server == TDSPreLoginTokenEncryptionType.Off || server == TDSPreLoginTokenEncryptionType.NotSupported) { return(TDSPreLoginTokenEncryptionType.NotSupported); } else { return(TDSPreLoginTokenEncryptionType.Required); } } else if (client == TDSPreLoginTokenEncryptionType.Off) { // Check corresponding server if (server == TDSPreLoginTokenEncryptionType.NotSupported) { return(TDSPreLoginTokenEncryptionType.NotSupported); } else if (server == TDSPreLoginTokenEncryptionType.Off) { return(TDSPreLoginTokenEncryptionType.Off); } else { return(TDSPreLoginTokenEncryptionType.Required); } } else if (client == TDSPreLoginTokenEncryptionType.On) { // Check server if (server == TDSPreLoginTokenEncryptionType.Off || server == TDSPreLoginTokenEncryptionType.On || server == TDSPreLoginTokenEncryptionType.Required) { return(TDSPreLoginTokenEncryptionType.On); } else { throw new ArgumentException("Server is configured to not support encryption", "server"); } } // This case is not documented so pick a default return(TDSPreLoginTokenEncryptionType.Off); }
/// <summary> /// Convert indications of encryption support by client and server into expected behavior /// </summary> public static TDSEncryptionType ResolveEncryption(TDSPreLoginTokenEncryptionType client, TDSPreLoginTokenEncryptionType server) { // Check each equivalence class if (client == TDSPreLoginTokenEncryptionType.NotSupported) { // Check server response if (server == TDSPreLoginTokenEncryptionType.Off || server == TDSPreLoginTokenEncryptionType.NotSupported) { return(TDSEncryptionType.Off); } else { // Encrypt login only return(TDSEncryptionType.LoginOnly); } } else if (client == TDSPreLoginTokenEncryptionType.Off) { // Check corresponding server if (server == TDSPreLoginTokenEncryptionType.NotSupported) { // Encryption should be turned off return(TDSEncryptionType.Off); } else if (server == TDSPreLoginTokenEncryptionType.Off) { // We encrypt only login packet return(TDSEncryptionType.LoginOnly); } } else if (client == TDSPreLoginTokenEncryptionType.On) { // Check server if (server == TDSPreLoginTokenEncryptionType.NotSupported || server == TDSPreLoginTokenEncryptionType.Off) { // This is an error case, however existing client stacks treat this as login-only encryption return(TDSEncryptionType.LoginOnly); } } // Full encryption is required return(TDSEncryptionType.Full); }
/// <summary> /// Initialization constructor /// </summary> public TDSPreLoginToken(Version version, TDSPreLoginTokenEncryptionType encryption, bool isMARS, uint threadID, TdsPreLoginFedAuthRequiredOption fedAuthRequired) : this(version, encryption, isMARS, threadID) { FedAuthRequired = fedAuthRequired; }
/// <summary> /// Initialization constructor /// </summary> public TDSPreLoginToken(Version version, TDSPreLoginTokenEncryptionType encryption, bool isMARS) : this(version, encryption) { // Save MARS IsMARS = isMARS; }
/// <summary> /// Initialization constructor /// </summary> public TDSPreLoginToken(Version version, TDSPreLoginTokenEncryptionType encryption, bool isMARS, uint threadID) : this(version, encryption, isMARS) { // Save thread ID ThreadID = threadID; }
/// <summary> /// Initialization constructor /// </summary> public TDSPreLoginToken(Version version, TDSPreLoginTokenEncryptionType encryption) : this(version) { // Save encryption setting Encryption = encryption; }
/// <summary> /// Convert indications of encryption support by client and server into expected behavior /// </summary> public static TDSEncryptionType ResolveEncryption(TDSPreLoginTokenEncryptionType client, TDSPreLoginTokenEncryptionType server) { // Check each equivalence class if (client == TDSPreLoginTokenEncryptionType.NotSupported) { // Check server response if (server == TDSPreLoginTokenEncryptionType.Off || server == TDSPreLoginTokenEncryptionType.NotSupported) { return TDSEncryptionType.Off; } else { // Encrypt login only return TDSEncryptionType.LoginOnly; } } else if (client == TDSPreLoginTokenEncryptionType.Off) { // Check corresponding server if (server == TDSPreLoginTokenEncryptionType.NotSupported) { // Encryption should be turned off return TDSEncryptionType.Off; } else if (server == TDSPreLoginTokenEncryptionType.Off) { // We encrypt only login packet return TDSEncryptionType.LoginOnly; } } else if (client == TDSPreLoginTokenEncryptionType.On) { // Check server if (server == TDSPreLoginTokenEncryptionType.NotSupported || server == TDSPreLoginTokenEncryptionType.Off) { // This is an error case, however existing client stacks treat this as login-only encryption return TDSEncryptionType.LoginOnly; } } // Full encryption is required return TDSEncryptionType.Full; }
/// <summary> /// Generate an encryption response based on the client request and server setting /// </summary> /// <param name="client">A value received from the client</param> /// <param name="server">Configuration of the server</param> public static TDSPreLoginTokenEncryptionType GetEncryptionResponse(TDSPreLoginTokenEncryptionType client, TDSPreLoginTokenEncryptionType server) { // Check each equivalence class if (client == TDSPreLoginTokenEncryptionType.NotSupported) { // Check server response if (server == TDSPreLoginTokenEncryptionType.Off || server == TDSPreLoginTokenEncryptionType.NotSupported) { return TDSPreLoginTokenEncryptionType.NotSupported; } else { return TDSPreLoginTokenEncryptionType.Required; } } else if (client == TDSPreLoginTokenEncryptionType.Off) { // Check corresponding server if (server == TDSPreLoginTokenEncryptionType.NotSupported) { return TDSPreLoginTokenEncryptionType.NotSupported; } else if (server == TDSPreLoginTokenEncryptionType.Off) { return TDSPreLoginTokenEncryptionType.Off; } else { return TDSPreLoginTokenEncryptionType.Required; } } else if (client == TDSPreLoginTokenEncryptionType.On) { // Check server if (server == TDSPreLoginTokenEncryptionType.Off || server == TDSPreLoginTokenEncryptionType.On || server == TDSPreLoginTokenEncryptionType.Required) { return TDSPreLoginTokenEncryptionType.On; } else { throw new ArgumentException("Server is configured to not support encryption", "server"); } } // This case is not documented so pick a default return TDSPreLoginTokenEncryptionType.Off; }