Re: inetd(8): continue or exit on error?

2023-06-03 Thread David Holland
On Fri, Jun 02, 2023 at 01:21:15PM +0200, tlaro...@polynum.com wrote:
 > > I have not read most of the traffic yet, but I feel, fairly strongly,
 > > that inetd should _not_ exit, except (maybe) if the config is broken
 > > during its initial startup. It's a critical service.
 > 
 > So I will put together the result of the exchanges in the thread and of
 > my reading of the source:
 > 
 > Not stopping on an error was logical with the old syntax since _all the
 > directives were independent_: failing to read a line for a service
 > shouldn't have the side effect of failing to serve the other services.
 > 
 > But this assumption does not anymore with the new syntax: the feature of
 > the implicit address---one does not need to specify an address: it will
 > then be what is the default at the moment---makes the config a whole,
 > and failing on a line may define the default address with something
 > completely different from what was intended: what will be the result of
 > runnin login on the external interface instead of an internal one?
 > 
 > => a failure in the config now must discard the whole config.

I don't understand. You read the config, you check it, if it's bad you
complain to syslog and if it's good you install it. There's still no
reason to exit.

 > If the [-r] mode is asked for (r for "resilient"), in case of failure to
 > validate the config, inetd falls back to "/etc/inetd.fallback.conf" that
 > is also parses and, if checking successful, served. If even this
 > fallback fails, inetd(8) does not exit but serves the "no-op" config: it
 > does nothing simply waiting for the instruction to reload the config
 > ("the config" is always the one passed, explicitely or implicitely, on
 > the call).

That sounds way more complicated than necessary.

-- 
David A. Holland
dholl...@netbsd.org


Re: inetd(8): continue or exit on error?

2023-06-02 Thread tlaronde
Le Fri, Jun 02, 2023 at 07:01:40AM +, David Holland a écrit :
> On Mon, May 29, 2023 at 10:11:09AM +0200, tlaro...@polynum.com wrote:
>  > There are infelicities in /usr/src/usr.sbin/inetd/parse.c and I will
>  > send a PR with patches attached.
>  > 
>  > The question is what to do in case of a config file not found (this is
>  > the initial problem: the realpath() return status is not tested and a
>  > structure is inconditionnally added to a linked list with an unreachable
>  > config file).
>  > 
>  > It seems to me, since these are services, that the failure to load a
>  > config is critical enough (since the server may be then servicing what
>  > was not intended to be serviced; the reverse is less problematic)
>  > to exit at least on this error.
>  > 
>  > What do others think?
> 
> I have not read most of the traffic yet, but I feel, fairly strongly,
> that inetd should _not_ exit, except (maybe) if the config is broken
> during its initial startup. It's a critical service.

So I will put together the result of the exchanges in the thread and of
my reading of the source:

Not stopping on an error was logical with the old syntax since _all the
directives were independent_: failing to read a line for a service
shouldn't have the side effect of failing to serve the other services.

But this assumption does not anymore with the new syntax: the feature of
the implicit address---one does not need to specify an address: it will
then be what is the default at the moment---makes the config a whole,
and failing on a line may define the default address with something
completely different from what was intended: what will be the result of
runnin login on the external interface instead of an internal one?

=> a failure in the config now must discard the whole config.

Hence to address this and the need for essential services the following
will be done (in the process in fact):

Two modes:

Server mode: inetd [-rl] [-f [-d]] [rooted_config]

Checker mode: inetd -c [-d] [rooted_config]

inetd always checks the config it is asked to serve first and does not
serve anything before validating the config. If default mode, a failure
to check the config causes an exit of the daemon.

Disentangling the parsing from the executing/serving, there is a check
mode that just parses the config and returns EXIT_SUCCESS if the config
is OK, EXIT_FAILURE if not (unfortunately, there is no EXIT_RTFM to
indicate that the call was nonsense...).

Checker mode:

So inetd just exits with the status in check mode. In check mode, if -d
is given, debug message about the parsing (and the errors) are sent to
stderr and, if successful, the parsed config in new syntax is sent to
stdout. Nothing is printed if [-d] is not given.

Server mode:

Inetd always checks the config and if the convid is invalid it exits
with error (default mode).

