From d591cfb204c36bf92ddb952e667e491b72670c42 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: May 06 2019 16:04:58 +0000
Subject: Initial design page for prompting configuration


---

diff --git a/design_pages/index.rst b/design_pages/index.rst
index 9b74c75..e08be8a 100644
--- a/design_pages/index.rst
+++ b/design_pages/index.rst
@@ -23,6 +23,7 @@ Implemented in 2.0.x
 
    certmaps_for_LDAP_AD_file
    smartcard_authentication_require
+   prompting_configuration
 
 Implemented in 1.16.x
 ---------------------
diff --git a/design_pages/prompting_configuration.rst b/design_pages/prompting_configuration.rst
new file mode 100644
index 0000000..4a48b92
--- /dev/null
+++ b/design_pages/prompting_configuration.rst
@@ -0,0 +1,302 @@
+Make authentication prompting configurable
+==========================================
+
+Related ticket(s):
+------------------
+    https://pagure.io/SSSD/sssd/issue/3264
+    https://pagure.io/SSSD/sssd/issue/3856
+    https://bugzilla.redhat.com/show_bug.cgi?id=1623624
+
+Problem statement
+-----------------
+Although SSSD tries to use the most suitable prompting depending on which
+authentication options (password, two-factor authentication, smartcard
+authentication) are available for the user it does not fit in all cases.  It
+should be possible with the help of configuration options to tune the prompting
+during authentication.
+
+Use cases
+---------
+General prompting
+^^^^^^^^^^^^^^^^^
+Sometimes just asking ``Password:`` is not sufficient because different
+authentication domains are used and something like ``Enter your AD Password:``
+is more suitable.
+
+Another example is SSSD's default prompting for two-factor authentication if
+both plain password and two-factor authentication is available for the user. In
+this case an ``(optional)`` is shown with the prompt for the second factor.
+This might be irritating on systems where two-factor authentication is
+required.
+
+Two-Factor Authentication Prompting
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+There are two ways how the two factors can be entered. Either each factor in a
+separate prompt and both chained together in a single prompt.
+
+The `PAM Conversation of OTP`_ design page explains some details why using two
+separate prompts is useful from the SSSD point of view. However there are
+services which cannot handle PAM conversations and ask the user directly to
+enter the needed credentials. On the PAM level those application can put the
+user input in both prompts or only in the first one. Instead of adding
+heuristics to SSSD to figure out what is meant be which application it would be
+easier and more reliable to be able to configure the expected behavior for each
+service individually if needed.
+
+.. _PAM Conversation of OTP: https://docs.pagure.org/SSSD.sssd/design_pages/pam_conversation_for_otp.html
+
+What has to be noted here is that SSSD must know somehow if the user entered a
+single password or or two-factor credentials in a single string. The reason is
+that both types of authentication might be treated differently on the server
+side. This can e.g. be seen with Kerberos where a special pre-authentication
+scheme described in `RFC6560`_ is used. If here the plain password is used
+authentication will fail and if the two-factor string is used with plain
+Kerberos authentication not using the OTP pre-auth method authentication will
+fail as well. Since a failed authentication might increment a bad-password
+count and cause a user lock, try-and-error is not an option here.
+
+.. _RFC6560: https://tools.ietf.org/html/rfc6560.html
+
+Alternative authentication principal
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Typically during authentication the user name of the POSIX user trying to
+authenticate is entered and SSSD tries to figure out to which account in the
+authentication domain the POSIX user relates. If the account cannot be found,
+e.g. because the backend simply does not support such lookup, and there is a
+strict 1:1 mapping the `krb5_map_user` option might be used. But this might
+become cumbersome if many users have to be managed or if multiple users from an
+authentication domain should be allowed to authenticate as a single POSIX user.
+
+To cover those cases and additional prompt for a user name which should be used
+for authentication would be helpful. Of course it has to be noted that a
+suitable access control scheme has to be used to make sure that only expected
+accounts from the authentication domain can login in as a given POSIX user.
+
+Additionally this can only work properly with services which offer full PAM
+conversation functionality so that the prompt for the alternative name is shown
+to the user.
+
+Asking for missing user name
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+There is also the case of `gdm-smartcard` where typically no user name is
+prompted at all because it is expected that the user name can be derived from
+the certificate found on the Smartcard. But there are cases where this is not
+possible as described in `Smartcards and Multiple Identities`_. Here is would
+be useful to have a configurable extra prompt for a user name hint.
+
+.. _Smartcards and Multiple Identities: https://docs.pagure.org/SSSD.sssd/design_pages/smartcards_and_multiple_identities.html
+
+Using specific authentication methods
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Currently SSSD tries to determine on its own what would be the most suitable
+prompting if multiple authentication methods are available. E.g. if a Smartcard
+with a certificate suitable to authenticate the current user is available SSSD
+will prompt for a Smartcard PIN even if password authentication would be
+available for the user as well. To see a password prompt the Smartcard has to
+be remove first. But there might be cases where password or two-factor
+authentication should be preferred and having to remove the Smartcard might be
+irritating.
+
+Another use case would be to only ask for two-factor authentication even if
+password authentication would be available for the user as well.
+
+An option where the prompting types can be ordered by preference would be
+useful here.
+
+Overview of the solution
+------------------------
+On one hand it can be seen from the use cases above that it should be possible
+to set the options for each PAM service individually. On the other hand it
+should be easy to set e.g. a global welcome/warning message for all services.
+For this a hierarchical configuration scheme, which SSSD already uses e.g. to
+configure sub-domains, would be suitable.
+
+The hierarchy would start with a `[prompting]` section valid for all
+authentication types and services. The next level would be
+`[prompting/password]`, `[prompting/2fa]` and `[prompting/cert_auth]` for
+password, two-factor and Smartcard authentication respectively. Finally there
+will be a level for the PAM service specific options like e.g.
+`[prompting/2fa/sshd]`. Lower level, i.e. more specific, options will of course
+overwrite higher level, i.e. more general, options.
+
+All those options will be evaluated by SSSD's PAM responder. It would be
+possible to have all those options in `[pam/prompting/....]` sections. But
+always having the `pam/` prefix looks redundant and the section names are
+already long enough.
+
+Currently the prompting for the different authentication schemes and the
+selection is basically hardcoded in the `pam_sss.so` PAM module. Since the PAM
+responder will control the prompting if any option is set below `[prompting]`
+the PAM responder must set `/var/lib/sss/pubconf/pam_preauth_available` in this
+case to make sure `pam_sss.so` tries to call the PAM responder before prompting
+the user.
+
+One or more new PAM `response_type` should be added to send the needed data for
+prompting to `pam_sss.so`.
+
+To handle the alternative authentication principal `enum sss_authtok_type` and
+the related methods for `struct sss_auth_token` should be extended.
+
+Implementation details
+----------------------
+
+_`sssd.conf` man page section
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The details of the expected behavior of the new configuration option are best
+documented in a man page. For a start it might look like::
+
+    PROMPTING CONFIGURATION SECTION
+       If a special file (/var/lib/sss/pubconf/pam_preauth_available) exists
+       SSSD's PAM module pam_sss will ask SSSD to figure out which authentication
+       methods are available for the user trying to log in. Based on the results
+       pam_sss will prompt the user for appropriate credentials.
+
+       With the growing number of authentication methods and the possibility
+       that there are multiple ones for a single user the heuristic used by pam_sss to
+       select the prompting might not be suitable for all use cases. To following
+       options should provide a better flexibility here.
+
+       Each supported authentication method has it's own configuration
+       sub-section under “[prompting/...]”. Currently there are:
+
+       [prompting/password]
+           to configure password prompting, allowed options are:
+
+           password_prompt
+               to change the string of the password prompt
+
+       [prompting/2fa]
+           to configure two-factor authentication prompting, allowed options are:
+
+           first_prompt
+               to change the string of the prompt for the first factor
+
+           second_prompt
+               to change the string of the prompt for the second factor
+
+           single_prompt
+               boolean value, if True there will be only a single prompt using
+               the value of first_prompt where it is expected that both factor are entered as
+               a single string
+
+       It is possible to add a sub-section for specific PAM services like e.g.
+       “[prompting/password/sshd]” to individual change the prompting for this
+       service.
+
+Changes to `pam_sss.so`
+^^^^^^^^^^^^^^^^^^^^^^^
+If there is a `SSS_PAM_PROMPT_CONFIG` item during the pre-auth step in the
+response from the PAM responder SSSD's PAM module `pam_sss.so` should act
+according to the received configuration. If there is no such item `pam_sss.so`
+should just show the current behavior.
+
+The response currently has the following structure:
+
++-----------------------------------------------+---------------------------+--------------------+-----------------------------------+
+| number of prompting configurations (uint32_t) | prompting type (uint32_t) | type specific data | ... additional type-data pairs ...|
++-----------------------------------------------+---------------------------+--------------------+-----------------------------------+
+
+where the type is defined by::
+
+    enum prompt_config_type {
+        PC_TYPE_INVALID = 0,
+        PC_TYPE_PASSWORD,
+        PC_TYPE_2FA,
+        PC_TYPE_2FA_SINGLE,
+        PC_TYPE_SC_PIN,
+        PC_TYPE_LAST
+    };
+
+Where the data for `PC_TYPE_PASSWORD` is:
+
++--------------------------+------------------------+
+| string length (uint32_t) | string of given length |
++--------------------------+------------------------+
+
+`PC_TYPE_2FA` obviously has 2 strings:
+
++---------------------------------------+--------------+------------------------------------+---------------+
+| length of the first string (uint32_t) | first string | length of second string (uint32_t) | second string |
++---------------------------------------+--------------+------------------------------------+---------------+
+
+`PC_TYPE_2FA_SINGLE` uses a single prompt hence also only a single string
+
++--------------------------+------------------------+
+| string length (uint32_t) | string of given length |
++--------------------------+------------------------+
+
+Finally `PC_TYPE_SC_PIN` currently has no specific data.
+
+Changes to the PAM responder
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+First the PAM responder has to read the new configuration option from
+`sssd.conf` and if there are any it should create the pre-auth indicator file
+so that the PAM module `pam_sss.so` will run the pre-auth step.  During the
+pre-auth step the PAM responder has to check if configured options apply to the
+given request and create an appropriate `SSS_PAM_PROMPT_CONFIG` responses if
+needed.
+
+Configuration changes
+---------------------
+See sssd.conf_
+
+How To Test
+-----------
+Please see sssd.conf_ what options are currently available.
+
+In general testing can start with changing the password prompt for all services by adding::
+
+    [prompting/password]
+    password_prompt = My Password Prompt
+
+If now `su` is called as non-root user for an SSSD user::
+
+    $ su sssd_user
+    My Password Prompt
+
+    $ su - sssd_user
+    My Password Prompt
+
+Next step can be to add a specific prompt for `su-l`::
+
+    [prompting/password/su-l]
+    password_prompt = My su-l Prompt
+
+and now calling `su` should show::
+
+    $ su sssd_user
+    My Password Prompt
+
+    $ su - sssd_user
+    My su-l Prompt
+
+If a FreeIPA setup with users configured for 2-Factor Authentication you can
+use `first_prompt` and `second_prompt` in the `[prompting/2fa]` section to
+change the 2FA prompting strings for all services. With::
+
+    [prompting/2fa/my_service]
+    single_prompt = True
+    first_prompt = Please enter password + OTP token value
+
+you can enable single 2FA prompting for the PAM service `my_service` where only
+one prompt will be show where the long term password and the one-time password
+have to be entered in a single string.
+
+How To Debug
+------------
+Setting `debug_level` in the `[pam]` section of `sssd.conf` to a sufficiently
+high value will show error and debugging information for the processing of the
+prompting option.
+
+If you compile `pam_sss.so` with `-DPAM_DEBUG` in the C-compiler flags the PAM
+module will write some debug information to `/var/run/pam-debug.log` (or a
+similar file depending on the platform). Since this is typically not the case
+using `gdb` might help to identify issues in processing the prompting
+configuration. Suitable break points are `pc_list_from_response()` where the
+response form the PAM responder is translated and `prompt_by_config()` where
+the right prompting based on the received configuration is selected.
+
+Authors
+-------
+Sumit Bose <sbose@redhat.com>

