mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-05-30 04:20:53 +00:00
Refactor Changes structure, new method prepare to verify checksums and copy files. #71
This commit is contained in:
+94
-19
@@ -3,39 +3,66 @@ package deb
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/smira/aptly/utils"
|
"github.com/smira/aptly/utils"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Changes is a result of .changes file parsing
|
// Changes is a result of .changes file parsing
|
||||||
type Changes struct {
|
type Changes struct {
|
||||||
Changes string
|
Changes string
|
||||||
Distribution string
|
Distribution string
|
||||||
Files PackageFiles
|
Files PackageFiles
|
||||||
|
BasePath, ChangesName string
|
||||||
|
TempDir string
|
||||||
|
Stanza Stanza
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseChangesFile does optional signature verification and parses changes files
|
func NewChanges(path string) (*Changes, error) {
|
||||||
func ParseChangesFile(path string, acceptUnsigned, ignoreSignature bool, verifier utils.Verifier) (*Changes, error) {
|
var err error
|
||||||
input, err := os.Open(path)
|
|
||||||
|
c := &Changes{
|
||||||
|
BasePath: filepath.Dir(path),
|
||||||
|
ChangesName: filepath.Base(path),
|
||||||
|
}
|
||||||
|
|
||||||
|
c.TempDir, err = ioutil.TempDir(os.TempDir(), "aptly")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy .changes file into temporary directory
|
||||||
|
err = utils.CopyFile(filepath.Join(c.BasePath, c.ChangesName), filepath.Join(c.TempDir, c.ChangesName))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifyAndParse does optional signature verification and parses changes files
|
||||||
|
func (c *Changes) VerifyAndParse(acceptUnsigned, ignoreSignature bool, verifier utils.Verifier) error {
|
||||||
|
input, err := os.Open(filepath.Join(c.TempDir, c.ChangesName))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
defer input.Close()
|
defer input.Close()
|
||||||
|
|
||||||
isClearSigned, err := verifier.IsClearSigned(input)
|
isClearSigned, err := verifier.IsClearSigned(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
input.Seek(0, 0)
|
input.Seek(0, 0)
|
||||||
|
|
||||||
if !isClearSigned && !acceptUnsigned {
|
if !isClearSigned && !acceptUnsigned {
|
||||||
return nil, fmt.Errorf(".changes file is not signed and unsigned processing hasn't been enabled")
|
return fmt.Errorf(".changes file is not signed and unsigned processing hasn't been enabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
if isClearSigned && !ignoreSignature {
|
if isClearSigned && !ignoreSignature {
|
||||||
err = verifier.VerifyClearsigned(input)
|
err = verifier.VerifyClearsigned(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
input.Seek(0, 0)
|
input.Seek(0, 0)
|
||||||
}
|
}
|
||||||
@@ -45,7 +72,7 @@ func ParseChangesFile(path string, acceptUnsigned, ignoreSignature bool, verifie
|
|||||||
if isClearSigned {
|
if isClearSigned {
|
||||||
text, err = verifier.ExtractClearsigned(input)
|
text, err = verifier.ExtractClearsigned(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
defer text.Close()
|
defer text.Close()
|
||||||
} else {
|
} else {
|
||||||
@@ -53,20 +80,68 @@ func ParseChangesFile(path string, acceptUnsigned, ignoreSignature bool, verifie
|
|||||||
}
|
}
|
||||||
|
|
||||||
reader := NewControlFileReader(text)
|
reader := NewControlFileReader(text)
|
||||||
stanza, err := reader.ReadStanza()
|
c.Stanza, err = reader.ReadStanza()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := &Changes{
|
c.Distribution = c.Stanza["Distribution"]
|
||||||
Distribution: stanza["Distribution"],
|
c.Changes = c.Stanza["Changes"]
|
||||||
Changes: stanza["Changes"],
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Files, err = result.Files.ParseSumFields(stanza)
|
c.Files, err = c.Files.ParseSumFields(c.Stanza)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare creates temporary directory, copies file there and verifies checksums
|
||||||
|
func (c *Changes) Prepare() error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
for _, file := range c.Files {
|
||||||
|
if filepath.Dir(file.Filename) != "." {
|
||||||
|
return fmt.Errorf("file is not in the same folder as .changes file: %s", file.Filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
file.Filename = filepath.Base(file.Filename)
|
||||||
|
|
||||||
|
err = utils.CopyFile(filepath.Join(c.BasePath, file.Filename), filepath.Join(c.TempDir, file.Filename))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range c.Files {
|
||||||
|
var info utils.ChecksumInfo
|
||||||
|
|
||||||
|
info, err = utils.ChecksumsForFile(filepath.Join(c.TempDir, file.Filename))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.MD5 != file.Checksums.MD5 {
|
||||||
|
return fmt.Errorf("checksum mismatch MD5: expected %v != obtained %v", file.Checksums.MD5, info.MD5)
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.SHA1 != file.Checksums.SHA1 {
|
||||||
|
return fmt.Errorf("checksum mismatch SHA1: expected %v != obtained %v", file.Checksums.SHA1, info.SHA1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.SHA256 != file.Checksums.SHA256 {
|
||||||
|
return fmt.Errorf("checksum mismatch SHA256 expected %v != obtained %v", file.Checksums.SHA256, info.SHA256)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup removes all temporary files
|
||||||
|
func (c *Changes) Cleanup() error {
|
||||||
|
if c.TempDir == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return os.RemoveAll(c.TempDir)
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -11,7 +11,7 @@ type ChangesSuite struct {
|
|||||||
|
|
||||||
var _ = Suite(&ChangesSuite{})
|
var _ = Suite(&ChangesSuite{})
|
||||||
|
|
||||||
func (s *ChangesSuite) TestParseChanges(c *C) {
|
func (s *ChangesSuite) TestParseAndVerify(c *C) {
|
||||||
dir := c.MkDir()
|
dir := c.MkDir()
|
||||||
path := filepath.Join(dir, "calamares.changes")
|
path := filepath.Join(dir, "calamares.changes")
|
||||||
|
|
||||||
@@ -21,7 +21,10 @@ func (s *ChangesSuite) TestParseChanges(c *C) {
|
|||||||
f.WriteString(changesFile)
|
f.WriteString(changesFile)
|
||||||
f.Close()
|
f.Close()
|
||||||
|
|
||||||
changes, err := ParseChangesFile(path, true, true, &NullVerifier{})
|
changes, err := NewChanges(path)
|
||||||
|
c.Check(err, IsNil)
|
||||||
|
|
||||||
|
err = changes.VerifyAndParse(true, true, &NullVerifier{})
|
||||||
c.Check(err, IsNil)
|
c.Check(err, IsNil)
|
||||||
|
|
||||||
c.Check(changes.Distribution, Equals, "sid")
|
c.Check(changes.Distribution, Equals, "sid")
|
||||||
@@ -31,6 +34,7 @@ func (s *ChangesSuite) TestParseChanges(c *C) {
|
|||||||
c.Check(changes.Files[0].Checksums.MD5, Equals, "05fd8f3ffe8f362c5ef9bad2f936a56e")
|
c.Check(changes.Files[0].Checksums.MD5, Equals, "05fd8f3ffe8f362c5ef9bad2f936a56e")
|
||||||
c.Check(changes.Files[0].Checksums.SHA1, Equals, "79f10e955dab6eb25b7f7bae18213f367a3a0396")
|
c.Check(changes.Files[0].Checksums.SHA1, Equals, "79f10e955dab6eb25b7f7bae18213f367a3a0396")
|
||||||
c.Check(changes.Files[0].Checksums.SHA256, Equals, "35b3280a7b1ffe159a276128cb5c408d687318f60ecbb8ab6dedb2e49c4e82dc")
|
c.Check(changes.Files[0].Checksums.SHA256, Equals, "35b3280a7b1ffe159a276128cb5c408d687318f60ecbb8ab6dedb2e49c4e82dc")
|
||||||
|
c.Check(changes.BasePath, Equals, dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
var changesFile = `Format: 1.8
|
var changesFile = `Format: 1.8
|
||||||
|
|||||||
Reference in New Issue
Block a user