settings.rs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. use std::path::PathBuf;
  2. use fxhash::FxHashMap;
  3. use log::info;
  4. use serde::Deserialize;
  5. use structopt::StructOpt;
  6. use structopt_toml::StructOptToml;
  7. use toml::Value;
  8. use url::Url;
  9. use darkfi::{net::settings::SettingsOpt, Result};
  10. pub const CONFIG_FILE: &str = "ircd_config.toml";
  11. pub const CONFIG_FILE_CONTENTS: &str = include_str!("../ircd_config.toml");
  12. /// ircd cli
  13. #[derive(Clone, Debug, Deserialize, StructOpt, StructOptToml)]
  14. #[serde(default)]
  15. #[structopt(name = "ircd")]
  16. pub struct Args {
  17. /// Sets a custom config file
  18. #[structopt(long)]
  19. pub config: Option<String>,
  20. /// JSON-RPC listen URL
  21. #[structopt(long = "rpc", default_value = "tcp://127.0.0.1:11055")]
  22. pub rpc_listen: Url,
  23. /// IRC listen URL
  24. #[structopt(long = "irc", default_value = "tcp://127.0.0.1:11066")]
  25. pub irc_listen: Url,
  26. /// Generate a new NaCl secret and exit
  27. #[structopt(long)]
  28. pub gen_secret: bool,
  29. /// Autojoin channels
  30. #[structopt(long)]
  31. pub autojoin: Vec<String>,
  32. #[structopt(flatten)]
  33. pub net: SettingsOpt,
  34. /// Increase verbosity
  35. #[structopt(short, parse(from_occurrences))]
  36. pub verbose: u8,
  37. }
  38. /// This struct holds information about preconfigured channels.
  39. /// In the TOML configuration file, we can configure channels as such:
  40. /// ```toml
  41. /// [channel."#dev"]
  42. /// secret = "GvH4kno3kUu6dqPrZ8zjMhqxTUDZ2ev16EdprZiZJgj1"
  43. /// topic = "DarkFi Development Channel"
  44. /// ```
  45. /// Having a secret will enable a NaCl box that is able to encrypt and
  46. /// decrypt messages in this channel using this set shared secret.
  47. /// The secret should be shared OOB, via a secure channel.
  48. /// Having a topic set is useful if one wants to have a topic in the
  49. /// configured channel. It is not shared with others, but it is useful
  50. /// for personal reference.
  51. #[derive(Clone)]
  52. pub struct ChannelInfo {
  53. /// Optional topic for the channel
  54. pub topic: Option<String>,
  55. /// Optional NaCl box for the channel, used for {en,de}cryption.
  56. pub salt_box: Option<crypto_box::Box>,
  57. /// Flag indicates whether the user has joined the channel or not
  58. pub joined: bool,
  59. /// All nicknames which are visible on the channel
  60. pub names: Vec<String>,
  61. }
  62. impl ChannelInfo {
  63. pub fn new() -> Result<Self> {
  64. Ok(Self { topic: None, salt_box: None, joined: true, names: vec![] })
  65. }
  66. }
  67. /// Parse the configuration file for any configured channels and return
  68. /// a map containing said configurations.
  69. pub fn parse_configured_channels(config_file: &PathBuf) -> Result<FxHashMap<String, ChannelInfo>> {
  70. let toml_contents = std::fs::read_to_string(config_file)?;
  71. let mut ret = FxHashMap::default();
  72. if let Value::Table(map) = toml::from_str(&toml_contents)? {
  73. if map.contains_key("channel") && map["channel"].is_table() {
  74. for chan in map["channel"].as_table().unwrap() {
  75. info!("Found configuration for channel {}", chan.0);
  76. let mut channel_info = ChannelInfo::new()?;
  77. if chan.1.as_table().unwrap().contains_key("topic") {
  78. let topic = chan.1["topic"].as_str().unwrap().to_string();
  79. info!("Found topic for channel {}: {}", chan.0, topic);
  80. channel_info.topic = Some(topic);
  81. }
  82. if chan.1.as_table().unwrap().contains_key("secret") {
  83. // Build the NaCl box
  84. let s = chan.1["secret"].as_str().unwrap();
  85. let bytes: [u8; 32] = bs58::decode(s).into_vec()?.try_into().unwrap();
  86. let secret = crypto_box::SecretKey::from(bytes);
  87. let public = secret.public_key();
  88. let msg_box = crypto_box::Box::new(&public, &secret);
  89. channel_info.salt_box = Some(msg_box);
  90. info!("Instantiated NaCl box for channel {}", chan.0);
  91. }
  92. ret.insert(chan.0.to_string(), channel_info);
  93. }
  94. }
  95. };
  96. Ok(ret)
  97. }