Blame SOURCES/rsyslog-8.24.0-rhbz1507145-omelastic-client-cert.patch

f656cf
From 02772eb5f28b3c3a98f0d739b6210ca82d58f7ee Mon Sep 17 00:00:00 2001
f656cf
From: Rich Megginson <rmeggins@redhat.com>
f656cf
Date: Thu, 8 Feb 2018 18:13:13 -0700
f656cf
Subject: [PATCH] omelasticsearch - add support for CA cert, client cert auth
f656cf
f656cf
This allows omelasticsearch to perform client cert based authentication
f656cf
to Elasticsearch.
f656cf
Add the following parameters:
f656cf
`tls.cacert` - Full path and filename of the file containing the CA cert
f656cf
               for the CA that issued the Elasticsearch server(s) cert(s)
f656cf
`tls.mycert` - Full path and filename of the file containing the client
f656cf
               cert used to authenticate to Elasticsearch
f656cf
`tls.myprivkey` - Full path and filename of the file containing the client
f656cf
                  key used to authenticate to Elasticsearch
f656cf
---
f656cf
 plugins/omelasticsearch/omelasticsearch.c | 79 ++++++++++++++++++++++++++++---
f656cf
 1 file changed, 73 insertions(+), 6 deletions(-)
f656cf
f656cf
diff --git a/plugins/omelasticsearch/omelasticsearch.c b/plugins/omelasticsearch/omelasticsearch.c
f656cf
index 97d8fb233..88bd5e16c 100644
f656cf
--- a/plugins/omelasticsearch/omelasticsearch.c
f656cf
+++ b/plugins/omelasticsearch/omelasticsearch.c
f656cf
@@ -110,6 +110,9 @@ typedef struct _instanceData {
f656cf
 	size_t maxbytes;
f656cf
 	sbool useHttps;
f656cf
 	sbool allowUnsignedCerts;
f656cf
+	uchar *caCertFile;
f656cf
+	uchar *myCertFile;
f656cf
+	uchar *myPrivKeyFile;
f656cf
 } instanceData;
f656cf
 
f656cf
 typedef struct wrkrInstanceData {
f656cf
@@ -154,7 +157,10 @@ static struct cnfparamdescr actpdescr[] = {
f656cf
 	{ "template", eCmdHdlrGetWord, 0 },
f656cf
 	{ "dynbulkid", eCmdHdlrBinary, 0 },
f656cf
 	{ "bulkid", eCmdHdlrGetWord, 0 },
f656cf
-	{ "allowunsignedcerts", eCmdHdlrBinary, 0 }
f656cf
+	{ "allowunsignedcerts", eCmdHdlrBinary, 0 },
f656cf
+	{ "tls.cacert", eCmdHdlrString, 0 },
f656cf
+	{ "tls.mycert", eCmdHdlrString, 0 },
f656cf
+	{ "tls.myprivkey", eCmdHdlrString, 0 }
f656cf
 };
f656cf
 static struct cnfparamblk actpblk =
f656cf
 	{ CNFPARAMBLK_VERSION,
f656cf
@@ -168,6 +174,9 @@ BEGINcreateInstance
f656cf
 CODESTARTcreateInstance
f656cf
 	pData->fdErrFile = -1;
f656cf
 	pthread_mutex_init(&pData->mutErrFile, NULL);
f656cf
+	pData->caCertFile = NULL;
f656cf
+	pData->myCertFile = NULL;
f656cf
+	pData->myPrivKeyFile = NULL;
f656cf
 ENDcreateInstance
f656cf
 
f656cf
 BEGINcreateWrkrInstance
f656cf
@@ -216,6 +225,9 @@ CODESTARTfreeInstance
f656cf
 	free(pData->timeout);
f656cf
 	free(pData->errorFile);
f656cf
 	free(pData->bulkId);
f656cf
+	free(pData->caCertFile);
f656cf
+	free(pData->myCertFile);
f656cf
+	free(pData->myPrivKeyFile);
f656cf
 ENDfreeInstance
f656cf
 
f656cf
 BEGINfreeWrkrInstance
f656cf
@@ -270,6 +282,9 @@ CODESTARTdbgPrintInstInfo
f656cf
 	dbgprintf("\tinterleaved=%d\n", pData->interleaved);
f656cf
 	dbgprintf("\tdynbulkid=%d\n", pData->dynBulkId);
f656cf
 	dbgprintf("\tbulkid='%s'\n", pData->bulkId);
f656cf
+	dbgprintf("\ttls.cacert='%s'\n", pData->caCertFile);
f656cf
+	dbgprintf("\ttls.mycert='%s'\n", pData->myCertFile);
f656cf
+	dbgprintf("\ttls.myprivkey='%s'\n", pData->myPrivKeyFile);
f656cf
 ENDdbgPrintInstInfo
f656cf
 
f656cf
 
f656cf
@@ -311,7 +326,7 @@ computeBaseUrl(const char*const serverParam,
f656cf
 		r = useHttps ? es_addBuf(&urlBuf, SCHEME_HTTPS, sizeof(SCHEME_HTTPS)-1) :
f656cf
 			es_addBuf(&urlBuf, SCHEME_HTTP, sizeof(SCHEME_HTTP)-1);
f656cf
 
f656cf
-	if (r == 0) r = es_addBuf(&urlBuf, serverParam, strlen(serverParam));
f656cf
+	if (r == 0) r = es_addBuf(&urlBuf, (char *)serverParam, strlen(serverParam));
f656cf
 	if (r == 0 && !strchr(host, ':')) {
f656cf
 		snprintf(portBuf, sizeof(portBuf), ":%d", defaultPort);
f656cf
 		r = es_addBuf(&urlBuf, portBuf, strlen(portBuf));
f656cf
@@ -1296,7 +1311,7 @@ finalize_it:
f656cf
 }
f656cf
 
f656cf
 static void
f656cf
-curlCheckConnSetup(CURL *handle, HEADER *header, long timeout, sbool allowUnsignedCerts)
f656cf
+curlCheckConnSetup(CURL *handle, HEADER *header, long timeout, sbool allowUnsignedCerts, wrkrInstanceData_t *pWrkrData)
f656cf
 {
f656cf
 	curl_easy_setopt(handle, CURLOPT_HTTPHEADER, header);
f656cf
 	curl_easy_setopt(handle, CURLOPT_NOBODY, TRUE);
f656cf
@@ -1305,13 +1320,21 @@ curlCheckConnSetup(CURL *handle, HEADER *header, long timeout, sbool allowUnsign
f656cf
 
f656cf
 	if(allowUnsignedCerts)
f656cf
 		curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, FALSE);
f656cf
+	if(pWrkrData->pData->caCertFile)
f656cf
+		curl_easy_setopt(handle, CURLOPT_CAINFO, pWrkrData->pData->caCertFile);
f656cf
+	if(pWrkrData->pData->myCertFile)
f656cf
+		curl_easy_setopt(handle, CURLOPT_SSLCERT, pWrkrData->pData->myCertFile);
f656cf
+	if(pWrkrData->pData->myPrivKeyFile)
f656cf
+		curl_easy_setopt(handle, CURLOPT_SSLKEY, pWrkrData->pData->myPrivKeyFile);
f656cf
+	/* uncomment for in-dept debuggung:
f656cf
+	curl_easy_setopt(handle, CURLOPT_VERBOSE, TRUE); */
f656cf
 
f656cf
 	/* Only enable for debugging
f656cf
 	curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE); */
f656cf
 }
f656cf
 
f656cf
 static void
f656cf
-curlPostSetup(CURL *handle, HEADER *header, uchar* authBuf)
f656cf
+curlPostSetup(CURL *handle, HEADER *header, uchar* authBuf, wrkrInstanceData_t *pWrkrData)
f656cf
 {
f656cf
 	curl_easy_setopt(handle, CURLOPT_HTTPHEADER, header);
f656cf
 	curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, curlResult);
f656cf
@@ -1322,6 +1345,12 @@ curlPostSetup(CURL *handle, HEADER *header, uchar* authBuf)
f656cf
 		curl_easy_setopt(handle, CURLOPT_USERPWD, authBuf);
f656cf
 		curl_easy_setopt(handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
f656cf
 	}
f656cf
+	if(pWrkrData->pData->caCertFile)
f656cf
+		curl_easy_setopt(handle, CURLOPT_CAINFO, pWrkrData->pData->caCertFile);
f656cf
+	if(pWrkrData->pData->myCertFile)
f656cf
+		curl_easy_setopt(handle, CURLOPT_SSLCERT, pWrkrData->pData->myCertFile);
f656cf
+	if(pWrkrData->pData->myPrivKeyFile)
f656cf
+		curl_easy_setopt(handle, CURLOPT_SSLKEY, pWrkrData->pData->myPrivKeyFile);
f656cf
 }
f656cf
 
f656cf
 static rsRetVal
f656cf
@@ -1332,7 +1361,7 @@ curlSetup(wrkrInstanceData_t *pWrkrData, instanceData *pData)
f656cf
 	if (pWrkrData->curlPostHandle == NULL) {
f656cf
 		return RS_RET_OBJ_CREATION_FAILED;
f656cf
 	}
f656cf
-	curlPostSetup(pWrkrData->curlPostHandle, pWrkrData->curlHeader, pData->authBuf);
f656cf
+	curlPostSetup(pWrkrData->curlPostHandle, pWrkrData->curlHeader, pData->authBuf, pWrkrData);
f656cf
 
f656cf
 	pWrkrData->curlCheckConnHandle = curl_easy_init();
f656cf
 	if (pWrkrData->curlCheckConnHandle == NULL) {
f656cf
@@ -1341,7 +1370,7 @@ curlSetup(wrkrInstanceData_t *pWrkrData, instanceData *pData)
f656cf
 		return RS_RET_OBJ_CREATION_FAILED;
f656cf
 	}
f656cf
 	curlCheckConnSetup(pWrkrData->curlCheckConnHandle, pWrkrData->curlHeader,
f656cf
-		pData->healthCheckTimeout, pData->allowUnsignedCerts);
f656cf
+		pData->healthCheckTimeout, pData->allowUnsignedCerts, pWrkrData);
f656cf
 
f656cf
 	return RS_RET_OK;
f656cf
 }
f656cf
@@ -1372,6 +1401,9 @@ setInstParamDefaults(instanceData *pData)
f656cf
 	pData->interleaved=0;
f656cf
 	pData->dynBulkId= 0;
f656cf
 	pData->bulkId = NULL;
f656cf
+	pData->caCertFile = NULL;
f656cf
+	pData->myCertFile = NULL;
f656cf
+	pData->myPrivKeyFile = NULL;
f656cf
 }
f656cf
 
f656cf
 BEGINnewActInst
f656cf
@@ -1380,6 +1412,8 @@ BEGINnewActInst
f656cf
 	struct cnfarray* servers = NULL;
f656cf
 	int i;
f656cf
 	int iNumTpls;
f656cf
+	FILE *fp;
f656cf
+	char errStr[1024];
f656cf
 CODESTARTnewActInst
f656cf
 	if((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) {
f656cf
 		ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS);
f656cf
@@ -1435,6 +1469,39 @@ CODESTARTnewActInst
f656cf
 			pData->dynBulkId = pvals[i].val.d.n;
f656cf
 		} else if(!strcmp(actpblk.descr[i].name, "bulkid")) {
f656cf
 			pData->bulkId = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
f656cf
+		} else if(!strcmp(actpblk.descr[i].name, "tls.cacert")) {
f656cf
+			pData->caCertFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
f656cf
+			fp = fopen((const char*)pData->caCertFile, "r");
f656cf
+			if(fp == NULL) {
f656cf
+				rs_strerror_r(errno, errStr, sizeof(errStr));
f656cf
+				errmsg.LogError(0, RS_RET_NO_FILE_ACCESS,
f656cf
+						"error: 'tls.cacert' file %s couldn't be accessed: %s\n",
f656cf
+						pData->caCertFile, errStr);
f656cf
+			} else {
f656cf
+				fclose(fp);
f656cf
+			}
f656cf
+		} else if(!strcmp(actpblk.descr[i].name, "tls.mycert")) {
f656cf
+			pData->myCertFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
f656cf
+			fp = fopen((const char*)pData->myCertFile, "r");
f656cf
+			if(fp == NULL) {
f656cf
+				rs_strerror_r(errno, errStr, sizeof(errStr));
f656cf
+				errmsg.LogError(0, RS_RET_NO_FILE_ACCESS,
f656cf
+						"error: 'tls.mycert' file %s couldn't be accessed: %s\n",
f656cf
+						pData->myCertFile, errStr);
f656cf
+			} else {
f656cf
+				fclose(fp);
f656cf
+			}
f656cf
+		} else if(!strcmp(actpblk.descr[i].name, "tls.myprivkey")) {
f656cf
+			pData->myPrivKeyFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
f656cf
+			fp = fopen((const char*)pData->myPrivKeyFile, "r");
f656cf
+			if(fp == NULL) {
f656cf
+				rs_strerror_r(errno, errStr, sizeof(errStr));
f656cf
+				errmsg.LogError(0, RS_RET_NO_FILE_ACCESS,
f656cf
+						"error: 'tls.myprivkey' file %s couldn't be accessed: %s\n",
f656cf
+						pData->myPrivKeyFile, errStr);
f656cf
+			} else {
f656cf
+				fclose(fp);
f656cf
+			}
f656cf
 		} else {
f656cf
 			dbgprintf("omelasticsearch: program error, non-handled "
f656cf
 			  "param '%s'\n", actpblk.descr[i].name);
f656cf
-- 
f656cf
2.14.3
f656cf