Skip to content

Commit

Permalink
Add support to remote access plugin for root_cert_path
Browse files Browse the repository at this point in the history
Signed-off-by: James Rhodes <[email protected]>
  • Loading branch information
jarhodes314 committed Jul 22, 2024
1 parent cf449e7 commit 2cf978b
Show file tree
Hide file tree
Showing 15 changed files with 82 additions and 63 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion clippy.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
disallowed-types = ["reqwest::ClientBuilder"]
disallowed-methods = ["reqwest::Client::builder"]
disallowed-methods = ["reqwest::Client::builder", "reqwest::Client::new", "hyper::client::Client::new"]
1 change: 1 addition & 0 deletions crates/common/axum_tls/src/acceptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ fn common_name<'a>(cert: Option<&'a (&[u8], X509Certificate)>) -> Option<&'a str
}

#[cfg(test)]
#[allow(clippy::disallowed_methods)]
mod tests {
use super::*;
use crate::ssl_config;
Expand Down
10 changes: 6 additions & 4 deletions crates/common/axum_tls/src/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,7 @@ mod tests {
let app = Router::new().route("/test", get(|| async { "it works!" }));

let task = tokio::spawn(crate::start_tls_server(listener, config, app));
let client = reqwest::Client::builder()
.add_root_certificate(cert)
.build()
.unwrap();
let client = client_builder().add_root_certificate(cert).build().unwrap();
assert_eq!(
client
.get(format!("https://localhost:{port}/test"))
Expand All @@ -339,6 +336,11 @@ mod tests {
task.abort();
}

#[allow(clippy::disallowed_methods, clippy::disallowed_types)]
fn client_builder() -> reqwest::ClientBuilder {
reqwest::Client::builder()
}

fn listener() -> (u16, std::net::TcpListener) {
let mut port = 3500;
loop {
Expand Down
1 change: 1 addition & 0 deletions crates/core/plugin_sm/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ pub struct ExternalPluginCommand {
}

impl ExternalPluginCommand {
#[allow(clippy::too_many_arguments)]
pub fn new(
name: impl Into<SoftwareType>,
path: impl Into<PathBuf>,
Expand Down
2 changes: 2 additions & 0 deletions crates/core/tedge_agent/src/file_transfer_server/actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ mod tests {
format!("http://localhost:{}/tedge/file-transfer/{path}", self.port)
}

#[allow(clippy::disallowed_methods)]
fn client(&self) -> reqwest::Client {
reqwest::Client::new()
}
Expand Down Expand Up @@ -304,6 +305,7 @@ mod tests {
.context("building anonymous client")
}

#[allow(clippy::disallowed_types, clippy::disallowed_methods)]
fn client_builder(&self) -> anyhow::Result<reqwest::ClientBuilder> {
let reqwest_certificate = Certificate::from_der(
&self
Expand Down
1 change: 1 addition & 0 deletions crates/extensions/c8y_auth_proxy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ rustls = { workspace = true }
tedge_actors = { workspace = true }
tedge_config = { workspace = true }
tedge_config_macros = { workspace = true }
tedge_utils = { workspace = true }
tokio = { workspace = true, features = [
"macros",
"rt-multi-thread",
Expand Down
2 changes: 2 additions & 0 deletions crates/extensions/c8y_auth_proxy/src/actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ impl C8yAuthProxyBuilder {
config: &TEdgeConfig,
jwt: &mut ServerActorBuilder<C8YJwtRetriever, Sequential>,
) -> anyhow::Result<Self> {
let reqwest_client = config.root_cert_client().builder().build().unwrap();
let app_data = AppData {
is_https: true,
host: config.c8y.http.or_config_not_set()?.to_string(),
token_manager: TokenManager::new(JwtRetriever::new(jwt)).shared(),
client: reqwest_client,
};
let bind = &config.c8y.proxy.bind;
let (signal_sender, signal_receiver) = mpsc::channel(10);
Expand Down
76 changes: 30 additions & 46 deletions crates/extensions/c8y_auth_proxy/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,13 @@ pub(crate) struct AppData {
pub is_https: bool,
pub host: String,
pub token_manager: SharedTokenManager,
pub client: reqwest::Client,
}

#[derive(Clone)]
struct AppState {
target_host: TargetHost,
client: reqwest::Client,
token_manager: SharedTokenManager,
}

Expand All @@ -156,6 +158,7 @@ impl From<AppData> for AppState {
without_scheme: host.into(),
},
token_manager: value.token_manager,
client: value.client,
}
}
}
Expand All @@ -172,6 +175,12 @@ impl FromRef<AppState> for SharedTokenManager {
}
}

impl FromRef<AppState> for reqwest::Client {
fn from_ref(input: &AppState) -> Self {
input.client.clone()
}
}

#[derive(Clone)]
struct TargetHost {
http: Arc<str>,
Expand Down Expand Up @@ -372,6 +381,7 @@ where
#[allow(clippy::too_many_arguments)]
async fn respond_to(
State(host): State<TargetHost>,
State(client): State<reqwest::Client>,
retrieve_token: State<SharedTokenManager>,
path: Option<Path<String>>,
uri: hyper::Uri,
Expand Down Expand Up @@ -409,7 +419,6 @@ async fn respond_to(
let path = path.to_owned();
return Ok(ws.on_upgrade(|socket| proxy_ws(socket, host, retrieve_token, headers, path)));
}
let client = reqwest::Client::new();
let (body, body_clone) = small_body.try_clone();
if body_clone.is_none() {
let destination = format!("{}/tenant/currentTenant", host.http);
Expand Down Expand Up @@ -549,11 +558,7 @@ mod tests {

let proxy_port = start_server_port(target.port(), vec!["unused token"]);
tokio::spawn(async move {
let client = reqwest::Client::builder()
.danger_accept_invalid_certs(true)
.build()
.unwrap();
client
reqwest_client()
.get(format!("http://127.0.0.1:{proxy_port}/c8y/test"))
.send()
.await
Expand Down Expand Up @@ -825,11 +830,7 @@ mod tests {

let port = start_server(&server, vec!["test-token"]);

let client = reqwest::Client::builder()
.danger_accept_invalid_certs(true)
.build()
.unwrap();
let res = client
let res = reqwest_client()
.get(format!("https://localhost:{port}/c8y/hello"))
.send()
.await
Expand All @@ -853,6 +854,7 @@ mod tests {

let port = start_server_with_certificate(&server, vec!["test-token"], certificate, None);

#[allow(clippy::disallowed_methods)]
let client = reqwest::Client::builder()
.add_root_certificate(reqwest::tls::Certificate::from_der(&cert_der).unwrap())
.build()
Expand All @@ -876,11 +878,7 @@ mod tests {

let port = start_server(&server, vec!["test-token"]);

let client = reqwest::Client::builder()
.danger_accept_invalid_certs(true)
.build()
.unwrap();
let res = client
let res = reqwest_client()
.get(format!("https://localhost:{port}/c8y/not-a-known-url"))
.send()
.await
Expand All @@ -899,11 +897,7 @@ mod tests {
None,
);

let client = reqwest::Client::builder()
.danger_accept_invalid_certs(true)
.build()
.unwrap();
let res = client
let res = reqwest_client()
.get(format!("https://localhost:{port}/c8y/not-a-known-url"))
.send()
.await
Expand All @@ -923,11 +917,7 @@ mod tests {

let port = start_server(&server, vec!["test-token"]);

let client = reqwest::Client::builder()
.danger_accept_invalid_certs(true)
.build()
.unwrap();
let res = client
let res = reqwest_client()
.get(format!(
"https://localhost:{port}/c8y/inventory/managedObjects?pageSize=100"
))
Expand All @@ -949,11 +939,7 @@ mod tests {

let port = start_server(&server, vec!["test-token"]);

let client = reqwest::Client::builder()
.danger_accept_invalid_certs(true)
.build()
.unwrap();
let res = client
let res = reqwest_client()
.get(format!(
"https://localhost:{port}/c8y/inventory/managedObjects"
))
Expand Down Expand Up @@ -983,12 +969,8 @@ mod tests {

let port = start_server(&server, vec!["old-token", "test-token"]);

let client = reqwest::Client::builder()
.danger_accept_invalid_certs(true)
.build()
.unwrap();
let body = "A body";
let res = client
let res = reqwest_client()
.put(format!("https://localhost:{port}/c8y/hello"))
.header("Content-Length", body.bytes().len())
.body(body)
Expand Down Expand Up @@ -1019,12 +1001,8 @@ mod tests {

let port = start_server(&server, vec!["old-token", "test-token"]);

let client = reqwest::Client::builder()
.danger_accept_invalid_certs(true)
.build()
.unwrap();
let body = "A body";
let res = client
let res = reqwest_client()
.put(format!("https://localhost:{port}/c8y/hello"))
.body(reqwest::Body::wrap_stream(once(ready(Ok::<
_,
Expand Down Expand Up @@ -1058,11 +1036,7 @@ mod tests {

let port = start_server(&server, vec!["stale-token", "test-token"]);

let client = reqwest::Client::builder()
.danger_accept_invalid_certs(true)
.build()
.unwrap();
let res = client
let res = reqwest_client()
.get(format!("https://localhost:{port}/c8y/hello"))
.send()
.await
Expand All @@ -1071,6 +1045,14 @@ mod tests {
assert_eq!(res.bytes().await.unwrap(), Bytes::from("Succeeded"));
}

#[allow(clippy::disallowed_methods)]
fn reqwest_client() -> reqwest::Client {
reqwest::Client::builder()
.danger_accept_invalid_certs(true)
.build()
.unwrap()
}

fn start_server(server: &mockito::Server, tokens: Vec<impl Into<Cow<'static, str>>>) -> u16 {
start_server_with_certificate(
server,
Expand Down Expand Up @@ -1100,6 +1082,7 @@ mod tests {
start_proxy_to_url(host, tokens, certificate, ca_dir)
}

#[allow(clippy::disallowed_methods)]
fn start_proxy_to_url(
target_host: &str,
tokens: Vec<impl Into<Cow<'static, str>>>,
Expand All @@ -1113,6 +1096,7 @@ mod tests {
is_https: false,
host: target_host.into(),
token_manager: TokenManager::new(JwtRetriever::new(&mut retriever)).shared(),
client: reqwest::Client::new(),
};
let trust_store = ca_dir
.as_ref()
Expand Down
1 change: 1 addition & 0 deletions crates/extensions/c8y_http_proxy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ serde = { workspace = true }
serde_json = { workspace = true }
tedge_actors = { workspace = true, features = ["test-helpers"] }
tedge_http_ext = { workspace = true, features = ["test_helpers"] }
tedge_test_utils = { workspace = true }
time = { workspace = true }

[lints]
Expand Down
12 changes: 10 additions & 2 deletions crates/extensions/c8y_http_proxy/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ use tedge_actors::Sender;
use tedge_actors::Server;
use tedge_actors::ServerActor;
use tedge_actors::ServerMessageBoxBuilder;
use tedge_config::TEdgeConfigLocation;
use tedge_http_ext::test_helpers::HttpResponseBuilder;
use tedge_http_ext::HttpActor;
use tedge_http_ext::HttpRequest;
use tedge_http_ext::HttpRequestBuilder;
use tedge_http_ext::HttpResult;
use tedge_test_utils::fs::TempTedgeDir;
use tedge_utils::certificates::RootCertClient;
use time::macros::datetime;

Expand Down Expand Up @@ -352,7 +354,10 @@ async fn retry_internal_id_on_expired_jwt_with_mock() {
let target_url = server.url();
let mut jwt = ServerMessageBoxBuilder::new("JWT Actor", 16);

let mut http_actor = HttpActor::new().builder();
let ttd = TempTedgeDir::new();
let config_loc = TEdgeConfigLocation::from_custom_root(ttd.path());
let tedge_config = config_loc.load().unwrap();
let mut http_actor = HttpActor::new(&tedge_config).builder();

let config = C8YHttpConfig {
c8y_http_host: target_url.clone(),
Expand Down Expand Up @@ -418,7 +423,10 @@ async fn retry_create_event_on_expired_jwt_with_mock() {
let target_url = server.url();
let mut jwt = ServerMessageBoxBuilder::new("JWT Actor", 16);

let mut http_actor = HttpActor::new().builder();
let ttd = TempTedgeDir::new();
let config_loc = TEdgeConfigLocation::from_custom_root(ttd.path());
let tedge_config = config_loc.load().unwrap();
let mut http_actor = HttpActor::new(&tedge_config).builder();

let config = C8YHttpConfig {
c8y_http_host: target_url.clone(),
Expand Down
1 change: 1 addition & 0 deletions crates/extensions/tedge_http_ext/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ tokio = { workspace = true, default_features = false, features = [

[dev-dependencies]
mockito = { workspace = true }
tedge_test_utils = { workspace = true }

[lints]
workspace = true
7 changes: 6 additions & 1 deletion crates/extensions/tedge_http_ext/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::*;
use tedge_actors::ClientMessageBox;
use tedge_config::TEdgeConfigLocation;
use tedge_test_utils::fs::TempTedgeDir;

#[tokio::test]
async fn get_over_https() {
Expand All @@ -18,7 +20,10 @@ async fn get_over_https() {
}

async fn spawn_http_actor() -> ClientMessageBox<HttpRequest, HttpResult> {
let mut builder = HttpActor::new().builder();
let ttd = TempTedgeDir::new();
let config_loc = TEdgeConfigLocation::from_custom_root(ttd.path());
let config = config_loc.load().unwrap();
let mut builder = HttpActor::new(&config).builder();
let handle = ClientMessageBox::new(&mut builder);

tokio::spawn(builder.run());
Expand Down
4 changes: 3 additions & 1 deletion plugins/c8y_remote_access_plugin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,10 @@ async fn proxy(command: RemoteAccessConnect, config: TEdgeConfig) -> miette::Res
let jwt = Jwt::retrieve(&config)
.await
.context("Failed when requesting JWT from Cumulocity")?;
let client_config = config.cloud_client_tls_config();

let proxy = WebsocketSocketProxy::connect(&url, command.target_address(), jwt).await?;
let proxy =
WebsocketSocketProxy::connect(&url, command.target_address(), jwt, client_config).await?;

proxy.run().await;
Ok(())
Expand Down
Loading

0 comments on commit 2cf978b

Please sign in to comment.