Overview: www/shttpd includes a switch to run under inetd(8), and a sample line for inetd.conf. When run from inetd, shttpd attempts to open a listening socket, instead of using stdin/stdout for communications, and sends an error message back to the browser.
Steps to reproduce:
- pkg install shttpd
- copy inetd.conf line from man page (http stream tcp nowait nobody /bin/shttpd shttpd -inetd 1 -root /var/www)
- place a text file in the webroot for shttpd to serve
- service inetd reload
- attempt to browse to web server (e.g., http://server.local/)
Web browser displays an error that should have gone to stderr. There's no HTTP headers, so this probably shouldn't go out on the wire. Also note that even if the actual port is changed (by replacing 'http' in the inetd.conf line with another service), shttpd still tries to open the default port 80. If you include a -ports ## switch in the inetd command line, it will attempt to open that port, and if the port is above 1024, you'll get a segfault instead (see additional info below.)
open_listening_port(80): Permission denied
cannot open port 80
Cannot initialize SHTTPD context
shttpd auto-generates a directory listing, or serves up the index.htm file, if it exists. Compare to non-inetd functionality: remove the inetd entry, run shttpd -root /var/www -ports 8080 (or run as root), and then access the server.
Build and hardware:
shttpd 1.42, FreeBSD 11.0-RELEASE-p10, amd64
This failure can also be provoked on the command line, by using echo 'GET / HTTP/1.1' | shttpd -inetd 1. I'm not too good with C, so I couldn't track it down myself, but in the source file shttpd.c, the similar-but-distinct set_opt() (line 1780) and shttpd_set_option() (line 1689) look like an option may not get properly set, depending on which version is used. Also, set_inetd() (line 1392) is asking for a segfault by setting ctx to NULL and then dereferencing it. This segfault can be observed by running from the command line, as above, and adding '-ports 8080', or any other unprivileged port.