X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/agedu/blobdiff_plain/812e4bf21dbd3754acf9cec3ea8065054f684c8e..9c6e61f23dd65086378606be16d3740d909477d4:/httpd.c diff --git a/httpd.c b/httpd.c index 486ca21..8087a28 100644 --- a/httpd.c +++ b/httpd.c @@ -20,7 +20,8 @@ #include #include -#include "malloc.h" +#include "agedu.h" +#include "alloc.h" #include "html.h" #include "httpd.h" @@ -66,7 +67,7 @@ static char *http_error(char *code, char *errmsg, char *extraheader, { return dupfmt("HTTP/1.1 %s %s\r\n" "Date: %D\r\n" - "Server: agedu\r\n" + "Server: " PNAME "\r\n" "Connection: close\r\n" "%s" "Content-Type: text/html; charset=US-ASCII\r\n" @@ -87,7 +88,7 @@ static char *http_success(char *mimetype, int stuff_cr, char *document) return dupfmt("HTTP/1.1 200 OK\r\n" "Date: %D\r\n" "Expires: %D\r\n" - "Server: agedu\r\n" + "Server: " PNAME "\r\n" "Connection: close\r\n" "Content-Type: %s\r\n" "\r\n" @@ -103,7 +104,8 @@ static char *http_success(char *mimetype, int stuff_cr, char *document) * socket before closing it. */ char *got_data(struct connctx *ctx, char *data, int length, - int magic_access, const char *auth_string) + int magic_access, const char *auth_string, + const struct html_config *cfg) { char *line, *p, *q, *r, *z1, *z2, c1, c2; int auth_provided = 0, auth_correct = 0; @@ -185,7 +187,7 @@ char *got_data(struct connctx *ctx, char *data, int length, /* Restore the request to the way we received it. */ *z2 = c2; *z1 = c1; - text = dupfmt("agedu received the HTTP request" + text = dupfmt("" PNAME " received the HTTP request" " \"%h\", which contains no URL.", line); ret = http_error("400", "Bad request", NULL, text); @@ -278,8 +280,8 @@ char *got_data(struct connctx *ctx, char *data, int length, if (!magic_access && !auth_correct) { if (auth_string && !auth_provided) { ret = http_error("401", "Unauthorized", - "WWW-Authenticate: Basic realm=\"agedu\"\r\n", - "Please authenticate to view these pages."); + "WWW-Authenticate: Basic realm=\""PNAME"\"\r", + "\nPlease authenticate to view these pages."); } else { ret = http_error("403", "Forbidden", NULL, "This is a restricted-access set of pages."); @@ -288,7 +290,7 @@ char *got_data(struct connctx *ctx, char *data, int length, p = ctx->url; p += strspn(p, "/?"); index = strtoul(p, NULL, 10); - document = html_query(ctx->t, index, "%lu"); + document = html_query(ctx->t, index, cfg); if (document) { ret = http_success("text/html", 1, document); sfree(document); @@ -416,15 +418,19 @@ static void base64_encode_atom(unsigned char *data, int n, char *out) out[3] = '='; } -void run_httpd(const void *t, int authmask) +void run_httpd(const void *t, int authmask, const struct httpd_config *dcfg, + const struct html_config *incfg) { int fd; int authtype; - char *authstring = NULL, authbuf[512]; + char *authstring = NULL; unsigned long ipaddr; struct fd *f; struct sockaddr_in addr; socklen_t addrlen; + struct html_config cfg = *incfg; + + cfg.format = "%.0lu"; /* * Establish the listening socket and retrieve its port @@ -436,13 +442,18 @@ void run_httpd(const void *t, int authmask) exit(1); } addr.sin_family = AF_INET; - srand(0L); - ipaddr = 0x7f000000; - ipaddr += (1 + rand() % 255) << 16; - ipaddr += (1 + rand() % 255) << 8; - ipaddr += (1 + rand() % 255); - addr.sin_addr.s_addr = htonl(ipaddr); - addr.sin_port = htons(0); + if (!dcfg->address) { + srand(0L); + ipaddr = 0x7f000000; + ipaddr += (1 + rand() % 255) << 16; + ipaddr += (1 + rand() % 255) << 8; + ipaddr += (1 + rand() % 255); + addr.sin_addr.s_addr = htonl(ipaddr); + addr.sin_port = htons(0); + } else { + addr.sin_addr.s_addr = inet_addr(dcfg->address); + addr.sin_port = dcfg->port ? htons(dcfg->port) : 80; + } addrlen = sizeof(addr); if (bind(fd, (struct sockaddr *)&addr, addrlen) < 0) { fprintf(stderr, "bind: %s\n", strerror(errno)); @@ -460,73 +471,98 @@ void run_httpd(const void *t, int authmask) if ((authmask & HTTPD_AUTH_MAGIC) && (check_owning_uid(fd, 1) == getuid())) { authtype = HTTPD_AUTH_MAGIC; - printf("Using Linux /proc/net magic authentication\n"); + if (authmask != HTTPD_AUTH_MAGIC) + printf("Using Linux /proc/net magic authentication\n"); } else if ((authmask & HTTPD_AUTH_BASIC)) { - char username[128], password[128], userpass[259]; + char username[128], password[128], userpassbuf[259]; + const char *userpass; const char *rname; unsigned char passbuf[10]; int i, j, k, fd; authtype = HTTPD_AUTH_BASIC; - sprintf(username, "agedu"); - rname = "/dev/urandom"; - fd = open(rname, O_RDONLY); - if (fd < 0) { - int err = errno; - rname = "/dev/random"; + if (authmask != HTTPD_AUTH_BASIC) + printf("Using HTTP Basic authentication\n"); + + if (dcfg->basicauthdata) { + userpass = dcfg->basicauthdata; + } else { + strcpy(username, PNAME); + rname = "/dev/urandom"; fd = open(rname, O_RDONLY); if (fd < 0) { - int err2 = errno; - fprintf(stderr, "/dev/urandom: open: %s\n", strerror(err)); - fprintf(stderr, "/dev/random: open: %s\n", strerror(err2)); - exit(1); + int err = errno; + rname = "/dev/random"; + fd = open(rname, O_RDONLY); + if (fd < 0) { + int err2 = errno; + fprintf(stderr, "/dev/urandom: open: %s\n", strerror(err)); + fprintf(stderr, "/dev/random: open: %s\n", strerror(err2)); + exit(1); + } } - } - for (i = 0; i < 10 ;) { - j = read(fd, passbuf + i, 10 - i); - if (j <= 0) { - fprintf(stderr, "%s: read: %s\n", rname, - j < 0 ? strerror(errno) : "unexpected EOF"); - exit(1); + for (i = 0; i < 10 ;) { + j = read(fd, passbuf + i, 10 - i); + if (j <= 0) { + fprintf(stderr, "%s: read: %s\n", rname, + j < 0 ? strerror(errno) : "unexpected EOF"); + exit(1); + } + i += j; } - i += j; - } - close(fd); - for (i = 0; i < 16; i++) { - /* 32 characters out of the 36 alphanumerics gives me the - * latitude to discard i,l,o for being too numeric-looking, - * and w because it has two too many syllables and one too - * many presidential associations. */ - static const char chars[32] = "0123456789abcdefghjkmnpqrstuvxyz"; - int v = 0; - - k = i / 8 * 5; - for (j = 0; j < 5; j++) - v |= ((passbuf[k+j] >> (i%8)) & 1) << j; - - password[i] = chars[v]; - } - password[i] = '\0'; + close(fd); + for (i = 0; i < 16; i++) { + /* + * 32 characters out of the 36 alphanumerics gives + * me the latitude to discard i,l,o for being too + * numeric-looking, and w because it has two too + * many syllables and one too many presidential + * associations. + */ + static const char chars[32] = + "0123456789abcdefghjkmnpqrstuvxyz"; + int v = 0; + + k = i / 8 * 5; + for (j = 0; j < 5; j++) + v |= ((passbuf[k+j] >> (i%8)) & 1) << j; + + password[i] = chars[v]; + } + password[i] = '\0'; + + sprintf(userpassbuf, "%s:%s", username, password); + userpass = userpassbuf; - printf("Using HTTP Basic authentication\nUsername: %s\nPassword: %s\n", - username, password); + printf("Username: %s\nPassword: %s\n", username, password); + } - k = sprintf(userpass, "%s:%s", username, password); + k = strlen(userpass); + authstring = snewn(k * 4 / 3 + 16, char); for (i = j = 0; i < k ;) { int s = k-i < 3 ? k-i : 3; - base64_encode_atom((unsigned char *)(userpass+i), s, authbuf+j); + base64_encode_atom((unsigned char *)(userpass+i), s, authstring+j); i += s; j += 4; } - authbuf[j] = '\0'; - authstring = authbuf; - } else { + authstring[j] = '\0'; + } else if ((authmask & HTTPD_AUTH_NONE)) { authtype = HTTPD_AUTH_NONE; - printf("Web server is unauthenticated\n"); + if (authmask != HTTPD_AUTH_NONE) + printf("Web server is unauthenticated\n"); + } else { + fprintf(stderr, PNAME ": authentication method not supported\n"); + exit(1); + } + if (!dcfg->address) { + if (ntohs(addr.sin_port) == 80) { + printf("URL: http://%s/\n", inet_ntoa(addr.sin_addr)); + } else { + printf("URL: http://%s:%d/\n", + inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); + } } - printf("URL: http://%s:%d/\n", - inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); /* * Now construct an fd structure to hold it. @@ -666,7 +702,7 @@ void run_httpd(const void *t, int authmask) fds[i].wdata = got_data (fds[i].cctx, readbuf, ret, (authtype == HTTPD_AUTH_NONE || - fds[i].magic_access), authstring); + fds[i].magic_access), authstring, &cfg); if (fds[i].wdata) { fds[i].wdatalen = strlen(fds[i].wdata); fds[i].wdatapos = 0;