diff options
Diffstat (limited to 'internal/fusefrontend_reverse')
| -rw-r--r-- | internal/fusefrontend_reverse/rfs.go | 21 | ||||
| -rw-r--r-- | internal/fusefrontend_reverse/rpath.go | 6 | 
2 files changed, 27 insertions, 0 deletions
| diff --git a/internal/fusefrontend_reverse/rfs.go b/internal/fusefrontend_reverse/rfs.go index 6089d41..cfe23b6 100644 --- a/internal/fusefrontend_reverse/rfs.go +++ b/internal/fusefrontend_reverse/rfs.go @@ -1,6 +1,7 @@  package fusefrontend_reverse  import ( +	"encoding/base64"  	"fmt"  	"os"  	"path/filepath" @@ -275,3 +276,23 @@ func (rfs *reverseFS) OpenDir(cipherPath string, context *fuse.Context) ([]fuse.  func (rfs *reverseFS) StatFs(name string) *fuse.StatfsOut {  	return rfs.loopbackfs.StatFs(name)  } + +// Readlink - FUSE call +func (rfs *reverseFS) Readlink(cipherPath string, context *fuse.Context) (string, fuse.Status) { +	absPath, err := rfs.abs(rfs.decryptPath(cipherPath)) +	if err != nil { +		return "", fuse.ToStatus(err) +	} +	plainTarget, err := os.Readlink(absPath) +	if err != nil { +		return "", fuse.ToStatus(err) +	} +	if rfs.args.PlaintextNames { +		return plainTarget, fuse.OK +	} +	nonce := derivePathIV(cipherPath) +	// Symlinks are encrypted like file contents and base64-encoded +	cBinTarget := rfs.contentEnc.EncryptBlock([]byte(plainTarget), 0, nil, contentenc.ExternalNonce, nonce) +	cTarget := base64.URLEncoding.EncodeToString(cBinTarget) +	return cTarget, fuse.OK +} diff --git a/internal/fusefrontend_reverse/rpath.go b/internal/fusefrontend_reverse/rpath.go index c603cad..6d418e0 100644 --- a/internal/fusefrontend_reverse/rpath.go +++ b/internal/fusefrontend_reverse/rpath.go @@ -47,6 +47,12 @@ func (rfs *reverseFS) decryptPath(relPath string) (string, error) {  				if _, ok := err.(base64.CorruptInputError); ok {  					return "", syscall.ENOENT  				} +				// Stat attempts on the link target of encrypted symlinks. +				// These are always valid base64 but the length is not a +				// multiple of 16. +				if err == syscall.EINVAL { +					return "", syscall.ENOENT +				}  				return "", err  			}  		} else if nameType == nametransform.LongNameContent { | 
