aboutsummaryrefslogtreecommitdiff
path: root/cmd/fscrypt
diff options
context:
space:
mode:
authorJoe Richey joerichey@google.com <joerichey@google.com>2017-07-17 17:30:46 -0700
committerJoe Richey joerichey@google.com <joerichey@google.com>2017-07-17 17:30:46 -0700
commit1a4a020ad5766fce3b3ad719d85593a3e8159733 (patch)
treeca9476a0aecaf79cfc8716875db073ea54d5f748 /cmd/fscrypt
parentbd12a36ca860f8de5beb5095b7d97510363b7cc7 (diff)
cmd/fscrypt: username and login token fix
The commit changes how we get the username representation, and uses the new pam API for checking the proposed login token.
Diffstat (limited to 'cmd/fscrypt')
-rw-r--r--cmd/fscrypt/errors.go2
-rw-r--r--cmd/fscrypt/keys.go11
-rw-r--r--cmd/fscrypt/prompt.go24
3 files changed, 25 insertions, 12 deletions
diff --git a/cmd/fscrypt/errors.go b/cmd/fscrypt/errors.go
index c698673..f11ff12 100644
--- a/cmd/fscrypt/errors.go
+++ b/cmd/fscrypt/errors.go
@@ -46,7 +46,6 @@ var (
ErrCanceled = errors.New("operation canceled")
ErrNoDesctructiveOps = errors.New("operation would be destructive")
ErrMaxPassphrase = util.SystemError("max passphrase length exceeded")
- ErrPAMPassphrase = errors.New("incorrect login passphrase")
ErrInvalidSource = errors.New("invalid source type")
ErrPassphraseMismatch = errors.New("entered passphrases do not match")
ErrSpecifyProtector = errors.New("multiple protectors available")
@@ -59,6 +58,7 @@ var (
ErrBadOwners = errors.New("you do not own this directory")
ErrNotEmptyDir = errors.New("not an empty directory")
ErrNotPassphrase = errors.New("protector does not use a passphrase")
+ ErrUnknownUser = errors.New("unknown user")
)
var loadHelpText = fmt.Sprintf("You may need to mount a linked filesystem. Run with %s for more information.", shortDisplay(verboseFlag))
diff --git a/cmd/fscrypt/keys.go b/cmd/fscrypt/keys.go
index 820ddec..65360a9 100644
--- a/cmd/fscrypt/keys.go
+++ b/cmd/fscrypt/keys.go
@@ -125,7 +125,7 @@ func makeKeyFunc(supportRetry, shouldConfirm bool, prefix string) actions.KeyFun
switch info.Source() {
case metadata.SourceType_pam_passphrase:
prompt := fmt.Sprintf("Enter %slogin passphrase for %s: ",
- prefix, getUsername(info.UID()))
+ prefix, formatUsername(info.UID()))
key, err := getPassphraseKey(prompt)
if err != nil {
return nil, err
@@ -134,15 +134,16 @@ func makeKeyFunc(supportRetry, shouldConfirm bool, prefix string) actions.KeyFun
// To confirm, check that the passphrase is the user's
// login passphrase.
if shouldConfirm {
- username := getUsername(info.UID())
- ok, err := pam.IsUserLoginToken(username, key)
+ username, err := usernameFromID(info.UID())
if err != nil {
key.Wipe()
return nil, err
}
- if !ok {
+
+ err = pam.IsUserLoginToken(username, key, quietFlag.Value)
+ if err != nil {
key.Wipe()
- return nil, ErrPAMPassphrase
+ return nil, err
}
}
return key, nil
diff --git a/cmd/fscrypt/prompt.go b/cmd/fscrypt/prompt.go
index fdbef81..52f8c47 100644
--- a/cmd/fscrypt/prompt.go
+++ b/cmd/fscrypt/prompt.go
@@ -27,6 +27,8 @@ import (
"strconv"
"strings"
+ "github.com/pkg/errors"
+
"github.com/google/fscrypt/actions"
"github.com/google/fscrypt/metadata"
"github.com/google/fscrypt/util"
@@ -106,21 +108,31 @@ func askConfirmation(question string, defaultChoice bool, warning string) error
return nil
}
-// getUsername returns the username for the provided UID. If the UID does not
-// correspond to a user or the username is blank, "UID=<uid>" is returned.
-func getUsername(uid int64) string {
+// usernameFromID returns the username for the provided UID. If the UID does not
+// correspond to a user or the username is blank, an error is returned.
+func usernameFromID(uid int64) (string, error) {
u, err := user.LookupId(strconv.Itoa(int(uid)))
if err != nil || u.Username == "" {
- return fmt.Sprintf("UID=%d", uid)
+ return "", errors.Wrapf(ErrUnknownUser, "uid %d", uid)
+ }
+ return u.Username, nil
+}
+
+// formatUsername either returns the username for the provided UID, or a string
+// containing the error for unknown UIDs.
+func formatUsername(uid int64) string {
+ username, err := usernameFromID(uid)
+ if err != nil {
+ return fmt.Sprintf("[%v]", err)
}
- return u.Username
+ return username
}
// formatInfo gives a string description of metadata.ProtectorData.
func formatInfo(data actions.ProtectorInfo) string {
switch data.Source() {
case metadata.SourceType_pam_passphrase:
- return "login protector for " + getUsername(data.UID())
+ return "login protector for " + formatUsername(data.UID())
case metadata.SourceType_custom_passphrase:
return fmt.Sprintf("custom protector %q", data.Name())
case metadata.SourceType_raw_key: