refactor: Decompose fetch func

This commit is contained in:
Felix Pojtinger
2021-12-06 22:15:28 +01:00
parent fdafd1a57a
commit 7ac5346ec0
15 changed files with 746 additions and 645 deletions
+11 -1
View File
@@ -3,6 +3,16 @@ package config
import "errors"
var (
ErrUnsupportedEncryptionFormat = errors.New("unsupported encryption format")
ErrUnsupportedCompressionFormat = errors.New("unsupported compression format")
ErrUnsupportedEncryptionFormat = errors.New("unsupported encryption format")
ErrUnsupportedSignatureFormat = errors.New("unsupported signature format")
ErrIdentityUnparsable = errors.New("recipient could not be parsed")
ErrRecipientUnparsable = errors.New("recipient could not be parsed")
ErrEmbeddedHeaderMissing = errors.New("embedded header is missing")
ErrSignatureFormatOnlyRegularSupport = errors.New("this signature format only supports regular files, not i.e. tape drives")
ErrSignatureInvalid = errors.New("signature invalid")
ErrSignatureMissing = errors.New("signature missing")
)
+138 -1
View File
@@ -1,6 +1,19 @@
package recovery
import (
"archive/tar"
"bufio"
"io"
"os"
"path/filepath"
"github.com/pojntfx/stfs/internal/compression"
"github.com/pojntfx/stfs/internal/controllers"
"github.com/pojntfx/stfs/internal/encryption"
"github.com/pojntfx/stfs/internal/formatting"
"github.com/pojntfx/stfs/internal/pax"
"github.com/pojntfx/stfs/internal/signature"
"github.com/pojntfx/stfs/internal/tape"
"github.com/pojntfx/stfs/pkg/config"
)
@@ -13,7 +26,131 @@ func Fetch(
record int,
block int,
to string,
preview string,
preview bool,
showHeader bool,
) error {
f, isRegular, err := tape.OpenTapeReadOnly(state.Drive)
if err != nil {
return err
}
defer f.Close()
var tr *tar.Reader
if isRegular {
// Seek to record and block
if _, err := f.Seek(int64((recordSize*controllers.BlockSize*record)+block*controllers.BlockSize), io.SeekStart); err != nil {
return err
}
tr = tar.NewReader(f)
} else {
// Seek to record
if err := controllers.SeekToRecordOnTape(f, int32(record)); err != nil {
return err
}
// Seek to block
br := bufio.NewReaderSize(f, controllers.BlockSize*recordSize)
if _, err := br.Read(make([]byte, block*controllers.BlockSize)); err != nil {
return err
}
tr = tar.NewReader(br)
}
hdr, err := tr.Next()
if err != nil {
return err
}
if err := encryption.DecryptHeader(hdr, pipes.Encryption, crypto.Identity); err != nil {
return err
}
if err := signature.VerifyHeader(hdr, isRegular, pipes.Signature, crypto.Recipient); err != nil {
return err
}
if showHeader {
if err := formatting.PrintCSV(formatting.TARHeaderCSV); err != nil {
return err
}
if err := formatting.PrintCSV(formatting.GetTARHeaderAsCSV(int64(record), int64(block), hdr)); err != nil {
return err
}
}
if !preview {
if to == "" {
to = filepath.Base(hdr.Name)
}
if hdr.Typeflag == tar.TypeDir {
return os.MkdirAll(to, hdr.FileInfo().Mode())
}
dstFile, err := os.OpenFile(to, os.O_WRONLY|os.O_CREATE, hdr.FileInfo().Mode())
if err != nil {
return err
}
if err := dstFile.Truncate(0); err != nil {
return err
}
// Don't decompress non-regular files
if !hdr.FileInfo().Mode().IsRegular() {
if _, err := io.Copy(dstFile, tr); err != nil {
return err
}
return nil
}
decryptor, err := encryption.Decrypt(tr, pipes.Encryption, crypto.Identity)
if err != nil {
return err
}
decompressor, err := compression.Decompress(decryptor, pipes.Compression)
if err != nil {
return err
}
sig := ""
if hdr.PAXRecords != nil {
if s, ok := hdr.PAXRecords[pax.STFSRecordSignature]; ok {
sig = s
}
}
verifier, verify, err := signature.Verify(decompressor, isRegular, pipes.Signature, crypto.Recipient, sig)
if err != nil {
return err
}
if _, err := io.Copy(dstFile, verifier); err != nil {
return err
}
if err := verify(); err != nil {
return err
}
if err := decryptor.Close(); err != nil {
return err
}
if err := decompressor.Close(); err != nil {
return err
}
if err := dstFile.Close(); err != nil {
return err
}
}
return nil
}