lemonldap-ng issueshttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues2024-03-20T13:29:26Zhttps://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/3092Display an error message when issuer context is not restored2024-01-25T15:49:33ZMaxime BessonDisplay an error message when issuer context is not restored### Affected version
Version: 2.18.1
### Summary
* Configure LLNG as an SAML/OIDC or CAS issuer
* Initialize login from a SP
* Log in using 2FA, SAML or something else that longer than issuersTimeout to perform
* Login works, but yo...### Affected version
Version: 2.18.1
### Summary
* Configure LLNG as an SAML/OIDC or CAS issuer
* Initialize login from a SP
* Log in using 2FA, SAML or something else that longer than issuersTimeout to perform
* Login works, but you are redirected either to the portal (SAML/CAS) or an error message (OIDC)
### Logs
```
[INFO] Bad (or expired) token 1706124567_32351
[ERROR] Unknown response type:
```
### Possible fixes
The user often gets confused about ending up on the portal, we should at least give them an error message that says they took too long so that they can understand why the application isn't displayed2.19.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3040Allow auto-detection of portal URL and domain2024-03-28T16:34:28ZMaxime BessonAllow auto-detection of portal URL and domainOne of my LLNG instances needs to be reached by internal and external users but on a different URL.
The portal uses $self->conf->{portal} and $self->conf->{domain} to get its own URL and cookie domain. But it doesn't work in this partic...One of my LLNG instances needs to be reached by internal and external users but on a different URL.
The portal uses $self->conf->{portal} and $self->conf->{domain} to get its own URL and cookie domain. But it doesn't work in this particular use case, because in my use case the portal and domain depends on `$req`.
This is similar to #933, but I think the fix proposed there no longer works since the migration to PSGI.
In the handler: it's probably not too difficult to do because every access to the portal URL goes through $class->tsv->portal. We just need to pass `$req` to it.
In the portal: we need to replace all calls to `$self->conf->{portal}` and `$self->conf->{domain}` to methods such as `getPortalUrl($req)` and `getDomain($req)`. This will require a lot of refactoring, but I think its a good idea because users will no longer have to define the `portal` and `domain` configuration variables anymore in most cases.
This is also a requirement of #2285
If I can find sponsorship for this feature I might implement it in 2.192.19.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2941Replace userLogger with a more flexible system2024-03-25T16:13:33ZMaxime BessonReplace userLogger with a more flexible system# Current situation
Currently, events are logged by the userLogger system, with the same semantic as technical logs:
Code:
```
$self->userLogger->notice( 'User '
. $ref->{ $self->conf->{whatToTrace} }
. " succes...# Current situation
Currently, events are logged by the userLogger system, with the same semantic as technical logs:
Code:
```
$self->userLogger->notice( 'User '
. $ref->{ $self->conf->{whatToTrace} }
. " successfully authenticated at level $ref->{authenticationLevel}"
);
```
Result:
```
[notice] User dwho successfully authenticated at level 2
```
This system has limitations:
* Not enough information (ip address? authentication method? etc)
* Hard to parse for analysis tools (`/User (.+) successfully authenticated at level (\d+)/`)
* Fragile: if the error message changes sysadmins have to reconfigure their logging system
* Difficult to integrate to a third party system (storing events to a db, redis, or sending them to a security tool)
* There is no central list of all possible events
* Do levels even make sense? What is the difference between `userLogger->notice` and `userLogger->error`? They are both events.
# Proposal
I would like to replace userLogger with a more flexible system, for example by passing a hash with contextual data:
Code:
```
$self->auditLog($req,
event_code => "USER_AUTHENTICATED",
level => $ref->{authenticationLevel},
user_id => $ref->{ $self->conf->{whatToTrace});
);
```
What happens then could be completely delegated to a plugin, for example, one plugin could construct a template from the `event_code`:
```
"USER_AUTHENTICATED": "User $user_id successfully authenticated at level $level from IP $req->ipaddr"
```
and render it as:
```
User dwho successfully authenticated at level 2 from IP 127.0.0.1
```
Another plugin could simply log:
```
USER_AUTHENTICATED: user_id=dwho, level=2, ip=127.0.0.1
```
Another plugin could save the data into Redis, etc.
# Roadmap
I am hoping to have this feature sponsored and integrated into the 2.X branch, which means we have to preserve compatibility. In order to do this:
* We need to modify all $self->userLogger calls to use the new system in the existing code base
* The default configuration of the new system must match the old error messages, so that existing log parsing tools are not broken (this can be done by shipping a plugin that maps event codes to the previously logged string)
* For people who use userLogger in third-party plugins, we need to povide a userLogger adapter that plugs into the new system, like this:
```
sub error {
my ($message) = @_;
$self->auditLog( level => "error", message => $message );
}
```2.19.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2700session extension hook2024-03-27T10:57:12Zdcoutadeur dcoutadeursession extension hook### Summary
This feature is asked by a customer, but can be interresting for other, especially if it is design in a generic way.
The main feature is to intercept some events and trigger a SSO session extension.
### Design proposition...### Summary
This feature is asked by a customer, but can be interresting for other, especially if it is design in a generic way.
The main feature is to intercept some events and trigger a SSO session extension.
### Design proposition
After some basic researches, I didn't found any sort of norms or standards for this.
Here is the design proposition:
1. the hook will intercept some events. Possible events are:
- when user call /ping endpoint on the portal, with a valid cookie
- when user authenticates,
- when user reauthenticates,
- when user asks for a "refresh my rights from the portal",
- when user is asked for a session upgrade (he must enter a second factor for accessing a more secure application)
- when an application sends a direct call to /ping, with the user session id passed in the Authentication header (we should think about security risks. Maybe replay attacks?)
- when refreshing an access token with a refresk token
- any other event I haven't think about?
The list of triggering events must be customizable.
2. it possibly triggers two actions:
- if timeoutActivity is set, it performs the same actions as in `Handler/Main/Run.pm` (function `retrieveSession`): it verifies if session is valid, checks the session is not expired (timeoutActivity), and updates _lastSeen in session. Note: thus it may be interresting to factorize this code if possible.
- if triggers an AT refresh thanks to the refresh token. The list of OIDC provider on which it is triggered must be customizable. Obviously, the refresh must occurs only if the user has authenticated against the given OIDC provider.
Do not hesitate to discuss this proposition and give your ideas.2.19.0dcoutadeur dcoutadeurdcoutadeur dcoutadeurhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/1848select authentication scheme according to authentication level2024-03-18T11:43:02Zdcoutadeur dcoutadeurselect authentication scheme according to authentication level### Summary
It would be nice to have a feature allowing the portal to choose the authentication scheme according to an authentication level.
This feature is to be considered as an evolution of:
```
https://lemonldap-ng.org/documentation...### Summary
It would be nice to have a feature allowing the portal to choose the authentication scheme according to an authentication level.
This feature is to be considered as an evolution of:
```
https://lemonldap-ng.org/documentation/latest/writingrulesand_headers
Instead of returning a 403 code, “minimum level” returns user to a form that explain that a higher level is required and propose the user to reauthenticate himself.
```
in other words, make the application "decide" the authentication scheme of the portal.
### Design proposition
[manager]
add a new parameter: desiredAuthenticationLevel for each vhost
[handler]
handler checks if desiredAuthenticationLevel is set
if desiredAuthenticationLevel > 0, handler redirects the user to <portal>?url=base64(url)&desiredAuthenticationLevel=n
[portal]
if portal is configured for "combination" module (and maybe also for choice module), then he tries to honor the desiredAuthenticationLevel only in case of scheme testing (ie combination using OR).
**example1:**
* desiredAuthenticationLevel = 5
* SSL = 5
* Kerberos = 4
* LDAP = 2
if after evaluating the if conditions in the combination rule, we get:
```
[Kerberos, LDAP] or [SSL, LDAP] or [LDAP, LDAP]
```
the OR components should be rearranged to make SSL appear first:
```
[SSL, LDAP] or [Kerberos, LDAP] or [LDAP, LDAP]
```
**example2:**
* desiredAuthenticationLevel = 2
* SSL = 5
* Kerberos = 4
* LDAP = 2
if after evaluating the if conditions in the combination rule, we get:
```
[SSL, LDAP] or [Kerberos, LDAP] or [LDAP, LDAP]
```
the OR components should be rearranged into:
```
[LDAP, LDAP] or [SSL, LDAP] or [Kerberos, LDAP]
```
if the authentication is set to "Choice", then we could also rely on the desiredAuthenticationLevel to display by default the tab corresponding to the desired authentication scheme.
### Security considerations
It might be dangerous to let desiredAuthenticationLevel be passed as an unencrypted GET parameter.
It might be used by an attacker to prevent a user to access an application.
What do you think about this proposition? Is there already some attempts to do something similar? Do you think about a better architecture / conception for this feature? It's opened to discussion.2.19.0Maxime BessonMaxime Bessonhttps://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/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/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/3056Remove XML::Simple (again)2024-03-27T08:18:27ZMaxime BessonRemove XML::Simple (again)Same as #1491 but in 2.0 branchSame as #1491 but in 2.0 branch2.20.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3051Add messaging broker support to share instantaneously events like logout or c...2024-03-27T10:53:38ZYaddAdd messaging broker support to share instantaneously events like logout or configuration updateWe can propose here a plugin system like logger interface. Proposed plugin list:
* [Redis pub/sub](https://redis.io/docs/interact/pubsub/)
* [RabbitMQ](https://www.rabbitmq.com/)
Such system can also provide a backend for a better "stat...We can propose here a plugin system like logger interface. Proposed plugin list:
* [Redis pub/sub](https://redis.io/docs/interact/pubsub/)
* [RabbitMQ](https://www.rabbitmq.com/)
Such system can also provide a backend for a better "status" system2.20.0https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3019Update fontawesome to v5 (LTS)2024-03-27T10:55:07ZBenjamin DemarteauUpdate fontawesome to v5 (LTS)### Summary
Font awesome 4 which was [added a few months ago](https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/merge_requests/322) is great, but the next LTS has been available for a long time and has a lot more icons to chose from.
...### Summary
Font awesome 4 which was [added a few months ago](https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/merge_requests/322) is great, but the next LTS has been available for a long time and has a lot more icons to chose from.
### Design proposition
Migrating from one the v4 to the v5 should be mostly painless (cf https://fontawesome.com/v5/docs/web/setup/upgrade-from-v4). Not sure if there are attention points.2.20.0https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3015Minimal skin to help developers2024-03-27T10:04:16ZYaddMinimal skin to help developersLLNG is distributed with a bootstrap skin. We decided some years ago to stop developing alternatives skins because it requires too many work.
However, create a custom skin is a huge work if one wants to change for example bootstrap to s...LLNG is distributed with a bootstrap skin. We decided some years ago to stop developing alternatives skins because it requires too many work.
However, create a custom skin is a huge work if one wants to change for example bootstrap to something else.
Proposition:
* continue to distribute LLNG with one elaborated skin
* add a very minimal skin, "_ready-to-be-changed_":
* no CSS
* minimize `portal.js` dependencies (maybe `jQuery` isn't really needed) **or** build it using a modern way _(Typescript + rollup)_
* no tabs and such CSS-based scripts...: Choice will simply provides `<ul><li>`
* move dependencies from common/*tpl to bootstrap/*.tpl
NB: this skin could also be used to simplify HTML parsing inside Perl tests2.20.0YaddYaddhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3006OIDC shouldn't rotate keys when they are fixed in lemonldap-ng.ini2023-11-20T16:27:28ZYaddOIDC shouldn't rotate keys when they are fixed in lemonldap-ng.iniIn discussionhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2999Better Session API2024-03-27T09:45:47ZMaxime BessonBetter Session APIThe current session API is not very satisfying:
* We use the same method to create and update a session (getApacheSession) which leads to bugs when $id is unexpectedly `undef`, or when creation works but setting attributes fail
* Error ...The current session API is not very satisfying:
* We use the same method to create and update a session (getApacheSession) which leads to bugs when $id is unexpectedly `undef`, or when creation works but setting attributes fail
* Error reporting is difficult (we need to test `$session->error`) and incomplete (#2995)
* Locking is not supported in most backends, which may cause bugs on high load
* Implementation is difficult to debug (use of `tie` behind the scenes, etc)
We should work on a new session API with cleaner methods, maybe we could even replace Apache::Session completely since I'm pretty sure noone uses Apache::Session::Browseable except for us, and Browseable backends are the recommended way to deploy LemonLDAP::NG ?2.20.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2967SAML federation plugin should use Name instead of FriendlyName2024-03-27T10:04:42ZMaxime BessonSAML federation plugin should use Name instead of FriendlyNameCurrently, SAML federation defines *session attributes* => *SAML attributes* mapping based on the FriendlyName of the requested attribute:
```
<md:RequestedAttribute NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" N...Currently, SAML federation defines *session attributes* => *SAML attributes* mapping based on the FriendlyName of the requested attribute:
```
<md:RequestedAttribute NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" Name="urn:oid:0.9.2342.19200300.100.1.3" FriendlyName="mail" isRequired="true"/>
```
Creates a "mail" > "urn:oid:0.9.2342.19200300.100.1.3" mapping
However, in the Edugain federation, some attributes have different FriendlyNames:
```
<md:RequestedAttribute NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" Name="urn:oid:0.9.2342.19200300.100.1.3" FriendlyName="Email" isRequired="true"/>
```
which forces us to create macros to map "Email" => "$mail"
We must find a different way to handle SAML attributes in federation, perhaps ship a dictionary for standard attributes, and let the users do the mapping themselves?2.20.0Maxime BessonMaxime Bessonhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2951Append a conf test to check if password generation regexp matches LLNG passwo...2024-03-27T10:05:09ZChristophe Maudouxchrmdx@gmail.comAppend a conf test to check if password generation regexp matches LLNG password policy### Affected version
Version: All
Platform: All
### Summary
When saving conf, a test should warn if password generation RegExp does not match the LLNG password policy### Affected version
Version: All
Platform: All
### Summary
When saving conf, a test should warn if password generation RegExp does not match the LLNG password policy2.20.0Christophe Maudouxchrmdx@gmail.comChristophe Maudouxchrmdx@gmail.comhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2947Append an OAuth2ST handler wrapper2024-03-27T10:05:35ZChristophe Maudouxchrmdx@gmail.comAppend an OAuth2ST handler wrapper### Summary
Some WebServices can be requested by OIDC applications using AccessToken and Web applications using ServiceToken.
It leads to define two routes, 1 protected by the ST handler and 1 protected by the OAuth2 handler.
### Desig...### Summary
Some WebServices can be requested by OIDC applications using AccessToken and Web applications using ServiceToken.
It leads to define two routes, 1 protected by the ST handler and 1 protected by the OAuth2 handler.
### Design proposition
The idea is to provide a handler able to serve both AT and ST like DevOpsST wrapper.2.20.0Christophe Maudouxchrmdx@gmail.comChristophe Maudouxchrmdx@gmail.comhttps://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2890Allow syslog to send logs to a remote host2024-03-28T07:43:58ZYaddAllow syslog to send logs to a remote host### Summary
In a docker environment, it's annoying to have to instantiate a syslog to send logs to a remote server.
### Design proposition
[Sys::Sylog](https://metacpan.org/pod/Sys::Syslog#setlogsock()) provides a `setlogsock()` funct...### Summary
In a docker environment, it's annoying to have to instantiate a syslog to send logs to a remote server.
### Design proposition
[Sys::Sylog](https://metacpan.org/pod/Sys::Syslog#setlogsock()) provides a `setlogsock()` function that allow to configure syslog to use a remote syslog (host, port, usd/tcp).
So we just have to add an option to call `setlogsock()` with custom parameters.2.20.0YaddYadd