Skip to content

Commit

Permalink
Merge pull request #68 from wa5i/approle
Browse files Browse the repository at this point in the history
Add the approle auth module
  • Loading branch information
InfoHunter authored Sep 18, 2024
2 parents ccc46df + 4055b7a commit aa85b17
Show file tree
Hide file tree
Showing 58 changed files with 7,590 additions and 289 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ jobs:
- uses: actions/checkout@v3
- name: Build
run: cargo build --verbose
- name: ulimit -n
run: ulimit -n 65535
- name: Run tests
run: cargo test --verbose

Expand Down Expand Up @@ -83,6 +85,8 @@ jobs:
run: diesel setup --database-url mysql://root:password@127.0.0.1:3306/vault
- name: Build
run: cargo build --features storage_mysql --verbose
- name: ulimit -n
run: ulimit -n 65535
- name: Run tests
run: cargo test --verbose
- name: Build crate doc
Expand Down
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ glob = "0.3"
serde_asn1_der = "0.8"
base64 = "0.22"
ipnetwork = "0.20"
blake2b_simd = "1.0"
derive_more = "0.99.17"
dashmap = "5.5"
tokio = "1.38"

# optional dependencies
openssl = { version = "0.10.64", optional = true }
Expand Down
8 changes: 2 additions & 6 deletions src/cli/command/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,8 @@ use openssl::{
use sysexits::ExitCode;

use crate::{
cli::config,
core::Core,
errors::RvError,
http,
storage,
EXIT_CODE_INSUFFICIENT_PARAMS, EXIT_CODE_LOAD_CONFIG_FAILURE, EXIT_CODE_OK,
cli::config, core::Core, errors::RvError, http, storage, EXIT_CODE_INSUFFICIENT_PARAMS,
EXIT_CODE_LOAD_CONFIG_FAILURE, EXIT_CODE_OK,
};

pub const WORK_DIR_PATH_DEFAULT: &str = "/tmp/rusty_vault";
Expand Down
30 changes: 19 additions & 11 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,35 @@

use std::{
any::Any,
cell::RefCell,
collections::HashMap,
sync::{Arc, Mutex},
sync::{Arc, RwLock},
};

use dashmap::DashMap;

#[derive(Debug)]
pub struct Context {
data_map: Mutex<HashMap<String, Arc<RefCell<dyn Any>>>>,
data_map: DashMap<String, Arc<dyn Any + Send + Sync>>,
data_map_mut: DashMap<String, Arc<RwLock<dyn Any + Send + Sync>>>,
}

impl Context {
pub fn new() -> Self {
Self { data_map: Mutex::new(HashMap::new()) }
Self { data_map: DashMap::new(), data_map_mut: DashMap::new() }
}

pub fn set_mut(&self, key: &str, data: Arc<RwLock<dyn Any + Send + Sync>>) {
self.data_map_mut.insert(key.to_string(), data);
}

pub fn get_mut(&self, key: &str) -> Option<Arc<RwLock<dyn Any + Send + Sync>>> {
self.data_map_mut.get(key).map(|r| Arc::clone(&r.value()))
}

pub fn set(&self, key: &str, data: Arc<RefCell<dyn Any>>) {
let mut data_map = self.data_map.lock().unwrap();
data_map.insert(key.to_string(), data);
pub fn set(&self, key: &str, data: Arc<dyn Any + Send + Sync>) {
self.data_map.insert(key.to_string(), data);
}

pub fn get(&self, key: &str) -> Option<Arc<RefCell<dyn Any>>> {
let data_map = self.data_map.lock().unwrap();
data_map.get(key).cloned()
pub fn get(&self, key: &str) -> Option<Arc<dyn Any + Send + Sync>> {
self.data_map.get(key).map(|r| Arc::clone(&*r))
}
}
41 changes: 29 additions & 12 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,38 @@

use std::{
collections::HashMap,
sync::{Arc, Mutex, RwLock},
ops::{Deref, DerefMut},
sync::{Arc, Mutex, RwLock},
};

use as_any::Downcast;
use go_defer::defer;
use serde::{Deserialize, Serialize};
use zeroize::Zeroizing;

use crate::{
cli::config::Config,
errors::RvError,
handler::Handler,
logical::{Backend, Request, Response},
module_manager::ModuleManager,
modules::{auth::AuthModule, credential::userpass::UserPassModule, pki::PkiModule},
modules::{
auth::AuthModule,
credential::{
userpass::UserPassModule,
approle::AppRoleModule,
},
pki::PkiModule,
},
mount::MountTable,
router::Router,
shamir::{ShamirSecret, SHAMIR_OVERHEAD},
storage::{
barrier::SecurityBarrier,
barrier_aes_gcm,
barrier_view::BarrierView,
physical,
Backend as PhysicalBackend,
BackendEntry as PhysicalBackendEntry,
barrier::SecurityBarrier, barrier_aes_gcm, barrier_view::BarrierView, physical, Backend as PhysicalBackend,
BackendEntry as PhysicalBackendEntry, Storage,
},
};

use zeroize::Zeroizing;

pub type LogicalBackendNewFunc = dyn Fn(Arc<RwLock<Core>>) -> Result<Arc<dyn Backend>, RvError> + Send + Sync;

pub const SEAL_CONFIG_PATH: &str = "core/seal-config";
Expand Down Expand Up @@ -118,6 +120,10 @@ impl Core {
let userpass_module = UserPassModule::new(self);
self.module_manager.add_module(Arc::new(RwLock::new(Box::new(userpass_module))))?;

// add credential module: approle
let approle_module = AppRoleModule::new(self);
self.module_manager.add_module(Arc::new(RwLock::new(Box::new(approle_module))))?;

Ok(())
}

Expand Down Expand Up @@ -156,8 +162,11 @@ impl Core {
if seal_config.secret_shares == 1 {
init_result.secret_shares.deref_mut().push(master_key.deref().clone());
} else {
init_result.secret_shares =
ShamirSecret::split(master_key.deref().as_slice(), seal_config.secret_shares, seal_config.secret_threshold)?;
init_result.secret_shares = ShamirSecret::split(
master_key.deref().as_slice(),
seal_config.secret_shares,
seal_config.secret_threshold,
)?;
}

log::debug!("master_key: {}", hex::encode(master_key.deref()));
Expand Down Expand Up @@ -197,6 +206,14 @@ impl Core {
Ok(init_result)
}

pub fn get_system_view(&self) -> Option<Arc<BarrierView>> {
self.system_view.clone()
}

pub fn get_system_storage(&self) -> &dyn Storage {
self.system_view.as_ref().unwrap().as_storage()
}

pub fn get_logical_backend(&self, logical_type: &str) -> Result<Arc<LogicalBackendNewFunc>, RvError> {
let logical_backends = self.logical_backends.lock().unwrap();
if let Some(backend) = logical_backends.get(logical_type) {
Expand Down
2 changes: 1 addition & 1 deletion src/http/logical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
core::Core,
errors::RvError,
http::{request_auth, response_error, response_json_ok, response_ok, Connection},
logical::{Operation, Connection as ReqConnection, Response},
logical::{Connection as ReqConnection, Operation, Response},
};

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ pub mod module_manager;
pub mod modules;
pub mod mount;
pub mod router;
#[cfg(feature = "storage_mysql")]
pub mod schema;
pub mod shamir;
pub mod storage;
pub mod utils;
#[cfg(feature = "storage_mysql")]
pub mod schema;

/// Exit ok
pub const EXIT_CODE_OK: sysexits::ExitCode = sysexits::ExitCode::Ok;
Expand Down
23 changes: 17 additions & 6 deletions src/logical/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ use std::{collections::HashMap, sync::Arc};
use regex::Regex;
use serde_json::{Map, Value};

use super::{path::Path, request::Request, response::Response, secret::Secret, FieldType, Backend, Operation};
use crate::errors::RvError;
use super::{path::Path, request::Request, response::Response, secret::Secret, Backend, FieldType, Operation};
use crate::{context::Context, errors::RvError};

type BackendOperationHandler = dyn Fn(&dyn Backend, &mut Request) -> Result<Option<Response>, RvError> + Send + Sync;

pub const CTX_KEY_BACKEND_PATH: &str = "backend.path";

#[derive(Clone)]
pub struct LogicalBackend {
pub paths: Vec<Arc<Path>>,
Expand All @@ -17,6 +19,7 @@ pub struct LogicalBackend {
pub help: String,
pub secrets: Vec<Arc<Secret>>,
pub auth_renew_handler: Option<Arc<BackendOperationHandler>>,
pub ctx: Arc<Context>,
}

impl Backend for LogicalBackend {
Expand Down Expand Up @@ -58,6 +61,10 @@ impl Backend for LogicalBackend {
Some(self.root_paths.clone())
}

fn get_ctx(&self) -> Option<Arc<Context>> {
Some(Arc::clone(&self.ctx))
}

fn handle_request(&self, req: &mut Request) -> Result<Option<Response>, RvError> {
if req.storage.is_none() {
return Err(RvError::ErrRequestNotReady);
Expand Down Expand Up @@ -86,6 +93,7 @@ impl Backend for LogicalBackend {
req.match_path = Some(path.clone());
for operation in &path.operations {
if operation.op == req.operation {
self.ctx.set(CTX_KEY_BACKEND_PATH, path.clone());
let ret = operation.handle_request(self, req);
self.clear_secret_field(req);
return ret;
Expand Down Expand Up @@ -113,6 +121,7 @@ impl LogicalBackend {
help: String::new(),
secrets: Vec::new(),
auth_renew_handler: None,
ctx: Arc::new(Context::new()),
}
}

Expand Down Expand Up @@ -251,9 +260,8 @@ mod test {

use super::*;
use crate::{
logical::{Field, field::FieldTrait, FieldType, PathOperation},
new_fields, new_fields_internal, new_path, new_path_internal, new_secret, new_secret_internal,
storage,
logical::{field::FieldTrait, Field, FieldType, PathOperation},
new_fields, new_fields_internal, new_path, new_path_internal, new_secret, new_secret_internal, storage,
};

struct MyTest;
Expand Down Expand Up @@ -429,7 +437,10 @@ mod test {
"mytype": 1,
"mypath": "/pp",
"mypassword": "123qwe",
}).as_object().unwrap().clone();
})
.as_object()
.unwrap()
.clone();
req.body = Some(body);
req.storage = Some(Arc::new(barrier));
assert!(logical_backend.handle_request(&mut req).is_ok());
Expand Down
5 changes: 1 addition & 4 deletions src/logical/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ pub struct Connection {

impl Default for Connection {
fn default() -> Self {
Self {
peer_addr: String::new(),
peer_tls_cert: None,
}
Self { peer_addr: String::new(), peer_tls_cert: None }
}
}
Loading

0 comments on commit aa85b17

Please sign in to comment.