On 02/23/2015 03:56 AM, Sumit Bose wrote:
On Fri, Feb 20, 2015 at 07:28:13PM -0500, Dmitri Pal wrote:
> On 02/20/2015 05:16 AM, Sumit Bose wrote:
>> On Thu, Feb 19, 2015 at 05:52:55PM -0500, Dmitri Pal wrote:
>>> On 02/18/2015 06:55 AM, Sumit Bose wrote:
>>>> Hi,
>>>>
>>>> I have created a design page for the special prompting for long-term
>>>> password and one-time password at
>>>>
https://fedorahosted.org/sssd/wiki/DesignDocs/PAMConversationForOTP
>>> Nice write-up.
>>> There are some typos but this is OK.
>>> Questions are inline.
>> Thank you for the review.
>>
>>>> Comments and suggestions are welcome. Please note, there are two open
>>>> questions related to configuration.
>>>>
>>>> For your convenience I added the text below as well.
>>>>
>>>> bye,
>>>> Sumit
>>>>
>>>> = PAM Conversation for OTP/Two-Factor-Authentication =
>>>>
>>>> Related ticket(s):
>>>> *
https://fedorahosted.org/sssd/ticket/2335
>>>>
>>>> === Problem statement ===
>>>> Two-Factor-Authentication (2FA) typically uses a long term password or
>>>> PIN and an One-Time-Password (OTP) which in general is generated by a
>>>> small device. To be backward compatible and to allow 2FA in existing
>>>> application both factors can be entered one after the other in a single
>>>> password prompt. This single string is then evaluated by the
>>>> authentication backend.
>>>>
>>>> On desktop systems where a single password (One-Factor-Authentication -
>>>> 1FA) is used this password is often used for other purposes to improve
>>>> the user experience. For example to
>>>> - unlock a keyring
>>>> - un-encrypt files or the complete home-directory
>>>> - allow authentication even if the authentication backend is not
>>>> reachable (offline authentication).
>>>> These convenience features are not available if 2FA is used with both
>>>> factors combined in a single string because there is no general rule
>>>> which would allow to split the long-term and the one-time part. Only the
>>>> authentication backend knows how to handle it. To make these features
>>>> possible again with 2FA the user must enter the two factor individually
>>>> into two separate prompts. This design page will show how this can be
>>>> achieved with the help of PAM and SSSD.
>>>> Short overview (up to a couple of sentences) of the change being
>>>> designed. Might include pointers to reference materials (such as MSDN
>>>> articles when designing an AD integration feature) or other information
>>>> required to understand what the change is about.
>>>>
>>>> === Use cases ===
>>>> ==== Unlock user's keyring ====
>>>> Assuming a user with 2FA enabled which log into a desktop session. If
>>>> the two factors are entered into a single prompt the resulting string
>>>> cannot be used as a password for the desktop keyring application because
>>>> it will change at every login. To not create issues SSSD will
>>>> automatically remove the password item from the PAM environment in this
>>>> case (see #2287 for details).
>>>>
>>>> If the two factors are entered separately the first factor, the
>>>> long-term password, can but used as a password for the keyring
>>>> application because changes will be rare. In this case SSS can put the
>>>> long term password into the PAM environment so that the PAM modules of
>>>> the keyring application can pick it up at login time so that there is no
>>>> need to unlock the keyring in a separate step.
>>>>
>>>> ==== Offline-authentication ====
>>>> Assuming a user with 2FA enabled which log into a desktop session which
>>>> currently does not have a connection to the central authentication
>>>> server. If the two factors are entered into a single prompt the
>>>> resulting string can only be processed by the central authentication
>>>> server and a loss of connection will make authentication and login
>>>> impossible. Even the SSSD offline-authentication feature won't help
>>>> because SSSD will only store a hash of the password used for the last
>>>> successful authentication and compare it with the hash of the current
>>>> password. Since the combined password will change at every login the
>>>> current combined password cannot be validated against any previously
>>>> used password.
>>>>
>>>> If the two factors are entered separately SSSD can save a hash of the
>>>> first factor can can compare the hashes for the first factor when
>>>> offline to allow at least access to the local machine. It has to be
>>>> noted that the even if krb5_store_password_if_offline is set to true
>>>> SSSD will not try to get a TGT when going online again because in the
>>>> general case the second factor (OTP) might be already invalid.
>>>>
>>>> Both use-cases mentioned above might only be working if the first factor
>>>> (long-term password) is sufficiently long. A 4-digit PIN used by some
>>>> OTP systems is not secure enough to be uses as a password for a keyring
>>>> or to allow local access.
>>>>
>>>> === Overview of the solution ===
>>>> On of the design principals of SSSD's PAM module pam_sss was that it
>>>> should do any decisions on its own but let SSSD do this. As a
>>>> consequence pam_sss cannot decide which type of password prompt should
>>>> be shown to the user but must ask SSSD first. Currently the first
>>>> communication between pam_sss and SSSD's PAM responder happens after
the
>>>> user entered the password. Hence a new request, a pre-authentication
>>>> request, to the PAM responder must be added before the user is prompted
>>>> for the password. The pam responder can then relay the request to a
>>>> suitable backend where it can be evaluated which type of prompt should
>>>> be shown to the user. The result can be send back to pam_sss in a PAM
>>>> response message which is already use to return other types of messages
>>>> to pam_sss. This message can be used to send addition hints like e.g.
>>>> type or vendor of the expected OTP hardware token to the user.
>>>>
>>>> Based on the response pam_sss will ask the user for a single password or
>>>> for the two factors in individual prompts. If only the first factor is
>>>> entered and the second is empty the input will be treated as a single
>>>> password. This might happen is the user accidentally entered both factor
>>>> together or if applications or protocols (ssh, ftp) are configured or
>>>> can handle only a single password prompt.
>>>>
>>>> Keep keep the delays due to the new request to a minimum pam_sss should
>>>> only run it, if the backend really supports it. Additionally is should
>>>> be possilbe to disable the pre-authentication request completely with a
>>>> new option for pam_sss.
>>>>
>>>> In addition to the authentication dialog the password change dialog
>>>> should respect the splitting of the two factors as well.
>>>>
>>>> === Implementation details ===
>>>> ==== Making sure the PAM calls SSSD the ask for credentials for SSSD
>>>> users ====
>>>> PAM allows to configure multiple different authentication methods but
>>>> ideally only ask the user once for a password (or other credentials).
>>>> Typically the first configure authentication method will ask for a
>>>> password and if the user is not know to the authentication method the
>>>> password is passed on to the next authentication method. Obviously this
>>>> only works well with a single type of credentials.
>>>>
>>>> In our case we want to prompt the user differently depending on whether
>>>> 1FA or 2FA is configured for the user. Typically pam_unix is the first
>>>> authentication module to make sure the authentication of local users
>>>> (especially root) is not affected by other modules. But since pam_unix
>>>> does not know anything about SSSD users or 2FA we have to make sure that
>>>> pam_unix will not ask for a password for SSSD users. Instead of putting
>>>> pam_sss in front of pam_unix we would like to use pam_localuser to skip
>>>> pam_unix for non-local users. A PAM auth configuration might look like
>>>> this
>>>>
>>>> {{{
>>>> auth required pam_env.so
>>>> auth [default=1 success=ok] pam_localuser.so
>>>> auth sufficient pam_unix.so nullok try_first_pass
>>>> auth requisite pam_succeed_if.so uid >= 1000
>>>> quiet_success
>>>> auth sufficient pam_sss.so
>>>> auth required pam_deny.so
>>>> }}}
>>>>
>>>> If the user is in /etc/passwd pam_localuser will return success and
>>>> pam_unix will be called. Otherwise the next entry (default=1) will be
>>>> skipped which is pam_unix in this case. The next module for a user which
>>>> does not come from /etc/passwd if pam_succeed_if. I think it is a good
>>>> idea to keep the pam_succeed_if to keep the separation between local
>>>> users (uid < 1000) and remote users (uid >= 1000).
>>>>
>>>> For the time being we keep the PAM password section (for password
>>>> changes) as is because it is already used to handle changing the
>>>> long-term password.
>>>> ==== Handling the two authentication factors ====
>>>> Both the wire protocol between pam_ssd and the pam responder and SSSD
>>>> internally with the sss_auth_token struct handle the credentials as a
>>>> blob with a length and a type. Currently the blob contains either the
>>>> password or is NULL in case of no password (there is a special usage
>>>> where it contains a Kerberos credential cache identification).
>>>>
>>>> Adding the two authentication factor to those structure can be achieve
>>>> without modifying them by using a new type for 2FA and creating a blob
>>>> which starts with two 32bit unsigned integer value containing the size
>>>> of the first and second authentication factor respectively followed by
>>>> the first factor and finally the second factor.
>>>>
>>>> {{{
>>>> uint32_t | uint32_t | uint8_t[6] | uint8_t[5]
>>>> ---------|----------|------------|-----------
>>>> 0x06 | 0x06 | abcdef | 12345\0
>>>> }}}
>>>>
>>>> As shown the first and second factor may or may not include a trailing
>>>> \0 in the blob. But calls which decompose the blob into its component
>>>> must assure that that there is a trailing \0 if strings are expected.
>>>>
>>>> With this scheme only packaging and un-packaging the two factors has to
>>>> be added to existing or new calls but all other internal handling like
>>>> sending the data from the responder to the backends can be left
>>>> unchanged.
>>>>
>>>> Backends which should handle 2FA must be made aware of the new
>>>> authentication token type.
>>>> ==== The pre-authentication request ====
>>>> The pre-authentication request will follow the same path as the
>>>> authentication request with an empty password and with type
>>>> SSS_PAM_PREAUTH instead of SSS_PAM_AUTHENTICATE. It is up to the backend
>>>> if and how this request will be handled. Currently only the IPA auth
>>>> provider will support the pre-auth request in the sense that it can send
>>>> different results base on the expected authentication type (1FA, 2FA)
>>>> back to the client. Since the IPA provider will basically use the
>>>> generic krb5 auth provider the krb5 auth provider will support the
>>>> pre-auth request as well.
>>>>
>>>> The IPA provider will send a back a PAM response of the type
>>>> SSS_PAM_OTP_INFO in case of 2FA with optional token_id, vendor name and
>>>> challenge so that pam_sss can give additional hints to the user and a
>>>> unsigned 32bit integer value indication the type of the optional data.
>>>> This indicator will make it more easy to add more data in future or just
>>>> indicate that the user uses 2FA but the backend is offline.
>>>>
>>>> If 2FA is not enable for the user or errors occur just a PAM_SUCCESS
>>>> will be returned. In this case pam_sss will just ask for a single
>>>> password.
>>>>
>>>> If the backend is offline the PAM responder will tell the client that
>>>> only the first factor is needed for local authentication with the help
>>>> of a special SSS_PAM_OTP_INFO message. To achieve this the type of the
>>>> hashed authentication token in the cache must be saved. Additionally the
>>>> length of the second factor should be saved in the cache to allow
>>>> splitting a combined password which might be entered by the user
>>>> accidentally or via services where special prompting might not be
>>>> available like e.g. ssh. If the second factor varies in size this scheme
>>>> will fail but saving the length of the first factor will make an offline
>>>> attack against the hashed password much easier.
>>>>
>>>>
>>>> Since the pre-auth request is an additional round-trip from pam_sss to
>>>> the KDC and back it might delay the logon process a bit. To avoid this
>>>> in environments where only 1FA is used and option the pam_sss,
>>>> ''disable_preauth'', can disable the pre_auth request
completely.
>>>> Additionally I would suggest a more dynamic solution where is pre-auth
>>>> request is only send if a special file, e.g.
>>>> /var/lib/sssd/pubconf/do_pam_preauth, exits. The IPA provider can create
>>>> this file at startup if 2FA is supported.
>>> Why a file and not an SSSD option? You lost me here.
>> I want to avoid any un-needed communication between the pam_ss client
>> and the responder. An SSSD option would be a backend specific option and
>> pam_sss would have to ask for every auth request the responder first
>> (which might ask the backend) which is imo too much overhead for the
>> general non-2FA case. Checking for the existence of a file looks like
>> the most easy and fastest way to check if the pre-auth request should
>> really be run.
> Why create a new machanizm. Can we use a pam option instead? It is
> definitely available to the PAM stack without any extra fie operations.
This would work and option 'use_2fa' is already mentioned in the design.
Nevertheless this would require special authconfig option to switch
between the the cases. My goal is to make both cases work in the default
configuration and allow SSSD to detect at run-time if double-prompting
is needed or not.
>>> Also is it really a round trip to KDC or it is an LDAP lookup?
>>> Are you planning to determine whether you can prompt by getting the
>>> supported auth mechs for user from KDC?
>> Yes. Although in the IPA case we might already get useful information
> >from LDAP the KDC is the authoritative source. This will get even mor
>> important when we start to support additional methods. Additionally
>> there are some data e.g. the challenge for challenge-response OTP
>> tokens, which is only available form the KDC.
> But some other data is available only from LDAP for example if we use OTP as
> the second factor for AD users.
> IMO this will be a more important use case in a short term. In this case
> SSSD will talk exdom to IPA, figure that OTP is required and prompt for two
> factors. The first factor will go directly to AD while the second will be
> handled by IPA.
This is an upcoming feature and I currently only see the related freeipa
ticket
https://fedorahosted.org/freeipa/ticket/4876 for this. But this
will fit in seamlessly into the described scheme.
>>> I see that it would be a very rare case when different users of the same
>>> system would have different prompts. It is possible but a corner case. In
>>> this case it is fine to have a roundtrip.
>> I'm not so sure, think e.g. of an environment with FreeIPA and trust
>> where IPA users are using 2FA but AD users not.
> Yes and I suspect that in this case if it is a server box they would want
> everyone to have 2FA. Think about bastion host cases. Everyone 2FA and then
> SSO inside.
This is a special use-case where the 'use_2fa' option for pam_sss might
be useful. Nevertheless for the general case we should not assume that
everyone will use 2FA. There are e.g FreeIPA tickets
https://fedorahosted.org/freeipa/ticket/4498 and
https://fedorahosted.org/freeipa/ticket/4875 which ask allow 2FA usages
per service or host. While both of them might also solved by other mean
I think they illustrate that authentication schemes should be handled
dynamic and central management should be possible.
Additionally I would like to mention that if existing environments want
to migrate from 1FA to 2FA this will not happen in a single step but
users will be migrated individually and depending on the size of the
environment this will take week or months where we have to support a
flexible scheme anyways.
Finally I would like to point out that I already wrote all the needed
code for the POC so there would be at least not additional development
effort to implement this.
>> Additionally SSSD supports multiple domains and not all configured
>> domains might support 2FA, think e.g of the plans to support local users
>> with SSSD.
>
> This is IMO orthogonal. My point is that the whole domain is probably either
> 2FA or not.
I don't agree, see comments above. Saying that a whole domain must be
either 2FA or not is imo a quite strong limitation for users and
customers for no good reason. I agree that there are use-case where the
whole domain will only have 2FA but why should we ignore the others?
>>> But for the usual case when the system is either enabled for 2FA or not I
>>> would rather have an override in sssd.conf saying always prompt for two or
>>> for one since I know what environment the system is deployed in.
>>> This way we save a trip and can always prompt the way configuration
>>> prescribes.
>> We cannot save the pre-auth round-trip in the general case 2FA case
>> because we might has a challenge-response OTP token. (This and other
>> authentication schemes won't be supported now but I would like to have a
>> design where it is easy to add support for this later).
> But we can if we know we do not have challenge response tokens.
> IMO it still a good optimization to allow override.
I agree and the 'use_2fa' option can you used for this kind of
optimization but it should not be the default.
OK I agree with the comments above.
As long as the use cases I mentioned are taken into the account I am fine.
bye,
Sumit
>
>>> Am I missing something?
>> I hope I was able to explain the reasoning above.
>>
>>>> ==== Special use of the first factor (long term password) ====
>>>> ===== Cached password hash for offline-authentication =====
>>>> If authentication was successful, the
''cache_credentials'' option is
>>>> set to ''true'' and the first factor has at least
>>>> ''[#minimal_password_length minimal_password_length]''
SSSD will saved a
>>>> hashed version of the first factor to the user's cache entry as it
is
>>>> done for the 1FA password.
>>>>
>>>> ===== PAM =====
>>>> If authentication is successful and the ''forward_pass''
option is given
>>>> for pam_sss the first factor will be saved in the PAM_AUTHTOK item so
>>>> that other modules in the PAM stack can use it. '''QUESTION:
shall
>>>> we(authconfig) add forward_pass by default? Currently is it
not.'''
>>> We should open corresponding tickets for authconfig and make sure they are
>>> addressed in the same time frame.
>> That's my plan, I just wanted to agree on the general design first.
>>
>>> Should we also create tickets for ipa-client and realmd to say "this is
a
>>> client where there will be two prompts" and pass it through?
>> afaik both use authconfig and the authconfig changes will be always
>> applied if --enablesssd is used.
>>
>>>> === Configuration changes ===
>>>> ==== pam_sss ====
>>>> New options:
>>>> - ''disable_preauth'' will unconditionally disable the
>>>> pre-authentication request
>>>> - ''use_2fa'' will always ask for two authentication
factor, might be
>>>> only useful for testing
>>>>
>>>> ==== sssd.conf ====
>>>> New option:
>>>> - [=#minimal_password_length]
''minimal_password_length'' will let the
>>>> pam responder only safe a hash of the password if it has a minimal
>>>> length. Additionally it might indicate to pam_sss to remove passwords
>>> >from the PAM environment which are shorter. '''Question: We
can limit
>>>> this option to the first factor of a 2FA authentication. Although it
>>>> might be useful for 1FA passwords as well it might introduce a
>>>> regression to existing installations.'''
>>> IMO we would have a marker in the user entry whether this user has a single
>>> factor or not based on his first authentication and apply this min length
>>> only to users that cave 2FA enabled.
>>> That would prevent a regression.
>> yes, it is planned to save the auth type. And the more I think about it
>> I think this new option should be only used for the first factor of 2FA.
>>
>> In the long run we might want to introduce something like
>> (cached)-password-policies which will offer a more general handling of
>> the (cached) password and replace all the different options we currently
>> have. I put 'cached' in () because Jakub mentioned that we might meed
>> those policies if we start supporting local users where it will not be
>> the 'cached' but 'the' password.
>>
>> bye,
>> Sumit
>>
>>>> ==== Changing the first factor ====
>>>> It is already possible to change the long-term password (first factor),
>>>> the current scheme will not be changed here.
>>>>
>>>> === How To Test ===
>>>> ==== Prerequisites ====
>>>> Create an user with 2FA/OTP authentication as e.g. described in
>>>>
http://www.freeipa.org/page/V4/OTP#Configuration
>>>>
>>>> ==== Login prompt ====
>>>> If 2FA is enabled for a user there should be two separate prompts for
>>>> the two authentication factors for services which can support special
>>>> prompting. This includes e.g. gdm and su. ssh can only support this if
>>>> ''ChallengeResponseAuthentication'' is enabled on the
server side.
>>>> Nevertheless even if ''ChallengeResponseAuthentication''
is not enabled
>>>> ssh should allow login if both factors are given at the password prompt
>>>> in a single string.
>>>>
>>>> For users without 2FA the single password prompt should be seen.
>>>> {{{
>>>> # su - otpuser
>>>> First factor:
>>>> Second factor:
>>>> sh$
>>>> }}}
>>>>
>>>> {{{
>>>> # su - user
>>>> Password:
>>>> sh$
>>>> }}}
>>>>
>>>> If both factors are entered at the ''First factor''
prompt and the
>>>> second factor prompt is empty, authentication should be successful but
>>>> it cannot be expected that the user's keyring is unlocked or that
>>>> offline-authentication will be available.
>>>>
>>>> ==== Unlocking user's keyring ====
>>>> If an otpuser logs in with gdm and enters the two authentication factors
>>>> separately in the expected prompts the keyring of the user should be
>>>> unlocked automatically and no additional password prompt should be seen
>>>> after logging in.
>>>>
>>>> ==== Offline authentication ====
>>>> If an otpuser logs in with an application which supports special
>>>> prompting, e.g. gdm or su, and the SSSD configuration option
>>>> ''cache_credentials'' is set to ''True''
SSSD will save a hash of the
>>>> first factor in the cache to allow offline authentication. If later on
>>>> the system goes offline authentication should still be possible with the
>>>> first authentication factor. Only a prompt for the first factor should
>>>> be shown by application which supports special prompting.
>>>>
>>>> === Authors ===
>>>> Sumit Bose <sbose(a)redhat.com>
>>>> _______________________________________________
>>>> sssd-devel mailing list
>>>> sssd-devel(a)lists.fedorahosted.org
>>>>
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel
>>> --
>>> Thank you,
>>> Dmitri Pal
>>>
>>> Sr. Engineering Manager IdM portfolio
>>> Red Hat, Inc.
>>>
>>> _______________________________________________
>>> sssd-devel mailing list
>>> sssd-devel(a)lists.fedorahosted.org
>>>
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel
>> _______________________________________________
>> sssd-devel mailing list
>> sssd-devel(a)lists.fedorahosted.org
>>
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel
>
> --
> Thank you,
> Dmitri Pal
>
> Sr. Engineering Manager IdM portfolio
> Red Hat, Inc.
>
> _______________________________________________
> sssd-devel mailing list
> sssd-devel(a)lists.fedorahosted.org
>
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel
_______________________________________________
sssd-devel mailing list
sssd-devel(a)lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel
--
Thank you,
Dmitri Pal
Sr. Engineering Manager IdM portfolio
Red Hat, Inc.