Upgrade from 2.x to 2.y
=======================


Please apply general caution as you would with any software: have
backups and a rollback plan ready!

Known regressions in the latest released version
------------------------------------------------

None at the moment

Security issue involving Nginx handlers
---------------------------------------

In Nginx < 1.29.5, a hacker can workaround the correlation between a Nginx virtualHost and the "Host" field.
And despite its documentation and the RFC 9112, Nginx builds automatically the HTTP_HOST variable based on the
maybe-forged host header (fastCGI or uWSGI).
F5 fixes this but doesn't want to consider this as a security issue, therefore there will be no fix for previous
versions.

In Lemonldap-NG context this security issue may allow an attacker who has a valid account to gain privileges to
handler protected application, including the LemonLDAP::NG manager application if not protected by other means.

Default Nginx files installed in versions 2.16.8, 2.21.4, and 2.22.3 may help **but are not enough to fix the issue**.

You are vulnerable if you have:

* Nginx (< 1.29.5) as web server, AND one of:

  * ``$http_host`` variable is used in your Nginx files
  * OR you didn't force ``HTTP_HOST`` in your FastCGI/uWSGI parameters

* AND no network component able to block the bad request (haproxy blocks the poisoned requests for example)

If so, you MUST apply this fix for every virtual host.

You must spot these lines anywhere you're using FastCGI *(including Lemonldap-NG files of course)*::

    fastcgi_param HOST $http_host;
    # or if using uwsgi server:
    #uwsgi_param HOST $http_host;

and **replace** them by::

    fastcgi_param HTTP_HOST $host;
    # or if using uwsgi server:
    # Do not set this line if your /etc/nginx/uwsgi_params contains already this line
    #uwsgi_param HTTP_HOST $host;

.. important::

    If the HOST variable is not defined in a protected handler virtual host, you MUST still **add** the HTTP_HOST as defined above

For precaution measures, it is also recommended to fix the Host header sent when using Nginx as (reverse-)proxy. You should spot this line::

    proxy_set_header Host $http_host;

and **replace** it by::

    proxy_set_header Host $host;


2.23.1
------

Regression on session purge
~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you are using the ``Apache::Session::Browseable::Postgres`` or
``Apache::Session::Browseable::MySQL`` session backends, you may be affected by
a regression in the session cleanup script that prevents old sessions from
being purged and slowly degrade performance over time.

This issue affects LemonLDAP::NG versions 2.22.x and 2.23.0. Users of these
versions are advised to upgrade to 2.23.1 as soon as possible, and double check
that session purge correctly works after upgrading.

SAML Common Domain Cookie now validates the return URL
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The SAML Common Domain Cookie (CDC) endpoint used to redirect to the ``url``
parameter without any control on its origin, which allowed it to be abused as
an open redirector (CWE-601).

Starting from this version, the CDC endpoint only redirects to a return URL
whose host belongs to:

* a registered SAML federation member (any host found in the ``entityID`` or
  endpoint ``Location`` of your declared SAML SP/IdP metadata), or
* a domain listed in the ``trustedDomains`` configuration parameter, or
* the portal hosting the CDC.

Any other return URL is now rejected with an HTTP 400 error.

Existing federations keep working without any change, since their members are
already declared through SAML metadata. **However**, if your CDC is shared with
partners whose return URL host is not present in the SAML metadata (for example
non-LL::NG service providers), you must add their domain to ``trustedDomains``.

2.23.0
------

OAuth2 Handler now hides Access Tokens
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The :doc:`oauth2handler` no longer transmits the Access Token to the backend application after verifying it.

You you rely on this behavior, you can add a custom exported header such as

* Key: ``Auth-Token``
* Value: ``$_accessToken``

JQuery Cookie is no longer bundled
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

LemonLDAP::NG no longer provides the ``jquery.cookie`` library. If you need this
library in your custom JS code, you need to add it back to
``/usr/share/lemonldap-ng/portal/htdocs/static/`` directory, or use a CDN.

New index on CAS session
~~~~~~~~~~~~~~~~~~~~~~~~

This new version can now manage backchannel logoutRequest coming from a CAS server (LL::NG configred as CAS client).

You need to add an index on CAS sessions table on ``auth_cas_ticket`` if you use a DB backend, and you want to use this new feature without impacting performances.

See ``sessions.my.sql`` and ``sessions.pg.sql`` to get SQL instructions.

2.22.2
------

OpenID-Connect secrets
~~~~~~~~~~~~~~~~~~~~~~

Starting from this version, LLNG follows strictly RFC 6749, so client\_id
and client\_secret are "URI-decoded" before comparison. In some rare case
this could generate a regression, then avoid using `%` character.

*sessionNotOnOrAfter duration* now starts when SAML response is built
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Previously, setting the *sessionNotOnOrAfter duration* on a SAML SP caused the
SAML response generated by LemonLDAP to indicate that the SAML session should
expire once that duration has elapsed since the user has logged in.

