settings.rs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. use crypto_box::SalsaBox;
  2. use log::error;
  3. use serde::{self, Deserialize, Serialize};
  4. use std::collections::HashMap;
  5. use structopt::StructOpt;
  6. use structopt_toml::StructOptToml;
  7. use url::Url;
  8. use darkfi::{net::settings::SettingsOpt, Result};
  9. // Location for config file
  10. pub const CONFIG_FILE: &str = "ircd_config.toml";
  11. pub const CONFIG_FILE_CONTENTS: &str = include_str!("../ircd_config.toml");
  12. // Msg config
  13. pub const MAXIMUM_LENGTH_OF_MESSAGE: usize = 1024;
  14. pub const MAXIMUM_LENGTH_OF_NICKNAME: usize = 32;
  15. // IRC Client
  16. pub enum RPL {
  17. NoTopic = 331,
  18. Topic = 332,
  19. NameReply = 353,
  20. EndOfNames = 366,
  21. }
  22. /// ircd cli
  23. #[derive(Clone, Deserialize, StructOpt, StructOptToml)]
  24. #[serde(default)]
  25. #[structopt(name = "ircd")]
  26. pub struct Args {
  27. /// Sets a custom config file
  28. #[structopt(long)]
  29. pub config: Option<String>,
  30. /// JSON-RPC listen URL
  31. #[structopt(long = "rpc", default_value = "tcp://127.0.0.1:25550")]
  32. pub rpc_listen: Url,
  33. /// IRC listen URL
  34. #[structopt(long = "irc", default_value = "tcp://127.0.0.1:6667")]
  35. pub irc_listen: Url,
  36. /// Optional TLS certificate file path if `irc_listen` uses TLS
  37. pub irc_tls_cert: Option<String>,
  38. /// Optional TLS certificate key file path if `irc_listen` uses TLS
  39. pub irc_tls_secret: Option<String>,
  40. /// Generate a new NaCl keypair and exit
  41. #[structopt(long)]
  42. pub gen_keypair: bool,
  43. /// Path to save keypair in
  44. #[structopt(short)]
  45. pub output: Option<String>,
  46. /// Autojoin channels
  47. #[structopt(long)]
  48. pub autojoin: Vec<String>,
  49. /// Password
  50. #[structopt(long)]
  51. pub password: Option<String>,
  52. /// Channels
  53. #[structopt(skip)]
  54. pub channels: HashMap<String, ChannelInfo>,
  55. /// Channels
  56. #[structopt(skip)]
  57. pub contacts: HashMap<String, ContactInfo>,
  58. /// Private key
  59. #[structopt(skip)]
  60. pub private_key: Option<String>,
  61. #[structopt(flatten)]
  62. pub net: SettingsOpt,
  63. /// Increase verbosity
  64. #[structopt(short, parse(from_occurrences))]
  65. pub verbose: u8,
  66. }
  67. /// This struct holds information about preconfigured contacts.
  68. /// In the TOML configuration file, we can configure contacts as such:
  69. ///
  70. /// ```toml
  71. /// [contact."nick"]
  72. /// pubkey = "7CkVuFgwTUpJn5Sv67Q3fyEDpa28yrSeL5Hg2GqQ4jfM"
  73. /// ```
  74. #[derive(Default, Clone, Debug, Deserialize, Serialize)]
  75. pub struct ContactInfo {
  76. pub pubkey: Option<String>,
  77. }
  78. impl ContactInfo {
  79. pub fn new() -> Self {
  80. Self { pubkey: None }
  81. }
  82. pub fn salt_box(&self, private_key: &str, contact_name: &str) -> Option<SalsaBox> {
  83. if let Ok(private) = parse_priv(private_key) {
  84. if let Some(p) = &self.pubkey {
  85. if let Ok(public) = parse_pub(p) {
  86. return Some(SalsaBox::new(&public, &private))
  87. } else {
  88. error!("Uncorrect public key in for contact {}", contact_name);
  89. }
  90. }
  91. } else {
  92. error!("Uncorrect Private key in config",);
  93. }
  94. None
  95. }
  96. }
  97. /// This struct holds information about preconfigured channels.
  98. /// In the TOML configuration file, we can configure channels as such:
  99. /// ```toml
  100. /// [channel."#dev"]
  101. /// secret = "GvH4kno3kUu6dqPrZ8zjMhqxTUDZ2ev16EdprZiZJgj1"
  102. /// topic = "DarkFi Development Channel"
  103. /// ```
  104. /// Having a secret will enable a NaCl box that is able to encrypt and
  105. /// decrypt messages in this channel using this set shared secret.
  106. /// The secret should be shared OOB, via a secure channel.
  107. /// Having a topic set is useful if one wants to have a topic in the
  108. /// configured channel. It is not shared with others, but it is useful
  109. /// for personal reference.
  110. #[derive(Default, Clone, Debug, Serialize, Deserialize)]
  111. pub struct ChannelInfo {
  112. /// Optional topic for the channel
  113. pub topic: Option<String>,
  114. /// Optional NaCl box for the channel, used for {en,de}cryption.
  115. pub secret: Option<String>,
  116. /// Flag indicates whether the user has joined the channel or not
  117. #[serde(default, skip_serializing)]
  118. pub joined: bool,
  119. /// All nicknames which are visible on the channel
  120. #[serde(default, skip_serializing)]
  121. pub names: Vec<String>,
  122. }
  123. impl ChannelInfo {
  124. pub fn new() -> Self {
  125. Self { topic: None, secret: None, joined: false, names: vec![] }
  126. }
  127. pub fn salt_box(&self, channel_name: &str) -> Option<SalsaBox> {
  128. if let Some(s) = &self.secret {
  129. let secret = parse_priv(s);
  130. if secret.is_err() {
  131. error!("Uncorrect secret key for the channel {}", channel_name);
  132. return None
  133. }
  134. let secret = secret.unwrap();
  135. let public = secret.public_key();
  136. return Some(SalsaBox::new(&public, &secret))
  137. }
  138. None
  139. }
  140. }
  141. pub fn get_current_time() -> u64 {
  142. let start = std::time::SystemTime::now();
  143. start
  144. .duration_since(std::time::UNIX_EPOCH)
  145. .expect("Time went backwards")
  146. .as_millis()
  147. .try_into()
  148. .unwrap()
  149. }
  150. fn parse_priv(key: &str) -> Result<crypto_box::SecretKey> {
  151. let bytes: [u8; 32] = bs58::decode(key).into_vec()?.try_into().unwrap();
  152. Ok(crypto_box::SecretKey::from(bytes))
  153. }
  154. fn parse_pub(key: &str) -> Result<crypto_box::PublicKey> {
  155. let bytes: [u8; 32] = bs58::decode(key).into_vec()?.try_into().unwrap();
  156. Ok(crypto_box::PublicKey::from(bytes))
  157. }