If the [-r] mode is asked for (r for "resilient"), in case of failure to
validate the config, inetd falls back to "/etc/inetd.fallback.conf" that
is also parses and, if checking successful, served. If even this
fallback fails, inetd(8) does not exit but serves the "no-op" config: it
does nothing simply waiting for the instruction to reload the config
("the config" is always the one passed, explicitely or implicitely, on
the call).

Still in resilient mode, if the server is instructed to reload the
config, it does not stop serving the old but first checks the new. If
the new is valid, it switches to these new instructions. If the new is
not valid, it continues to serve the current served one.

In daemon mode but in foreground mode, messages are logged via syslog.

When in foreground, messages go to stderr.

A new control is added:

Sending USR1 signal instruct inetd to switch to the fallback config (it
is not "sticky": when instructed to reload via HUP, it will reload "the
config" not the fallback one).

Compatibility:

I was unhappy about:

-d run in foreground and add debug messages
-f run in foreground

that seems to me not very Unix like.

Hence the [-f [-d]] but for compatibility in the switch it is a
fallthrough: case d will fallthrough f so the behavior will be the same.

-c takes also -d; no problem since -cfd will invoke the checker, not the
daemon: "inetd is human and always grasps to the first opportunity to do
less work".
-- 
Thierry Laronde 
 http://www.kergis.com/
http://kertex.kergis.com/
Key fingerprint = 0FF7 E906 FBAF FE95 FD89  250D 52B1 AE95 6006 F40C


Re: inetd(8): continue or exit on error?

2023-06-02 Thread David Holland
On Mon, May 29, 2023 at 10:11:09AM +0200, tlaro...@polynum.com wrote:
 > There are infelicities in /usr/src/usr.sbin/inetd/parse.c and I will
 > send a PR with patches attached.
 > 
 > The question is what to do in case of a config file not found (this is
 > the initial problem: the realpath() return status is not tested and a
 > structure is inconditionnally added to a linked list with an unreachable
 > config file).
 > 
 > It seems to me, since these are services, that the failure to load a
 > config is critical enough (since the server may be then servicing what
 > was not intended to be serviced; the reverse is less problematic)
 > to exit at least on this error.
 > 
 > What do others think?

I have not read most of the traffic yet, but I feel, fairly strongly,
that inetd should _not_ exit, except (maybe) if the config is broken
during its initial startup. It's a critical service.

At the moment it's no longer the case that remote machines are likely
to become completely inaccessible and require a site visit if inetd
craps out, but that could change again in the future.

There's at least one variant inetd out there that does not exit once
started, except for SIGTERM. I know this, because I wrote/patched it :-)

-- 
David A. Holland
dholl...@netbsd.org


Re: inetd(8): continue or exit on error?

2023-05-29 Thread tlaronde
Le Mon, May 29, 2023 at 07:49:44AM -0400, Mouse a écrit :
> >> I'm not sure inetd(8) has any business calling realpath in the first
> >> place.
> 
> I agree.
> 
> > It has to call realpath(3) since in order to not include several
> > times the same file, it makes strings comparaisons about names.
> 
> If I as an admin write a config that tries to include the same file
> twice, whether via the same or different paths, I expect it to include
> the same file twice.  If that leads to errors, that's on me.  (It might
> or might not _always_ lead to an error, depending on how the include
> file syntax is defined to interact with the stateful aspects of the
> config language and what's in the config files.)

I tend to agree that since, with globbing, the order of the inclusion of
files is not guaranteed, reloading several times the same file, as long
as there is no loop, is not less legitimate (but for
globbing, there could be an added defined behavior to sort
lexicographically the files list so that carefully choosen names can
guarantee a defined order of inclusion; and this will be compatible with
"present" behavior, since no order was guaranteed; hence any order
imposed now will do). 

But, at first, I will add a flag to check the present syntax and keep 
the present theorical behavior (in fact, due to bugs, it doesn't
work), and will correct the bugs and make the program exit on error.

And only in a second time, perhaps review the way things are processed
(perhaps allowing multiple inclusions of the same file---do what
the admin requested; as you wrote, it is his work so his responsability
as long as, syntactically, the program can parse what he asked, deliver).

