pam: Set PAM_AUTHTOK on successful authentication - #1190
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1190 +/- ##
==========================================
+ Coverage 87.53% 87.64% +0.11%
==========================================
Files 91 91
Lines 6231 6231
Branches 111 111
==========================================
+ Hits 5454 5461 +7
+ Misses 717 714 -3
+ Partials 60 56 -4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
This would be fine per the current broker, but we have the problem that we don't handle the change password phase well (as per #944 (comment)). And so, without it we may just end up having the token just set once and then be broken by a password change. Then, the problem, daemon side, is that we do not have the information to know whether the broker supports secrets or not to be sure if we should set this all the times. So the token that we are setting may be:
Thus again, this is something that IMHO we should not do without the broker providing us the AuthTok to set. My idea to have something more generic was:
PRO: Independent from authentication mode being used For the current situation, we could workaround the problem by keeping a similar structure, but sending back the very same secret that has been used by the user to authenticate. In this way we still leave the control to the broker, but also we should be able to use the information only if it's possible. However, in general I'd personally prefer to handle it all together (I mean, also once the passwd case is fixed), rather than having half-baked solutions, since this is the reason why we did not do this in the beginning. |
I read that comment before opening the PR but I don't understand the issue. We only support changing the password after a successful device authentication, in which case the same code path is taken and we set |
I need to check again the keyring pam code, but that was expected I think when using |
I also tried |
|
Also if the one authenticating to use |
I'll try that. |
It's always asking for the password of the user actually: #851 |
Yes, the keyring is also unlocked when I change the password via |
|
With #1234 we will have the case that there is no local password. I think authd could instead generate a secret the first time the user authenticates and set That is similar to your suggestion @3v1n0, but I think it makes more sense to let authd generate that secret than the broker, because there's nothing broker-specific about that secret. WDYT? |
22bc3d5 to
2f5d0e1
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1190 +/- ##
=======================================
Coverage 87.89% 87.89%
=======================================
Files 96 96
Lines 6965 6974 +9
Branches 111 111
=======================================
+ Hits 6122 6130 +8
- Misses 787 788 +1
Partials 56 56 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
2f5d0e1 to
2dac51d
Compare
|
@3v1n0 and I discussed this today. A reason to let the broker decide which secret to use is that it allows using the local password if there is one, which allows the user to unlock the keyring themself with that password in case that the keyring is locked during a session. That won't be possible without UI changes if we use an authd-generated secret instead. However, locking and unlocking the screen could be a workaround to also unlock the keyring in that case. An issue if we do use the local password as the keyring secret is that it won't be updated if the |
2dac51d to
cfab192
Compare
|
braindumping an idea:
|
What do we do in the other scenario where the local password is enabled back and there is a Do we perform the similar steps with |
That is technically possible, although risky (as the module may fail and us not discover it), but it's currently the only possibility. Ideally having a keyring that supports multiple secrets would be nice. |
|
Ok. Please feel free to let me know if my help is needed there, I will be happy to help. I will rebase #1234 after that. |
cfab192 to
d0544ad
Compare
|
@3v1n0, regarding our discussion, this would handle the MFA case you mentioned, right? diff --git a/pam/internal/adapter/authentication.go b/pam/internal/adapter/authentication.go
index 9c920c52d..67eeefa91 100644
--- a/pam/internal/adapter/authentication.go
+++ b/pam/internal/adapter/authentication.go
@@ -349,6 +349,8 @@ func (m authenticationModel) Update(msg tea.Msg) (authModel authenticationModel,
var secret string
if msg.secret != nil {
secret = *msg.secret
+ } else if m.currentSecret != "" {
+ secret = m.currentSecret
} else {
log.Warningf(context.Background(), "authentication granted, but no secret returned, cannot set PAM_AUTHTOK")
} |
d0544ad to
c44302e
Compare
Yeah, unless the fact that if there are multiple fields, we may pick the wrong one (so I'd still use the last secret if that it's the one that provided the granted access)... But in case that there is one form and then a non-form entry, it would work. It's tricky in the case that we have a Password authentication first and then an OTP for example, we can maybe do assumptions on the visibility of the form.. But well, as you know this is the reason why I liked the broker to drive all this. |
True, but changing the password is also broken in that case. Like I said in our discussion, I would leave solving that to later, when we actually have a broker that supports these kind of flows. |
|
Let's add some |
done |
401a714 to
406e936
Compare
|
Rebased on main and resolved conflicts |
406e936 to
f381360
Compare
|
@3v1n0 anything missing for this to be merged? |
f381360 to
d2a2f9d
Compare
10b2c75 to
95efad7
Compare
Call the PAM return value a "return value" instead of an "exit status" because I found the naming confusing.
By setting PAM_AUTHTOK the GNOME keyring is unlocked. UDENG-8799
Ensure that VM_NAME is exported to the environment of the ssh script to avoid Error: Missing required argument <release>
For example to pipe the output of one command into another.
I'm repeatedly seeing the launch of ptyxis time out after 30 seconds. Let's see if bumping the timeout fixes it.
…iles PAM_AUTHTOK can only be read by service modules — applications get PAM_BAD_ITEM from pam_get_item(3). Since pam-runner is an application, it cannot read the token directly after pam_authenticate/pam_chauthtok returns. Instead, use a reportAuthtok hook in pam.go (no-op by default, following the debugMessageFormatter pattern) that is overridden under the pam_debug build tag to print the token to stdout. This works for both the exec child (which inherits the PAM module's stdout so output reaches pam-runner's PTY) and the GDM native .so path (also built with pam_debug in tests). The print happens right after SetItem, so it appears before pam-runner's printPamResult output, and the existing waitForRunnerResult regex captures it naturally in the final snapshot. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Writing these e2e tests blind is hard for an agent: most assertions go through OCR, which is non-deterministic, and there was no documented way to verify an OCR match without running a full suite against the VM. Add an agent-facing authoring guide and a wrapper that launches YARF's interactive console against the live VM. The console gives the missing feedback loop: drive the screen to a state and probe what the OCR actually reads before committing a match, instead of guessing. The guide also records the assertion priority order (SSH/journal over OCR) and the OCR/keyword idioms the existing suite relies on, so agents compose from them rather than reinventing brittle sequences. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
After changing their local password with passwd, a user's GNOME login keyring would no longer unlock at login: the keyring stayed locked under the old password and secret-tool would hang waiting on an unlock prompt. pam_gnome_keyring re-keys an existing keyring during chauthtok using PAM_OLDAUTHTOK (to open it) and PAM_AUTHTOK (the new passphrase). We set PAM_AUTHTOK but never PAM_OLDAUTHTOK, so the keyring could not be re-keyed and was orphaned under the old password. During a password change the user authenticates with their old local password before setting the new one, so the previous step's secret is the old password. Carry it through to PAM_OLDAUTHTOK, but only for a CHANGE_PASSWORD session and only when the old and new secrets differ, so plain authentication never sets a spurious PAM_OLDAUTHTOK. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Guards against the login keyring being orphaned when a remote user changes their local password: log in with device auth, store a secret in the keyring, change the password with passwd, log back in with the new password, and require the stored secret to still be retrievable. The secret round-trip is what makes this discriminating: if the password change left the old keyring locked (or a fresh one was created), the lookup after re-login fails. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
95efad7 to
4359c7a
Compare
By setting
PAM_AUTHTOKthe GNOME keyring is unlocked.Closes #944
UDENG-8799