mirror of
https://github.com/rosenpass/rosenpass.git
synced 2025-12-10 06:40:31 -08:00
Compare commits
2 Commits
analyze_py
...
dev/add-ud
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2f8f9006a | ||
|
|
c072b7825f |
@@ -2,6 +2,7 @@ public_key = "peer-a-public-key"
|
|||||||
secret_key = "peer-a-secret-key"
|
secret_key = "peer-a-secret-key"
|
||||||
listen = ["[::]:10001"]
|
listen = ["[::]:10001"]
|
||||||
verbosity = "Quiet"
|
verbosity = "Quiet"
|
||||||
|
control_socket = "rosenpassd.sock"
|
||||||
|
|
||||||
[[peers]]
|
[[peers]]
|
||||||
public_key = "peer-b-public-key"
|
public_key = "peer-b-public-key"
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use log::debug;
|
||||||
|
use log::trace;
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use mio::Interest;
|
use mio::Interest;
|
||||||
use mio::Token;
|
use mio::Token;
|
||||||
@@ -15,6 +17,7 @@ use std::net::SocketAddr;
|
|||||||
use std::net::SocketAddrV4;
|
use std::net::SocketAddrV4;
|
||||||
use std::net::SocketAddrV6;
|
use std::net::SocketAddrV6;
|
||||||
use std::net::ToSocketAddrs;
|
use std::net::ToSocketAddrs;
|
||||||
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::process::Stdio;
|
use std::process::Stdio;
|
||||||
@@ -30,6 +33,7 @@ use crate::{
|
|||||||
|
|
||||||
const IPV4_ANY_ADDR: Ipv4Addr = Ipv4Addr::new(0, 0, 0, 0);
|
const IPV4_ANY_ADDR: Ipv4Addr = Ipv4Addr::new(0, 0, 0, 0);
|
||||||
const IPV6_ANY_ADDR: Ipv6Addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
|
const IPV6_ANY_ADDR: Ipv6Addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
const CONTROL_SOCKET_TOKEN: mio::Token = mio::Token(usize::MAX);
|
||||||
|
|
||||||
fn ipv4_any_binding() -> SocketAddr {
|
fn ipv4_any_binding() -> SocketAddr {
|
||||||
// addr, port
|
// addr, port
|
||||||
@@ -78,6 +82,9 @@ pub struct AppServer {
|
|||||||
pub peers: Vec<AppPeer>,
|
pub peers: Vec<AppPeer>,
|
||||||
pub verbosity: Verbosity,
|
pub verbosity: Verbosity,
|
||||||
pub all_sockets_drained: bool,
|
pub all_sockets_drained: bool,
|
||||||
|
|
||||||
|
/// Optional control socket to change the configuration of a running rosenpassd
|
||||||
|
pub maybe_control_socket: Option<mio::net::UnixDatagram>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A socket pointer is an index assigned to a socket;
|
/// A socket pointer is an index assigned to a socket;
|
||||||
@@ -335,11 +342,13 @@ impl HostPathDiscoveryEndpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AppServer {
|
impl AppServer {
|
||||||
pub fn new(
|
pub fn new<P: AsRef<Path> + core::fmt::Debug>(
|
||||||
|
// TODO @wucke13 check if requiring Debug breaks important types that otherwise fulfill AsRef<Path>
|
||||||
sk: SSk,
|
sk: SSk,
|
||||||
pk: SPk,
|
pk: SPk,
|
||||||
addrs: Vec<SocketAddr>,
|
addrs: Vec<SocketAddr>,
|
||||||
verbosity: Verbosity,
|
verbosity: Verbosity,
|
||||||
|
uds: Option<P>,
|
||||||
) -> anyhow::Result<Self> {
|
) -> anyhow::Result<Self> {
|
||||||
// setup mio
|
// setup mio
|
||||||
let mio_poll = mio::Poll::new()?;
|
let mio_poll = mio::Poll::new()?;
|
||||||
@@ -417,13 +426,31 @@ impl AppServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// register all sockets to mio
|
// register all sockets to mio
|
||||||
|
debug!("registering all UDP sockets to mio");
|
||||||
for (i, socket) in sockets.iter_mut().enumerate() {
|
for (i, socket) in sockets.iter_mut().enumerate() {
|
||||||
|
trace!("registering {socket:?}");
|
||||||
mio_poll
|
mio_poll
|
||||||
.registry()
|
.registry()
|
||||||
.register(socket, Token(i), Interest::READABLE)?;
|
.register(socket, Token(i), Interest::READABLE)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut maybe_control_socket = uds
|
||||||
|
.map(|p| {
|
||||||
|
debug!("binding control socket {p:?}");
|
||||||
|
mio::net::UnixDatagram::bind(p)
|
||||||
|
})
|
||||||
|
.transpose()?;
|
||||||
|
if let Some(control_socket) = &mut maybe_control_socket {
|
||||||
|
debug!("registering control socket to mio");
|
||||||
|
mio_poll.registry().register(
|
||||||
|
control_socket,
|
||||||
|
CONTROL_SOCKET_TOKEN,
|
||||||
|
Interest::READABLE,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO use mio::net::UnixStream together with std::os::unix::net::UnixStream for Linux
|
// TODO use mio::net::UnixStream together with std::os::unix::net::UnixStream for Linux
|
||||||
|
debug!("finalizing AppServer creation");
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
crypt: CryptoServer::new(sk, pk),
|
crypt: CryptoServer::new(sk, pk),
|
||||||
@@ -433,6 +460,7 @@ impl AppServer {
|
|||||||
events,
|
events,
|
||||||
mio_poll,
|
mio_poll,
|
||||||
all_sockets_drained: false,
|
all_sockets_drained: false,
|
||||||
|
maybe_control_socket,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,6 +666,7 @@ impl AppServer {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Polls the crypto servers state machine for new actions
|
||||||
pub fn poll(&mut self, rx_buf: &mut [u8]) -> anyhow::Result<AppPollResult> {
|
pub fn poll(&mut self, rx_buf: &mut [u8]) -> anyhow::Result<AppPollResult> {
|
||||||
use crate::protocol::PollResult as C;
|
use crate::protocol::PollResult as C;
|
||||||
use AppPollResult as A;
|
use AppPollResult as A;
|
||||||
@@ -654,7 +683,7 @@ impl AppServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tries to receive a new message
|
/// Tries to receive a new control socket command or incoming message
|
||||||
///
|
///
|
||||||
/// - might wait for an duration up to `timeout`
|
/// - might wait for an duration up to `timeout`
|
||||||
/// - returns immediately if an error occurs
|
/// - returns immediately if an error occurs
|
||||||
@@ -693,6 +722,27 @@ impl AppServer {
|
|||||||
self.mio_poll.poll(&mut self.events, Some(timeout))?;
|
self.mio_poll.poll(&mut self.events, Some(timeout))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace!("checking for new command on control socket");
|
||||||
|
// control socket always has priority
|
||||||
|
if let Some(control_socket) = &mut self.maybe_control_socket {
|
||||||
|
let mut buf = [0u8; 16];
|
||||||
|
|
||||||
|
match control_socket.recv(&mut buf) {
|
||||||
|
Ok(size) => {
|
||||||
|
// TODO handle command
|
||||||
|
// to send something here, use the following shell snippet:
|
||||||
|
//
|
||||||
|
// printf '\x7\' | nc -NuU rosenpassd.sock
|
||||||
|
log::debug!("buf received {:?}", &buf[0..size]);
|
||||||
|
}
|
||||||
|
Err(e) if e.kind() == ErrorKind::WouldBlock => {
|
||||||
|
trace!("no new commands on control socket")
|
||||||
|
}
|
||||||
|
Err(e) => return Err(e.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// then normal traffic is processed
|
||||||
let mut would_block_count = 0;
|
let mut would_block_count = 0;
|
||||||
for (sock_no, socket) in self.sockets.iter_mut().enumerate() {
|
for (sock_no, socket) in self.sockets.iter_mut().enumerate() {
|
||||||
match socket.recv_from(buf) {
|
match socket.recv_from(buf) {
|
||||||
|
|||||||
@@ -228,6 +228,7 @@ impl Cli {
|
|||||||
pk,
|
pk,
|
||||||
config.listen,
|
config.listen,
|
||||||
config.verbosity,
|
config.verbosity,
|
||||||
|
config.control_socket.as_ref(),
|
||||||
)?);
|
)?);
|
||||||
|
|
||||||
for cfg_peer in config.peers {
|
for cfg_peer in config.peers {
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ pub struct Rosenpass {
|
|||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub config_file_path: PathBuf,
|
pub config_file_path: PathBuf,
|
||||||
|
|
||||||
|
pub control_socket: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
@@ -133,6 +135,7 @@ impl Rosenpass {
|
|||||||
verbosity: Verbosity::Quiet,
|
verbosity: Verbosity::Quiet,
|
||||||
peers: vec![],
|
peers: vec![],
|
||||||
config_file_path: PathBuf::new(),
|
config_file_path: PathBuf::new(),
|
||||||
|
control_socket: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
38
src/control_commands.rs
Normal file
38
src/control_commands.rs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
//! Data structures representing the control messages going over the control socket
|
||||||
|
//!
|
||||||
|
//! This module uses the same de-/serialization mechanism as [crate::msgs].
|
||||||
|
//! If you want to interface with `rosenpassd`, this is where you can look up the format
|
||||||
|
//! of the messages that are accepted.
|
||||||
|
|
||||||
|
use crate::{data_lense, msgs::LenseView, RosenpassError};
|
||||||
|
|
||||||
|
data_lense! { ControlComand<C> :=
|
||||||
|
/// [MsgType] of this message
|
||||||
|
msg_type: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(u8)]
|
||||||
|
#[derive(Hash, PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
|
||||||
|
pub enum CommandType {
|
||||||
|
/// Add one peer
|
||||||
|
AddPeer = 0x10,
|
||||||
|
|
||||||
|
/// Remove all peers that match the given public key
|
||||||
|
RemovePeerPk = 0x11,
|
||||||
|
|
||||||
|
/// Remove all peers that match the given address
|
||||||
|
RemovePeerIp = 0x12,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<u8> for CommandType {
|
||||||
|
type Error = RosenpassError;
|
||||||
|
|
||||||
|
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||||
|
Ok(match value {
|
||||||
|
0x10 => CommandType::AddPeer,
|
||||||
|
0x11 => CommandType::RemovePeerPk,
|
||||||
|
0x12 => CommandType::RemovePeerIp,
|
||||||
|
_ => return Err(RosenpassError::InvalidMessageType(value)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ pub mod labeled_prf;
|
|||||||
pub mod app_server;
|
pub mod app_server;
|
||||||
pub mod cli;
|
pub mod cli;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
pub mod control_commands;
|
||||||
pub mod msgs;
|
pub mod msgs;
|
||||||
pub mod pqkem;
|
pub mod pqkem;
|
||||||
pub mod prftree;
|
pub mod prftree;
|
||||||
@@ -26,6 +27,9 @@ pub enum RosenpassError {
|
|||||||
},
|
},
|
||||||
#[error("invalid message type")]
|
#[error("invalid message type")]
|
||||||
InvalidMessageType(u8),
|
InvalidMessageType(u8),
|
||||||
|
|
||||||
|
#[error("invalid command type")]
|
||||||
|
InvalidCommandType(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RosenpassError {
|
impl RosenpassError {
|
||||||
|
|||||||
Reference in New Issue
Block a user