Skip to content

Commit

Permalink
add filename decryption to ls
Browse files Browse the repository at this point in the history
  • Loading branch information
iychoi committed Feb 29, 2024
1 parent b93a737 commit 802ed9c
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 17 deletions.
12 changes: 12 additions & 0 deletions cmd/flag/encryption.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,21 @@ func GetEncryptionFlagValues() *EncryptionFlagValues {
encryptionFlagValues.EncryptFilename = true
}

if encryptionFlagValues.EncryptFilename {
encryptionFlagValues.Encryption = true
}

if len(encryptionFlagValues.Key) > 0 {
encryptionFlagValues.Encryption = true
}

return &encryptionFlagValues
}

func GetDecryptionFlagValues() *DecryptionFlagValues {
if len(decryptionFlagValues.Key) > 0 {
decryptionFlagValues.Decryption = true
}

return &decryptionFlagValues
}
10 changes: 10 additions & 0 deletions cmd/subcmd/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ func processGetCommand(command *cobra.Command, args []string) error {

defer filesystem.Release()

// set default key for decryption
if len(decryptionFlagValues.Key) == 0 {
decryptionFlagValues.Key = account.Password
}

targetPath := "./"
sourcePaths := args[:]

Expand Down Expand Up @@ -182,6 +187,11 @@ func getOne(parallelJobManager *commons.ParallelJobManager, inputPathMap map[str

// decrypt first if necessary
encryptionMode, encryptFilename := commons.DetectEncryptionMode(sourceEntry.Name)
if encryptionMode == commons.EncryptionModeUnknown {
// filename doesn't have .pgp.enc
encryptionMode = commons.EncryptionModePGP
encryptFilename = false
}

encryptManager := commons.NewEncryptionManager(encryptionMode, encryptFilename, []byte(decryptionFlagValues.Key))

Expand Down
72 changes: 56 additions & 16 deletions cmd/subcmd/ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func AddLsCommand(rootCmd *cobra.Command) {

flag.SetListFlags(lsCmd)
flag.SetTicketAccessFlags(lsCmd)
flag.SetDecryptionFlags(lsCmd)

rootCmd.AddCommand(lsCmd)
}
Expand Down Expand Up @@ -66,6 +67,7 @@ func processLsCommand(command *cobra.Command, args []string) error {

ticketAccessFlagValues := flag.GetTicketAccessFlagValues()
listFlagValues := flag.GetListFlagValues()
decryptionFlagValues := flag.GetDecryptionFlagValues()

appConfig := commons.GetConfig()
syncAccount := false
Expand All @@ -91,14 +93,19 @@ func processLsCommand(command *cobra.Command, args []string) error {

defer filesystem.Release()

// set default key for decryption
if len(decryptionFlagValues.Key) == 0 {
decryptionFlagValues.Key = account.Password
}

sourcePaths := args[:]

if len(args) == 0 {
sourcePaths = []string{"."}
}

for _, sourcePath := range sourcePaths {
err = listOne(filesystem, sourcePath, listFlagValues)
err = listOne(filesystem, sourcePath, listFlagValues, decryptionFlagValues)
if err != nil {
return xerrors.Errorf("failed to perform ls %s: %w", sourcePath, err)
}
Expand All @@ -107,7 +114,7 @@ func processLsCommand(command *cobra.Command, args []string) error {
return nil
}

func listOne(fs *irodsclient_fs.FileSystem, sourcePath string, listFlagValues *flag.ListFlagValues) error {
func listOne(fs *irodsclient_fs.FileSystem, sourcePath string, listFlagValues *flag.ListFlagValues, decryptionFlagValues *flag.DecryptionFlagValues) error {
cwd := commons.GetCWD()
home := commons.GetHomeDir()
zone := commons.GetZone()
Expand Down Expand Up @@ -137,7 +144,7 @@ func listOne(fs *irodsclient_fs.FileSystem, sourcePath string, listFlagValues *f
return xerrors.Errorf("failed to list data-objects in %s: %w", sourcePath, err)
}

printDataObjects(objs, listFlagValues)
printDataObjects(objs, listFlagValues, decryptionFlagValues)
printCollections(colls, listFlagValues)
return nil
}
Expand All @@ -156,7 +163,7 @@ func listOne(fs *irodsclient_fs.FileSystem, sourcePath string, listFlagValues *f
}

entries := []*irodsclient_types.IRODSDataObject{entry}
printDataObjects(entries, listFlagValues)
printDataObjects(entries, listFlagValues, decryptionFlagValues)
return nil
}

Expand Down Expand Up @@ -233,16 +240,16 @@ func getFlatReplicaSortFunction(entries []*FlatReplica, sortOrder commons.ListSo
}
}

func printDataObjects(entries []*irodsclient_types.IRODSDataObject, listFlagValues *flag.ListFlagValues) {
func printDataObjects(entries []*irodsclient_types.IRODSDataObject, listFlagValues *flag.ListFlagValues, decryptionFlagValues *flag.DecryptionFlagValues) {
if listFlagValues.Format == commons.ListFormatNormal {
sort.SliceStable(entries, getDataObjectSortFunction(entries, listFlagValues.SortOrder, listFlagValues.SortReverse))
for _, entry := range entries {
printDataObjectShort(entry)
printDataObjectShort(entry, decryptionFlagValues)
}
} else {
replicas := flattenReplicas(entries)
sort.SliceStable(replicas, getFlatReplicaSortFunction(replicas, listFlagValues.SortOrder, listFlagValues.SortReverse))
printReplicas(replicas, listFlagValues)
printReplicas(replicas, listFlagValues, decryptionFlagValues)
}
}

Expand Down Expand Up @@ -319,35 +326,68 @@ func getDataObjectModifyTime(object *irodsclient_types.IRODSDataObject) time.Tim
return maxTime
}

func printDataObjectShort(entry *irodsclient_types.IRODSDataObject) {
fmt.Printf(" %s\n", entry.Name)
func printDataObjectShort(entry *irodsclient_types.IRODSDataObject, decryptionFlagValues *flag.DecryptionFlagValues) {
newName := entry.Name

if decryptionFlagValues.Decryption {
// need to decrypted
encryptionMode, encryptFilename := commons.DetectEncryptionMode(newName)
if encryptFilename {
encryptManager := commons.NewEncryptionManager(encryptionMode, encryptFilename, []byte(decryptionFlagValues.Key))
decryptedFilename, err := encryptManager.DecryptFilename(newName)
if err != nil {
newName = fmt.Sprintf("%s\tdecryption_failed", newName)
} else {
newName = fmt.Sprintf("%s\tencrypted\t%s", decryptedFilename, newName)
}
}
}

fmt.Printf(" %s\n", newName)
}

func printReplicas(flatReplicas []*FlatReplica, listFlagValues *flag.ListFlagValues) {
func printReplicas(flatReplicas []*FlatReplica, listFlagValues *flag.ListFlagValues, decryptionFlagValues *flag.DecryptionFlagValues) {
for _, flatReplica := range flatReplicas {
printReplica(*flatReplica, listFlagValues)
printReplica(*flatReplica, listFlagValues, decryptionFlagValues)
}
}

func printReplica(flatReplica FlatReplica, listFlagValues *flag.ListFlagValues) {
func printReplica(flatReplica FlatReplica, listFlagValues *flag.ListFlagValues, decryptionFlagValues *flag.DecryptionFlagValues) {
newName := flatReplica.DataObject.Name

if decryptionFlagValues.Decryption {
// need to decrypted
encryptionMode, encryptFilename := commons.DetectEncryptionMode(newName)
if encryptFilename {
encryptManager := commons.NewEncryptionManager(encryptionMode, encryptFilename, []byte(decryptionFlagValues.Key))
decryptedFilename, err := encryptManager.DecryptFilename(newName)
if err != nil {
newName = fmt.Sprintf("%s\tdecryption_failed", newName)
} else {
newName = fmt.Sprintf("%s\tencrypted\t%s", decryptedFilename, newName)
}
}
}

size := fmt.Sprintf("%v", flatReplica.DataObject.Size)
if listFlagValues.HumanReadableSizes {
size = humanize.Bytes(uint64(flatReplica.DataObject.Size))
}

switch listFlagValues.Format {
case commons.ListFormatNormal:
fmt.Printf(" %d\t%s\n", flatReplica.Replica.Number, flatReplica.DataObject.Name)
fmt.Printf(" %d\t%s\n", flatReplica.Replica.Number, newName)
case commons.ListFormatLong:
modTime := commons.MakeDateTimeString(flatReplica.Replica.ModifyTime)
fmt.Printf(" %s\t%d\t%s\t%s\t%s\t%s\t%s\n", flatReplica.Replica.Owner, flatReplica.Replica.Number, flatReplica.Replica.ResourceHierarchy,
size, modTime, getStatusMark(flatReplica.Replica.Status), flatReplica.DataObject.Name)
size, modTime, getStatusMark(flatReplica.Replica.Status), newName)
case commons.ListFormatVeryLong:
modTime := commons.MakeDateTimeString(flatReplica.Replica.ModifyTime)
fmt.Printf(" %s\t%d\t%s\t%s\t%s\t%s\t%s\n", flatReplica.Replica.Owner, flatReplica.Replica.Number, flatReplica.Replica.ResourceHierarchy,
size, modTime, getStatusMark(flatReplica.Replica.Status), flatReplica.DataObject.Name)
size, modTime, getStatusMark(flatReplica.Replica.Status), newName)
fmt.Printf(" %s\t%s\n", flatReplica.Replica.Checksum.OriginalChecksum, flatReplica.Replica.Path)
default:
fmt.Printf(" %d\t%s\n", flatReplica.Replica.Number, flatReplica.DataObject.Name)
fmt.Printf(" %d\t%s\n", flatReplica.Replica.Number, newName)
}
}

Expand Down
5 changes: 5 additions & 0 deletions cmd/subcmd/put.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ func processPutCommand(command *cobra.Command, args []string) error {

defer filesystem.Release()

// set default key for encryption
if len(encryptionFlagValues.Key) == 0 {
encryptionFlagValues.Key = account.Password
}

targetPath := "./"
sourcePaths := args[:]

Expand Down
16 changes: 15 additions & 1 deletion commons/encrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func DetectEncryptionMode(p string) (EncryptionMode, bool) {
// winscp
return EncryptionModeWinSCP, true
} else {
return EncryptionModePGP, false
return EncryptionModeUnknown, false
}
}

Expand Down Expand Up @@ -190,9 +190,23 @@ func (manager *EncryptionManager) decryptFilenameWinSCP(filename string) (string
return "", xerrors.Errorf("failed to decrypt filename: %w", err)
}

if !manager.isCorrectFilename(decryptedFilename) {
return "", xerrors.Errorf("failed to decrypt filename with wrong key")
}

return string(decryptedFilename), nil
}

func (manager *EncryptionManager) isCorrectFilename(filename []byte) bool {
for _, c := range filename {
if c < 32 || c >= 126 {
return false
}
}

return true
}

func (manager *EncryptionManager) encryptFilenamePGP(filename string) (string, error) {
if !manager.encryptFilename {
return filename, nil
Expand Down

0 comments on commit 802ed9c

Please sign in to comment.