diff --git a/services/tunnelbroker/src/cxx_bridge.rs b/services/tunnelbroker/src/cxx_bridge.rs --- a/services/tunnelbroker/src/cxx_bridge.rs +++ b/services/tunnelbroker/src/cxx_bridge.rs @@ -1,9 +1,38 @@ #[cxx::bridge] pub mod ffi { + enum GRPCStatusCodes { + Ok, + Cancelled, + Unknown, + InvalidArgument, + DeadlineExceeded, + NotFound, + AlreadyExists, + PermissionDenied, + ResourceExhausted, + FailedPrecondition, + Aborted, + OutOfRange, + Unimplemented, + Internal, + Unavailable, + DataLoss, + Unauthenticated, + } + struct GrpcResult { + statusCode: GRPCStatusCodes, + errorText: String, + } + struct SessionSignatureResult { + toSign: String, + grpcStatus: GrpcResult, + } + unsafe extern "C++" { include!("tunnelbroker/src/libcpp/Tunnelbroker.h"); pub fn initialize(); pub fn getConfigParameter(parameter: &str) -> Result; pub fn isSandbox() -> Result; + pub fn sessionSignatureHandler(deviceID: &str) -> SessionSignatureResult; } } diff --git a/services/tunnelbroker/src/libcpp/Tunnelbroker.h b/services/tunnelbroker/src/libcpp/Tunnelbroker.h --- a/services/tunnelbroker/src/libcpp/Tunnelbroker.h +++ b/services/tunnelbroker/src/libcpp/Tunnelbroker.h @@ -1,7 +1,9 @@ #pragma once #include "rust/cxx.h" +#include "tunnelbroker/src/cxx_bridge.rs.h" void initialize(); rust::String getConfigParameter(rust::Str parameter); bool isSandbox(); +SessionSignatureResult sessionSignatureHandler(rust::Str deviceID); diff --git a/services/tunnelbroker/src/libcpp/Tunnelbroker.cpp b/services/tunnelbroker/src/libcpp/Tunnelbroker.cpp --- a/services/tunnelbroker/src/libcpp/Tunnelbroker.cpp +++ b/services/tunnelbroker/src/libcpp/Tunnelbroker.cpp @@ -7,6 +7,7 @@ #include "Tools.h" #include "rust/cxx.h" +#include "tunnelbroker/src/cxx_bridge.rs.h" void initialize() { comm::network::tools::InitLogging("tunnelbroker"); @@ -45,3 +46,23 @@ bool isSandbox() { return comm::network::tools::isSandbox(); } + +SessionSignatureResult sessionSignatureHandler(rust::Str deviceID) { + const std::string requestedDeviceID(deviceID); + if (!comm::network::tools::validateDeviceID(requestedDeviceID)) { + return SessionSignatureResult{ + .grpcStatus = { + .statusCode = GRPCStatusCodes::InvalidArgument, + .errorText = + "Format validation failed for deviceID: " + requestedDeviceID}}; + } + const std::string toSign = comm::network::tools::generateRandomString( + comm::network::SIGNATURE_REQUEST_LENGTH); + std::shared_ptr SessionSignItem = + std::make_shared( + toSign, requestedDeviceID); + comm::network::database::DatabaseManager::getInstance().putSessionSignItem( + *SessionSignItem); + + return SessionSignatureResult{.toSign = toSign}; +} diff --git a/services/tunnelbroker/src/server/mod.rs b/services/tunnelbroker/src/server/mod.rs --- a/services/tunnelbroker/src/server/mod.rs +++ b/services/tunnelbroker/src/server/mod.rs @@ -1,4 +1,5 @@ use super::constants; +use super::cxx_bridge::ffi::{sessionSignatureHandler, GRPCStatusCodes}; use anyhow::Result; use futures::Stream; use std::pin::Pin; @@ -7,7 +8,7 @@ use tunnelbroker::tunnelbroker_service_server::{ TunnelbrokerService, TunnelbrokerServiceServer, }; - +mod tools; mod tunnelbroker { tonic::include_proto!("tunnelbroker"); } @@ -19,9 +20,18 @@ impl TunnelbrokerService for TunnelbrokerServiceHandlers { async fn session_signature( &self, - _request: Request, + request: Request, ) -> Result, Status> { - Err(Status::unimplemented("Not implemented yet")) + let result = sessionSignatureHandler(&request.into_inner().device_id); + if result.grpcStatus.statusCode != GRPCStatusCodes::Ok { + return Err(tools::create_tonic_status( + result.grpcStatus.statusCode, + &result.grpcStatus.errorText, + )); + } + Ok(Response::new(tunnelbroker::SessionSignatureResponse { + to_sign: result.toSign, + })) } async fn new_session( diff --git a/services/tunnelbroker/src/server/tools.rs b/services/tunnelbroker/src/server/tools.rs new file mode 100644 --- /dev/null +++ b/services/tunnelbroker/src/server/tools.rs @@ -0,0 +1,26 @@ +use crate::server::GRPCStatusCodes; +use tonic::{Code, Status}; + +pub fn create_tonic_status(code: GRPCStatusCodes, text: &str) -> Status { + let status = match code { + GRPCStatusCodes::Ok => Code::Ok, + GRPCStatusCodes::Cancelled => Code::Cancelled, + GRPCStatusCodes::Unknown => Code::Unknown, + GRPCStatusCodes::InvalidArgument => Code::InvalidArgument, + GRPCStatusCodes::DeadlineExceeded => Code::DeadlineExceeded, + GRPCStatusCodes::NotFound => Code::NotFound, + GRPCStatusCodes::AlreadyExists => Code::AlreadyExists, + GRPCStatusCodes::PermissionDenied => Code::PermissionDenied, + GRPCStatusCodes::ResourceExhausted => Code::ResourceExhausted, + GRPCStatusCodes::FailedPrecondition => Code::FailedPrecondition, + GRPCStatusCodes::Aborted => Code::Aborted, + GRPCStatusCodes::OutOfRange => Code::OutOfRange, + GRPCStatusCodes::Unimplemented => Code::Unimplemented, + GRPCStatusCodes::Internal => Code::Internal, + GRPCStatusCodes::Unavailable => Code::Unavailable, + GRPCStatusCodes::DataLoss => Code::DataLoss, + GRPCStatusCodes::Unauthenticated => Code::Unauthenticated, + _ => Code::Internal, + }; + Status::new(status, text) +}