> If you really want to avoid including the same file twice even if
> that's what the config says to do, I'd say it should do so with
> dev/ino > comparisons, not pathname comparisons.

Yes. Since the operation of calling realpath then open is definitively
not atomic, hence the success of realpath(3) been no guarantee of the
opening of the file, and since realpath has to go in kernel space also,
so there is no process time gained, even if I maintain the not multiple
inclusions for the first step, I will make the comparisons with lower
level identifiers. 
-- 
Thierry Laronde 
 http://www.kergis.com/
http://kertex.kergis.com/
Key fingerprint = 0FF7 E906 FBAF FE95 FD89  250D 52B1 AE95 6006 F40C


Re: inetd(8): continue or exit on error?

2023-05-29 Thread Taylor R Campbell
> Date: Mon, 29 May 2023 10:11:09 +0200
> From: tlaro...@polynum.com
> 
> The question is what to do in case of a config file not found (this is
> the initial problem: the realpath() return status is not tested and a
> structure is inconditionnally added to a linked list with an unreachable
> config file).

I'm not sure inetd(8) has any business calling realpath in the first
place.  Can we just remove it and let it continue to use paths exactly
as written in the config file?


Re: inetd(8): continue or exit on error?

2023-05-29 Thread Mouse
>> I'm not sure inetd(8) has any business calling realpath in the first
>> place.

I agree.

> It has to call realpath(3) since in order to not include several
> times the same file, it makes strings comparaisons about names.

If I as an admin write a config that tries to include the same file
twice, whether via the same or different paths, I expect it to include
the same file twice.  If that leads to errors, that's on me.  (It might
or might not _always_ lead to an error, depending on how the include
file syntax is defined to interact with the stateful aspects of the
config language and what's in the config files.)

If you really want to avoid including the same file twice even if
that's what the config says to do, I'd say it should do so with dev/ino
comparisons, not pathname comparisons.

/~\ The ASCII Mouse
\ / Ribbon Campaign
 X  Against HTMLmo...@rodents-montreal.org
/ \ Email!   7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B


Re: inetd(8): continue or exit on error?

2023-05-29 Thread tlaronde
Le Mon, May 29, 2023 at 11:20:32AM +, Taylor R Campbell a écrit :
> > Date: Mon, 29 May 2023 10:11:09 +0200
> > From: tlaro...@polynum.com
> > 
> > The question is what to do in case of a config file not found (this is
> > the initial problem: the realpath() return status is not tested and a
> > structure is inconditionnally added to a linked list with an unreachable
> > config file).
> 
> I'm not sure inetd(8) has any business calling realpath in the first
> place.  Can we just remove it and let it continue to use paths exactly
> as written in the config file?

It has to call realpath(3) since in order to not include several times
the same file, it makes strings comparaisons about names. Hence a file
has to have some canonical form, not maskerading with differing forms
or it will not be able to detect it is the same file or to detect a
loop.
-- 
Thierry Laronde 
 http://www.kergis.com/
http://kertex.kergis.com/
Key fingerprint = 0FF7 E906 FBAF FE95 FD89  250D 52B1 AE95 6006 F40C


Re: inetd(8): continue or exit on error?

2023-05-29 Thread tlaronde
Le Mon, May 29, 2023 at 11:19:22AM +, Taylor R Campbell a écrit :
> > Date: Mon, 29 May 2023 13:13:33 +0200
> > From: tlaro...@polynum.com
> > 
> > I'm for: exit on any error. If we provide a way to check, that's the
> > responsability of the administrator to check his config before trying to
> > run the thing.
> 
> Yes please.  Should provide an option to check a configuration file
> without starting inetd(8), make `service inetd check' do this, and
> make `service inetd reload' (maybe also `service inetd restart') do
> check first.  This should be standard practice for all daemons.

So: OK. I take this one (inetd) and will do it sometime in the week
(at worst, you should here from me on Monday the 4th).
-- 
Thierry Laronde 
 http://www.kergis.com/
http://kertex.kergis.com/
Key fingerprint = 0FF7 E906 FBAF FE95 FD89  250D 52B1 AE95 6006 F40C


