feat: Allow automatic re-indexing without private key
This commit is contained in:
@@ -54,6 +54,8 @@ var (
|
|||||||
|
|
||||||
errRecipientNotAccessible = errors.New("recipient/public key not found or accessible")
|
errRecipientNotAccessible = errors.New("recipient/public key not found or accessible")
|
||||||
errIdentityNotAccessible = errors.New("identity/private 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 {
|
type flusher interface {
|
||||||
@@ -99,10 +101,6 @@ var archiveCmd = &cobra.Command{
|
|||||||
if _, err := os.Stat(viper.GetString(recipientFlag)); err != nil {
|
if _, err := os.Stat(viper.GetString(recipientFlag)); err != nil {
|
||||||
return errRecipientNotAccessible
|
return errRecipientNotAccessible
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := os.Stat(viper.GetString(identityFlag)); err != nil {
|
|
||||||
return errIdentityNotAccessible
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -130,7 +128,6 @@ var archiveCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
pubkey := []byte{}
|
pubkey := []byte{}
|
||||||
privkey := []byte{}
|
|
||||||
if viper.GetString(encryptionFlag) != encryptionFormatNoneKey {
|
if viper.GetString(encryptionFlag) != encryptionFormatNoneKey {
|
||||||
p, err := ioutil.ReadFile(viper.GetString(recipientFlag))
|
p, err := ioutil.ReadFile(viper.GetString(recipientFlag))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -138,14 +135,9 @@ var archiveCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
pubkey = p
|
pubkey = p
|
||||||
|
|
||||||
privkey, err = ioutil.ReadFile(viper.GetString(identityFlag))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := archive(
|
hdrs, err := archive(
|
||||||
viper.GetString(tapeFlag),
|
viper.GetString(tapeFlag),
|
||||||
viper.GetInt(recordSizeFlag),
|
viper.GetInt(recordSizeFlag),
|
||||||
viper.GetString(srcFlag),
|
viper.GetString(srcFlag),
|
||||||
@@ -154,7 +146,8 @@ var archiveCmd = &cobra.Command{
|
|||||||
viper.GetString(compressionLevelFlag),
|
viper.GetString(compressionLevelFlag),
|
||||||
viper.GetString(encryptionFlag),
|
viper.GetString(encryptionFlag),
|
||||||
pubkey,
|
pubkey,
|
||||||
); err != nil {
|
)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +160,17 @@ var archiveCmd = &cobra.Command{
|
|||||||
viper.GetBool(overwriteFlag),
|
viper.GetBool(overwriteFlag),
|
||||||
viper.GetString(compressionFlag),
|
viper.GetString(compressionFlag),
|
||||||
viper.GetString(encryptionFlag),
|
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,
|
compressionLevel string,
|
||||||
encryptionFormat string,
|
encryptionFormat string,
|
||||||
pubkey []byte,
|
pubkey []byte,
|
||||||
) error {
|
) ([]*tar.Header, error) {
|
||||||
dirty := false
|
dirty := false
|
||||||
tw, isRegular, cleanup, err := openTapeWriter(tape)
|
tw, isRegular, cleanup, err := openTapeWriter(tape)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return []*tar.Header{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if overwrite {
|
if overwrite {
|
||||||
if isRegular {
|
if isRegular {
|
||||||
if err := cleanup(&dirty); err != nil { // dirty will always be false here
|
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)
|
f, err := os.OpenFile(tape, os.O_WRONLY|os.O_CREATE, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return []*tar.Header{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the file's content
|
// Clear the file's content
|
||||||
if err := f.Truncate(0); err != nil {
|
if err := f.Truncate(0); err != nil {
|
||||||
return err
|
return []*tar.Header{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := f.Close(); err != nil {
|
if err := f.Close(); err != nil {
|
||||||
return err
|
return []*tar.Header{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tw, isRegular, cleanup, err = openTapeWriter(tape)
|
tw, isRegular, cleanup, err = openTapeWriter(tape)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return []*tar.Header{}, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := cleanup(&dirty); err != nil { // dirty will always be false here
|
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)
|
f, err := os.OpenFile(tape, os.O_WRONLY, os.ModeCharDevice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return []*tar.Header{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seek to the start of the tape
|
// Seek to the start of the tape
|
||||||
if err := controllers.SeekToRecordOnTape(f, 0); err != nil {
|
if err := controllers.SeekToRecordOnTape(f, 0); err != nil {
|
||||||
return err
|
return []*tar.Header{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := f.Close(); err != nil {
|
if err := f.Close(); err != nil {
|
||||||
return err
|
return []*tar.Header{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tw, isRegular, cleanup, err = openTapeWriter(tape)
|
tw, isRegular, cleanup, err = openTapeWriter(tape)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return []*tar.Header{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defer cleanup(&dirty)
|
defer cleanup(&dirty)
|
||||||
|
|
||||||
|
headers := []*tar.Header{}
|
||||||
first := true
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -343,6 +347,9 @@ func archive(
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hdrToAppend := *hdr
|
||||||
|
headers = append(headers, &hdrToAppend)
|
||||||
|
|
||||||
if err := encryptHeader(hdr, encryptionFormat, pubkey); err != nil {
|
if err := encryptHeader(hdr, encryptionFormat, pubkey); err != nil {
|
||||||
return err
|
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().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(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(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()
|
viper.AutomaticEnv()
|
||||||
|
|
||||||
|
|||||||
@@ -68,6 +68,10 @@ var recoveryIndexCmd = &cobra.Command{
|
|||||||
viper.GetString(compressionFlag),
|
viper.GetString(compressionFlag),
|
||||||
viper.GetString(encryptionFlag),
|
viper.GetString(encryptionFlag),
|
||||||
privkey,
|
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,
|
compressionFormat string,
|
||||||
encryptionFormat string,
|
encryptionFormat string,
|
||||||
privkey []byte,
|
privkey []byte,
|
||||||
|
decryptHeader func(
|
||||||
|
hdr *tar.Header,
|
||||||
|
encryptionFormat string,
|
||||||
|
privkey []byte,
|
||||||
|
i int,
|
||||||
|
) error,
|
||||||
|
offset int,
|
||||||
) error {
|
) error {
|
||||||
if overwrite {
|
if overwrite {
|
||||||
f, err := os.OpenFile(metadata, os.O_WRONLY|os.O_CREATE, 0600)
|
f, err := os.OpenFile(metadata, os.O_WRONLY|os.O_CREATE, 0600)
|
||||||
@@ -119,6 +130,7 @@ func index(
|
|||||||
|
|
||||||
record := int64(record)
|
record := int64(record)
|
||||||
block := int64(block)
|
block := int64(block)
|
||||||
|
i := 0
|
||||||
|
|
||||||
for {
|
for {
|
||||||
hdr, err := tr.Next()
|
hdr, err := tr.Next()
|
||||||
@@ -169,12 +181,14 @@ func index(
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := decryptHeader(hdr, encryptionFormat, privkey); err != nil {
|
if i >= offset {
|
||||||
return err
|
if err := decryptHeader(hdr, encryptionFormat, privkey, i-offset); err != nil {
|
||||||
}
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := indexHeader(record, block, hdr, metadataPersister, compressionFormat, encryptionFormat); err != nil {
|
if err := indexHeader(record, block, hdr, metadataPersister, compressionFormat, encryptionFormat); err != nil {
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
curr, err := f.Seek(0, io.SeekCurrent)
|
curr, err := f.Seek(0, io.SeekCurrent)
|
||||||
@@ -199,6 +213,8 @@ func index(
|
|||||||
record++
|
record++
|
||||||
block = 0
|
block = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Seek to record
|
// Seek to record
|
||||||
@@ -217,6 +233,7 @@ func index(
|
|||||||
|
|
||||||
curr := int64((recordSize * controllers.BlockSize * int(record)) + (int(block) * controllers.BlockSize))
|
curr := int64((recordSize * controllers.BlockSize * int(record)) + (int(block) * controllers.BlockSize))
|
||||||
counter := &counters.CounterReader{Reader: br, BytesRead: int(curr)}
|
counter := &counters.CounterReader{Reader: br, BytesRead: int(curr)}
|
||||||
|
i := 0
|
||||||
|
|
||||||
tr := tar.NewReader(counter)
|
tr := tar.NewReader(counter)
|
||||||
for {
|
for {
|
||||||
@@ -246,12 +263,14 @@ func index(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := decryptHeader(hdr, encryptionFormat, privkey); err != nil {
|
if i >= offset {
|
||||||
return err
|
if err := decryptHeader(hdr, encryptionFormat, privkey, i-offset); err != nil {
|
||||||
}
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := indexHeader(record, block, hdr, metadataPersister, compressionFormat, encryptionFormat); err != nil {
|
if err := indexHeader(record, block, hdr, metadataPersister, compressionFormat, encryptionFormat); err != nil {
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
curr = int64(counter.BytesRead)
|
curr = int64(counter.BytesRead)
|
||||||
@@ -270,6 +289,8 @@ func index(
|
|||||||
record++
|
record++
|
||||||
block = 0
|
block = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,6 @@ var updateCmd = &cobra.Command{
|
|||||||
if _, err := os.Stat(viper.GetString(recipientFlag)); err != nil {
|
if _, err := os.Stat(viper.GetString(recipientFlag)); err != nil {
|
||||||
return errRecipientNotAccessible
|
return errRecipientNotAccessible
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := os.Stat(viper.GetString(identityFlag)); err != nil {
|
|
||||||
return errIdentityNotAccessible
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -67,7 +63,6 @@ var updateCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
pubkey := []byte{}
|
pubkey := []byte{}
|
||||||
privkey := []byte{}
|
|
||||||
if viper.GetString(encryptionFlag) != encryptionFormatNoneKey {
|
if viper.GetString(encryptionFlag) != encryptionFormatNoneKey {
|
||||||
p, err := ioutil.ReadFile(viper.GetString(recipientFlag))
|
p, err := ioutil.ReadFile(viper.GetString(recipientFlag))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -75,14 +70,9 @@ var updateCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
pubkey = p
|
pubkey = p
|
||||||
|
|
||||||
privkey, err = ioutil.ReadFile(viper.GetString(identityFlag))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := update(
|
hdrs, err := update(
|
||||||
viper.GetString(tapeFlag),
|
viper.GetString(tapeFlag),
|
||||||
viper.GetInt(recordSizeFlag),
|
viper.GetInt(recordSizeFlag),
|
||||||
viper.GetString(srcFlag),
|
viper.GetString(srcFlag),
|
||||||
@@ -91,7 +81,8 @@ var updateCmd = &cobra.Command{
|
|||||||
viper.GetString(compressionLevelFlag),
|
viper.GetString(compressionLevelFlag),
|
||||||
viper.GetString(encryptionFlag),
|
viper.GetString(encryptionFlag),
|
||||||
pubkey,
|
pubkey,
|
||||||
); err != nil {
|
)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +95,17 @@ var updateCmd = &cobra.Command{
|
|||||||
false,
|
false,
|
||||||
viper.GetString(compressionFlag),
|
viper.GetString(compressionFlag),
|
||||||
viper.GetString(encryptionFlag),
|
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,
|
compressionLevel string,
|
||||||
encryptionFormat string,
|
encryptionFormat string,
|
||||||
pubkey []byte,
|
pubkey []byte,
|
||||||
) error {
|
) ([]*tar.Header, error) {
|
||||||
dirty := false
|
dirty := false
|
||||||
tw, isRegular, cleanup, err := openTapeWriter(tape)
|
tw, isRegular, cleanup, err := openTapeWriter(tape)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return []*tar.Header{}, err
|
||||||
}
|
}
|
||||||
defer cleanup(&dirty)
|
defer cleanup(&dirty)
|
||||||
|
|
||||||
|
headers := []*tar.Header{}
|
||||||
first := true
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -237,6 +239,9 @@ func update(
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hdrToAppend := *hdr
|
||||||
|
headers = append(headers, &hdrToAppend)
|
||||||
|
|
||||||
if err := encryptHeader(hdr, encryptionFormat, pubkey); err != nil {
|
if err := encryptHeader(hdr, encryptionFormat, pubkey); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -304,6 +309,9 @@ func update(
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hdrToAppend := *hdr
|
||||||
|
headers = append(headers, &hdrToAppend)
|
||||||
|
|
||||||
if err := encryptHeader(hdr, encryptionFormat, pubkey); err != nil {
|
if err := encryptHeader(hdr, encryptionFormat, pubkey); err != nil {
|
||||||
return err
|
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().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(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(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()
|
viper.AutomaticEnv()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user