Skip to content

pam_zfs_key: support keyfile for filesystem mount in sm_open_session #11247

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

CragW
Copy link
Contributor

@CragW CragW commented Nov 27, 2020

pam_zfs_key: support keyfile for filesystem mount in sm_open_session

Use pam's pw_get to decrypt the filesystem if 'keylocation=prompt',
otherwise use zfs_crypto_load_key to verify and parse the keylocation
in order to get the key loaded.

If the authentication token is being changed for a user, the dataset in
relation to that user will do password change conditionally.

Only conditionally do if 'keylocation=prompt' already in use or argv
convKeyPrompt has been set. Thr former one will get the dataset updated
naturally without the need of convKeyPrompt.

The latter one, convKeyPrompt, does change keyformat and keylocation to
passphrase and prompt respectively even the original key is a file.

Signed-off-by: Crag Wang [email protected]

Motivation and Context

Support keyfile to mount a filesystem when user session opens up.

Description

  1. move the behavior of decrypt_mount() into pam_sm_open_session's body
  2. leverage authentication token only if prompt in use from the encrypted dataset
  3. leverage pw_get() if prompt in use from the encrypted dataset, for the others use zfs_crypto_load_key()
  4. check if the filesystem already mounted

How Has This Been Tested?

Compiled successfully on top of 04a82e, deployed onto Ubuntu 20.04 for testing through ssh, su and graphical login . The encrypted dataset corresponding to the user can be mounted successfully, the key worked from not only passphrase from pw_get() but also keyfile.

Tests for convKeyPrompt:

  1. Without convKeyPrompt, case prompt:
    Result: change_key updated the password successfully; login and dataset gets mounted successfully

  2. Without convKeyPrompt, case file:
    Result: ignored password change; login and dataset gets mounted successfully

  3. With convKeyPrompt, case prompt:
    Result: change_key updated the password successfully; login and dataset gets mounted successfully

  4. With convKeyPrompt, case file:
    Result: change_key updated the password successfully; login and dataset gets mounted successfully

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Performance enhancement (non-breaking change which improves efficiency)
  • Code cleanup (non-breaking change which makes code smaller or more readable)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation (a change to man pages or other documentation)

Checklist:

@CragW
Copy link
Contributor Author

CragW commented Nov 27, 2020

Adding @behlendorf , @aerusso and @felixdoerre for your insights and suggestions. I can do rebase #11226 when needed.

@felixdoerre
Copy link
Contributor

I am not really sure what the use of this behavior would be. This essentially disables pam_zfs_key on datasets not having keylocation=prompt. What would be the benefit compared to not encrypting/decrypting the dataset and not using pam_zfs_key at all?

@CragW
Copy link
Contributor Author

CragW commented Nov 28, 2020

Main objective here is that pam_zfs_key will get extensive sources to unlock the dataset e.g. keyfile, in addition to present prompt. The change_key should leave keyfile as is to prevent overridden forcefully.

We can create new argv handler for forcible change, for instance convKeyPrompt so users have clear line of sight that pam_zfs_key will change their keyfile structure.

@felixdoerre
Copy link
Contributor

felixdoerre commented Nov 28, 2020

The current behavior (which I find correct) is that pam_zfs_key ignores the configured source and always assumes "prompt", because "why would you use pam_zfs_key, if the key isn't prompted for?". Currently (according to documentation) there are only possible key sources "prompt" and "file". I am also not sure that the way this PR handles "changing" of file-keylocations the way anyone would expect. One might expect that when the user changes a password the keyfile is somehow updated.

So I find this behavior rather confusing. I'd be ok with the pam module just ignoring all datasets where keylocation is not prompt, but that this is the behavior for file://-keylocations is not obvious to me.

So I'd find this behavior resonable:

  • Without any argv[]: ignore datasets with keylocation != "prompt"
  • With convKeyPrompt in argv[]: behavior as it currently is.

@behlendorf behlendorf added the Status: Design Review Needed Architecture or design is under discussion label Nov 28, 2020
@CragW
Copy link
Contributor Author

CragW commented Nov 29, 2020

Thanks for your feedback, I will include the modification in next revision.

Use pam's pw_get to decrypt the filesystem if 'keylocation=prompt',
otherwise use zfs_crypto_load_key to verify and parse the keylocation
in order to get the key loaded.

If the authentication token is being changed for a user, the dataset in
relation to that user will do password change conditionally.

Only conditionally do if 'keylocation=prompt' already in use or argv
convKeyPrompt has been set. Thr former one will get the dataset updated
naturally without the need of convKeyPrompt.

The latter one, convKeyPrompt, does change keyformat and keylocation to
passphrase and prompt respectively even the original key is a file.

Signed-off-by: Crag Wang <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Design Review Needed Architecture or design is under discussion
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants