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 .
This commit is contained in:
parent
ad7942f434
commit
d5adde1eeb
19
cli_args.go
19
cli_args.go
@ -9,6 +9,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/rfjakob/gocryptfs/internal/configfile"
|
"github.com/rfjakob/gocryptfs/internal/configfile"
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/exitcodes"
|
||||||
"github.com/rfjakob/gocryptfs/internal/prefer_openssl"
|
"github.com/rfjakob/gocryptfs/internal/prefer_openssl"
|
||||||
"github.com/rfjakob/gocryptfs/internal/stupidgcm"
|
"github.com/rfjakob/gocryptfs/internal/stupidgcm"
|
||||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
"github.com/rfjakob/gocryptfs/internal/tlog"
|
||||||
@ -56,7 +57,7 @@ func prefixOArgs(osArgs []string) []string {
|
|||||||
// Last argument?
|
// Last argument?
|
||||||
if i+1 >= len(osArgs) {
|
if i+1 >= len(osArgs) {
|
||||||
tlog.Fatal.Printf("The \"-o\" option requires an argument")
|
tlog.Fatal.Printf("The \"-o\" option requires an argument")
|
||||||
os.Exit(ErrExitUsage)
|
os.Exit(exitcodes.Usage)
|
||||||
}
|
}
|
||||||
oOpts = strings.Split(osArgs[i+1], ",")
|
oOpts = strings.Split(osArgs[i+1], ",")
|
||||||
// Skip over the arguments to "-o"
|
// Skip over the arguments to "-o"
|
||||||
@ -76,7 +77,7 @@ func prefixOArgs(osArgs []string) []string {
|
|||||||
}
|
}
|
||||||
if o == "o" || o == "-o" {
|
if o == "o" || o == "-o" {
|
||||||
tlog.Fatal.Printf("You can't pass \"-o\" to \"-o\"")
|
tlog.Fatal.Printf("You can't pass \"-o\" to \"-o\"")
|
||||||
os.Exit(ErrExitUsage)
|
os.Exit(exitcodes.Usage)
|
||||||
}
|
}
|
||||||
newArgs = append(newArgs, "-"+o)
|
newArgs = append(newArgs, "-"+o)
|
||||||
}
|
}
|
||||||
@ -153,7 +154,7 @@ func parseCliOpts() (args argContainer) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Warn.Printf("You passed: %s", prettyArgs())
|
tlog.Warn.Printf("You passed: %s", prettyArgs())
|
||||||
tlog.Fatal.Printf("%v", err)
|
tlog.Fatal.Printf("%v", err)
|
||||||
os.Exit(ErrExitUsage)
|
os.Exit(exitcodes.Usage)
|
||||||
}
|
}
|
||||||
// "-openssl" needs some post-processing
|
// "-openssl" needs some post-processing
|
||||||
if opensslAuto == "auto" {
|
if opensslAuto == "auto" {
|
||||||
@ -162,27 +163,27 @@ func parseCliOpts() (args argContainer) {
|
|||||||
args.openssl, err = strconv.ParseBool(opensslAuto)
|
args.openssl, err = strconv.ParseBool(opensslAuto)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("Invalid \"-openssl\" setting: %v", err)
|
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
|
// "-forcedecode" only works with openssl. Check compilation and command line parameters
|
||||||
if args.forcedecode == true {
|
if args.forcedecode == true {
|
||||||
if stupidgcm.BuiltWithoutOpenssl == true {
|
if stupidgcm.BuiltWithoutOpenssl == true {
|
||||||
tlog.Fatal.Printf("The -forcedecode flag requires openssl support, but gocryptfs was compiled without it!")
|
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 {
|
if args.aessiv == true {
|
||||||
tlog.Fatal.Printf("The -forcedecode and -aessiv flags are incompatible because they use different crypto libs (openssl vs native Go)")
|
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 {
|
if args.reverse == true {
|
||||||
tlog.Fatal.Printf("The reverse mode and the -forcedecode option are not compatible")
|
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"?
|
// Has the user explicitely disabled openssl using "-openssl=false/0"?
|
||||||
if !args.openssl && opensslAuto != "auto" {
|
if !args.openssl && opensslAuto != "auto" {
|
||||||
tlog.Fatal.Printf("-forcedecode requires openssl, but is disabled via command-line option")
|
tlog.Fatal.Printf("-forcedecode requires openssl, but is disabled via command-line option")
|
||||||
os.Exit(ErrExitUsage)
|
os.Exit(exitcodes.Usage)
|
||||||
}
|
}
|
||||||
args.openssl = true
|
args.openssl = true
|
||||||
|
|
||||||
@ -197,7 +198,7 @@ func parseCliOpts() (args argContainer) {
|
|||||||
}
|
}
|
||||||
if args.extpass != "" && args.masterkey != "" {
|
if args.extpass != "" && args.masterkey != "" {
|
||||||
tlog.Fatal.Printf("The options -extpass and -masterkey cannot be used at the same time")
|
tlog.Fatal.Printf("The options -extpass and -masterkey cannot be used at the same time")
|
||||||
os.Exit(ErrExitUsage)
|
os.Exit(exitcodes.Usage)
|
||||||
}
|
}
|
||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/exitcodes"
|
||||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
"github.com/rfjakob/gocryptfs/internal/tlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ func forkChild() int {
|
|||||||
err := c.Start()
|
err := c.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("forkChild: starting %s failed: %v\n", name, err)
|
tlog.Fatal.Printf("forkChild: starting %s failed: %v\n", name, err)
|
||||||
return 1
|
return exitcodes.ForkChild
|
||||||
}
|
}
|
||||||
err = c.Wait()
|
err = c.Wait()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -46,7 +47,7 @@ func forkChild() int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tlog.Fatal.Printf("forkChild: wait returned an unknown error: %v\n", err)
|
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.
|
// The child exited with 0 - let's do the same.
|
||||||
return 0
|
return 0
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/rfjakob/gocryptfs/internal/configfile"
|
"github.com/rfjakob/gocryptfs/internal/configfile"
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/exitcodes"
|
||||||
"github.com/rfjakob/gocryptfs/internal/nametransform"
|
"github.com/rfjakob/gocryptfs/internal/nametransform"
|
||||||
"github.com/rfjakob/gocryptfs/internal/readpassword"
|
"github.com/rfjakob/gocryptfs/internal/readpassword"
|
||||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
"github.com/rfjakob/gocryptfs/internal/tlog"
|
||||||
@ -22,13 +23,13 @@ func initDir(args *argContainer) {
|
|||||||
_, err = os.Stat(args.config)
|
_, err = os.Stat(args.config)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
tlog.Fatal.Printf("Config file %q already exists", args.config)
|
tlog.Fatal.Printf("Config file %q already exists", args.config)
|
||||||
os.Exit(ErrExitInit)
|
os.Exit(exitcodes.Init)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err = checkDirEmpty(args.cipherdir)
|
err = checkDirEmpty(args.cipherdir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("Invalid cipherdir: %v", err)
|
tlog.Fatal.Printf("Invalid cipherdir: %v", err)
|
||||||
os.Exit(ErrExitInit)
|
os.Exit(exitcodes.Init)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Choose password for config file
|
// 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)
|
err = configfile.CreateConfFile(args.config, password, args.plaintextnames, args.scryptn, creator, args.aessiv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Println(err)
|
tlog.Fatal.Println(err)
|
||||||
os.Exit(ErrExitInit)
|
os.Exit(exitcodes.Init)
|
||||||
}
|
}
|
||||||
// Forward mode with filename encryption enabled needs a gocryptfs.diriv
|
// Forward mode with filename encryption enabled needs a gocryptfs.diriv
|
||||||
// in the root dir
|
// in the root dir
|
||||||
@ -49,7 +50,7 @@ func initDir(args *argContainer) {
|
|||||||
err = nametransform.WriteDirIV(args.cipherdir)
|
err = nametransform.WriteDirIV(args.cipherdir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Println(err)
|
tlog.Fatal.Println(err)
|
||||||
os.Exit(ErrExitInit)
|
os.Exit(exitcodes.Init)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mountArgs := ""
|
mountArgs := ""
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"golang.org/x/crypto/scrypt"
|
"golang.org/x/crypto/scrypt"
|
||||||
|
|
||||||
"github.com/rfjakob/gocryptfs/internal/cryptocore"
|
"github.com/rfjakob/gocryptfs/internal/cryptocore"
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/exitcodes"
|
||||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
"github.com/rfjakob/gocryptfs/internal/tlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -84,22 +85,22 @@ func (s *ScryptKDF) validateParams() {
|
|||||||
minN := 1 << scryptMinLogN
|
minN := 1 << scryptMinLogN
|
||||||
if s.N < minN {
|
if s.N < minN {
|
||||||
tlog.Fatal.Println("Fatal: scryptn below 10 is too low to make sense")
|
tlog.Fatal.Println("Fatal: scryptn below 10 is too low to make sense")
|
||||||
os.Exit(1)
|
os.Exit(exitcodes.ScryptParams)
|
||||||
}
|
}
|
||||||
if s.R < scryptMinR {
|
if s.R < scryptMinR {
|
||||||
tlog.Fatal.Printf("Fatal: scrypt parameter R below minimum: value=%d, min=%d", 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 {
|
if s.P < scryptMinP {
|
||||||
tlog.Fatal.Printf("Fatal: scrypt parameter P below minimum: value=%d, min=%d", 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 {
|
if len(s.Salt) < scryptMinSaltLen {
|
||||||
tlog.Fatal.Printf("Fatal: scrypt salt length below minimum: value=%d, min=%d", 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 {
|
if s.KeyLen < cryptocore.KeyLen {
|
||||||
tlog.Fatal.Printf("Fatal: scrypt parameter KeyLen below minimum: value=%d, min=%d", len(s.Salt), 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,39 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
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 error - please inspect the message
|
||||||
Other = 11
|
Other = 11
|
||||||
// PasswordIncorrect - the password was incorrect
|
// PasswordIncorrect - the password was incorrect
|
||||||
PasswordIncorrect = 12
|
PasswordIncorrect = 12
|
||||||
// TODO several other exit codes are defined in main.go. These will be
|
// ScryptParams means that scrypt was called with invalid parameters
|
||||||
// ported over here.
|
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
|
// Err wraps an error with an associated numeric exit code
|
||||||
|
@ -12,11 +12,11 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
|
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/exitcodes"
|
||||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
"github.com/rfjakob/gocryptfs/internal/tlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
exitCode = 9
|
|
||||||
// 2kB limit like EncFS
|
// 2kB limit like EncFS
|
||||||
maxPasswordLen = 2048
|
maxPasswordLen = 2048
|
||||||
)
|
)
|
||||||
@ -46,7 +46,7 @@ func Twice(extpass string) string {
|
|||||||
p2 := readPasswordTerminal("Repeat: ")
|
p2 := readPasswordTerminal("Repeat: ")
|
||||||
if p1 != p2 {
|
if p1 != p2 {
|
||||||
tlog.Fatal.Println("Passwords do not match")
|
tlog.Fatal.Println("Passwords do not match")
|
||||||
os.Exit(exitCode)
|
os.Exit(exitcodes.ReadPassword)
|
||||||
}
|
}
|
||||||
return p1
|
return p1
|
||||||
}
|
}
|
||||||
@ -60,12 +60,12 @@ func readPasswordTerminal(prompt string) string {
|
|||||||
p, err := terminal.ReadPassword(fd)
|
p, err := terminal.ReadPassword(fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("Could not read password from terminal: %v\n", err)
|
tlog.Fatal.Printf("Could not read password from terminal: %v\n", err)
|
||||||
os.Exit(exitCode)
|
os.Exit(exitcodes.ReadPassword)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "\n")
|
fmt.Fprintf(os.Stderr, "\n")
|
||||||
if len(p) == 0 {
|
if len(p) == 0 {
|
||||||
tlog.Fatal.Println("Password is empty")
|
tlog.Fatal.Println("Password is empty")
|
||||||
os.Exit(exitCode)
|
os.Exit(exitcodes.ReadPassword)
|
||||||
}
|
}
|
||||||
return string(p)
|
return string(p)
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ func readPasswordStdin() string {
|
|||||||
p := readLineUnbuffered(os.Stdin)
|
p := readLineUnbuffered(os.Stdin)
|
||||||
if len(p) == 0 {
|
if len(p) == 0 {
|
||||||
tlog.Fatal.Println("Got empty password from stdin")
|
tlog.Fatal.Println("Got empty password from stdin")
|
||||||
os.Exit(exitCode)
|
os.Exit(exitcodes.ReadPassword)
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
@ -102,23 +102,23 @@ func readPasswordExtpass(extpass string) string {
|
|||||||
pipe, err := cmd.StdoutPipe()
|
pipe, err := cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("extpass pipe setup failed: %v", err)
|
tlog.Fatal.Printf("extpass pipe setup failed: %v", err)
|
||||||
os.Exit(exitCode)
|
os.Exit(exitcodes.ReadPassword)
|
||||||
}
|
}
|
||||||
err = cmd.Start()
|
err = cmd.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("extpass cmd start failed: %v", err)
|
tlog.Fatal.Printf("extpass cmd start failed: %v", err)
|
||||||
os.Exit(exitCode)
|
os.Exit(exitcodes.ReadPassword)
|
||||||
}
|
}
|
||||||
p := readLineUnbuffered(pipe)
|
p := readLineUnbuffered(pipe)
|
||||||
pipe.Close()
|
pipe.Close()
|
||||||
err = cmd.Wait()
|
err = cmd.Wait()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("extpass program returned an error: %v", err)
|
tlog.Fatal.Printf("extpass program returned an error: %v", err)
|
||||||
os.Exit(exitCode)
|
os.Exit(exitcodes.ReadPassword)
|
||||||
}
|
}
|
||||||
if len(p) == 0 {
|
if len(p) == 0 {
|
||||||
tlog.Fatal.Println("extpass: password is empty")
|
tlog.Fatal.Println("extpass: password is empty")
|
||||||
os.Exit(exitCode)
|
os.Exit(exitcodes.ReadPassword)
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
@ -130,7 +130,7 @@ func readLineUnbuffered(r io.Reader) (l string) {
|
|||||||
for {
|
for {
|
||||||
if len(l) > maxPasswordLen {
|
if len(l) > maxPasswordLen {
|
||||||
tlog.Fatal.Printf("fatal: maximum password length of %d bytes exceeded", 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)
|
n, err := r.Read(b)
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
@ -138,7 +138,7 @@ func readLineUnbuffered(r io.Reader) (l string) {
|
|||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("readLineUnbuffered: %v", err)
|
tlog.Fatal.Printf("readLineUnbuffered: %v", err)
|
||||||
os.Exit(exitCode)
|
os.Exit(exitcodes.ReadPassword)
|
||||||
}
|
}
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
continue
|
continue
|
||||||
@ -170,7 +170,7 @@ func CheckTrailingGarbage() {
|
|||||||
n, _ := os.Stdin.Read(b)
|
n, _ := os.Stdin.Read(b)
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
tlog.Fatal.Printf("Received trailing garbage after the password")
|
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
|
// Wait for the goroutine to start up plus one millisecond for the read to
|
||||||
|
@ -5,6 +5,8 @@ package stupidgcm
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/exitcodes"
|
||||||
)
|
)
|
||||||
|
|
||||||
type stupidGCM struct{}
|
type stupidGCM struct{}
|
||||||
@ -16,7 +18,7 @@ const (
|
|||||||
|
|
||||||
func errExit() {
|
func errExit() {
|
||||||
fmt.Fprintln(os.Stderr, "gocryptfs has been compiled without openssl support but you are still trying to use openssl")
|
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 {
|
func New(_ []byte, _ bool) stupidGCM {
|
||||||
|
33
main.go
33
main.go
@ -12,22 +12,13 @@ import (
|
|||||||
|
|
||||||
"github.com/rfjakob/gocryptfs/internal/configfile"
|
"github.com/rfjakob/gocryptfs/internal/configfile"
|
||||||
"github.com/rfjakob/gocryptfs/internal/contentenc"
|
"github.com/rfjakob/gocryptfs/internal/contentenc"
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/exitcodes"
|
||||||
"github.com/rfjakob/gocryptfs/internal/readpassword"
|
"github.com/rfjakob/gocryptfs/internal/readpassword"
|
||||||
"github.com/rfjakob/gocryptfs/internal/speed"
|
"github.com/rfjakob/gocryptfs/internal/speed"
|
||||||
"github.com/rfjakob/gocryptfs/internal/stupidgcm"
|
"github.com/rfjakob/gocryptfs/internal/stupidgcm"
|
||||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
"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
|
// GitVersion is the gocryptfs version according to git, set by build.bash
|
||||||
var GitVersion = "[GitVersion not set - please compile using ./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) {
|
func changePassword(args *argContainer) {
|
||||||
masterkey, confFile, err := loadConfig(args)
|
masterkey, confFile, err := loadConfig(args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
os.Exit(ErrExitLoadConf)
|
os.Exit(exitcodes.LoadConf)
|
||||||
}
|
}
|
||||||
tlog.Info.Println("Please enter your new password.")
|
tlog.Info.Println("Please enter your new password.")
|
||||||
newPw := readpassword.Twice(args.extpass)
|
newPw := readpassword.Twice(args.extpass)
|
||||||
@ -96,7 +87,7 @@ func changePassword(args *argContainer) {
|
|||||||
err = os.Link(args.config, bak)
|
err = os.Link(args.config, bak)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("Could not create backup file: %v", err)
|
tlog.Fatal.Printf("Could not create backup file: %v", err)
|
||||||
os.Exit(ErrExitInit)
|
os.Exit(exitcodes.Init)
|
||||||
}
|
}
|
||||||
tlog.Info.Printf(tlog.ColorGrey+
|
tlog.Info.Printf(tlog.ColorGrey+
|
||||||
"A copy of the old config file has been created at %q.\n"+
|
"A copy of the old config file has been created at %q.\n"+
|
||||||
@ -106,7 +97,7 @@ func changePassword(args *argContainer) {
|
|||||||
err = confFile.WriteFile()
|
err = confFile.WriteFile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Println(err)
|
tlog.Fatal.Println(err)
|
||||||
os.Exit(ErrExitInit)
|
os.Exit(exitcodes.Init)
|
||||||
}
|
}
|
||||||
tlog.Info.Printf(tlog.ColorGreen + "Password changed." + tlog.ColorReset)
|
tlog.Info.Printf(tlog.ColorGreen + "Password changed." + tlog.ColorReset)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
@ -169,11 +160,11 @@ func main() {
|
|||||||
err = checkDir(args.cipherdir)
|
err = checkDir(args.cipherdir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("Invalid cipherdir: %v", err)
|
tlog.Fatal.Printf("Invalid cipherdir: %v", err)
|
||||||
os.Exit(ErrExitCipherDir)
|
os.Exit(exitcodes.CipherDir)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
usageText()
|
usageText()
|
||||||
os.Exit(ErrExitUsage)
|
os.Exit(exitcodes.Usage)
|
||||||
}
|
}
|
||||||
// "-q"
|
// "-q"
|
||||||
if args.quiet {
|
if args.quiet {
|
||||||
@ -188,7 +179,7 @@ func main() {
|
|||||||
args.config, err = filepath.Abs(args.config)
|
args.config, err = filepath.Abs(args.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("Invalid \"-config\" setting: %v", err)
|
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)
|
tlog.Info.Printf("Using config file at custom location %s", args.config)
|
||||||
args._configCustom = true
|
args._configCustom = true
|
||||||
@ -204,7 +195,7 @@ func main() {
|
|||||||
f, err = os.Create(args.cpuprofile)
|
f, err = os.Create(args.cpuprofile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Println(err)
|
tlog.Fatal.Println(err)
|
||||||
os.Exit(ErrExitInit)
|
os.Exit(exitcodes.Init)
|
||||||
}
|
}
|
||||||
pprof.StartCPUProfile(f)
|
pprof.StartCPUProfile(f)
|
||||||
defer pprof.StopCPUProfile()
|
defer pprof.StopCPUProfile()
|
||||||
@ -216,7 +207,7 @@ func main() {
|
|||||||
f, err = os.Create(args.memprofile)
|
f, err = os.Create(args.memprofile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Println(err)
|
tlog.Fatal.Println(err)
|
||||||
os.Exit(ErrExitInit)
|
os.Exit(exitcodes.Init)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
pprof.WriteHeapProfile(f)
|
pprof.WriteHeapProfile(f)
|
||||||
@ -238,7 +229,7 @@ func main() {
|
|||||||
if args.init {
|
if args.init {
|
||||||
if flagSet.NArg() > 1 {
|
if flagSet.NArg() > 1 {
|
||||||
tlog.Fatal.Printf("Usage: %s -init [OPTIONS] CIPHERDIR", tlog.ProgramName)
|
tlog.Fatal.Printf("Usage: %s -init [OPTIONS] CIPHERDIR", tlog.ProgramName)
|
||||||
os.Exit(ErrExitUsage)
|
os.Exit(exitcodes.Usage)
|
||||||
}
|
}
|
||||||
initDir(&args) // does not return
|
initDir(&args) // does not return
|
||||||
}
|
}
|
||||||
@ -246,7 +237,7 @@ func main() {
|
|||||||
if args.passwd {
|
if args.passwd {
|
||||||
if flagSet.NArg() > 1 {
|
if flagSet.NArg() > 1 {
|
||||||
tlog.Fatal.Printf("Usage: %s -passwd [OPTIONS] CIPHERDIR", tlog.ProgramName)
|
tlog.Fatal.Printf("Usage: %s -passwd [OPTIONS] CIPHERDIR", tlog.ProgramName)
|
||||||
os.Exit(ErrExitUsage)
|
os.Exit(exitcodes.Usage)
|
||||||
}
|
}
|
||||||
changePassword(&args) // does not return
|
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",
|
tlog.Info.Printf("Wrong number of arguments (have %d, want 2). You passed: %s",
|
||||||
flagSet.NArg(), prettyArgs)
|
flagSet.NArg(), prettyArgs)
|
||||||
tlog.Fatal.Printf("Usage: %s [OPTIONS] CIPHERDIR MOUNTPOINT [-o COMMA-SEPARATED-OPTIONS]", tlog.ProgramName)
|
tlog.Fatal.Printf("Usage: %s [OPTIONS] CIPHERDIR MOUNTPOINT [-o COMMA-SEPARATED-OPTIONS]", tlog.ProgramName)
|
||||||
os.Exit(ErrExitUsage)
|
os.Exit(exitcodes.Usage)
|
||||||
}
|
}
|
||||||
ret := doMount(&args)
|
ret := doMount(&args)
|
||||||
if ret != 0 {
|
if ret != 0 {
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"golang.org/x/crypto/ssh/terminal"
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
|
|
||||||
"github.com/rfjakob/gocryptfs/internal/cryptocore"
|
"github.com/rfjakob/gocryptfs/internal/cryptocore"
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/exitcodes"
|
||||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
"github.com/rfjakob/gocryptfs/internal/tlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -50,11 +51,11 @@ func parseMasterKey(masterkey string) []byte {
|
|||||||
key, err := hex.DecodeString(masterkey)
|
key, err := hex.DecodeString(masterkey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("Could not parse master key: %v", err)
|
tlog.Fatal.Printf("Could not parse master key: %v", err)
|
||||||
os.Exit(1)
|
os.Exit(exitcodes.MasterKey)
|
||||||
}
|
}
|
||||||
if len(key) != cryptocore.KeyLen {
|
if len(key) != cryptocore.KeyLen {
|
||||||
tlog.Fatal.Printf("Master key has length %d but we require length %d", 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("Using explicit master key.")
|
||||||
tlog.Info.Printf(tlog.ColorYellow +
|
tlog.Info.Printf(tlog.ColorYellow +
|
||||||
|
17
mount.go
17
mount.go
@ -36,14 +36,14 @@ func doMount(args *argContainer) int {
|
|||||||
args.mountpoint, err = filepath.Abs(flagSet.Arg(1))
|
args.mountpoint, err = filepath.Abs(flagSet.Arg(1))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("Invalid mountpoint: %v", err)
|
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
|
// We cannot mount "/home/user/.cipher" at "/home/user" because the mount
|
||||||
// will hide ".cipher" also for us.
|
// will hide ".cipher" also for us.
|
||||||
if args.cipherdir == args.mountpoint || strings.HasPrefix(args.cipherdir, args.mountpoint+"/") {
|
if args.cipherdir == args.mountpoint || strings.HasPrefix(args.cipherdir, args.mountpoint+"/") {
|
||||||
tlog.Fatal.Printf("Mountpoint %q would shadow cipherdir %q, this is not supported",
|
tlog.Fatal.Printf("Mountpoint %q would shadow cipherdir %q, this is not supported",
|
||||||
args.mountpoint, args.cipherdir)
|
args.mountpoint, args.cipherdir)
|
||||||
os.Exit(ErrExitMountPoint)
|
os.Exit(exitcodes.MountPoint)
|
||||||
}
|
}
|
||||||
if args.nonempty {
|
if args.nonempty {
|
||||||
err = checkDir(args.mountpoint)
|
err = checkDir(args.mountpoint)
|
||||||
@ -52,7 +52,7 @@ func doMount(args *argContainer) int {
|
|||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("Invalid mountpoint: %v", err)
|
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
|
// Open control socket early so we can error out before asking the user
|
||||||
// for the password
|
// for the password
|
||||||
@ -64,7 +64,7 @@ func doMount(args *argContainer) int {
|
|||||||
sock, err = net.Listen("unix", args.ctlsock)
|
sock, err = net.Listen("unix", args.ctlsock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("ctlsock: %v", err)
|
tlog.Fatal.Printf("ctlsock: %v", err)
|
||||||
os.Exit(ErrExitMount)
|
os.Exit(exitcodes.Mount)
|
||||||
}
|
}
|
||||||
args._ctlsockFd = sock
|
args._ctlsockFd = sock
|
||||||
// Close also deletes the socket file
|
// Close also deletes the socket file
|
||||||
@ -118,7 +118,7 @@ func doMount(args *argContainer) int {
|
|||||||
paniclog, err = ioutil.TempFile("", "gocryptfs_paniclog.")
|
paniclog, err = ioutil.TempFile("", "gocryptfs_paniclog.")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("Failed to create gocryptfs_paniclog: %v", err)
|
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
|
// Switch all of our logs and the generic logger to syslog
|
||||||
tlog.Info.SwitchToSyslog(syslog.LOG_USER | syslog.LOG_INFO)
|
tlog.Info.SwitchToSyslog(syslog.LOG_USER | syslog.LOG_INFO)
|
||||||
@ -165,6 +165,7 @@ func doMount(args *argContainer) int {
|
|||||||
} else if fi.Size() > 0 {
|
} else if fi.Size() > 0 {
|
||||||
tlog.Warn.Printf("paniclog at %q is not empty (size %d). Not deleting it.",
|
tlog.Warn.Printf("paniclog at %q is not empty (size %d). Not deleting it.",
|
||||||
paniclog.Name(), fi.Size())
|
paniclog.Name(), fi.Size())
|
||||||
|
return exitcodes.PanicLog
|
||||||
} else {
|
} else {
|
||||||
syscall.Unlink(paniclog.Name())
|
syscall.Unlink(paniclog.Name())
|
||||||
}
|
}
|
||||||
@ -227,7 +228,7 @@ func initFuseFrontend(key []byte, args *argContainer, confFile *configfile.ConfF
|
|||||||
frontendArgs.CryptoBackend = cryptocore.BackendAESSIV
|
frontendArgs.CryptoBackend = cryptocore.BackendAESSIV
|
||||||
} else if args.reverse {
|
} else if args.reverse {
|
||||||
tlog.Fatal.Printf("AES-SIV is required by reverse mode, but not enabled in the config file")
|
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
|
// 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)
|
srv, err := fuse.NewServer(conn.RawFS(), args.mountpoint, &mOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Fatal.Printf("Mount failed: %v", err)
|
tlog.Fatal.Printf("Mount failed: %v", err)
|
||||||
os.Exit(ErrExitMount)
|
os.Exit(exitcodes.Mount)
|
||||||
}
|
}
|
||||||
srv.SetDebug(args.fusedebug)
|
srv.SetDebug(args.fusedebug)
|
||||||
|
|
||||||
@ -336,6 +337,6 @@ func handleSigint(srv *fuse.Server, mountpoint string) {
|
|||||||
cmd.Run()
|
cmd.Run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
os.Exit(1)
|
os.Exit(exitcodes.SigInt)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/rfjakob/gocryptfs/internal/configfile"
|
"github.com/rfjakob/gocryptfs/internal/configfile"
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/exitcodes"
|
||||||
|
|
||||||
"github.com/rfjakob/gocryptfs/tests/test_helpers"
|
"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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user