Git Product home page Git Product logo

pam-cryptsetup's Introduction

Disclamer: This is not an official Google product.

Overview

pam-cryptsetup provides a PAM module that allows LUKS-based disk encryption passwords to be kept in sync with account passwords automatically based on factors like if the user has decrypted the disk successfully previously.

The project as a whole consists of two parts: a PAM module pam_cryptsetup.so for triggering on user authentication, and a helper program pam_cryptsetup_helper to perform the actual encryption checks and modifications required.

Building and Installing

Built with GNU Autotools and includes an autogen.sh script:

  1. ./autogen.sh
  2. ./configure
  3. make [prefix={path}]
  4. make check # (optional)
  5. sudo make install [prefix={path}]

Depends on:

  • GLib
  • Linux-PAM
  • libcryptsetup
  • libdevicemapper
  • Autoconf, Automake, Libtool

The Autotools Prefix

Due to this project's use of GNU Autotools, all the components are built and installed relative to a user-definable prefix via make prefix={path}. Any time this documentation references {prefix}, substitute the value given to make, or /usr/local if none was given.

Additionally, when using make install, it is required to manually link pam_cryptsetup.so to the proper PAM modules directory (usually /lib/security) from the build default {prefix}/lib/security. This can be avoided by defining the prefix to be empty via make install prefix=.

Components

pam_cryptsetup.so

The pam_cryptsetup.so module attaches to a PAM authentication or credential stack, and passes information provided to the pam_cryptsetup_helper executable to enact any changes that might be necessary.

Module Configuration

When adding this module to a PAM stack, it is recommended to use either the [default=ignore] or optional flags and to place the entry for the module at the very end of the PAM config file sequence.

Module Arguments:

Declaration Default Description
crypt_name=<container> (none) Name of encrypted /dev/mapper based container to probe. Required for operation.
debug=<state> false If set to 'true', provide additional module execution details via pam_syslog.
background=<state> true If set to 'false', authentication module will wait for helper process to complete

Module Examples:

Authentication mode

Authentication mode is most useful when a user's login password can be changed by external factors, such as in an LDAP authentication environment.

The following example changes would be placed in /etc/pam/common.auth

For an encrypted device at /dev/mapper/rootdev_crypt:

<snip>
auth [default=ignore] pam_cryptsetup.so crypt_name=rootdev_crypt

Square brackets ([ and ]) can be used for device names with spaces:

<snip>
auth [default=ignore] pam_cryptsetup.so [crypt_name=my special device]

And if your device has a really weird name, closing square brackets must be escaped by using \]:

<snip>
auth [default=ignore] pam_cryptsetup.so [crypt_name=my [extra\] special device]

Credential mode

As an alternative authentication mode, the module can instead be used in credential mode, and will run only when a user account password is set via the passwd command. This is recommended for setups where the password is never expected to change outside of the passwd command being run.

For credential mode, changes should be made in /etc/pam/passwd

For an encrypted device at /dev/mapper/rootdev_crypt:

<snip>
password [default=ignore] pam_cryptsetup.so crypt_name=rootdev_crypt

pam_cryptsetup_helper

The pam_cryptsetup_helper executable receives data via unnamed piping and command line arguments when invoked by the pam_cryptsetup.so module, and uses the data passed to decide if updates to the encrypted disk are necessary.

A Note on Security

Because this helper module handles sensitive information (notably password and volume keys) outside the secure PAM context, the following steps are taken to prevent leaking data:

  • memlockall() is called at the start of the process to prevent it or any libraries' memory from being paged to disk during runtime.
  • Variables that held sensitive information are zeroed before being freed via either a native implementation of explicit_bzero or an included equivalent.
  • While non-sensitive data like username or crypt name are passed via argument, password tokens are read via inter-process anonymous pipes.

Additionally, while this executable can be called manually if one knows the proper invocation, it is not setuid, and requires the caller have root permissions in order for changes to be made to the encrypted disk.

Helper Crypt Slot Cache

All user information, such as which (if any) slot was most recently unlocked with their login password, is recoded in {prefix}/var/pam-cryptsetup/slots as a GLib string array. The default format, before any unlocking has happened, is as follows:

['', '', '', '', '', '', '', '']

where each string associates with one of the 8 LUKS slots (numbered 0-7) available. Once a user's password has successfully unlocked a slot on the disk, their username is added to the string associated with the number slot unlocked.

For example, if we had a user 'kathy' unlock slot 3, the cache would be updated as follows:

['', '', '', 'kathy', '', '', '', '']

Next time kathy authenticates, this info will be used to determine the appropriate action for the helper to take.

Helper Operation

During a run, the module takes the following information into account:

  • Username
  • Password
  • Old Password (cred mode only)
  • Cache entries
  • Crypt slots unlock-able using
    • password (auth mode)
    • old password (cred mode)

