mod.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2023 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::{collections::HashMap, fs::File, net::SocketAddr};
  19. use async_std::{net::TcpListener, sync::Arc};
  20. use futures::{io::BufReader, AsyncRead, AsyncReadExt, AsyncWrite};
  21. use futures_rustls::{rustls, TlsAcceptor};
  22. use log::{error, info};
  23. use darkfi::{net::P2pPtr, system::SubscriberPtr, util::path::expand_path, Error, Result};
  24. use crate::{
  25. model::{Event, EventId, ModelPtr},
  26. privmsg::{EventAction, PrivMsgEvent},
  27. protocol_event::{Seen, SeenPtr, UnreadEventsPtr},
  28. settings::{get_current_time, Args, ChannelInfo, ContactInfo},
  29. view::ViewPtr,
  30. };
  31. mod client;
  32. pub use client::IrcClient;
  33. #[derive(Clone)]
  34. pub struct IrcConfig {
  35. // init bool
  36. pub is_nick_init: bool,
  37. pub is_user_init: bool,
  38. pub is_registered: bool,
  39. pub is_cap_end: bool,
  40. pub is_pass_init: bool,
  41. // user config
  42. pub nickname: String,
  43. pub password: String,
  44. pub private_key: Option<String>,
  45. pub capabilities: HashMap<String, bool>,
  46. // channels and contacts
  47. pub channels: HashMap<String, ChannelInfo>,
  48. pub contacts: HashMap<String, ContactInfo>,
  49. }
  50. impl IrcConfig {
  51. pub fn new(settings: &Args) -> Result<Self> {
  52. let password = settings.password.as_ref().unwrap_or(&String::new()).clone();
  53. let private_key = settings.private_key.clone();
  54. let mut channels = settings.channels.clone();
  55. for chan in settings.autojoin.iter() {
  56. if !channels.contains_key(chan) {
  57. channels.insert(chan.clone(), ChannelInfo::new());
  58. }
  59. }
  60. let contacts = settings.contacts.clone();
  61. let mut capabilities = HashMap::new();
  62. capabilities.insert("no-history".to_string(), false);
  63. Ok(Self {
  64. is_nick_init: false,
  65. is_user_init: false,
  66. is_registered: false,
  67. is_cap_end: true,
  68. is_pass_init: false,
  69. nickname: "anon".to_string(),
  70. password,
  71. channels,
  72. contacts,
  73. private_key,
  74. capabilities,
  75. })
  76. }
  77. }
  78. #[derive(Clone)]
  79. pub enum ClientSubMsg {
  80. Privmsg(PrivMsgEvent),
  81. Config(IrcConfig),
  82. }
  83. #[derive(Clone)]
  84. pub enum NotifierMsg {
  85. Privmsg(PrivMsgEvent),
  86. UpdateConfig,
  87. }
  88. pub struct IrcServer {
  89. settings: Args,
  90. p2p: P2pPtr,
  91. model: ModelPtr,
  92. view: ViewPtr,
  93. unread_events: UnreadEventsPtr,
  94. clients_subscriptions: SubscriberPtr<ClientSubMsg>,
  95. seen: SeenPtr<EventId>,
  96. }
  97. impl IrcServer {
  98. pub async fn new(
  99. settings: Args,
  100. p2p: P2pPtr,
  101. model: ModelPtr,
  102. view: ViewPtr,
  103. unread_events: UnreadEventsPtr,
  104. clients_subscriptions: SubscriberPtr<ClientSubMsg>,
  105. ) -> Result<Self> {
  106. let seen = Seen::new();
  107. Ok(Self { settings, p2p, model, view, unread_events, clients_subscriptions, seen })
  108. }
  109. pub async fn start(&self, executor: Arc<smol::Executor<'_>>) -> Result<()> {
  110. let (msg_notifier, msg_recv) = smol::channel::unbounded();
  111. // Listen to msgs from clients
  112. executor
  113. .clone()
  114. .spawn(Self::listen_to_msgs(
  115. self.p2p.clone(),
  116. self.model.clone(),
  117. self.seen.clone(),
  118. self.unread_events.clone(),
  119. msg_recv,
  120. self.clients_subscriptions.clone(),
  121. ))
  122. .detach();
  123. executor
  124. .clone()
  125. .spawn(Self::listen_to_view(
  126. self.view.clone(),
  127. self.seen.clone(),
  128. self.clients_subscriptions.clone(),
  129. ))
  130. .detach();
  131. // Start listening for new connections
  132. self.listen(msg_notifier, executor.clone()).await?;
  133. Ok(())
  134. }
  135. async fn listen_to_view(
  136. view: ViewPtr,
  137. seen: SeenPtr<EventId>,
  138. clients_subscriptions: SubscriberPtr<ClientSubMsg>,
  139. ) -> Result<()> {
  140. loop {
  141. let event = view.lock().await.process().await?;
  142. if !seen.push(&event.hash()).await {
  143. continue
  144. }
  145. let msg = match event.action {
  146. EventAction::PrivMsg(x) => x,
  147. };
  148. clients_subscriptions.notify(ClientSubMsg::Privmsg(msg)).await;
  149. }
  150. }
  151. /// Start listening to msgs from irc clients
  152. pub async fn listen_to_msgs(
  153. p2p: P2pPtr,
  154. model: ModelPtr,
  155. seen: SeenPtr<EventId>,
  156. unread_events: UnreadEventsPtr,
  157. recv: smol::channel::Receiver<(NotifierMsg, u64)>,
  158. clients_subscriptions: SubscriberPtr<ClientSubMsg>,
  159. ) -> Result<()> {
  160. loop {
  161. let (msg, subscription_id) = recv.recv().await?;
  162. match msg {
  163. NotifierMsg::Privmsg(msg) => {
  164. let event = Event {
  165. previous_event_hash: model.lock().await.get_current_root(),
  166. action: EventAction::PrivMsg(msg.clone()),
  167. timestamp: get_current_time(),
  168. read_confirms: 0,
  169. };
  170. // Since this will be added to the View directly, other clients connected to irc
  171. // server must get informed about this new msg
  172. clients_subscriptions
  173. .notify_with_exclude(ClientSubMsg::Privmsg(msg), &[subscription_id])
  174. .await;
  175. if !seen.push(&event.hash()).await {
  176. continue
  177. }
  178. // view.lock().await.seen.insert(event.hash(), event.clone());
  179. // unread_events.lock().await.insert(&event);
  180. p2p.broadcast(event).await?;
  181. }
  182. NotifierMsg::UpdateConfig => {
  183. //
  184. // load and parse the new settings from configuration file and pass it to all
  185. // irc clients
  186. //
  187. // let new_config = IrcConfig::new()?;
  188. // clients_subscriptions.notify(ClientSubMsg::Config(new_config)).await;
  189. }
  190. }
  191. }
  192. }
  193. /// Start listening to new connections from irc clients
  194. pub async fn listen(
  195. &self,
  196. notifier: smol::channel::Sender<(NotifierMsg, u64)>,
  197. executor: Arc<smol::Executor<'_>>,
  198. ) -> Result<()> {
  199. let (listener, acceptor) = self.setup_listener().await?;
  200. info!("[IRC SERVER] listening on {}", self.settings.irc_listen);
  201. loop {
  202. let (stream, peer_addr) = match listener.accept().await {
  203. Ok((s, a)) => (s, a),
  204. Err(e) => {
  205. error!("[IRC SERVER] Failed accepting new connections: {}", e);
  206. continue
  207. }
  208. };
  209. let result = if let Some(acceptor) = acceptor.clone() {
  210. // TLS connection
  211. let stream = match acceptor.accept(stream).await {
  212. Ok(s) => s,
  213. Err(e) => {
  214. error!("[IRC SERVER] Failed accepting TLS connection: {}", e);
  215. continue
  216. }
  217. };
  218. self.process_connection(stream, peer_addr, notifier.clone(), executor.clone()).await
  219. } else {
  220. // TCP connection
  221. self.process_connection(stream, peer_addr, notifier.clone(), executor.clone()).await
  222. };
  223. if let Err(e) = result {
  224. error!("[IRC SERVER] Failed processing connection {}: {}", peer_addr, e);
  225. continue
  226. };
  227. info!("[IRC SERVER] Accept new connection: {}", peer_addr);
  228. }
  229. }
  230. /// On every new connection create new IrcClient
  231. async fn process_connection<C: AsyncRead + AsyncWrite + Send + Unpin + 'static>(
  232. &self,
  233. stream: C,
  234. peer_addr: SocketAddr,
  235. notifier: smol::channel::Sender<(NotifierMsg, u64)>,
  236. executor: Arc<smol::Executor<'_>>,
  237. ) -> Result<()> {
  238. let (reader, writer) = stream.split();
  239. let reader = BufReader::new(reader);
  240. // Subscription for the new client
  241. let client_subscription = self.clients_subscriptions.clone().subscribe().await;
  242. // new irc configuration
  243. let irc_config = IrcConfig::new(&self.settings)?;
  244. // New irc client
  245. let mut client = IrcClient::new(
  246. writer,
  247. reader,
  248. peer_addr,
  249. irc_config,
  250. notifier,
  251. client_subscription,
  252. self.unread_events.clone(),
  253. );
  254. // Start listening and detach
  255. executor
  256. .spawn(async move {
  257. client.listen().await;
  258. })
  259. .detach();
  260. Ok(())
  261. }
  262. /// Setup a listener for irc server
  263. async fn setup_listener(&self) -> Result<(TcpListener, Option<TlsAcceptor>)> {
  264. let listenaddr = self.settings.irc_listen.socket_addrs(|| None)?[0];
  265. let listener = TcpListener::bind(listenaddr).await?;
  266. let acceptor = match self.settings.irc_listen.scheme() {
  267. "tls" => {
  268. // openssl genpkey -algorithm ED25519 > example.com.key
  269. // openssl req -new -out example.com.csr -key example.com.key
  270. // openssl x509 -req -days 700 -in example.com.csr -signkey example.com.key -out example.com.crt
  271. if self.settings.irc_tls_secret.is_none() || self.settings.irc_tls_cert.is_none() {
  272. error!("[IRC SERVER] To listen using TLS, please set irc_tls_secret and irc_tls_cert in your config file.");
  273. return Err(Error::KeypairPathNotFound)
  274. }
  275. let file =
  276. File::open(expand_path(self.settings.irc_tls_secret.as_ref().unwrap())?)?;
  277. let mut reader = std::io::BufReader::new(file);
  278. let secret = &rustls_pemfile::pkcs8_private_keys(&mut reader)?[0];
  279. let secret = rustls::PrivateKey(secret.clone());
  280. let file = File::open(expand_path(self.settings.irc_tls_cert.as_ref().unwrap())?)?;
  281. let mut reader = std::io::BufReader::new(file);
  282. let certificate = &rustls_pemfile::certs(&mut reader)?[0];
  283. let certificate = rustls::Certificate(certificate.clone());
  284. let config = rustls::ServerConfig::builder()
  285. .with_safe_defaults()
  286. .with_no_client_auth()
  287. .with_single_cert(vec![certificate], secret)?;
  288. let acceptor = TlsAcceptor::from(Arc::new(config));
  289. Some(acceptor)
  290. }
  291. _ => None,
  292. };
  293. Ok((listener, acceptor))
  294. }
  295. }