Re: inetd(8): continue or exit on error?

2023-05-29 Thread Taylor R Campbell
> Date: Mon, 29 May 2023 13:13:33 +0200
> From: tlaro...@polynum.com
> 
> I'm for: exit on any error. If we provide a way to check, that's the
> responsability of the administrator to check his config before trying to
> run the thing.

Yes please.  Should provide an option to check a configuration file
without starting inetd(8), make `service inetd check' do this, and
make `service inetd reload' (maybe also `service inetd restart') do
check first.  This should be standard practice for all daemons.


Re: inetd(8): continue or exit on error?

2023-05-29 Thread tlaronde
Le Mon, May 29, 2023 at 11:43:33AM +0100, David Brownlee a écrit :
> On Mon, 29 May 2023 at 11:38, Michael van Elst  wrote:
> >
> > tlaro...@polynum.com writes:
> >
> > >If inetd is not running, if the administrator doesn't look at the logs,
> >
> > That's why people monitor services and logs and use manual or
> > automated procedures to validate and deploy configuration changes.
> 
> I have a slight preference towards 'exit on error', but both options
> have completely valid use cases.
> Could add a command line flag to determine whether to exit on error.
> Is there any prior art in other BSDs/Linux?
> One aspect to bear in mind is that inetd has been around ~forever, and
> conventions have changed over time.
> 
> > >At least, wouldn't it be worth to add a flag simply to parse and
> > >validate the syntax without running the daemon?
> >
> > It's always a good thing to be able to validate a configuration.
> 
> This absolutely sounds like a nice idea - could then be chained in
> rc.d so 'inetd reload' could check the file and abort with an error
> rather than reloading (similar to the recent sshd changes)
> 

So seems others are OK at least for the checking without running (that
seems to me the bare minimum to provide due to the complexity of the
thing and the security implications).

But I will once more plead for exit on error due to this feature (from
the man page):

---8<---
To avoid the need to repeat listen addresses over and over again, listen
addresses are inherited from line to line, and the listen address
can be changed without defining a service by including a line containing
just a listen-addr followed by a colon.
--->8---

If one such line fails, all that will be parsed after (necessarily from
another file) will potentially not listen where it should!

Imagine what it can be if telnet is listening on 22!

(One solution: clear the definition of the default address defhost when
including another file.)

I'm for: exit on any error. If we provide a way to check, that's the
responsability of the administrator to check his config before trying to
run the thing.

I will also modify the man page, because including several times the
same config files has not an undefined behavior (well, at the moment:
yes, but only because of a blunder in the code): the file is only
included once; every other appearance is skipped (it doesn't really work
at the moment due to the bugs).

Thing that I will not do now but could be done: when globbing is used
and this results in several files, since the order of inclusion is
random, verify that the files are orthogonal and exit with error if they
are not.
-- 
Thierry Laronde 
 http://www.kergis.com/
http://kertex.kergis.com/
Key fingerprint = 0FF7 E906 FBAF FE95 FD89  250D 52B1 AE95 6006 F40C


Re: inetd(8): continue or exit on error?

2023-05-29 Thread David Brownlee
On Mon, 29 May 2023 at 11:38, Michael van Elst  wrote:
>
> tlaro...@polynum.com writes:
>
> >If inetd is not running, if the administrator doesn't look at the logs,
>
> That's why people monitor services and logs and use manual or
> automated procedures to validate and deploy configuration changes.

I have a slight preference towards 'exit on error', but both options
have completely valid use cases.
Could add a command line flag to determine whether to exit on error.
Is there any prior art in other BSDs/Linux?
One aspect to bear in mind is that inetd has been around ~forever, and
conventions have changed over time.

> >At least, wouldn't it be worth to add a flag simply to parse and
> >validate the syntax without running the daemon?
>
> It's always a good thing to be able to validate a configuration.

This absolutely sounds like a nice idea - could then be chained in
rc.d so 'inetd reload' could check the file and abort with an error
rather than reloading (similar to the recent sshd changes)

Thanks

David


Re: inetd(8): continue or exit on error?

2023-05-29 Thread Michael van Elst
tlaro...@polynum.com writes:

