From 5ce329545e6036fc8a6e624ad0741f20d0c68c68 Mon Sep 17 00:00:00 2001 From: jbtrystram Date: Tue, 5 Jul 2022 15:16:23 +0200 Subject: [PATCH] Add an insecure flag for drg stream, allowing to connect to self signed certs. Partially addresses #143 --- Cargo.lock | 41 ++++++++--------------------------------- Cargo.toml | 3 ++- src/arguments/cli.rs | 8 ++++++++ src/config.rs | 18 ++++++++++++++---- src/main.rs | 3 ++- src/stream.rs | 38 ++++++++++++++++++++++++++++++++------ 6 files changed, 66 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d09116b..2233003 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -143,15 +143,6 @@ dependencies = [ "wyz", ] -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - [[package]] name = "block-buffer" version = "0.10.2" @@ -429,7 +420,7 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ - "block-buffer 0.10.2", + "block-buffer", "crypto-common", ] @@ -481,6 +472,7 @@ dependencies = [ "edit", "json_value_merge", "log", + "native-tls", "oauth2", "qstring", "rand", @@ -891,15 +883,6 @@ dependencies = [ "serde", ] -[[package]] -name = "input_buffer" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f97967975f448f1a7ddb12b0bc41069d09ed6a1c161a92687e057325db35d413" -dependencies = [ - "bytes", -] - [[package]] name = "instant" version = "0.1.12" @@ -1264,12 +1247,6 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "openid" version = "0.9.4" @@ -1945,15 +1922,13 @@ dependencies = [ [[package]] name = "sha-1" -version = "0.9.8" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" dependencies = [ - "block-buffer 0.9.0", "cfg-if", "cpufeatures", - "digest 0.9.0", - "opaque-debug", + "digest 0.10.3", ] [[package]] @@ -2330,20 +2305,20 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "tungstenite" -version = "0.12.0" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ada8297e8d70872fa9a551d93250a9f407beb9f37ef86494eb20012a2ff7c24" +checksum = "d96a2dea40e7570482f28eb57afbe42d97551905da6a9400acc5c328d24004f5" dependencies = [ "base64", "byteorder", "bytes", "http", "httparse", - "input_buffer", "log", "native-tls", "rand", "sha-1", + "thiserror", "url", "utf-8", ] diff --git a/Cargo.toml b/Cargo.toml index 8d227a6..7bb54ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,7 +59,8 @@ rsa = "0.5.0" rand = "0.8.4" sha-crypt = "0.3.2" -tungstenite = { version = "0.12.0", features = ["native-tls"]} +tungstenite = { version = "0.17.2", features = ["native-tls"]} +native-tls = "0.2.10" [dev-dependencies] assert_cmd = "2.0.4" diff --git a/src/arguments/cli.rs b/src/arguments/cli.rs index 3d2866e..d0ffd62 100644 --- a/src/arguments/cli.rs +++ b/src/arguments/cli.rs @@ -118,6 +118,7 @@ pub enum Parameters { // stream command count, device, + insecure, // login & whoami command token, @@ -530,10 +531,17 @@ pub fn app_arguments() -> clap::Command<'static> { .global(true) .help("The number of messages to stream before exiting."); + let insecure = Arg::new(Parameters::insecure.as_ref()) + .required(false) + .long("insecure") + .takes_value(false) + .help("Skip the TLS certificate verification"); + let stream = Command::new(Action::stream.as_ref()) .about("Stream all events going through drogue cloud") .arg(&app_flag) .arg(&count) + .arg(&insecure) .arg( Arg::new(Parameters::device.as_ref()) .long("device") diff --git a/src/config.rs b/src/config.rs index 6547aa1..7b296af 100644 --- a/src/config.rs +++ b/src/config.rs @@ -69,17 +69,27 @@ impl RequestBuilderExt for reqwest::RequestBuilder { } } -impl RequestBuilderExt for tungstenite::http::request::Builder { - fn auth(self, token: &Token) -> Self { +impl RequestBuilderExt for tungstenite::http::Request<()> { + fn auth(mut self, token: &Token) -> Self { match token { Token::TokenResponse(token) => { let bearer_header = format!("Bearer {}", &token.access_token().secret()); - self.header(tungstenite::http::header::AUTHORIZATION, bearer_header) + let mut bearer_header = + tungstenite::http::HeaderValue::from_str(&bearer_header).unwrap(); + bearer_header.set_sensitive(true); + self.headers_mut() + .insert(tungstenite::http::header::AUTHORIZATION, bearer_header); + self } Token::AccessToken(auth) => { let encoded = base64::encode(&format!("{}:{}", auth.id, auth.token).as_bytes()); let basic_header = format!("Basic {}", encoded); - self.header(tungstenite::http::header::AUTHORIZATION, basic_header) + let mut basic_header = + tungstenite::http::HeaderValue::from_str(&basic_header).unwrap(); + basic_header.set_sensitive(true); + self.headers_mut() + .insert(tungstenite::http::header::AUTHORIZATION, basic_header); + self } } } diff --git a/src/main.rs b/src/main.rs index 49a63e4..c14691b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -240,8 +240,9 @@ async fn process_arguments(matches: ArgMatches) -> Result { .map(|s| s.parse::().unwrap()) .unwrap_or(usize::MAX); let device = matches.value_of(Parameters::device.as_ref()); + let insecure = matches.is_present(Parameters::insecure.as_ref()); - stream::stream_app(context, &app_id, device, count).await?; + stream::stream_app(context, &app_id, device, count, insecure).await?; 0 } diff --git a/src/stream.rs b/src/stream.rs index 01f1544..1e3e3ff 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -1,29 +1,41 @@ use anyhow::{anyhow, Context as AnyhowContext, Result}; use colored_json::write_colored_json; +use native_tls::TlsConnector; use oauth2::TokenResponse; use serde_json::Value; use std::io::stdout; +use std::net::TcpStream; use tungstenite::http::Request; use tungstenite::{connect, Message}; use crate::config::{Context, RequestBuilderExt, Token}; use crate::{openid, util}; use drogue_client::integration::ws::v1::client::Message as Drogue_ws_message; +use tungstenite::client::IntoClientRequest; pub async fn stream_app( config: &mut Context, app: &str, device: Option<&str>, mut count: usize, + insecure: bool, ) -> Result<()> { - let url = util::get_drogue_websocket_endpoint(config).await?; - let url = format!("{}{}", url, urlencoding::encode(app)); + let ws_endpoint = util::get_drogue_websocket_endpoint(config).await?; + let url = format!("{}{}", ws_endpoint, urlencoding::encode(app)); - let request = Request::builder().uri(url).auth(&config.token).body(())?; + let mut request: Request<()> = url.into_client_request()?; + request = request.auth(&config.token); + + log::debug!("Connecting to websocket with request : {:?}", &request); + let (mut socket, response) = if insecure { + log::warn!("Skipping certificate verification"); + let (connector, stream) = insecure_stream(&ws_endpoint.socket_addrs(|| None).unwrap())?; + tungstenite::client_tls_with_config(request, stream, None, Some(connector)) + .context("Error connecting to the Websocket endpoint:")? + } else { + connect(request).context("Error connecting to the Websocket endpoint:")? + }; - log::debug!("Connecting to websocket with request : {:?}", request); - let (mut socket, response) = - connect(request).context("Error connecting to the Websocket endpoint:")?; log::debug!("HTTP response: {}", response.status()); while count > 0 { @@ -97,3 +109,17 @@ async fn refresh_token(config: &mut Context) -> Option { } } } + +fn insecure_stream( + address: &Vec, +) -> Result<(tungstenite::Connector, TcpStream)> { + let connector = TlsConnector::builder() + .danger_accept_invalid_certs(true) + .build() + .unwrap(); + + let stream = TcpStream::connect(address.as_slice())?; + let connector: tungstenite::Connector = tungstenite::Connector::NativeTls(connector); + + Ok((connector, stream)) +}