Skip to content

Commit

Permalink
pam_fscrypt: warn user if OLDAUTHTOK not given in chauthtok
Browse files Browse the repository at this point in the history
If someone runs 'passwd USER' as root, the user is assigned a new login
passphrase without their fscrypt login protector being updated.  Detect
this case and show a warning message using pam_info().

Fixes #273
  • Loading branch information
ebiggers committed Dec 22, 2021
1 parent ce477ef commit b739990
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 0 deletions.
5 changes: 5 additions & 0 deletions pam/pam.c
Expand Up @@ -20,6 +20,7 @@
#include "pam.h"

#include <security/pam_appl.h>
#include <security/pam_ext.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand Down Expand Up @@ -107,3 +108,7 @@ void freeSecret(pam_handle_t* pamh, char* data, int error_status) {
munlock(data, size);
free(data);
}

void infoMessage(pam_handle_t* pamh, const char* message) {
pam_info(pamh, "%s", message);
}
7 changes: 7 additions & 0 deletions pam/pam.go
Expand Up @@ -166,6 +166,13 @@ func (h *Handle) err() error {
return errors.New(s)
}

// InfoMessage sends a message to the application using pam_info().
func (h *Handle) InfoMessage(message string) {
cMessage := C.CString(message)
defer C.free(unsafe.Pointer(cMessage))
C.infoMessage(h.handle, cMessage)
}

// Transaction represents a wrapped pam_handle_t type created with pam_start
// form an application.
type Transaction Handle
Expand Down
3 changes: 3 additions & 0 deletions pam/pam.h
Expand Up @@ -41,4 +41,7 @@ void *copyIntoSecret(void *data);
// CleaupFunc that Zeros wipes a C string and unlocks and frees its memory.
void freeSecret(pam_handle_t *pamh, char *data, int error_status);

// Sends a message to the application using pam_info().
void infoMessage(pam_handle_t *pamh, const char *message);

#endif // FSCRYPT_PAM_H
12 changes: 12 additions & 0 deletions pam_fscrypt/pam_fscrypt.go
Expand Up @@ -29,6 +29,7 @@ package main
*/
import "C"
import (
"fmt"
"log"
"unsafe"

Expand Down Expand Up @@ -300,6 +301,14 @@ func lockLoginPolicies(handle *pam.Handle) (bool, error) {
return needDropCaches, nil
}

var noOldAuthTokMessage string = `
pam_fscrypt: cannot update login protector for '%s' because old passphrase
was not given. This is expected when changing a user's passphrase as root.
You'll need to manually update the protector's passphrase using:
fscrypt metadata change-passphrase --protector=%s:%s
`

// Chauthtok rewraps the login protector when the passphrase changes.
func Chauthtok(handle *pam.Handle, _ map[string]bool) error {
if err := handle.StartAsPamUser(); err != nil {
Expand All @@ -322,6 +331,9 @@ func Chauthtok(handle *pam.Handle, _ map[string]bool) error {
}
authtok, err := handle.GetItem(pam.Oldauthtok)
if err != nil {
handle.InfoMessage(fmt.Sprintf(noOldAuthTokMessage,
handle.PamUser.Username,
protector.Context.Mount.Path, protector.Descriptor()))
return nil, errors.Wrap(err, "could not get OLDAUTHTOK")
}
return crypto.NewKeyFromCString(authtok)
Expand Down

0 comments on commit b739990

Please sign in to comment.