Once all available information is gathered, the action taken is decided by the following logic:

Authentication mode:

  • No action if:
    • User is not recorded in-cache, and password does not unlock any slot
    • User is recorded in-cache, and password unlocks the associated slot
  • Update disk and cache slot if:
    • User is recorded in-cache, and password does not unlock recorded slot
  • Update cache if:
    • User is recorded in-cache, and password unlocks different slot than the one recorded
    • User is not recorded in-cache, and password unlocks a slot

Password mode:

  • No action if:
    • Old password does not unlock a slot
  • Update disk if:
    • Old password unlocks a slot
  • ADDITIONALLY update cache if:
    • User entry exists in a different cache slot compared to new crypt slot

Note: While credential mode will interact with the cache in some cases, it is not meant to be used in addition to authentication mode; using it as such is untested and considered unsupported at this time!

Potential Future Improvements

  • Save cache to drive encryption header using LUKS2 unbound slots

    • Would allow easier drive transfer to new systems while keeping existing pam-cryptsetup info intact.
    • Security-conscious might appreciate a less-easily-accessible record of users who can unlock the drive with their passwords.
  • Reintroduce multi-threading in helper application (unlikely)

    • Code was messy
    • Performance benefits don't matter when helper runs in the background.
  • Utilize kernel keychain for retrieving active volume key

    • Would allow dropping the direct libdevmapper usage
    • Would require that user's kernel is set to store the volume key in an accessible keychain.

pam-cryptsetup's People

Contributors

joshk0 avatar kcolford avatar michel-slm avatar warrenpw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

pam-cryptsetup's Issues

Module run failed: Failed to write to helper process

Hi pam-cryptsetup,

I am attempting to setup the module using authentication mode, I can confirm that the module has been installed in:

> /lib/x86_64-linux-gnu/security/pam_cryptsetup.so
> /usr/lib/pam-cryptsetup/pam_cryptsetup_helper

In the common-auth file I have added at the end of the file:
auth [default=ignore] pam_cryptsetup.so crypt_name=nvme0n1p3_crypt debug=true

Whilst I see the module attempting to run, it fails with the following:

gdm-password]: pam_cryptsetup(gdm-password:auth): Spawned encryption process under PID 2497
pam_cryptsetup(gdm-password:auth): Module run failed: Failed to write to helper process.
pam_unix(gdm-password:session): session opened for user <user> by (uid=0)

When using sudo with the user, I also see the following error messages:

PamCryptsetup_Helper[3054]: Starting
PamCryptsetup_Helper[3054]: uid: 0; euid: 0
PamCryptsetup_Helper[3054]: Process memory locked
PamCryptsetup_Helper[3054]: Too few arguments. Expected: volume_name username [cache_path].

Any help to get this module working would be greatly appreciated.

Many Thanks,
Tania

Ubuntu 21.04: "Failed to retrieve current crypt slot: Failed to find keyslot holding password: Operation not permitted (1)"

I've built and installed this on Ubuntu 21.04 and linked the module into /lib/security. /etc/pam.d/passwd has:

password [default=ignore] pam_cryptsetup.so crypt_name=nvme0n1p3_crypt

pam-cryptsetup is getting invoked when running passwd, but it's not working:

$ passwd
Changing password for michiel.
Current password: 
no password available
New password: 
Retype new password: 
PamCryptsetup_Helper[63658]: Starting
PamCryptsetup_Helper[63658]: uid: 0; euid: 0
PamCryptsetup_Helper[63658]: Process memory locked
PamCryptsetup_Helper[63658]: Argument 0: /usr/local/libexec/pam-cryptsetup/pam_cryptsetup_helper
PamCryptsetup_Helper[63658]: Argument 1: nvme0n1p3_crypt
PamCryptsetup_Helper[63658]: Argument 2: michiel
PamCryptsetup_Helper[63658]: Reading argument 1
PamCryptsetup_Helper[63658]: Reading argument 2
PamCryptsetup_Helper[63658]: Reading password from login module.
PamCryptsetup_Helper[63658]: Reading old_password from login module.
PamCryptsetup_Helper[63658]: Checking if old password exists in crypt header
Crypt update process started.
passwd: password updated successfully
PamCryptsetup_Helper[63658]: Failed to retrieve current crypt slot: Failed to find keyslot holding password: Operation not permitted (1)

auth.log says:

Sep  2 11:26:16 michiel-laptop passwd[63800]: pam_cryptsetup(passwd:chauthtok): Module run failed: no password available
Sep  2 11:26:28 michiel-laptop passwd[63800]: pam_unix(passwd:chauthtok): password changed for michiel
Sep  2 11:26:28 michiel-laptop passwd[63800]: gkr-pam: changed password for login keyring
Sep  2 11:26:28 michiel-laptop passwd[63800]: pam_cryptsetup(passwd:chauthtok): Encryption helper sucessfully opened crypt volume nvme0n1p3_crypt.

