From 01aaeef619cc249a6c4555b3c865bb081e5b80c5 Mon Sep 17 00:00:00 2001 From: Luca Bruno Date: Sun, 14 Oct 2012 14:45:21 +0200 Subject: [PATCH] Use gpgv for signature verification in cargo Parsing gpg output for signature verification is not recommended, as it can break easily (and doesn't work with i18n). This patch makes use of gpgv, as suggested by gpg authors: http://lists.gnupg.org/pipermail/gnupg-users/2004-August/023141.html This closes #3762. Signed-off-by: Luca Bruno --- src/cargo/cargo.rs | 37 ++++++++++++++++++------------------- src/cargo/pgp.rs | 23 +++++++++++------------ 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/cargo/cargo.rs b/src/cargo/cargo.rs index 5f39eb6b960e2..322d780042089 100644 --- a/src/cargo/cargo.rs +++ b/src/cargo/cargo.rs @@ -1162,20 +1162,20 @@ fn sync_one_file(c: &Cargo, dir: &Path, src: @Source) -> bool { } match (src.key, src.keyfp) { (Some(_), Some(f)) => { - let r = pgp::verify(&c.root, &pkgfile, &sigfile, f); + let r = pgp::verify(&c.root, &pkgfile, &sigfile); if !r { - error(fmt!("signature verification failed for source %s", - name)); + error(fmt!("signature verification failed for source %s with key %s", + name, f)); return false; } if has_src_file { - let e = pgp::verify(&c.root, &srcfile, &srcsigfile, f); + let e = pgp::verify(&c.root, &srcfile, &srcsigfile); if !e { - error(fmt!("signature verification failed for source %s", - name)); + error(fmt!("signature verification failed for source %s with key %s", + name, f)); return false; } } @@ -1273,21 +1273,21 @@ fn sync_one_git(c: &Cargo, dir: &Path, src: @Source) -> bool { } match (src.key, src.keyfp) { (Some(_), Some(f)) => { - let r = pgp::verify(&c.root, &pkgfile, &sigfile, f); + let r = pgp::verify(&c.root, &pkgfile, &sigfile); if !r { - error(fmt!("signature verification failed for source %s", - name)); + error(fmt!("signature verification failed for source %s with key %s", + name, f)); rollback(name, dir, false); return false; } if has_src_file { - let e = pgp::verify(&c.root, &srcfile, &srcsigfile, f); + let e = pgp::verify(&c.root, &srcfile, &srcsigfile); if !e { - error(fmt!("signature verification failed for source %s", - name)); + error(fmt!("signature verification failed for source %s with key %s", + name, f)); rollback(name, dir, false); return false; } @@ -1370,11 +1370,11 @@ fn sync_one_curl(c: &Cargo, dir: &Path, src: @Source) -> bool { return false; } - let r = pgp::verify(&c.root, &pkgfile, &sigfile, f); + let r = pgp::verify(&c.root, &pkgfile, &sigfile); if !r { - error(fmt!("signature verification failed for source %s", - name)); + error(fmt!("signature verification failed for source %s with key %s", + name, f)); return false; } @@ -1390,11 +1390,11 @@ fn sync_one_curl(c: &Cargo, dir: &Path, src: @Source) -> bool { return false; } - let e = pgp::verify(&c.root, &srcfile, &srcsigfile, f); + let e = pgp::verify(&c.root, &srcfile, &srcsigfile); if !e { error(~"signature verification failed for " + - ~"source " + name); + ~"source " + name + ~" with key " + f); return false; } } @@ -1463,8 +1463,7 @@ fn cmd_init(c: &Cargo) { return; } - let r = pgp::verify(&c.root, &srcfile, &sigfile, - pgp::signing_key_fp()); + let r = pgp::verify(&c.root, &srcfile, &sigfile); if !r { error(fmt!("signature verification failed for '%s'", srcfile.to_str())); diff --git a/src/cargo/pgp.rs b/src/cargo/pgp.rs index 17cb8dc648789..5fbfa55838c8e 100644 --- a/src/cargo/pgp.rs +++ b/src/cargo/pgp.rs @@ -1,5 +1,5 @@ -fn gpg(args: ~[~str]) -> { status: int, out: ~str, err: ~str } { - return run::program_output(~"gpg", args); +fn gpgv(args: ~[~str]) -> { status: int, out: ~str, err: ~str } { + return run::program_output(~"gpgv", args); } fn signing_key() -> ~str { @@ -59,7 +59,7 @@ fn signing_key_fp() -> ~str { } fn supported() -> bool { - let r = gpg(~[~"--version"]); + let r = gpgv(~[~"--version"]); r.status == 0 } @@ -88,15 +88,14 @@ fn add(root: &Path, key: &Path) { } } -fn verify(root: &Path, data: &Path, sig: &Path, keyfp: ~str) -> bool { +fn verify(root: &Path, data: &Path, sig: &Path) -> bool { let path = root.push("gpg"); - let p = gpg(~[~"--homedir", path.to_str(), - ~"--with-fingerprint", - ~"--verify", sig.to_str(), - data.to_str()]); - let res = ~"Primary key fingerprint: " + keyfp; - for str::split_char_each(p.err, '\n') |line| { - if line == res { return true; } + let res = gpgv(~[~"--homedir", path.to_str(), + ~"--keyring", ~"pubring.gpg", + ~"--verbose", + sig.to_str(), data.to_str()]); + if res.status != 0 { + return false; } - return false; + return true; }