mirror of
https://github.com/troglobit/finit.git
synced 2026-11-01 13:10:32 +00:00
Add support for a deny filter syntax to inetd services
This patch changes the syntax for custom inetd services and adds support
for deny filters. The new syntax is:
inetd service/proto[@iface,!iface,...] </path/to/cmd | internal[.service]>
This means the second column now defines what@from and the third to/what
process. For internal services on a custom port the internal.service
syntax must be specified, so Finit can properly bind the inetd service
to the correct plugin. Here follows a few examples:
inetd time/udp wait [2345] internal -- UNIX rdate service
inetd time/tcp nowait [2345] internal -- UNIX rdate service
inetd 3737/tcp nowait [2345] internal.time -- UNIX rdate service
inetd telnet/tcp@*,!eth1,!eth0, nowait [2345] /sbin/telnetd -i -F -- Telnet service
inetd 2323/tcp@eth1,eth2,eth0 nowait [2345] /sbin/telnetd -i -F -- Telnet service
inetd 222/tcp@eth0 nowait [2345] /sbin/dropbear -i -R -F -- SSH service
inetd ssh/tcp@*,!eth0 nowait [2345] /sbin/dropbear -i -R -F -- SSH service
Access to telnet on port `2323` is only possible from interfaces `eth0`,
`eth1` and `eth2`. The standard telnet port (`23`) is available from
all other interfaces, but also `eth2`. The `*` notation used in the ssh
stanza means *any* interface, however, here `eth0` is not allowed.
NOTE: This patch breaks syntax compatibility with Finit v1.12!
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
1 parent
b0c759e518
commit
03573b41ca
7 files changed
+177
-195
No files matched your search
@@ -42,7 +42,7 @@ static int is_norespawn (void);
|
||||
static void restart_lost_procs (void);
|
||||
static void svc_dance (svc_t *svc);
|
||||
static void utmp_save (int pre, int now);
|
||||
static svc_t *find_inetd_svc (char *path, char *service, char *proto, char *port);
|
||||
static svc_t *find_inetd_svc (char *path, char *service, char *proto);
|
||||
|
||||
|
||||
/**
|
||||
@@ -537,7 +537,7 @@ int service_register(int type, char *line, time_t mtime, char *username)
|
||||
#ifndef INETD_DISABLED
|
||||
int forking = 0;
|
||||
#endif
|
||||
char *service = NULL, *proto = NULL, *iface = NULL, *port = NULL;
|
||||
char *service = NULL, *proto = NULL, *ifaces = NULL;
|
||||
char *cmd, *desc, *runlevels = NULL;
|
||||
svc_t *svc;
|
||||
plugin_t *plugin = NULL;
|
||||
@@ -582,37 +582,42 @@ int service_register(int type, char *line, time_t mtime, char *username)
|
||||
goto incomplete;
|
||||
}
|
||||
|
||||
/* Example: inetd ssh@eth0:222/tcp */
|
||||
/* Example: inetd ssh/tcp@eth0,eth1 or 222/tcp@eth2 */
|
||||
if (service) {
|
||||
ifaces = strchr(service, '@');
|
||||
if (ifaces)
|
||||
*ifaces++ = 0;
|
||||
|
||||
proto = strchr(service, '/');
|
||||
if (!proto)
|
||||
goto incomplete;
|
||||
*proto++ = 0;
|
||||
|
||||
port = strchr(service, ':');
|
||||
if (port)
|
||||
*port++ = 0;
|
||||
|
||||
iface = strchr(service, '@');
|
||||
if (iface)
|
||||
*iface++ = 0;
|
||||
}
|
||||
|
||||
#ifndef INETD_DISABLED
|
||||
/* Find plugin that provides a callback for this inetd service */
|
||||
if (type == SVC_TYPE_INETD) {
|
||||
if (!strncasecmp(cmd, "internal", 8)) {
|
||||
plugin = plugin_find(service);
|
||||
char *ptr, *ps = service;
|
||||
|
||||
/* internal.service */
|
||||
ptr = strchr(cmd, '.');
|
||||
if (ptr) {
|
||||
*ptr++ = 0;
|
||||
ps = ptr;
|
||||
}
|
||||
|
||||
plugin = plugin_find(ps);
|
||||
if (!plugin || !plugin->inetd.cmd) {
|
||||
_e("Inetd service %s has no internal plugin, skipping.", service);
|
||||
return errno = ENOENT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if known inetd, then add ifname for filtering only. */
|
||||
svc = find_inetd_svc(cmd, service, proto, port);
|
||||
/* Check if known inetd, then add ifnames for filtering only. */
|
||||
svc = find_inetd_svc(cmd, service, proto);
|
||||
if (svc)
|
||||
return inetd_allow(&svc->inetd, iface);
|
||||
goto inetd_setup;
|
||||
|
||||
id = svc_next_id(cmd);
|
||||
}
|
||||
@@ -644,23 +649,6 @@ int service_register(int type, char *line, time_t mtime, char *username)
|
||||
strlcpy(svc->username, username, sizeof(svc->username));
|
||||
}
|
||||
|
||||
#ifndef INETD_DISABLED
|
||||
if (svc_is_inetd(svc)) {
|
||||
int result;
|
||||
|
||||
_d("Creating new svc job %d inetd %s proto %s iface %s port %s",
|
||||
svc->job, service, proto, iface, port);
|
||||
result = inetd_new(&svc->inetd, service, proto, forking);
|
||||
result += inetd_init(&svc->inetd, svc, iface, port);
|
||||
|
||||
if (result) {
|
||||
_e("Failed registering new inetd service %s.", service);
|
||||
inetd_del(&svc->inetd);
|
||||
return svc_del(svc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (plugin) {
|
||||
/* Internal plugin provides this service */
|
||||
svc->inetd.cmd = plugin->inetd.cmd;
|
||||
@@ -681,6 +669,35 @@ int service_register(int type, char *line, time_t mtime, char *username)
|
||||
svc->runlevels = parse_runlevels(runlevels);
|
||||
_d("Service %s runlevel 0x%2x", svc->cmd, svc->runlevels);
|
||||
|
||||
#ifndef INETD_DISABLED
|
||||
if (svc_is_inetd(svc)) {
|
||||
char *iface;
|
||||
|
||||
_d("Creating new svc job %d inetd %s proto %s iface %s",
|
||||
svc->job, service, proto, ifaces);
|
||||
if (inetd_new(&svc->inetd, service, proto, forking, svc)) {
|
||||
_e("Failed registering new inetd service %s.", service);
|
||||
inetd_del(&svc->inetd);
|
||||
return svc_del(svc);
|
||||
}
|
||||
|
||||
inetd_setup:
|
||||
if (!ifaces) {
|
||||
_d("No specific iface listed for %s, allowing ANY.", service);
|
||||
return inetd_allow(&svc->inetd, NULL);
|
||||
}
|
||||
|
||||
_d("Setting up interface filters for inetd service %s ...", service);
|
||||
for (iface = strtok(ifaces, ","); iface; iface = strtok(NULL, ",")) {
|
||||
_d("Checking interface name %s ...", iface);
|
||||
if (iface[0] == '!')
|
||||
inetd_deny(&svc->inetd, &iface[1]);
|
||||
else
|
||||
inetd_allow(&svc->inetd, iface);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -814,7 +831,7 @@ static void utmp_save(int pre, int now)
|
||||
}
|
||||
|
||||
#ifndef INETD_DISABLED
|
||||
static svc_t *find_inetd_svc(char *path, char *service, char *proto, char *port)
|
||||
static svc_t *find_inetd_svc(char *path, char *service, char *proto)
|
||||
{
|
||||
svc_t *svc;
|
||||
|
||||
@@ -822,8 +839,8 @@ static svc_t *find_inetd_svc(char *path, char *service, char *proto, char *port)
|
||||
if (strncmp(path, svc->cmd, strlen(svc->cmd)))
|
||||
continue;
|
||||
|
||||
if (inetd_match(&svc->inetd, service, proto, port)) {
|
||||
_d("Found a matching inetd svc for %s %s %s %s", path, service, proto, port);
|
||||
if (inetd_match(&svc->inetd, service, proto)) {
|
||||
_d("Found a matching inetd svc for %s %s %s", path, service, proto);
|
||||
return svc;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user