Initial commit

This commit is contained in:
southerntofu 2021-01-05 18:25:58 +01:00
commit 0ef7291684
5 changed files with 138 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target
.*.sw*

5
Cargo.lock generated Normal file
View File

@ -0,0 +1,5 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "testsuid"
version = "0.1.0"

9
Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "testsuid"
version = "0.1.0"
authors = ["southerntofu <southerntofu@thunix.net>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

54
README.md Normal file
View File

@ -0,0 +1,54 @@
# testsuid
This program is a simple git wrapper intended to be used with suid/guid bits set to "impersonate" another user and let them clone a repository (with their consent, of course).
When cloning the repository without initializing the submodules, everything works as expected. However, it appears git fails when cloning submodules when called from a suid program (the program uses `git clone --recursive`).
How to reproduce:
```
$ git clone https://tildegit.org/southerntofu/testsuid
$ cd testsuid
$ cargo build --release
$ cp target/release/testsuid /tmp/testsuid
$ chmod u+s,g+s /tmp/testsuid
$ mkdir /tmp/dest/
$ /tmp/testsuid "https://tildegit.org/tilde-fr/site" /tmp/dest/1
Cloning https://tildegit.org/tilde-fr/site to /tmp/dest/1 (recursive: false)
$ # SUCCESS
$ /tmp/testsuid --recursive "https://tildegit.org/tilde-fr/site" /tmp/dest/2
Cloning https://tildegit.org/tilde-fr/site to /tmp/dest/2 (recursive: true)
$ # SUCCESS
$ # Now let's try from a different user.
$ su guest
$ /tmp/testsuid "https://tildegit.org/tilde-fr/site" /tmp/dest/3
Cloning https://tildegit.org/tilde-fr/site to /tmp/dest3 (recursive: false)
$ # SUCCESS
$ /tmp/testsuid --recursive "https://tildegit.org/tilde-fr/site" /tmp/dest/4
Cloning https://tildegit.org/tilde-fr/site to /tmp/dest/4 (recursive: true)
FAILED!
STDOUT:
STDERR:
18:24:38.064467 git.c:418 trace: built-in: git clone --recursive https://tildegit.org/tilde-fr/site /tmp/dest/4
Cloning into '/tmp/dest/4'...
18:24:38.070170 run-command.c:643 trace: run_command: git-remote-https origin https://tildegit.org/tilde-fr/site
18:24:38.621635 run-command.c:643 trace: run_command: git fetch-pack --stateless-rpc --stdin --lock-pack --thin --check-self-contained-and-connected --cloning --no-progress https://tildegit.org/tilde-fr/site/
18:24:38.625704 git.c:418 trace: built-in: git fetch-pack --stateless-rpc --stdin --lock-pack --thin --check-self-contained-and-connected --cloning --no-progress https://tildegit.org/tilde-fr/site/
18:24:38.820744 run-command.c:643 trace: run_command: git unpack-objects -q --pack_header=2,60
18:24:38.823934 git.c:418 trace: built-in: git unpack-objects -q --pack_header=2,60
18:24:38.840025 run-command.c:643 trace: run_command: git rev-list --objects --stdin --not --all --quiet
18:24:38.841075 git.c:418 trace: built-in: git rev-list --objects --stdin --not --all --quiet
warning: unable to access '/home/guest/.config/git/attributes': Permission denied
18:24:38.848734 run-command.c:643 trace: run_command: git submodule update --require-init --recursive
18:24:38.849745 git.c:669 trace: exec: git-submodule update --require-init --recursive
18:24:38.849789 run-command.c:643 trace: run_command: git-submodule update --require-init --recursive
18:24:38.857209 git.c:418 trace: built-in: git rev-parse --git-dir
18:24:38.858398 git.c:418 trace: built-in: git rev-parse --git-path objects
18:24:38.859289 git.c:418 trace: built-in: git rev-parse -q --git-dir
18:24:38.861442 git.c:418 trace: built-in: git rev-parse --show-prefix
18:24:38.862713 git.c:418 trace: built-in: git rev-parse --show-toplevel
18:24:38.864570 git.c:418 trace: built-in: git submodule--helper init
error: could not lock config file /tmp/dest/4/.git/config: Permission denied
fatal: Failed to register url for submodule path 'themes/water'
```

68
src/main.rs Normal file
View File

@ -0,0 +1,68 @@
use std::process::Command;
fn help() {
eprintln!("testsuid [--recursive] REMOTE DESTINATION");
}
fn main() {
let args: Vec<String> = std::env::args().collect();
let (recurse, source, dest) = match args.len() {
0|1|2 => {
help();
panic!();
},
3 => {
(
false,
args.get(1).unwrap(),
args.get(2).unwrap()
)
},
4 => {
let recurse = args.get(1).unwrap();
if ! (recurse == "--recursive" || recurse == "-r") {
eprintln!("You provided 3 arguments. The first one must be -r or --recursive.");
eprintln!("Otherwise, please give me only 2 arguments.");
help();
panic!();
}
(
true,
args.get(2).unwrap(),
args.get(3).unwrap()
)
},
_ => {
help();
panic!();
}
};
println!("Cloning {} to {} (recursive: {})", source, dest, recurse);
let output = if recurse {
Command::new("git")
.arg("clone")
.arg("--recursive")
.arg(source)
.arg(dest)
.env("GIT_TRACE", "1")
.output().expect("Failed to run process")
} else {
Command::new("git")
.arg("clone")
.arg(source)
.arg(dest)
.env("GIT_TRACE", "1")
.output().expect("Failed to run process")
};
if !output.status.success() {
println!("FAILED!");
println!("STDOUT:");
println!("{}", String::from_utf8_lossy(&output.stdout));
println!("STDERR:");
println!("{}", String::from_utf8_lossy(&output.stderr));
}
}