Compare commits

...

13 Commits

Author SHA1 Message Date
Jakob Unterwurzacher a55b3cc15a tests/matrix: fix data race in TestConcurrentReadWrite
Fixes https://github.com/golang/go/issues/54715

Output was:

$ go test ./tests/matrix -run TestConcurrentReadWrite -race
test_helpers: warning: testParentDir "/tmp/gocryptfs-test-parent-1026" does not reside on ext4, we will miss failures caused by ino reuse
PASS
PASS
==================
WARNING: DATA RACE
Write at 0x00c00038a0e0 by goroutine 63:
  runtime.racewriterange()
      <autogenerated>:1 +0x29
  internal/poll.(*FD).Pread()
      /usr/local/go/src/internal/poll/fd_unix.go:193 +0x169
  os.(*File).pread()
      /usr/local/go/src/os/file_posix.go:40 +0x335
  os.(*File).ReadAt()
      /usr/local/go/src/os/file.go:136 +0x2de
  github.com/rfjakob/gocryptfs/v2/tests/matrix.TestConcurrentReadWrite.func1()
      /home/jakob/go/src/github.com/rfjakob/gocryptfs/tests/matrix/concurrency_test.go:40 +0x14b

Previous write at 0x00c00038a0e0 by goroutine 61:
  runtime.racewriterange()
      <autogenerated>:1 +0x29
  internal/poll.(*FD).Pread()
      /usr/local/go/src/internal/poll/fd_unix.go:193 +0x169
  os.(*File).pread()
      /usr/local/go/src/os/file_posix.go:40 +0x335
  os.(*File).ReadAt()
      /usr/local/go/src/os/file.go:136 +0x2de
  github.com/rfjakob/gocryptfs/v2/tests/matrix.TestConcurrentReadWrite.func1()
      /home/jakob/go/src/github.com/rfjakob/gocryptfs/tests/matrix/concurrency_test.go:40 +0x14b

Goroutine 63 (running) created at:
  github.com/rfjakob/gocryptfs/v2/tests/matrix.TestConcurrentReadWrite()
      /home/jakob/go/src/github.com/rfjakob/gocryptfs/tests/matrix/concurrency_test.go:34 +0x31d
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:1446 +0x216
  testing.(*T).Run.func1()
      /usr/local/go/src/testing/testing.go:1493 +0x47

Goroutine 61 (running) created at:
  github.com/rfjakob/gocryptfs/v2/tests/matrix.TestConcurrentReadWrite()
      /home/jakob/go/src/github.com/rfjakob/gocryptfs/tests/matrix/concurrency_test.go:34 +0x31d
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:1446 +0x216
  testing.(*T).Run.func1()
      /usr/local/go/src/testing/testing.go:1493 +0x47
==================
--- FAIL: TestConcurrentReadWrite (0.03s)
    testing.go:1319: race detected during execution of test
FAIL
TestMain: matrix[2] = matrix.testcaseMatrix{plaintextnames:false, openssl:"false", aessiv:false, raw64:false, extraArgs:[]string(nil)} failed
FAIL	github.com/rfjakob/gocryptfs/v2/tests/matrix	0.170s
FAIL
2022-08-28 20:31:27 +02:00
Jakob Unterwurzacher 59165f0f53 github ci: add new stable Go versions 2022-08-28 12:10:25 +02:00
Jakob Unterwurzacher 4bd1a8db4c README: Update Changelog for v2.3 2022-08-28 12:04:44 +02:00
Jakob Unterwurzacher 6677d8f1d5 Replace remaining golang.org/x/crypto/ssh/terminal ref with golang.org/x/term
Fixes https://github.com/rfjakob/gocryptfs/issues/681
Fixes 2a25c3a8fd
2022-08-28 12:03:34 +02:00
Jakob Unterwurzacher 003a7fa2e5 make format 2022-08-28 11:11:36 +02:00
NekoGirlSAIKOU 4808adc761 Add comment to pass Codacy Static Code Analysis 2022-08-28 11:09:06 +02:00
NekoGirlSAIKOU 1bff80b46c Fix invalid -longnamemax for reverse mode 2022-08-28 11:09:01 +02:00
Jakob Unterwurzacher bf29c9f99d tests: add TestLongnamemax100Reverse
Fails right now as reported in https://github.com/rfjakob/gocryptfs/pull/655

