Fix passwords not being percent decoded

The password portion of the `Url` type is post-percent encoding
and needs to be manually decoded before processing and being
sent to the server.
This commit is contained in:
Wesley Norris 2020-01-21 18:53:07 -05:00
parent d26040f675
commit 1461891901
5 changed files with 21 additions and 7 deletions

1
Cargo.lock generated
View file

@ -1388,6 +1388,7 @@ dependencies = [
"md-5 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-bigint 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -42,6 +42,7 @@ log = { version = "0.4.8", default-features = false }
md-5 = { version = "0.8.0", default-features = false, optional = true }
memchr = { version = "2.3.0", default-features = false }
num-bigint = { version = "0.2.5", default-features = false, optional = true, features = [ "std" ] }
percent-encoding = "2.1.0"
rand = { version = "0.7.3", default-features = false, optional = true, features = [ "std" ] }
sha-1 = { version = "0.8.2", default-features = false, optional = true }
sha2 = { version = "0.8.1", default-features = false, optional = true }

View file

@ -555,7 +555,7 @@ impl MySqlConnection {
let auth_response = self_
.make_auth_initial_response(
&handshake.auth_plugin,
password,
&password,
&handshake.auth_plugin_data,
)
.await?;
@ -569,7 +569,7 @@ impl MySqlConnection {
self_
.receive_auth_ok(
&handshake.auth_plugin,
password,
&password,
&handshake.auth_plugin_data,
)
.await?;

View file

@ -177,7 +177,7 @@ impl PgConnection {
protocol::Authentication::ClearTextPassword => {
protocol::PasswordMessage::ClearText(
url.password().unwrap_or_default(),
&url.password().unwrap_or_default(),
)
.encode(self.stream.buffer_mut());
@ -186,7 +186,7 @@ impl PgConnection {
protocol::Authentication::Md5Password { salt } => {
protocol::PasswordMessage::Md5 {
password: url.password().unwrap_or_default(),
password: &url.password().unwrap_or_default(),
user: username,
salt,
}
@ -217,7 +217,7 @@ impl PgConnection {
if has_sasl || has_sasl_plus {
// TODO: Handle -PLUS differently if we're in a TLS stream
sasl_auth(self, username, url.password().unwrap_or_default())
sasl_auth(self, username, &url.password().unwrap_or_default())
.await?;
} else {
return Err(protocol_err!(

View file

@ -52,8 +52,20 @@ impl Url {
}
}
pub fn password(&self) -> Option<&str> {
self.0.password()
pub fn password(&self) -> Option<Cow<str>> {
match self.0.password() {
Some(s) => {
let decoded = percent_encoding::percent_decode_str(s);
// FIXME: Handle error
Some(
decoded
.decode_utf8()
.expect("percent-encoded password contained non-UTF-8 bytes"),
)
}
None => None,
}
}
pub fn database(&self) -> Option<&str> {