lemonldap-ng issues
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues
2024-03-27T13:29:12Z
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3127
Support SAML subject-id and pairwise-id natively
2024-03-27T13:29:12Z
Maxime Besson
Support SAML subject-id and pairwise-id natively
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 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 configs
2.20.0
Maxime Besson
Maxime Besson
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3126
Allow multiple TOTP devices to be registered
2024-03-27T10:11:12Z
Maxime Besson
Allow 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 TOTP
2.20.0
Maxime Besson
Maxime Besson
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3124
Allow users to configure WebAuthn relying party ID
2024-03-20T13:29:26Z
Maxime Besson
Allow 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::WebAuthn
2.19.0
Maxime Besson
Maxime Besson
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3118
Minimal LDAP server load-balancing
2024-03-08T14:10:26Z
Yadd
Minimal 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 discussion
Yadd
Yadd
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3116
Restart authentication process when error is linked to token expiration
2024-03-27T10:59:00Z
Clément OUDOT
Restart authentication process when error is linked to token expiration
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 ...
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.0
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3092
Display an error message when issuer context is not restored
2024-01-25T15:49:33Z
Maxime Besson
Display 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 displayed
2.19.0
Maxime Besson
Maxime Besson
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3056
Remove XML::Simple (again)
2024-03-27T08:18:27Z
Maxime Besson
Remove XML::Simple (again)
Same as #1491 but in 2.0 branch
Same as #1491 but in 2.0 branch
2.20.0
Maxime Besson
Maxime Besson
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3051
Add messaging broker support to share instantaneously events like logout or c...
2024-03-27T10:53:38Z
Yadd
Add messaging broker support to share instantaneously events like logout or configuration update
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 "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" system
2.20.0
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3040
Allow auto-detection of portal URL and domain
2024-03-28T16:34:28Z
Maxime Besson
Allow auto-detection of portal URL and domain
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 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.19
2.19.0
Maxime Besson
Maxime Besson
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3019
Update fontawesome to v5 (LTS)
2024-03-27T10:55:07Z
Benjamin Demarteau
Update 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.0
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3015
Minimal skin to help developers
2024-03-27T10:04:16Z
Yadd
Minimal skin to help developers
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 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 tests
2.20.0
Yadd
Yadd
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3006
OIDC shouldn't rotate keys when they are fixed in lemonldap-ng.ini
2023-11-20T16:27:28Z
Yadd
OIDC shouldn't rotate keys when they are fixed in lemonldap-ng.ini
In discussion
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/3000
Implement continuations in the portal login flow
2023-10-10T13:31:15Z
Maxime Besson
Implement continuations in the portal login flow
### Summary
The LemonLDAP::NG portal is centered around the idea of running a list of methods (with `do`) in order.
(extractFormInfo, getUser, etc)
But this flow generally needs to be interrupted at some point for user interaction:
*...
### Summary
The LemonLDAP::NG portal is centered around the idea of running a list of methods (with `do`) in order.
(extractFormInfo, getUser, etc)
But this flow generally needs to be interrupted at some point for user interaction:
* Entering credentials
* Entering 2FA
* Showing notifications
* Showing info
* etc.
Each component of LemonLDAP::NG has its own way of doing that. Generally a OneTimeToken is used, but not always.
* Issuer saves the request environment
* 2FA saves sessionInfo + a couple other fields
* Notifications encrypt the session cookie but require $req->data->{url} to be persisted
* etc.
There are literally dozens of bugs, maybe more, caused by the fact that the
current `$req` object needs to be serialized before the interaction and
restored after, and this is done incorrectly.
There are many bugs caused by interactions that arise for the fact that some
early part of the processing sets something in `$req->data` that is needed
later, but not restored correctly.
There are also many bugs caused by the fact that some extra steps are stored in
`$req->steps` but not restored after an interaction.
### Design proposition
We need to create a generic system for storing the request state during a user
interaction, including `$req->steps`. This system should be used by every part
of LemonLDAP::NG that needs to interrupt the current flow to display a page.
I will update this issue with a design proposal later, but it will take a lot
of time to implement this correctly, and require many preliminary steps.
Maxime Besson
Maxime Besson
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2999
Better Session API
2024-03-27T09:45:47Z
Maxime Besson
Better Session API
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 ...
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.0
Maxime Besson
Maxime Besson
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2967
SAML federation plugin should use Name instead of FriendlyName
2024-03-27T10:04:42Z
Maxime Besson
SAML federation plugin should use Name instead of FriendlyName
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" 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.0
Maxime Besson
Maxime Besson
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2951
Append a conf test to check if password generation regexp matches LLNG passwo...
2024-03-27T10:05:09Z
Christophe Maudoux
chrmdx@gmail.com
Append 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 policy
2.20.0
Christophe Maudoux
chrmdx@gmail.com
Christophe Maudoux
chrmdx@gmail.com
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2947
Append an OAuth2ST handler wrapper
2024-03-27T10:05:35Z
Christophe Maudoux
chrmdx@gmail.com
Append 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.0
Christophe Maudoux
chrmdx@gmail.com
Christophe Maudoux
chrmdx@gmail.com
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2941
Replace userLogger with a more flexible system
2024-03-25T16:13:33Z
Maxime Besson
Replace 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.0
Maxime Besson
Maxime Besson
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2890
Allow syslog to send logs to a remote host
2024-03-28T07:43:58Z
Yadd
Allow 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.0
Yadd
Yadd
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2880
php-jwt requires "alg" parameter in JWKS
2024-03-27T10:08:14Z
Maxime Besson
php-jwt requires "alg" parameter in JWKS
Software that relies on php-jwt (such as GLPI) needs an "alg" subkey in JWKS.
Problem is that a single RSA key can be used by multiple JWE algs, and "alg" is single valued, in addition to being non-mandatory
A workaround in some compet...
Software that relies on php-jwt (such as GLPI) needs an "alg" subkey in JWKS.
Problem is that a single RSA key can be used by multiple JWE algs, and "alg" is single valued, in addition to being non-mandatory
A workaround in some competing solutions is to declare `"alg": "RS256"` even if it's technically false
Backlog
Maxime Besson
Maxime Besson