diff --git a/README.md b/README.md index b733100..d24fc67 100644 --- a/README.md +++ b/README.md @@ -65,15 +65,15 @@ Amnezichat offers a highly secure and privacy-focused messaging experience by en sudo apt install docker.io git git clone https://github.com/umutcamliyurt/Amnezichat.git cd Amnezichat/server/ - sudo docker build -t amnezichatserver:latest . - sudo docker run -p 8080:8080 amnezichatserver:latest + docker build --network=host -t amnezichatserver:latest . + docker run --network=host amnezichatserver:latest ## Client setup: **For Web UI connect to http://localhost:8000** sudo apt update - sudo apt install curl build-essential git tor + sudo apt install curl build-essential git tor xterm sudo systemctl enable --now tor.service curl https://sh.rustup.rs -sSf | sh -s -- -y git clone https://github.com/umutcamliyurt/Amnezichat.git @@ -87,8 +87,15 @@ Amnezichat offers a highly secure and privacy-focused messaging experience by en sudo apt install docker.io git git clone https://github.com/umutcamliyurt/Amnezichat.git cd Amnezichat/client/ - sudo docker build -t amnezichat:latest . - sudo docker run -p 8000:8000 amnezichat:latest + docker build --network=host -t amnezichat . + xhost +local:docker + docker run --rm \ + --network=host \ + -e DISPLAY=$DISPLAY \ + -v /tmp/.X11-unix:/tmp/.X11-unix \ + --env QT_X11_NO_MITSHM=1 \ + amnezichat:latest + ## Requirements: diff --git a/README_TR.md b/README_TR.md index e419eba..35fcc94 100644 --- a/README_TR.md +++ b/README_TR.md @@ -65,15 +65,15 @@ Amnezichat, hiçbir kayıt tutulmamasını ve tüm mesaj verilerinin yalnızca s sudo apt install docker.io git git clone https://github.com/umutcamliyurt/Amnezichat.git cd Amnezichat/server/ - sudo docker build -t amnezichatserver:latest . - sudo docker run -p 8080:8080 amnezichatserver:latest + docker build --network=host -t amnezichatserver:latest . + docker run --network=host amnezichatserver:latest ## İstemci kurulumu: **Web UI için http://localhost:8000 adresine bağlanın** sudo apt update - sudo apt install curl build-essential git tor + sudo apt install curl build-essential git tor xterm sudo systemctl enable --now tor.service curl https://sh.rustup.rs -sSf | sh -s -- -y git clone https://github.com/umutcamliyurt/Amnezichat.git @@ -87,8 +87,14 @@ Amnezichat, hiçbir kayıt tutulmamasını ve tüm mesaj verilerinin yalnızca s sudo apt install docker.io git git clone https://github.com/umutcamliyurt/Amnezichat.git cd Amnezichat/client/ - sudo docker build -t amnezichat:latest . - sudo docker run -p 8000:8000 amnezichat:latest + docker build --network=host -t amnezichat . + xhost +local:docker + docker run --rm \ + --network=host \ + -e DISPLAY=$DISPLAY \ + -v /tmp/.X11-unix:/tmp/.X11-unix \ + --env QT_X11_NO_MITSHM=1 \ + amnezichat:latest ## Gereksinimler: diff --git a/client/Cargo.toml b/client/Cargo.toml index c16d9ff..75515e0 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -24,4 +24,5 @@ ed25519-dalek = "2.1.1" rocket = { version = "0.5", features = ["json"] } eframe = "0.26" egui = "0.26" -rfd = "0.12" \ No newline at end of file +rfd = "0.12" +which = "4.4" \ No newline at end of file diff --git a/client/Dockerfile b/client/Dockerfile index 5d4f472..abf96d9 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -9,10 +9,21 @@ RUN apt-get update && \ apt-get install -y \ curl \ build-essential \ + clang \ + cmake \ + libclang-dev \ + llvm-dev \ + net-tools \ + libxkbcommon-x11-0 \ git \ - tor && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* + tor \ + xterm \ + pkg-config \ + iputils-ping \ + libglib2.0-dev \ + libssl-dev \ + libgtk-3-dev \ + dnsutils RUN curl https://sh.rustup.rs -sSf | sh -s -- -y @@ -23,4 +34,10 @@ RUN cargo build --release EXPOSE 8000 -CMD tor & cargo run --release +CMD bash -c "\ + if pgrep -x tor > /dev/null; then \ + echo 'Killing existing Tor process...'; \ + pkill -x tor; \ + sleep 1; \ + fi; \ + cargo run --release" \ No newline at end of file diff --git a/client/src/main.rs b/client/src/main.rs index b0a6e83..22c18e7 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -51,6 +51,7 @@ use std::{ collections::HashSet, error::Error, }; +use std::fs; use serde::{Deserialize, Serialize}; use chacha20poly1305::aead::OsRng; use rand::RngCore; @@ -61,6 +62,9 @@ use rfd::MessageDialog; use rfd::MessageButtons; use rfd::MessageLevel; use rfd::MessageDialogResult; +use std::process::Stdio; +use std::os::unix::fs::PermissionsExt; +use which::which; fn get_raw_bytes_public_key(pk: &PublicKey) -> &[u8] { pk.as_ref() @@ -250,11 +254,8 @@ impl Default for AppState { fn main() -> Result<(), Box> { let mut options = eframe::NativeOptions::default(); - - options.viewport.resizable = Some(false); - - options.viewport.inner_size = Some(egui::vec2(600.0, 900.0)); - + options.viewport.resizable = Some(false); + options.viewport.inner_size = Some(egui::vec2(600.0, 1000.0)); eframe::run_native("Messaging Setup", options, Box::new(|_cc| Box::new(SetupApp::default())))?; Ok(()) } @@ -284,7 +285,6 @@ impl eframe::App for SetupApp { ui.label(egui::RichText::new("Choose an action:").size(24.0)); ui.add_space(10.0); ui.horizontal_wrapped(|ui| { - ui.add_space(20.0); if ui.add( egui::Button::new(egui::RichText::new("➕ Create Room").size(24.0)) @@ -390,11 +390,25 @@ impl eframe::App for SetupApp { if let Err(err) = validate_and_start(self.state.clone()) { self.state.error_message = Some(err.to_string()); } else { - self.state.show_url_label = true; } } + ui.add_space(20.0); + + if ui.add( + egui::Button::new(egui::RichText::new("🌐 Host Server").size(24.0)) + .fill(egui::Color32::from_rgb(30, 30, 150)) + .min_size(egui::vec2(250.0, 50.0)) + ).clicked() { + self.state.error_message = None; + std::thread::spawn(|| { + if let Err(e) = host_server() { + eprintln!("Host server error: {}", e); + } + }); + } + if let Some(err) = &self.state.error_message { ui.add_space(20.0); ui.colored_label(egui::Color32::RED, egui::RichText::new(format!("❗ {}", err)).size(22.0)); @@ -409,6 +423,110 @@ impl eframe::App for SetupApp { } } +fn host_server() -> Result<(), Box> { + let pkg_install = if which("apt").is_ok() { + "sudo apt update && sudo apt install -y git curl build-essential tor" + } else if which("dnf").is_ok() { + "sudo dnf install -y git curl gcc cmake make kernel-devel tor" + } else if which("pacman").is_ok() { + "sudo pacman -Sy --noconfirm git curl base-devel tor" + } else { + return Err("No supported package manager found".into()); + }; + + Command::new("xterm") + .arg("-e") + .arg(format!("bash -c '{}'", pkg_install)) + .spawn()? + .wait()?; + + let setup_script = r#" + #!/bin/bash + set -e + + # Install Rust if not already installed + if ! command -v cargo &> /dev/null; then + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + source $HOME/.cargo/env + fi + + # Clone the repo if not already cloned + if [ ! -d "Amnezichat" ]; then + git clone https://github.com/umutcamliyurt/Amnezichat.git + fi + + cd Amnezichat + + # Clean everything except 'server' + find . -mindepth 1 -maxdepth 1 ! -name 'server' -exec rm -rf {} + + + cd server + cargo build --release + cargo run --release + "#; + + fs::write("start_server.sh", setup_script)?; + fs::set_permissions("start_server.sh", fs::Permissions::from_mode(0o755))?; + + Command::new("xterm") + .arg("-e") + .arg("bash -c './start_server.sh'") + .spawn()? + .wait()?; + + configure_tor_for_onion_service()?; + + Ok(()) +} + +fn configure_tor_for_onion_service() -> Result<(), Box> { + let hidden_dir = "./hidden_service"; + fs::create_dir_all(hidden_dir)?; + fs::set_permissions(hidden_dir, fs::Permissions::from_mode(0o700))?; + + let torrc_path = format!("{}/torrc", hidden_dir); + let torrc_content = format!( + "HiddenServiceDir {}\nHiddenServicePort 80 127.0.0.1:8080\n", + hidden_dir + ); + let mut file = OpenOptions::new() + .create(true) + .write(true) + .truncate(true) + .open(&torrc_path)?; + file.write_all(torrc_content.as_bytes())?; + + let _ = Command::new("pkill").arg("tor").output(); + + let tor_cmd = format!("tor -f {}", torrc_path); + Command::new("nohup") + .arg("bash") + .arg("-c") + .arg(&tor_cmd) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn()?; + + let hostname_path = format!("{}/hostname", hidden_dir); + let start_time = std::time::Instant::now(); + while !Path::new(&hostname_path).exists() { + if start_time.elapsed().as_secs() > 30 { + return Err("Timeout waiting for Tor to create the .onion address.".into()); + } + std::thread::sleep(std::time::Duration::from_secs(1)); + } + + let onion = fs::read_to_string(&hostname_path)?.trim().to_string(); + println!("Your Amnezichat server is live at: http://{}", onion); + + MessageDialog::new() + .set_title("Tor Hidden Service") + .set_description(&format!("Your Amnezichat server is live at: http://{}", onion)) + .show(); + + Ok(()) +} + fn validate_and_start(state: AppState) -> Result<(), Box> { if state.server_url.is_empty() || state.username.is_empty() || state.private_password.is_empty() { return Err("Please fill in all fields.".into()); @@ -751,4 +869,4 @@ fn clear_screen() { .status() .expect("Failed to clear screen on Unix"); } -} +} \ No newline at end of file diff --git a/screenshot.png b/screenshot.png index c424f50..c5b97be 100644 Binary files a/screenshot.png and b/screenshot.png differ diff --git a/server/static/index.html b/server/static/index.html index 54d5142..6372e8e 100644 --- a/server/static/index.html +++ b/server/static/index.html @@ -53,7 +53,7 @@

Build it Yourself

 sudo apt update
-sudo apt install curl build-essential git tor
+sudo apt install curl build-essential git tor xterm
 sudo systemctl enable --now tor.service
 curl https://sh.rustup.rs -sSf | sh -s -- -y
 git clone https://github.com/umutcamliyurt/Amnezichat.git