pam: Set PAM_AUTHTOK on successful authentication#1190
pam: Set PAM_AUTHTOK on successful authentication#1190
PAM_AUTHTOK on successful authentication#1190Conversation
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 80.57% 87.56% +6.99%
==========================================
Files 20 91 +71
Lines 978 6232 +5254
Branches 0 111 +111
==========================================
+ Hits 788 5457 +4669
- Misses 190 719 +529
- Partials 0 56 +56 ☔ View full report in Codecov by Sentry. 🚀 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")
} |
By setting PAM_AUTHTOK the GNOME keyring is unlocked. UDENG-8799
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 |
|
@copilot review this PR |
Here's a summary of the current PR changes:
The MFA fallback ( |
| var secret string | ||
| // TODO: This will not select the correct secret in case the last authentication step uses a secret | ||
| // which is not the local password (e.g. OTP). | ||
| if msg.secret != nil { |
There was a problem hiding this comment.
I don't remember if it's still available at this level, but I think that here we could at least rely on the currentModel type and basically only set this if this an hidden form model or a new password one.
| if msg.secret != nil { | ||
| secret = *msg.secret | ||
| } else if m.currentSecret != "" { | ||
| secret = m.currentSecret |
There was a problem hiding this comment.
| secret = m.currentSecret | |
| // FIXME: We should move this to the broker when all the stars align....... :) | |
| secret = m.currentSecret |
| } else if m.currentSecret != "" { | ||
| secret = m.currentSecret | ||
| } else { | ||
| log.Warningf(context.Background(), "authentication granted, but no secret returned, cannot set PAM_AUTHTOK") |
There was a problem hiding this comment.
| log.Warningf(context.Background(), "authentication granted, but no secret returned, cannot set PAM_AUTHTOK") | |
| log.Warningf(context.Background(), "authentication granted, but no secret is available, cannot set PAM_AUTHTOK") |
|
We should also add tests here, at least it would suffice to print the value (when set) in |
|
And testing the gdm model should also be easy, given that it's the main target (but not the only one, since we need the cli for password change anyways) |
By setting
PAM_AUTHTOKthe GNOME keyring is unlocked.UDENG-8799