summaryrefslogtreecommitdiff
path: root/net.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2008-03-29 12:14:33 +0100
committerMichael Biebl <biebl@debian.org>2008-03-29 12:14:33 +0100
commitdb2b679ef6aa0ac3d4679ad3e00a72993204ea78 (patch)
tree0f95fbe227c3276e051ac79a921045c533b06dda /net.c
parent2bff2e5d72345617f3b3e394ff28823067024f7a (diff)
downloadrsyslog-db2b679ef6aa0ac3d4679ad3e00a72993204ea78.tar.gz
Imported Upstream version 1.19.7upstream/1.19.7
Diffstat (limited to 'net.c')
-rw-r--r--net.c102
1 files changed, 74 insertions, 28 deletions
diff --git a/net.c b/net.c
index bf0e468..bcefad4 100644
--- a/net.c
+++ b/net.c
@@ -65,8 +65,9 @@ int should_use_so_bsdcompat(void)
init_done = 1;
if (uname(&utsname) < 0) {
- dbgprintf("uname: %s\r\n", strerror(errno));
- return 1;
+ char errStr[1024];
+ dbgprintf("uname: %s\r\n", strerror_r(errno, errStr, sizeof(errStr)));
+ return 1;
}
/* Format is <version>.<patchlevel>.<sublevel><extraversion>
where the first three are unsigned integers and the last
@@ -92,14 +93,11 @@ int should_use_so_bsdcompat(void)
#endif
-/* Return a printable representation of a host address.
- * Now (2007-07-16) also returns the full host name (if it could be obtained)
- * in the second param [thanks to mildew@gmail.com for the patch].
- * The caller must provide buffer space for pszHost and pszHostFQDN. These
- * buffers must be of size NI_MAXHOST. This is not checked here, because
- * there is no way to check it. We use this way of doing things because it
- * frees us from using dynamic memory allocation where it really does not
- * pay.
+/* get the hostname of the message source. This was originally in cvthname()
+ * but has been moved out of it because of clarity and fuctional separation.
+ * It must be provided by the socket we received the message on as well as
+ * a NI_MAXHOST size large character buffer for the FQDN.
+ *
* Please see http://www.hmug.org/man/3/getnameinfo.php (under Caveats)
* for some explanation of the code found below. We do by default not
* discard message where we detected malicouos DNS PTR records. However,
@@ -107,16 +105,16 @@ int should_use_so_bsdcompat(void)
* we should abort. For this, the return value tells the caller if the
* message should be processed (1) or discarded (0).
*/
-int cvthname(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN)
+/* TODO: after the bughunt, make this function static - rgerhards, 2007-09-18 */
+rsRetVal gethname(struct sockaddr_storage *f, uchar *pszHostFQDN)
{
- register uchar *p;
- int count, error;
+ DEFiRet;
+ int error;
sigset_t omask, nmask;
char ip[NI_MAXHOST];
struct addrinfo hints, *res;
assert(f != NULL);
- assert(pszHost != NULL);
assert(pszHostFQDN != NULL);
error = getnameinfo((struct sockaddr *)f, SALEN((struct sockaddr *)f),
@@ -124,17 +122,16 @@ int cvthname(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN)
if (error) {
dbgprintf("Malformed from address %s\n", gai_strerror(error));
- strcpy((char*) pszHost, "???");
strcpy((char*) pszHostFQDN, "???");
- return 1;
+ ABORT_FINALIZE(RS_RET_INVALID_SOURCE);
}
if (!DisableDNS) {
sigemptyset(&nmask);
sigaddset(&nmask, SIGHUP);
- sigprocmask(SIG_BLOCK, &nmask, &omask);
+ pthread_sigmask(SIG_BLOCK, &nmask, &omask);
- error = getnameinfo((struct sockaddr *)f, sizeof(*f),
+ error = getnameinfo((struct sockaddr *)f, SALEN((struct sockaddr *) f),
(char*)pszHostFQDN, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
if (error == 0) {
@@ -143,7 +140,7 @@ int cvthname(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN)
hints.ai_socktype = SOCK_DGRAM;
/* we now do a lookup once again. This one should fail,
- * because we should not have obtained a numeric address. If
+ * because we should not have obtained a non-numeric address. If
* we got a numeric one, someone messed with DNS!
*/
if (getaddrinfo ((char*)pszHostFQDN, NULL, &hints, &res) == 0) {
@@ -164,12 +161,13 @@ int cvthname(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN)
"IP = \"%s\" HOST = \"%s\"",
ip, pszHostFQDN);
logerror((char*)szErrMsg);
- return 0;
+ pthread_sigmask(SIG_SETMASK, &omask, NULL);
+ ABORT_FINALIZE(RS_RET_MALICIOUS_ENTITY);
}
/* Please note: we deal with a malicous entry. Thus, we have crafted
* the snprintf() below so that all text is in front of the entry - maybe
- * it would contain characters that would make the message unreadble
+ * it contains characters that make the message unreadable
* (OK, I admit this is more or less impossible, but I am paranoid...)
* rgerhards, 2007-07-16
*/
@@ -182,16 +180,48 @@ int cvthname(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN)
error = 1; /* that will trigger using IP address below. */
}
}
- sigprocmask(SIG_SETMASK, &omask, NULL);
+ pthread_sigmask(SIG_SETMASK, &omask, NULL);
}
if (error || DisableDNS) {
dbgprintf("Host name for your address (%s) unknown\n", ip);
strcpy((char*) pszHostFQDN, ip);
- strcpy((char*) pszHost, ip);
- return 1;
+ ABORT_FINALIZE(RS_RET_ADDRESS_UNKNOWN);
}
+finalize_it:
+ return iRet;
+}
+/* Return a printable representation of a host address.
+ * Now (2007-07-16) also returns the full host name (if it could be obtained)
+ * in the second param [thanks to mildew@gmail.com for the patch].
+ * The caller must provide buffer space for pszHost and pszHostFQDN. These
+ * buffers must be of size NI_MAXHOST. This is not checked here, because
+ * there is no way to check it. We use this way of doing things because it
+ * frees us from using dynamic memory allocation where it really does not
+ * pay.
+ */
+rsRetVal cvthname(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN)
+{
+ DEFiRet;
+ register uchar *p;
+ int count;
+
+ assert(f != NULL);
+ assert(pszHost != NULL);
+ assert(pszHostFQDN != NULL);
+
+ iRet = gethname(f, pszHostFQDN);
+
+ if(iRet == RS_RET_INVALID_SOURCE || iRet == RS_RET_ADDRESS_UNKNOWN) {
+ strcpy((char*) pszHost, (char*) pszHostFQDN); /* we use whatever was provided as replacement */
+ ABORT_FINALIZE(RS_RET_OK); /* this is handled, we are happy with it */
+ } else if(iRet != RS_RET_OK) {
+ FINALIZE; /* we return whatever error state we have - can not handle it */
+ }
+
+ /* if we reach this point, we obtained a non-numeric hostname and can now process it */
+
/* Convert to lower case, just like LocalDomain above
*/
for (p = pszHostFQDN ; *p ; p++)
@@ -202,14 +232,21 @@ int cvthname(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN)
* part if we were instructed to do so.
*/
/* TODO: quick and dirty right now: we need to optimize that. We simply
- * copy over the buffer and then use the old code.
+ * copy over the buffer and then use the old code. In the long term, that should
+ * be placed in its own function and probably outside of the net module (at least
+ * if should no longer reley on syslogd.c's global config-setting variables).
+ * Note that the old code always removes the local domain. We may want to
+ * make this in option in the long term. (rgerhards, 2007-09-11)
*/
strcpy((char*)pszHost, (char*)pszHostFQDN);
- if ((p = (uchar*) strchr((char*)pszHost, '.'))) {
+ if ((p = (uchar*) strchr((char*)pszHost, '.'))) { /* find start of domain name "machine.example.com" */
if(strcmp((char*) (p + 1), LocalDomain) == 0) {
*p = '\0'; /* simply terminate the string */
return 1;
} else {
+ /* now check if we belong to any of the domain names that were specified
+ * in the -s command line option. If so, remove and we are done.
+ */
if (StripDomains) {
count=0;
while (StripDomains[count]) {
@@ -220,7 +257,14 @@ int cvthname(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN)
count++;
}
}
- /* TODO: bug in syslogd? That all doesn't make so much sense... rger 2007-07-16 */
+ /* if we reach this point, we have not found any domain we should strip. Now
+ * we try and see if the host itself is listed in the -l command line option
+ * and so should be stripped also. If so, we do it and return. Please note that
+ * -l list FQDNs, not just the hostname part. If it did just list the hostname, the
+ * door would be wide-open for all kinds of mixing up of hosts. Because of this,
+ * you'll see comparison against the full string (pszHost) below. The termination
+ * still occurs at *p, which points at the first dot after the hostname.
+ */
if (LocalHosts) {
count=0;
while (LocalHosts[count]) {
@@ -233,7 +277,9 @@ int cvthname(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN)
}
}
}
- return 1;
+
+finalize_it:
+ return iRet;
}
#endif /* #ifdef SYSLOG_INET */