summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2016-12-10 14:54:06 +0100
committerJakob Unterwurzacher2016-12-10 14:54:06 +0100
commit6af725ff099e78fab2920f060c127415aa3b1893 (patch)
treef376bb15a52b9711e9f7072490e902d441d3df18
parente1833fa26a2a42e61aeff6f6e350714133dee378 (diff)
ctlsock: exit early if socket cannot be created; delete on exit
Both are achieved by opening the socket from main and passing it to the ctlsock package instead of passing the path.
-rw-r--r--cli_args.go5
-rw-r--r--internal/ctlsock/ctlsock_serve.go13
-rw-r--r--mount.go37
3 files changed, 36 insertions, 19 deletions
diff --git a/cli_args.go b/cli_args.go
index 7301d9a..4d16570 100644
--- a/cli_args.go
+++ b/cli_args.go
@@ -3,6 +3,7 @@ package main
import (
"flag"
"fmt"
+ "net"
"os"
"strconv"
"strings"
@@ -23,9 +24,11 @@ type argContainer struct {
// Configuration file name override
config string
notifypid, scryptn int
+ // Helper variables that are NOT cli options all start with an underscore
// _configCustom is true when the user sets a custom config file name.
- // This is not a CLI option.
_configCustom bool
+ // _ctlsockFd stores the control socket file descriptor (ctlsock stores the path)
+ _ctlsockFd net.Listener
}
var flagSet *flag.FlagSet
diff --git a/internal/ctlsock/ctlsock_serve.go b/internal/ctlsock/ctlsock_serve.go
index 63515c0..45b1e5b 100644
--- a/internal/ctlsock/ctlsock_serve.go
+++ b/internal/ctlsock/ctlsock_serve.go
@@ -46,19 +46,14 @@ type ctlSockHandler struct {
socket *net.UnixListener
}
-// CreateAndServe creates an unix socket at "path" and serves incoming
-// connections in a new goroutine.
-func CreateAndServe(path string, fs Interface) error {
- sock, err := net.Listen("unix", path)
- if err != nil {
- return err
- }
+// Serve serves incoming connections on "sock". This call blocks so you
+// probably want to run it in a new goroutine.
+func Serve(sock net.Listener, fs Interface) {
handler := ctlSockHandler{
fs: fs,
socket: sock.(*net.UnixListener),
}
- go handler.acceptLoop()
- return nil
+ handler.acceptLoop()
}
func (ch *ctlSockHandler) acceptLoop() {
diff --git a/mount.go b/mount.go
index b9bdc40..bd65fc6 100644
--- a/mount.go
+++ b/mount.go
@@ -4,6 +4,7 @@ import (
"encoding/json"
"io/ioutil"
"log/syslog"
+ "net"
"os"
"os/exec"
"os/signal"
@@ -50,7 +51,28 @@ func doMount(args *argContainer) int {
tlog.Fatal.Printf("Invalid mountpoint: %v", err)
os.Exit(ErrExitMountPoint)
}
- // Get master key
+ // Open control socket early so we can error out before asking the user
+ // for the password
+ if args.ctlsock != "" {
+ // We must use an absolute path because we cd to / when daemonizing.
+ // This messes up the delete-on-close logic in the unix socket object.
+ args.ctlsock, _ = filepath.Abs(args.ctlsock)
+ var sock net.Listener
+ sock, err = net.Listen("unix", args.ctlsock)
+ if err != nil {
+ tlog.Fatal.Printf("ctlsock: %v", err)
+ os.Exit(ErrExitMount)
+ }
+ args._ctlsockFd = sock
+ // Close also deletes the socket file
+ defer func() {
+ err = sock.Close()
+ if err != nil {
+ tlog.Warn.Print(err)
+ }
+ }()
+ }
+ // Get master key (may prompt for the password)
var masterkey []byte
var confFile *configfile.ConfFile
if args.masterkey != "" {
@@ -65,6 +87,7 @@ func doMount(args *argContainer) int {
masterkey = make([]byte, cryptocore.KeyLen)
} else {
// Load master key from config file
+ // Prompts the user for the password
masterkey, confFile = loadConfig(args)
printMasterKey(masterkey)
}
@@ -177,14 +200,10 @@ func initFuseFrontend(key []byte, args *argContainer, confFile *configfile.ConfF
finalFs = fs
ctlSockBackend = fs
}
- if args.ctlsock != "" {
- err := ctlsock.CreateAndServe(args.ctlsock, ctlSockBackend)
- if err != nil {
- // TODO if the socket cannot be created, we should exit BEFORE
- // asking the user for the password
- tlog.Fatal.Printf("ctlsock: %v", err)
- os.Exit(ErrExitMount)
- }
+ // We have opened the socket early so that we cannot fail here after
+ // asking the user for the password
+ if args._ctlsockFd != nil {
+ go ctlsock.Serve(args._ctlsockFd, ctlSockBackend)
}
pathFsOpts := &pathfs.PathNodeFsOptions{ClientInodes: true}
pathFs := pathfs.NewPathNodeFs(finalFs, pathFsOpts)