Pārlūkot izejas kodu

bin/darkirc: pad/unpad nickname and target on encrypt/decrypt

Dastan-glitch 3 gadi atpakaļ
vecāks
revīzija
af306673f3

+ 27 - 9
bin/darkirc/src/crypto.rs

@@ -26,7 +26,7 @@ use rand::rngs::OsRng;
 
 use crate::{
     privmsg::PrivMsgEvent,
-    settings::{ChannelInfo, ContactInfo},
+    settings::{ChannelInfo, ContactInfo, MAXIMUM_LENGTH_OF_NICK_CHAN_CNT},
 };
 
 #[derive(serde::Serialize)]
@@ -69,9 +69,9 @@ fn try_decrypt(salt_box: &SalsaBox, ciphertext: &str) -> Option<String> {
 }
 
 /// The format we're using is nonce+ciphertext, where nonce is 24 bytes.
-pub fn encrypt(salt_box: &SalsaBox, plaintext: &str) -> String {
+pub fn encrypt(salt_box: &SalsaBox, plaintext: &[u8]) -> String {
     let nonce = SalsaBox::generate_nonce(&mut OsRng);
-    let mut ciphertext = salt_box.encrypt(&nonce, plaintext.as_bytes()).unwrap();
+    let mut ciphertext = salt_box.encrypt(&nonce, plaintext).unwrap();
 
     let mut concat = vec![];
     concat.append(&mut nonce.as_slice().to_vec());
@@ -100,7 +100,8 @@ pub fn decrypt_target(
                 continue
             }
 
-            let target = decrypted_target.unwrap();
+            let target =
+                String::from_utf8_lossy(&unpad(decrypted_target.unwrap().into())).to_string();
             if *chan_name == target {
                 privmsg.target = target;
                 return
@@ -118,7 +119,8 @@ pub fn decrypt_target(
                 continue
             }
 
-            let target = decrypted_target.unwrap();
+            let target =
+                String::from_utf8_lossy(&unpad(decrypted_target.unwrap().into())).to_string();
             privmsg.target = target;
             *contact = cnt_name.into();
             return
@@ -135,13 +137,29 @@ pub fn decrypt_privmsg(salt_box: &SalsaBox, privmsg: &mut PrivMsgEvent) {
         return
     }
 
-    privmsg.nick = decrypted_nick.unwrap();
+    privmsg.nick = String::from_utf8_lossy(&unpad(decrypted_nick.unwrap().into())).to_string();
     privmsg.msg = decrypted_msg.unwrap();
 }
 
 /// Encrypt PrivMsg
 pub fn encrypt_privmsg(salt_box: &SalsaBox, privmsg: &mut PrivMsgEvent) {
-    privmsg.nick = encrypt(salt_box, &privmsg.nick);
-    privmsg.target = encrypt(salt_box, &privmsg.target);
-    privmsg.msg = encrypt(salt_box, &privmsg.msg);
+    privmsg.nick = encrypt(salt_box, &pad(privmsg.nick.clone().into()));
+    privmsg.target = encrypt(salt_box, &pad(privmsg.target.clone().into()));
+    privmsg.msg = encrypt(salt_box, privmsg.msg.as_bytes());
+}
+
+fn pad(mut data: Vec<u8>) -> Vec<u8> {
+    let pad_len = (MAXIMUM_LENGTH_OF_NICK_CHAN_CNT - data.len()) as u8;
+    for _ in 0..pad_len {
+        data.push(pad_len);
+    }
+    data
+}
+
+fn unpad(mut data: Vec<u8>) -> Vec<u8> {
+    let pad_len = data[data.len() - 1];
+    for _ in 0..pad_len {
+        data.pop();
+    }
+    data
 }

+ 1 - 1
bin/darkirc/src/irc/client.rs

@@ -286,7 +286,7 @@ impl<C: AsyncRead + AsyncWrite + Send + Unpin + 'static> IrcClient<C> {
     }
 
     async fn on_receive_nick(&mut self, nickname: &str) -> Result<()> {
-        if nickname.len() > settings::MAXIMUM_LENGTH_OF_NICKNAME {
+        if nickname.len() >= settings::MAXIMUM_LENGTH_OF_NICK_CHAN_CNT {
             return Ok(())
         }
 

+ 3 - 2
bin/darkirc/src/irc/mod.rs

@@ -23,7 +23,7 @@ use darkfi::{util::path::get_config_path, Result};
 use crate::{
     settings::{
         parse_configured_channels, parse_configured_contacts, Args, ChannelInfo, ContactInfo,
-        CONFIG_FILE,
+        CONFIG_FILE, MAXIMUM_LENGTH_OF_NICK_CHAN_CNT,
     },
     PrivMsgEvent,
 };
@@ -58,7 +58,8 @@ impl IrcConfig {
     pub fn new(settings: &Args) -> Result<Self> {
         let password = settings.password.as_ref().unwrap_or(&String::new()).clone();
 
-        let auto_channels = settings.autojoin.clone();
+        let mut auto_channels = settings.autojoin.clone();
+        auto_channels.retain(|chan| chan.len() <= MAXIMUM_LENGTH_OF_NICK_CHAN_CNT);
 
         // Pick up channel settings from the TOML configuration
         let cfg_path = get_config_path(settings.config.clone(), CONFIG_FILE)?;

+ 9 - 1
bin/darkirc/src/settings.rs

@@ -33,7 +33,7 @@ pub const CONFIG_FILE_CONTENTS: &str = include_str!("../darkirc_config.toml");
 
 // Msg config
 pub const MAXIMUM_LENGTH_OF_MESSAGE: usize = 1024;
-pub const MAXIMUM_LENGTH_OF_NICKNAME: usize = 32;
+pub const MAXIMUM_LENGTH_OF_NICK_CHAN_CNT: usize = 32;
 
 // IRC Client
 pub enum RPL {
@@ -166,6 +166,10 @@ pub fn parse_configured_channels(data: &str) -> Result<HashMap<String, ChannelIn
     }
 
     for chan in map["channel"].as_table().unwrap() {
+        if chan.0.len() > MAXIMUM_LENGTH_OF_NICK_CHAN_CNT {
+            warn!("Channel name is too long, skipping...");
+            continue
+        }
         info!("Found configuration for channel {}", chan.0);
         let mut channel_info = ChannelInfo::new()?;
 
@@ -247,6 +251,10 @@ pub fn parse_configured_contacts(data: &str) -> Result<HashMap<String, ContactIn
     let secret = crypto_box::SecretKey::from(bytes);
 
     for cnt in contacts {
+        if cnt.0.len() > MAXIMUM_LENGTH_OF_NICK_CHAN_CNT {
+            warn!("Contact name is too long, skipping...");
+            continue
+        }
         info!("Found configuration for contact {}", cnt.0);
         let mut contact_info = ContactInfo::new()?;