housekeeping(server): fixed clippy warns
Some checks failed
ci/woodpecker/pr/server-audit Pipeline was successful
ci/woodpecker/pr/server-vet Pipeline failed
ci/woodpecker/pr/server-lint Pipeline failed
ci/woodpecker/pr/server-test Pipeline failed
ci/woodpecker/pr/useragent-analyze Pipeline failed

This commit is contained in:
hdbg
2026-04-04 14:33:20 +02:00
parent 4a50daa7ea
commit 01b12515bd
27 changed files with 114 additions and 96 deletions

View File

@@ -109,9 +109,7 @@ async fn receive_auth_confirmation(
.await
.map_err(|_| AuthError::UnexpectedAuthResponse)?;
let payload = response
.payload
.ok_or(AuthError::UnexpectedAuthResponse)?;
let payload = response.payload.ok_or(AuthError::UnexpectedAuthResponse)?;
match payload {
ClientResponsePayload::AuthResult(result)
if AuthResult::try_from(result).ok() == Some(AuthResult::Success) =>

View File

@@ -1,9 +1,7 @@
use std::io::{self, Write};
use arbiter_client::ArbiterClient;
use arbiter_proto::{ClientMetadata, url::ArbiterUrl};
use tonic::ConnectError;
#[tokio::main]
async fn main() {
@@ -23,8 +21,6 @@ async fn main() {
return;
}
let url = match ArbiterUrl::try_from(input) {
Ok(url) => url,
Err(err) => {

View File

@@ -1,11 +1,16 @@
use arbiter_proto::{ClientMetadata, proto::arbiter_service_client::ArbiterServiceClient, url::ArbiterUrl};
use arbiter_proto::{
ClientMetadata, proto::arbiter_service_client::ArbiterServiceClient, url::ArbiterUrl,
};
use std::sync::Arc;
use tokio::sync::{Mutex, mpsc};
use tokio_stream::wrappers::ReceiverStream;
use tonic::transport::ClientTlsConfig;
use crate::{
StorageError, auth::{AuthError, authenticate}, storage::{FileSigningKeyStorage, SigningKeyStorage}, transport::{BUFFER_LENGTH, ClientTransport}
StorageError,
auth::{AuthError, authenticate},
storage::{FileSigningKeyStorage, SigningKeyStorage},
transport::{BUFFER_LENGTH, ClientTransport},
};
#[cfg(feature = "evm")]
@@ -30,7 +35,6 @@ pub enum Error {
#[error("Storage error")]
Storage(#[from] StorageError),
}
pub struct ArbiterClient {
@@ -61,7 +65,8 @@ impl ArbiterClient {
let anchor = webpki::anchor_from_trusted_cert(&url.ca_cert)?.to_owned();
let tls = ClientTlsConfig::new().trust_anchor(anchor);
let channel = tonic::transport::Channel::from_shared(format!("https://{}:{}", url.host, url.port))?
let channel =
tonic::transport::Channel::from_shared(format!("https://{}:{}", url.host, url.port))?
.tls_config(tls)?
.connect()
.await?;

View File

@@ -1,6 +1,4 @@
use arbiter_proto::proto::{
client::{ClientRequest, ClientResponse},
};
use arbiter_proto::proto::client::{ClientRequest, ClientResponse};
use std::sync::atomic::{AtomicI32, Ordering};
use tokio::sync::mpsc;
@@ -36,9 +34,7 @@ impl ClientTransport {
.map_err(|_| ClientSignError::ChannelClosed)
}
pub(crate) async fn recv(
&mut self,
) -> std::result::Result<ClientResponse, ClientSignError> {
pub(crate) async fn recv(&mut self) -> std::result::Result<ClientResponse, ClientSignError> {
match self.receiver.message().await {
Ok(Some(resp)) => Ok(resp),
Ok(None) => Err(ClientSignError::ConnectionClosed),

View File

@@ -7,7 +7,6 @@ const ARBITER_URL_SCHEME: &str = "arbiter";
const CERT_QUERY_KEY: &str = "cert";
const BOOTSTRAP_TOKEN_QUERY_KEY: &str = "bootstrap_token";
#[derive(Debug, Clone)]
pub struct ArbiterUrl {
pub host: String,

View File

@@ -1,5 +1,6 @@
use arbiter_proto::{
ClientMetadata, format_challenge, transport::{Bi, expect_message}
ClientMetadata, format_challenge,
transport::{Bi, expect_message},
};
use chrono::Utc;
use diesel::{

View File

@@ -3,7 +3,7 @@ use kameo::actor::Spawn;
use tracing::{error, info};
use crate::{
actors::{GlobalActors, client::{ session::ClientSession}},
actors::{GlobalActors, client::session::ClientSession},
db,
};

View File

@@ -9,7 +9,7 @@ use rand::{SeedableRng, rng, rngs::StdRng};
use crate::{
actors::keyholder::{CreateNew, Decrypt, KeyHolder},
db::{
self, DatabaseError, DatabasePool,
DatabaseError, DatabasePool,
models::{self, SqliteTimestamp},
schema,
},

View File

@@ -15,7 +15,7 @@ use crate::actors::{
pub struct Args {
pub client: ClientProfile,
pub user_agents: Vec<ActorRef<UserAgentSession>>,
pub reply: ReplySender<Result<bool, ApprovalError>>
pub reply: ReplySender<Result<bool, ApprovalError>>,
}
pub struct ClientApprovalController {
@@ -39,7 +39,11 @@ impl Actor for ClientApprovalController {
type Error = ();
async fn on_start(
Args { client, mut user_agents, reply }: Self::Args,
Args {
client,
mut user_agents,
reply,
}: Self::Args,
actor_ref: ActorRef<Self>,
) -> Result<Self, Self::Error> {
let this = Self {

View File

@@ -8,7 +8,14 @@ use kameo::{Actor, Reply, messages};
use strum::{EnumDiscriminants, IntoDiscriminant};
use tracing::{error, info};
use crate::{crypto::{KeyCell, derive_key, encryption::v1::{self, Nonce}, integrity::v1::compute_integrity_tag}, safe_cell::SafeCell};
use crate::{
crypto::{
KeyCell, derive_key,
encryption::v1::{self, Nonce},
integrity::v1::compute_integrity_tag,
},
safe_cell::SafeCell,
};
use crate::{
db::{
self,
@@ -18,7 +25,6 @@ use crate::{
safe_cell::SafeCellHandle as _,
};
#[derive(Default, EnumDiscriminants)]
#[strum_discriminants(derive(Reply), vis(pub), name(KeyHolderState))]
enum State {
@@ -112,8 +118,7 @@ impl KeyHolder {
.first(conn)
.await?;
let mut nonce =
Nonce::try_from(current_nonce.as_slice()).map_err(|_| {
let mut nonce = Nonce::try_from(current_nonce.as_slice()).map_err(|_| {
error!(
"Broken database: invalid nonce for root key history id={}",
root_key_id
@@ -265,11 +270,8 @@ impl KeyHolder {
return Err(Error::NotBootstrapped);
};
let tag = compute_integrity_tag(
root_key,
&purpose_tag,
data_parts.iter().map(Vec::as_slice),
);
let tag =
compute_integrity_tag(root_key, &purpose_tag, data_parts.iter().map(Vec::as_slice));
Ok(tag.to_vec())
}

View File

@@ -2,7 +2,7 @@ use std::sync::Mutex;
use alloy::primitives::Address;
use chacha20poly1305::{AeadInPlace, XChaCha20Poly1305, XNonce, aead::KeyInit};
use diesel::{ExpressionMethods as _, QueryDsl as _, SelectableHelper, dsl::update};
use diesel::{ExpressionMethods as _, QueryDsl as _, SelectableHelper};
use diesel_async::{AsyncConnection, RunQueryDsl};
use kameo::error::SendError;
use kameo::messages;
@@ -13,9 +13,8 @@ use x25519_dalek::{EphemeralSecret, PublicKey};
use crate::actors::flow_coordinator::client_connect_approval::ClientApprovalAnswer;
use crate::actors::keyholder::KeyHolderState;
use crate::actors::user_agent::session::Error;
use crate::crypto::integrity::v1::USERAGENT_INTEGRITY_TAG;
use crate::db::models::{
EvmWalletAccess, KeyType, NewEvmWalletAccess, ProgramClient, ProgramClientMetadata,
EvmWalletAccess, NewEvmWalletAccess, ProgramClient, ProgramClientMetadata,
};
use crate::evm::policies::{Grant, SpecificGrant};
use crate::safe_cell::SafeCell;
@@ -24,7 +23,7 @@ use crate::{
evm::{
Generate, ListWallets, UseragentCreateGrant, UseragentDeleteGrant, UseragentListGrants,
},
keyholder::{self, Bootstrap, SignIntegrityTag, TryUnseal},
keyholder::{self, Bootstrap, TryUnseal},
user_agent::session::{
UserAgentSession,
state::{UnsealContext, UserAgentEvents, UserAgentStates},

View File

@@ -116,9 +116,7 @@ impl TlsCa {
];
params
.subject_alt_names
.push(SanType::IpAddress(IpAddr::from([
127, 0, 0, 1,
])));
.push(SanType::IpAddress(IpAddr::from([127, 0, 0, 1])));
let mut dn = DistinguishedName::new();
dn.push(DnType::CommonName, "Arbiter Instance Leaf");

View File

@@ -5,7 +5,6 @@ use rand::{
rngs::{StdRng, SysRng},
};
pub const ROOT_KEY_TAG: &[u8] = "arbiter/seal/v1".as_bytes();
pub const TAG: &[u8] = "arbiter/private-key/v1".as_bytes();
@@ -42,8 +41,6 @@ impl<'a> TryFrom<&'a [u8]> for Nonce {
}
}
pub type Salt = [u8; ArgonSalt::RECOMMENDED_LENGTH];
pub fn generate_salt() -> Salt {
@@ -62,7 +59,10 @@ mod tests {
use std::ops::Deref as _;
use super::*;
use crate::{crypto::derive_key, safe_cell::{SafeCell, SafeCellHandle as _}};
use crate::{
crypto::derive_key,
safe_cell::{SafeCell, SafeCellHandle as _},
};
#[test]
pub fn derive_seal_key_deterministic() {
@@ -93,8 +93,6 @@ mod tests {
assert_ne!(key_ref.as_slice(), &[0u8; 32][..]);
}
#[test]
// We should fuzz this
pub fn test_nonce_increment() {

View File

@@ -5,7 +5,6 @@ use hmac::Mac as _;
pub const USERAGENT_INTEGRITY_DERIVE_TAG: &[u8] = "arbiter/useragent/integrity-key/v1".as_bytes();
pub const USERAGENT_INTEGRITY_TAG: &[u8] = "arbiter/useragent/pubkey-entry/v1".as_bytes();
/// Computes an integrity tag for a specific domain and payload shape.
pub fn compute_integrity_tag<'a, I>(
integrity_key: &mut KeyCell,
@@ -33,10 +32,12 @@ where
#[cfg(test)]
mod tests {
use crate::{crypto::{derive_key, encryption::v1::generate_salt}, safe_cell::{SafeCell, SafeCellHandle as _}};
use super::{compute_integrity_tag, USERAGENT_INTEGRITY_TAG};
use crate::{
crypto::{derive_key, encryption::v1::generate_salt},
safe_cell::{SafeCell, SafeCellHandle as _},
};
use super::{USERAGENT_INTEGRITY_TAG, compute_integrity_tag};
#[test]
pub fn integrity_tag_deterministic() {

View File

@@ -5,9 +5,12 @@ use chacha20poly1305::{
AeadInPlace, Key, KeyInit as _, XChaCha20Poly1305, XNonce,
aead::{AeadMut, Error, Payload},
};
use rand::{Rng as _, SeedableRng as _, rngs::{StdRng, SysRng}};
use rand::{
Rng as _, SeedableRng as _,
rngs::{StdRng, SysRng},
};
use crate::{safe_cell::{SafeCell, SafeCellHandle as _}};
use crate::safe_cell::{SafeCell, SafeCellHandle as _};
pub mod encryption;
pub mod integrity;
@@ -124,8 +127,11 @@ pub fn derive_key(mut password: SafeCell<Vec<u8>>, salt: &Salt) -> KeyCell {
#[cfg(test)]
mod tests {
use crate::{safe_cell::{SafeCell, SafeCellHandle as _}};
use super::{derive_key, encryption::v1::{Nonce, generate_salt}};
use super::{
derive_key,
encryption::v1::{Nonce, generate_salt},
};
use crate::safe_cell::{SafeCell, SafeCellHandle as _};
#[test]
pub fn encrypt_decrypt() {

View File

@@ -8,7 +8,6 @@ use alloy::{
use chrono::Utc;
use diesel::{ExpressionMethods as _, QueryDsl as _, QueryResult, insert_into, sqlite::Sqlite};
use diesel_async::{AsyncConnection, RunQueryDsl};
use tracing_subscriber::registry::Data;
use crate::{
db::{

View File

@@ -34,7 +34,9 @@ async fn dispatch_loop(
mut request_tracker: RequestTracker,
) {
loop {
let Some(message) = bi.recv().await else { return };
let Some(message) = bi.recv().await else {
return;
};
let conn = match message {
Ok(conn) => conn,
@@ -53,16 +55,24 @@ async fn dispatch_loop(
};
let Some(payload) = conn.payload else {
let _ = bi.send(Err(Status::invalid_argument("Missing client request payload"))).await;
let _ = bi
.send(Err(Status::invalid_argument(
"Missing client request payload",
)))
.await;
return;
};
match dispatch_inner(&actor, payload).await {
Ok(response) => {
if bi.send(Ok(ClientResponse {
if bi
.send(Ok(ClientResponse {
request_id: Some(request_id),
payload: Some(response),
})).await.is_err() {
}))
.await
.is_err()
{
return;
}
}

View File

@@ -1,11 +1,13 @@
use arbiter_proto::{
ClientMetadata, proto::client::{
ClientMetadata,
proto::client::{
AuthChallenge as ProtoAuthChallenge, AuthChallengeRequest as ProtoAuthChallengeRequest,
AuthChallengeSolution as ProtoAuthChallengeSolution, AuthResult as ProtoAuthResult,
ClientInfo as ProtoClientInfo, ClientRequest, ClientResponse,
client_request::Payload as ClientRequestPayload,
client_response::Payload as ClientResponsePayload,
}, transport::{Bi, Error as TransportError, Receiver, Sender, grpc::GrpcBi}
},
transport::{Bi, Error as TransportError, Receiver, Sender, grpc::GrpcBi},
};
use async_trait::async_trait;
use tonic::Status;

View File

@@ -20,8 +20,7 @@ use arbiter_proto::{
SdkClientConnectionRequest as ProtoSdkClientConnectionRequest,
SdkClientEntry as ProtoSdkClientEntry, SdkClientError as ProtoSdkClientError,
SdkClientGrantWalletAccess, SdkClientList as ProtoSdkClientList,
SdkClientListResponse as ProtoSdkClientListResponse, SdkClientRevokeWalletAccess,
SdkClientWalletAccess, UnsealEncryptedKey as ProtoUnsealEncryptedKey,
SdkClientListResponse as ProtoSdkClientListResponse, SdkClientRevokeWalletAccess, UnsealEncryptedKey as ProtoUnsealEncryptedKey,
UnsealResult as ProtoUnsealResult, UnsealStart, UserAgentRequest, UserAgentResponse,
VaultState as ProtoVaultState,
sdk_client_list_response::Result as ProtoSdkClientListResult,
@@ -53,7 +52,7 @@ use crate::{
},
},
},
db::models::{CoreEvmWalletAccess, NewEvmWalletAccess},
db::models::NewEvmWalletAccess,
grpc::{Convert, TryConvert, request_tracker::RequestTracker},
};
mod auth;
@@ -404,7 +403,10 @@ async fn dispatch_inner(
}
UserAgentRequestPayload::RevokeWalletAccess(SdkClientRevokeWalletAccess { accesses }) => {
match actor.ask(HandleRevokeEvmWalletAccess { entries: accesses }).await {
match actor
.ask(HandleRevokeEvmWalletAccess { entries: accesses })
.await
{
Ok(()) => {
info!("Successfully revoked wallet access");
return Ok(None);

View File

@@ -10,7 +10,7 @@ use chrono::{DateTime, TimeZone, Utc};
use prost_types::Timestamp as ProtoTimestamp;
use tonic::Status;
use crate::db::models::{CoreEvmWalletAccess, NewEvmWallet, NewEvmWalletAccess};
use crate::db::models::{CoreEvmWalletAccess, NewEvmWalletAccess};
use crate::grpc::Convert;
use crate::{
evm::policies::{

View File

@@ -1,9 +1,9 @@
#![forbid(unsafe_code)]
use crate::context::ServerContext;
pub mod crypto;
pub mod actors;
pub mod context;
pub mod crypto;
pub mod db;
pub mod evm;
pub mod grpc;

View File

@@ -1,5 +1,8 @@
use arbiter_server::{
actors::keyholder::{Error, KeyHolder}, crypto::encryption::v1::{Nonce, ROOT_KEY_TAG}, db::{self, models, schema}, safe_cell::{SafeCell, SafeCellHandle as _}
actors::keyholder::{Error, KeyHolder},
crypto::encryption::v1::{Nonce, ROOT_KEY_TAG},
db::{self, models, schema},
safe_cell::{SafeCell, SafeCellHandle as _},
};
use diesel::{QueryDsl, SelectableHelper};
use diesel_async::RunQueryDsl;
@@ -23,16 +26,10 @@ async fn test_bootstrap() {
.unwrap();
assert_eq!(row.schema_version, 1);
assert_eq!(
row.tag,
ROOT_KEY_TAG
);
assert_eq!(row.tag, ROOT_KEY_TAG);
assert!(!row.ciphertext.is_empty());
assert!(!row.salt.is_empty());
assert_eq!(
row.data_encryption_nonce,
Nonce::default().to_vec()
);
assert_eq!(row.data_encryption_nonce, Nonce::default().to_vec());
}
#[tokio::test]

View File

@@ -1,7 +1,10 @@
use std::collections::HashSet;
use arbiter_server::{
actors::keyholder::Error, crypto::encryption::v1::Nonce, db::{self, models, schema}, safe_cell::{SafeCell, SafeCellHandle as _}
actors::keyholder::Error,
crypto::encryption::v1::Nonce,
db::{self, models, schema},
safe_cell::{SafeCell, SafeCellHandle as _},
};
use diesel::{ExpressionMethods as _, QueryDsl, SelectableHelper, dsl::update};
use diesel_async::RunQueryDsl;