lemonldap-ng issueshttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues2024-03-27T13:29:12Zhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3127Support SAML subject-id and pairwise-id natively2024-03-27T13:29:12ZMaxime BessonSupport SAML subject-id and pairwise-id nativelysubject-id and pairwise-id are replacement for SAML NameIDs in use in Renater/Edugain federations :
https://docs.oasis-open.org/security/saml-subject-id-attr/v1.0/cs01/saml-subject-id-attr-v1.0-cs01.html
Currently, subject-id and pairwi...subject-id and pairwise-id are replacement for SAML NameIDs in use in Renater/Edugain federations :
https://docs.oasis-open.org/security/saml-subject-id-attr/v1.0/cs01/saml-subject-id-attr-v1.0-cs01.html
Currently, subject-id and pairwise-id can be enabled via a macro, but this is complex to configure. Especially pairwise-id which must be configured as a per-SP macro for all SPs
Maybe we should natively implement subject-id and pairwise-id through simple options in SAML SP configs2.20.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3126Allow multiple TOTP devices to be registered2024-03-27T10:11:12ZMaxime BessonAllow multiple TOTP devices to be registered### Summary
Currently it is possible to register multiple Webauthn devices, but not multiple TOTP### Summary
Currently it is possible to register multiple Webauthn devices, but not multiple TOTP2.20.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3125Add base class for "reset password by SMS"2024-03-27T10:22:31ZYaddAdd base class for "reset password by SMS"SMS API are not standard, however we could easily have a base class to prepare that.
## Design proposition
* Move part of [MailPasswordReset](lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/MailPasswordReset.pm) into "Lib/PasswordR...SMS API are not standard, however we could easily have a base class to prepare that.
## Design proposition
* Move part of [MailPasswordReset](lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/MailPasswordReset.pm) into "Lib/PasswordReset.pm"
* Maybe create a "Lib/SMSBase.pm" that stores custom parameters somewhere and just needs a "sendSMS" method in sub classes
* Create a "Lib/SMS.pm" that requires a class that exposes a `sendSMS($phone, $text)`
* Create a "Plugins/SMSPasswordResetBase.pm" that inherits from "Lib/PasswordReset.pm" and uses "Lib/SMS.pm"2.20.0YaddYaddhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3124Allow users to configure WebAuthn relying party ID2024-03-20T13:29:26ZMaxime BessonAllow users to configure WebAuthn relying party ID### Summary
Some users want to use an external system to register WebAuthn credentials
This requires a given WebAuthn device to share credentials between the portal and the registration system
### Design proposition
Allow the RP ID t...### Summary
Some users want to use an external system to register WebAuthn credentials
This requires a given WebAuthn device to share credentials between the portal and the registration system
### Design proposition
Allow the RP ID to be configured in 2F::WebAuthn2.19.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3123JWKS timeout is not implemented2024-03-27T10:40:19ZMaxime BessonJWKS timeout is not implemented### Affected version
Version: 2.18.2
### Summary
* Configure Auth::OpenIDConnect with a test OP
* set oidcOPMetaDataOptionsJWKSTimeout = 30 (or any non zero value)
* When restarting portal, JWKS is downloaded :white_check_mark:
* Aft...### Affected version
Version: 2.18.2
### Summary
* Configure Auth::OpenIDConnect with a test OP
* set oidcOPMetaDataOptionsJWKSTimeout = 30 (or any non zero value)
* When restarting portal, JWKS is downloaded :white_check_mark:
* After 30 seconds, JWKS is not refreshed :x:2.19.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3119Inconsistent logs when using "faketicket" CAS access policy2024-03-08T15:03:36ZMaxime BessonInconsistent logs when using "faketicket" CAS access policy### Affected version
Version: 2.18.2
### Summary
* Configure CAS Access control policy = Fake ticket
* Set an access rule for a CAS service
### Logs
When accessing with an unauthorized user:
```
[warn] User dwho is not authorized t...### Affected version
Version: 2.18.2
### Summary
* Configure CAS Access control policy = Fake ticket
* Set an access rule for a CAS service
### Logs
When accessing with an unauthorized user:
```
[warn] User dwho is not authorized to access to testcasapp
[notice] User dwho is authorized to access to testcasapp
```
Logs are contradictory2.19.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3118Minimal LDAP server load-balancing2024-03-08T14:10:26ZYaddMinimal LDAP server load-balancing[Net::LDAP](https://metacpan.org/pod/Net::LDAP) provide a way to have more than one LDAP server, this permits to have a fallback. However it tries servers always in the same order. This has some issues:
- only one server is used
- when...[Net::LDAP](https://metacpan.org/pod/Net::LDAP) provide a way to have more than one LDAP server, this permits to have a fallback. However it tries servers always in the same order. This has some issues:
- only one server is used
- when the first server is down, all LDAP connections are slowed down to wait for first failure
# Design proposition
This should be pushed to [Lemonldap::NG::Portal::Lib::Net::LDAP](lemonldap-ng-portal/blib/lib/Lemonldap/NG/Portal/Lib/Net/LDAP.pm) and [Apache::Session::Browseable](https://metacpan.org/pod/Apache::Session::Browseable).
```perl
our %knownDown;
our %knownLdapServerStrings;
sub sortDead {
return 1 if $knownDown{$a} and !$knownDown{$b};
return -1 if $knownDown{$b} and !$knownDown{$a};
return 0;
}
# ...
sub new {
# ...
$knownLdapServerStrings{$conf->ldapServer} ||= [ split( /\s+/, $conf->ldapServer ) || 'localhost' ];
# Simple round-robbin if asked
if ($conf->{ldapRoundRobbin}) {
my $last = shift @{ $knownLdapServerStrings{$conf->ldapServer} };
push @{ $knownLdapServerStrings{$conf->ldapServer} }, $last;
}
# Push server which have failed to the end of the list
my @uris = sort pushDeadToEnd @uris;
my $first = $uris[0];
# ... create LDAP object using \@uris
# Update knownDone list:
# The server chosen by Net::LDAP is up
delete $knownDown{ $self->{net_ldap_uri} };
# If Net::LDAP changed, this means that first LDAP is down
if ( $self->{net_ldap_uri} != $first ) {
$knownDown{ $first } = 1;
}
# ...
}
```
@clement_oudot, @maxbes: what do you think ?In discussionYaddYaddhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3117Add a hook before 2fa retry2024-03-08T10:17:50ZMaxime BessonAdd a hook before 2fa retryWe added the possibility to retry a second factor in #3080
It could be useful to run some custom code (eg for reporting) right before the 2FA is retriedWe added the possibility to retry a second factor in #3080
It could be useful to run some custom code (eg for reporting) right before the 2FA is retried2.19.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3116Restart authentication process when error is linked to token expiration2024-03-27T10:59:00ZClément OUDOTRestart authentication process when error is linked to token expirationCurrently, when the security token is expired (`Returned error: 82 (PE_TOKENEXPIRED)`), we end up on error page and user must return to portal to restart authentication process.
It could be better to display the error on the login form ...Currently, when the security token is expired (`Returned error: 82 (PE_TOKENEXPIRED)`), we end up on error page and user must return to portal to restart authentication process.
It could be better to display the error on the login form so user can directly restart the authentication process.2.20.0https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3115Date in login history is based on session _utime, not the very same time as t...2024-03-27T09:53:05Zphilippe lhardyphilha@worteks.comDate in login history is based on session _utime, not the very same time as the login triggering action### Affected version
All versions up to 2.18 and including current dev.
### Summary
Success or Failure records for login history use _utime and not actual time of action.
This is enlighted when using 2FA.
When tentatively implementi...### Affected version
All versions up to 2.18 and including current dev.
### Summary
Success or Failure records for login history use _utime and not actual time of action.
This is enlighted when using 2FA.
When tentatively implementing #3106 ordering of login failure of multiple successive 2FA failure couldn't be based on time since all entries had the very same one.
### Possible fixes
Use current time within loging history.2.19.0philippe lhardyphilha@worteks.comphilippe lhardyphilha@worteks.comhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3113Add possibility to store conf secrets in separated files2024-03-27T09:09:10ZYaddAdd possibility to store conf secrets in separated filesWhen I'm using Lemonldap with static configuration (deployed using help chart), the key rotation maybe lost when restarting containers.
## Design proposition
`lemonldap-ng.ini` contains a new key `secretsPath`. Then when [Common::Conf]...When I'm using Lemonldap with static configuration (deployed using help chart), the key rotation maybe lost when restarting containers.
## Design proposition
`lemonldap-ng.ini` contains a new key `secretsPath`. Then when [Common::Conf](lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf.pm) see that:
- when "load": read the list of secret and launches them from this directory (keyName == fileName)
- when "store": ignore this changes ?
@clement_oudot, @maxbes, @xavierb : any idea/advice ?2.19.0YaddYaddhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3111Hide Code2F secrets even from debug logs2024-03-27T10:25:25ZMaxime BessonHide Code2F secrets even from debug logsCurrently, secrets such as OTP codes (Code2F.pm) are displayed in cleartext in debug logs.
This is useful for debugging
Some users want to be able to hide the values even from error logs
We should find a way to do this, maybe a special ...Currently, secrets such as OTP codes (Code2F.pm) are displayed in cleartext in debug logs.
This is useful for debugging
Some users want to be able to hide the values even from error logs
We should find a way to do this, maybe a special value in hiddenAttributes ?2.19.0Clément OUDOTClément OUDOThttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3105SAML cannot set custom signature scheme when used in Choice2024-02-19T13:24:27ZMaxime BessonSAML cannot set custom signature scheme when used in Choice### Affected version
Version: 2.18.2
### Summary
* Configure Auth::Choice
* One choice: SAML
* Add an IDP
* Set custom signature method (RSA_SHA1 or other)
* Try to login on IDP: all other settings (nameID policy, etc) are ignored
#...### Affected version
Version: 2.18.2
### Summary
* Configure Auth::Choice
* One choice: SAML
* Add an IDP
* Set custom signature method (RSA_SHA1 or other)
* Try to login on IDP: all other settings (nameID policy, etc) are ignored
### Logs
```
filename_or_buffer cannot be undef at /home/maxbes/src/lemonldap-ng/lemonldap-ng-portal/blib/lib/Lemonldap/NG/Portal/Lib/SAML.pm line 3435
```
### Possible fixes
For some extremely weird reason, the fact that `$self->conf` is a tied hash when Choice is in used interferes with the Lasso binding, which sees the key and certificate strings as empty even if they are not empty2.19.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3104Incorrect initialization of SAML IDP causes IDP to fallback to default settings2024-03-27T08:25:53ZMaxime BessonIncorrect initialization of SAML IDP causes IDP to fallback to default settingsWhen initializing a SAML IDP in Auth::SAML, if some step goes wrong (impossible to set signature policy, or bad rule), the IDP is still useable but no defaults are set
We need to make sure the IDP is correctly loaded before enabling it,...When initializing a SAML IDP in Auth::SAML, if some step goes wrong (impossible to set signature policy, or bad rule), the IDP is still useable but no defaults are set
We need to make sure the IDP is correctly loaded before enabling it, and report an error if it isn't the case2.19.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3103Add a plugin/issuer for Jitsi Meet JWT authentication2024-03-27T04:30:33ZMaxime BessonAdd a plugin/issuer for Jitsi Meet JWT authenticationThe popular Jitsi Meet application does not use OIDC or SAML, but relies on a custom JWT format.
Some projects already bridge the gap between Jitsi and standard SSO protocols
https://github.com/Renater/Jitsi-SAML2JWT
(and others)
But ...The popular Jitsi Meet application does not use OIDC or SAML, but relies on a custom JWT format.
Some projects already bridge the gap between Jitsi and standard SSO protocols
https://github.com/Renater/Jitsi-SAML2JWT
(and others)
But they require deploying yet another piece of software, usually from Docker
We could include a plugin that does the same job, directly inside LLNG2.19.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3102Allow custom ordering in history session keys2024-03-18T13:07:55ZMaxime BessonAllow custom ordering in history session keysSurrently, session keys are displayed in the login history by alphabetical order
We should let users reorder them, for example using 1_xxx prefixes like we do for ChoicesSurrently, session keys are displayed in the login history by alphabetical order
We should let users reorder them, for example using 1_xxx prefixes like we do for Choices2.19.0Abhishek PaiAbhishek Paihttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3101OIDC offline session refresh has no access to previous session info2024-03-26T13:21:23ZMaxime BessonOIDC offline session refresh has no access to previous session infoFor a custom plugin, I need to access the _samlToken stored at login time in getUser.
Currently, the offline refresh code does not allow it:
```
$req->user( $refreshSession->data->{_session_uid} );
$req->data->{$_} = $r...For a custom plugin, I need to access the _samlToken stored at login time in getUser.
Currently, the offline refresh code does not allow it:
```
$req->user( $refreshSession->data->{_session_uid} );
$req->data->{$_} = $refreshSession->data->{$_} foreach (qw(_choice));
$req->steps( [
'getUser', @{ $self->p->betweenAuthAndData },
'setSessionInfo', $self->p->groupsAndMacros,
'setLocalGroups',
]
);
```
Only _choice is kept, and the _samlToken cannot be exposed to getUser
In order to fix this, a possible solution would be to run the same process we do in the "Refresh my rights" feature:
keep existing session keys, refresh, and update the session with the new keys. This will remove some code duplication between OIDC and Main2.19.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3100Add PKCE option inside Auth::OpenIDConnect2024-02-28T04:51:07ZYaddAdd PKCE option inside Auth::OpenIDConnectYes this is strange but required by some IDP even if login/password is also required.Yes this is strange but required by some IDP even if login/password is also required.2.19.0YaddYaddhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3099second factor type is not stored in history in case of a 2FA failure2024-03-26T12:32:06ZMaxime Bessonsecond factor type is not stored in history in case of a 2FA failure### Summary
If you add the `_2f` session variable to `sessionDataToRemember`, you will only see the _2f variable in your login history if it succeeded
1FA failure:
```
# 'failedLogin' => [
# ...### Summary
If you add the `_2f` session variable to `sessionDataToRemember`, you will only see the _2f variable in your login history if it succeeded
1FA failure:
```
# 'failedLogin' => [
# {
# '_auth' => 'Demo',
# ...
# },
```
2FA failure:
```
# 'failedLogin' => [
# {
# '_auth' => 'Demo',
# '_2f' => undef,
# ...
# },
```
### Design proposition
We should set the _2f variable even if 2FA failed, so it can be displayed in history2.19.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3098[security:low] PKCE is not enforced when requested by RP but not required by OP2024-02-12T02:44:25ZMaxime Besson[security:low] PKCE is not enforced when requested by RP but not required by OP### Affected version
Version: 2.18.1
### Summary
* Configure an OIDC RP in LemonLDAP but don't require PKCE on it
* Use a PKCE flow to login to the RP, with a valid verifier => WORKS :white_check_mark:
* Use a PKCE flow to login to t...### Affected version
Version: 2.18.1
### Summary
* Configure an OIDC RP in LemonLDAP but don't require PKCE on it
* Use a PKCE flow to login to the RP, with a valid verifier => WORKS :white_check_mark:
* Use a PKCE flow to login to the RP, with a non-valid verifier => ALSO WORKS :thinking:
PKCE is a mechanism that protect the authorization code from being stolen by another application. LemonLDAP implements PKCE as an optional security mechanism.
As per https://datatracker.ietf.org/doc/html/rfc7636#section-4.4
> When the server issues the authorization code in the authorization
> response, it MUST associate the "code_challenge" and
> "code_challenge_method" values with the authorization code so it can
> be verified later.
In my understanding, this means that when the RP triggers PKCE, the OP MUST enforce it during the token request, which is not the case now.
Current behavior is:
* Require PKCE enabled: PKCE is required at authorization time in all cases + enforced at token request time
* Require PKCE disabled: PKCE not required at authorization time + not enforced at token request time
In my opinion, the behaviour should be:
* Require PKCE enabled: same as above
* Require PKCE disabled: PKCE not required at authorization time + *but enforced at token request time* if the application used it
Do you agree @guimard @clement_oudot ?2.18.2Maxime BessonMaxime Besson