server.rs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2025 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::{BufReader, Cursor},
  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. zk::{empty_witnesses, ProvingKey, VerifyingKey, ZkCircuit},
  30. zkas::ZkBinary,
  31. Error, Result,
  32. };
  33. use darkfi_sdk::crypto::MerkleTree;
  34. use darkfi_serial::serialize_async;
  35. use futures_rustls::{
  36. rustls::{self, pki_types::PrivateKeyDer},
  37. TlsAcceptor,
  38. };
  39. use log::{debug, error, info, warn};
  40. use sled_overlay::sled;
  41. use smol::{
  42. fs,
  43. lock::{Mutex, RwLock},
  44. net::{SocketAddr, TcpListener},
  45. prelude::{AsyncRead, AsyncWrite},
  46. Executor,
  47. };
  48. use url::Url;
  49. use super::{client::Client, ChaChaBox, IrcChannel, IrcContact, Priv, Privmsg};
  50. use crate::{
  51. crypto::{
  52. rln::{RlnIdentity, RLN2_SIGNAL_ZKBIN, RLN2_SLASH_ZKBIN},
  53. saltbox,
  54. },
  55. settings::{
  56. parse_autojoin_channels, parse_configured_channels, parse_configured_contacts,
  57. parse_rln_identity,
  58. },
  59. DarkIrc,
  60. };
  61. /// Max channel/nick length
  62. pub const MAX_NICK_LEN: usize = 24;
  63. /// Max message length
  64. pub const MAX_MSG_LEN: usize = 512;
  65. /// IRC server instance
  66. pub struct IrcServer {
  67. /// DarkIrc instance
  68. pub darkirc: Arc<DarkIrc>,
  69. /// Path to the darkirc config file
  70. config_path: PathBuf,
  71. /// TCP listener
  72. listener: TcpListener,
  73. /// TLS acceptor
  74. acceptor: Option<TlsAcceptor>,
  75. /// Configured autojoin channels
  76. pub autojoin: RwLock<Vec<String>>,
  77. /// Configured IRC channels
  78. pub channels: RwLock<HashMap<String, IrcChannel>>,
  79. /// Configured IRC contacts
  80. pub contacts: RwLock<HashMap<String, IrcContact>>,
  81. /// Configured RLN identity
  82. pub rln_identity: RwLock<Option<RlnIdentity>>,
  83. /// Saltbox used to encrypt our nick in direct messages
  84. saltbox: RwLock<Option<Arc<ChaChaBox>>>,
  85. /// Active client connections
  86. clients: Mutex<HashMap<u16, StoppableTaskPtr>>,
  87. /// IRC server Password
  88. pub password: String,
  89. /// Persistent server storage
  90. pub server_store: sled::Tree,
  91. /// RLN identity storage
  92. pub rln_identity_store: sled::Tree,
  93. /// RLN Signal VerifyingKey
  94. pub rln_signal_vk: VerifyingKey,
  95. }
  96. impl IrcServer {
  97. /// Instantiate a new IRC server. This function will try to bind a TCP socket,
  98. /// and optionally load a TLS certificate and key. To start the listening loop,
  99. /// call `IrcServer::listen()`.
  100. pub async fn new(
  101. darkirc: Arc<DarkIrc>,
  102. listen: Url,
  103. tls_cert: Option<String>,
  104. tls_secret: Option<String>,
  105. config_path: PathBuf,
  106. password: String,
  107. ) -> Result<Arc<Self>> {
  108. let scheme = listen.scheme();
  109. if scheme != "tcp" && scheme != "tcp+tls" {
  110. error!("IRC server supports listening only on tcp:// or tcp+tls://");
  111. return Err(Error::BindFailed(listen.to_string()))
  112. }
  113. if scheme == "tcp+tls" && (tls_cert.is_none() || tls_secret.is_none()) {
  114. error!("You must provide a TLS certificate and key if you want a TLS server");
  115. return Err(Error::BindFailed(listen.to_string()))
  116. }
  117. // Bind listener
  118. let listen_addr = listen.socket_addrs(|| None)?[0];
  119. let listener = TcpListener::bind(listen_addr).await?;
  120. let acceptor = match scheme {
  121. "tcp+tls" => {
  122. // openssl genpkey -algorithm ED25519 > example.com.key
  123. // openssl req -new -out example.com.csr -key example.com.key
  124. // openssl x509 -req -in example.com.csr -signkey example.com.key -out example.com.crt
  125. let f = File::open(expand_path(tls_secret.as_ref().unwrap())?)?;
  126. let mut reader = BufReader::new(f);
  127. let secret = PrivateKeyDer::Pkcs8(
  128. rustls_pemfile::pkcs8_private_keys(&mut reader).next().unwrap().unwrap(),
  129. );
  130. let f = File::open(expand_path(tls_cert.as_ref().unwrap())?)?;
  131. let mut reader = BufReader::new(f);
  132. let cert = rustls_pemfile::certs(&mut reader).next().unwrap().unwrap();
  133. let config = rustls::ServerConfig::builder()
  134. .with_no_client_auth()
  135. .with_single_cert(vec![cert], secret)
  136. .unwrap();
  137. let acceptor = TlsAcceptor::from(Arc::new(config));
  138. Some(acceptor)
  139. }
  140. _ => None,
  141. };
  142. // Open persistent dbs
  143. let server_store = darkirc.sled.open_tree("server_store")?;
  144. let rln_identity_store = darkirc.sled.open_tree("rln_identity_store")?;
  145. // Generate RLN proving and verifying keys, if needed
  146. let rln_signal_zkbin = ZkBinary::decode(RLN2_SIGNAL_ZKBIN)?;
  147. let rln_signal_circuit =
  148. ZkCircuit::new(empty_witnesses(&rln_signal_zkbin)?, &rln_signal_zkbin);
  149. if server_store.get("rlnv2-diff-signal-pk")?.is_none() {
  150. info!(target: "irc::server", "[RLN] Creating RlnV2_Diff_Signal ProvingKey");
  151. let provingkey = ProvingKey::build(rln_signal_zkbin.k, &rln_signal_circuit);
  152. let mut buf = vec![];
  153. provingkey.write(&mut buf)?;
  154. server_store.insert("rlnv2-diff-signal-pk", buf)?;
  155. }
  156. let rln_signal_vk = match server_store.get("rlnv2-diff-signal-vk")? {
  157. Some(vk) => {
  158. let mut reader = Cursor::new(vk);
  159. VerifyingKey::read(&mut reader, rln_signal_circuit)?
  160. }
  161. None => {
  162. info!(target: "irc::server", "[RLN] Creating RlnV2_Diff_Signal VerifyingKey");
  163. let verifyingkey = VerifyingKey::build(rln_signal_zkbin.k, &rln_signal_circuit);
  164. let mut buf = vec![];
  165. verifyingkey.write(&mut buf)?;
  166. server_store.insert("rlnv2-diff-signal-vk", buf)?;
  167. verifyingkey
  168. }
  169. };
  170. if server_store.get("rlnv2-diff-slash-pk")?.is_none() {
  171. info!(target: "irc::server", "[RLN] Creating RlnV2_Diff_Slash ProvingKey");
  172. let zkbin = ZkBinary::decode(RLN2_SLASH_ZKBIN)?;
  173. let circuit = ZkCircuit::new(empty_witnesses(&zkbin).unwrap(), &zkbin);
  174. let provingkey = ProvingKey::build(zkbin.k, &circuit);
  175. let mut buf = vec![];
  176. provingkey.write(&mut buf)?;
  177. server_store.insert("rlnv2-diff-slash-pk", buf)?;
  178. }
  179. if server_store.get("rlnv2-diff-slash-vk")?.is_none() {
  180. info!(target: "irc::server", "[RLN] Creating RlnV2_Diff_Slash VerifyingKey");
  181. let zkbin = ZkBinary::decode(RLN2_SIGNAL_ZKBIN)?;
  182. let circuit = ZkCircuit::new(empty_witnesses(&zkbin).unwrap(), &zkbin);
  183. let verifyingkey = VerifyingKey::build(zkbin.k, &circuit);
  184. let mut buf = vec![];
  185. verifyingkey.write(&mut buf)?;
  186. server_store.insert("rlnv2-diff-slash-vk", buf)?;
  187. }
  188. // Initialize RLN Incremental Merkle tree if necessary
  189. if server_store.get("rln_identity_tree")?.is_none() {
  190. let tree = MerkleTree::new(1);
  191. server_store.insert("rln_identity_tree", serialize_async(&tree).await)?;
  192. }
  193. let self_ = Arc::new(Self {
  194. darkirc,
  195. config_path,
  196. listener,
  197. acceptor,
  198. autojoin: RwLock::new(Vec::new()),
  199. channels: RwLock::new(HashMap::new()),
  200. contacts: RwLock::new(HashMap::new()),
  201. saltbox: RwLock::new(None),
  202. rln_identity: RwLock::new(None),
  203. clients: Mutex::new(HashMap::new()),
  204. password,
  205. server_store,
  206. rln_identity_store,
  207. rln_signal_vk,
  208. });
  209. // Load any channel/contact configuration.
  210. self_.rehash().await?;
  211. Ok(self_)
  212. }
  213. /// Reload the darkirc configuration file and reconfigure channels and contacts.
  214. pub async fn rehash(&self) -> Result<()> {
  215. let contents = fs::read_to_string(&self.config_path).await?;
  216. let contents = match toml::from_str(&contents) {
  217. Ok(v) => v,
  218. Err(e) => {
  219. error!("Failed parsing TOML config: {}", e);
  220. return Err(Error::ParseFailed("Failed parsing TOML config"))
  221. }
  222. };
  223. // Parse autojoin channels
  224. let autojoin = parse_autojoin_channels(&contents)?;
  225. // Parse configured channels
  226. let channels = parse_configured_channels(&contents)?;
  227. // Parse configured contacts
  228. let (contacts, saltbox) = parse_configured_contacts(&contents)?;
  229. // Parse RLN identity
  230. let rln_identity = parse_rln_identity(&contents)?;
  231. // FIXME: This will remove clients' joined channels. They need to stay.
  232. // Only if everything is fine, replace.
  233. *self.autojoin.write().await = autojoin;
  234. *self.channels.write().await = channels;
  235. *self.contacts.write().await = contacts;
  236. *self.saltbox.write().await = saltbox;
  237. *self.rln_identity.write().await = rln_identity;
  238. Ok(())
  239. }
  240. /// Start accepting new IRC connections.
  241. pub async fn listen(self: Arc<Self>, ex: Arc<Executor<'_>>) -> Result<()> {
  242. loop {
  243. let (stream, peer_addr) = match self.listener.accept().await {
  244. Ok((s, a)) => (s, a),
  245. // As per usual accept(2) recommendations
  246. Err(e) if e.raw_os_error().is_some() => match e.raw_os_error().unwrap() {
  247. libc::EAGAIN | libc::ECONNABORTED | libc::EPROTO | libc::EINTR => continue,
  248. _ => {
  249. error!("[IRC SERVER] Failed accepting connection: {}", e);
  250. return Err(e.into())
  251. }
  252. },
  253. Err(e) => {
  254. error!("[IRC SERVER] Failed accepting new connection: {}", e);
  255. continue
  256. }
  257. };
  258. match &self.acceptor {
  259. // Expecting encrypted TLS connection
  260. Some(acceptor) => {
  261. let stream = match acceptor.accept(stream).await {
  262. Ok(s) => s,
  263. Err(e) => {
  264. error!("[IRC SERVER] Failed accepting new TLS connection: {}", e);
  265. continue
  266. }
  267. };
  268. // Subscribe to incoming events and set up the connection.
  269. let incoming = self.darkirc.event_graph.event_pub.clone().subscribe().await;
  270. if let Err(e) = self
  271. .clone()
  272. .process_connection(stream, peer_addr, incoming, ex.clone())
  273. .await
  274. {
  275. error!("[IRC SERVER] Failed processing new connection: {}", e);
  276. continue
  277. };
  278. }
  279. // Expecting plain TCP connection
  280. None => {
  281. // Subscribe to incoming events and set up the connection.
  282. let incoming = self.darkirc.event_graph.event_pub.clone().subscribe().await;
  283. if let Err(e) = self
  284. .clone()
  285. .process_connection(stream, peer_addr, incoming, ex.clone())
  286. .await
  287. {
  288. error!("[IRC SERVER] Failed processing new connection: {}", e);
  289. continue
  290. };
  291. }
  292. }
  293. info!("[IRC SERVER] Accepted new client connection at: {}", peer_addr);
  294. }
  295. }
  296. /// IRC client connection process.
  297. /// Sets up multiplexing between the server and client.
  298. /// Detaches the connection as a `StoppableTask`.
  299. async fn process_connection<C: AsyncRead + AsyncWrite + Send + Unpin + 'static>(
  300. self: Arc<Self>,
  301. stream: C,
  302. peer_addr: SocketAddr,
  303. incoming: Subscription<Event>,
  304. ex: Arc<Executor<'_>>,
  305. ) -> Result<()> {
  306. let port = peer_addr.port();
  307. let client = Client::new(self.clone(), incoming, peer_addr).await?;
  308. let conn_task = StoppableTask::new();
  309. self.clients.lock().await.insert(port, conn_task.clone());
  310. conn_task.clone().start(
  311. async move { client.multiplex_connection(stream).await },
  312. move |res| async move {
  313. match res {
  314. Ok(()) => info!("[IRC SERVER] Disconnected client from {}", peer_addr),
  315. Err(e) => error!("[IRC SERVER] Disconnected client from {}: {}", peer_addr, e),
  316. }
  317. self.clone().clients.lock().await.remove(&port);
  318. },
  319. Error::ChannelStopped,
  320. ex,
  321. );
  322. Ok(())
  323. }
  324. fn pad(string: &str) -> Vec<u8> {
  325. let mut bytes = string.as_bytes().to_vec();
  326. bytes.resize(MAX_NICK_LEN, 0x00);
  327. bytes
  328. }
  329. fn unpad(vec: &mut Vec<u8>) {
  330. if let Some(i) = vec.iter().rposition(|x| *x != 0) {
  331. let new_len = i + 1;
  332. vec.truncate(new_len);
  333. }
  334. }
  335. /// Try encrypting a given `Privmsg` if there is such a channel/contact.
  336. pub async fn try_encrypt<T: Priv>(&self, privmsg: &mut T) {
  337. if let Some((name, channel)) = self.channels.read().await.get_key_value(privmsg.channel()) {
  338. if let Some(saltbox) = &channel.saltbox {
  339. // We will use a dummy channel value of MAX_NICK_LEN,
  340. // since its not used, so all encrypted messages look the same.
  341. *privmsg.channel() = saltbox::encrypt(saltbox, &[0x00; MAX_NICK_LEN]);
  342. // We will pad the name to MAX_NICK_LEN so they all look the same
  343. *privmsg.nick() = saltbox::encrypt(saltbox, &Self::pad(privmsg.nick()));
  344. *privmsg.msg() = saltbox::encrypt(saltbox, privmsg.msg().as_bytes());
  345. debug!("Successfully encrypted message for {}", name);
  346. return
  347. }
  348. };
  349. if let Some((name, contact)) = self.contacts.read().await.get_key_value(privmsg.channel()) {
  350. if let Some(saltbox) = &contact.saltbox {
  351. // We will use dummy channel and nick values of MAX_NICK_LEN,
  352. // since they are not used, so all encrypted messages look the same.
  353. *privmsg.channel() = saltbox::encrypt(saltbox, &[0x00; MAX_NICK_LEN]);
  354. // We will encrypt the dummy nick value using our own self saltbox,
  355. // so we can identify our messages. We can safely unwrap here since
  356. // we know that if contacts exist, our self saltbox does as well.
  357. *privmsg.nick() = saltbox::encrypt(
  358. self.saltbox.read().await.as_ref().unwrap(),
  359. &[0x00; MAX_NICK_LEN],
  360. );
  361. *privmsg.msg() = saltbox::encrypt(saltbox, privmsg.msg().as_bytes());
  362. debug!("Successfully encrypted message for {}", name);
  363. }
  364. };
  365. }
  366. /// Try decrypting a given potentially encrypted `Privmsg` object.
  367. pub async fn try_decrypt(&self, privmsg: &mut Privmsg, self_nickname: &str) {
  368. // If all fields have base58, then we can consider decrypting.
  369. let channel_ciphertext = match bs58::decode(&privmsg.channel).into_vec() {
  370. Ok(v) => v,
  371. Err(_) => return,
  372. };
  373. let nick_ciphertext = match bs58::decode(&privmsg.nick).into_vec() {
  374. Ok(v) => v,
  375. Err(_) => return,
  376. };
  377. let msg_ciphertext = match bs58::decode(&privmsg.msg).into_vec() {
  378. Ok(v) => v,
  379. Err(_) => return,
  380. };
  381. // Now go through all 3 ciphertexts. We'll use intermediate buffers
  382. // for decryption, iff all passes, we will return a modified
  383. // (i.e. decrypted) privmsg, otherwise we return the original.
  384. for (name, channel) in self.channels.read().await.iter() {
  385. let Some(saltbox) = &channel.saltbox else { continue };
  386. if saltbox::try_decrypt(saltbox, &channel_ciphertext).is_none() {
  387. continue
  388. };
  389. let Some(mut nick_dec) = saltbox::try_decrypt(saltbox, &nick_ciphertext) else {
  390. warn!(target: "darkirc::irc::server::try_decrypt", "Could not decrypt nick ciphertext for channel: {name}");
  391. continue
  392. };
  393. let Some(msg_dec) = saltbox::try_decrypt(saltbox, &msg_ciphertext) else {
  394. warn!(target: "darkirc::irc::server::try_decrypt", "Could not decrypt message ciphertext for channel: {name}");
  395. continue
  396. };
  397. Self::unpad(&mut nick_dec);
  398. privmsg.channel = name.to_string();
  399. privmsg.nick = String::from_utf8_lossy(&nick_dec).into();
  400. privmsg.msg = String::from_utf8_lossy(&msg_dec).into();
  401. debug!("Successfully decrypted message for {}", name);
  402. return
  403. }
  404. for (name, contact) in self.contacts.read().await.iter() {
  405. let Some(saltbox) = &contact.saltbox else { continue };
  406. if saltbox::try_decrypt(saltbox, &channel_ciphertext).is_none() {
  407. continue
  408. };
  409. // Since everyone encrypts the dummy nick value with their self saltbox,
  410. // we try to decrypt using our, to identify our messages. We can safely
  411. // unwrap here since we know that if contacts exist, our self saltbox does as well.
  412. let nick = if saltbox::try_decrypt(
  413. self.saltbox.read().await.as_ref().unwrap(),
  414. &nick_ciphertext,
  415. )
  416. .is_some()
  417. {
  418. String::from(self_nickname)
  419. } else {
  420. name.to_string()
  421. };
  422. let Some(msg_dec) = saltbox::try_decrypt(saltbox, &msg_ciphertext) else {
  423. warn!(target: "darkirc::irc::server::try_decrypt", "Could not decrypt message ciphertext for contact: {name}");
  424. continue
  425. };
  426. privmsg.channel = name.to_string();
  427. privmsg.nick = nick;
  428. privmsg.msg = String::from_utf8_lossy(&msg_dec).into();
  429. debug!("Successfully decrypted message from {}", name);
  430. return
  431. }
  432. }
  433. }