server.rs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2026 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use std::{
  19. collections::HashMap,
  20. fs::File,
  21. io::{BufRead, BufReader},
  22. path::PathBuf,
  23. sync::Arc,
  24. };
  25. use darkfi::{
  26. event_graph::Event,
  27. system::{StoppableTask, StoppableTaskPtr, Subscription},
  28. util::path::expand_path,
  29. Error, Result,
  30. };
  31. use darkfi_serial::{deserialize_async, deserialize_async_partial, serialize_async};
  32. use futures_rustls::{
  33. rustls::{
  34. self,
  35. pki_types::{CertificateDer, PrivateKeyDer},
  36. },
  37. TlsAcceptor,
  38. };
  39. use kvdb_overlay::{Batch, Database};
  40. use smol::{
  41. fs,
  42. lock::{Mutex, RwLock},
  43. net::{SocketAddr, TcpListener},
  44. prelude::{AsyncRead, AsyncWrite},
  45. Executor,
  46. };
  47. use tracing::{debug, error, info, warn};
  48. use url::Url;
  49. use super::{
  50. client::Client,
  51. services::nickserv::{ACCOUNTS_DB_PREFIX, ACCOUNTS_DEFAULT_TREE, ACCOUNTS_KEY_RLN_IDENTITY},
  52. IrcChannel, IrcContact,
  53. };
  54. use crate::{
  55. crypto::{rln::RlnIdentity, saltbox},
  56. pad,
  57. settings::{parse_autojoin_channels, parse_configured_channels, parse_configured_contacts},
  58. unpad, DarkIrc, Privmsg,
  59. };
  60. /// Max channel/nick length
  61. pub const MAX_NICK_LEN: usize = 24;
  62. /// Max message length
  63. pub const MAX_MSG_LEN: usize = 512;
  64. /// Kvdb tree storing every public (`#`-prefixed) IRC channel we have
  65. /// observed on the p2p network. Keys are channel names; values are empty.
  66. pub const SEEN_CHANNELS_TREE: &str = "darkirc_seen_channels";
  67. /// Result of attempting to reserve the next RLN message slot.
  68. pub enum RlnMessageReservation {
  69. /// No active RLN identity is configured.
  70. MissingIdentity,
  71. /// The active identity has already used its epoch budget.
  72. BudgetExhausted,
  73. /// A message slot was persisted and can be used to build a proof.
  74. Reserved { identity: RlnIdentity, message_id: u64 },
  75. }
  76. /// Persist the active RLN counter to the default mirror and matching account tree.
  77. async fn persist_rln_identity_counter(kvdb: &Database, identity: &RlnIdentity) -> Result<()> {
  78. let encoded = serialize_async(identity).await;
  79. let active_commitment = identity.commitment();
  80. let mut updated_account = false;
  81. for name in kvdb.tree_names()? {
  82. let Some(account_name) = name.strip_prefix(ACCOUNTS_DB_PREFIX) else { continue };
  83. if account_name == "default" || account_name.is_empty() {
  84. continue
  85. }
  86. let tree = kvdb.open_tree_default(&name)?;
  87. let Some(blob) = tree.get(ACCOUNTS_KEY_RLN_IDENTITY)? else { continue };
  88. let Ok(stored): std::result::Result<RlnIdentity, _> = deserialize_async(&blob).await else {
  89. continue
  90. };
  91. if stored.commitment() == active_commitment {
  92. tree.insert(ACCOUNTS_KEY_RLN_IDENTITY, &encoded)?;
  93. updated_account = true;
  94. }
  95. }
  96. if !updated_account {
  97. warn!(
  98. target: "darkirc::irc::server",
  99. "active RLN identity has no matching account tree; persisting default mirror only",
  100. );
  101. }
  102. let default_db = kvdb.open_tree_default(ACCOUNTS_DEFAULT_TREE)?;
  103. default_db.insert(ACCOUNTS_KEY_RLN_IDENTITY, &encoded)?;
  104. kvdb.flush_default_mode_async().await?;
  105. Ok(())
  106. }
  107. /// Reserve the next RLN message ID and persist it before proof creation.
  108. pub(crate) async fn reserve_rln_message_id_in_store(
  109. kvdb: &Database,
  110. active: &mut Option<RlnIdentity>,
  111. now_millis: u64,
  112. ) -> Result<RlnMessageReservation> {
  113. let Some(current) = active else { return Ok(RlnMessageReservation::MissingIdentity) };
  114. let mut updated = *current;
  115. let Some(message_id) = updated.next_message_id(now_millis) else {
  116. return Ok(RlnMessageReservation::BudgetExhausted)
  117. };
  118. persist_rln_identity_counter(kvdb, &updated).await?;
  119. *current = updated;
  120. Ok(RlnMessageReservation::Reserved { identity: updated, message_id })
  121. }
  122. fn parse_tls_secret<R>(reader: &mut R) -> Result<PrivateKeyDer<'static>>
  123. where
  124. R: BufRead,
  125. {
  126. let key = rustls_pemfile::pkcs8_private_keys(reader)
  127. .next()
  128. .ok_or(Error::ParseFailed("TLS key missing PKCS#8 private key"))?
  129. .map_err(|_| Error::ParseFailed("TLS key contains invalid PKCS#8 private key"))?;
  130. Ok(PrivateKeyDer::Pkcs8(key))
  131. }
  132. fn parse_tls_cert<R>(reader: &mut R) -> Result<CertificateDer<'static>>
  133. where
  134. R: BufRead,
  135. {
  136. rustls_pemfile::certs(reader)
  137. .next()
  138. .ok_or(Error::ParseFailed("TLS certificate missing"))?
  139. .map_err(|_| Error::ParseFailed("TLS certificate contains invalid DER"))
  140. }
  141. fn tls_acceptor_from_pem<CR, KR>(
  142. cert_reader: &mut CR,
  143. secret_reader: &mut KR,
  144. ) -> Result<TlsAcceptor>
  145. where
  146. CR: BufRead,
  147. KR: BufRead,
  148. {
  149. let secret = parse_tls_secret(secret_reader)?;
  150. let cert = parse_tls_cert(cert_reader)?;
  151. let config = rustls::ServerConfig::builder()
  152. .with_no_client_auth()
  153. .with_single_cert(vec![cert], secret)
  154. .map_err(|_| Error::ParseFailed("TLS certificate and key are invalid"))?;
  155. Ok(TlsAcceptor::from(Arc::new(config)))
  156. }
  157. fn load_tls_acceptor(tls_cert: &str, tls_secret: &str) -> Result<TlsAcceptor> {
  158. let f = File::open(expand_path(tls_secret)?)?;
  159. let mut secret_reader = BufReader::new(f);
  160. let f = File::open(expand_path(tls_cert)?)?;
  161. let mut cert_reader = BufReader::new(f);
  162. tls_acceptor_from_pem(&mut cert_reader, &mut secret_reader)
  163. }
  164. async fn load_default_rln_identity(kvdb: &Database) -> Result<Option<RlnIdentity>> {
  165. let default_db = kvdb.open_tree_default(ACCOUNTS_DEFAULT_TREE)?;
  166. let Some(blob) = default_db.get(ACCOUNTS_KEY_RLN_IDENTITY)? else {
  167. if default_db.is_empty()? {
  168. return Ok(None)
  169. }
  170. return Err(Error::ParseFailed("Default RLN account is missing identity record"))
  171. };
  172. let identity: RlnIdentity = deserialize_async(&blob)
  173. .await
  174. .map_err(|_| Error::ParseFailed("Default RLN account identity is corrupted"))?;
  175. Ok(Some(identity))
  176. }
  177. /// IRC server instance
  178. pub struct IrcServer {
  179. /// DarkIrc instance
  180. pub darkirc: Arc<DarkIrc>,
  181. /// Path to the darkirc config file
  182. config_path: PathBuf,
  183. /// TCP listener
  184. listener: TcpListener,
  185. /// TLS acceptor
  186. acceptor: Option<TlsAcceptor>,
  187. /// Configured autojoin channels
  188. pub autojoin: RwLock<Vec<String>>,
  189. /// Configured IRC channels
  190. pub channels: RwLock<HashMap<String, IrcChannel>>,
  191. /// Configured IRC contacts
  192. pub contacts: RwLock<HashMap<String, IrcContact>>,
  193. /// Configured RLN identity
  194. pub rln_identity: RwLock<Option<RlnIdentity>>,
  195. /// Static-DAG events whose broadcast is deferred until the
  196. /// EventGraph is synced.
  197. pub pending_static_broadcasts: Mutex<Vec<(Event, Vec<u8>)>>,
  198. /// Active client connections
  199. clients: Mutex<HashMap<u16, StoppableTaskPtr>>,
  200. /// IRC server Password
  201. pub password: String,
  202. }
  203. impl IrcServer {
  204. /// Reserve and persist the next RLN message slot before proof creation.
  205. pub async fn reserve_rln_message_id(&self, now_millis: u64) -> Result<RlnMessageReservation> {
  206. let mut active = self.rln_identity.write().await;
  207. reserve_rln_message_id_in_store(&self.darkirc.kvdb, &mut active, now_millis).await
  208. }
  209. /// Instantiate a new IRC server. This function will try to bind a TCP socket,
  210. /// and optionally load a TLS certificate and key. To start the listening loop,
  211. /// call `IrcServer::listen()`.
  212. pub async fn new(
  213. darkirc: Arc<DarkIrc>,
  214. listen: Url,
  215. tls_cert: Option<String>,
  216. tls_secret: Option<String>,
  217. config_path: PathBuf,
  218. password: String,
  219. ) -> Result<Arc<Self>> {
  220. let scheme = listen.scheme();
  221. if scheme != "tcp" && scheme != "tcp+tls" {
  222. error!("IRC server supports listening only on tcp:// or tcp+tls://");
  223. return Err(Error::BindFailed(listen.to_string()))
  224. }
  225. if scheme == "tcp+tls" && (tls_cert.is_none() || tls_secret.is_none()) {
  226. error!("You must provide a TLS certificate and key if you want a TLS server");
  227. return Err(Error::BindFailed(listen.to_string()))
  228. }
  229. // Bind listener
  230. let listen_addr = listen.socket_addrs(|| None)?[0];
  231. let listener = TcpListener::bind(listen_addr).await?;
  232. let acceptor = match scheme {
  233. "tcp+tls" => {
  234. // openssl genpkey -algorithm ED25519 > example.com.key
  235. // openssl req -new -out example.com.csr -key example.com.key
  236. // openssl x509 -req -in example.com.csr -signkey example.com.key -out example.com.crt
  237. let (Some(tls_cert), Some(tls_secret)) = (tls_cert.as_ref(), tls_secret.as_ref())
  238. else {
  239. return Err(Error::ParseFailed("TLS certificate and key are required"))
  240. };
  241. Some(load_tls_acceptor(tls_cert, tls_secret)?)
  242. }
  243. _ => None,
  244. };
  245. // Set the default RLN account if any. When RLN is disabled, avoid
  246. // loading account state that cannot affect outbound messages.
  247. let rln_identity = if darkirc.event_graph.rln_enabled() {
  248. let rln_identity = load_default_rln_identity(&darkirc.kvdb).await?;
  249. if rln_identity.is_some() {
  250. info!("Default RLN account set");
  251. }
  252. rln_identity
  253. } else {
  254. info!("RLN disabled; skipping default RLN account load");
  255. None
  256. };
  257. let self_ = Arc::new(Self {
  258. darkirc,
  259. config_path,
  260. listener,
  261. acceptor,
  262. autojoin: RwLock::new(Vec::new()),
  263. channels: RwLock::new(HashMap::new()),
  264. contacts: RwLock::new(HashMap::new()),
  265. rln_identity: RwLock::new(rln_identity),
  266. pending_static_broadcasts: Mutex::new(Vec::new()),
  267. clients: Mutex::new(HashMap::new()),
  268. password,
  269. });
  270. // Load any channel/contact configuration.
  271. self_.rehash().await?;
  272. Ok(self_)
  273. }
  274. /// Drain `pending_static_broadcasts` and broadcast each entry.
  275. pub async fn drain_pending_static_broadcasts(&self) -> Result<usize> {
  276. let drained: Vec<(Event, Vec<u8>)> = {
  277. let mut guard = self.pending_static_broadcasts.lock().await;
  278. std::mem::take(&mut *guard)
  279. };
  280. let n = drained.len();
  281. for (event, blob) in drained {
  282. self.darkirc.event_graph.static_broadcast(event, blob).await?;
  283. }
  284. Ok(n)
  285. }
  286. /// Reload the darkirc configuration file and reconfigure channels and contacts.
  287. pub async fn rehash(&self) -> Result<()> {
  288. let contents = fs::read_to_string(&self.config_path).await?;
  289. let contents = match toml::from_str(&contents) {
  290. Ok(v) => v,
  291. Err(e) => {
  292. error!("Failed parsing TOML config: {e}");
  293. return Err(Error::ParseFailed("Failed parsing TOML config"))
  294. }
  295. };
  296. // Parse autojoin channels
  297. let autojoin = parse_autojoin_channels(&contents)?;
  298. // Parse configured channels
  299. let configured_channels = parse_configured_channels(&contents)?;
  300. // Parse configured contacts
  301. let contacts = parse_configured_contacts(&contents)?;
  302. // Persist unconfigured channels (joined from client, or autojoined without config)
  303. let channels = {
  304. let old_channels = self.channels.read().await.clone();
  305. let unconfigured_channels: HashMap<String, IrcChannel> = old_channels
  306. .into_iter()
  307. .filter(|(chan_str, _)| !configured_channels.contains_key(chan_str))
  308. .collect();
  309. configured_channels.into_iter().chain(unconfigured_channels).collect()
  310. };
  311. // Only if everything is fine, replace.
  312. *self.autojoin.write().await = autojoin;
  313. *self.channels.write().await = channels;
  314. *self.contacts.write().await = contacts;
  315. // Record configured public channels so `/LIST` can report them even
  316. // before any traffic is observed for them on the network.
  317. let names: Vec<String> = self.channels.read().await.keys().cloned().collect();
  318. for name in &names {
  319. self.record_seen_channel(name).await?;
  320. }
  321. Ok(())
  322. }
  323. /// Start accepting new IRC connections.
  324. pub async fn listen(self: Arc<Self>, ex: Arc<Executor<'_>>) -> Result<()> {
  325. loop {
  326. let (stream, peer_addr) = match self.listener.accept().await {
  327. Ok((s, a)) => (s, a),
  328. // As per usual accept(2) recommendations
  329. Err(e)
  330. if matches!(
  331. e.raw_os_error(),
  332. Some(libc::EAGAIN | libc::ECONNABORTED | libc::EPROTO | libc::EINTR)
  333. ) =>
  334. {
  335. continue
  336. }
  337. Err(e) => {
  338. error!("[IRC SERVER] Failed accepting new connection: {e}");
  339. continue
  340. }
  341. };
  342. match &self.acceptor {
  343. // Expecting encrypted TLS connection
  344. Some(acceptor) => {
  345. let stream = match acceptor.accept(stream).await {
  346. Ok(s) => s,
  347. Err(e) => {
  348. error!("[IRC SERVER] Failed accepting new TLS connection: {e}");
  349. continue
  350. }
  351. };
  352. // Subscribe to incoming events and set up the connection.
  353. let incoming = self.darkirc.event_graph.event_pub.clone().subscribe().await;
  354. let incoming_st = self.darkirc.event_graph.static_pub.clone().subscribe().await;
  355. if let Err(e) = self
  356. .clone()
  357. .process_connection(stream, peer_addr, incoming, incoming_st, ex.clone())
  358. .await
  359. {
  360. error!("[IRC SERVER] Failed processing new connection: {e}");
  361. continue
  362. };
  363. }
  364. // Expecting plain TCP connection
  365. None => {
  366. // Subscribe to incoming events and set up the connection.
  367. let incoming = self.darkirc.event_graph.event_pub.clone().subscribe().await;
  368. let incoming_st = self.darkirc.event_graph.static_pub.clone().subscribe().await;
  369. if let Err(e) = self
  370. .clone()
  371. .process_connection(stream, peer_addr, incoming, incoming_st, ex.clone())
  372. .await
  373. {
  374. error!("[IRC SERVER] Failed processing new connection: {e}");
  375. continue
  376. };
  377. }
  378. }
  379. info!("[IRC SERVER] Accepted new client connection at: {peer_addr}");
  380. }
  381. }
  382. /// IRC client connection process.
  383. /// Sets up multiplexing between the server and client.
  384. /// Detaches the connection as a `StoppableTask`.
  385. async fn process_connection<C: AsyncRead + AsyncWrite + Send + Unpin + 'static>(
  386. self: Arc<Self>,
  387. stream: C,
  388. peer_addr: SocketAddr,
  389. incoming: Subscription<Event>,
  390. incoming_st: Subscription<Event>,
  391. ex: Arc<Executor<'_>>,
  392. ) -> Result<()> {
  393. let port = peer_addr.port();
  394. let client = Client::new(self.clone(), incoming, incoming_st, peer_addr).await?;
  395. let conn_task = StoppableTask::new();
  396. self.clients.lock().await.insert(port, conn_task.clone());
  397. conn_task.clone().start(
  398. async move { client.multiplex_connection(stream).await },
  399. move |res| async move {
  400. match res {
  401. Ok(()) => info!("[IRC SERVER] Disconnected client from {peer_addr}"),
  402. Err(e) => error!("[IRC SERVER] Disconnected client from {peer_addr}: {e}"),
  403. }
  404. self.clone().clients.lock().await.remove(&port);
  405. },
  406. Error::ChannelStopped,
  407. ex,
  408. );
  409. Ok(())
  410. }
  411. /// Record a public (`#`-prefixed) IRC channel in the `SEEN_CHANNELS_TREE`
  412. /// so that `/LIST` can report channels observed on the p2p network.
  413. /// Private (encrypted) channels — those with a configured saltbox — are
  414. /// skipped. Idempotent. Emits a debug log the first time a given channel
  415. /// is seen.
  416. pub async fn record_seen_channel(&self, channel: &str) -> Result<()> {
  417. if !channel.starts_with('#') {
  418. return Ok(())
  419. }
  420. // Skip private channels that have a configured saltbox.
  421. if let Some(chan) = self.channels.read().await.get(channel) {
  422. if chan.saltbox.is_some() {
  423. return Ok(())
  424. }
  425. }
  426. let tree = self.darkirc.kvdb.open_tree_default(SEEN_CHANNELS_TREE)?;
  427. if tree.insert(channel.as_bytes(), &[])?.is_none() {
  428. debug!(
  429. target: "darkirc::irc::server",
  430. "Recorded new public channel: {channel}"
  431. );
  432. }
  433. Ok(())
  434. }
  435. /// Walk every stored event in the DAG and record all public (`#`-prefixed)
  436. /// channels into the `SEEN_CHANNELS_TREE`. Intended to be called once the
  437. /// event graph finishes syncing, so that `/LIST` reflects the full set of
  438. /// known public channels even before any new live traffic arrives.
  439. /// Only the raw wire channel field is inspected: encrypted (private)
  440. /// channels carry base58 ciphertext and are skipped.
  441. pub async fn populate_seen_channels(&self) -> Result<usize> {
  442. let events = self.darkirc.event_graph.order_events().await?;
  443. let tree = self.darkirc.kvdb.open_tree_default(SEEN_CHANNELS_TREE)?;
  444. let mut batch = Batch::default();
  445. let mut count = 0usize;
  446. for event in events.iter() {
  447. let Ok((privmsg, _)) = deserialize_async_partial::<Privmsg>(event.content()).await
  448. else {
  449. continue
  450. };
  451. if privmsg.channel.starts_with('#') {
  452. batch.insert(privmsg.channel.as_bytes(), &[]);
  453. count += 1;
  454. }
  455. }
  456. if count > 0 {
  457. self.darkirc.kvdb.atomic_write(&[(&tree, &batch)])?;
  458. }
  459. Ok(count)
  460. }
  461. /// Try encrypting a given `Privmsg` if there is such a channel/contact.
  462. pub async fn try_encrypt(&self, privmsg: &mut Privmsg) {
  463. if let Some((name, channel)) = self.channels.read().await.get_key_value(&privmsg.channel) {
  464. if let Some(saltbox) = &channel.saltbox {
  465. // We will use a dummy channel value of MAX_NICK_LEN,
  466. // since its not used, so all encrypted messages look the same.
  467. privmsg.channel = saltbox::encrypt(saltbox, &[0x00; MAX_NICK_LEN]);
  468. // We will pad the name to MAX_NICK_LEN so they all look the same
  469. privmsg.nick = saltbox::encrypt(saltbox, &pad(&privmsg.nick));
  470. privmsg.msg = saltbox::encrypt(saltbox, privmsg.msg.as_bytes());
  471. debug!("Successfully encrypted message for {name}");
  472. return
  473. }
  474. };
  475. if let Some((name, contact)) = self.contacts.read().await.get_key_value(&privmsg.channel) {
  476. // We will use dummy channel and nick values of MAX_NICK_LEN,
  477. // since they are not used, so all encrypted messages look the same.
  478. privmsg.channel = saltbox::encrypt(&contact.saltbox, &[0x00; MAX_NICK_LEN]);
  479. // We will encrypt the dummy nick value using our own self saltbox,
  480. // so we can identify our messages.
  481. privmsg.nick = saltbox::encrypt(&contact.self_saltbox, &[0x00; MAX_NICK_LEN]);
  482. privmsg.msg = saltbox::encrypt(&contact.saltbox, privmsg.msg.as_bytes());
  483. debug!("Successfully encrypted message for {name}");
  484. };
  485. }
  486. /// Try decrypting a given potentially encrypted `Privmsg` object.
  487. pub async fn try_decrypt(&self, privmsg: &mut Privmsg, self_nickname: &str) {
  488. // If all fields have base58, then we can consider decrypting.
  489. let channel_ciphertext = match bs58::decode(&privmsg.channel).into_vec() {
  490. Ok(v) => v,
  491. Err(_) => return,
  492. };
  493. let nick_ciphertext = match bs58::decode(&privmsg.nick).into_vec() {
  494. Ok(v) => v,
  495. Err(_) => return,
  496. };
  497. let msg_ciphertext = match bs58::decode(&privmsg.msg).into_vec() {
  498. Ok(v) => v,
  499. Err(_) => return,
  500. };
  501. // Now go through all 3 ciphertexts. We'll use intermediate buffers
  502. // for decryption, iff all passes, we will return a modified
  503. // (i.e. decrypted) privmsg, otherwise we return the original.
  504. for (name, channel) in self.channels.read().await.iter() {
  505. let Some(saltbox) = &channel.saltbox else { continue };
  506. if saltbox::try_decrypt(saltbox, &channel_ciphertext).is_none() {
  507. continue
  508. };
  509. let Some(mut nick_dec) = saltbox::try_decrypt(saltbox, &nick_ciphertext) else {
  510. warn!(target: "darkirc::irc::server::try_decrypt", "Could not decrypt nick ciphertext for channel: {name}");
  511. continue
  512. };
  513. let Some(msg_dec) = saltbox::try_decrypt(saltbox, &msg_ciphertext) else {
  514. warn!(target: "darkirc::irc::server::try_decrypt", "Could not decrypt message ciphertext for channel: {name}");
  515. continue
  516. };
  517. unpad(&mut nick_dec);
  518. privmsg.channel = name.to_string();
  519. privmsg.nick = String::from_utf8_lossy(&nick_dec).into();
  520. privmsg.msg = String::from_utf8_lossy(&msg_dec).into();
  521. debug!("Successfully decrypted message for {name}");
  522. return
  523. }
  524. for (name, contact) in self.contacts.read().await.iter() {
  525. if saltbox::try_decrypt(&contact.saltbox, &channel_ciphertext).is_none() {
  526. continue
  527. };
  528. // Since everyone encrypts the dummy nick value with their self saltbox,
  529. // we try to decrypt using our, to identify our messages.
  530. let nick = if saltbox::try_decrypt(&contact.self_saltbox, &nick_ciphertext).is_some() {
  531. String::from(self_nickname)
  532. } else {
  533. name.to_string()
  534. };
  535. let Some(msg_dec) = saltbox::try_decrypt(&contact.saltbox, &msg_ciphertext) else {
  536. warn!(target: "darkirc::irc::server::try_decrypt", "Could not decrypt message ciphertext for contact: {name}");
  537. continue
  538. };
  539. privmsg.channel = name.to_string();
  540. privmsg.nick = nick;
  541. privmsg.msg = String::from_utf8_lossy(&msg_dec).into();
  542. debug!("Successfully decrypted message from {name}");
  543. return
  544. }
  545. }
  546. }
  547. #[cfg(test)]
  548. mod tests {
  549. use std::io::Cursor;
  550. use darkfi::{event_graph::rln::epoch_of, Error};
  551. use darkfi_sdk::pasta::pallas;
  552. use darkfi_serial::deserialize_async;
  553. use super::*;
  554. fn test_identity(limit: u64) -> RlnIdentity {
  555. RlnIdentity {
  556. nullifier: pallas::Base::from(0xabc_u64),
  557. trapdoor: pallas::Base::from(0xdef_u64),
  558. user_message_limit: limit,
  559. message_id: 0,
  560. last_epoch: 0,
  561. }
  562. }
  563. #[test]
  564. fn tls_secret_parser_rejects_malformed_key() {
  565. let mut reader = Cursor::new(b"not a private key".as_slice());
  566. assert!(matches!(parse_tls_secret(&mut reader), Err(Error::ParseFailed(_))));
  567. }
  568. #[test]
  569. fn tls_cert_parser_rejects_malformed_cert() {
  570. let mut reader = Cursor::new(b"not a certificate".as_slice());
  571. assert!(matches!(parse_tls_cert(&mut reader), Err(Error::ParseFailed(_))));
  572. }
  573. #[test]
  574. fn load_default_rln_identity_returns_none_for_empty_tree() {
  575. smol::block_on(async {
  576. let (kvdb, _kvdb_folder) = Database::open_temp().unwrap();
  577. let identity = load_default_rln_identity(&kvdb).await.unwrap();
  578. assert!(identity.is_none());
  579. })
  580. }
  581. #[test]
  582. fn load_default_rln_identity_rejects_missing_identity_record() {
  583. smol::block_on(async {
  584. let (kvdb, _kvdb_folder) = Database::open_temp().unwrap();
  585. let default = kvdb.open_tree_default(ACCOUNTS_DEFAULT_TREE).unwrap();
  586. default.insert(b"other", b"value").unwrap();
  587. let err = match load_default_rln_identity(&kvdb).await {
  588. Ok(_) => panic!("expected missing identity record error"),
  589. Err(e) => e,
  590. };
  591. assert!(matches!(
  592. err,
  593. Error::ParseFailed("Default RLN account is missing identity record")
  594. ));
  595. })
  596. }
  597. #[test]
  598. fn load_default_rln_identity_rejects_corrupted_identity_record() {
  599. smol::block_on(async {
  600. let (kvdb, _kvdb_folder) = Database::open_temp().unwrap();
  601. let default = kvdb.open_tree_default(ACCOUNTS_DEFAULT_TREE).unwrap();
  602. default.insert(ACCOUNTS_KEY_RLN_IDENTITY, b"not an identity").unwrap();
  603. let err = match load_default_rln_identity(&kvdb).await {
  604. Ok(_) => panic!("expected corrupted identity record error"),
  605. Err(e) => e,
  606. };
  607. assert!(matches!(err, Error::ParseFailed("Default RLN account identity is corrupted")));
  608. })
  609. }
  610. #[test]
  611. fn rln_message_reservation_persists_default_and_account_counters() {
  612. smol::block_on(async {
  613. let (kvdb, _kvdb_folder) = Database::open_temp().unwrap();
  614. let account = kvdb.open_tree_default(&format!("{ACCOUNTS_DB_PREFIX}alice")).unwrap();
  615. let default = kvdb.open_tree_default(ACCOUNTS_DEFAULT_TREE).unwrap();
  616. let identity = test_identity(2);
  617. let encoded = serialize_async(&identity).await;
  618. account.insert(ACCOUNTS_KEY_RLN_IDENTITY, &encoded).unwrap();
  619. default.insert(ACCOUNTS_KEY_RLN_IDENTITY, &encoded).unwrap();
  620. let now = 1_704_067_800_000;
  621. let mut active = Some(identity);
  622. let reservation =
  623. reserve_rln_message_id_in_store(&kvdb, &mut active, now).await.unwrap();
  624. let RlnMessageReservation::Reserved { identity: reserved, message_id } = reservation
  625. else {
  626. panic!("expected reservation")
  627. };
  628. assert_eq!(message_id, 0);
  629. assert_eq!(reserved.message_id, 1);
  630. assert_eq!(reserved.last_epoch, epoch_of(now));
  631. let stored_default: RlnIdentity =
  632. deserialize_async(&default.get(ACCOUNTS_KEY_RLN_IDENTITY).unwrap().unwrap())
  633. .await
  634. .unwrap();
  635. let stored_account: RlnIdentity =
  636. deserialize_async(&account.get(ACCOUNTS_KEY_RLN_IDENTITY).unwrap().unwrap())
  637. .await
  638. .unwrap();
  639. assert_eq!(stored_default.message_id, 1);
  640. assert_eq!(stored_account.message_id, 1);
  641. assert_eq!(stored_default.last_epoch, epoch_of(now));
  642. assert_eq!(stored_account.last_epoch, epoch_of(now));
  643. let reservation =
  644. reserve_rln_message_id_in_store(&kvdb, &mut active, now).await.unwrap();
  645. let RlnMessageReservation::Reserved { message_id, .. } = reservation else {
  646. panic!("expected second reservation")
  647. };
  648. assert_eq!(message_id, 1);
  649. let exhausted = reserve_rln_message_id_in_store(&kvdb, &mut active, now).await.unwrap();
  650. assert!(matches!(exhausted, RlnMessageReservation::BudgetExhausted));
  651. })
  652. }
  653. }