Skip to content

Conversation

dzianisv
Copy link

This commit introduces two new commands:

  • gocryptfs -takeout CIPHERDIR PATH DESTDIR: Decrypts a specific file or directory from the encrypted filesystem and moves it to a destination, deleting the original encrypted file.
  • gocryptfs -list CIPHERDIR: Lists the decrypted file and directory names in a tree-like structure.

These commands enhance the utility of gocryptfs by providing more granular control over file decryption and better visibility into the encrypted filesystem's contents without requiring FUSE.

fix: list command outputs full decrypted file paths

The previous implementation of the list command outputted a tree-like structure and failed to decrypt special files. This commit modifies the list command to:

  • Output full, relative decrypted file paths, similar to git ls-files.
  • Correctly handle and skip special files like gocryptfs.diriv and gocryptfs.conf.
  • Decrypt each component of the path individually to ensure correct decryption of nested directories.

fix: takeout command handles plaintext paths correctly

The takeout command previously failed when provided with a plaintext path, as it attempted to directly access the encrypted equivalent. This commit refactors the takeout command to:

  • Walk the entire encrypted CIPHERDIR.
  • Decrypt each file's relative path on the fly.
  • Compare the decrypted path with the user-provided plaintext PATH.
  • Only process files and directories that match or are children of the specified PATH.
  • Add a helper function decryptRelativePath to encapsulate the path decryption logic.
  • Skip files starting with ._ to avoid decryption errors with macOS metadata files.

fix: takeout command handles longnames and special files

The takeout command previously failed when encountering longnames (hashed filenames) and special files (like macOS metadata files starting with ._). This commit addresses these issues by:

  • Adding IsLongName and ReadLongName functions to internal/nametransform/names.go to correctly identify and read the original plaintext names of longname files.
  • Modifying take_out.go to use these new functions, ensuring that longnames are properly decrypted.
  • Expanding the special file skipping logic in take_out.go to include files starting with ._, preventing decryption errors with macOS metadata.
  • Gracefully handling decryption errors for non-gocryptfs files by logging them at a debug level instead of warnings.

fix: takeout and list commands handle non-gocryptfs filenames

The takeout and list commands previously failed when encountering filenames that were not valid gocryptfs encrypted names (e.g., non-encrypted files, macOS metadata, or files copied without gocryptfs's knowledge). This commit addresses these issues by:

  • Adding IsValidBase64 function to internal/nametransform/names.go to check if a string is a valid base64 encoding.
  • Modifying decryptRelativePath in take_out.go and list.go to use IsValidBase64. If a filename component is not a valid base64 string, it is now treated as a literal plaintext name and passed through without decryption. This prevents "bad message" and "padding too long" errors.
  • Ensuring that only properly encrypted filenames are subjected to decryption, making the tools more resilient to unexpected file types.$

dzianisv added 4 commits July 15, 2025 17:32
This commit introduces two new commands:

- : Decrypts a specific file or directory from the encrypted filesystem and moves it to a destination, deleting the original encrypted file.
- : Lists the decrypted file and directory names in a tree-like structure.

These commands enhance the utility of gocryptfs v2.5.1; go-fuse [vendored]; 2025-01-23 go1.23.6 darwin/arm64

Usage: gocryptfs -init|-passwd|-info [OPTIONS] CIPHERDIR
  or   gocryptfs [OPTIONS] CIPHERDIR MOUNTPOINT

Common Options (use -hh to show all):
  -aessiv            Use AES-SIV encryption (with -init)
  -allow_other       Allow other users to access the mount
  -i, -idle          Unmount automatically after specified idle duration
  -config            Custom path to config file
  -ctlsock           Create control socket at location
  -extpass           Call external program to prompt for the password
  -fg                Stay in the foreground
  -fsck              Check filesystem integrity
  -fusedebug         Debug FUSE calls
  -h, -help          This short help text
  -hh                Long help text with all options
  -init              Initialize encrypted directory
  -info              Display information about encrypted directory
  -masterkey         Mount with explicit master key instead of password
  -nonempty          Allow mounting over non-empty directory
  -nosyslog          Do not redirect log messages to syslog
  -passfile          Read password from plain text file(s)
  -passwd            Change password
  -plaintextnames    Do not encrypt file names (with -init)
  -q, -quiet         Silence informational messages
  -reverse           Enable reverse mode
  -ro                Mount read-only
  -speed             Run crypto speed test
  -version           Print version information
  --                 Stop option parsing by providing more granular control over file decryption and better visibility into the encrypted filesystem's contents without requiring FUSE.
The  command previously failed when provided with a plaintext path, as it attempted to directly access the encrypted equivalent. This commit refactors the  command to:

- Walk the entire encrypted .
- Decrypt each file's relative path on the fly.
- Compare the decrypted path with the user-provided plaintext .
- Only process files and directories that match or are children of the specified .
- Add a helper function  to encapsulate the path decryption logic.
- Skip files starting with  to avoid decryption errors with macOS metadata files.
The  command previously failed when encountering longnames (hashed filenames) and special files (like macOS metadata files starting with ). This commit addresses these issues by:

- Adding  and  functions to  to correctly identify and read the original plaintext names of longname files.
- Modifying  to use these new functions, ensuring that longnames are properly decrypted.
- Expanding the special file skipping logic in  to include files starting with , preventing decryption errors with macOS metadata.
- Gracefully handling decryption errors for non-gocryptfs files by logging them at a debug level instead of warnings.
This commit adds a logging message to the `takeout` command, printing "Took out $src -> $dst" after a file has been successfully decrypted, moved, and the original encrypted file has been removed.
@rfjakob
Copy link
Owner

rfjakob commented Jul 15, 2025

Hi, uh, first, is this AI generated? Please declare this in the PR already.

These are big features and will need to go big in tests. I don't see a single one right now.

Copy link
Owner

@rfjakob rfjakob left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a complete review. But tests are completely missing. Will continue the review when there's some tests.

@rfjakob rfjakob changed the title feat: Add and commands feat: add -takeout, -list commands Aug 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants