diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2008-05-26 11:01:42 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2008-05-26 11:01:42 +0200 |
commit | 7b604269c725eaa6120ddbece6a1ec0b67d9cf82 (patch) | |
tree | 1e2416798213053f67f1ea4c4b18117ed7f628db /runtime | |
parent | f31a0537c649b0ecf40986e5dc8fea6386e6bcb0 (diff) | |
download | rsyslog-7b604269c725eaa6120ddbece6a1ec0b67d9cf82.tar.gz rsyslog-7b604269c725eaa6120ddbece6a1ec0b67d9cf82.tar.xz rsyslog-7b604269c725eaa6120ddbece6a1ec0b67d9cf82.zip |
added capability to auto-configure tls auth rule for client connecting to server
must match hostname in send action
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/nsd_gtls.c | 64 | ||||
-rw-r--r-- | runtime/nsd_gtls.h | 1 |
2 files changed, 52 insertions, 13 deletions
diff --git a/runtime/nsd_gtls.c b/runtime/nsd_gtls.c index 54fbecd2..fab400fc 100644 --- a/runtime/nsd_gtls.c +++ b/runtime/nsd_gtls.c @@ -504,6 +504,45 @@ finalize_it: } +/* Perform a match on ONE peer name obtained from the certificate. This name + * is checked against the set of configured credentials. *pbFoundPositiveMatch is + * set to 1 if the ID matches. *pbFoundPositiveMatch must have been initialized + * to 0 by the caller (this is a performance enhancement as we expect to be + * called multiple times) + * rgerhards, 2008-05-26 + */ +static rsRetVal +gtlsChkOnePeerName(nsd_gtls_t *pThis, uchar *pszPeerID, int *pbFoundPositiveMatch) +{ + permittedPeers_t *pPeer; + DEFiRet; + + ISOBJ_TYPE_assert(pThis, nsd_gtls); + assert(pszPeerID != NULL); + assert(pbFoundPositiveMatch != NULL); + + if(pThis->pPermPeers) { /* do we have configured peer IDs? */ + pPeer = pThis->pPermPeers; + while(pPeer != NULL && !*pbFoundPositiveMatch) { + if(!strcmp((char*)pszPeerID, (char*)pPeer->pszID)) { + *pbFoundPositiveMatch = 1; + } else { + pPeer = pPeer->pNext; + } + } + } else { + /* we do not have configured peer IDs, so we use defaults */ +RUNLOG_VAR("%s", pThis->pszConnectHost); + if( pThis->pszConnectHost + && !strcmp((char*)pszPeerID, (char*)pThis->pszConnectHost)) { + *pbFoundPositiveMatch = 1; + } + } + + RETiRet; +} + + /* Check the peer's ID in name auth mode. * rgerhards, 2008-05-22 */ @@ -515,7 +554,6 @@ gtlsChkPeerName(nsd_gtls_t *pThis, gnutls_x509_crt *pCert) int iAltName; size_t szAltNameLen; int bFoundPositiveMatch; - permittedPeers_t *pPeer; cstr_t *pStr = NULL; int gnuRet; DEFiRet; @@ -537,18 +575,7 @@ gtlsChkPeerName(nsd_gtls_t *pThis, gnutls_x509_crt *pCert) dbgprintf("subject alt dnsName: '%s'\n", szAltName); snprintf((char*)lnBuf, sizeof(lnBuf), "DNSname: %s; ", szAltName); CHKiRet(rsCStrAppendStr(pStr, lnBuf)); - /* we found it - now we need to loop through the list of permitted - * peer IDs. As soon as we have a positive match, we are all set. - */ - pPeer = pThis->pPermPeers; - while(pPeer != NULL && !bFoundPositiveMatch) { -RUNLOG_VAR("%s", pPeer->pszID); - if(!strcmp(szAltName, (char*)pPeer->pszID)) { - bFoundPositiveMatch = 1; - } else { - pPeer = pPeer->pNext; - } - } + CHKiRet(gtlsChkOnePeerName(pThis, (uchar*)szAltName, &bFoundPositiveMatch)); /* do NOT break, because there may be multiple dNSName's! */ } ++iAltName; @@ -647,6 +674,7 @@ gtlsChkPeerCertValidity(nsd_gtls_t *pThis) ISOBJ_TYPE_assert(pThis, nsd_gtls); gnuRet = gnutls_certificate_verify_peers(pThis->sess); if(gnuRet == GNUTLS_E_NO_CERTIFICATE_FOUND) { + errno = 0; errmsg.LogError(NO_ERRCODE, "peer did not provide a certificate, not permitted to talk to it"); ABORT_FINALIZE(RS_RET_TLS_NO_CERT); } else if(gnuRet < 1) @@ -781,6 +809,10 @@ CODESTARTobjDestruct(nsd_gtls) if(pThis->pTcp != NULL) { nsd_ptcp.Destruct(&pThis->pTcp); } + + if(pThis->pszConnectHost != NULL) { + free(pThis->pszConnectHost); + } ENDobjDestruct(nsd_gtls) @@ -1131,6 +1163,12 @@ Connect(nsd_t *pNsd, int family, uchar *port, uchar *host) CHKiRet(nsd_ptcp.GetSock(pThis->pTcp, &sock)); gtlsSetTransportPtr(pThis, sock); + /* we need to store the hostname as an alternate mean of authentication if no + * permitted peer names are given. Using the hostname is quite useful. It permits + * auto-configuration of security if a commen root cert is present. -- rgerhards, 2008-05-26 + */ + CHKmalloc(pThis->pszConnectHost = (uchar*)strdup((char*)host)); + /* and perform the handshake */ CHKgnutls(gnutls_handshake(pThis->sess)); dbgprintf("GnuTLS handshake succeeded\n"); diff --git a/runtime/nsd_gtls.h b/runtime/nsd_gtls.h index 59109e68..a88e34fc 100644 --- a/runtime/nsd_gtls.h +++ b/runtime/nsd_gtls.h @@ -37,6 +37,7 @@ typedef nsd_if_t nsd_gtls_if_t; /* we just *implement* this interface */ struct nsd_gtls_s { BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */ nsd_t *pTcp; /**< our aggregated nsd_ptcp data */ + uchar *pszConnectHost; /**< hostname used for connect - may be used to authenticate peer if no other name given */ int iMode; /* 0 - plain tcp, 1 - TLS */ int bAbortConn; /* if set, abort conncection (fatal error had happened) */ enum { |