diff options
| -rw-r--r-- | cli_args.go | 21 | ||||
| -rw-r--r-- | fsck.go | 9 | ||||
| -rw-r--r-- | main.go | 47 | ||||
| -rw-r--r-- | tests/cli/cli_test.go | 41 | 
4 files changed, 91 insertions, 27 deletions
| diff --git a/cli_args.go b/cli_args.go index 7bde89d..2f0c936 100644 --- a/cli_args.go +++ b/cli_args.go @@ -22,7 +22,7 @@ type argContainer struct {  	plaintextnames, quiet, nosyslog, wpanic,  	longnames, allow_other, ro, reverse, aessiv, nonempty, raw64,  	noprealloc, speed, hkdf, serialize_reads, forcedecode, hh, info, -	sharedstorage, devrandom bool +	sharedstorage, devrandom, fsck bool  	masterkey, mountpoint, cipherdir, cpuprofile, extpass,  	memprofile, ko, passfile, ctlsock, fsname, force_owner, trace string  	// Configuration file name override @@ -133,6 +133,7 @@ func parseCliOpts() (args argContainer) {  	flagSet.BoolVar(&args.info, "info", false, "Display information about CIPHERDIR")  	flagSet.BoolVar(&args.sharedstorage, "sharedstorage", false, "Make concurrent access to a shared CIPHERDIR safer")  	flagSet.BoolVar(&args.devrandom, "devrandom", false, "Use /dev/random for generating master key") +	flagSet.BoolVar(&args.fsck, "fsck", false, "Run a filesystem check on CIPHERDIR")  	flagSet.StringVar(&args.masterkey, "masterkey", "", "Mount with explicit master key")  	flagSet.StringVar(&args.cpuprofile, "cpuprofile", "", "Write cpu profile to specified file")  	flagSet.StringVar(&args.memprofile, "memprofile", "", "Write memory profile to specified file") @@ -220,3 +221,21 @@ func prettyArgs() string {  	pa = pa[1 : len(pa)-1]  	return pa  } + +// countOpFlags counts the number of operation flags we were passed. +func countOpFlags(args *argContainer) int { +	var count int +	if args.info { +		count++ +	} +	if args.passwd { +		count++ +	} +	if args.init { +		count++ +	} +	if args.fsck { +		count++ +	} +	return count +} @@ -0,0 +1,9 @@ +package main + +import ( +	"log" +) + +func fsck(args *argContainer) { +	log.Panic("Not yet implemented") +} @@ -246,45 +246,46 @@ func main() {  		tlog.Debug.Printf("OpenSSL enabled")  	}  	// Operation flags -	if args.info && args.init || args.info && args.passwd || args.passwd && args.init { -		tlog.Fatal.Printf("At most one of -info, -init, -passwd is allowed") +	nOps := countOpFlags(&args) +	if nOps == 0 { +		// Default operation: mount. +		if flagSet.NArg() != 2 { +			prettyArgs := prettyArgs() +			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(exitcodes.Usage) +		} +		doMount(&args) +		// Don't call os.Exit to give deferred functions a chance to run +		return +	} +	if nOps > 1 { +		tlog.Fatal.Printf("At most one of -info, -init, -passwd, -fsck is allowed") +		os.Exit(exitcodes.Usage) +	} +	if flagSet.NArg() != 1 { +		tlog.Fatal.Printf("The options -info, -init, -passwd, -fsck take exactly one argument, %d given", +			flagSet.NArg())  		os.Exit(exitcodes.Usage)  	}  	// "-info"  	if args.info { -		if flagSet.NArg() > 1 { -			tlog.Fatal.Printf("Usage: %s -info CIPHERDIR", tlog.ProgramName) -			os.Exit(exitcodes.Usage) -		}  		info(args.config)  		os.Exit(0)  	}  	// "-init"  	if args.init { -		if flagSet.NArg() > 1 { -			tlog.Fatal.Printf("Usage: %s -init [OPTIONS] CIPHERDIR", tlog.ProgramName) -			os.Exit(exitcodes.Usage) -		}  		initDir(&args)  		os.Exit(0)  	}  	// "-passwd"  	if args.passwd { -		if flagSet.NArg() > 1 { -			tlog.Fatal.Printf("Usage: %s -passwd [OPTIONS] CIPHERDIR", tlog.ProgramName) -			os.Exit(exitcodes.Usage) -		}  		changePassword(&args)  		os.Exit(0)  	} -	// Default operation: mount. -	if flagSet.NArg() != 2 { -		prettyArgs := prettyArgs() -		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(exitcodes.Usage) +	// "-fsck" +	if args.fsck { +		fsck(&args)  	} -	doMount(&args) -	// Don't call os.Exit to give deferred functions a chance to run  } diff --git a/tests/cli/cli_test.go b/tests/cli/cli_test.go index 9eebc5f..2cdaf37 100644 --- a/tests/cli/cli_test.go +++ b/tests/cli/cli_test.go @@ -18,6 +18,18 @@ import (  var testPw = []byte("test") +// Extract the exit code from an error value that was returned from +// exec.Run() +func extractExitCode(err error) int { +	if err == nil { +		return 0 +	} +	// OMG this is convoluted +	err2 := err.(*exec.ExitError) +	code := err2.Sys().(syscall.WaitStatus).ExitStatus() +	return code +} +  func TestMain(m *testing.M) {  	test_helpers.ResetTmpDir(false)  	r := m.Run() @@ -332,8 +344,7 @@ func TestMountPasswordIncorrect(t *testing.T) {  	cDir := test_helpers.InitFS(t) // Create filesystem with password "test"  	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() +	exitCode := extractExitCode(err)  	if exitCode != exitcodes.PasswordIncorrect {  		t.Errorf("want=%d, got=%d", exitcodes.PasswordIncorrect, exitCode)  	} @@ -362,7 +373,7 @@ func TestPasswdPasswordIncorrect(t *testing.T) {  		t.Fatal(err)  	}  	err = cmd.Wait() -	exitCode := err.(*exec.ExitError).Sys().(syscall.WaitStatus).ExitStatus() +	exitCode := extractExitCode(err)  	if exitCode != exitcodes.PasswordIncorrect {  		t.Errorf("want=%d, got=%d", exitcodes.PasswordIncorrect, exitCode)  	} @@ -417,3 +428,27 @@ func TestMountBackground(t *testing.T) {  		t.Fatal("timeout")  	}  } + +// Test that "gocryptfs -init -info CIPHERDIR" returns an error to the +// user. Only one operation flag is allowed. +func TestMultipleOperationFlags(t *testing.T) { +	// Test all combinations +	opFlags := []string{"-init", "-info", "-passwd", "-fsck"} +	for _, flag1 := range opFlags { +		var flag2 string +		for _, flag2 = range opFlags { +			if flag1 == flag2 { +				continue +			} +			args := []string{flag1, flag2, "/tmp"} +			//t.Logf("testing %v", args) +			cmd := exec.Command(test_helpers.GocryptfsBinary, args...) +			err := cmd.Run() +			exitCode := extractExitCode(err) +			if exitCode != exitcodes.Usage { +				t.Fatalf("this should have failed with code %d, but returned %d", +					exitcodes.Usage, exitCode) +			} +		} +	} +} | 
