This is fairly simple, yet useful with netconsole. Remote socket address is not
used to obtain hostname, it would be easy to fake it via UDP anyway, which is
probably not desirable. If clients wish, they should identify themselves via
identifier field in syslog packets.

Disabled by default.
---
 man/systemd-journald.service.xml |  6 ++++++
 src/journal/journald-server.c    | 16 +++++++++++++---
 src/journal/journald-server.h    |  1 +
 src/journal/journald-syslog.c    | 10 ++++++++++
 units/systemd-journald.socket    |  1 +
 5 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/man/systemd-journald.service.xml b/man/systemd-journald.service.xml
index 7158888..7c0d277 100644
--- a/man/systemd-journald.service.xml
+++ b/man/systemd-journald.service.xml
@@ -97,6 +97,12 @@
                 obtains the the handles from systemd via activation 
socket-passing
                 interface, or opens them itself.</para>
 
+                <para>Additionally, journal might be passed an open
+                <constant>SOCK_DGRAM</constant> inet socket, which will be 
used for
+                an UDP syslog protocol listener. Note that you should not 
normally
+                need this and it would allow remote machines to inject logs 
into
+                journal without any authentication.</para>
+
                 <para><filename>systemd-journald</filename> will
                 forward all received log messages to the 
<constant>AF_UNIX</constant>
                 <constant>SOCK_DGRAM</constant> socket
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 381d80a..7f7bf6e 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -1108,7 +1108,7 @@ int process_datagram(sd_event_source *es, int fd, 
uint32_t revents, void *userda
         Server *s = userdata;
 
         assert(s);
-        assert(fd == s->native_fd || fd == s->syslog_fd);
+        assert(fd == s->native_fd || fd == s->syslog_fd || fd == 
s->syslog_udp_fd);
 
         if (revents != EPOLLIN) {
                 log_error("Got invalid event from epoll for datagram fd: 
%"PRIx32, revents);
@@ -1191,7 +1191,7 @@ int process_datagram(sd_event_source *es, int fd, 
uint32_t revents, void *userda
                         }
                 }
 
-                if (fd == s->syslog_fd) {
+                if (fd == s->syslog_fd || fd == s->syslog_udp_fd) {
                         if (n > 0 && n_fds == 0) {
                                 s->buffer[n] = 0;
                                 server_process_syslog_message(s, 
strstrip(s->buffer), ucred, tv, label, label_len);
@@ -1460,7 +1460,7 @@ int server_init(Server *s) {
         assert(s);
 
         zero(*s);
-        s->syslog_fd = s->native_fd = s->stdout_fd = s->dev_kmsg_fd = 
s->hostname_fd = -1;
+        s->syslog_fd = s->syslog_udp_fd = s->native_fd = s->stdout_fd = 
s->dev_kmsg_fd = s->hostname_fd = -1;
         s->compress = true;
         s->seal = true;
 
@@ -1544,6 +1544,15 @@ int server_init(Server *s) {
 
                         s->syslog_fd = fd;
 
+                } else if (sd_is_socket_inet(fd, AF_UNSPEC, SOCK_DGRAM, -1, 
514) > 0) {
+
+                        if (s->syslog_udp_fd >= 0) {
+                                log_error("Too many syslog UDP sockets 
passed.");
+                                return -EINVAL;
+                        }
+
+                        s->syslog_udp_fd = fd;
+
                 } else {
                         log_error("Unknown socket passed.");
                         return -EINVAL;
@@ -1648,6 +1657,7 @@ void server_done(Server *s) {
         sd_event_unref(s->event);
 
         safe_close(s->syslog_fd);
+        safe_close(s->syslog_udp_fd);
         safe_close(s->native_fd);
         safe_close(s->stdout_fd);
         safe_close(s->dev_kmsg_fd);
diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h
index e468b82..c757704 100644
--- a/src/journal/journald-server.h
+++ b/src/journal/journald-server.h
@@ -56,6 +56,7 @@ typedef struct StdoutStream StdoutStream;
 
 typedef struct Server {
         int syslog_fd;
+        int syslog_udp_fd;
         int native_fd;
         int stdout_fd;
         int dev_kmsg_fd;
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index 434eac4..8fe2eae 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -478,6 +478,16 @@ int server_open_syslog_socket(Server *s) {
                 return r;
         }
 
+        if (s->syslog_udp_fd > 0) {
+                fd_nonblock(s->syslog_udp_fd, 1);
+
+                r = sd_event_add_io(s->event, &s->syslog_event_source, 
s->syslog_udp_fd, EPOLLIN, process_datagram, s);
+                if (r < 0) {
+                        log_error("Failed to add syslog server fd to event 
loop: %s", strerror(-r));
+                        return r;
+                }
+        }
+
         return 0;
 }
 
diff --git a/units/systemd-journald.socket b/units/systemd-journald.socket
index fbeb10b..add6785 100644
--- a/units/systemd-journald.socket
+++ b/units/systemd-journald.socket
@@ -16,6 +16,7 @@ Before=sockets.target
 # hence let's exclude this from isolate requests.
 IgnoreOnIsolate=yes
 
+# You can enable syslog UDP listener by adding ListenDatagram=514
 [Socket]
 ListenStream=/run/systemd/journal/stdout
 ListenDatagram=/run/systemd/journal/socket
-- 
1.9.3

_______________________________________________
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel

Reply via email to