Is this a misconfiguration or a bug?

Logging

Hi,

I notice using the software that it's quite noisy both in the GUI and terminal. For example on logging on via GUI you see the message "Crypt process started" and when using sudo you get lots of PamCryptsetup_helper messages, e.g. "Starting", "uid:0 puid:0", "Argument...".

Is it possible to change the logging so that those messages go to auth.log, and if messaging to screen is needed for debugging the error messages can be switched on using the debug option? I don't mind attempting a pull request and working through the logging if this sounds like a good idea.

Many thanks,
Tania

dokumentation pam with Authentication mode

Hi,

i try to use pam-cryptsetup in my deployment. I am use pam_sss.so to authenticate the user from AD. My original common-auth was like this:

# cat /etc/pam.d/common-auth
auth    required        pam_env.so
auth    optional        pam_gnome_keyring.so
auth    sufficient      pam_unix.so     try_first_pass 
auth    required        pam_sss.so      use_first_pass

Your documentation example is like this:

<snip>
auth [default=ignore] pam_cryptsetup.so crypt_name=rootdev_crypt

This results to:

auth    required        pam_env.so
auth    optional        pam_gnome_keyring.so
auth    sufficient      pam_unix.so     try_first_pass 
auth    required        pam_sss.so      use_first_pass
auth [default=ignore] pam_cryptsetup.so crypt_name=rootdev_crypt

Here the problem: If a attacker types a wrong password, i get no login, but the password is stored in LUKS header. After this, the attacker is able to open LUKS and boot the system. I changed my configuration:

auth    required        pam_env.so
auth    optional        pam_gnome_keyring.so
auth    sufficient      pam_unix.so     try_first_pass
auth    [success=ok ignore=ignore user_unknown=ignore default=die]      pam_sss.so      use_first_pass
auth [default=ignore] pam_cryptsetup.so crypt_name=rootdev_crypt

Now, if pam_sss.so has no authentication, it will die and pam_cryptsetup.so will not triggered.

I think it is better to give more details in the documentation part Authentication mode. What do you think, is my change correct? Or is there a better way to configure this?

thanks, Oliver

Failed to retrieve valid crypt volume key: Operation not permitted

I tried setting this up in credential mode on ubuntu 20.04. When I change my password, the encryption key doesn't get changed.
I see these logs when I run passwd:

$ passwd
Changing password for user.
Current password:
no password available
New password:
PamCryptsetup_Helper[2754]: Starting
PamCryptsetup_Helper[2754]: uid: 0; euid: 0
PamCryptsetup_Helper[2754]: Process memory locked
PamCryptsetup_Helper[2754]: Argument 0 /usr/lib/pam-cryptsetup/pam_cryptsetup_helper
PamCryptsetup_Helper[2754]: Argument 1: sda3_crypt
PamCryptsetup_Helper[2754]: Argument 2: user
PamCryptsetup_Helper[2754]: Reading argument 1
PamCryptsetup_Helper[2754]: Reading argument 2 
PamCryptsetup_Helper[2754]: Reading password from login module.
PamCryptsetup_Helper[2754]: Reading old_password from login module.
PamCryptsetup_Helper[2754]: Checking if old password exists in crypt headerCrypt update process started.

passwd: password udpated successfully
PamCryptsetup_Helper[2754]: Crypt slot check returned 1
PamCryptsetup_Helper[2754]: Updating passpharse in slot 1
Volume key does not match the volume.
PamCryptsetup_Helper[2754]: Failed to update passphrase: Failed to retrieve valid crypt volume key: Operation not permitted (1)

Do I have something configured incorrectly?

Improve Testing of Module -> Helper Interface

At this time, the unit tests included focus on the behavior of the helper executable, due to initial difficulties seen attempting to write unit tests for PAM modules.

However, as shown in issue #5, testing is needed for the PAM module to ensure that it interfaces with the system and the helper binary as expected. I will focus my efforts when I have a chance to implement some tests for the PAM module using pam_wrapper

Build failed error: unknown option after ‘#pragma GCC diagnostic’

https://travis-ci.org/github/aarnaud/pam-cryptsetup/jobs/749145808

Maybe introduced by 39d343b #9

libtool: link: /bin/grep -E -e "pam_sm_*" ".libs/pam_cryptsetup.exp" > ".libs/pam_cryptsetup.expT"

libtool: link: mv -f ".libs/pam_cryptsetup.expT" ".libs/pam_cryptsetup.exp"

libtool: link: echo "{ global:" > .libs/pam_cryptsetup.ver