We now compute the requested session end time from the moment the SAML response
is generated, which can happen several hours after the user has logged in. If
you relied on the previous behavior, please adjust your configuration.

2.22.0
------

lemonldap-ng-cli
~~~~~~~~~~~~~~~~

Starting from this version, the ``lemonldap-ng-cli`` refuses to store
invalid configurations. If you use it with intermediate steps that are
invalid before next changes, use the new **--unsafe** option.

Stricter check on OIDC post-logout redirect URIs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In logout scenarios involving disconnecting from a remote IDP, you may start to
encouter error messages that warn about unauthorized URIs.

This happens because the `post_logout_redirect_uri` is now more strictly
enforced in those scenarios.  Make sure you have allowed the value of that
parameter in *OpenID Connect Relying Parties* > XXX > *Options* > *Logout* >
*Allowed redirection addresses for logout*

Change in post-logout redirect URI when LLNG is an OIDC client
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you use :doc:`authopenidconnect`, to delegate authentication to an external
OpenID Connect provider, you have to update your provider's configuration in
order to allow a new *post-logout* redirect URIs::

    https://<portal>/oauth2/rlogoutreturn

Change in timeout behavior for 2FA
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Contrary to previous versions, resending a 2FA code no longer extends the 2FA timeout anymore.

If your users start having issues with timeouts after upgrading, make sure you have set

*General parameters* » *Second factors* » *Global options* » *Login timeout* to a high enough value

In the particular case of email-based code delivery, you can override this parameter with

*General parameters* » *Second factors* » *Mail second factor* » *Code timeout*


Configuration update needed for OpenID Connect Providers that use signed requests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you configured the following option:

OpenID Connect Providers » op-example » Options » Protocol » Token endpoint authentication method = client_secret_jwt or private_key_jwt

Then, starting with this version, you need to explicitely configure the desired algorithm in *Signature algorithm for token endpoint authentication*:

* For ``client_secret_jwt``, specify ``HS256`` or greater.
* For ``private_key_jwt``, specify ``RS256`` or greater if you are using a RSA key, or ``ES256`` or greater if you are using an EC key.

2.21.1
------

Make sure no bogus CAS servers have been created
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Because of an issue in LemonLDAP::NG 2.21.0, your CAS applications might have
been erroneously created under the "CAS Servers" section as well.

Remove all unwanted **CAS Servers** entries from the manager after upgrading to
version 2.21.1 (or above) if this is the case.

2.21.0
------

Log4Perl log level
~~~~~~~~~~~~~~~~~~

Starting from this version, the global ``logLevel`` parameter is applied
for all loggers. Thus if you managed your log level inside the log4perl
configuration file, you may loose unimportant logs if your ``logLevel`` is
higher.

"typ" header in JWT
~~~~~~~~~~~~~~~~~~~

Version earlier than 2.17.0 had a "typ" header in all JWT following OIDC
specification. In version 2.17.0, this header was wrongly removed when
JWT library changed. This header has been restored starting from version
2.21.0. However some application may fail with it, so a
``Don't insert typ header`` option has been aded into RP/OP options to be
able to restore 2.17.0 behavior.


2.20.2
------

Post-logout redirection
~~~~~~~~~~~~~~~~~~~~~~~

