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
|
||||
|
||||
cd gocryptfs_main
|
||||
echo -n "Compiling... "
|
||||
go build
|
||||
echo "done."
|
||||
|
@ -9,10 +9,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
DEFAULT_PLAINBS = 4096
|
||||
KEY_LEN = 16
|
||||
NONCE_LEN = 12
|
||||
AUTH_TAG_LEN = 16
|
||||
DEFAULT_PLAINBS = 4096
|
||||
FILEID_LEN = 16
|
||||
)
|
||||
|
||||
type CryptFS struct {
|
||||
|
19
gocryptfs
19
gocryptfs
@ -1,9 +1,13 @@
|
||||
#!/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
|
||||
|
||||
trap "exit 0" SIGUSR1
|
||||
shopt -u huponexit
|
||||
|
||||
dir=$(dirname "$0")
|
||||
main="$dir/gocryptfs_main/gocryptfs_main"
|
||||
|
||||
@ -12,11 +16,8 @@ if [ ! -x $main ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# This needs user input and cannot run in the background
|
||||
if [[ $* == *--init* ]]; then
|
||||
"$main" $*
|
||||
else
|
||||
"$main" $* &
|
||||
sleep 0.1
|
||||
disown
|
||||
fi
|
||||
# A backgrounded process gets /dev/null as stdin per default.
|
||||
# Explicitly set stdin to the current stdin so we can ask the user for input.
|
||||
"$main" $* < /proc/self/fd/0 & wait
|
||||
# The "& wait" is neccessary because bash only processes signals when
|
||||
# executing internal commands
|
||||
|
@ -128,11 +128,20 @@ func main() {
|
||||
fmt.Println(err)
|
||||
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)
|
||||
}
|
||||
|
||||
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
|
||||
@ -143,12 +152,13 @@ func printMasterKey(key []byte) {
|
||||
h = h[0:8] + "-" + h[8:16] + "-" + h[16:24] + "-" + h[24:32]
|
||||
|
||||
fmt.Printf(`
|
||||
WARNING:
|
||||
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.
|
||||
ATTENTION:
|
||||
|
||||
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)
|
||||
}
|
||||
@ -171,7 +181,7 @@ func readPassword() string {
|
||||
fd := int(os.Stdin.Fd())
|
||||
p, err := terminal.ReadPassword(fd)
|
||||
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)
|
||||
}
|
||||
return string(p)
|
||||
@ -189,7 +199,7 @@ func dirEmpty(dir string) bool {
|
||||
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)
|
||||
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
|
||||
mOpts.Name = "gocryptfs"
|
||||
|
||||
state, err := fuse.NewServer(conn.RawFS(), mountpoint, &mOpts)
|
||||
srv, err := fuse.NewServer(conn.RawFS(), mountpoint, &mOpts)
|
||||
if err != nil {
|
||||
fmt.Printf("Mount fail: %v\n", err)
|
||||
fmt.Printf("Mount failed: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
state.SetDebug(debug)
|
||||
srv.SetDebug(debug)
|
||||
|
||||
fmt.Println("Mounted.")
|
||||
state.Serve()
|
||||
return srv
|
||||
}
|
||||
|
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