--- FAIL: TestLongnamemax100Reverse (0.09s)
    longnamemax_test.go:104: l=64: should see a longname now
    longnamemax_test.go:104: l=65: should see a longname now
    longnamemax_test.go:104: l=66: should see a longname now
    longnamemax_test.go:104: l=67: should see a longname now
    longnamemax_test.go:104: l=68: should see a longname now
    longnamemax_test.go:104: l=69: should see a longname now
    longnamemax_test.go:104: l=70: should see a longname now
    longnamemax_test.go:104: l=71: should see a longname now
    longnamemax_test.go:104: l=72: should see a longname now
    longnamemax_test.go:104: l=73: should see a longname now
    longnamemax_test.go:104: l=74: should see a longname now
    longnamemax_test.go:104: l=75: should see a longname now
    longnamemax_test.go:104: l=76: should see a longname now
    longnamemax_test.go:104: l=77: should see a longname now
    longnamemax_test.go:104: l=78: should see a longname now
    longnamemax_test.go:104: l=79: should see a longname now
    longnamemax_test.go:104: l=80: should see a longname now
    longnamemax_test.go:104: l=81: should see a longname now
    longnamemax_test.go:104: l=82: should see a longname now
    longnamemax_test.go:104: l=83: should see a longname now
    longnamemax_test.go:104: l=84: should see a longname now
    longnamemax_test.go:104: l=85: should see a longname now
    longnamemax_test.go:104: l=86: should see a longname now
    longnamemax_test.go:104: l=87: should see a longname now
    longnamemax_test.go:104: l=88: should see a longname now
    longnamemax_test.go:104: l=89: should see a longname now
    longnamemax_test.go:104: l=90: should see a longname now
    longnamemax_test.go:104: l=91: should see a longname now
    longnamemax_test.go:104: l=92: should see a longname now
    longnamemax_test.go:104: l=93: should see a longname now
    longnamemax_test.go:104: l=94: should see a longname now
    longnamemax_test.go:104: l=95: should see a longname now
    longnamemax_test.go:104: l=96: should see a longname now
    longnamemax_test.go:104: l=97: should see a longname now
    longnamemax_test.go:104: l=98: should see a longname now
    longnamemax_test.go:104: l=99: should see a longname now
    longnamemax_test.go:104: l=100: should see a longname now
    longnamemax_test.go:104: l=101: should see a longname now
    longnamemax_test.go:104: l=102: should see a longname now
    longnamemax_test.go:104: l=103: should see a longname now
    longnamemax_test.go:104: l=104: should see a longname now
    longnamemax_test.go:104: l=105: should see a longname now
    longnamemax_test.go:104: l=106: should see a longname now
    longnamemax_test.go:104: l=107: should see a longname now
    longnamemax_test.go:104: l=108: should see a longname now
    longnamemax_test.go:104: l=109: should see a longname now
    longnamemax_test.go:104: l=110: should see a longname now
    longnamemax_test.go:104: l=111: should see a longname now
    longnamemax_test.go:104: l=112: should see a longname now
    longnamemax_test.go:104: l=113: should see a longname now
    longnamemax_test.go:104: l=114: should see a longname now
    longnamemax_test.go:104: l=115: should see a longname now
    longnamemax_test.go:104: l=116: should see a longname now
    longnamemax_test.go:104: l=117: should see a longname now
    longnamemax_test.go:104: l=118: should see a longname now
    longnamemax_test.go:104: l=119: should see a longname now
    longnamemax_test.go:104: l=120: should see a longname now
    longnamemax_test.go:104: l=121: should see a longname now
    longnamemax_test.go:104: l=122: should see a longname now
    longnamemax_test.go:104: l=123: should see a longname now
    longnamemax_test.go:104: l=124: should see a longname now
    longnamemax_test.go:104: l=125: should see a longname now
    longnamemax_test.go:104: l=126: should see a longname now
    longnamemax_test.go:104: l=127: should see a longname now
    longnamemax_test.go:104: l=128: should see a longname now
    longnamemax_test.go:104: l=129: should see a longname now
    longnamemax_test.go:104: l=130: should see a longname now
    longnamemax_test.go:104: l=131: should see a longname now
    longnamemax_test.go:104: l=132: should see a longname now
    longnamemax_test.go:104: l=133: should see a longname now
    longnamemax_test.go:104: l=134: should see a longname now
    longnamemax_test.go:104: l=135: should see a longname now
    longnamemax_test.go:104: l=136: should see a longname now
    longnamemax_test.go:104: l=137: should see a longname now
    longnamemax_test.go:104: l=138: should see a longname now
    longnamemax_test.go:104: l=139: should see a longname now
    longnamemax_test.go:104: l=140: should see a longname now
    longnamemax_test.go:104: l=141: should see a longname now
    longnamemax_test.go:104: l=142: should see a longname now
    longnamemax_test.go:104: l=143: should see a longname now
    longnamemax_test.go:104: l=144: should see a longname now
    longnamemax_test.go:104: l=145: should see a longname now
    longnamemax_test.go:104: l=146: should see a longname now
    longnamemax_test.go:104: l=147: should see a longname now
    longnamemax_test.go:104: l=148: should see a longname now
    longnamemax_test.go:104: l=149: should see a longname now
    longnamemax_test.go:104: l=150: should see a longname now
    longnamemax_test.go:104: l=151: should see a longname now
    longnamemax_test.go:104: l=152: should see a longname now
    longnamemax_test.go:104: l=153: should see a longname now
    longnamemax_test.go:104: l=154: should see a longname now
    longnamemax_test.go:104: l=155: should see a longname now
    longnamemax_test.go:104: l=156: should see a longname now
    longnamemax_test.go:104: l=157: should see a longname now
    longnamemax_test.go:104: l=158: should see a longname now
    longnamemax_test.go:104: l=159: should see a longname now
    longnamemax_test.go:104: l=160: should see a longname now
    longnamemax_test.go:104: l=161: should see a longname now
    longnamemax_test.go:104: l=162: should see a longname now
    longnamemax_test.go:104: l=163: should see a longname now
    longnamemax_test.go:104: l=164: should see a longname now
    longnamemax_test.go:104: l=165: should see a longname now
    longnamemax_test.go:104: l=166: should see a longname now
    longnamemax_test.go:104: l=167: should see a longname now
    longnamemax_test.go:104: l=168: should see a longname now
    longnamemax_test.go:104: l=169: should see a longname now
    longnamemax_test.go:104: l=170: should see a longname now
    longnamemax_test.go:104: l=171: should see a longname now
    longnamemax_test.go:104: l=172: should see a longname now
    longnamemax_test.go:104: l=173: should see a longname now
    longnamemax_test.go:104: l=174: should see a longname now
    longnamemax_test.go:104: l=175: should see a longname now
