Hi,
please find the SSSD design page for the Authentication Indicator
(
http://www.freeipa.org/page/V4/Authentication_Indicators) related changes on
the SSSD side tracked by
https://fedorahosted.org/sssd/ticket/2988 at
https://fedorahosted.org/sssd/wiki/DesignDocs/PromptingForMultipleAuthent....
For your convenience it can be found below as well.
Comments and suggestions are welcome.
bye,
Sumit
= Prompting For Multiple Authentication Types =
Related ticket(s):
*
https://fedorahosted.org/sssd/ticket/2988
=== Problem statement ===
Currently FreeIPA only allows one authentication type at a given time for a user. Even if
both authentication types 'password' and 'otp' were configured for the
user only 'otp' was allowed in that case. Because of this SSSD only had to prompt
for either 'Password' or 'First factor' and 'Second factor'.
New version of FreeIPA will allow that the sue can authentication with different
authentication types at the same time (
https://fedorahosted.org/freeipa/ticket/433). SSSD
now must prompt the user differently to make clear which authentication types are
available for the user ideally without making the login process more complicated.
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 ===
(taken from
http://www.freeipa.org/page/V4/Authentication_Indicators)
==== Strong Authentication on Selected System ====
===== User story =====
As an Administrator, I want to setup authentication to a critical system in my
infrastructure (gateway VPN, accounting system) to only allow IdM users authenticated via
strong authentication methods (2FA). I do not want to require strong authentication on
other systems.
===== Description =====
A realm has two servers configured for ssh which use the following principals configured
with authentication indicators:
host/lowsecurity.example.com []
host/highesecurity.example.com [otp radius]
When the administrator logs in using both his password and an OTP token, he can access
both systems via ssh. However, when the administrator logs in using just a password, he
can only access
lowsecurity.example.com.
=== Overview of the solution ===
Depending on the available authentication types SSSD will show different login prompts:
||= Authentication types =||= Login Prompt =||
|| password || Password: ||
|| otp || First factor: \\ Second factor: ||
|| password + otp || First factor or password: \\ Second factor, press return for Password
authentication: ||
If Smartcard authentication is enabled (''pam_cert_auth = True'') and a
Smartcard is inserted in a reader with a certificate matching the user who wants to login
the login prompt will ask for the Smartcard PIN for local authentication
(wiki:SmartcardAuthenticationStep1). Upcoming support for pkinit might lead to another
extension of the prompting scheme.
=== Implementation details ===
First it has to be noted that this feature is related to Kerberos authentication because
here the available authentication types are indicated by the server during the
authentication request. Other authentication schemes like e.g. LDAP bind based
authentication do support multiple different methods as well, e.g. you can bind to the
FreeIPA LDAP server with password and 2FA authentication if the user is configured
accordingly. But here the client either has to try which authentication might work or
figure out possible authentication methods by other means which might be unreliable.
Kerberos indicates the available authentication methods via the available
pre-authentication methods listed in the 'Additional pre-authentication required'
response. The different pre-authentication methods are implemented as plugins and there
are two ways for the plugins to interact with a user. The first one is a prompter callback
which can be given as argument to e.g. krb5_get_init_creds_password(). The second, newer
and more advanced method, are responders which can be set with
krb5_get_init_creds_opt_set_responder() which is available since version 1.11 of MIT
Kerberos.
For older versions of Kerberos where krb5_get_init_creds_opt_set_responder() is not
available nothing changes because those versions do not support OTP either, so only
password authentication will be available here.
For builds with a newer version of MIT Kerberos all authentication decision will be moved
to the responder. This means that calls like krb5_get_init_creds_password() will not get
the password as an argument anymore but the password is set inside of the responder if
password based authentication is chosen.
The responder will chech which authentication types are available by calling
krb5_responder_list_questions(). If password authentication is available, indicated by the
value of KRB5_RESPONDER_QUESTION_PASSWORD and the provided authentication token is of type
password as well the password is set as answer to the password authentication and no
further methods are considered.
If password authentication is not avail or the provided authentication token is of type
SSS_AUTHTOK_TYPE_2FA the existing OTP responder component is called.
During the SSSD pre-authentication request a new pam response is added which indicate that
password authentication is available. Based on this and the OTP related response the
pam_sss PAM modules can choose the right set of prompts.
=== Configuration changes ===
No configuration changes are needed on the client the available authentication types are
determined based the the responses of the server.
=== How To Test ===
First create an IPA user and assign an OTP token to the user, see
http://www.freeipa.org/page/V4/OTP#How_to_Test for details. Additionally two services with
different authentication indicator requirements are useful to test the returned
credentials but are not necessary to test the prompting.
{{{
$ ipa service-add ANY/ipa-client.example.dom
$ ipa-getkeytab -p
ANY/ipa-client.example.com -k /tmp/any.keytab
$ ipa service-add
OTP/ipa-client.example.com --auth-ind=otp
$ ipa-getkeytab -p
OTP/ipa-client.example.com -k /tmp/otp.keytab
}}}
(the keytab files are not needed for further testing).
===== Password only =====
To test plain password authentication call
{{{
$ ipa user-mod test_user --user-auth-type=password
}}}
and then as an un-privileged user
{{{
$ su - test_user
Password:
}}}
after login you can test by calling
{{{
$ kvno ANY/ipa-client.example.dom(a)EXAMLE.COM
ANY/ipa-client.example.com(a)EXAMPLE.COM: kvno = 1
$ kvno OTP/ipa-client.example.dom(a)EXAMLE.COM
kvno: KDC policy rejects request while getting credentials for
OTP/ipa-client.example.dom(a)EXAMLE.COM
}}}
that only a ticket for the ANY service can be requested but not for the OTP service
because only the password was used for authentication.
Entering Password+TokenValue in a single string at the ''Password:''
prompt will cause an authentication failure.
===== OTP only =====
The second test is for OTP only authentication
{{{
$ ipa user-mod test_user --user-auth-type=otp
}}}
and then as an un-privileged user call
{{{
$ su - test_user
First Factor:
Second Factor:
}}}
after login you can test by calling
{{{
$ kvno ANY/ipa-client.example.dom(a)EXAMLE.COM
ANY/ipa-client.example.com(a)EXAMPLE.COM: kvno = 1
$ kvno OTP/ipa-client.example.dom(a)EXAMLE.COM
OTP/ipa-client.example.com(a)EXAMPLE.COM: kvno = 1
}}}
that tickets for both services can be request successfully because now 2-Factor
authentication was used to log in.
Entering Password+TokenValue in a single string at the ''First Factor:''
prompt will authenticate the user successfully as well but features like off-line
authentication or unlocking of the user's keyring might not be availble.
===== Password and OTP =====
Finally both authentication methods are enabled on the server:
{{{
$ ipa user-mod test_user --user-auth-type=otp --user-auth-type=password
}}}
If now call ''su'' as an un-privileged user
{{{
$ su - test_user
First Factor or Password:
Second Factor, press return for Password authentication:
}}}
you can either just enter the password and press enter at the second prompt or enter the
password and the OTP token value at the respective prompt. In the first case only a ticket
for the ANY service can be requested:
{{{
$ kvno ANY/ipa-client.example.dom(a)EXAMLE.COM
ANY/ipa-client.example.com(a)EXAMPLE.COML: kvno = 1
$ kvno OTP/ipa-client.example.dom(a)EXAMLE.COM
kvno: KDC policy rejects request while getting credentials for
OTP/ipa-client.example.dom(a)EXAMLE.COM
}}}
If both factor are given tickets for both services can be requested successfully:
{{{
$ kvno ANY/ipa-client.example.dom(a)EXAMLE.COM
ANY/ipa-client.example.com(a)EXAMPLE.COM: kvno = 1
$ kvno OTP/ipa-client.example.dom(a)EXAMLE.COM
OTP/ipa-client.example.com(a)EXAMPLE.COM: kvno = 1
}}}
Entering Password+TokenValue in a single string at the ''First Factor or
Password:'' prompt will cause an authentication failure.
=== How To Debug ===
If password authentication is not working when both password and OTP authentication are
enabled you might hit
https://bugzilla.redhat.com//show_bug.cgi?id=1340304 and should
update the Kerbeors packages.
==== Inspecting log files ====
Setting ''debug_level = 9'' in the ''[domain/...]''
section of ''sssd.conf'' will add libkrb5 trace messages to the
krb5_child.log file which e.g. will show the pre-authentication methods offered by the
KDC. Based on this SSSD will determine which authentication methods are available. In the
''Processing preauth types:'' line of the trace output
''141'' represents the OTP authentication while ''2''
(without FAST) or ''138'' (with FAST) stand for password authentication.
==== Manual testing with kinit ====
If only password authentication or password and OTP authentication are configured for a
user kinit should ask for the password:
{{{
$ kinit test_user
Password for test_user(a)EXAMPLE.COM
}}}
OTP authentication is only available if FAST is enabled. The needed armor credential cache
must be requested with kinit as well:
{{{
$ kinit -c ./armor.ccache -k
}}}
which will use the default keytab (/etc/krb5.keytab) which is accessible only by root to
get a TGT. For easier testing you can create a special service and give suitable
permissions to the service keytab. To use it with kinit use the -t option
{{{
$ kinit -c ./armor.ccache -k -t ./service.keytab
}}}
Now you can call
{{{
$ kinit -T ./armor.ccache test_user
Enter OTP Token Value:
}}}
If OTP is not enable for the user you should see the password prompt.
As usual, setting ''KRB5_TRACE=/dev/stdout'' before calling
''kinit'' or ''kvno'' will produce some extra output which
might be useful.
=== Authors ===
* Sumit Bose <sbose(a)redhat.com>