mirror of
https://github.com/troglobit/finit.git
synced 2026-11-03 13:28:27 +00:00
Merge remote-tracking branch 'origin/inetd-plugins'
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
commit
7b00969f6c
12 files changed
+473
-49
No files matched your search
@@ -73,8 +73,11 @@ interface, reducing the need for a full blown firewall.
|
|||||||
|
|
||||||
Built-in optional inetd services:
|
Built-in optional inetd services:
|
||||||
|
|
||||||
- time (rdate) RFC862
|
- echo RFC862
|
||||||
- echo RFC868
|
- chargen RFC864
|
||||||
|
- daytime RFC867
|
||||||
|
- discard RFC863
|
||||||
|
- time (rdate) RFC868
|
||||||
|
|
||||||
|
|
||||||
**Runlevels**
|
**Runlevels**
|
||||||
@@ -437,7 +440,8 @@ Inetd
|
|||||||
A built-in *Internet Super Server* support was added in Finit v1.12 and
|
A built-in *Internet Super Server* support was added in Finit v1.12 and
|
||||||
v1.13, along with an internal `time` inetd service, RFC 868 (rdate).
|
v1.13, along with an internal `time` inetd service, RFC 868 (rdate).
|
||||||
The latter is supplied as a plugin to illustrate how simple it is to
|
The latter is supplied as a plugin to illustrate how simple it is to
|
||||||
extend finit with more internal inetd services.
|
extend finit with more internal inetd services. Today more built-in
|
||||||
|
services are available.
|
||||||
|
|
||||||
> Please note, not all UNIX daemons are prepared to run as inetd services.
|
> Please note, not all UNIX daemons are prepared to run as inetd services.
|
||||||
> In the example below `sshd` also need the command line argument `-i`.
|
> In the example below `sshd` also need the command line argument `-i`.
|
||||||
@@ -474,28 +478,40 @@ default port. To run ssh on port 222, and all others on port 22:
|
|||||||
|
|
||||||
Compared to Finit v1.12 you must *explicitly deny* access from `eth0`!
|
Compared to Finit v1.12 you must *explicitly deny* access from `eth0`!
|
||||||
|
|
||||||
|
To protect against looping attacks, the inetd server will refuse UDP
|
||||||
|
service if the reply port corresponds to any internal service. Similar
|
||||||
|
to how the FreeBSD inetd operates.
|
||||||
|
|
||||||
|
|
||||||
**Internal Services**
|
**Internal Services**
|
||||||
|
|
||||||
The original `inetd` had a few standard services built-in:
|
Like the original `inetd`, Finit has a few standard services built-in.
|
||||||
|
They are realized as plugins to provide a simple means of testing the
|
||||||
|
inetd functionality stand-alone. But this also provides both a useful
|
||||||
|
network testing/availability, as well as a rudimentary time server for
|
||||||
|
`rdate` clients.
|
||||||
|
|
||||||
- time
|
|
||||||
- echo
|
- echo
|
||||||
- chargen
|
- chargen
|
||||||
|
- daytime
|
||||||
- discard
|
- discard
|
||||||
|
- time
|
||||||
|
|
||||||
Finit currently supports the `time` and `echo` services. Both of which
|
For security reasons they are all disabled by default and have to be
|
||||||
are realized as plugins to provide a simple means of testing the inetd
|
enabled with both the `configure` script and a special `inetd` stanza in
|
||||||
functionality stand-alone. But this also provides both a useful network
|
the `finit.conf` or `finit.d/*.conf` like this:
|
||||||
testing/availability and a rudimentary time server for rdate clients.
|
|
||||||
|
|
||||||
Internal inetd services are set up as follows:
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
inetd time/udp wait [2345] internal
|
|
||||||
inetd time/tcp nowait [2345] internal
|
|
||||||
inetd echo/udp wait [2345] internal
|
inetd echo/udp wait [2345] internal
|
||||||
inetd echo/tcp nowait [2345] internal
|
inetd echo/tcp nowait [2345] internal
|
||||||
|
inetd chargen/udp wait [2345] internal
|
||||||
|
inetd chargen/tcp nowait [2345] internal
|
||||||
|
inetd daytime/udp wait [2345] internal
|
||||||
|
inetd daytime/tcp nowait [2345] internal
|
||||||
|
inetd discard/udp wait [2345] internal
|
||||||
|
inetd discard/tcp nowait [2345] internal
|
||||||
|
inetd time/udp wait [2345] internal
|
||||||
|
inetd time/tcp nowait [2345] internal
|
||||||
```
|
```
|
||||||
|
|
||||||
Then call `rdate` from a remote machine (or use localhost):
|
Then call `rdate` from a remote machine (or use localhost):
|
||||||
@@ -512,6 +528,20 @@ Or `echoping` to reach the echo service:
|
|||||||
echoping -uv <IP>
|
echoping -uv <IP>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Or `echoping -d` to reach the discard service:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
echoping -dv <IP>
|
||||||
|
echoping -duv <IP>
|
||||||
|
```
|
||||||
|
|
||||||
|
Or `echoping -c` to reach the chargen service:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
echoping -cv <IP>
|
||||||
|
echoping -cuv <IP>
|
||||||
|
```
|
||||||
|
|
||||||
If you use `time/udp` you must use the standard rdate implementation and
|
If you use `time/udp` you must use the standard rdate implementation and
|
||||||
then call it with `rdate -up` to connect using UDP. Without the `-p`
|
then call it with `rdate -up` to connect using UDP. Without the `-p`
|
||||||
argument rdate will try to set the system clock. Please note that rdate
|
argument rdate will try to set the system clock. Please note that rdate
|
||||||
@@ -554,6 +584,12 @@ For your convenience a set of *optional* plugins are available:
|
|||||||
|
|
||||||
* *echo.so*: RFC 862 plugin. Start as inetd service, like time below.
|
* *echo.so*: RFC 862 plugin. Start as inetd service, like time below.
|
||||||
|
|
||||||
|
* *chargen.so*: RFC 864 plugin. Start as inetd service, like time below.
|
||||||
|
|
||||||
|
* *daytime.so*: RFC 867 plugin. Start as inetd service, like time below.
|
||||||
|
|
||||||
|
* *discard.so*: RFC 863 plugin. Start as inetd service, like time below.
|
||||||
|
|
||||||
* *hwclock.so*: Restore and save system clock from/to RTC on
|
* *hwclock.so*: Restore and save system clock from/to RTC on
|
||||||
startup/shutdown.
|
startup/shutdown.
|
||||||
|
|
||||||
|
|||||||
+11
-8
@@ -53,14 +53,17 @@ AC_ARG_ENABLE(quiet,
|
|||||||
|
|
||||||
# Check for extra plugins to enable
|
# Check for extra plugins to enable
|
||||||
enable_all_plugins=auto
|
enable_all_plugins=auto
|
||||||
AC_PLUGIN([alsa-utils], [no], [Save and restore ALSA sound settings using alsactl])
|
AC_PLUGIN([alsa-utils], [no], [Save and restore ALSA sound settings using alsactl])
|
||||||
AC_PLUGIN([dbus], [no], [Setup and start system message bus, D-Bus])
|
AC_PLUGIN([dbus], [no], [Setup and start system message bus, D-Bus])
|
||||||
AC_PLUGIN([inetd-echo], [no], [Inetd plugin: echo server, RFC862])
|
AC_PLUGIN([inetd-echo], [no], [Inetd plugin: echo server, RFC862])
|
||||||
AC_PLUGIN([inetd-time], [no], [Inetd plugin: time (rdate) server, RFC868])
|
AC_PLUGIN([inetd-chargen], [no], [Inetd plugin: character generator, RFC864])
|
||||||
AC_PLUGIN([lost], [no], [Example HOOK_SVC_LOST plugin, very noisy as-is!])
|
AC_PLUGIN([inetd-daytime], [no], [Inetd plugin: daytime server, RFC867])
|
||||||
AC_PLUGIN([resolvconf], [no], [Setup necessary files for resolvconf])
|
AC_PLUGIN([inetd-discard], [no], [Inetd plugin: discard server, RFC863])
|
||||||
AC_PLUGIN([x11-common], [no], [Console setup (for X)])
|
AC_PLUGIN([inetd-time], [no], [Inetd plugin: time (rdate) server, RFC868])
|
||||||
AC_PLUGIN([netlink], [yes], [Basic netlink plugin for IFUP/IFDN and GW events. Can be replaced with externally built plugin that links with libnl or similar.])
|
AC_PLUGIN([lost], [no], [Example HOOK_SVC_LOST plugin, very noisy as-is!])
|
||||||
|
AC_PLUGIN([resolvconf], [no], [Setup necessary files for resolvconf])
|
||||||
|
AC_PLUGIN([x11-common], [no], [Console setup (for X)])
|
||||||
|
AC_PLUGIN([netlink], [yes], [Basic netlink plugin for IFUP/IFDN and GW events. Can be replaced with externally built plugin that links with libnl or similar.])
|
||||||
|
|
||||||
# Check for extra arguments or packages
|
# Check for extra arguments or packages
|
||||||
AC_ARG_WITH(heading,
|
AC_ARG_WITH(heading,
|
||||||
|
|||||||
@@ -38,7 +38,6 @@
|
|||||||
#include "service.h"
|
#include "service.h"
|
||||||
#include "sig.h"
|
#include "sig.h"
|
||||||
#include "tty.h"
|
#include "tty.h"
|
||||||
#include "inetd.h"
|
|
||||||
#include "sm.h"
|
#include "sm.h"
|
||||||
|
|
||||||
int debug = 0;
|
int debug = 0;
|
||||||
|
|||||||
@@ -107,8 +107,8 @@ static int inetd_stream_peek(int sd, char *ifname)
|
|||||||
|
|
||||||
static int get_stdin(svc_t *svc)
|
static int get_stdin(svc_t *svc)
|
||||||
{
|
{
|
||||||
char ifname[IF_NAMESIZE] = "UNKNOWN";
|
|
||||||
int stdin = svc->inetd.watcher.fd;
|
int stdin = svc->inetd.watcher.fd;
|
||||||
|
char ifname[IF_NAMESIZE] = "UNKNOWN";
|
||||||
|
|
||||||
if (svc->inetd.type == SOCK_STREAM) {
|
if (svc->inetd.type == SOCK_STREAM) {
|
||||||
/* Open new client socket from server socket */
|
/* Open new client socket from server socket */
|
||||||
@@ -189,6 +189,33 @@ static void socket_cb(uev_t *UNUSED(w), void *arg, int UNUSED(events))
|
|||||||
service_step(task);
|
service_step(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Refuse service if the request specifies a reply port corresponding to any internal service.
|
||||||
|
* This is done as a defense against looping attacks; the remote IP address is logged.
|
||||||
|
* http://www.freebsd.org/cgi/man.cgi?inetd(8)
|
||||||
|
* https://svnweb.freebsd.org/base/head/usr.sbin/inetd/inetd.c?revision=298909&view=markup#l2094
|
||||||
|
*/
|
||||||
|
int inetd_check_loop(struct sockaddr *sa, socklen_t len, char *name)
|
||||||
|
{
|
||||||
|
svc_t *svc;
|
||||||
|
char pname[NI_MAXHOST];
|
||||||
|
|
||||||
|
for (svc = svc_inetd_iterator(1); svc; svc = svc_inetd_iterator(0)) {
|
||||||
|
inetd_t *i = &svc->inetd;
|
||||||
|
|
||||||
|
if (!i->builtin || i->type != SOCK_DGRAM)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (((const struct sockaddr_in *)sa)->sin_port == i->port) {
|
||||||
|
getnameinfo(sa, len, pname, sizeof(pname), NULL, 0, NI_NUMERICHOST);
|
||||||
|
FLOG_WARN("%s/%s:%s/%s loop request REFUSED from %s", i->name, "UDP", name, "UDP", pname);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Launch Inet socket for service.
|
/* Launch Inet socket for service.
|
||||||
* TODO: Add filtering ALLOW/DENY per interface.
|
* TODO: Add filtering ALLOW/DENY per interface.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ typedef struct {
|
|||||||
int proto;
|
int proto;
|
||||||
int port;
|
int port;
|
||||||
int forking;
|
int forking;
|
||||||
|
int builtin; /* Set by built-in inetd services only */
|
||||||
int next_id; /* Next child job's id */
|
int next_id; /* Next child job's id */
|
||||||
char name[10];
|
char name[10];
|
||||||
int (*cmd)(int type); /* internal inetd service, like 'time' */
|
int (*cmd)(int type); /* internal inetd service, like 'time' */
|
||||||
@@ -53,6 +54,8 @@ typedef struct {
|
|||||||
TAILQ_HEAD(, inetd_filter) filters;
|
TAILQ_HEAD(, inetd_filter) filters;
|
||||||
} inetd_t;
|
} inetd_t;
|
||||||
|
|
||||||
|
int inetd_check_loop (struct sockaddr *sa, socklen_t len, char *name);
|
||||||
|
|
||||||
int inetd_start (inetd_t *inetd);
|
int inetd_start (inetd_t *inetd);
|
||||||
void inetd_stop (inetd_t *inetd);
|
void inetd_stop (inetd_t *inetd);
|
||||||
|
|
||||||
|
|||||||
@@ -15,13 +15,27 @@ if BUILD_DBUS_PLUGIN
|
|||||||
libplug_la_SOURCES += dbus.c
|
libplug_la_SOURCES += dbus.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if INETD
|
||||||
if BUILD_INETD_ECHO_PLUGIN
|
if BUILD_INETD_ECHO_PLUGIN
|
||||||
libplug_la_SOURCES += echo.c
|
libplug_la_SOURCES += echo.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if BUILD_INETD_CHARGEN_PLUGIN
|
||||||
|
libplug_la_SOURCES += chargen.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
if BUILD_INETD_DAYTIME_PLUGIN
|
||||||
|
libplug_la_SOURCES += daytime.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
if BUILD_INETD_DISCARD_PLUGIN
|
||||||
|
libplug_la_SOURCES += discard.c
|
||||||
|
endif
|
||||||
|
|
||||||
if BUILD_INETD_TIME_PLUGIN
|
if BUILD_INETD_TIME_PLUGIN
|
||||||
libplug_la_SOURCES += time.c
|
libplug_la_SOURCES += time.c
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
if BUILD_LOST_PLUGIN
|
if BUILD_LOST_PLUGIN
|
||||||
libplug_la_SOURCES += lost.c
|
libplug_la_SOURCES += lost.c
|
||||||
@@ -46,13 +60,27 @@ if BUILD_DBUS_PLUGIN
|
|||||||
pkglib_LTLIBRARIES += dbus.la
|
pkglib_LTLIBRARIES += dbus.la
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if INETD
|
||||||
if BUILD_INETD_ECHO_PLUGIN
|
if BUILD_INETD_ECHO_PLUGIN
|
||||||
pkglib_LTLIBRARIES += echo.la
|
pkglib_LTLIBRARIES += echo.la
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if BUILD_INETD_CHARGEN_PLUGIN
|
||||||
|
pkglib_LTLIBRARIES += chargen.la
|
||||||
|
endif
|
||||||
|
|
||||||
|
if BUILD_INETD_DAYTIME_PLUGIN
|
||||||
|
pkglib_LTLIBRARIES += daytime.la
|
||||||
|
endif
|
||||||
|
|
||||||
|
if BUILD_INETD_DISCARD_PLUGIN
|
||||||
|
pkglib_LTLIBRARIES += discard.la
|
||||||
|
endif
|
||||||
|
|
||||||
if BUILD_INETD_TIME_PLUGIN
|
if BUILD_INETD_TIME_PLUGIN
|
||||||
pkglib_LTLIBRARIES += time.la
|
pkglib_LTLIBRARIES += time.la
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
if BUILD_LOST_PLUGIN
|
if BUILD_LOST_PLUGIN
|
||||||
pkglib_LTLIBRARIES += lost.la
|
pkglib_LTLIBRARIES += lost.la
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
/* Optional inetd plugin for the Character Generator Protocol, RFC 864
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Joachim Nilsson <troglobit@gmail.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <unistd.h> /* STDIN_FILENO */
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "../plugin.h"
|
||||||
|
|
||||||
|
#define NAME "chargen"
|
||||||
|
#define PATTERN "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ "
|
||||||
|
|
||||||
|
static char *generator(char *buf, size_t len)
|
||||||
|
{
|
||||||
|
size_t num;
|
||||||
|
static size_t pos = 0;
|
||||||
|
const char pattern[] = PATTERN;
|
||||||
|
|
||||||
|
len = 72;
|
||||||
|
if (pos + len > sizeof(pattern)) {
|
||||||
|
num = sizeof(pattern) - pos;
|
||||||
|
len -= num;
|
||||||
|
} else {
|
||||||
|
num = 72;
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(&buf[0], &pattern[pos], num--);
|
||||||
|
if (len++)
|
||||||
|
strncpy(&buf[num], pattern, len);
|
||||||
|
strcat(buf, "\r\n");
|
||||||
|
|
||||||
|
if (++pos >= sizeof(pattern) - 1)
|
||||||
|
pos = 0;
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int recv_peer(int sd, char *buf, ssize_t len, struct sockaddr *sa, socklen_t *sa_len)
|
||||||
|
{
|
||||||
|
len = recvfrom(sd, buf, len, MSG_DONTWAIT, sa, sa_len);
|
||||||
|
if (-1 == len)
|
||||||
|
return -1; /* On error, close connection. */
|
||||||
|
|
||||||
|
if (inetd_check_loop(sa, *sa_len, NAME))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int send_peer(int sd, char *buf, ssize_t len, struct sockaddr *sa, socklen_t sa_len)
|
||||||
|
{
|
||||||
|
char *pattern = generator(buf, len);
|
||||||
|
|
||||||
|
return sendto(sd, pattern, strlen(pattern), MSG_DONTWAIT, sa, sa_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cb(int type)
|
||||||
|
{
|
||||||
|
int sd = STDIN_FILENO;
|
||||||
|
ssize_t len;
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
struct sockaddr_storage sa;
|
||||||
|
socklen_t sa_len = sizeof(sa);
|
||||||
|
|
||||||
|
if (recv_peer(sd, buf, sizeof(buf), (struct sockaddr *)&sa, &sa_len))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return send_peer(sd, buf, sizeof(buf), (struct sockaddr *)&sa, sa_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static plugin_t plugin = {
|
||||||
|
.name = NAME, /* Must match the inetd /etc/services entry */
|
||||||
|
.inetd = {
|
||||||
|
.cmd = cb
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
PLUGIN_INIT(plugin_init)
|
||||||
|
{
|
||||||
|
plugin_register(&plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
PLUGIN_EXIT(plugin_exit)
|
||||||
|
{
|
||||||
|
plugin_unregister(&plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Local Variables:
|
||||||
|
* indent-tabs-mode: t
|
||||||
|
* c-file-style: "linux"
|
||||||
|
* End:
|
||||||
|
*/
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
/* Optional inetd plugin for Daytime Protocol, RFC 867
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Joachim Nilsson <troglobit@gmail.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h> /* STDIN_FILENO */
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "../plugin.h"
|
||||||
|
|
||||||
|
#define NAME "daytime"
|
||||||
|
|
||||||
|
|
||||||
|
static char *daytime(char *buf, size_t len)
|
||||||
|
{
|
||||||
|
time_t t;
|
||||||
|
struct tm *tmp;
|
||||||
|
|
||||||
|
t = time(NULL);
|
||||||
|
tmp = localtime(&t);
|
||||||
|
|
||||||
|
memset(buf, 0, len);
|
||||||
|
strftime(buf, len, "%a, %B %d, %Y %T-%Z", tmp);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int recv_peer(int sd, char *buf, ssize_t len, struct sockaddr *sa, socklen_t *sa_len)
|
||||||
|
{
|
||||||
|
len = recvfrom(sd, buf, sizeof(buf), MSG_DONTWAIT, sa, sa_len);
|
||||||
|
if (-1 == len)
|
||||||
|
return -1; /* On error, close connection. */
|
||||||
|
|
||||||
|
if (inetd_check_loop(sa, *sa_len, NAME))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int send_peer(int sd, char *buf, ssize_t len, struct sockaddr *sa, socklen_t sa_len)
|
||||||
|
{
|
||||||
|
char *now = daytime(buf, len);
|
||||||
|
|
||||||
|
return sendto(sd, now, strlen(now), MSG_DONTWAIT, sa, sa_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cb(int type)
|
||||||
|
{
|
||||||
|
int sd = STDIN_FILENO;
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
struct sockaddr_storage sa;
|
||||||
|
socklen_t sa_len = sizeof(sa);
|
||||||
|
|
||||||
|
if (recv_peer(sd, buf, sizeof(buf), (struct sockaddr *)&sa, &sa_len))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return send_peer(sd, buf, sizeof(buf), (struct sockaddr *)&sa, sa_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static plugin_t plugin = {
|
||||||
|
.name = NAME, /* Must match the inetd /etc/services entry */
|
||||||
|
.inetd = {
|
||||||
|
.cmd = cb
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PLUGIN_INIT(plugin_init)
|
||||||
|
{
|
||||||
|
plugin_register(&plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
PLUGIN_EXIT(plugin_exit)
|
||||||
|
{
|
||||||
|
plugin_unregister(&plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Local Variables:
|
||||||
|
* indent-tabs-mode: t
|
||||||
|
* c-file-style: "linux"
|
||||||
|
* End:
|
||||||
|
*/
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/* Optional inetd plugin for the Discard Protocol, RFC 863
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Joachim Nilsson <troglobit@gmail.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <unistd.h> /* STDIN_FILENO */
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "../plugin.h"
|
||||||
|
|
||||||
|
static int cb(int type)
|
||||||
|
{
|
||||||
|
int sd = STDIN_FILENO;
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
ssize_t len;
|
||||||
|
struct sockaddr_storage sa;
|
||||||
|
socklen_t sa_len = sizeof(sa);
|
||||||
|
|
||||||
|
len = recvfrom(sd, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr *)&sa, &sa_len);
|
||||||
|
if (-1 == len)
|
||||||
|
return -1; /* On error, close connection. */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static plugin_t plugin = {
|
||||||
|
.name = "discard", /* Must match the inetd /etc/services entry */
|
||||||
|
.inetd = {
|
||||||
|
.cmd = cb
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
PLUGIN_INIT(plugin_init)
|
||||||
|
{
|
||||||
|
plugin_register(&plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
PLUGIN_EXIT(plugin_exit)
|
||||||
|
{
|
||||||
|
plugin_unregister(&plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Local Variables:
|
||||||
|
* indent-tabs-mode: t
|
||||||
|
* c-file-style: "linux"
|
||||||
|
* End:
|
||||||
|
*/
|
||||||
+19
-5
@@ -1,4 +1,4 @@
|
|||||||
/* Optional inetd plugin for the echo protocol RFC 862
|
/* Optional inetd plugin for the Echo Protocol, RFC 862
|
||||||
*
|
*
|
||||||
* Copyright (c) 2016 Joachim Nilsson <troglobit@gmail.com>
|
* Copyright (c) 2016 Joachim Nilsson <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
@@ -27,7 +27,21 @@
|
|||||||
|
|
||||||
#include "../plugin.h"
|
#include "../plugin.h"
|
||||||
|
|
||||||
static int echo_cb(int type)
|
#define NAME "echo"
|
||||||
|
|
||||||
|
static int recv_peer(int sd, char *buf, ssize_t len, struct sockaddr *sa, socklen_t *sa_len)
|
||||||
|
{
|
||||||
|
len = recvfrom(sd, buf, sizeof(buf), MSG_DONTWAIT, sa, sa_len);
|
||||||
|
if (-1 == len)
|
||||||
|
return -1; /* On error, close connection. */
|
||||||
|
|
||||||
|
if (inetd_check_loop(sa, *sa_len, NAME))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cb(int type)
|
||||||
{
|
{
|
||||||
int sd = STDIN_FILENO;
|
int sd = STDIN_FILENO;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
@@ -35,7 +49,7 @@ static int echo_cb(int type)
|
|||||||
struct sockaddr_storage sa;
|
struct sockaddr_storage sa;
|
||||||
socklen_t sa_len = sizeof(sa);
|
socklen_t sa_len = sizeof(sa);
|
||||||
|
|
||||||
len = recvfrom(sd, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr *)&sa, &sa_len);
|
len = recv_peer(sd, buf, sizeof(buf), (struct sockaddr *)&sa, &sa_len);
|
||||||
if (-1 == len)
|
if (-1 == len)
|
||||||
return -1; /* On error, close connection. */
|
return -1; /* On error, close connection. */
|
||||||
|
|
||||||
@@ -43,9 +57,9 @@ static int echo_cb(int type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static plugin_t plugin = {
|
static plugin_t plugin = {
|
||||||
.name = "echo", /* Must match the inetd /etc/services entry */
|
.name = NAME, /* Must match the inetd /etc/services entry */
|
||||||
.inetd = {
|
.inetd = {
|
||||||
.cmd = echo_cb
|
.cmd = cb
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+51
-21
@@ -1,4 +1,4 @@
|
|||||||
/* Optional inetd plugin for time (rdate) protocol RFC 868
|
/* Optional inetd plugin for Time Protocol (rdate), RFC 868
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015 Joachim Nilsson <troglobit@gmail.com>
|
* Copyright (c) 2015 Joachim Nilsson <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
@@ -28,43 +28,73 @@
|
|||||||
|
|
||||||
#include "../plugin.h"
|
#include "../plugin.h"
|
||||||
|
|
||||||
|
#define NAME "time"
|
||||||
|
|
||||||
/* UNIX epoch starts midnight, 1st Jan, 1970 */
|
/* UNIX epoch starts midnight, 1st Jan, 1970 */
|
||||||
#define EPOCH_OFFSET 2208988800ULL
|
#define EPOCH_OFFSET 2208988800ULL
|
||||||
|
|
||||||
/* Return number of seconds since midnight, 1st Jan, 1900 */
|
/* Return number of seconds since midnight, 1st Jan, 1900 */
|
||||||
static int rfc868(int type)
|
static char *rfctime(char *buf, size_t *len)
|
||||||
{
|
{
|
||||||
int sd = STDIN_FILENO;
|
|
||||||
time_t now;
|
time_t now;
|
||||||
struct sockaddr_storage sa;
|
|
||||||
socklen_t sa_len = sizeof(sa);
|
|
||||||
|
|
||||||
if (SOCK_DGRAM == type) {
|
|
||||||
int dummy;
|
|
||||||
|
|
||||||
/* Read empty datagram in UDP mode before sending reply. */
|
|
||||||
if (-1 == recvfrom(sd, &dummy, sizeof(dummy), MSG_DONTWAIT, (struct sockaddr *)&sa, &sa_len))
|
|
||||||
return -1; /* On error, close connection. */
|
|
||||||
}
|
|
||||||
|
|
||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
if ((time_t)-1 == now)
|
if ((time_t)-1 == now)
|
||||||
return -1; /* On error, close connection. */
|
return NULL;
|
||||||
|
|
||||||
/* Account for UNIX epoch offset */
|
/*
|
||||||
|
* Account for UNIX epoch offset, and
|
||||||
|
* convert to network byte order
|
||||||
|
*/
|
||||||
now += EPOCH_OFFSET;
|
now += EPOCH_OFFSET;
|
||||||
|
now = htonl(now);
|
||||||
|
|
||||||
/* Convert to network byte order, not explicitly stated in RFC */
|
*len = sizeof(now);
|
||||||
now = htonl(now);
|
memcpy(buf, &now, *len);
|
||||||
|
|
||||||
/* Send reply, ignore error, simply close connection. */
|
return buf;
|
||||||
return sendto(sd, &now, sizeof(now), MSG_DONTWAIT, (struct sockaddr *)&sa, sa_len);
|
}
|
||||||
|
|
||||||
|
static int recv_peer(int sd, char *buf, ssize_t len, struct sockaddr *sa, socklen_t *sa_len)
|
||||||
|
{
|
||||||
|
len = recvfrom(sd, buf, sizeof(buf), MSG_DONTWAIT, sa, sa_len);
|
||||||
|
if (-1 == len)
|
||||||
|
return -1; /* On error, close connection. */
|
||||||
|
|
||||||
|
if (inetd_check_loop(sa, *sa_len, NAME))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int send_peer(int sd, char *buf, ssize_t len, struct sockaddr *sa, socklen_t sa_len)
|
||||||
|
{
|
||||||
|
char *now;
|
||||||
|
|
||||||
|
now = rfctime(buf, &len);
|
||||||
|
if (!now)
|
||||||
|
return -1; /* On error, close connection. */
|
||||||
|
|
||||||
|
return sendto(sd, now, len, MSG_DONTWAIT, sa, sa_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cb(int type)
|
||||||
|
{
|
||||||
|
int sd = STDIN_FILENO;
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
struct sockaddr_storage sa;
|
||||||
|
socklen_t sa_len = sizeof(sa);
|
||||||
|
|
||||||
|
if (recv_peer(sd, buf, sizeof(buf), (struct sockaddr *)&sa, &sa_len))
|
||||||
|
return -1; /* On error, close connection. */
|
||||||
|
|
||||||
|
return send_peer(sd, buf, sizeof(buf), (struct sockaddr *)&sa, sa_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static plugin_t plugin = {
|
static plugin_t plugin = {
|
||||||
.name = "time", /* Must match the inetd /etc/services entry */
|
.name = NAME, /* Must match the inetd /etc/services entry */
|
||||||
.inetd = {
|
.inetd = {
|
||||||
.cmd = rfc868
|
.cmd = cb
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -589,6 +589,7 @@ recreate:
|
|||||||
if (plugin) {
|
if (plugin) {
|
||||||
/* Internal plugin provides this service */
|
/* Internal plugin provides this service */
|
||||||
svc->inetd.cmd = plugin->inetd.cmd;
|
svc->inetd.cmd = plugin->inetd.cmd;
|
||||||
|
svc->inetd.builtin = 1;
|
||||||
} else {
|
} else {
|
||||||
strlcpy(svc->args[i++], cmd, sizeof(svc->args[0]));
|
strlcpy(svc->args[i++], cmd, sizeof(svc->args[0]));
|
||||||
while ((cmd = strtok(NULL, " ")))
|
while ((cmd = strtok(NULL, " ")))
|
||||||
|
|||||||
Reference in new issue
Block a user