summaryrefslogtreecommitdiffstats
path: root/daemons/ipa-slapi-plugins
diff options
context:
space:
mode:
authorNathaniel McCallum <npmccallum@redhat.com>2016-05-12 15:10:47 -0400
committerMartin Basti <mbasti@redhat.com>2016-05-26 18:47:05 +0200
commit168a6c7d4778a2a3c729e3ac24e4ad9dfacb46c0 (patch)
treef753c7b71b1f721aa138088d87676859a5c97dfa /daemons/ipa-slapi-plugins
parentcd9bc84240c99ed744e5ee44db18d925a5292ffd (diff)
downloadfreeipa-168a6c7d4778a2a3c729e3ac24e4ad9dfacb46c0.tar.gz
freeipa-168a6c7d4778a2a3c729e3ac24e4ad9dfacb46c0.tar.xz
freeipa-168a6c7d4778a2a3c729e3ac24e4ad9dfacb46c0.zip
Ensure that ipa-otpd bind auths validate an OTP
Before this patch, if the user was configured for either OTP or password it was possible to do a 1FA authentication through ipa-otpd. Because this correctly respected the configuration, it is not a security error. However, once we begin to insert authentication indicators into the Kerberos tickets, we cannot allow 1FA authentications through this code path. Otherwise the ticket would contain a 2FA indicator when only 1FA was actually performed. To solve this problem, we have ipa-otpd send a critical control during the bind operation which informs the LDAP server that it *MUST* validate an OTP token for authentication to be successful. Next, we implement support for this control in the ipa-pwd-extop plugin. The end result is that the bind operation will always fail if the control is present and no OTP is validated. https://fedorahosted.org/freeipa/ticket/433 Reviewed-By: Sumit Bose <sbose@redhat.com>
Diffstat (limited to 'daemons/ipa-slapi-plugins')
-rw-r--r--daemons/ipa-slapi-plugins/ipa-pwd-extop/otpctrl.h3
-rw-r--r--daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c13
2 files changed, 11 insertions, 5 deletions
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/otpctrl.h b/daemons/ipa-slapi-plugins/ipa-pwd-extop/otpctrl.h
index c38d4915a..4cbc17b99 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/otpctrl.h
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/otpctrl.h
@@ -55,6 +55,9 @@
*/
#define OTP_SYNC_REQUEST_OID "2.16.840.1.113730.3.8.10.6"
+/* This control has no data. */
+#define OTP_REQUIRED_OID "2.16.840.1.113730.3.8.10.7"
+
bool otpctrl_present(Slapi_PBlock *pb, const char *oid);
bool otpctrl_sync_handle(const struct otp_config *cfg, Slapi_PBlock *pb,
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
index f41b1ac9d..5c700211b 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
@@ -1172,7 +1172,7 @@ done:
* validation.
*/
static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
- struct berval *creds)
+ struct berval *creds, bool otpreq)
{
uint32_t auth_types;
@@ -1204,10 +1204,10 @@ static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
return false;
}
- /* If the user has no active tokens, succeed. */
+ /* With no tokens, succeed if tokens aren't required. */
if (tokens[0] == NULL) {
otp_token_free_array(tokens);
- return true;
+ return !otpreq;
}
if (otp_token_validate_berval(tokens, creds, NULL)) {
@@ -1218,7 +1218,7 @@ static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
otp_token_free_array(tokens);
}
- return auth_types & OTP_CONFIG_AUTH_TYPE_PASSWORD;
+ return (auth_types & OTP_CONFIG_AUTH_TYPE_PASSWORD) && !otpreq;
}
static int ipapwd_authenticate(const char *dn, Slapi_Entry *entry,
@@ -1394,6 +1394,7 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
char *dn = NULL;
int method = 0;
bool syncreq;
+ bool otpreq;
int ret = 0;
time_t current_time;
time_t expire_time;
@@ -1451,7 +1452,8 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
/* Try to do OTP first. */
syncreq = otpctrl_present(pb, OTP_SYNC_REQUEST_OID);
- if (!syncreq && !ipapwd_pre_bind_otp(dn, entry, credentials))
+ otpreq = otpctrl_present(pb, OTP_REQUIRED_OID);
+ if (!syncreq && !ipapwd_pre_bind_otp(dn, entry, credentials, otpreq))
goto invalid_creds;
/* Ensure that there is a password. */
@@ -1488,6 +1490,7 @@ int ipapwd_pre_init(Slapi_PBlock *pb)
int ret;
slapi_register_supported_control(OTP_SYNC_REQUEST_OID, SLAPI_OPERATION_BIND);
+ slapi_register_supported_control(OTP_REQUIRED_OID, SLAPI_OPERATION_BIND);
ret = slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&ipapwd_plugin_desc);