>If inetd is not running, if the administrator doesn't look at the logs,

That's why people monitor services and logs and use manual or
automated procedures to validate and deploy configuration changes.

>At least, wouldn't it be worth to add a flag simply to parse and
>validate the syntax without running the daemon?

It's always a good thing to be able to validate a configuration.




Re: inetd(8): continue or exit on error?

2023-05-29 Thread tlaronde
Le Mon, May 29, 2023 at 11:47:28AM +0200, tlaro...@polynum.com a écrit :
> 
> And some log messages are problematic too:
> 
> DPRINTCONF("Syntax error; Exiting '%s'", CONFIG);
> 
> while it never exits: the function returns an invalid status code, and
> the process goes on...

For this, I mean "Quitting '%s'" is what it does. "Exiting" has an
implicit meaning when it comes to a program. A program exits, but you
don't "exit" a file.
-- 
Thierry Laronde 
 http://www.kergis.com/
http://kertex.kergis.com/
Key fingerprint = 0FF7 E906 FBAF FE95 FD89  250D 52B1 AE95 6006 F40C


Re: inetd(8): continue or exit on error?

2023-05-29 Thread tlaronde
Le Mon, May 29, 2023 at 09:03:07AM -, Michael van Elst a écrit :
> tlaro...@polynum.com writes:
> 
> >It seems to me, since these are services, that the failure to load a
> >config is critical enough (since the server may be then servicing what
> >was not intended to be serviced; the reverse is less problematic)
> >to exit at least on this error.
> 
> inetd will service what is configured. Skipping an unparsable directive
> may have unwanted side effects, but so will a syntactically correct but
> otherwise wrong directive.
> 
> The impact of not providing some services in case of a syntax error
> can easily be as problematic or dangerous as a wrongly configured service
> that the parser is unable to detect.
> 
> If you want to protect against bad configurations, you could separate
> each service, e.g. chose a syntax without side effects or even use
> a config file per service.

We can not achieve "semantical" correctness: be able to "understand"
what the user wanted to do. But, at least, if a config file is not
reachable or if a directive is unparsable, there is obviously something
wrong.

If inetd is not running, if the administrator doesn't look at the logs,
he will very probably be reachable by phone or by email, and users will
be sure telling him that something is wrong...

At least, wouldn't it be worth to add a flag simply to parse and
validate the syntax without running the daemon?

And some log messages are problematic too:

DPRINTCONF("Syntax error; Exiting '%s'", CONFIG);

while it never exits: the function returns an invalid status code, and
the process goes on...
-- 
Thierry Laronde 
 http://www.kergis.com/
http://kertex.kergis.com/
Key fingerprint = 0FF7 E906 FBAF FE95 FD89  250D 52B1 AE95 6006 F40C


Re: inetd(8): continue or exit on error?

2023-05-29 Thread Michael van Elst
tlaro...@polynum.com writes:

>It seems to me, since these are services, that the failure to load a
>config is critical enough (since the server may be then servicing what
>was not intended to be serviced; the reverse is less problematic)
>to exit at least on this error.

inetd will service what is configured. Skipping an unparsable directive
may have unwanted side effects, but so will a syntactically correct but
otherwise wrong directive.

The impact of not providing some services in case of a syntax error
can easily be as problematic or dangerous as a wrongly configured service
that the parser is unable to detect.

If you want to protect against bad configurations, you could separate
each service, e.g. chose a syntax without side effects or even use
a config file per service.



inetd(8): continue or exit on error?

2023-05-29 Thread tlaronde
There are infelicities in /usr/src/usr.sbin/inetd/parse.c and I will
send a PR with patches attached.

The question is what to do in case of a config file not found (this is
the initial problem: the realpath() return status is not tested and a
structure is inconditionnally added to a linked list with an unreachable
config file).

It seems to me, since these are services, that the failure to load a
config is critical enough (since the server may be then servicing what
was not intended to be serviced; the reverse is less problematic)
to exit at least on this error.

What do others think?
-- 
Thierry Laronde 
 http://www.kergis.com/
http://kertex.kergis.com/
Key fingerprint = 0FF7 E906 FBAF FE95 FD89  250D 52B1 AE95 6006 F40C