OSSP CVS Repository

ossp - Check-in [1016]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 1016
Date: 2001-Sep-14 21:11:00 (local)
2001-Sep-14 19:11:00 (UTC)
User:rse
Branch:
Comment: Revamp Syslog output channel. It now fully supports local AND remote logging. The local variant is still based on syslog(3), the remote variant is based on manual network connections with the syslog protocol as defined in RFC3164.
Tickets:
Inspections:
Files:
ossp-pkg/l2/l2_ch_syslog.c      1.20 -> 1.21     243 inserted, 28 deleted
ossp-pkg/l2/l2_test.c      1.22 -> 1.23     2 inserted, 2 deleted

ossp-pkg/l2/l2_ch_syslog.c 1.20 -> 1.21

--- l2_ch_syslog.c       2001/09/12 09:42:34     1.20
+++ l2_ch_syslog.c       2001/09/14 19:11:00     1.21
@@ -28,33 +28,123 @@
 */
 
 #include "l2.h"
+#include "l2_p.h"
 
 #include <syslog.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <unistd.h>
 
 /* declare private channel configuration */
 typedef struct {
-    char *pszIdent; /* String to prepend to each syslog message */
-    int iLogopt;    /* Manipulates how kernel interacts with syslogd */
-    int iFacility;  /* Which part of the system generates this message */
-    int iPriority;  /* EMERG, ALERT, CRIT, ERR, WARNING, NOTICE, INFO... */
-    int iMaskpri;   /* Controls which priorities are or are not logged */
+    char      *szTarget;
+    char      *szRemoteHost;
+    int        nRemotePort;
+    char      *szLocalHost;
+    char      *szFacility;
+    int        nFacility;
+    char      *szIdent;
+    int        bLogPid;
+    sa_t      *saRemoteSock;
+    sa_addr_t *saaRemoteAddr;
 } l2_ch_syslog_t;
 
