Update to upstream changes and polish SSL API

Also several debug messages were added for debugging SSL connections.

Signed-off-by: Sayan Nandan <nandansayan@outlook.com>
next
Sayan Nandan 4 years ago
parent 07b9985732
commit d84234724d
No known key found for this signature in database
GPG Key ID: C31EFD7DDA12AEE0

160
Cargo.lock generated

@ -71,9 +71,9 @@ checksum = "e0dcbc35f504eb6fc275a6d20e4ebcda18cf50d40ba6fabff8c711fa16cb3b16"
[[package]]
name = "bytes"
version = "1.0.0"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad1f8e949d755f9d79112b5bb46938e0ef9d3804a0b16dfab13aafcaa5f0fa72"
checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
[[package]]
name = "cc"
@ -277,6 +277,17 @@ dependencies = [
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4060f4657be78b8e766215b02b18a2e862d83745545de804638e2b545e81aee6"
dependencies = [
"cfg-if 1.0.0",
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
]
[[package]]
name = "hermit-abi"
version = "0.1.15"
@ -357,9 +368,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.11"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
checksum = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2"
dependencies = [
"cfg-if 0.1.10",
]
@ -567,9 +578,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.7"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
dependencies = [
"proc-macro2",
]
@ -580,11 +591,23 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom",
"getrandom 0.1.15",
"libc",
"rand_chacha 0.2.2",
"rand_core 0.5.1",
"rand_hc 0.2.0",
]
[[package]]
name = "rand"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c24fcd450d3fa2b592732565aa4f17a27a61c65ece4726353e000939b0edee34"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
"rand_chacha 0.3.0",
"rand_core 0.6.1",
"rand_hc 0.3.0",
]
[[package]]
@ -594,7 +617,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.5.1",
]
[[package]]
name = "rand_chacha"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
dependencies = [
"ppv-lite86",
"rand_core 0.6.1",
]
[[package]]
@ -603,7 +636,16 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom",
"getrandom 0.1.15",
]
[[package]]
name = "rand_core"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c026d7df8b298d90ccbbc5190bd04d85e159eaf5576caeacf8741da93ccbd2e5"
dependencies = [
"getrandom 0.2.1",
]
[[package]]
@ -612,7 +654,16 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core",
"rand_core 0.5.1",
]
[[package]]
name = "rand_hc"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
dependencies = [
"rand_core 0.6.1",
]
[[package]]
@ -653,18 +704,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "1.0.118"
version = "1.0.119"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800"
checksum = "9bdd36f49e35b61d49efd8aa7fc068fd295961fd2286d0b2ee9a4c7a14e99cc3"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.118"
version = "1.0.119"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df"
checksum = "552954ce79a059ddd5fd68c271592374bd15cab2274970380c000118aeffe1cd"
dependencies = [
"proc-macro2",
"quote",
@ -724,9 +775,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "syn"
version = "1.0.54"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5"
dependencies = [
"proc-macro2",
"quote",
@ -738,10 +789,11 @@ name = "tdb"
version = "0.5.0"
dependencies = [
"bincode",
"bytes 0.6.0",
"bytes 1.0.1",
"chrono",
"clap",
"env_logger",
"futures",
"jemallocator",
"lazy_static",
"libtdb",
@ -753,8 +805,8 @@ dependencies = [
"serde",
"serde_derive",
"tdb_macros",
"tokio 0.3.6",
"tokio-openssl 0.5.0",
"tokio",
"tokio-openssl",
"toml",
]
@ -765,7 +817,7 @@ dependencies = [
"clap",
"devtimer",
"libtdb",
"rand",
"rand 0.7.3",
"serde",
"serde_json",
]
@ -776,7 +828,7 @@ version = "0.2.2"
dependencies = [
"proc-macro2",
"quote",
"rand",
"rand 0.8.1",
"syn",
]
@ -818,28 +870,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "tokio"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "720ba21c25078711bf456d607987d95bce90f7c3bea5abe1db587862e7a1e87c"
dependencies = [
"autocfg",
"bytes 0.6.0",
"futures-core",
"libc",
"memchr",
"mio",
"num_cpus",
"once_cell",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"slab",
"tokio-macros 0.3.1",
"winapi",
]
[[package]]
name = "tokio"
version = "1.0.1"
@ -847,7 +877,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d258221f566b6c803c7b4714abadc080172b272090cdc5e244a6d4dd13c3a6bd"
dependencies = [
"autocfg",
"bytes 1.0.0",
"bytes 1.0.1",
"libc",
"memchr",
"mio",
@ -856,21 +886,10 @@ dependencies = [
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"tokio-macros 1.0.0",
"tokio-macros",
"winapi",
]
[[package]]
name = "tokio-macros"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21d30fdbb5dc2d8f91049691aa1a9d4d4ae422a21c334ce8936e5886d30c5c45"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-macros"
version = "1.0.0"
@ -882,17 +901,6 @@ dependencies = [
"syn",
]
[[package]]
name = "tokio-openssl"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d01e5cc2d3a154fa310982d0affaec8140d6476805422265b2f648eb813f937f"
dependencies = [
"openssl",
"openssl-sys",
"tokio 0.3.6",
]
[[package]]
name = "tokio-openssl"
version = "0.6.1"
@ -902,14 +910,14 @@ dependencies = [
"futures",
"openssl",
"pin-project",
"tokio 1.0.1",
"tokio",
]
[[package]]
name = "toml"
version = "0.5.7"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645"
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
dependencies = [
"serde",
]
@ -918,14 +926,14 @@ dependencies = [
name = "tsh"
version = "0.5.0"
dependencies = [
"bytes 1.0.0",
"bytes 1.0.1",
"clap",
"lazy_static",
"libtdb",
"openssl",
"regex",
"tokio 1.0.1",
"tokio-openssl 0.6.1",
"tokio",
"tokio-openssl",
]
[[package]]

@ -9,7 +9,7 @@ edition = "2018"
[dependencies]
libtdb = {path = "../libtdb"}
tokio = {version = "1.0.1", features = ["full"]}
bytes = "1.0.0"
bytes = "1.0.1"
regex = "1.4.3"
lazy_static = "1.4.0"
clap = {version = "2.33.3", features=["yaml"]}

@ -40,7 +40,6 @@ pub async fn start_repl() {
Some(h) => h.to_owned(),
None => ADDR.to_owned(),
};
let domain = host.clone();
host.push(':');
match matches.value_of("port") {
Some(p) => match p.parse::<u16>() {
@ -52,8 +51,9 @@ pub async fn start_repl() {
},
None => host.push_str("2003"),
}
let mut con = if let Some(sslcert) = matches.value_of("cert") {
let con = match SslConnection::new(&domain, &host, sslcert).await {
let ssl = matches.value_of("cert");
let mut con = if let Some(sslcert) = ssl {
let con = match SslConnection::new(&host, sslcert).await {
Ok(c) => c,
Err(e) => {
eprintln!("ERROR: {}", e);

@ -26,7 +26,8 @@ use lazy_static::lazy_static;
use libtdb::terrapipe;
use libtdb::TResult;
use libtdb::BUF_CAP;
use openssl::ssl::SslConnector;
use openssl::ssl::Ssl;
use openssl::ssl::SslContext;
use openssl::ssl::SslMethod;
use regex::Regex;
use std::pin::Pin;
@ -94,10 +95,6 @@ impl Connection {
return;
}
}
println!(
"The server returned: {}",
String::from_utf8_lossy(&self.buffer)
);
match self.try_response().await {
ClientResult::Empty(f) => {
self.buffer.advance(f);
@ -144,10 +141,10 @@ pub struct SslConnection {
impl SslConnection {
/// Create a new connection, creating a connection to `host`
pub async fn new(domain: &str, host: &str, sslcert: &str) -> TResult<Self> {
let mut connector = SslConnector::builder(SslMethod::tls())?;
connector.set_ca_file(sslcert)?;
let ssl = connector.build().configure()?.into_ssl(&domain)?;
pub async fn new(host: &str, sslcert: &str) -> TResult<Self> {
let mut ctx = SslContext::builder(SslMethod::tls_client())?;
ctx.set_ca_file(sslcert)?;
let ssl = Ssl::new(&ctx.build())?;
let stream = TcpStream::connect(host).await?;
let mut stream = SslStream::new(ssl, stream)?;
Pin::new(&mut stream).connect().await.unwrap();
@ -184,10 +181,6 @@ impl SslConnection {
return;
}
}
println!(
"The server returned: {}",
String::from_utf8_lossy(&self.buffer)
);
match self.try_response().await {
ClientResult::Empty(f) => {
self.buffer.advance(f);

@ -7,26 +7,27 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tokio = { version = "0.3.6", features = ["full"] }
bytes = "0.6.0"
tokio = { version = "1.0.1", features = ["full"] }
bytes = "1.0.1"
libtdb = {path ="../libtdb"}
bincode = "1.3.1"
parking_lot = "0.11.1"
lazy_static = "1.4.0"
serde_derive = "1.0.117"
serde = {version = "1.0.118", features= ["derive"]}
toml = "0.5.7"
serde_derive = "1.0.119"
futures = "0.3.9"
serde = {version = "1.0.119", features= ["derive"]}
toml = "0.5.8"
clap = {version = "2.33.3", features=["yaml"]}
env_logger = "0.8.2"
log = "0.4.11"
log = "0.4.13"
chrono = "0.4.19"
regex = "1.4.2"
regex = "1.4.3"
tdb_macros = {path="../tdb-macros"}
tokio-openssl = "0.5.0"
tokio-openssl = "0.6.1"
openssl = { version = "0.10", features = ["vendored"] }
openssl-sys = "0.9.59"
openssl-sys = "0.9.60"
[target.'cfg(not(target_env = "msvc"))'.dependencies]
jemallocator = "0.3.2"
[dev-dependencies]
tokio = { version = "0.3.6", features = ["test-util"] }
tokio = { version = "1.0.1", features = ["test-util"] }

@ -144,7 +144,7 @@ impl Listener {
loop {
// Take the permit first, but we won't use it right now
// that's why we will forget it
self.climit.acquire().await.forget();
self.climit.acquire().await.unwrap().forget();
let stream = self.accept().await?;
let mut chandle = CHandler {
db: self.db.clone(),

@ -30,15 +30,15 @@ use crate::resp::Writable;
use crate::CoreDB;
use bytes::Buf;
use bytes::BytesMut;
use futures::future;
use libtdb::TResult;
use libtdb::BUF_CAP;
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
use openssl::ssl::{Ssl, SslAcceptor, SslFiletype, SslMethod};
use std::net::SocketAddr;
use std::pin::Pin;
use std::sync::Arc;
use tokio::io::BufWriter;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpListener;
use tokio::net::TcpStream;
use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt};
use tokio::net::{TcpListener, TcpStream};
use tokio::sync::Semaphore;
use tokio::sync::{broadcast, mpsc};
use tokio::time::{self, Duration};
@ -57,7 +57,7 @@ pub struct SslListener {
// We send a clone of `terminate_tx` to each `CHandler`
pub terminate_tx: mpsc::Sender<()>,
pub terminate_rx: mpsc::Receiver<()>,
acceptor: Arc<SslAcceptor>,
acceptor: SslAcceptor,
}
impl SslListener {
@ -71,10 +71,11 @@ impl SslListener {
terminate_tx: mpsc::Sender<()>,
terminate_rx: mpsc::Receiver<()>,
) -> TResult<Self> {
log::debug!("New SSL/TLS connection registered");
let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls())?;
acceptor.set_private_key_file(key_file, SslFiletype::PEM)?;
acceptor.set_certificate_chain_file(chain_file)?;
let acceptor = Arc::new(acceptor.build());
let acceptor = acceptor.build();
Ok(SslListener {
db,
listener,
@ -86,19 +87,23 @@ impl SslListener {
})
}
async fn accept(&mut self) -> TResult<SslStream<TcpStream>> {
println!("Received connection");
log::debug!("Trying to accept a SSL connection");
let mut backoff = 1;
loop {
match self.listener.accept().await {
// We don't need the bindaddr
// We get the encrypted stream which we need to decrypt
// by using the acceptor
Ok((encrypted_stream, _)) => {
let decrypted_stream =
tokio_openssl::accept(&self.acceptor, encrypted_stream).await?;
return Ok(decrypted_stream);
Ok((stream, _)) => {
log::debug!("Accepted an SSL/TLS connection");
let ssl = Ssl::new(self.acceptor.context())?;
let mut stream = SslStream::new(ssl, stream)?;
Pin::new(&mut stream).accept().await?;
log::debug!("Connected to secure socket over TCP");
return Ok(stream);
}
Err(e) => {
log::debug!("Failed to establish a secure connection");
if backoff > 64 {
// Too many retries, goodbye user
return Err(e.into());
@ -112,10 +117,11 @@ impl SslListener {
}
}
pub async fn run(&mut self) -> TResult<()> {
log::debug!("Started secure server");
loop {
// Take the permit first, but we won't use it right now
// that's why we will forget it
self.climit.acquire().await.forget();
self.climit.acquire().await.unwrap().forget();
let stream = self.accept().await?;
let mut sslhandle = SslConnectionHandler {
db: self.db.clone(),
@ -125,6 +131,7 @@ impl SslListener {
_term_sig_tx: self.terminate_tx.clone(),
};
tokio::spawn(async move {
log::debug!("Spawned listener task");
if let Err(e) = sslhandle.run().await {
eprintln!("Error: {}", e);
}
@ -143,6 +150,7 @@ pub struct SslConnectionHandler {
impl SslConnectionHandler {
pub async fn run(&mut self) -> TResult<()> {
log::debug!("SslConnectionHanler initialized to handle a remote client");
while !self.terminator.is_termination_signal() {
let try_df = tokio::select! {
tdf = self.con.read_query() => tdf,
@ -174,19 +182,19 @@ impl Drop for SslConnectionHandler {
}
pub struct SslConnection {
stream: BufWriter<SslStream<TcpStream>>,
stream: SslStream<TcpStream>,
buffer: BytesMut,
}
impl SslConnection {
pub fn new(stream: SslStream<TcpStream>) -> Self {
SslConnection {
stream: BufWriter::new(stream),
stream: stream,
buffer: BytesMut::with_capacity(BUF_CAP),
}
}
async fn read_again(&mut self) -> Result<(), String> {
match self.stream.read_buf(&mut self.buffer).await {
match self.stream.get_mut().read_buf(&mut self.buffer).await {
Ok(0) => {
// If 0 bytes were received, then the remote end closed
// the connection
@ -209,7 +217,7 @@ impl SslConnection {
}
}
fn get_peer(&self) -> IoResult<SocketAddr> {
self.stream.get_ref().get_ref().peer_addr()
self.stream.get_ref().peer_addr()
}
/// Try to parse a query from the buffered data
fn try_query(&mut self) -> Result<ParseResult, ()> {
@ -244,14 +252,14 @@ impl SslConnection {
Ok(())
}
pub async fn flush_stream(&mut self) -> TResult<()> {
self.stream.flush().await?;
self.stream.get_mut().flush().await?;
Ok(())
}
/// Wraps around the `write_response` used to differentiate between a
/// success response and an error response
pub async fn close_conn_with_error(&mut self, resp: Vec<u8>) -> TResult<()> {
self.write_response(resp).await?;
self.stream.flush().await?;
self.stream.get_mut().flush().await?;
Ok(())
}
}

@ -63,12 +63,12 @@ impl IsConnection for BufWriter<TcpStream> {
}
}
impl IsConnection for BufWriter<SslStream<TcpStream>> {
impl IsConnection for SslStream<TcpStream> {
fn write_lowlevel<'s>(
&'s mut self,
bytes: &'s [u8],
) -> Pin<Box<dyn Future<Output = Result<usize, IoError>> + Send + Sync + 's>> {
Box::pin(self.write(bytes))
Box::pin(self.get_mut().write(bytes))
}
}

@ -24,7 +24,7 @@ mod __private {
use crate::protocol::responses::fresp;
use libtdb::terrapipe;
use tokio::io::AsyncReadExt;
use tokio::prelude::*;
use tokio::io::AsyncWriteExt;
/// Test a HEYA query: The server should return HEY!
async fn test_heya() {
let heya = terrapipe::proc_query("HEYA");
@ -82,7 +82,7 @@ mod __private {
) where
T: AsRef<str>,
{
use tokio::prelude::*;
use tokio::io::AsyncWriteExt;
let mut query = String::from("MSET ");
query.push_str(values_split_with_whitespace.as_ref());
let count_bytes_len = homwany.to_string().as_bytes().len();

@ -10,7 +10,7 @@ edition = "2018"
proc-macro = true
[dependencies]
syn = {version = "1.0.54", features = ["full"]}
quote = "1.0.7"
rand = "0.7.3"
syn = {version = "1.0.58", features = ["full"]}
quote = "1.0.8"
rand = "0.8.1"
proc-macro2 = "1.0.24"

@ -67,7 +67,7 @@ fn parse_dbtest(mut input: syn::ItemFn, rand: u16) -> Result<TokenStream, syn::E
let addr = crate::tests::start_test_server(#rand, Some(asyncdb.clone())).await;
let mut stream = tokio::net::TcpStream::connect(&addr).await.unwrap();
#body
stream.shutdown(::std::net::Shutdown::Write).unwrap();
stream.shutdown().await.unwrap();
asyncdb.finish_db();
drop(asyncdb);
};
@ -183,11 +183,11 @@ fn parse_test_module(args: TokenStream, item: TokenStream) -> TokenStream {
over by Hyper-V, which is why we'll prevent attempts to bind to them, if
the OS is Windows.
*/
let mut rand: u16 = rng.gen_range(1025, 65535);
let mut rand: u16 = rng.gen_range(1025..=65535);
#[cfg(not(target_os = "windows"))]
{
while in_set.contains(&rand) {
rand = rng.gen_range(1025, 65535);
rand = rng.gen_range(1025..=65535);
}
}
#[cfg(target_os = "windows")]
@ -195,7 +195,7 @@ fn parse_test_module(args: TokenStream, item: TokenStream) -> TokenStream {
in_set.insert(5357);
in_set.insert(7680);
while in_set.contains(&rand) || (rand >= 49670 && rand <= 50293) {
rand = rng.gen_range(1025, 65535);
rand = rng.gen_range(1025..=65535);
}
}
in_set.insert(rand);

Loading…
Cancel
Save