refactor: Decompose all utilities from cmd package
This commit is contained in:
@@ -3,11 +3,9 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
|
"github.com/pojntfx/stfs/internal/compression"
|
||||||
"github.com/pojntfx/stfs/internal/keys"
|
"github.com/pojntfx/stfs/internal/keys"
|
||||||
"github.com/pojntfx/stfs/internal/persisters"
|
"github.com/pojntfx/stfs/internal/persisters"
|
||||||
"github.com/pojntfx/stfs/pkg/config"
|
"github.com/pojntfx/stfs/pkg/config"
|
||||||
@@ -23,29 +21,9 @@ const (
|
|||||||
fromFlag = "from"
|
fromFlag = "from"
|
||||||
overwriteFlag = "overwrite"
|
overwriteFlag = "overwrite"
|
||||||
compressionLevelFlag = "compression-level"
|
compressionLevelFlag = "compression-level"
|
||||||
|
recipientFlag = "recipient"
|
||||||
recipientFlag = "recipient"
|
identityFlag = "identity"
|
||||||
identityFlag = "identity"
|
passwordFlag = "password"
|
||||||
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")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var archiveCmd = &cobra.Command{
|
var archiveCmd = &cobra.Command{
|
||||||
@@ -57,15 +35,15 @@ var archiveCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := checkCompressionLevel(viper.GetString(compressionLevelFlag)); err != nil {
|
if err := compression.CheckCompressionLevel(viper.GetString(compressionLevelFlag)); err != nil {
|
||||||
return err
|
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 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 {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if viper.GetBool(verboseFlag) {
|
if viper.GetBool(verboseFlag) {
|
||||||
@@ -89,7 +67,7 @@ var archiveCmd = &cobra.Command{
|
|||||||
lastIndexedBlock = b
|
lastIndexedBlock = b
|
||||||
}
|
}
|
||||||
|
|
||||||
pubkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
|
pubkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -99,7 +77,7 @@ var archiveCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
privkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
privkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -130,6 +108,9 @@ var archiveCmd = &cobra.Command{
|
|||||||
viper.GetBool(overwriteFlag),
|
viper.GetBool(overwriteFlag),
|
||||||
viper.GetString(compressionLevelFlag),
|
viper.GetString(compressionLevelFlag),
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return recovery.Index(
|
return recovery.Index(
|
||||||
config.StateConfig{
|
config.StateConfig{
|
||||||
@@ -159,7 +140,7 @@ var archiveCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(hdrs) <= i-1 {
|
if len(hdrs) <= i-1 {
|
||||||
return errMissingTarHeader
|
return config.ErrMissingTarHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
*hdr = *hdrs[i-1]
|
*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() {
|
func init() {
|
||||||
archiveCmd.PersistentFlags().IntP(recordSizeFlag, "z", 20, "Amount of 512-bit blocks per record")
|
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().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().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(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(identityFlag, "i", "", "Path to private key to sign with")
|
||||||
archiveCmd.PersistentFlags().StringP(passwordFlag, "p", "", "Password for the private key")
|
archiveCmd.PersistentFlags().StringP(passwordFlag, "p", "", "Password for the private key")
|
||||||
|
|||||||
@@ -22,22 +22,18 @@ var deleteCmd = &cobra.Command{
|
|||||||
return err
|
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 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 {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if viper.GetBool(verboseFlag) {
|
if viper.GetBool(verboseFlag) {
|
||||||
boil.DebugMode = true
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -47,7 +43,7 @@ var deleteCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
privkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
privkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"github.com/pojntfx/stfs/pkg/hardware"
|
"github.com/pojntfx/stfs/pkg/hardware"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var driveEjectCmd = &cobra.Command{
|
var driveEjectCmd = &cobra.Command{
|
||||||
@@ -15,10 +14,6 @@ var driveEjectCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if viper.GetBool(verboseFlag) {
|
|
||||||
boil.DebugMode = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return hardware.Eject(
|
return hardware.Eject(
|
||||||
hardware.DriveConfig{
|
hardware.DriveConfig{
|
||||||
Drive: viper.GetString(driveFlag),
|
Drive: viper.GetString(driveFlag),
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"github.com/pojntfx/stfs/pkg/hardware"
|
"github.com/pojntfx/stfs/pkg/hardware"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var driveTellCmd = &cobra.Command{
|
var driveTellCmd = &cobra.Command{
|
||||||
@@ -17,10 +16,6 @@ var driveTellCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if viper.GetBool(verboseFlag) {
|
|
||||||
boil.DebugMode = true
|
|
||||||
}
|
|
||||||
|
|
||||||
currentRecord, err := hardware.Tell(
|
currentRecord, err := hardware.Tell(
|
||||||
hardware.DriveConfig{
|
hardware.DriveConfig{
|
||||||
Drive: viper.GetString(driveFlag),
|
Drive: viper.GetString(driveFlag),
|
||||||
|
|||||||
@@ -9,22 +9,17 @@ import (
|
|||||||
"github.com/pojntfx/stfs/pkg/utility"
|
"github.com/pojntfx/stfs/pkg/utility"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var keygenCmd = &cobra.Command{
|
var keygenCmd = &cobra.Command{
|
||||||
Use: "keygen",
|
Use: "keygen",
|
||||||
Aliases: []string{"key", "k"},
|
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 {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if viper.GetBool(verboseFlag) {
|
|
||||||
boil.DebugMode = true
|
|
||||||
}
|
|
||||||
|
|
||||||
pubkey, privkey, err := utility.Keygen(
|
pubkey, privkey, err := utility.Keygen(
|
||||||
config.PipeConfig{
|
config.PipeConfig{
|
||||||
Compression: viper.GetString(compressionFlag),
|
Compression: viper.GetString(compressionFlag),
|
||||||
|
|||||||
@@ -18,22 +18,18 @@ var moveCmd = &cobra.Command{
|
|||||||
return err
|
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 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 {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if viper.GetBool(verboseFlag) {
|
if viper.GetBool(verboseFlag) {
|
||||||
boil.DebugMode = true
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -43,7 +39,7 @@ var moveCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
privkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
privkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/pojntfx/stfs/internal/keys"
|
"github.com/pojntfx/stfs/internal/keys"
|
||||||
"github.com/pojntfx/stfs/pkg/config"
|
"github.com/pojntfx/stfs/pkg/config"
|
||||||
|
"github.com/pojntfx/stfs/pkg/hardware"
|
||||||
"github.com/pojntfx/stfs/pkg/recovery"
|
"github.com/pojntfx/stfs/pkg/recovery"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -18,40 +16,22 @@ const (
|
|||||||
previewFlag = "preview"
|
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{
|
var recoveryFetchCmd = &cobra.Command{
|
||||||
Use: "fetch",
|
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 {
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
||||||
return err
|
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 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 {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
pubkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if viper.GetBool(verboseFlag) {
|
|
||||||
boil.DebugMode = true
|
|
||||||
}
|
|
||||||
|
|
||||||
pubkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -61,7 +41,7 @@ var recoveryFetchCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
privkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
|
privkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -72,9 +52,8 @@ var recoveryFetchCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
return recovery.Fetch(
|
return recovery.Fetch(
|
||||||
config.StateConfig{
|
hardware.DriveConfig{
|
||||||
Drive: viper.GetString(driveFlag),
|
Drive: viper.GetString(driveFlag),
|
||||||
Metadata: viper.GetString(metadataFlag),
|
|
||||||
},
|
},
|
||||||
config.PipeConfig{
|
config.PipeConfig{
|
||||||
Compression: viper.GetString(compressionFlag),
|
Compression: viper.GetString(compressionFlag),
|
||||||
|
|||||||
@@ -21,22 +21,18 @@ var recoveryIndexCmd = &cobra.Command{
|
|||||||
return err
|
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 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 {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if viper.GetBool(verboseFlag) {
|
if viper.GetBool(verboseFlag) {
|
||||||
boil.DebugMode = true
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -46,7 +42,7 @@ var recoveryIndexCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
privkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
|
privkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"github.com/pojntfx/stfs/internal/keys"
|
"github.com/pojntfx/stfs/internal/keys"
|
||||||
"github.com/pojntfx/stfs/pkg/config"
|
"github.com/pojntfx/stfs/pkg/config"
|
||||||
|
"github.com/pojntfx/stfs/pkg/hardware"
|
||||||
"github.com/pojntfx/stfs/pkg/recovery"
|
"github.com/pojntfx/stfs/pkg/recovery"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var recoveryQueryCmd = &cobra.Command{
|
var recoveryQueryCmd = &cobra.Command{
|
||||||
@@ -17,22 +17,14 @@ var recoveryQueryCmd = &cobra.Command{
|
|||||||
return err
|
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 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 {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
pubkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if viper.GetBool(verboseFlag) {
|
|
||||||
boil.DebugMode = true
|
|
||||||
}
|
|
||||||
|
|
||||||
pubkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(recipientFlag))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -42,7 +34,7 @@ var recoveryQueryCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
privkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
|
privkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -53,9 +45,8 @@ var recoveryQueryCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if _, err := recovery.Query(
|
if _, err := recovery.Query(
|
||||||
config.StateConfig{
|
hardware.DriveConfig{
|
||||||
Drive: viper.GetString(driveFlag),
|
Drive: viper.GetString(driveFlag),
|
||||||
Metadata: viper.GetString(metadataFlag),
|
|
||||||
},
|
},
|
||||||
config.PipeConfig{
|
config.PipeConfig{
|
||||||
Compression: viper.GetString(compressionFlag),
|
Compression: viper.GetString(compressionFlag),
|
||||||
|
|||||||
@@ -22,22 +22,18 @@ var restoreCmd = &cobra.Command{
|
|||||||
return err
|
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 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 {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if viper.GetBool(verboseFlag) {
|
if viper.GetBool(verboseFlag) {
|
||||||
boil.DebugMode = true
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -47,7 +43,7 @@ var restoreCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
privkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
|
privkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(identityFlag))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,75 +1,26 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"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/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
driveFlag = "drive"
|
driveFlag = "drive"
|
||||||
metadataFlag = "metadata"
|
metadataFlag = "metadata"
|
||||||
verboseFlag = "verbose"
|
verboseFlag = "verbose"
|
||||||
|
|
||||||
compressionFlag = "compression"
|
compressionFlag = "compression"
|
||||||
|
encryptionFlag = "encryption"
|
||||||
noneKey = "none"
|
signatureFlag = "signature"
|
||||||
|
|
||||||
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")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
@@ -83,46 +34,15 @@ https://github.com/pojntfx/stfs`,
|
|||||||
viper.SetEnvPrefix("stbak")
|
viper.SetEnvPrefix("stbak")
|
||||||
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_", ".", "_"))
|
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_", ".", "_"))
|
||||||
|
|
||||||
compressionFormatIsKnown := false
|
if err := compression.CheckCompressionFormat(viper.GetString(compressionFlag)); err != nil {
|
||||||
compressionFormat := viper.GetString(compressionFlag)
|
return err
|
||||||
|
|
||||||
for _, candidate := range knownCompressionFormats {
|
|
||||||
if compressionFormat == candidate {
|
|
||||||
compressionFormatIsKnown = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !compressionFormatIsKnown {
|
if err := encryption.CheckEncryptionFormat(viper.GetString(encryptionFlag)); err != nil {
|
||||||
return errUnknownCompressionFormat
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptionFormatIsKnown := false
|
return signature.CheckSignatureFormat(viper.GetString(signatureFlag))
|
||||||
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
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,9 +57,9 @@ func Execute() {
|
|||||||
rootCmd.PersistentFlags().StringP(driveFlag, "d", "/dev/nst0", "Tape or tar file to use")
|
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().StringP(metadataFlag, "m", metadataPath, "Metadata database to use")
|
||||||
rootCmd.PersistentFlags().BoolP(verboseFlag, "v", false, "Enable verbose logging")
|
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(compressionFlag, "c", config.NoneKey, fmt.Sprintf("Compression format to use (default %v, available are %v)", config.NoneKey, config.KnownCompressionFormats))
|
||||||
rootCmd.PersistentFlags().StringP(encryptionFlag, "e", noneKey, fmt.Sprintf("Encryption format to use (default %v, available are %v)", noneKey, knownEncryptionFormats))
|
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", noneKey, fmt.Sprintf("Signature format to use (default %v, available are %v)", noneKey, knownSignatureFormats))
|
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 {
|
if err := viper.BindPFlags(rootCmd.PersistentFlags()); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/pojntfx/stfs/internal/compression"
|
||||||
"github.com/pojntfx/stfs/internal/keys"
|
"github.com/pojntfx/stfs/internal/keys"
|
||||||
"github.com/pojntfx/stfs/internal/persisters"
|
"github.com/pojntfx/stfs/internal/persisters"
|
||||||
"github.com/pojntfx/stfs/pkg/config"
|
"github.com/pojntfx/stfs/pkg/config"
|
||||||
@@ -24,15 +25,15 @@ var updateCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := checkCompressionLevel(viper.GetString(compressionLevelFlag)); err != nil {
|
if err := compression.CheckCompressionLevel(viper.GetString(compressionLevelFlag)); err != nil {
|
||||||
return err
|
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 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 {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
|
||||||
@@ -53,7 +54,7 @@ var updateCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
pubkey, err := readKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
|
pubkey, err := keys.ReadKey(viper.GetString(encryptionFlag), viper.GetString(recipientFlag))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -63,7 +64,7 @@ var updateCmd = &cobra.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
privkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
privkey, err := keys.ReadKey(viper.GetString(signatureFlag), viper.GetString(identityFlag))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -126,7 +127,7 @@ var updateCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(hdrs) <= i-1 {
|
if len(hdrs) <= i-1 {
|
||||||
return errMissingTarHeader
|
return config.ErrMissingTarHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
*hdr = *hdrs[i-1]
|
*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().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().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().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(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(identityFlag, "i", "", "Path to private key to sign with")
|
||||||
updateCmd.PersistentFlags().StringP(passwordFlag, "p", "", "Password for the private key")
|
updateCmd.PersistentFlags().StringP(passwordFlag, "p", "", "Password for the private key")
|
||||||
|
|||||||
37
internal/compression/check.go
Normal file
37
internal/compression/check.go
Normal 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
|
||||||
|
}
|
||||||
19
internal/encryption/check.go
Normal file
19
internal/encryption/check.go
Normal 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
|
||||||
|
}
|
||||||
@@ -8,10 +8,10 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
|
|
||||||
"filippo.io/age"
|
"filippo.io/age"
|
||||||
|
"github.com/ProtonMail/go-crypto/openpgp"
|
||||||
"github.com/pojntfx/stfs/internal/noop"
|
"github.com/pojntfx/stfs/internal/noop"
|
||||||
"github.com/pojntfx/stfs/internal/pax"
|
"github.com/pojntfx/stfs/internal/pax"
|
||||||
"github.com/pojntfx/stfs/pkg/config"
|
"github.com/pojntfx/stfs/pkg/config"
|
||||||
"golang.org/x/crypto/openpgp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Encrypt(
|
func Encrypt(
|
||||||
|
|||||||
24
internal/keys/check.go
Normal file
24
internal/keys/check.go
Normal 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
15
internal/keys/read.go
Normal 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)
|
||||||
|
}
|
||||||
19
internal/signature/check.go
Normal file
19
internal/signature/check.go
Normal 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
|
||||||
|
}
|
||||||
@@ -21,3 +21,13 @@ const (
|
|||||||
CompressionLevelBalanced = "balanced"
|
CompressionLevelBalanced = "balanced"
|
||||||
CompressionLevelSmallest = "smallest"
|
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}
|
||||||
|
)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package config
|
|||||||
import "errors"
|
import "errors"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
ErrEncryptionFormatUnknown = errors.New("unknown encryption format")
|
||||||
ErrEncryptionFormatUnsupported = errors.New("unsupported encryption format")
|
ErrEncryptionFormatUnsupported = errors.New("unsupported encryption format")
|
||||||
|
|
||||||
ErrIdentityUnparsable = errors.New("recipient could not be parsed")
|
ErrIdentityUnparsable = errors.New("recipient could not be parsed")
|
||||||
@@ -10,6 +11,7 @@ var (
|
|||||||
|
|
||||||
ErrEmbeddedHeaderMissing = errors.New("embedded header is missing")
|
ErrEmbeddedHeaderMissing = errors.New("embedded header is missing")
|
||||||
|
|
||||||
|
ErrSignatureFormatUnknown = errors.New("unknown signature format")
|
||||||
ErrSignatureFormatUnsupported = errors.New("unsupported signature format")
|
ErrSignatureFormatUnsupported = errors.New("unsupported signature format")
|
||||||
ErrSignatureFormatOnlyRegularSupport = errors.New("this signature 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")
|
||||||
ErrSignatureInvalid = errors.New("signature is invalid")
|
ErrSignatureInvalid = errors.New("signature is invalid")
|
||||||
@@ -17,10 +19,12 @@ var (
|
|||||||
|
|
||||||
ErrKeygenForFormatUnsupported = errors.New("can not generate keys for this format")
|
ErrKeygenForFormatUnsupported = errors.New("can not generate keys for this format")
|
||||||
|
|
||||||
|
ErrCompressionFormatUnknown = errors.New("unknown compression format")
|
||||||
ErrCompressionFormatUnsupported = errors.New("unsupported compression format")
|
ErrCompressionFormatUnsupported = errors.New("unsupported compression format")
|
||||||
ErrCompressionFormatOnlyRegularSupport = errors.New("this compression format only supports regular files, not i.e. tape drives")
|
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")
|
ErrCompressionFormatRequiresLargerRecordSize = errors.New("this compression format requires a larger record size")
|
||||||
ErrCompressionLevelUnsupported = errors.New("compression level is unsupported")
|
ErrCompressionLevelUnsupported = errors.New("compression level is unsupported")
|
||||||
|
ErrCompressionLevelUnknown = errors.New("unknown compression level")
|
||||||
|
|
||||||
ErrMissingTarHeader = errors.New("tar header is missing")
|
ErrMissingTarHeader = errors.New("tar header is missing")
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/pojntfx/stfs/internal/formatting"
|
"github.com/pojntfx/stfs/internal/formatting"
|
||||||
"github.com/pojntfx/stfs/internal/persisters"
|
"github.com/pojntfx/stfs/internal/persisters"
|
||||||
"github.com/pojntfx/stfs/pkg/config"
|
"github.com/pojntfx/stfs/pkg/config"
|
||||||
|
"github.com/pojntfx/stfs/pkg/hardware"
|
||||||
"github.com/pojntfx/stfs/pkg/recovery"
|
"github.com/pojntfx/stfs/pkg/recovery"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -88,7 +89,9 @@ func Restore(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := recovery.Fetch(
|
if err := recovery.Fetch(
|
||||||
state,
|
hardware.DriveConfig{
|
||||||
|
Drive: state.Drive,
|
||||||
|
},
|
||||||
pipes,
|
pipes,
|
||||||
crypto,
|
crypto,
|
||||||
|
|
||||||
|
|||||||
@@ -15,10 +15,11 @@ import (
|
|||||||
"github.com/pojntfx/stfs/internal/signature"
|
"github.com/pojntfx/stfs/internal/signature"
|
||||||
"github.com/pojntfx/stfs/internal/tape"
|
"github.com/pojntfx/stfs/internal/tape"
|
||||||
"github.com/pojntfx/stfs/pkg/config"
|
"github.com/pojntfx/stfs/pkg/config"
|
||||||
|
"github.com/pojntfx/stfs/pkg/hardware"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Fetch(
|
func Fetch(
|
||||||
state config.StateConfig,
|
state hardware.DriveConfig,
|
||||||
pipes config.PipeConfig,
|
pipes config.PipeConfig,
|
||||||
crypto config.CryptoConfig,
|
crypto config.CryptoConfig,
|
||||||
|
|
||||||
|
|||||||
@@ -14,10 +14,11 @@ import (
|
|||||||
"github.com/pojntfx/stfs/internal/signature"
|
"github.com/pojntfx/stfs/internal/signature"
|
||||||
"github.com/pojntfx/stfs/internal/tape"
|
"github.com/pojntfx/stfs/internal/tape"
|
||||||
"github.com/pojntfx/stfs/pkg/config"
|
"github.com/pojntfx/stfs/pkg/config"
|
||||||
|
"github.com/pojntfx/stfs/pkg/hardware"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Query(
|
func Query(
|
||||||
state config.StateConfig,
|
state hardware.DriveConfig,
|
||||||
pipes config.PipeConfig,
|
pipes config.PipeConfig,
|
||||||
crypto config.CryptoConfig,
|
crypto config.CryptoConfig,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user