refactor: Decompose all utilities from cmd package

This commit is contained in:
Felicitas Pojtinger
2021-12-08 00:27:46 +01:00
parent c5e7cab4f3
commit 0be10a7698
23 changed files with 208 additions and 270 deletions

View File

@@ -3,11 +3,9 @@ package cmd
import (
"archive/tar"
"context"
"errors"
"fmt"
"io/ioutil"
"os"
"github.com/pojntfx/stfs/internal/compression"
"github.com/pojntfx/stfs/internal/keys"
"github.com/pojntfx/stfs/internal/persisters"
"github.com/pojntfx/stfs/pkg/config"
@@ -23,29 +21,9 @@ const (
fromFlag = "from"
overwriteFlag = "overwrite"
compressionLevelFlag = "compression-level"
recipientFlag = "recipient"
identityFlag = "identity"
passwordFlag = "password"
)
var (
knownCompressionLevels = []string{config.CompressionLevelFastest, config.CompressionLevelBalanced, config.CompressionLevelSmallest}
errUnknownCompressionLevel = errors.New("unknown compression level")
errUnsupportedCompressionLevel = errors.New("unsupported compression level")
errKeyNotAccessible = errors.New("key not found or accessible")
errMissingTarHeader = errors.New("tar header is missing")
errRecipientUnparsable = errors.New("recipient could not be parsed")
errCompressionFormatRequiresLargerRecordSize = errors.New("this compression format requires a larger record size")
errCompressionFormatOnlyRegularSupport = errors.New("this compression format only supports regular files, not i.e. tape drives")
errSignatureFormatOnlyRegularSupport = errors.New("this signature format only supports regular files, not i.e. tape drives")
recipientFlag = "recipient"
identityFlag = "identity"
passwordFlag = "password"
)
var archiveCmd = &cobra.Command{
@@ -57,15 +35,15 @@ var archiveCmd = &cobra.Command{
return err
}
if err := checkCompressionLevel(viper.GetString(compressionLevelFlag)); err != nil {
if err := compression.CheckCompressionLevel(viper.GetString(compressionLevelFlag)); err != nil {
return err
}
if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil {
if err := keys.CheckKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil {
return err
}
return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag))
return keys.CheckKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag))
},
RunE: func(cmd *cobra.Command, args []string) error {
if viper.GetBool(verboseFlag) {
@@ -89,7 +67,7 @@ var archiveCmd = &cobra.Command{
lastIndexedBlock = b
}
pubkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
pubkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
if err != nil {
return err
}
@@ -99,7 +77,7 @@ var archiveCmd = &cobra.Command{
return err
}
privkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
privkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
if err != nil {
return err
}
@@ -130,6 +108,9 @@ var archiveCmd = &cobra.Command{
viper.GetBool(overwriteFlag),
viper.GetString(compressionLevelFlag),
)
if err != nil {
return nil
}
return recovery.Index(
config.StateConfig{
@@ -159,7 +140,7 @@ var archiveCmd = &cobra.Command{
}
if len(hdrs) <= i-1 {
return errMissingTarHeader
return config.ErrMissingTarHeader
}
*hdr = *hdrs[i-1]
@@ -173,47 +154,11 @@ var archiveCmd = &cobra.Command{
},
}
func checkKeyAccessible(encryptionFormat string, pathToKey string) error {
if encryptionFormat == noneKey {
return nil
}
if _, err := os.Stat(pathToKey); err != nil {
return errKeyNotAccessible
}
return nil
}
func readKey(encryptionFormat string, pathToKey string) ([]byte, error) {
if encryptionFormat == noneKey {
return []byte{}, nil
}
return ioutil.ReadFile(pathToKey)
}
func checkCompressionLevel(compressionLevel string) error {
compressionLevelIsKnown := false
for _, candidate := range knownCompressionLevels {
if compressionLevel == candidate {
compressionLevelIsKnown = true
}
}
if !compressionLevelIsKnown {
return errUnknownCompressionLevel
}
return nil
}
func init() {
archiveCmd.PersistentFlags().IntP(recordSizeFlag, "z", 20, "Amount of 512-bit blocks per record")
archiveCmd.PersistentFlags().StringP(fromFlag, "f", ".", "File or directory to archive")
archiveCmd.PersistentFlags().BoolP(overwriteFlag, "o", false, "Start writing from the start instead of from the end of the tape or tar file")
archiveCmd.PersistentFlags().StringP(compressionLevelFlag, "l", config.CompressionLevelBalanced, fmt.Sprintf("Compression level to use (default %v, available are %v)", config.CompressionLevelBalanced, knownCompressionLevels))
archiveCmd.PersistentFlags().StringP(compressionLevelFlag, "l", config.CompressionLevelBalanced, fmt.Sprintf("Compression level to use (default %v, available are %v)", config.CompressionLevelBalanced, config.KnownCompressionLevels))
archiveCmd.PersistentFlags().StringP(recipientFlag, "r", "", "Path to public key of recipient to encrypt for")
archiveCmd.PersistentFlags().StringP(identityFlag, "i", "", "Path to private key to sign with")
archiveCmd.PersistentFlags().StringP(passwordFlag, "p", "", "Password for the private key")

View File

@@ -22,22 +22,18 @@ var deleteCmd = &cobra.Command{
return err
}
if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil {
if err := keys.CheckKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil {
return err
}
return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag))
return keys.CheckKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag))
},
RunE: func(cmd *cobra.Command, args []string) error {
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
return err
}
if viper.GetBool(verboseFlag) {
boil.DebugMode = true
}
pubkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
pubkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
if err != nil {
return err
}
@@ -47,7 +43,7 @@ var deleteCmd = &cobra.Command{
return err
}
privkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
privkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
if err != nil {
return err
}

