Skip to content

Commit

Permalink
Merge pull request #2 from kpcyrd/fix-url-join
Browse files Browse the repository at this point in the history
Fix url join with colon in filename
  • Loading branch information
kpcyrd authored Aug 24, 2021
2 parents 355f35b + 0e4e146 commit a2fef4f
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 22 deletions.
46 changes: 46 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Rust

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
name: build
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose

# clippy:
# name: clippy
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v2
# - uses: actions-rs/toolchain@v1
# with:
# profile: minimal
# toolchain: stable
# override: true
# components: clippy
# - uses: actions-rs/cargo@v1
# with:
# command: clippy
# args: --workspace --all-targets -- --deny warnings
#
# fmt:
# name: fmt
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v2
# - name: Run cargo fmt
# run: cargo fmt -- --check
5 changes: 3 additions & 2 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use pacman_bintrans_common::http::Proxy;
use std::path::PathBuf;
use structopt::StructOpt;
use structopt::clap::AppSettings;
use url::Url;

#[derive(Debug, StructOpt)]
#[structopt(global_settings = &[AppSettings::ColoredHelp])]
Expand All @@ -13,7 +14,7 @@ pub struct Args {
#[structopt(short = "O", long)]
pub output: PathBuf,
#[structopt(long)]
pub transparency_url: Option<String>,
pub transparency_url: Option<Url>,
#[structopt(long)]
pub pubkey: String,
/// Example: socks5://127.0.0.1:9050
Expand All @@ -22,7 +23,7 @@ pub struct Args {
/// Only use the proxy for transparency signatures, not the pkg
#[structopt(long)]
pub bypass_proxy_for_pkgs: bool,
pub url: String,
pub url: Url,
}

fn parse_proxy(proxy: &str) -> Result<Proxy> {
Expand Down
36 changes: 20 additions & 16 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use pacman_bintrans::proof;
use pacman_bintrans_common::errors::*;
use pacman_bintrans_common::http;
use std::fs;
use std::path::Path;
use std::rc::Rc;
use structopt::StructOpt;
use url::Url;
Expand All @@ -29,6 +28,12 @@ fn needs_transparency_proof(url: &str) -> bool {
iter.next() == Some(&"pkg")
}

fn filename_from_url(url: &Url) -> Option<String> {
let segments = url.path_segments()?;
let filename = segments.last()?;
Some(filename.to_string())
}

#[tokio::main]
async fn main() -> Result<()> {
let args = Args::from_args();
Expand All @@ -46,30 +51,29 @@ async fn main() -> Result<()> {
.context("Failed to load transparency public key")?
.to_box()?;

let client = Rc::new(Client::new(args.proxy)?);
let client = Rc::new(Client::new(args.proxy.clone())?);
let pkg_client = if args.bypass_proxy_for_pkgs {
Rc::new(Client::new(None)?)
} else {
client.clone()
};

if needs_transparency_proof(&args.url) {
if needs_transparency_proof(&args.url.as_str()) {
info!(
"Transparency proof is required for {:?}, downloading into memory",
args.url
args.url.as_str()
);
let pkg = pkg_client.download_to_mem(&args.url, None).await?;
let pkg = pkg_client.download_to_mem(args.url.as_str(), None).await?;
debug!("Downloaded {} bytes", pkg.len());

let url = if let Some(url) = args.transparency_url {
let p = Path::new(&args.url);
let file_name = p.file_name()
.ok_or_else(|| anyhow!("Missing filename for url"))?
.to_str()
.ok_or_else(|| anyhow!("Invalid filename"))?;
let url = url.parse::<Url>()?;
let url = url.join(file_name)?;
url.as_str().to_string()
let url = if let Some(transparency_url) = &args.transparency_url {
let file_name = filename_from_url(&args.url)
.ok_or_else(|| anyhow!("Couldn't detect filename for url: {:?}", args.url.as_str()))?;
let mut url = transparency_url.clone();
url.path_segments_mut()
.map_err(|_| anyhow!("Failed to get path segments for url"))?
.pop_if_empty().push(&file_name);
url
} else {
args.url
};
Expand All @@ -81,8 +85,8 @@ async fn main() -> Result<()> {
fs::write(args.output, &pkg).context("Failed to write database file after verification")?;
debug!("Wrote {} bytes", pkg.len());
} else {
info!("Downloading {:?} to {:?}", args.url, args.output);
let n = client.download_to_file(&args.url, &args.output).await?;
info!("Downloading {:?} to {:?}", args.url.as_str(), args.output);
let n = client.download_to_file(args.url.as_str(), &args.output).await?;
debug!("Downloaded {} bytes", n);
}

Expand Down
10 changes: 6 additions & 4 deletions src/proof.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use pacman_bintrans_common::errors::*;
use minisign::{PublicKeyBox, SignatureBox};
use pacman_bintrans_common::errors::*;
use pacman_bintrans_common::http::Client;
use sha2::{Sha256, Digest};
use std::fs;
Expand All @@ -8,6 +8,7 @@ use std::process::Stdio;
use tempfile::NamedTempFile;
use tokio::io::AsyncWriteExt;
use tokio::process::Command;
use url::Url;

const PROOF_SIZE_LIMIT: usize = 1024; // 1K

Expand Down Expand Up @@ -69,11 +70,12 @@ pub async fn verify(pubkey: &PublicKeyBox, artifact: &[u8], sig: &[u8]) -> Resul
Ok(())
}

pub async fn fetch_and_verify(client: &Client, pubkey: &PublicKeyBox, url: &str, pkg: &[u8]) -> Result<()> {
let url = format!("{}.t", url);
pub async fn fetch_and_verify(client: &Client, pubkey: &PublicKeyBox, url: &Url, pkg: &[u8]) -> Result<()> {
let url = format!("{}.t", url.as_str());
info!("Trying to download transparency proof from {:?}", url);
let url = url.parse::<Url>()?;

let proof = client.download_to_mem(&url, Some(PROOF_SIZE_LIMIT)).await?;
let proof = client.download_to_mem(url.as_str(), Some(PROOF_SIZE_LIMIT)).await?;
debug!("Downloaded {} bytes", proof.len());

verify(&pubkey, pkg, &proof).await
Expand Down

0 comments on commit a2fef4f

Please sign in to comment.