prisma / tiberius

TDS 7.2+ (Microsoft SQL Server) driver for Rust
Apache License 2.0
311 stars 113 forks source link

TLS handshake stalls #320

Open reenigneEsrever92 opened 8 months ago

reenigneEsrever92 commented 8 months ago

TLSHandshake is awaited even though encryption is advertised as being off - EncryptionLevel::Off

Here is the code:

#[tokio::main]
async fn main() -> Result<(), Error> {
    tracing_subscriber::fmt()
        .with_max_level(Level::TRACE)
        .init();

    let mut config = Config::from_ado_string(
        "server=tcp:localhost,1433;IntegratedSecurity=true;TrustServerCertificate=true",
    )?;

    config.authentication(AuthMethod::sql_server("sa", "PW"));
    // config.encryption(tiberius::EncryptionLevel::NotSupported);

    let tcp = TcpStream::connect(config.get_addr()).await?;
    tcp.set_nodelay(true)?;

    let mut client = Client::connect(config, tcp.compat_write()).await?;

    client.query("SELECT * FROM some_table", &[]).await?;

    Ok(())
}

Yet, still TLS handshake will be performed in this function:

#[cfg(any(
    feature = "rustls",
    feature = "native-tls",
    feature = "vendored-openssl"
))]
async fn tls_handshake(
    self,
    config: &Config,
    encryption: EncryptionLevel,
) -> crate::Result<Self> {
    if encryption != EncryptionLevel::NotSupported {
        event!(Level::INFO, "Performing a TLS handshake");

        let Self {
            transport, context, ..
        } = self;
        let mut stream = match transport.into_inner() {
            MaybeTlsStream::Raw(tcp) => {
                create_tls_stream(config, TlsPreloginWrapper::new(tcp)).await?
            }
            _ => unreachable!(),
        };

        stream.get_mut().handshake_complete();
        event!(Level::INFO, "TLS handshake successful");

        let transport = Framed::new(MaybeTlsStream::Tls(stream), PacketCodec);

        Ok(Self {
            transport,
            context,
            flushed: false,
            buf: BytesMut::new(),
        })
    } else {
        event!(
            Level::WARN,
            "TLS encryption is not enabled. All traffic including the login credentials are not encrypted."
        );

        Ok(self)
    }
}

I'm not sure if this is right!? At least in my case it stalls and never returns from calling create_tls_stream() function on line 450 in tiberius::client::connection.

Here you can see the pre-login message stated encryption level is off:

image
burmecia commented 7 months ago

Using EncryptionLevel::Off will still need to do tls handshake, but only for that. If the server doesn't support tls, this will block. So to use EncryptionLevel::NotSupported might be better choice, it will fully disable tls including handshake.