+/* mapping from L2 log levels to syslog(3) log levels */
+static struct {
+    int levelL2;
+    int levelSL;
+} l2_ch_syslog_L2toSL[] = {
+    { L2_LEVEL_PANIC,    LOG_EMERG   },
+    { L2_LEVEL_CRITICAL, LOG_CRIT    },
+    { L2_LEVEL_ERROR,    LOG_ERR         },
+    { L2_LEVEL_WARNING,  LOG_WARNING },
+    { L2_LEVEL_NOTICE,   LOG_NOTICE  },
+    { L2_LEVEL_INFO,     LOG_INFO        },
+    { L2_LEVEL_TRACE,    LOG_INFO    },
+    { L2_LEVEL_DEBUG,    LOG_DEBUG   },
+    { -1,                -1          }
+};
+
+/* Syslog Facility Table */
+static struct {
+    char *name;      /* the common name */
+    int   numREMOTE; /* number according to RFC3164 */
+    int   numLOCAL;  /* local encoding */
+} l2_ch_syslog_SLfac[] = {
+    { "kern",      0,      LOG_KERN     },
+    { "user",      1,      LOG_USER     },
+    { "mail",      2,      LOG_MAIL     },
+    { "daemon",    3,      LOG_DAEMON   },
+    { "auth",      4,      LOG_AUTH     },
+#ifndef LOG_SYSLOG
+#define LOG_SYSLOG   (5 << 3)
+#endif
+    { "syslog",    5,      LOG_SYSLOG   },
+    { "lpr",       6,      LOG_LPR      },
+    { "news",      7,      LOG_NEWS     },
+    { "uucp",      8,      LOG_UUCP     },
+    { "cron",      9,      LOG_CRON     },
+#ifndef LOG_AUTHPRIV
+#define LOG_AUTHPRIV (10 << 3)
+#endif
+    { "authpriv", 10,      LOG_AUTHPRIV },
+    { "ftp",      11,      LOG_FTP      },
+#ifndef LOG_NTP
+#define LOG_NTP      (12 << 3)
+#endif
+    { "ntp",      12,      LOG_NTP      },
+#ifndef LOG_SECURITY
+#define LOG_SECURITY (13 << 3)
+#endif
+    { "security", 13,      LOG_SECURITY },
+#ifndef LOG_CONSOLE
+#define LOG_CONSOLE  (14 << 3)
+#endif
+    { "console",  14,      LOG_CONSOLE  },
+#ifndef LOG_CLOCK
+#define LOG_CLOCK    (15 << 3)
+#endif
+    { "clock",    15,      LOG_CLOCK    },
+    { "local0",   16,      LOG_LOCAL0   },
+    { "local1",   17,      LOG_LOCAL1   },
+    { "local2",   18,      LOG_LOCAL2   },
+    { "local3",   19,      LOG_LOCAL3   },
+    { "local4",   20,      LOG_LOCAL4   },
+    { "local5",   21,      LOG_LOCAL5   },
+    { "local6",   22,      LOG_LOCAL6   },
+    { "local7",   23,      LOG_LOCAL7   },
+    { NULL,       0,       0            }
+};
+
 /* create channel */
 static l2_result_t hook_create(l2_context_t *ctx, l2_channel_t *ch)
 {
     l2_ch_syslog_t *cfg;
+    struct utsname uts;
+    char *cp;
 
     /* allocate private channel configuration */
     if ((cfg = (l2_ch_syslog_t *)malloc(sizeof(l2_ch_syslog_t))) == NULL)
         return L2_ERR_MEM;
 
     /* initialize configuration with reasonable defaults */
-    cfg->pszIdent  = NULL;
-    cfg->iLogopt   = 0;
-    cfg->iFacility = LOG_USER;
-    cfg->iPriority = (LOG_DEBUG|LOG_ERR);
-    cfg->iMaskpri  = (0xFFFFFFFF); /* Allow all priorities to pass through */
+    cfg->szTarget      = strdup("local");
+    cfg->szRemoteHost  = NULL;
+    cfg->nRemotePort   = 514;
+    if (uname(&uts) == 0) {
+        cfg->szLocalHost = strdup(uts.nodename);
+        if ((cp = strchr(cfg->szLocalHost, '.')) != NULL)
+            *cp = '\0';
+    }
+    else
+        cfg->szLocalHost = strdup("localhost");
+    cfg->szFacility    = strdup("user");
+    cfg->nFacility     = LOG_USER;
+    cfg->szIdent       = NULL;
+    cfg->bLogPid       = FALSE;
+    cfg->saRemoteSock  = NULL;
+    cfg->saaRemoteAddr = NULL;
 
     /* link private channel configuration into channel context */
     ctx->vp = cfg;
@@ -66,18 +156,45 @@
 static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list ap)
 {
     l2_ch_syslog_t *cfg = (l2_ch_syslog_t *)ctx->vp;
-    l2_param_t pa[6];
+    l2_param_t pa[8];
     l2_result_t rv;
+    int i;
 
     /* feed and call generic parameter parsing engine */
-    L2_PARAM_SET(pa[0], ident,   CHARPTR,  &cfg->pszIdent);
-    L2_PARAM_SET(pa[1], logopts, INT,      &cfg->iLogopt);
-    L2_PARAM_SET(pa[2], facility, INT,     &cfg->iFacility);
-    L2_PARAM_SET(pa[3], priority, INT,     &cfg->iPriority);
-    L2_PARAM_SET(pa[4], maskpriority, INT, &cfg->iMaskpri);
-    L2_PARAM_END(pa[5]);
-    rv = l2_util_setparams(pa, fmt, ap);
+    L2_PARAM_SET(pa[0], target,     STRING, &cfg->szTarget);
+    L2_PARAM_SET(pa[1], remotehost, STRING, &cfg->szRemoteHost);
+    L2_PARAM_SET(pa[2], remoteport, INT,    &cfg->nRemotePort);
+    L2_PARAM_SET(pa[3], localhost,  STRING, &cfg->szLocalHost);
+    L2_PARAM_SET(pa[4], facility,   STRING, &cfg->szFacility);
+    L2_PARAM_SET(pa[5], ident,      STRING, &cfg->szIdent);
+    L2_PARAM_SET(pa[6], logpid,     INT,    &cfg->bLogPid);
+    L2_PARAM_END(pa[7]);
 
+    /* sanity checking & post-processing */
+    rv = l2_util_setparams(pa, fmt, ap);
+    if (cfg->szTarget == NULL || cfg->szFacility == NULL)
+        return L2_ERR_USE;
+    if (!(   strcmp(cfg->szTarget, "local") == 0
+          || strcmp(cfg->szTarget, "remote") == 0))
+        return L2_ERR_USE;
+    for (i = 0; l2_ch_syslog_SLfac[i].name != NULL; i++)
+        if (strcmp(l2_ch_syslog_SLfac[i].name, cfg->szFacility) == 0)
+            break;
+    if (l2_ch_syslog_SLfac[i].name == NULL)
+        return L2_ERR_USE;
+    if (strcmp(cfg->szTarget, "local") == 0)
+        cfg->nFacility = l2_ch_syslog_SLfac[i].numLOCAL;
+    else
+        cfg->nFacility = (l2_ch_syslog_SLfac[i].numREMOTE << 3);
+    if (   strcmp(cfg->szTarget, "remote") == 0 
+        && (cfg->szRemoteHost == NULL
+            || (cfg->nRemotePort <= 0 || cfg->nRemotePort >= 65536)))
+        return L2_ERR_USE;
+    if (   cfg->szLocalHost == NULL
+        || strchr(cfg->szLocalHost, '.') != NULL)
+        return L2_ERR_USE;
+    if (cfg->szIdent != NULL && strlen(cfg->szIdent) > (32-(1+5+1)))
+        return L2_ERR_USE;
     return rv;
 }
 
