diff --git a/forward-proxy/src/handler/mod.rs b/forward-proxy/src/handler/mod.rs index 1e8aed5..1fa2e75 100644 --- a/forward-proxy/src/handler/mod.rs +++ b/forward-proxy/src/handler/mod.rs @@ -105,24 +105,45 @@ impl ForwardHandler { ); ctx.insert_response_header("Connection", "close"); // Ensure connection closes??? - - Err(APIHandlerResponse { + return Err(APIHandlerResponse { status: StatusCode::BAD_REQUEST, - body: Some(response_body.to_bytes()), - }) - } else { - #[derive(Deserialize, Debug)] - struct AuthServerResponse { - pub x509_certificate: String, - pub client_id: String, + body: Some( + serde_json::to_vec(&response_body).expect("this struct is json serializable"), + ), + }); + } + #[derive(Deserialize, Debug)] + struct AuthServerResponse { + pub x509_certificate: String, + pub client_id: String, + } + + let auth_res: AuthServerResponse = res.json().await.map_err(|err| { + error!( + %correlation_id, + log_type=LogTypes::AUTHENTICATION_SERVER, + "Failed to parse authentication server response: {:?}", + err + ); + APIHandlerResponse { + status: StatusCode::INTERNAL_SERVER_ERROR, + body: None, } + })?; + + // save `client_id` to ctx for later use + ctx.set( + consts::CtxKeys::BACKEND_AUTH_CLIENT_ID.to_string(), + auth_res.client_id.clone(), + ); - let auth_res: AuthServerResponse = res.json().await.map_err(|err| { + let pub_key = + utils::cert::extract_x509_pem(auth_res.x509_certificate.clone()).map_err(|e| { error!( %correlation_id, log_type=LogTypes::AUTHENTICATION_SERVER, - "Failed to parse authentication server response: {:?}", - err + "Failed to parse x509 certificate: {:?}", + e ); APIHandlerResponse { status: StatusCode::INTERNAL_SERVER_ERROR, @@ -130,39 +151,18 @@ impl ForwardHandler { } })?; - // save `client_id` to ctx for later use - ctx.set( - consts::CtxKeys::BACKEND_AUTH_CLIENT_ID.to_string(), - auth_res.client_id.clone(), - ); - - let pub_key = utils::cert::extract_x509_pem(auth_res.x509_certificate.clone()) - .map_err(|e| { - error!( - %correlation_id, - log_type=LogTypes::AUTHENTICATION_SERVER, - "Failed to parse x509 certificate: {:?}", - e - ); - APIHandlerResponse { - status: StatusCode::INTERNAL_SERVER_ERROR, - body: None, - } - })?; - - debug!(%correlation_id, "AuthenticationServer response: {:?}", auth_res); - info!( - %correlation_id, - log_type=LogTypes::AUTHENTICATION_SERVER, - "Obtained ntor credentials for backend_url: {}", - backend_url - ); + debug!(%correlation_id, "AuthenticationServer response: {:?}", auth_res); + info!( + %correlation_id, + log_type=LogTypes::AUTHENTICATION_SERVER, + "Obtained ntor credentials for backend_url: {}", + backend_url + ); - Ok(NTorServerCertificate { - server_id: backend_url, // todo I still prefer taking the server_id value from certificate's subject - public_key: pub_key, - }) - } + Ok(NTorServerCertificate { + server_id: backend_url, // todo I still prefer taking the server_id value from certificate's subject + public_key: pub_key, + }) } /// Verify `int_fp_jwt` and return `fp_rp_jwt` @@ -237,67 +237,63 @@ impl ForwardHandler { pub fn handle_init_tunnel_response(&self, ctx: &mut Layer8Context) -> APIHandlerResponse { let ntor_server_id = ctx - .get(&consts::CtxKeys::NTOR_SERVER_ID) + .get(consts::CtxKeys::NTOR_SERVER_ID) .unwrap_or(&"".to_string()) .clone(); let ntor_static_public_key = hex::decode( - ctx.get(&consts::CtxKeys::NTOR_STATIC_PUBLIC_KEY) + ctx.get(consts::CtxKeys::NTOR_STATIC_PUBLIC_KEY) .unwrap_or(&"".to_string()), ) .unwrap_or_default(); - let response_body = ctx.get_response_body(); - - return match utils::bytes_to_json::(response_body) { - Err(e) => { - error!( - correlation_id = ctx.get_correlation_id(), - log_type = LogTypes::HANDLE_UPSTREAM_RESPONSE, - "Error parsing RP response: {:?}", - e - ); - APIHandlerResponse { - status: StatusCode::INTERNAL_SERVER_ERROR, - body: None, + let res_from_rp = + match serde_json::from_slice::(ctx.get_response_body()) { + Ok(val) => val, + Err(e) => { + error!( + correlation_id = ctx.get_correlation_id(), + log_type = LogTypes::HANDLE_UPSTREAM_RESPONSE, + "Error parsing RP response: {:?}", + e + ); + return APIHandlerResponse { + status: StatusCode::INTERNAL_SERVER_ERROR, + body: None, + }; } - } - Ok(res_from_rp) => { - let int_fp_jwt = { - let mut claims = JWTClaims::new(Some(self.config.jwt_exp_in_hours)); - claims.uuid = Some(utils::new_uuid()); - utils::jwt::create_jwt_token(claims, &self.config.jwt_virtual_connection_key) - }; + }; - let int_fp_session = IntFPSession { - client_id: ctx - .get(&consts::CtxKeys::BACKEND_AUTH_CLIENT_ID) - .unwrap_or(&"".to_string()) - .to_string(), - rp_base_url: ctx - .param("backend_url") - .unwrap_or(&"".to_string()) - .to_string(), - fp_rp_jwt: res_from_rp.fp_rp_jwt, - }; + let int_fp_jwt = { + let mut claims = JWTClaims::new(Some(self.config.jwt_exp_in_hours)); + claims.uuid = Some(utils::new_uuid()); + utils::jwt::create_jwt_token(claims, &self.config.jwt_virtual_connection_key) + }; - let mut jwts = self.jwts_storage.lock().unwrap(); - jwts.insert(int_fp_jwt.clone(), int_fp_session); + let int_fp_session = IntFPSession { + client_id: ctx + .get(consts::CtxKeys::BACKEND_AUTH_CLIENT_ID) + .unwrap_or(&"".to_string()) + .clone(), + rp_base_url: ctx.param("backend_url").unwrap_or(&"".to_string()).clone(), + fp_rp_jwt: res_from_rp.fp_rp_jwt, + }; - let res_to_int = InitTunnelResponseToINT { - ephemeral_public_key: res_from_rp.public_key, - t_b_hash: res_from_rp.t_b_hash, - int_rp_jwt: res_from_rp.int_rp_jwt, - int_fp_jwt, - ntor_static_public_key, - ntor_server_id, - }; + let mut jwts = self.jwts_storage.lock().unwrap(); + jwts.insert(int_fp_jwt.clone(), int_fp_session); - APIHandlerResponse { - status: StatusCode::OK, - body: Some(res_to_int.to_bytes()), - } - } + let res_to_int = InitTunnelResponseToINT { + ephemeral_public_key: res_from_rp.public_key, + t_b_hash: res_from_rp.t_b_hash, + int_rp_jwt: res_from_rp.int_rp_jwt, + int_fp_jwt, + ntor_static_public_key, + ntor_server_id, }; + + APIHandlerResponse { + status: StatusCode::OK, + body: Some(res_to_int.to_bytes()), + } } pub fn handle_healthcheck(&self, ctx: &mut Layer8Context) -> APIHandlerResponse { diff --git a/forward-proxy/src/main.rs b/forward-proxy/src/main.rs index 5c9aa05..58b03a5 100644 --- a/forward-proxy/src/main.rs +++ b/forward-proxy/src/main.rs @@ -1,15 +1,16 @@ +use pingora::prelude::*; +use tokio::runtime::Runtime; +use tracing::{debug, info}; + mod config; mod handler; mod proxy; mod statistics; -use crate::config::FPConfig; -use crate::handler::ForwardHandler; -use crate::statistics::Statistics; -use pingora::prelude::*; +use config::FPConfig; +use handler::ForwardHandler; use proxy::ForwardProxy; -use tokio::runtime::Runtime; -use tracing::{debug, info}; +use statistics::Statistics; fn load_config() -> FPConfig { // Load environment variables from .env file diff --git a/forward-proxy/src/proxy.rs b/forward-proxy/src/proxy.rs index 9f5f60e..3643476 100644 --- a/forward-proxy/src/proxy.rs +++ b/forward-proxy/src/proxy.rs @@ -1,8 +1,6 @@ -use crate::config::TlsConfig; -use crate::handler::ForwardHandler; -use crate::handler::consts::{CtxKeys, HeaderKeys, LogTypes, RequestPaths}; -use crate::handler::types::response::ErrorResponse; -use crate::statistics::Statistics; +use std::sync::Arc; +use std::time::Duration; + use async_trait::async_trait; use boring::x509::X509; use bytes::Bytes; @@ -17,10 +15,14 @@ use pingora_error::ErrorType; use pingora_router::ctx::{Layer8Context, Layer8ContextTrait}; use pingora_router::handler::ResponseBodyTrait; use reqwest::header::TRANSFER_ENCODING; -use std::sync::Arc; -use std::time::Duration; use tracing::{debug, error, info}; +use crate::config::TlsConfig; +use crate::handler::ForwardHandler; +use crate::handler::consts::{CtxKeys, HeaderKeys, LogTypes, RequestPaths}; +use crate::handler::types::response::ErrorResponse; +use crate::statistics::Statistics; + pub struct ForwardProxy { tls_config: TlsConfig, handler: ForwardHandler, @@ -361,7 +363,7 @@ impl ProxyHttp for ForwardProxy { request_summary = session.request_summary(), "Forward proxy passing through request body unchanged." ); - *body = Some(Bytes::copy_from_slice(ctx.get_request_body().as_slice())); + *body = Some(Bytes::copy_from_slice(ctx.get_request_body())); return Ok(()); } }; @@ -441,7 +443,6 @@ impl ProxyHttp for ForwardProxy { "{} token is empty", HeaderKeys::INT_FP_JWT ); - return Err(pingora::Error::new(pingora::ErrorType::HTTPStatus( u16::from(StatusCode::BAD_REQUEST), ))); @@ -545,7 +546,7 @@ impl ProxyHttp for ForwardProxy { request_summary = session.request_summary(), "Forward proxy passing through response body unchanged." ); - *body = Some(Bytes::copy_from_slice(ctx.get_response_body().as_slice())); + *body = Some(Bytes::copy_from_slice(ctx.get_response_body())); return Ok(None); } }; diff --git a/pingora-router/src/ctx.rs b/pingora-router/src/ctx.rs index 34b2126..69ceeb8 100644 --- a/pingora-router/src/ctx.rs +++ b/pingora-router/src/ctx.rs @@ -1,10 +1,12 @@ -use crate::utils::get_request_body; -use pingora::http::{Method, RequestHeader, StatusCode}; -use pingora::proxy::Session; use std::collections::HashMap; use std::time::Instant; + +use pingora::http::{Method, RequestHeader, StatusCode}; +use pingora::proxy::Session; use uuid; +use crate::utils::get_request_body; + /* * Each type in this crate serves a specific purpose and may be updated as requirements evolve. */ @@ -186,8 +188,8 @@ impl Layer8ContextTrait for Layer8Context { self.request.body.extend(body) } - fn get_request_body(&self) -> Vec { - self.request.body.clone() + fn get_request_body(&self) -> &[u8] { + &self.request.body } fn set_response_body(&mut self, body: Vec) { @@ -198,8 +200,8 @@ impl Layer8ContextTrait for Layer8Context { self.response.body.extend(body); } - fn get_response_body(&self) -> Vec { - self.response.body.clone() + fn get_response_body(&self) -> &[u8] { + &self.response.body } fn get(&self, key: &str) -> Option<&String> { @@ -254,10 +256,10 @@ pub trait Layer8ContextTrait { fn get_response_header(&self) -> &Layer8Header; fn set_request_body(&mut self, body: Vec); fn extend_request_body(&mut self, body: Vec); - fn get_request_body(&self) -> Vec; + fn get_request_body(&self) -> &[u8]; fn set_response_body(&mut self, body: Vec); fn extend_response_body(&mut self, body: Vec); - fn get_response_body(&self) -> Vec; + fn get_response_body(&self) -> &[u8]; fn get(&self, key: &str) -> Option<&String>; fn set(&mut self, key: String, value: String); fn set_request_summary(&mut self, summary: Layer8ContextRequestSummary); diff --git a/pingora-router/src/handler.rs b/pingora-router/src/handler.rs index e78d707..d67d081 100644 --- a/pingora-router/src/handler.rs +++ b/pingora-router/src/handler.rs @@ -70,8 +70,8 @@ pub trait ResponseBodyTrait: Serialize + for<'de> Deserialize<'de> + Debug { serde_json::to_vec(self).unwrap() } - fn from_bytes(bytes: Vec) -> Result, serde_json::Error> { - serde_json::from_slice(&bytes) + fn from_bytes(bytes: &[u8]) -> Result, serde_json::Error> { + serde_json::from_slice(bytes) } /// Override this method to handle error serialization if your handler implements @@ -93,8 +93,8 @@ pub trait RequestBodyTrait: Serialize + for<'de> Deserialize<'de> + Debug { serde_json::to_vec(self).unwrap() } - fn from_bytes(bytes: Vec) -> Result, serde_json::Error> { - serde_json::from_slice(&bytes) + fn from_bytes(bytes: &[u8]) -> Result, serde_json::Error> { + serde_json::from_slice(bytes) } } @@ -112,9 +112,9 @@ pub trait RequestBodyTrait: Serialize + for<'de> Deserialize<'de> + Debug { /// ResponseBodyTrait` (constructed from the JSON error), and a 400 Bad Request status. pub trait DefaultHandlerTrait { fn parse_request_body( - data: &Vec, + data: &[u8], ) -> Result> { - match T::from_bytes(data.clone()) { + match T::from_bytes(data) { Ok(body) => Ok(*body), Err(e) => Err(E::from_json_err(e)), } diff --git a/reverse-proxy/Cargo.toml b/reverse-proxy/Cargo.toml index f971e24..861b5b6 100644 --- a/reverse-proxy/Cargo.toml +++ b/reverse-proxy/Cargo.toml @@ -5,25 +5,30 @@ edition = "2024" [dependencies] async-trait = "0.1" +bincode = "2.0.1" +boring = "4.17.0" bytes = "1.10.1" +chrono = "0.4.40" +config = "0.15.11" +dotenv = "0.15.0" +env_logger = "0.11.7" +envy = "0.4.2" +futures = "0.3.31" +hex = "0.4.3" +ntor = { git = "https://github.com/globe-and-citizen/ntor.git", branch = "fix/use-bincode-instead-of-json" } +once_cell = "1.21.3" +pingora = { version = "0.5.0", features = ["lb", "boringssl"] } +pingora-router = { path = "../pingora-router", version = "0.1.0" } +reqwest = { version = "0.11", default-features = false, features = [ + "json", + "rustls-tls", +] } serde = { version = "1.0.219", features = ["derive"] } serde_json = "1.0.140" serde_yaml = "0.8.26" -chrono = "0.4.40" -reqwest = { version="0.11", default-features=false, features=["json", "rustls-tls"] } -tokio-rustls = "0.26.2" tokio = "1.44.2" -pingora-router = { path = "../pingora-router", version = "0.1.0" } -pingora = { version = "0.5.0", features = ["lb", "boringssl"] } -futures = "0.3.31" -boring = "4.17.0" -once_cell = "1.21.3" -dotenv = "0.15.0" -ntor = { git = "https://github.com/globe-and-citizen/ntor.git", tag = "0.1.1" } -config = "0.15.11" +tokio-rustls = "0.26.2" toml = "0.8.23" -uuid = { version = "1.16.0", features = ["v4"] } utils = { path = "../utils", version = "0.1.0" } -envy = "0.4.2" -hex = "0.4.3" tracing = "0.1.41" +uuid = { version = "1.16.0", features = ["v4"] } diff --git a/reverse-proxy/src/handler/init_tunnel/handler.rs b/reverse-proxy/src/handler/init_tunnel/handler.rs index a14d8d2..596c2c1 100644 --- a/reverse-proxy/src/handler/init_tunnel/handler.rs +++ b/reverse-proxy/src/handler/init_tunnel/handler.rs @@ -1,11 +1,12 @@ -use crate::handler::common::types::ErrorResponse; -use crate::handler::init_tunnel::InitEncryptedTunnelRequest; use pingora::http::StatusCode; use pingora_router::ctx::{Layer8Context, Layer8ContextTrait}; use pingora_router::handler::{APIHandlerResponse, DefaultHandlerTrait, ResponseBodyTrait}; +use crate::handler::common::types::ErrorResponse; +use crate::handler::init_tunnel::InitEncryptedTunnelRequest; + /// Struct containing only associated methods (no instance methods or fields) -pub(crate) struct InitTunnelHandler {} +pub(crate) struct InitTunnelHandler; impl DefaultHandlerTrait for InitTunnelHandler {} diff --git a/reverse-proxy/src/handler/mod.rs b/reverse-proxy/src/handler/mod.rs index c0e5828..4b8d867 100644 --- a/reverse-proxy/src/handler/mod.rs +++ b/reverse-proxy/src/handler/mod.rs @@ -1,16 +1,12 @@ -use crate::config::{HandlerConfig, RPConfig}; -use crate::handler::common::consts::LogTypes; -use crate::handler::healthcheck::{RpHealthcheckError, RpHealthcheckSuccess}; -use init_tunnel::InitEncryptedTunnelResponse; -use init_tunnel::handler::InitTunnelHandler; +use std::collections::HashMap; +use std::sync::{Mutex, MutexGuard}; + use ntor::common::{InitSessionMessage, NTorParty}; use ntor::server::NTorServer; use pingora::http::StatusCode; use pingora_router::ctx::{Layer8Context, Layer8ContextTrait}; use pingora_router::handler::{APIHandlerResponse, ResponseBodyTrait}; use proxy::handler::ProxyHandler; -use std::collections::HashMap; -use std::sync::{Mutex, MutexGuard}; use tracing::info; use utils::jwt::JWTClaims; use utils::new_uuid; @@ -20,6 +16,12 @@ mod healthcheck; mod init_tunnel; mod proxy; +use crate::config::{HandlerConfig, RPConfig}; +use crate::handler::common::consts::LogTypes; +use crate::handler::healthcheck::{RpHealthcheckError, RpHealthcheckSuccess}; +use init_tunnel::InitEncryptedTunnelResponse; +use init_tunnel::handler::InitTunnelHandler; + thread_local! { // static NTOR_SHARED_SECRETS: Mutex>> = Mutex::new(HashMap::new()); @@ -103,8 +105,8 @@ impl ReverseHandler { }; let response = InitEncryptedTunnelResponse { - public_key: init_session_response.public_key(), - t_b_hash: init_session_response.t_b_hash(), + public_key: init_session_response.public_key().to_vec(), + t_b_hash: init_session_response.t_b_hash().to_vec(), int_rp_jwt, fp_rp_jwt, }; @@ -116,11 +118,12 @@ impl ReverseHandler { "Save new nTor session: {}", ntor_session_id ); + NTOR_SHARED_SECRETS.with(|memory| { let mut guard: MutexGuard>> = memory.lock().unwrap(); guard.insert( ntor_session_id, - ntor_server.get_shared_secret().unwrap_or_default(), + ntor_server.get_shared_secret().unwrap_or_default().to_vec(), ); }); @@ -177,17 +180,24 @@ impl ReverseHandler { Err(res) => return res, }; - return match ProxyHandler::encrypt_response_body( + let encrypted_message = ProxyHandler::encrypt_response_body( wrapped_response, self.config.ntor_server_id.clone(), shared_secret, - ) { - Ok(encrypted_message) => APIHandlerResponse { - status: StatusCode::OK, - body: Some(encrypted_message.to_bytes()), - }, + ); + + match encrypted_message { + Ok(encrypted_message) => { + let data = bincode::encode_to_vec(&encrypted_message, bincode::config::standard()) + .expect("this struct is bincode serializable"); + + APIHandlerResponse { + status: StatusCode::OK, + body: Some(data), + } + } Err(res) => res, - }; + } } pub async fn handle_healthcheck(&self, ctx: &mut Layer8Context) -> APIHandlerResponse { diff --git a/reverse-proxy/src/handler/proxy/handler.rs b/reverse-proxy/src/handler/proxy/handler.rs index 814e59f..cf80e3d 100644 --- a/reverse-proxy/src/handler/proxy/handler.rs +++ b/reverse-proxy/src/handler/proxy/handler.rs @@ -1,7 +1,4 @@ -use crate::handler::common::consts::{HeaderKeys, LogTypes}; -use crate::handler::common::types::ErrorResponse; -use crate::handler::proxy::{EncryptedMessage, L8RequestObject, L8ResponseObject}; -use ntor::common::NTorParty; +use ntor::common::{EncryptedMessage, NTorParty}; use ntor::server::NTorServer; use pingora::http::StatusCode; use pingora_router::ctx::{Layer8Context, Layer8ContextTrait}; @@ -9,9 +6,12 @@ use pingora_router::handler::{APIHandlerResponse, DefaultHandlerTrait, ResponseB use reqwest::Client; use reqwest::header::HeaderMap; use tracing::{debug, error, info}; -use utils::bytes_to_json; use utils::jwt::JWTClaims; +use crate::handler::common::consts::{HeaderKeys, LogTypes}; +use crate::handler::common::types::ErrorResponse; +use crate::handler::proxy::{L8RequestObject, L8ResponseObject}; + /// Struct containing only associated methods (no instance methods or fields) pub struct ProxyHandler {} @@ -21,7 +21,7 @@ impl ProxyHandler { fn validate_jwt_token( ctx: &mut Layer8Context, header_key: &str, - jwt_secret: &Vec, + jwt_secret: &[u8], ) -> Result { match ctx.get_request_header().get(header_key) { None => { @@ -110,28 +110,24 @@ impl ProxyHandler { pub(crate) fn validate_request_body( ctx: &mut Layer8Context, ) -> Result { - let correlation_id = ctx.get_correlation_id(); - - match ProxyHandler::parse_request_body::( - &ctx.get_request_body(), - ) { - Ok(res) => Ok(res), + match bincode::decode_from_slice(&ctx.get_request_body(), bincode::config::standard()) { + Ok((data, _)) => Ok(data), Err(err) => { - let body = match err { - None => None, - Some(err_response) => { - error!( - %correlation_id, - log_type=LogTypes::HANDLE_PROXY_REQUEST, - "Error parsing request body: {}", - err_response.error - ); - Some(err_response.to_bytes()) - } - }; + let correlation_id = ctx.get_correlation_id(); + error!( + %correlation_id, + log_type=LogTypes::HANDLE_PROXY_REQUEST, + "Error parsing request body: {}", + err.to_string() + ); + Err(APIHandlerResponse { status: StatusCode::BAD_REQUEST, - body, + body: Some( + format!("Failed to parse request body: {}", err) + .as_bytes() + .to_vec(), + ), }) } } @@ -143,34 +139,29 @@ impl ProxyHandler { shared_secret: Vec, ) -> Result { let mut ntor_server = NTorServer::new(ntor_server_id); - ntor_server.set_shared_secret(shared_secret.clone()); + ntor_server.set_shared_secret(shared_secret); // Decrypt the request body using nTor shared secret - let decrypted_data = ntor_server - .decrypt(ntor::common::EncryptedMessage { - nonce: <[u8; 12]>::try_from(request_body.nonce).unwrap_or_default(), - data: request_body.data, - }) - .map_err(|err| { - return APIHandlerResponse { - status: StatusCode::BAD_REQUEST, - body: Some(format!("Decryption failed: {}", err).as_bytes().to_vec()), - }; - })?; - // let decrypted_data = request_body.data; - - // parse decrypted data into WrappedUserRequest - let wrapped_request: L8RequestObject = bytes_to_json(decrypted_data).map_err(|err| { + let decrypted_data = ntor_server.decrypt(request_body).map_err(|err| { return APIHandlerResponse { status: StatusCode::BAD_REQUEST, - body: Some( - format!("Failed to parse request body: {}", err) - .as_bytes() - .to_vec(), - ), + body: Some(format!("Decryption failed: {}", err).as_bytes().to_vec()), }; })?; + // parse decrypted data into WrappedUserRequest + let wrapped_request: L8RequestObject = + serde_json::from_slice(&decrypted_data).map_err(|err| { + return APIHandlerResponse { + status: StatusCode::BAD_REQUEST, + body: Some( + format!("Failed to parse request body: {}", err) + .as_bytes() + .to_vec(), + ), + }; + })?; + Ok(wrapped_request) } @@ -272,19 +263,14 @@ impl ProxyHandler { let mut ntor_server = NTorServer::new(ntor_server_id); ntor_server.set_shared_secret(shared_secret); - let data = response_body.to_bytes(); + let data = serde_json::to_vec(&response_body).expect("the struct is json serializable"); // Encrypt the response body using nTor shared secret - let encrypted_data = ntor_server.encrypt(data).map_err(|err| { + ntor_server.encrypt(&data).map_err(|err| { return APIHandlerResponse { status: StatusCode::INTERNAL_SERVER_ERROR, body: Some(format!("Encryption failed: {}", err).as_bytes().to_vec()), }; - })?; - - Ok(EncryptedMessage { - nonce: encrypted_data.nonce.to_vec(), - data: encrypted_data.data, }) } } diff --git a/reverse-proxy/src/handler/proxy/mod.rs b/reverse-proxy/src/handler/proxy/mod.rs index bdf4e0a..f5b6c73 100644 --- a/reverse-proxy/src/handler/proxy/mod.rs +++ b/reverse-proxy/src/handler/proxy/mod.rs @@ -4,15 +4,6 @@ use pingora_router::handler::{RequestBodyTrait, ResponseBodyTrait}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; -#[derive(Serialize, Deserialize, Debug)] -pub struct EncryptedMessage { - pub nonce: Vec, - pub data: Vec, -} - -impl RequestBodyTrait for EncryptedMessage {} -impl ResponseBodyTrait for EncryptedMessage {} - #[derive(Serialize, Deserialize, Debug)] pub struct L8RequestObject { pub method: String, diff --git a/reverse-proxy/src/main.rs b/reverse-proxy/src/main.rs index b7b71b1..a03eab0 100644 --- a/reverse-proxy/src/main.rs +++ b/reverse-proxy/src/main.rs @@ -1,20 +1,20 @@ -mod handler; -mod proxy; -mod tls_conf; +use std::sync::Arc; -use crate::config::RPConfig; -use crate::handler::ReverseHandler; -use crate::proxy::ReverseProxy; use futures::FutureExt; use pingora::server::Server; use pingora::server::configuration::Opt; use pingora::{listeners::tls::TlsSettings, prelude::http_proxy_service}; use pingora_router::handler::APIHandler; use pingora_router::router::Router; -use std::sync::Arc; use tracing::{debug, error}; mod config; +mod handler; +mod proxy; +mod tls_conf; +use config::RPConfig; +use handler::ReverseHandler; +use proxy::ReverseProxy; fn load_config() -> RPConfig { // Load environment variables from .env file diff --git a/reverse-proxy/src/proxy.rs b/reverse-proxy/src/proxy.rs index 1458d2f..3f508e9 100644 --- a/reverse-proxy/src/proxy.rs +++ b/reverse-proxy/src/proxy.rs @@ -1,4 +1,3 @@ -use crate::handler::common::consts::LogTypes; use async_trait::async_trait; use bytes::Bytes; use pingora::http::{ResponseHeader, StatusCode}; @@ -8,6 +7,8 @@ use pingora_router::ctx::{Layer8Context, Layer8ContextTrait}; use pingora_router::router::Router; use tracing::info; +use crate::handler::common::consts::LogTypes; + pub struct ReverseProxy { router: Router, } diff --git a/utils/src/jwt.rs b/utils/src/jwt.rs index 86fb802..37400f4 100644 --- a/utils/src/jwt.rs +++ b/utils/src/jwt.rs @@ -157,13 +157,10 @@ pub fn create_jwt_token(claims: JWTClaims, jwt_secret: &[u8]) -> String { .unwrap() } -pub fn verify_jwt_token( - token: &str, - jwt_secret: &Vec, -) -> Result, JwtError> { +pub fn verify_jwt_token(token: &str, jwt_secret: &[u8]) -> Result, JwtError> { jsonwebtoken::decode::( token, - &DecodingKey::from_secret(jwt_secret.as_slice()), + &DecodingKey::from_secret(jwt_secret), &Validation::default(), ) } diff --git a/utils/src/lib.rs b/utils/src/lib.rs index c43b7ef..75955f0 100644 --- a/utils/src/lib.rs +++ b/utils/src/lib.rs @@ -1,18 +1,17 @@ -pub mod cert; -pub mod deserializer; -pub mod jwt; -pub mod log; - -use url::Url; +use std::collections::HashMap; use base64::Engine; use base64::engine::general_purpose; use reqwest::header::{HeaderMap, HeaderName, HeaderValue}; -use std::collections::HashMap; -use uuid::Uuid; - use serde::{Deserialize, Serialize}; use tracing::error; +use url::Url; +use uuid::Uuid; + +pub mod cert; +pub mod deserializer; +pub mod jwt; +pub mod log; pub fn to_reqwest_header(map: HashMap) -> HeaderMap { let mut header_map = HeaderMap::new(); @@ -54,7 +53,7 @@ where serde_json::from_slice::(&bytes) } -pub fn bytes_to_string(bytes: &Vec) -> String { +pub fn bytes_to_string(bytes: &[u8]) -> String { String::from_utf8_lossy(bytes).to_string() }