Hi, this patch-set aims to solve https://fedorahosted.org/sssd/ticket/2596. The first patch is unrelated but needed to make the changes in the second patch properly aligned.
Patches 3,4 and 6 add some certificate related utilities while patch 5 adds the backend changes and patch 7 the changes for InfoPipe. bye, Sumit
From 8ac976d5e5476c7dcf7fac2217f0b6c9bb1daab4 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Thu, 7 May 2015 10:58:33 +0200 Subject: [PATCH 1/7] adding ldap_user_auth_type where missing --- src/config/SSSDConfig/__init__.py.in | 2 ++ src/config/etc/sssd.api.d/sssd-ad.conf | 1 + src/config/etc/sssd.api.d/sssd-ipa.conf | 1 + src/config/etc/sssd.api.d/sssd-ldap.conf | 1 + 4 files changed, 5 insertions(+) diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in index f58c52faf7dd3f9199bd0af4286546d4fe804a88..4851f20810b8bc793916db04c8709b6189271452 100644 --- a/src/config/SSSDConfig/__init__.py.in +++ b/src/config/SSSDConfig/__init__.py.in @@ -306,6 +306,8 @@ option_strings = { 'ldap_user_nds_login_expiration_time' : _('loginExpirationTime attribute of NDS'), 'ldap_user_nds_login_allowed_time_map' : _('loginAllowedTimeMap attribute of NDS'), 'ldap_user_ssh_public_key' : _('SSH public key attribute'), + 'ldap_user_auth_type' : _('attribute listing allowed authentication types for a user'), + 'ldap_user_extra_attrs' : _('A list of extra attributes to download along with the user entry'), 'ldap_group_search_base' : _('Base DN for group lookups'), diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf index c46f3a7cb50db519d113e15f425c7f746d34ad81..23194d38a35fcc9ae2134c3dbbc7cef1aefcf079 100644 --- a/src/config/etc/sssd.api.d/sssd-ad.conf +++ b/src/config/etc/sssd.api.d/sssd-ad.conf @@ -93,6 +93,7 @@ ldap_user_krb_last_pwd_change = str, None, false ldap_user_krb_password_expiration = str, None, false ldap_pwd_attribute = str, None, false ldap_user_ssh_public_key = str, None, false +ldap_user_auth_type = str, None, false ldap_group_search_base = str, None, false ldap_group_search_scope = str, None, false ldap_group_search_filter = str, None, false diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf index 6bae609fa9ff57e70c195b858eeea4eca680f62f..075a74e3aabe4ff664814b8a1aef8117496e9273 100644 --- a/src/config/etc/sssd.api.d/sssd-ipa.conf +++ b/src/config/etc/sssd.api.d/sssd-ipa.conf @@ -89,6 +89,7 @@ ldap_user_krb_last_pwd_change = str, None, false ldap_user_krb_password_expiration = str, None, false ldap_pwd_attribute = str, None, false ldap_user_ssh_public_key = str, None, false +ldap_user_auth_type = str, None, false ldap_group_search_base = str, None, false ldap_group_search_scope = str, None, false ldap_group_search_filter = str, None, false diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf index ba5f56f1942da552fc6ab8f82851714756683a8f..e27d570b8cdf8ad765d16b8f8befe5c25fbebc28 100644 --- a/src/config/etc/sssd.api.d/sssd-ldap.conf +++ b/src/config/etc/sssd.api.d/sssd-ldap.conf @@ -83,6 +83,7 @@ ldap_user_nds_login_disabled = str, None, false ldap_user_nds_login_expiration_time = str, None, false ldap_user_nds_login_allowed_time_map = str, None, false ldap_user_ssh_public_key = str, None, false +ldap_user_auth_type = str, None, false ldap_group_search_base = str, None, false ldap_group_search_scope = str, None, false ldap_group_search_filter = str, None, false -- 2.1.0
From 7eaaeb2561fdbaef1c562be9a5457aa77bba6e85 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Thu, 7 May 2015 10:59:10 +0200 Subject: [PATCH 2/7] LDAP: add ldap_user_certificate option Related to https://fedorahosted.org/sssd/ticket/2596 --- src/config/SSSDConfig/__init__.py.in | 1 + src/config/etc/sssd.api.d/sssd-ad.conf | 1 + src/config/etc/sssd.api.d/sssd-ipa.conf | 1 + src/config/etc/sssd.api.d/sssd-ldap.conf | 1 + src/db/sysdb.h | 1 + src/man/sssd-ldap.5.xml | 14 ++++++++++++++ src/providers/ad/ad_opts.h | 1 + src/providers/ipa/ipa_opts.h | 1 + src/providers/ldap/ldap_opts.h | 3 +++ src/providers/ldap/sdap.h | 1 + 10 files changed, 25 insertions(+) diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in index 4851f20810b8bc793916db04c8709b6189271452..2d488d878450623ff4cc92bf3423acab4f38059e 100644 --- a/src/config/SSSDConfig/__init__.py.in +++ b/src/config/SSSDConfig/__init__.py.in @@ -307,6 +307,7 @@ option_strings = { 'ldap_user_nds_login_allowed_time_map' : _('loginAllowedTimeMap attribute of NDS'), 'ldap_user_ssh_public_key' : _('SSH public key attribute'), 'ldap_user_auth_type' : _('attribute listing allowed authentication types for a user'), + 'ldap_user_certificate' : _('attribute containing the X509 certificate of the user'), 'ldap_user_extra_attrs' : _('A list of extra attributes to download along with the user entry'), diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf index 23194d38a35fcc9ae2134c3dbbc7cef1aefcf079..faab3a51e54d6d498392021a8945501120870f70 100644 --- a/src/config/etc/sssd.api.d/sssd-ad.conf +++ b/src/config/etc/sssd.api.d/sssd-ad.conf @@ -94,6 +94,7 @@ ldap_user_krb_password_expiration = str, None, false ldap_pwd_attribute = str, None, false ldap_user_ssh_public_key = str, None, false ldap_user_auth_type = str, None, false +ldap_user_certificate = str, None, false ldap_group_search_base = str, None, false ldap_group_search_scope = str, None, false ldap_group_search_filter = str, None, false diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf index 075a74e3aabe4ff664814b8a1aef8117496e9273..cfcc00f6f7ca768df861e8cf7face065f90e9e83 100644 --- a/src/config/etc/sssd.api.d/sssd-ipa.conf +++ b/src/config/etc/sssd.api.d/sssd-ipa.conf @@ -90,6 +90,7 @@ ldap_user_krb_password_expiration = str, None, false ldap_pwd_attribute = str, None, false ldap_user_ssh_public_key = str, None, false ldap_user_auth_type = str, None, false +ldap_user_certificate = str, None, false ldap_group_search_base = str, None, false ldap_group_search_scope = str, None, false ldap_group_search_filter = str, None, false diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf index e27d570b8cdf8ad765d16b8f8befe5c25fbebc28..c10290217b1b133792b893d9b80e2599969838a6 100644 --- a/src/config/etc/sssd.api.d/sssd-ldap.conf +++ b/src/config/etc/sssd.api.d/sssd-ldap.conf @@ -84,6 +84,7 @@ ldap_user_nds_login_expiration_time = str, None, false ldap_user_nds_login_allowed_time_map = str, None, false ldap_user_ssh_public_key = str, None, false ldap_user_auth_type = str, None, false +ldap_user_certificate = str, None, false ldap_group_search_base = str, None, false ldap_group_search_scope = str, None, false ldap_group_search_filter = str, None, false diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 4035a39d3cd37390259cda79e6fcafe688bfd360..361d26d37481c521e93584b23af48a0861296e1f 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -132,6 +132,7 @@ #define SYSDB_SSH_PUBKEY "sshPublicKey" #define SYSDB_AUTH_TYPE "authType" +#define SYSDB_USER_CERT "userCertificate" #define SYSDB_SUBDOMAIN_REALM "realmName" #define SYSDB_SUBDOMAIN_FLAT "flatName" diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml index 1b7a2609ac4ebd0bccfd15a04d041e283bcf9cab..f14090843fd32141ad4f491b69868aa7b2412301 100644 --- a/src/man/sssd-ldap.5.xml +++ b/src/man/sssd-ldap.5.xml @@ -814,6 +814,20 @@ </varlistentry> <varlistentry> + <term>ldap_user_certificate (string)</term> + <listitem> + <para> + Name of the LDAP attribute containing the X509 + certificate of the user. + </para> + <para> + Default: no set in the general case, userCertificate + for IPA + </para> + </listitem> + </varlistentry> + + <varlistentry> <term>ldap_group_object_class (string)</term> <listitem> <para> diff --git a/src/providers/ad/ad_opts.h b/src/providers/ad/ad_opts.h index 0f03d33839affe1381fd5eb72bfeba6e5b1dcc68..cb4c05d846d9abe5eedb28013ad13fff6476d431 100644 --- a/src/providers/ad/ad_opts.h +++ b/src/providers/ad/ad_opts.h @@ -216,6 +216,7 @@ struct sdap_attr_map ad_2008r2_user_map[] = { { "ldap_user_nds_login_allowed_time_map", NULL, SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL }, { "ldap_user_ssh_public_key", NULL, SYSDB_SSH_PUBKEY, NULL }, { "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL }, + { "ldap_user_certificate", NULL, SYSDB_USER_CERT, NULL }, SDAP_ATTR_MAP_TERMINATOR }; diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h index 34e9e167eb46f290d017b5af817571122b359b4f..253c0715355536cc181c57beed5326a77e87e464 100644 --- a/src/providers/ipa/ipa_opts.h +++ b/src/providers/ipa/ipa_opts.h @@ -203,6 +203,7 @@ struct sdap_attr_map ipa_user_map[] = { { "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL }, { "ldap_user_ssh_public_key", "ipaSshPubKey", SYSDB_SSH_PUBKEY, NULL }, { "ldap_user_auth_type", "ipaUserAuthType", SYSDB_AUTH_TYPE, NULL }, + { "ldap_user_certificate", "userCertificate", SYSDB_USER_CERT, NULL }, SDAP_ATTR_MAP_TERMINATOR }; diff --git a/src/providers/ldap/ldap_opts.h b/src/providers/ldap/ldap_opts.h index f449ec7c309a5f664941cdefbb3c45a2fab10c99..c1b9bf688ef0a92046195c13a11d2c17b2419d67 100644 --- a/src/providers/ldap/ldap_opts.h +++ b/src/providers/ldap/ldap_opts.h @@ -180,6 +180,7 @@ struct sdap_attr_map rfc2307_user_map[] = { { "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL }, { "ldap_user_ssh_public_key", "sshPublicKey", SYSDB_SSH_PUBKEY, NULL }, { "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL }, + { "ldap_user_certificate", NULL, SYSDB_USER_CERT, NULL }, SDAP_ATTR_MAP_TERMINATOR }; @@ -235,6 +236,7 @@ struct sdap_attr_map rfc2307bis_user_map[] = { { "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL }, { "ldap_user_ssh_public_key", "sshPublicKey", SYSDB_SSH_PUBKEY, NULL }, { "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL }, + { "ldap_user_certificate", NULL, SYSDB_USER_CERT, NULL }, SDAP_ATTR_MAP_TERMINATOR }; @@ -290,6 +292,7 @@ struct sdap_attr_map gen_ad2008r2_user_map[] = { { "ldap_user_nds_login_allowed_time_map", NULL, SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL }, { "ldap_user_ssh_public_key", NULL, SYSDB_SSH_PUBKEY, NULL }, { "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL }, + { "ldap_user_certificate", NULL, SYSDB_USER_CERT, NULL }, SDAP_ATTR_MAP_TERMINATOR }; diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index d7f6c646e59a8af8347e39afb644d8ea40b9a4c3..582ac8d4d51e63d3fff42417d63ea3d8959f502a 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -281,6 +281,7 @@ enum sdap_user_attrs { SDAP_AT_NDS_LOGIN_ALLOWED_TIME_MAP, SDAP_AT_USER_SSH_PUBLIC_KEY, SDAP_AT_USER_AUTH_TYPE, + SDAP_AT_USER_CERT, SDAP_OPTS_USER /* attrs counter */ }; -- 2.1.0
From d36e68e147a3f5614af2cdfcb9f4cbb26a3df5e5 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Fri, 8 May 2015 09:02:26 +0200 Subject: [PATCH 3/7] certs: add PEM/DER conversion utilities Related to https://fedorahosted.org/sssd/ticket/2596 --- Makefile.am | 33 ++++ configure.ac | 5 +- src/tests/cmocka/test_cert_utils.c | 361 +++++++++++++++++++++++++++++++++++++ src/util/cert.h | 47 +++++ src/util/cert/cert_common.c | 154 ++++++++++++++++ src/util/cert/libcrypto/cert.c | 168 +++++++++++++++++ 6 files changed, 765 insertions(+), 3 deletions(-) create mode 100644 src/tests/cmocka/test_cert_utils.c create mode 100644 src/util/cert.h create mode 100644 src/util/cert/cert_common.c create mode 100644 src/util/cert/libcrypto/cert.c diff --git a/Makefile.am b/Makefile.am index 34c18ebbf8f75abee0200892c395c9601b570472..303dd44e1e0e3e66c8d2739051a9d5d63bf8e075 100644 --- a/Makefile.am +++ b/Makefile.am @@ -225,6 +225,7 @@ if HAVE_CMOCKA test_sbus_opath \ test_fo_srv \ pam-srv-tests \ + test_cert_utils \ $(NULL) if HAVE_LIBRESOLV @@ -495,6 +496,7 @@ endif dist_noinst_HEADERS = \ src/monitor/monitor.h \ src/util/crypto/sss_crypto.h \ + src/util/cert.h \ src/util/dlinklist.h \ src/util/util.h \ src/util/io.h \ @@ -716,6 +718,23 @@ libsss_crypt_la_LIBADD = \ libsss_crypt_la_LDFLAGS = \ -avoid-version +pkglib_LTLIBRARIES += libsss_cert.la + +libsss_cert_la_SOURCES = \ + src/util/cert/cert_common.c \ + src/util/cert/libcrypto/cert.c \ + $(NULL) +libsss_cert_la_CFLAGS = \ + $(CRYPTO_CFLAGS) \ + $(NULL) +libsss_cert_la_LIBADD = \ + $(CRYPTO_LIBS) \ + libsss_crypt.la \ + $(NULL) +libsss_cert_la_LDFLAGS = \ + -avoid-version \ + $(NULL) + pkglib_LTLIBRARIES += libsss_util.la libsss_util_la_SOURCES = \ src/confdb/confdb.c \ @@ -2405,6 +2424,20 @@ test_fo_srv_LDADD = \ libsss_test_common.la \ $(NULL) +test_cert_utils_SOURCES = \ + src/tests/cmocka/test_cert_utils.c \ + $(NULL) +test_cert_utils_CFLAGS = \ + $(AM_CFLAGS) \ + $(NULL) +test_cert_utils_LDADD = \ + $(CMOCKA_LIBS) \ + $(POPT_LIBS) \ + $(TALLOC_LIBS) \ + libsss_debug.la \ + libsss_test_common.la \ + libsss_cert.la \ + $(NULL) endif # HAVE_CMOCKA noinst_PROGRAMS = pam_test_client diff --git a/configure.ac b/configure.ac index a127d0bd57ee4149f664e193a65271d50d95f83b..d1c6ba35f6deed327ca8305cc567b77b9a9be5d6 100644 --- a/configure.ac +++ b/configure.ac @@ -339,9 +339,8 @@ fi if test x$cryptolib = xnss; then AM_CHECK_NSS fi -if test x$cryptolib = xlibcrypto; then - AM_CHECK_LIBCRYPTO -fi + +AM_CHECK_LIBCRYPTO AM_CHECK_INOTIFY diff --git a/src/tests/cmocka/test_cert_utils.c b/src/tests/cmocka/test_cert_utils.c new file mode 100644 index 0000000000000000000000000000000000000000..5bcbafb27dbdff596c07b8aad10ca15a35ff4ef5 --- /dev/null +++ b/src/tests/cmocka/test_cert_utils.c @@ -0,0 +1,361 @@ +/* + SSSD + + Certificates - Utilities tests + + Authors: + Sumit Bose <sb...@redhat.com> + + Copyright (C) 2015 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <popt.h> +#include <openssl/objects.h> + +#include "util/cert.h" +#include "tests/cmocka/common_mock.h" +#include "util/crypto/nss/nss_util.h" + + +/* TODO: create a certificate for this test */ +const uint8_t test_cert_der[] = { +0x30, 0x82, 0x04, 0x09, 0x30, 0x82, 0x02, 0xf1, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x09, +0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, +0x34, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x09, 0x49, 0x50, 0x41, 0x2e, +0x44, 0x45, 0x56, 0x45, 0x4c, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x15, +0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, +0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x34, 0x32, 0x38, 0x31, +0x30, 0x32, 0x31, 0x31, 0x31, 0x5a, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x34, 0x32, 0x38, 0x31, 0x30, +0x32, 0x31, 0x31, 0x31, 0x5a, 0x30, 0x32, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, +0x0c, 0x09, 0x49, 0x50, 0x41, 0x2e, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, +0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, 0x69, 0x70, 0x61, 0x2d, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x2e, +0x69, 0x70, 0x61, 0x2e, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, +0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, +0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb2, 0x32, 0x92, 0xab, 0x47, 0xb8, +0x0c, 0x13, 0x54, 0x4a, 0x1f, 0x1e, 0x29, 0x06, 0xff, 0xd0, 0x50, 0xcb, 0xf7, 0x5f, 0x79, 0x91, +0x65, 0xb1, 0x39, 0x01, 0x83, 0x6a, 0xad, 0x9e, 0x77, 0x3b, 0xf3, 0x0d, 0xd7, 0xb9, 0xf6, 0xdc, +0x9e, 0x4a, 0x49, 0xa7, 0xd0, 0x66, 0x72, 0xcc, 0xbf, 0x77, 0xd6, 0xde, 0xa9, 0xfe, 0x67, 0x96, +0xcc, 0x49, 0xf1, 0x37, 0x23, 0x2e, 0xc4, 0x50, 0xf4, 0xeb, 0xba, 0x62, 0xd4, 0x23, 0x4d, 0xf3, +0x37, 0x38, 0x82, 0xee, 0x3b, 0x3f, 0x2c, 0xd0, 0x80, 0x9b, 0x17, 0xaa, 0x9b, 0xeb, 0xa6, 0xdd, +0xf6, 0x15, 0xff, 0x06, 0xb2, 0xce, 0xff, 0xdf, 0x8a, 0x9e, 0x95, 0x85, 0x49, 0x1f, 0x84, 0xfd, +0x81, 0x26, 0xce, 0x06, 0x32, 0x0d, 0x36, 0xca, 0x7c, 0x15, 0x81, 0x68, 0x6b, 0x8f, 0x3e, 0xb3, +0xa2, 0xfc, 0xae, 0xaf, 0xc2, 0x44, 0x58, 0x15, 0x95, 0x40, 0xfc, 0x56, 0x19, 0x91, 0x80, 0xed, +0x42, 0x11, 0x66, 0x04, 0xef, 0x3c, 0xe0, 0x76, 0x33, 0x4b, 0x83, 0xfa, 0x7e, 0xb4, 0x47, 0xdc, +0xfb, 0xed, 0x46, 0xa5, 0x8d, 0x0a, 0x66, 0x87, 0xa5, 0xef, 0x7b, 0x74, 0x62, 0xac, 0xbe, 0x73, +0x36, 0xc9, 0xb4, 0xfe, 0x20, 0xc4, 0x81, 0xf3, 0xfe, 0x78, 0x19, 0xa8, 0xd0, 0xaf, 0x7f, 0x81, +0x72, 0x24, 0x61, 0xd9, 0x76, 0x93, 0xe3, 0x0b, 0xd2, 0x4f, 0x19, 0x17, 0x33, 0x57, 0xd4, 0x82, +0xb0, 0xf1, 0xa8, 0x03, 0xf6, 0x01, 0x99, 0xa9, 0xb8, 0x8c, 0x83, 0xc9, 0xba, 0x19, 0x87, 0xea, +0xd6, 0x3b, 0x06, 0xeb, 0x4c, 0xf7, 0xf1, 0xe5, 0x28, 0xa9, 0x10, 0xb6, 0x46, 0xde, 0xe1, 0xe1, +0x3f, 0xc1, 0xcc, 0x72, 0xbe, 0x2a, 0x43, 0xc6, 0xf6, 0xd0, 0xb5, 0xa0, 0xc4, 0x24, 0x6e, 0x4f, +0xbd, 0xec, 0x22, 0x8a, 0x07, 0x11, 0x3d, 0xf9, 0xd3, 0x15, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, +0x82, 0x01, 0x26, 0x30, 0x82, 0x01, 0x22, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, +0x30, 0x16, 0x80, 0x14, 0xf2, 0x9d, 0x42, 0x4e, 0x0f, 0xc4, 0x48, 0x25, 0x58, 0x2f, 0x1c, 0xce, +0x0f, 0xa1, 0x3f, 0x22, 0xc8, 0x55, 0xc8, 0x91, 0x30, 0x3b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, +0x05, 0x07, 0x01, 0x01, 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, +0x05, 0x07, 0x30, 0x01, 0x86, 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x69, 0x70, 0x61, +0x2d, 0x63, 0x61, 0x2e, 0x69, 0x70, 0x61, 0x2e, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x2f, 0x63, 0x61, +0x2f, 0x6f, 0x63, 0x73, 0x70, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, +0x04, 0x03, 0x02, 0x04, 0xf0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, +0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, +0x05, 0x07, 0x03, 0x02, 0x30, 0x74, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x6d, 0x30, 0x6b, 0x30, +0x69, 0xa0, 0x31, 0xa0, 0x2f, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x69, 0x70, +0x61, 0x2d, 0x63, 0x61, 0x2e, 0x69, 0x70, 0x61, 0x2e, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x2f, 0x69, +0x70, 0x61, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x43, 0x52, 0x4c, +0x2e, 0x62, 0x69, 0x6e, 0xa2, 0x34, 0xa4, 0x32, 0x30, 0x30, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, +0x55, 0x04, 0x0a, 0x0c, 0x05, 0x69, 0x70, 0x61, 0x63, 0x61, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, +0x55, 0x04, 0x03, 0x0c, 0x15, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, +0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, +0x0e, 0x04, 0x16, 0x04, 0x14, 0x2d, 0x2b, 0x3f, 0xcb, 0xf5, 0xb2, 0xff, 0x32, 0x2c, 0xa8, 0xc2, +0x1c, 0xdd, 0xbd, 0x8c, 0x80, 0x1e, 0xdd, 0x31, 0x82, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, +0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x9a, 0x47, 0x2e, +0x50, 0xa7, 0x4d, 0x1d, 0x53, 0x0f, 0xc9, 0x71, 0x42, 0x0c, 0xe5, 0xda, 0x7d, 0x49, 0x64, 0xe7, +0xab, 0xc8, 0xdf, 0xdf, 0x02, 0xc1, 0x87, 0xd1, 0x5b, 0xde, 0xda, 0x6f, 0x2b, 0xe4, 0xf0, 0xbe, +0xba, 0x09, 0xdf, 0x02, 0x85, 0x0b, 0x8a, 0xe6, 0x9b, 0x06, 0x7d, 0x69, 0x38, 0x6c, 0x72, 0xff, +0x4c, 0x7b, 0x2a, 0x0d, 0x3f, 0x23, 0x2f, 0x16, 0x46, 0xff, 0x05, 0x93, 0xb0, 0xea, 0x24, 0x28, +0xd7, 0x12, 0xa1, 0x57, 0xb8, 0x59, 0x19, 0x25, 0xf3, 0x43, 0x0a, 0xd3, 0xfd, 0x0f, 0x37, 0x8d, +0xb8, 0xca, 0x15, 0xe7, 0x48, 0x8a, 0xa0, 0xc7, 0xc7, 0x4b, 0x7f, 0x01, 0x3c, 0x58, 0xd7, 0x37, +0xe5, 0xff, 0x7d, 0x2b, 0x01, 0xac, 0x0d, 0x9f, 0x51, 0x6a, 0xe5, 0x40, 0x24, 0xe6, 0x5e, 0x55, +0x0d, 0xf7, 0xb8, 0x2f, 0x42, 0xac, 0x6d, 0xe5, 0x29, 0x6b, 0xc6, 0x0b, 0xa4, 0xbf, 0x19, 0xbd, +0x39, 0x27, 0xee, 0xfe, 0xc5, 0xb3, 0xdb, 0x62, 0xd4, 0xbe, 0xd2, 0x47, 0xba, 0x96, 0x30, 0x5a, +0xfd, 0x62, 0x00, 0xb8, 0x27, 0x5d, 0x2f, 0x3a, 0x94, 0x0b, 0x95, 0x35, 0x85, 0x40, 0x2c, 0xbc, +0x67, 0xdf, 0x8a, 0xf9, 0xf1, 0x7b, 0x19, 0x96, 0x3e, 0x42, 0x48, 0x13, 0x23, 0x04, 0x95, 0xa9, +0x6b, 0x11, 0x33, 0x81, 0x47, 0x5a, 0x83, 0x72, 0xf6, 0x20, 0xfa, 0x8e, 0x41, 0x7b, 0x8f, 0x77, +0x47, 0x7c, 0xc7, 0x5d, 0x46, 0xf4, 0x4f, 0xfd, 0x81, 0x0a, 0xae, 0x39, 0x27, 0xb6, 0x6a, 0x26, +0x63, 0xb1, 0xd3, 0xbf, 0x55, 0x83, 0x82, 0x9b, 0x36, 0x6c, 0x33, 0x64, 0x0f, 0x50, 0xc0, 0x55, +0x94, 0x13, 0xc3, 0x85, 0xf4, 0xd5, 0x71, 0x65, 0xd0, 0xc0, 0xdd, 0xfc, 0xe6, 0xec, 0x9c, 0x5b, +0xf0, 0x11, 0xb5, 0x2c, 0xf3, 0x48, 0xc1, 0x36, 0x8c, 0xa2, 0x96, 0x48, 0x84}; + +#define TEST_CERT_PEM "-----BEGIN CERTIFICATE-----\n" \ +"MIIECTCCAvGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu\n" \ +"REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNTA0Mjgx\n" \ +"MDIxMTFaFw0xNzA0MjgxMDIxMTFaMDIxEjAQBgNVBAoMCUlQQS5ERVZFTDEcMBoG\n" \ +"A1UEAwwTaXBhLWRldmVsLmlwYS5kZXZlbDCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" \ +"ADCCAQoCggEBALIykqtHuAwTVEofHikG/9BQy/dfeZFlsTkBg2qtnnc78w3Xufbc\n" \ +"nkpJp9Bmcsy/d9beqf5nlsxJ8TcjLsRQ9Ou6YtQjTfM3OILuOz8s0ICbF6qb66bd\n" \ +"9hX/BrLO/9+KnpWFSR+E/YEmzgYyDTbKfBWBaGuPPrOi/K6vwkRYFZVA/FYZkYDt\n" \ +"QhFmBO884HYzS4P6frRH3PvtRqWNCmaHpe97dGKsvnM2ybT+IMSB8/54GajQr3+B\n" \ +"ciRh2XaT4wvSTxkXM1fUgrDxqAP2AZmpuIyDyboZh+rWOwbrTPfx5SipELZG3uHh\n" \ +"P8HMcr4qQ8b20LWgxCRuT73sIooHET350xUCAwEAAaOCASYwggEiMB8GA1UdIwQY\n" \ +"MBaAFPKdQk4PxEglWC8czg+hPyLIVciRMDsGCCsGAQUFBwEBBC8wLTArBggrBgEF\n" \ +"BQcwAYYfaHR0cDovL2lwYS1jYS5pcGEuZGV2ZWwvY2Evb2NzcDAOBgNVHQ8BAf8E\n" \ +"BAMCBPAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHQGA1UdHwRtMGsw\n" \ +"aaAxoC+GLWh0dHA6Ly9pcGEtY2EuaXBhLmRldmVsL2lwYS9jcmwvTWFzdGVyQ1JM\n" \ +"LmJpbqI0pDIwMDEOMAwGA1UECgwFaXBhY2ExHjAcBgNVBAMMFUNlcnRpZmljYXRl\n" \ +"IEF1dGhvcml0eTAdBgNVHQ4EFgQULSs/y/Wy/zIsqMIc3b2MgB7dMYIwDQYJKoZI\n" \ +"hvcNAQELBQADggEBAJpHLlCnTR1TD8lxQgzl2n1JZOeryN/fAsGH0Vve2m8r5PC+\n" \ +"ugnfAoULiuabBn1pOGxy/0x7Kg0/Iy8WRv8Fk7DqJCjXEqFXuFkZJfNDCtP9DzeN\n" \ +"uMoV50iKoMfHS38BPFjXN+X/fSsBrA2fUWrlQCTmXlUN97gvQqxt5Slrxgukvxm9\n" \ +"OSfu/sWz22LUvtJHupYwWv1iALgnXS86lAuVNYVALLxn34r58XsZlj5CSBMjBJWp\n" \ +"axEzgUdag3L2IPqOQXuPd0d8x11G9E/9gQquOSe2aiZjsdO/VYOCmzZsM2QPUMBV\n" \ +"lBPDhfTVcWXQwN385uycW/ARtSzzSME2jKKWSIQ=\n" \ +"-----END CERTIFICATE-----\n" + +#define TEST_CERT_DERB64 \ +"MIIECTCCAvGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \ +"REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNTA0Mjgx" \ +"MDIxMTFaFw0xNzA0MjgxMDIxMTFaMDIxEjAQBgNVBAoMCUlQQS5ERVZFTDEcMBoG" \ +"A1UEAwwTaXBhLWRldmVsLmlwYS5kZXZlbDCCASIwDQYJKoZIhvcNAQEBBQADggEP" \ +"ADCCAQoCggEBALIykqtHuAwTVEofHikG/9BQy/dfeZFlsTkBg2qtnnc78w3Xufbc" \ +"nkpJp9Bmcsy/d9beqf5nlsxJ8TcjLsRQ9Ou6YtQjTfM3OILuOz8s0ICbF6qb66bd" \ +"9hX/BrLO/9+KnpWFSR+E/YEmzgYyDTbKfBWBaGuPPrOi/K6vwkRYFZVA/FYZkYDt" \ +"QhFmBO884HYzS4P6frRH3PvtRqWNCmaHpe97dGKsvnM2ybT+IMSB8/54GajQr3+B" \ +"ciRh2XaT4wvSTxkXM1fUgrDxqAP2AZmpuIyDyboZh+rWOwbrTPfx5SipELZG3uHh" \ +"P8HMcr4qQ8b20LWgxCRuT73sIooHET350xUCAwEAAaOCASYwggEiMB8GA1UdIwQY" \ +"MBaAFPKdQk4PxEglWC8czg+hPyLIVciRMDsGCCsGAQUFBwEBBC8wLTArBggrBgEF" \ +"BQcwAYYfaHR0cDovL2lwYS1jYS5pcGEuZGV2ZWwvY2Evb2NzcDAOBgNVHQ8BAf8E" \ +"BAMCBPAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHQGA1UdHwRtMGsw" \ +"aaAxoC+GLWh0dHA6Ly9pcGEtY2EuaXBhLmRldmVsL2lwYS9jcmwvTWFzdGVyQ1JM" \ +"LmJpbqI0pDIwMDEOMAwGA1UECgwFaXBhY2ExHjAcBgNVBAMMFUNlcnRpZmljYXRl" \ +"IEF1dGhvcml0eTAdBgNVHQ4EFgQULSs/y/Wy/zIsqMIc3b2MgB7dMYIwDQYJKoZI" \ +"hvcNAQELBQADggEBAJpHLlCnTR1TD8lxQgzl2n1JZOeryN/fAsGH0Vve2m8r5PC+" \ +"ugnfAoULiuabBn1pOGxy/0x7Kg0/Iy8WRv8Fk7DqJCjXEqFXuFkZJfNDCtP9DzeN" \ +"uMoV50iKoMfHS38BPFjXN+X/fSsBrA2fUWrlQCTmXlUN97gvQqxt5Slrxgukvxm9" \ +"OSfu/sWz22LUvtJHupYwWv1iALgnXS86lAuVNYVALLxn34r58XsZlj5CSBMjBJWp" \ +"axEzgUdag3L2IPqOQXuPd0d8x11G9E/9gQquOSe2aiZjsdO/VYOCmzZsM2QPUMBV" \ +"lBPDhfTVcWXQwN385uycW/ARtSzzSME2jKKWSIQ=" + +struct test_state { + void *dummy; +}; + +static int setup(void **state) +{ + struct test_state *ts = NULL; + + assert_true(leak_check_setup()); + + ts = talloc(global_talloc_context, struct test_state); + assert_non_null(ts); + + check_leaks_push(ts); + *state = (void *)ts; + return 0; +} + +static int teardown(void **state) +{ + struct test_state *ts = talloc_get_type_abort(*state, struct test_state); + + assert_non_null(ts); + + assert_true(check_leaks_pop(ts)); + talloc_free(ts); + assert_true(leak_check_teardown()); + return 0; +} + +void test_sss_cert_der_to_pem(void **state) +{ + int ret; + char *pem_str; + size_t pem_size; + struct test_state *ts = talloc_get_type_abort(*state, struct test_state); + assert_non_null(ts); + + ret = sss_cert_der_to_pem(NULL, NULL, 0, NULL, NULL); + assert_int_equal(ret, EINVAL); + + ret = sss_cert_der_to_pem(ts, test_cert_der, sizeof(test_cert_der), + &pem_str, &pem_size); + assert_int_equal(ret, EOK); + assert_int_equal(sizeof(TEST_CERT_PEM) - 1, pem_size); + assert_string_equal(pem_str, TEST_CERT_PEM); + + talloc_free(pem_str); +} + +void test_sss_cert_pem_to_der(void **state) +{ + int ret; + uint8_t *der; + size_t der_size; + struct test_state *ts = talloc_get_type_abort(*state, struct test_state); + assert_non_null(ts); + + ret = sss_cert_pem_to_der(NULL, NULL, NULL, NULL); + assert_int_equal(ret, EINVAL); + + ret = sss_cert_pem_to_der(ts, TEST_CERT_PEM, &der, &der_size); + assert_int_equal(ret, EOK); + assert_int_equal(sizeof(test_cert_der), der_size); + assert_memory_equal(der, test_cert_der, der_size); + + talloc_free(der); +} + +void test_sss_cert_derb64_to_pem(void **state) +{ + int ret; + char *pem_str; + size_t pem_size; + struct test_state *ts = talloc_get_type_abort(*state, struct test_state); + assert_non_null(ts); + + ret = sss_cert_derb64_to_pem(NULL, NULL, NULL, NULL); + assert_int_equal(ret, EINVAL); + + ret = sss_cert_derb64_to_pem(ts, TEST_CERT_DERB64, &pem_str, &pem_size); + assert_int_equal(ret, EOK); + assert_int_equal(sizeof(TEST_CERT_PEM) - 1, pem_size); + assert_string_equal(pem_str, TEST_CERT_PEM); + + talloc_free(pem_str); +} + +void test_sss_cert_pem_to_derb64(void **state) +{ + int ret; + char *derb64; + struct test_state *ts = talloc_get_type_abort(*state, struct test_state); + assert_non_null(ts); + + ret = sss_cert_pem_to_derb64(NULL, NULL, NULL); + assert_int_equal(ret, EINVAL); + + ret = sss_cert_pem_to_derb64(ts, TEST_CERT_PEM, &derb64); + assert_int_equal(ret, EOK); + assert_string_equal(derb64, TEST_CERT_DERB64); + + talloc_free(derb64); +} + +void test_bin_to_ldap_filter_value(void **state) +{ + int ret; + size_t c; + char *str; + struct test_state *ts = talloc_get_type_abort(*state, struct test_state); + assert_non_null(ts); + + struct test_data { + uint8_t blob[5]; + const char *str; + } test_data[] = { + {{0x01, 0x02, 0x03, 0x04, 0x05}, "\\01\\02\\03\\04\\05"}, + {{0x00, 0x00, 0x00, 0x00, 0x00}, "\\00\\00\\00\\00\\00"}, + {{0xff, 0xff, 0xff, 0xff, 0xff}, "\\ff\\ff\\ff\\ff\\ff"}, + {{0xca, 0xfe, 0xc0, 0xff, 0xee}, "\\ca\\fe\\c0\\ff\\ee"}, + {{0}, NULL} + }; + + ret = bin_to_ldap_filter_value(ts, NULL, 0, NULL); + assert_int_equal(ret, EINVAL); + + for (c = 0; test_data[c].str != NULL; c++) { + ret = bin_to_ldap_filter_value(ts, test_data[c].blob, 5, &str); + assert_int_equal(ret, EOK); + assert_string_equal(str, test_data[c].str); + + talloc_free(str); + } + +} + +void test_sss_cert_derb64_to_ldap_filter(void **state) +{ + int ret; + char *filter; + + struct test_state *ts = talloc_get_type_abort(*state, struct test_state); + assert_non_null(ts); + + ret = sss_cert_derb64_to_ldap_filter(ts, NULL, NULL, NULL); + assert_int_equal(ret, EINVAL); + + ret = sss_cert_derb64_to_ldap_filter(ts, "AAECAwQFBgcICQ==", "attrName", + &filter); + assert_int_equal(ret, EOK); + assert_string_equal(filter, + "(attrName=\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09)"); + + talloc_free(filter); +} + +int main(int argc, const char *argv[]) +{ + poptContext pc; + int opt; + int ret; + struct poptOption long_options[] = { + POPT_AUTOHELP + SSSD_DEBUG_OPTS + POPT_TABLEEND + }; + + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown(test_sss_cert_der_to_pem, + setup, teardown), + cmocka_unit_test_setup_teardown(test_sss_cert_pem_to_der, + setup, teardown), + cmocka_unit_test_setup_teardown(test_sss_cert_derb64_to_pem, + setup, teardown), + cmocka_unit_test_setup_teardown(test_sss_cert_pem_to_derb64, + setup, teardown), + cmocka_unit_test_setup_teardown(test_bin_to_ldap_filter_value, + setup, teardown), + cmocka_unit_test_setup_teardown(test_sss_cert_derb64_to_ldap_filter, + setup, teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ + debug_level = SSSDBG_INVALID; + + pc = poptGetContext(argv[0], argc, argv, long_options, 0); + while((opt = poptGetNextOpt(pc)) != -1) { + switch(opt) { + default: + fprintf(stderr, "\nInvalid option %s: %s\n\n", + poptBadOption(pc, 0), poptStrerror(opt)); + poptPrintUsage(pc, stderr, 0); + return 1; + } + } + poptFreeContext(pc); + + DEBUG_CLI_INIT(debug_level); + + ret = cmocka_run_group_tests(tests, NULL, NULL); + + CRYPTO_cleanup_all_ex_data(); /* to make valgrind happy */ + +#ifdef HAVE_NSS + /* Cleanup NSS and NSPR to make valgrind happy. */ + nspr_nss_cleanup(); +#endif + + + return ret; +} diff --git a/src/util/cert.h b/src/util/cert.h new file mode 100644 index 0000000000000000000000000000000000000000..79ea1a4ab58149a312bece265798ab3a3f459114 --- /dev/null +++ b/src/util/cert.h @@ -0,0 +1,47 @@ +/* + SSSD - certificate handling utils - openssl version + + Copyright (C) Sumit Bose <sb...@redhat.com> 2015 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdint.h> +#include <talloc.h> + +#include "util/util.h" + +#ifndef __CERT_H__ +#define __CERT_H__ + +errno_t sss_cert_der_to_pem(TALLOC_CTX *mem_ctx, const uint8_t *der_blob, + size_t der_size, char **pem, size_t *pem_size); + +errno_t sss_cert_pem_to_der(TALLOC_CTX *mem_ctx, const char *pem, + uint8_t **der_blob, size_t *der_size); + +errno_t sss_cert_derb64_to_pem(TALLOC_CTX *mem_ctx, const char *derb64, + char **pem, size_t *pem_size); + +errno_t sss_cert_pem_to_derb64(TALLOC_CTX *mem_ctx, const char *pem, + char **derb64); + +errno_t sss_cert_derb64_to_ldap_filter(TALLOC_CTX *mem_ctx, const char *derb64, + const char *attr_name, + char **ldap_filter); + +errno_t bin_to_ldap_filter_value(TALLOC_CTX *mem_ctx, + const uint8_t *blob, size_t blob_size, + char **_str); +#endif /* __CERT_H__ */ diff --git a/src/util/cert/cert_common.c b/src/util/cert/cert_common.c new file mode 100644 index 0000000000000000000000000000000000000000..a29696ed3cd9f2168f47323fac97d44e9b49f921 --- /dev/null +++ b/src/util/cert/cert_common.c @@ -0,0 +1,154 @@ +/* + SSSD - certificate handling utils + + Copyright (C) Sumit Bose <sb...@redhat.com> 2015 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "util/util.h" +#include "util/cert.h" +#include "util/crypto/sss_crypto.h" + +errno_t sss_cert_derb64_to_pem(TALLOC_CTX *mem_ctx, const char *derb64, + char **pem, size_t *pem_size) +{ + int ret; + unsigned char *der; + size_t der_size; + + if (derb64 == NULL) { + return EINVAL; + } + + der = sss_base64_decode(mem_ctx, derb64, &der_size); + if (der == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n"); + return EINVAL; + } + + ret = sss_cert_der_to_pem(mem_ctx, der, der_size, pem, pem_size); + talloc_free(der); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sss_cert_der_to_pem failed.\n"); + } + + return ret; +} + +errno_t sss_cert_pem_to_derb64(TALLOC_CTX *mem_ctx, const char *pem, + char **derb64) +{ + int ret; + uint8_t *der; + size_t der_size; + + ret = sss_cert_pem_to_der(mem_ctx, pem, &der, &der_size); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sss_cert_pem_to_der failed.\n"); + return ret; + } + + *derb64 = sss_base64_encode(mem_ctx, der, der_size); + talloc_free(der); + if (*derb64 == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "sss_base64_encode failed.\n"); + return EINVAL; + } + + return EOK; +} + +errno_t sss_cert_derb64_to_ldap_filter(TALLOC_CTX *mem_ctx, const char *derb64, + const char *attr_name, + char **ldap_filter) +{ + int ret; + unsigned char *der; + size_t der_size; + char *val; + + if (derb64 == NULL || attr_name == NULL) { + return EINVAL; + } + + der = sss_base64_decode(mem_ctx, derb64, &der_size); + if (der == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n"); + return EINVAL; + } + + ret = bin_to_ldap_filter_value(mem_ctx, der, der_size, &val); + talloc_free(der); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "bin_to_ldap_filter_value failed.\n"); + return ret; + } + + *ldap_filter = talloc_asprintf(mem_ctx, "(%s=%s)", attr_name, val); + talloc_free(val); + if (*ldap_filter == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); + return ENOMEM; + } + + return EOK; +} + +errno_t bin_to_ldap_filter_value(TALLOC_CTX *mem_ctx, + const uint8_t *blob, size_t blob_size, + char **_str) +{ + int ret; + size_t c; + size_t len; + char *str = NULL; + char *p; + + if (blob == NULL || blob_size == 0 || _str == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "Missing input parameter.\n"); + return EINVAL; + } + + len = (blob_size * 3) + 1; + str = talloc_size(mem_ctx, len); + if (str == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n"); + return ENOMEM; + } + str[len - 1] = '\0'; + + p = str; + for (c = 0; c < blob_size; c++) { + ret = snprintf(p, 4, "\\%02x", blob[c]); + if (ret != 3) { + DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n"); + ret = EIO; + goto done; + } + + p += 3; + } + + ret = EOK; + +done: + if (ret == EOK) { + *_str = str; + } else { + talloc_free(str); + } + + return ret; +} diff --git a/src/util/cert/libcrypto/cert.c b/src/util/cert/libcrypto/cert.c new file mode 100644 index 0000000000000000000000000000000000000000..1a250f60d1a7dfd5c883ec7e9b1f9491fb74c9b0 --- /dev/null +++ b/src/util/cert/libcrypto/cert.c @@ -0,0 +1,168 @@ +/* + SSSD - certificate handling utils - openssl version + + Copyright (C) Sumit Bose <sb...@redhat.com> 2015 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <openssl/x509.h> +#include <openssl/bio.h> +#include <openssl/pem.h> + +#include "util/util.h" + +errno_t sss_cert_der_to_pem(TALLOC_CTX *mem_ctx, const uint8_t *der_blob, + size_t der_size, char **pem, size_t *pem_size) +{ + X509 *x509 = NULL; + BIO *bio_mem = NULL; + const unsigned char *d; + int ret; + long p_size; + char *p; + + if (der_blob == NULL || der_size == 0) { + return EINVAL; + } + + d = (const unsigned char *) der_blob; + + x509 = d2i_X509(NULL, &d, (int) der_size); + if (x509 == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "d2i_X509 failed.\n"); + return EINVAL; + } + + bio_mem = BIO_new(BIO_s_mem()); + if (bio_mem == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "BIO_new failed.\n"); + ret = ENOMEM; + goto done; + } + + ret = PEM_write_bio_X509(bio_mem, x509); + if (ret != 1) { + DEBUG(SSSDBG_OP_FAILURE, "PEM_write_bio_X509 failed.\n"); + ret = EIO; + goto done; + } + + p_size = BIO_get_mem_data(bio_mem, &p); + if (p_size == 0) { + DEBUG(SSSDBG_OP_FAILURE, "Unexpected PEM size [%ld].\n", p_size); + ret = EINVAL; + goto done; + } + + if (pem != NULL) { + *pem = talloc_strndup(mem_ctx, p, p_size); + if (*pem == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_memdup failed.\n"); + ret = ENOMEM; + goto done; + } + } + + if (pem_size != NULL) { + *pem_size = p_size; + } + + ret = EOK; + +done: + X509_free(x509); + BIO_free_all(bio_mem); + + return ret; +} + +errno_t sss_cert_pem_to_der(TALLOC_CTX *mem_ctx, const char *pem, + uint8_t **_der_blob, size_t *_der_size) +{ + X509 *x509 = NULL; + BIO *bio_mem = NULL; + int ret; + unsigned char *buf; + int buf_size; + uint8_t *der_blob; + size_t der_size; + + if (pem == NULL) { + return EINVAL; + } + + bio_mem = BIO_new(BIO_s_mem()); + if (bio_mem == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "BIO_new failed.\n"); + ret = ENOMEM; + goto done; + } + + ret = BIO_puts(bio_mem, pem); + if (ret <= 0) { + DEBUG(SSSDBG_OP_FAILURE, "BIO_puts failed.\n"); + ret = EIO; + goto done; + } + + x509 = PEM_read_bio_X509(bio_mem, NULL, NULL, NULL); + if (x509 == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "PEM_read_bio_X509 failed.\n"); + ret = EIO; + goto done; + } + + buf_size = i2d_X509(x509, NULL); + if (buf_size <= 0) { + DEBUG(SSSDBG_OP_FAILURE, "i2d_X509 failed.\n"); + ret = EIO; + goto done; + } + + if (_der_blob != NULL) { + buf = talloc_size(mem_ctx, buf_size); + if (buf == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n"); + ret = ENOMEM; + goto done; + } + + der_blob = buf; + + der_size = i2d_X509(x509, &buf); + if (der_size != buf_size) { + talloc_free(der_blob); + DEBUG(SSSDBG_CRIT_FAILURE, + "i2d_X509 size mismatch between two calls.\n"); + ret = EIO; + goto done; + } + + *_der_blob = der_blob; + } + + if (_der_size != NULL) { + *_der_size = buf_size; + } + + ret = EOK; + +done: + X509_free(x509); + BIO_free_all(bio_mem); + + return ret; + +} -- 2.1.0
From 46e477e2821ed9f824b715acdf8b504b1153379a Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Wed, 27 May 2015 11:22:20 +0200 Subject: [PATCH 4/7] sysdb: add sysdb_search_user_by_cert() and sysdb_search_object_by_cert() Related to https://fedorahosted.org/sssd/ticket/2596 --- Makefile.am | 1 + src/db/sysdb.h | 14 ++++++++++++ src/db/sysdb_ops.c | 35 ++++++++++++++++++++++++++++++ src/tests/cwrap/Makefile.am | 2 ++ src/tests/sysdb-tests.c | 53 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 105 insertions(+) diff --git a/Makefile.am b/Makefile.am index 303dd44e1e0e3e66c8d2739051a9d5d63bf8e075..9e68c37826776b52c4b18bd75108f56638158ef4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -804,6 +804,7 @@ libsss_util_la_LIBADD = \ libsss_debug.la \ libsss_child.la \ libsss_crypt.la \ + libsss_cert.la \ $(NULL) if BUILD_SUDO libsss_util_la_SOURCES += src/db/sysdb_sudo.c diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 361d26d37481c521e93584b23af48a0861296e1f..9759642c4953bfc2e67599193f7846189fbdfa59 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -193,6 +193,7 @@ #define SYSDB_SID_FILTER "(&(|("SYSDB_UC")("SYSDB_GC"))("SYSDB_SID_STR"=%s))" #define SYSDB_UUID_FILTER "(&(|("SYSDB_UC")("SYSDB_GC"))("SYSDB_UUID"=%s))" +#define SYSDB_USER_CERT_FILTER "(&("SYSDB_UC")%s)" #define SYSDB_HAS_ENUMERATED "has_enumerated" @@ -1060,6 +1061,19 @@ errno_t sysdb_search_object_by_uuid(TALLOC_CTX *mem_ctx, const char **attrs, struct ldb_result **res); +errno_t sysdb_search_object_by_cert(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *cert, + const char **attrs, + struct ldb_result **res); + +errno_t sysdb_search_user_by_cert(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *cert, + struct ldb_result **res); + + + /* === Functions related to GPOs === */ #define SYSDB_GPO_CONTAINER "cn=gpos,cn=ad,cn=custom" diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index d132af3813351aff69b3afac41a0735e30531ba2..5f09acb517e243fd5040be9380e1bca4ade66132 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -24,6 +24,7 @@ #include "db/sysdb_services.h" #include "db/sysdb_autofs.h" #include "util/crypto/sss_crypto.h" +#include "util/cert.h" #include <time.h> int add_string(struct ldb_message *msg, int flags, @@ -3713,6 +3714,40 @@ errno_t sysdb_search_object_by_uuid(TALLOC_CTX *mem_ctx, uuid_str, attrs, res); } +errno_t sysdb_search_object_by_cert(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *cert, + const char **attrs, + struct ldb_result **res) +{ + int ret; + char *user_filter; + + ret = sss_cert_derb64_to_ldap_filter(mem_ctx, cert, SYSDB_USER_CERT, + &user_filter); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sss_cert_derb64_to_ldap_filter failed.\n"); + return ret; + } + + ret = sysdb_search_object_by_str_attr(mem_ctx, domain, + SYSDB_USER_CERT_FILTER, + user_filter, attrs, res); + talloc_free(user_filter); + + return ret; +} + +errno_t sysdb_search_user_by_cert(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *cert, + struct ldb_result **res) +{ + const char *user_attrs[] = SYSDB_PW_ATTRS; + + return sysdb_search_object_by_cert(mem_ctx, domain, cert, user_attrs, res); +} + errno_t sysdb_get_sids_of_members(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *group_name, diff --git a/src/tests/cwrap/Makefile.am b/src/tests/cwrap/Makefile.am index b805e834977f60d6ba2efdf0f700061bb5e0e264..dc92192928a55abb247096ef310251098d16038f 100644 --- a/src/tests/cwrap/Makefile.am +++ b/src/tests/cwrap/Makefile.am @@ -109,6 +109,7 @@ server_tests_LDADD = \ $(abs_top_builddir)/libsss_debug.la \ $(abs_top_builddir)/libsss_crypt.la \ $(abs_top_builddir)/libsss_test_common.la \ + $(abs_top_builddir)/libsss_cert.la \ $(NULL) usertools_tests_SOURCES = \ @@ -143,6 +144,7 @@ usertools_tests_LDADD = \ $(abs_top_builddir)/libsss_debug.la \ $(abs_top_builddir)/libsss_crypt.la \ $(abs_top_builddir)/libsss_test_common.la \ + $(abs_top_builddir)/libsss_cert.la \ $(NULL) responder_common_tests_SOURCES =\ diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c index 6a77c6eebc4d8e29c09d67f9b1de17939591410a..b892f5ad9ab39567ccf379e27ead3ce9a42a5ddd 100644 --- a/src/tests/sysdb-tests.c +++ b/src/tests/sysdb-tests.c @@ -5201,6 +5201,56 @@ START_TEST(test_sysdb_search_object_by_uuid) } END_TEST +/* For simple searches the content of the certificate does not matter */ +#define TEST_USER_CERT_DERB64 "gJznJT7L0aETU5CMk+n+1Q==" +START_TEST(test_sysdb_search_user_by_cert) +{ + errno_t ret; + struct sysdb_test_ctx *test_ctx; + struct ldb_result *res; + struct sysdb_attrs *attrs = NULL; + struct ldb_val val; + + /* Setup */ + ret = setup_sysdb_tests(&test_ctx); + fail_if(ret != EOK, "Could not set up the test"); + + val.data = sss_base64_decode(test_ctx, TEST_USER_CERT_DERB64, &val.length); + fail_unless(val.data != NULL, "sss_base64_decode failed."); + + attrs = sysdb_new_attrs(test_ctx); + fail_unless(attrs != NULL, "sysdb_new_attrs failed"); + + ret = sysdb_attrs_add_val(attrs, SYSDB_USER_CERT, &val); + fail_unless(ret == EOK, "sysdb_attrs_add_val failed with [%d][%s].", + ret, strerror(ret)); + + ret = sysdb_add_user(test_ctx->domain, "certuser", + 234567, 0, "cert user", "/home/certuser", "/bin/bash", + NULL, attrs, 0, 0); + fail_unless(ret == EOK, "sysdb_add_user failed with [%d][%s].", + ret, strerror(ret)); + + ret = sysdb_search_user_by_cert(test_ctx, test_ctx->domain, "ABC", &res); + fail_unless(ret == ENOENT, + "Unexpected return code from sysdb_search_user_by_cert for " + "missing object, expected [%d], got [%d].", ENOENT, ret); + + ret = sysdb_search_user_by_cert(test_ctx, test_ctx->domain, + TEST_USER_CERT_DERB64, &res); + fail_unless(ret == EOK, "sysdb_search_user_by_cert failed with [%d][%s].", + ret, strerror(ret)); + fail_unless(res->count == 1, "Unexpected number of results, " \ + "expected [%u], get [%u].", 1, res->count); + fail_unless(strcmp(ldb_msg_find_attr_as_string(res->msgs[0], + SYSDB_NAME, ""), + "certuser") == 0, "Unexpected object found, " \ + "expected [%s], got [%s].", "certuser", + ldb_msg_find_attr_as_string(res->msgs[0],SYSDB_NAME, "")); + talloc_free(test_ctx); +} +END_TEST + START_TEST(test_sysdb_delete_by_sid) { errno_t ret; @@ -6370,6 +6420,9 @@ Suite *create_sysdb_suite(void) /* Test UUID string searches */ tcase_add_test(tc_sysdb, test_sysdb_search_object_by_uuid); + /* Test user by certificate searches */ + tcase_add_test(tc_sysdb, test_sysdb_search_user_by_cert); + /* Test canonicalizing names */ tcase_add_test(tc_sysdb, test_sysdb_get_real_name); -- 2.1.0
From 49a9cfe5d90e246738eddea3afcb1ef72dddf2b9 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Wed, 27 May 2015 18:23:49 +0200 Subject: [PATCH 5/7] LDAP/IPA: add user lookup by certificate Related to https://fedorahosted.org/sssd/ticket/2596 --- src/providers/data_provider.h | 6 +++- src/providers/data_provider_be.c | 5 ++++ src/providers/ipa/ipa_subdomains_id.c | 14 +++++++++ src/providers/ldap/ldap_id.c | 55 +++++++++++++++++++++++++++++++---- 4 files changed, 73 insertions(+), 7 deletions(-) diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h index 5df493e9d1ae21ada6f5fd6198a6d9c36680d044..cea478fe4d6f7202f9d599b566c7b503a9728734 100644 --- a/src/providers/data_provider.h +++ b/src/providers/data_provider.h @@ -128,6 +128,7 @@ #define BE_FILTER_ENUM 3 #define BE_FILTER_SECID 4 #define BE_FILTER_UUID 5 +#define BE_FILTER_CERT 6 #define BE_REQ_USER 0x0001 #define BE_REQ_GROUP 0x0002 @@ -140,14 +141,17 @@ #define BE_REQ_HOST 0x0010 #define BE_REQ_BY_SECID 0x0011 #define BE_REQ_USER_AND_GROUP 0x0012 -#define BE_REQ_BY_UUID 0x0013 +#define BE_REQ_BY_UUID 0x0013 +#define BE_REQ_BY_CERT 0x0014 #define BE_REQ_TYPE_MASK 0x00FF #define BE_REQ_FAST 0x1000 #define DP_SEC_ID "secid" +#define DP_CERT "cert" /* sizeof() counts the trailing \0 so we must substract 1 for the string * length */ #define DP_SEC_ID_LEN (sizeof(DP_SEC_ID) - 1) +#define DP_CERT_LEN (sizeof(DP_CERT) - 1) #define EXTRA_NAME_IS_UPN "U" #define EXTRA_INPUT_MAYBE_WITH_VIEW "V" diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c index 34c7b2c766ee4072ee980ad43f1e1d33ee7c8a5a..f5bdfb676011975defa4c5a734d420c8694f3bdd 100644 --- a/src/providers/data_provider_be.c +++ b/src/providers/data_provider_be.c @@ -1199,6 +1199,11 @@ static int be_get_account_info(struct sbus_request *dbus_req, void *user_data) ret = split_name_extended(req, &filter[DP_SEC_ID_LEN + 1], &req->filter_value, &req->extra_value); + } else if (strncmp(filter, DP_CERT"=", DP_CERT_LEN + 1) == 0) { + req->filter_type = BE_FILTER_CERT; + ret = split_name_extended(req, &filter[DP_CERT_LEN + 1], + &req->filter_value, + &req->extra_value); } else if (strcmp(filter, ENUM_INDICATOR) == 0) { req->filter_type = BE_FILTER_ENUM; req->filter_value = NULL; diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c index 617c091d3abc4808da4a279213ffc3e1119001bf..74773def113553ccf011d2c99a6ef3fd2b3150a9 100644 --- a/src/providers/ipa/ipa_subdomains_id.c +++ b/src/providers/ipa/ipa_subdomains_id.c @@ -918,6 +918,20 @@ errno_t get_object_from_cache(TALLOC_CTX *mem_ctx, ret = EOK; goto done; + } else if (ar->filter_type == BE_FILTER_CERT) { + ret = sysdb_search_object_by_cert(mem_ctx, dom, ar->filter_value, attrs, + &res); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Failed to make request to our cache: [%d]: [%s]\n", + ret, sss_strerror(ret)); + goto done; + } + + *_msg = res->msgs[0]; + + ret = EOK; + goto done; } else if (ar->filter_type == BE_FILTER_IDNUM) { errno = 0; id = strtouint32(ar->filter_value, NULL, 10); diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c index d4f46f1dcd69898e5883d21be07f895fd198cf50..952ca20ef486f57de9e5415945b8369c6df8d39c 100644 --- a/src/providers/ldap/ldap_id.c +++ b/src/providers/ldap/ldap_id.c @@ -28,6 +28,7 @@ #include "util/util.h" #include "util/strtonum.h" +#include "util/cert.h" #include "db/sysdb.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" @@ -78,12 +79,13 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx, struct tevent_req *req; struct users_get_state *state; const char *attr_name = NULL; - char *clean_name; + char *clean_name = NULL; char *endptr; int ret; uid_t uid; enum idmap_error_code err; char *sid; + char *user_filter = NULL; req = tevent_req_create(memctx, &state, struct users_get_state); if (!req) return NULL; @@ -194,6 +196,23 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx, goto done; } break; + case BE_FILTER_CERT: + attr_name = ctx->opts->user_map[SDAP_AT_USER_CERT].name; + if (attr_name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Certificate search not configured for this backend.\n"); + ret = EINVAL; + goto done; + } + + ret = sss_cert_derb64_to_ldap_filter(state, attr_name, name, + &user_filter); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "sss_cert_derb64_to_ldap_filter failed.\n"); + goto done; + } + break; default: ret = EINVAL; goto done; @@ -205,29 +224,39 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx, goto done; } + if (user_filter == NULL) { + user_filter = talloc_asprintf(state, "(%s=%s)", attr_name, clean_name); + talloc_free(clean_name); + if (user_filter == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); + ret = ENOMEM; + goto done; + } + } + if (state->use_id_mapping || filter_type == BE_FILTER_SECID) { /* When mapping IDs or looking for SIDs, we don't want to limit * ourselves to users with a UID value. But there must be a SID to map * from. */ state->filter = talloc_asprintf(state, - "(&(%s=%s)(objectclass=%s)(%s=*)(%s=*))", - attr_name, clean_name, + "(&%s(objectclass=%s)(%s=*)(%s=*))", + user_filter, ctx->opts->user_map[SDAP_OC_USER].name, ctx->opts->user_map[SDAP_AT_USER_NAME].name, ctx->opts->user_map[SDAP_AT_USER_OBJECTSID].name); } else { /* When not ID-mapping, make sure there is a non-NULL UID */ state->filter = talloc_asprintf(state, - "(&(%s=%s)(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))", - attr_name, clean_name, + "(&%s(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))", + user_filter, ctx->opts->user_map[SDAP_OC_USER].name, ctx->opts->user_map[SDAP_AT_USER_NAME].name, ctx->opts->user_map[SDAP_AT_USER_UID].name, ctx->opts->user_map[SDAP_AT_USER_UID].name); } - talloc_zfree(clean_name); + talloc_zfree(user_filter); if (!state->filter) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build the base filter\n"); ret = ENOMEM; @@ -1537,6 +1566,16 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, noexist_delete); break; + case BE_REQ_BY_CERT: + subreq = users_get_send(state, be_ctx->ev, id_ctx, + sdom, conn, + ar->filter_value, + ar->filter_type, + ar->extra_value, + ar->attr_type, + noexist_delete); + break; + default: /*fail*/ ret = EINVAL; state->err = "Invalid request type"; @@ -1602,6 +1641,10 @@ sdap_handle_acct_req_done(struct tevent_req *subreq) ret = sdap_get_user_and_group_recv(subreq, &state->dp_error, &state->sdap_ret); break; + case BE_REQ_BY_CERT: + err = "User lookup by certificate failed"; + ret = users_get_recv(subreq, &state->dp_error, &state->sdap_ret); + break; default: /*fail*/ ret = EINVAL; break; -- 2.1.0
From ca7d49f5d256a39a144e063b98372c0b4d123d4a Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Wed, 3 Jun 2015 16:18:05 +0200 Subject: [PATCH 6/7] ncache: add calls for certificate based searches Related to https://fedorahosted.org/sssd/ticket/2596 --- src/responder/common/negcache.c | 31 +++++++++++++++++++++++++++++ src/responder/common/negcache.h | 3 +++ src/tests/cmocka/test_negcache.c | 42 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c index cf70dc52fe122328810064ebd112aec501f892a4..64270f4672f81fcd71f60acb83728d82dd4a1965 100644 --- a/src/responder/common/negcache.c +++ b/src/responder/common/negcache.c @@ -35,6 +35,7 @@ #define NC_UID_PREFIX NC_ENTRY_PREFIX"UID" #define NC_GID_PREFIX NC_ENTRY_PREFIX"GID" #define NC_SID_PREFIX NC_ENTRY_PREFIX"SID" +#define NC_CERT_PREFIX NC_ENTRY_PREFIX"CERT" struct sss_nc_ctx { struct tdb_context *tdb; @@ -417,6 +418,21 @@ int sss_ncache_check_sid(struct sss_nc_ctx *ctx, int ttl, const char *sid) return ret; } +int sss_ncache_check_cert(struct sss_nc_ctx *ctx, int ttl, const char *cert) +{ + char *str; + int ret; + + str = talloc_asprintf(ctx, "%s/%s", NC_CERT_PREFIX, cert); + if (!str) return ENOMEM; + + ret = sss_ncache_check_str(ctx, str, ttl); + + talloc_free(str); + return ret; +} + + static int sss_ncache_set_user_int(struct sss_nc_ctx *ctx, bool permanent, const char *domain, const char *name) { @@ -548,6 +564,21 @@ int sss_ncache_set_sid(struct sss_nc_ctx *ctx, bool permanent, const char *sid) return ret; } +int sss_ncache_set_cert(struct sss_nc_ctx *ctx, bool permanent, + const char *cert) +{ + char *str; + int ret; + + str = talloc_asprintf(ctx, "%s/%s", NC_CERT_PREFIX, cert); + if (!str) return ENOMEM; + + ret = sss_ncache_set_str(ctx, str, permanent); + + talloc_free(str); + return ret; +} + static int delete_permanent(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) { diff --git a/src/responder/common/negcache.h b/src/responder/common/negcache.h index b96fbfda5a63ce32c42b31bcfe517d2369f06138..e7cbfe11451399a639d8e77b3479e74968e72921 100644 --- a/src/responder/common/negcache.h +++ b/src/responder/common/negcache.h @@ -37,6 +37,7 @@ int sss_ncache_check_netgr(struct sss_nc_ctx *ctx, int ttl, int sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl, uid_t uid); int sss_ncache_check_gid(struct sss_nc_ctx *ctx, int ttl, gid_t gid); int sss_ncache_check_sid(struct sss_nc_ctx *ctx, int ttl, const char *sid); +int sss_ncache_check_cert(struct sss_nc_ctx *ctx, int ttl, const char *cert); int sss_ncache_check_service(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, @@ -60,6 +61,8 @@ int sss_ncache_set_netgr(struct sss_nc_ctx *ctx, bool permanent, int sss_ncache_set_uid(struct sss_nc_ctx *ctx, bool permanent, uid_t uid); int sss_ncache_set_gid(struct sss_nc_ctx *ctx, bool permanent, gid_t gid); int sss_ncache_set_sid(struct sss_nc_ctx *ctx, bool permanent, const char *sid); +int sss_ncache_set_cert(struct sss_nc_ctx *ctx, bool permanent, + const char *cert); int sss_ncache_set_service_name(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, const char *name, const char *proto); diff --git a/src/tests/cmocka/test_negcache.c b/src/tests/cmocka/test_negcache.c index 6f9802a38c44adfc41688ce1a9297a8636c5d616..fa07ea2481e2040e3e83eecfb5c69dbec17e26fa 100644 --- a/src/tests/cmocka/test_negcache.c +++ b/src/tests/cmocka/test_negcache.c @@ -45,6 +45,7 @@ #define PORT 21 #define SID "S-1-2-3-4-5" +#define CERT "MIIECTCCAvGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEuREVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNTA0MjgxMDIxMTFaFw0xNzA0MjgxMDIxMTFaMDIxEjAQBgNVBAoMCUlQQS5ERVZFTDEcMBoGA1UEAwwTaXBhLWRldmVsLmlwYS5kZXZlbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALIykqtHuAwTVEofHikG/9BQy/dfeZFlsTkBg2qtnnc78w3XufbcnkpJp9Bmcsy/d9beqf5nlsxJ8TcjLsRQ9Ou6YtQjTfM3OILuOz8s0ICbF6qb66bd9hX/BrLO/9+KnpWFSR+E/YEmzgYyDTbKfBWBaGuPPrOi/K6vwkRYFZVA/FYZkYDtQhFmBO884HYzS4P6frRH3PvtRqWNCmaHpe97dGKsvnM2ybT+IMSB8/54GajQr3+BciRh2XaT4wvSTxkXM1fUgrDxqAP2AZmpuIyDyboZh+rWOwbrTPfx5SipELZG3uHhP8HMcr4qQ8b20LWgxCRuT73sIooHET350xUCAwEAAaOCASYwggEiMB8GA1UdIwQYMBaAFPKdQk4PxEglWC8czg+hPyLIVciRMDsGCCsGAQUFBwEBBC8wLTArBggrBgEFBQcwAYYfaHR0cDovL2lwYS1jYS5pcGEuZGV2ZWwvY2Evb2NzcDAOBgNVHQ8BAf8EBAMCBPAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHQGA1UdHwRtMGswaaAxoC+GLWh0dHA6Ly9pcGEtY2EuaXBhLmRldmVsL2lwYS9jcmwvTWFzdGVyQ1JMLmJpbqI0pDIwMDEOMAwGA1UECgwFaXBhY2ExHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAdBgNVHQ4EFgQULSs/y/Wy/zIsqMIc3b2MgB7dMYIwDQYJKoZIhvcNAQELBQADggEBAJpHLlCnTR1TD8lxQgzl2n1JZOeryN/fAsGH0Vve2m8r5PC+ugnfAoULiuabBn1pOGxy/0x7Kg0/Iy8WRv8Fk7DqJCjXEqFXuFkZJfNDCtP9DzeNuMoV50iKoMfHS38BPFjXN+X/fSsBrA2fUWrlQCTmXlUN97gvQqxt5Slrxgukvxm9OSfu/sWz22LUvtJHupYwWv1iALgnXS86lAuVNYVALLxn34r58XsZlj5CSBMjBJWpaxEzgUdag3L2IPqOQXuPd0d8x11G9E/9gQquOSe2aiZjsdO/VYOCmzZsM2QPUMBVlBPDhfTVcWXQwN385uycW/ARtSzzSME2jKKWSIQ=" #define PROTO "TCP" #define LIFETIME 200 #define SHORTSPAN 1 @@ -317,6 +318,46 @@ static void test_sss_ncache_sid(void **state) assert_int_equal(ret, EEXIST); } +/* @test_sss_ncache_cert : test following functions + * sss_ncache_set_cert + * sss_ncache_check_cert_ + */ +static void test_sss_ncache_cert(void **state) +{ + int ret, ttl; + bool permanent; + const char *cert = NULL; + struct test_state *ts; + + ttl = LIFETIME; + cert = CERT; + ts = talloc_get_type_abort(*state, struct test_state); + + /*test when cert in not present in database */ + ret = sss_ncache_check_cert(ts->ctx, ttl, cert); + assert_int_equal(ret, ENOENT); + + /* test when cert is present in database */ + permanent = true; + ret = sss_ncache_set_cert(ts->ctx, permanent, cert); + assert_int_equal(ret, EOK); + + ret = sss_ncache_check_cert(ts->ctx, ttl, cert); + assert_int_equal(ret, EEXIST); + + permanent = false; + ret = sss_ncache_set_cert(ts->ctx, permanent, cert); + assert_int_equal(ret, EOK); + + ret = sss_ncache_check_cert(ts->ctx, ttl, cert); + assert_int_equal(ret, EEXIST); + + /* test when ttl is -1 with cert present in database*/ + ttl = -1; + ret = sss_ncache_check_cert(ts->ctx, ttl, cert); + assert_int_equal(ret, EEXIST); +} + /* @test_sss_ncache_user : test following functions * sss_ncache_check_user * sss_ncache_set_user @@ -809,6 +850,7 @@ int main(void) cmocka_unit_test_setup_teardown(test_sss_ncache_uid, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_gid, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_sid, setup, teardown), + cmocka_unit_test_setup_teardown(test_sss_ncache_cert, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_user, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_group, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_netgr, setup, teardown), -- 2.1.0
From 2736c0c926d0f01b281243d15fcd664191a54886 Mon Sep 17 00:00:00 2001 From: Sumit Bose <sb...@redhat.com> Date: Tue, 26 May 2015 14:29:17 +0200 Subject: [PATCH 7/7] IFP: add FindByCertificate method for User objects Related to https://fedorahosted.org/sssd/ticket/2596 --- Makefile.am | 4 +- src/responder/common/responder.h | 3 +- src/responder/common/responder_cache_req.c | 59 ++++++++++++++++++-- src/responder/common/responder_cache_req.h | 16 +++++- src/responder/common/responder_dp.c | 11 ++++ src/responder/ifp/ifp_iface.c | 1 + src/responder/ifp/ifp_iface.xml | 4 ++ src/responder/ifp/ifp_iface_generated.c | 26 +++++++++ src/responder/ifp/ifp_iface_generated.h | 5 ++ src/responder/ifp/ifp_users.c | 87 ++++++++++++++++++++++++++++++ src/responder/ifp/ifp_users.h | 4 ++ src/sbus/sssd_dbus_errors.h | 1 + 12 files changed, 215 insertions(+), 6 deletions(-) diff --git a/Makefile.am b/Makefile.am index 9e68c37826776b52c4b18bd75108f56638158ef4..b1a41eb8ac230f30fa2925fe766fdb45a51d8494 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1127,7 +1127,9 @@ sssd_ifp_CFLAGS = \ $(AM_CFLAGS) sssd_ifp_LDADD = \ $(SSSD_LIBS) \ - $(SSSD_INTERNAL_LTLIBS) + $(SSSD_INTERNAL_LTLIBS) \ + libsss_cert.la \ + $(NULL) dist_dbuspolicy_DATA = \ src/responder/ifp/org.freedesktop.sssd.infopipe.conf dist_dbusservice_DATA = \ diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h index 9c7a73809a3de8859aa546c2a7d31620fea39ac9..bd0250d52aae1efdac3bc0847f692542c6cfb6d2 100644 --- a/src/responder/common/responder.h +++ b/src/responder/common/responder.h @@ -281,7 +281,8 @@ enum sss_dp_acct_type { SSS_DP_NETGR, SSS_DP_SERVICES, SSS_DP_SECID, - SSS_DP_USER_AND_GROUP + SSS_DP_USER_AND_GROUP, + SSS_DP_CERT }; struct tevent_req * diff --git a/src/responder/common/responder_cache_req.c b/src/responder/common/responder_cache_req.c index 7ba257276b064d923b6144f45ade59cac48849d5..2afc01b0f9a14a97007df21d2ad59a8d96ad482f 100644 --- a/src/responder/common/responder_cache_req.c +++ b/src/responder/common/responder_cache_req.c @@ -70,6 +70,7 @@ cache_req_input_create(TALLOC_CTX *mem_ctx, /* Check that input parameters match selected type. */ switch (input->type) { case CACHE_REQ_USER_BY_NAME: + case CACHE_REQ_USER_BY_CERT: case CACHE_REQ_GROUP_BY_NAME: case CACHE_REQ_INITGROUPS: if (name == NULL) { @@ -108,6 +109,9 @@ cache_req_input_create(TALLOC_CTX *mem_ctx, case CACHE_REQ_INITGROUPS: input->dp_type = SSS_DP_INITGROUPS; break; + case CACHE_REQ_USER_BY_CERT: + input->dp_type = SSS_DP_CERT; + break; } return input; @@ -192,6 +196,14 @@ cache_req_input_set_domain(struct cache_req_input *input, goto done; } break; + case CACHE_REQ_USER_BY_CERT: + fqn = talloc_asprintf(tmp_ctx, "CERT:%s@%s", input->orig_name, + domain->name); + if (fqn == NULL) { + ret = ENOMEM; + goto done; + } + break; } input->domain = domain; @@ -227,6 +239,9 @@ static errno_t cache_req_check_ncache(struct cache_req_input *input, case CACHE_REQ_GROUP_BY_ID: ret = sss_ncache_check_gid(ncache, neg_timeout, input->id); break; + case CACHE_REQ_USER_BY_CERT: + ret = sss_ncache_check_cert(ncache, neg_timeout, input->orig_name); + break; } if (ret == EEXIST) { @@ -254,6 +269,7 @@ static void cache_req_add_to_ncache(struct cache_req_input *input, break; case CACHE_REQ_USER_BY_ID: case CACHE_REQ_GROUP_BY_ID: + case CACHE_REQ_USER_BY_CERT: /* Nothing to do. Those types must be unique among all domains so * the don't contain domain part. Therefore they must be set only * if all domains are search and the entry is not found. */ @@ -290,6 +306,9 @@ static void cache_req_add_to_ncache_global(struct cache_req_input *input, case CACHE_REQ_GROUP_BY_ID: ret = sss_ncache_set_gid(ncache, false, input->id); break; + case CACHE_REQ_USER_BY_CERT: + ret = sss_ncache_set_cert(ncache, false, input->orig_name); + break; } if (ret != EOK) { @@ -338,6 +357,11 @@ static errno_t cache_req_get_object(TALLOC_CTX *mem_ctx, ret = sysdb_initgroups_with_views(mem_ctx, input->domain, input->dom_objname, &result); break; + case CACHE_REQ_USER_BY_CERT: + one_item_only = true; + ret = sysdb_search_user_by_cert(mem_ctx, input->domain, + input->orig_name, &result); + break; } if (ret != EOK) { @@ -461,6 +485,7 @@ static errno_t cache_req_cache_check(struct tevent_req *req) const char *extra_flag = NULL; uint64_t cache_expire = 0; errno_t ret; + const char *search_str; state = tevent_req_data(req, struct cache_req_cache_state); @@ -479,6 +504,8 @@ static errno_t cache_req_cache_check(struct tevent_req *req) state->cache_refresh_percent, cache_expire); } + search_str = state->input->type == CACHE_REQ_USER_BY_CERT ? + state->input->orig_name : state->input->dom_objname; switch (ret) { case EOK: DEBUG(SSSDBG_TRACE_FUNC, "Cached entry is valid, returning...\n"); @@ -492,7 +519,7 @@ static errno_t cache_req_cache_check(struct tevent_req *req) subreq = sss_dp_get_account_send(state, state->rctx, state->input->domain, true, state->input->dp_type, - state->input->dom_objname, + search_str, state->input->id, NULL); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending out-of-band " @@ -514,7 +541,7 @@ static errno_t cache_req_cache_check(struct tevent_req *req) subreq = sss_dp_get_account_send(state, state->rctx, state->input->domain, true, state->input->dp_type, - state->input->dom_objname, + search_str, state->input->id, extra_flag); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, @@ -648,7 +675,10 @@ struct tevent_req *cache_req_send(TALLOC_CTX *mem_ctx, state->cache_refresh_percent = cache_refresh_percent; state->input = input; - if (state->input->orig_name != NULL && domain == NULL) { + if (state->input->orig_name != NULL && domain == NULL + && (input->type == CACHE_REQ_USER_BY_NAME + || input->type == CACHE_REQ_GROUP_BY_NAME + || input->type == CACHE_REQ_INITGROUPS)) { /* Parse input name first, since it may contain domain name. */ subreq = sss_parse_inp_send(state, rctx, input->orig_name); if (subreq == NULL) { @@ -923,6 +953,29 @@ cache_req_user_by_id_send(TALLOC_CTX *mem_ctx, } struct tevent_req * +cache_req_user_by_cert_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct resp_ctx *rctx, + struct sss_nc_ctx *ncache, + int neg_timeout, + int cache_refresh_percent, + const char *domain, + const char *pem_cert) +{ + struct cache_req_input *input; + + input = cache_req_input_create(mem_ctx, CACHE_REQ_USER_BY_CERT, + pem_cert, 0); + if (input == NULL) { + return NULL; + } + + return cache_req_steal_input_and_send(mem_ctx, ev, rctx, ncache, + neg_timeout, cache_refresh_percent, + domain, input); +} + +struct tevent_req * cache_req_group_by_name_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, diff --git a/src/responder/common/responder_cache_req.h b/src/responder/common/responder_cache_req.h index 088e8efe0ceefe49510bc5eab37e7825b667e5f3..9b862a8b7751bfd938205184b4d6452a75f2684e 100644 --- a/src/responder/common/responder_cache_req.h +++ b/src/responder/common/responder_cache_req.h @@ -32,7 +32,8 @@ enum cache_req_type { CACHE_REQ_USER_BY_ID, CACHE_REQ_GROUP_BY_NAME, CACHE_REQ_GROUP_BY_ID, - CACHE_REQ_INITGROUPS + CACHE_REQ_INITGROUPS, + CACHE_REQ_USER_BY_CERT }; struct cache_req_input; @@ -90,6 +91,19 @@ cache_req_user_by_id_send(TALLOC_CTX *mem_ctx, cache_req_recv(mem_ctx, req, _result, _domain, NULL) struct tevent_req * +cache_req_user_by_cert_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct resp_ctx *rctx, + struct sss_nc_ctx *ncache, + int neg_timeout, + int cache_refresh_percent, + const char *domain, + const char *pem_cert); + +#define cache_req_user_by_cert_recv(mem_ctx, req, _result, _domain, _name) \ + cache_req_recv(mem_ctx, req, _result, _domain, _name) + +struct tevent_req * cache_req_group_by_name_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, diff --git a/src/responder/common/responder_dp.c b/src/responder/common/responder_dp.c index 853b3eae3877a8b6b2ffb310a0fb9ccf017498ae..f752c94c37fd0efa0d072ef8c567bd875a08e6f7 100644 --- a/src/responder/common/responder_dp.c +++ b/src/responder/common/responder_dp.c @@ -548,6 +548,9 @@ sss_dp_get_account_msg(void *pvt) case SSS_DP_USER_AND_GROUP: be_type = BE_REQ_USER_AND_GROUP; break; + case SSS_DP_CERT: + be_type = BE_REQ_BY_CERT; + break; } if (info->fast_reply) { @@ -563,6 +566,14 @@ sss_dp_get_account_msg(void *pvt) filter = talloc_asprintf(info, "%s=%s", DP_SEC_ID, info->opt_name); } + } else if (info->type == SSS_DP_CERT) { + if (info->extra) { + filter = talloc_asprintf(info, "%s=%s:%s", DP_CERT, + info->opt_name, info->extra); + } else { + filter = talloc_asprintf(info, "%s=%s", DP_CERT, + info->opt_name); + } } else { if (info->extra) { filter = talloc_asprintf(info, "name=%s:%s", diff --git a/src/responder/ifp/ifp_iface.c b/src/responder/ifp/ifp_iface.c index 015c66dc5323e237dd21575162e434b11acd8ed7..86d8d338c3d18c22a8dc449b6520f65f8968e26b 100644 --- a/src/responder/ifp/ifp_iface.c +++ b/src/responder/ifp/ifp_iface.c @@ -82,6 +82,7 @@ struct iface_ifp_users iface_ifp_users = { { &iface_ifp_users_meta, 0 }, .FindByName = ifp_users_find_by_name, .FindByID = ifp_users_find_by_id, + .FindByCertificate = ifp_users_find_by_cert, .ListByName = ifp_users_list_by_name, .ListByDomainAndName = ifp_users_list_by_domain_and_name }; diff --git a/src/responder/ifp/ifp_iface.xml b/src/responder/ifp/ifp_iface.xml index 340eb6d23ebfebb508e12118b9ac6c9a71fed099..612a5b5a2817231d5793346778b49cc5a132fc73 100644 --- a/src/responder/ifp/ifp_iface.xml +++ b/src/responder/ifp/ifp_iface.xml @@ -136,6 +136,10 @@ <arg name="id" type="u" direction="in" /> <arg name="result" type="o" direction="out" /> </method> + <method name="FindByCertificate"> + <arg name="pem_cert" type="s" direction="in" /> + <arg name="result" type="o" direction="out" /> + </method> <method name="ListByName"> <arg name="name_filter" type="s" direction="in" /> <arg name="limit" type="u" direction="in" /> diff --git a/src/responder/ifp/ifp_iface_generated.c b/src/responder/ifp/ifp_iface_generated.c index 8255cbea729d9b2c0696cbfdef5c0daf9d958631..a4fdd5d12cd5c82e7832de9d07f55ea6eb621fba 100644 --- a/src/responder/ifp/ifp_iface_generated.c +++ b/src/responder/ifp/ifp_iface_generated.c @@ -685,6 +685,25 @@ int iface_ifp_users_FindByID_finish(struct sbus_request *req, const char *arg_re DBUS_TYPE_INVALID); } +/* arguments for org.freedesktop.sssd.infopipe.Users.FindByCertificate */ +const struct sbus_arg_meta iface_ifp_users_FindByCertificate__in[] = { + { "pem_cert", "s" }, + { NULL, } +}; + +/* arguments for org.freedesktop.sssd.infopipe.Users.FindByCertificate */ +const struct sbus_arg_meta iface_ifp_users_FindByCertificate__out[] = { + { "result", "o" }, + { NULL, } +}; + +int iface_ifp_users_FindByCertificate_finish(struct sbus_request *req, const char *arg_result) +{ + return sbus_request_return_and_finish(req, + DBUS_TYPE_OBJECT_PATH, &arg_result, + DBUS_TYPE_INVALID); +} + /* arguments for org.freedesktop.sssd.infopipe.Users.ListByName */ const struct sbus_arg_meta iface_ifp_users_ListByName__in[] = { { "name_filter", "s" }, @@ -743,6 +762,13 @@ const struct sbus_method_meta iface_ifp_users__methods[] = { invoke_u_method, }, { + "FindByCertificate", /* name */ + iface_ifp_users_FindByCertificate__in, + iface_ifp_users_FindByCertificate__out, + offsetof(struct iface_ifp_users, FindByCertificate), + invoke_s_method, + }, + { "ListByName", /* name */ iface_ifp_users_ListByName__in, iface_ifp_users_ListByName__out, diff --git a/src/responder/ifp/ifp_iface_generated.h b/src/responder/ifp/ifp_iface_generated.h index d2e5cdd3a689d42509e63adde70237cbde627ee2..4dfe61ddff3763b1d3ee165b9098efd667037663 100644 --- a/src/responder/ifp/ifp_iface_generated.h +++ b/src/responder/ifp/ifp_iface_generated.h @@ -68,6 +68,7 @@ #define IFACE_IFP_USERS "org.freedesktop.sssd.infopipe.Users" #define IFACE_IFP_USERS_FINDBYNAME "FindByName" #define IFACE_IFP_USERS_FINDBYID "FindByID" +#define IFACE_IFP_USERS_FINDBYCERTIFICATE "FindByCertificate" #define IFACE_IFP_USERS_LISTBYNAME "ListByName" #define IFACE_IFP_USERS_LISTBYDOMAINANDNAME "ListByDomainAndName" @@ -235,6 +236,7 @@ struct iface_ifp_users { struct sbus_vtable vtable; /* derive from sbus_vtable */ int (*FindByName)(struct sbus_request *req, void *data, const char *arg_name); int (*FindByID)(struct sbus_request *req, void *data, uint32_t arg_id); + int (*FindByCertificate)(struct sbus_request *req, void *data, const char *arg_pem_cert); int (*ListByName)(struct sbus_request *req, void *data, const char *arg_name_filter, uint32_t arg_limit); int (*ListByDomainAndName)(struct sbus_request *req, void *data, const char *arg_domain_name, const char *arg_name_filter, uint32_t arg_limit); }; @@ -245,6 +247,9 @@ int iface_ifp_users_FindByName_finish(struct sbus_request *req, const char *arg_ /* finish function for FindByID */ int iface_ifp_users_FindByID_finish(struct sbus_request *req, const char *arg_result); +/* finish function for FindByCertificate */ +int iface_ifp_users_FindByCertificate_finish(struct sbus_request *req, const char *arg_result); + /* finish function for ListByName */ int iface_ifp_users_ListByName_finish(struct sbus_request *req, const char *arg_result[], int len_result); diff --git a/src/responder/ifp/ifp_users.c b/src/responder/ifp/ifp_users.c index fa6f47f0d2f7ce52c3f0069b8ebf0bf1c98dbf22..e661b8b1b886fed922df7ea286b8756c5ad429de 100644 --- a/src/responder/ifp/ifp_users.c +++ b/src/responder/ifp/ifp_users.c @@ -25,6 +25,7 @@ #include "db/sysdb.h" #include "util/util.h" #include "util/strtonum.h" +#include "util/cert.h" #include "sbus/sssd_dbus_errors.h" #include "responder/common/responder.h" #include "responder/common/responder_cache_req.h" @@ -222,6 +223,92 @@ done: return; } +static void ifp_users_find_by_cert_done(struct tevent_req *req); + +int ifp_users_find_by_cert(struct sbus_request *sbus_req, void *data, + const char *pem_cert) +{ + struct ifp_ctx *ctx; + struct tevent_req *req; + int ret; + char *derb64; + DBusError *error; + + ctx = talloc_get_type(data, struct ifp_ctx); + if (ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); + return ERR_INTERNAL; + } + + ret = sss_cert_pem_to_derb64(sbus_req, pem_cert, &derb64); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sss_cert_pem_to_derb64 failed.\n"); + + if (ret == ENOMEM) { + return ret; + } + + error = sbus_error_new(sbus_req, SBUS_ERROR_EINVAL, + "Invalid certificate format"); + sbus_request_fail_and_finish(sbus_req, error); + /* the connection is already terminated with an error message, hence + * we have to return EOK to not terminate the connection twice. */ + return EOK; + } + + req = cache_req_user_by_cert_send(sbus_req, ctx->rctx->ev, ctx->rctx, + ctx->ncache, ctx->neg_timeout, 0, + NULL, derb64); + if (req == NULL) { + return ENOMEM; + } + + tevent_req_set_callback(req, ifp_users_find_by_cert_done, sbus_req); + + return EOK; +} + +static void ifp_users_find_by_cert_done(struct tevent_req *req) +{ + DBusError *error; + struct sbus_request *sbus_req; + struct sss_domain_info *domain; + struct ldb_result *result; + char *object_path; + errno_t ret; + + sbus_req = tevent_req_callback_data(req, struct sbus_request); + + ret = cache_req_user_by_cert_recv(sbus_req, req, &result, &domain, NULL); + talloc_zfree(req); + if (ret == ENOENT) { + error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND, + "User not found"); + goto done; + } else if (ret != EOK) { + error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " + "user [%d]: %s\n", ret, sss_strerror(ret)); + goto done; + } + + object_path = ifp_users_build_path_from_msg(sbus_req, domain, + result->msgs[0]); + if (object_path == NULL) { + error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL, + "Failed to compose object path"); + goto done; + } + +done: + if (ret != EOK) { + sbus_request_fail_and_finish(sbus_req, error); + return; + } + + iface_ifp_users_FindByCertificate_finish(sbus_req, object_path); + return; +} + int ifp_users_list_by_name(struct sbus_request *sbus_req, void *data, const char *filter, diff --git a/src/responder/ifp/ifp_users.h b/src/responder/ifp/ifp_users.h index 4da0a734752a2a1bd11b0e21c532a1302c9126f1..471c3fb019c7cd0858b2928969b045091f370446 100644 --- a/src/responder/ifp/ifp_users.h +++ b/src/responder/ifp/ifp_users.h @@ -43,6 +43,10 @@ int ifp_users_find_by_id(struct sbus_request *sbus_req, void *data, uint32_t id); +int ifp_users_find_by_cert(struct sbus_request *sbus_req, + void *data, + const char *pem_cert); + int ifp_users_list_by_name(struct sbus_request *sbus_req, void *data, const char *filter, diff --git a/src/sbus/sssd_dbus_errors.h b/src/sbus/sssd_dbus_errors.h index b2b2b233be4d2839d59cb32389505de2b393ba57..7f1656a274f3d2fd52ccd4cb1575ace78bc6d0d1 100644 --- a/src/sbus/sssd_dbus_errors.h +++ b/src/sbus/sssd_dbus_errors.h @@ -25,5 +25,6 @@ #define SBUS_ERROR_INTERNAL "org.freedesktop.sssd.Error.Internal" #define SBUS_ERROR_NOT_FOUND "org.freedesktop.sssd.Error.NotFound" +#define SBUS_ERROR_EINVAL "org.freedesktop.sssd.Error.InvalidArgument" #endif /* SSSD_DBUS_ERRORS_H_ */ -- 2.1.0
_______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/sssd-devel