diff --git a/README.md b/README.md index e8f1491..2ba86df 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,15 @@ cd examples/client cargo run -- hsts.badssl.com ``` +### Danger Client Example Program + +See [examples/danger_client](examples/danger_client/src/main.rs). You can run it with: + +```sh +cd examples/danger_client +cargo run -- hsts.badssl.com +``` + ### Server Example Program See [examples/server](examples/server/src/main.rs). You can run it with: diff --git a/examples/danger_client/Cargo.toml b/examples/danger_client/Cargo.toml new file mode 100644 index 0000000..8041271 --- /dev/null +++ b/examples/danger_client/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "danger_client" +version = "0.1.0" +authors = ["Mingming Yu "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +structopt = {version = "0.3"} +async-std = "1.8.0" +async-tls = { path = "../.." } +rustls = {version="0.19.0", features=["dangerous_configuration"]} +webpki = "0.21.4" diff --git a/examples/danger_client/src/main.rs b/examples/danger_client/src/main.rs new file mode 100644 index 0000000..9d0753f --- /dev/null +++ b/examples/danger_client/src/main.rs @@ -0,0 +1,83 @@ +use async_std::io; +use async_std::net::TcpStream; +use async_std::prelude::*; +use async_std::task; +use async_tls::TlsConnector; +use std::sync::Arc; +use structopt::StructOpt; + +#[derive(StructOpt)] +struct Options { + /// The host ip address to connect to + serverip: String, + + /// The host port to connect to + #[structopt(short = "p", long = "port", default_value = "443")] + port: u16, +} + +mod danger { + + use webpki; + + pub struct NoCertificateVerification {} + + impl rustls::ServerCertVerifier for NoCertificateVerification { + fn verify_server_cert( + &self, + _roots: &rustls::RootCertStore, + _presented_certs: &[rustls::Certificate], + _dns_name: webpki::DNSNameRef<'_>, + _ocsp: &[u8], + ) -> Result { + Ok(rustls::ServerCertVerified::assertion()) + } + + fn verify_tls12_signature( + &self, + _message: &[u8], + _cert: &rustls::Certificate, + _dss: &rustls::internal::msgs::handshake::DigitallySignedStruct, + ) -> Result { + Ok(rustls::HandshakeSignatureValid::assertion()) + } + + fn verify_tls13_signature( + &self, + _message: &[u8], + _cert: &rustls::Certificate, + _dss: &rustls::internal::msgs::handshake::DigitallySignedStruct, + ) -> Result { + Ok(rustls::HandshakeSignatureValid::assertion()) + } + } +} + +fn main() -> io::Result<()> { + let options = Options::from_args(); + // Create a bare bones HTTP GET request + let http_request = format!("GET / HTTP/1.0\r\n\r\n"); + + task::block_on(async move { + let addr = format!("{}:{}", options.serverip, options.port); + + let mut config = rustls::ClientConfig::new(); + config + .dangerous() + .set_certificate_verifier(Arc::new(danger::NoCertificateVerification {})); + + let tcp_stream = TcpStream::connect(addr).await.unwrap(); + let connector = TlsConnector::from(config); + let mut tls_stream = connector.connect("localhost", tcp_stream).await.unwrap(); + + // We write our crafted HTTP request to it + tls_stream.write_all(http_request.as_bytes()).await?; + + // And read it all to stdout + let mut stdout = io::stdout(); + io::copy(&mut tls_stream, &mut stdout).await?; + + // Voila, we're done here! + Ok(()) + }) +} diff --git a/tests/test.rs b/tests/test.rs index d0f4ffa..39ed2c0 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -1,7 +1,7 @@ +use async_std::channel::bounded as channel; use async_std::io; use async_std::net::{TcpListener, TcpStream}; use async_std::prelude::*; -use async_std::sync::channel; use async_std::task; use async_tls::{TlsAcceptor, TlsConnector}; use lazy_static::lazy_static; @@ -32,7 +32,7 @@ lazy_static! { let addr = SocketAddr::from(([127, 0, 0, 1], 0)); let listener = TcpListener::bind(&addr).await?; - send.send(listener.local_addr()?).await; + let _ = send.send(listener.local_addr()?).await; let mut incoming = listener.incoming(); while let Some(stream) = incoming.next().await {