summaryrefslogtreecommitdiff
path: root/internal/readpassword/passfile.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2018-12-15 17:09:38 +0100
committerJakob Unterwurzacher2018-12-15 17:09:38 +0100
commit295d432175292dbaef572093d784aab55f5c0b8f (patch)
treed5db468806d211d0ea5bbd589dad3a0a337de714 /internal/readpassword/passfile.go
parentb29ee62749244d1985a71f8df37a1582d9e790c9 (diff)
passfile: directly read file instead of invoking cat
Allows better error handling, gets rid of the call to an external program, and fixes https://github.com/rfjakob/gocryptfs/issues/278 .
Diffstat (limited to 'internal/readpassword/passfile.go')
-rw-r--r--internal/readpassword/passfile.go43
1 files changed, 43 insertions, 0 deletions
diff --git a/internal/readpassword/passfile.go b/internal/readpassword/passfile.go
new file mode 100644
index 0000000..73af279
--- /dev/null
+++ b/internal/readpassword/passfile.go
@@ -0,0 +1,43 @@
+package readpassword
+
+import (
+ "bytes"
+ "os"
+
+ "github.com/rfjakob/gocryptfs/internal/exitcodes"
+ "github.com/rfjakob/gocryptfs/internal/tlog"
+)
+
+func readPassFile(passfile string) []byte {
+ tlog.Info.Printf("passfile: reading from file %q", passfile)
+ f, err := os.Open(passfile)
+ if err != nil {
+ tlog.Fatal.Printf("fatal: passfile: could not open %q: %v", passfile, err)
+ os.Exit(exitcodes.ReadPassword)
+ }
+ defer f.Close()
+ // +1 for an optional trailing newline,
+ // +2 so we can detect if maxPasswordLen is exceeded.
+ buf := make([]byte, maxPasswordLen+2)
+ n, err := f.Read(buf)
+ if err != nil {
+ tlog.Fatal.Printf("fatal: passfile: could not read from %q: %v", passfile, err)
+ os.Exit(exitcodes.ReadPassword)
+ }
+ buf = buf[:n]
+ // Split into first line and "trailing garbage"
+ lines := bytes.SplitN(buf, []byte("\n"), 2)
+ if len(lines[0]) == 0 {
+ tlog.Fatal.Printf("fatal: passfile: empty first line in %q", passfile)
+ os.Exit(exitcodes.ReadPassword)
+ }
+ if len(lines[0]) > maxPasswordLen {
+ tlog.Fatal.Printf("fatal: passfile: max password length (%d bytes) exceeded", maxPasswordLen)
+ os.Exit(exitcodes.ReadPassword)
+ }
+ if len(lines) > 1 && len(lines[1]) > 0 {
+ tlog.Warn.Printf("passfile: ignoring trailing garbage (%d bytes) after first line",
+ len(lines[1]))
+ }
+ return lines[0]
+}