Opening plaintext names volumes
This commit is contained in:
parent
4d47306b29
commit
e63981c788
@ -15,8 +15,8 @@ android {
|
|||||||
applicationId "sushi.hardcore.droidfs"
|
applicationId "sushi.hardcore.droidfs"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 9
|
versionCode 10
|
||||||
versionName "1.4.1"
|
versionName "1.4.2"
|
||||||
|
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters 'x86_64', 'armeabi-v7a', 'arm64-v8a'
|
abiFilters 'x86_64', 'armeabi-v7a', 'arm64-v8a'
|
||||||
@ -56,11 +56,11 @@ dependencies {
|
|||||||
implementation "com.github.bumptech.glide:glide:4.11.0"
|
implementation "com.github.bumptech.glide:glide:4.11.0"
|
||||||
implementation "com.google.android.exoplayer:exoplayer-core:2.11.7"
|
implementation "com.google.android.exoplayer:exoplayer-core:2.11.7"
|
||||||
implementation "com.google.android.exoplayer:exoplayer-ui:2.11.7"
|
implementation "com.google.android.exoplayer:exoplayer-ui:2.11.7"
|
||||||
implementation "androidx.biometric:biometric:1.0.1"
|
implementation "androidx.biometric:biometric:1.1.0"
|
||||||
|
|
||||||
def camerax_version = "1.0.0-rc01"
|
def camerax_version = "1.1.0-alpha01"
|
||||||
implementation "androidx.camera:camera-camera2:$camerax_version"
|
implementation "androidx.camera:camera-camera2:$camerax_version"
|
||||||
implementation "androidx.camera:camera-lifecycle:$camerax_version"
|
implementation "androidx.camera:camera-lifecycle:$camerax_version"
|
||||||
implementation "androidx.camera:camera-view:1.0.0-alpha20"
|
implementation "androidx.camera:camera-view:1.0.0-alpha21"
|
||||||
implementation "androidx.camera:camera-extensions:1.0.0-alpha20"
|
implementation "androidx.camera:camera-extensions:1.0.0-alpha21"
|
||||||
}
|
}
|
||||||
|
@ -2,25 +2,25 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"C"
|
"C"
|
||||||
"crypto/cipher"
|
|
||||||
"crypto/aes"
|
|
||||||
"syscall"
|
|
||||||
"strings"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"unsafe"
|
"crypto/aes"
|
||||||
"os"
|
"crypto/cipher"
|
||||||
"io"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"./gocryptfs_internal/cryptocore"
|
"./gocryptfs_internal/cryptocore"
|
||||||
"./gocryptfs_internal/stupidgcm"
|
|
||||||
"./gocryptfs_internal/eme"
|
"./gocryptfs_internal/eme"
|
||||||
"./gocryptfs_internal/nametransform"
|
"./gocryptfs_internal/nametransform"
|
||||||
"./rewrites/syscallcompat"
|
"./gocryptfs_internal/stupidgcm"
|
||||||
"./rewrites/configfile"
|
"./rewrites/configfile"
|
||||||
"./rewrites/contentenc"
|
"./rewrites/contentenc"
|
||||||
|
"./rewrites/syscallcompat"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -40,6 +40,7 @@ type File struct {
|
|||||||
|
|
||||||
type SessionVars struct {
|
type SessionVars struct {
|
||||||
root_cipher_dir string
|
root_cipher_dir string
|
||||||
|
plainTextNames bool
|
||||||
nameTransform *nametransform.NameTransform
|
nameTransform *nametransform.NameTransform
|
||||||
cryptoCore *cryptocore.CryptoCore
|
cryptoCore *cryptocore.CryptoCore
|
||||||
contentEnc *contentenc.ContentEnc
|
contentEnc *contentenc.ContentEnc
|
||||||
@ -72,6 +73,16 @@ func clear_dirCache(sessionID int) {
|
|||||||
|
|
||||||
func openBackingDir(sessionID int, relPath string) (dirfd int, cName string, err error) {
|
func openBackingDir(sessionID int, relPath string) (dirfd int, cName string, err error) {
|
||||||
dirRelPath := nametransform.Dir(relPath)
|
dirRelPath := nametransform.Dir(relPath)
|
||||||
|
// With PlaintextNames, we don't need to read DirIVs. Easy.
|
||||||
|
if sessions[sessionID].plainTextNames {
|
||||||
|
dirfd, err = syscallcompat.OpenDirNofollow(sessions[sessionID].root_cipher_dir, dirRelPath)
|
||||||
|
if err != nil {
|
||||||
|
return -1, "", err
|
||||||
|
}
|
||||||
|
// If relPath is empty, cName is ".".
|
||||||
|
cName = filepath.Base(relPath)
|
||||||
|
return dirfd, cName, nil
|
||||||
|
}
|
||||||
dir, ok := sessions[sessionID].dirCache[dirRelPath]
|
dir, ok := sessions[sessionID].dirCache[dirRelPath]
|
||||||
if ok {
|
if ok {
|
||||||
// If relPath is empty, cName is ".".
|
// If relPath is empty, cName is ".".
|
||||||
@ -487,6 +498,9 @@ func init_new_session(root_cipher_dir string, masterkey []byte, cf *configfile.C
|
|||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
var new_session SessionVars
|
var new_session SessionVars
|
||||||
|
|
||||||
|
new_session.plainTextNames = cf.IsFeatureFlagSet(configfile.FlagPlaintextNames)
|
||||||
|
|
||||||
emeCipher = eme.New(emeBlockCipher)
|
emeCipher = eme.New(emeBlockCipher)
|
||||||
new_session.nameTransform = nametransform.New(emeCipher, true, true)
|
new_session.nameTransform = nametransform.New(emeCipher, true, true)
|
||||||
|
|
||||||
@ -524,7 +538,7 @@ func init_new_session(root_cipher_dir string, masterkey []byte, cf *configfile.C
|
|||||||
if sessions == nil {
|
if sessions == nil {
|
||||||
sessions = make(map[int]SessionVars)
|
sessions = make(map[int]SessionVars)
|
||||||
}
|
}
|
||||||
sessions[sessionID] = new_session;
|
sessions[sessionID] = new_session
|
||||||
return sessionID
|
return sessionID
|
||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
@ -614,11 +628,13 @@ func gcf_list_dir(sessionID int, dirName string) (*C.char, *C.int, C.int) {
|
|||||||
}
|
}
|
||||||
// Get DirIV (stays nil if PlaintextNames is used)
|
// Get DirIV (stays nil if PlaintextNames is used)
|
||||||
var cachedIV []byte
|
var cachedIV []byte
|
||||||
|
if !sessions[sessionID].plainTextNames {
|
||||||
// Read the DirIV from disk
|
// Read the DirIV from disk
|
||||||
cachedIV, err = nametransform.ReadDirIVAt(fd)
|
cachedIV, err = nametransform.ReadDirIVAt(fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, 0
|
return nil, nil, 0
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Decrypted directory entries
|
// Decrypted directory entries
|
||||||
var plain strings.Builder
|
var plain strings.Builder
|
||||||
var modes []uint32
|
var modes []uint32
|
||||||
@ -629,6 +645,11 @@ func gcf_list_dir(sessionID int, dirName string) (*C.char, *C.int, C.int) {
|
|||||||
// silently ignore "gocryptfs.conf" in the top level dir
|
// silently ignore "gocryptfs.conf" in the top level dir
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if sessions[sessionID].plainTextNames {
|
||||||
|
plain.WriteString(cipherEntries[i].Name + "\x00")
|
||||||
|
modes = append(modes, cipherEntries[i].Mode)
|
||||||
|
continue
|
||||||
|
}
|
||||||
if cName == nametransform.DirIVFilename {
|
if cName == nametransform.DirIVFilename {
|
||||||
// silently ignore "gocryptfs.diriv" everywhere if dirIV is enabled
|
// silently ignore "gocryptfs.diriv" everywhere if dirIV is enabled
|
||||||
continue
|
continue
|
||||||
@ -670,6 +691,18 @@ func gcf_mkdir(sessionID int, newPath string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
defer syscall.Close(dirfd)
|
defer syscall.Close(dirfd)
|
||||||
|
|
||||||
|
if sessions[sessionID].plainTextNames {
|
||||||
|
err = syscallcompat.Mkdirat(dirfd, cName, folder_mode)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
var ust unix.Stat_t
|
||||||
|
err = syscallcompat.Fstatat(dirfd, cName, &ust, unix.AT_SYMLINK_NOFOLLOW)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// We need write and execute permissions to create gocryptfs.diriv.
|
// We need write and execute permissions to create gocryptfs.diriv.
|
||||||
// Also, we need read permissions to open the directory (to avoid
|
// Also, we need read permissions to open the directory (to avoid
|
||||||
// race-conditions between getting and setting the mode).
|
// race-conditions between getting and setting the mode).
|
||||||
@ -718,6 +751,7 @@ func gcf_mkdir(sessionID int, newPath string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -729,6 +763,11 @@ func gcf_rmdir(sessionID int, relPath string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
defer syscall.Close(parentDirFd)
|
defer syscall.Close(parentDirFd)
|
||||||
|
if sessions[sessionID].plainTextNames {
|
||||||
|
// Unlinkat with AT_REMOVEDIR is equivalent to Rmdir
|
||||||
|
err = unix.Unlinkat(parentDirFd, cName, unix.AT_REMOVEDIR)
|
||||||
|
return err_to_bool(err)
|
||||||
|
}
|
||||||
dirfd, err := syscallcompat.Openat(parentDirFd, cName, syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NOFOLLOW, 0)
|
dirfd, err := syscallcompat.Openat(parentDirFd, cName, syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NOFOLLOW, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
@ -797,7 +836,7 @@ func gcf_open_write_mode(sessionID int, path string) int {
|
|||||||
defer syscall.Close(dirfd)
|
defer syscall.Close(dirfd)
|
||||||
fd := -1
|
fd := -1
|
||||||
// Handle long file name
|
// Handle long file name
|
||||||
if nametransform.IsLongContent(cName) {
|
if !sessions[sessionID].plainTextNames && nametransform.IsLongContent(cName) {
|
||||||
// Create ".name"
|
// Create ".name"
|
||||||
err = sessions[sessionID].nameTransform.WriteLongNameAt(dirfd, cName, path)
|
err = sessions[sessionID].nameTransform.WriteLongNameAt(dirfd, cName, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -851,7 +890,7 @@ func gcf_close_file(sessionID, handleID int){
|
|||||||
func gcf_read_file(sessionID, handleID int, offset uint64, dst_buff []byte) uint32 {
|
func gcf_read_file(sessionID, handleID int, offset uint64, dst_buff []byte) uint32 {
|
||||||
length := uint64(len(dst_buff))
|
length := uint64(len(dst_buff))
|
||||||
if length > contentenc.MAX_KERNEL_WRITE {
|
if length > contentenc.MAX_KERNEL_WRITE {
|
||||||
return 0;
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
out, _ := doRead(sessionID, handleID, dst_buff[:0], offset, length)
|
out, _ := doRead(sessionID, handleID, dst_buff[:0], offset, length)
|
||||||
@ -863,7 +902,7 @@ func gcf_read_file(sessionID, handleID int, offset uint64, dst_buff []byte) uint
|
|||||||
func gcf_write_file(sessionID, handleID int, offset uint64, data []byte) uint32 {
|
func gcf_write_file(sessionID, handleID int, offset uint64, data []byte) uint32 {
|
||||||
length := uint64(len(data))
|
length := uint64(len(data))
|
||||||
if length > contentenc.MAX_KERNEL_WRITE {
|
if length > contentenc.MAX_KERNEL_WRITE {
|
||||||
return 0;
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
written, _ := doWrite(sessionID, handleID, data, offset)
|
written, _ := doWrite(sessionID, handleID, data, offset)
|
||||||
@ -899,6 +938,11 @@ func gcf_rename(sessionID int, oldPath string, newPath string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
defer syscall.Close(newDirfd)
|
defer syscall.Close(newDirfd)
|
||||||
|
|
||||||
|
// Easy case.
|
||||||
|
if sessions[sessionID].plainTextNames {
|
||||||
|
return err_to_bool(syscallcompat.Renameat(oldDirfd, oldCName, newDirfd, newCName))
|
||||||
|
}
|
||||||
// Long destination file name: create .name file
|
// Long destination file name: create .name file
|
||||||
nameFileAlreadyThere := false
|
nameFileAlreadyThere := false
|
||||||
if nametransform.IsLongContent(newCName) {
|
if nametransform.IsLongContent(newCName) {
|
||||||
@ -950,7 +994,7 @@ func gcf_remove_file(sessionID int, path string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// Delete ".name" file
|
// Delete ".name" file
|
||||||
if nametransform.IsLongContent(cName) {
|
if !sessions[sessionID].plainTextNames && nametransform.IsLongContent(cName) {
|
||||||
err = nametransform.DeleteLongNameAt(dirfd, cName)
|
err = nametransform.DeleteLongNameAt(dirfd, cName)
|
||||||
}
|
}
|
||||||
return err_to_bool(err)
|
return err_to_bool(err)
|
||||||
|
Loading…
Reference in New Issue
Block a user