Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connection Failure with MSSQL: Special Character Password #333

Open
keithmss opened this issue Mar 1, 2024 · 3 comments
Open

Connection Failure with MSSQL: Special Character Password #333

keithmss opened this issue Mar 1, 2024 · 3 comments

Comments

@keithmss
Copy link

keithmss commented Mar 1, 2024

Summary

I'm encountering a connection issue when attempting to tiberius to connect to a Microsoft SQL Server. This issue does not arise when connecting via php or sqlcmd with the same credentials.

Detailed Description

I have successfully connected to the MSSQL server using both php and sqlcmd commands, indicating that the server is accessible and the credentials are correct. The connection details include a password that contains the special character $ followed by numbers, which I suspect might be related to the issue. Here are examples of the successful connection attempts for reference:

  • Using sqlcmd:
sqlcmd -S "sql.foo.com,999" -d "Database" -u "User" -P "Password`$1337"
  • Using php:
// PHP 7.2, ODBC 17
$conn=odbc_connect(Server=sql.foo.com,999;Database=Database","User","Password$1337");

However, attempting the same connection using this library:

use anyhow::Result;
use tiberius::Client;
use tiberius::Config;
use tokio::net::TcpStream;
use tokio_util::compat::TokioAsyncWriteCompatExt;

const CONNECTION_STRING: &str = r"Server=sql.foo.com,999;Database=Database;UID='User';PWD='Password$1337'";

#[tokio::main]
async fn main() -> Result<()> {
    let mut config = Config::from_ado_string(CONNECTION_STRING)?;
    config.trust_cert();
    let tcp = TcpStream::connect(config.get_addr()).await?;
    tcp.set_nodelay(true)?;
    let _ = Client::connect(config, tcp.compat_write()).await?;
    Ok(())
}

Fails with the following error message:

Error: Token error: 'Login failed for user 'User'.' on server SERVER executing  on line 1 (code: 18456, state: 1, class: 14)

Environment

Server: Microsoft SQL Server 2019 (RTM-CU19) (KB5023049 - 15.0.4298.1 (X64))

Issue Analysis

The error suggests a login failure, which is peculiar given that the same credentials work with other methods. The inclusion of a special character in the password and its handling within the Rust environment might be contributing factors but I'm not sure.

@janpio
Copy link
Member

janpio commented Mar 1, 2024

Does it work if you urlencode the special character?

@keithmss
Copy link
Author

keithmss commented Mar 1, 2024

By hand:

use anyhow::Result;
use tiberius::Client;
use tiberius::Config;
use tokio::net::TcpStream;
use tokio_util::compat::TokioAsyncWriteCompatExt;

const CONNECTION_STRING: &str = r"Server=sql.foo.com,999;Database=Database;UID='User';PWD='Password%241337'";

#[tokio::main]
async fn main() -> Result<()> {
    let mut config = Config::from_ado_string(CONNECTION_STRING)?;
    config.trust_cert();
    let tcp = TcpStream::connect(config.get_addr()).await?;
    tcp.set_nodelay(true)?;
    let _ = Client::connect(config, tcp.compat_write()).await?;
    Ok(())
}

It does not.

@keithmss
Copy link
Author

keithmss commented Mar 1, 2024

Update: By using wireshark and setting encryption to NotSupported I can confirm that the login packet contains the correct password. I can't compare packets because SqlCmd does encrypt the login.

What is interesting is that SqlCmd uses an older version of the pre login message.

SqlCmd uses version: 0.0.1537
Tiberius uses version: 0.2.3072

Should this be a cause for concern?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants