rsyslog/SOURCES/rsyslog-8.37.0-rhbz1733244-...

619 lines
26 KiB
Diff

From b15e6ab7242b25311a9e0dcf14187d21a80a44a6 Mon Sep 17 00:00:00 2001
From: Jiri Vymazal <jvymazal@redhat.com>
Date: Fri, 16 Aug 2019 15:01:11 +0200
Subject: [PATCH] Stricter GnuTLS operation
This commit adds to new flags which can be set to allow
1) checking of extendedKeyUsage certificate field
2) stricter checking of certificate name/adresses
---
plugins/imtcp/imtcp.c | 12 +++++++
runtime/netstrm.c | 22 +++++++++++++
runtime/netstrm.h | 5 ++-
runtime/netstrms.c | 47 +++++++++++++++++++++++++++
runtime/netstrms.h | 6 ++++
runtime/nsd.h | 7 ++--
runtime/nsd_gtls.c | 74 ++++++++++++++++++++++++++++++++++++++++---
runtime/nsd_gtls.h | 12 +++++++
runtime/nsd_ossl.c | 36 +++++++++++++++++++++
runtime/nsd_ptcp.c | 35 ++++++++++++++++++++
runtime/tcpsrv.c | 24 ++++++++++++++
runtime/tcpsrv.h | 7 +++-
tools/omfwd.c | 12 +++++++
13 files changed, 291 insertions(+), 8 deletions(-)
diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c
index 55245842d5..6b3401f8fe 100644
--- a/plugins/imtcp/imtcp.c
+++ b/plugins/imtcp/imtcp.c
@@ -131,6 +131,8 @@ struct modConfData_s {
int iTCPSessMax; /* max number of sessions */
int iTCPLstnMax; /* max number of sessions */
int iStrmDrvrMode; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */
+ int iStrmDrvrExtendedCertCheck; /* verify also purpose OID in certificate extended field */
+ int iStrmDrvrSANPreference; /* ignore CN when any SAN set */
int iAddtlFrameDelim; /* addtl frame delimiter, e.g. for netscreen, default none */
int maxFrameSize;
int bSuppOctetFram;
@@ -170,6 +172,8 @@ static struct cnfparamdescr modpdescr[] = {
{ "streamdriver.mode", eCmdHdlrNonNegInt, 0 },
{ "streamdriver.authmode", eCmdHdlrString, 0 },
{ "streamdriver.name", eCmdHdlrString, 0 },
+ { "streamdriver.CheckExtendedKeyPurpose", eCmdHdlrBinary, 0 },
+ { "streamdriver.PrioritizeSAN", eCmdHdlrBinary, 0 },
{ "permittedpeer", eCmdHdlrArray, 0 },
{ "keepalive", eCmdHdlrBinary, 0 },
{ "keepalive.probes", eCmdHdlrPositiveInt, 0 },
@@ -368,6 +372,8 @@ addListner(modConfData_t *modConf, instanceConf_t *inst)
CHKiRet(tcpsrv.SetSessMax(pOurTcpsrv, modConf->iTCPSessMax));
CHKiRet(tcpsrv.SetLstnMax(pOurTcpsrv, modConf->iTCPLstnMax));
CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, modConf->iStrmDrvrMode));
+ CHKiRet(tcpsrv.SetDrvrCheckExtendedKeyUsage(pOurTcpsrv, modConf->iStrmDrvrExtendedCertCheck));
+ CHKiRet(tcpsrv.SetDrvrPrioritizeSAN(pOurTcpsrv, modConf->iStrmDrvrSANPreference));
CHKiRet(tcpsrv.SetUseFlowControl(pOurTcpsrv, modConf->bUseFlowControl));
CHKiRet(tcpsrv.SetAddtlFrameDelim(pOurTcpsrv, modConf->iAddtlFrameDelim));
CHKiRet(tcpsrv.SetMaxFrameSize(pOurTcpsrv, modConf->maxFrameSize));
@@ -479,6 +485,8 @@ CODESTARTbeginCnfLoad
loadModConf->iTCPLstnMax = 20;
loadModConf->bSuppOctetFram = 1;
loadModConf->iStrmDrvrMode = 0;
+ loadModConf->iStrmDrvrExtendedCertCheck = 0;
+ loadModConf->iStrmDrvrSANPreference = 0;
loadModConf->bUseFlowControl = 1;
loadModConf->bKeepAlive = 0;
loadModConf->iKeepAliveIntvl = 0;
@@ -560,6 +568,10 @@ CODESTARTsetModCnf
loadModConf->gnutlsPriorityString = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if(!strcmp(modpblk.descr[i].name, "streamdriver.mode")) {
loadModConf->iStrmDrvrMode = (int) pvals[i].val.d.n;
+ } else if(!strcmp(modpblk.descr[i].name, "streamdriver.CheckExtendedKeyPurpose")) {
+ loadModConf->iStrmDrvrExtendedCertCheck = (int) pvals[i].val.d.n;
+ } else if(!strcmp(modpblk.descr[i].name, "streamdriver.PrioritizeSAN")) {
+ loadModConf->iStrmDrvrSANPreference = (int) pvals[i].val.d.n;
} else if(!strcmp(modpblk.descr[i].name, "streamdriver.authmode")) {
loadModConf->pszStrmDrvrAuthMode = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if(!strcmp(modpblk.descr[i].name, "streamdriver.name")) {
diff --git a/runtime/netstrm.c b/runtime/netstrm.c
index e1df83edee..59aa135997 100644
--- a/runtime/netstrm.c
+++ b/runtime/netstrm.c
@@ -221,6 +221,26 @@ SetDrvrPermPeers(netstrm_t *pThis, permittedPeers_t *pPermPeers)
RETiRet;
}
+/* Mandate also verification of Extended key usage / purpose field */
+static rsRetVal
+SetDrvrCheckExtendedKeyUsage(netstrm_t *pThis, int ChkExtendedKeyUsage)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, netstrm);
+ iRet = pThis->Drvr.SetCheckExtendedKeyUsage(pThis->pDrvrData, ChkExtendedKeyUsage);
+ RETiRet;
+}
+
+/* Mandate stricter name checking per RFC 6125 - ignoce CN if any SAN present */
+static rsRetVal
+SetDrvrPrioritizeSAN(netstrm_t *pThis, int prioritizeSan)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, netstrm);
+ iRet = pThis->Drvr.SetPrioritizeSAN(pThis->pDrvrData, prioritizeSan);
+ RETiRet;
+}
+
/* End of methods to shuffle autentication settings to the driver.
* -------------------------------------------------------------------------- */
@@ -405,6 +425,8 @@ CODESTARTobjQueryInterface(netstrm)
pIf->SetKeepAliveTime = SetKeepAliveTime;
pIf->SetKeepAliveIntvl = SetKeepAliveIntvl;
pIf->SetGnutlsPriorityString = SetGnutlsPriorityString;
+ pIf->SetDrvrCheckExtendedKeyUsage = SetDrvrCheckExtendedKeyUsage;
+ pIf->SetDrvrPrioritizeSAN = SetDrvrPrioritizeSAN;
finalize_it:
ENDobjQueryInterface(netstrm)
diff --git a/runtime/netstrm.h b/runtime/netstrm.h
index 113585d0a5..08b58fd119 100644
--- a/runtime/netstrm.h
+++ b/runtime/netstrm.h
@@ -78,8 +78,11 @@ BEGINinterface(netstrm) /* name must also be changed in ENDinterface macro! */
rsRetVal (*SetKeepAliveTime)(netstrm_t *pThis, int keepAliveTime);
rsRetVal (*SetKeepAliveIntvl)(netstrm_t *pThis, int keepAliveIntvl);
rsRetVal (*SetGnutlsPriorityString)(netstrm_t *pThis, uchar *priorityString);
+ /* v12 -- two new binary flags added to gtls driver enabling stricter operation */
+ rsRetVal (*SetDrvrCheckExtendedKeyUsage)(netstrm_t *pThis, int ChkExtendedKeyUsage);
+ rsRetVal (*SetDrvrPrioritizeSAN)(netstrm_t *pThis, int prioritizeSan);
ENDinterface(netstrm)
-#define netstrmCURR_IF_VERSION 10 /* increment whenever you change the interface structure! */
+#define netstrmCURR_IF_VERSION 12 /* increment whenever you change the interface structure! */
/* interface version 3 added GetRemAddr()
* interface version 4 added EnableKeepAlive() -- rgerhards, 2009-06-02
* interface version 5 changed return of CheckConnection from void to rsRetVal -- alorbach, 2012-09-06
diff --git a/runtime/netstrms.c b/runtime/netstrms.c
index bd6a06bd7f..a8c342b76b 100644
--- a/runtime/netstrms.c
+++ b/runtime/netstrms.c
@@ -279,6 +279,49 @@ GetDrvrMode(netstrms_t *pThis)
}
+/* set the driver cert extended key usage check setting -- jvymazal, 2019-08-16 */
+static rsRetVal
+SetDrvrCheckExtendedKeyUsage(netstrms_t *pThis, int ChkExtendedKeyUsage)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, netstrms);
+ pThis->DrvrChkExtendedKeyUsage = ChkExtendedKeyUsage;
+ RETiRet;
+}
+
+
+/* return the driver cert extended key usage check setting
+ * jvymazal, 2019-08-16
+ */
+static int
+GetDrvrCheckExtendedKeyUsage(netstrms_t *pThis)
+{
+ ISOBJ_TYPE_assert(pThis, netstrms);
+ return pThis->DrvrChkExtendedKeyUsage;
+}
+
+
+/* set the driver name checking policy -- jvymazal, 2019-08-16 */
+static rsRetVal
+SetDrvrPrioritizeSAN(netstrms_t *pThis, int prioritizeSan)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, netstrms);
+ pThis->DrvrPrioritizeSan = prioritizeSan;
+ RETiRet;
+}
+
+
+/* return the driver name checking policy
+ * jvymazal, 2019-08-16
+ */
+static int
+GetDrvrPrioritizeSAN(netstrms_t *pThis)
+{
+ ISOBJ_TYPE_assert(pThis, netstrms);
+ return pThis->DrvrPrioritizeSan;
+}
+
/* create an instance of a netstrm object. It is initialized with default
* values. The current driver is used. The caller may set netstrm properties
* and must call ConstructFinalize().
@@ -337,6 +380,10 @@ CODESTARTobjQueryInterface(netstrms)
pIf->GetDrvrGnutlsPriorityString = GetDrvrGnutlsPriorityString;
pIf->SetDrvrPermPeers = SetDrvrPermPeers;
pIf->GetDrvrPermPeers = GetDrvrPermPeers;
+ pIf->SetDrvrCheckExtendedKeyUsage = SetDrvrCheckExtendedKeyUsage;
+ pIf->GetDrvrCheckExtendedKeyUsage = GetDrvrCheckExtendedKeyUsage;
+ pIf->SetDrvrPrioritizeSAN = SetDrvrPrioritizeSAN;
+ pIf->GetDrvrPrioritizeSAN = GetDrvrPrioritizeSAN;
finalize_it:
ENDobjQueryInterface(netstrms)
diff --git a/runtime/netstrms.h b/runtime/netstrms.h
index 440beb20c9..f21bd6a8e2 100644
--- a/runtime/netstrms.h
+++ b/runtime/netstrms.h
@@ -33,6 +33,8 @@ struct netstrms_s {
uchar *pDrvrName; /**< full base driver name (set when driver is loaded) */
int iDrvrMode; /**< current default driver mode */
uchar *pszDrvrAuthMode; /**< current driver authentication mode */
+ int DrvrChkExtendedKeyUsage; /**< if true, verify extended key usage in certs */
+ int DrvrPrioritizeSan; /**< if true, perform stricter checking of names in certs */
uchar *gnutlsPriorityString; /**< priorityString for connection */
permittedPeers_t *pPermPeers;/**< current driver's permitted peers */
@@ -58,6 +60,10 @@ BEGINinterface(netstrms) /* name must also be changed in ENDinterface macro! */
permittedPeers_t* (*GetDrvrPermPeers)(netstrms_t *pThis);
rsRetVal (*SetDrvrGnutlsPriorityString)(netstrms_t *pThis, uchar*);
uchar* (*GetDrvrGnutlsPriorityString)(netstrms_t *pThis);
+ rsRetVal (*SetDrvrCheckExtendedKeyUsage)(netstrms_t *pThis, int ChkExtendedKeyUsage);
+ int (*GetDrvrCheckExtendedKeyUsage)(netstrms_t *pThis);
+ rsRetVal (*SetDrvrPrioritizeSAN)(netstrms_t *pThis, int prioritizeSan);
+ int (*GetDrvrPrioritizeSAN)(netstrms_t *pThis);
ENDinterface(netstrms)
#define netstrmsCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
diff --git a/runtime/nsd.h b/runtime/nsd.h
index eab53ad6ae..f0cb5bd1aa 100644
--- a/runtime/nsd.h
+++ b/runtime/nsd.h
@@ -85,8 +85,11 @@ BEGINinterface(nsd) /* name must also be changed in ENDinterface macro! */
rsRetVal (*SetKeepAliveProbes)(nsd_t *pThis, int keepAliveProbes);
rsRetVal (*SetKeepAliveTime)(nsd_t *pThis, int keepAliveTime);
rsRetVal (*SetGnutlsPriorityString)(nsd_t *pThis, uchar *gnutlsPriorityString);
+ /* v13 -- two new binary flags added to gtls driver enabling stricter operation */
+ rsRetVal (*SetCheckExtendedKeyUsage)(nsd_t *pThis, int ChkExtendedKeyUsage);
+ rsRetVal (*SetPrioritizeSAN)(nsd_t *pThis, int prioritizeSan);
ENDinterface(nsd)
-#define nsdCURR_IF_VERSION 11 /* increment whenever you change the interface structure! */
+#define nsdCURR_IF_VERSION 13 /* increment whenever you change the interface structure! */
/* interface version 4 added GetRemAddr()
* interface version 5 added EnableKeepAlive() -- rgerhards, 2009-06-02
* interface version 6 changed return of CheckConnection from void to rsRetVal -- alorbach, 2012-09-06
diff --git a/runtime/nsd_gtls.c b/runtime/nsd_gtls.c
index 56238b9cb4..a3662bedf4 100644
--- a/runtime/nsd_gtls.c
+++ b/runtime/nsd_gtls.c
@@ -1004,6 +1004,7 @@ gtlsChkPeerName(nsd_gtls_t *pThis, gnutls_x509_crt_t *pCert)
int iAltName;
size_t szAltNameLen;
int bFoundPositiveMatch;
+ int bHaveSAN = 0;
cstr_t *pStr = NULL;
cstr_t *pstrCN = NULL;
int gnuRet;
@@ -1023,6 +1024,7 @@ gtlsChkPeerName(nsd_gtls_t *pThis, gnutls_x509_crt_t *pCert)
if(gnuRet < 0)
break;
else if(gnuRet == GNUTLS_SAN_DNSNAME) {
+ bHaveSAN = 1;
dbgprintf("subject alt dnsName: '%s'\n", szAltName);
snprintf((char*)lnBuf, sizeof(lnBuf), "DNSname: %s; ", szAltName);
CHKiRet(rsCStrAppendStr(pStr, lnBuf));
@@ -1032,8 +1034,8 @@ gtlsChkPeerName(nsd_gtls_t *pThis, gnutls_x509_crt_t *pCert)
++iAltName;
}
- if(!bFoundPositiveMatch) {
- /* if we did not succeed so far, we try the CN part of the DN... */
+ /* Check also CN only if not configured per stricter RFC 6125 or no SAN present*/
+ if(!bFoundPositiveMatch && (!pThis->bSANpriority || !bHaveSAN)) {
CHKiRet(gtlsGetCN(pCert, &pstrCN));
if(pstrCN != NULL) { /* NULL if there was no CN present */
dbgprintf("gtls now checking auth for CN '%s'\n", cstrGetSzStrNoNULL(pstrCN));
@@ -1044,7 +1044,19 @@ gtlsChkPeerCertValidity(nsd_gtls_t *pThis)
ABORT_FINALIZE(RS_RET_TLS_NO_CERT);
}
- CHKgnutls(gnutls_certificate_verify_peers2(pThis->sess, &stateCert));
+ if (pThis->dataTypeCheck == GTLS_NONE) {
+ CHKgnutls(gnutls_certificate_verify_peers2(pThis->sess, &stateCert));
+ } else { /* we have configured data to check in addition to cert */
+ gnutls_typed_vdata_st data;
+ data.type = GNUTLS_DT_KEY_PURPOSE_OID;
+ if (pThis->bIsInitiator) { /* client mode */
+ data.data = (uchar *)GNUTLS_KP_TLS_WWW_SERVER;
+ } else { /* server mode */
+ data.data = (uchar *)GNUTLS_KP_TLS_WWW_CLIENT;
+ }
+ data.size = ustrlen(data.data);
+ CHKgnutls(gnutls_certificate_verify_peers(pThis->sess, &data, 1, &stateCert));
+ }
if(stateCert & GNUTLS_CERT_INVALID) {
/* provide error details if we have them */
@@ -1188,6 +1205,8 @@ gtlsChkPeerCertValidity(nsd_gtls_t *pThis)
pszErrCause = "insecure algorithm";
} else if(stateCert & GNUTLS_CERT_REVOKED) {
pszErrCause = "certificate revoked";
+ } else if(stateCert & GNUTLS_CERT_PURPOSE_MISMATCH) {
+ pszErrCause = "key purpose OID does not match";
} else {
pszErrCause = "GnuTLS returned no specific reason";
dbgprintf("GnuTLS returned no specific reason for GNUTLS_CERT_INVALID, certificate "
@@ -1499,6 +1516,53 @@ SetGnutlsPriorityString(nsd_t *pNsd, uchar *gnutlsPriorityString)
RETiRet;
}
+/* Set the driver cert extended key usage check setting
+ * 0 - ignore contents of extended key usage
+ * 1 - verify that cert contents is compatible with appropriate OID
+ * jvymazal, 2019-08-16
+ */
+static rsRetVal
+SetCheckExtendedKeyUsage(nsd_t *pNsd, int ChkExtendedKeyUsage)
+{
+ DEFiRet;
+ nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
+
+ ISOBJ_TYPE_assert((pThis), nsd_gtls);
+ if(ChkExtendedKeyUsage != 0 && ChkExtendedKeyUsage != 1) {
+ LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver ChkExtendedKeyUsage %d "
+ "not supported by gtls netstream driver", ChkExtendedKeyUsage);
+ ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED);
+ }
+
+ pThis->dataTypeCheck = ChkExtendedKeyUsage;
+
+finalize_it:
+ RETiRet;
+}
+
+/* Set the driver name checking strictness
+ * 0 - less strict per RFC 5280, section 4.1.2.6 - either SAN or CN match is good
+ * 1 - more strict per RFC 6125 - if any SAN present it must match (CN is ignored)
+ * jvymazal, 2019-08-16
+ */
+static rsRetVal
+SetPrioritizeSAN(nsd_t *pNsd, int prioritizeSan)
+{
+ DEFiRet;
+ nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
+
+ ISOBJ_TYPE_assert((pThis), nsd_gtls);
+ if(prioritizeSan != 0 && prioritizeSan != 1) {
+ LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver prioritizeSan %d "
+ "not supported by gtls netstream driver", prioritizeSan);
+ ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED);
+ }
+
+ pThis->bSANpriority = prioritizeSan;
+
+finalize_it:
+ RETiRet;
+}
/* Provide access to the underlying OS socket. This is primarily
* useful for other drivers (like nsd_gtls) who utilize ourselfs
@@ -2124,6 +2188,8 @@ CODESTARTobjQueryInterface(nsd_gtls)
pIf->SetKeepAliveProbes = SetKeepAliveProbes;
pIf->SetKeepAliveTime = SetKeepAliveTime;
pIf->SetGnutlsPriorityString = SetGnutlsPriorityString;
+ pIf->SetCheckExtendedKeyUsage = SetCheckExtendedKeyUsage;
+ pIf->SetPrioritizeSAN = SetPrioritizeSAN;
finalize_it:
ENDobjQueryInterface(nsd_gtls)
diff --git a/runtime/nsd_gtls.h b/runtime/nsd_gtls.h
index 80a86f21d7..d73c0e6a4d 100644
--- a/runtime/nsd_gtls.h
+++ b/runtime/nsd_gtls.h
@@ -54,6 +54,11 @@ struct nsd_gtls_s {
GTLS_AUTH_CERTVALID = 2,
GTLS_AUTH_CERTANON = 3
} authMode;
+ enum {
+ GTLS_NONE = 0,
+ GTLS_PURPOSE = 1
+ } dataTypeCheck;
+ int bSANpriority; /* if true, we do stricter checking (if any SAN present we do not cehck CN) */
gtlsRtryCall_t rtryCall;/**< what must we retry? */
int bIsInitiator; /**< 0 if socket is the server end (listener), 1 if it is the initiator */
gnutls_session_t sess;
diff --git a/runtime/nsd_ossl.c b/runtime/nsd_ossl.c
index 0a474fd744..419e0e97ef 100644
--- a/runtime/nsd_ossl.c
+++ b/runtime/nsd_ossl.c
@@ -1864,6 +1864,40 @@ SetGnutlsPriorityString(__attribute__((unused)) nsd_t *pNsd, __attribute__((unus
RETiRet;
}
+/* Set the driver cert extended key usage check setting, for now it is empty wrapper.
+ * TODO: implement openSSL version
+ * jvymazal, 2019-08-16
+ */
+static rsRetVal
+SetCheckExtendedKeyUsage(nsd_t __attribute__((unused)) *pNsd, int ChkExtendedKeyUsage)
+{
+ DEFiRet;
+ if(ChkExtendedKeyUsage != 0) {
+ LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver ChkExtendedKeyUsage %d "
+ "not supported by ossl netstream driver", ChkExtendedKeyUsage);
+ ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED);
+ }
+finalize_it:
+ RETiRet;
+}
+
+/* Set the driver name checking strictness, for now it is empty wrapper.
+ * TODO: implement openSSL version
+ * jvymazal, 2019-08-16
+ */
+static rsRetVal
+SetPrioritizeSAN(nsd_t __attribute__((unused)) *pNsd, int prioritizeSan)
+{
+ DEFiRet;
+ if(prioritizeSan != 0) {
+ LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver prioritizeSan %d "
+ "not supported by ossl netstream driver", prioritizeSan);
+ ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED);
+ }
+finalize_it:
+ RETiRet;
+}
+
/* queryInterface function */
BEGINobjQueryInterface(nsd_ossl)
CODESTARTobjQueryInterface(nsd_ossl)
@@ -1898,6 +1932,8 @@ CODESTARTobjQueryInterface(nsd_ossl)
pIf->SetKeepAliveProbes = SetKeepAliveProbes;
pIf->SetKeepAliveTime = SetKeepAliveTime;
pIf->SetGnutlsPriorityString = SetGnutlsPriorityString; /* we don't NEED this interface! */
+ pIf->SetCheckExtendedKeyUsage = SetCheckExtendedKeyUsage; /* we don't NEED this interface! */
+ pIf->SetPrioritizeSAN = SetPrioritizeSAN; /* we don't NEED this interface! */
finalize_it:
ENDobjQueryInterface(nsd_ossl)
diff --git a/runtime/nsd_ptcp.c b/runtime/nsd_ptcp.c
index 68bed5b9ea..60c40ad444 100644
--- a/runtime/nsd_ptcp.c
+++ b/runtime/nsd_ptcp.c
@@ -150,6 +150,37 @@ SetMode(nsd_t __attribute__((unused)) *pNsd, int mode)
RETiRet;
}
+/* Set the driver cert extended key usage check setting, not supported in ptcp.
+ * jvymazal, 2019-08-16
+ */
+static rsRetVal
+SetCheckExtendedKeyUsage(nsd_t __attribute__((unused)) *pNsd, int ChkExtendedKeyUsage)
+{
+ DEFiRet;
+ if(ChkExtendedKeyUsage != 0) {
+ LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver ChkExtendedKeyUsage %d "
+ "not supported by ptcp netstream driver", ChkExtendedKeyUsage);
+ ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED);
+ }
+finalize_it:
+ RETiRet;
+}
+
+/* Set the driver name checking strictness, not supported in ptcp.
+ * jvymazal, 2019-08-16
+ */
+static rsRetVal
+SetPrioritizeSAN(nsd_t __attribute__((unused)) *pNsd, int prioritizeSan)
+{
+ DEFiRet;
+ if(prioritizeSan != 0) {
+ LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver prioritizeSan %d "
+ "not supported by ptcp netstream driver", prioritizeSan);
+ ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED);
+ }
+finalize_it:
+ RETiRet;
+}
/* Set the authentication mode. For us, the following is supported:
* anon - no certificate checks whatsoever (discouraged, but supported)
@@ -613,6 +644,8 @@ LstnInit(netstrms_t *pNS, void *pUsr, rsRetVal(*fAddLstn)(void*,netstrm_t*),
CHKiRet(pNS->Drvr.Construct(&pNewNsd));
CHKiRet(pNS->Drvr.SetSock(pNewNsd, sock));
CHKiRet(pNS->Drvr.SetMode(pNewNsd, netstrms.GetDrvrMode(pNS)));
+ CHKiRet(pNS->Drvr.SetCheckExtendedKeyUsage(pNewNsd, netstrms.GetDrvrCheckExtendedKeyUsage(pNS)));
+ CHKiRet(pNS->Drvr.SetPrioritizeSAN(pNewNsd, netstrms.GetDrvrPrioritizeSAN(pNS)));
CHKiRet(pNS->Drvr.SetAuthMode(pNewNsd, netstrms.GetDrvrAuthMode(pNS)));
CHKiRet(pNS->Drvr.SetPermPeers(pNewNsd, netstrms.GetDrvrPermPeers(pNS)));
CHKiRet(pNS->Drvr.SetGnutlsPriorityString(pNewNsd, netstrms.GetDrvrGnutlsPriorityString(pNS)));
@@ -963,6 +996,8 @@ CODESTARTobjQueryInterface(nsd_ptcp)
pIf->SetKeepAliveIntvl = SetKeepAliveIntvl;
pIf->SetKeepAliveProbes = SetKeepAliveProbes;
pIf->SetKeepAliveTime = SetKeepAliveTime;
+ pIf->SetCheckExtendedKeyUsage = SetCheckExtendedKeyUsage;
+ pIf->SetPrioritizeSAN = SetPrioritizeSAN;
finalize_it:
ENDobjQueryInterface(nsd_ptcp)
diff --git a/runtime/tcpsrv.c b/runtime/tcpsrv.c
index d7ea2f9f00..43a6687b4a 100644
--- a/runtime/tcpsrv.c
+++ b/runtime/tcpsrv.c
@@ -1013,6 +1013,8 @@ tcpsrvConstructFinalize(tcpsrv_t *pThis)
if(pThis->pszDrvrName != NULL)
CHKiRet(netstrms.SetDrvrName(pThis->pNS, pThis->pszDrvrName));
CHKiRet(netstrms.SetDrvrMode(pThis->pNS, pThis->iDrvrMode));
+ CHKiRet(netstrms.SetDrvrCheckExtendedKeyUsage(pThis->pNS, pThis->DrvrChkExtendedKeyUsage));
+ CHKiRet(netstrms.SetDrvrPrioritizeSAN(pThis->pNS, pThis->DrvrPrioritizeSan));
if(pThis->pszDrvrAuthMode != NULL)
CHKiRet(netstrms.SetDrvrAuthMode(pThis->pNS, pThis->pszDrvrAuthMode));
if(pThis->pPermPeers != NULL)
@@ -1405,6 +1407,26 @@ SetDrvrPermPeers(tcpsrv_t *pThis, permittedPeers_t *pPermPeers)
RETiRet;
}
+/* set the driver cert extended key usage check setting -- jvymazal, 2019-08-16 */
+static rsRetVal
+SetDrvrCheckExtendedKeyUsage(tcpsrv_t *pThis, int ChkExtendedKeyUsage)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, tcpsrv);
+ pThis->DrvrChkExtendedKeyUsage = ChkExtendedKeyUsage;
+ RETiRet;
+}
+
+/* set the driver name checking policy -- jvymazal, 2019-08-16 */
+static rsRetVal
+SetDrvrPrioritizeSAN(tcpsrv_t *pThis, int prioritizeSan)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, tcpsrv);
+ pThis->DrvrPrioritizeSan = prioritizeSan;
+ RETiRet;
+}
+
/* End of methods to shuffle autentication settings to the driver.;
@@ -1522,6 +1544,8 @@ CODESTARTobjQueryInterface(tcpsrv)
pIf->SetLinuxLikeRatelimiters = SetLinuxLikeRatelimiters;
pIf->SetNotificationOnRemoteClose = SetNotificationOnRemoteClose;
pIf->SetPreserveCase = SetPreserveCase;
+ pIf->SetDrvrCheckExtendedKeyUsage = SetDrvrCheckExtendedKeyUsage;
+ pIf->SetDrvrPrioritizeSAN = SetDrvrPrioritizeSAN;
finalize_it:
ENDobjQueryInterface(tcpsrv)
diff --git a/runtime/tcpsrv.h b/runtime/tcpsrv.h
index 55aa8e9922..79b659013d 100644
--- a/runtime/tcpsrv.h
+++ b/runtime/tcpsrv.h
@@ -61,6 +61,8 @@ struct tcpsrv_s {
int iKeepAliveTime; /**< socket layer KEEPALIVE timeout */
netstrms_t *pNS; /**< pointer to network stream subsystem */
int iDrvrMode; /**< mode of the stream driver to use */
+ int DrvrChkExtendedKeyUsage; /**< if true, verify extended key usage in certs */
+ int DrvrPrioritizeSan; /**< if true, perform stricter checking of names in certs */
uchar *gnutlsPriorityString; /**< priority string for gnutls */
uchar *pszDrvrAuthMode; /**< auth mode of the stream driver to use */
uchar *pszDrvrName; /**< name of stream driver to use */
@@ -185,8 +187,11 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */
rsRetVal (*SetGnutlsPriorityString)(tcpsrv_t*, uchar*);
/* added v21 -- Preserve case in fromhost, 2018-08-16 */
rsRetVal (*SetPreserveCase)(tcpsrv_t *pThis, int bPreserveCase);
+ /* added v23 -- Options for stricter driver behavior, 2019-08-16 */
+ rsRetVal (*SetDrvrCheckExtendedKeyUsage)(tcpsrv_t *pThis, int ChkExtendedKeyUsage);
+ rsRetVal (*SetDrvrPrioritizeSAN)(tcpsrv_t *pThis, int prioritizeSan);
ENDinterface(tcpsrv)
-#define tcpsrvCURR_IF_VERSION 21 /* increment whenever you change the interface structure! */
+#define tcpsrvCURR_IF_VERSION 23 /* increment whenever you change the interface structure! */
/* change for v4:
* - SetAddtlFrameDelim() added -- rgerhards, 2008-12-10
* - SetInputName() added -- rgerhards, 2008-12-10
diff --git a/tools/omfwd.c b/tools/omfwd.c
index cdb74b8d22..96fa68752c 100644
--- a/tools/omfwd.c
+++ b/tools/omfwd.c
@@ -83,6 +83,8 @@ typedef struct _instanceData {
uchar *pszStrmDrvrAuthMode;
permittedPeers_t *pPermPeers;
int iStrmDrvrMode;
+ int iStrmDrvrExtendedCertCheck; /* verify also purpose OID in certificate extended field */
+ int iStrmDrvrSANPreference; /* ignore CN when any SAN set */
char *target;
char *address;
char *device;
@@ -189,6 +191,8 @@ static struct cnfparamdescr actpdescr[] = {
{ "streamdrivermode", eCmdHdlrInt, 0 },
{ "streamdriverauthmode", eCmdHdlrGetWord, 0 },
{ "streamdriverpermittedpeers", eCmdHdlrGetWord, 0 },
+ { "streamdriver.CheckExtendedKeyPurpose", eCmdHdlrBinary, 0 },
+ { "streamdriver.PrioritizeSAN", eCmdHdlrBinary, 0 },
{ "resendlastmsgonreconnect", eCmdHdlrBinary, 0 },
{ "udp.sendtoall", eCmdHdlrBinary, 0 },
{ "udp.senddelay", eCmdHdlrInt, 0 },
@@ -748,6 +752,8 @@ static rsRetVal TCPSendInit(void *pvData)
CHKiRet(netstrms.CreateStrm(pWrkrData->pNS, &pWrkrData->pNetstrm));
CHKiRet(netstrm.ConstructFinalize(pWrkrData->pNetstrm));
CHKiRet(netstrm.SetDrvrMode(pWrkrData->pNetstrm, pData->iStrmDrvrMode));
+ CHKiRet(netstrm.SetDrvrCheckExtendedKeyUsage(pWrkrData->pNetstrm, pData->iStrmDrvrExtendedCertCheck));
+ CHKiRet(netstrm.SetDrvrPrioritizeSAN(pWrkrData->pNetstrm, pData->iStrmDrvrSANPreference));
/* now set optional params, but only if they were actually configured */
if(pData->pszStrmDrvrAuthMode != NULL) {
CHKiRet(netstrm.SetDrvrAuthMode(pWrkrData->pNetstrm, pData->pszStrmDrvrAuthMode));
@@ -1119,6 +1125,8 @@ setInstParamDefaults(instanceData *pData)
pData->pszStrmDrvr = NULL;
pData->pszStrmDrvrAuthMode = NULL;
pData->iStrmDrvrMode = 0;
+ pData->iStrmDrvrExtendedCertCheck = 0;
+ pData->iStrmDrvrSANPreference = 0;
pData->iRebindInterval = 0;
pData->bKeepAlive = 0;
pData->iKeepAliveProbes = 0;
@@ -1220,6 +1228,10 @@ CODESTARTnewActInst
pData->pszStrmDrvr = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if(!strcmp(actpblk.descr[i].name, "streamdrivermode")) {
pData->iStrmDrvrMode = pvals[i].val.d.n;
+ } else if(!strcmp(actpblk.descr[i].name, "streamdriver.CheckExtendedKeyPurpose")) {
+ pData->iStrmDrvrExtendedCertCheck = pvals[i].val.d.n;
+ } else if(!strcmp(actpblk.descr[i].name, "streamdriver.PrioritizeSAN")) {
+ pData->iStrmDrvrSANPreference = pvals[i].val.d.n;
} else if(!strcmp(actpblk.descr[i].name, "streamdriverauthmode")) {
pData->pszStrmDrvrAuthMode = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if(!strcmp(actpblk.descr[i].name, "streamdriverpermittedpeers")) {