From 7369904b578322f7fb22897def3cd63b27eacf46 Mon Sep 17 00:00:00 2001
From: Axel Rau
Date: Wed, 1 May 2013 18:45:31 +0200
Subject: Add configurable local client IP
---
plugins/omrelp/omrelp.c | 6 +++++-
runtime/glbl.c | 20 ++++++++++++++++++++
runtime/glbl.h | 2 ++
tools/rsyslogd.8 | 4 ++++
tools/syslogd.c | 10 +++++++++-
5 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/plugins/omrelp/omrelp.c b/plugins/omrelp/omrelp.c
index c9e32444..f2fc87e0 100644
--- a/plugins/omrelp/omrelp.c
+++ b/plugins/omrelp/omrelp.c
@@ -209,7 +209,11 @@ static rsRetVal doConnect(instanceData *pData)
DEFiRet;
if(pData->bInitialConnect) {
- iRet = relpCltConnect(pData->pRelpClt, glbl.GetDefPFFamily(), pData->port, pData->target);
+ if (glbl.GetSourceIPofLocalClient() == NULL) { /* ar Do we have a client IP set? */
+ iRet = relpCltConnect(pData->pRelpClt, glbl.GetDefPFFamily(), pData->port, pData->target);
+ } else { /* ar YES: use it */
+ iRet = relpCltConnect2(pData->pRelpClt, glbl.GetDefPFFamily(), pData->port, pData->target, glbl.GetSourceIPofLocalClient());
+ }
if(iRet == RELP_RET_OK)
pData->bInitialConnect = 0;
} else {
diff --git a/runtime/glbl.c b/runtime/glbl.c
index b3fe3a1d..ccb978ba 100644
--- a/runtime/glbl.c
+++ b/runtime/glbl.c
@@ -89,6 +89,7 @@ static DEF_ATOMIC_HELPER_MUT(mutTerminateInputs);
#ifdef USE_UNLIMITED_SELECT
static int iFdSetSize = howmany(FD_SETSIZE, __NFDBITS) * sizeof (fd_mask); /* size of select() bitmask in bytes */
#endif
+static uchar *SourceIPofLocalClient = NULL; /* [ar] Source IP for local client to be used on multihomed host */
/* tables for interfacing with the v6 config system */
@@ -478,6 +479,23 @@ GetDfltNetstrmDrvrCertFile(void)
}
+/* [ar] Source IP for local client to be used on multihomed host */
+static rsRetVal
+SetSourceIPofLocalClient(uchar *newname)
+{
+ if(SourceIPofLocalClient != NULL) {
+ free(SourceIPofLocalClient); }
+ SourceIPofLocalClient = newname;
+ return RS_RET_OK;
+}
+
+static uchar*
+GetSourceIPofLocalClient(void)
+{
+ return(SourceIPofLocalClient);
+}
+
+
/* queryInterface function
* rgerhards, 2008-02-21
*/
@@ -498,6 +516,8 @@ CODESTARTobjQueryInterface(glbl)
pIf->GetLocalHostIP = GetLocalHostIP;
pIf->SetGlobalInputTermination = SetGlobalInputTermination;
pIf->GetGlobalInputTermState = GetGlobalInputTermState;
+ pIf->GetSourceIPofLocalClient = GetSourceIPofLocalClient; /* [ar] */
+ pIf->SetSourceIPofLocalClient = SetSourceIPofLocalClient; /* [ar] */
#define SIMP_PROP(name) \
pIf->Get##name = Get##name; \
pIf->Set##name = Set##name;
diff --git a/runtime/glbl.h b/runtime/glbl.h
index e95e48f7..413f8225 100644
--- a/runtime/glbl.h
+++ b/runtime/glbl.h
@@ -81,6 +81,8 @@ BEGINinterface(glbl) /* name must also be changed in ENDinterface macro! */
/* next change is v9! */
/* v8 - 2012-03-21 */
prop_t* (*GetLocalHostIP)(void);
+ prop_t* (*GetSourceIPofLocalClient)(void); /* [ar] */
+ prop_t* (*SetSourceIPofLocalClient)(uchar*); /* [ar] */
#undef SIMP_PROP
ENDinterface(glbl)
#define glblCURR_IF_VERSION 7 /* increment whenever you change the interface structure! */
diff --git a/tools/rsyslogd.8 b/tools/rsyslogd.8
index 620006f2..ac732b88 100644
--- a/tools/rsyslogd.8
+++ b/tools/rsyslogd.8
@@ -191,6 +191,10 @@ is specified and the host logging resolves to satu.infodrom.north.de
no domain would be cut, you will have to specify two domains like:
.BR "\-s north.de:infodrom.north.de" .
.TP
+.BI "\-S ip_address" "local client source IP"
+rsyslogd uses ip_address as local client address while connecting
+to remote logserver. Currently used by omrelp only and only with tcp.
+.TP
.BI "\-u " "userlevel"
This is a "catch all" option for some very seldomly-used user settings.
The "userlevel" variable selects multiple things. Add the specific values
diff --git a/tools/syslogd.c b/tools/syslogd.c
index 1b38bf92..47a21585 100644
--- a/tools/syslogd.c
+++ b/tools/syslogd.c
@@ -1773,7 +1773,7 @@ int realMain(int argc, char **argv)
* of other options, we do this during the inital option processing.
* rgerhards, 2008-04-04
*/
- while((ch = getopt(argc, argv, "46a:Ac:dDef:g:hi:l:m:M:nN:op:qQr::s:t:T:u:vwx")) != EOF) {
+ while((ch = getopt(argc, argv, "46a:Ac:dDef:g:hi:l:m:M:nN:op:qQr::s:S:t:T:u:vwx")) != EOF) {
switch((char)ch) {
case '4':
case '6':
@@ -1791,6 +1791,7 @@ int realMain(int argc, char **argv)
case 'q': /* add hostname if DNS resolving has failed */
case 'Q': /* dont resolve hostnames in ACL to IPs */
case 's':
+ case 'S': /* Source IP for local client to be used on multihomed host */
case 'T': /* chroot on startup (primarily for testing) */
case 'u': /* misc user settings */
case 'w': /* disable disallowed host warnings */
@@ -1882,6 +1883,13 @@ int realMain(int argc, char **argv)
case 'a':
fprintf(stderr, "rsyslogd: error -a is no longer supported, use module imuxsock instead");
break;
+ case 'S': /* Source IP for local client to be used on multihomed host */
+ if(glbl.GetSourceIPofLocalClient() != NULL) {
+ fprintf (stderr, "rsyslogd: Only one -S argument allowed, the first one is taken.\n");
+ } else {
+ glbl.SetSourceIPofLocalClient(arg);
+ }
+ break;
case 'f': /* configuration file */
ConfFile = (uchar*) arg;
break;
--
cgit v1.2.3
From 036323e76c547ada6829a76e684bd3a602588ff9 Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Mon, 6 May 2013 17:46:11 +0200
Subject: doc: add Axel Rau's patch to ChangeLog
---
ChangeLog | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index b927d130..9a5c5edc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,9 @@
---------------------------------------------------------------------------
+Version 7.5.0 [devel] 2013-0?-??
+- add -S command line option to specify IP address to use for RELP client
+ connections
+ Thanks to Axel Rau for the patch.
+---------------------------------------------------------------------------
Version 7.3.14 [beta] 2013-05-06
- bugfix: some man pages were not properly installed
either rscryutil or rsgtutil man was installed, but not both
--
cgit v1.2.3
From 40de50a892ffc3fa16c49c8ba91c7a1cd5af1b95 Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Wed, 8 May 2013 09:21:02 +0200
Subject: cosmetic: update .gitignore files
---
grammar/.gitignore | 1 +
1 file changed, 1 insertion(+)
create mode 100644 grammar/.gitignore
diff --git a/grammar/.gitignore b/grammar/.gitignore
new file mode 100644
index 00000000..8bd546bd
--- /dev/null
+++ b/grammar/.gitignore
@@ -0,0 +1 @@
+lexer.c
--
cgit v1.2.3
From 4ae3176e2824607b8016699d3fc3f1f6a8371495 Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Wed, 8 May 2013 11:19:23 +0200
Subject: extend crypto provider interface so that it can support queue
subsystem
---
runtime/cryprov.h | 11 +++++++++--
runtime/lmcry_gcry.c | 50 +++++++++++++++++++++++++++++++++++---------------
tools/omfile.c | 2 +-
3 files changed, 45 insertions(+), 18 deletions(-)
diff --git a/runtime/cryprov.h b/runtime/cryprov.h
index 8496b745..cbb2f45d 100644
--- a/runtime/cryprov.h
+++ b/runtime/cryprov.h
@@ -26,14 +26,21 @@
#include
+/* we unfortunately need to have two different param names depending on the
+ * context in which parameters are set. Other than (re/over)engineering the core
+ * interface, we just define some values to keep track of that.
+ */
+#define CRYPROV_PARAMTYPE_REGULAR 0
+#define CRYPROV_PARAMTYPE_DISK 1
+
/* interface */
BEGINinterface(cryprov) /* name must also be changed in ENDinterface macro! */
rsRetVal (*Construct)(void *ppThis);
- rsRetVal (*SetCnfParam)(void *ppThis, struct nvlst *lst);
+ rsRetVal (*SetCnfParam)(void *ppThis, struct nvlst *lst, int paramType);
rsRetVal (*Destruct)(void *ppThis);
rsRetVal (*OnFileOpen)(void *pThis, uchar *fn, void *pFileInstData);
rsRetVal (*Encrypt)(void *pFileInstData, uchar *buf, size_t *lenBuf);
rsRetVal (*OnFileClose)(void *pFileInstData, off64_t offsLogfile);
ENDinterface(cryprov)
-#define cryprovCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
+#define cryprovCURR_IF_VERSION 2 /* increment whenever you change the interface structure! */
#endif /* #ifndef INCLUDED_CRYPROV_H */
diff --git a/runtime/lmcry_gcry.c b/runtime/lmcry_gcry.c
index 0a9b94bc..31fab0d4 100644
--- a/runtime/lmcry_gcry.c
+++ b/runtime/lmcry_gcry.c
@@ -43,17 +43,30 @@ DEFobjCurrIf(errmsg)
DEFobjCurrIf(glbl)
/* tables for interfacing with the v6 config system */
-static struct cnfparamdescr cnfpdescr[] = {
+static struct cnfparamdescr cnfpdescrRegular[] = {
{ "cry.key", eCmdHdlrGetWord, 0 },
{ "cry.keyfile", eCmdHdlrGetWord, 0 },
{ "cry.keyprogram", eCmdHdlrGetWord, 0 },
{ "cry.mode", eCmdHdlrGetWord, 0 }, /* CBC, ECB, etc */
{ "cry.algo", eCmdHdlrGetWord, 0 }
};
-static struct cnfparamblk pblk =
+static struct cnfparamblk pblkRegular =
{ CNFPARAMBLK_VERSION,
- sizeof(cnfpdescr)/sizeof(struct cnfparamdescr),
- cnfpdescr
+ sizeof(cnfpdescrRegular)/sizeof(struct cnfparamdescr),
+ cnfpdescrRegular
+ };
+
+static struct cnfparamdescr cnfpdescrQueue[] = {
+ { "queue.cry.key", eCmdHdlrGetWord, 0 },
+ { "queue.cry.keyfile", eCmdHdlrGetWord, 0 },
+ { "queue.cry.keyprogram", eCmdHdlrGetWord, 0 },
+ { "queue.cry.mode", eCmdHdlrGetWord, 0 }, /* CBC, ECB, etc */
+ { "queue.cry.algo", eCmdHdlrGetWord, 0 }
+};
+static struct cnfparamblk pblkQueue =
+ { CNFPARAMBLK_VERSION,
+ sizeof(cnfpdescrQueue)/sizeof(struct cnfparamdescr),
+ cnfpdescrQueue
};
@@ -85,7 +98,7 @@ ENDobjDestruct(lmcry_gcry)
* Defaults are expected to have been set during construction.
*/
static rsRetVal
-SetCnfParam(void *pT, struct nvlst *lst)
+SetCnfParam(void *pT, struct nvlst *lst, int paramType)
{
lmcry_gcry_t *pThis = (lmcry_gcry_t*) pT;
int i, r;
@@ -97,34 +110,41 @@ SetCnfParam(void *pT, struct nvlst *lst)
uchar *mode = NULL;
int nKeys; /* number of keys (actually methods) specified */
struct cnfparamvals *pvals;
+ struct cnfparamblk *pblk;
DEFiRet;
+ pblk = (paramType == CRYPROV_PARAMTYPE_REGULAR ) ? &pblkRegular : &pblkQueue;
nKeys = 0;
- pvals = nvlstGetParams(lst, &pblk, NULL);
+ pvals = nvlstGetParams(lst, pblk, NULL);
if(Debug) {
dbgprintf("param blk in lmcry_gcry:\n");
- cnfparamsPrint(&pblk, pvals);
+ cnfparamsPrint(pblk, pvals);
}
- for(i = 0 ; i < pblk.nParams ; ++i) {
+ for(i = 0 ; i < pblk->nParams ; ++i) {
if(!pvals[i].bUsed)
continue;
- if(!strcmp(pblk.descr[i].name, "cry.key")) {
+ if(!strcmp(pblk->descr[i].name, "cry.key") ||
+ !strcmp(pblk->descr[i].name, "queue.cry.key")) {
key = (uchar*) es_str2cstr(pvals[i].val.d.estr, NULL);
++nKeys;
- } else if(!strcmp(pblk.descr[i].name, "cry.keyfile")) {
+ } else if(!strcmp(pblk->descr[i].name, "cry.keyfile") ||
+ !strcmp(pblk->descr[i].name, "queue.cry.keyfile")) {
keyfile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
++nKeys;
- } else if(!strcmp(pblk.descr[i].name, "cry.keyprogram")) {
+ } else if(!strcmp(pblk->descr[i].name, "cry.keyprogram") ||
+ !strcmp(pblk->descr[i].name, "queue.cry.keyprogram")) {
keyprogram = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
++nKeys;
- } else if(!strcmp(pblk.descr[i].name, "cry.mode")) {
+ } else if(!strcmp(pblk->descr[i].name, "cry.mode") ||
+ !strcmp(pblk->descr[i].name, "queue.cry.mode")) {
mode = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
- } else if(!strcmp(pblk.descr[i].name, "cry.algo")) {
+ } else if(!strcmp(pblk->descr[i].name, "cry.algo") ||
+ !strcmp(pblk->descr[i].name, "queue.cry.algo")) {
algo = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
} else {
DBGPRINTF("lmcry_gcry: program error, non-handled "
- "param '%s'\n", pblk.descr[i].name);
+ "param '%s'\n", pblk->descr[i].name);
}
}
if(algo != NULL) {
@@ -177,7 +197,7 @@ SetCnfParam(void *pT, struct nvlst *lst)
ABORT_FINALIZE(RS_RET_INVALID_PARAMS);
}
- cnfparamvalsDestruct(pvals, &pblk);
+ cnfparamvalsDestruct(pvals, pblk);
if(key != NULL) {
memset(key, 0, strlen((char*)key));
free(key);
diff --git a/tools/omfile.c b/tools/omfile.c
index ba9f7f70..1740e8bf 100644
--- a/tools/omfile.c
+++ b/tools/omfile.c
@@ -1089,7 +1089,7 @@ initCryprov(instanceData *pData, struct nvlst *lst)
szDrvrName);
ABORT_FINALIZE(RS_RET_CRYPROV_ERR);
}
- CHKiRet(pData->cryprov.SetCnfParam(pData->cryprovData, lst));
+ CHKiRet(pData->cryprov.SetCnfParam(pData->cryprovData, lst, CRYPROV_PARAMTYPE_REGULAR));
dbgprintf("loaded crypto provider %s, data instance at %p\n",
szDrvrName, pData->cryprovData);
--
cgit v1.2.3
From 415b26d5a19d8b1fd50d8e0b7b29cc8527537316 Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Fri, 10 May 2013 15:39:42 +0200
Subject: enable shuffling of crypto parameters down through queue definition
---
action.c | 15 +++-----
action.h | 4 +-
dirty.h | 2 +-
runtime/queue.c | 107 ++++++++++++++++++++++++++++++++++++++++++++----------
runtime/queue.h | 11 ++++--
runtime/rsyslog.h | 2 +
runtime/ruleset.c | 6 +--
tools/syslogd.c | 8 ++--
8 files changed, 112 insertions(+), 43 deletions(-)
diff --git a/action.c b/action.c
index 259fb666..85766941 100644
--- a/action.c
+++ b/action.c
@@ -357,7 +357,7 @@ finalize_it:
/* action construction finalizer
*/
rsRetVal
-actionConstructFinalize(action_t *pThis, struct cnfparamvals *queueParams)
+actionConstructFinalize(action_t *pThis, struct nvlst *lst)
{
DEFiRet;
uchar pszAName[64]; /* friendly name of our action */
@@ -432,7 +432,7 @@ actionConstructFinalize(action_t *pThis, struct cnfparamvals *queueParams)
obj.SetName((obj_t*) pThis->pQueue, pszAName);
qqueueSetpAction(pThis->pQueue, pThis);
- if(queueParams == NULL) { /* use legacy params? */
+ if(lst == NULL) { /* use legacy params? */
/* ... set some properties ... */
# define setQPROP(func, directive, data) \
CHKiRet_Hdlr(func(pThis->pQueue, data)) { \
@@ -466,7 +466,7 @@ actionConstructFinalize(action_t *pThis, struct cnfparamvals *queueParams)
} else {
/* we have v6-style config params */
qqueueSetDefaultsActionQueue(pThis->pQueue);
- qqueueApplyCnfParam(pThis->pQueue, queueParams);
+ qqueueApplyCnfParam(pThis->pQueue, lst);
}
# undef setQPROP
@@ -1788,7 +1788,7 @@ actionApplyCnfParam(action_t *pAction, struct cnfparamvals *pvals)
rsRetVal
addAction(action_t **ppAction, modInfo_t *pMod, void *pModData,
omodStringRequest_t *pOMSR, struct cnfparamvals *actParams,
- struct cnfparamvals *queueParams, int bSuspended)
+ struct nvlst *lst, int bSuspended)
{
DEFiRet;
int i;
@@ -1881,7 +1881,7 @@ addAction(action_t **ppAction, modInfo_t *pMod, void *pModData,
if(bSuspended)
actionSuspend(pAction);
- CHKiRet(actionConstructFinalize(pAction, queueParams));
+ CHKiRet(actionConstructFinalize(pAction, lst));
/* TODO: if we exit here, we have a memory leak... */
@@ -1940,7 +1940,6 @@ rsRetVal
actionNewInst(struct nvlst *lst, action_t **ppAction)
{
struct cnfparamvals *paramvals;
- struct cnfparamvals *queueParams;
modInfo_t *pMod;
uchar *cnfModName = NULL;
omodStringRequest_t *pOMSR;
@@ -1971,9 +1970,7 @@ actionNewInst(struct nvlst *lst, action_t **ppAction)
FINALIZE; /* iRet is already set to error state */
}
- qqueueDoCnfParams(lst, &queueParams);
-
- if((iRet = addAction(&pAction, pMod, pModData, pOMSR, paramvals, queueParams,
+ if((iRet = addAction(&pAction, pMod, pModData, pOMSR, paramvals, lst,
(iRet == RS_RET_SUSPENDED)? 1 : 0)) == RS_RET_OK) {
/* check if the module is compatible with select features
* (currently no such features exist) */
diff --git a/action.h b/action.h
index dfafe301..54cdb54c 100644
--- a/action.h
+++ b/action.h
@@ -91,7 +91,7 @@ struct action_s {
/* function prototypes
*/
rsRetVal actionConstruct(action_t **ppThis);
-rsRetVal actionConstructFinalize(action_t *pThis, struct cnfparamvals *queueParams);
+rsRetVal actionConstructFinalize(action_t *pThis, struct nvlst *lst);
rsRetVal actionDestruct(action_t *pThis);
rsRetVal actionDbgPrint(action_t *pThis);
rsRetVal actionSetGlobalResumeInterval(int iNewVal);
@@ -99,7 +99,7 @@ rsRetVal actionDoAction(action_t *pAction);
rsRetVal actionWriteToAction(action_t *pAction, msg_t *pMsg);
rsRetVal actionCallHUPHdlr(action_t *pAction);
rsRetVal actionClassInit(void);
-rsRetVal addAction(action_t **ppAction, modInfo_t *pMod, void *pModData, omodStringRequest_t *pOMSR, struct cnfparamvals *actParams, struct cnfparamvals *queueParams, int bSuspended);
+rsRetVal addAction(action_t **ppAction, modInfo_t *pMod, void *pModData, omodStringRequest_t *pOMSR, struct cnfparamvals *actParams, struct nvlst *lst, int bSuspended);
rsRetVal activateActions(void);
rsRetVal actionNewInst(struct nvlst *lst, action_t **ppAction);
rsRetVal actionProcessCnf(struct cnfobj *o);
diff --git a/dirty.h b/dirty.h
index 4db2e3ce..e0a6e26e 100644
--- a/dirty.h
+++ b/dirty.h
@@ -35,7 +35,7 @@ rsRetVal multiSubmitFlush(multi_submit_t *pMultiSub);
rsRetVal logmsgInternal(int iErr, int pri, uchar *msg, int flags);
rsRetVal __attribute__((deprecated)) parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int flags, flowControl_t flowCtlTypeu, prop_t *pInputName, struct syslogTime *stTime, time_t ttGenTime, ruleset_t *pRuleset);
rsRetVal diagGetMainMsgQSize(int *piSize); /* for imdiag */
-rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct cnfparamvals *queueParams);
+rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct nvlst *lst);
extern int MarkInterval;
extern qqueue_t *pMsgQueue; /* the main message queue */
diff --git a/runtime/queue.c b/runtime/queue.c
index 85b1e45b..87f5819e 100644
--- a/runtime/queue.c
+++ b/runtime/queue.c
@@ -12,7 +12,7 @@
* function names - this makes it really hard to read and does not provide much
* benefit, at least I (now) think so...
*
- * Copyright 2008-2011 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2008-2013 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of the rsyslog runtime library.
*
@@ -118,6 +118,7 @@ static struct cnfparamdescr cnfpdescr[] = {
{ "queue.dequeueslowdown", eCmdHdlrInt, 0 },
{ "queue.dequeuetimebegin", eCmdHdlrInt, 0 },
{ "queue.dequeuetimeend", eCmdHdlrInt, 0 },
+ { "queue.cry.provider", eCmdHdlrGetWord, 0 }
};
static struct cnfparamblk pblk =
{ CNFPARAMBLK_VERSION,
@@ -2389,6 +2390,7 @@ CODESTARTobjDestruct(qqueue)
free(pThis->pszFilePrefix);
free(pThis->pszSpoolDir);
+ free(pThis->cryprovName);
/* some queues do not provide stats and thus have no statsobj! */
if(pThis->statsobj != NULL)
@@ -2672,27 +2674,67 @@ finalize_it:
}
-/* take v6 config list and extract the queue params out of it. Hand the
- * param values back to the caller. Caller is responsible for destructing
- * them when no longer needed. Caller can use this param block to configure
- * all parameters for a newly created queue with one call to qqueueSetParams().
- * rgerhards, 2011-07-22
+/* are any queue params set at all? 1 - yes, 0 - no
+ * We need to evaluate the param block for this function, which is somewhat
+ * inefficient. HOWEVER, this is only done during config load, so we really
+ * don't care... -- rgerhards, 2013-05-10
*/
-rsRetVal
-qqueueDoCnfParams(struct nvlst *lst, struct cnfparamvals **ppvals)
+int
+queueCnfParamsSet(struct nvlst *lst)
{
- *ppvals = nvlstGetParams(lst, &pblk, NULL);
- return RS_RET_OK;
+ int r;
+ struct cnfparamvals *pvals;
+
+ pvals = nvlstGetParams(lst, &pblk, NULL);
+ r = cnfparamvalsIsSet(&pblk, pvals);
+ cnfparamvalsDestruct(pvals, &pblk);
+ return r;
}
-/* are any queue params set at all? 1 - yes, 0 - no */
-int
-queueCnfParamsSet(struct cnfparamvals *pvals)
+static inline rsRetVal
+initCryprov(qqueue_t *pThis, struct nvlst *lst)
{
- return cnfparamvalsIsSet(&pblk, pvals);
-}
+ uchar szDrvrName[1024];
+ DEFiRet;
+ if(snprintf((char*)szDrvrName, sizeof(szDrvrName), "lmcry_%s", pThis->cryprovName)
+ == sizeof(szDrvrName)) {
+ errmsg.LogError(0, RS_RET_ERR, "omfile: crypto provider "
+ "name is too long: '%s' - encryption disabled",
+ pThis->cryprovName);
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ pThis->cryprovNameFull = ustrdup(szDrvrName);
+
+ pThis->cryprov.ifVersion = cryprovCURR_IF_VERSION;
+ /* The pDrvrName+2 below is a hack to obtain the object name. It
+ * safes us to have yet another variable with the name without "lm" in
+ * front of it. If we change the module load interface, we may re-think
+ * about this hack, but for the time being it is efficient and clean enough.
+ */
+ if(obj.UseObj(__FILE__, szDrvrName, szDrvrName, (void*) &pThis->cryprov)
+ != RS_RET_OK) {
+ errmsg.LogError(0, RS_RET_LOAD_ERROR, "omfile: could not load "
+ "crypto provider '%s' - encryption disabled",
+ szDrvrName);
+ ABORT_FINALIZE(RS_RET_CRYPROV_ERR);
+ }
+
+ if(pThis->cryprov.Construct(&pThis->cryprovData) != RS_RET_OK) {
+ errmsg.LogError(0, RS_RET_CRYPROV_ERR, "omfile: error constructing "
+ "crypto provider %s dataset - encryption disabled",
+ szDrvrName);
+ ABORT_FINALIZE(RS_RET_CRYPROV_ERR);
+ }
+ CHKiRet(pThis->cryprov.SetCnfParam(pThis->cryprovData, lst, CRYPROV_PARAMTYPE_DISK));
+
+ dbgprintf("loaded crypto provider %s, data instance at %p\n",
+ szDrvrName, pThis->cryprovData);
+ pThis->useCryprov = 1;
+finalize_it:
+ RETiRet;
+}
/* apply all params from param block to queue. Must be called before
* finalizing. This supports the v6 config system. Defaults were already
@@ -2700,15 +2742,25 @@ queueCnfParamsSet(struct cnfparamvals *pvals)
* function.
*/
rsRetVal
-qqueueApplyCnfParam(qqueue_t *pThis, struct cnfparamvals *pvals)
+qqueueApplyCnfParam(qqueue_t *pThis, struct nvlst *lst)
{
int i;
+ struct cnfparamvals *pvals;
+
+ pvals = nvlstGetParams(lst, &pblk, NULL);
+ if(Debug) {
+ dbgprintf("queue param blk:\n");
+ cnfparamsPrint(&pblk, pvals);
+ }
for(i = 0 ; i < pblk.nParams ; ++i) {
if(!pvals[i].bUsed)
continue;
if(!strcmp(pblk.descr[i].name, "queue.filename")) {
pThis->pszFilePrefix = (uchar*) es_str2cstr(pvals[i].val.d.estr, NULL);
pThis->lenFilePrefix = es_strlen(pvals[i].val.d.estr);
+ } else if(!strcmp(pblk.descr[i].name, "queue.cry.provider")) {
+ pThis->cryprovName = (uchar*) es_str2cstr(pvals[i].val.d.estr, NULL);
+dbgprintf("DDDD: crypto provider set: '%s'\n", pThis->cryprovName);
} else if(!strcmp(pblk.descr[i].name, "queue.size")) {
pThis->iMaxQueueSize = pvals[i].val.d.n;
} else if(!strcmp(pblk.descr[i].name, "queue.dequeuebatchsize")) {
@@ -2760,12 +2812,27 @@ qqueueApplyCnfParam(qqueue_t *pThis, struct cnfparamvals *pvals)
"param '%s'\n", pblk.descr[i].name);
}
}
- if(pThis->qType == QUEUETYPE_DISK && pThis->pszFilePrefix == NULL) {
- errmsg.LogError(0, RS_RET_QUEUE_DISK_NO_FN, "error on queue '%s', disk mode selected, but "
- "no queue file name given; queue type changed to 'linkedList'",
+ if(pThis->qType == QUEUETYPE_DISK) {
+ if(pThis->pszFilePrefix == NULL) {
+ errmsg.LogError(0, RS_RET_QUEUE_DISK_NO_FN, "error on queue '%s', disk mode selected, but "
+ "no queue file name given; queue type changed to 'linkedList'",
+ obj.GetName((obj_t*) pThis));
+ pThis->qType = QUEUETYPE_LINKEDLIST;
+ }
+ }
+
+ if(pThis->pszFilePrefix == NULL && pThis->cryprovName != NULL) {
+ errmsg.LogError(0, RS_RET_QUEUE_CRY_DISK_ONLY, "error on queue '%s', crypto provider can "
+ "only be set for disk or disk assisted queue - ignored",
obj.GetName((obj_t*) pThis));
- pThis->qType = QUEUETYPE_LINKEDLIST;
+ free(pThis->cryprovName);
+ pThis->cryprovName = NULL;
}
+
+ if(pThis->cryprovName != NULL) {
+ initCryprov(pThis, lst);
+ }
+
cnfparamvalsDestruct(pvals, &pblk);
return RS_RET_OK;
}
diff --git a/runtime/queue.h b/runtime/queue.h
index 886fac8d..9ed7f87d 100644
--- a/runtime/queue.h
+++ b/runtime/queue.h
@@ -30,6 +30,7 @@
#include "batch.h"
#include "stream.h"
#include "statsobj.h"
+#include "cryprov.h"
/* support for the toDelete list */
typedef struct toDeleteLst_s toDeleteLst_t;
@@ -168,6 +169,11 @@ struct queue_s {
strm_t *pReadDel; /* current file for deleting */
} disk;
} tVars;
+ sbool useCryprov; /* quicker than checkig ptr (1 vs 8 bytes!) */
+ uchar *cryprovName; /* crypto provider to use */
+ cryprov_if_t cryprov; /* ptr to crypto provider interface */
+ uchar *cryprovNameFull;/* full internal crypto provider name */
+ void *cryprovData; /* opaque data ptr for provider use */
DEF_ATOMIC_HELPER_MUT(mutQueueSize);
DEF_ATOMIC_HELPER_MUT(mutLogDeq);
/* for statistics subsystem */
@@ -197,9 +203,8 @@ rsRetVal qqueueSetFilePrefix(qqueue_t *pThis, uchar *pszPrefix, size_t iLenPrefi
rsRetVal qqueueConstruct(qqueue_t **ppThis, queueType_t qType, int iWorkerThreads,
int iMaxQueueSize, rsRetVal (*pConsumer)(void*,batch_t*, int*));
rsRetVal qqueueEnqObjDirectBatch(qqueue_t *pThis, batch_t *pBatch);
-rsRetVal qqueueDoCnfParams(struct nvlst *lst, struct cnfparamvals **ppvals);
-int queueCnfParamsSet(struct cnfparamvals *pvals);
-rsRetVal qqueueApplyCnfParam(qqueue_t *pThis, struct cnfparamvals *pvals);
+int queueCnfParamsSet(struct nvlst *lst);
+rsRetVal qqueueApplyCnfParam(qqueue_t *pThis, struct nvlst *lst);
void qqueueSetDefaultsRulesetQueue(qqueue_t *pThis);
void qqueueSetDefaultsActionQueue(qqueue_t *pThis);
void qqueueDbgPrint(qqueue_t *pThis);
diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h
index 47b34783..e8c2eb68 100644
--- a/runtime/rsyslog.h
+++ b/runtime/rsyslog.h
@@ -413,6 +413,8 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_CRY_INVLD_ALGO = -2326,/**< user specified invalid (unkonwn) crypto algorithm */
RS_RET_CRY_INVLD_MODE = -2327,/**< user specified invalid (unkonwn) crypto mode */
RS_RET_QUEUE_DISK_NO_FN = -2328,/**< disk queue configured, but filename not set */
+ /* up to 2350 reserved for 7.4 */
+ RS_RET_QUEUE_CRY_DISK_ONLY = -2351,/**< crypto provider only supported for disk-associated queues */
/* RainerScript error messages (range 1000.. 1999) */
RS_RET_SYSVAR_NOT_FOUND = 1001, /**< system variable could not be found (maybe misspelled) */
diff --git a/runtime/ruleset.c b/runtime/ruleset.c
index e3348938..aacbdf57 100644
--- a/runtime/ruleset.c
+++ b/runtime/ruleset.c
@@ -928,7 +928,6 @@ rsRetVal
rulesetProcessCnf(struct cnfobj *o)
{
struct cnfparamvals *pvals;
- struct cnfparamvals *queueParams;
rsRetVal localRet;
uchar *rsName = NULL;
uchar *parserName;
@@ -974,11 +973,10 @@ rulesetProcessCnf(struct cnfobj *o)
}
/* pick up ruleset queue parameters */
- qqueueDoCnfParams(o->nvlst, &queueParams);
- if(queueCnfParamsSet(queueParams)) {
+ if(queueCnfParamsSet(o->nvlst)) {
rsname = (pRuleset->pszName == NULL) ? (uchar*) "[ruleset]" : pRuleset->pszName;
DBGPRINTF("adding a ruleset-specific \"main\" queue for ruleset '%s'\n", rsname);
- CHKiRet(createMainQueue(&pRuleset->pQueue, rsname, queueParams));
+ CHKiRet(createMainQueue(&pRuleset->pQueue, rsname, o->nvlst));
}
finalize_it:
diff --git a/tools/syslogd.c b/tools/syslogd.c
index 47a21585..d2f249cf 100644
--- a/tools/syslogd.c
+++ b/tools/syslogd.c
@@ -1057,7 +1057,7 @@ finalize_it:
* the time being (remember that we want to restructure config processing at large!).
* rgerhards, 2009-10-27
*/
-rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct cnfparamvals *queueParams)
+rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct nvlst *lst)
{
struct queuefilenames_s *qfn;
uchar *qfname = NULL;
@@ -1073,7 +1073,7 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct cnfpara
/* name our main queue object (it's not fatal if it fails...) */
obj.SetName((obj_t*) (*ppQueue), pszQueueName);
- if(queueParams == NULL) { /* use legacy parameters? */
+ if(lst == NULL) { /* use legacy parameters? */
/* ... set some properties ... */
# define setQPROP(func, directive, data) \
CHKiRet_Hdlr(func(*ppQueue, data)) { \
@@ -1130,7 +1130,7 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct cnfpara
# undef setQPROPstr
} else { /* use new style config! */
qqueueSetDefaultsRulesetQueue(*ppQueue);
- qqueueApplyCnfParam(*ppQueue, queueParams);
+ qqueueApplyCnfParam(*ppQueue, lst);
}
/* ... and finally start the queue! */
@@ -1887,7 +1887,7 @@ int realMain(int argc, char **argv)
if(glbl.GetSourceIPofLocalClient() != NULL) {
fprintf (stderr, "rsyslogd: Only one -S argument allowed, the first one is taken.\n");
} else {
- glbl.SetSourceIPofLocalClient(arg);
+ glbl.SetSourceIPofLocalClient((uchar*)arg);
}
break;
case 'f': /* configuration file */
--
cgit v1.2.3
From 0d000a8b1096abb26f9e47a4083dc560fed0282d Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Mon, 13 May 2013 08:04:13 +0200
Subject: basic queue file encryption
---
runtime/cryprov.h | 5 +-
runtime/libgcry.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++---
runtime/libgcry.h | 10 ++-
runtime/lmcry_gcry.c | 16 +++-
runtime/queue.c | 27 ++++++-
runtime/queue.h | 2 +-
runtime/stream.c | 8 +-
tools/omfile.c | 1 -
8 files changed, 248 insertions(+), 23 deletions(-)
diff --git a/runtime/cryprov.h b/runtime/cryprov.h
index cbb2f45d..66c1cfd1 100644
--- a/runtime/cryprov.h
+++ b/runtime/cryprov.h
@@ -38,9 +38,10 @@ BEGINinterface(cryprov) /* name must also be changed in ENDinterface macro! */
rsRetVal (*Construct)(void *ppThis);
rsRetVal (*SetCnfParam)(void *ppThis, struct nvlst *lst, int paramType);
rsRetVal (*Destruct)(void *ppThis);
- rsRetVal (*OnFileOpen)(void *pThis, uchar *fn, void *pFileInstData);
+ rsRetVal (*OnFileOpen)(void *pThis, uchar *fn, void *pFileInstData, char openMode);
rsRetVal (*Encrypt)(void *pFileInstData, uchar *buf, size_t *lenBuf);
+ rsRetVal (*Decrypt)(void *pFileInstData, uchar *buf, size_t *lenBuf);
rsRetVal (*OnFileClose)(void *pFileInstData, off64_t offsLogfile);
ENDinterface(cryprov)
-#define cryprovCURR_IF_VERSION 2 /* increment whenever you change the interface structure! */
+#define cryprovCURR_IF_VERSION 3 /* increment whenever you change the interface structure! */
#endif /* #ifndef INCLUDED_CRYPROV_H */
diff --git a/runtime/libgcry.c b/runtime/libgcry.c
index 51c10af4..3fca50ec 100644
--- a/runtime/libgcry.c
+++ b/runtime/libgcry.c
@@ -49,8 +49,10 @@
#include
#include "rsyslog.h"
+#include "srUtils.h"
#include "libgcry.h"
+#define READBUF_SIZE 4096 /* size of the read buffer */
static rsRetVal
eiWriteRec(gcryfile gf, char *recHdr, size_t lenRecHdr, char *buf, size_t lenBuf)
@@ -90,19 +92,66 @@ finalize_it:
RETiRet;
}
+static rsRetVal
+eiRead(gcryfile gf)
+{
+ ssize_t nRead;
+ DEFiRet;
+
+ if(gf->readBuf == NULL) {
+ CHKmalloc(gf->readBuf = malloc(READBUF_SIZE));
+ }
+
+ nRead = read(gf->fd, gf->readBuf, READBUF_SIZE);
+ if(nRead <= 0) { /* TODO: provide specific EOF case? */
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ gf->readBufMaxIdx = (int16_t) nRead;
+ gf->readBufIdx = 0;
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* returns EOF on any kind of error */
+static int
+eiReadChar(gcryfile gf)
+{
+ int c;
+
+ if(gf->readBufIdx >= gf->readBufMaxIdx) {
+ if(eiRead(gf) != RS_RET_OK) {
+ c = EOF;
+ goto finalize_it;
+ }
+ }
+ c = gf->readBuf[gf->readBufIdx++];
+finalize_it:
+ return c;
+}
+
static rsRetVal
eiCheckFiletype(gcryfile gf)
{
char hdrBuf[128];
size_t toRead, didRead;
+ sbool bNeedClose = 0;
DEFiRet;
- CHKiRet(eiOpenRead(gf));
+ if(gf->fd == -1) {
+ bNeedClose = 1;
+ CHKiRet(eiOpenRead(gf));
+ }
+
if(Debug) memset(hdrBuf, 0, sizeof(hdrBuf)); /* for dbgprintf below! */
toRead = sizeof("FILETYPE:")-1 + sizeof(RSGCRY_FILETYPE_NAME)-1 + 1;
didRead = read(gf->fd, hdrBuf, toRead);
- close(gf->fd);
+ if(bNeedClose) {
+ close(gf->fd);
+ gf->fd = -1;
+ }
DBGPRINTF("eiCheckFiletype read %d bytes: '%s'\n", didRead, hdrBuf);
if( didRead != toRead
|| strncmp(hdrBuf, "FILETYPE:" RSGCRY_FILETYPE_NAME "\n", toRead))
@@ -111,6 +160,79 @@ finalize_it:
RETiRet;
}
+/* rectype/value must be EIF_MAX_*_LEN+1 long!
+ * returns 0 on success or something else on error/EOF
+ */
+static rsRetVal
+eiGetRecord(gcryfile gf, char *rectype, char *value)
+{
+ unsigned short i, j;
+ int c;
+ DEFiRet;
+
+ for(i = 0 ; i < EIF_MAX_RECTYPE_LEN ; ++i) {
+ c = eiReadChar(gf);
+ if(c == ':' || c == EOF)
+ break;
+ rectype[i] = c;
+ }
+ if(c != ':') { ABORT_FINALIZE(RS_RET_ERR); }
+ rectype[i] = '\0';
+ j = 0;
+ for(++i ; i < EIF_MAX_VALUE_LEN ; ++i, ++j) {
+ c = eiReadChar(gf);
+ if(c == '\n' || c == EOF)
+ break;
+ value[j] = c;
+ }
+ if(c != '\n') { ABORT_FINALIZE(RS_RET_ERR); }
+ value[j] = '\0';
+finalize_it:
+ RETiRet;
+}
+
+static rsRetVal
+eiGetIV(gcryfile gf, uchar *iv, size_t leniv)
+{
+ char rectype[EIF_MAX_RECTYPE_LEN+1];
+ char value[EIF_MAX_VALUE_LEN+1];
+ size_t valueLen;
+ unsigned short i, j;
+ unsigned char nibble;
+ DEFiRet;
+
+ CHKiRet(eiGetRecord(gf, rectype, value));
+ if(strcmp(rectype, "IV")) {
+ DBGPRINTF("no IV record found when expected, record type "
+ "seen is '%s'\n", rectype);
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ valueLen = strlen(value);
+ if(valueLen/2 != leniv) {
+ DBGPRINTF("length of IV is %d, expected %d\n",
+ valueLen/2, leniv);
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+
+ for(i = j = 0 ; i < valueLen ; ++i) {
+ if(value[i] >= '0' && value[i] <= '9')
+ nibble = value[i] - '0';
+ else if(value[i] >= 'a' && value[i] <= 'f')
+ nibble = value[i] - 'a' + 10;
+ else {
+ DBGPRINTF("invalid IV '%s'\n", value);
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ if(i % 2 == 0)
+ iv[j] = nibble << 4;
+ else
+ iv[j++] |= nibble;
+ }
+finalize_it:
+ RETiRet;
+}
+
+
static rsRetVal
eiOpenAppend(gcryfile gf)
{
@@ -180,7 +302,9 @@ eiClose(gcryfile gf, off64_t offsLogfile)
/* 2^64 is 20 digits, so the snprintf buffer is large enough */
len = snprintf(offs, sizeof(offs), "%lld", offsLogfile);
eiWriteRec(gf, "END:", 4, offs, len);
+ free(gf->readBuf);
close(gf->fd);
+ gf->fd = -1;
DBGPRINTF("encryption info file %s: closed\n", gf->eiName);
}
@@ -193,6 +317,7 @@ gcryfileConstruct(gcryctx ctx, gcryfile *pgf, uchar *logfn)
CHKmalloc(gf = calloc(1, sizeof(struct gcryfile_s)));
gf->ctx = ctx;
+ gf->fd = -1;
snprintf(fn, sizeof(fn), "%s%s", logfn, ENCINFO_SUFFIX);
fn[MAXFNAME] = '\0'; /* be on save side */
gf->eiName = (uchar*) strdup(fn);
@@ -246,13 +371,13 @@ addPadding(gcryfile pF, uchar *buf, size_t *plen)
}
static inline void
-removePadding(char *buf, size_t *plen)
+removePadding(uchar *buf, size_t *plen)
{
unsigned len = (unsigned) *plen;
unsigned iSrc, iDst;
- char *frstNUL;
+ uchar *frstNUL;
- frstNUL = strchr(buf, 0x00);
+ frstNUL = (uchar*)strchr((char*)buf, 0x00);
if(frstNUL == NULL)
goto done;
iDst = iSrc = frstNUL - buf;
@@ -343,8 +468,31 @@ seedIV(gcryfile gf, uchar **iv)
}
}
+static inline rsRetVal
+readIV(gcryfile gf, uchar **iv)
+{
+ rsRetVal localRet;
+ DEFiRet;
+
+ do {
+ localRet = eiOpenRead(gf);
+ if(localRet == RS_RET_EI_NO_EXISTS) {
+ /* wait until it is created */
+ srSleep(0, 10000);
+ } else {
+ CHKiRet(localRet);
+ }
+ } while(localRet != RS_RET_OK);
+ CHKiRet(eiCheckFiletype(gf));
+ *iv = malloc(gf->blkLength); /* do NOT zero-out! */
+ CHKiRet(eiGetIV(gf, *iv, (size_t) gf->blkLength));
+dbgprintf("DDDD: read %d bytes of IV\n", (int) gf->blkLength);
+finalize_it:
+ RETiRet;
+}
+
rsRetVal
-rsgcryInitCrypt(gcryctx ctx, gcryfile *pgf, uchar *fname)
+rsgcryInitCrypt(gcryctx ctx, gcryfile *pgf, uchar *fname, char openMode)
{
gcry_error_t gcryError;
gcryfile gf = NULL;
@@ -352,6 +500,7 @@ rsgcryInitCrypt(gcryctx ctx, gcryfile *pgf, uchar *fname)
DEFiRet;
CHKiRet(gcryfileConstruct(ctx, &gf, fname));
+ gf->mode = openMode;
gf->blkLength = gcry_cipher_get_algo_blklen(ctx->algo);
@@ -371,7 +520,12 @@ rsgcryInitCrypt(gcryctx ctx, gcryfile *pgf, uchar *fname)
ABORT_FINALIZE(RS_RET_ERR);
}
- seedIV(gf, &iv);
+ if(openMode == 'r') {
+ readIV(gf, &iv);
+ } else {
+ seedIV(gf, &iv);
+ }
+
gcryError = gcry_cipher_setiv(gf->chd, iv, gf->blkLength);
if (gcryError) {
dbgprintf("gcry_cipher_setiv failed: %s/%s\n",
@@ -379,8 +533,10 @@ rsgcryInitCrypt(gcryctx ctx, gcryfile *pgf, uchar *fname)
gcry_strerror(gcryError));
ABORT_FINALIZE(RS_RET_ERR);
}
- CHKiRet(eiOpenAppend(gf));
- CHKiRet(eiWriteIV(gf, iv));
+ if(openMode == 'w') {
+ CHKiRet(eiOpenAppend(gf));
+ CHKiRet(eiWriteIV(gf, iv));
+ }
*pgf = gf;
finalize_it:
free(iv);
@@ -389,7 +545,7 @@ finalize_it:
RETiRet;
}
-int
+rsRetVal
rsgcryEncrypt(gcryfile pF, uchar *buf, size_t *len)
{
int gcryError;
@@ -410,6 +566,32 @@ finalize_it:
RETiRet;
}
+/* TODO: handle multiple blocks
+ * test-read END record; if present, store offset, else unbounded (current active block)
+ * when decrypting, check if bound is reached. If yes, split into two blocks, get new IV for
+ * second one.
+ */
+rsRetVal
+rsgcryDecrypt(gcryfile pF, uchar *buf, size_t *len)
+{
+ gcry_error_t gcryError;
+ DEFiRet;
+
+ gcryError = gcry_cipher_decrypt(pF->chd, buf, *len, NULL, 0);
+ if(gcryError) {
+ DBGPRINTF("gcry_cipher_decrypt failed: %s/%s\n",
+ gcry_strsource(gcryError),
+ gcry_strerror(gcryError));
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ removePadding(buf, len);
+dbgprintf("DDDD: decrypted, buffer is now '%50.50s'\n", buf);
+
+finalize_it:
+ RETiRet;
+}
+
+
/* module-init dummy for potential later use */
int
diff --git a/runtime/libgcry.h b/runtime/libgcry.h
index b77b0f9e..190f4737 100644
--- a/runtime/libgcry.h
+++ b/runtime/libgcry.h
@@ -38,7 +38,11 @@ struct gcryfile_s {
size_t blkLength; /* size of low-level crypto block */
uchar *eiName; /* name of .encinfo file */
int fd; /* descriptor of .encinfo file (-1 if not open) */
+ char mode; /* 'r': read, 'w': write */
gcryctx ctx;
+ uchar *readBuf;
+ int16_t readBufIdx;
+ int16_t readBufMaxIdx;
};
int gcryGetKeyFromFile(char *fn, char **key, unsigned *keylen);
@@ -50,8 +54,10 @@ rsRetVal rsgcrySetAlgo(gcryctx ctx, uchar *modename);
gcryctx gcryCtxNew(void);
void rsgcryCtxDel(gcryctx ctx);
int gcryfileDestruct(gcryfile gf, off64_t offsLogfile);
-rsRetVal rsgcryInitCrypt(gcryctx ctx, gcryfile *pgf, uchar *fname);
-int rsgcryEncrypt(gcryfile pF, uchar *buf, size_t *len);
+rsRetVal rsgcryInitCrypt(gcryctx ctx, gcryfile *pgf, uchar *fname, char openMode);
+rsRetVal rsgcryEncrypt(gcryfile pF, uchar *buf, size_t *len);
+rsRetVal rsgcryDecrypt(gcryfile pF, uchar *buf, size_t *len);
+int gcryGetKeyFromProg(char *cmd, char **key, unsigned *keylen);
/* error states */
#define RSGCRYE_EI_OPEN 1 /* error opening .encinfo file */
diff --git a/runtime/lmcry_gcry.c b/runtime/lmcry_gcry.c
index 31fab0d4..decb8591 100644
--- a/runtime/lmcry_gcry.c
+++ b/runtime/lmcry_gcry.c
@@ -211,13 +211,14 @@ finalize_it:
static rsRetVal
-OnFileOpen(void *pT, uchar *fn, void *pGF)
+OnFileOpen(void *pT, uchar *fn, void *pGF, char openMode)
{
lmcry_gcry_t *pThis = (lmcry_gcry_t*) pT;
gcryfile *pgf = (gcryfile*) pGF;
DEFiRet;
+dbgprintf("DDDD: open file '%s', mode '%c'\n", fn, openMode);
- CHKiRet(rsgcryInitCrypt(pThis->ctx, pgf, fn));
+ CHKiRet(rsgcryInitCrypt(pThis->ctx, pgf, fn, openMode));
finalize_it:
/* TODO: enable this error message (need to cleanup loop first ;))
errmsg.LogError(0, iRet, "Encryption Provider"
@@ -226,6 +227,16 @@ finalize_it:
RETiRet;
}
+static rsRetVal
+Decrypt(void *pF, uchar *rec, size_t *lenRec)
+{
+ DEFiRet;
+ iRet = rsgcryDecrypt(pF, rec, lenRec);
+
+ RETiRet;
+}
+
+
static rsRetVal
Encrypt(void *pF, uchar *rec, size_t *lenRec)
{
@@ -254,6 +265,7 @@ CODESTARTobjQueryInterface(lmcry_gcry)
pIf->Destruct = (rsRetVal(*)(void*)) lmcry_gcryDestruct;
pIf->OnFileOpen = OnFileOpen;
pIf->Encrypt = Encrypt;
+ pIf->Decrypt = Decrypt;
pIf->OnFileClose = OnFileClose;
finalize_it:
ENDobjQueryInterface(lmcry_gcry)
diff --git a/runtime/queue.c b/runtime/queue.c
index 87f5819e..6af4905b 100644
--- a/runtime/queue.c
+++ b/runtime/queue.c
@@ -835,6 +835,10 @@ static rsRetVal qConstructDisk(qqueue_t *pThis)
CHKiRet(strm.SetiMaxFiles(pThis->tVars.disk.pWrite, 10000000));
CHKiRet(strm.SettOperationsMode(pThis->tVars.disk.pWrite, STREAMMODE_WRITE));
CHKiRet(strm.SetsType(pThis->tVars.disk.pWrite, STREAMTYPE_FILE_CIRCULAR));
+ if(pThis->useCryprov) {
+ CHKiRet(strm.Setcryprov(pThis->tVars.disk.pWrite, &pThis->cryprov));
+ CHKiRet(strm.SetcryprovData(pThis->tVars.disk.pWrite, pThis->cryprovData));
+ }
CHKiRet(strm.ConstructFinalize(pThis->tVars.disk.pWrite));
CHKiRet(strm.Construct(&pThis->tVars.disk.pReadDeq));
@@ -843,6 +847,10 @@ static rsRetVal qConstructDisk(qqueue_t *pThis)
CHKiRet(strm.SetiMaxFiles(pThis->tVars.disk.pReadDeq, 10000000));
CHKiRet(strm.SettOperationsMode(pThis->tVars.disk.pReadDeq, STREAMMODE_READ));
CHKiRet(strm.SetsType(pThis->tVars.disk.pReadDeq, STREAMTYPE_FILE_CIRCULAR));
+ if(pThis->useCryprov) {
+ CHKiRet(strm.Setcryprov(pThis->tVars.disk.pReadDeq, &pThis->cryprov));
+ CHKiRet(strm.SetcryprovData(pThis->tVars.disk.pReadDeq, pThis->cryprovData));
+ }
CHKiRet(strm.ConstructFinalize(pThis->tVars.disk.pReadDeq));
CHKiRet(strm.Construct(&pThis->tVars.disk.pReadDel));
@@ -852,6 +860,10 @@ static rsRetVal qConstructDisk(qqueue_t *pThis)
CHKiRet(strm.SetiMaxFiles(pThis->tVars.disk.pReadDel, 10000000));
CHKiRet(strm.SettOperationsMode(pThis->tVars.disk.pReadDel, STREAMMODE_READ));
CHKiRet(strm.SetsType(pThis->tVars.disk.pReadDel, STREAMTYPE_FILE_CIRCULAR));
+ if(pThis->useCryprov) {
+ CHKiRet(strm.Setcryprov(pThis->tVars.disk.pReadDel, &pThis->cryprov));
+ CHKiRet(strm.SetcryprovData(pThis->tVars.disk.pReadDel, pThis->cryprovData));
+ }
CHKiRet(strm.ConstructFinalize(pThis->tVars.disk.pReadDel));
CHKiRet(strm.SetFName(pThis->tVars.disk.pWrite, pThis->pszFilePrefix, pThis->lenFilePrefix));
@@ -1321,6 +1333,7 @@ rsRetVal qqueueConstruct(qqueue_t **ppThis, queueType_t qType, int iWorkerThread
pThis->iMaxFileSize = 1024 * 1024; /* default is 1 MiB */
pThis->iQueueSize = 0;
pThis->nLogDeq = 0;
+ pThis->useCryprov = 0;
pThis->iMaxQueueSize = iMaxQueueSize;
pThis->pConsumer = pConsumer;
pThis->iNumWorkerThreads = iWorkerThreads;
@@ -2390,7 +2403,13 @@ CODESTARTobjDestruct(qqueue)
free(pThis->pszFilePrefix);
free(pThis->pszSpoolDir);
- free(pThis->cryprovName);
+ if(pThis->useCryprov) {
+ pThis->cryprov.Destruct(&pThis->cryprovData);
+ obj.ReleaseObj(__FILE__, pThis->cryprovNameFull+2, pThis->cryprovNameFull,
+ (void*) &pThis->cryprov);
+ free(pThis->cryprovName);
+ free(pThis->cryprovNameFull);
+ }
/* some queues do not provide stats and thus have no statsobj! */
if(pThis->statsobj != NULL)
@@ -2700,7 +2719,7 @@ initCryprov(qqueue_t *pThis, struct nvlst *lst)
if(snprintf((char*)szDrvrName, sizeof(szDrvrName), "lmcry_%s", pThis->cryprovName)
== sizeof(szDrvrName)) {
- errmsg.LogError(0, RS_RET_ERR, "omfile: crypto provider "
+ errmsg.LogError(0, RS_RET_ERR, "queue: crypto provider "
"name is too long: '%s' - encryption disabled",
pThis->cryprovName);
ABORT_FINALIZE(RS_RET_ERR);
@@ -2715,14 +2734,14 @@ initCryprov(qqueue_t *pThis, struct nvlst *lst)
*/
if(obj.UseObj(__FILE__, szDrvrName, szDrvrName, (void*) &pThis->cryprov)
!= RS_RET_OK) {
- errmsg.LogError(0, RS_RET_LOAD_ERROR, "omfile: could not load "
+ errmsg.LogError(0, RS_RET_LOAD_ERROR, "queue: could not load "
"crypto provider '%s' - encryption disabled",
szDrvrName);
ABORT_FINALIZE(RS_RET_CRYPROV_ERR);
}
if(pThis->cryprov.Construct(&pThis->cryprovData) != RS_RET_OK) {
- errmsg.LogError(0, RS_RET_CRYPROV_ERR, "omfile: error constructing "
+ errmsg.LogError(0, RS_RET_CRYPROV_ERR, "queue: error constructing "
"crypto provider %s dataset - encryption disabled",
szDrvrName);
ABORT_FINALIZE(RS_RET_CRYPROV_ERR);
diff --git a/runtime/queue.h b/runtime/queue.h
index 9ed7f87d..844523ad 100644
--- a/runtime/queue.h
+++ b/runtime/queue.h
@@ -172,8 +172,8 @@ struct queue_s {
sbool useCryprov; /* quicker than checkig ptr (1 vs 8 bytes!) */
uchar *cryprovName; /* crypto provider to use */
cryprov_if_t cryprov; /* ptr to crypto provider interface */
+ void *cryprovData; /* opaque data ptr for provider use */
uchar *cryprovNameFull;/* full internal crypto provider name */
- void *cryprovData; /* opaque data ptr for provider use */
DEF_ATOMIC_HELPER_MUT(mutQueueSize);
DEF_ATOMIC_HELPER_MUT(mutLogDeq);
/* for statistics subsystem */
diff --git a/runtime/stream.c b/runtime/stream.c
index b781324a..e411577f 100644
--- a/runtime/stream.c
+++ b/runtime/stream.c
@@ -257,7 +257,8 @@ doPhysOpen(strm_t *pThis)
if(pThis->cryprov != NULL) {
CHKiRet(pThis->cryprov->OnFileOpen(pThis->cryprovData,
- pThis->pszCurrFName, &pThis->cryprovFileData));
+ pThis->pszCurrFName, &pThis->cryprovFileData,
+ (pThis->tOperationsMode == STREAMMODE_READ) ? 'r' : 'w'));
}
finalize_it:
RETiRet;
@@ -568,11 +569,16 @@ strmReadBuf(strm_t *pThis)
CHKiRet(strmOpenFile(pThis));
iLenRead = read(pThis->fd, pThis->pIOBuf, pThis->sIOBufSize);
DBGOPRINT((obj_t*) pThis, "file %d read %ld bytes\n", pThis->fd, iLenRead);
+ /* end crypto */
if(iLenRead == 0) {
CHKiRet(strmHandleEOF(pThis));
} else if(iLenRead < 0)
ABORT_FINALIZE(RS_RET_IO_ERROR);
else { /* good read */
+ /* here we place our crypto interface */
+ if(pThis->cryprov != NULL) {
+ pThis->cryprov->Decrypt(pThis->cryprovFileData, pThis->pIOBuf, &iLenRead);
+ }
pThis->iBufPtrMax = iLenRead;
bRun = 0; /* exit loop */
}
diff --git a/tools/omfile.c b/tools/omfile.c
index 1740e8bf..2ebb7df9 100644
--- a/tools/omfile.c
+++ b/tools/omfile.c
@@ -155,7 +155,6 @@ typedef struct _instanceData {
uchar *cryprovName; /* crypto provider */
uchar *cryprovNameFull;/* full internal crypto provider name */
void *cryprovData; /* opaque data ptr for provider use */
- void *cryprovFileData;/* opaque data ptr for file instance */
cryprov_if_t cryprov; /* ptr to crypto provider interface */
sbool useCryprov; /* quicker than checkig ptr (1 vs 8 bytes!) */
int iCurrElt; /* currently active cache element (-1 = none) */
--
cgit v1.2.3
From 53e99a6cffd5f0926af0cf38d4b21ced7eca2db8 Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Mon, 13 May 2013 08:50:06 +0200
Subject: fix invalid function prototypes
regression from yet-unreleased enhancement (RELP IP address setting)
---
runtime/glbl.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/runtime/glbl.h b/runtime/glbl.h
index 413f8225..2c7f3b31 100644
--- a/runtime/glbl.h
+++ b/runtime/glbl.h
@@ -81,8 +81,8 @@ BEGINinterface(glbl) /* name must also be changed in ENDinterface macro! */
/* next change is v9! */
/* v8 - 2012-03-21 */
prop_t* (*GetLocalHostIP)(void);
- prop_t* (*GetSourceIPofLocalClient)(void); /* [ar] */
- prop_t* (*SetSourceIPofLocalClient)(uchar*); /* [ar] */
+ uchar* (*GetSourceIPofLocalClient)(void); /* [ar] */
+ rsRetVal (*SetSourceIPofLocalClient)(uchar*); /* [ar] */
#undef SIMP_PROP
ENDinterface(glbl)
#define glblCURR_IF_VERSION 7 /* increment whenever you change the interface structure! */
--
cgit v1.2.3
From a64a87e0edeb1711271ba277e267eff75564d067 Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Mon, 13 May 2013 11:52:59 +0200
Subject: reflect librelp API change
---
plugins/omrelp/omrelp.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/plugins/omrelp/omrelp.c b/plugins/omrelp/omrelp.c
index 16e2e3ed..62f81fca 100644
--- a/plugins/omrelp/omrelp.c
+++ b/plugins/omrelp/omrelp.c
@@ -113,6 +113,10 @@ doCreateRelpClient(instanceData *pData)
ABORT_FINALIZE(RS_RET_RELP_ERR);
if(relpCltSetTimeout(pData->pRelpClt, pData->timeout) != RELP_RET_OK)
ABORT_FINALIZE(RS_RET_RELP_ERR);
+ if(glbl.GetSourceIPofLocalClient() == NULL) { /* ar Do we have a client IP set? */
+ if(relpCltSetClientIP(pData->pRelpClt, glbl.GetSourceIPofLocalClient()) != RELP_RET_OK)
+ ABORT_FINALIZE(RS_RET_RELP_ERR);
+ }
finalize_it:
RETiRet;
}
@@ -210,11 +214,7 @@ static rsRetVal doConnect(instanceData *pData)
DEFiRet;
if(pData->bInitialConnect) {
- if (glbl.GetSourceIPofLocalClient() == NULL) { /* ar Do we have a client IP set? */
- iRet = relpCltConnect(pData->pRelpClt, glbl.GetDefPFFamily(), pData->port, pData->target);
- } else { /* ar YES: use it */
- iRet = relpCltConnect2(pData->pRelpClt, glbl.GetDefPFFamily(), pData->port, pData->target, glbl.GetSourceIPofLocalClient());
- }
+ iRet = relpCltConnect(pData->pRelpClt, glbl.GetDefPFFamily(), pData->port, pData->target);
if(iRet == RELP_RET_OK)
pData->bInitialConnect = 0;
} else {
--
cgit v1.2.3
From 5e51fa8a60cc8f1f68a945afc9b242f5a3057818 Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Tue, 14 May 2013 12:37:36 +0200
Subject: omrelp: add support for TLS
---
configure.ac | 2 +-
plugins/imrelp/imrelp.c | 2 ++
plugins/omrelp/omrelp.c | 15 ++++++++++++++-
3 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index e18a0a72..841b8246 100644
--- a/configure.ac
+++ b/configure.ac
@@ -980,7 +980,7 @@ AC_ARG_ENABLE(relp,
[enable_relp=no]
)
if test "x$enable_relp" = "xyes"; then
- PKG_CHECK_MODULES(RELP, relp >= 1.0.3)
+ PKG_CHECK_MODULES(RELP, relp >= 1.1.0)
fi
AM_CONDITIONAL(ENABLE_RELP, test x$enable_relp = xyes)
diff --git a/plugins/imrelp/imrelp.c b/plugins/imrelp/imrelp.c
index 5e0ae552..21b30730 100644
--- a/plugins/imrelp/imrelp.c
+++ b/plugins/imrelp/imrelp.c
@@ -210,6 +210,8 @@ addListner(modConfData_t __attribute__((unused)) *modConf, instanceConf_t *inst)
CHKiRet(relpEngineSetDbgprint(pRelpEngine, dbgprintf));
CHKiRet(relpEngineSetFamily(pRelpEngine, glbl.GetDefPFFamily()));
CHKiRet(relpEngineSetEnableCmd(pRelpEngine, (uchar*) "syslog", eRelpCmdState_Required));
+// TODO: make configurable
+CHKiRet(relpEngineEnableTLS(pRelpEngine));
CHKiRet(relpEngineSetSyslogRcv(pRelpEngine, onSyslogRcv));
if (!glbl.GetDisableDNS()) {
CHKiRet(relpEngineSetDnsLookupMode(pRelpEngine, 1));
diff --git a/plugins/omrelp/omrelp.c b/plugins/omrelp/omrelp.c
index 62f81fca..95571f40 100644
--- a/plugins/omrelp/omrelp.c
+++ b/plugins/omrelp/omrelp.c
@@ -55,6 +55,8 @@ DEF_OMOD_STATIC_DATA
DEFobjCurrIf(errmsg)
DEFobjCurrIf(glbl)
+#define DFLT_ENABLE_TLS 0
+
static relpEngine_t *pRelpEngine; /* our relp engine */
typedef struct _instanceData {
@@ -65,6 +67,7 @@ typedef struct _instanceData {
int bIsConnected; /* currently connected to server? 0 - no, 1 - yes */
unsigned timeout;
relpClt_t *pRelpClt; /* relp client for this instance */
+ sbool bEnableTLS;
uchar *tplName;
} instanceData;
@@ -78,6 +81,7 @@ static configSettings_t __attribute__((unused)) cs;
/* action (instance) parameters */
static struct cnfparamdescr actpdescr[] = {
{ "target", eCmdHdlrGetWord, 1 },
+ { "tls", eCmdHdlrBinary, 0 },
{ "port", eCmdHdlrGetWord, 0 },
{ "timeout", eCmdHdlrInt, 0 },
{ "template", eCmdHdlrGetWord, 1 }
@@ -113,6 +117,12 @@ doCreateRelpClient(instanceData *pData)
ABORT_FINALIZE(RS_RET_RELP_ERR);
if(relpCltSetTimeout(pData->pRelpClt, pData->timeout) != RELP_RET_OK)
ABORT_FINALIZE(RS_RET_RELP_ERR);
+
+ if(pData->bEnableTLS) {
+ if(relpCltEnableTLS(pData->pRelpClt) != RELP_RET_OK)
+ ABORT_FINALIZE(RS_RET_RELP_ERR);
+ }
+
if(glbl.GetSourceIPofLocalClient() == NULL) { /* ar Do we have a client IP set? */
if(relpCltSetClientIP(pData->pRelpClt, glbl.GetSourceIPofLocalClient()) != RELP_RET_OK)
ABORT_FINALIZE(RS_RET_RELP_ERR);
@@ -126,6 +136,7 @@ BEGINcreateInstance
CODESTARTcreateInstance
pData->bInitialConnect = 1;
pData->timeout = 90;
+ pData->bEnableTLS = DFLT_ENABLE_TLS;
ENDcreateInstance
BEGINfreeInstance
@@ -144,6 +155,7 @@ setInstParamDefaults(instanceData *pData)
pData->port = NULL;
pData->tplName = NULL;
pData->timeout = 90;
+ pData->bEnableTLS = DFLT_ENABLE_TLS;
}
@@ -169,6 +181,8 @@ CODESTARTnewActInst
pData->tplName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if(!strcmp(actpblk.descr[i].name, "timeout")) {
pData->timeout = (unsigned) pvals[i].val.d.n;
+ } else if(!strcmp(actpblk.descr[i].name, "tls")) {
+ pData->bEnableTLS = (unsigned) pvals[i].val.d.n;
} else {
dbgprintf("omrelp: program error, non-handled "
"param '%s'\n", actpblk.descr[i].name);
@@ -389,7 +403,6 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
++p;
}
- /* TODO: make this if go away! */
if(*p == ';') {
*p = '\0'; /* trick to obtain hostname (later)! */
CHKmalloc(pData->target = ustrdup(q));
--
cgit v1.2.3
From c9cf58c073dde222b213637a1b682a43ca6c2175 Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Tue, 14 May 2013 13:22:34 +0200
Subject: imrelp: add support for TLS
---
plugins/imrelp/imrelp.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/plugins/imrelp/imrelp.c b/plugins/imrelp/imrelp.c
index 21b30730..f3972233 100644
--- a/plugins/imrelp/imrelp.c
+++ b/plugins/imrelp/imrelp.c
@@ -74,6 +74,7 @@ static struct configSettings_s {
struct instanceConf_s {
uchar *pszBindPort; /* port to bind to */
+ sbool bEnableTLS;
struct instanceConf_s *next;
};
@@ -90,7 +91,8 @@ static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current lo
/* input instance parameters */
static struct cnfparamdescr inppdescr[] = {
- { "port", eCmdHdlrString, CNFPARAM_REQUIRED }
+ { "port", eCmdHdlrString, CNFPARAM_REQUIRED },
+ { "tls", eCmdHdlrBinary, 0 }
};
static struct cnfparamblk inppblk =
{ CNFPARAMBLK_VERSION,
@@ -155,6 +157,7 @@ createInstance(instanceConf_t **pinst)
inst->next = NULL;
inst->pszBindPort = NULL;
+ inst->bEnableTLS = 0;
/* node created, let's add to config */
if(loadModConf->tail == NULL) {
@@ -179,7 +182,7 @@ std_checkRuleset_genErrMsg(modConfData_t *modConf, __attribute__((unused)) insta
}
-/* This function is called when a new listener instace shall be added to
+/* This function is called when a new listener instance shall be added to
* the current config object via the legacy config system. It just shuffles
* all parameters to the listener in-memory instance.
* rgerhards, 2011-05-04
@@ -204,21 +207,24 @@ finalize_it:
static rsRetVal
addListner(modConfData_t __attribute__((unused)) *modConf, instanceConf_t *inst)
{
+ relpSrv_t *pSrv;
DEFiRet;
if(pRelpEngine == NULL) {
CHKiRet(relpEngineConstruct(&pRelpEngine));
CHKiRet(relpEngineSetDbgprint(pRelpEngine, dbgprintf));
CHKiRet(relpEngineSetFamily(pRelpEngine, glbl.GetDefPFFamily()));
CHKiRet(relpEngineSetEnableCmd(pRelpEngine, (uchar*) "syslog", eRelpCmdState_Required));
-// TODO: make configurable
-CHKiRet(relpEngineEnableTLS(pRelpEngine));
CHKiRet(relpEngineSetSyslogRcv(pRelpEngine, onSyslogRcv));
if (!glbl.GetDisableDNS()) {
CHKiRet(relpEngineSetDnsLookupMode(pRelpEngine, 1));
}
}
- CHKiRet(relpEngineAddListner(pRelpEngine, inst->pszBindPort));
+ CHKiRet(relpEngineListnerConstruct(pRelpEngine, &pSrv));
+ CHKiRet(relpSrvSetLstnPort(pSrv, inst->pszBindPort));
+ if(inst->bEnableTLS)
+ relpSrvEnableTLS(pSrv);
+ CHKiRet(relpEngineListnerConstructFinalize(pRelpEngine, pSrv));
finalize_it:
RETiRet;
@@ -251,6 +257,8 @@ CODESTARTnewInpInst
continue;
if(!strcmp(inppblk.descr[i].name, "port")) {
inst->pszBindPort = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
+ } else if(!strcmp(inppblk.descr[i].name, "tls")) {
+ inst->bEnableTLS = (unsigned) pvals[i].val.d.n;
} else {
dbgprintf("imrelp: program error, non-handled "
"param '%s'\n", inppblk.descr[i].name);
--
cgit v1.2.3
From 24372200d1ff9a70c0474e99fe03e0faca6cc17f Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Tue, 14 May 2013 14:57:00 +0200
Subject: omrelp: add "rebindInterval" parameter
---
ChangeLog | 1 +
plugins/omrelp/omrelp.c | 31 ++++++++++++++++++++++++++-----
2 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 5984fab3..550fd3ed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
---------------------------------------------------------------------------
Version 7.5.0 [devel] 2013-0?-??
+- omrelp: add "rebindInterval" parameter
- add -S command line option to specify IP address to use for RELP client
connections
Thanks to Axel Rau for the patch.
diff --git a/plugins/omrelp/omrelp.c b/plugins/omrelp/omrelp.c
index 32f7ad73..a8e2e55c 100644
--- a/plugins/omrelp/omrelp.c
+++ b/plugins/omrelp/omrelp.c
@@ -65,6 +65,8 @@ typedef struct _instanceData {
int bInitialConnect; /* is this the initial connection request of our module? (0-no, 1-yes) */
int bIsConnected; /* currently connected to server? 0 - no, 1 - yes */
unsigned timeout;
+ unsigned rebindInterval;
+ unsigned nSent;
relpClt_t *pRelpClt; /* relp client for this instance */
sbool bEnableTLS;
uchar *tplName;
@@ -82,6 +84,7 @@ static struct cnfparamdescr actpdescr[] = {
{ "target", eCmdHdlrGetWord, 1 },
{ "tls", eCmdHdlrBinary, 0 },
{ "port", eCmdHdlrGetWord, 0 },
+ { "rebindinterval", eCmdHdlrInt, 0 },
{ "timeout", eCmdHdlrInt, 0 },
{ "template", eCmdHdlrGetWord, 1 }
};
@@ -116,16 +119,16 @@ doCreateRelpClient(instanceData *pData)
ABORT_FINALIZE(RS_RET_RELP_ERR);
if(relpCltSetTimeout(pData->pRelpClt, pData->timeout) != RELP_RET_OK)
ABORT_FINALIZE(RS_RET_RELP_ERR);
-
if(pData->bEnableTLS) {
if(relpCltEnableTLS(pData->pRelpClt) != RELP_RET_OK)
ABORT_FINALIZE(RS_RET_RELP_ERR);
}
-
if(glbl.GetSourceIPofLocalClient() == NULL) { /* ar Do we have a client IP set? */
if(relpCltSetClientIP(pData->pRelpClt, glbl.GetSourceIPofLocalClient()) != RELP_RET_OK)
ABORT_FINALIZE(RS_RET_RELP_ERR);
}
+ pData->bInitialConnect = 1;
+ pData->nSent = 0;
finalize_it:
RETiRet;
}
@@ -133,8 +136,8 @@ finalize_it:
BEGINcreateInstance
CODESTARTcreateInstance
- pData->bInitialConnect = 1;
pData->timeout = 90;
+ pData->rebindInterval = 0;
pData->bEnableTLS = DFLT_ENABLE_TLS;
ENDcreateInstance
@@ -154,6 +157,7 @@ setInstParamDefaults(instanceData *pData)
pData->port = NULL;
pData->tplName = NULL;
pData->timeout = 90;
+ pData->rebindInterval = 0;
pData->bEnableTLS = DFLT_ENABLE_TLS;
}
@@ -180,6 +184,8 @@ CODESTARTnewActInst
pData->tplName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if(!strcmp(actpblk.descr[i].name, "timeout")) {
pData->timeout = (unsigned) pvals[i].val.d.n;
+ } else if(!strcmp(actpblk.descr[i].name, "rebindinterval")) {
+ pData->rebindInterval = (unsigned) pvals[i].val.d.n;
} else if(!strcmp(actpblk.descr[i].name, "tls")) {
pData->bEnableTLS = (unsigned) pvals[i].val.d.n;
} else {
@@ -250,6 +256,17 @@ CODESTARTtryResume
iRet = doConnect(pData);
ENDtryResume
+static inline rsRetVal
+doRebind(instanceData *pData)
+{
+ DEFiRet;
+ DBGPRINTF("omrelp: destructing relp client due to rebindInterval\n");
+ CHKiRet(relpEngineCltDestruct(pRelpEngine, &pData->pRelpClt));
+ pData->bIsConnected = 0;
+ CHKiRet(doCreateRelpClient(pData));
+finalize_it:
+ RETiRet;
+}
BEGINdoAction
uchar *pMsg; /* temporary buffering */
@@ -265,7 +282,7 @@ CODESTARTdoAction
pMsg = ppString[0];
lenMsg = strlen((char*) pMsg); /* TODO: don't we get this? */
- /* TODO: think about handling oversize messages! */
+ /* we need to truncate oversize msgs - no way around that... */
if((int) lenMsg > glbl.GetMaxLine())
lenMsg = glbl.GetMaxLine();
@@ -274,9 +291,13 @@ CODESTARTdoAction
if(ret != RELP_RET_OK) {
/* error! */
dbgprintf("error forwarding via relp, suspending\n");
- iRet = RS_RET_SUSPENDED;
+ ABORT_FINALIZE(RS_RET_SUSPENDED);
}
+ if(pData->rebindInterval != 0 &&
+ (++pData->nSent >= pData->rebindInterval)) {
+ doRebind(pData);
+ }
finalize_it:
ENDdoAction
--
cgit v1.2.3
From bad876b26584379aba136a0e580e8ab6a5b95a6e Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Wed, 15 May 2013 12:08:54 +0200
Subject: clean up crypto provider state files on queue file close
---
runtime/cryprov.h | 1 +
runtime/libgcry.c | 5 +++++
runtime/libgcry.h | 9 +++++++++
runtime/lmcry_gcry.c | 7 +++++++
runtime/queue.c | 1 -
runtime/stream.c | 19 ++++++++++++++++++-
6 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/runtime/cryprov.h b/runtime/cryprov.h
index 66c1cfd1..a940d833 100644
--- a/runtime/cryprov.h
+++ b/runtime/cryprov.h
@@ -42,6 +42,7 @@ BEGINinterface(cryprov) /* name must also be changed in ENDinterface macro! */
rsRetVal (*Encrypt)(void *pFileInstData, uchar *buf, size_t *lenBuf);
rsRetVal (*Decrypt)(void *pFileInstData, uchar *buf, size_t *lenBuf);
rsRetVal (*OnFileClose)(void *pFileInstData, off64_t offsLogfile);
+ void (*SetDeleteOnClose)(void *pFileInstData, int val);
ENDinterface(cryprov)
#define cryprovCURR_IF_VERSION 3 /* increment whenever you change the interface structure! */
#endif /* #ifndef INCLUDED_CRYPROV_H */
diff --git a/runtime/libgcry.c b/runtime/libgcry.c
index 3fca50ec..57380243 100644
--- a/runtime/libgcry.c
+++ b/runtime/libgcry.c
@@ -344,7 +344,12 @@ gcryfileDestruct(gcryfile gf, off64_t offsLogfile)
if(gf == NULL)
goto done;
+dbgprintf("DDDD: cryprov closes file %s\n", gf->eiName);
eiClose(gf, offsLogfile);
+ if(gf->bDeleteOnClose) {
+ DBGPRINTF("unlink file '%s' due to bDeleteOnClose set\n", gf->eiName);
+ unlink((char*)gf->eiName);
+ }
free(gf->eiName);
free(gf);
done: return r;
diff --git a/runtime/libgcry.h b/runtime/libgcry.h
index 190f4737..7c704bcf 100644
--- a/runtime/libgcry.h
+++ b/runtime/libgcry.h
@@ -43,6 +43,7 @@ struct gcryfile_s {
uchar *readBuf;
int16_t readBufIdx;
int16_t readBufMaxIdx;
+ int8_t bDeleteOnClose; /* for queue support, similar to stream subsys */
};
int gcryGetKeyFromFile(char *fn, char **key, unsigned *keylen);
@@ -68,6 +69,14 @@ int gcryGetKeyFromProg(char *cmd, char **key, unsigned *keylen);
#define RSGCRY_FILETYPE_NAME "rsyslog-enrcyption-info"
#define ENCINFO_SUFFIX ".encinfo"
+/* Note: gf may validly be NULL, e.g. if file has not yet been opened! */
+static inline void
+gcryfileSetDeleteOnClose(gcryfile gf, int val)
+{
+ if(gf != NULL)
+ gf->bDeleteOnClose = val;
+}
+
static inline int
rsgcryAlgoname2Algo(char *algoname) {
if(!strcmp((char*)algoname, "3DES")) return GCRY_CIPHER_3DES;
diff --git a/runtime/lmcry_gcry.c b/runtime/lmcry_gcry.c
index decb8591..d30aeddc 100644
--- a/runtime/lmcry_gcry.c
+++ b/runtime/lmcry_gcry.c
@@ -209,6 +209,12 @@ finalize_it:
RETiRet;
}
+static void
+SetDeleteOnClose(void *pF, int val)
+{
+dbgprintf("DDDD: SetDeleteOnClose %d\n", val);
+ gcryfileSetDeleteOnClose(pF, val);
+}
static rsRetVal
OnFileOpen(void *pT, uchar *fn, void *pGF, char openMode)
@@ -262,6 +268,7 @@ CODESTARTobjQueryInterface(lmcry_gcry)
}
pIf->Construct = (rsRetVal(*)(void*)) lmcry_gcryConstruct;
pIf->SetCnfParam = SetCnfParam;
+ pIf->SetDeleteOnClose = SetDeleteOnClose;
pIf->Destruct = (rsRetVal(*)(void*)) lmcry_gcryDestruct;
pIf->OnFileOpen = OnFileOpen;
pIf->Encrypt = Encrypt;
diff --git a/runtime/queue.c b/runtime/queue.c
index 6af4905b..0f77bceb 100644
--- a/runtime/queue.c
+++ b/runtime/queue.c
@@ -2779,7 +2779,6 @@ qqueueApplyCnfParam(qqueue_t *pThis, struct nvlst *lst)
pThis->lenFilePrefix = es_strlen(pvals[i].val.d.estr);
} else if(!strcmp(pblk.descr[i].name, "queue.cry.provider")) {
pThis->cryprovName = (uchar*) es_str2cstr(pvals[i].val.d.estr, NULL);
-dbgprintf("DDDD: crypto provider set: '%s'\n", pThis->cryprovName);
} else if(!strcmp(pblk.descr[i].name, "queue.size")) {
pThis->iMaxQueueSize = pvals[i].val.d.n;
} else if(!strcmp(pblk.descr[i].name, "queue.dequeuebatchsize")) {
diff --git a/runtime/stream.c b/runtime/stream.c
index e411577f..19daaed6 100644
--- a/runtime/stream.c
+++ b/runtime/stream.c
@@ -259,6 +259,8 @@ doPhysOpen(strm_t *pThis)
CHKiRet(pThis->cryprov->OnFileOpen(pThis->cryprovData,
pThis->pszCurrFName, &pThis->cryprovFileData,
(pThis->tOperationsMode == STREAMMODE_READ) ? 'r' : 'w'));
+dbgprintf("DDDD: stream bDeleteOnClose %d\n", pThis->bDeleteOnClose);
+ pThis->cryprov->SetDeleteOnClose(pThis->cryprovFileData, pThis->bDeleteOnClose);
}
finalize_it:
RETiRet;
@@ -406,6 +408,12 @@ static rsRetVal strmCloseFile(strm_t *pThis)
}
}
+ /* if we have a signature provider, we must make sure that the crypto
+ * state files are opened and proper close processing happens. */
+ if(pThis->fd == -1) {
+ strmOpenFile(pThis);
+ }
+
/* the file may already be closed (or never have opened), so guard
* against this. -- rgerhards, 2010-03-19
*/
@@ -1611,7 +1619,6 @@ finalize_it:
/* property set methods */
/* simple ones first */
-DEFpropSetMeth(strm, bDeleteOnClose, int)
DEFpropSetMeth(strm, iMaxFileSize, int)
DEFpropSetMeth(strm, iFileNumDigits, int)
DEFpropSetMeth(strm, tOperationsMode, int)
@@ -1627,6 +1634,16 @@ DEFpropSetMeth(strm, pszSizeLimitCmd, uchar*)
DEFpropSetMeth(strm, cryprov, cryprov_if_t*)
DEFpropSetMeth(strm, cryprovData, void*)
+static rsRetVal strmSetbDeleteOnClose(strm_t *pThis, int val)
+{
+ pThis->bDeleteOnClose = val;
+ if(pThis->cryprov != NULL) {
+dbgprintf("DDDD: set stream bDeleteOnClose %d\n", pThis->bDeleteOnClose);
+ pThis->cryprov->SetDeleteOnClose(pThis->cryprovFileData, pThis->bDeleteOnClose);
+ }
+ return RS_RET_OK;
+}
+
static rsRetVal strmSetiMaxFiles(strm_t *pThis, int iNewVal)
{
pThis->iMaxFiles = iNewVal;
--
cgit v1.2.3
From 3382800afc3b078780ac492e0c4ddc91fbec3eb6 Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Wed, 15 May 2013 12:19:18 +0200
Subject: do not try to write to read-open encryption state file
---
runtime/libgcry.c | 10 ++++++----
runtime/libgcry.h | 2 +-
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/runtime/libgcry.c b/runtime/libgcry.c
index 57380243..bbf6e1e6 100644
--- a/runtime/libgcry.c
+++ b/runtime/libgcry.c
@@ -299,9 +299,11 @@ eiClose(gcryfile gf, off64_t offsLogfile)
size_t len;
if(gf->fd == -1)
return;
- /* 2^64 is 20 digits, so the snprintf buffer is large enough */
- len = snprintf(offs, sizeof(offs), "%lld", offsLogfile);
- eiWriteRec(gf, "END:", 4, offs, len);
+ if(gf->openMode == 'w') {
+ /* 2^64 is 20 digits, so the snprintf buffer is large enough */
+ len = snprintf(offs, sizeof(offs), "%lld", offsLogfile);
+ eiWriteRec(gf, "END:", 4, offs, len);
+ }
free(gf->readBuf);
close(gf->fd);
gf->fd = -1;
@@ -505,7 +507,7 @@ rsgcryInitCrypt(gcryctx ctx, gcryfile *pgf, uchar *fname, char openMode)
DEFiRet;
CHKiRet(gcryfileConstruct(ctx, &gf, fname));
- gf->mode = openMode;
+ gf->openMode = openMode;
gf->blkLength = gcry_cipher_get_algo_blklen(ctx->algo);
diff --git a/runtime/libgcry.h b/runtime/libgcry.h
index 7c704bcf..a3004a01 100644
--- a/runtime/libgcry.h
+++ b/runtime/libgcry.h
@@ -38,7 +38,7 @@ struct gcryfile_s {
size_t blkLength; /* size of low-level crypto block */
uchar *eiName; /* name of .encinfo file */
int fd; /* descriptor of .encinfo file (-1 if not open) */
- char mode; /* 'r': read, 'w': write */
+ char openMode; /* 'r': read, 'w': write */
gcryctx ctx;
uchar *readBuf;
int16_t readBufIdx;
--
cgit v1.2.3
From 9205c5541bf2ad524803f7feec0bdbad366566f3 Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Wed, 15 May 2013 12:59:11 +0200
Subject: clean up crypto provider state files on queue file rollover
---
runtime/cryprov.h | 1 +
runtime/libgcry.c | 17 +++++++++++++++++
runtime/libgcry.h | 1 +
runtime/lmcry_gcry.c | 8 +++++++-
runtime/stream.c | 6 +++---
5 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/runtime/cryprov.h b/runtime/cryprov.h
index a940d833..0c3053d4 100644
--- a/runtime/cryprov.h
+++ b/runtime/cryprov.h
@@ -43,6 +43,7 @@ BEGINinterface(cryprov) /* name must also be changed in ENDinterface macro! */
rsRetVal (*Decrypt)(void *pFileInstData, uchar *buf, size_t *lenBuf);
rsRetVal (*OnFileClose)(void *pFileInstData, off64_t offsLogfile);
void (*SetDeleteOnClose)(void *pFileInstData, int val);
+ rsRetVal (*DeleteStateFiles)(uchar *logfn);
ENDinterface(cryprov)
#define cryprovCURR_IF_VERSION 3 /* increment whenever you change the interface structure! */
#endif /* #ifndef INCLUDED_CRYPROV_H */
diff --git a/runtime/libgcry.c b/runtime/libgcry.c
index bbf6e1e6..0b3b8fc2 100644
--- a/runtime/libgcry.c
+++ b/runtime/libgcry.c
@@ -310,6 +310,23 @@ eiClose(gcryfile gf, off64_t offsLogfile)
DBGPRINTF("encryption info file %s: closed\n", gf->eiName);
}
+/* this is a special functon for use by the rsyslog disk queue subsystem. It
+ * needs to have the capability to delete state when a queue file is rolled
+ * over. This simply generates the file name and deletes it. It must take care
+ * of "all" state files, which currently happens to be a single one.
+ */
+rsRetVal
+gcryfileDeleteState(uchar *logfn)
+{
+ char fn[MAXFNAME+1];
+ DEFiRet;
+ snprintf(fn, sizeof(fn), "%s%s", logfn, ENCINFO_SUFFIX);
+ fn[MAXFNAME] = '\0'; /* be on save side */
+ DBGPRINTF("crypto provider deletes state file '%s' on request\n", fn);
+ unlink(fn);
+ RETiRet;
+}
+
static rsRetVal
gcryfileConstruct(gcryctx ctx, gcryfile *pgf, uchar *logfn)
{
diff --git a/runtime/libgcry.h b/runtime/libgcry.h
index a3004a01..819ac77c 100644
--- a/runtime/libgcry.h
+++ b/runtime/libgcry.h
@@ -59,6 +59,7 @@ rsRetVal rsgcryInitCrypt(gcryctx ctx, gcryfile *pgf, uchar *fname, char openMode
rsRetVal rsgcryEncrypt(gcryfile pF, uchar *buf, size_t *len);
rsRetVal rsgcryDecrypt(gcryfile pF, uchar *buf, size_t *len);
int gcryGetKeyFromProg(char *cmd, char **key, unsigned *keylen);
+rsRetVal gcryfileDeleteState(uchar *fn);
/* error states */
#define RSGCRYE_EI_OPEN 1 /* error opening .encinfo file */
diff --git a/runtime/lmcry_gcry.c b/runtime/lmcry_gcry.c
index d30aeddc..3941b06c 100644
--- a/runtime/lmcry_gcry.c
+++ b/runtime/lmcry_gcry.c
@@ -212,10 +212,15 @@ finalize_it:
static void
SetDeleteOnClose(void *pF, int val)
{
-dbgprintf("DDDD: SetDeleteOnClose %d\n", val);
gcryfileSetDeleteOnClose(pF, val);
}
+static void
+DeleteStateFiles(uchar *logfn)
+{
+ return gcryfileDeleteState(logfn);
+}
+
static rsRetVal
OnFileOpen(void *pT, uchar *fn, void *pGF, char openMode)
{
@@ -274,6 +279,7 @@ CODESTARTobjQueryInterface(lmcry_gcry)
pIf->Encrypt = Encrypt;
pIf->Decrypt = Decrypt;
pIf->OnFileClose = OnFileClose;
+ pIf->DeleteStateFiles = DeleteStateFiles;
finalize_it:
ENDobjQueryInterface(lmcry_gcry)
diff --git a/runtime/stream.c b/runtime/stream.c
index 19daaed6..ac97d484 100644
--- a/runtime/stream.c
+++ b/runtime/stream.c
@@ -259,7 +259,6 @@ doPhysOpen(strm_t *pThis)
CHKiRet(pThis->cryprov->OnFileOpen(pThis->cryprovData,
pThis->pszCurrFName, &pThis->cryprovFileData,
(pThis->tOperationsMode == STREAMMODE_READ) ? 'r' : 'w'));
-dbgprintf("DDDD: stream bDeleteOnClose %d\n", pThis->bDeleteOnClose);
pThis->cryprov->SetDeleteOnClose(pThis->cryprovFileData, pThis->bDeleteOnClose);
}
finalize_it:
@@ -410,7 +409,7 @@ static rsRetVal strmCloseFile(strm_t *pThis)
/* if we have a signature provider, we must make sure that the crypto
* state files are opened and proper close processing happens. */
- if(pThis->fd == -1) {
+ if(pThis->cryprov != NULL && pThis->fd == -1) {
strmOpenFile(pThis);
}
@@ -1469,6 +1468,8 @@ strmMultiFileSeek(strm_t *pThis, int FNum, off64_t offs, off64_t *bytesDel)
"deleting '%s' (%lld bytes)\n", pThis->iCurrFNum, FNum,
pThis->pszCurrFName, (long long) *bytesDel);
unlink((char*)pThis->pszCurrFName);
+ if(pThis->cryprov != NULL)
+ pThis->cryprov->DeleteStateFiles(pThis->pszCurrFName);
free(pThis->pszCurrFName);
pThis->pszCurrFName = NULL;
pThis->iCurrFNum = FNum;
@@ -1638,7 +1639,6 @@ static rsRetVal strmSetbDeleteOnClose(strm_t *pThis, int val)
{
pThis->bDeleteOnClose = val;
if(pThis->cryprov != NULL) {
-dbgprintf("DDDD: set stream bDeleteOnClose %d\n", pThis->bDeleteOnClose);
pThis->cryprov->SetDeleteOnClose(pThis->cryprovFileData, pThis->bDeleteOnClose);
}
return RS_RET_OK;
--
cgit v1.2.3
From 940bdc4c4117117beb7e34c84e5ea5bd3f441d4f Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Wed, 15 May 2013 18:49:07 +0200
Subject: enable ability to read existing encrypted queue file
---
runtime/queue.c | 11 ++++++++++-
runtime/stream.c | 20 ++++++++++++++++++--
2 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/runtime/queue.c b/runtime/queue.c
index 0f77bceb..d569318d 100644
--- a/runtime/queue.c
+++ b/runtime/queue.c
@@ -777,12 +777,21 @@ qqueueTryLoadPersistedInfo(qqueue_t *pThis)
(rsRetVal(*)(obj_t*,void*))qqueueLoadPersStrmInfoFixup, pThis));
CHKiRet(obj.Deserialize(&pThis->tVars.disk.pReadDel, (uchar*) "strm", psQIF,
(rsRetVal(*)(obj_t*,void*))qqueueLoadPersStrmInfoFixup, pThis));
-
/* create a duplicate for the read "pointer". */
CHKiRet(strm.Dup(pThis->tVars.disk.pReadDel, &pThis->tVars.disk.pReadDeq));
CHKiRet(strm.SetbDeleteOnClose(pThis->tVars.disk.pReadDeq, 0)); /* deq must NOT delete the files! */
CHKiRet(strm.ConstructFinalize(pThis->tVars.disk.pReadDeq));
+ /* if we use a crypto provider, we need to amend the objects with it's info */
+ if(pThis->useCryprov) {
+ CHKiRet(strm.Setcryprov(pThis->tVars.disk.pWrite, &pThis->cryprov));
+ CHKiRet(strm.SetcryprovData(pThis->tVars.disk.pWrite, pThis->cryprovData));
+ CHKiRet(strm.Setcryprov(pThis->tVars.disk.pReadDeq, &pThis->cryprov));
+ CHKiRet(strm.SetcryprovData(pThis->tVars.disk.pReadDeq, pThis->cryprovData));
+ CHKiRet(strm.Setcryprov(pThis->tVars.disk.pReadDel, &pThis->cryprov));
+ CHKiRet(strm.SetcryprovData(pThis->tVars.disk.pReadDel, pThis->cryprovData));
+ }
+dbgprintf("DDDD: seeking offsets (here we need crypto)\n");
CHKiRet(strm.SeekCurrOffs(pThis->tVars.disk.pWrite));
CHKiRet(strm.SeekCurrOffs(pThis->tVars.disk.pReadDel));
CHKiRet(strm.SeekCurrOffs(pThis->tVars.disk.pReadDeq));
diff --git a/runtime/stream.c b/runtime/stream.c
index ac97d484..0cac4f07 100644
--- a/runtime/stream.c
+++ b/runtime/stream.c
@@ -585,6 +585,7 @@ strmReadBuf(strm_t *pThis)
/* here we place our crypto interface */
if(pThis->cryprov != NULL) {
pThis->cryprov->Decrypt(pThis->cryprovFileData, pThis->pIOBuf, &iLenRead);
+dbgprintf("DDDD: data read, decrypted: %1024.1024s\n", pThis->pIOBuf);
}
pThis->iBufPtrMax = iLenRead;
bRun = 0; /* exit loop */
@@ -1483,17 +1484,32 @@ finalize_it:
}
-
/* seek to current offset. This is primarily a helper to readjust the OS file
* pointer after a strm object has been deserialized.
*/
static rsRetVal strmSeekCurrOffs(strm_t *pThis)
{
+ off64_t targetOffs;
+ uchar c;
DEFiRet;
ISOBJ_TYPE_assert(pThis, strm);
- iRet = strmSeek(pThis, pThis->iCurrOffs);
+dbgprintf("DDDD: seekCurrOffs file #%d, offs %lld\n", pThis->fd, (long long) pThis->iCurrOffs);
+ if(pThis->cryprov == NULL || pThis->tOperationsMode != STREAMMODE_READ) {
+ iRet = strmSeek(pThis, pThis->iCurrOffs);
+ FINALIZE;
+ }
+
+ targetOffs = pThis->iCurrOffs;
+ pThis->iCurrOffs = 0;
+dbgprintf("DDDD: skip read offs %lld, data: ", (long long) targetOffs);
+ while(targetOffs != pThis->iCurrOffs) {
+ CHKiRet(strmReadChar(pThis, &c));
+dbgprintf("%c", c);
+ }
+dbgprintf("\n");
+finalize_it:
RETiRet;
}
--
cgit v1.2.3
From 3aeafbdfadc73860a16dc965c14728a3e50a216c Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Thu, 16 May 2013 07:58:50 +0200
Subject: properly handle padding bytes when reading queue files
---
runtime/stream.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/runtime/stream.c b/runtime/stream.c
index 0cac4f07..a26f2451 100644
--- a/runtime/stream.c
+++ b/runtime/stream.c
@@ -559,11 +559,12 @@ finalize_it:
* rgerhards, 2008-02-13
*/
static rsRetVal
-strmReadBuf(strm_t *pThis)
+strmReadBuf(strm_t *pThis, int *padBytes)
{
DEFiRet;
int bRun;
long iLenRead;
+ size_t actualDataLen;
ISOBJ_TYPE_assert(pThis, strm);
/* We need to try read at least twice because we may run into EOF and need to switch files. */
@@ -584,8 +585,11 @@ strmReadBuf(strm_t *pThis)
else { /* good read */
/* here we place our crypto interface */
if(pThis->cryprov != NULL) {
- pThis->cryprov->Decrypt(pThis->cryprovFileData, pThis->pIOBuf, &iLenRead);
-dbgprintf("DDDD: data read, decrypted: %1024.1024s\n", pThis->pIOBuf);
+ actualDataLen = iLenRead;
+ pThis->cryprov->Decrypt(pThis->cryprovFileData, pThis->pIOBuf, &actualDataLen);
+ *padBytes = iLenRead - actualDataLen;
+ iLenRead = actualDataLen;
+dbgprintf("DDDD: data read (padBytes %d), decrypted: %1024.1024s\n", *padBytes, pThis->pIOBuf);
}
pThis->iBufPtrMax = iLenRead;
bRun = 0; /* exit loop */
@@ -608,6 +612,7 @@ finalize_it:
*/
static rsRetVal strmReadChar(strm_t *pThis, uchar *pC)
{
+ int padBytes = 0; /* in crypto mode, we may have some padding (non-data) bytes */
DEFiRet;
ASSERT(pThis != NULL);
@@ -623,8 +628,9 @@ static rsRetVal strmReadChar(strm_t *pThis, uchar *pC)
/* do we need to obtain a new buffer? */
if(pThis->iBufPtr >= pThis->iBufPtrMax) {
- CHKiRet(strmReadBuf(pThis));
+ CHKiRet(strmReadBuf(pThis, &padBytes));
}
+ pThis->iCurrOffs += padBytes;
/* if we reach this point, we have data available in the buffer */
@@ -1495,7 +1501,6 @@ static rsRetVal strmSeekCurrOffs(strm_t *pThis)
ISOBJ_TYPE_assert(pThis, strm);
-dbgprintf("DDDD: seekCurrOffs file #%d, offs %lld\n", pThis->fd, (long long) pThis->iCurrOffs);
if(pThis->cryprov == NULL || pThis->tOperationsMode != STREAMMODE_READ) {
iRet = strmSeek(pThis, pThis->iCurrOffs);
FINALIZE;
--
cgit v1.2.3
From afe14ce2f6a514d9e2bf43501f1a02008d9ddea6 Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Thu, 16 May 2013 09:49:22 +0200
Subject: complete handle multiple blocks in encrypted queue files
---
runtime/cryprov.h | 3 +-
runtime/libgcry.c | 151 +++++++++++++++++++++++++++++++++++++++------------
runtime/libgcry.h | 4 ++
runtime/lmcry_gcry.c | 9 ++-
runtime/rsyslog.h | 1 +
runtime/stream.c | 15 ++++-
6 files changed, 146 insertions(+), 37 deletions(-)
diff --git a/runtime/cryprov.h b/runtime/cryprov.h
index 0c3053d4..5690904d 100644
--- a/runtime/cryprov.h
+++ b/runtime/cryprov.h
@@ -42,8 +42,9 @@ BEGINinterface(cryprov) /* name must also be changed in ENDinterface macro! */
rsRetVal (*Encrypt)(void *pFileInstData, uchar *buf, size_t *lenBuf);
rsRetVal (*Decrypt)(void *pFileInstData, uchar *buf, size_t *lenBuf);
rsRetVal (*OnFileClose)(void *pFileInstData, off64_t offsLogfile);
- void (*SetDeleteOnClose)(void *pFileInstData, int val);
rsRetVal (*DeleteStateFiles)(uchar *logfn);
+ rsRetVal (*GetBytesLeftInBlock)(void *pFileInstData, ssize_t *left);
+ void (*SetDeleteOnClose)(void *pFileInstData, int val);
ENDinterface(cryprov)
#define cryprovCURR_IF_VERSION 3 /* increment whenever you change the interface structure! */
#endif /* #ifndef INCLUDED_CRYPROV_H */
diff --git a/runtime/libgcry.c b/runtime/libgcry.c
index 0b3b8fc2..d3ac629c 100644
--- a/runtime/libgcry.c
+++ b/runtime/libgcry.c
@@ -54,6 +54,8 @@
#define READBUF_SIZE 4096 /* size of the read buffer */
+static rsRetVal rsgcryBlkBegin(gcryfile gf);
+
static rsRetVal
eiWriteRec(gcryfile gf, char *recHdr, size_t lenRecHdr, char *buf, size_t lenBuf)
{
@@ -170,11 +172,13 @@ eiGetRecord(gcryfile gf, char *rectype, char *value)
int c;
DEFiRet;
+ c = eiReadChar(gf);
+ if(c == EOF) { ABORT_FINALIZE(RS_RET_NO_DATA); }
for(i = 0 ; i < EIF_MAX_RECTYPE_LEN ; ++i) {
- c = eiReadChar(gf);
if(c == ':' || c == EOF)
break;
rectype[i] = c;
+ c = eiReadChar(gf);
}
if(c != ':') { ABORT_FINALIZE(RS_RET_ERR); }
rectype[i] = '\0';
@@ -232,6 +236,23 @@ finalize_it:
RETiRet;
}
+static rsRetVal
+eiGetEND(gcryfile gf, off64_t *offs)
+{
+ char rectype[EIF_MAX_RECTYPE_LEN+1];
+ char value[EIF_MAX_VALUE_LEN+1];
+ DEFiRet;
+
+ CHKiRet(eiGetRecord(gf, rectype, value));
+ if(strcmp(rectype, "END")) {
+ DBGPRINTF("no END record found when expected, record type "
+ "seen is '%s'\n", rectype);
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ *offs = atoll(value);
+finalize_it:
+ RETiRet;
+}
static rsRetVal
eiOpenAppend(gcryfile gf)
@@ -304,12 +325,33 @@ eiClose(gcryfile gf, off64_t offsLogfile)
len = snprintf(offs, sizeof(offs), "%lld", offsLogfile);
eiWriteRec(gf, "END:", 4, offs, len);
}
+ gcry_cipher_close(gf->chd);
free(gf->readBuf);
close(gf->fd);
gf->fd = -1;
DBGPRINTF("encryption info file %s: closed\n", gf->eiName);
}
+/* this returns the number of bytes left inside the block or -1, if the block
+ * size is unbounded. The function automatically handles end-of-block and begins
+ * to read the next block in this case.
+ */
+rsRetVal
+gcryfileGetBytesLeftInBlock(gcryfile gf, ssize_t *left)
+{
+ DEFiRet;
+ if(gf->bytesToBlkEnd == 0) {
+ DBGPRINTF("libgcry: end of current crypto block\n");
+ gcry_cipher_close(gf->chd);
+ CHKiRet(rsgcryBlkBegin(gf));
+ }
+ *left = gf->bytesToBlkEnd;
+finalize_it:
+ // TODO: remove once this code is sufficiently well-proven
+ DBGPRINTF("gcryfileGetBytesLeftInBlock returns %lld, iRet %d\n", (long long) *left, iRet);
+ RETiRet;
+}
+
/* this is a special functon for use by the rsyslog disk queue subsystem. It
* needs to have the capability to delete state when a queue file is rolled
* over. This simply generates the file name and deletes it. It must take care
@@ -363,7 +405,7 @@ gcryfileDestruct(gcryfile gf, off64_t offsLogfile)
if(gf == NULL)
goto done;
-dbgprintf("DDDD: cryprov closes file %s\n", gf->eiName);
+ DBGPRINTF("libgcry: close file %s\n", gf->eiName);
eiClose(gf, offsLogfile);
if(gf->bDeleteOnClose) {
DBGPRINTF("unlink file '%s' due to bDeleteOnClose set\n", gf->eiName);
@@ -498,72 +540,111 @@ readIV(gcryfile gf, uchar **iv)
rsRetVal localRet;
DEFiRet;
- do {
- localRet = eiOpenRead(gf);
- if(localRet == RS_RET_EI_NO_EXISTS) {
- /* wait until it is created */
- srSleep(0, 10000);
- } else {
- CHKiRet(localRet);
+ if(gf->fd == -1) {
+ while(gf->fd == -1) {
+ localRet = eiOpenRead(gf);
+ if(localRet == RS_RET_EI_NO_EXISTS) {
+ /* wait until it is created */
+ srSleep(0, 10000);
+ } else {
+ CHKiRet(localRet);
+ }
}
- } while(localRet != RS_RET_OK);
- CHKiRet(eiCheckFiletype(gf));
+ CHKiRet(eiCheckFiletype(gf));
+ }
*iv = malloc(gf->blkLength); /* do NOT zero-out! */
CHKiRet(eiGetIV(gf, *iv, (size_t) gf->blkLength));
-dbgprintf("DDDD: read %d bytes of IV\n", (int) gf->blkLength);
finalize_it:
RETiRet;
}
-rsRetVal
-rsgcryInitCrypt(gcryctx ctx, gcryfile *pgf, uchar *fname, char openMode)
+/* this tries to read the END record. HOWEVER, no such record may be
+ * present, which is the case if we handle a currently-written to queue
+ * file. On the other hand, the queue file may contain multiple blocks. So
+ * what we do is try to see if there is a block end or not - and set the
+ * status accordingly. Note that once we found no end-of-block, we will never
+ * retry. This is because that case can never happen under current queue
+ * implementations. -- gerhards, 2013-05-16
+ */
+static inline rsRetVal
+readBlkEnd(gcryfile gf)
{
- gcry_error_t gcryError;
- gcryfile gf = NULL;
- uchar *iv = NULL;
+ off64_t blkEnd;
DEFiRet;
- CHKiRet(gcryfileConstruct(ctx, &gf, fname));
- gf->openMode = openMode;
+ iRet = eiGetEND(gf, &blkEnd);
+ if(iRet == RS_RET_OK) {
+ gf->bytesToBlkEnd = (ssize_t) blkEnd;
+ } else if(iRet == RS_RET_NO_DATA) {
+ gf->bytesToBlkEnd = -1;
+ } else {
+ FINALIZE;
+ }
+
+finalize_it:
+ RETiRet;
+}
- gf->blkLength = gcry_cipher_get_algo_blklen(ctx->algo);
- gcryError = gcry_cipher_open(&gf->chd, ctx->algo, ctx->mode, 0);
+/* Read the block begin metadata and set our state variables accordingly. Can also
+ * be used to init the first block in write case.
+ */
+static rsRetVal
+rsgcryBlkBegin(gcryfile gf)
+{
+ gcry_error_t gcryError;
+ uchar *iv = NULL;
+ DEFiRet;
+
+ gcryError = gcry_cipher_open(&gf->chd, gf->ctx->algo, gf->ctx->mode, 0);
if (gcryError) {
- dbgprintf("gcry_cipher_open failed: %s/%s\n",
- gcry_strsource(gcryError),
- gcry_strerror(gcryError));
+ DBGPRINTF("gcry_cipher_open failed: %s/%s\n",
+ gcry_strsource(gcryError), gcry_strerror(gcryError));
ABORT_FINALIZE(RS_RET_ERR);
}
gcryError = gcry_cipher_setkey(gf->chd, gf->ctx->key, gf->ctx->keyLen);
if (gcryError) {
- dbgprintf("gcry_cipher_setkey failed: %s/%s\n",
- gcry_strsource(gcryError),
- gcry_strerror(gcryError));
+ DBGPRINTF("gcry_cipher_setkey failed: %s/%s\n",
+ gcry_strsource(gcryError), gcry_strerror(gcryError));
ABORT_FINALIZE(RS_RET_ERR);
}
- if(openMode == 'r') {
+ if(gf->openMode == 'r') {
readIV(gf, &iv);
+ readBlkEnd(gf);
} else {
seedIV(gf, &iv);
}
gcryError = gcry_cipher_setiv(gf->chd, iv, gf->blkLength);
if (gcryError) {
- dbgprintf("gcry_cipher_setiv failed: %s/%s\n",
- gcry_strsource(gcryError),
- gcry_strerror(gcryError));
+ DBGPRINTF("gcry_cipher_setiv failed: %s/%s\n",
+ gcry_strsource(gcryError), gcry_strerror(gcryError));
ABORT_FINALIZE(RS_RET_ERR);
}
- if(openMode == 'w') {
+
+ if(gf->openMode == 'w') {
CHKiRet(eiOpenAppend(gf));
CHKiRet(eiWriteIV(gf, iv));
}
- *pgf = gf;
finalize_it:
free(iv);
+ RETiRet;
+}
+
+rsRetVal
+rsgcryInitCrypt(gcryctx ctx, gcryfile *pgf, uchar *fname, char openMode)
+{
+ gcryfile gf = NULL;
+ DEFiRet;
+
+ CHKiRet(gcryfileConstruct(ctx, &gf, fname));
+ gf->openMode = openMode;
+ gf->blkLength = gcry_cipher_get_algo_blklen(ctx->algo);
+ CHKiRet(rsgcryBlkBegin(gf));
+ *pgf = gf;
+finalize_it:
if(iRet != RS_RET_OK && gf != NULL)
gcryfileDestruct(gf, -1);
RETiRet;
@@ -601,6 +682,7 @@ rsgcryDecrypt(gcryfile pF, uchar *buf, size_t *len)
gcry_error_t gcryError;
DEFiRet;
+ pF->bytesToBlkEnd -= *len;
gcryError = gcry_cipher_decrypt(pF->chd, buf, *len, NULL, 0);
if(gcryError) {
DBGPRINTF("gcry_cipher_decrypt failed: %s/%s\n",
@@ -609,7 +691,8 @@ rsgcryDecrypt(gcryfile pF, uchar *buf, size_t *len)
ABORT_FINALIZE(RS_RET_ERR);
}
removePadding(buf, len);
-dbgprintf("DDDD: decrypted, buffer is now '%50.50s'\n", buf);
+ // TODO: remove dbgprintf once things are sufficently stable -- rgerhards, 2013-05-16
+ dbgprintf("libgcry: decrypted, bytesToBlkEnd %lld, buffer is now '%50.50s'\n", (long long) pF->bytesToBlkEnd, buf);
finalize_it:
RETiRet;
diff --git a/runtime/libgcry.h b/runtime/libgcry.h
index 819ac77c..2f700554 100644
--- a/runtime/libgcry.h
+++ b/runtime/libgcry.h
@@ -44,6 +44,9 @@ struct gcryfile_s {
int16_t readBufIdx;
int16_t readBufMaxIdx;
int8_t bDeleteOnClose; /* for queue support, similar to stream subsys */
+ ssize_t bytesToBlkEnd; /* number of bytes remaining in current crypto block
+ -1 means -> no end (still being writen to, queue files),
+ 0 means -> end of block, new one must be started. */
};
int gcryGetKeyFromFile(char *fn, char **key, unsigned *keylen);
@@ -60,6 +63,7 @@ rsRetVal rsgcryEncrypt(gcryfile pF, uchar *buf, size_t *len);
rsRetVal rsgcryDecrypt(gcryfile pF, uchar *buf, size_t *len);
int gcryGetKeyFromProg(char *cmd, char **key, unsigned *keylen);
rsRetVal gcryfileDeleteState(uchar *fn);
+rsRetVal gcryfileGetBytesLeftInBlock(gcryfile gf, ssize_t *left);
/* error states */
#define RSGCRYE_EI_OPEN 1 /* error opening .encinfo file */
diff --git a/runtime/lmcry_gcry.c b/runtime/lmcry_gcry.c
index 3941b06c..041cd581 100644
--- a/runtime/lmcry_gcry.c
+++ b/runtime/lmcry_gcry.c
@@ -215,7 +215,13 @@ SetDeleteOnClose(void *pF, int val)
gcryfileSetDeleteOnClose(pF, val);
}
-static void
+static rsRetVal
+GetBytesLeftInBlock(void *pF, ssize_t *left)
+{
+ return gcryfileGetBytesLeftInBlock((gcryfile) pF, left);
+}
+
+static rsRetVal
DeleteStateFiles(uchar *logfn)
{
return gcryfileDeleteState(logfn);
@@ -280,6 +286,7 @@ CODESTARTobjQueryInterface(lmcry_gcry)
pIf->Decrypt = Decrypt;
pIf->OnFileClose = OnFileClose;
pIf->DeleteStateFiles = DeleteStateFiles;
+ pIf->GetBytesLeftInBlock = GetBytesLeftInBlock;
finalize_it:
ENDobjQueryInterface(lmcry_gcry)
diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h
index e8c2eb68..179d93e6 100644
--- a/runtime/rsyslog.h
+++ b/runtime/rsyslog.h
@@ -415,6 +415,7 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_QUEUE_DISK_NO_FN = -2328,/**< disk queue configured, but filename not set */
/* up to 2350 reserved for 7.4 */
RS_RET_QUEUE_CRY_DISK_ONLY = -2351,/**< crypto provider only supported for disk-associated queues */
+ RS_RET_NO_DATA = -2352,/**< file has no data; more a state than a real error */
/* RainerScript error messages (range 1000.. 1999) */
RS_RET_SYSVAR_NOT_FOUND = 1001, /**< system variable could not be found (maybe misspelled) */
diff --git a/runtime/stream.c b/runtime/stream.c
index a26f2451..5b1e105c 100644
--- a/runtime/stream.c
+++ b/runtime/stream.c
@@ -565,6 +565,8 @@ strmReadBuf(strm_t *pThis, int *padBytes)
int bRun;
long iLenRead;
size_t actualDataLen;
+ size_t toRead;
+ ssize_t bytesLeft;
ISOBJ_TYPE_assert(pThis, strm);
/* We need to try read at least twice because we may run into EOF and need to switch files. */
@@ -575,7 +577,17 @@ strmReadBuf(strm_t *pThis, int *padBytes)
* rgerhards, 2008-02-13
*/
CHKiRet(strmOpenFile(pThis));
- iLenRead = read(pThis->fd, pThis->pIOBuf, pThis->sIOBufSize);
+ if(pThis->cryprov == NULL) {
+ toRead = pThis->sIOBufSize;
+ } else {
+ CHKiRet(pThis->cryprov->GetBytesLeftInBlock(pThis->cryprovFileData, &bytesLeft));
+ if(bytesLeft == -1 || bytesLeft > pThis->sIOBufSize) {
+ toRead = pThis->sIOBufSize;
+ } else {
+ toRead = (size_t) bytesLeft;
+ }
+ }
+ iLenRead = read(pThis->fd, pThis->pIOBuf, toRead);
DBGOPRINT((obj_t*) pThis, "file %d read %ld bytes\n", pThis->fd, iLenRead);
/* end crypto */
if(iLenRead == 0) {
@@ -1506,6 +1518,7 @@ static rsRetVal strmSeekCurrOffs(strm_t *pThis)
FINALIZE;
}
+ /* As the cryprov may use CBC or similiar things, we need to read skip data */
targetOffs = pThis->iCurrOffs;
pThis->iCurrOffs = 0;
dbgprintf("DDDD: skip read offs %lld, data: ", (long long) targetOffs);
--
cgit v1.2.3
From a336dc690f8e39ba10806b118c99e06f4b5dc862 Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Thu, 16 May 2013 10:01:02 +0200
Subject: cleanup
---
runtime/lmcry_gcry.c | 2 +-
runtime/queue.c | 1 -
runtime/stream.c | 10 +++++-----
3 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/runtime/lmcry_gcry.c b/runtime/lmcry_gcry.c
index 041cd581..9a0c0072 100644
--- a/runtime/lmcry_gcry.c
+++ b/runtime/lmcry_gcry.c
@@ -233,7 +233,7 @@ OnFileOpen(void *pT, uchar *fn, void *pGF, char openMode)
lmcry_gcry_t *pThis = (lmcry_gcry_t*) pT;
gcryfile *pgf = (gcryfile*) pGF;
DEFiRet;
-dbgprintf("DDDD: open file '%s', mode '%c'\n", fn, openMode);
+ DBGPRINTF("lmcry_gcry: open file '%s', mode '%c'\n", fn, openMode);
CHKiRet(rsgcryInitCrypt(pThis->ctx, pgf, fn, openMode));
finalize_it:
diff --git a/runtime/queue.c b/runtime/queue.c
index d569318d..699e2a66 100644
--- a/runtime/queue.c
+++ b/runtime/queue.c
@@ -791,7 +791,6 @@ qqueueTryLoadPersistedInfo(qqueue_t *pThis)
CHKiRet(strm.SetcryprovData(pThis->tVars.disk.pReadDel, pThis->cryprovData));
}
-dbgprintf("DDDD: seeking offsets (here we need crypto)\n");
CHKiRet(strm.SeekCurrOffs(pThis->tVars.disk.pWrite));
CHKiRet(strm.SeekCurrOffs(pThis->tVars.disk.pReadDel));
CHKiRet(strm.SeekCurrOffs(pThis->tVars.disk.pReadDeq));
diff --git a/runtime/stream.c b/runtime/stream.c
index 5b1e105c..3f42953e 100644
--- a/runtime/stream.c
+++ b/runtime/stream.c
@@ -581,7 +581,7 @@ strmReadBuf(strm_t *pThis, int *padBytes)
toRead = pThis->sIOBufSize;
} else {
CHKiRet(pThis->cryprov->GetBytesLeftInBlock(pThis->cryprovFileData, &bytesLeft));
- if(bytesLeft == -1 || bytesLeft > pThis->sIOBufSize) {
+ if(bytesLeft == -1 || bytesLeft > (ssize_t) pThis->sIOBufSize) {
toRead = pThis->sIOBufSize;
} else {
toRead = (size_t) bytesLeft;
@@ -601,7 +601,8 @@ strmReadBuf(strm_t *pThis, int *padBytes)
pThis->cryprov->Decrypt(pThis->cryprovFileData, pThis->pIOBuf, &actualDataLen);
*padBytes = iLenRead - actualDataLen;
iLenRead = actualDataLen;
-dbgprintf("DDDD: data read (padBytes %d), decrypted: %1024.1024s\n", *padBytes, pThis->pIOBuf);
+ DBGOPRINT((obj_t*) pThis, "encrypted file %d pad bytes %d, actual "
+ "data %ld\n", pThis->fd, *padBytes, iLenRead);
}
pThis->iBufPtrMax = iLenRead;
bRun = 0; /* exit loop */
@@ -1521,12 +1522,11 @@ static rsRetVal strmSeekCurrOffs(strm_t *pThis)
/* As the cryprov may use CBC or similiar things, we need to read skip data */
targetOffs = pThis->iCurrOffs;
pThis->iCurrOffs = 0;
-dbgprintf("DDDD: skip read offs %lld, data: ", (long long) targetOffs);
+ DBGOPRINT((obj_t*) pThis, "encrypted, doing skip read of %lld bytes\n",
+ (long long) targetOffs);
while(targetOffs != pThis->iCurrOffs) {
CHKiRet(strmReadChar(pThis, &c));
-dbgprintf("%c", c);
}
-dbgprintf("\n");
finalize_it:
RETiRet;
}
--
cgit v1.2.3
From c1c441562b545369b35efc0f6dead2eec1035457 Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Thu, 16 May 2013 10:04:04 +0200
Subject: fix regression on unencrypted queue files
---
runtime/stream.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/runtime/stream.c b/runtime/stream.c
index 3f42953e..53039056 100644
--- a/runtime/stream.c
+++ b/runtime/stream.c
@@ -603,6 +603,8 @@ strmReadBuf(strm_t *pThis, int *padBytes)
iLenRead = actualDataLen;
DBGOPRINT((obj_t*) pThis, "encrypted file %d pad bytes %d, actual "
"data %ld\n", pThis->fd, *padBytes, iLenRead);
+ } else {
+ *padBytes = 0;
}
pThis->iBufPtrMax = iLenRead;
bRun = 0; /* exit loop */
--
cgit v1.2.3
From e89e0c957420860425ea9b826c9f3dd5de8d3324 Mon Sep 17 00:00:00 2001
From: Rainer Gerhards
Date: Thu, 16 May 2013 10:05:14 +0200
Subject: fix handling of unbounded blocks
---
runtime/libgcry.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/runtime/libgcry.c b/runtime/libgcry.c
index d3ac629c..4772cf47 100644
--- a/runtime/libgcry.c
+++ b/runtime/libgcry.c
@@ -682,7 +682,8 @@ rsgcryDecrypt(gcryfile pF, uchar *buf, size_t *len)
gcry_error_t gcryError;
DEFiRet;
- pF->bytesToBlkEnd -= *len;
+ if(pF->bytesToBlkEnd != -1)
+ pF->bytesToBlkEnd -= *len;
gcryError = gcry_cipher_decrypt(pF->chd, buf, *len, NULL, 0);
if(gcryError) {
DBGPRINTF("gcry_cipher_decrypt failed: %s/%s\n",
--
cgit v1.2.3
From 127671fed1707e686e8d7b316b2641b663892fec Mon Sep 17 00:00:00 2001
From: Jan Gerhards
Date: Wed, 15 May 2013 10:47:54 +0200
Subject: doc: describe relp tls parameters
---
doc/imrelp.html | 5 ++++-
doc/omrelp.html | 9 ++++++---
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/doc/imrelp.html b/doc/imrelp.html
index 9f3e4875..bcf52414 100644
--- a/doc/imrelp.html
+++ b/doc/imrelp.html
@@ -28,12 +28,15 @@ nits outlined above, is a much more reliable solution than plain tcp
syslog and so it is highly suggested to use RELP instead of plain tcp.
Clients send messages to the RELP server via omrelp.
-Configuration Directives:
+Input Parameters:
- Ruleset <name>
Binds the specified ruleset to all RELP listeners.
- Port <port>
Starts a RELP server on selected port
+- tls (not mandatory, values "on","off", default "off")
+ If set to "on", the RELP connection will be encrypted by TLS, so that the data is protected against observers. Please note that both the client and the server must have set TLS to either "on" or "off". Other combinations lead to unpredictable results.
+
Caveats/Known Bugs: