예제 #1
0
        private SNIErrorDetails GetSniErrorDetails()
        {
            SNIErrorDetails details = new SNIErrorDetails();

            if (TdsParserStateObjectFactory.UseManagedSNI)
            {
                SNIError sniError = SNIProxy.Singleton.GetLastError();
                details.sniErrorNumber = sniError.sniError;
                details.errorMessage   = sniError.errorMessage;
                details.nativeError    = sniError.nativeError;
                details.provider       = (int)sniError.provider;
                details.lineNumber     = sniError.lineNumber;
                details.function       = sniError.function;
                details.exception      = sniError.exception;
            }
            else
            {
                SNINativeMethodWrapper.SNI_Error sniError;
                SNINativeMethodWrapper.SNIGetLastError(out sniError);
                details.sniErrorNumber = sniError.sniError;
                details.errorMessage   = sniError.errorMessage;
                details.nativeError    = sniError.nativeError;
                details.provider       = (int)sniError.provider;
                details.lineNumber     = sniError.lineNumber;
                details.function       = sniError.function;
            }
            return(details);
        }
예제 #2
0
        // creates a physical connection
        internal SNIHandle(
            SNINativeMethodWrapper.ConsumerInfo myInfo,
            string serverName,
            byte[] spnBuffer,
            bool ignoreSniOpenTimeout,
            int timeout,
            out byte[] instanceName,
            bool flushCache,
            bool fSync,
            bool fParallel,
            TransparentNetworkResolutionState transparentNetworkResolutionState,
            int totalTimeout)
            : base(IntPtr.Zero, true)
        {
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            { }
            finally
            {
                _fSync       = fSync;
                instanceName = new byte[256]; // Size as specified by netlibs.
                if (ignoreSniOpenTimeout)
                {
                    // UNDONE: ITEM12001110 (DB Mirroring Reconnect) Old behavior of not truly honoring timeout presevered
                    //  for non-failover scenarios to avoid breaking changes as part of a QFE.  Consider fixing timeout
                    //  handling in next full release and removing ignoreSniOpenTimeout parameter.
                    timeout = Timeout.Infinite; // -1 == native SNIOPEN_TIMEOUT_VALUE / INFINITE
                }

                int transparentNetworkResolutionStateNo = (int)transparentNetworkResolutionState;
                _status = SNINativeMethodWrapper.SNIOpenSyncEx(myInfo, serverName, ref base.handle,
                                                               spnBuffer, instanceName, flushCache, fSync, timeout, fParallel, transparentNetworkResolutionStateNo, totalTimeout,
                                                               ADP.IsAzureSqlServerEndpoint(serverName));
            }
        }
예제 #3
0
 // constructs SNI Handle for MARS session
 internal SNIHandle(SNINativeMethodWrapper.ConsumerInfo myInfo, SNIHandle parent) : base(IntPtr.Zero, true)
 {
     RuntimeHelpers.PrepareConstrainedRegions();
     try {} finally {
         _status = SNINativeMethodWrapper.SNIOpenMarsSession(myInfo, parent, ref base.handle, parent._fSync);
     }
 }
