From 1e598e96fcd2ef53ab2ee1e2b408e4ebe920e59b Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Tue, 30 May 2017 19:01:32 +0200 Subject: [PATCH] main: add "-info" option Pretty-prints the config while stripping out sensitive (and uninteresting) data https://github.com/rfjakob/gocryptfs/issues/111 --- Documentation/MANPAGE.md | 10 +++++++++ cli_args.go | 3 ++- help.go | 3 ++- info.go | 45 ++++++++++++++++++++++++++++++++++++++++ main.go | 14 ++++++++++++- 5 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 info.go diff --git a/Documentation/MANPAGE.md b/Documentation/MANPAGE.md index c559bf1..054fc66 100644 --- a/Documentation/MANPAGE.md +++ b/Documentation/MANPAGE.md @@ -86,6 +86,16 @@ same name. By default, CIPHERDIR is used. #### -fusedebug Enable fuse library debug output +#### -h, -help +Print a short help text that shows the more-often used options. + +#### -hh +Long help text, shows all available options. + +#### -info +Pretty-print the contents of the config file for human consumption, +stripping out sensitive data. + #### -init Initialize encrypted directory diff --git a/cli_args.go b/cli_args.go index eb844e1..5f4b328 100644 --- a/cli_args.go +++ b/cli_args.go @@ -20,7 +20,7 @@ type argContainer struct { debug, init, zerokey, fusedebug, openssl, passwd, fg, version, plaintextnames, quiet, nosyslog, wpanic, longnames, allow_other, ro, reverse, aessiv, nonempty, raw64, - noprealloc, speed, hkdf, serialize_reads, forcedecode, hh bool + noprealloc, speed, hkdf, serialize_reads, forcedecode, hh, info bool masterkey, mountpoint, cipherdir, cpuprofile, extpass, memprofile, ko, passfile, ctlsock, fsname string // Configuration file name override @@ -126,6 +126,7 @@ func parseCliOpts() (args argContainer) { flagSet.BoolVar(&args.forcedecode, "forcedecode", false, "Force decode of files even if integrity check fails."+ " Requires gocryptfs to be compiled with openssl support and implies -openssl true") flagSet.BoolVar(&args.hh, "hh", false, "Show this long help text") + flagSet.BoolVar(&args.info, "info", false, "Display information about 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") diff --git a/help.go b/help.go index 378c380..714fcbf 100644 --- a/help.go +++ b/help.go @@ -7,7 +7,7 @@ import ( ) const tUsage = "" + - "Usage: " + tlog.ProgramName + " -init|-passwd [OPTIONS] CIPHERDIR\n" + + "Usage: " + tlog.ProgramName + " -init|-passwd|-info [OPTIONS] CIPHERDIR\n" + " or " + tlog.ProgramName + " [OPTIONS] CIPHERDIR MOUNTPOINT\n" // helpShort is what gets displayed when passed "-h" or on syntax error. @@ -27,6 +27,7 @@ Common Options (use -hh to show all): -h, -help This short help text -hh Long help text with all options -init Initialize encrypted directory + -info Display information about encrypted directory -masterkey Mount with explicit master key instead of password -nonempty Allow mounting over non-empty directory -nosyslog Do not redirect log messages to syslog diff --git a/info.go b/info.go new file mode 100644 index 0000000..c2e0038 --- /dev/null +++ b/info.go @@ -0,0 +1,45 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strings" + + "github.com/rfjakob/gocryptfs/internal/configfile" + "github.com/rfjakob/gocryptfs/internal/contentenc" + "github.com/rfjakob/gocryptfs/internal/exitcodes" + "github.com/rfjakob/gocryptfs/internal/tlog" +) + +// info pretty-prints the contents of the config file at "filename" for human +// consumption, stripping out sensitive data. +// This is called when you pass the "-info" option. +func info(filename string) { + // Read from disk + js, err := ioutil.ReadFile(filename) + if err != nil { + tlog.Fatal.Printf("info: ReadFile: %#v\n", err) + os.Exit(exitcodes.LoadConf) + } + // Unmarshal + var cf configfile.ConfFile + err = json.Unmarshal(js, &cf) + if err != nil { + tlog.Fatal.Printf("Failed to unmarshal config file") + os.Exit(exitcodes.LoadConf) + } + if cf.Version != contentenc.CurrentVersion { + tlog.Fatal.Printf("Unsupported on-disk format %d", cf.Version) + os.Exit(exitcodes.LoadConf) + } + // Pretty-print + fmt.Printf("Creator: %s\n", cf.Creator) + fmt.Printf("FeatureFlags: %s\n", strings.Join(cf.FeatureFlags, " ")) + fmt.Printf("EncryptedKey: %dB\n", len(cf.EncryptedKey)) + s := cf.ScryptObject + fmt.Printf("ScryptObject: Salt=%dB N=%d R=%d P=%d KeyLen=%d\n", + len(s.Salt), s.N, s.R, s.P, s.KeyLen) + os.Exit(0) +} diff --git a/main.go b/main.go index bc2ca12..8dada52 100644 --- a/main.go +++ b/main.go @@ -214,7 +214,19 @@ func main() { } else { tlog.Debug.Printf("OpenSSL enabled") } - // Operation flags: -init or -passwd; otherwise: mount + // 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") + 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) // does not return + } // "-init" if args.init { if flagSet.NArg() > 1 {