@@ -85,11 +202,36 @@
 static l2_result_t hook_open(l2_context_t *ctx, l2_channel_t *ch)
 {
     l2_ch_syslog_t *cfg = (l2_ch_syslog_t *)ctx->vp;
-
-    /* open channel syslog */
-    openlog(cfg->pszIdent, cfg->iLogopt, cfg->iFacility);
-    setlogmask(cfg->iMaskpri);
-
+    int opt;
+    sa_rc_t rc;
+    sa_addr_t *la;
+
+    if (cfg->szIdent == NULL)
+        return L2_ERR_USE;
+    if (strcmp(cfg->szTarget, "local") == 0) {
+        /* open local syslog connection via syslog(3) */
+        opt = 0;
+        if (cfg->bLogPid)
+            opt |= LOG_PID;
+        openlog(cfg->szIdent, opt, cfg->nFacility);
+        /* setlogmask(0); */
+    }
+    else {
+        /* open remote syslog connection via UDP socket */
+        if (cfg->szRemoteHost == NULL)
+            return L2_ERR_USE;
+        if ((rc = sa_u2a(&cfg->saaRemoteAddr, "udp://%s:%d", 
+                         cfg->szRemoteHost, cfg->nRemotePort)) != SA_OK)
+            return (rc == SA_ERR_SYS ? L2_ERR_SYS : L2_ERR_INT);
+        if ((rc = sa_create(&cfg->saRemoteSock)) != SA_OK)
+            return (rc == SA_ERR_SYS ? L2_ERR_SYS : L2_ERR_INT);
+        sa_timeout(cfg->saRemoteSock, 10, 0);
+        /* FIXME: if uid == 0 -> use port 514 */
+        if ((rc = sa_u2a(&la, "udp://0.0.0.0:0")) != SA_OK)
+            return (rc == SA_ERR_SYS ? L2_ERR_SYS : L2_ERR_INT);
+        if ((rc = sa_bind(cfg->saRemoteSock, la)) != SA_OK)
+            return (rc == SA_ERR_SYS ? L2_ERR_SYS : L2_ERR_INT);
+    }
     return L2_OK;
 }
 
