refactor(connlib): create login_url utility (#2237)

This commit is contained in:
Thomas Eizinger
2023-10-05 15:15:51 +11:00
committed by GitHub
parent 9166ddce7b
commit 3fcfaa6bfd
6 changed files with 48 additions and 34 deletions

4
rust/Cargo.lock generated
View File

@@ -794,11 +794,9 @@ version = "1.20231001.0"
dependencies = [
"async-trait",
"backoff",
"boringtun",
"chrono",
"connlib-shared",
"firezone-tunnel",
"rand",
"reqwest",
"secrecy",
"serde",
@@ -822,11 +820,9 @@ version = "1.20231001.0"
dependencies = [
"async-trait",
"backoff",
"boringtun",
"chrono",
"connlib-shared",
"firezone-tunnel",
"rand",
"secrecy",
"serde",
"serde_json",

View File

@@ -19,13 +19,11 @@ async-trait = { version = "0.1", default-features = false }
connlib-shared = { workspace = true }
firezone-tunnel = { workspace = true }
serde = { version = "1.0", default-features = false, features = ["std", "derive"] }
boringtun = { workspace = true }
backoff = { workspace = true }
webrtc = "0.8"
url = { version = "2.4.1", features = ["serde"] }
time = { version = "0.3.29", features = ["formatting"] }
reqwest = { version = "0.11.20", default-features = false, features = ["stream", "rustls-tls"] }
rand = { version = "0.8", default-features = false, features = ["std"] }
tokio-tungstenite = { version = "0.20", default-features = false, features = ["connect", "handshake", "rustls-tls-webpki-roots"] }
[target.'cfg(target_os = "android")'.dependencies]

View File

@@ -5,17 +5,13 @@ pub use tracing_appender::non_blocking::WorkerGuard;
use crate::control::ControlSignaler;
use backoff::{backoff::Backoff, ExponentialBackoffBuilder};
use boringtun::x25519::{PublicKey, StaticSecret};
use connlib_shared::control::SecureUrl;
use connlib_shared::{
control::PhoenixChannel, get_websocket_path, messages::Key, sha256, CallbackErrorFacade, Result,
};
use connlib_shared::{control::PhoenixChannel, login_url, CallbackErrorFacade, Mode, Result};
use control::ControlPlane;
use firezone_tunnel::Tunnel;
use messages::IngressMessages;
use messages::Messages;
use messages::ReplyMessages;
use rand::{distributions::Alphanumeric, thread_rng, Rng};
use secrecy::{Secret, SecretString};
use std::sync::Arc;
use std::time::Duration;
@@ -128,12 +124,8 @@ where
callbacks: CallbackErrorFacade<CB>,
) {
runtime.spawn(async move {
let private_key = StaticSecret::random_from_rng(rand::rngs::OsRng);
let name_suffix: String = thread_rng().sample_iter(&Alphanumeric).take(8).map(char::from).collect();
let external_id = sha256(device_id);
let connect_url = fatal_error!(
get_websocket_path(portal_url, token, "client", &Key(PublicKey::from(&private_key).to_bytes()), &external_id, &name_suffix),
let (connect_url, private_key) = fatal_error!(
login_url(Mode::Client, portal_url, token, device_id),
runtime_stopper,
&callbacks
);

View File

@@ -12,12 +12,10 @@ firezone-tunnel = { workspace = true }
tokio = { version = "1.32", default-features = false, features = ["sync"] }
tracing = { workspace = true }
serde = { version = "1.0", default-features = false, features = ["std", "derive"] }
boringtun = { workspace = true }
chrono = { workspace = true }
backoff = { workspace = true }
webrtc = "0.8"
url = { version = "2.4.1", default-features = false }
rand = { version = "0.8", default-features = false, features = ["std"] }
tokio-tungstenite = { version = "0.20", default-features = false, features = ["connect", "handshake", "rustls-tls-webpki-roots"] }
[dev-dependencies]

View File

@@ -3,15 +3,11 @@ pub use connlib_shared::{get_device_id, messages::ResourceDescription, Callbacks
use crate::control::ControlSignaler;
use backoff::{backoff::Backoff, ExponentialBackoffBuilder};
use boringtun::x25519::{PublicKey, StaticSecret};
use connlib_shared::control::SecureUrl;
use connlib_shared::{
control::PhoenixChannel, get_websocket_path, messages::Key, sha256, CallbackErrorFacade, Result,
};
use connlib_shared::{control::PhoenixChannel, login_url, CallbackErrorFacade, Mode, Result};
use control::ControlPlane;
use firezone_tunnel::Tunnel;
use messages::IngressMessages;
use rand::{distributions::Alphanumeric, thread_rng, Rng};
use secrecy::{Secret, SecretString};
use std::sync::Arc;
use std::time::Duration;
@@ -122,17 +118,12 @@ where
callbacks: CallbackErrorFacade<CB>,
) {
runtime.spawn(async move {
let private_key = StaticSecret::random_from_rng(rand::rngs::OsRng);
let name_suffix: String = thread_rng().sample_iter(&Alphanumeric).take(8).map(char::from).collect();
let external_id = sha256(device_id);
let connect_url = fatal_error!(
get_websocket_path(portal_url, token, "gateway", &Key(PublicKey::from(&private_key).to_bytes()), &external_id, &name_suffix),
let (connect_url, private_key) = fatal_error!(
login_url(Mode::Gateway, portal_url, token, device_id),
runtime_stopper,
&callbacks
);
// This is kinda hacky, the buffer size is 1 so that we make sure that we
// process one message at a time, blocking if a previous message haven't been processed
// to force queue ordering.

View File

@@ -14,7 +14,10 @@ pub use callbacks_error_facade::CallbackErrorFacade;
pub use error::ConnlibError as Error;
pub use error::Result;
use boringtun::x25519::{PublicKey, StaticSecret};
use messages::Key;
use rand::distributions::Alphanumeric;
use rand::{thread_rng, Rng};
use ring::digest::{Context, SHA256};
use secrecy::{ExposeSecret, SecretString};
use std::net::Ipv4Addr;
@@ -25,6 +28,42 @@ pub const DNS_SENTINEL: Ipv4Addr = Ipv4Addr::new(100, 100, 111, 1);
const VERSION: &str = env!("CARGO_PKG_VERSION");
const LIB_NAME: &str = "connlib";
/// Creates a new login URL to use with the portal.
pub fn login_url(
mode: Mode,
portal_url: Url,
portal_token: SecretString,
device_id: String,
) -> Result<(Url, StaticSecret)> {
let private_key = StaticSecret::random_from_rng(rand::rngs::OsRng);
let name_suffix: String = thread_rng()
.sample_iter(&Alphanumeric)
.take(8)
.map(char::from)
.collect();
let external_id = sha256(device_id);
let url = get_websocket_path(
portal_url,
portal_token,
match mode {
Mode::Client => "client",
Mode::Gateway => "gateway",
},
&Key(PublicKey::from(&private_key).to_bytes()),
&external_id,
&name_suffix,
)?;
Ok((url, private_key))
}
// FIXME: This is a terrible name :(
pub enum Mode {
Client,
Gateway,
}
pub fn get_user_agent() -> String {
let info = os_info::get();
let os_type = info.os_type();
@@ -64,7 +103,7 @@ pub fn get_device_id() -> String {
uuid::Uuid::new_v4().to_string()
}
pub fn set_ws_scheme(url: &mut Url) -> Result<()> {
fn set_ws_scheme(url: &mut Url) -> Result<()> {
let scheme = match url.scheme() {
"http" | "ws" => "ws",
"https" | "wss" => "wss",
@@ -75,7 +114,7 @@ pub fn set_ws_scheme(url: &mut Url) -> Result<()> {
Ok(())
}
pub fn sha256(input: String) -> String {
fn sha256(input: String) -> String {
let mut ctx = Context::new(&SHA256);
ctx.update(input.as_bytes());
let digest = ctx.finish();
@@ -87,7 +126,7 @@ pub fn sha256(input: String) -> String {
.collect()
}
pub fn get_websocket_path(
fn get_websocket_path(
mut url: Url,
secret: SecretString,
mode: &str,