Channel binding support in tokio-postgres
This commit is contained in:
parent
705ef7d5b2
commit
6edab70b0e
@ -11,7 +11,7 @@ extern crate tokio;
|
||||
use bytes::{Buf, BufMut};
|
||||
use futures::{Future, IntoFuture, Poll};
|
||||
use openssl::error::ErrorStack;
|
||||
use openssl::ssl::{ConnectConfiguration, SslConnector, SslMethod};
|
||||
use openssl::ssl::{ConnectConfiguration, SslConnector, SslMethod, SslRef};
|
||||
use std::error::Error;
|
||||
use std::io::{self, Read, Write};
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
@ -124,4 +124,18 @@ impl AsyncWrite for SslStream {
|
||||
}
|
||||
}
|
||||
|
||||
impl TlsStream for SslStream {}
|
||||
impl TlsStream for SslStream {
|
||||
fn tls_unique(&self) -> Option<Vec<u8>> {
|
||||
let f = if self.0.get_ref().ssl().session_reused() {
|
||||
SslRef::peer_finished
|
||||
} else {
|
||||
SslRef::finished
|
||||
};
|
||||
|
||||
let len = f(self.0.get_ref().ssl(), &mut []);
|
||||
let mut buf = vec![0; len];
|
||||
f(self.0.get_ref().ssl(), &mut buf);
|
||||
|
||||
Some(buf)
|
||||
}
|
||||
}
|
||||
|
@ -263,25 +263,49 @@ impl PollHandshake for Handshake {
|
||||
let pass = state.user.password().ok_or_else(missing_password)?;
|
||||
|
||||
let mut has_scram = false;
|
||||
let mut has_scram_plus = false;
|
||||
let mut mechanisms = body.mechanisms();
|
||||
while let Some(mechanism) = mechanisms.next()? {
|
||||
match mechanism {
|
||||
sasl::SCRAM_SHA_256 => has_scram = true,
|
||||
sasl::SCRAM_SHA_256_PLUS => has_scram_plus = true,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
let channel_binding = state
|
||||
.stream
|
||||
.get_ref()
|
||||
.tls_unique()
|
||||
.map(ChannelBinding::tls_unique)
|
||||
.or_else(|| {
|
||||
state
|
||||
.stream
|
||||
.get_ref()
|
||||
.tls_server_end_point()
|
||||
.map(ChannelBinding::tls_server_end_point)
|
||||
});
|
||||
|
||||
if !has_scram {
|
||||
let (channel_binding, mechanism) = if has_scram_plus {
|
||||
match channel_binding {
|
||||
Some(channel_binding) => (channel_binding, sasl::SCRAM_SHA_256_PLUS),
|
||||
None => (ChannelBinding::unsupported(), sasl::SCRAM_SHA_256),
|
||||
}
|
||||
} else if has_scram {
|
||||
match channel_binding {
|
||||
Some(_) => (ChannelBinding::unrequested(), sasl::SCRAM_SHA_256),
|
||||
None => (ChannelBinding::unsupported(), sasl::SCRAM_SHA_256),
|
||||
}
|
||||
} else {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"unsupported SASL authentication",
|
||||
).into());
|
||||
}
|
||||
};
|
||||
|
||||
let mut scram = ScramSha256::new(pass.as_bytes(), ChannelBinding::unsupported())?;
|
||||
let mut scram = ScramSha256::new(pass.as_bytes(), channel_binding)?;
|
||||
|
||||
let mut buf = vec![];
|
||||
frontend::sasl_initial_response(sasl::SCRAM_SHA_256, scram.message(), &mut buf)?;
|
||||
frontend::sasl_initial_response(mechanism, scram.message(), &mut buf)?;
|
||||
|
||||
transition!(SendingSasl {
|
||||
future: state.stream.send(buf),
|
||||
|
@ -58,6 +58,26 @@ pub trait TlsConnect {
|
||||
) -> Box<Future<Item = Box<TlsStream>, Error = Box<Error + Sync + Send>> + Sync + Send>;
|
||||
}
|
||||
|
||||
pub trait TlsStream: 'static + Sync + Send + AsyncRead + AsyncWrite {}
|
||||
pub trait TlsStream: 'static + Sync + Send + AsyncRead + AsyncWrite {
|
||||
/// Returns the data associated with the `tls-unique` channel binding type as described in
|
||||
/// [RFC 5929], if supported.
|
||||
///
|
||||
/// An implementation only needs to support one of this or `tls_server_end_point`.
|
||||
///
|
||||
/// [RFC 5929]: https://tools.ietf.org/html/rfc5929
|
||||
fn tls_unique(&self) -> Option<Vec<u8>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the data associated with the `tls-server-end-point` channel binding type as
|
||||
/// described in [RFC 5929], if supported.
|
||||
///
|
||||
/// An implementation only needs to support one of this or `tls_unique`.
|
||||
///
|
||||
/// [RFC 5929]: https://tools.ietf.org/html/rfc5929
|
||||
fn tls_server_end_point(&self) -> Option<Vec<u8>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl TlsStream for proto::Socket {}
|
||||
|
Loading…
Reference in New Issue
Block a user