libtool: link:  cat .libs/pam_cryptsetup.exp | sed -e "s/\(.*\)/\1;/" >> .libs/pam_cryptsetup.ver

libtool: link:  echo "local: *; };" >> .libs/pam_cryptsetup.ver

libtool: link:  gcc -shared  -fPIC -DPIC  .libs/pam_cryptsetup_la-module.o   -lglib-2.0 -lpam -lcryptsetup  -fstack-protector-all -Wl,-z -Wl,relro -Wl,-z -Wl,now -g -O2 -fstack-protector-strong -Wl,-Bsymbolic-functions -Wl,-z -Wl,relro   -Wl,-soname -Wl,pam_cryptsetup.so -Wl,-version-script -Wl,.libs/pam_cryptsetup.ver -o .libs/pam_cryptsetup.so

libtool: link: ( cd ".libs" && rm -f "pam_cryptsetup.la" && ln -s "../pam_cryptsetup.la" "pam_cryptsetup.la" )

gcc -DPACKAGE_NAME=\"pam-cryptsetup\" -DPACKAGE_TARNAME=\"pam-cryptsetup\" -DPACKAGE_VERSION=\"0.1\" -DPACKAGE_STRING=\"pam-cryptsetup\ 0.1\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"pam-cryptsetup\" -DVERSION=\"0.1\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_LIBCRYPTSETUP=1 -DHAVE_LIBPAM=1 -DHAVE_ERRNO_H=1 -DHAVE_FCNTL_H=1 -DHAVE_STDIO_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_WAIT_H=1 -DHAVE_SYSEXITS_H=1 -DHAVE_SYSLOG_H=1 -DHAVE_UNISTD_H=1 -DHAVE_LIBCRYPTSETUP_H=1 -DHAVE_LIBDEVMAPPER_H=1 -DHAVE_SECURITY_PAM_EXT_H=1 -DHAVE_SECURITY_PAM_MODULES_H=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_MEMSET=1 -DHAVE_EXPLICIT_BZERO=1 -I.  -DCACHE_DIR='"/usr/var/pam_cryptsetup"' -Wdate-time -D_FORTIFY_SOURCE=2 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -Wall -Werror -DG_LOG_DOMAIN="\"pamcryptsetup\"" -D_GNU_SOURCE=1 -fstack-protector-all -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now, -Wformat -Wformat-security -g -O2 -fdebug-prefix-map=/home/travis/build/aarnaud/pam-cryptsetup=. -fstack-protector-strong -Wformat -Werror=format-security -c -o pam_cryptsetup_helper-helper.o `test -f 'helper.c' || echo './'`helper.c

helper.c: In function ‘main’:

helper.c:389:40: error: unknown option after ‘#pragma GCC diagnostic’ kind [-Werror=pragmas]

         #pragma GCC diagnostic ignored "-Wstringop-truncation"

                                        ^~~~~~~~~~~~~~~~~~~~~~~

cc1: all warnings being treated as errors

Makefile:1014: recipe for target 'pam_cryptsetup_helper-helper.o' failed

make[3]: *** [pam_cryptsetup_helper-helper.o] Error 1

make[3]: Leaving directory '/home/travis/build/aarnaud/pam-cryptsetup/src'

Makefile:668: recipe for target 'all' failed

make[2]: *** [all] Error 2

make[2]: Leaving directory '/home/travis/build/aarnaud/pam-cryptsetup/src'

Makefile:391: recipe for target 'all-recursive' failed

make[1]: *** [all-recursive] Error 1

make[1]: Leaving directory '/home/travis/build/aarnaud/pam-cryptsetup'

dh_auto_build: make -j1 returned exit code 2

debian/rules:4: recipe for target 'build' failed

make: *** [build] Error 2

dpkg-buildpackage: error: debian/rules build subprocess returned exit status 2

The command "dpkg-buildpackage -rfakeroot -b -uc" exited with 2.

Ubuntu 18.04, causes su and polkit to hang

Hi, this piece of work is great and i've been using it for some time. However, on Ubuntu 18.04 LTS I've noticed if the auth line is added to /etc/pam.d/common-auth, all polkit GUI prompts hang. In addition to this, trying to 'su' to another user causes the same hanging behavior. There isn't anything particularly apparent in the logs, the helper runs through the normal 2-stage process of comparing the password and updating the disk / cache as needed and exits - its just that the calling process appears to hang (su, polkit).

sudo works fine, and so does OS login.

To work around this, i've kept the common-auth change in place, however I duplicated the stock common-auth (without the added cryptsetup module) and updated the @include references in /etc/pam.d/polkit-1 and /etc/pam.d/su to point to the original version of common-auth. I'm unsure what else is having the hanging issue, more testing would be needed.

Any ideas?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.