mod.rs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. use async_std::{net::TcpListener, sync::Arc};
  2. use std::{fs::File, net::SocketAddr};
  3. use async_executor::Executor;
  4. use futures::{io::BufReader, AsyncRead, AsyncReadExt, AsyncWrite};
  5. use futures_rustls::{rustls, TlsAcceptor};
  6. use fxhash::FxHashMap;
  7. use log::{error, info};
  8. use darkfi::{
  9. net::P2pPtr,
  10. system::SubscriberPtr,
  11. util::{expand_path, path::get_config_path},
  12. Error, Result,
  13. };
  14. use crate::{
  15. buffers::Buffers,
  16. settings::{
  17. parse_configured_channels, parse_configured_contacts, Args, ChannelInfo, ContactInfo,
  18. CONFIG_FILE,
  19. },
  20. Privmsg,
  21. };
  22. mod client;
  23. pub use client::IrcClient;
  24. #[derive(Clone)]
  25. pub struct IrcConfig {
  26. // init bool
  27. pub is_nick_init: bool,
  28. pub is_user_init: bool,
  29. pub is_registered: bool,
  30. pub is_cap_end: bool,
  31. pub is_pass_init: bool,
  32. // user config
  33. pub nickname: String,
  34. pub password: String,
  35. pub capabilities: FxHashMap<String, bool>,
  36. // channels and contacts
  37. pub auto_channels: Vec<String>,
  38. pub configured_chans: FxHashMap<String, ChannelInfo>,
  39. pub configured_contacts: FxHashMap<String, ContactInfo>,
  40. }
  41. impl IrcConfig {
  42. pub fn new(settings: &Args) -> Result<Self> {
  43. let password = settings.password.as_ref().unwrap_or(&String::new()).clone();
  44. let auto_channels = settings.autojoin.clone();
  45. // Pick up channel settings from the TOML configuration
  46. let cfg_path = get_config_path(settings.config.clone(), CONFIG_FILE)?;
  47. let toml_contents = std::fs::read_to_string(cfg_path)?;
  48. let configured_chans = parse_configured_channels(&toml_contents)?;
  49. let configured_contacts = parse_configured_contacts(&toml_contents)?;
  50. let mut capabilities = FxHashMap::default();
  51. capabilities.insert("no-history".to_string(), false);
  52. Ok(Self {
  53. is_nick_init: false,
  54. is_user_init: false,
  55. is_registered: false,
  56. is_cap_end: true,
  57. is_pass_init: false,
  58. nickname: "anon".to_string(),
  59. password,
  60. auto_channels,
  61. configured_chans,
  62. configured_contacts,
  63. capabilities,
  64. })
  65. }
  66. }
  67. pub struct IrcServer {
  68. settings: Args,
  69. irc_config: IrcConfig,
  70. buffers: Buffers,
  71. p2p: P2pPtr,
  72. p2p_notifiers: SubscriberPtr<Privmsg>,
  73. }
  74. impl IrcServer {
  75. pub async fn new(
  76. settings: Args,
  77. buffers: Buffers,
  78. p2p: P2pPtr,
  79. p2p_notifiers: SubscriberPtr<Privmsg>,
  80. ) -> Result<Self> {
  81. let irc_config = IrcConfig::new(&settings)?;
  82. Ok(Self { settings, irc_config, buffers, p2p, p2p_notifiers })
  83. }
  84. /// Start listening to new irc clients connecting to the irc server address
  85. /// then spawn new connections
  86. pub async fn start(&self, executor: Arc<Executor<'_>>) -> Result<()> {
  87. let (listener, acceptor) = self.setup_listener().await?;
  88. info!("[IRC SERVER] listening on {}", self.settings.irc_listen);
  89. loop {
  90. let (stream, peer_addr) = match listener.accept().await {
  91. Ok((s, a)) => (s, a),
  92. Err(e) => {
  93. error!("[IRC SERVER] Failed accepting new connections: {}", e);
  94. continue
  95. }
  96. };
  97. let result = if let Some(acceptor) = acceptor.clone() {
  98. let stream = match acceptor.accept(stream).await {
  99. Ok(s) => s,
  100. Err(e) => {
  101. error!("[IRC SERVER] Failed accepting TLS connection: {}", e);
  102. continue
  103. }
  104. };
  105. self.process_connection(executor.clone(), stream, peer_addr).await
  106. } else {
  107. self.process_connection(executor.clone(), stream, peer_addr).await
  108. };
  109. if let Err(e) = result {
  110. error!("[IRC SERVER] Failed processing connection {}: {}", peer_addr, e);
  111. continue
  112. };
  113. info!("[IRC SERVER] Accept new connection: {}", peer_addr);
  114. }
  115. }
  116. /// On every new connection create new IrcClient which will process the messages
  117. async fn process_connection<C: AsyncRead + AsyncWrite + Send + Unpin + 'static>(
  118. &self,
  119. executor: Arc<Executor<'_>>,
  120. stream: C,
  121. peer_addr: SocketAddr,
  122. ) -> Result<()> {
  123. let (reader, writer) = stream.split();
  124. let reader = BufReader::new(reader);
  125. // New subscription
  126. let p2p_subscription = self.p2p_notifiers.clone().subscribe().await;
  127. // New irc connection
  128. let mut client = IrcClient::new(
  129. writer,
  130. peer_addr,
  131. self.buffers.clone(),
  132. self.irc_config.clone(),
  133. self.p2p.clone(),
  134. self.p2p_notifiers.clone(),
  135. p2p_subscription,
  136. );
  137. executor
  138. .spawn(async move {
  139. client.listen(reader).await;
  140. })
  141. .detach();
  142. Ok(())
  143. }
  144. /// Setup a listener for irc server
  145. async fn setup_listener(&self) -> Result<(TcpListener, Option<TlsAcceptor>)> {
  146. let listenaddr = self.settings.irc_listen.socket_addrs(|| None)?[0];
  147. let listener = TcpListener::bind(listenaddr).await?;
  148. let acceptor = match self.settings.irc_listen.scheme() {
  149. "tls" => {
  150. // openssl genpkey -algorithm ED25519 > example.com.key
  151. // openssl req -new -out example.com.csr -key example.com.key
  152. // openssl x509 -req -days 700 -in example.com.csr -signkey example.com.key -out example.com.crt
  153. if self.settings.irc_tls_secret.is_none() || self.settings.irc_tls_cert.is_none() {
  154. error!("[IRC SERVER] To listen using TLS, please set irc_tls_secret and irc_tls_cert in your config file.");
  155. return Err(Error::KeypairPathNotFound)
  156. }
  157. let file =
  158. File::open(expand_path(self.settings.irc_tls_secret.as_ref().unwrap())?)?;
  159. let mut reader = std::io::BufReader::new(file);
  160. let secret = &rustls_pemfile::pkcs8_private_keys(&mut reader)?[0];
  161. let secret = rustls::PrivateKey(secret.clone());
  162. let file = File::open(expand_path(self.settings.irc_tls_cert.as_ref().unwrap())?)?;
  163. let mut reader = std::io::BufReader::new(file);
  164. let certificate = &rustls_pemfile::certs(&mut reader)?[0];
  165. let certificate = rustls::Certificate(certificate.clone());
  166. let config = rustls::ServerConfig::builder()
  167. .with_safe_defaults()
  168. .with_no_client_auth()
  169. .with_single_cert(vec![certificate], secret)?;
  170. let acceptor = TlsAcceptor::from(Arc::new(config));
  171. Some(acceptor)
  172. }
  173. _ => None,
  174. };
  175. Ok((listener, acceptor))
  176. }
  177. }