diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2008-05-16 18:26:25 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2008-05-16 18:26:25 +0200 |
commit | 6ea98ec5fff21c362e28a0121b78b8e6bb3b2528 (patch) | |
tree | 3b4f434a5b8329acd82ef77d3d5d0144218b9e79 /runtime | |
parent | 29ebd4ab3e391aea53b6e337061d226359aeb993 (diff) | |
download | rsyslog-6ea98ec5fff21c362e28a0121b78b8e6bb3b2528.tar.gz rsyslog-6ea98ec5fff21c362e28a0121b78b8e6bb3b2528.tar.xz rsyslog-6ea98ec5fff21c362e28a0121b78b8e6bb3b2528.zip |
added first rough ability to authenticate the server against its certificate
This is very experimental and needs some more work. It probably even
segfaults - but the base code is there and running. The rest is
refinement.
While working on this, I did these two bugfixes:
- bugfix: small mem leak in omfwd on exit (strmdriver name was not freed)
- bugfix: $ActionSendStreamDriver had no effect
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/netstrm.c | 32 | ||||
-rw-r--r-- | runtime/netstrm.h | 4 | ||||
-rw-r--r-- | runtime/nsd.h | 4 | ||||
-rw-r--r-- | runtime/nsd_gtls.c | 73 | ||||
-rw-r--r-- | runtime/nsd_gtls.h | 6 | ||||
-rw-r--r-- | runtime/rsyslog.h | 3 |
6 files changed, 117 insertions, 5 deletions
diff --git a/runtime/netstrm.c b/runtime/netstrm.c index a1384a28..899cb3bf 100644 --- a/runtime/netstrm.c +++ b/runtime/netstrm.c @@ -172,6 +172,10 @@ Rcv(netstrm_t *pThis, uchar *pBuf, ssize_t *pLenBuf) RETiRet; } +/* here follows a number of methods that shuffle authentication settings down + * to the drivers. Drivers not supporting these settings may return an error + * state. + * -------------------------------------------------------------------------- */ /* set the driver mode * rgerhards, 2008-04-28 @@ -186,6 +190,32 @@ SetDrvrMode(netstrm_t *pThis, int iMode) } +/* set the driver authentication mode -- rgerhards, 2008-05-16 + */ +static rsRetVal +SetDrvrAuthMode(netstrm_t *pThis, uchar *mode) +{ + DEFiRet; + ISOBJ_TYPE_assert(pThis, netstrm); + iRet = pThis->Drvr.SetAuthMode(pThis->pDrvrData, mode); + RETiRet; +} + + +/* add an accepted fingerprint -- rgerhards, 2008-05-16 + */ +static rsRetVal +AddDrvrPermittedFingerprint(netstrm_t *pThis, uchar *fingerprint) +{ + DEFiRet; + ISOBJ_TYPE_assert(pThis, netstrm); + iRet = pThis->Drvr.AddPermFingerprint(pThis->pDrvrData, fingerprint); + RETiRet; +} + +/* End of methods to shuffle autentication settings to the driver. + * -------------------------------------------------------------------------- */ + /* send a buffer. On entry, pLenBuf contains the number of octets to * write. On exit, it contains the number of octets actually written. * If this number is lower than on entry, only a partial buffer has @@ -280,6 +310,8 @@ CODESTARTobjQueryInterface(netstrm) pIf->GetRemoteHName = GetRemoteHName; pIf->GetRemoteIP = GetRemoteIP; pIf->SetDrvrMode = SetDrvrMode; + pIf->SetDrvrAuthMode = SetDrvrAuthMode; + pIf->AddDrvrPermittedFingerprint = AddDrvrPermittedFingerprint; pIf->GetSock = GetSock; finalize_it: ENDobjQueryInterface(netstrm) diff --git a/runtime/netstrm.h b/runtime/netstrm.h index a15c1d9b..ffdb392e 100644 --- a/runtime/netstrm.h +++ b/runtime/netstrm.h @@ -50,6 +50,8 @@ BEGINinterface(netstrm) /* name must also be changed in ENDinterface macro! */ rsRetVal (*GetRemoteHName)(netstrm_t *pThis, uchar **pszName); rsRetVal (*GetRemoteIP)(netstrm_t *pThis, uchar **pszIP); rsRetVal (*SetDrvrMode)(netstrm_t *pThis, int iMode); + rsRetVal (*SetDrvrAuthMode)(netstrm_t *pThis, uchar*); + rsRetVal (*AddDrvrPermittedFingerprint)(netstrm_t *pThis, uchar*); /* the GetSock() below is a hack to make imgssapi work. In the long term, * we should migrate imgssapi to a stream driver, which will relieve us of * this problem. Please note that nobody else should use GetSock(). Using it @@ -59,7 +61,7 @@ BEGINinterface(netstrm) /* name must also be changed in ENDinterface macro! */ */ rsRetVal (*GetSock)(netstrm_t *pThis, int *pSock); ENDinterface(netstrm) -#define netstrmCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */ +#define netstrmCURR_IF_VERSION 2 /* increment whenever you change the interface structure! */ /* prototypes */ PROTOTYPEObj(netstrm); diff --git a/runtime/nsd.h b/runtime/nsd.h index cc06c877..1dc9efe9 100644 --- a/runtime/nsd.h +++ b/runtime/nsd.h @@ -51,6 +51,8 @@ BEGINinterface(nsd) /* name must also be changed in ENDinterface macro! */ rsRetVal (*GetRemoteHName)(nsd_t *pThis, uchar **pszName); rsRetVal (*GetRemoteIP)(nsd_t *pThis, uchar **pszIP); rsRetVal (*SetMode)(nsd_t *pThis, int mode); /* sets a driver specific mode - see driver doc for details */ + rsRetVal (*SetAuthMode)(nsd_t *pThis, uchar*); /* sets a driver specific mode - see driver doc for details */ + rsRetVal (*AddPermFingerprint)(nsd_t *pThis, uchar*); /* sets a driver specific mode - see driver doc for details */ rsRetVal (*GetSock)(nsd_t *pThis, int *pSock); rsRetVal (*SetSock)(nsd_t *pThis, int sock); /* GetSock() and SetSock() return an error if the driver does not use plain @@ -58,7 +60,7 @@ BEGINinterface(nsd) /* name must also be changed in ENDinterface macro! */ * those drivers that utilize the nsd_ptcp to do some of their work. */ ENDinterface(nsd) -#define nsdCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */ +#define nsdCURR_IF_VERSION 2 /* increment whenever you change the interface structure! */ /* interface for the select call */ BEGINinterface(nsdsel) /* name must also be changed in ENDinterface macro! */ diff --git a/runtime/nsd_gtls.c b/runtime/nsd_gtls.c index 60685de7..131a3679 100644 --- a/runtime/nsd_gtls.c +++ b/runtime/nsd_gtls.c @@ -225,9 +225,6 @@ finalize_it: static rsRetVal gtlsGlblInitLstn(void) { - int gnuRet; - uchar *keyFile; - uchar *certFile; DEFiRet; if(bGlblSrvrInitDone == 0) { @@ -290,6 +287,14 @@ gtlsChkFingerprint(nsd_gtls_t *pThis) CHKiRet(GenFingerprintStr(fingerprint, size, &pstrFingerprint)); dbgprintf("peer's certificate SHA1 fingerprint: %s\n", rsCStrGetSzStr(pstrFingerprint)); + if(pThis->authMode != GTLS_AUTH_CERTFINGERPRINT) + FINALIZE; + + if(pThis->authIDs == NULL || rsCStrSzStrCmp(pstrFingerprint, pThis->authIDs, strlen((char*) pThis->authIDs))) { + // TODO: logerror + dbgprintf("invalid server fingerprint, not authorized\n"); + ABORT_FINALIZE(RS_RET_INVALID_FINGERPRINT); + } finalize_it: dbgprintf("exit fingerprint check, iRet %d\n", iRet); @@ -397,6 +402,66 @@ finalize_it: } +/* Set the authentication mode. For us, the following is supported: + * anon - no certificate checks whatsoever (discouraged, but supported) + * x509/fingerprint - certificate fingerprint + * x509/name - cerfificate name check + * mode == NULL is valid and defaults to x509/name + * rgerhards, 2008-05-16 + */ +static rsRetVal +SetAuthMode(nsd_t *pNsd, uchar *mode) +{ + DEFiRet; + nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd; + + ISOBJ_TYPE_assert((pThis), nsd_gtls); +RUNLOG_VAR("%s", mode); + if(mode == NULL || !strcasecmp((char*)mode, "x509/name")) { + pThis->authMode = GTLS_AUTH_CERTNAME; + } else if(!strcasecmp((char*) mode, "x509/fingerprint")) { + pThis->authMode = GTLS_AUTH_CERTFINGERPRINT; + } else if(!strcasecmp((char*) mode, "anon")) { + pThis->authMode = GTLS_AUTH_CERTANON; + } else { + // TODO: logerror()? + ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); + } + +/* TODO: clear stored IDs! */ + +finalize_it: +dbgprintf("gtls auth mode %d set\n", pThis->authMode); + RETiRet; +} + + +/* Add a permitted fingerprint. Only useful to call if we are using + * fingerprint authentication. Results in error if we are not in this mode. + * rgerhards, 2008-05-16 + */ +static rsRetVal +AddPermFingerprint(nsd_t *pNsd, uchar *pszFingerprint) +{ + DEFiRet; + nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd; + + ISOBJ_TYPE_assert((pThis), nsd_gtls); + if(pThis->authMode != GTLS_AUTH_CERTFINGERPRINT) + ABORT_FINALIZE(RS_RET_VALUE_NOT_IN_THIS_MODE); + + // TODO: proper handling - but we need to redo this when we do the + // linked list. So for now, this is good enough (but MUST BE CHANGED!). + // + + pThis->authIDs = pszFingerprint; +dbgprintf("gtls fingerprint '%s' set\n", pThis->authIDs); + +finalize_it: + RETiRet; +} + + /* Provide access to the underlying OS socket. This is primarily * useful for other drivers (like nsd_gtls) who utilize ourselfs * for some of their functionality. -- rgerhards, 2008-04-18 @@ -689,6 +754,8 @@ CODESTARTobjQueryInterface(nsd_gtls) pIf->Connect = Connect; pIf->SetSock = SetSock; pIf->SetMode = SetMode; + pIf->SetAuthMode = SetAuthMode; + pIf->AddPermFingerprint = AddPermFingerprint; pIf->GetRemoteHName = GetRemoteHName; pIf->GetRemoteIP = GetRemoteIP; finalize_it: diff --git a/runtime/nsd_gtls.h b/runtime/nsd_gtls.h index bbb0eb9e..885a8b30 100644 --- a/runtime/nsd_gtls.h +++ b/runtime/nsd_gtls.h @@ -38,11 +38,17 @@ struct nsd_gtls_s { BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */ nsd_t *pTcp; /**< our aggregated nsd_ptcp data */ int iMode; /* 0 - plain tcp, 1 - TLS */ + enum { + GTLS_AUTH_CERTNAME = 0, + GTLS_AUTH_CERTFINGERPRINT = 1, + GTLS_AUTH_CERTANON = 2 + } authMode; 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 sess; int bHaveSess; /* as we don't know exactly which gnutls_session values are invalid, we use this one to flag whether or not we are in a session (same as -1 for a socket meaning no sess) */ + uchar *authIDs; /* TODO: make linked list, currently just a single fingerprint, must also support names */ }; /* interface is defined in nsd.h, we just implement it! */ diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h index 367a239f..088a14db 100644 --- a/runtime/rsyslog.h +++ b/runtime/rsyslog.h @@ -224,6 +224,9 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth RS_RET_TLS_HANDSHAKE_ERR = -2083, /**< TLS handshake failed */ RS_RET_TLS_CERT_ERR = -2084, /**< generic TLS certificate error */ RS_RET_TLS_NO_CERT = -2085, /**< no TLS certificate available where one was expected */ + RS_RET_VALUE_NOT_SUPPORTED = -2086, /**< a provided value is not supported */ + RS_RET_VALUE_NOT_IN_THIS_MODE = -2087, /**< a provided value is invalid for the curret mode */ + RS_RET_INVALID_FINGERPRINT = -2088, /**< a fingerprint is not valid for this use case */ /* RainerScript error messages (range 1000.. 1999) */ RS_RET_SYSVAR_NOT_FOUND = 1001, /**< system variable could not be found (maybe misspelled) */ |