Nweb: a tiny, safe web server (static pages only)
ibm.com
ibm.com
I'm not saying it's secure, but I certainly intended it to be, and it doesn't suffer from the particular problems tptacek, evmar, kedean, and nknighthb identify in nweb. I'd like to think I'm not naïve enough to have written problems like that, but that's probably not true.
(I'm pretty sure that "Try my new secure software!" is something that should not be followed with "I wrote it in C!" but usually assembly language is not going to be an improvement. In this case I think it happens to be.)
httpdito was discussed on HN a bit before it was finished; for example, it's no longer completely trivial to DoS it, although I could do more to protect it against that.
Also, casting function calls to (void) is nonsensical.
You can perhaps forgive the sprintf() call because, AIX. (Believe it or not, there was a time when snprintf was a portability problem). You can't forgive the log() function that doesn't explicitly bounds check its argument (though it's not exploitable in this code).
This is an older convention to indicate that the programmer knows the function returns a value but has chosen to ignore it. It got around the false positives generated by lint.
This code uses SIGCLD which I don't think is supported by BSD, where it is called SIGCHLD and is slightly different (someone please correct me if I'm wrong). If that's the case, then the author's assertion that it "should run unchanged on AIX, Linux®, or any other UNIX version" is incorrect - it will only run on System V varieties.
I had to change it to SIGCHLD to get it to compile on my Mac.
This also has the side effect of this implementation not supporting IPv6, among others.
So please, don't use this as anything other than an example how not to do sockets.
If you want to learn how to do it right, I can recommend the excellent "Guide to Network Programming Using Internet Sockets" by Brian "Beej Jorgensen" Hall (You should definitely buy the printed version, just to support him :)).
Does extremely pedantic C require the results of function calls to be used?
I know the correct way to mark a variable as unused is to cast it to void, but I'm not sure if you're supposed to do that for function return values as well.
(void)create_widget(&widget);
It's clear that `create_widget` returns some value -- it's probably an error code that tells us whether the widget creation was successful. The source code here says "I know this function returns an important value, but I'm going to disregard it here". This could be useful for debugging if you find that, for example, an error condition is being handled improperly (e.g. "oh, we're obviously throwing out the return value of this function, which we shouldn't be doing"). This function call is much less informative: create_widget(&widget);You can see exactly what it can and can't do.
Thank you Mr. Griffiths. Your example will help extend my understanding of an http server, even if I don't intend on writing one. I would never read through the 90 klocs of httpd.
* BUFSIZE is 8096.
* logbuffer (the local variable) is BUFSIZEx2
* s1 looks like it's always trusted and an order of magnitude smaller than BUFSIZE.
* The format strings and numbers are nowhere near big enough to make up the difference.
* Where s2 is untrusted data, I think it's always guaranteed to be <=BUFSIZE and zero-terminated.
But there are definitely other possible issues I haven't looked at closely, and I'm certainly troubled that this mess has showed up on an IBM site as an example of a "safe" web server.
Folks building embedded stuff have been using this stuff to create their UIs for like forever it seems, and this kind of web server works pretty well in that capacity.
It appears that if you request a path like "//etc/foobar" with two slashes at the front it'll allow traversal outside the starting directory, though it's mitigated by checking file extensions.
DJB appears to have changed the license to public domain, but at some point in the past there was a license that prohibited distribution of binaries from modified source. There's still the request that the paths not be changed to comply with the FHS.
DJB has strong opinions about the construction and distribution of software. So do quite a lot of debian people. These views are incompatible.
I think the reason is low demand largely due to the fact that gnome-desktop depends on gnome-user-share (AKA: apache).
ruby -e 'require "rack"; include Rack; \
Server.start :app => Directory.new(".", \
Static.new(nil, :urls => ["/"], :root => "."))' python -m SimpleHTTPServer ruby -run -ehttpd .
Here's a handy snippet for bashrc: function S {
ruby -run -ehttpd . -p${1-8080} # default to port 8080 unless given as parameter
} twistd -no web --path=.Python is nearly always installed, and that depends on nothing but the standard library. You can stick an alias in your dotfiles (I have, it's called "serve-this") and not have to worry about having twisted¹ getting to wherever your dotfiles get put. (I distribute my dotfiles over git/github, so it's really easy to move them around. More work to get Twisted.)
¹Or Ruby… or Go…
package main
import (
"flag"
"net/http"
)
var serveDir = flag.String("d", ".", "Directory to serve from")
func main() {
flag.Parse()
panic(http.ListenAndServe("127.0.0.1:8000", http.FileServer(
http.Dir(*serveDir))))
} #!/bin/bash
unlink /Library/WebServer/Documents
ln -s "$(pwd)" /Library/WebServer/Documents
echo "http://localhost/ mounted on $(pwd)"
Of course, it's only "lightweight" in as far as you already have Apache installed and running.You could always try to package it for Debian, although I understand that's not a small amount of work.
I don't know of anything else designed for security. Hard to beat DJB in that respect. If you left out the security requirement, I would say just use the Python SimpleHTTPServer. I think it's probably secure, but definitely not explicitly designed for it.
Thanks in advance.
Edit: I "know" C and C++ and would like to remain in one of these languages, if it's not asking too much.
Having said this, have a look at Wt and Poco
It is not a HTTP server, but a library to create your own ones. With many examples, as a trivial only share files at https://github.com/davidmoreno/onion/blob/master/examples/ba...
thttpd is a very, very nice tool. It's very handy sometimes to just fire up thttpd -d /some/dir because you want to look at the contents of the dir in a web browser but don't want to spin up the whole environment and server, etc.
I put thttpd on a lot of informal servers just to have it around when I need something like that...
Although it was largely unfinished, the approach outlined in C10m would be interesting to see implemented here (via the intel user-space driver).
can someone explain that please?
After the last byte of the file is sent, the nweb web server web() function stops for one second. This is to enable the file contents to be sent down the socket. If it immediately closes the socket, some operating systems do not wait for the socket to finish sending the data but drops the connection very abruptly. This would mean that some of the file content would not get to the browser, and this confuses the browser by waiting forever for the last bit of the file and often results in a blank web page being displayed.
Still it's good for building your confidence as a programmer, no?
would this cause connection timeouts if copying data to the socket took longer than one second? i'm always a bit sceptical when i encounter such seemingly arbitrary timing assumptions.
The technical criticisms are confirmation of that. How many HN submissions to open source projects are as well explained?
> python -m SimpleHTTPServer