From 395d1a4b3bae84385240234d06abd6e6b149ec83 Mon Sep 17 00:00:00 2001 From: AryzXploit Date: Wed, 3 Sep 2025 15:26:22 +0700 Subject: [PATCH 1/8] fix(deploy): pipe deploy key directly to ssh-add to avoid temp file hijack --- setup-deploy-keys/src/deploy.rs | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/setup-deploy-keys/src/deploy.rs b/setup-deploy-keys/src/deploy.rs index f612c7ede..a4478a6b9 100644 --- a/setup-deploy-keys/src/deploy.rs +++ b/setup-deploy-keys/src/deploy.rs @@ -1,6 +1,5 @@ use std::env; -use std::fs; -use std::io::{Read, Write}; +use std::io::Write; use std::os::unix::net::UnixStream; use std::os::unix::prelude::*; use std::process::{Command, Stdio}; @@ -17,36 +16,44 @@ fn main() { std::thread::sleep(std::time::Duration::from_millis(5)); } + // decode base64 → pipe ke ssh-add via stdin let mut decode = Command::new("base64") .arg("-d") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn() .unwrap(); + decode .stdin .take() .unwrap() .write_all(key.as_bytes()) .unwrap(); - let mut key = Vec::new(); - decode.stdout.take().unwrap().read_to_end(&mut key).unwrap(); - decode.wait().unwrap(); - let path = "_the_key"; - fs::write(path, key).unwrap(); - fs::set_permissions(path, fs::Permissions::from_mode(0o600)).unwrap(); - run(Command::new("ssh-add") - .arg(path) - .env("SSH_AUTH_SOCK", socket)); - fs::remove_file(path).unwrap(); + let mut ssh_add = Command::new("ssh-add") + .arg("-") // baca key dari stdin + .env("SSH_AUTH_SOCK", socket) + .stdin(Stdio::piped()) + .spawn() + .unwrap(); + + // pipe decode.stdout ke ssh-add.stdin + { + let mut ssh_stdin = ssh_add.stdin.take().unwrap(); + let mut decode_stdout = decode.stdout.take().unwrap(); + std::io::copy(&mut decode_stdout, &mut ssh_stdin).unwrap(); + } + + decode.wait().unwrap(); + ssh_add.wait().unwrap(); let sha = env::var("BUILD_SOURCEVERSION") .or_else(|_| env::var("GITHUB_SHA")) .unwrap(); let msg = format!("Deploy {sha} to gh-pages"); - drop(fs::remove_dir_all(".git")); + let _ = std::fs::remove_dir_all(".git"); run(Command::new("git").arg("init")); run(Command::new("git") .arg("config") From 32b2bbd3933417b6ecb653ccf3e01b73eb3e64a4 Mon Sep 17 00:00:00 2001 From: Muhammad Arya Arjuna Habibulah Date: Wed, 3 Sep 2025 15:52:50 +0700 Subject: [PATCH 2/8] Update deploy.rs --- setup-deploy-keys/src/deploy.rs | 36 +++++++-------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/setup-deploy-keys/src/deploy.rs b/setup-deploy-keys/src/deploy.rs index a4478a6b9..5974d2836 100644 --- a/setup-deploy-keys/src/deploy.rs +++ b/setup-deploy-keys/src/deploy.rs @@ -1,14 +1,13 @@ use std::env; use std::io::Write; use std::os::unix::net::UnixStream; -use std::os::unix::prelude::*; use std::process::{Command, Stdio}; fn main() { let slug = env::var("BUILD_REPOSITORY_ID") .or_else(|_| env::var("GITHUB_REPOSITORY")) .unwrap(); - let key = env::var("GITHUB_DEPLOY_KEY").unwrap(); + let key_b64 = env::var("GITHUB_DEPLOY_KEY").unwrap(); let socket = "/tmp/.github-deploy-socket"; run(Command::new("ssh-agent").arg("-a").arg(socket)); @@ -16,36 +15,18 @@ fn main() { std::thread::sleep(std::time::Duration::from_millis(5)); } - // decode base64 → pipe ke ssh-add via stdin - let mut decode = Command::new("base64") - .arg("-d") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .unwrap(); - - decode - .stdin - .take() - .unwrap() - .write_all(key.as_bytes()) - .unwrap(); + // decode langsung via crate base64 + let decoded = base64::decode(&key_b64).expect("invalid base64 key"); + // pipe ke ssh-add via stdin let mut ssh_add = Command::new("ssh-add") - .arg("-") // baca key dari stdin + .arg("-") .env("SSH_AUTH_SOCK", socket) .stdin(Stdio::piped()) .spawn() .unwrap(); - // pipe decode.stdout ke ssh-add.stdin - { - let mut ssh_stdin = ssh_add.stdin.take().unwrap(); - let mut decode_stdout = decode.stdout.take().unwrap(); - std::io::copy(&mut decode_stdout, &mut ssh_stdin).unwrap(); - } - - decode.wait().unwrap(); + ssh_add.stdin.as_mut().unwrap().write_all(&decoded).unwrap(); ssh_add.wait().unwrap(); let sha = env::var("BUILD_SOURCEVERSION") @@ -55,10 +36,7 @@ fn main() { let _ = std::fs::remove_dir_all(".git"); run(Command::new("git").arg("init")); - run(Command::new("git") - .arg("config") - .arg("user.name") - .arg("Deploy from CI")); + run(Command::new("git").arg("config").arg("user.name").arg("Deploy from CI")); run(Command::new("git").arg("config").arg("user.email").arg("")); run(Command::new("git").arg("add").arg(".")); run(Command::new("git").arg("commit").arg("-m").arg(&msg)); From 241c106c647313b6b759e7d546e1737151ffd042 Mon Sep 17 00:00:00 2001 From: Muhammad Arya Arjuna Habibulah Date: Sat, 6 Sep 2025 16:00:08 +0700 Subject: [PATCH 3/8] Update deploy.rs --- setup-deploy-keys/src/deploy.rs | 52 +++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/setup-deploy-keys/src/deploy.rs b/setup-deploy-keys/src/deploy.rs index 5974d2836..065d159f3 100644 --- a/setup-deploy-keys/src/deploy.rs +++ b/setup-deploy-keys/src/deploy.rs @@ -1,7 +1,9 @@ use std::env; -use std::io::Write; +use std::fs; use std::os::unix::net::UnixStream; +use std::os::unix::prelude::*; use std::process::{Command, Stdio}; +use std::io::Write; fn main() { let slug = env::var("BUILD_REPOSITORY_ID") @@ -15,42 +17,56 @@ fn main() { std::thread::sleep(std::time::Duration::from_millis(5)); } - // decode langsung via crate base64 - let decoded = base64::decode(&key_b64).expect("invalid base64 key"); - - // pipe ke ssh-add via stdin + // Pipe base64-decoded deploy key directly into ssh-add let mut ssh_add = Command::new("ssh-add") .arg("-") .env("SSH_AUTH_SOCK", socket) .stdin(Stdio::piped()) .spawn() - .unwrap(); + .expect("failed to spawn ssh-add"); + + { + let mut child = Command::new("base64") + .arg("-d") + .stdin(Stdio::piped()) + .stdout(ssh_add.stdin.take().unwrap()) + .spawn() + .expect("failed to spawn base64"); - ssh_add.stdin.as_mut().unwrap().write_all(&decoded).unwrap(); - ssh_add.wait().unwrap(); + child + .stdin + .as_mut() + .unwrap() + .write_all(key_b64.as_bytes()) + .expect("failed to write key to base64 stdin"); + + let status = child.wait().expect("failed to wait on base64"); + if !status.success() { + panic!("base64 decoding failed"); + } + } + + let status = ssh_add.wait().expect("failed to wait on ssh-add"); + if !status.success() { + panic!("ssh-add failed with exit code {:?}", status.code()); + } let sha = env::var("BUILD_SOURCEVERSION") .or_else(|_| env::var("GITHUB_SHA")) .unwrap(); let msg = format!("Deploy {sha} to gh-pages"); - let _ = std::fs::remove_dir_all(".git"); + let _ = fs::remove_dir_all(".git"); run(Command::new("git").arg("init")); run(Command::new("git").arg("config").arg("user.name").arg("Deploy from CI")); run(Command::new("git").arg("config").arg("user.email").arg("")); run(Command::new("git").arg("add").arg(".")); run(Command::new("git").arg("commit").arg("-m").arg(&msg)); - run(Command::new("git") - .arg("push") - .arg(format!("git@github.com:{slug}")) - .arg("master:gh-pages") - .env("GIT_SSH_COMMAND", "ssh -o StrictHostKeyChecking=no") - .env("SSH_AUTH_SOCK", socket) - .arg("-f")); } fn run(cmd: &mut Command) { - println!("{cmd:?}"); let status = cmd.status().unwrap(); - assert!(status.success()); + if !status.success() { + panic!("command {:?} failed with {:?}", cmd, status.code()); + } } From f5649023416e5d0a3f673b524e6723fca1ef4305 Mon Sep 17 00:00:00 2001 From: Muhammad Arya Arjuna Habibulah Date: Sun, 5 Oct 2025 06:45:25 +0700 Subject: [PATCH 4/8] Update deploy.rs --- setup-deploy-keys/src/deploy.rs | 105 +++++++++++++++++--------------- 1 file changed, 56 insertions(+), 49 deletions(-) diff --git a/setup-deploy-keys/src/deploy.rs b/setup-deploy-keys/src/deploy.rs index 065d159f3..d184c6955 100644 --- a/setup-deploy-keys/src/deploy.rs +++ b/setup-deploy-keys/src/deploy.rs @@ -1,72 +1,79 @@ use std::env; use std::fs; +use std::io::Write; use std::os::unix::net::UnixStream; use std::os::unix::prelude::*; use std::process::{Command, Stdio}; -use std::io::Write; fn main() { let slug = env::var("BUILD_REPOSITORY_ID") .or_else(|_| env::var("GITHUB_REPOSITORY")) - .unwrap(); - let key_b64 = env::var("GITHUB_DEPLOY_KEY").unwrap(); - - let socket = "/tmp/.github-deploy-socket"; - run(Command::new("ssh-agent").arg("-a").arg(socket)); - while UnixStream::connect(socket).is_err() { - std::thread::sleep(std::time::Duration::from_millis(5)); - } + .unwrap_or_else(|_| "unknown".to_string()); - // Pipe base64-decoded deploy key directly into ssh-add - let mut ssh_add = Command::new("ssh-add") - .arg("-") - .env("SSH_AUTH_SOCK", socket) - .stdin(Stdio::piped()) - .spawn() - .expect("failed to spawn ssh-add"); + let msg = env::var("BUILD_SOURCEVERSIONMESSAGE") + .or_else(|_| env::var("GITHUB_COMMIT_MESSAGE")) + .unwrap_or_else(|_| "Deploy from CI".to_string()); - { - let mut child = Command::new("base64") - .arg("-d") - .stdin(Stdio::piped()) - .stdout(ssh_add.stdin.take().unwrap()) - .spawn() - .expect("failed to spawn base64"); + let mut sock_path = env::temp_dir(); + sock_path.push("deploy.sock"); - child - .stdin - .as_mut() - .unwrap() - .write_all(key_b64.as_bytes()) - .expect("failed to write key to base64 stdin"); - - let status = child.wait().expect("failed to wait on base64"); - if !status.success() { - panic!("base64 decoding failed"); + // Connect ke unix socket + let stream = match UnixStream::connect(&sock_path) { + Ok(s) => s, + Err(e) => { + eprintln!("Failed to connect to socket: {}", e); + std::process::exit(1); } - } + }; - let status = ssh_add.wait().expect("failed to wait on ssh-add"); - if !status.success() { - panic!("ssh-add failed with exit code {:?}", status.code()); + let mut stream = stream; + let payload = format!("deploy {}", slug); + if let Err(e) = stream.write_all(payload.as_bytes()) { + eprintln!("Failed to send deploy request: {}", e); + std::process::exit(1); } - let sha = env::var("BUILD_SOURCEVERSION") - .or_else(|_| env::var("GITHUB_SHA")) - .unwrap(); - let msg = format!("Deploy {sha} to gh-pages"); - let _ = fs::remove_dir_all(".git"); run(Command::new("git").arg("init")); - run(Command::new("git").arg("config").arg("user.name").arg("Deploy from CI")); - run(Command::new("git").arg("config").arg("user.email").arg("")); + + // --- FIXED CONFIG --- + run(Command::new("git") + .arg("config") + .arg("user.name") + .arg("CI Bot")); + run(Command::new("git") + .arg("config") + .arg("user.email") + .arg("ci@example.com")); + run(Command::new("git").arg("add").arg(".")); - run(Command::new("git").arg("commit").arg("-m").arg(&msg)); + + // --- Handle no changes --- + let status_output = run(Command::new("git").arg("status").arg("--porcelain")); + if status_output.trim().is_empty() { + println!("No changes to commit, skipping commit."); + } else { + run(Command::new("git").arg("commit").arg("-m").arg(&msg)); + } } -fn run(cmd: &mut Command) { - let status = cmd.status().unwrap(); - if !status.success() { - panic!("command {:?} failed with {:?}", cmd, status.code()); +// Helper buat ngejalanin perintah +fn run(cmd: &mut Command) -> String { + let output = cmd + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .output() + .expect("failed to execute command"); + + if !output.status.success() { + eprintln!( + "Command failed: {:?}\nstdout: {}\nstderr: {}", + cmd, + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr) + ); + std::process::exit(1); } + + String::from_utf8_lossy(&output.stdout).to_string() } From 7d8c899c498ed36991b1b2313da664f62666a5e8 Mon Sep 17 00:00:00 2001 From: Muhammad Arya Arjuna Habibulah Date: Sun, 5 Oct 2025 06:46:08 +0700 Subject: [PATCH 5/8] Update deploy.rs --- setup-deploy-keys/src/deploy.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/setup-deploy-keys/src/deploy.rs b/setup-deploy-keys/src/deploy.rs index d184c6955..b2bd3828e 100644 --- a/setup-deploy-keys/src/deploy.rs +++ b/setup-deploy-keys/src/deploy.rs @@ -16,8 +16,7 @@ fn main() { let mut sock_path = env::temp_dir(); sock_path.push("deploy.sock"); - - // Connect ke unix socket + let stream = match UnixStream::connect(&sock_path) { Ok(s) => s, Err(e) => { @@ -48,7 +47,6 @@ fn main() { run(Command::new("git").arg("add").arg(".")); - // --- Handle no changes --- let status_output = run(Command::new("git").arg("status").arg("--porcelain")); if status_output.trim().is_empty() { println!("No changes to commit, skipping commit."); @@ -57,7 +55,7 @@ fn main() { } } -// Helper buat ngejalanin perintah +// Helper fn run(cmd: &mut Command) -> String { let output = cmd .stdout(Stdio::piped()) From e88948c5ebc97616d9872dfda13779e42fb1d9cf Mon Sep 17 00:00:00 2001 From: Muhammad Arya Arjuna Habibulah Date: Sun, 5 Oct 2025 06:46:32 +0700 Subject: [PATCH 6/8] Update deploy.rs --- setup-deploy-keys/src/deploy.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/setup-deploy-keys/src/deploy.rs b/setup-deploy-keys/src/deploy.rs index b2bd3828e..a4c4fc95a 100644 --- a/setup-deploy-keys/src/deploy.rs +++ b/setup-deploy-keys/src/deploy.rs @@ -35,7 +35,6 @@ fn main() { let _ = fs::remove_dir_all(".git"); run(Command::new("git").arg("init")); - // --- FIXED CONFIG --- run(Command::new("git") .arg("config") .arg("user.name") From 48446bc679b1ac1bf760bf3a199fcb2706675756 Mon Sep 17 00:00:00 2001 From: Muhammad Arya Arjuna Habibulah Date: Sun, 5 Oct 2025 06:48:09 +0700 Subject: [PATCH 7/8] Update deploy.rs --- setup-deploy-keys/src/deploy.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup-deploy-keys/src/deploy.rs b/setup-deploy-keys/src/deploy.rs index a4c4fc95a..f3129fd2c 100644 --- a/setup-deploy-keys/src/deploy.rs +++ b/setup-deploy-keys/src/deploy.rs @@ -16,7 +16,7 @@ fn main() { let mut sock_path = env::temp_dir(); sock_path.push("deploy.sock"); - + let stream = match UnixStream::connect(&sock_path) { Ok(s) => s, Err(e) => { @@ -54,7 +54,7 @@ fn main() { } } -// Helper +// Helper fn run(cmd: &mut Command) -> String { let output = cmd .stdout(Stdio::piped()) From 54e332f31025094fcae364c68b0324d7c2010b0b Mon Sep 17 00:00:00 2001 From: Muhammad Arya Arjuna Habibulah Date: Sun, 5 Oct 2025 06:50:06 +0700 Subject: [PATCH 8/8] Update deploy.rs --- setup-deploy-keys/src/deploy.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/setup-deploy-keys/src/deploy.rs b/setup-deploy-keys/src/deploy.rs index f3129fd2c..37988582a 100644 --- a/setup-deploy-keys/src/deploy.rs +++ b/setup-deploy-keys/src/deploy.rs @@ -2,7 +2,6 @@ use std::env; use std::fs; use std::io::Write; use std::os::unix::net::UnixStream; -use std::os::unix::prelude::*; use std::process::{Command, Stdio}; fn main() {