Skip to content

Commit

Permalink
RPC: Check for passwords in admin endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
marcospb19-cw committed Dec 16, 2024
1 parent 37c4617 commit f9f9e42
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 16 deletions.
4 changes: 4 additions & 0 deletions src/eth/primitives/stratus_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ pub enum StratusError {
#[strum(props(kind = "server_state"))]
StratusNotFollower,

#[error("Incorrect password, cancelling operation.")]
#[strum(props(kind = "server_state"))]
InvalidPassword,

#[error("Stratus node is already in the process of changing mode.")]
#[strum(props(kind = "server_state"))]
ModeChangeInProgress,
Expand Down
63 changes: 47 additions & 16 deletions src/eth/rpc/rpc_server.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! RPC server for HTTP and WS.
use std::collections::HashMap;
use std::env;
use std::ops::Deref;
use std::str::FromStr;
use std::sync::Arc;
Expand Down Expand Up @@ -256,6 +257,13 @@ where
Ok(())
}

fn validate_password(pass: &str) -> Result<(), StratusError> {
if env::var_os("ADMIN_PASSWORD").is_some_and(|real_pass| real_pass != pass) {
return Err(StratusError::InvalidPassword);
}
Ok(())
}

// -----------------------------------------------------------------------------
// Debug
// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -320,7 +328,9 @@ fn stratus_reset(_: Params<'_>, ctx: Arc<RpcContext>, _: Extensions) -> Result<J

static MODE_CHANGE_SEMAPHORE: Lazy<Semaphore> = Lazy::new(|| Semaphore::new(1));

