|
|
6cf099 |
From 95bea503429c3f44654265486a07f1696b017e84 Mon Sep 17 00:00:00 2001
|
|
|
6cf099 |
From: Sumit Bose <sbose@redhat.com>
|
|
|
6cf099 |
Date: Fri, 10 Jul 2015 12:10:53 +0200
|
|
|
6cf099 |
Subject: [PATCH 31/37] Add NSS version of p11_child
|
|
|
6cf099 |
|
|
|
6cf099 |
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
6cf099 |
---
|
|
|
6cf099 |
Makefile.am | 25 +-
|
|
|
6cf099 |
contrib/sssd.spec.in | 1 +
|
|
|
6cf099 |
src/p11_child/p11_child_nss.c | 636 ++++++++++++++++++++++++++++++++++++++++++
|
|
|
6cf099 |
3 files changed, 661 insertions(+), 1 deletion(-)
|
|
|
6cf099 |
create mode 100644 src/p11_child/p11_child_nss.c
|
|
|
6cf099 |
|
|
|
6cf099 |
diff --git a/Makefile.am b/Makefile.am
|
|
|
6cf099 |
index 277166ec66b3d67101e628990e68704c886b0c59..e4add9757058773915f1971786b8a9ad584ec51f 100644
|
|
|
6cf099 |
--- a/Makefile.am
|
|
|
6cf099 |
+++ b/Makefile.am
|
|
|
6cf099 |
@@ -148,7 +148,9 @@ endif
|
|
|
6cf099 |
if BUILD_SEMANAGE
|
|
|
6cf099 |
sssdlibexec_PROGRAMS += selinux_child
|
|
|
6cf099 |
endif
|
|
|
6cf099 |
-
|
|
|
6cf099 |
+if HAVE_NSS
|
|
|
6cf099 |
+sssdlibexec_PROGRAMS += p11_child
|
|
|
6cf099 |
+endif
|
|
|
6cf099 |
|
|
|
6cf099 |
if BUILD_PAC_RESPONDER
|
|
|
6cf099 |
sssdlibexec_PROGRAMS += sssd_pac
|
|
|
6cf099 |
@@ -3146,6 +3148,23 @@ proxy_child_LDADD = \
|
|
|
6cf099 |
$(SSSD_LIBS) \
|
|
|
6cf099 |
$(SSSD_INTERNAL_LTLIBS)
|
|
|
6cf099 |
|
|
|
6cf099 |
+p11_child_SOURCES = \
|
|
|
6cf099 |
+ src/p11_child/p11_child_nss.c \
|
|
|
6cf099 |
+ src/util/atomic_io.c \
|
|
|
6cf099 |
+ $(NULL)
|
|
|
6cf099 |
+p11_child_CFLAGS = \
|
|
|
6cf099 |
+ $(AM_CFLAGS) \
|
|
|
6cf099 |
+ $(POPT_CFLAGS) \
|
|
|
6cf099 |
+ $(NSS_CFLAGS) \
|
|
|
6cf099 |
+ $(NULL)
|
|
|
6cf099 |
+p11_child_LDADD = \
|
|
|
6cf099 |
+ libsss_debug.la \
|
|
|
6cf099 |
+ $(TALLOC_LIBS) \
|
|
|
6cf099 |
+ $(POPT_LIBS) \
|
|
|
6cf099 |
+ $(NSS_LIBS) \
|
|
|
6cf099 |
+ libsss_crypt.la \
|
|
|
6cf099 |
+ $(NULL)
|
|
|
6cf099 |
+
|
|
|
6cf099 |
memberof_la_SOURCES = \
|
|
|
6cf099 |
src/ldb_modules/memberof.c \
|
|
|
6cf099 |
src/util/util.c
|
|
|
6cf099 |
@@ -3541,6 +3560,10 @@ if BUILD_SEMANAGE
|
|
|
6cf099 |
-chgrp $(SSSD_USER) $(DESTDIR)$(sssdlibexecdir)/selinux_child
|
|
|
6cf099 |
chmod 4750 $(DESTDIR)$(sssdlibexecdir)/selinux_child
|
|
|
6cf099 |
endif
|
|
|
6cf099 |
+if HAVE_NSS
|
|
|
6cf099 |
+ -chgrp $(SSSD_USER) $(DESTDIR)$(sssdlibexecdir)/p11_child
|
|
|
6cf099 |
+ chmod 4750 $(DESTDIR)$(sssdlibexecdir)/p11_child
|
|
|
6cf099 |
+endif
|
|
|
6cf099 |
endif
|
|
|
6cf099 |
|
|
|
6cf099 |
install-data-hook:
|
|
|
6cf099 |
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
|
|
|
6cf099 |
index 54260e32e24ece372ed7130ab29d766bb1923f77..9ca9a8b4dce5c5d70fb4df268270bcfb0c9b17bb 100644
|
|
|
6cf099 |
--- a/contrib/sssd.spec.in
|
|
|
6cf099 |
+++ b/contrib/sssd.spec.in
|
|
|
6cf099 |
@@ -684,6 +684,7 @@ rm -rf $RPM_BUILD_ROOT
|
|
|
6cf099 |
%{_libexecdir}/%{servicename}/sssd_autofs
|
|
|
6cf099 |
%{_libexecdir}/%{servicename}/sssd_ssh
|
|
|
6cf099 |
%{_libexecdir}/%{servicename}/sssd_sudo
|
|
|
6cf099 |
+%attr(4750,root,sssd) %{_libexecdir}/%{servicename}/p11_child
|
|
|
6cf099 |
|
|
|
6cf099 |
%dir %{_libdir}/%{name}
|
|
|
6cf099 |
%{_libdir}/%{name}/libsss_simple.so
|
|
|
6cf099 |
diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c
|
|
|
6cf099 |
new file mode 100644
|
|
|
6cf099 |
index 0000000000000000000000000000000000000000..6948c142aa7843cda5ff6d18f5853b10c387c224
|
|
|
6cf099 |
--- /dev/null
|
|
|
6cf099 |
+++ b/src/p11_child/p11_child_nss.c
|
|
|
6cf099 |
@@ -0,0 +1,636 @@
|
|
|
6cf099 |
+/*
|
|
|
6cf099 |
+ SSSD
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ Helper child to commmunicate with SmartCard via NSS
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ Authors:
|
|
|
6cf099 |
+ Sumit Bose <sbose@redhat.com>
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ Copyright (C) 2015 Red Hat
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ This program is free software; you can redistribute it and/or modify
|
|
|
6cf099 |
+ it under the terms of the GNU General Public License as published by
|
|
|
6cf099 |
+ the Free Software Foundation; either version 3 of the License, or
|
|
|
6cf099 |
+ (at your option) any later version.
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ This program is distributed in the hope that it will be useful,
|
|
|
6cf099 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
6cf099 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
6cf099 |
+ GNU General Public License for more details.
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ You should have received a copy of the GNU General Public License
|
|
|
6cf099 |
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
6cf099 |
+*/
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+#include <unistd.h>
|
|
|
6cf099 |
+#include <stdio.h>
|
|
|
6cf099 |
+#include <stdlib.h>
|
|
|
6cf099 |
+#include <string.h>
|
|
|
6cf099 |
+#include <popt.h>
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+#include "util/util.h"
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+#include <nss.h>
|
|
|
6cf099 |
+#include <base64.h>
|
|
|
6cf099 |
+#include <cryptohi.h>
|
|
|
6cf099 |
+#include <secmod.h>
|
|
|
6cf099 |
+#include <cert.h>
|
|
|
6cf099 |
+#include <keyhi.h>
|
|
|
6cf099 |
+#include <pk11pub.h>
|
|
|
6cf099 |
+#include <prerror.h>
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+#include "util/child_common.h"
|
|
|
6cf099 |
+#include "providers/dp_backend.h"
|
|
|
6cf099 |
+#include "util/crypto/sss_crypto.h"
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+enum op_mode {
|
|
|
6cf099 |
+ OP_NONE,
|
|
|
6cf099 |
+ OP_AUTH,
|
|
|
6cf099 |
+ OP_PREAUTH
|
|
|
6cf099 |
+};
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+enum pin_mode {
|
|
|
6cf099 |
+ PIN_NONE,
|
|
|
6cf099 |
+ PIN_STDIN,
|
|
|
6cf099 |
+ PIN_KEYPAD
|
|
|
6cf099 |
+};
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static char *password_passthrough(PK11SlotInfo *slot, PRBool retry, void *arg)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ /* give up if 1) no password was supplied, or 2) the password has already
|
|
|
6cf099 |
+ * been rejected once by this token. */
|
|
|
6cf099 |
+ if (retry || (arg == NULL)) {
|
|
|
6cf099 |
+ return NULL;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ return PL_strdup((char *)arg);
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
|
|
|
6cf099 |
+ enum op_mode mode, const char *pin, char **cert,
|
|
|
6cf099 |
+ char **token_name_out)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ int ret;
|
|
|
6cf099 |
+ SECStatus rv;
|
|
|
6cf099 |
+ NSSInitContext *nss_ctx;
|
|
|
6cf099 |
+ SECMODModuleList *mod_list;
|
|
|
6cf099 |
+ SECMODModuleList *mod_list_item;
|
|
|
6cf099 |
+ const char *slot_name;
|
|
|
6cf099 |
+ const char *token_name;
|
|
|
6cf099 |
+ uint32_t flags = NSS_INIT_READONLY
|
|
|
6cf099 |
+ | NSS_INIT_FORCEOPEN
|
|
|
6cf099 |
+ | NSS_INIT_NOROOTINIT
|
|
|
6cf099 |
+ | NSS_INIT_OPTIMIZESPACE
|
|
|
6cf099 |
+ | NSS_INIT_PK11RELOAD;
|
|
|
6cf099 |
+ NSSInitParameters parameters = { 0 };
|
|
|
6cf099 |
+ parameters.length = sizeof (parameters);
|
|
|
6cf099 |
+ PK11SlotInfo *slot = NULL;
|
|
|
6cf099 |
+ CK_SLOT_ID slot_id;
|
|
|
6cf099 |
+ SECMODModuleID module_id;
|
|
|
6cf099 |
+ CERTCertList *cert_list = NULL;
|
|
|
6cf099 |
+ CERTCertListNode *cert_list_node;
|
|
|
6cf099 |
+ const PK11DefaultArrayEntry friendly_attr = { "Publicly-readable certs",
|
|
|
6cf099 |
+ SECMOD_FRIENDLY_FLAG,
|
|
|
6cf099 |
+ CKM_INVALID_MECHANISM };
|
|
|
6cf099 |
+ CERTCertDBHandle *handle;
|
|
|
6cf099 |
+ unsigned char random_value[128];
|
|
|
6cf099 |
+ SECKEYPrivateKey *priv_key;
|
|
|
6cf099 |
+ SECOidTag algtag;
|
|
|
6cf099 |
+ SECItem signed_random_value = {0};
|
|
|
6cf099 |
+ SECKEYPublicKey *pub_key;
|
|
|
6cf099 |
+ CERTCertificate *found_cert = NULL;
|
|
|
6cf099 |
+ PK11SlotList *list = NULL;
|
|
|
6cf099 |
+ PK11SlotListElement *le;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ nss_ctx = NSS_InitContext(nss_db, "", "", SECMOD_DB, ¶meters, flags);
|
|
|
6cf099 |
+ if (nss_ctx == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "NSS_InitContext failed [%d].\n",
|
|
|
6cf099 |
+ PR_GetError());
|
|
|
6cf099 |
+ return EIO;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ PK11_SetPasswordFunc(password_passthrough);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "Default Module List:\n");
|
|
|
6cf099 |
+ mod_list = SECMOD_GetDefaultModuleList();
|
|
|
6cf099 |
+ for (mod_list_item = mod_list; mod_list_item != NULL;
|
|
|
6cf099 |
+ mod_list_item = mod_list_item->next) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "common name: [%s].\n",
|
|
|
6cf099 |
+ mod_list_item->module->commonName);
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "dll name: [%s].\n",
|
|
|
6cf099 |
+ mod_list_item->module->dllName);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "Dead Module List:\n");
|
|
|
6cf099 |
+ mod_list = SECMOD_GetDeadModuleList();
|
|
|
6cf099 |
+ for (mod_list_item = mod_list; mod_list_item != NULL;
|
|
|
6cf099 |
+ mod_list_item = mod_list_item->next) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "common name: [%s].\n",
|
|
|
6cf099 |
+ mod_list_item->module->commonName);
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "dll name: [%s].\n",
|
|
|
6cf099 |
+ mod_list_item->module->dllName);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "DB Module List:\n");
|
|
|
6cf099 |
+ mod_list = SECMOD_GetDBModuleList();
|
|
|
6cf099 |
+ for (mod_list_item = mod_list; mod_list_item != NULL;
|
|
|
6cf099 |
+ mod_list_item = mod_list_item->next) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "common name: [%s].\n",
|
|
|
6cf099 |
+ mod_list_item->module->commonName);
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "dll name: [%s].\n",
|
|
|
6cf099 |
+ mod_list_item->module->dllName);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (slot_name_in != NULL) {
|
|
|
6cf099 |
+ slot = PK11_FindSlotByName(slot_name_in);
|
|
|
6cf099 |
+ if (slot == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "PK11_FindSlotByName failed for [%s]: [%d].\n",
|
|
|
6cf099 |
+ slot_name_in, PR_GetError());
|
|
|
6cf099 |
+ return EIO;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ } else {
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE,
|
|
|
6cf099 |
+ NULL);
|
|
|
6cf099 |
+ if (list == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "PK11_GetAllTokens failed.\n");
|
|
|
6cf099 |
+ return EIO;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ for (le = list->head; le; le = le->next) {
|
|
|
6cf099 |
+ CK_SLOT_INFO slInfo;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ slInfo.flags = 0;
|
|
|
6cf099 |
+ rv = PK11_GetSlotInfo(le->slot, &slInfo);
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL,
|
|
|
6cf099 |
+ "Description [%s] Manufacturer [%s] flags [%lu].\n",
|
|
|
6cf099 |
+ slInfo.slotDescription, slInfo.manufacturerID, slInfo.flags);
|
|
|
6cf099 |
+ if (rv == SECSuccess && (slInfo.flags & CKF_REMOVABLE_DEVICE)) {
|
|
|
6cf099 |
+ slot = PK11_ReferenceSlot(le->slot);
|
|
|
6cf099 |
+ break;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ PK11_FreeSlotList(list);
|
|
|
6cf099 |
+ if (slot == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "No removable slots found.\n");
|
|
|
6cf099 |
+ return EIO;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ slot_id = PK11_GetSlotID(slot);
|
|
|
6cf099 |
+ module_id = PK11_GetModuleID(slot);
|
|
|
6cf099 |
+ slot_name = PK11_GetSlotName(slot);
|
|
|
6cf099 |
+ token_name = PK11_GetTokenName(slot);
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "Found [%s] in slot [%s][%d] of module [%d].\n",
|
|
|
6cf099 |
+ token_name, slot_name, (int) slot_id, (int) module_id);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (PK11_IsFriendly(slot)) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "Token is friendly.\n");
|
|
|
6cf099 |
+ } else {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL,
|
|
|
6cf099 |
+ "Token is NOT friendly.\n");
|
|
|
6cf099 |
+ if (mode == OP_PREAUTH) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "Trying to switch to friendly to read certificate.\n");
|
|
|
6cf099 |
+ rv = PK11_UpdateSlotAttribute(slot, &friendly_attr, PR_TRUE);
|
|
|
6cf099 |
+ if (rv != SECSuccess) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
6cf099 |
+ "PK11_UpdateSlotAttribute failed, continue.\n");
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ /* TODO: check PK11_ProtectedAuthenticationPath() and return the result */
|
|
|
6cf099 |
+ if (mode == OP_AUTH || PK11_NeedLogin(slot)) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "Login required.\n");
|
|
|
6cf099 |
+ if (pin != NULL) {
|
|
|
6cf099 |
+ rv = PK11_Authenticate(slot, PR_FALSE, discard_const(pin));
|
|
|
6cf099 |
+ if (rv != SECSuccess) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "PK11_Authenticate failed: [%d].\n",
|
|
|
6cf099 |
+ PR_GetError());
|
|
|
6cf099 |
+ return EIO;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ } else {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
6cf099 |
+ "Login required but no pin available, continue.\n");
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ } else {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "Login NOT required.\n");
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ cert_list = PK11_ListCertsInSlot(slot);
|
|
|
6cf099 |
+ if (cert_list == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "PK11_ListCertsInSlot failed: [%d].\n",
|
|
|
6cf099 |
+ PR_GetError());
|
|
|
6cf099 |
+ return EIO;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ for (cert_list_node = CERT_LIST_HEAD(cert_list);
|
|
|
6cf099 |
+ !CERT_LIST_END(cert_list_node, cert_list);
|
|
|
6cf099 |
+ cert_list_node = CERT_LIST_NEXT(cert_list_node)) {
|
|
|
6cf099 |
+ if (cert_list_node->cert) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "found cert[%s][%s]\n",
|
|
|
6cf099 |
+ cert_list_node->cert->nickname,
|
|
|
6cf099 |
+ cert_list_node->cert->subjectName);
|
|
|
6cf099 |
+ } else {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "--- empty cert list node ---\n");
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ rv = CERT_FilterCertListByUsage(cert_list, certUsageSSLClient, PR_FALSE);
|
|
|
6cf099 |
+ if (rv != SECSuccess) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "CERT_FilterCertListByUsage failed: [%d].\n",
|
|
|
6cf099 |
+ PR_GetError());
|
|
|
6cf099 |
+ return EIO;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ rv = CERT_FilterCertListForUserCerts(cert_list);
|
|
|
6cf099 |
+ if (rv != SECSuccess) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "CERT_FilterCertListForUserCerts failed: [%d].\n",
|
|
|
6cf099 |
+ PR_GetError());
|
|
|
6cf099 |
+ return EIO;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ handle = CERT_GetDefaultCertDB();
|
|
|
6cf099 |
+ if (handle == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "CERT_GetDefaultCertDB failed: [%d].\n",
|
|
|
6cf099 |
+ PR_GetError());
|
|
|
6cf099 |
+ return EIO;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ found_cert = NULL;
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "Filtered certificates:\n");
|
|
|
6cf099 |
+ for (cert_list_node = CERT_LIST_HEAD(cert_list);
|
|
|
6cf099 |
+ !CERT_LIST_END(cert_list_node, cert_list);
|
|
|
6cf099 |
+ cert_list_node = CERT_LIST_NEXT(cert_list_node)) {
|
|
|
6cf099 |
+ if (cert_list_node->cert) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "found cert[%s][%s]\n",
|
|
|
6cf099 |
+ cert_list_node->cert->nickname,
|
|
|
6cf099 |
+ cert_list_node->cert->subjectName);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (found_cert == NULL) {
|
|
|
6cf099 |
+ found_cert = cert_list_node->cert;
|
|
|
6cf099 |
+ } else {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "More than one certificate found, " \
|
|
|
6cf099 |
+ "using just the first one.\n");
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ } else {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "--- empty cert list node ---\n");
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (found_cert == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL, "No certificate found.\n");
|
|
|
6cf099 |
+ *cert = NULL;
|
|
|
6cf099 |
+ *token_name_out = NULL;
|
|
|
6cf099 |
+ ret = EOK;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ rv = CERT_VerifyCertificateNow(handle, found_cert, PR_TRUE,
|
|
|
6cf099 |
+ certificateUsageSSLClient, NULL, NULL);
|
|
|
6cf099 |
+ if (rv != SECSuccess) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
6cf099 |
+ "CERT_VerifyCertificateNow failed [%d].\n",
|
|
|
6cf099 |
+ PR_GetError());
|
|
|
6cf099 |
+ ret = EIO;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (mode == OP_AUTH) {
|
|
|
6cf099 |
+ rv = PK11_GenerateRandom(random_value, sizeof(random_value));
|
|
|
6cf099 |
+ if (rv != SECSuccess) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
6cf099 |
+ "PK11_GenerateRandom failed [%d].\n", PR_GetError());
|
|
|
6cf099 |
+ return EIO;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ priv_key = PK11_FindPrivateKeyFromCert(slot, found_cert, NULL);
|
|
|
6cf099 |
+ if (priv_key == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
6cf099 |
+ "PK11_FindPrivateKeyFromCert failed [%d]." \
|
|
|
6cf099 |
+ "Maybe pin is missing.\n", PR_GetError());
|
|
|
6cf099 |
+ ret = EIO;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ algtag = SEC_GetSignatureAlgorithmOidTag(priv_key->keyType,
|
|
|
6cf099 |
+ SEC_OID_SHA1);
|
|
|
6cf099 |
+ if (algtag == SEC_OID_UNKNOWN) {
|
|
|
6cf099 |
+ SECKEY_DestroyPrivateKey(priv_key);
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
6cf099 |
+ "SEC_GetSignatureAlgorithmOidTag failed [%d].",
|
|
|
6cf099 |
+ PR_GetError());
|
|
|
6cf099 |
+ ret = EIO;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ rv = SEC_SignData(&signed_random_value,
|
|
|
6cf099 |
+ random_value, sizeof(random_value),
|
|
|
6cf099 |
+ priv_key, algtag);
|
|
|
6cf099 |
+ SECKEY_DestroyPrivateKey(priv_key);
|
|
|
6cf099 |
+ if (rv != SECSuccess) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "SEC_SignData failed [%d].",
|
|
|
6cf099 |
+ PR_GetError());
|
|
|
6cf099 |
+ ret = EIO;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ pub_key = CERT_ExtractPublicKey(found_cert);
|
|
|
6cf099 |
+ if (pub_key == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
6cf099 |
+ "CERT_ExtractPublicKey failed [%d].", PR_GetError());
|
|
|
6cf099 |
+ ret = EIO;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ rv = VFY_VerifyData(random_value, sizeof(random_value),
|
|
|
6cf099 |
+ pub_key, &signed_random_value, algtag,
|
|
|
6cf099 |
+ NULL);
|
|
|
6cf099 |
+ SECKEY_DestroyPublicKey(pub_key);
|
|
|
6cf099 |
+ if (rv != SECSuccess) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "VFY_VerifyData failed [%d].",
|
|
|
6cf099 |
+ PR_GetError());
|
|
|
6cf099 |
+ ret = EACCES;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_ALL,
|
|
|
6cf099 |
+ "Certificate verified and validated.\n");
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ *cert = sss_base64_encode(mem_ctx, found_cert->derCert.data,
|
|
|
6cf099 |
+ found_cert->derCert.len);
|
|
|
6cf099 |
+ if (*cert == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "sss_base64_encode failed.\n");
|
|
|
6cf099 |
+ ret = ENOMEM;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ *token_name_out = talloc_strdup(mem_ctx, token_name);
|
|
|
6cf099 |
+ if (*token_name_out == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy slot name.\n");
|
|
|
6cf099 |
+ ret = ENOMEM;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = EOK;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+done:
|
|
|
6cf099 |
+ if (slot != NULL) {
|
|
|
6cf099 |
+ PK11_FreeSlot(slot);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (cert_list != NULL) {
|
|
|
6cf099 |
+ CERT_DestroyCertList(cert_list);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ PORT_Free(signed_random_value.data);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ rv = NSS_ShutdownContext(nss_ctx);
|
|
|
6cf099 |
+ if (rv != SECSuccess) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "NSS_ShutdownContext failed [%d].\n",
|
|
|
6cf099 |
+ PR_GetError());
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ return ret;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static errno_t p11c_recv_data(TALLOC_CTX *mem_ctx, int fd, char **pin)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ uint8_t buf[IN_BUF_SIZE];
|
|
|
6cf099 |
+ ssize_t len;
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+ char *str;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ errno = 0;
|
|
|
6cf099 |
+ len = sss_atomic_read_s(fd, buf, IN_BUF_SIZE);
|
|
|
6cf099 |
+ if (len == -1) {
|
|
|
6cf099 |
+ ret = errno;
|
|
|
6cf099 |
+ ret = (ret == 0) ? EINVAL: ret;
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
6cf099 |
+ "read failed [%d][%s].\n", ret, strerror(ret));
|
|
|
6cf099 |
+ return ret;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (len == 0 || *buf == '\0') {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Missing PIN.\n");
|
|
|
6cf099 |
+ return EINVAL;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ str = talloc_strndup(mem_ctx, (char *) buf, len);
|
|
|
6cf099 |
+ if (str == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n");
|
|
|
6cf099 |
+ return ENOMEM;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (strlen(str) != len) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
6cf099 |
+ "Input contains additional data, only PIN expected.\n");
|
|
|
6cf099 |
+ talloc_free(str);
|
|
|
6cf099 |
+ return EINVAL;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ *pin = str;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ return EOK;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+int main(int argc, const char *argv[])
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ int opt;
|
|
|
6cf099 |
+ poptContext pc;
|
|
|
6cf099 |
+ int debug_fd = -1;
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+ TALLOC_CTX *main_ctx = NULL;
|
|
|
6cf099 |
+ char *cert;
|
|
|
6cf099 |
+ enum op_mode mode = OP_NONE;
|
|
|
6cf099 |
+ enum pin_mode pin_mode = PIN_NONE;
|
|
|
6cf099 |
+ char *pin = NULL;
|
|
|
6cf099 |
+ char *slot_name_in = NULL;
|
|
|
6cf099 |
+ char *token_name_out = NULL;
|
|
|
6cf099 |
+ char *nss_db = NULL;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ struct poptOption long_options[] = {
|
|
|
6cf099 |
+ POPT_AUTOHELP
|
|
|
6cf099 |
+ {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0,
|
|
|
6cf099 |
+ _("Debug level"), NULL},
|
|
|
6cf099 |
+ {"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0,
|
|
|
6cf099 |
+ _("Add debug timestamps"), NULL},
|
|
|
6cf099 |
+ {"debug-microseconds", 0, POPT_ARG_INT, &debug_microseconds, 0,
|
|
|
6cf099 |
+ _("Show timestamps with microseconds"), NULL},
|
|
|
6cf099 |
+ {"debug-fd", 0, POPT_ARG_INT, &debug_fd, 0,
|
|
|
6cf099 |
+ _("An open file descriptor for the debug logs"), NULL},
|
|
|
6cf099 |
+ {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN,
|
|
|
6cf099 |
+ &debug_to_stderr, 0,
|
|
|
6cf099 |
+ _("Send the debug output to stderr directly."), NULL },
|
|
|
6cf099 |
+ {"auth", 0, POPT_ARG_NONE, NULL, 'a', _("Run in auth mode"), NULL},
|
|
|
6cf099 |
+ {"pre", 0, POPT_ARG_NONE, NULL, 'p', _("Run in pre-auth mode"), NULL},
|
|
|
6cf099 |
+ {"pin", 0, POPT_ARG_NONE, NULL, 'i', _("Expect PIN on stdin"), NULL},
|
|
|
6cf099 |
+ {"keypad", 0, POPT_ARG_NONE, NULL, 'k', _("Expect PIN on keypad"),
|
|
|
6cf099 |
+ NULL},
|
|
|
6cf099 |
+ {"nssdb", 0, POPT_ARG_STRING, &nss_db, 0, _("NSS DB to use"),
|
|
|
6cf099 |
+ NULL},
|
|
|
6cf099 |
+ POPT_TABLEEND
|
|
|
6cf099 |
+ };
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ /* Set debug level to invalid value so we can decide if -d 0 was used. */
|
|
|
6cf099 |
+ debug_level = SSSDBG_INVALID;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ pc = poptGetContext(argv[0], argc, argv, long_options, 0);
|
|
|
6cf099 |
+ while ((opt = poptGetNextOpt(pc)) != -1) {
|
|
|
6cf099 |
+ switch(opt) {
|
|
|
6cf099 |
+ case 'a':
|
|
|
6cf099 |
+ if (mode != OP_NONE) {
|
|
|
6cf099 |
+ fprintf(stderr,
|
|
|
6cf099 |
+ "\n--auth and --pre are mutually exclusive and " \
|
|
|
6cf099 |
+ "should be only used once.\n\n");
|
|
|
6cf099 |
+ poptPrintUsage(pc, stderr, 0);
|
|
|
6cf099 |
+ _exit(-1);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ mode = OP_AUTH;
|
|
|
6cf099 |
+ break;
|
|
|
6cf099 |
+ case 'p':
|
|
|
6cf099 |
+ if (mode != OP_NONE) {
|
|
|
6cf099 |
+ fprintf(stderr,
|
|
|
6cf099 |
+ "\n--auth and --pre are mutually exclusive and " \
|
|
|
6cf099 |
+ "should be only used once.\n\n");
|
|
|
6cf099 |
+ poptPrintUsage(pc, stderr, 0);
|
|
|
6cf099 |
+ _exit(-1);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ mode = OP_PREAUTH;
|
|
|
6cf099 |
+ break;
|
|
|
6cf099 |
+ case 'i':
|
|
|
6cf099 |
+ if (pin_mode != PIN_NONE) {
|
|
|
6cf099 |
+ fprintf(stderr, "\n--pin and --keypad are mutually exclusive " \
|
|
|
6cf099 |
+ "and should be only used once.\n\n");
|
|
|
6cf099 |
+ poptPrintUsage(pc, stderr, 0);
|
|
|
6cf099 |
+ _exit(-1);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ pin_mode = PIN_STDIN;
|
|
|
6cf099 |
+ break;
|
|
|
6cf099 |
+ case 'k':
|
|
|
6cf099 |
+ if (pin_mode != PIN_NONE) {
|
|
|
6cf099 |
+ fprintf(stderr, "\n--pin and --keypad are mutually exclusive " \
|
|
|
6cf099 |
+ "and should be only used once.\n\n");
|
|
|
6cf099 |
+ poptPrintUsage(pc, stderr, 0);
|
|
|
6cf099 |
+ _exit(-1);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ pin_mode = PIN_KEYPAD;
|
|
|
6cf099 |
+ break;
|
|
|
6cf099 |
+ default:
|
|
|
6cf099 |
+ fprintf(stderr, "\nInvalid option %s: %s\n\n",
|
|
|
6cf099 |
+ poptBadOption(pc, 0), poptStrerror(opt));
|
|
|
6cf099 |
+ poptPrintUsage(pc, stderr, 0);
|
|
|
6cf099 |
+ _exit(-1);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (nss_db == NULL) {
|
|
|
6cf099 |
+ fprintf(stderr, "\nMissing NSS DB --nssdb must be specified.\n\n");
|
|
|
6cf099 |
+ poptPrintUsage(pc, stderr, 0);
|
|
|
6cf099 |
+ _exit(-1);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (mode == OP_NONE) {
|
|
|
6cf099 |
+ fprintf(stderr, "\nMissing operation mode, " \
|
|
|
6cf099 |
+ "either --auth or --pre must be specified.\n\n");
|
|
|
6cf099 |
+ poptPrintUsage(pc, stderr, 0);
|
|
|
6cf099 |
+ _exit(-1);
|
|
|
6cf099 |
+ } else if (mode == OP_AUTH && pin_mode == PIN_NONE) {
|
|
|
6cf099 |
+ fprintf(stderr, "\nMissing pin mode for authentication, " \
|
|
|
6cf099 |
+ "either --pin or --keypad must be specified.\n");
|
|
|
6cf099 |
+ poptPrintUsage(pc, stderr, 0);
|
|
|
6cf099 |
+ _exit(-1);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ poptFreeContext(pc);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ DEBUG_INIT(debug_level);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ debug_prg_name = talloc_asprintf(NULL, "[sssd[p11_child[%d]]]", getpid());
|
|
|
6cf099 |
+ if (debug_prg_name == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
|
|
|
6cf099 |
+ goto fail;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (debug_fd != -1) {
|
|
|
6cf099 |
+ ret = set_debug_file_from_fd(debug_fd);
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n");
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_FUNC, "p11_child started.\n");
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_INTERNAL, "Running in [%s] mode.\n",
|
|
|
6cf099 |
+ mode == OP_AUTH ? "auth"
|
|
|
6cf099 |
+ : (mode == OP_PREAUTH ? "pre-auth" : "unknown"));
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_INTERNAL,
|
|
|
6cf099 |
+ "Running with effective IDs: [%"SPRIuid"][%"SPRIgid"].\n",
|
|
|
6cf099 |
+ geteuid(), getegid());
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (getuid() != 0) {
|
|
|
6cf099 |
+ ret = setuid(0);
|
|
|
6cf099 |
+ if (ret == -1) {
|
|
|
6cf099 |
+ ret = errno;
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
6cf099 |
+ "setuid failed: %d, p11_child might not work!\n", ret);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (getgid() != 0) {
|
|
|
6cf099 |
+ ret = setgid(0);
|
|
|
6cf099 |
+ if (ret == -1) {
|
|
|
6cf099 |
+ ret = errno;
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
6cf099 |
+ "setgid failed: %d, p11_child might not work!\n", ret);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ DEBUG(SSSDBG_TRACE_INTERNAL,
|
|
|
6cf099 |
+ "Running with real IDs [%"SPRIuid"][%"SPRIgid"].\n",
|
|
|
6cf099 |
+ getuid(), getgid());
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ main_ctx = talloc_new(NULL);
|
|
|
6cf099 |
+ if (main_ctx == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n");
|
|
|
6cf099 |
+ talloc_free(discard_const(debug_prg_name));
|
|
|
6cf099 |
+ goto fail;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ talloc_steal(main_ctx, debug_prg_name);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (mode == OP_AUTH && pin_mode == PIN_STDIN) {
|
|
|
6cf099 |
+ ret = p11c_recv_data(main_ctx, STDIN_FILENO, &pin;;
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_FATAL_FAILURE, "Failed to read pin.\n");
|
|
|
6cf099 |
+ goto fail;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = do_work(main_ctx, nss_db, slot_name_in, mode, pin, &cert,
|
|
|
6cf099 |
+ &token_name_out);
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_OP_FAILURE, "do_work failed.\n");
|
|
|
6cf099 |
+ goto fail;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (cert != NULL) {
|
|
|
6cf099 |
+ fprintf(stdout, "%s\n", token_name_out);
|
|
|
6cf099 |
+ fprintf(stdout, "%s\n", cert);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ talloc_free(main_ctx);
|
|
|
6cf099 |
+ return EXIT_SUCCESS;
|
|
|
6cf099 |
+fail:
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "p11_child failed!\n");
|
|
|
6cf099 |
+ close(STDOUT_FILENO);
|
|
|
6cf099 |
+ talloc_free(main_ctx);
|
|
|
6cf099 |
+ return EXIT_FAILURE;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
--
|
|
|
6cf099 |
2.4.3
|
|
|
6cf099 |
|