~aw/patches

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
3 2

[PATCH mygit v1 1/3] implement "dumb" HTTP(S) cloning

Johann Galle
Details
Message ID
<20210324203822.10854-1-johann@qwertqwefsday.eu>
DKIM signature
pass
Download raw message
Patch: +43 -9
From: Johann150 <johann@qwertqwefsday.eu>

---
 src/main.rs                | 50 ++++++++++++++++++++++++++++++++------
 templates/repo-navbar.html |  2 +-
 2 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 4146a32..87fe0ca 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -137,6 +137,7 @@ fn repo_from_request(repo_name: &str) -> Result<Repository, tide::Error> {
        // Prevent path traversal
        return Err(tide::Error::from_str(400, "Invalid name"));
    }
    // TODO: check for export_ok file
    let repo_path = Path::new(&CONFIG.projectroot).join(repo_name);
    Repository::open(repo_path).or_else(|_| {
        Err(tide::Error::from_str(
@@ -149,8 +150,6 @@ fn repo_from_request(repo_name: &str) -> Result<Repository, tide::Error> {
async fn repo_home(req: Request<()>) -> tide::Result {
    use pulldown_cmark::{escape::escape_html, html::push_html, Options, Parser};

    // TODO check headers to see if this is a git clone, if it is, redirect to .git

    enum ReadmeFormat {
        Plaintext,
        Html,
@@ -425,10 +424,44 @@ async fn repo_file(req: Request<()>) -> tide::Result {
    Ok(tmpl)
}

async fn git_clone(req: Request<()>) -> tide::Result {
    let repo = req.param("repo_name")?;
    println!("{}", repo);
    Ok("adsf".into())
async fn git_data(req: Request<()>) -> tide::Result {
    match repo_from_request(req.param("repo_name")?) {
        Ok(repo) => {
            let path = req
                .url()
                .path()
                .strip_prefix(&format!("/{}/", req.param("repo_name").unwrap()))
                .unwrap_or_default();
            let path = repo.path().join(path);

            if !path.starts_with(repo.path()) {
                // that path got us outside of the repository structure somehow
                tide::log::warn!("Attempt to acces file outside of repo dir: {:?}", path);
                Err(tide::Error::from_str(
                    403,
                    "You do not have access to this file.",
                ))
            } else if !path.is_file() {
                // Either the requested resource does not exist or it is not
                // a file, i.e. a directory.
                Err(tide::Error::from_str(
                    404,
                    "The file you tried to access does not exist.",
                ))
            } else {
                // ok - inside the repo directory
                let mut resp = tide::Response::new(200);
                let mut body = tide::Body::from_file(path).await?;
                body.set_mime("text/plain; charset=utf-8");
                resp.set_body(body);
                Ok(resp)
            }
        }
        Err(_) => Err(tide::Error::from_str(
            404,
            "This repository does not exist.",
        )),
    }
}

mod filters {
@@ -504,8 +537,9 @@ async fn main() -> Result<(), std::io::Error> {
    app.at("/:repo_name").get(repo_home);
    app.at("/:repo_name/").get(repo_home);
    // git clone stuff -- handle thse urls
    // app.at("/:repo_name/info/refs")
    // app.at("/:repo_name/objects")
    app.at("/:repo_name/info/refs").get(git_data);
    app.at("/:repo_name/HEAD").get(git_data);
    app.at("/:repo_name/objects/*obj").get(git_data);
    app.at("/:repo_name/commit/:commit").get(repo_commit);
    app.at("/:repo_name/refs").get(repo_refs);
    app.at("/:repo_name/log").get(repo_log);
diff --git a/templates/repo-navbar.html b/templates/repo-navbar.html
index 42596ba..f897cfd 100644
--- a/templates/repo-navbar.html
+++ b/templates/repo-navbar.html
@@ -1,5 +1,5 @@
<h1><a href="/">index</a>/{{repo|repo_name}}</h1>
<div>{{repo|description}}</div>
<div class="clone-url">git clone {{crate::CONFIG.clone_base}}/{{repo|repo_name}}.git</div>
<div class="clone-url">git clone {{crate::CONFIG.clone_base}}/{{repo|repo_name}}</div>
<div class="navbar"><a href="/{{repo|repo_name|urlencode_strict}}">README</a> |  <a href="/{{repo|repo_name|urlencode_strict}}/tree">tree</a> |  <a href="/{{repo|repo_name|urlencode_strict}}/log">log</a> |  <a href="/{{repo|repo_name|urlencode_strict}}/refs">refs</a></div>
<hr class='thin'>
-- 
2.20.1

[PATCH mygit v1 3/3] clean up repo_from_request

Johann Galle
Details
Message ID
<20210324203822.10854-3-johann@qwertqwefsday.eu>
In-Reply-To
<20210324203822.10854-1-johann@qwertqwefsday.eu> (view parent)
DKIM signature
pass
Download raw message
Patch: +23 -7
From: Johann150 <johann@qwertqwefsday.eu>

Check for the export file and also improve path traversal protection:
Do not just check if the path contains .. but instead check that the
resulting path does not leave the project root directory.
---
 src/main.rs | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 87fe0ca..c5cb8cd 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -133,18 +133,34 @@ fn repo_from_request(repo_name: &str) -> Result<Repository, tide::Error> {
    let repo_name = percent_encoding::percent_decode_str(repo_name)
        .decode_utf8_lossy()
        .into_owned();
    if repo_name.contains("..") {
        // Prevent path traversal
        return Err(tide::Error::from_str(400, "Invalid name"));
    }
    // TODO: check for export_ok file

    let repo_path = Path::new(&CONFIG.projectroot).join(repo_name);
    Repository::open(repo_path).or_else(|_| {

    // prevent path traversal
    if !repo_path.starts_with(&CONFIG.projectroot) {
        return Err(tide::Error::from_str(
            403,
            "You do not have access to this resource.",
        ));
    }

    let repo = Repository::open(repo_path).or_else(|_| {
        Err(tide::Error::from_str(
            404,
            "This repository does not exist.",
        ))
    })?;

    if !repo.path().join(&CONFIG.export_ok).exists() {
        // outside users should not be able to tell the difference between
        // nonexistent and existing but forbidden repos, so not using 403
        Err(tide::Error::from_str(
            404,
            "This repository does not exist.",
        ))
    })
    } else {
        Ok(repo)
    }
}

async fn repo_home(req: Request<()>) -> tide::Result {
-- 
2.20.1

[PATCH mygit v1 2/3] update dependencies

Johann Galle
Details
Message ID
<20210324203822.10854-2-johann@qwertqwefsday.eu>
In-Reply-To
<20210324203822.10854-1-johann@qwertqwefsday.eu> (view parent)
DKIM signature
pass
Download raw message
Patch: +39 -40
From: Johann150 <johann@qwertqwefsday.eu>

---
 Cargo.lock | 79 +++++++++++++++++++++++++++---------------------------
 1 file changed, 39 insertions(+), 40 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 38149c0..c9c9b3f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -62,9 +62,9 @@ dependencies = [

[[package]]
name = "anyhow"
version = "1.0.38"
version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
checksum = "81cddc5f91628367664cc7c69714ff08deee8a3efc54623011c772544d7b2767"

[[package]]
name = "arrayref"
@@ -630,9 +630,9 @@ dependencies = [

[[package]]
name = "ctor"
version = "0.1.19"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8f45d9ad417bcef4817d614a501ab55cdd96a6fdb24f49aab89a54acfd66b19"
checksum = "5e98e2ad1a782e33928b96fc3948e7c355e5af34ba4de7670fe8bac2a3b2006d"
dependencies = [
 "quote",
 "syn",
@@ -1035,9 +1035,9 @@ dependencies = [

[[package]]
name = "js-sys"
version = "0.3.48"
version = "0.3.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc9f84f9b115ce7843d60706df1422a916680bfdfcbdb0447c5614ff9d7e4d78"
checksum = "dc15e39392125075f60c95ba416f5381ff6c3a948ff02ab12464715adf56c821"
dependencies = [
 "wasm-bindgen",
]
@@ -1078,9 +1078,9 @@ dependencies = [

[[package]]
name = "libc"
version = "0.2.89"
version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "538c092e5586f4cdd7dd8078c4a79220e3e168880218124dcbce860f0ea938c6"
checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7"

[[package]]
name = "libgit2-sys"
@@ -1182,9 +1182,9 @@ dependencies = [

[[package]]
name = "nb-connect"
version = "1.0.3"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670361df1bc2399ee1ff50406a0d422587dd3bb0da596e1978fe8e05dabddf4f"
checksum = "a19900e7eee95eb2b3c2e26d12a874cc80aaf750e31be6fcbe743ead369fa45d"
dependencies = [
 "libc",
 "socket2",
@@ -1344,11 +1344,11 @@ dependencies = [

[[package]]
name = "polling"
version = "2.0.2"
version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2a7bc6b2a29e632e45451c941832803a18cce6781db04de8a04696cdca8bde4"
checksum = "4fc12d774e799ee9ebae13f4076ca003b40d18a11ac0f3641e6f899618580b7b"
dependencies = [
 "cfg-if 0.1.10",
 "cfg-if 1.0.0",
 "libc",
 "log",
 "wepoll-sys",
@@ -1560,18 +1560,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"

[[package]]
name = "serde"
version = "1.0.124"
version = "1.0.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f"
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
dependencies = [
 "serde_derive",
]

[[package]]
name = "serde_derive"
version = "1.0.124"
version = "1.0.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b"
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
dependencies = [
 "proc-macro2",
 "quote",
@@ -1668,11 +1668,10 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"

[[package]]
name = "socket2"
version = "0.3.19"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2"
dependencies = [
 "cfg-if 1.0.0",
 "libc",
 "winapi",
]
@@ -1685,9 +1684,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"

[[package]]
name = "standback"
version = "0.2.15"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2beb4d1860a61f571530b3f855a1b538d0200f7871c63331ecd6f17b1f014f8"
checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff"
dependencies = [
 "version_check",
]
@@ -2000,9 +1999,9 @@ checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"

[[package]]
name = "vec-arena"
version = "1.0.0"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eafc1b9b2dfc6f5529177b62cf806484db55b32dc7c9658a118e11bbeb33061d"
checksum = "34b2f665b594b07095e3ac3f718e13c2197143416fae4c5706cffb7b1af8d7f1"

[[package]]
name = "version_check"
@@ -2018,9 +2017,9 @@ checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"

[[package]]
name = "walkdir"
version = "2.3.1"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
dependencies = [
 "same-file",
 "winapi",
@@ -2041,9 +2040,9 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"

[[package]]
name = "wasm-bindgen"
version = "0.2.71"
version = "0.2.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ee1280240b7c461d6a0071313e08f34a60b0365f14260362e5a2b17d1d31aa7"
checksum = "8fe8f61dba8e5d645a4d8132dc7a0a66861ed5e1045d2c0ed940fab33bac0fbe"
dependencies = [
 "cfg-if 1.0.0",
 "serde",
@@ -2053,9 +2052,9 @@ dependencies = [

[[package]]
name = "wasm-bindgen-backend"
version = "0.2.71"
version = "0.2.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b7d8b6942b8bb3a9b0e73fc79b98095a27de6fa247615e59d096754a3bc2aa8"
checksum = "046ceba58ff062da072c7cb4ba5b22a37f00a302483f7e2a6cdc18fedbdc1fd3"
dependencies = [
 "bumpalo",
 "lazy_static",
@@ -2068,9 +2067,9 @@ dependencies = [

[[package]]
name = "wasm-bindgen-futures"
version = "0.4.21"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e67a5806118af01f0d9045915676b22aaebecf4178ae7021bc171dab0b897ab"
checksum = "73157efb9af26fb564bb59a009afd1c7c334a44db171d280690d0c3faaec3468"
dependencies = [
 "cfg-if 1.0.0",
 "js-sys",
@@ -2080,9 +2079,9 @@ dependencies = [

[[package]]
name = "wasm-bindgen-macro"
version = "0.2.71"
version = "0.2.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5ac38da8ef716661f0f36c0d8320b89028efe10c7c0afde65baffb496ce0d3b"
checksum = "0ef9aa01d36cda046f797c57959ff5f3c615c9cc63997a8d545831ec7976819b"
dependencies = [
 "quote",
 "wasm-bindgen-macro-support",
@@ -2090,9 +2089,9 @@ dependencies = [

[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.71"
version = "0.2.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc053ec74d454df287b9374ee8abb36ffd5acb95ba87da3ba5b7d3fe20eb401e"
checksum = "96eb45c1b2ee33545a813a92dbb53856418bf7eb54ab34f7f7ff1448a5b3735d"
dependencies = [
 "proc-macro2",
 "quote",
@@ -2103,15 +2102,15 @@ dependencies = [

[[package]]
name = "wasm-bindgen-shared"
version = "0.2.71"
version = "0.2.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d6f8ec44822dd71f5f221a5847fb34acd9060535c1211b70a05844c0f6383b1"
checksum = "b7148f4696fb4960a346eaa60bbfb42a1ac4ebba21f750f75fc1375b098d5ffa"

[[package]]
name = "web-sys"
version = "0.3.48"
version = "0.3.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec600b26223b2948cedfde2a0aa6756dcf1fef616f43d7b3097aaf53a6c4d92b"
checksum = "59fe19d70f5dacc03f6e46777213facae5ac3801575d56ca6cbd4c93dcd12310"
dependencies = [
 "js-sys",
 "wasm-bindgen",
-- 
2.20.1
Details
Message ID
<CA5VQH7TO5GT.23YCWYX0YO7BT@debian-alex>
In-Reply-To
<20210324203822.10854-1-johann@qwertqwefsday.eu> (view parent)
DKIM signature
fail
Download raw message
DKIM signature: fail
This looks great! I'll test it out, I think it's the last thing I need
before deploying an alpha to git.alexwennerberg.com

On Wed Mar 24, 2021 at 1:38 PM PDT, Johann Galle wrote:
> From: Johann150 <johann@qwertqwefsday.eu>
>
> ---
> src/main.rs | 50 ++++++++++++++++++++++++++++++++------
> templates/repo-navbar.html | 2 +-
> 2 files changed, 43 insertions(+), 9 deletions(-)
>
> diff --git a/src/main.rs b/src/main.rs
> index 4146a32..87fe0ca 100644
> --- a/src/main.rs
> +++ b/src/main.rs
> @@ -137,6 +137,7 @@ fn repo_from_request(repo_name: &str) ->
> Result<Repository, tide::Error> {
> // Prevent path traversal
> return Err(tide::Error::from_str(400, "Invalid name"));
> }
> + // TODO: check for export_ok file
> let repo_path = Path::new(&CONFIG.projectroot).join(repo_name);
> Repository::open(repo_path).or_else(|_| {
> Err(tide::Error::from_str(
> @@ -149,8 +150,6 @@ fn repo_from_request(repo_name: &str) ->
> Result<Repository, tide::Error> {
> async fn repo_home(req: Request<()>) -> tide::Result {
> use pulldown_cmark::{escape::escape_html, html::push_html, Options,
> Parser};
>  
> - // TODO check headers to see if this is a git clone, if it is,
> redirect to .git
> -
> enum ReadmeFormat {
> Plaintext,
> Html,
> @@ -425,10 +424,44 @@ async fn repo_file(req: Request<()>) ->
> tide::Result {
> Ok(tmpl)
> }
>  
> -async fn git_clone(req: Request<()>) -> tide::Result {
> - let repo = req.param("repo_name")?;
> - println!("{}", repo);
> - Ok("adsf".into())
> +async fn git_data(req: Request<()>) -> tide::Result {
> + match repo_from_request(req.param("repo_name")?) {
> + Ok(repo) => {
> + let path = req
> + .url()
> + .path()
> + .strip_prefix(&format!("/{}/", req.param("repo_name").unwrap()))
> + .unwrap_or_default();
> + let path = repo.path().join(path);
> +
> + if !path.starts_with(repo.path()) {
> + // that path got us outside of the repository structure somehow
> + tide::log::warn!("Attempt to acces file outside of repo dir: {:?}",
> path);
> + Err(tide::Error::from_str(
> + 403,
> + "You do not have access to this file.",
> + ))
> + } else if !path.is_file() {
> + // Either the requested resource does not exist or it is not
> + // a file, i.e. a directory.
> + Err(tide::Error::from_str(
> + 404,
> + "The file you tried to access does not exist.",
> + ))
> + } else {
> + // ok - inside the repo directory
> + let mut resp = tide::Response::new(200);
> + let mut body = tide::Body::from_file(path).await?;
> + body.set_mime("text/plain; charset=utf-8");
> + resp.set_body(body);
> + Ok(resp)
> + }
> + }
> + Err(_) => Err(tide::Error::from_str(
> + 404,
> + "This repository does not exist.",
> + )),
> + }
> }
>  
> mod filters {
> @@ -504,8 +537,9 @@ async fn main() -> Result<(), std::io::Error> {
> app.at("/:repo_name").get(repo_home);
> app.at("/:repo_name/").get(repo_home);
> // git clone stuff -- handle thse urls
> - // app.at("/:repo_name/info/refs")
> - // app.at("/:repo_name/objects")
> + app.at("/:repo_name/info/refs").get(git_data);
> + app.at("/:repo_name/HEAD").get(git_data);
> + app.at("/:repo_name/objects/*obj").get(git_data);
> app.at("/:repo_name/commit/:commit").get(repo_commit);
> app.at("/:repo_name/refs").get(repo_refs);
> app.at("/:repo_name/log").get(repo_log);
> diff --git a/templates/repo-navbar.html b/templates/repo-navbar.html
> index 42596ba..f897cfd 100644
> --- a/templates/repo-navbar.html
> +++ b/templates/repo-navbar.html
> @@ -1,5 +1,5 @@
> <h1><a href="/">index</a>/{{repo|repo_name}}</h1>
> <div>{{repo|description}}</div>
> -<div class="clone-url">git clone
> {{crate::CONFIG.clone_base}}/{{repo|repo_name}}.git</div>
> +<div class="clone-url">git clone
> {{crate::CONFIG.clone_base}}/{{repo|repo_name}}</div>
> <div class="navbar"><a
> href="/{{repo|repo_name|urlencode_strict}}">README</a> | <a
> href="/{{repo|repo_name|urlencode_strict}}/tree">tree</a> | <a
> href="/{{repo|repo_name|urlencode_strict}}/log">log</a> | <a
> href="/{{repo|repo_name|urlencode_strict}}/refs">refs</a></div>
> <hr class='thin'>
> --
> 2.20.1
Reply to thread Export thread (mbox)