diff options
| author | Joseph Richey <joerichey@google.com> | 2017-08-31 14:51:55 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-08-31 14:51:55 -0700 |
| commit | b04d7ef31dc2e21f055b1b656efb9511e72db6c6 (patch) | |
| tree | 04daee42d94ddda55d956e72f44bafec0ef6dde1 /pam_fscrypt | |
| parent | 5285a8c451ef660f932e9f1823ad7da52ad25b74 (diff) | |
| parent | f1bd511fff8e411687001bd8e76e8a41c9f5ff41 (diff) | |
Merge pull request #52 from google/keyrings
Changes to the keyrings interface, corresponding UI changes, and misc changes
Diffstat (limited to 'pam_fscrypt')
| -rw-r--r-- | pam_fscrypt/pam_fscrypt.go | 36 | ||||
| -rw-r--r-- | pam_fscrypt/run_fscrypt.go | 21 | ||||
| -rw-r--r-- | pam_fscrypt/run_test.go | 35 |
3 files changed, 68 insertions, 24 deletions
diff --git a/pam_fscrypt/pam_fscrypt.go b/pam_fscrypt/pam_fscrypt.go index 5beb311..7eccc85 100644 --- a/pam_fscrypt/pam_fscrypt.go +++ b/pam_fscrypt/pam_fscrypt.go @@ -55,18 +55,19 @@ const ( // Authenticate copies the AUTHTOK (if necessary) into the PAM data so it can be // used in pam_sm_open_session. func Authenticate(handle *pam.Handle, _ map[string]bool) error { - if err := handle.DropThreadPrivileges(); err != nil { + log.Print("Authenticate()") + if err := handle.StartAsPamUser(); err != nil { return err } - defer handle.RaiseThreadPrivileges() + defer handle.StopAsPamUser() // If this user doesn't have a login protector, no unlocking is needed. if _, err := loginProtector(handle); err != nil { - log.Printf("no need to copy AUTHTOK: %s", err) + log.Printf("no protector, no need for AUTHTOK: %s", err) return nil } - log.Print("Authenticate: copying AUTHTOK for use in the session") + log.Print("copying AUTHTOK for use in the session open") authtok, err := handle.GetItem(pam.Authtok) if err != nil { return errors.Wrap(err, "could not get AUTHTOK") @@ -77,6 +78,7 @@ func Authenticate(handle *pam.Handle, _ map[string]bool) error { // OpenSession provisions any policies protected with the login protector. func OpenSession(handle *pam.Handle, _ map[string]bool) error { + log.Print("OpenSession()") // We will always clear the the AUTHTOK data defer handle.ClearData(authtokLabel) // Increment the count as we add a session @@ -84,15 +86,15 @@ func OpenSession(handle *pam.Handle, _ map[string]bool) error { return err } - if err := handle.DropThreadPrivileges(); err != nil { + if err := handle.StartAsPamUser(); err != nil { return err } - defer handle.RaiseThreadPrivileges() + defer handle.StopAsPamUser() // If there are no polices for the login protector, no unlocking needed. protector, err := loginProtector(handle) if err != nil { - log.Printf("nothing to unlock: %s", err) + log.Printf("no protector to unlock: %s", err) return nil } policies := policiesUsingProtector(protector) @@ -101,7 +103,7 @@ func OpenSession(handle *pam.Handle, _ map[string]bool) error { return nil } - log.Print("OpenSession: unlocking policies protected with AUTHTOK") + log.Printf("unlocking %d policies protected with AUTHTOK", len(policies)) keyFn := func(_ actions.ProtectorInfo, retry bool) (*crypto.Key, error) { if retry { // Login passphrase and login protector have diverged. @@ -150,6 +152,7 @@ func OpenSession(handle *pam.Handle, _ map[string]bool) error { // CloseSession can deprovision all keys provisioned at the start of the // session. It can also clear the cache so these changes take effect. func CloseSession(handle *pam.Handle, args map[string]bool) error { + log.Printf("CloseSession(%v)", args) // Only do stuff on session close when we are the last session if count, err := AdjustCount(handle, -1); err != nil || count != 0 { log.Printf("count is %d and we are not locking", count) @@ -159,12 +162,12 @@ func CloseSession(handle *pam.Handle, args map[string]bool) error { var errLock, errCache error // Don't automatically drop privileges, we may need them to drop caches. if args[lockFlag] { - log.Print("CloseSession: locking polices protected with login") + log.Print("locking polices protected with login protector") errLock = lockLoginPolicies(handle) } if args[cacheFlag] { - log.Print("CloseSession: dropping inode caches") + log.Print("dropping inode caches at session close") errCache = security.DropInodeCache() } @@ -177,10 +180,10 @@ func CloseSession(handle *pam.Handle, args map[string]bool) error { // lockLoginPolicies deprovisions all policy keys that are protected by // the user's login protector. func lockLoginPolicies(handle *pam.Handle) error { - if err := handle.DropThreadPrivileges(); err != nil { + if err := handle.StartAsPamUser(); err != nil { return err } - defer handle.RaiseThreadPrivileges() + defer handle.StopAsPamUser() // If there are no polices for the login protector, no locking needed. protector, err := loginProtector(handle) @@ -211,14 +214,15 @@ func lockLoginPolicies(handle *pam.Handle) error { // Chauthtok rewraps the login protector when the passphrase changes. func Chauthtok(handle *pam.Handle, _ map[string]bool) error { - if err := handle.DropThreadPrivileges(); err != nil { + log.Print("Chauthtok()") + if err := handle.StartAsPamUser(); err != nil { return err } - defer handle.RaiseThreadPrivileges() + defer handle.StopAsPamUser() protector, err := loginProtector(handle) if err != nil { - log.Printf("nothing to rewrap: %s", err) + log.Printf("no login protector to rewrap: %s", err) return nil } @@ -244,7 +248,7 @@ func Chauthtok(handle *pam.Handle, _ map[string]bool) error { return crypto.NewKeyFromCString(authtok) } - log.Print("Chauthtok: rewrapping login protector") + log.Print("rewrapping login protector") if err = protector.Unlock(oldKeyFn); err != nil { return err } diff --git a/pam_fscrypt/run_fscrypt.go b/pam_fscrypt/run_fscrypt.go index 1527d42..c02b05f 100644 --- a/pam_fscrypt/run_fscrypt.go +++ b/pam_fscrypt/run_fscrypt.go @@ -82,6 +82,9 @@ func RunPamFunc(f PamFunc, pamh unsafe.Pointer, argc C.int, argv **C.char) C.int // where a key has a value of true if it appears in the argument list. func parseArgs(argc C.int, argv **C.char) map[string]bool { args := make(map[string]bool) + if argc == 0 || argv == nil { + return args + } for _, cString := range util.PointerSlice(unsafe.Pointer(argv))[:argc] { args[C.GoString((*C.char)(cString))] = true } @@ -112,7 +115,7 @@ func setupLogging(args map[string]bool) io.Writer { // one exists. This protector descriptor (if found) will be cached in the pam // data, under descriptorLabel. func loginProtector(handle *pam.Handle) (*actions.Protector, error) { - ctx, err := actions.NewContextFromMountpoint("/") + ctx, err := actions.NewContextFromMountpoint("/", handle.PamUser) if err != nil { return nil, err } @@ -122,13 +125,13 @@ func loginProtector(handle *pam.Handle) (*actions.Protector, error) { if err != nil { return nil, err } + uid := int64(util.AtoiOrPanic(handle.PamUser.Uid)) for _, option := range options { - if option.Source() == metadata.SourceType_pam_passphrase && - option.UID() == int64(handle.UID) { + if option.Source() == metadata.SourceType_pam_passphrase && option.UID() == uid { return actions.GetProtectorFromOption(ctx, option) } } - return nil, errors.Errorf("no PAM protector for UID=%d on %q", handle.UID, ctx.Mount.Path) + return nil, errors.Errorf("no PAM protector for UID=%d on %q", uid, ctx.Mount.Path) } // policiesUsingProtector searches all the mountpoints for any policies @@ -152,9 +155,11 @@ func policiesUsingProtector(protector *actions.Protector) []*actions.Policy { continue } - ctx := &actions.Context{Config: protector.Context.Config, Mount: mount} + // Clone context but modify the mountpoint + ctx := *protector.Context + ctx.Mount = mount for _, policyDescriptor := range policyDescriptors { - policy, err := actions.GetPolicy(ctx, policyDescriptor) + policy, err := actions.GetPolicy(&ctx, policyDescriptor) if err != nil { log.Printf("reading policy: %s", err) continue @@ -178,7 +183,7 @@ func AdjustCount(handle *pam.Handle, delta int) (int, error) { return 0, err } - path := filepath.Join(countDirectory, fmt.Sprintf("%d.count", handle.UID)) + path := filepath.Join(countDirectory, handle.PamUser.Uid+".count") file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, countFilePermissions) if err != nil { return 0, err @@ -196,7 +201,7 @@ func AdjustCount(handle *pam.Handle, delta int) (int, error) { return 0, err } - log.Printf("Session count for UID=%d updated to %d", handle.UID, newCount) + log.Printf("Session count for UID=%s updated to %d", handle.PamUser.Uid, newCount) return newCount, nil } diff --git a/pam_fscrypt/run_test.go b/pam_fscrypt/run_test.go new file mode 100644 index 0000000..1e74528 --- /dev/null +++ b/pam_fscrypt/run_test.go @@ -0,0 +1,35 @@ +/* + * run_test.go - tests that the PAM helper functionsd work properly + * + * Copyright 2017 Google Inc. + * Author: Joe Richey (joerichey@google.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package main + +import ( + "testing" +) + +func TestParseArgsEmpty(t *testing.T) { + // An empty argv should create a map with no entries + args := parseArgs(0, nil) + if args == nil { + t.Fatal("args map should not be nil") + } + if len(args) > 0 { + t.Fatal("args map should not have any entries") + } +} |