View File

@@ -4,7 +4,6 @@ import (
"github.com/pojntfx/stfs/pkg/hardware"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/volatiletech/sqlboiler/v4/boil"
)
var driveEjectCmd = &cobra.Command{
@@ -15,10 +14,6 @@ var driveEjectCmd = &cobra.Command{
return err
}
if viper.GetBool(verboseFlag) {
boil.DebugMode = true
}
return hardware.Eject(
hardware.DriveConfig{
Drive: viper.GetString(driveFlag),

View File

@@ -6,7 +6,6 @@ import (
"github.com/pojntfx/stfs/pkg/hardware"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/volatiletech/sqlboiler/v4/boil"
)
var driveTellCmd = &cobra.Command{
@@ -17,10 +16,6 @@ var driveTellCmd = &cobra.Command{
return err
}
if viper.GetBool(verboseFlag) {
boil.DebugMode = true
}
currentRecord, err := hardware.Tell(
hardware.DriveConfig{
Drive: viper.GetString(driveFlag),

View File

@@ -9,22 +9,17 @@ import (
"github.com/pojntfx/stfs/pkg/utility"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/volatiletech/sqlboiler/v4/boil"
)
var keygenCmd = &cobra.Command{
Use: "keygen",
Aliases: []string{"key", "k"},
Short: "Restore a file or directory from tape or tar file",
Short: "Generate a encryption or signature key",
RunE: func(cmd *cobra.Command, args []string) error {
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
return err
}
if viper.GetBool(verboseFlag) {
boil.DebugMode = true
}
pubkey, privkey, err := utility.Keygen(
config.PipeConfig{
Compression: viper.GetString(compressionFlag),

View File

@@ -18,22 +18,18 @@ var moveCmd = &cobra.Command{
return err
}
if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil {
if err := keys.CheckKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil {
return err
}
return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag))
return keys.CheckKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag))
},
RunE: func(cmd *cobra.Command, args []string) error {
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
return err
}
if viper.GetBool(verboseFlag) {
boil.DebugMode = true
}
pubkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
pubkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
if err != nil {
return err
}
@@ -43,7 +39,7 @@ var moveCmd = &cobra.Command{
return err
}
privkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
privkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
if err != nil {
return err
}

View File

@@ -1,14 +1,12 @@
package cmd
import (
"errors"
"github.com/pojntfx/stfs/internal/keys"
"github.com/pojntfx/stfs/pkg/config"
"github.com/pojntfx/stfs/pkg/hardware"
"github.com/pojntfx/stfs/pkg/recovery"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/volatiletech/sqlboiler/v4/boil"
)
const (
@@ -18,40 +16,22 @@ const (
previewFlag = "preview"
)
var (
errEmbeddedHeaderMissing = errors.New("embedded header is missing")
errIdentityUnparsable = errors.New("recipient could not be parsed")
errInvalidSignature = errors.New("invalid signature")
errSignatureMissing = errors.New("missing signature")
)
var recoveryFetchCmd = &cobra.Command{
Use: "fetch",
Short: "Fetch a file or directory from tape or tar file by record and block",
Short: "Fetch a file or directory from tape or tar file by record and block without the index",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
return err
}
if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(identityFlag)); err != nil {
if err := keys.CheckKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(identityFlag)); err != nil {
return err
}
return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
return keys.CheckKeyAccessible(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
},
RunE: func(cmd *cobra.Command, args []string) error {
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
return err
}
if viper.GetBool(verboseFlag) {
boil.DebugMode = true
}
pubkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
pubkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
if err != nil {
return err
}
@@ -61,7 +41,7 @@ var recoveryFetchCmd = &cobra.Command{
return err
}
privkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
privkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
if err != nil {
return err
}
@@ -72,9 +52,8 @@ var recoveryFetchCmd = &cobra.Command{
}
return recovery.Fetch(
config.StateConfig{
Drive: viper.GetString(driveFlag),
Metadata: viper.GetString(metadataFlag),
hardware.DriveConfig{
Drive: viper.GetString(driveFlag),
},
config.PipeConfig{
Compression: viper.GetString(compressionFlag),

View File

@@ -21,22 +21,18 @@ var recoveryIndexCmd = &cobra.Command{
return err
}
if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(identityFlag)); err != nil {
if err := keys.CheckKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(identityFlag)); err != nil {
return err
}
return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
return keys.CheckKeyAccessible(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
},
RunE: func(cmd *cobra.Command, args []string) error {
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
return err
}
if viper.GetBool(verboseFlag) {
boil.DebugMode = true
}
pubkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
pubkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
if err != nil {
return err
}
@@ -46,7 +42,7 @@ var recoveryIndexCmd = &cobra.Command{
return err
}
privkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
privkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
if err != nil {
return err
}

View File

@@ -3,10 +3,10 @@ package cmd
import (
"github.com/pojntfx/stfs/internal/keys"
"github.com/pojntfx/stfs/pkg/config"
"github.com/pojntfx/stfs/pkg/hardware"
"github.com/pojntfx/stfs/pkg/recovery"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/volatiletech/sqlboiler/v4/boil"
)
var recoveryQueryCmd = &cobra.Command{
@@ -17,22 +17,14 @@ var recoveryQueryCmd = &cobra.Command{
return err
}
if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(identityFlag)); err != nil {
if err := keys.CheckKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(identityFlag)); err != nil {
return err
}
return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
return keys.CheckKeyAccessible(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
},
RunE: func(cmd *cobra.Command, args []string) error {
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
return err
}
if viper.GetBool(verboseFlag) {
boil.DebugMode = true
}
pubkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
pubkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
if err != nil {
return err
}
@@ -42,7 +34,7 @@ var recoveryQueryCmd = &cobra.Command{
return err
}
privkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
privkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
if err != nil {
return err
}
@@ -53,9 +45,8 @@ var recoveryQueryCmd = &cobra.Command{
}
if _, err := recovery.Query(
config.StateConfig{
Drive: viper.GetString(driveFlag),
Metadata: viper.GetString(metadataFlag),
hardware.DriveConfig{
Drive: viper.GetString(driveFlag),
},
config.PipeConfig{
Compression: viper.GetString(compressionFlag),

View File

@@ -22,22 +22,18 @@ var restoreCmd = &cobra.Command{
return err
}
if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(identityFlag)); err != nil {
if err := keys.CheckKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(identityFlag)); err != nil {
return err
}
return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
return keys.CheckKeyAccessible(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
},
RunE: func(cmd *cobra.Command, args []string) error {
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
return err
}
if viper.GetBool(verboseFlag) {
boil.DebugMode = true
}
pubkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
pubkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
if err != nil {
return err
}
@@ -47,7 +43,7 @@ var restoreCmd = &cobra.Command{
return err
}
privkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
privkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
if err != nil {
return err
}

View File

@@ -1,75 +1,26 @@
package cmd
import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/pojntfx/stfs/internal/compression"
"github.com/pojntfx/stfs/internal/encryption"
"github.com/pojntfx/stfs/internal/signature"
"github.com/pojntfx/stfs/pkg/config"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
const (
driveFlag = "drive"
metadataFlag = "metadata"
verboseFlag = "verbose"
driveFlag = "drive"
metadataFlag = "metadata"
verboseFlag = "verbose"
compressionFlag = "compression"
noneKey = "none"
compressionFormatGZipKey = "gzip"
compressionFormatGZipSuffix = ".gz"
compressionFormatParallelGZipKey = "parallelgzip"
compressionFormatLZ4Key = "lz4"
compressionFormatLZ4Suffix = ".lz4"
compressionFormatZStandardKey = "zstandard"
compressionFormatZStandardSuffix = ".zst"
compressionFormatBrotliKey = "brotli"
compressionFormatBrotliSuffix = ".br"
compressionFormatBzip2Key = "bzip2"
compressionFormatBzip2Suffix = ".bz2"
compressionFormatBzip2ParallelKey = "parallelbzip2"
encryptionFlag = "encryption"
encryptionFormatAgeKey = "age"
encryptionFormatAgeSuffix = ".age"
encryptionFormatPGPKey = "pgp"
encryptionFormatPGPSuffix = ".pgp"
signatureFlag = "signature"
signatureFormatMinisignKey = "minisign"
signatureFormatPGPKey = "pgp"
)
var (
knownCompressionFormats = []string{noneKey, compressionFormatGZipKey, compressionFormatParallelGZipKey, compressionFormatLZ4Key, compressionFormatZStandardKey, compressionFormatBrotliKey, compressionFormatBzip2Key, compressionFormatBzip2ParallelKey}
errUnknownCompressionFormat = errors.New("unknown compression format")
errUnsupportedCompressionFormat = errors.New("unsupported compression format")
knownEncryptionFormats = []string{noneKey, encryptionFormatAgeKey, encryptionFormatPGPKey}
errUnknownEncryptionFormat = errors.New("unknown encryption format")
errUnsupportedEncryptionFormat = errors.New("unsupported encryption format")
errKeygenForFormatUnsupported = errors.New("can not generate keys for this format")
knownSignatureFormats = []string{noneKey, signatureFormatMinisignKey, signatureFormatPGPKey}
errUnknownSignatureFormat = errors.New("unknown signature format")
errUnsupportedSignatureFormat = errors.New("unsupported signature format")
encryptionFlag = "encryption"
signatureFlag = "signature"
)
var rootCmd = &cobra.Command{
@@ -83,46 +34,15 @@ https://github.com/pojntfx/stfs`,
viper.SetEnvPrefix("stbak")
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_", ".", "_"))
compressionFormatIsKnown := false
compressionFormat := viper.GetString(compressionFlag)
for _, candidate := range knownCompressionFormats {
if compressionFormat == candidate {
compressionFormatIsKnown = true
}
if err := compression.CheckCompressionFormat(viper.GetString(compressionFlag)); err != nil {
return err
}
if !compressionFormatIsKnown {
return errUnknownCompressionFormat
if err := encryption.CheckEncryptionFormat(viper.GetString(encryptionFlag)); err != nil {
return err
}
encryptionFormatIsKnown := false
encryptionFormat := viper.GetString(encryptionFlag)
for _, candidate := range knownEncryptionFormats {
if encryptionFormat == candidate {
encryptionFormatIsKnown = true
}
}
if !encryptionFormatIsKnown {
return errUnknownEncryptionFormat
}
signatureFormatIsKnown := false
signatureFormat := viper.GetString(signatureFlag)
for _, candidate := range knownSignatureFormats {
if signatureFormat == candidate {
signatureFormatIsKnown = true
}
}
if !signatureFormatIsKnown {
return errUnknownSignatureFormat
}
return nil
return signature.CheckSignatureFormat(viper.GetString(signatureFlag))
},
}
@@ -137,9 +57,9 @@ func Execute() {
rootCmd.PersistentFlags().StringP(driveFlag, "d", "/dev/nst0", "Tape or tar file to use")
rootCmd.PersistentFlags().StringP(metadataFlag, "m", metadataPath, "Metadata database to use")
rootCmd.PersistentFlags().BoolP(verboseFlag, "v", false, "Enable verbose logging")
rootCmd.PersistentFlags().StringP(compressionFlag, "c", noneKey, fmt.Sprintf("Compression format to use (default %v, available are %v)", noneKey, knownCompressionFormats))
rootCmd.PersistentFlags().StringP(encryptionFlag, "e", noneKey, fmt.Sprintf("Encryption format to use (default %v, available are %v)", noneKey, knownEncryptionFormats))
rootCmd.PersistentFlags().StringP(signatureFlag, "s", noneKey, fmt.Sprintf("Signature format to use (default %v, available are %v)", noneKey, knownSignatureFormats))
rootCmd.PersistentFlags().StringP(compressionFlag, "c", config.NoneKey, fmt.Sprintf("Compression format to use (default %v, available are %v)", config.NoneKey, config.KnownCompressionFormats))
rootCmd.PersistentFlags().StringP(encryptionFlag, "e", config.NoneKey, fmt.Sprintf("Encryption format to use (default %v, available are %v)", config.NoneKey, config.KnownEncryptionFormats))
rootCmd.PersistentFlags().StringP(signatureFlag, "s", config.NoneKey, fmt.Sprintf("Signature format to use (default %v, available are %v)", config.NoneKey, config.KnownSignatureFormats))
if err := viper.BindPFlags(rootCmd.PersistentFlags()); err != nil {
panic(err)

View File

@@ -5,6 +5,7 @@ import (
"context"
"fmt"
"github.com/pojntfx/stfs/internal/compression"
"github.com/pojntfx/stfs/internal/keys"
"github.com/pojntfx/stfs/internal/persisters"
"github.com/pojntfx/stfs/pkg/config"
@@ -24,15 +25,15 @@ var updateCmd = &cobra.Command{
return err
}
if err := checkCompressionLevel(viper.GetString(compressionLevelFlag)); err != nil {
if err := compression.CheckCompressionLevel(viper.GetString(compressionLevelFlag)); err != nil {
return err
}
if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil {
if err := keys.CheckKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil {
return err
}
return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag))
return keys.CheckKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag))
},
RunE: func(cmd *cobra.Command, args []string) error {
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
@@ -53,7 +54,7 @@ var updateCmd = &cobra.Command{
return err
}
pubkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
pubkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
if err != nil {
return err
}
@@ -63,7 +64,7 @@ var updateCmd = &cobra.Command{
return err
}
privkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
privkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
if err != nil {
return err
}
@@ -126,7 +127,7 @@ var updateCmd = &cobra.Command{
}
if len(hdrs) <= i-1 {
return errMissingTarHeader
return config.ErrMissingTarHeader
}
*hdr = *hdrs[i-1]
@@ -144,7 +145,7 @@ func init() {
updateCmd.PersistentFlags().IntP(recordSizeFlag, "z", 20, "Amount of 512-bit blocks per record")
updateCmd.PersistentFlags().StringP(fromFlag, "f", "", "Path of the file or directory to update")
updateCmd.PersistentFlags().BoolP(overwriteFlag, "o", false, "Replace the content on the tape or tar file")
updateCmd.PersistentFlags().StringP(compressionLevelFlag, "l", config.CompressionLevelBalanced, fmt.Sprintf("Compression level to use (default %v, available are %v)", config.CompressionLevelBalanced, knownCompressionLevels))
updateCmd.PersistentFlags().StringP(compressionLevelFlag, "l", config.CompressionLevelBalanced, fmt.Sprintf("Compression level to use (default %v, available are %v)", config.CompressionLevelBalanced, config.KnownCompressionLevels))
updateCmd.PersistentFlags().StringP(recipientFlag, "r", "", "Path to public key of recipient to encrypt for")
updateCmd.PersistentFlags().StringP(identityFlag, "i", "", "Path to private key to sign with")
updateCmd.PersistentFlags().StringP(passwordFlag, "p", "", "Password for the private key")

View File

@@ -0,0 +1,37 @@
package compression
import (
"github.com/pojntfx/stfs/pkg/config"
)
func CheckCompressionFormat(compressionFormat string) error {
compressionFormatIsKnown := false
for _, candidate := range config.KnownCompressionFormats {
if compressionFormat == candidate {
compressionFormatIsKnown = true
}
}
if !compressionFormatIsKnown {
return config.ErrCompressionFormatUnknown
}
return nil
}
func CheckCompressionLevel(compressionLevel string) error {
compressionLevelIsKnown := false
for _, candidate := range config.KnownCompressionLevels {
if compressionLevel == candidate {
compressionLevelIsKnown = true
}
}
if !compressionLevelIsKnown {
return config.ErrCompressionLevelUnknown
}
return nil
}

View File

@@ -0,0 +1,19 @@
package encryption
import "github.com/pojntfx/stfs/pkg/config"
func CheckEncryptionFormat(encryptionFormat string) error {
encryptionFormatIsKnown := false
for _, candidate := range config.KnownEncryptionFormats {
if encryptionFormat == candidate {
encryptionFormatIsKnown = true
}
}
if !encryptionFormatIsKnown {
return config.ErrEncryptionFormatUnknown
}
return nil
}

View File

@@ -8,10 +8,10 @@ import (
"io"
"filippo.io/age"
"github.com/ProtonMail/go-crypto/openpgp"
"github.com/pojntfx/stfs/internal/noop"
"github.com/pojntfx/stfs/internal/pax"
"github.com/pojntfx/stfs/pkg/config"
"golang.org/x/crypto/openpgp"
)
func Encrypt(

24
internal/keys/check.go Normal file
View File

@@ -0,0 +1,24 @@
package keys
import (
"errors"
"os"
"github.com/pojntfx/stfs/pkg/config"
)
var (
ErrKeyNotAccessible = errors.New("key not found or accessible")
)
func CheckKeyAccessible(encryptionFormat string, pathToKey string) error {
if encryptionFormat == config.NoneKey {
return nil
}
if _, err := os.Stat(pathToKey); err != nil {
return ErrKeyNotAccessible
}
return nil
}

15
internal/keys/read.go Normal file
View File

@@ -0,0 +1,15 @@
package keys
import (
"io/ioutil"
"github.com/pojntfx/stfs/pkg/config"
)
func ReadKey(encryptionFormat string, pathToKey string) ([]byte, error) {
if encryptionFormat == config.NoneKey {
return []byte{}, nil
}
return ioutil.ReadFile(pathToKey)
}

View File

@@ -0,0 +1,19 @@
package signature
import "github.com/pojntfx/stfs/pkg/config"
func CheckSignatureFormat(signatureFormat string) error {
signatureFormatIsKnown := false
for _, candidate := range config.KnownSignatureFormats {
if signatureFormat == candidate {
signatureFormatIsKnown = true
}
}
if !signatureFormatIsKnown {
return config.ErrSignatureFormatUnknown
}
return nil
}

View File

@@ -21,3 +21,13 @@ const (
CompressionLevelBalanced = "balanced"
CompressionLevelSmallest = "smallest"
)
var (
KnownCompressionLevels = []string{CompressionLevelFastest, CompressionLevelBalanced, CompressionLevelSmallest}
KnownCompressionFormats = []string{NoneKey, CompressionFormatGZipKey, CompressionFormatParallelGZipKey, CompressionFormatLZ4Key, CompressionFormatZStandardKey, CompressionFormatBrotliKey, CompressionFormatBzip2Key, CompressionFormatBzip2ParallelKey}
KnownEncryptionFormats = []string{NoneKey, EncryptionFormatAgeKey, EncryptionFormatPGPKey}
KnownSignatureFormats = []string{NoneKey, SignatureFormatMinisignKey, SignatureFormatPGPKey}
)

View File

@@ -3,6 +3,7 @@ package config
import "errors"
var (
ErrEncryptionFormatUnknown = errors.New("unknown encryption format")
ErrEncryptionFormatUnsupported = errors.New("unsupported encryption format")
ErrIdentityUnparsable = errors.New("recipient could not be parsed")
@@ -10,6 +11,7 @@ var (
ErrEmbeddedHeaderMissing = errors.New("embedded header is missing")
ErrSignatureFormatUnknown = errors.New("unknown signature format")
ErrSignatureFormatUnsupported = errors.New("unsupported signature format")
ErrSignatureFormatOnlyRegularSupport = errors.New("this signature format only supports regular files, not i.e. tape drives")
ErrSignatureInvalid = errors.New("signature is invalid")
@@ -17,10 +19,12 @@ var (
ErrKeygenForFormatUnsupported = errors.New("can not generate keys for this format")
ErrCompressionFormatUnknown = errors.New("unknown compression format")
ErrCompressionFormatUnsupported = errors.New("unsupported compression format")
ErrCompressionFormatOnlyRegularSupport = errors.New("this compression format only supports regular files, not i.e. tape drives")
ErrCompressionFormatRequiresLargerRecordSize = errors.New("this compression format requires a larger record size")
ErrCompressionLevelUnsupported = errors.New("compression level is unsupported")
ErrCompressionLevelUnknown = errors.New("unknown compression level")
ErrMissingTarHeader = errors.New("tar header is missing")
)

View File

@@ -13,6 +13,7 @@ import (
"github.com/pojntfx/stfs/internal/formatting"
"github.com/pojntfx/stfs/internal/persisters"
"github.com/pojntfx/stfs/pkg/config"
"github.com/pojntfx/stfs/pkg/hardware"
"github.com/pojntfx/stfs/pkg/recovery"
)
@@ -88,7 +89,9 @@ func Restore(
}
if err := recovery.Fetch(
state,
hardware.DriveConfig{
Drive: state.Drive,
},
pipes,
crypto,

View File

@@ -15,10 +15,11 @@ import (
"github.com/pojntfx/stfs/internal/signature"
"github.com/pojntfx/stfs/internal/tape"
"github.com/pojntfx/stfs/pkg/config"
"github.com/pojntfx/stfs/pkg/hardware"
)
func Fetch(
state config.StateConfig,
state hardware.DriveConfig,
pipes config.PipeConfig,
crypto config.CryptoConfig,

View File

@@ -14,10 +14,11 @@ import (
"github.com/pojntfx/stfs/internal/signature"
"github.com/pojntfx/stfs/internal/tape"
"github.com/pojntfx/stfs/pkg/config"
"github.com/pojntfx/stfs/pkg/hardware"
)
func Query(
state config.StateConfig,
state hardware.DriveConfig,
pipes config.PipeConfig,
crypto config.CryptoConfig,