diff options
| author | Jakob Unterwurzacher | 2017-05-07 22:15:01 +0200 | 
|---|---|---|
| committer | Jakob Unterwurzacher | 2017-05-07 22:16:22 +0200 | 
| commit | d5adde1eeb13ba377f7c05b9f21893c01f61ec16 (patch) | |
| tree | 011813ca5afd81ae6311bb007f5dc10ef69b2e7a | |
| parent | ad7942f434fea567f24458e67a0919291b5ec8dd (diff) | |
exitcodes: pull all exit code definitions into the package
This commit defines all exit codes in one place in the exitcodes
package.
Also, it adds a test to verify the exit code on incorrect
password, which is what SiriKali cares about the most.
Fixes https://github.com/rfjakob/gocryptfs/issues/77 .
| -rw-r--r-- | cli_args.go | 19 | ||||
| -rw-r--r-- | daemonize.go | 5 | ||||
| -rw-r--r-- | init_dir.go | 9 | ||||
| -rw-r--r-- | internal/configfile/scrypt.go | 11 | ||||
| -rw-r--r-- | internal/exitcodes/exitcodes.go | 31 | ||||
| -rw-r--r-- | internal/readpassword/read.go | 24 | ||||
| -rw-r--r-- | internal/stupidgcm/without_openssl.go | 4 | ||||
| -rw-r--r-- | main.go | 33 | ||||
| -rw-r--r-- | masterkey.go | 5 | ||||
| -rw-r--r-- | mount.go | 17 | ||||
| -rw-r--r-- | tests/cli/cli_test.go | 14 | 
11 files changed, 106 insertions, 66 deletions
| diff --git a/cli_args.go b/cli_args.go index e8fab75..be6d688 100644 --- a/cli_args.go +++ b/cli_args.go @@ -9,6 +9,7 @@ import (  	"strings"  	"github.com/rfjakob/gocryptfs/internal/configfile" +	"github.com/rfjakob/gocryptfs/internal/exitcodes"  	"github.com/rfjakob/gocryptfs/internal/prefer_openssl"  	"github.com/rfjakob/gocryptfs/internal/stupidgcm"  	"github.com/rfjakob/gocryptfs/internal/tlog" @@ -56,7 +57,7 @@ func prefixOArgs(osArgs []string) []string {  			// Last argument?  			if i+1 >= len(osArgs) {  				tlog.Fatal.Printf("The \"-o\" option requires an argument") -				os.Exit(ErrExitUsage) +				os.Exit(exitcodes.Usage)  			}  			oOpts = strings.Split(osArgs[i+1], ",")  			// Skip over the arguments to "-o" @@ -76,7 +77,7 @@ func prefixOArgs(osArgs []string) []string {  		}  		if o == "o" || o == "-o" {  			tlog.Fatal.Printf("You can't pass \"-o\" to \"-o\"") -			os.Exit(ErrExitUsage) +			os.Exit(exitcodes.Usage)  		}  		newArgs = append(newArgs, "-"+o)  	} @@ -153,7 +154,7 @@ func parseCliOpts() (args argContainer) {  	if err != nil {  		tlog.Warn.Printf("You passed: %s", prettyArgs())  		tlog.Fatal.Printf("%v", err) -		os.Exit(ErrExitUsage) +		os.Exit(exitcodes.Usage)  	}  	// "-openssl" needs some post-processing  	if opensslAuto == "auto" { @@ -162,27 +163,27 @@ func parseCliOpts() (args argContainer) {  		args.openssl, err = strconv.ParseBool(opensslAuto)  		if err != nil {  			tlog.Fatal.Printf("Invalid \"-openssl\" setting: %v", err) -			os.Exit(ErrExitUsage) +			os.Exit(exitcodes.Usage)  		}  	}  	// "-forcedecode" only works with openssl. Check compilation and command line parameters  	if args.forcedecode == true {  		if stupidgcm.BuiltWithoutOpenssl == true {  			tlog.Fatal.Printf("The -forcedecode flag requires openssl support, but gocryptfs was compiled without it!") -			os.Exit(ErrExitUsage) +			os.Exit(exitcodes.Usage)  		}  		if args.aessiv == true {  			tlog.Fatal.Printf("The -forcedecode and -aessiv flags are incompatible because they use different crypto libs (openssl vs native Go)") -			os.Exit(ErrExitUsage) +			os.Exit(exitcodes.Usage)  		}  		if args.reverse == true {  			tlog.Fatal.Printf("The reverse mode and the -forcedecode option are not compatible") -			os.Exit(ErrExitUsage) +			os.Exit(exitcodes.Usage)  		}  		// Has the user explicitely disabled openssl using "-openssl=false/0"?  		if !args.openssl && opensslAuto != "auto" {  			tlog.Fatal.Printf("-forcedecode requires openssl, but is disabled via command-line option") -			os.Exit(ErrExitUsage) +			os.Exit(exitcodes.Usage)  		}  		args.openssl = true @@ -197,7 +198,7 @@ func parseCliOpts() (args argContainer) {  	}  	if args.extpass != "" && args.masterkey != "" {  		tlog.Fatal.Printf("The options -extpass and -masterkey cannot be used at the same time") -		os.Exit(ErrExitUsage) +		os.Exit(exitcodes.Usage)  	}  	return args  } diff --git a/daemonize.go b/daemonize.go index 9869258..de09743 100644 --- a/daemonize.go +++ b/daemonize.go @@ -7,6 +7,7 @@ import (  	"os/signal"  	"syscall" +	"github.com/rfjakob/gocryptfs/internal/exitcodes"  	"github.com/rfjakob/gocryptfs/internal/tlog"  ) @@ -36,7 +37,7 @@ func forkChild() int {  	err := c.Start()  	if err != nil {  		tlog.Fatal.Printf("forkChild: starting %s failed: %v\n", name, err) -		return 1 +		return exitcodes.ForkChild  	}  	err = c.Wait()  	if err != nil { @@ -46,7 +47,7 @@ func forkChild() int {  			}  		}  		tlog.Fatal.Printf("forkChild: wait returned an unknown error: %v\n", err) -		return 1 +		return exitcodes.ForkChild  	}  	// The child exited with 0 - let's do the same.  	return 0 diff --git a/init_dir.go b/init_dir.go index 7b1dc7b..65b25d1 100644 --- a/init_dir.go +++ b/init_dir.go @@ -6,6 +6,7 @@ import (  	"strings"  	"github.com/rfjakob/gocryptfs/internal/configfile" +	"github.com/rfjakob/gocryptfs/internal/exitcodes"  	"github.com/rfjakob/gocryptfs/internal/nametransform"  	"github.com/rfjakob/gocryptfs/internal/readpassword"  	"github.com/rfjakob/gocryptfs/internal/tlog" @@ -22,13 +23,13 @@ func initDir(args *argContainer) {  		_, err = os.Stat(args.config)  		if err == nil {  			tlog.Fatal.Printf("Config file %q already exists", args.config) -			os.Exit(ErrExitInit) +			os.Exit(exitcodes.Init)  		}  	} else {  		err = checkDirEmpty(args.cipherdir)  		if err != nil {  			tlog.Fatal.Printf("Invalid cipherdir: %v", err) -			os.Exit(ErrExitInit) +			os.Exit(exitcodes.Init)  		}  	}  	// Choose password for config file @@ -41,7 +42,7 @@ func initDir(args *argContainer) {  	err = configfile.CreateConfFile(args.config, password, args.plaintextnames, args.scryptn, creator, args.aessiv)  	if err != nil {  		tlog.Fatal.Println(err) -		os.Exit(ErrExitInit) +		os.Exit(exitcodes.Init)  	}  	// Forward mode with filename encryption enabled needs a gocryptfs.diriv  	// in the root dir @@ -49,7 +50,7 @@ func initDir(args *argContainer) {  		err = nametransform.WriteDirIV(args.cipherdir)  		if err != nil {  			tlog.Fatal.Println(err) -			os.Exit(ErrExitInit) +			os.Exit(exitcodes.Init)  		}  	}  	mountArgs := "" diff --git a/internal/configfile/scrypt.go b/internal/configfile/scrypt.go index 0646754..b5a3edb 100644 --- a/internal/configfile/scrypt.go +++ b/internal/configfile/scrypt.go @@ -8,6 +8,7 @@ import (  	"golang.org/x/crypto/scrypt"  	"github.com/rfjakob/gocryptfs/internal/cryptocore" +	"github.com/rfjakob/gocryptfs/internal/exitcodes"  	"github.com/rfjakob/gocryptfs/internal/tlog"  ) @@ -84,22 +85,22 @@ func (s *ScryptKDF) validateParams() {  	minN := 1 << scryptMinLogN  	if s.N < minN {  		tlog.Fatal.Println("Fatal: scryptn below 10 is too low to make sense") -		os.Exit(1) +		os.Exit(exitcodes.ScryptParams)  	}  	if s.R < scryptMinR {  		tlog.Fatal.Printf("Fatal: scrypt parameter R below minimum: value=%d, min=%d", s.R, scryptMinR) -		os.Exit(1) +		os.Exit(exitcodes.ScryptParams)  	}  	if s.P < scryptMinP {  		tlog.Fatal.Printf("Fatal: scrypt parameter P below minimum: value=%d, min=%d", s.P, scryptMinP) -		os.Exit(1) +		os.Exit(exitcodes.ScryptParams)  	}  	if len(s.Salt) < scryptMinSaltLen {  		tlog.Fatal.Printf("Fatal: scrypt salt length below minimum: value=%d, min=%d", len(s.Salt), scryptMinSaltLen) -		os.Exit(1) +		os.Exit(exitcodes.ScryptParams)  	}  	if s.KeyLen < cryptocore.KeyLen {  		tlog.Fatal.Printf("Fatal: scrypt parameter KeyLen below minimum: value=%d, min=%d", len(s.Salt), cryptocore.KeyLen) -		os.Exit(1) +		os.Exit(exitcodes.ScryptParams)  	}  } diff --git a/internal/exitcodes/exitcodes.go b/internal/exitcodes/exitcodes.go index 2ec3ae6..7a2efdb 100644 --- a/internal/exitcodes/exitcodes.go +++ b/internal/exitcodes/exitcodes.go @@ -8,12 +8,39 @@ import (  )  const ( +	// Usage error: cli syntax etc +	Usage = 1 +	// 2 is reserved because it is used by Go panic + +	// Mount is an error on mount +	Mount = 3 +	// CipherDir means that the CIPHERDIR does not exist +	CipherDir = 6 +	// Init is an error on filesystem init +	Init = 7 +	// LoadConf is an error while loading gocryptfs.conf +	LoadConf = 8 +	// ReadPassword means something went wrong reading the password +	ReadPassword = 9 +	// MountPoint error means that the mountpoint is invalid (not empty etc). +	MountPoint = 10  	// Other error - please inspect the message  	Other = 11  	// PasswordIncorrect - the password was incorrect  	PasswordIncorrect = 12 -	// TODO several other exit codes are defined in main.go. These will be -	// ported over here. +	// ScryptParams means that scrypt was called with invalid parameters +	ScryptParams = 13 +	// MasterKey means that something went wrong when parsing the "-masterkey" +	// command line option +	MasterKey = 14 +	// SigInt means we got SIGINT +	SigInt = 15 +	// PanicLog means the panic log was not empty when we were unmounted +	PanicLog = 16 +	// ForkChild means forking the worker child failed +	ForkChild = 17 +	// OpenSSL means you tried to enable OpenSSL, but we were compiled without it. +	OpenSSL = 18  )  // Err wraps an error with an associated numeric exit code diff --git a/internal/readpassword/read.go b/internal/readpassword/read.go index 563c62d..058735d 100644 --- a/internal/readpassword/read.go +++ b/internal/readpassword/read.go @@ -12,11 +12,11 @@ import (  	"golang.org/x/crypto/ssh/terminal" +	"github.com/rfjakob/gocryptfs/internal/exitcodes"  	"github.com/rfjakob/gocryptfs/internal/tlog"  )  const ( -	exitCode = 9  	// 2kB limit like EncFS  	maxPasswordLen = 2048  ) @@ -46,7 +46,7 @@ func Twice(extpass string) string {  	p2 := readPasswordTerminal("Repeat: ")  	if p1 != p2 {  		tlog.Fatal.Println("Passwords do not match") -		os.Exit(exitCode) +		os.Exit(exitcodes.ReadPassword)  	}  	return p1  } @@ -60,12 +60,12 @@ func readPasswordTerminal(prompt string) string {  	p, err := terminal.ReadPassword(fd)  	if err != nil {  		tlog.Fatal.Printf("Could not read password from terminal: %v\n", err) -		os.Exit(exitCode) +		os.Exit(exitcodes.ReadPassword)  	}  	fmt.Fprintf(os.Stderr, "\n")  	if len(p) == 0 {  		tlog.Fatal.Println("Password is empty") -		os.Exit(exitCode) +		os.Exit(exitcodes.ReadPassword)  	}  	return string(p)  } @@ -77,7 +77,7 @@ func readPasswordStdin() string {  	p := readLineUnbuffered(os.Stdin)  	if len(p) == 0 {  		tlog.Fatal.Println("Got empty password from stdin") -		os.Exit(exitCode) +		os.Exit(exitcodes.ReadPassword)  	}  	return p  } @@ -102,23 +102,23 @@ func readPasswordExtpass(extpass string) string {  	pipe, err := cmd.StdoutPipe()  	if err != nil {  		tlog.Fatal.Printf("extpass pipe setup failed: %v", err) -		os.Exit(exitCode) +		os.Exit(exitcodes.ReadPassword)  	}  	err = cmd.Start()  	if err != nil {  		tlog.Fatal.Printf("extpass cmd start failed: %v", err) -		os.Exit(exitCode) +		os.Exit(exitcodes.ReadPassword)  	}  	p := readLineUnbuffered(pipe)  	pipe.Close()  	err = cmd.Wait()  	if err != nil {  		tlog.Fatal.Printf("extpass program returned an error: %v", err) -		os.Exit(exitCode) +		os.Exit(exitcodes.ReadPassword)  	}  	if len(p) == 0 {  		tlog.Fatal.Println("extpass: password is empty") -		os.Exit(exitCode) +		os.Exit(exitcodes.ReadPassword)  	}  	return p  } @@ -130,7 +130,7 @@ func readLineUnbuffered(r io.Reader) (l string) {  	for {  		if len(l) > maxPasswordLen {  			tlog.Fatal.Printf("fatal: maximum password length of %d bytes exceeded", maxPasswordLen) -			os.Exit(exitCode) +			os.Exit(exitcodes.ReadPassword)  		}  		n, err := r.Read(b)  		if err == io.EOF { @@ -138,7 +138,7 @@ func readLineUnbuffered(r io.Reader) (l string) {  		}  		if err != nil {  			tlog.Fatal.Printf("readLineUnbuffered: %v", err) -			os.Exit(exitCode) +			os.Exit(exitcodes.ReadPassword)  		}  		if n == 0 {  			continue @@ -170,7 +170,7 @@ func CheckTrailingGarbage() {  		n, _ := os.Stdin.Read(b)  		if n > 0 {  			tlog.Fatal.Printf("Received trailing garbage after the password") -			os.Exit(exitCode) +			os.Exit(exitcodes.ReadPassword)  		}  	}()  	// Wait for the goroutine to start up plus one millisecond for the read to diff --git a/internal/stupidgcm/without_openssl.go b/internal/stupidgcm/without_openssl.go index 1c6ebcf..efd37f3 100644 --- a/internal/stupidgcm/without_openssl.go +++ b/internal/stupidgcm/without_openssl.go @@ -5,6 +5,8 @@ package stupidgcm  import (  	"fmt"  	"os" + +	"github.com/rfjakob/gocryptfs/internal/exitcodes"  )  type stupidGCM struct{} @@ -16,7 +18,7 @@ const (  func errExit() {  	fmt.Fprintln(os.Stderr, "gocryptfs has been compiled without openssl support but you are still trying to use openssl") -	os.Exit(2) +	os.Exit(exitcodes.OpenSSL)  }  func New(_ []byte, _ bool) stupidGCM { @@ -12,22 +12,13 @@ import (  	"github.com/rfjakob/gocryptfs/internal/configfile"  	"github.com/rfjakob/gocryptfs/internal/contentenc" +	"github.com/rfjakob/gocryptfs/internal/exitcodes"  	"github.com/rfjakob/gocryptfs/internal/readpassword"  	"github.com/rfjakob/gocryptfs/internal/speed"  	"github.com/rfjakob/gocryptfs/internal/stupidgcm"  	"github.com/rfjakob/gocryptfs/internal/tlog"  ) -// Exit codes -const ( -	ErrExitUsage      = 1 -	ErrExitMount      = 3 -	ErrExitCipherDir  = 6 -	ErrExitInit       = 7 -	ErrExitLoadConf   = 8 -	ErrExitMountPoint = 10 -) -  // GitVersion is the gocryptfs version according to git, set by build.bash  var GitVersion = "[GitVersion not set - please compile using ./build.bash]" @@ -85,7 +76,7 @@ func loadConfig(args *argContainer) (masterkey []byte, confFile *configfile.Conf  func changePassword(args *argContainer) {  	masterkey, confFile, err := loadConfig(args)  	if err != nil { -		os.Exit(ErrExitLoadConf) +		os.Exit(exitcodes.LoadConf)  	}  	tlog.Info.Println("Please enter your new password.")  	newPw := readpassword.Twice(args.extpass) @@ -96,7 +87,7 @@ func changePassword(args *argContainer) {  		err = os.Link(args.config, bak)  		if err != nil {  			tlog.Fatal.Printf("Could not create backup file: %v", err) -			os.Exit(ErrExitInit) +			os.Exit(exitcodes.Init)  		}  		tlog.Info.Printf(tlog.ColorGrey+  			"A copy of the old config file has been created at %q.\n"+ @@ -106,7 +97,7 @@ func changePassword(args *argContainer) {  	err = confFile.WriteFile()  	if err != nil {  		tlog.Fatal.Println(err) -		os.Exit(ErrExitInit) +		os.Exit(exitcodes.Init)  	}  	tlog.Info.Printf(tlog.ColorGreen + "Password changed." + tlog.ColorReset)  	os.Exit(0) @@ -169,11 +160,11 @@ func main() {  		err = checkDir(args.cipherdir)  		if err != nil {  			tlog.Fatal.Printf("Invalid cipherdir: %v", err) -			os.Exit(ErrExitCipherDir) +			os.Exit(exitcodes.CipherDir)  		}  	} else {  		usageText() -		os.Exit(ErrExitUsage) +		os.Exit(exitcodes.Usage)  	}  	// "-q"  	if args.quiet { @@ -188,7 +179,7 @@ func main() {  		args.config, err = filepath.Abs(args.config)  		if err != nil {  			tlog.Fatal.Printf("Invalid \"-config\" setting: %v", err) -			os.Exit(ErrExitInit) +			os.Exit(exitcodes.Init)  		}  		tlog.Info.Printf("Using config file at custom location %s", args.config)  		args._configCustom = true @@ -204,7 +195,7 @@ func main() {  		f, err = os.Create(args.cpuprofile)  		if err != nil {  			tlog.Fatal.Println(err) -			os.Exit(ErrExitInit) +			os.Exit(exitcodes.Init)  		}  		pprof.StartCPUProfile(f)  		defer pprof.StopCPUProfile() @@ -216,7 +207,7 @@ func main() {  		f, err = os.Create(args.memprofile)  		if err != nil {  			tlog.Fatal.Println(err) -			os.Exit(ErrExitInit) +			os.Exit(exitcodes.Init)  		}  		defer func() {  			pprof.WriteHeapProfile(f) @@ -238,7 +229,7 @@ func main() {  	if args.init {  		if flagSet.NArg() > 1 {  			tlog.Fatal.Printf("Usage: %s -init [OPTIONS] CIPHERDIR", tlog.ProgramName) -			os.Exit(ErrExitUsage) +			os.Exit(exitcodes.Usage)  		}  		initDir(&args) // does not return  	} @@ -246,7 +237,7 @@ func main() {  	if args.passwd {  		if flagSet.NArg() > 1 {  			tlog.Fatal.Printf("Usage: %s -passwd [OPTIONS] CIPHERDIR", tlog.ProgramName) -			os.Exit(ErrExitUsage) +			os.Exit(exitcodes.Usage)  		}  		changePassword(&args) // does not return  	} @@ -256,7 +247,7 @@ func main() {  		tlog.Info.Printf("Wrong number of arguments (have %d, want 2). You passed: %s",  			flagSet.NArg(), prettyArgs)  		tlog.Fatal.Printf("Usage: %s [OPTIONS] CIPHERDIR MOUNTPOINT [-o COMMA-SEPARATED-OPTIONS]", tlog.ProgramName) -		os.Exit(ErrExitUsage) +		os.Exit(exitcodes.Usage)  	}  	ret := doMount(&args)  	if ret != 0 { diff --git a/masterkey.go b/masterkey.go index d943745..3d7afd1 100644 --- a/masterkey.go +++ b/masterkey.go @@ -8,6 +8,7 @@ import (  	"golang.org/x/crypto/ssh/terminal"  	"github.com/rfjakob/gocryptfs/internal/cryptocore" +	"github.com/rfjakob/gocryptfs/internal/exitcodes"  	"github.com/rfjakob/gocryptfs/internal/tlog"  ) @@ -50,11 +51,11 @@ func parseMasterKey(masterkey string) []byte {  	key, err := hex.DecodeString(masterkey)  	if err != nil {  		tlog.Fatal.Printf("Could not parse master key: %v", err) -		os.Exit(1) +		os.Exit(exitcodes.MasterKey)  	}  	if len(key) != cryptocore.KeyLen {  		tlog.Fatal.Printf("Master key has length %d but we require length %d", len(key), cryptocore.KeyLen) -		os.Exit(1) +		os.Exit(exitcodes.MasterKey)  	}  	tlog.Info.Printf("Using explicit master key.")  	tlog.Info.Printf(tlog.ColorYellow + @@ -36,14 +36,14 @@ func doMount(args *argContainer) int {  	args.mountpoint, err = filepath.Abs(flagSet.Arg(1))  	if err != nil {  		tlog.Fatal.Printf("Invalid mountpoint: %v", err) -		os.Exit(ErrExitMountPoint) +		os.Exit(exitcodes.MountPoint)  	}  	// We cannot mount "/home/user/.cipher" at "/home/user" because the mount  	// will hide ".cipher" also for us.  	if args.cipherdir == args.mountpoint || strings.HasPrefix(args.cipherdir, args.mountpoint+"/") {  		tlog.Fatal.Printf("Mountpoint %q would shadow cipherdir %q, this is not supported",  			args.mountpoint, args.cipherdir) -		os.Exit(ErrExitMountPoint) +		os.Exit(exitcodes.MountPoint)  	}  	if args.nonempty {  		err = checkDir(args.mountpoint) @@ -52,7 +52,7 @@ func doMount(args *argContainer) int {  	}  	if err != nil {  		tlog.Fatal.Printf("Invalid mountpoint: %v", err) -		os.Exit(ErrExitMountPoint) +		os.Exit(exitcodes.MountPoint)  	}  	// Open control socket early so we can error out before asking the user  	// for the password @@ -64,7 +64,7 @@ func doMount(args *argContainer) int {  		sock, err = net.Listen("unix", args.ctlsock)  		if err != nil {  			tlog.Fatal.Printf("ctlsock: %v", err) -			os.Exit(ErrExitMount) +			os.Exit(exitcodes.Mount)  		}  		args._ctlsockFd = sock  		// Close also deletes the socket file @@ -118,7 +118,7 @@ func doMount(args *argContainer) int {  			paniclog, err = ioutil.TempFile("", "gocryptfs_paniclog.")  			if err != nil {  				tlog.Fatal.Printf("Failed to create gocryptfs_paniclog: %v", err) -				os.Exit(ErrExitMount) +				os.Exit(exitcodes.Mount)  			}  			// Switch all of our logs and the generic logger to syslog  			tlog.Info.SwitchToSyslog(syslog.LOG_USER | syslog.LOG_INFO) @@ -165,6 +165,7 @@ func doMount(args *argContainer) int {  		} else if fi.Size() > 0 {  			tlog.Warn.Printf("paniclog at %q is not empty (size %d). Not deleting it.",  				paniclog.Name(), fi.Size()) +			return exitcodes.PanicLog  		} else {  			syscall.Unlink(paniclog.Name())  		} @@ -227,7 +228,7 @@ func initFuseFrontend(key []byte, args *argContainer, confFile *configfile.ConfF  			frontendArgs.CryptoBackend = cryptocore.BackendAESSIV  		} else if args.reverse {  			tlog.Fatal.Printf("AES-SIV is required by reverse mode, but not enabled in the config file") -			os.Exit(ErrExitUsage) +			os.Exit(exitcodes.Usage)  		}  	}  	// If allow_other is set and we run as root, try to give newly created files to @@ -306,7 +307,7 @@ func initFuseFrontend(key []byte, args *argContainer, confFile *configfile.ConfF  	srv, err := fuse.NewServer(conn.RawFS(), args.mountpoint, &mOpts)  	if err != nil {  		tlog.Fatal.Printf("Mount failed: %v", err) -		os.Exit(ErrExitMount) +		os.Exit(exitcodes.Mount)  	}  	srv.SetDebug(args.fusedebug) @@ -336,6 +337,6 @@ func handleSigint(srv *fuse.Server, mountpoint string) {  				cmd.Run()  			}  		} -		os.Exit(1) +		os.Exit(exitcodes.SigInt)  	}()  } diff --git a/tests/cli/cli_test.go b/tests/cli/cli_test.go index cce7fa0..905a890 100644 --- a/tests/cli/cli_test.go +++ b/tests/cli/cli_test.go @@ -10,6 +10,7 @@ import (  	"testing"  	"github.com/rfjakob/gocryptfs/internal/configfile" +	"github.com/rfjakob/gocryptfs/internal/exitcodes"  	"github.com/rfjakob/gocryptfs/tests/test_helpers"  ) @@ -316,3 +317,16 @@ func TestInitTrailingGarbage(t *testing.T) {  		}  	}  } + +// TestPasswordIncorrect makes sure the correct exit code is used when the password +// was incorrect +func TestPasswordIncorrect(t *testing.T) { +	cDir := test_helpers.InitFS(t) +	pDir := cDir + ".mnt" +	err := test_helpers.Mount(cDir, pDir, false, "-extpass", "echo WRONG", "-wpanic=false") +	//          vvvvvvvvvvvvvv OMG vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +	exitCode := err.(*exec.ExitError).Sys().(syscall.WaitStatus).ExitStatus() +	if exitCode != exitcodes.PasswordIncorrect { +		t.Errorf("want=%d, got=%d", exitcodes.PasswordIncorrect, exitCode) +	} +} | 
