feat: Allow automatic re-indexing without private key

This commit is contained in:
Felicitas Pojtinger
2021-12-02 12:16:05 +01:00
parent f4dc9f9f52
commit b5a99751de
3 changed files with 88 additions and 54 deletions

View File

@@ -54,6 +54,8 @@ var (
errRecipientNotAccessible = errors.New("recipient/public key not found or accessible")
errIdentityNotAccessible = errors.New("identity/private key not found or accessible")
errMissingTarHeader = errors.New("tar header is missing")
)
type flusher interface {
@@ -99,10 +101,6 @@ var archiveCmd = &cobra.Command{
if _, err := os.Stat(viper.GetString(recipientFlag)); err != nil {
return errRecipientNotAccessible
}
if _, err := os.Stat(viper.GetString(identityFlag)); err != nil {
return errIdentityNotAccessible
}
}
return nil
@@ -130,7 +128,6 @@ var archiveCmd = &cobra.Command{
}
pubkey := []byte{}
privkey := []byte{}
if viper.GetString(encryptionFlag) != encryptionFormatNoneKey {
p, err := ioutil.ReadFile(viper.GetString(recipientFlag))
if err != nil {
@@ -138,14 +135,9 @@ var archiveCmd = &cobra.Command{
}
pubkey = p
privkey, err = ioutil.ReadFile(viper.GetString(identityFlag))
if err != nil {
return err
}
}
if err := archive(
hdrs, err := archive(
viper.GetString(tapeFlag),
viper.GetInt(recordSizeFlag),
viper.GetString(srcFlag),
@@ -154,7 +146,8 @@ var archiveCmd = &cobra.Command{
viper.GetString(compressionLevelFlag),
viper.GetString(encryptionFlag),
pubkey,
); err != nil {
)
if err != nil {
return err
}
@@ -167,7 +160,17 @@ var archiveCmd = &cobra.Command{
viper.GetBool(overwriteFlag),
viper.GetString(compressionFlag),
viper.GetString(encryptionFlag),
privkey,
[]byte{},
func(hdr *tar.Header, encryptionFormat string, privkey []byte, i int) error {
if len(hdrs) <= i {
return errMissingTarHeader
}
*hdr = *hdrs[i]
return nil
},
0,
)
},
}
@@ -181,67 +184,68 @@ func archive(
compressionLevel string,
encryptionFormat string,
pubkey []byte,
) error {
) ([]*tar.Header, error) {
dirty := false
tw, isRegular, cleanup, err := openTapeWriter(tape)
if err != nil {
return err
return []*tar.Header{}, err
}
if overwrite {
if isRegular {
if err := cleanup(&dirty); err != nil { // dirty will always be false here
return err
return []*tar.Header{}, err
}
f, err := os.OpenFile(tape, os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
return err
return []*tar.Header{}, err
}
// Clear the file's content
if err := f.Truncate(0); err != nil {
return err
return []*tar.Header{}, err
}
if err := f.Close(); err != nil {
return err
return []*tar.Header{}, err
}
tw, isRegular, cleanup, err = openTapeWriter(tape)
if err != nil {
return err
return []*tar.Header{}, err
}
} else {
if err := cleanup(&dirty); err != nil { // dirty will always be false here
return err
return []*tar.Header{}, err
}
f, err := os.OpenFile(tape, os.O_WRONLY, os.ModeCharDevice)
if err != nil {
return err
return []*tar.Header{}, err
}
// Seek to the start of the tape
if err := controllers.SeekToRecordOnTape(f, 0); err != nil {
return err
return []*tar.Header{}, err
}
if err := f.Close(); err != nil {
return err
return []*tar.Header{}, err
}
tw, isRegular, cleanup, err = openTapeWriter(tape)
if err != nil {
return err
return []*tar.Header{}, err
}
}
}
defer cleanup(&dirty)
headers := []*tar.Header{}
first := true
return filepath.Walk(src, func(path string, info fs.FileInfo, err error) error {
return headers, filepath.Walk(src, func(path string, info fs.FileInfo, err error) error {
if err != nil {
return err
}
@@ -343,6 +347,9 @@ func archive(
return err
}
hdrToAppend := *hdr
headers = append(headers, &hdrToAppend)
if err := encryptHeader(hdr, encryptionFormat, pubkey); err != nil {
return err
}
@@ -657,7 +664,6 @@ func init() {
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", compressionLevelBalanced, fmt.Sprintf("Compression level to use (default %v, available are %v)", compressionLevelBalanced, knownCompressionLevels))
archiveCmd.PersistentFlags().StringP(recipientFlag, "r", "", "Path to public key of recipient to encrypt for")
archiveCmd.PersistentFlags().StringP(identityFlag, "i", "", "Path to private key of recipient that has been encrypted for")
viper.AutomaticEnv()

View File

@@ -68,6 +68,10 @@ var recoveryIndexCmd = &cobra.Command{
viper.GetString(compressionFlag),
viper.GetString(encryptionFlag),
privkey,
func(hdr *tar.Header, encryptionFormat string, privkey []byte, i int) error {
return decryptHeader(hdr, encryptionFormat, privkey)
},
0,
)
},
}
@@ -82,6 +86,13 @@ func index(
compressionFormat string,
encryptionFormat string,
privkey []byte,
decryptHeader func(
hdr *tar.Header,
encryptionFormat string,
privkey []byte,
i int,
) error,
offset int,
) error {
if overwrite {
f, err := os.OpenFile(metadata, os.O_WRONLY|os.O_CREATE, 0600)
@@ -119,6 +130,7 @@ func index(
record := int64(record)
block := int64(block)
i := 0
for {
hdr, err := tr.Next()
@@ -169,12 +181,14 @@ func index(
break
}
if err := decryptHeader(hdr, encryptionFormat, privkey); err != nil {
return err
}
if i >= offset {
if err := decryptHeader(hdr, encryptionFormat, privkey, i-offset); err != nil {
return err
}
if err := indexHeader(record, block, hdr, metadataPersister, compressionFormat, encryptionFormat); err != nil {
return nil
if err := indexHeader(record, block, hdr, metadataPersister, compressionFormat, encryptionFormat); err != nil {
return nil
}
}
curr, err := f.Seek(0, io.SeekCurrent)
@@ -199,6 +213,8 @@ func index(
record++
block = 0
}
i++
}
} else {
// Seek to record
@@ -217,6 +233,7 @@ func index(
curr := int64((recordSize * controllers.BlockSize * int(record)) + (int(block) * controllers.BlockSize))
counter := &counters.CounterReader{Reader: br, BytesRead: int(curr)}
i := 0
tr := tar.NewReader(counter)
for {
@@ -246,12 +263,14 @@ func index(
}
}
if err := decryptHeader(hdr, encryptionFormat, privkey); err != nil {
return err
}
if i >= offset {
if err := decryptHeader(hdr, encryptionFormat, privkey, i-offset); err != nil {
return err
}
if err := indexHeader(record, block, hdr, metadataPersister, compressionFormat, encryptionFormat); err != nil {
return nil
if err := indexHeader(record, block, hdr, metadataPersister, compressionFormat, encryptionFormat); err != nil {
return nil
}
}
curr = int64(counter.BytesRead)
@@ -270,6 +289,8 @@ func index(
record++
block = 0
}
i++
}
}

View File

@@ -39,10 +39,6 @@ var updateCmd = &cobra.Command{
if _, err := os.Stat(viper.GetString(recipientFlag)); err != nil {
return errRecipientNotAccessible
}
if _, err := os.Stat(viper.GetString(identityFlag)); err != nil {
return errIdentityNotAccessible
}
}
return nil
@@ -67,7 +63,6 @@ var updateCmd = &cobra.Command{
}
pubkey := []byte{}
privkey := []byte{}
if viper.GetString(encryptionFlag) != encryptionFormatNoneKey {
p, err := ioutil.ReadFile(viper.GetString(recipientFlag))
if err != nil {
@@ -75,14 +70,9 @@ var updateCmd = &cobra.Command{
}
pubkey = p
privkey, err = ioutil.ReadFile(viper.GetString(identityFlag))
if err != nil {
return err
}
}
if err := update(
hdrs, err := update(
viper.GetString(tapeFlag),
viper.GetInt(recordSizeFlag),
viper.GetString(srcFlag),
@@ -91,7 +81,8 @@ var updateCmd = &cobra.Command{
viper.GetString(compressionLevelFlag),
viper.GetString(encryptionFlag),
pubkey,
); err != nil {
)
if err != nil {
return err
}
@@ -104,7 +95,17 @@ var updateCmd = &cobra.Command{
false,
viper.GetString(compressionFlag),
viper.GetString(encryptionFlag),
privkey,
[]byte{},
func(hdr *tar.Header, encryptionFormat string, privkey []byte, i int) error {
if len(hdrs) <= i {
return errMissingTarHeader
}
*hdr = *hdrs[i]
return nil
},
1,
)
},
}
@@ -118,16 +119,17 @@ func update(
compressionLevel string,
encryptionFormat string,
pubkey []byte,
) error {
) ([]*tar.Header, error) {
dirty := false
tw, isRegular, cleanup, err := openTapeWriter(tape)
if err != nil {
return err
return []*tar.Header{}, err
}
defer cleanup(&dirty)
headers := []*tar.Header{}
first := true
return filepath.Walk(src, func(path string, info fs.FileInfo, err error) error {
return headers, filepath.Walk(src, func(path string, info fs.FileInfo, err error) error {
if err != nil {
return err
}
@@ -237,6 +239,9 @@ func update(
return err
}
hdrToAppend := *hdr
headers = append(headers, &hdrToAppend)
if err := encryptHeader(hdr, encryptionFormat, pubkey); err != nil {
return err
}
@@ -304,6 +309,9 @@ func update(
return err
}
hdrToAppend := *hdr
headers = append(headers, &hdrToAppend)
if err := encryptHeader(hdr, encryptionFormat, pubkey); err != nil {
return err
}
@@ -325,7 +333,6 @@ func init() {
updateCmd.PersistentFlags().BoolP(overwriteFlag, "o", false, "Replace the content on the tape or tar file")
updateCmd.PersistentFlags().StringP(compressionLevelFlag, "l", compressionLevelBalanced, fmt.Sprintf("Compression level to use (default %v, available are %v)", compressionLevelBalanced, knownCompressionLevels))
updateCmd.PersistentFlags().StringP(recipientFlag, "r", "", "Path to public key of recipient to encrypt for")
updateCmd.PersistentFlags().StringP(identityFlag, "i", "", "Path to private key of recipient that has been encrypted for")
viper.AutomaticEnv()