diff --git a/services/commtest/Cargo.lock b/services/commtest/Cargo.lock --- a/services/commtest/Cargo.lock +++ b/services/commtest/Cargo.lock @@ -26,7 +26,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -37,7 +37,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -119,6 +119,12 @@ "generic-array", ] +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "bytes" version = "1.3.0" @@ -153,6 +159,7 @@ "bytesize", "derive_more", "futures", + "futures-util", "hex", "lazy_static", "num_cpus", @@ -160,8 +167,10 @@ "prost", "sha2", "tokio", + "tokio-tungstenite", "tonic", "tonic-build", + "url", ] [[package]] @@ -199,7 +208,7 @@ "proc-macro2", "quote", "rustc_version", - "syn", + "syn 1.0.107", ] [[package]] @@ -254,6 +263,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + [[package]] name = "futures" version = "0.1.31" @@ -271,32 +289,46 @@ [[package]] name = "futures-core" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] [[package]] name = "futures-sink" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-core", + "futures-macro", + "futures-sink", "futures-task", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -442,6 +474,16 @@ "tokio-io-timeout", ] +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "indexmap" version = "1.9.2" @@ -572,7 +614,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -621,7 +663,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -655,14 +697,14 @@ checksum = "2c8992a85d8e93a28bdf76137db888d3874e3b230dee5ed8bebac4c9f7617773" dependencies = [ "proc-macro2", - "syn", + "syn 1.0.107", ] [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] @@ -694,7 +736,7 @@ "prost", "prost-types", "regex", - "syn", + "syn 1.0.107", "tempfile", "which", ] @@ -709,7 +751,7 @@ "itertools", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -724,9 +766,9 @@ [[package]] name = "quote" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -821,6 +863,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sha2" version = "0.10.6" @@ -862,6 +915,17 @@ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "sync_wrapper" version = "0.1.1" @@ -882,6 +946,41 @@ "winapi", ] +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.24.2" @@ -918,7 +1017,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -932,6 +1031,18 @@ "tokio", ] +[[package]] +name = "tokio-tungstenite" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54319c93411147bced34cb5609a80e0a8e44c5999c93903a81cd866630ec0bfd" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + [[package]] name = "tokio-util" version = "0.7.4" @@ -988,7 +1099,7 @@ "proc-macro2", "prost-build", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1063,7 +1174,7 @@ dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1091,18 +1202,69 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "tungstenite" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788" +dependencies = [ + "base64 0.13.1", + "byteorder", + "bytes", + "http", + "httparse", + "log", + "rand", + "sha1", + "thiserror", + "url", + "utf-8", +] + [[package]] name = "typenum" version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + [[package]] name = "unicode-ident" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "vcpkg" version = "0.2.15" diff --git a/services/commtest/Cargo.toml b/services/commtest/Cargo.toml --- a/services/commtest/Cargo.toml +++ b/services/commtest/Cargo.toml @@ -19,6 +19,9 @@ num_cpus = "1.13.1" sha2 = "0.10.2" hex = "0.4.3" +tokio-tungstenite = "0.18.0" +url = "2.3.1" +futures-util = "0.3.28" [build-dependencies] tonic-build = "0.8" diff --git a/services/commtest/src/tunnelbroker/mod.rs b/services/commtest/src/tunnelbroker/mod.rs --- a/services/commtest/src/tunnelbroker/mod.rs +++ b/services/commtest/src/tunnelbroker/mod.rs @@ -1,2 +1 @@ -pub mod new_session; -pub mod tunnelbroker_utils; + diff --git a/services/commtest/src/tunnelbroker/new_session.rs b/services/commtest/src/tunnelbroker/new_session.rs deleted file mode 100644 --- a/services/commtest/src/tunnelbroker/new_session.rs +++ /dev/null @@ -1,57 +0,0 @@ -use super::tunnelbroker_utils::proto::new_session_request::DeviceTypes; -use crate::tools::Error; -use crate::tunnelbroker::tunnelbroker_utils::{ - proto::NewSessionRequest, proto::SessionSignatureRequest, - TunnelbrokerServiceClient, -}; -use openssl::hash::MessageDigest; -use openssl::pkey::PKey; -use openssl::sign::Signer; -use tonic::Request; - -pub async fn get_string_to_sign( - client: &mut TunnelbrokerServiceClient, - device_id: &str, -) -> Result { - let response = client - .session_signature(Request::new(SessionSignatureRequest { - device_id: String::from(device_id), - })) - .await?; - Ok(response.into_inner().to_sign) -} - -pub fn sign_string_with_private_key( - keypair: &PKey, - string_to_be_signed: &str, -) -> anyhow::Result { - let mut signer = Signer::new(MessageDigest::sha256(), &keypair)?; - signer.update(string_to_be_signed.as_bytes())?; - let signature = signer.sign_to_vec()?; - Ok(base64::encode(signature)) -} - -pub async fn create_new_session( - client: &mut TunnelbrokerServiceClient, - device_id: &str, - public_key: &str, - signature: &str, - notify_token: &str, - device_type: DeviceTypes, - device_app_version: &str, - device_os: &str, -) -> Result { - let response = client - .new_session(Request::new(NewSessionRequest { - device_id: device_id.to_string(), - public_key: public_key.to_string(), - signature: signature.to_string(), - notify_token: Some(notify_token.to_string()), - device_type: device_type as i32, - device_app_version: device_app_version.to_string(), - device_os: device_os.to_string(), - })) - .await?; - let session_id = response.into_inner().session_id; - Ok(session_id) -} diff --git a/services/commtest/src/tunnelbroker/tunnelbroker_utils.rs b/services/commtest/src/tunnelbroker/tunnelbroker_utils.rs deleted file mode 100644 --- a/services/commtest/src/tunnelbroker/tunnelbroker_utils.rs +++ /dev/null @@ -1,29 +0,0 @@ -use anyhow::bail; -use std::env; -use tonic::transport::Channel; -use tonic::transport::Error; -pub mod proto { - tonic::include_proto!("tunnelbroker"); -} -use super::new_session::get_string_to_sign; -pub use proto::tunnelbroker_service_client::TunnelbrokerServiceClient; - -pub async fn tonic_client_builder( -) -> Result, Error> { - let port = env::var("COMM_SERVICES_PORT_TUNNELBROKER") - .unwrap_or(String::from("50051")); - let host = env::var("COMM_SERVICES_HOST_TUNNELBROKER") - .unwrap_or(String::from("localhost")); - TunnelbrokerServiceClient::connect(format!("http://{}:{}", host, port)).await -} - -pub async fn session_signature_device_id_format_validation( - client: &mut TunnelbrokerServiceClient, -) -> anyhow::Result<()> { - let wrong_device_id = - "some:OOOQ7b2ueEmQ4QsevRWlXxFCNt055y20T1PHdoYAQRt0S6TLzZWNM6XSvdWqxm"; - if let Ok(_) = get_string_to_sign(client, wrong_device_id).await { - bail!("Got success result on wrong deviceID format") - } - Ok(()) -} diff --git a/services/commtest/tests/tunnelbroker_integration_test.rs b/services/commtest/tests/tunnelbroker_integration_test.rs --- a/services/commtest/tests/tunnelbroker_integration_test.rs +++ b/services/commtest/tests/tunnelbroker_integration_test.rs @@ -1,68 +1,21 @@ -use commtest::tunnelbroker::{ - new_session::create_new_session, - new_session::get_string_to_sign, - new_session::sign_string_with_private_key, - tunnelbroker_utils::{ - proto::new_session_request::DeviceTypes, - session_signature_device_id_format_validation, tonic_client_builder, - }, -}; -use openssl::pkey::PKey; -use openssl::rsa::Rsa; +use futures_util::SinkExt; +use tokio_tungstenite::{connect_async, tungstenite::Message}; #[tokio::test] -async fn tunnelbroker_integration_test() -> Result<(), anyhow::Error> { - const DEVICE_ID: &str = - "mobile:OOOTESTb2ueEmQ4QsevRWlXxFCNt055y20T1PHdoYAQRt0S6TLzZWNM6XSvdW000"; - - // Should fail on the wrong device ID format provided - let mut client = tonic_client_builder().await?; - assert!( - session_signature_device_id_format_validation(&mut client) - .await - .is_ok(), - "DeviceID format validation failed on getting session signature request" - ); - - // Generate a keypair - let keypair = Rsa::generate(1024)?; - let keypair = PKey::from_rsa(keypair)?; - let public_key_pem = String::from_utf8(keypair.public_key_to_pem()?)?; - - // Get and sign the string to be signed - let string_to_be_signed = get_string_to_sign(&mut client, DEVICE_ID).await?; - let signature_base64 = - sign_string_with_private_key(&keypair, &string_to_be_signed)?; - - // Should fail on the wrong signature provided - assert!( - create_new_session( - &mut client, - DEVICE_ID, - &public_key_pem, - "wrong_signature", - "fake_notify_token", - DeviceTypes::Mobile, - "v.x.x.x", - "iOS x.x.x", - ) +async fn open_websocket_connection() { + let (mut socket, _) = connect_async("ws://localhost:51001") .await - .is_err(), - "New session returns success when using wrong signature" - ); + .expect("Can't connect"); - // Create a new session with the correct signature - let _session_id = create_new_session( - &mut client, - DEVICE_ID, - &public_key_pem, - &signature_base64, - "fake_notify_token", - DeviceTypes::Mobile, - "v.x.x.x", - "iOS x.x.x", - ) - .await?; + let session_request = r#"{ + "type": "sessionRequest", + "accessToken": "xkdeifjsld", + "deviceId": "foo", + "deviceType": "keyserver" + }"#; - Ok(()) + socket + .send(Message::Text(session_request.to_string())) + .await + .expect("Failed to send message"); } diff --git a/services/tunnelbroker/Cargo.lock b/services/tunnelbroker/Cargo.lock --- a/services/tunnelbroker/Cargo.lock +++ b/services/tunnelbroker/Cargo.lock @@ -858,6 +858,15 @@ "cfg-if", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + [[package]] name = "matchit" version = "0.7.0" @@ -1228,9 +1237,24 @@ dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.7.1", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.7.1" @@ -1814,10 +1838,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ + "matchers", "nu-ansi-term", + "once_cell", + "regex", "sharded-slab", "smallvec", "thread_local", + "tracing", "tracing-core", "tracing-log", ] diff --git a/services/tunnelbroker/Cargo.toml b/services/tunnelbroker/Cargo.toml --- a/services/tunnelbroker/Cargo.toml +++ b/services/tunnelbroker/Cargo.toml @@ -28,7 +28,7 @@ tokio = { version = "1.24", features = ["rt-multi-thread"]} tonic = "0.8" tracing = "0.1" -tracing-subscriber = "0.3.16" +tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } tunnelbroker_messages = { path = "../../shared/tunnelbroker_messages" } [build-dependencies] diff --git a/services/tunnelbroker/src/constants.rs b/services/tunnelbroker/src/constants.rs --- a/services/tunnelbroker/src/constants.rs +++ b/services/tunnelbroker/src/constants.rs @@ -4,3 +4,6 @@ pub const GRPC_SERVER_PORT: u64 = 50051; pub const GRPC_KEEP_ALIVE_PING_INTERVAL: Duration = Duration::from_secs(3); pub const GRPC_KEEP_ALIVE_PING_TIMEOUT: Duration = Duration::from_secs(10); + +pub const LOG_LEVEL_ENV_VAR: &str = + tracing_subscriber::filter::EnvFilter::DEFAULT_ENV; diff --git a/services/tunnelbroker/src/main.rs b/services/tunnelbroker/src/main.rs --- a/services/tunnelbroker/src/main.rs +++ b/services/tunnelbroker/src/main.rs @@ -5,7 +5,8 @@ use once_cell::sync::Lazy; use std::io::{self, Error, ErrorKind}; use tokio::sync::mpsc::UnboundedSender; -use tracing; +use tracing::{self, Level}; +use tracing_subscriber::EnvFilter; use tunnelbroker_messages::Messages; pub static ACTIVE_CONNECTIONS: Lazy< @@ -14,7 +15,12 @@ #[tokio::main] async fn main() -> Result<(), io::Error> { - let subscriber = tracing_subscriber::FmtSubscriber::new(); + let filter = EnvFilter::builder() + .with_default_directive(Level::INFO.into()) + .with_env_var(constants::LOG_LEVEL_ENV_VAR) + .from_env_lossy(); + + let subscriber = tracing_subscriber::fmt().with_env_filter(filter).finish(); tracing::subscriber::set_global_default(subscriber) .expect("Unable to configure tracing"); diff --git a/services/tunnelbroker/src/websockets/mod.rs b/services/tunnelbroker/src/websockets/mod.rs --- a/services/tunnelbroker/src/websockets/mod.rs +++ b/services/tunnelbroker/src/websockets/mod.rs @@ -4,6 +4,7 @@ use std::{env, io::Error}; use tokio::net::{TcpListener, TcpStream}; use tokio::sync::mpsc; +use tokio_tungstenite::tungstenite::Message; use tracing::{debug, error, info}; use tunnelbroker_messages::messages::Messages; @@ -41,17 +42,22 @@ let (_outgoing, incoming) = ws_stream.split(); let handle_incoming = incoming.try_for_each(|msg| { - let message_text = msg.to_text().unwrap(); - debug!("Received message from {}: {}", addr, message_text); - - match handle_message(message_text) { - Ok(_) => { - debug!("Successfully handled message: {}", message_text) + debug!("Received message from {}", addr); + match msg { + Message::Text(text) => { + match handle_message(&text) { + Ok(_) => { + debug!("Successfully handled message: {}", text) + } + Err(e) => { + error!("Failed to process message: {}", e); + } + }; } - Err(e) => { - error!("Failed to process message: {}", e); + _ => { + error!("Invalid message was received"); } - }; + } future::ok(()) }); @@ -61,9 +67,10 @@ // TODO: Use device's public key, once we support the SessionRequest message ACTIVE_CONNECTIONS.insert("test".to_string(), tx.clone()); + debug!("Polling for messages from: {}", addr); tokio::select! { Some(_) = rx.recv() => { debug!("Received message from channel") }, - Ok(_) = handle_incoming => { debug!("Received message from websocket" )}, + Ok(_) = handle_incoming => { debug!("Received message from websocket") }, else => { info!("Connection with {} closed.", addr); ACTIVE_CONNECTIONS.remove("test"); diff --git a/shared/tunnelbroker_messages/src/messages/mod.rs b/shared/tunnelbroker_messages/src/messages/mod.rs --- a/shared/tunnelbroker_messages/src/messages/mod.rs +++ b/shared/tunnelbroker_messages/src/messages/mod.rs @@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] +#[serde(untagged)] pub enum Messages { RefreshKeysRequest(RefreshKeyRequest), SessionRequest(SessionRequest),