FAIL

https://github.com/rfjakob/gocryptfs/pull/655
2022-08-28 11:07:35 +02:00
Jakob Unterwurzacher 5582d8370c ctlsock: raise timeout to 10 seconds
There was at least one user who hit the earlier 1 second timeout. Raise to 10
seconds which ought to be enough for anyone.

Fixes https://github.com/rfjakob/gocryptfs/issues/683
2022-08-22 14:00:36 +02:00
Abirdcfly 702a2e19cc fix minor unreachable code caused by t.Fatal
Signed-off-by: Abirdcfly <fp544037857@gmail.com>
2022-08-15 14:24:18 +02:00
Yuta Hayashibe e9ecff7f07 Fix typos 2022-06-26 10:59:06 +02:00
Val c9e4e4f741 Fix reverse gocryptfs.conf access on macOS
Unlike the FUSE implementation on Linux, macFUSE doesn't cache the file
attributes from the `LOOKUP` call, so it calls `GETATTR` prior to
accessing a file.

In the case of the `VirtualConfNode` (reverse config file passthrough),
this resulted in the default `GETATTR` implementation returning an empty
result, ultimately resulting in a "permission denied" error.

    14:44:14.095207 rx 3: GETATTR n2
    14:44:14.095229 tx 3:     OK, {tA=1s {M0100000 SZ=0 L=0 0:0 0 0:8954996 A 0.000000 M 0.000000 C 0.000000}}
    14:44:14.099943 rx 4: ACCESS n2 {u=501 g=20 r}
    14:44:14.099990 tx 4:     13=permission denied

By impementing `Getattr` (from `fs.NodeGetattrer`) on `VirtualConfNode`
this solves the issue.
2022-04-02 15:15:04 +02:00
Jakob Unterwurzacher ad2904f9ed MANPAGE: document that -scryptn also applies to -passwd
Closes https://github.com/rfjakob/gocryptfs/issues/646
2022-03-19 15:18:39 +01:00
42 changed files with 146 additions and 47 deletions

View File

@ -13,8 +13,9 @@ jobs:
go:
- "1.13.x" # Ubuntu 20.04 LTS "focal"
- "1.15.x" # Debian 11 "Bullseye"
- "1.16.x" # Golang upstream stable
- "1.17.x" # Golang upstream stable
- "1.18.x" # Golang upstream stable
- "1.19.x" # Golang upstream stable
# Don't cancel everything when one Go version fails
fail-fast: false
runs-on: ubuntu-latest

