Implement proper daemonization
The shell wrapper sends gocryptfs into the background and waits for SIGUSR1
This commit is contained in:
parent
552c32c5e9
commit
022a6968ae
2
all.bash
2
all.bash
@ -3,6 +3,4 @@
|
|||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
cd gocryptfs_main
|
cd gocryptfs_main
|
||||||
echo -n "Compiling... "
|
|
||||||
go build
|
go build
|
||||||
echo "done."
|
|
||||||
|
@ -9,10 +9,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
DEFAULT_PLAINBS = 4096
|
||||||
KEY_LEN = 16
|
KEY_LEN = 16
|
||||||
NONCE_LEN = 12
|
NONCE_LEN = 12
|
||||||
AUTH_TAG_LEN = 16
|
AUTH_TAG_LEN = 16
|
||||||
DEFAULT_PLAINBS = 4096
|
FILEID_LEN = 16
|
||||||
)
|
)
|
||||||
|
|
||||||
type CryptFS struct {
|
type CryptFS struct {
|
||||||
|
19
gocryptfs
19
gocryptfs
@ -1,9 +1,13 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Simple wrapper that runs the gocryptfs process in the background
|
# Shell wrapper that runs the gocryptfs process in the background
|
||||||
|
# and exits on SIGUSR1
|
||||||
|
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
|
trap "exit 0" SIGUSR1
|
||||||
|
shopt -u huponexit
|
||||||
|
|
||||||
dir=$(dirname "$0")
|
dir=$(dirname "$0")
|
||||||
main="$dir/gocryptfs_main/gocryptfs_main"
|
main="$dir/gocryptfs_main/gocryptfs_main"
|
||||||
|
|
||||||
@ -12,11 +16,8 @@ if [ ! -x $main ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# This needs user input and cannot run in the background
|
# A backgrounded process gets /dev/null as stdin per default.
|
||||||
if [[ $* == *--init* ]]; then
|
# Explicitly set stdin to the current stdin so we can ask the user for input.
|
||||||
"$main" $*
|
"$main" $* < /proc/self/fd/0 & wait
|
||||||
else
|
# The "& wait" is neccessary because bash only processes signals when
|
||||||
"$main" $* &
|
# executing internal commands
|
||||||
sleep 0.1
|
|
||||||
disown
|
|
||||||
fi
|
|
||||||
|
@ -128,11 +128,20 @@ func main() {
|
|||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(ERREXIT_LOADCONF)
|
os.Exit(ERREXIT_LOADCONF)
|
||||||
}
|
}
|
||||||
fmt.Printf("Success\n")
|
fmt.Printf("done.\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
srv := pathfsFrontend(key, cipherdir, mountpoint, fusedebug)
|
||||||
|
fmt.Printf("Mounted.\n")
|
||||||
|
|
||||||
|
if zerokey == false {
|
||||||
printMasterKey(key)
|
printMasterKey(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
pathfsFrontend(key, cipherdir, mountpoint, fusedebug)
|
// Send notification to our parent
|
||||||
|
sendSig()
|
||||||
|
// Jump into server loop
|
||||||
|
srv.Serve()
|
||||||
}
|
}
|
||||||
|
|
||||||
// printMasterKey - remind the user that he should store the master key in
|
// printMasterKey - remind the user that he should store the master key in
|
||||||
@ -143,12 +152,13 @@ func printMasterKey(key []byte) {
|
|||||||
h = h[0:8] + "-" + h[8:16] + "-" + h[16:24] + "-" + h[24:32]
|
h = h[0:8] + "-" + h[8:16] + "-" + h[16:24] + "-" + h[24:32]
|
||||||
|
|
||||||
fmt.Printf(`
|
fmt.Printf(`
|
||||||
WARNING:
|
ATTENTION:
|
||||||
If the gocryptfs config file becomes corrupted or you ever
|
|
||||||
forget your password, there is only one hope for recovery:
|
|
||||||
The master key. Print it to a piece of paper and store it in a drawer.
|
|
||||||
|
|
||||||
Master key: %s
|
Your master key is: %s
|
||||||
|
|
||||||
|
If the gocryptfs.conf file becomes corrupted or you ever forget your password,
|
||||||
|
there is only one hope for recovery: The master key. Print it to a piece of
|
||||||
|
paper and store it in a drawer.
|
||||||
|
|
||||||
`, h)
|
`, h)
|
||||||
}
|
}
|
||||||
@ -171,7 +181,7 @@ func readPassword() string {
|
|||||||
fd := int(os.Stdin.Fd())
|
fd := int(os.Stdin.Fd())
|
||||||
p, err := terminal.ReadPassword(fd)
|
p, err := terminal.ReadPassword(fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error: Could not read password: %s\n")
|
fmt.Printf("Error: Could not read password: %v\n", err)
|
||||||
os.Exit(ERREXIT_PASSWORD)
|
os.Exit(ERREXIT_PASSWORD)
|
||||||
}
|
}
|
||||||
return string(p)
|
return string(p)
|
||||||
@ -189,7 +199,7 @@ func dirEmpty(dir string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func pathfsFrontend(key []byte, cipherdir string, mountpoint string, debug bool) {
|
func pathfsFrontend(key []byte, cipherdir string, mountpoint string, debug bool) *fuse.Server {
|
||||||
|
|
||||||
finalFs := pathfs_frontend.NewFS(key, cipherdir, USE_OPENSSL)
|
finalFs := pathfs_frontend.NewFS(key, cipherdir, USE_OPENSSL)
|
||||||
pathFsOpts := &pathfs.PathNodeFsOptions{ClientInodes: true}
|
pathFsOpts := &pathfs.PathNodeFsOptions{ClientInodes: true}
|
||||||
@ -210,13 +220,12 @@ func pathfsFrontend(key []byte, cipherdir string, mountpoint string, debug bool)
|
|||||||
// Second column, "Type", will be shown as "fuse." + Name
|
// Second column, "Type", will be shown as "fuse." + Name
|
||||||
mOpts.Name = "gocryptfs"
|
mOpts.Name = "gocryptfs"
|
||||||
|
|
||||||
state, err := fuse.NewServer(conn.RawFS(), mountpoint, &mOpts)
|
srv, err := fuse.NewServer(conn.RawFS(), mountpoint, &mOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Mount fail: %v\n", err)
|
fmt.Printf("Mount failed: %v", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
state.SetDebug(debug)
|
srv.SetDebug(debug)
|
||||||
|
|
||||||
fmt.Println("Mounted.")
|
return srv
|
||||||
state.Serve()
|
|
||||||
}
|
}
|
||||||
|
42
gocryptfs_main/sendsig.go
Normal file
42
gocryptfs_main/sendsig.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"io/ioutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// cmdline looks like this: /bin/bash \0 /path/to/gocryptfs \0 --zerokey \0 ...
|
||||||
|
const (
|
||||||
|
WRAPPER_PREFIX = "/bin/bash\000"
|
||||||
|
WRAPPER_CONTAINS = "gocryptfs\000"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Send USR1 to the "gocryptfs" wrapper shell script. This notifies it that the
|
||||||
|
// mounting has completed sucessfully.
|
||||||
|
//
|
||||||
|
// Checks /proc/$PPID/cmdline to make sure we do not kill an unrelated process.
|
||||||
|
func sendSig() {
|
||||||
|
ppid := os.Getppid()
|
||||||
|
fn := fmt.Sprintf("/proc/%d/cmdline", ppid)
|
||||||
|
cmdline, err := ioutil.ReadFile(fn)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("sendSig: ReadFile: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if bytes.HasPrefix(cmdline, []byte(WRAPPER_PREFIX)) && bytes.Contains(cmdline, []byte(WRAPPER_CONTAINS)) {
|
||||||
|
p, err := os.FindProcess(ppid)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("sendSig: FindProcess: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = p.Signal(syscall.SIGUSR1)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("sendSig: Signal: %v\n", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Not running under the gocryptfs wrapper - will not daemonize\n")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user