clean up warnings and tests

This commit is contained in:
Benjamin Fry 2018-09-22 17:33:42 -07:00
parent a7d5faa970
commit 0b4db24e63
16 changed files with 89 additions and 115 deletions

View File

@ -7,8 +7,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Added
- feature `dns-over-rustls` to `trust-dns-server`
- feature `dns-over-https-rustls`, `dns-over-https-openssl` *experimental*
- feature `dns-over-rustls` to `trust-dns-server` (server) and `trust-dns` (client)
- feature `dns-over-https-rustls` *experimental*
- new configuration options for tls, see `server/tests/named_test_configs/dns_over_tls_rustls_and_openssl.toml`
### Changed

View File

@ -95,7 +95,7 @@ where
Sender: DnsRequestSender<DnsResponseFuture = Response>,
Response: Future<Item = DnsResponse, Error = ProtoError> + Send,
{
// FIXME: change this to take the multiplexed connection, and create the exchange internally...
// TODO: consider changing this to take the multiplexed connection, and create the exchange internally...
/// Spawns a new ClientFuture Stream. This uses a default timeout of 5 seconds for all requests.
///
/// # Arguments

View File

@ -9,8 +9,7 @@ use std::{fmt, io};
use failure::{Backtrace, Context, Fail};
use h2;
use http;
use trust_dns_proto::error::{ProtoError, ProtoErrorKind};
use trust_dns_proto::error::ProtoError;
use typed_headers;
/// An alias for results returned by functions of this crate

View File

@ -8,7 +8,6 @@
use std::fmt::{self, Display};
use std::mem;
use std::net::SocketAddr;
use std::str::FromStr;
use std::sync::Arc;
use bytes::Bytes;
@ -16,16 +15,13 @@ use futures::{Async, Future, Poll, Stream};
use h2::client::{Handshake, SendRequest};
use h2::{self, RecvStream};
use http::header;
use http::uri;
use http::{Request, Response, StatusCode, Uri, Version};
use http::{Response, StatusCode};
use rustls::{Certificate, ClientConfig, ClientSession};
use tokio_executor;
use tokio_rustls::ClientConfigExt;
use tokio_rustls::{ConnectAsync, TlsStream as TokioTlsStream};
use tokio_tcp::{ConnectFuture, TcpStream as TokioTcpStream};
use typed_headers::{
mime::Mime, Accept, ContentLength, ContentType, HeaderMapExt, Quality, QualityItem,
};
use typed_headers::{ContentLength, HeaderMapExt};
use webpki::DNSNameRef;
use trust_dns_proto::error::ProtoError;

View File

@ -5,6 +5,8 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
//! HTTPS related server items
use std::borrow::Borrow;
use std::fmt::Debug;
use std::sync::Arc;
@ -15,10 +17,12 @@ use h2;
use http::{Method, Request};
use typed_headers::{ContentLength, HeaderMapExt};
use trust_dns_proto::op::Message;
use {HttpsError, HttpsResult};
use HttpsError;
// TODO: change RecvStream to Generic over Stream of Bytes
/// Given an HTTP request, return a future that will result in the next sequence of bytes.
///
/// To allow downstream clients to do something interesting with the lifetime of the bytes, this doesn't
/// perform a conversion to a Message, only collects all the bytes.
pub fn message_from<R>(this_server_name: Arc<String>, request: Request<R>) -> HttpsToMessage<R>
where
R: Stream<Item = Bytes, Error = h2::Error> + 'static + Send + Debug,
@ -53,6 +57,8 @@ where
}
}
/// A Future result of the bytes of a DNS message
#[must_use = "futures do nothing unless polled"]
pub struct HttpsToMessage<R>(HttpsToMessageInner<R>);
impl<R> From<HttpsToMessageInner<R>> for HttpsToMessage<R> {
@ -123,7 +129,7 @@ where
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
loop {
let mut bytes = match self.stream.poll() {
let bytes = match self.stream.poll() {
Ok(Async::NotReady) => return Ok(Async::NotReady),
Ok(Async::Ready(Some(bytes))) => bytes,
Ok(Async::Ready(None)) => return Err("not all bytes received".into()),
@ -152,6 +158,7 @@ where
#[cfg(test)]
mod tests {
use request;
use trust_dns_proto::op::Message;
use super::*;

View File

@ -9,15 +9,14 @@
use std::str::FromStr;
use http::{header, uri, Method, Request, Response, StatusCode, Uri, Version};
use http::{header, uri, Method, Request, Uri, Version};
use typed_headers::{
mime::Mime, Accept, ContentLength, ContentType, HeaderMapExt, Quality, QualityItem,
};
use trust_dns_proto::error::ProtoError;
use trust_dns_proto::op::Message;
use {HttpsError, HttpsResult};
use HttpsResult;
/// Create a new Reqeust for an http/2 dns-message request
///
@ -140,13 +139,11 @@ pub fn verify<T>(name_server: &str, request: &Request<T>) -> HttpsResult<()> {
#[cfg(test)]
mod tests {
use trust_dns_proto::op::*;
use super::*;
#[test]
fn test_new_verify() {
let request = new("ns.example.com", 512).expect("error converting to http");
let decoded_msg = verify("ns.example.com", &request);
assert!(verify("ns.example.com", &request).is_ok());
}
}

View File

@ -9,15 +9,12 @@
use std::str::FromStr;
use http::{header, uri, Response, StatusCode, Uri, Version};
use typed_headers::{
mime::Mime, Accept, ContentLength, ContentType, HeaderMapExt, Quality, QualityItem,
};
use http::{Response, StatusCode, Version};
use typed_headers::{mime::Mime, ContentLength, ContentType, HeaderMapExt};
use trust_dns_proto::error::ProtoError;
use trust_dns_proto::op::Message;
use {HttpsError, HttpsResult};
use HttpsResult;
/// Create a new Response for an http/2 dns-message request
///

View File

@ -16,8 +16,10 @@ use std::time;
use chrono::Duration;
use openssl::rsa::Rsa;
#[cfg(feature = "dnssec")]
use trust_dns::client::SecureSyncClient;
#[allow(deprecated)]
use trust_dns::client::{Client, ClientConnection, SecureSyncClient, SyncClient};
use trust_dns::client::{Client, ClientConnection, SyncClient};
use trust_dns::error::ClientErrorKind;
use trust_dns::op::*;
use trust_dns::rr::dnssec::{Algorithm, KeyPair, Signer};
@ -135,6 +137,7 @@ where
#[test]
#[ignore]
#[allow(deprecated)]
#[cfg(feature = "dnssec")]
fn test_secure_query_example_udp() {
let addr: SocketAddr = ("8.8.8.8", 53).to_socket_addrs().unwrap().next().unwrap();
let conn = UdpClientConnection::new(addr).unwrap();
@ -146,6 +149,7 @@ fn test_secure_query_example_udp() {
#[test]
#[ignore]
#[allow(deprecated)]
#[cfg(feature = "dnssec")]
fn test_secure_query_example_tcp() {
let addr: SocketAddr = ("8.8.8.8", 53).to_socket_addrs().unwrap().next().unwrap();
let conn = TcpClientConnection::new(addr).unwrap();
@ -155,6 +159,7 @@ fn test_secure_query_example_tcp() {
}
#[allow(deprecated)]
#[cfg(feature = "dnssec")]
fn test_secure_query_example<CC>(client: SecureSyncClient<CC>)
where
CC: ClientConnection,
@ -281,6 +286,7 @@ fn test_timeout_query_tcp() {
#[test]
#[ignore]
#[allow(deprecated)]
#[cfg(feature = "dnssec")]
fn test_nsec_query_example_udp() {
let addr: SocketAddr = ("8.8.8.8", 53).to_socket_addrs().unwrap().next().unwrap();
let conn = UdpClientConnection::new(addr).unwrap();
@ -291,6 +297,7 @@ fn test_nsec_query_example_udp() {
#[test]
#[ignore]
#[allow(deprecated)]
#[cfg(feature = "dnssec")]
fn test_nsec_query_example_tcp() {
let addr: SocketAddr = ("8.8.8.8", 53).to_socket_addrs().unwrap().next().unwrap();
let conn = TcpClientConnection::new(addr).unwrap();
@ -299,6 +306,7 @@ fn test_nsec_query_example_tcp() {
}
#[allow(deprecated)]
#[cfg(feature = "dnssec")]
fn test_nsec_query_example<CC>(client: SecureSyncClient<CC>)
where
CC: ClientConnection,
@ -315,6 +323,7 @@ where
#[test]
#[ignore]
#[allow(deprecated)]
#[cfg(feature = "dnssec")]
fn test_nsec_query_type() {
let name = Name::from_str("www.example.com").unwrap();
@ -366,8 +375,8 @@ fn test_nsec_query_type() {
// assert_eq!(response.get_response_code(), ResponseCode::NXDomain);
// }
#[cfg(feature = "dnssec")]
#[allow(deprecated)]
#[cfg(feature = "dnssec")]
fn create_sig0_ready_client(mut catalog: Catalog) -> (SyncClient<TestClientConnection>, Name) {
let mut authority = create_example();
authority.set_allow_update(true);

View File

@ -144,10 +144,12 @@ fn read_file(path: &str) -> Vec<u8> {
}
// TODO: move all this to future based clients
#[cfg(all(
feature = "dns-over-openssl",
not(feature = "dns-over-rustls")
))]
#[cfg(
all(
feature = "dns-over-openssl",
not(feature = "dns-over-rustls")
)
)]
#[test]
fn test_server_www_tls() {
@ -292,10 +294,12 @@ fn server_thread_tcp(tcp_listener: TcpListener, server_continue: Arc<AtomicBool>
}
// FIXME: need a rustls option
#[cfg(all(
feature = "dns-over-openssl",
not(feature = "dns-over-rustls")
))]
#[cfg(
all(
feature = "dns-over-openssl",
not(feature = "dns-over-rustls")
)
)]
fn server_thread_tls(
tls_listener: TcpListener,
server_continue: Arc<AtomicBool>,
@ -311,6 +315,7 @@ fn server_thread_tls(
.expect("bad pkcs12 der")
.parse("mypass")
.expect("Pkcs12::from_der");
let pkcs12 = ((pkcs12.cert, pkcs12.chain), pkcs12.pkey);
future::result(server.register_tls_listener(
tls_listener,
Duration::from_secs(30),

View File

@ -46,7 +46,7 @@ futures = "^0.1.17"
openssl = { version = "^0.10", features = ["v102", "v110"] }
tokio-openssl = "^0.2"
tokio-tcp = "^0.1"
trust-dns-proto = { version = "0.5.0-alpha", path = "../proto" }
trust-dns-proto = { version = "0.5.0-alpha", path = "../proto", features = ["openssl"] }
[dev-dependencies]
openssl = { version = "^0.10", features = ["v102", "v110"] }

View File

@ -10,8 +10,7 @@ use std::io;
use std::io::Read;
use std::path::Path;
use openssl::dh::Dh;
use openssl::ssl::{self, SslAcceptor, SslMethod, SslMode, SslOptions, SslVerifyMode};
use openssl::ssl::{SslAcceptor, SslMethod, SslOptions, SslVerifyMode};
use trust_dns_proto::error::{ProtoError, ProtoResult};
pub use openssl::pkcs12::{ParsedPkcs12, Pkcs12};

View File

@ -6,12 +6,11 @@
// copied, modified, or distributed except according to those terms.
use std::fs::File;
use std::io;
use std::io::{BufReader, Read};
use std::path::Path;
use rustls::internal::pemfile::{certs, pkcs8_private_keys};
use rustls::{self, Certificate, PrivateKey, ProtocolVersion, ServerConfig};
use rustls::{self, Certificate, PrivateKey, ServerConfig};
use trust_dns_proto::error::{ProtoError, ProtoResult};

View File

@ -62,12 +62,19 @@ use trust_dns::rr::dnssec::{KeyPair, Private, Signer};
use trust_dns::rr::Name;
use trust_dns::serialize::txt::{Lexer, Parser};
#[cfg(feature = "dns-over-openssl")]
#[cfg(
all(
feature = "dns-over-openssl",
not(feature = "dns-over-rustls")
)
)]
use trust_dns_openssl::tls_server::*;
use trust_dns_server::authority::{Authority, Catalog, Journal, ZoneType};
#[cfg(feature = "dnssec")]
use trust_dns_server::config::KeyConfig;
use trust_dns_server::config::{self, Config, TlsCertConfig, ZoneConfig};
#[cfg(feature = "dns-over-tls")]
use trust_dns_server::config::TlsCertConfig;
use trust_dns_server::config::{Config, ZoneConfig};
use trust_dns_server::logger;
use trust_dns_server::server::ServerFuture;
@ -275,6 +282,7 @@ fn load_cert(
tls_cert_config: &TlsCertConfig,
) -> Result<((X509, Option<Stack<X509>>), PKey<Private>), String> {
use trust_dns_openssl::tls_server::{read_cert_pem, read_cert_pkcs12, read_key_from_der};
use trust_dns_server::config::{CertType, PrivateKeyType};
let path = zone_dir.to_owned().join(tls_cert_config.get_path());
let cert_type = tls_cert_config.get_cert_type();
@ -286,11 +294,11 @@ fn load_cert(
// if it's pkcs12, we'll be collecting the key and certs from that, otherwise continue processing
let (cert, cert_chain) = match cert_type {
config::CertType::Pem => {
CertType::Pem => {
info!("loading TLS PEM certificate from: {:?}", path);
read_cert_pem(&path)?
}
config::CertType::Pkcs12 => {
CertType::Pkcs12 => {
if private_key_path.is_some() {
warn!(
"ignoring specified key, using the one in the PKCS12 file: {}",
@ -304,11 +312,11 @@ fn load_cert(
// it wasn't plcs12, we need to load the key separately
let key = match (private_key_path, private_key_type) {
(Some(private_key_path), config::PrivateKeyType::Pkcs8) => {
(Some(private_key_path), PrivateKeyType::Pkcs8) => {
info!("loading TLS PKCS8 key from: {}", private_key_path.display());
read_key_from_pkcs8(&private_key_path, password)?
}
(Some(private_key_path), config::PrivateKeyType::Der) => {
(Some(private_key_path), PrivateKeyType::Der) => {
info!("loading TLS DER key from: {}", private_key_path.display());
read_key_from_der(&private_key_path)?
}
@ -328,6 +336,7 @@ fn load_cert(
tls_cert_config: &TlsCertConfig,
) -> Result<(Vec<Certificate>, PrivateKey), String> {
use trust_dns_rustls::tls_server::{read_cert, read_key_from_der, read_key_from_pkcs8};
use trust_dns_server::config::{CertType, PrivateKeyType};
let path = zone_dir.to_owned().join(tls_cert_config.get_path());
let cert_type = tls_cert_config.get_cert_type();
@ -338,11 +347,11 @@ fn load_cert(
let private_key_type = tls_cert_config.get_private_key_type();
let cert = match cert_type {
config::CertType::Pem => {
CertType::Pem => {
info!("loading TLS PEM certificate chain from: {}", path.display());
read_cert(&path).map_err(|e| format!("error reading cert: {}", e))?
}
config::CertType::Pkcs12 => {
CertType::Pkcs12 => {
return Err(format!(
"PKCS12 is not supported with Rustls for certificate, use PEM encoding"
))
@ -350,7 +359,7 @@ fn load_cert(
};
let key = match (private_key_path, private_key_type) {
(Some(private_key_path), config::PrivateKeyType::Pkcs8) => {
(Some(private_key_path), PrivateKeyType::Pkcs8) => {
info!("loading TLS PKCS8 key from: {}", private_key_path.display());
if password.is_some() {
warn!("Password for key supplied, but Rustls does not support encrypted PKCS8");
@ -358,7 +367,7 @@ fn load_cert(
read_key_from_pkcs8(&private_key_path)?
}
(Some(private_key_path), config::PrivateKeyType::Der) => {
(Some(private_key_path), PrivateKeyType::Der) => {
info!("loading TLS DER key from: {}", private_key_path.display());
read_key_from_der(&private_key_path)?
}
@ -534,6 +543,7 @@ pub fn main() {
let mut io_loop = Runtime::new().expect("error when creating tokio Runtime");
// now, run the server, based on the config
#[cfg_attr(not(feature = "dns-over-tls"), allow(unused_mut))]
let mut server = ServerFuture::new(catalog);
let server_future: Box<Future<Item = (), Error = ()> + Send> = Box::new(future::lazy(
@ -556,7 +566,7 @@ pub fn main() {
// and TLS as necessary
// TODO: we should add some more control from configs to enable/disable TLS/HTTPS
if let Some(tls_cert_config) = tls_cert_config {
if let Some(_tls_cert_config) = tls_cert_config {
// setup TLS listeners
// TODO: support rustls
#[cfg(feature = "dns-over-tls")]
@ -564,7 +574,7 @@ pub fn main() {
&args,
&mut server,
&config,
tls_cert_config.clone(),
_tls_cert_config.clone(),
zone_dir,
&listen_addrs,
);
@ -575,7 +585,7 @@ pub fn main() {
&args,
&mut server,
&config,
tls_cert_config.clone(),
_tls_cert_config.clone(),
zone_dir,
&listen_addrs,
);
@ -606,18 +616,6 @@ pub fn main() {
info!("Trust-DNS {} stopping", trust_dns::version());
}
#[cfg(not(feature = "dns-over-tls"))]
fn config_tls(
_args: &Args,
_server: &mut ServerFuture<Catalog>,
_config: &Config,
_tls_cert_config: &TlsCertConfig,
_zone_dir: &Path,
_listen_addrs: &[IpAddr],
) {
panic!("TLS not enabled");
}
#[cfg(feature = "dns-over-tls")]
fn config_tls(
args: &Args,
@ -658,18 +656,6 @@ fn config_tls(
}
}
#[cfg(not(feature = "dns-over-https"))]
fn config_https(
_args: &Args,
_server: &mut ServerFuture<Catalog>,
_config: &Config,
_tls_cert_config: &TlsCertConfig,
_zone_dir: &Path,
_listen_addrs: &[IpAddr],
) {
panic!("HTTPS not enabled");
}
#[cfg(feature = "dns-over-https")]
fn config_https(
args: &Args,

View File

@ -9,16 +9,11 @@ use std::io;
use std::net::SocketAddr;
use std::sync::{Arc, Mutex};
use bytes::Bytes;
use futures::{Future, Stream};
use h2::{server, server::Connection};
use http::{Response, StatusCode};
use rustls::ServerConfig;
use h2::server;
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_rustls::ServerConfigExt;
use trust_dns_https::https_server;
use trust_dns_proto::serialize::binary::BinDecodable;
use trust_dns_rustls::tls_server;
use authority::MessageResponse;
use server::request_handler::RequestHandler;
@ -72,8 +67,6 @@ impl ResponseHandler for HttpsResponseHandle {
fn send_response(mut self, response: MessageResponse) -> io::Result<()> {
use bytes::Bytes;
use h2::server::SendResponse;
use trust_dns_https::response;
use trust_dns_https::HttpsError;
use trust_dns_proto::serialize::binary::BinEncoder;

View File

@ -5,7 +5,6 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
use std;
use std::borrow::Borrow;
use std::io;
use std::net::SocketAddr;
use std::sync::{Arc, Mutex};
@ -20,18 +19,20 @@ use tokio_reactor::Handle;
use tokio_tcp;
use tokio_udp;
#[cfg(feature = "dns-over-openssl")]
#[cfg(
all(
feature = "dns-over-openssl",
not(feature = "dns-over-rustls")
)
)]
use trust_dns_openssl::tls_server::*;
#[cfg(feature = "dns-over-openssl")]
use trust_dns_openssl::{tls_server, TlsStream};
use trust_dns_proto::op::Message;
use trust_dns_proto::serialize::binary::{BinDecodable, BinDecoder};
use trust_dns_proto::tcp::TcpStream;
use trust_dns_proto::udp::UdpStream;
use trust_dns_proto::xfer::SerialMessage;
use trust_dns_proto::BufStreamHandle;
use authority::{MessageRequest, MessageResponse};
use authority::MessageRequest;
use server::{Request, RequestHandler, ResponseHandle, ResponseHandler, TimeoutStream};
// TODO, would be nice to have a Slab for buffers here...
@ -118,7 +119,6 @@ impl<T: RequestHandler> ServerFuture<T> {
tokio_executor::spawn(
timeout_stream
.for_each(move |message| {
let src_addr = message.addr();
self::handle_raw_request(
message,
handler.clone(),
@ -188,6 +188,7 @@ impl<T: RequestHandler> ServerFuture<T> {
certificate_and_key: ((X509, Option<Stack<X509>>), PKey<Private>),
) -> io::Result<()> {
use futures::future;
use trust_dns_openssl::{tls_server, TlsStream};
let ((cert, chain), key) = certificate_and_key;
let handler = self.handler.clone();
@ -303,8 +304,8 @@ impl<T: RequestHandler> ServerFuture<T> {
use futures::{future, Stream};
use rustls::ServerConfig;
use tokio_rustls::ServerConfigExt;
use trust_dns_rustls::{tls_from_stream, tls_server};
use trust_dns_rustls::{tls_from_stream, tls_server, TlsStream};
let handler = self.handler.clone();
debug!("registered tcp: {:?}", listener);
@ -416,18 +417,16 @@ impl<T: RequestHandler> ServerFuture<T> {
pub fn register_https_listener(
&self,
listener: tokio_tcp::TcpListener,
timeout: Duration,
// TODO: need to set a timeout between requests.
_timeout: Duration,
certificate_and_key: (Vec<Certificate>, PrivateKey),
dns_hostname: String,
) -> io::Result<()> {
use futures::{future, Stream};
use h2::server;
use http::{Response, StatusCode};
use rustls::ServerConfig;
use tokio_rustls::ServerConfigExt;
use server::https_handler::h2_handler;
use trust_dns_https::https_server;
use trust_dns_rustls::tls_server;
let dns_hostname = Arc::new(dns_hostname);

View File

@ -71,22 +71,8 @@ fn test_example_https_toml_startup() {
io_loop.spawn(bg);
query_a(&mut io_loop, &mut client);
// FIXME: second call should succeed
// let addr: SocketAddr = ("127.0.0.1", https_port)
// .to_socket_addrs()
// .unwrap()
// .next()
// .unwrap();
// let mut https_conn_builder = HttpsClientStreamBuilder::new();
// let cert = to_trust_anchor(&cert_der);
// https_conn_builder.add_ca(cert);
// let mp = https_conn_builder.build(addr, "ns.example.com".to_string());
// let (exchange, handle) = DnsExchange::connect(mp);
// let (bg, mut client) = ClientFuture::from_exchange(exchange, handle);
// io_loop.spawn(bg);
// // ipv6 should succeed
// query_a(&mut io_loop, &mut client);
// a second request should work...
query_a(&mut io_loop, &mut client);
assert!(true);
})