예제 #4
0
        private SNILoadHandle() : base(IntPtr.Zero, true)
        {
            // From security review - SafeHandle guarantees this is only called once.
            // The reason for the safehandle is guaranteed initialization and termination of SNI to
            // ensure SNI terminates and cleans up properly.
            try
            { }
            finally
            {
                _sniStatus = SNINativeMethodWrapper.SNIInitialize();

                uint value = 0;

                // VSDevDiv 479597: If initialize fails, don't call QueryInfo.
                if (TdsEnums.SNI_SUCCESS == _sniStatus)
                {
                    // Query OS to find out whether encryption is supported.
                    SNINativeMethodWrapper.SNIQueryInfo(SNINativeMethodWrapper.QTypes.SNI_QUERY_CLIENT_ENCRYPT_POSSIBLE, ref value);
                }

                _encryptionOption = (value == 0) ? EncryptionOptions.NOT_SUP : EncryptionOptions.OFF;

                base.handle = (IntPtr)1; // Initialize to non-zero dummy variable.
            }
        }
        protected override void OnEventCommand(EventCommandEventArgs e)
        {
            // Internally, EventListener.EnableEvents sends an event command, with a reserved value of 0, -2, or -3.
            // When a command is sent via EnableEvents or SendCommand, check if it is a user-defined value
            // to enable or disable event tracing in sni.dll.
            // If registration fails, all write and unregister commands will be a no-op.

            // If managed networking is enabled, don't call native wrapper methods
#if netcoreapp
            if (AppContext.TryGetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", out bool isEnabled) && isEnabled)
            {
                return;
            }
#endif
            // Only register the provider if it's not already registered. Registering a provider that is already
            // registered can lead to unpredictable behaviour.
            if (!_traceLoggingProviderEnabled && e.Command > 0 && (e.Command & (SNINativeTrace | SNINativeScope)) != 0)
            {
                int eventKeyword = (int)(e.Command & (SNINativeTrace | SNINativeScope));
                _traceLoggingProviderEnabled = SNINativeMethodWrapper.RegisterTraceProvider(eventKeyword);
                Debug.Assert(_traceLoggingProviderEnabled, "Failed to enable TraceLogging provider.");
            }
            else if (_traceLoggingProviderEnabled && (e.Command == SNINativeDisable))
            {
                // Only unregister the provider if it's currently registered.
                SNINativeMethodWrapper.UnregisterTraceProvider();
                _traceLoggingProviderEnabled = false;
            }
        }
예제 #6
0
        // creates a physical connection
        internal SNIHandle(
            SNINativeMethodWrapper.ConsumerInfo myInfo,
            string serverName,
            byte[] spnBuffer,
            bool ignoreSniOpenTimeout,
            int timeout,
            out byte[] instanceName,
            bool flushCache,
            bool fSync,
            bool fParallel)
            : base(IntPtr.Zero, true)
        {
            try { }
            finally
            {
                _fSync       = fSync;
                instanceName = new byte[256]; // Size as specified by netlibs.
                if (ignoreSniOpenTimeout)
                {
                    timeout = Timeout.Infinite; // -1 == native SNIOPEN_TIMEOUT_VALUE / INFINITE
                }

                _status = SNINativeMethodWrapper.SNIOpenSyncEx(myInfo, serverName, ref base.handle,
                                                               spnBuffer, instanceName, flushCache, fSync, timeout, fParallel);
            }
        }
예제 #7
0
        private void LoadSSPILibrary()
        {
            if (TdsParserStateObjectFactory.UseManagedSNI)
            {
                return;
            }
            // Outer check so we don't acquire lock once it's loaded.
            if (!s_fSSPILoaded)
            {
                lock (s_tdsParserLock)
                {
                    // re-check inside lock
                    if (!s_fSSPILoaded)
                    {
                        // use local for ref param to defer setting s_maxSSPILength until we know the call succeeded.
                        uint maxLength = 0;

                        if (0 != SNINativeMethodWrapper.SNISecInitPackage(ref maxLength))
                        {
                            SSPIError(SQLMessage.SSPIInitializeError(), TdsEnums.INIT_SSPI_PACKAGE);
                        }

                        s_maxSSPILength = maxLength;
                        s_fSSPILoaded   = true;
                    }
                }
            }

            if (s_maxSSPILength > int.MaxValue)
            {
                throw SQL.InvalidSSPIPacketSize();   // SqlBu 332503
            }
        }
 internal SNIPacket(SafeHandle sniHandle) : base(IntPtr.Zero, true)
 {
     SNINativeMethodWrapper.SNIPacketAllocate(sniHandle, SNINativeMethodWrapper.IOType.WRITE, ref base.handle);
     if (IntPtr.Zero == base.handle)
     {
         throw SQL.SNIPacketAllocationFailure();
     }
 }
예제 #9
0
 // constructs SNI Handle for MARS session
 internal SNIHandle(SNINativeMethodWrapper.ConsumerInfo myInfo, SNIHandle parent) : base(IntPtr.Zero, true)
 {
     try { }
     finally
     {
         _status = SNINativeMethodWrapper.SNIOpenMarsSession(myInfo, parent, ref base.handle, parent._fSync);
     }
 }
예제 #10
0
 // constructs SNI Handle for MARS session
 internal SNIHandle(SNINativeMethodWrapper.ConsumerInfo myInfo, SNIHandle parent, SqlConnectionIPAddressPreference ipPreference, SQLDNSInfo cachedDNSInfo) : base(IntPtr.Zero, true)
 {
     try
     { }
     finally
     {
         _status = SNINativeMethodWrapper.SNIOpenMarsSession(myInfo, parent, ref base.handle, parent._fSync, ipPreference, cachedDNSInfo);
     }
 }
예제 #11
0
 override protected bool ReleaseHandle()
 {
     // NOTE: The SafeHandle class guarantees this will be called exactly once.
     IntPtr ptr = base.handle;
     base.handle = IntPtr.Zero;
     if (IntPtr.Zero != ptr)
     {
         SNINativeMethodWrapper.SNIPacketRelease(ptr);
     }
     return true;
 }
        internal override PacketHandle ReadSyncOverAsync(int timeoutRemaining, out uint error)
        {
            SNIHandle handle = Handle;

            if (handle == null)
            {
                throw ADP.ClosedConnectionError();
            }
            IntPtr readPacketPtr = IntPtr.Zero;

            error = SNINativeMethodWrapper.SNIReadSyncOverAsync(handle, ref readPacketPtr, GetTimeoutRemaining());
            return(PacketHandle.FromNativePointer(readPacketPtr));
        }
 private SNILoadHandle() : base(IntPtr.Zero, true)
 {
     // From security review - SafeHandle guarantees this is only called once.
     // The reason for the safehandle is guaranteed initialization and termination of SNI to
     // ensure SNI terminates and cleans up properly.
     try
     { }
     finally
     {
         _sniStatus  = SNINativeMethodWrapper.SNIInitialize();
         base.handle = (IntPtr)1; // Initialize to non-zero dummy variable.
     }
 }
        override protected bool ReleaseHandle()
        {
            if (base.handle != IntPtr.Zero)
            {
                if (TdsEnums.SNI_SUCCESS == _sniStatus)
                {
                    LocalDBAPI.ReleaseDLLHandles();
                    SNINativeMethodWrapper.SNITerminate();
                }
                base.handle = IntPtr.Zero;
            }

            return(true);
        }
예제 #15
0
 override protected bool ReleaseHandle()
 {
     // NOTE: The SafeHandle class guarantees this will be called exactly once.
     IntPtr ptr = base.handle;
     base.handle = IntPtr.Zero;
     if (IntPtr.Zero != ptr)
     {
         if (0 != SNINativeMethodWrapper.SNIClose(ptr))
         {
             return false;   // SNIClose should never fail.
         }
     }
     return true;
 }
예제 #16
0
        internal override void AssignPendingDNSInfo(string userProtocol, string DNSCacheKey, ref SQLDNSInfo pendingDNSInfo)
        {
            uint      result;
            ushort    portFromSNI     = 0;
            string    IPStringFromSNI = string.Empty;
            IPAddress IPFromSNI;

            _parser.isTcpProtocol = false;
            SNINativeMethodWrapper.ProviderEnum providerNumber = SNINativeMethodWrapper.ProviderEnum.INVALID_PROV;

            if (string.IsNullOrEmpty(userProtocol))
            {
                result = SNINativeMethodWrapper.SniGetProviderNumber(Handle, ref providerNumber);
                Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetProviderNumber");
                _parser.isTcpProtocol = (providerNumber == SNINativeMethodWrapper.ProviderEnum.TCP_PROV);
            }
            else if (userProtocol == TdsEnums.TCP)
            {
                _parser.isTcpProtocol = true;
            }

            // serverInfo.UserProtocol could be empty
            if (_parser.isTcpProtocol)
            {
                result = SNINativeMethodWrapper.SniGetConnectionPort(Handle, ref portFromSNI);
                Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetConnectionPort");


                result = SNINativeMethodWrapper.SniGetConnectionIPString(Handle, ref IPStringFromSNI);
                Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetConnectionIPString");

                pendingDNSInfo = new SQLDNSInfo(DNSCacheKey, null, null, portFromSNI.ToString());

                if (IPAddress.TryParse(IPStringFromSNI, out IPFromSNI))
                {
                    if (System.Net.Sockets.AddressFamily.InterNetwork == IPFromSNI.AddressFamily)
                    {
                        pendingDNSInfo.AddrIPv4 = IPStringFromSNI;
                    }
                    else if (System.Net.Sockets.AddressFamily.InterNetworkV6 == IPFromSNI.AddressFamily)
                    {
                        pendingDNSInfo.AddrIPv6 = IPStringFromSNI;
                    }
                }
            }
            else
            {
                pendingDNSInfo = null;
            }
        }
예제 #17
0
 public SNIPacket Take(SNIHandle sniHandle)
 {
     SNIPacket packet;
     if (_packets.Count > 0)
     {
         // Success - reset the packet
         packet = _packets.Pop();
         SNINativeMethodWrapper.SNIPacketReset(sniHandle, SNINativeMethodWrapper.IOType.WRITE, packet, SNINativeMethodWrapper.ConsumerNumber.SNI_Consumer_SNI);
     }
     else
     {
         // Failed to take a packet - create a new one
         packet = new SNIPacket(sniHandle);
     }
     return packet;
 }
 protected override uint SNIPacketGetData(PacketHandle packet, byte[] _inBuff, ref uint dataSize)
 {
     Debug.Assert(packet.Type == PacketHandle.NativePointerType, "unexpected packet type when requiring NativePointer");
     return(SNINativeMethodWrapper.SNIPacketGetData(packet.NativePointer, _inBuff, ref dataSize));
 }