async fn stratus_change_to_leader(_: Params<'_>, ctx: Arc<RpcContext>, ext: Extensions) -> Result<JsonValue, StratusError> {
async fn stratus_change_to_leader(params: Params<'_>, ctx: Arc<RpcContext>, ext: Extensions) -> Result<JsonValue, StratusError> {
let (_, password) = next_rpc_param::<&str>(params.sequence())?;
validate_password(password)?;
let permit = MODE_CHANGE_SEMAPHORE.try_acquire();
let _permit: SemaphorePermit = match permit {
Ok(permit) => permit,
Expand Down Expand Up @@ -370,6 +380,8 @@ async fn stratus_change_to_leader(_: Params<'_>, ctx: Arc<RpcContext>, ext: Exte
}

async fn stratus_change_to_follower(params: Params<'_>, ctx: Arc<RpcContext>, ext: Extensions) -> Result<JsonValue, StratusError> {
let (_, password) = next_rpc_param::<&str>(params.sequence())?;
validate_password(password)?;
let permit = MODE_CHANGE_SEMAPHORE.try_acquire();
let _permit: SemaphorePermit = match permit {
Ok(permit) => permit,
Expand Down Expand Up @@ -424,7 +436,9 @@ async fn stratus_change_to_follower(params: Params<'_>, ctx: Arc<RpcContext>, ex
}

async fn stratus_init_importer(params: Params<'_>, ctx: Arc<RpcContext>, _: Extensions) -> Result<JsonValue, StratusError> {
let (params, external_rpc) = next_rpc_param::<String>(params.sequence())?;
let (params, password) = next_rpc_param::<&str>(params.sequence())?;
validate_password(password)?;
let (params, external_rpc) = next_rpc_param::<String>(params)?;
let (params, external_rpc_ws) = next_rpc_param::<String>(params)?;
let (params, raw_external_rpc_timeout) = next_rpc_param::<String>(params)?;
let (_, raw_sync_interval) = next_rpc_param::<String>(params)?;
Expand All @@ -449,7 +463,9 @@ async fn stratus_init_importer(params: Params<'_>, ctx: Arc<RpcContext>, _: Exte
importer_config.init_follower_importer(ctx).await
}

fn stratus_shutdown_importer(_: Params<'_>, ctx: &RpcContext, _: &Extensions) -> Result<JsonValue, StratusError> {
fn stratus_shutdown_importer(params: Params<'_>, ctx: &RpcContext, _: &Extensions) -> Result<JsonValue, StratusError> {
let (_, password) = next_rpc_param::<&str>(params.sequence())?;
validate_password(password)?;
if GlobalState::get_node_mode() != NodeMode::Follower {
tracing::error!("node is currently not a follower");
return Err(StratusError::StratusNotFollower);
Expand All @@ -469,7 +485,10 @@ fn stratus_shutdown_importer(_: Params<'_>, ctx: &RpcContext, _: &Extensions) ->
}

async fn stratus_change_miner_mode(params: Params<'_>, ctx: Arc<RpcContext>, _: Extensions) -> Result<JsonValue, StratusError> {
let (_, mode_str) = next_rpc_param::<String>(params.sequence())?;
let (params, password) = next_rpc_param::<&str>(params.sequence())?;
validate_password(password)?;
let (_, mode_str) = next_rpc_param::<String>(params)?;

let mode = MinerMode::from_str(&mode_str).map_err(|e| {
tracing::error!(reason = ?e, "failed to parse miner mode");
StratusError::MinerModeParamInvalid
Expand Down Expand Up @@ -530,34 +549,46 @@ async fn change_miner_mode(new_mode: MinerMode, ctx: &RpcContext) -> Result<Json
Ok(json!(true))
}

fn stratus_enable_unknown_clients(_: Params<'_>, _: &RpcContext, _: &Extensions) -> bool {
fn stratus_enable_unknown_clients(params: Params<'_>, _: &RpcContext, _: &Extensions) -> Result<bool, StratusError> {
let (_, password) = next_rpc_param::<&str>(params.sequence())?;
validate_password(password)?;
GlobalState::set_unknown_client_enabled(true);
GlobalState::is_unknown_client_enabled()
Ok(GlobalState::is_unknown_client_enabled())
}

fn stratus_disable_unknown_clients(_: Params<'_>, _: &RpcContext, _: &Extensions) -> bool {
fn stratus_disable_unknown_clients(params: Params<'_>, _: &RpcContext, _: &Extensions) -> Result<bool, StratusError> {
let (_, password) = next_rpc_param::<&str>(params.sequence())?;
validate_password(password)?;
GlobalState::set_unknown_client_enabled(false);
GlobalState::is_unknown_client_enabled()
Ok(GlobalState::is_unknown_client_enabled())
}

fn stratus_enable_transactions(_: Params<'_>, _: &RpcContext, _: &Extensions) -> bool {
fn stratus_enable_transactions(params: Params<'_>, _: &RpcContext, _: &Extensions) -> Result<bool, StratusError> {
let (_, password) = next_rpc_param::<&str>(params.sequence())?;
validate_password(password)?;
GlobalState::set_transactions_enabled(true);
GlobalState::is_transactions_enabled()
Ok(GlobalState::is_transactions_enabled())
}

fn stratus_disable_transactions(_: Params<'_>, _: &RpcContext, _: &Extensions) -> bool {
fn stratus_disable_transactions(params: Params<'_>, _: &RpcContext, _: &Extensions) -> Result<bool, StratusError> {
let (_, password) = next_rpc_param::<&str>(params.sequence())?;
validate_password(password)?;
GlobalState::set_transactions_enabled(false);
GlobalState::is_transactions_enabled()
Ok(GlobalState::is_transactions_enabled())
}

fn stratus_enable_miner(_: Params<'_>, ctx: &RpcContext, _: &Extensions) -> bool {
fn stratus_enable_miner(params: Params<'_>, ctx: &RpcContext, _: &Extensions) -> Result<bool, StratusError> {
let (_, password) = next_rpc_param::<&str>(params.sequence())?;
validate_password(password)?;
ctx.miner.unpause();
true
Ok(true)
}

fn stratus_disable_miner(_: Params<'_>, ctx: &RpcContext, _: &Extensions) -> bool {
fn stratus_disable_miner(params: Params<'_>, ctx: &RpcContext, _: &Extensions) -> Result<bool, StratusError> {
let (_, password) = next_rpc_param::<&str>(params.sequence())?;
validate_password(password)?;
ctx.miner.pause();
false
Ok(false)
}

/// Returns the count of executed transactions waiting to enter the next block.
Expand Down

0 comments on commit f9f9e42

Please sign in to comment.