Starting from this version, passing a ``url=`` parameter to the LemonLDAP logout
URL (``https://auth.example.com/logout`` or
``https://auth.example.com/?logout=1``) will only redirect the user to this URL
if the URL's domain is a known VHost, or a trusted domain.

To add a new domain to the trusted domain list, use the ``trustedDomains``
variable or the *General parameters* > *Advanced parameters* > *Security* >
*Trusted domains*. Wildcards can be used to allow all subdomains.

2.20.0
------

2FA deletion now uses a timeout
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Users may start encountering timeout errors if they remain on the 2FA manager
page too long before deleting their 2FA. In this situation, the page is
automatically refreshed. However, to improve user experience, you may want to
increase the *General Parameters* » *Second factors* » *Global options* »
*Login timeout* setting to increase the timeout.

Client secrets as GET parameters are no longer allowed
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

When calling the OIDC ``/oauth2/token`` endpoint, we no longer allow the
``client_secret`` parameter to be sent as an URL parameter. It has to be sent
either in the body (*client_secret_post*), or as part of and ``Authentication``
HTTP header (*client_secret_basic*).


U2F is no more supported
~~~~~~~~~~~~~~~~~~~~~~~~

Current browsers no more support U2F specification which has been replaced by
**Webauthn**. Starting from version 2.20.0, LemonLDAP::NG no more supports U2F also.

You can easily replace **U2F** by **Webauthn**. LemonLDAP::NG provides also migration tools:

::

   lemonldap-ng-sessions secondfactors migrateu2f --all
   lemonldap-ng-sessions secondfactors delType --all U2F

See :ref:`lemonldap-ng-sessions doc <cli-sessions>`

window.datas.login is no longer defined in JS code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The `window.datas.login` global JS variable used to contain the user's login.
It caused a security issue and was removed in this version. This only affects
users who wrote custom JS code for the portal and who explicitely used this
variable.

Status changed
^^^^^^^^^^^^^^

The obsolete "portal status" and "status" features were removed from 2.20.0.
An alternative is available using :doc:`Use message broker to collect status <statuscollect>`.

SAML federations
^^^^^^^^^^^^^^^^

The recommended way of configuring SAML federations is now to keep bundled metadata in a separate file.

Switching to this method should improve performance.

Check :doc:`SAML federation documentation <samlfederation>` to know how use this new method.

Auth::DBI no longer uses stored procedures to generate UNIX-style hashes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In this version, we no longer require stored procedures to generate
``unixcrypt1``, ``unixcrypt5`` and ``unixcrypt6`` hashes. The computation is
performed by LemonLDAP::NG itself.
This does not require any action by the admin or users. Let us know if you
encounter regressions.

Portal templates changes
~~~~~~~~~~~~~~~~~~~~~~~~

If you modified some non-custom HTML templates, :doc:`refer to template upgrade instructions<upgrade_templates>`

2.19.0
------

RPM packaging
~~~~~~~~~~~~~

RPM packages have been reorganized to match the Debian packages naming convention.
The upgrade via ``yum`` or ``dnf`` should work smoothly.

For EL8 and EL9, you must update the GPG key:

::

   curl https://lemonldap-ng.org/security/GPG-KEY-LLNG-SECURITY.asc > /etc/pki/rpm-gpg/RPM-GPG-KEY-OW2


Like Debian, jobs are now managed through systemd timers:

::

    systemctl edit lemonldap-ng-portal.timer
    systemctl edit lemonldap-ng-handler.timer

Portal templates changes
~~~~~~~~~~~~~~~~~~~~~~~~

If you modified some non-custom HTML templates, :doc:`refer to template upgrade instructions<upgrade_templates>`


2.18.2
------

PKCE is enforced for all OIDC clients supporting it
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In versions before 2.18.2, PKCE was not verified doing the token request of an
OIDC flow unless the "Require PKCE" option was set explicitly in the
LemonLDAP::NG configuration for this RP.

Starting from now, PKCE will be verified anytime a RP enabled it by specifying
the ``code_challenge`` parameter during the authorization request.

RPs that do not support PKCE will not send the ``code_challenge`` parameter,
and therefore will not be affected by this change.

2.18.0
------

"Stay connected" has changed name
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The "Stay connected on this device" feature has been refactored into a more
generic :doc:`trustedbrowser` feature. The name of the configuration section
has changed in the manager but no particular actions are required for existing
installations.

Change in second factor UI
~~~~~~~~~~~~~~~~~~~~~~~~~~

After registering a new second factor of type Webauthn, TOTP or Generic,
the user is now brought back to the main 2FA Management screen.
You can cancel this behavior by calling preventDefault in your JS handler:

.. code:: javascript

         $(document).on( "mfaAdded", { }, function( event, info ) {
                    event.preventDefault();
         });

See :doc:`jqueryevents` for more information

Apache2 handler now uses IP from mod_remoteip
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you use `mod_remoteip <https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html>`__ in your handlers,
LemonLDAP::NG will now correctly use the IP from ``mod_remoteip`` in
``$env->{REMOTE_ADDR}``.

OpenID Connect issuer now implements ``acr_values``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The `acr_values` from OpenID Connect authorization requests can now be used to increase the authentication level required for accessing a service. If after upgrading you start noticing that users are now asked to upgrade their session when trying to access OIDC applications, you should check the `acr_values` requested by you application, and map them to the desired authentication level in `OpenID Connect Service` » `Authentication context`

Cron files moved to systemd timers on Debian
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

On Debian, LemonLDAP::NG now uses systemd timers for maintenance tasks instead
of ``cron.d`` scripts.

If you need to modify the frequency of execution of your maintenance tasks, you should use a systemd override:

::

    systemctl edit liblemonldap-ng-portal-perl.timer
    systemctl edit liblemonldap-ng-handler-perl.timer

::

    [Timer]
    OnCalendar=*-*-* *:07:07


Encryption of password in session
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you store the password in session because you need to replay it on a protected application (Auth Basic or form replay),
you should now enable password encryption in session (this option is disabled by default).

This requires to decrypt the ``$_password``` value before sending it to the application, with the ``decrypt()`` method.

Safe Jail
~~~~~~~~~

For security reason, we now enforce Safe Jail by default in lemonldap-ng.ini, so an administrator with only access to Manager
cannot disable it. If you want to improve security, update your lemonldap-ng.ini. To retrieve the old behavior (Safe Jail configuration
through Manager), just let the option commented in lemonldap-ng.ini.

Portal templates changes
~~~~~~~~~~~~~~~~~~~~~~~~

If you modified some non-custom HTML templates, :doc:`refer to template upgrade instructions<upgrade_templates>`

2.17.1
------

Restriction in use of OIDC `request_uri`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A little-know feature of OIDC (*note*: you are probably not using it) allows the OpenID Provider, LemonLDAP::NG in this case, to fetch the Authorization request parameters itself by indicating a `request_uri` parameter.

By default, we now disallow this feature, and require LemonLDAP::NG admins to explicitly allow Request URIs in the configuration (*OpenID Connect Relying Parties* » *Your RP* » *Options* » *Security* » *Allowed URLs for fetching Request Object*). This setting allows wildcards such as ``http://rp.example.com/*``.

2.17.0
------

"Stay connected" now uses a TOTP challenge
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The :doc:`Stay connected on this device <trustedbrowser>` feature now relies on
a TOTP challenge. This means it only works if the client web browser is in
sync with the server.  Existing sessions are not affected by this new
requirement.

Possible regression in unicode character handling for UWSGI users
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

We fixed an issue that made UWSGI behavior inconsistent with other deployment
methods (FastCGI, ApacheMP2). As a consequence, you might notice a change in
the way non-ASCII characters are displayed by LemonLDAP::NG.

If you used workarounds to make non-ASCII characters work in UWSGI, you can
remove them in this new release.

If you instead wish to restore previous behavior, you can also set the
following configuration in `/etc/uwsgi/apps-available/llng-server.yaml` :

.. code:: yaml

    uwsgi:
            # ...
            env: LLNG_SKIPUTF8DOWNGRADE=1

However, restoring previous behavior is not recommended, as you are likely to run into
even more encoding bugs in the long run.


Portal templates changes
~~~~~~~~~~~~~~~~~~~~~~~~

If you modified some non-custom HTML templates, :doc:`refer to template upgrade instructions<upgrade_templates>`

2.16.1
--------

AuthBasic now enforces 2FA activation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In previous versions of LemonLDAP::NG, a 2FA protected account didn't need to use their second factor when authenticating to an :doc:`AuthBasic handler <authbasichandler>`.

If you are *absolutely sure* that you want 2FA protected accounts to access AuthBasic handlers, which are password only, you can add the following test in your 2FA activation rules ::

    and not $env->{AuthBasic}


2.0.16
------

Security
~~~~~~~~

Behaviour change in 2FA registration to avoid adding device without testing current authentication level.
(see `issue 2803 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2803>`__)
User must log in by using its higher available 2FA to register a new one.

Change in error messages
~~~~~~~~~~~~~~~~~~~~~~~~

The error messages for the following situations have been changed:

.. csv-table::
   :header: "Situation", "Translation code (lemonldap-ng.ini)", "Translation code (lang.json)", "New error message"
   :delim: ,
   :widths: auto

   An authentication request has been made to an unknown CAS application,error_107,PE107,This application is not known
   An authentication request has been made to an unknown SAML service provider,error_107,PE107,This application is not known
   An authentication request has been made to an unknown OIDC relying party,error_107,PE107,This application is not known
   User was not allowed to access a CAS application,error_84,PE84,You're not authorized to access to this host
   An unauthorized logout URL was specified during logout from a CAS application,error_108,PE108,Unauthorized URL
   An unauthorized Redirect URI was used during an OIDC login,error_108,PE108,Unauthorized URL
   The provided url= parameter does not correspond to a protected URL,error_109,PE109,Not a protected or trusted URL

Users who wish to adjust error messages in these situations should update their translation files


Improve the use of multiple 2FA types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Changes in custom 2F::Register:: modules
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

* Users who use their own ``Lemonldap::NG::Portal::2F::Register::`` modules
  must now inherit from ``Lemonldap::NG::Portal::2F::Register::Base``

* The `canUpdateSfa` function has been moved into the 2FA Engine and should not
  be called by your registration module anymore



For plugin developpers
~~~~~~~~~~~~~~~~~~~~~~

Change in ``passwordAfterChange`` hook behavior
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If you wrote a custom plugin using the ``passwordAfterChange`` hook, return
codes other than ``PE_OK`` will now be displayed by the portal, instead of
being ignored.

Change in ``modifyPassword`` method
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The ``modifyPassword`` method now takes a hash of arguments to specify extra behavior

Before:

.. code:: perl

    # Method definition
    sub modifyPassword {
         my ( $self, $req, $pwd, $useMail ) = @_;
         ...
    }

    # Method call
    $self->p->_passwordDB->modifyPassword($req, $pwd, $useMail);

After:

.. code:: perl

    # Method definition
    sub modifyPassword {
        my ( $self, $req, $pwd, %args ) = @_;
        my $useMail = $args{useMail};
        ...
    }

    # Method call
    $self->p->_passwordDB->modifyPassword($req, $pwd, useMail => $useMail);

2.0.15
------

Translation overrides in lemonldap-ng.ini now take priority over skin
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Previously, the presence of a translation JSON file within a skin prevented
translation messages defined in ``lemonldap-ng.ini`` from being used.

Additionally, it was not possible to translate strings in email templates using
a custom skin file.

These two bugs are now fixed, be sure to check that you do not have duplicate
translations in ``lemonldap-ng.ini`` and in your skin files (``*.json``). If you do,
the translation in ``lemonldap-ng.ini`` will now take priority.

See :ref:`documentation on translating messages <intlmessages>` for
details

Portal templates changes
~~~~~~~~~~~~~~~~~~~~~~~~

If you modified some non-custom HTML templates, :doc:`refer to template upgrade instructions<upgrade_templates>`

2.0.14
------

Security
~~~~~~~~

* **CVE-2021-40874**: RESTServer pwdConfirm always returns true with Combination + Kerberos (see `issue 2612 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2612>`__)


U2F deprecation in Chrome 98
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Chrome 98 `removed U2F support by default <https://developer.chrome.com/blog/deps-rems-95/#deprecate-u2f-api-cryptotoken>`__. You can enable them back temporarily in ``chrome://flags`` by setting *Enable the U2F Security Key API* to *Enabled* and *Enable a permission prompt for the U2F Security Key API* to *Disabled*

LemonLDAP::NG provides a newer alternative: :doc:`webauthn2f`, which is compatible with U2F security keys. Please read :ref:`migrateu2ftowebauthn` for instructions on how to convert U2F secrets to WebAuthn.

After migration, you will need to disable U2F from the configuration and enable WebAuthn instead, in *General Parameters* » *Second Factors* » *WebAuthn*

Weak encryption used for password-protected SAML keys
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Previous versions of LemonLDAP::NG used a weak encryption algorithm to protect
SAML keys when a password was set during certificate generation.

Run the following command to check if this is your case::

    lemonldap-ng-cli get samlServicePrivateKeySig
    lemonldap-ng-cli get samlServicePrivateKeyEnc

If the output of either command starts with ``BEGIN ENCRYPTED PRIVATE KEY``,
then it probably means you generated your keys using the vulnerable manager
code.

In this case, you can convert your existing keys to a stronger encryption using
the following command ::

    # Extract your existing keys. If samlServicePrivateKeyEnc is empty, you can
    # skip it entirely
    lemonldap-ng-cli get samlServicePrivateKeySig | \
        sed 's/samlServicePrivateKeySig = //' > saml-sig.pem
    lemonldap-ng-cli get samlServicePrivateKeyEnc | \
        sed 's/samlServicePrivateKeyEnc = //' > saml-enc.pem

    # Re-encrypt the private key, using the same passphrase
    openssl pkey -in saml-sig.pem -aes256 -out saml-sig-aes.pem
    openssl pkey -in saml-enc.pem -aes256 -out saml-enc-aes.pem

    #Or, if you are using OpenSSL 3+
    openssl pkey -provider legacy -provider default -in saml-sig.pem \
        -aes256 -out saml-sig-aes.pem
    openssl pkey -provider legacy -provider default -in saml-enc.pem \
        -aes256 -out saml-enc-aes.pem

Then, simply reimport your keys ::

    lemonldap-ng-cli set samlServicePrivateKeySig "$(cat saml-sig-aes.pem)"
    lemonldap-ng-cli set samlServicePrivateKeyEnc "$(cat saml-enc-aes.pem)"

If is recommended to keep the same password as before, if not, adjust the
``samlServicePrivateKeySigPwd`` and ``samlServicePrivateKeyEncPwd`` variables as well.

This operation is transparent and does not require any change to your existing
SAML configuration or SAML applications

LemonLDAP::NG version is returned by the CheckState plugin
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you use the `/checkstate` URL to monitor LemonLDAP::NG, you may notice a slight change in the output format:

*2.0.13* ::

    {"result":1}

*2.0.14* ::

    {"result":1,"version":"2.0.14"}

Depending on your load balancer or monitoring configuration, this can cause false negatives.

This plugin is disabled by default, and you may use a shared secret to hide this information to regular users and bots, please check the :doc:`checkstate` documentation for more information.

Empty scopes now rejected in OAuth2.0 grants
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Previously, it was possible to be granted an empty scope, or an automatic
``openid`` scope when doing :ref:`OAuth2.0 Password Grant
<resource-owner-password-grant>` or :ref:`Client Credentials Grant
<client-credentials-grant>`.

Starting with *2.0.14*, empty scopes are no longer allowed (:rfc:`6749#section-3.3`).
You need to either add a `scope` parameter to your request, or define a default
scope in your Relying Party's :ref:`Scope Rules <oidcscoperules>`.

Manager API
~~~~~~~~~~~

The service parameter set in a request to create or update a CAS application must now be an array, and no more a string.

Changes impacting plugin developpers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* If you are using Custom authentication modules, userDB modules or password
  modules, ``$portal->loadedPlugins`` no longer contains a key with the name of
  your module. You should use ``$portal->_authentication``, ``$portal->_userDB``,
  or ``$portal->_passwordDB`` instead to get your module instance.

Portal templates changes
~~~~~~~~~~~~~~~~~~~~~~~~

If you modified some non-custom HTML templates, :doc:`refer to template upgrade instructions<upgrade_templates>`



2.0.13
------

Portal templates changes
~~~~~~~~~~~~~~~~~~~~~~~~

If you modified some non-custom HTML templates, :doc:`refer to template upgrade instructions<upgrade_templates>`

2.0.12
------

Security
~~~~~~~~

* **CVE-2021-35473**: Access token lifetime is not verified with OAuth2 Handler (see `issue 2549 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2549>`__)
* **CVE-2021-35472**: Session cache corruption can lead to authorization bypass or spoofing (see `issue 2539 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2539>`__)
* 2FA bypass with sfOnlyUpgrade and totp2fDisplayExistingSecret (see `issue 2543 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2543>`__)
* Incorrect regexp construction in isTrustedUrl lets attacker steal session on CDA application (see `issue 2535 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2535>`__)
* XSS on register form (see `issue 2495 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2495>`__)
* Wildcard in virtualhost allows being redirected to untrusted domains (see `issue 2477 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2477>`__)

Client Credential sessions missing expiration time
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you started using Client Credential grants in 2.0.11, you may have encountered
`issue 2481 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2481>`__.

Because of this bug, the created sessions may never be purged by the ``purgeCentralCache`` script.

In order to detect these sessions, you can run the following command:

::

   lemonldap-ng-sessions  search --where _session_kind=SSO --select _session_id --select _utime | \
   jq -r  '. | map(select(._utime == null)) | map(._session_id) | join ("\n")'

This will output a list of SSO sessions with no expiration time.

Review them manually using ::

   lemonldap-ng-sessions get <session_id>

You can then remove them with ::

   lemonldap-ng-sessions delete <session_id> <session_id> <etc.>

Brute-force protection plugin may cause duplicate persistent sessions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Because of `bug #2482 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2482>`__ , some users may notice that the persistent session database is filling with duplicate sessions. Some examples include:

* An uppercase version of the regular persistent session (dwho vs DWHO)
* An unqualified version (dwho vs dwho@idp.com)

This bug was fixed in 2.0.12, but administrators are advised to clean up their persistent session database to remove any duplicate persistent sessions remaining after the upgrade.

OpenID Connect check session iframe
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The OIDC check session iframe is not working, it has been removed from OIDC configuration metadata. It should not impact any installation as this feature was already broken.

Simplification of TOTP options
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The following options have been removed from TOTP configuration:

* Display existing secret (``totp2fDisplayExistingSecret``)
* Change existing secret (``totp2fUserCanChangeKey``)

Portal templates changes
~~~~~~~~~~~~~~~~~~~~~~~~

If you modified some non-custom HTML templates, :doc:`refer to template upgrade instructions<upgrade_templates>`


2.0.11
------

Portal templates changes
~~~~~~~~~~~~~~~~~~~~~~~~

If you modified some non-custom HTML templates, :doc:`refer to template upgrade instructions<upgrade_templates>`

2.0.10
------

Security
~~~~~~~~

A vulnerability affecting LemonLDAP::NG installations has been found out when ALL following criteria apply:

* Your handler server uses Nginx
* Your virtual host configuration contains per-URL ``skip`` or ``unprotect`` access rule

In this situation, you have to update your LUA configuration file like ``/etc/nginx/nginx-lua-headers.conf``. See also `issue 2434 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2434>`__.

Other minor security fixes:

* It is now possible to hide sessions identifier in Manager (parameter ``displaySessionId``). See also `issue 2350 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2350>`__.
* Second factor management by end user now requires safer conditions. See also `issue 2332 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2332>`__, `issue 2337 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2337>`__ and `issue 2338 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2338>`__.

Main changes
~~~~~~~~~~~~

- New dependency: IO::Socket::Timeout
- TOTP check tolerates forward AND backward clock drift (totp2fRange)
- Avoid assignment in expressions option is disabled by default
- RHEL/CentOS SELinux users should install the new ``lemonldap-ng-selinux`` package to fix `an issue with the new default cache directory <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2401>`__
- If you use :doc:`applications/mattermost` with OpenID Connect, you need to set the ``id`` claim type to *Integer*
- BruteForceProtection plugin now prevents authentication on backend if an account is locked
- In the Manager API, postLogoutRedirectUri is now `returned and consumed as an array <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2347>`__
- We fixed a bug that caused SAML sessions to be created and never deleted, you should check your session databases for sessions that have ``"_session_kind": "ISAML"`` but no ``_utime``. You can safely delete SAML sessions with no ``_utime`` during the upgrade.

Portal templates changes
~~~~~~~~~~~~~~~~~~~~~~~~

If you modified some non-custom HTML templates, :doc:`refer to template upgrade instructions<upgrade_templates>`

2.0.9
-----

-  Bad default value to display OIDC Consents tab has been fixed.
   The default value is now:  ``$_oidcConsents && $_oidcConsents =~ /\w+/``
-  Some user log messages have been modified, check :doc:`logs documentation <logs>`
   (see also `#2244 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues/2244>`__)
-  SAML SOAP calls are now using ``text/xml`` instead of ``application/xml`` as the MIME Content Type, as required by `the SOAP standard <https://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383526>`__
-  Incremental lock times values can now be set in BruteForceProtection plugin through Manager.
   It MUST be a list of comma separated values. Default values are ``5, 15, 60, 300, 600``
-  This version is not compatible with :doc:`applications/mattermost`

Cookie issues with Chrome
~~~~~~~~~~~~~~~~~~~~~~~~~

This release fixes several issues related to the change in SameSite cookie
policy for Google Chrome users. The new default value of the SameSite
configuration parameter will set SameSite to ``Lax`` unless you are using SAML,
in which case it will be set to ``None``.

This means that from now on, any LemonLDAP::NG installation using SAML must be
served over HTTPS, as SameSite ``None`` value requires the ``Secure`` flag in cookie.

Change in default cache directory
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The default config/session cache directory has been moved from ``/tmp`` to
``/var/cache/lemonldap-ng`` in order to avoid `issues with cache purges
<https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2254>`__  when using
Systemd. This change is only applied to new installations.  If your
installation is experiencing cache purge issues, you need to manually change
your existing ``localSessionStorageOptions/cache_root`` parameter from ``/tmp``
to ``/var/cache/lemonldap-ng``. Be sure to create this directory on your
file system before modifying your configuration.

If you are using SELinux, you also need to run the following commands ::

   semanage fcontext --add -t httpd_cache_t -f a '/var/cache/lemonldap-ng(/.*)?'
   restorecon -R /var/cache/lemonldap-ng/

Required changes in NGINX handler rules (CVE-2020-24660)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

We discovered a vulnerability that affects LemonLDAP::NG installations when ALL of the following criteria apply:

* You are using the :doc:`LemonLDAP::NG Handler<configvhost>` to protect applications
* Your handler server uses Nginx
* Your virtual host configuration contains per-URL access rules based on
  regular expressions in addition to the built-in *default* access rule.

.. note::

   You are safe from this vulnerability if your virtualhost only uses a regexp-based rule to trigger logout

If you are in this situation, you need to modify *all* your handler-protected
virtualhosts by making the following change:

* Replace ``fastcgi_param X_ORIGINAL_URI $request_uri`` by ``fastcgi_param X_ORIGINAL_URI $original_uri`` if you are using FastCGI
* Replace ``uwsgi_param X_ORIGINAL_URI $request_uri`` by ``uwsgi_param X_ORIGINAL_URI $original_uri`` if you are using uWSGI
* Right after ``auth_request /lmauth;``, add the following line ::

   set $original_uri $uri$is_args$args;

You can check the :doc:`configvhost` page for more information

LDAP certificate validation (CVE-2020-16093)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

LDAP server certificates were previously not verified by default when using secure transports (LDAPS or TLS), see `CVE-2020-16093 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2250>`__. Starting from this release, certificate validation is now enabled by default, including on existing installations.

If you have configured your CA certificates incorrectly, LemonLDAP::NG will now start complaining about invalid certificates. You may temporarily disable it again with the following command ::

   /your/path/to/lemonldap-ng-cli set ldapVerify none

If you use LDAP as a configuration storage, and want to temporarily disable certificate validation, you must make the following addition to `/etc/lemonldap-ng/lemonldap-ng.ini` ::

   [configuration]
   ...
   ldapVerify = none

If you use LDAP as a session backend, you are strongly encouraged to also upgrade corresponding ``Apache::Session`` modules (``Apache::Session::LDAP`` or ``Apache::Session::Browseable``). After this upgrade, if you want to temporarily disable certificate validation, you can add the following parameter to the list of Apache::Session module options:

* key: ``ldapVerify``
* value: ``none``

Please note that it is HIGHLY recommended to set certificate validation to `require` when contacting LDAP servers over a secure transport to avoid man-in-the-middle attacks.

2.0.8
-----

-  New dependency: Perl module Time::Fake is now required to run unit
   test and build packages, but should not be mandatory to run the
   software.
-  Nginx configuration: some changes are required to allow IPv6, see
   `#2152 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues/2152>`__
-  Option ``singleSessionUserByIP`` was removed, see
   `#2159 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues/2159>`__
-  A memory leak was found in perl-fcgi with Perl < 5.18, a workaround
   is possible with Apache and llng-fastcgi-server, see
   `#1314 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues/1314>`__

   -  With Apache: set ``FcgidMaxRequestsPerProcess 500`` in portal
      virtual host
   -  With llng-fastcgi-server: set ``PM_MAX_REQUESTS=500`` in
      llng-fastcgi-server service configuration

-  Cookie ``SameSite`` value: to avoid problems with recent browsers,
   SAML POST binding, LLNG cookies are now tagged as
   "**SameSite=None**". You can change this value using manager,
   "**SameSite=Lax**" is best for installations without federations.
   **Important note**: if you're using an unsecured connection *(http://
   instead of https://)*, "SameSite=None" will be ignored by browsers
   and users that already have a valid session might be prompted to
   login again.
-  OAuth2.0 Handler: a VHost protected by the OAuth2.0 handler will now
   return a 401 when called without an Access Token, instead of
   redirecting to the portal, as specified by
   :rfc:`6750#section-3`.

-  If you encounter the following issue:

::

   AH01630: client denied by server configuration: /usr/share/lemonldap-ng/manager/api/api.fcgi

when trying to access the portal. It probably comes from incorrect
Apache configuration. Remove the (optional and disabled by default)
manager API config:

::

   rm /etc/httpd/conf.d/z-lemonldap-ng-api.conf && systemctl reload httpd

2.0.7
-----

-  Security:

   -  `#2040 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues/2040>`__:
      Configuration of a redirection URI for an OpenID Connect Relying
      Party is now mandatory, as defined in the specifications. If you
      save your configuration, you will have an error if some of your RP
      don't have a redirect URI configured.
   -  `#1943 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues/1943>`__
      /
      `CVE-2019-19791 <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-19791>`__:
      along with the patch provided in 2.0.7 in
      ``Lemonldap/NG/Common/PSGI/Request.pm``, Apache rewrite rule must
      be updated to avoid an unprotected access to REST services:

::

   portal-apache2.conf

.. code-block:: apache

       RewriteCond "%{REQUEST_URI}" "!^/(?:(?:static|javascript|favicon).*|.*\.fcgi(?:/.*)?)$"
       RewriteRule "^/(.+)$" "/index.fcgi/$1" [PT]

::

   manager-apache2.conf

.. code-block:: apache

       RewriteCond "%{REQUEST_URI}" "!^/(?:static|doc|lib|javascript|favicon).*"
       RewriteRule "^/(.+)$" "/manager.fcgi/$1" [PT]

-  Other:

   -  Option ``checkTime`` was enabled by default in
      ``lemonldap-ng.ini``, this let the portal check the configuration
      immediately instead of waiting for configuration cache expiration.
      You can keep this option enabled unless you need strong
      :doc:`performances<performances>`.

-  Removed parameters:

   -  ``samlIdPResolveCookie``

2.0.6
-----

-  Option was added to display generate password box in
   :doc:`password reset by mail plugin<resetpassword>`. If you use this
   feature, you must enable this option, which is disabled by default.
-  If you use the default \_whatToTrace macro and a case insensitive
   authentication backend, then a user can generate several persistent
   sessions for the same login (see `issue
   1869 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues/1869>`__).
   This can lead to a security bug if you enabled 2FA, which rely on
   data stored in the persistent session. To fix this, either choose a
   unique attribute for \_whatToTrace, either force lower case in your
   macro:

.. code-block:: perl

   $_auth eq 'SAML' ? lc($_user.'@'.$_idpConfKey) : $_auth eq 'OpenIDConnect' ? lc($_user.'@'.$_oidc_OP) : lc($_user)

-  On CentOS 7 / RHEL 7, a system upgrade breaks ImageMagick, which is
   used to display captchas (see
   `#1951 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues/1951>`__).
   To fix this, you can run the following commands:

::

   yum install -y urw-base35-fonts-legacy
   sed 's,/usr/share/fonts/default/Type1/,/usr/share/X11/fonts/urw-fonts/,g' -i /etc/ImageMagick/type-ghostscript.xml

2.0.5
-----

-  The Text::Unidecode perl module becomes a requirement *(it will be
   automatically installed if you upgrade from from the deb or RPM
   repositories)*
-  CAS logout starts validating the service= parameter, but only if you
   use the CAS Access control policy. The URL sent in the service=
   parameter will be checked against
   :ref:`known CAS applications<idpcas-configuring-cas-applications>`,
   Virtual Hosts, and
   :ref:`trusted domains<security-configure-security-settings>`. Add
   your target domain to trusted domains if you suddenly start having
   "Invalid URL" messages on logout
-  Improvements in cryptographic functions: to take advantage of them,
   **you must change the encryption key** of LemonLDAP::NG (see
   :ref:`CLI example<cli-examples-encryption-key>`).
-  Debian packaging: FastCGI / uWsgi servers require llng-lmlog.conf and
   llng-lua-headers.conf. Those configuration files are now provided by
   lemonldap-ng-handler package and installed in /etc/nginx/snippets
   directory.

Upgrading from 2.0.0 or 2.0.1 to later versions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you have :doc:`installed LemonLDAP::NG from official RPMs<installrpm>`, you
may run into bug `#1757
<https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues/1757>`__ and lose your
Apache configuration files while updating from LemonLDAP::NG 2.0.0 or 2.0.1 to
later versions. Please backup your ``/etc/httpd/conf.d/z-lemonldap-ng-*.conf``
files before the update.
