1 /* msg.h
2  * Header file for all msg-related functions.
3  *
4  * File begun on 2007-07-13 by RGerhards (extracted from syslogd.c)
5  *
6  * Copyright 2007-2018 Rainer Gerhards and Adiscon GmbH.
7  *
8  * This file is part of the rsyslog runtime library.
9  *
10  * The rsyslog runtime library is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * The rsyslog runtime library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with the rsyslog runtime library.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  * A copy of the GPL can be found in the file "COPYING" in this distribution.
24  * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution.
25  */
26 #include "template.h" /* this is a quirk, but these two are too interdependant... */
27 
28 #ifndef	MSG_H_INCLUDED
29 #define	MSG_H_INCLUDED 1
30 
31 #include <pthread.h>
32 #include <libestr.h>
33 #include <stdint.h>
34 #include <json.h>
35 #include "obj.h"
36 #include "syslogd-types.h"
37 #include "template.h"
38 #include "atomic.h"
39 
40 /* rgerhards 2004-11-08: The following structure represents a
41  * syslog message.
42  *
43  * Important Note:
44  * The message object is used for multiple purposes (once it
45  * has been created). Once created, it actully is a read-only
46  * object (though we do not specifically express this). In order
47  * to avoid multiple copies of the same object, we use a
48  * reference counter. This counter is set to 1 by the constructer
49  * and increased by 1 with a call to MsgAddRef(). The destructor
50  * checks the reference count. If it is more than 1, only the counter
51  * will be decremented. If it is 1, however, the object is actually
52  * destroyed. To make this work, it is vital that MsgAddRef() is
53  * called each time a "copy" is stored somewhere.
54  *
55  * WARNING: this structure is not calloc()ed, so be careful when
56  * adding new fields. You need to initialize them in
57  * msgBaseConstruct(). That function header comment also describes
58  * why this is the case.
59  */
60 struct msg {
61 	BEGINobjInstance;	/* Data to implement generic object - MUST be the first data element! */
62 	flowControl_t flowCtlType;
63 	/**< type of flow control we can apply, for enqueueing, needs not to be persisted because
64 				        once data has entered the queue, this property is no longer needed. */
65 	pthread_mutex_t mut;
66 	int	iRefCount;	/* reference counter (0 = unused) */
67 	sbool	bParseSuccess;	/* set to reflect state of last executed higher level parser */
68 	unsigned short	iSeverity;/* the severity  */
69 	unsigned short	iFacility;/* Facility code */
70 	int offAfterPRI;	/* offset, at which raw message WITHOUT PRI part starts in pszRawMsg */
71 	int offMSG;		/* offset at which the MSG part starts in pszRawMsg */
72 	short	iProtocolVersion;/* protocol version of message received 0 - legacy, 1 syslog-protocol) */
73 	int	msgFlags;	/* flags associated with this message */
74 	int	iLenRawMsg;	/* length of raw message */
75 	int	iLenMSG;	/* Length of the MSG part */
76 	int	iLenTAG;	/* Length of the TAG part */
77 	int	iLenHOSTNAME;	/* Length of HOSTNAME */
78 	int	iLenPROGNAME;	/* Length of PROGNAME (-1 = not yet set) */
79 	uchar	*pszRawMsg;	/* message as it was received on the wire. This is important in case we
80 				 * need to preserve cryptographic verifiers.  */
81 	uchar	*pszHOSTNAME;	/* HOSTNAME from syslog message */
82 	char *pszRcvdAt3164;	/* time as RFC3164 formatted string (always 15 characters) */
83 	char *pszRcvdAt3339;	/* time as RFC3164 formatted string (32 characters at most) */
84 	char *pszRcvdAt_MySQL;	/* rcvdAt as MySQL formatted string (always 14 characters) */
85 	char *pszRcvdAt_PgSQL;  /* rcvdAt as PgSQL formatted string (always 21 characters) */
86 	char *pszTIMESTAMP3164;	/* TIMESTAMP as RFC3164 formatted string (always 15 characters) */
87 	char *pszTIMESTAMP3339;	/* TIMESTAMP as RFC3339 formatted string (32 characters at most) */
88 	char *pszTIMESTAMP_MySQL;/* TIMESTAMP as MySQL formatted string (always 14 characters) */
89 	char *pszTIMESTAMP_PgSQL;/* TIMESTAMP as PgSQL formatted string (always 21 characters) */
90 	uchar *pszStrucData;    /* STRUCTURED-DATA */
91 	uint16_t lenStrucData;	/* (cached) length of STRUCTURED-DATA */
92 	cstr_t *pCSAPPNAME;	/* APP-NAME */
93 	cstr_t *pCSPROCID;	/* PROCID */
94 	cstr_t *pCSMSGID;	/* MSGID */
95 	prop_t *pInputName;	/* input name property */
96 	prop_t *pRcvFromIP;	/* IP of system message was received from */
97 	union {
98 		prop_t *pRcvFrom;/* name of system message was received from */
99 		struct sockaddr_storage *pfrominet; /* unresolved name */
100 	} rcvFrom;
101 
102 	ruleset_t *pRuleset;	/* ruleset to be used for processing this message */
103 	time_t ttGenTime;	/* time msg object was generated, same as tRcvdAt, but a Unix timestamp.
104 				   While this field looks redundant, it is required because a Unix timestamp
105 				   is used at later processing stages (namely in the output arena). Thanks to
106 				   the subleties of how time is defined, there is no reliable way to reconstruct
107 				   the Unix timestamp from the syslogTime fields (in practice, we may be close
108 				   enough to reliable, but I prefer to leave the subtle things to the OS, where
109 				   it obviously is solved in way or another...). */
110 	struct syslogTime tRcvdAt;/* time the message entered this program */
111 	struct syslogTime tTIMESTAMP;/* (parsed) value of the timestamp */
112 	struct json_object *json;
113 	struct json_object *localvars;
114 	/* some fixed-size buffers to save malloc()/free() for frequently used fields (from the default templates) */
115 	uchar szRawMsg[CONF_RAWMSG_BUFSIZE];
116 	/* most messages are small, and these are stored here (without malloc/free!) */
117 	uchar szHOSTNAME[CONF_HOSTNAME_BUFSIZE];
118 	union {
119 		uchar	*ptr;	/* pointer to progname value */
120 		uchar	szBuf[CONF_PROGNAME_BUFSIZE];
121 	} PROGNAME;
122 	union {
123 		uchar	*pszTAG;	/* pointer to tag value */
124 		uchar	szBuf[CONF_TAG_BUFSIZE];
125 	} TAG;
126 	char pszTimestamp3164[CONST_LEN_TIMESTAMP_3164 + 1];
127 	char pszTimestamp3339[CONST_LEN_TIMESTAMP_3339 + 1];
128 	char pszTIMESTAMP_SecFrac[7];
129 	/* Note: a pointer is 64 bits/8 char, so this is actually fewer than a pointer! */
130 	char pszRcvdAt_SecFrac[7];
131 	/* same as above. Both are fractional seconds for their respective timestamp */
132 	char pszTIMESTAMP_Unix[12]; /* almost as small as a pointer! */
133 	char pszRcvdAt_Unix[12];
134 	char dfltTZ[8];	    /* 7 chars max, less overhead than ptr! */
135 	uchar *pszUUID; /* The message's UUID */
136 };
137 
138 
139 /* message flags (msgFlags), not an enum for historical reasons */
140 #define NOFLAG		0x000
141 /* no flag is set (to be used when a flag must be specified and none is required) */
142 #define INTERNAL_MSG	0x001
143 /* msg generated by logmsgInternal() --> special handling */
144 /* 0x002 not used because it was previously a known value - rgerhards, 2008-10-09 */
145 #define IGNDATE		0x004
146 /* ignore, if given, date in message and use date of reception as msg date */
147 #define MARK		0x008
148 /* this message is a mark */
149 #define NEEDS_PARSING	0x010
150 /* raw message, must be parsed before processing can be done */
151 #define PARSE_HOSTNAME	0x020
152 /* parse the hostname during message parsing */
153 #define NEEDS_DNSRESOL	0x040
154 /* fromhost address is unresolved and must be locked up via DNS reverse lookup first */
155 #define NEEDS_ACLCHK_U	0x080
156 /* check UDP ACLs after DNS resolution has been done in main queue consumer */
157 #define NO_PRI_IN_RAW	0x100
158 /* rawmsg does not include a PRI (Solaris!), but PRI is already set correctly in the msg object */
159 #define PRESERVE_CASE	0x200
160 /* preserve case in fromhost */
161 
162 /* (syslog) protocol types */
163 #define MSG_LEGACY_PROTOCOL 0
164 #define MSG_RFC5424_PROTOCOL 1
165 
166 #define MAX_VARIABLE_NAME_LEN 1024
167 
168 /* function prototypes
169  */
170 PROTOTYPEObjClassInit(msg);
171 rsRetVal msgConstruct(smsg_t **ppThis);
172 rsRetVal msgConstructWithTime(smsg_t **ppThis, const struct syslogTime *stTime, const time_t ttGenTime);
173 rsRetVal msgConstructForDeserializer(smsg_t **ppThis);
174 rsRetVal msgConstructFinalizer(smsg_t *pThis);
175 rsRetVal msgDestruct(smsg_t **ppM);
176 smsg_t * MsgDup(smsg_t * pOld);
177 smsg_t *MsgAddRef(smsg_t *pM);
178 void setProtocolVersion(smsg_t *pM, int iNewVersion);
179 void MsgSetInputName(smsg_t *pMsg, prop_t*);
180 void MsgSetDfltTZ(smsg_t *pThis, char *tz);
181 rsRetVal MsgSetAPPNAME(smsg_t *pMsg, const char* pszAPPNAME);
182 rsRetVal MsgSetPROCID(smsg_t *pMsg, const char* pszPROCID);
183 rsRetVal MsgSetMSGID(smsg_t *pMsg, const char* pszMSGID);
184 void MsgSetParseSuccess(smsg_t *pMsg, int bSuccess);
185 void MsgSetTAG(smsg_t *pMsg, const uchar* pszBuf, const size_t lenBuf);
186 void MsgSetRuleset(smsg_t *pMsg, ruleset_t*);
187 rsRetVal MsgSetFlowControlType(smsg_t *pMsg, flowControl_t eFlowCtl);
188 rsRetVal MsgSetStructuredData(smsg_t *const pMsg, const char* pszStrucData);
189 rsRetVal MsgAddToStructuredData(smsg_t *pMsg, uchar *toadd, rs_size_t len);
190 void MsgGetStructuredData(smsg_t *pM, uchar **pBuf, rs_size_t *len);
191 rsRetVal msgSetFromSockinfo(smsg_t *pThis, struct sockaddr_storage *sa);
192 void MsgSetRcvFrom(smsg_t *pMsg, prop_t*);
193 void MsgSetRcvFromStr(smsg_t *const pMsg, const uchar* pszRcvFrom, const int, prop_t **);
194 rsRetVal MsgSetRcvFromIP(smsg_t *pMsg, prop_t*);
195 rsRetVal MsgSetRcvFromIPStr(smsg_t *const pThis, const uchar *psz, const int len, prop_t **ppProp);
196 void MsgSetHOSTNAME(smsg_t *pMsg, const uchar* pszHOSTNAME, const int lenHOSTNAME);
197 rsRetVal MsgSetAfterPRIOffs(smsg_t *pMsg, int offs);
198 void MsgSetMSGoffs(smsg_t *pMsg, int offs);
199 void MsgSetRawMsgWOSize(smsg_t *pMsg, char* pszRawMsg);
200 void ATTR_NONNULL() MsgSetRawMsg(smsg_t *const pThis, const char*const pszRawMsg, const size_t lenMsg);
201 rsRetVal MsgReplaceMSG(smsg_t *pThis, const uchar* pszMSG, int lenMSG);
202 uchar *MsgGetProp(smsg_t *pMsg, struct templateEntry *pTpe, msgPropDescr_t *pProp,
203 		  rs_size_t *pPropLen, unsigned short *pbMustBeFreed, struct syslogTime *ttNow);
204 uchar *getRcvFrom(smsg_t *pM);
205 void getTAG(smsg_t *pM, uchar **ppBuf, int *piLen, sbool);
206 const char *getTimeReported(smsg_t *pM, enum tplFormatTypes eFmt);
207 const char *getPRI(smsg_t *pMsg);
208 int getPRIi(const smsg_t * const pM);
209 int ATTR_NONNULL() getRawMsgLen(const smsg_t *const pMsg);
210 void getRawMsg(const smsg_t *pM, uchar **pBuf, int *piLen);
211 void ATTR_NONNULL() MsgTruncateToMaxSize(smsg_t *const pThis);
212 rsRetVal msgAddJSON(smsg_t *pM, uchar *name, struct json_object *json, int force_reset, int sharedReference);
213 rsRetVal msgAddMetadata(smsg_t *msg, uchar *metaname, uchar *metaval);
214 rsRetVal msgAddMultiMetadata(smsg_t *msg, const uchar **metaname, const uchar **metaval, const int count);
215 rsRetVal MsgGetSeverity(smsg_t *pThis, int *piSeverity);
216 rsRetVal MsgDeserialize(smsg_t *pMsg, strm_t *pStrm);
217 rsRetVal MsgSetPropsViaJSON(smsg_t *__restrict__ const pMsg, const uchar *__restrict__ const json);
218 rsRetVal MsgSetPropsViaJSON_Object(smsg_t *__restrict__ const pMsg, struct json_object *json);
219 const uchar* msgGetJSONMESG(smsg_t *__restrict__ const pMsg);
220 
221 uchar *getMSG(smsg_t *pM);
222 const char *getHOSTNAME(smsg_t *pM);
223 char *getPROCID(smsg_t *pM, sbool bLockMutex);
224 char *getAPPNAME(smsg_t *pM, sbool bLockMutex);
225 void setMSGLen(smsg_t *pM, int lenMsg);
226 int getMSGLen(smsg_t *pM);
227 void getInputName(const smsg_t * const pM, uchar **ppsz, int *const plen);
228 
229 int getHOSTNAMELen(smsg_t *pM);
230 uchar *getProgramName(smsg_t *pM, sbool bLockMutex);
231 uchar *getRcvFrom(smsg_t *pM);
232 rsRetVal propNameToID(const uchar *pName, propid_t *pPropID);
233 uchar *propIDToName(propid_t propID);
234 rsRetVal ATTR_NONNULL() msgCheckVarExists(smsg_t *const pMsg, msgPropDescr_t *pProp);
235 rsRetVal msgGetJSONPropJSON(smsg_t *pMsg, msgPropDescr_t *pProp, struct json_object **pjson);
236 rsRetVal msgGetJSONPropJSONorString(smsg_t * const pMsg, msgPropDescr_t *pProp, struct json_object **pjson,
237 uchar **pcstr);
238 rsRetVal getJSONPropVal(smsg_t *pMsg, msgPropDescr_t *pProp, uchar **pRes, rs_size_t *buflen,
239 unsigned short *pbMustBeFreed);
240 rsRetVal msgSetJSONFromVar(smsg_t *pMsg, uchar *varname, struct svar *var, int force_reset);
241 rsRetVal msgDelJSON(smsg_t *pMsg, uchar *varname);
242 rsRetVal jsonFind(smsg_t *const pMsg, msgPropDescr_t *pProp, struct json_object **jsonres);
243 struct json_object *jsonDeepCopy(struct json_object *src);
244 
245 rsRetVal msgPropDescrFill(msgPropDescr_t *pProp, uchar *name, int nameLen);
246 void msgPropDescrDestruct(msgPropDescr_t *pProp);
247 void msgSetPRI(smsg_t *const __restrict__ pMsg, syslog_pri_t pri);
248 
249 #define msgGetProtocolVersion(pM) ((pM)->iProtocolVersion)
250 
251 /* returns non-zero if the message has structured data, 0 otherwise */
252 #define MsgHasStructuredData(pM) (((pM)->pszStrucData == NULL) ? 0 : 1)
253 
254 /* ------------------------------ some inline functions ------------------------------ */
255 
256 /* add Metadata to the message. This is stored in a special JSON
257  * container. Note that only string types are currently supported,
258  * what should pose absolutely no problem with the string-ish nature
259  * of rsyslog metadata.
260  * added 2015-01-09 rgerhards
261  */
262 /* set raw message size. This is needed in some cases where a trunctation is necessary
263  * but the raw message must not be newly set. The most important (and currently only)
264  * use case is if we remove trailing LF or NUL characters. Note that the size can NOT
265  * be extended, only shrunk!
266  * rgerhards, 2009-08-26
267  */
268 static inline void __attribute__((unused))
MsgSetRawMsgSize(smsg_t * const __restrict__ pMsg,const size_t newLen)269 MsgSetRawMsgSize(smsg_t *const __restrict__ pMsg, const size_t newLen)
270 {
271 	assert(newLen <= (size_t) pMsg->iLenRawMsg);
272 	pMsg->iLenRawMsg = newLen;
273 	pMsg->pszRawMsg[newLen] = '\0';
274 }
275 
276 /* get the ruleset that is associated with the ruleset.
277  * May be NULL. -- rgerhards, 2009-10-27
278  */
279 #define MsgGetRuleset(pMsg) ((pMsg)->pRuleset)
280 
281 #endif /* #ifndef MSG_H_INCLUDED */
282