Update dependencies

This commit is contained in:
Matéo Duparc 2021-09-02 20:39:22 +02:00
parent ede41e5715
commit 0bd49c092d
Signed by: hardcoresushi
GPG Key ID: AFE384344A45E13A
3 changed files with 856 additions and 821 deletions

1603
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[package] [package]
name = "aira" name = "aira"
version = "0.0.3" version = "0.1.1"
authors = ["Hardcore Sushi <hardcore.sushi@disroot.org>"] authors = ["Hardcore Sushi <hardcore.sushi@disroot.org>"]
edition = "2018" edition = "2018"
exclude = ["src/frontend"] exclude = ["src/frontend"]
@ -12,31 +12,32 @@ tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros", "net", "
async-psec = { version = "0.4", features = ["split"] } async-psec = { version = "0.4", features = ["split"] }
lazy_static = "1.4" lazy_static = "1.4"
socket2 = "0.4" socket2 = "0.4"
rusqlite = { version = "0.25.1", features = ["bundled"] } rusqlite = { version = "0.27", features = ["bundled"] }
ed25519-dalek = "1" #for singatures ed25519-dalek = "1" #for singatures
sha2 = "0.9" sha2 = "0.10"
aes-gcm = "0.9" aes-gcm = "0.9"
aes-gcm-siv = "0.10" #database encryption aes-gcm-siv = "0.10" #database encryption
hkdf = "0.11" hkdf = "0.12"
hex = "0.4" hex = "0.4"
actix-web = "3" actix-web = "4"
actix-multipart = "0.3" env_logger = "0.9"
time = "0.2" #needed for actix cookies actix-multipart = "0.4"
time = "0.3" #needed for actix cookies
futures = "0.3" futures = "0.3"
tungstenite = "0.15" #websocket tungstenite = "0.17" #websocket
serde = "1.0" #serialization serde = { version = "1.0", features = ["derive"] } #serialization
html-escape = "0.2" html-escape = "0.2"
sanitize-filename = "0.3" sanitize-filename = "0.3"
platform-dirs = "0.3" platform-dirs = "0.3"
uuid = { version = "0.8", features = ["v4"] } uuid = { version = "1.0", features = ["v4"] }
webbrowser = "0.5" webbrowser = "0.7"
libmdns = "0.6" #mDNS advertiser libmdns = "0.6" #mDNS advertiser
multicast_dns = "0.5" #mDNS browser multicast_dns = "0.5" #mDNS browser
if-addrs = "0.6" if-addrs = "0.7"
base64 = "0.13" base64 = "0.13"
scrypt = "0.7" scrypt = "0.10"
zeroize = "1.2" zeroize = "1.5"
image = "0.23" image = "0.24"
yaml-rust = "0.4" #only in debug mode yaml-rust = "0.4" #only in debug mode
[build-dependencies] [build-dependencies]

View File

@ -8,11 +8,11 @@ mod ui_interface;
mod constants; mod constants;
mod discovery; mod discovery;
use std::{env, fs, io, net::SocketAddr, str::{FromStr, from_utf8}, sync::{Arc, RwLock}, cmp::Ordering}; use std::{env, fs, io::{self, Cursor}, net::SocketAddr, str::{FromStr, from_utf8}, sync::{Arc, RwLock}, cmp::Ordering};
use image::GenericImageView; use image::GenericImageView;
use tokio::{net::TcpListener, runtime::Handle, sync::mpsc, task::JoinError}; use tokio::{net::TcpListener, runtime::Handle, sync::mpsc, task::JoinError};
use tungstenite::Message; use tungstenite::Message;
use actix_web::{App, HttpMessage, HttpRequest, HttpResponse, HttpServer, http::{header, CookieBuilder}, web, web::Data}; use actix_web::{App, HttpRequest, HttpResponse, HttpServer, http::header, cookie::CookieBuilder, web, web::Data};
use actix_multipart::Multipart; use actix_multipart::Multipart;
use futures::{StreamExt, TryStreamExt}; use futures::{StreamExt, TryStreamExt};
use rand::{RngCore, rngs::OsRng}; use rand::{RngCore, rngs::OsRng};
@ -321,7 +321,7 @@ fn is_authenticated(req: &HttpRequest) -> bool {
async fn handle_set_avatar(req: HttpRequest, mut payload: Multipart) -> HttpResponse { async fn handle_set_avatar(req: HttpRequest, mut payload: Multipart) -> HttpResponse {
if let Ok(Some(mut field)) = payload.try_next().await { if let Ok(Some(mut field)) = payload.try_next().await {
let content_disposition = field.content_disposition().unwrap(); let content_disposition = field.content_disposition();
if let Some(name) = content_disposition.get_name() { if let Some(name) = content_disposition.get_name() {
if name == "avatar" { if name == "avatar" {
let mut buffer = Vec::new(); let mut buffer = Vec::new();
@ -339,9 +339,9 @@ async fn handle_set_avatar(req: HttpRequest, mut payload: Multipart) -> HttpResp
Ordering::Equal => image, Ordering::Equal => image,
}; };
let mut avatar = Vec::new(); let mut avatar = Vec::new();
image.write_to(&mut avatar, format).unwrap(); image.write_to(&mut Cursor::new(&mut avatar), format).unwrap();
let global_vars = req.app_data::<Data<Arc<RwLock<GlobalVars>>>>().unwrap(); let global_vars = req.app_data::<Data<GlobalVars>>().unwrap();
let session_manager = &global_vars.read().unwrap().session_manager; let session_manager = &global_vars.session_manager;
let is_authenticated = is_authenticated(&req); let is_authenticated = is_authenticated(&req);
let is_running = session_manager.is_identity_loaded(); let is_running = session_manager.is_identity_loaded();
if is_authenticated || !is_running { if is_authenticated || !is_running {
@ -386,7 +386,7 @@ fn reply_with_avatar(avatar: Option<Vec<u8>>, name: Option<&str>) -> HttpRespons
} }
} }
fn handle_avatar(req: HttpRequest) -> HttpResponse { async fn handle_avatar(req: HttpRequest) -> HttpResponse {
let splits: Vec<&str> = req.path()[1..].split('/').collect(); let splits: Vec<&str> = req.path()[1..].split('/').collect();
if splits.len() == 2 { if splits.len() == 2 {
if splits[1] == "self" { if splits[1] == "self" {
@ -406,13 +406,13 @@ struct FileInfo {
uuid: String, uuid: String,
file_name: String, file_name: String,
} }
fn handle_load_file(req: HttpRequest, file_info: web::Query<FileInfo>) -> HttpResponse { async fn handle_load_file(req: HttpRequest, file_info: web::Query<FileInfo>) -> HttpResponse {
if is_authenticated(&req) { if is_authenticated(&req) {
match Uuid::from_str(&file_info.uuid) { match Uuid::from_str(&file_info.uuid) {
Ok(uuid) => { Ok(uuid) => {
let global_vars = req.app_data::<Data<GlobalVars>>().unwrap(); let global_vars = req.app_data::<Data<GlobalVars>>().unwrap();
if let Some(buffer) = global_vars.session_manager.identity.read().unwrap().as_ref().unwrap().load_file(uuid) { if let Some(buffer) = global_vars.session_manager.identity.read().unwrap().as_ref().unwrap().load_file(uuid) {
return HttpResponse::Ok().header("Content-Disposition", format!("attachment; filename=\"{}\"", escape_double_quote(html_escape::decode_html_entities(&file_info.file_name).to_string()))).content_type("application/octet-stream").body(buffer); return HttpResponse::Ok().append_header(("Content-Disposition", format!("attachment; filename=\"{}\"", escape_double_quote(html_escape::decode_html_entities(&file_info.file_name).to_string())))).content_type("application/octet-stream").body(buffer);
} }
} }
Err(e) => print_error!(e) Err(e) => print_error!(e)
@ -425,14 +425,14 @@ async fn handle_send_file(req: HttpRequest, mut payload: Multipart) -> HttpRespo
if is_authenticated(&req) { if is_authenticated(&req) {
let mut session_id: Option<usize> = None; let mut session_id: Option<usize> = None;
while let Ok(Some(mut field)) = payload.try_next().await { while let Ok(Some(mut field)) = payload.try_next().await {
let content_disposition = field.content_disposition().unwrap(); let content_disposition = field.content_disposition();
if let Some(name) = content_disposition.get_name() { if let Some(name) = content_disposition.get_name() {
if name == "session_id" { if name == "session_id" {
if let Some(Ok(raw_id)) = field.next().await { if let Some(Ok(raw_id)) = field.next().await {
session_id = Some(from_utf8(&raw_id).unwrap().parse().unwrap()); session_id = Some(from_utf8(&raw_id).unwrap().parse().unwrap());
} }
} else if session_id.is_some() { } else if session_id.is_some() {
let filename = content_disposition.get_filename().unwrap(); let filename = content_disposition.get_filename().unwrap().to_owned();
let session_id = session_id.unwrap(); let session_id = session_id.unwrap();
let global_vars = req.app_data::<Data<GlobalVars>>().unwrap(); let global_vars = req.app_data::<Data<GlobalVars>>().unwrap();
if req.path() == "/send_file" { if req.path() == "/send_file" {
@ -440,7 +440,7 @@ async fn handle_send_file(req: HttpRequest, mut payload: Multipart) -> HttpRespo
while let Some(Ok(chunk)) = field.next().await { while let Some(Ok(chunk)) = field.next().await {
buffer.extend(chunk); buffer.extend(chunk);
} }
if let Ok(sent) = global_vars.session_manager.send_or_add_to_pending(&session_id, protocol::file(filename, &buffer)).await { if let Ok(sent) = global_vars.session_manager.send_or_add_to_pending(&session_id, protocol::file(&filename, &buffer)).await {
return if sent { return if sent {
HttpResponse::Ok().finish() HttpResponse::Ok().finish()
} else { } else {
@ -512,7 +512,7 @@ async fn handle_logout(req: HttpRequest) -> HttpResponse {
global_vars.session_manager.stop().await; global_vars.session_manager.stop().await;
} }
if Identity::is_protected().unwrap_or(true) { if Identity::is_protected().unwrap_or(true) {
HttpResponse::Found().header(header::LOCATION, "/").finish() HttpResponse::Found().append_header((header::LOCATION, "/")).finish()
} else { } else {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
let html = fs::read_to_string("src/frontend/logout.html").unwrap(); let html = fs::read_to_string("src/frontend/logout.html").unwrap();
@ -541,8 +541,8 @@ fn login(identity: Identity, global_vars: &GlobalVars) -> HttpResponse {
*global_vars.ui_auth_token.write().unwrap() = Some(cookie_value.clone()); *global_vars.ui_auth_token.write().unwrap() = Some(cookie_value.clone());
let cookie = CookieBuilder::new(constants::HTTP_COOKIE_NAME, cookie_value).max_age(time::Duration::hours(4)).finish(); let cookie = CookieBuilder::new(constants::HTTP_COOKIE_NAME, cookie_value).max_age(time::Duration::hours(4)).finish();
HttpResponse::Found() HttpResponse::Found()
.header(header::LOCATION, "/") .append_header((header::LOCATION, "/"))
.set_header(header::SET_COOKIE, cookie.to_string()) .insert_header((header::SET_COOKIE, cookie.to_string()))
.finish() .finish()
} }
@ -558,7 +558,7 @@ fn on_identity_loaded(identity: Identity, global_vars: &Arc<GlobalVars>) -> Http
struct LoginParams { struct LoginParams {
password: String, password: String,
} }
fn handle_login(req: HttpRequest, mut params: web::Form<LoginParams>) -> HttpResponse { async fn handle_login(req: HttpRequest, mut params: web::Form<LoginParams>) -> HttpResponse {
let response = match Identity::load_identity(Some(params.password.as_bytes())) { let response = match Identity::load_identity(Some(params.password.as_bytes())) {
Ok(identity) => { Ok(identity) => {
let global_vars = req.app_data::<Data<GlobalVars>>().unwrap(); let global_vars = req.app_data::<Data<GlobalVars>>().unwrap();
@ -683,7 +683,7 @@ fn replace_fields(file_path: &str) -> String {
content content
} }
fn handle_static(req: HttpRequest) -> HttpResponse { async fn handle_static(req: HttpRequest) -> HttpResponse {
let splits: Vec<&str> = req.path()[1..].split('/').collect(); let splits: Vec<&str> = req.path()[1..].split('/').collect();
if splits[0] == "static" { if splits[0] == "static" {
let mut response_builder = HttpResponse::Ok(); let mut response_builder = HttpResponse::Ok();
@ -780,7 +780,6 @@ fn handle_static(req: HttpRequest) -> HttpResponse {
HttpResponse::NotFound().finish() HttpResponse::NotFound().finish()
} }
#[actix_web::main]
async fn start_http_server(global_vars: GlobalVars) -> io::Result<()> { async fn start_http_server(global_vars: GlobalVars) -> io::Result<()> {
let http_addr = env::var("AIRA_HTTP_ADDR").unwrap_or_else(|_| "127.0.0.1".to_owned()).parse().expect("AIRA_HTTP_ADDR invalid"); let http_addr = env::var("AIRA_HTTP_ADDR").unwrap_or_else(|_| "127.0.0.1".to_owned()).parse().expect("AIRA_HTTP_ADDR invalid");
let http_port = match env::var("AIRA_HTTP_PORT") { let http_port = match env::var("AIRA_HTTP_PORT") {
@ -789,7 +788,7 @@ async fn start_http_server(global_vars: GlobalVars) -> io::Result<()> {
}; };
let server = HttpServer::new(move || { let server = HttpServer::new(move || {
App::new() App::new()
.data(global_vars.clone()) .app_data(Data::new(global_vars.clone()))
.service(web::resource("/") .service(web::resource("/")
.route(web::get().to(handle_index)) .route(web::get().to(handle_index))
.route(web::post().to(handle_create)) .route(web::post().to(handle_create))
@ -799,8 +798,8 @@ async fn start_http_server(global_vars: GlobalVars) -> io::Result<()> {
.route("/send_large_file", web::post().to(handle_send_file)) .route("/send_large_file", web::post().to(handle_send_file))
.route("/load_file", web::get().to(handle_load_file)) .route("/load_file", web::get().to(handle_load_file))
.route("/set_avatar", web::post().to(handle_set_avatar)) .route("/set_avatar", web::post().to(handle_set_avatar))
.route("/avatar/*", web::get().to(handle_avatar)) .route("/avatar/{_}*", web::get().to(handle_avatar))
.route("/static/.*", web::get().to(handle_static)) .route("/static/{_}*", web::get().to(handle_static))
.route("/logout", web::get().to(handle_logout)) .route("/logout", web::get().to(handle_logout))
} }
).bind(SocketAddr::new(http_addr, http_port))?; ).bind(SocketAddr::new(http_addr, http_port))?;
@ -835,5 +834,5 @@ async fn main() {
websocket_port, websocket_port,
ui_auth_token, ui_auth_token,
tokio_handle: Handle::current(), tokio_handle: Handle::current(),
}).unwrap(); }).await.unwrap();
} }