Patchwork [02/11] libnsdb: Add API for retrieving certificate data

login
register
mail settings
Submitter Chuck Lever
Date Jan. 16, 2013, 9:51 p.m.
Message ID <20130116215159.21683.16689.stgit@seurat.1015granger.net>
Download mbox | patch
Permalink /patch/213070/
State Accepted
Headers show

Comments

Chuck Lever - Jan. 16, 2013, 9:51 p.m.
We're about to optimize nsdb_lookup_nsdb() for the common case,
which is the case that does not need to retrieve any security data.
In fact, right now, there is only a single caller of
nsdb_lookup_nsdb() that needs this data.

Introduce a separate API for retrieving certificate data for an
already-initialized nsdb_t object.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 src/fedfsd/svc.c        |   36 +++++++++++++++++++--------
 src/include/nsdb.h      |    6 ++++
 src/libnsdb/Makefile.am |    4 +--
 src/libnsdb/connsec.c   |   63 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 96 insertions(+), 13 deletions(-)
 create mode 100644 src/libnsdb/connsec.c

Patch

diff --git a/src/fedfsd/svc.c b/src/fedfsd/svc.c
index 9132177..a384f32 100644
--- a/src/fedfsd/svc.c
+++ b/src/fedfsd/svc.c
@@ -1021,11 +1021,12 @@  static void
 fedfsd_svc_get_nsdb_params_1(SVCXPRT *xprt)
 {
 	FedFsGetNsdbParamsRes result;
-	struct fedfs_secdata secdata;
+	FedFsNsdbParams *params = &result.FedFsGetNsdbParamsRes_u.params;
+	FedFsConnectionSec type;
 	char *hostname = NULL;
 	unsigned short port;
 	FedFsNsdbName args;
-	nsdb_t host;
+	nsdb_t host = NULL;
 
 	memset(&args, 0, sizeof(args));
 	if (!svc_getargs(xprt, (xdrproc_t)xdr_FedFsNsdbName, (caddr_t)&args)) {
@@ -1040,14 +1041,27 @@  fedfsd_svc_get_nsdb_params_1(SVCXPRT *xprt)
 	if (result.status != FEDFS_OK)
 		goto out;
 
-	result.status = nsdb_lookup_nsdb(hostname, port, &host, &secdata);
-	if (result.status == FEDFS_OK) {
-		FedFsNsdbParams *params = &result.FedFsGetNsdbParamsRes_u.params;
-		params->secType = (FedFsConnectionSec)secdata.type;
-		params->FedFsNsdbParams_u.secData.secData_len =
-							secdata.len;
-		params->FedFsNsdbParams_u.secData.secData_val =
-							secdata.data;
+	result.status = nsdb_lookup_nsdb(hostname, port, &host, NULL);
+	if (result.status != FEDFS_OK)
+		goto out;
+
+	type = nsdb_sectype(host);
+	switch (type) {
+	case FEDFS_SEC_NONE:
+		result.status = FEDFS_OK;
+		params->secType = type;
+		break;
+	case FEDFS_SEC_TLS:
+		result.status = nsdb_connsec_get_cert_data(host,
+				&params->FedFsNsdbParams_u.secData.secData_val,
+				&params->FedFsNsdbParams_u.secData.secData_len);
+		if (result.status == FEDFS_OK)
+			params->secType = type;
+		break;
+	default:
+		result.status = FEDFS_ERR_SVRFAULT;
+		xlog(L_WARNING, "Unrecognized NSDB connection security "
+			"type for %s:%u", hostname, port);
 	}
 
 out:
@@ -1062,9 +1076,9 @@  out:
 	if (!svc_freeargs(xprt, (xdrproc_t)xdr_FedFsNsdbName, (caddr_t)&args))
 		xlog(L_WARNING, "Failed to free GET_NSDB_PARAMS arguments");
 
+	free(params->FedFsNsdbParams_u.secData.secData_val);
 	nsdb_free_nsdb(host);
 	free(hostname);
-	free(secdata.data);
 }
 
 /**
diff --git a/src/include/nsdb.h b/src/include/nsdb.h
index 2612263..bcf9432 100644
--- a/src/include/nsdb.h
+++ b/src/include/nsdb.h
@@ -186,6 +186,12 @@  FedFsStatus	 nsdb_lookup_nsdb(const char *hostname,
 FedFsStatus	 nsdb_lookup_nsdb_by_uri(const char *uri, nsdb_t *host);
 
 /**
+ * Retrieve NSDB certificate data for "host"
+ */
+FedFsStatus	 nsdb_connsec_get_cert_data(nsdb_t host,
+				char **data, unsigned int *len);
+
+/**
  * Update stored connection parameters for an NSDB
  */
 FedFsStatus	 nsdb_update_nsdb(const char *hostname,
diff --git a/src/libnsdb/Makefile.am b/src/libnsdb/Makefile.am
index cd7805b..13dc0b3 100644
--- a/src/libnsdb/Makefile.am
+++ b/src/libnsdb/Makefile.am
@@ -26,8 +26,8 @@ 
 noinst_HEADERS		= nsdb-internal.h
 
 noinst_LTLIBRARIES	= libnsdb.la
-libnsdb_la_SOURCES	= administrator.c annotation.c display.c fileserver.c \
-			  ldap.c nsdb.c path.c sqlite.c
+libnsdb_la_SOURCES	= administrator.c annotation.c connsec.c display.c \
+			  fileserver.c ldap.c nsdb.c path.c sqlite.c
 
 CLEANFILES		= cscope.in.out cscope.out cscope.po.out *~
 DISTCLEANFILES		= Makefile.in
diff --git a/src/libnsdb/connsec.c b/src/libnsdb/connsec.c
new file mode 100644
index 0000000..fb708cb
--- /dev/null
+++ b/src/libnsdb/connsec.c
@@ -0,0 +1,63 @@ 
+/**
+ * @file src/libnsdb/connsec.c
+ * @brief Handle security-related NSDB connection parameters
+ */
+
+/*
+ * Copyright 2012 Oracle.  All rights reserved.
+ *
+ * This file is part of fedfs-utils.
+ *
+ * fedfs-utils is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2.0 as
+ * published by the Free Software Foundation.
+ *
+ * fedfs-utils 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 version 2.0 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2.0 along with fedfs-utils.  If not, see:
+ *
+ *	http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
+ */
+
+#include "fedfs.h"
+#include "nsdb.h"
+#include "nsdb-internal.h"
+#include "xlog.h"
+
+/**
+ * Retrieve certificate data for NSDB "host" from NSDB database
+ *
+ * @param host an initialized nsdb_t object
+ * @param data OUT: buffer containing security data
+ * @param len OUT: length of security data buffer
+ * @return a FedFsStatus code
+ *
+ * On success, FEDFS_OK is returned and the security data is filled in.
+ *
+ * Caller must free the returned buffer with free(3).
+ */
+FedFsStatus
+nsdb_connsec_get_cert_data(nsdb_t host, char **data, unsigned int *len)
+{
+	FedFsStatus retval;
+
+	if (data == NULL || len == NULL)
+		return FEDFS_ERR_INVAL;
+
+	switch (nsdb_sectype(host)) {
+	case FEDFS_SEC_NONE:
+		retval = FEDFS_ERR_INVAL;
+		break;
+	case FEDFS_SEC_TLS:
+		retval = nsdb_read_certfile(nsdb_certfile(host), data, len);
+		break;
+	default:
+		retval = FEDFS_ERR_SVRFAULT;
+	}
+
+	return retval;
+}