View File

@ -157,14 +157,6 @@ mounted using gocryptfs v1.2 and higher. Default true.
Reverse mode shows a read-only encrypted view of a plaintext
directory. Implies "-aessiv".
#### -scryptn int
scrypt cost parameter expressed as scryptn=log2(N). Possible values are
10 to 28, representing N=2^10 to N=2^28.
Setting this to a lower
value speeds up mounting and reduces its memory needs, but makes
the password susceptible to brute-force attacks. The default is 16.
#### -xchacha
Use XChaCha20-Poly1305 file content encryption. This should be much faster
than AES-GCM on CPUs that lack AES acceleration.
@ -569,6 +561,16 @@ Quiet - silence informational messages.
Applies to: all actions.
#### -scryptn int
scrypt cost parameter expressed as scryptn=log2(N). Possible values are
10 to 28, representing N=2^10 to N=2^28.
Setting this to a lower
value speeds up mounting and reduces its memory needs, but makes
the password susceptible to brute-force attacks. The default is 16.
Applies to: `-init`, `-passwd`
#### -trace string
Write execution trace to file. View the trace using "go tool trace FILE".

View File

@ -196,11 +196,15 @@ RM: 2,367
Changelog
---------
#### vNEXT
#### v2.3, 2022-08-28
* Add **`-longnamemax`** flag to `-init` ([#499](https://github.com/rfjakob/gocryptfs/issues/499)).
Can be used to work around file or path length restrictions on online storage.
See the [man page](https://github.com/rfjakob/gocryptfs/blob/master/Documentation/MANPAGE.md#-longnamemax)
for details.
* Support for [`NO_COLOR`](https://no-color.org/) env variable ([#617](https://github.com/rfjakob/gocryptfs/issues/617))
* Fix `-force_owner` not not affecting socket files ([#629](https://github.com/rfjakob/gocryptfs/issues/629)
* MacOS: fix inaccessible `gocryptfs.conf` in reverse mode ([commit](https://github.com/rfjakob/gocryptfs/commit/c9e4e4f74150d2734496e90a4c442a17b79f52c1))
* Raise ctlsock operation timeout from 1 to 10 seconds ([#683](https://github.com/rfjakob/gocryptfs/issues/683))
#### v2.2.1, 2021-10-20
* Fix `-force_owner` only taking effect after 2 seconds ([#609](https://github.com/rfjakob/gocryptfs/issues/609)).

View File

@ -334,7 +334,7 @@ func countOpFlags(args *argContainer) int {
return count
}
// isFlagPassed finds out if the flag was explictely passed on the command line.
// isFlagPassed finds out if the flag was explicitly passed on the command line.
// https://stackoverflow.com/a/54747682/1380267
func isFlagPassed(flagSet *flag.FlagSet, name string) bool {
found := false

View File

@ -26,7 +26,7 @@ func usage() {
them in random order over a single "dst" file while reading the "dst"
file concurrently in a loop.
Progress and errors are reported as they occour in addition to a summary
Progress and errors are reported as they occur in addition to a summary
printed at the end. cifs and fuse filesystems are known to fail, local
filesystems and nfs seem ok.

View File

@ -153,7 +153,7 @@ func Verify(fd int, segments []Segment) (err error) {
case SegmentEOF:
continue
default:
log.Panicf("BUG: unkown segment type %d", s.Type)
log.Panicf("BUG: unknown segment type %d", s.Type)
}
for off := s.Offset; off < segments[i+1].Offset; off++ {
res, err := syscall.Seek(fd, off, whence)

View File

@ -1,4 +1,5 @@
//+build linux
//go:build linux
// +build linux
/*
Small tool to try to debug unix.Getdents problems on CIFS mounts

View File

@ -21,9 +21,13 @@ type CtlSock struct {
Conn net.Conn
}
// There was at least one user who hit the earlier 1 second timeout. Raise to 10
// seconds which ought to be enough for anyone.
const ctlsockTimeout = 10 * time.Second
// New opens the socket at `socketPath` and stores it in a `CtlSock` object.
func New(socketPath string) (*CtlSock, error) {
conn, err := net.DialTimeout("unix", socketPath, 1*time.Second)
conn, err := net.DialTimeout("unix", socketPath, ctlsockTimeout)
if err != nil {
return nil, err
}
@ -32,7 +36,7 @@ func New(socketPath string) (*CtlSock, error) {
// Query sends a request to the control socket returns the response.
func (c *CtlSock) Query(req *RequestStruct) (*ResponseStruct, error) {
c.Conn.SetDeadline(time.Now().Add(time.Second))
c.Conn.SetDeadline(time.Now().Add(ctlsockTimeout))
msg, err := json.Marshal(req)
if err != nil {
return nil, err

2
go.mod
View File

@ -16,5 +16,5 @@ require (
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect
golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035
)

6
go.sum
View File

@ -1,7 +1,5 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/hanwen/go-fuse/v2 v2.1.1-0.20210825171523-3ab5d95a30ae h1:4CB6T4YTUVvnro5ba8ju1QCbOuyGAeF3vvKlo50EJ4k=
github.com/hanwen/go-fuse/v2 v2.1.1-0.20210825171523-3ab5d95a30ae/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc=
github.com/hanwen/go-fuse/v2 v2.1.1-0.20211219085202-934a183ed914 h1:hGXMxS1wTE4y+f7iBqFArrJ6X8QozHnEdnVzGZI9Ywc=
github.com/hanwen/go-fuse/v2 v2.1.1-0.20211219085202-934a183ed914/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc=
github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115 h1:YuDUUFNM21CAbyPOpOP8BicaTD/0klJEKt5p8yuw+uY=
@ -43,8 +41,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 h1:c8PlLMqBbOHoqtjteWm5/kbe6rNY2pbRfbIMVnepueo=
golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc=
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View File

@ -1,3 +1,4 @@
//go:build go1.7
// +build go1.7
// ^^^^^^^^^^^^ we use the "sub-benchmark" feature that was added in Go 1.7
@ -10,7 +11,7 @@ import (
)
/*
The troughput we get from /dev/urandom / getentropy depends a lot on the used
The throughput we get from /dev/urandom / getentropy depends a lot on the used
block size. Results on my Pentium G630 running Linux 4.11:
BenchmarkRandSize/16-2 3000000 571 ns/op 27.98 MB/s

View File

@ -207,8 +207,8 @@ func (f *File) doRead(dst []byte, off uint64, length uint64) ([]byte, syscall.Er
plaintext, err := f.contentEnc.DecryptBlocks(ciphertext, firstBlockNo, fileID)
f.rootNode.contentEnc.CReqPool.Put(ciphertext)
if err != nil {
curruptBlockNo := firstBlockNo + f.contentEnc.PlainOffToBlockNo(uint64(len(plaintext)))
tlog.Warn.Printf("doRead %d: corrupt block #%d: %v", f.qIno.Ino, curruptBlockNo, err)
corruptBlockNo := firstBlockNo + f.contentEnc.PlainOffToBlockNo(uint64(len(plaintext)))
tlog.Warn.Printf("doRead %d: corrupt block #%d: %v", f.qIno.Ino, corruptBlockNo, err)
return nil, syscall.EIO
}

View File

@ -26,7 +26,7 @@ func (rn *RootNode) EncryptPath(plainPath string) (string, error) {
if err != nil {
return "", err
}
if rn.args.LongNames && len(encryptedPart) > unix.NAME_MAX {
if rn.args.LongNames && (len(encryptedPart) > unix.NAME_MAX || len(encryptedPart) > rn.nameTransform.GetLongNameMax()) {
encryptedPart = rn.nameTransform.HashLongName(encryptedPart)
}
cipherPath = filepath.Join(cipherPath, encryptedPart)

View File

@ -73,7 +73,7 @@ func (n *Node) Readdir(ctx context.Context) (stream fs.DirStream, errno syscall.
entries[i].Name = "___GOCRYPTFS_INVALID_NAME___"
continue
}
if len(cName) > unix.NAME_MAX {
if len(cName) > unix.NAME_MAX || len(cName) > rn.nameTransform.GetLongNameMax() {
cName = rn.nameTransform.HashLongName(cName)
dotNameFile := fuse.DirEntry{
Mode: virtualFileMode,

View File

@ -42,6 +42,9 @@ type RootNode struct {
// rootDev stores the device number of the backing directory. Used for
// --one-file-system.
rootDev uint64
// If a file name length is shorter than shortNameMax, there is no need to
// hash it.
shortNameMax int
}
// NewRootNode returns an encrypted FUSE overlay filesystem.
@ -50,6 +53,7 @@ type RootNode struct {
func NewRootNode(args fusefrontend.Args, c *contentenc.ContentEnc, n *nametransform.NameTransform) *RootNode {
var rootDev uint64
var st syscall.Stat_t
var shortNameMax int
if err := syscall.Stat(args.Cipherdir, &st); err != nil {
tlog.Warn.Printf("Could not stat backing directory %q: %v", args.Cipherdir, err)
if args.OneFileSystem {
@ -60,12 +64,16 @@ func NewRootNode(args fusefrontend.Args, c *contentenc.ContentEnc, n *nametransf
rootDev = uint64(st.Dev)
}
shortNameMax = n.GetLongNameMax() * 3 / 4
shortNameMax = shortNameMax - shortNameMax%16 - 1
rn := &RootNode{
args: args,
nameTransform: n,
contentEnc: c,
inoMap: inomap.New(rootDev),
rootDev: rootDev,
shortNameMax: shortNameMax,
}
if len(args.Exclude) > 0 || len(args.ExcludeWildcard) > 0 || len(args.ExcludeFrom) > 0 {
rn.excluder = prepareExcluder(args)
@ -87,16 +95,16 @@ func (rn *RootNode) findLongnameParent(fd int, diriv []byte, longname string) (p
return
}
for _, entry := range entries {
if len(entry.Name) <= shortNameMax {
if len(entry.Name) <= rn.shortNameMax {
continue
}
cFullName, err = rn.nameTransform.EncryptName(entry.Name, diriv)
if err != nil {
continue
}
if len(cFullName) <= unix.NAME_MAX {
if len(cFullName) <= unix.NAME_MAX && len(cFullName) <= rn.nameTransform.GetLongNameMax() {
// Entry should have been skipped by the shortNameMax check above
log.Panic("logic error or wrong shortNameMax constant?")
log.Panic("logic error or wrong shortNameMax?")
}
hName := rn.nameTransform.HashLongName(cFullName)
if longname == hName {

View File

@ -10,6 +10,7 @@ import (
)
var _ = (fs.NodeOpener)((*VirtualConfNode)(nil))
var _ = (fs.NodeGetattrer)((*VirtualConfNode)(nil))
type VirtualConfNode struct {
fs.Inode
@ -27,6 +28,16 @@ func (n *VirtualConfNode) Open(ctx context.Context, flags uint32) (fh fs.FileHan
return
}
func (n *VirtualConfNode) Getattr(ctx context.Context, fh fs.FileHandle, out *fuse.AttrOut) syscall.Errno {
var st syscall.Stat_t
err := syscall.Stat(n.path, &st)
if err != nil {
return fs.ToErrno(err)
}
out.FromStat(&st)
return 0
}
// Check that we have implemented the fs.File* interfaces
var _ = (fs.FileReader)((*VirtualConfFile)(nil))
var _ = (fs.FileReleaser)((*VirtualConfFile)(nil))

View File

@ -9,7 +9,7 @@
// Each (Dev, Tag) tuple gets a namespace id assigned. The original inode
// number is then passed through in the lower 48 bits.
//
// If namespace ids are exhaused, or the original id is larger than 48 bits,
// If namespace ids are exhausted, or the original id is larger than 48 bits,
// the whole (Dev, Tag, Ino) tuple gets mapped in the spill map, and the
// spill bit is set to 1.
package inomap
@ -114,7 +114,7 @@ func (m *InoMap) Translate(in QIno) (out uint64) {
// TranslateStat translates (device, ino) pair contained in "st" into a unique
// inode number and overwrites the ino in "st" with it.
// Convience wrapper around Translate().
// Convenience wrapper around Translate().
func (m *InoMap) TranslateStat(st *syscall.Stat_t) {
in := QInoFromStat(st)
st.Ino = m.Translate(in)

View File

@ -34,7 +34,7 @@ func (be *NameTransform) EncryptAndHashBadName(name string, iv []byte, dirfd int
//file found, return result
return lastFoundName, nil
}
//BadName Mode: check if the name was tranformed without change (badname suffix and undecryptable cipher name)
//BadName Mode: check if the name was transformed without change (badname suffix and undecryptable cipher name)
err = syscallcompat.Fstatat(dirfd, name[:len(name)-len(BadnameSuffix)], &st, unix.AT_SYMLINK_NOFOLLOW)
if err == nil {
filesFound++

View File

@ -167,3 +167,9 @@ func Dir(path string) string {
}
return d
}
// GetLongNameMax will return curent `longNameMax`. File name longer than
// this should be hashed.
func (n *NameTransform) GetLongNameMax() int {
return n.longNameMax
}

View File

@ -9,7 +9,7 @@ import (
"os/exec"
"strings"
"golang.org/x/crypto/ssh/terminal"
"golang.org/x/term"
"github.com/rfjakob/gocryptfs/v2/internal/tlog"
)
@ -31,7 +31,7 @@ func Once(extpass []string, passfile []string, prompt string) ([]byte, error) {
if prompt == "" {
prompt = "Password"
}
if !terminal.IsTerminal(int(os.Stdin.Fd())) {
if !term.IsTerminal(int(os.Stdin.Fd())) {
return readPasswordStdin(prompt)
}
return readPasswordTerminal(prompt + ": ")
@ -46,7 +46,7 @@ func Twice(extpass []string, passfile []string) ([]byte, error) {
if len(extpass) != 0 {
return readPasswordExtpass(extpass)
}
if !terminal.IsTerminal(int(os.Stdin.Fd())) {
if !term.IsTerminal(int(os.Stdin.Fd())) {
return readPasswordStdin("Password")
}
p1, err := readPasswordTerminal("Password: ")
@ -72,8 +72,8 @@ func Twice(extpass []string, passfile []string) ([]byte, error) {
func readPasswordTerminal(prompt string) ([]byte, error) {
fd := int(os.Stdin.Fd())
fmt.Fprintf(os.Stderr, prompt)
// terminal.ReadPassword removes the trailing newline
p, err := terminal.ReadPassword(fd)
// term.ReadPassword removes the trailing newline
p, err := term.ReadPassword(fd)
if err != nil {
return nil, fmt.Errorf("Could not read password from terminal: %v\n", err)
}

View File

@ -1,3 +1,4 @@
//go:build !without_openssl
// +build !without_openssl
package stupidgcm

View File

@ -1,3 +1,4 @@
//go:build !without_openssl
// +build !without_openssl
package stupidgcm

View File

@ -1,3 +1,4 @@
//go:build !without_openssl
// +build !without_openssl
package stupidgcm

View File

@ -1,3 +1,4 @@
//go:build cgo && !without_openssl
// +build cgo,!without_openssl
package stupidgcm
@ -52,11 +53,11 @@ func testEncryptDecrypt(t *testing.T, c1 cipher.AEAD, c2 cipher.AEAD) {
// Ciphertext must be identical to Go GCM
if !bytes.Equal(c1out, c2out) {
t.Fatalf("Compare failed for encryption, size %d", i)
t.Log("c1out:")
t.Log("\n" + hex.Dump(c1out))
t.Log("c2out:")
t.Log("\n" + hex.Dump(c2out))
t.Fatalf("Compare failed for encryption, size %d", i)
}
c1out2, sErr := c1.Open(dst, iv, c1out[len(dst):], authData)
@ -115,11 +116,11 @@ func testInplaceSeal(t *testing.T, c1 cipher.AEAD, c2 cipher.AEAD) {
// Ciphertext must be identical to Go GCM
if !bytes.Equal(c1out, c2out) {
t.Fatalf("Compare failed for encryption, size %d", i)
t.Log("sOut:")
t.Log("\n" + hex.Dump(c1out))
t.Log("gOut:")
t.Log("\n" + hex.Dump(c2out))
t.Fatalf("Compare failed for encryption, size %d", i)
}
}
}

View File

@ -1,3 +1,4 @@
//go:build !without_openssl
// +build !without_openssl
package stupidgcm

View File

@ -1,3 +1,4 @@
//go:build !without_openssl
// +build !without_openssl
// We compare against Go's built-in GCM implementation. Since stupidgcm only

View File

@ -1,3 +1,4 @@
//go:build !without_openssl
// +build !without_openssl
package stupidgcm

View File

@ -1,3 +1,4 @@
//go:build !without_openssl
// +build !without_openssl
package stupidgcm
@ -117,7 +118,7 @@ func slicePointerOrNull(s []byte) (ptr *C.uchar) {
}
// This functions exists to benchmark the C call overhead from Go.
// See BenchmarkCCall for resuts.
// See BenchmarkCCall for results.
func noopCFunction() {
C.noop_c_function()
}

View File

@ -40,7 +40,7 @@ func PreferOpenSSLXchacha20poly1305() bool {
if runtime.GOARCH == "amd64" {
return false
}
// On arm64 and arm, OpenSSL is faster. Probably everwhere else too.
// On arm64 and arm, OpenSSL is faster. Probably everywhere else too.
return true
}

View File

@ -1,3 +1,4 @@
//go:build without_openssl
// +build without_openssl
package stupidgcm

View File

@ -1,3 +1,4 @@
//go:build !without_openssl
// +build !without_openssl
// Copyright 2018 The Go Authors. All rights reserved.

View File

@ -1,3 +1,4 @@
//go:build !without_openssl
// +build !without_openssl
package stupidgcm

View File

@ -1,3 +1,4 @@
//go:build linux
// +build linux
package syscallcompat

View File

@ -1,3 +1,4 @@
//go:build linux
// +build linux
package syscallcompat

View File

@ -1,3 +1,4 @@
//go:build race
// +build race
package main

View File

@ -951,7 +951,7 @@ func TestInitNotEmpty(t *testing.T) {
}
// TestSharedstorage checks that `-sharedstorage` shows stable inode numbers to
// userpsace despite having hard link tracking disabled
// userspace despite having hard link tracking disabled
func TestSharedstorage(t *testing.T) {
dir := test_helpers.InitFS(t)
mnt := dir + ".mnt"

View File

@ -16,7 +16,7 @@ import (
// Create & test fs with -longnamemax=100
func TestLongnamemax100(t *testing.T) {
cDir := test_helpers.InitFS(nil, "-longnamemax", "100")
cDir := test_helpers.InitFS(t, "-longnamemax", "100")
pDir := cDir + ".mnt"
// Check config file sanity
@ -59,3 +59,49 @@ func TestLongnamemax100(t *testing.T) {
}
}
}
// Create & test fs with -reverse -longnamemax=100
func TestLongnamemax100Reverse(t *testing.T) {
backingDir := test_helpers.InitFS(t, "-reverse", "-longnamemax", "100")
mntDir := backingDir + ".mnt"
// Check config file sanity
_, c, err := configfile.LoadAndDecrypt(backingDir+"/"+configfile.ConfReverseName, testPw)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
if !c.IsFeatureFlagSet(configfile.FlagLongNameMax) {
t.Error("FlagLongNameMax should be on")
}
if c.LongNameMax != 100 {
t.Errorf("LongNameMax=%d, want 100", c.LongNameMax)
}
// Check that it takes effect
test_helpers.MountOrExit(backingDir, mntDir, "-reverse", "-extpass", "echo test")
defer test_helpers.UnmountPanic(mntDir)
for l := 1; l <= 255; l++ {
path := backingDir + "/" + strings.Repeat("x", l)
if err := ioutil.WriteFile(path, nil, 0600); err != nil {
t.Fatal(err)
}
matches, err := filepath.Glob(mntDir + "/gocryptfs.longname.*")
if err != nil {
t.Fatal(err)
}
err = syscall.Unlink(path)
if err != nil {
t.Fatal(err)
}
// As determined experimentally, a name of length >= 64 causes a longname
// to be created.
if l <= 63 && len(matches) != 0 {
t.Errorf("l=%d: should not see a longname yet", l)
}
if l >= 64 && len(matches) != 2 {
t.Errorf("l=%d: should see a longname now", l)
}
}
}

View File

@ -1,3 +1,4 @@
//go:build linux
// +build linux
package defaults

View File

@ -333,7 +333,7 @@ func TestExampleFSv13reverse(t *testing.T) {
}
dirA = tmpFsPath + dirA
// Mount using password
// We pass "-wpanic=false" because the '..' and '.' tests deliverately trigger warnings
// We pass "-wpanic=false" because the '..' and '.' tests deliberately trigger warnings
test_helpers.MountOrFatal(t, dirA, dirB, "-reverse", "-extpass", "echo test", "-wpanic=false", opensslOpt)
c := dirB + "/gocryptfs.conf"
if !test_helpers.VerifyExistence(t, c) {

View File

@ -24,7 +24,6 @@ func TestConcurrentReadWrite(t *testing.T) {
} else {
f.Close()
}
buf := make([]byte, 100)
content := []byte("1234567890")
threads := 10
loops := 30
@ -32,6 +31,7 @@ func TestConcurrentReadWrite(t *testing.T) {
// Reader thread
wg.Add(1)
go func() {
buf := make([]byte, 100)
fRd, err := os.Open(fn)
if err != nil {
log.Fatal(err)

View File

@ -1,4 +1,5 @@
//+build linux
//go:build linux
// +build linux
// Package root_test contains tests that need root
// permissions to run

View File

@ -1,4 +1,5 @@
//+build linux
//go:build linux
// +build linux
// Darwin does not support Fgetxattr and friends!