Skip to content

Commit

Permalink
feat(rust): project ticket show warning when using high values for …
Browse files Browse the repository at this point in the history
…ticket duration/usage
  • Loading branch information
adrianbenavides committed Oct 29, 2024
1 parent ee8fed6 commit 8d28714
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ use crate::authenticator::{
AuthorityEnrollmentTokenRepository, AuthorityMembersRepository, EnrollmentToken,
};

pub(super) const MAX_TOKEN_DURATION: Duration = Duration::from_secs(600);
pub const DEFAULT_TOKEN_DURATION: Duration = Duration::from_secs(60 * 10);
pub const MAX_RECOMMENDED_TOKEN_DURATION: Duration = Duration::from_secs(60 * 60 * 24 * 5);
pub const DEFAULT_TOKEN_USAGE_COUNT: u64 = 1;
pub const MAX_RECOMMENDED_TOKEN_USAGE_COUNT: u64 = 10;

pub struct EnrollmentTokenIssuerError(pub String);

Expand Down Expand Up @@ -90,8 +93,8 @@ impl EnrollmentTokenIssuer {
.take(10)
.map(char::from)
.collect();
let max_token_duration = token_duration.unwrap_or(MAX_TOKEN_DURATION);
let ttl_count = ttl_count.unwrap_or(1);
let max_token_duration = token_duration.unwrap_or(DEFAULT_TOKEN_DURATION);
let ttl_count = ttl_count.unwrap_or(DEFAULT_TOKEN_USAGE_COUNT);
let now = now()?;
let expires_at = now + max_token_duration.as_secs();
let tkn = EnrollmentToken {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,13 +269,17 @@ impl LegacyEnrollmentTicket {
.map_err(|_err| ApiError::core("Failed to authenticate with Okta"))?;
Ok(hex::encode(serialized))
}
}

impl FromStr for LegacyEnrollmentTicket {
type Err = ApiError;

pub fn from_str(data: &str) -> Result<Self> {
if let Ok(data) = hex::decode(data) {
fn from_str(contents: &str) -> std::result::Result<Self, Self::Err> {
if let Ok(data) = hex::decode(contents) {
Ok(serde_json::from_slice(&data)
.map_err(|_err| ApiError::core("Failed to decode EnrollmentTicket json"))?)
} else {
Ok(serde_json::from_str(data)
Ok(serde_json::from_str(contents)
.map_err(|_err| ApiError::core("Failed to decode EnrollmentTicket json"))?)
}
}
Expand Down
1 change: 1 addition & 0 deletions implementations/rust/ockam/ockam_app_lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//!
//! It exposes C APIs that can be used by the frontend to interact with the application.
//!
#![recursion_limit = "256"]

use thiserror::Error;
mod api;
Expand Down
35 changes: 28 additions & 7 deletions implementations/rust/ockam/ockam_command/src/project/ticket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ use ockam::Context;
use ockam_api::authenticator::direct::{
OCKAM_ROLE_ATTRIBUTE_ENROLLER_VALUE, OCKAM_ROLE_ATTRIBUTE_KEY, OCKAM_TLS_ATTRIBUTE_KEY,
};
use ockam_api::authenticator::enrollment_tokens::TokenIssuer;
use ockam_api::authenticator::enrollment_tokens::{
TokenIssuer, MAX_RECOMMENDED_TOKEN_DURATION, MAX_RECOMMENDED_TOKEN_USAGE_COUNT,
};
use ockam_api::cli_state::{ExportedEnrollmentTicket, ProjectRoute};
use ockam_api::colors::color_primary;
use ockam_api::nodes::InMemoryNode;
use ockam_api::{fmt_log, fmt_ok};
use ockam_api::{fmt_log, fmt_ok, fmt_warn};
use ockam_multiaddr::MultiAddr;

const LONG_ABOUT: &str = include_str!("./static/ticket/long_about.txt");
Expand Down Expand Up @@ -81,29 +83,30 @@ impl Command for TicketCommand {
}

async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> Result<()> {
let cmd = self.parse_args(&opts).await?;
let identity = opts
.state
.get_identity_name_or_default(&self.identity_opts.identity_name)
.get_identity_name_or_default(&cmd.identity_opts.identity_name)
.await?;

let node = InMemoryNode::start_with_project_name(
ctx,
&opts.state,
self.trust_opts.project_name.clone(),
cmd.trust_opts.project_name.clone(),
)
.await?;

let project = opts
.state
.projects()
.get_project_by_name_or_default(&self.trust_opts.project_name)
.get_project_by_name_or_default(&cmd.trust_opts.project_name)
.await?;

let authority_node_client = node
.create_authority_client_with_project(ctx, &project, Some(identity))
.await?;

let attributes = self.attributes()?;
let attributes = cmd.attributes()?;
debug!(attributes = ?attributes, "Attributes passed");

// Request an enrollment token that a future member can use to get a
Expand All @@ -114,7 +117,7 @@ impl Command for TicketCommand {
pb.set_message("Creating an enrollment ticket...");
}
authority_node_client
.create_token(ctx, attributes, self.expires_in, self.usage_count)
.create_token(ctx, attributes, cmd.expires_in, cmd.usage_count)
.await
.map_err(Error::Retry)?
};
Expand Down Expand Up @@ -159,6 +162,24 @@ impl Command for TicketCommand {
}

impl TicketCommand {
async fn parse_args(mut self, opts: &CommandGlobalOpts) -> Result<Self> {
// Handle expires_in and usage_count limits
if let (Some(expires_in), Some(usage_count)) = (self.expires_in, self.usage_count) {
if expires_in >= MAX_RECOMMENDED_TOKEN_DURATION
&& usage_count >= MAX_RECOMMENDED_TOKEN_USAGE_COUNT
{
opts.terminal.write_line(
fmt_warn!(
"You are creating a ticket with a long expiration time and a high usage count\n"
) + &fmt_log!(
"This is a security risk. Please consider reducing the values according to the ticket's intended use\n"
),
)?;
}
}
Ok(self)
}

fn attributes(&self) -> Result<BTreeMap<String, String>> {
let mut attributes = BTreeMap::new();
for attr in &self.attributes {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,19 @@ EOF
# Check that the identity can reach the project
run_success $OCKAM message send hi --to "/project/default/service/echo"
}

@test "nodes - create with config, using a json-encoded enrollment ticket" {
$OCKAM project ticket --output json >"$OCKAM_HOME/enrollment.ticket"
export ENROLLMENT_TICKET="$OCKAM_HOME/enrollment.ticket"

cat <<EOF >"$OCKAM_HOME/config.yaml"
ticket: ${ENROLLMENT_TICKET}
name: n1
EOF

run_success "$OCKAM" node create "$OCKAM_HOME/config.yaml"
run_success "$OCKAM" node show n1

# Check that the identity can reach the project
run_success $OCKAM message send hi --to "/project/default/service/echo"
}

0 comments on commit 8d28714

Please sign in to comment.