Просмотр исходного кода

bin/ircd: add support for password registration

Dastan-glitch 4 лет назад
Родитель
Сommit
1f679a9b9e
3 измененных файлов с 37 добавлено и 1 удалено
  1. 7 0
      bin/ircd/src/main.rs
  2. 26 1
      bin/ircd/src/server.rs
  3. 4 0
      bin/ircd/src/settings.rs

+ 7 - 0
bin/ircd/src/main.rs

@@ -60,6 +60,7 @@ struct Ircd {
     // p2p
     p2p: net::P2pPtr,
     senders: SubscriberPtr<Privmsg>,
+    password: String,
 }
 
 impl Ircd {
@@ -67,6 +68,7 @@ impl Ircd {
         seen_msg_ids: SeenMsgIds,
         privmsgs_buffer: PrivmsgsBuffer,
         autojoin_chans: Vec<String>,
+        password: String,
         configured_chans: FxHashMap<String, ChannelInfo>,
         configured_contacts: FxHashMap<String, crypto_box::SalsaBox>,
         p2p: net::P2pPtr,
@@ -76,6 +78,7 @@ impl Ircd {
             seen_msg_ids,
             privmsgs_buffer,
             autojoin_chans,
+            password,
             configured_chans,
             configured_contacts,
             p2p,
@@ -114,6 +117,7 @@ impl Ircd {
             self.seen_msg_ids.clone(),
             self.privmsgs_buffer.clone(),
             self.autojoin_chans.clone(),
+            self.password.clone(),
             self.configured_chans.clone(),
             self.configured_contacts.clone(),
             self.p2p.clone(),
@@ -174,6 +178,8 @@ async fn realmain(settings: Args, executor: Arc<Executor<'_>>) -> Result<()> {
         return Ok(())
     }
 
+    let password = settings.password.unwrap_or(String::default());
+
     // Pick up channel settings from the TOML configuration
     let cfg_path = get_config_path(settings.config, CONFIG_FILE)?;
     let toml_contents = std::fs::read_to_string(cfg_path)?;
@@ -271,6 +277,7 @@ async fn realmain(settings: Args, executor: Arc<Executor<'_>>) -> Result<()> {
                 seen_msg_ids.clone(),
                 privmsgs_buffer.clone(),
                 settings.autojoin.clone(),
+                password.clone(),
                 configured_chans.clone(),
                 configured_contacts.clone(),
                 p2p.clone(),

+ 26 - 1
bin/ircd/src/server.rs

@@ -31,6 +31,7 @@ pub struct IrcServerConnection<C: AsyncRead + AsyncWrite + Send + Unpin + 'stati
     is_user_init: bool,
     is_registered: bool,
     is_cap_end: bool,
+    is_pass_init: bool,
     nickname: String,
     auto_channels: Vec<String>,
     pub configured_chans: FxHashMap<String, ChannelInfo>,
@@ -40,6 +41,7 @@ pub struct IrcServerConnection<C: AsyncRead + AsyncWrite + Send + Unpin + 'stati
     p2p: P2pPtr,
     senders: SubscriberPtr<Privmsg>,
     subscriber_id: u64,
+    password: String,
 }
 
 impl<C: AsyncRead + AsyncWrite + Send + Unpin + 'static> IrcServerConnection<C> {
@@ -50,6 +52,7 @@ impl<C: AsyncRead + AsyncWrite + Send + Unpin + 'static> IrcServerConnection<C>
         seen_msg_ids: SeenMsgIds,
         privmsgs_buffer: PrivmsgsBuffer,
         auto_channels: Vec<String>,
+        password: String,
         configured_chans: FxHashMap<String, ChannelInfo>,
         configured_contacts: FxHashMap<String, crypto_box::SalsaBox>,
         p2p: P2pPtr,
@@ -67,8 +70,10 @@ impl<C: AsyncRead + AsyncWrite + Send + Unpin + 'static> IrcServerConnection<C>
             is_user_init: false,
             is_registered: false,
             is_cap_end: true,
+            is_pass_init: false,
             nickname: "anon".to_string(),
             auto_channels,
+            password,
             configured_chans,
             configured_contacts,
             capabilities,
@@ -83,6 +88,10 @@ impl<C: AsyncRead + AsyncWrite + Send + Unpin + 'static> IrcServerConnection<C>
             return Err(Error::MalformedPacket)
         }
 
+        if self.password.is_empty() {
+            self.is_pass_init = true
+        }
+
         let mut tokens = line.split_ascii_whitespace();
         // Commands can begin with :garbage but we will reject clients doing
         // that for now to keep the protocol simple and focused.
@@ -91,10 +100,26 @@ impl<C: AsyncRead + AsyncWrite + Send + Unpin + 'static> IrcServerConnection<C>
         info!("IRC server received command: {}", command.to_uppercase());
 
         match command.to_uppercase().as_str() {
+            "PASS" => {
+                let password = tokens.next().ok_or(Error::MalformedPacket)?;
+                if self.password == password.to_string() {
+                    self.is_pass_init = true
+                } else {
+                    // Close the connection
+                    warn!("Password is not correct!");
+                    return Err(Error::NetworkServiceStopped)
+                }
+            }
             "USER" => {
                 // We can stuff any extra things like public keys in here.
                 // Ignore it for now.
-                self.is_user_init = true;
+                if self.is_pass_init {
+                    self.is_user_init = true;
+                } else {
+                    // Close the connection
+                    warn!("Password is required");
+                    return Err(Error::NetworkServiceStopped)
+                }
             }
             "NAMES" => {
                 let channels = tokens.next().ok_or(Error::MalformedPacket)?;

+ 4 - 0
bin/ircd/src/settings.rs

@@ -43,6 +43,10 @@ pub struct Args {
     #[structopt(long)]
     pub autojoin: Vec<String>,
 
+    /// Password
+    #[structopt(long)]
+    pub password: Option<String>,
+
     #[structopt(flatten)]
     pub net: SettingsOpt,