Skip to content

Commit

Permalink
add a enable_cookie auth option to config and use it in all tests
Browse files Browse the repository at this point in the history
  • Loading branch information
oxarbitrage committed Oct 13, 2024
1 parent 7a7c14a commit e734e39
Show file tree
Hide file tree
Showing 18 changed files with 42 additions and 105 deletions.
2 changes: 0 additions & 2 deletions zebra-node-services/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ getblocktemplate-rpcs = [
# Tool and test features

rpc-client = [
"base64",
"color-eyre",
"jsonrpc-core",
"reqwest",
Expand All @@ -43,7 +42,6 @@ zebra-chain = { path = "../zebra-chain" , version = "1.0.0-beta.39" }
# Optional dependencies

# Tool and test feature rpc-client
base64 = { version = "0.22.1", optional = true }
color-eyre = { version = "0.6.3", optional = true }
jsonrpc-core = { version = "18.0.0", optional = true }
# Security: avoid default dependency on openssl
Expand Down
12 changes: 1 addition & 11 deletions zebra-node-services/src/rpc_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use std::net::SocketAddr;

use base64::{engine::general_purpose::URL_SAFE, Engine as _};
use reqwest::Client;

use crate::BoxError;
Expand All @@ -14,16 +13,14 @@ use crate::BoxError;
pub struct RpcRequestClient {
client: Client,
rpc_address: SocketAddr,
auth_cookie: String,
}

impl RpcRequestClient {
/// Creates new RPCRequestSender
pub fn new(rpc_address: SocketAddr, auth_cookie: String) -> Self {
pub fn new(rpc_address: SocketAddr) -> Self {
Self {
client: Client::new(),
rpc_address,
auth_cookie,
}
}

Expand All @@ -42,13 +39,6 @@ impl RpcRequestClient {
r#"{{"jsonrpc": "2.0", "method": "{method}", "params": {params}, "id":123 }}"#
))
.header("Content-Type", "application/json")
.header(
"Authorization",
format!(
"Basic {}",
URL_SAFE.encode(format!("__cookie__:{}", &self.auth_cookie))
),
)
.send()
.await
}
Expand Down
8 changes: 7 additions & 1 deletion zebra-rpc/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ pub struct Config {

/// The directory where Zebra stores RPC cookies.
pub cookie_dir: PathBuf,

/// Enable cookie-based authentication for RPCs.
pub enable_cookie_auth: bool,
}

// This impl isn't derivable because it depends on features.
Expand All @@ -100,8 +103,11 @@ impl Default for Config {
// Debug options are always off by default.
debug_force_finished_sync: false,

//
// Use the default cache dir for cookies.
cookie_dir: default_cache_dir(),

// Enable cookie-based authentication by default.
enable_cookie_auth: true,
}
}
}
3 changes: 3 additions & 0 deletions zebra-rpc/src/server/http_request_compatibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ impl FixHttpRequestMiddleware {

/// Check if the request is authenticated.
pub fn check_credentials(&self, headers: &header::HeaderMap) -> bool {
if !self.0.enable_cookie_auth {
return true;
}
headers
.get(header::AUTHORIZATION)
.and_then(|auth_header| auth_header.to_str().ok())
Expand Down
4 changes: 4 additions & 0 deletions zebra-rpc/src/server/tests/vectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ fn rpc_server_spawn(parallel_cpu_threads: bool) {
parallel_cpu_threads: if parallel_cpu_threads { 2 } else { 1 },
debug_force_finished_sync: false,
cookie_dir: Default::default(),
enable_cookie_auth: false,
};

let rt = tokio::runtime::Runtime::new().unwrap();
Expand Down Expand Up @@ -136,6 +137,7 @@ fn rpc_server_spawn_unallocated_port(parallel_cpu_threads: bool, do_shutdown: bo
parallel_cpu_threads: if parallel_cpu_threads { 0 } else { 1 },
debug_force_finished_sync: false,
cookie_dir: Default::default(),
enable_cookie_auth: false,
};

let rt = tokio::runtime::Runtime::new().unwrap();
Expand Down Expand Up @@ -218,6 +220,7 @@ fn rpc_server_spawn_port_conflict() {
parallel_cpu_threads: 1,
debug_force_finished_sync: false,
cookie_dir: Default::default(),
enable_cookie_auth: false,
};

let rt = tokio::runtime::Runtime::new().unwrap();
Expand Down Expand Up @@ -330,6 +333,7 @@ fn rpc_server_spawn_port_conflict_parallel_auto() {
parallel_cpu_threads: 2,
debug_force_finished_sync: false,
cookie_dir: Default::default(),
enable_cookie_auth: false,
};

let rt = tokio::runtime::Runtime::new().unwrap();
Expand Down
14 changes: 3 additions & 11 deletions zebra-rpc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,8 @@ impl TrustedChainSync {
rpc_address: SocketAddr,
db: ZebraDb,
non_finalized_state_sender: tokio::sync::watch::Sender<NonFinalizedState>,
cookie_dir: std::path::PathBuf,
) -> (LatestChainTip, ChainTipChange, JoinHandle<()>) {
let auth_cookie = crate::server::cookie::get(cookie_dir).expect("cookie should exist");
let rpc_client = RpcRequestClient::new(rpc_address, auth_cookie);
let rpc_client = RpcRequestClient::new(rpc_address);
let non_finalized_state = NonFinalizedState::new(&db.network());
let (chain_tip_sender, latest_chain_tip, chain_tip_change) =
ChainTipSender::new(None, &db.network());
Expand Down Expand Up @@ -318,7 +316,6 @@ impl TrustedChainSync {
/// a [`JoinHandle`] for the sync task.
pub fn init_read_state_with_syncer(
state_config: zebra_state::Config,
rpc_config: crate::config::Config,
network: &Network,
rpc_address: SocketAddr,
) -> tokio::task::JoinHandle<
Expand All @@ -340,13 +337,8 @@ pub fn init_read_state_with_syncer(

let (read_state, db, non_finalized_state_sender) =
spawn_init_read_only(state_config, &network).await?;
let (latest_chain_tip, chain_tip_change, sync_task) = TrustedChainSync::spawn(
rpc_address,
db,
non_finalized_state_sender,
rpc_config.cookie_dir,
)
.await;
let (latest_chain_tip, chain_tip_change, sync_task) =
TrustedChainSync::spawn(rpc_address, db, non_finalized_state_sender).await;
Ok((read_state, latest_chain_tip, chain_tip_change, sync_task))
})
}
Expand Down
4 changes: 0 additions & 4 deletions zebra-scan/src/bin/scanner/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use structopt::StructOpt;
use tracing::*;

use zebra_chain::{block::Height, parameters::Network};
use zebra_rpc::config::Config as RpcConfig;
use zebra_state::SaplingScanningKey;

use core::net::SocketAddr;
Expand Down Expand Up @@ -75,13 +74,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
db_config,
};

let rpc_config = RpcConfig::default();

// Get a read-only state and the database.
let (read_state, _latest_chain_tip, chain_tip_change, sync_task) =
zebra_rpc::sync::init_read_state_with_syncer(
state_config,
rpc_config,
&network,
args.zebra_rpc_listen_addr,
)
Expand Down
4 changes: 1 addition & 3 deletions zebra-utils/src/bin/zebra-checkpoints/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ use zebra_node_services::{
constants::{MAX_CHECKPOINT_BYTE_COUNT, MAX_CHECKPOINT_HEIGHT_GAP},
rpc_client::RpcRequestClient,
};
use zebra_rpc::{config::Config as RpcConfig, server::cookie};
use zebra_utils::init_tracing;

pub mod args;
Expand Down Expand Up @@ -61,8 +60,7 @@ where
let addr = our_args
.addr
.unwrap_or_else(|| "127.0.0.1:8232".parse().expect("valid address"));
let auth_cookie = cookie::get(RpcConfig::default().cookie_dir).expect("cookie should exist");
let client = RpcRequestClient::new(addr, auth_cookie);
let client = RpcRequestClient::new(addr);

// Launch a request with the RPC method and arguments
//
Expand Down
43 changes: 8 additions & 35 deletions zebrad/tests/acceptance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,7 @@ use zebra_chain::{
use zebra_consensus::ParameterCheckpoint;
use zebra_node_services::rpc_client::RpcRequestClient;

use zebra_rpc::{
config::Config as RpcConfig,
server::{cookie, OPENED_RPC_ENDPOINT_MSG},
};
use zebra_rpc::server::OPENED_RPC_ENDPOINT_MSG;

use zebra_state::{constants::LOCK_FILE_ERROR, state_database_format_version_in_code};

Expand Down Expand Up @@ -1596,11 +1593,8 @@ async fn rpc_endpoint(parallel_cpu_threads: bool) -> Result<()> {

// Wait until port is open.
let rpc_address = read_listen_addr_from_logs(&mut child, OPENED_RPC_ENDPOINT_MSG)?;
// Get the auth cookie
let auth_cookie =
zebra_rpc::server::cookie::get(config.rpc.cookie_dir).expect("cookie should exist");
// Create an http client
let client = RpcRequestClient::new(rpc_address, auth_cookie);
let client = RpcRequestClient::new(rpc_address);

// Make the call to the `getinfo` RPC method
let res = client.call("getinfo", "[]".to_string()).await?;
Expand Down Expand Up @@ -1656,12 +1650,8 @@ async fn rpc_endpoint_client_content_type() -> Result<()> {
// Wait until port is open.
let rpc_address = read_listen_addr_from_logs(&mut child, OPENED_RPC_ENDPOINT_MSG)?;

// Get the auth cookie
let auth_cookie =
zebra_rpc::server::cookie::get(config.rpc.cookie_dir).expect("cookie should exist");

// Create an http client
let client = RpcRequestClient::new(rpc_address, auth_cookie);
let client = RpcRequestClient::new(rpc_address);

// Call to `getinfo` RPC method with a no content type.
let res = client
Expand Down Expand Up @@ -1746,12 +1736,8 @@ fn non_blocking_logger() -> Result<()> {
// Wait until port is open.
let rpc_address = read_listen_addr_from_logs(&mut child, OPENED_RPC_ENDPOINT_MSG)?;

// Get the auth cookie
let auth_cookie =
zebra_rpc::server::cookie::get(config.rpc.cookie_dir).expect("cookie should exist");

// Create an http client
let client = RpcRequestClient::new(rpc_address, auth_cookie);
let client = RpcRequestClient::new(rpc_address);

// Most of Zebra's lines are 100-200 characters long, so 500 requests should print enough to fill the unix pipe,
// fill the channel that tracing logs are queued onto, and drop logs rather than block execution.
Expand Down Expand Up @@ -2422,10 +2408,7 @@ async fn fully_synced_rpc_test() -> Result<()> {

zebrad.expect_stdout_line_matches(format!("Opened RPC endpoint at {zebra_rpc_address}"))?;

// Get the auth cookie
let auth_cookie = cookie::get(RpcConfig::default().cookie_dir).expect("cookie should exist");

let client = RpcRequestClient::new(zebra_rpc_address, auth_cookie);
let client = RpcRequestClient::new(zebra_rpc_address);

// Make a getblock test that works only on synced node (high block number).
// The block is before the mandatory checkpoint, so the checkpoint cached state can be used
Expand Down Expand Up @@ -2865,14 +2848,9 @@ async fn fully_synced_rpc_z_getsubtreesbyindex_snapshot_test() -> Result<()> {
// Wait for zebrad to load the full cached blockchain.
zebrad.expect_stdout_line_matches(SYNC_FINISHED_REGEX)?;

// Get the auth cookie
let auth_cookie = cookie::get(RpcConfig::default().cookie_dir).expect("cookie should exist");

// Create an http client
let client = RpcRequestClient::new(
zebra_rpc_address.expect("already checked that address is valid"),
auth_cookie,
);
let client =
RpcRequestClient::new(zebra_rpc_address.expect("already checked that address is valid"));

// Create test vector matrix
let zcashd_test_vectors = vec![
Expand Down Expand Up @@ -3024,7 +3002,6 @@ async fn trusted_chain_sync_handles_forks_correctly() -> Result<()> {
let (read_state, _latest_chain_tip, mut chain_tip_change, _sync_task) =
zebra_rpc::sync::init_read_state_with_syncer(
config.state.clone(),
config.rpc,
&config.network.network,
rpc_address,
)
Expand All @@ -3042,10 +3019,7 @@ async fn trusted_chain_sync_handles_forks_correctly() -> Result<()> {

tracing::info!("got genesis chain tip change, submitting more blocks ..");

// Get the auth cookie
let auth_cookie = cookie::get(config.state.cache_dir).expect("cookie should exist");

let rpc_client = RpcRequestClient::new(rpc_address, auth_cookie);
let rpc_client = RpcRequestClient::new(rpc_address);
let mut blocks = Vec::new();
for _ in 0..10 {
let (block, height) = rpc_client.submit_block_from_template().await?;
Expand Down Expand Up @@ -3239,7 +3213,6 @@ async fn trusted_chain_sync_handles_forks_correctly() -> Result<()> {
let (_read_state, _latest_chain_tip, mut chain_tip_change, _sync_task) =
zebra_rpc::sync::init_read_state_with_syncer(
config.state,
config.rpc,
&config.network.network,
rpc_address,
)
Expand Down
6 changes: 1 addition & 5 deletions zebrad/tests/common/cached_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ use zebra_chain::{
};
use zebra_node_services::rpc_client::RpcRequestClient;

use zebra_rpc::{config::Config as RpcConfig, server::cookie};
use zebra_state::{ChainTipChange, LatestChainTip, MAX_BLOCK_REORG_HEIGHT};
use zebra_test::command::TestChild;

Expand Down Expand Up @@ -230,11 +229,8 @@ pub async fn get_raw_future_blocks(
true,
)?;

// Get the auth cookie
let auth_cookie = cookie::get(RpcConfig::default().cookie_dir).expect("cookie should exist");

// Create an http client
let rpc_client = RpcRequestClient::new(rpc_address, auth_cookie);
let rpc_client = RpcRequestClient::new(rpc_address);

let blockchain_info: serde_json::Value = serde_json::from_str(
&rpc_client
Expand Down
4 changes: 1 addition & 3 deletions zebrad/tests/common/checkpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use zebra_chain::{
};
use zebra_consensus::MAX_CHECKPOINT_HEIGHT_GAP;
use zebra_node_services::rpc_client::RpcRequestClient;
use zebra_rpc::{config::Config as RpcConfig, server::cookie};
use zebra_state::state_database_format_version_in_code;
use zebra_test::{
args,
Expand Down Expand Up @@ -505,8 +504,7 @@ pub fn wait_for_zebra_checkpoints_generation<
/// Returns an approximate `zebrad` tip height, using JSON-RPC.
#[tracing::instrument]
pub async fn zebrad_tip_height(zebra_rpc_address: SocketAddr) -> Result<Height> {
let auth_cookie = cookie::get(RpcConfig::default().cookie_dir).expect("cookie should exist");
let client = RpcRequestClient::new(zebra_rpc_address, auth_cookie);
let client = RpcRequestClient::new(zebra_rpc_address);

let zebrad_blockchain_info = client
.text_from_call("getblockchaininfo", "[]".to_string())
Expand Down
1 change: 1 addition & 0 deletions zebrad/tests/common/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ pub fn rpc_port_config(
// Default config, users who want to detect port conflicts configure this
config.rpc.parallel_cpu_threads = 1;
}
config.rpc.enable_cookie_auth = false;

Ok(config)
}
Expand Down
1 change: 1 addition & 0 deletions zebrad/tests/common/configs/v2.0.0-rc.0.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ peerset_initial_target_size = 25
[rpc]
cookie_dir = "cache_dir"
debug_force_finished_sync = false
enable_cookie_auth = true
parallel_cpu_threads = 0

[state]
Expand Down
15 changes: 5 additions & 10 deletions zebrad/tests/common/get_block_template_rpcs/get_block_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,11 @@ use zebra_chain::{
serialization::ZcashSerialize,
};
use zebra_node_services::rpc_client::RpcRequestClient;
use zebra_rpc::{
config::Config as RpcConfig,
methods::get_block_template_rpcs::{
get_block_template::{
proposal::TimeSource, GetBlockTemplate, JsonParameters, ProposalResponse,
},
types::get_block_template::proposal_block_from_template,
use zebra_rpc::methods::get_block_template_rpcs::{
get_block_template::{
proposal::TimeSource, GetBlockTemplate, JsonParameters, ProposalResponse,
},
server::cookie,
types::get_block_template::proposal_block_from_template,
};

use crate::common::{
Expand Down Expand Up @@ -98,8 +94,7 @@ pub(crate) async fn run() -> Result<()> {
true,
)?;

let auth_cookie = cookie::get(RpcConfig::default().cookie_dir).expect("cookie should exist");
let client = RpcRequestClient::new(rpc_address, auth_cookie);
let client = RpcRequestClient::new(rpc_address);

tracing::info!(
"calling getblocktemplate RPC method at {rpc_address}, \
Expand Down
Loading

0 comments on commit e734e39

Please sign in to comment.