mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-10-04 00:05:27 +00:00
Indicate that we support both forms of SCRAM (just always reject channel binding for now)
This commit is contained in:
parent
4f28590def
commit
c4a0ac50df
@ -7,13 +7,16 @@ use futures_core::future::BoxFuture;
|
|||||||
use crate::cache::StatementCache;
|
use crate::cache::StatementCache;
|
||||||
use crate::connection::Connection;
|
use crate::connection::Connection;
|
||||||
use crate::io::{Buf, BufStream};
|
use crate::io::{Buf, BufStream};
|
||||||
use crate::postgres::protocol::{self, Decode, Encode, Message, StatementId, SaslResponse, SaslInitialResponse, hi, Authentication};
|
use crate::postgres::protocol::{
|
||||||
|
self, hi, Authentication, Decode, Encode, Message, SaslInitialResponse, SaslResponse,
|
||||||
|
StatementId,
|
||||||
|
};
|
||||||
use crate::postgres::PgError;
|
use crate::postgres::PgError;
|
||||||
use crate::url::Url;
|
use crate::url::Url;
|
||||||
use sha2::{Sha256, Digest};
|
|
||||||
use hmac::{Mac, Hmac};
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
use hmac::{Hmac, Mac};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
/// An asynchronous connection to a [Postgres] database.
|
/// An asynchronous connection to a [Postgres] database.
|
||||||
///
|
///
|
||||||
@ -97,20 +100,35 @@ impl PgConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protocol::Authentication::Sasl { mechanisms } => {
|
protocol::Authentication::Sasl { mechanisms } => {
|
||||||
match mechanisms.get(0).map(|m| &**m) {
|
let mut has_sasl: bool = false;
|
||||||
Some("SCRAM-SHA-256") => {
|
let mut has_sasl_plus: bool = false;
|
||||||
sasl_auth(
|
|
||||||
self,
|
|
||||||
username,
|
|
||||||
url.password().unwrap_or_default(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => return Err(protocol_err!(
|
for mechanism in &*mechanisms {
|
||||||
"Expected mechanisms SCRAM-SHA-256, but received {:?}",
|
match &**mechanism {
|
||||||
|
"SCRAM-SHA-256" => {
|
||||||
|
has_sasl = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
"SCRAM-SHA-256-PLUS" => {
|
||||||
|
has_sasl_plus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
log::info!("unsupported auth mechanism: {}", mechanism);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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())
|
||||||
|
.await?;
|
||||||
|
} else {
|
||||||
|
return Err(protocol_err!(
|
||||||
|
"unsupported SASL auth mechanisms: {:?}",
|
||||||
mechanisms
|
mechanisms
|
||||||
).into()),
|
)
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,11 +306,7 @@ fn nonce() -> String {
|
|||||||
|
|
||||||
// Performs authenticiton using Simple Authentication Security Layer (SASL) which is what
|
// Performs authenticiton using Simple Authentication Security Layer (SASL) which is what
|
||||||
// Postgres uses
|
// Postgres uses
|
||||||
async fn sasl_auth<T: AsRef<str>>(
|
async fn sasl_auth<T: AsRef<str>>(conn: &mut PgConnection, username: T, password: T) -> Result<()> {
|
||||||
conn: &mut PgConnection,
|
|
||||||
username: T,
|
|
||||||
password: T,
|
|
||||||
) -> Result<()> {
|
|
||||||
// channel-binding = "c=" base64
|
// channel-binding = "c=" base64
|
||||||
let channel_binding = format!("{}={}", CHANNEL_ATTR, base64::encode(GS2_HEADER));
|
let channel_binding = format!("{}={}", CHANNEL_ATTR, base64::encode(GS2_HEADER));
|
||||||
// "n=" saslname ;; Usernames are prepared using SASLprep.
|
// "n=" saslname ;; Usernames are prepared using SASLprep.
|
||||||
@ -308,8 +322,7 @@ async fn sasl_auth<T: AsRef<str>>(
|
|||||||
client_first_message_bare = client_first_message_bare
|
client_first_message_bare = client_first_message_bare
|
||||||
);
|
);
|
||||||
|
|
||||||
SaslInitialResponse(&client_first_message)
|
SaslInitialResponse(&client_first_message).encode(conn.stream.buffer_mut());
|
||||||
.encode(conn.stream.buffer_mut());
|
|
||||||
conn.stream.flush().await?;
|
conn.stream.flush().await?;
|
||||||
|
|
||||||
let server_first_message = conn.receive().await?;
|
let server_first_message = conn.receive().await?;
|
||||||
@ -379,8 +392,7 @@ async fn sasl_auth<T: AsRef<str>>(
|
|||||||
client_proof = base64::encode(&client_proof)
|
client_proof = base64::encode(&client_proof)
|
||||||
);
|
);
|
||||||
|
|
||||||
SaslResponse(&client_final_message)
|
SaslResponse(&client_final_message).encode(conn.stream.buffer_mut());
|
||||||
.encode(conn.stream.buffer_mut());
|
|
||||||
conn.stream.flush().await?;
|
conn.stream.flush().await?;
|
||||||
let _server_final_response = conn.receive().await?;
|
let _server_final_response = conn.receive().await?;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user