mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-05-06 22:18:28 +00:00
Compatibility with GnuPG 1.x and 2.x, auto-detect GnuPG version
* aptly can sign and verify without issues with GnuPG 1.x and 2.x * aptly auto-detects GnuPG version and adapts accordingly * aptly automatically finds suitable GnuPG version Majority of the work was to get unit-tests which can work with GnuPG 1.x & 2.x. Locally I've verified that aptly supports GnuPG 1.4.x & 2.2.x. Travis CI environment is based on trusty, so it runs gpg2 tests with GnuPG 2.0.x. Configuration parameter gpgProvider now supports three values for GnuPG: * gpg (same as before, default): use GnuPG 1.x if available (checks gpg, gpg1), otherwise uses GnuPG 2.x; for aptly users who already have GnuPG 1.x environment (as it was the only supported version) nothing should change; new users might start with GnuPG 2.x if that's their installed version * gpg1 looks for GnuPG 1.x only, fails otherwise * gpg2 looks for GnuPG 2.x only, fails otherwise
This commit is contained in:
@@ -38,3 +38,6 @@ system/env/
|
|||||||
|
|
||||||
# created by make build for release artifacts
|
# created by make build for release artifacts
|
||||||
build/
|
build/
|
||||||
|
|
||||||
|
pgp/keyrings/aptly2*.gpg
|
||||||
|
pgp/keyrings/aptly2*.gpg~
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ addons:
|
|||||||
packages:
|
packages:
|
||||||
- python-virtualenv
|
- python-virtualenv
|
||||||
- graphviz
|
- graphviz
|
||||||
|
- gnupg2
|
||||||
|
- gpgv2
|
||||||
|
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
|
|||||||
+1
-1
@@ -119,7 +119,7 @@ package environment to new version.`,
|
|||||||
cmd.Flag.Bool("dep-verbose-resolve", false, "when processing dependencies, print detailed logs")
|
cmd.Flag.Bool("dep-verbose-resolve", false, "when processing dependencies, print detailed logs")
|
||||||
cmd.Flag.String("architectures", "", "list of architectures to consider during (comma-separated), default to all available")
|
cmd.Flag.String("architectures", "", "list of architectures to consider during (comma-separated), default to all available")
|
||||||
cmd.Flag.String("config", "", "location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf)")
|
cmd.Flag.String("config", "", "location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf)")
|
||||||
cmd.Flag.String("gpg-provider", "", "PGP implementation (\"gpg\" for external gpg or \"internal\" for Go internal implementation)")
|
cmd.Flag.String("gpg-provider", "", "PGP implementation (\"gpg\", \"gpg1\", \"gpg2\" for external gpg or \"internal\" for Go internal implementation)")
|
||||||
|
|
||||||
if aptly.EnableDebug {
|
if aptly.EnableDebug {
|
||||||
cmd.Flag.String("cpuprofile", "", "write cpu profile to file")
|
cmd.Flag.String("cpuprofile", "", "write cpu profile to file")
|
||||||
|
|||||||
+27
-7
@@ -387,23 +387,42 @@ func (context *AptlyContext) pgpProvider() string {
|
|||||||
provider = context.config().GpgProvider
|
provider = context.config().GpgProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(provider == "gpg" || provider == "internal") { // nolint: goconst
|
switch provider {
|
||||||
|
case "gpg": // nolint: goconst
|
||||||
|
case "gpg1": // nolint: goconst
|
||||||
|
case "gpg2": // nolint: goconst
|
||||||
|
case "internal": // nolint: goconst
|
||||||
|
default:
|
||||||
Fatal(fmt.Errorf("unknown gpg provider: %v", provider))
|
Fatal(fmt.Errorf("unknown gpg provider: %v", provider))
|
||||||
}
|
}
|
||||||
|
|
||||||
return provider
|
return provider
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (context *AptlyContext) getGPGFinder(provider string) pgp.GPGFinder {
|
||||||
|
switch context.pgpProvider() {
|
||||||
|
case "gpg1":
|
||||||
|
return pgp.GPG1Finder()
|
||||||
|
case "gpg2":
|
||||||
|
return pgp.GPG2Finder()
|
||||||
|
case "gpg":
|
||||||
|
return pgp.GPGDefaultFinder()
|
||||||
|
}
|
||||||
|
|
||||||
|
panic("uknown GPG provider type")
|
||||||
|
}
|
||||||
|
|
||||||
// GetSigner returns Signer with respect to provider
|
// GetSigner returns Signer with respect to provider
|
||||||
func (context *AptlyContext) GetSigner() pgp.Signer {
|
func (context *AptlyContext) GetSigner() pgp.Signer {
|
||||||
context.Lock()
|
context.Lock()
|
||||||
defer context.Unlock()
|
defer context.Unlock()
|
||||||
|
|
||||||
if context.pgpProvider() == "gpg" { // nolint: goconst
|
provider := context.pgpProvider()
|
||||||
return pgp.NewGpgSigner()
|
if provider == "internal" { // nolint: goconst
|
||||||
|
return &pgp.GoSigner{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pgp.GoSigner{}
|
return pgp.NewGpgSigner(context.getGPGFinder(provider))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVerifier returns Verifier with respect to provider
|
// GetVerifier returns Verifier with respect to provider
|
||||||
@@ -411,11 +430,12 @@ func (context *AptlyContext) GetVerifier() pgp.Verifier {
|
|||||||
context.Lock()
|
context.Lock()
|
||||||
defer context.Unlock()
|
defer context.Unlock()
|
||||||
|
|
||||||
if context.pgpProvider() == "gpg" { // nolint: goconst
|
provider := context.pgpProvider()
|
||||||
return pgp.NewGpgVerifier()
|
if provider == "internal" { // nolint: goconst
|
||||||
|
return &pgp.GoVerifier{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pgp.GoVerifier{}
|
return pgp.NewGpgVerifier(context.getGPGFinder(provider))
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateFlags sets internal copy of flags in the context
|
// UpdateFlags sets internal copy of flags in the context
|
||||||
|
|||||||
+15
-3
@@ -1,7 +1,7 @@
|
|||||||
.\" generated with Ronn/v0.7.3
|
.\" generated with Ronn/v0.7.3
|
||||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||||
.
|
.
|
||||||
.TH "APTLY" "1" "November 2017" "" ""
|
.TH "APTLY" "1" "September 2018" "" ""
|
||||||
.
|
.
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
\fBaptly\fR \- Debian repository management tool
|
\fBaptly\fR \- Debian repository management tool
|
||||||
@@ -150,7 +150,7 @@ don\(cqt verify remote mirrors with gpg(1), also can be disabled on per\-mirror
|
|||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBgpgProvider\fR
|
\fBgpgProvider\fR
|
||||||
implementation of PGP signing/validation \- \fBgpg\fR for external \fBgpg\fR utility or \fBinternal\fR to use Go internal implementation
|
implementation of PGP signing/validation \- \fBgpg\fR for external \fBgpg\fR utility or \fBinternal\fR to use Go internal implementation; \fBgpg1\fR might be used to force use of GnuPG 1\.x, \fBgpg2\fR enables GnuPG 2\.x only; default is to use GnuPG 1\.x if available and GnuPG 2\.x otherwise
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBdownloadSourcePackages\fR
|
\fBdownloadSourcePackages\fR
|
||||||
@@ -434,7 +434,7 @@ when processing dependencies, print detailed logs
|
|||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
\-\fBgpg\-provider\fR=
|
\-\fBgpg\-provider\fR=
|
||||||
PGP implementation ("gpg" for external gpg or "internal" for Go internal implementation)
|
PGP implementation ("gpg", "gpg1", "gpg2" for external gpg or "internal" for Go internal implementation)
|
||||||
.
|
.
|
||||||
.SH "CREATE NEW MIRROR"
|
.SH "CREATE NEW MIRROR"
|
||||||
\fBaptly\fR \fBmirror\fR \fBcreate\fR \fIname\fR \fIarchive url\fR \fIdistribution\fR [\fIcomponent1\fR \|\.\|\.\|\.]
|
\fBaptly\fR \fBmirror\fR \fBcreate\fR \fIname\fR \fIarchive url\fR \fIdistribution\fR [\fIcomponent1\fR \|\.\|\.\|\.]
|
||||||
@@ -2038,5 +2038,17 @@ Matt Martyn (https://github\.com/MMartyn)
|
|||||||
.IP "\[ci]" 4
|
.IP "\[ci]" 4
|
||||||
Ludovico Cavedon (https://github\.com/cavedon)
|
Ludovico Cavedon (https://github\.com/cavedon)
|
||||||
.
|
.
|
||||||
|
.IP "\[ci]" 4
|
||||||
|
Petr Jediny (https://github\.com/pjediny)
|
||||||
|
.
|
||||||
|
.IP "\[ci]" 4
|
||||||
|
Maximilian Stein (https://github\.com/steinymity)
|
||||||
|
.
|
||||||
|
.IP "\[ci]" 4
|
||||||
|
Strajan Sebastian (https://github\.com/strajansebastian)
|
||||||
|
.
|
||||||
|
.IP "\[ci]" 4
|
||||||
|
Artem Smirnov (https://github\.com/urpylka)
|
||||||
|
.
|
||||||
.IP "" 0
|
.IP "" 0
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,9 @@ Options:
|
|||||||
|
|
||||||
* `gpgProvider`:
|
* `gpgProvider`:
|
||||||
implementation of PGP signing/validation - `gpg` for external `gpg` utility or
|
implementation of PGP signing/validation - `gpg` for external `gpg` utility or
|
||||||
`internal` to use Go internal implementation
|
`internal` to use Go internal implementation; `gpg1` might be used to force use
|
||||||
|
of GnuPG 1.x, `gpg2` enables GnuPG 2.x only; default is to use GnuPG 1.x if
|
||||||
|
available and GnuPG 2.x otherwise
|
||||||
|
|
||||||
* `downloadSourcePackages`:
|
* `downloadSourcePackages`:
|
||||||
if enabled, all mirrors created would have flag set to download source packages;
|
if enabled, all mirrors created would have flag set to download source packages;
|
||||||
|
|||||||
+21
-55
@@ -3,6 +3,7 @@ package pgp
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@@ -18,12 +19,10 @@ var (
|
|||||||
_ Verifier = &GpgVerifier{}
|
_ Verifier = &GpgVerifier{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Skip GPG version check for GPG 1.x
|
|
||||||
var skipGPGVersionCheck bool
|
|
||||||
|
|
||||||
// GpgSigner is implementation of Signer interface using gpg as external program
|
// GpgSigner is implementation of Signer interface using gpg as external program
|
||||||
type GpgSigner struct {
|
type GpgSigner struct {
|
||||||
gpg string
|
gpg string
|
||||||
|
version GPGVersion
|
||||||
keyRef string
|
keyRef string
|
||||||
keyring, secretKeyring string
|
keyring, secretKeyring string
|
||||||
passphrase, passphraseFile string
|
passphrase, passphraseFile string
|
||||||
@@ -55,7 +54,7 @@ func (g *GpgSigner) gpgArgs() []string {
|
|||||||
if g.keyring != "" {
|
if g.keyring != "" {
|
||||||
args = append(args, "--no-auto-check-trustdb", "--no-default-keyring", "--keyring", g.keyring)
|
args = append(args, "--no-auto-check-trustdb", "--no-default-keyring", "--keyring", g.keyring)
|
||||||
}
|
}
|
||||||
if g.secretKeyring != "" {
|
if g.secretKeyring != "" && g.version == GPG1x {
|
||||||
args = append(args, "--secret-keyring", g.secretKeyring)
|
args = append(args, "--secret-keyring", g.secretKeyring)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +63,9 @@ func (g *GpgSigner) gpgArgs() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if g.passphrase != "" || g.passphraseFile != "" {
|
if g.passphrase != "" || g.passphraseFile != "" {
|
||||||
args = append(args, "--no-use-agent")
|
if g.version == GPG1x {
|
||||||
|
args = append(args, "--no-use-agent")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if g.passphrase != "" {
|
if g.passphrase != "" {
|
||||||
@@ -77,53 +78,21 @@ func (g *GpgSigner) gpgArgs() []string {
|
|||||||
|
|
||||||
if g.batch {
|
if g.batch {
|
||||||
args = append(args, "--no-tty", "--batch")
|
args = append(args, "--no-tty", "--batch")
|
||||||
|
if g.version == GPG21xPlus {
|
||||||
|
args = append(args, "--pinentry-mode", "loopback")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
func cliVersionCheck(cmd string, marker string) bool {
|
|
||||||
output, err := exec.Command(cmd, "--version").CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return skipGPGVersionCheck || strings.Contains(string(output), marker)
|
|
||||||
}
|
|
||||||
|
|
||||||
func findSuitableCLI(cmds []string, versionMarker string) string {
|
|
||||||
for _, cmd := range cmds {
|
|
||||||
if cliVersionCheck(cmd, versionMarker) {
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// We only support gpg1 at this time. Make sure we find a suitable binary.
|
|
||||||
func findGPG1() (string, error) {
|
|
||||||
cmd := findSuitableCLI([]string{"gpg", "gpg1"}, "gpg (GnuPG) 1.")
|
|
||||||
if cmd != "" {
|
|
||||||
return cmd, nil
|
|
||||||
}
|
|
||||||
return "", fmt.Errorf("Couldn't find a suitable gpg executable. Make sure gnupg1 is available as either gpg or gpg1 in $PATH")
|
|
||||||
}
|
|
||||||
|
|
||||||
// We only support gpgv1 at this time. Make sure we find a suitable binary.
|
|
||||||
func findGPGV1() (string, error) {
|
|
||||||
cmd := findSuitableCLI([]string{"gpgv", "gpgv1"}, "gpgv (GnuPG) 1.")
|
|
||||||
if cmd != "" {
|
|
||||||
return cmd, nil
|
|
||||||
}
|
|
||||||
return "", fmt.Errorf("Couldn't find a suitable gpgv executable. Make sure gpgv1 is available as either gpgv or gpgv1 in $PATH")
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewGpgSigner creates a new gpg signer
|
// NewGpgSigner creates a new gpg signer
|
||||||
func NewGpgSigner() *GpgSigner {
|
func NewGpgSigner(finder GPGFinder) *GpgSigner {
|
||||||
gpg, err := findGPG1()
|
gpg, version, err := finder.FindGPG()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return &GpgSigner{gpg: gpg}
|
return &GpgSigner{gpg: gpg, version: version}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init verifies availability of gpg & presence of keys
|
// Init verifies availability of gpg & presence of keys
|
||||||
@@ -171,22 +140,27 @@ func (g *GpgSigner) ClearSign(source string, destination string) error {
|
|||||||
type GpgVerifier struct {
|
type GpgVerifier struct {
|
||||||
gpg string
|
gpg string
|
||||||
gpgv string
|
gpgv string
|
||||||
|
version GPGVersion
|
||||||
keyRings []string
|
keyRings []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGpgVerifier creates a new gpg verifier
|
// NewGpgVerifier creates a new gpg verifier
|
||||||
func NewGpgVerifier() *GpgVerifier {
|
func NewGpgVerifier(finder GPGFinder) *GpgVerifier {
|
||||||
gpg, err := findGPG1()
|
gpg, versionGPG, err := finder.FindGPG()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
gpgv, err := findGPGV1()
|
gpgv, versionGPGV, err := finder.FindGPGV()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &GpgVerifier{gpg: gpg, gpgv: gpgv}
|
if versionGPG != versionGPGV {
|
||||||
|
panic(errors.New("gpg and gpgv versions don't match"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return &GpgVerifier{gpg: gpg, gpgv: gpgv, version: versionGPG}
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitKeyring verifies that gpg is installed and some keys are trusted
|
// InitKeyring verifies that gpg is installed and some keys are trusted
|
||||||
@@ -417,11 +391,3 @@ func (g *GpgVerifier) ExtractClearsigned(clearsigned io.Reader) (text *os.File,
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
skipCheck := os.Getenv("APTLY_SKIP_GPG_VERSION_CHECK")
|
|
||||||
switch strings.ToLower(skipCheck) {
|
|
||||||
case "1", "y", "yes", "true":
|
|
||||||
skipGPGVersionCheck = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,149 @@
|
|||||||
|
package pgp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GPGVersion stores discovered GPG version
|
||||||
|
type GPGVersion int
|
||||||
|
|
||||||
|
// GPG version as discovered
|
||||||
|
const (
|
||||||
|
GPG1x GPGVersion = 1
|
||||||
|
GPG20x GPGVersion = 2
|
||||||
|
GPG21xPlus GPGVersion = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
var gpgVersionRegex = regexp.MustCompile(`\(GnuPG\) (\d)\.(\d)`)
|
||||||
|
|
||||||
|
// GPGFinder implement search for gpg executables and returns version of discovered executables
|
||||||
|
type GPGFinder interface {
|
||||||
|
FindGPG() (gpg string, version GPGVersion, err error)
|
||||||
|
FindGPGV() (gpgv string, version GPGVersion, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type pathGPGFinder struct {
|
||||||
|
gpgNames []string
|
||||||
|
gpgvNames []string
|
||||||
|
errorMessage string
|
||||||
|
|
||||||
|
expectedVersionSubstring string
|
||||||
|
}
|
||||||
|
|
||||||
|
type iteratingGPGFinder struct {
|
||||||
|
finders []GPGFinder
|
||||||
|
errorMessage string
|
||||||
|
}
|
||||||
|
|
||||||
|
// GPGDefaultFinder looks for GPG1 first, but falls back to GPG2 if GPG1 is not available
|
||||||
|
func GPGDefaultFinder() GPGFinder {
|
||||||
|
return &iteratingGPGFinder{
|
||||||
|
finders: []GPGFinder{GPG1Finder(), GPG2Finder()},
|
||||||
|
errorMessage: "Couldn't find a suitable gpg executable. Make sure gnupg is installed",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GPG1Finder looks for GnuPG1.x only
|
||||||
|
func GPG1Finder() GPGFinder {
|
||||||
|
return &pathGPGFinder{
|
||||||
|
gpgNames: []string{"gpg", "gpg1"},
|
||||||
|
gpgvNames: []string{"gpgv", "gpgv1"},
|
||||||
|
expectedVersionSubstring: "(GnuPG) 1.",
|
||||||
|
errorMessage: "Couldn't find a suitable gpg executable. Make sure gnupg1 is available as either gpg(v) or gpg(v)1 in $PATH",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GPG2Finder looks for GnuPG2.x only
|
||||||
|
func GPG2Finder() GPGFinder {
|
||||||
|
return &pathGPGFinder{
|
||||||
|
gpgNames: []string{"gpg", "gpg2"},
|
||||||
|
gpgvNames: []string{"gpgv", "gpgv2"},
|
||||||
|
expectedVersionSubstring: "(GnuPG) 2.",
|
||||||
|
errorMessage: "Couldn't find a suitable gpg executable. Make sure gnupg2 is available as either gpg(v) or gpg(v)2 in $PATH",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pgf *pathGPGFinder) FindGPG() (gpg string, version GPGVersion, err error) {
|
||||||
|
for _, cmd := range pgf.gpgNames {
|
||||||
|
var result bool
|
||||||
|
result, version = cliVersionCheck(cmd, pgf.expectedVersionSubstring)
|
||||||
|
if result {
|
||||||
|
gpg = cmd
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if gpg == "" {
|
||||||
|
err = errors.New(pgf.errorMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pgf *pathGPGFinder) FindGPGV() (gpgv string, version GPGVersion, err error) {
|
||||||
|
for _, cmd := range pgf.gpgvNames {
|
||||||
|
var result bool
|
||||||
|
result, version = cliVersionCheck(cmd, pgf.expectedVersionSubstring)
|
||||||
|
if result {
|
||||||
|
gpgv = cmd
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if gpgv == "" {
|
||||||
|
err = errors.New(pgf.errorMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *iteratingGPGFinder) FindGPG() (gpg string, version GPGVersion, err error) {
|
||||||
|
for _, finder := range it.finders {
|
||||||
|
gpg, version, err = finder.FindGPG()
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = errors.New(it.errorMessage)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *iteratingGPGFinder) FindGPGV() (gpg string, version GPGVersion, err error) {
|
||||||
|
for _, finder := range it.finders {
|
||||||
|
gpg, version, err = finder.FindGPGV()
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = errors.New(it.errorMessage)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func cliVersionCheck(cmd string, marker string) (result bool, version GPGVersion) {
|
||||||
|
output, err := exec.Command(cmd, "--version").CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
strOutput := string(output)
|
||||||
|
result = strings.Contains(strOutput, marker)
|
||||||
|
|
||||||
|
version = GPG21xPlus
|
||||||
|
matches := gpgVersionRegex.FindStringSubmatch(strOutput)
|
||||||
|
if matches != nil {
|
||||||
|
if matches[1] == "1" {
|
||||||
|
version = GPG1x
|
||||||
|
} else if matches[1] == "2" && matches[2] == "0" {
|
||||||
|
version = GPG20x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
+118
-8
@@ -2,6 +2,7 @@ package pgp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
@@ -26,7 +27,7 @@ func (s *GnupgSuite) TestGPG1(c *C) {
|
|||||||
os.Setenv("PATH", filepath.Join(s.bins, "gpg1"))
|
os.Setenv("PATH", filepath.Join(s.bins, "gpg1"))
|
||||||
defer func() { os.Setenv("PATH", origPath) }()
|
defer func() { os.Setenv("PATH", origPath) }()
|
||||||
|
|
||||||
signer := NewGpgSigner()
|
signer := NewGpgSigner(GPG1Finder())
|
||||||
c.Assert(signer.gpg, Equals, "gpg")
|
c.Assert(signer.gpg, Equals, "gpg")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ func (s *GnupgSuite) TestGPG1Not2(c *C) {
|
|||||||
os.Setenv("PATH", filepath.Join(s.bins, "gpg2-and-1"))
|
os.Setenv("PATH", filepath.Join(s.bins, "gpg2-and-1"))
|
||||||
defer func() { os.Setenv("PATH", origPath) }()
|
defer func() { os.Setenv("PATH", origPath) }()
|
||||||
|
|
||||||
signer := NewGpgSigner()
|
signer := NewGpgSigner(GPG1Finder())
|
||||||
c.Assert(signer.gpg, Equals, "gpg1")
|
c.Assert(signer.gpg, Equals, "gpg1")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ func (s *GnupgSuite) TestGPGNothing(c *C) {
|
|||||||
os.Setenv("PATH", filepath.Join(s.bins, "gpg2-only"))
|
os.Setenv("PATH", filepath.Join(s.bins, "gpg2-only"))
|
||||||
defer func() { os.Setenv("PATH", origPath) }()
|
defer func() { os.Setenv("PATH", origPath) }()
|
||||||
|
|
||||||
c.Assert(func() { NewGpgSigner() }, PanicMatches, `Couldn't find a suitable gpg executable.+`)
|
c.Assert(func() { NewGpgSigner(GPG1Finder()) }, PanicMatches, `Couldn't find a suitable gpg executable.+`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If gpgv == gpgv1 = pick gpgv
|
// If gpgv == gpgv1 = pick gpgv
|
||||||
@@ -55,7 +56,7 @@ func (s *GnupgSuite) TestGPGV1(c *C) {
|
|||||||
os.Setenv("PATH", filepath.Join(s.bins, "gpgv1")+":"+filepath.Join(s.bins, "gpg1"))
|
os.Setenv("PATH", filepath.Join(s.bins, "gpgv1")+":"+filepath.Join(s.bins, "gpg1"))
|
||||||
defer func() { os.Setenv("PATH", origPath) }()
|
defer func() { os.Setenv("PATH", origPath) }()
|
||||||
|
|
||||||
verifier := NewGpgVerifier()
|
verifier := NewGpgVerifier(GPG1Finder())
|
||||||
c.Assert(verifier.gpgv, Equals, "gpgv")
|
c.Assert(verifier.gpgv, Equals, "gpgv")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +66,7 @@ func (s *GnupgSuite) TestGPGV1Not2(c *C) {
|
|||||||
os.Setenv("PATH", filepath.Join(s.bins, "gpgv2-and-1")+":"+filepath.Join(s.bins, "gpg1"))
|
os.Setenv("PATH", filepath.Join(s.bins, "gpgv2-and-1")+":"+filepath.Join(s.bins, "gpg1"))
|
||||||
defer func() { os.Setenv("PATH", origPath) }()
|
defer func() { os.Setenv("PATH", origPath) }()
|
||||||
|
|
||||||
verifier := NewGpgVerifier()
|
verifier := NewGpgVerifier(GPG1Finder())
|
||||||
c.Assert(verifier.gpgv, Equals, "gpgv1")
|
c.Assert(verifier.gpgv, Equals, "gpgv1")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +76,7 @@ func (s *GnupgSuite) TestGPGVNothing(c *C) {
|
|||||||
os.Setenv("PATH", filepath.Join(s.bins, "gpgv2-only")+":"+filepath.Join(s.bins, "gpg1"))
|
os.Setenv("PATH", filepath.Join(s.bins, "gpgv2-only")+":"+filepath.Join(s.bins, "gpg1"))
|
||||||
defer func() { os.Setenv("PATH", origPath) }()
|
defer func() { os.Setenv("PATH", origPath) }()
|
||||||
|
|
||||||
c.Assert(func() { NewGpgVerifier() }, PanicMatches, `Couldn't find a suitable gpgv executable.+`)
|
c.Assert(func() { NewGpgVerifier(GPG1Finder()) }, PanicMatches, `Couldn't find a suitable gpg executable.+`)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Gnupg1VerifierSuite struct {
|
type Gnupg1VerifierSuite struct {
|
||||||
@@ -85,7 +86,13 @@ type Gnupg1VerifierSuite struct {
|
|||||||
var _ = Suite(&Gnupg1VerifierSuite{})
|
var _ = Suite(&Gnupg1VerifierSuite{})
|
||||||
|
|
||||||
func (s *Gnupg1VerifierSuite) SetUpTest(c *C) {
|
func (s *Gnupg1VerifierSuite) SetUpTest(c *C) {
|
||||||
s.verifier = NewGpgVerifier()
|
finder := GPG1Finder()
|
||||||
|
_, _, err := finder.FindGPG()
|
||||||
|
if err != nil {
|
||||||
|
c.Skip(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
s.verifier = NewGpgVerifier(finder)
|
||||||
s.verifier.AddKeyring("./trusted.gpg")
|
s.verifier.AddKeyring("./trusted.gpg")
|
||||||
|
|
||||||
c.Assert(s.verifier.InitKeyring(), IsNil)
|
c.Assert(s.verifier.InitKeyring(), IsNil)
|
||||||
@@ -98,7 +105,18 @@ type Gnupg1SignerSuite struct {
|
|||||||
var _ = Suite(&Gnupg1SignerSuite{})
|
var _ = Suite(&Gnupg1SignerSuite{})
|
||||||
|
|
||||||
func (s *Gnupg1SignerSuite) SetUpTest(c *C) {
|
func (s *Gnupg1SignerSuite) SetUpTest(c *C) {
|
||||||
s.signer = NewGpgSigner()
|
finder := GPG1Finder()
|
||||||
|
_, _, err := finder.FindGPG()
|
||||||
|
if err != nil {
|
||||||
|
c.Skip(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
s.keyringNoPassphrase = [2]string{"keyrings/aptly.pub", "keyrings/aptly.sec"}
|
||||||
|
s.keyringPassphrase = [2]string{"keyrings/aptly_passphrase.pub", "keyrings/aptly_passphrase.sec"}
|
||||||
|
s.passphraseKey = "F30E8CB9CDDE2AF8"
|
||||||
|
s.noPassphraseKey = "21DBB89C16DB3E6D"
|
||||||
|
|
||||||
|
s.signer = NewGpgSigner(finder)
|
||||||
s.signer.SetBatch(true)
|
s.signer.SetBatch(true)
|
||||||
|
|
||||||
s.verifier = &GoVerifier{}
|
s.verifier = &GoVerifier{}
|
||||||
@@ -109,3 +127,95 @@ func (s *Gnupg1SignerSuite) SetUpTest(c *C) {
|
|||||||
|
|
||||||
s.SignerSuite.SetUpTest(c)
|
s.SignerSuite.SetUpTest(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Gnupg2VerifierSuite struct {
|
||||||
|
VerifierSuite
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = Suite(&Gnupg2VerifierSuite{})
|
||||||
|
|
||||||
|
func (s *Gnupg2VerifierSuite) SetUpTest(c *C) {
|
||||||
|
finder := GPG2Finder()
|
||||||
|
_, _, err := finder.FindGPG()
|
||||||
|
if err != nil {
|
||||||
|
c.Skip(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
s.verifier = NewGpgVerifier(finder)
|
||||||
|
s.verifier.AddKeyring("./trusted.gpg")
|
||||||
|
|
||||||
|
c.Assert(s.verifier.InitKeyring(), IsNil)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Gnupg2SignerSuite struct {
|
||||||
|
SignerSuite
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = Suite(&Gnupg2SignerSuite{})
|
||||||
|
|
||||||
|
func (s *Gnupg2SignerSuite) SetUpTest(c *C) {
|
||||||
|
finder := GPG2Finder()
|
||||||
|
gpg, ver, err := finder.FindGPG()
|
||||||
|
if err != nil {
|
||||||
|
c.Skip(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// import private keys into gpg2, they're stored outside of keyring files
|
||||||
|
for _, item := range []struct {
|
||||||
|
suffix string
|
||||||
|
key string
|
||||||
|
}{
|
||||||
|
{"", "751DF85C2B220D45"},
|
||||||
|
{"_passphrase", "6656CD181E92D2D5"},
|
||||||
|
} {
|
||||||
|
if _, err := exec.Command(gpg, "--list-secret-keys", item.key).CombinedOutput(); err == nil {
|
||||||
|
// key already exists
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
args := []string{"--import", "--no-default-keyring"}
|
||||||
|
|
||||||
|
if item.suffix == "_passprhase" {
|
||||||
|
args = append(args, "--passphrase", "verysecret", "--no-tty", "--batch")
|
||||||
|
if ver == GPG21xPlus {
|
||||||
|
args = append(args, "--pinentry-mode", "loopback")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args = append(args, "keyrings/aptly2"+item.suffix+".sec.armor")
|
||||||
|
|
||||||
|
output, err := exec.Command(gpg, args...).CombinedOutput()
|
||||||
|
c.Log(string(output))
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// import public keys into gpg2
|
||||||
|
// we can't use pre-built keyrings as gpg 2.0.x and 2.1+ have different keyring formats
|
||||||
|
for _, suffix := range []string{"", "_passphrase"} {
|
||||||
|
output, err := exec.Command(gpg, "--no-default-keyring", "--keyring", "./keyrings/aptly2"+suffix+".gpg",
|
||||||
|
"--import", "keyrings/aptly2"+suffix+".pub.armor").CombinedOutput()
|
||||||
|
c.Log(string(output))
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.keyringNoPassphrase = [2]string{"./keyrings/aptly2.gpg", ""}
|
||||||
|
s.keyringPassphrase = [2]string{"./keyrings/aptly2_passphrase.gpg", ""}
|
||||||
|
s.noPassphraseKey = "751DF85C2B220D45"
|
||||||
|
s.passphraseKey = "6656CD181E92D2D5"
|
||||||
|
|
||||||
|
s.signer = NewGpgSigner(finder)
|
||||||
|
s.signer.SetBatch(true)
|
||||||
|
|
||||||
|
s.verifier = &GoVerifier{}
|
||||||
|
s.verifier.AddKeyring("./keyrings/aptly2_trusted.pub")
|
||||||
|
|
||||||
|
c.Assert(s.verifier.InitKeyring(), IsNil)
|
||||||
|
|
||||||
|
s.SignerSuite.SetUpTest(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Gnupg2SignerSuite) TearDownTest(c *C) {
|
||||||
|
s.SignerSuite.TearDownTest(c)
|
||||||
|
|
||||||
|
os.Remove("./keyrings/aptly2.gpg")
|
||||||
|
os.Remove("./keyrings/aptly2_passphrase.gpg")
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ type GoSignerSuite struct {
|
|||||||
var _ = Suite(&GoSignerSuite{})
|
var _ = Suite(&GoSignerSuite{})
|
||||||
|
|
||||||
func (s *GoSignerSuite) SetUpTest(c *C) {
|
func (s *GoSignerSuite) SetUpTest(c *C) {
|
||||||
|
s.keyringNoPassphrase = [2]string{"keyrings/aptly.pub", "keyrings/aptly.sec"}
|
||||||
|
s.keyringPassphrase = [2]string{"keyrings/aptly_passphrase.pub", "keyrings/aptly_passphrase.sec"}
|
||||||
|
s.passphraseKey = "F30E8CB9CDDE2AF8"
|
||||||
|
s.noPassphraseKey = "21DBB89C16DB3E6D"
|
||||||
|
|
||||||
s.signer = &GoSigner{}
|
s.signer = &GoSigner{}
|
||||||
s.signer.SetBatch(true)
|
s.signer.SetBatch(true)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
mQENBFuAfvMBCACuElVMZctaYEMSIoYLAefC2ygH/MUWA41h/MT/kMakexK7B2N/
|
||||||
|
noPUhA0Z7xWiqxnvJqaOGuT2Bp2SSOuw8hXD870VMNNAVuvg63Zvj5DGhWAjR8Sm
|
||||||
|
zHaZ09+hkD+MB7+WJnyDJb0deGpJ7cFaUgS4fz1BlTWHpJX8wMBi3iqA2tulcoNn
|
||||||
|
L/pUomusNGiD+4TuWkEeYb3/ygXvfocuE0Ji7UFrijU4Dcrh7T7L7qzHDMy8hyEr
|
||||||
|
t3oZlFDlwRkr+1LrT1QBnndaddPRt1h3Av59WpasTUC8m/It0NvLpq9mqij3TNTx
|
||||||
|
OyZNJLqHrUsz1/cg3boiT4puY8gm2jpQpNLXABEBAAG0HkFwdGx5IFRlc3RlciA8
|
||||||
|
dGVzdEBhcHRseS5pbmZvPokBTgQTAQgAOBYhBOivfuFBYsLWPPwa1XUd+FwrIg1F
|
||||||
|
BQJbgH7zAhsDBQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEHUd+FwrIg1FWRwH
|
||||||
|
/RmXNwgh6DEj7wN7hILL15iXOrOIjEJ2GH0cWvPdyzc/qbL552QovcaK3yb/r3V+
|
||||||
|
+1wDJ2CuBtc/CoVFq1CN/i92wIDl+Cuozny5qcd8O6EjgdmLgeANRwqyMjiPiDz9
|
||||||
|
cuabD3JPRHIqEv26PQ+qkmad42E5mipHmbA+iOE9OEWSvhDudAlYzNXECUWlNQ9+
|
||||||
|
gWnLB6hONz5jnRDZHpcKeBcQ2aJ7r5L6qDzBIybAu3jiZfl5KlT6hArXi5vDi8DK
|
||||||
|
B5is80nWPTAEb2+CfBiY80mLScNe5jG/sgOOrTqWL681RfjRtTnRe7DFKIm8guqp
|
||||||
|
tbYrv4OzkFHJ/JbWAKsBruS5AQ0EW4B+8wEIANWaf4BWY2or9oyu001EmIdFiwu2
|
||||||
|
cxGA2y8bZiqmerk+2BXDEZN4OaLu1a9RWpwo1Mc+KuXpeJNv60SG0zRFBLVrvPyg
|
||||||
|
irhaue1p+SSuisxMdTOZrciYjWriTU4WKw+NOdiGHr5LJegE9hvW66ZYJHtYgkfB
|
||||||
|
mBuIQQ90h6qnXKGtV4FK8Fo+hr04Wh7gDGZxTRFNo3MO0a18Y87uiU5j8i/VxyfI
|
||||||
|
DSA2Uh92kPbItuEKtl23PhCSecZa4YkkWMILS7frMEbM9wDK/JFqPVPSUwQhV5jn
|
||||||
|
wwq9hwQrUimrhZjJn1EImK2QVYeJ1CVxc3K7bdlxPd8fi6zfTQ8AfpALDWkAEQEA
|
||||||
|
AYkBNgQYAQgAIBYhBOivfuFBYsLWPPwa1XUd+FwrIg1FBQJbgH7zAhsMAAoJEHUd
|
||||||
|
+FwrIg1FzpEH/2xi/DCaYRgbC4RrICebeC8FBTwI2RyBuOQJr5CIPrpWaWV4+5Ds
|
||||||
|
sIgPxU9E3QgNRjP9pzAzH2Z8WwJtRY0oYNWLFruNeg9Xl1Tf9pCK/0Csamyf/h3F
|
||||||
|
6NKfDTwNBWTsD5ttNyRx2nfDPaU4j2BZqU3kOzdwiXnmtvtxEoH059EMgQFLv91W
|
||||||
|
U7NydHYd8xcWlHIZx1uFB8HKRWB+AMXebkdLVXlUtJfZfxZr5Jb5eR77ojfsduYI
|
||||||
|
YmbV4jkDxuidSkYogYyXMO2jY2PAhx29iaZrDsNdsCsg8OmwEjCPEGWdp7tFA1QI
|
||||||
|
JrGSOnwXujoUwuqh53+n3bcVuuuKyPBW9b4=
|
||||||
|
=Tu5z
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
=vqFY
|
||||||
|
-----END PGP PRIVATE KEY BLOCK-----
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
mQENBFuAgf0BCADhVDnKyR5G6RzgFb7QseLqOzjvGotmbYYTuYinwLC+GGgOBD54
|
||||||
|
DTtzBk6PmU1/QW7x0yvffyeQWUXD+/zIuBLrkG2QXv9qRdADH6rCsVChtVsTRwHT
|
||||||
|
ZgJJXgfcjsZ2UUDQ43Jkb4dMaAIJTS0dASXgyLIRaN/1h4SsdKZUZY16lMH9kSxb
|
||||||
|
XI86qujCdC9WS7CWu8sLX7qKqmmAt8fTGTnTgyQCnIYtS1/je0ZfX4Z3ovzYyajJ
|
||||||
|
LA/jtCD6L+3qj9Y7desj1AvNKRCGYB8nzayYYVqozNFvlubDePinFqJThrICviNS
|
||||||
|
cNZuNmZjToPmSMF/B6zz1CkrR6Q0CIM5zkuxABEBAAG0HkFwdGx5IFRlc3RlciA8
|
||||||
|
dGVzdEBhcHRseS5pbmZvPokBTgQTAQgAOBYhBAvV0vLk0JvPtsmaFGZWzRgektLV
|
||||||
|
BQJbgIH9AhsDBQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEGZWzRgektLVAHoH
|
||||||
|
/jwdhMCDmgBR3vhS/i7ym5HFUx7o1cCv0cSoGQwgnRGLrTG4Ua4ds+FxAKjNAspC
|
||||||
|
hgxGGfTCmD1cYB4lx85I0XcpfT4ZA0ZCQ1I9m5/AJ9WWYoy2FFZNxZ7fCd2d+sm1
|
||||||
|
ydyJLCTRgJd0D2MD58vxF2+IWAkZTOridyyZP1qxfzcnSACTjbcrQFc1Bp7G1xJR
|
||||||
|
T135mcxtBSD2JeXbvq/UkeOE+LCIF5EIHUlwOdanyyHTyO86R2rU7qO0bylNyLGi
|
||||||
|
0SE3Y+j+qhg6Ns4I2SPo0JDBDrSVfPKcob1DYFF0K1yH6Cj3aGVUthsahNrP3K9S
|
||||||
|
NOVRC1JUg5an0eWcayIPpte5AQ0EW4CB/QEIAMrLVpvc2Syuhtov6mBTuIB9SUHy
|
||||||
|
9tyqK6WhyDAB7iQPC5Xrb4GXHM4z+2Vt7Pgabr630B6ySsmrKNfDB1EcUcY4aJ5Q
|
||||||
|
LBIttR25CB8PkmvllycjKp49hLXOruwx6t23/J3REyapQXLKpXDhzmMTmoGpAPcu
|
||||||
|
YTVMiiOFi0MNBI5ok9iQoG9Dbgf7F0Ie1MiLJzqfaf2dlRuh2JBayIMJ9VrtlThB
|
||||||
|
5v2CsV73Mj7EgE7oetZgH2I9Tl/2vv70VYnoXn/YL2xgfghWWlTvDTvg9s7sRnDI
|
||||||
|
4oor7SHaRZIWxqSuvVOchnlBjLADn902bFIPEanqBiAnPAHPwPOMKnBoR78AEQEA
|
||||||
|
AYkBNgQYAQgAIBYhBAvV0vLk0JvPtsmaFGZWzRgektLVBQJbgIH9AhsMAAoJEGZW
|
||||||
|
zRgektLVetQH/1QiJqu6JmEbJ4Z8mmwr25iqeC/9G1Llo6q4VAoLFygFU1EVW+wX
|
||||||
|
tPwz5RZpqoZ5K4NVFJcgLH1ExqgKW9MflPK+6ltYqH3Kgg73I5gnP9SX12hJ3oMZ
|
||||||
|
X15uGm8pN+na4fcu9rwvk87EBfXXmtP9oqdCPZ49DtkngyahTXFK/h5CbcgCx1Fw
|
||||||
|
rm1QXyH/sB8O3f6GOVly40u7CV0hzWAB98KLgEP093OI3AJjmINxErCt6cigxQzO
|
||||||
|
jgbiTMVgLKHidnpeOcKNXIlmIBFpBM4oaKFZ0qt5jiKz/QtmX7Uj+rTfCjaC1G7f
|
||||||
|
fGE72fE3nL5TcbwRyD7g9zRV3ddU5uvCnlg=
|
||||||
|
=075D
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
bt98YTvZ8TecvlNxvBHIPuD3NFXd11Tm68KeWA==
|
||||||
|
=YDL1
|
||||||
|
-----END PGP PRIVATE KEY BLOCK-----
|
||||||
Binary file not shown.
+21
-9
@@ -20,6 +20,12 @@ type SignerSuite struct {
|
|||||||
cleartext []byte
|
cleartext []byte
|
||||||
|
|
||||||
passwordFile string
|
passwordFile string
|
||||||
|
|
||||||
|
keyringNoPassphrase [2]string
|
||||||
|
keyringPassphrase [2]string
|
||||||
|
|
||||||
|
noPassphraseKey Key
|
||||||
|
passphraseKey Key
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignerSuite) SetUpTest(c *C) {
|
func (s *SignerSuite) SetUpTest(c *C) {
|
||||||
@@ -70,20 +76,23 @@ func (s *SignerSuite) testSignDetached(c *C) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignerSuite) TestSignDetachedNoPassphrase(c *C) {
|
func (s *SignerSuite) TestSignDetachedNoPassphrase(c *C) {
|
||||||
s.signer.SetKeyRing("keyrings/aptly.pub", "keyrings/aptly.sec")
|
s.signer.SetKey(string(s.noPassphraseKey))
|
||||||
|
s.signer.SetKeyRing(s.keyringNoPassphrase[0], s.keyringNoPassphrase[1])
|
||||||
|
|
||||||
s.testSignDetached(c)
|
s.testSignDetached(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignerSuite) TestSignDetachedPassphrase(c *C) {
|
func (s *SignerSuite) TestSignDetachedPassphrase(c *C) {
|
||||||
s.signer.SetKeyRing("keyrings/aptly_passphrase.pub", "keyrings/aptly_passphrase.sec")
|
s.signer.SetKey(string(s.passphraseKey))
|
||||||
|
s.signer.SetKeyRing(s.keyringPassphrase[0], s.keyringPassphrase[1])
|
||||||
s.signer.SetPassphrase("verysecret", "")
|
s.signer.SetPassphrase("verysecret", "")
|
||||||
|
|
||||||
s.testSignDetached(c)
|
s.testSignDetached(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignerSuite) TestSignDetachedPassphraseFile(c *C) {
|
func (s *SignerSuite) TestSignDetachedPassphraseFile(c *C) {
|
||||||
s.signer.SetKeyRing("keyrings/aptly_passphrase.pub", "keyrings/aptly_passphrase.sec")
|
s.signer.SetKey(string(s.passphraseKey))
|
||||||
|
s.signer.SetKeyRing(s.keyringPassphrase[0], s.keyringPassphrase[1])
|
||||||
s.signer.SetPassphrase("", s.passwordFile)
|
s.signer.SetPassphrase("", s.passwordFile)
|
||||||
|
|
||||||
s.testSignDetached(c)
|
s.testSignDetached(c)
|
||||||
@@ -114,21 +123,24 @@ func (s *SignerSuite) testClearSign(c *C, expectedKey Key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignerSuite) TestClearSignNoPassphrase(c *C) {
|
func (s *SignerSuite) TestClearSignNoPassphrase(c *C) {
|
||||||
s.signer.SetKeyRing("keyrings/aptly.pub", "keyrings/aptly.sec")
|
s.signer.SetKey(string(s.noPassphraseKey))
|
||||||
|
s.signer.SetKeyRing(s.keyringNoPassphrase[0], s.keyringNoPassphrase[1])
|
||||||
|
|
||||||
s.testClearSign(c, "21DBB89C16DB3E6D")
|
s.testClearSign(c, s.noPassphraseKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignerSuite) TestClearSignPassphrase(c *C) {
|
func (s *SignerSuite) TestClearSignPassphrase(c *C) {
|
||||||
s.signer.SetKeyRing("keyrings/aptly_passphrase.pub", "keyrings/aptly_passphrase.sec")
|
s.signer.SetKey(string(s.passphraseKey))
|
||||||
|
s.signer.SetKeyRing(s.keyringPassphrase[0], s.keyringPassphrase[1])
|
||||||
s.signer.SetPassphrase("verysecret", "")
|
s.signer.SetPassphrase("verysecret", "")
|
||||||
|
|
||||||
s.testClearSign(c, "F30E8CB9CDDE2AF8")
|
s.testClearSign(c, s.passphraseKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignerSuite) TestClearSignPassphraseFile(c *C) {
|
func (s *SignerSuite) TestClearSignPassphraseFile(c *C) {
|
||||||
s.signer.SetKeyRing("keyrings/aptly_passphrase.pub", "keyrings/aptly_passphrase.sec")
|
s.signer.SetKey(string(s.passphraseKey))
|
||||||
|
s.signer.SetKeyRing(s.keyringPassphrase[0], s.keyringPassphrase[1])
|
||||||
s.signer.SetPassphrase("", s.passwordFile)
|
s.signer.SetPassphrase("", s.passwordFile)
|
||||||
|
|
||||||
s.testClearSign(c, "F30E8CB9CDDE2AF8")
|
s.testClearSign(c, s.passphraseKey)
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-1
@@ -142,7 +142,16 @@ class BaseTest(object):
|
|||||||
self.fixtureWebServer))
|
self.fixtureWebServer))
|
||||||
|
|
||||||
if self.fixtureGpg:
|
if self.fixtureGpg:
|
||||||
self.run_cmd(["gpg", "--no-default-keyring", "--trust-model", "always", "--batch", "--keyring", "aptlytest.gpg", "--import"] +
|
# try to find gpg1 as that's what aptly prefers by default to build trusted keys in DB
|
||||||
|
# in lowest supported format
|
||||||
|
gpg = "gpg1"
|
||||||
|
try:
|
||||||
|
subprocess.check_output(["gpg1", "--version"])
|
||||||
|
except Exception:
|
||||||
|
gpg = "gpg"
|
||||||
|
|
||||||
|
# TODO: fixme
|
||||||
|
self.run_cmd([gpg, "--no-default-keyring", "--trust-model", "always", "--batch", "--keyring", "aptlytest.gpg", "--import"] +
|
||||||
[os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", key) for key in self.fixtureGpgKeys])
|
[os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", key) for key in self.fixtureGpgKeys])
|
||||||
|
|
||||||
if hasattr(self, "fixtureCmds"):
|
if hasattr(self, "fixtureCmds"):
|
||||||
|
|||||||
@@ -19,5 +19,5 @@ Options:
|
|||||||
-dep-follow-source: when processing dependencies, follow from binary to Source packages
|
-dep-follow-source: when processing dependencies, follow from binary to Source packages
|
||||||
-dep-follow-suggests: when processing dependencies, follow Suggests
|
-dep-follow-suggests: when processing dependencies, follow Suggests
|
||||||
-dep-verbose-resolve: when processing dependencies, print detailed logs
|
-dep-verbose-resolve: when processing dependencies, print detailed logs
|
||||||
-gpg-provider="": PGP implementation ("gpg" for external gpg or "internal" for Go internal implementation)
|
-gpg-provider="": PGP implementation ("gpg", "gpg1", "gpg2" for external gpg or "internal" for Go internal implementation)
|
||||||
|
|
||||||
|
|||||||
@@ -27,5 +27,5 @@ Options:
|
|||||||
-dep-follow-source: when processing dependencies, follow from binary to Source packages
|
-dep-follow-source: when processing dependencies, follow from binary to Source packages
|
||||||
-dep-follow-suggests: when processing dependencies, follow Suggests
|
-dep-follow-suggests: when processing dependencies, follow Suggests
|
||||||
-dep-verbose-resolve: when processing dependencies, print detailed logs
|
-dep-verbose-resolve: when processing dependencies, print detailed logs
|
||||||
-gpg-provider="": PGP implementation ("gpg" for external gpg or "internal" for Go internal implementation)
|
-gpg-provider="": PGP implementation ("gpg", "gpg1", "gpg2" for external gpg or "internal" for Go internal implementation)
|
||||||
ERROR: unable to parse command
|
ERROR: unable to parse command
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Options:
|
|||||||
-filter-with-deps: when filtering, include dependencies of matching packages as well
|
-filter-with-deps: when filtering, include dependencies of matching packages as well
|
||||||
-force-architectures: (only with architecture list) skip check that requested architectures are listed in Release file
|
-force-architectures: (only with architecture list) skip check that requested architectures are listed in Release file
|
||||||
-force-components: (only with component list) skip check that requested components are listed in Release file
|
-force-components: (only with component list) skip check that requested components are listed in Release file
|
||||||
-gpg-provider="": PGP implementation ("gpg" for external gpg or "internal" for Go internal implementation)
|
-gpg-provider="": PGP implementation ("gpg", "gpg1", "gpg2" for external gpg or "internal" for Go internal implementation)
|
||||||
-ignore-signatures: disable verification of Release file signatures
|
-ignore-signatures: disable verification of Release file signatures
|
||||||
-keyring=: gpg keyring to use when verifying Release file (could be specified multiple times)
|
-keyring=: gpg keyring to use when verifying Release file (could be specified multiple times)
|
||||||
-with-installer: download additional not packaged installer files
|
-with-installer: download additional not packaged installer files
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Options:
|
|||||||
-filter-with-deps: when filtering, include dependencies of matching packages as well
|
-filter-with-deps: when filtering, include dependencies of matching packages as well
|
||||||
-force-architectures: (only with architecture list) skip check that requested architectures are listed in Release file
|
-force-architectures: (only with architecture list) skip check that requested architectures are listed in Release file
|
||||||
-force-components: (only with component list) skip check that requested components are listed in Release file
|
-force-components: (only with component list) skip check that requested components are listed in Release file
|
||||||
-gpg-provider="": PGP implementation ("gpg" for external gpg or "internal" for Go internal implementation)
|
-gpg-provider="": PGP implementation ("gpg", "gpg1", "gpg2" for external gpg or "internal" for Go internal implementation)
|
||||||
-ignore-signatures: disable verification of Release file signatures
|
-ignore-signatures: disable verification of Release file signatures
|
||||||
-keyring=: gpg keyring to use when verifying Release file (could be specified multiple times)
|
-keyring=: gpg keyring to use when verifying Release file (could be specified multiple times)
|
||||||
-with-installer: download additional not packaged installer files
|
-with-installer: download additional not packaged installer files
|
||||||
|
|||||||
@@ -23,4 +23,4 @@ Options:
|
|||||||
-dep-follow-source: when processing dependencies, follow from binary to Source packages
|
-dep-follow-source: when processing dependencies, follow from binary to Source packages
|
||||||
-dep-follow-suggests: when processing dependencies, follow Suggests
|
-dep-follow-suggests: when processing dependencies, follow Suggests
|
||||||
-dep-verbose-resolve: when processing dependencies, print detailed logs
|
-dep-verbose-resolve: when processing dependencies, print detailed logs
|
||||||
-gpg-provider="": PGP implementation ("gpg" for external gpg or "internal" for Go internal implementation)
|
-gpg-provider="": PGP implementation ("gpg", "gpg1", "gpg2" for external gpg or "internal" for Go internal implementation)
|
||||||
|
|||||||
@@ -23,5 +23,5 @@ Options:
|
|||||||
-dep-follow-source: when processing dependencies, follow from binary to Source packages
|
-dep-follow-source: when processing dependencies, follow from binary to Source packages
|
||||||
-dep-follow-suggests: when processing dependencies, follow Suggests
|
-dep-follow-suggests: when processing dependencies, follow Suggests
|
||||||
-dep-verbose-resolve: when processing dependencies, print detailed logs
|
-dep-verbose-resolve: when processing dependencies, print detailed logs
|
||||||
-gpg-provider="": PGP implementation ("gpg" for external gpg or "internal" for Go internal implementation)
|
-gpg-provider="": PGP implementation ("gpg", "gpg1", "gpg2" for external gpg or "internal" for Go internal implementation)
|
||||||
ERROR: unable to parse command
|
ERROR: unable to parse command
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ Options:
|
|||||||
-filter-with-deps: when filtering, include dependencies of matching packages as well
|
-filter-with-deps: when filtering, include dependencies of matching packages as well
|
||||||
-force-architectures: (only with architecture list) skip check that requested architectures are listed in Release file
|
-force-architectures: (only with architecture list) skip check that requested architectures are listed in Release file
|
||||||
-force-components: (only with component list) skip check that requested components are listed in Release file
|
-force-components: (only with component list) skip check that requested components are listed in Release file
|
||||||
-gpg-provider="": PGP implementation ("gpg" for external gpg or "internal" for Go internal implementation)
|
-gpg-provider="": PGP implementation ("gpg", "gpg1", "gpg2" for external gpg or "internal" for Go internal implementation)
|
||||||
-ignore-signatures: disable verification of Release file signatures
|
-ignore-signatures: disable verification of Release file signatures
|
||||||
-keyring=: gpg keyring to use when verifying Release file (could be specified multiple times)
|
-keyring=: gpg keyring to use when verifying Release file (could be specified multiple times)
|
||||||
-with-installer: download additional not packaged installer files
|
-with-installer: download additional not packaged installer files
|
||||||
|
|||||||
Reference in New Issue
Block a user