Skip to content

Commit

Permalink
feat(rust): add optional --identity argument to secure-channel create
Browse files Browse the repository at this point in the history
  • Loading branch information
Mo-Fatah authored and adrianbenavides committed Jan 12, 2023
1 parent 0b1841f commit e083b52
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,16 @@ pub struct CreateSecureChannelRequest<'a> {
#[b(1)] pub addr: CowStr<'a>,
#[b(2)] pub authorized_identifiers: Option<Vec<CowStr<'a>>>,
#[n(3)] pub credential_exchange_mode: CredentialExchangeMode,
#[n(4)] pub timeout: Option<Duration>
#[n(4)] pub timeout: Option<Duration>,
#[b(5)] pub identity: Option<CowStr<'a>>,
}

impl<'a> CreateSecureChannelRequest<'a> {
pub fn new(
addr: &MultiAddr,
authorized_identifiers: Option<Vec<IdentityIdentifier>>,
credential_exchange_mode: CredentialExchangeMode,
identity: Option<String>,
) -> Self {
Self {
#[cfg(feature = "tag")]
Expand All @@ -50,6 +52,7 @@ impl<'a> CreateSecureChannelRequest<'a> {
.map(|x| x.into_iter().map(|y| y.to_string().into()).collect()),
credential_exchange_mode,
timeout: None,
identity: identity.map(|x| x.into()),
}
}
}
Expand Down
17 changes: 12 additions & 5 deletions implementations/rust/ockam/ockam_api/src/nodes/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ impl NodeManager {
addr: &MultiAddr,
auth: Option<IdentityIdentifier>,
timeout: Option<Duration>,
ctx: &Context,
) -> Result<(MultiAddr, MultiAddr)> {
if let Some(p) = addr.first() {
if p.code() == Project::CODE {
Expand All @@ -346,7 +347,9 @@ impl NodeManager {
multiaddr_to_route(&a).ok_or_else(|| ApiError::generic("invalid multiaddr"))?;
let i = Some(vec![i]);
let m = CredentialExchangeMode::Oneway;
let w = self.create_secure_channel_impl(r, i, m, timeout).await?;
let w = self
.create_secure_channel_impl(r, i, m, timeout, None, ctx)
.await?;
let a = MultiAddr::default().try_with(addr.iter().skip(1))?;
return Ok((try_address_to_multiaddr(&w)?, a));
}
Expand All @@ -358,7 +361,9 @@ impl NodeManager {
let r = multiaddr_to_route(&a).ok_or_else(|| ApiError::generic("invalid multiaddr"))?;
let i = auth.clone().map(|i| vec![i]);
let m = CredentialExchangeMode::Mutual;
let w = self.create_secure_channel_impl(r, i, m, timeout).await?;
let w = self
.create_secure_channel_impl(r, i, m, timeout, None, ctx)
.await?;
return Ok((try_address_to_multiaddr(&w)?, b));
}

Expand All @@ -368,7 +373,9 @@ impl NodeManager {
multiaddr_to_route(addr).ok_or_else(|| ApiError::generic("invalid multiaddr"))?;
let i = auth.clone().map(|i| vec![i]);
let m = CredentialExchangeMode::Mutual;
let w = self.create_secure_channel_impl(r, i, m, timeout).await?;
let w = self
.create_secure_channel_impl(r, i, m, timeout, None, ctx)
.await?;
return Ok((try_address_to_multiaddr(&w)?, MultiAddr::default()));
}

Expand Down Expand Up @@ -487,7 +494,7 @@ impl NodeManagerWorker {
.to_vec()?
}
(Post, ["node", "secure_channel"]) => {
self.create_secure_channel(req, dec).await?.to_vec()?
self.create_secure_channel(req, dec, ctx).await?.to_vec()?
}
(Delete, ["node", "secure_channel"]) => {
self.delete_secure_channel(req, dec).await?.to_vec()?
Expand Down Expand Up @@ -553,7 +560,7 @@ impl NodeManagerWorker {
let node_manager = self.node_manager.read().await;
self.get_outlets(req, &node_manager.registry).to_vec()?
}
(Post, ["node", "inlet"]) => self.create_inlet(req, dec).await?.to_vec()?,
(Post, ["node", "inlet"]) => self.create_inlet(req, dec, ctx).await?.to_vec()?,
(Post, ["node", "outlet"]) => self.create_outlet(req, dec).await?.to_vec()?,
(Delete, ["node", "portal"]) => todo!(),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl NodeManagerWorker {
debug!(addr = %req.address(), alias = ?req.alias(), "Handling CreateForwarder request");

let (sec_chan, suffix) = node_manager
.connect(req.address(), req.authorized(), None)
.connect(req.address(), req.authorized(), None, ctx)
.await?;

let full = sec_chan.clone().try_with(&suffix)?;
Expand Down Expand Up @@ -117,7 +117,7 @@ fn replacer(
let mut this = manager.write().await;
let _ = this.delete_secure_channel(&prev).await;
let timeout = Some(util::MAX_CONNECT_TIME);
let (sec, rest) = this.connect(&addr, auth, timeout).await?;
let (sec, rest) = this.connect(&addr, auth, timeout, ctx.as_ref()).await?;
let a = sec.clone().try_with(&rest)?;
let r = multiaddr_to_route(&a)
.ok_or_else(|| ApiError::message(format!("invalid multiaddr: {a}")))?;
Expand Down
16 changes: 11 additions & 5 deletions implementations/rust/ockam/ockam_api/src/nodes/service/portals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ use crate::{multiaddr_to_route, try_multiaddr_to_addr};
use minicbor::Decoder;
use ockam::compat::asynchronous::RwLock;
use ockam::compat::tokio::time::timeout;
use ockam::{Address, Result};
use ockam::{Address, AsyncTryClone, Result};
use ockam_abac::expr::{and, eq, ident, str};
use ockam_abac::{Action, Env, PolicyAccessControl, PolicyStorage, Resource};
use ockam_core::api::{Request, Response, ResponseBuilder};
use ockam_core::{AllowAll, IncomingAccessControl};
use ockam_identity::IdentityIdentifier;
use ockam_multiaddr::proto::{Project, Secure, Service};
use ockam_multiaddr::{MultiAddr, Protocol};
use ockam_node::Context;
use std::sync::Arc;

use super::{NodeManager, NodeManagerWorker};
Expand Down Expand Up @@ -106,6 +107,7 @@ impl NodeManagerWorker {
&mut self,
req: &Request<'_>,
dec: &mut Decoder<'_>,
ctx: &Context,
) -> Result<ResponseBuilder<InletStatus<'a>>> {
let manager = self.node_manager.clone();
let mut node_manager = self.node_manager.write().await;
Expand Down Expand Up @@ -134,11 +136,11 @@ impl NodeManagerWorker {
// to another node.
let (outer, rest) = {
let (sec1, rest) = node_manager
.connect(req.outlet_addr(), req.authorized(), None)
.connect(req.outlet_addr(), req.authorized(), None, ctx)
.await?;
if !sec1.is_empty() && rest.matches(0, &[Service::CODE.into(), Secure::CODE.into()]) {
let addr = sec1.clone().try_with(rest.iter().take(2))?;
let (sec2, _) = node_manager.connect(&addr, None, None).await?;
let (sec2, _) = node_manager.connect(&addr, None, None, ctx).await?;
(sec1, sec2.try_with(rest.iter().skip(2))?)
} else {
(MultiAddr::default(), sec1.try_with(&rest)?)
Expand Down Expand Up @@ -206,13 +208,15 @@ impl NodeManagerWorker {
let mut s = Session::new(without_outlet_address(rest));
s.data().put(INLET_WORKER, worker_addr.clone());
s.data().put(OUTER_CHAN, outer);
let ctx = Arc::new(ctx.async_try_clone().await?);
let repl = replacer(
manager,
s.data(),
listen_addr.clone(),
req.outlet_addr().clone(),
req.authorized(),
access_control.clone(),
ctx,
);
s.set_replacer(repl);
node_manager.sessions.lock().unwrap().add(s);
Expand Down Expand Up @@ -332,6 +336,7 @@ fn replacer(
addr: MultiAddr,
auth: Option<IdentityIdentifier>,
access: Arc<dyn IncomingAccessControl>,
ctx: Arc<Context>,
) -> Replacer {
Box::new(move |prev| {
let addr = addr.clone();
Expand All @@ -340,6 +345,7 @@ fn replacer(
let manager = manager.clone();
let access = access.clone();
let data = data.clone();
let ctx = ctx.clone();
Box::pin(async move {
debug!(%prev, %addr, "creating new tcp inlet");
// The future that recreates the inlet:
Expand All @@ -360,7 +366,7 @@ fn replacer(
// Now a connection attempt is made:

let rest = {
let (sec1, rest) = this.connect(&addr, auth, timeout).await?;
let (sec1, rest) = this.connect(&addr, auth, timeout, ctx.as_ref()).await?;
if !sec1.is_empty()
&& rest.matches(0, &[Service::CODE.into(), Secure::CODE.into()])
{
Expand All @@ -370,7 +376,7 @@ fn replacer(
data.put(OUTER_CHAN, sec1.clone());

let addr = sec1.clone().try_with(rest.iter().take(2))?;
let (sec2, _) = this.connect(&addr, None, timeout).await?;
let (sec2, _) = this.connect(&addr, None, timeout, ctx.as_ref()).await?;
sec2.try_with(rest.iter().skip(2))?
} else {
sec1.try_with(&rest)?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::time::Duration;

use super::{map_multiaddr_err, NodeManagerWorker};
use crate::cli_state::CliState;
use crate::error::ApiError;
use crate::nodes::models::secure_channel::{
CreateSecureChannelListenerRequest, CreateSecureChannelRequest, CreateSecureChannelResponse,
Expand All @@ -14,9 +15,10 @@ use minicbor::Decoder;
use ockam::identity::TrustEveryonePolicy;
use ockam::{Address, Result, Route};
use ockam_core::api::{Request, Response, ResponseBuilder};
use ockam_core::{route, AsyncTryClone};
use ockam_core::{route, AsyncTryClone, CowStr};
use ockam_identity::{Identity, IdentityIdentifier, TrustMultiIdentifiersPolicy};
use ockam_multiaddr::MultiAddr;
use ockam_node::Context;
use ockam_vault::Vault;

impl NodeManager {
Expand Down Expand Up @@ -90,8 +92,22 @@ impl NodeManager {
authorized_identifiers: Option<Vec<IdentityIdentifier>>,
credential_exchange_mode: CredentialExchangeMode,
timeout: Option<Duration>,
identity_name: Option<CowStr<'_>>,
ctx: &Context,
) -> Result<Address> {
let identity = self.identity()?.async_try_clone().await?;
let identity = if let Some(identity) = identity_name {
let state = CliState::new()?;
let idt_config = state.identities.get(&identity)?.config;
match idt_config.get(ctx, self.vault()?).await {
Ok(idt) => idt,
Err(_) => {
let default_vault = &state.vaults.default()?.config.get().await?;
idt_config.get(ctx, default_vault).await?
}
}
} else {
self.identity()?.async_try_clone().await?
};

let sc_addr = self
.create_secure_channel_internal(&identity, sc_route, authorized_identifiers, timeout)
Expand Down Expand Up @@ -217,13 +233,15 @@ impl NodeManagerWorker {
&mut self,
req: &Request<'_>,
dec: &mut Decoder<'_>,
ctx: &Context,
) -> Result<ResponseBuilder<CreateSecureChannelResponse<'a>>> {
let mut node_manager = self.node_manager.write().await;
let CreateSecureChannelRequest {
addr,
authorized_identifiers,
credential_exchange_mode,
timeout,
identity,
..
} = dec.decode()?;

Expand Down Expand Up @@ -252,6 +270,8 @@ impl NodeManagerWorker {
authorized_identifiers,
credential_exchange_mode,
timeout,
identity,
ctx,
)
.await?;

Expand Down
21 changes: 14 additions & 7 deletions implementations/rust/ockam/ockam_command/src/project/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ use std::io::Write;
use std::str::FromStr;

use anyhow::{anyhow, Context as _, Result};
use ockam_core::api::Request;
use tracing::debug;

use ockam::identity::IdentityIdentifier;
use ockam::TcpTransport;
use ockam_api::cloud::project::Project;
use ockam_api::config::lookup::{LookupMeta, ProjectAuthority, ProjectLookup};
use ockam_api::multiaddr_to_addr;
use ockam_api::nodes::models::secure_channel::*;
use ockam_api::nodes::models::{self, secure_channel::*};
use ockam_multiaddr::{MultiAddr, Protocol};

use crate::util::api::CloudOpts;
Expand Down Expand Up @@ -108,12 +109,16 @@ async fn create_secure_channel_to_project(
) -> crate::Result<MultiAddr> {
let authorized_identifier = vec![IdentityIdentifier::from_str(project_identity)?];
let mut rpc = RpcBuilder::new(ctx, opts, api_node).tcp(tcp)?.build();
rpc.request(api::create_secure_channel(

let payload = models::secure_channel::CreateSecureChannelRequest::new(
project_access_route,
Some(authorized_identifier),
credential_exchange_mode,
))
.await?;
None,
);
let req = Request::post("/node/secure_channel").body(payload);
rpc.request(req).await?;

let sc = rpc.parse_response::<CreateSecureChannelResponse>()?;
Ok(sc.addr()?)
}
Expand All @@ -128,12 +133,14 @@ pub async fn create_secure_channel_to_authority(
let mut rpc = RpcBuilder::new(ctx, opts, node_name).build();
debug!(%addr, "establishing secure channel to project authority");
let allowed = vec![authority.identity_id().clone()];
rpc.request(api::create_secure_channel(
let payload = models::secure_channel::CreateSecureChannelRequest::new(
addr,
Some(allowed),
CredentialExchangeMode::None,
))
.await?;
None,
);
let req = Request::post("/node/secure_channel").body(payload);
rpc.request(req).await?;
let res = rpc.parse_response::<CreateSecureChannelResponse>()?;
let addr = res.addr()?;
Ok(addr)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
use crate::{
help,
util::{api, exitcode, extract_address_value, node_rpc},
util::{exitcode, extract_address_value, node_rpc},
CommandGlobalOpts, OutputFormat, Result,
};

use anyhow::Context as _;
use clap::Args;
use colorful::Colorful;
use ockam_core::api::Request;
use serde_json::json;

use crate::secure_channel::HELP_DETAIL;
use crate::util::api::CloudOpts;
use crate::util::{is_tty, RpcBuilder};
use ockam::{identity::IdentityIdentifier, route, Context, TcpTransport};
use ockam_api::config::lookup::ConfigLookup;
use ockam_api::nodes::models::secure_channel::CredentialExchangeMode;
use ockam_api::{
clean_multiaddr, nodes::models::secure_channel::CreateSecureChannelResponse, route_to_multiaddr,
};
use ockam_api::{config::lookup::ConfigLookup, nodes::models};
use ockam_multiaddr::MultiAddr;

/// Create Secure Channels
Expand All @@ -39,6 +40,9 @@ pub struct CreateCommand {
/// Orchestrator address to resolve projects present in the `at` argument
#[command(flatten)]
cloud_opts: CloudOpts,

#[arg(value_name = "IDENTITY", long, display_order = 802)]
identity: Option<String>,
}

impl CreateCommand {
Expand Down Expand Up @@ -162,8 +166,14 @@ async fn rpc(ctx: Context, (opts, cmd): (CommandGlobalOpts, CreateCommand)) -> R

// Delegate the request to create a secure channel to the from node.
let mut rpc = RpcBuilder::new(&ctx, &opts, from).tcp(&tcp)?.build();
let request =
api::create_secure_channel(to, authorized_identifiers, CredentialExchangeMode::Mutual);

let payload = models::secure_channel::CreateSecureChannelRequest::new(
to,
authorized_identifiers,
CredentialExchangeMode::Mutual,
cmd.identity.clone(),
);
let request = Request::post("/node/secure_channel").body(payload);

rpc.request(request).await?;
let response = rpc.parse_response::<CreateSecureChannelResponse>()?;
Expand Down
15 changes: 0 additions & 15 deletions implementations/rust/ockam/ockam_command/src/util/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use tracing::trace;
use ockam::identity::IdentityIdentifier;
use ockam::Result;
use ockam_api::cloud::{BareCloudRequestWrapper, CloudRequestWrapper};
use ockam_api::nodes::models::secure_channel::CredentialExchangeMode;
use ockam_api::nodes::*;
use ockam_core::api::RequestBuilder;
use ockam_core::api::{Request, Response};
Expand Down Expand Up @@ -76,20 +75,6 @@ pub(crate) fn list_secure_channels() -> RequestBuilder<'static, ()> {
Request::get("/node/secure_channel")
}

/// Construct a request to create Secure Channels
pub(crate) fn create_secure_channel(
addr: &MultiAddr,
authorized_identifiers: Option<Vec<IdentityIdentifier>>,
credential_exchange_mode: CredentialExchangeMode,
) -> RequestBuilder<'static, models::secure_channel::CreateSecureChannelRequest<'static>> {
let payload = models::secure_channel::CreateSecureChannelRequest::new(
addr,
authorized_identifiers,
credential_exchange_mode,
);
Request::post("/node/secure_channel").body(payload)
}

pub(crate) fn delete_secure_channel(
addr: &Address,
) -> RequestBuilder<'static, models::secure_channel::DeleteSecureChannelRequest<'static>> {
Expand Down

0 comments on commit e083b52

Please sign in to comment.