@@ -98,9 +240,56 @@
                               l2_level_t level, const char *buf, size_t buf_size)
 {
     l2_ch_syslog_t *cfg = (l2_ch_syslog_t *)ctx->vp;
-
-    /* write message to channel syslog */
-    syslog(cfg->iPriority, buf);
+    int prio;
+    int i;
+    char caTime[15+1];
+    char caBuf[2048];
+    time_t t;
+    struct tm *tm;
+    size_t n;
+    sa_rc_t rc;
+
+    /* determine syslog priority */
+    prio = 0;
+    for (i = 0; l2_ch_syslog_L2toSL[i].levelL2 != -1; i++) {
+        if (l2_ch_syslog_L2toSL[i].levelL2 == level) {
+            prio = l2_ch_syslog_L2toSL[i].levelSL;
+            break;
+        }
+    }
+    if (l2_ch_syslog_L2toSL[i].levelL2 == -1)
+        return L2_ERR_USE;
+
+    /* FIXME: nul-terminate buf? */
+
+    if (strcmp(cfg->szTarget, "local") == 0) {
+        /* send to local syslogd via syslog(3) */
+        syslog(prio, buf);
+    }
+    else {
+        /* send to remote syslogd via UDP */
+        if (strlen(buf) > 1024)
+            return L2_ERR_MEM;
+        prio += cfg->nFacility;
+        t = time(NULL);
+        tm = localtime(&t);
+        strftime(caTime, sizeof(caTime), "%b %d %H:%M:%S", tm);
+        if (caTime[4] == '0')
+            caTime[4] = ' ';
+        if (cfg->bLogPid) 
+            sprintf(caBuf, "<%d>%s %s %s[%lu]: %s", 
+                    prio, caTime, cfg->szLocalHost, 
+                    cfg->szIdent, (unsigned long)getpid(), buf);
+        else
+            sprintf(caBuf, "<%d>%s %s %s: %s", 
+                    prio, caTime, cfg->szLocalHost, 
+                    cfg->szIdent, buf);
+        if ((n = strlen(caBuf)) > 1024)
+            return L2_ERR_IO;
+        if ((rc = sa_writeto(cfg->saRemoteSock, caBuf, n, 
+                             NULL, cfg->saaRemoteAddr)) != SA_OK)
+            return (rc == SA_ERR_SYS ? L2_ERR_SYS : L2_ERR_IO);
+    }
 
     return L2_OK;
 }
@@ -108,9 +297,21 @@
 /* close channel */
 static l2_result_t hook_close(l2_context_t *ctx, l2_channel_t *ch)
 {
-    /* close channel syslog */
-    closelog();
+    l2_ch_syslog_t *cfg = (l2_ch_syslog_t *)ctx->vp;
 
+    if (strcmp(cfg->szTarget, "local") == 0) {
+        closelog();
+    }
+    else {
+        if (cfg->saRemoteSock != NULL) {
+            sa_destroy(cfg->saRemoteSock);
+            cfg->saRemoteSock = NULL;
+        }
+        if (cfg->saaRemoteAddr != NULL) {
+            free(cfg->saaRemoteAddr);
+            cfg->saaRemoteAddr = NULL;
+        }
+    }
     return L2_OK;
 }
 
@@ -120,6 +321,20 @@
     l2_ch_syslog_t *cfg = (l2_ch_syslog_t *)ctx->vp;
 
     /* destroy channel configuration */
+    if (cfg->szTarget != NULL)
+        free(cfg->szTarget);
+    if (cfg->szRemoteHost != NULL)
+        free(cfg->szRemoteHost);
+    if (cfg->szLocalHost != NULL)
+        free(cfg->szLocalHost);
+    if (cfg->szFacility != NULL)
+        free(cfg->szFacility);
+    if (cfg->szIdent != NULL)
+        free(cfg->szIdent);
+    if (cfg->saRemoteSock != NULL)
+        sa_destroy(cfg->saRemoteSock);
+    if (cfg->saaRemoteAddr != NULL)
+        free(cfg->saaRemoteAddr);
     free(cfg);
 
     return L2_OK;


ossp-pkg/l2/l2_test.c 1.22 -> 1.23

--- l2_test.c    2001/09/14 18:49:36     1.22
+++ l2_test.c    2001/09/14 19:11:00     1.23
@@ -162,8 +162,8 @@
     if ((chSyslog = l2_channel_create(&l2_handler_syslog)) == NULL)   /* Syslog */
         die("failed to create syslog channel");
 
-    if (l2_channel_configure(chSyslog, "ident,facility,target",
-        "L2-Test", "user", "local") != L2_OK)
+    if (l2_channel_configure(chSyslog, "ident,facility,target,remotehost,logpid",
+        "L2-Test", "user", "remote", "en1", 1) != L2_OK)
         die("failed to configure syslog channel");
 
     if (l2_channel_open(chSyslog) != L2_OK)

CVSTrac 2.0.1