Safe messages parsing

This commit is contained in:
Matéo Duparc 2021-05-04 20:56:34 +02:00
parent 49a29ef9cd
commit d50dd127ba
Signed by: hardcoresushi
GPG Key ID: 007F84120107191E
5 changed files with 67 additions and 36 deletions

View File

@ -2,7 +2,7 @@ function generateAvatar(name){
let span = document.createElement("span"); let span = document.createElement("span");
if (typeof name == "undefined"){ if (typeof name == "undefined"){
span.appendChild(document.createTextNode("?")); span.appendChild(document.createTextNode("?"));
} else { } else if (name.length > 0) {
span.appendChild(document.createTextNode(name[0].toUpperCase())); span.appendChild(document.createTextNode(name[0].toUpperCase()));
} }
let div = document.createElement("div"); let div = document.createElement("div");

View File

@ -219,10 +219,10 @@ input[type="file"] {
content: url("/static/imgs/icons/verified/FF3C00"); content: url("/static/imgs/icons/verified/FF3C00");
} }
#left_panel ul li .not_seen_marker { #left_panel ul li .not_seen_marker {
width: 5px; width: 12px;
height: 5px; height: 12px;
background-color: var(--accent); background-color: var(--accent);
border-radius: 5px; border-radius: 12px;
} }
#refresher { #refresher {
position: relative; position: relative;
@ -242,7 +242,7 @@ input[type="file"] {
#chat_header { #chat_header {
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
padding: 5px 20px; padding: 20px 20px;
font-size: 1.5em; font-size: 1.5em;
} }
#chat_header>div { #chat_header>div {
@ -254,8 +254,9 @@ input[type="file"] {
#chat_header>div:hover p { #chat_header>div:hover p {
color: var(--accent); color: var(--accent);
} }
#chat_header>div>p { #chat_header>div>p { /*name*/
font-weight: bold; font-weight: bold;
margin: 0;
} }
#chat_header p::after { #chat_header p::after {
content: url("/static/imgs/icons/warning/FF3C00"); content: url("/static/imgs/icons/warning/FF3C00");

View File

@ -732,6 +732,11 @@ function displayHeader() {
function showPopup(content, closeButton = true) { function showPopup(content, closeButton = true) {
let popup_background = document.createElement("div"); let popup_background = document.createElement("div");
popup_background.classList.add("popup_background"); popup_background.classList.add("popup_background");
popup_background.onclick = function(e) {
if (e.target == popup_background) {
removePopup();
}
};
let popup = document.createElement("div"); let popup = document.createElement("div");
popup.classList.add("popup"); popup.classList.add("popup");
if (closeButton) { if (closeButton) {

View File

@ -1,7 +1,7 @@
mod session; mod session;
pub mod protocol; pub mod protocol;
use std::{collections::HashMap, net::{IpAddr, SocketAddr}, io::{self, Write}, convert::TryInto, str::from_utf8, fs::OpenOptions, sync::{Mutex, RwLock, Arc}}; use std::{collections::HashMap, net::{IpAddr, SocketAddr}, io::{self, Write}, str::from_utf8, fs::OpenOptions, sync::{Mutex, RwLock, Arc}};
use tokio::{net::{TcpListener, TcpStream}, sync::mpsc::{self, Sender, Receiver}}; use tokio::{net::{TcpListener, TcpStream}, sync::mpsc::{self, Sender, Receiver}};
use libmdns::Service; use libmdns::Service;
use strum_macros::Display; use strum_macros::Display;
@ -239,10 +239,7 @@ impl SessionManager {
} }
protocol::Headers::ASK_LARGE_FILE => { protocol::Headers::ASK_LARGE_FILE => {
if self.sessions.read().unwrap().get(&session_id).unwrap().file_download.is_none() { //don't accept 2 downloads at the same time if self.sessions.read().unwrap().get(&session_id).unwrap().file_download.is_none() { //don't accept 2 downloads at the same time
let file_size = u64::from_be_bytes(buffer[1..9].try_into().unwrap()); if let Some((file_size, file_name)) = protocol::parse_ask_file(&buffer) {
match from_utf8(&buffer[9..]) {
Ok(file_name) => {
let file_name = sanitize_filename::sanitize(file_name);
let download_dir = UserDirs::new().unwrap().download_dir; let download_dir = UserDirs::new().unwrap().download_dir;
self.sessions.write().unwrap().get_mut(&session_id).unwrap().file_download = Some(LargeFileDownload{ self.sessions.write().unwrap().get_mut(&session_id).unwrap().file_download = Some(LargeFileDownload{
file_name: file_name.clone(), file_name: file_name.clone(),
@ -257,8 +254,6 @@ impl SessionManager {
ui_connection.on_ask_large_file(&session_id, file_size, &file_name, download_dir.to_str().unwrap()); ui_connection.on_ask_large_file(&session_id, file_size, &file_name, download_dir.to_str().unwrap());
}) })
} }
Err(e) => print_error!(e),
}
} else if let Err(e) = session.encrypt_and_send(&[protocol::Headers::ABORT_FILE_TRANSFER]).await { } else if let Err(e) = session.encrypt_and_send(&[protocol::Headers::ABORT_FILE_TRANSFER]).await {
print_error!(e); print_error!(e);
break; break;
@ -361,9 +356,8 @@ impl SessionManager {
let header = buffer[0]; let header = buffer[0];
let buffer = match header { let buffer = match header {
protocol::Headers::FILE => { protocol::Headers::FILE => {
let file_name_len = u16::from_be_bytes([buffer[1], buffer[2]]) as usize; if let Some((file_name, content)) = protocol::parse_file(&buffer) {
let file_name = &buffer[3..3+file_name_len]; match self.store_file(&session_id, content) {
match self.store_file(&session_id, &buffer[3+file_name_len..]) {
Ok(file_uuid) => { Ok(file_uuid) => {
Some([&[protocol::Headers::FILE][..], file_uuid.as_bytes(), file_name].concat()) Some([&[protocol::Headers::FILE][..], file_uuid.as_bytes(), file_name].concat())
} }
@ -372,6 +366,9 @@ impl SessionManager {
None None
} }
} }
} else {
None
}
} }
_ => { _ => {
Some(buffer) Some(buffer)

View File

@ -1,3 +1,6 @@
use std::{convert::TryInto, str::from_utf8};
use crate::print_error;
pub struct Headers; pub struct Headers;
impl Headers { impl Headers {
@ -28,6 +31,31 @@ pub fn file(file_name: &str, buffer: &[u8]) -> Vec<u8> {
[&[Headers::FILE], &(file_name.len() as u16).to_be_bytes()[..], file_name.as_bytes(), buffer].concat() [&[Headers::FILE], &(file_name.len() as u16).to_be_bytes()[..], file_name.as_bytes(), buffer].concat()
} }
pub fn parse_file<'a>(buffer: &'a [u8]) -> Option<(&'a [u8], &'a [u8])> {
if buffer.len() > 3 {
let file_name_len = u16::from_be_bytes([buffer[1], buffer[2]]) as usize;
if buffer.len() > 3+file_name_len {
let file_name = &buffer[3..3+file_name_len];
return Some((file_name, &buffer[3+file_name_len..]));
}
}
None
}
pub fn ask_large_file(file_size: u64, file_name: &str) -> Vec<u8> { pub fn ask_large_file(file_size: u64, file_name: &str) -> Vec<u8> {
[&[Headers::ASK_LARGE_FILE], &file_size.to_be_bytes()[..], file_name.as_bytes()].concat() [&[Headers::ASK_LARGE_FILE], &file_size.to_be_bytes()[..], file_name.as_bytes()].concat()
} }
pub fn parse_ask_file(buffer: &[u8]) -> Option<(u64, String)> {
if buffer.len() > 9 {
let file_size = u64::from_be_bytes(buffer[1..9].try_into().unwrap());
match from_utf8(&buffer[9..]) {
Ok(file_name) => {
let file_name = sanitize_filename::sanitize(file_name);
return Some((file_size, file_name));
}
Err(e) => print_error!(e),
}
}
None
}