diff options
Diffstat (limited to 'apache1x/mod_httpauth.c')
-rw-r--r-- | apache1x/mod_httpauth.c | 1102 |
1 files changed, 551 insertions, 551 deletions
diff --git a/apache1x/mod_httpauth.c b/apache1x/mod_httpauth.c index 4b1abe6..9f0d491 100644 --- a/apache1x/mod_httpauth.c +++ b/apache1x/mod_httpauth.c @@ -16,12 +16,12 @@ module MODULE_VAR_EXPORT httpauth_module; typedef struct httpauth_context { - const char* socketname; - int socket; - int types; - const char* handler; - const char* domain; - pool* child_pool; + const char* socketname; + int socket; + int types; + const char* handler; + const char* domain; + pool* child_pool; } httpauth_context_t; @@ -44,77 +44,77 @@ httpauth_context_t; static void* httpauth_dir_config(pool* p, char* dir) { - httpauth_context_t* ctx; + httpauth_context_t* ctx; - ctx = (httpauth_context_t*)ap_pcalloc(p, sizeof(*ctx)); - memset(ctx, 0, sizeof(*ctx)); + ctx = (httpauth_context_t*)ap_pcalloc(p, sizeof(*ctx)); + memset(ctx, 0, sizeof(*ctx)); - ctx->socket = -1; - ctx->types = 0xFFFFFFFF; - ctx->child_pool = p; - return ctx; + ctx->socket = -1; + ctx->types = 0xFFFFFFFF; + ctx->child_pool = p; + return ctx; } static const char* set_socket(cmd_parms* cmd, void* config, const char* val) { - struct sockaddr_any sany; + struct sockaddr_any sany; - if(sock_any_pton(val, &sany, DEFAULT_PORT) == -1) - return "Invalid socket name or ip in HttpAuthSocket"; + if(sock_any_pton(val, &sany, DEFAULT_PORT) == -1) + return "Invalid socket name or ip in HttpAuthSocket"; - ((httpauth_context_t*)config)->socketname = val; - return NULL; + ((httpauth_context_t*)config)->socketname = val; + return NULL; } static const char* set_handler(cmd_parms* cmd, void* config, const char* val) { - httpauth_context_t* conf = (httpauth_context_t*)config; - conf->handler = val; - return NULL; + httpauth_context_t* conf = (httpauth_context_t*)config; + conf->handler = val; + return NULL; } static const char* set_types(cmd_parms* cmd, void* config, const char* val) { - httpauth_context_t* conf = (httpauth_context_t*)config; - int type = 0; - - if(strcasecmp(val, AUTH_PREFIX_BASIC) == 0) - type = AUTH_TYPE_BASIC; - else if(strcasecmp(val, AUTH_PREFIX_DIGEST) == 0) - type = AUTH_TYPE_DIGEST; - else if(strcasecmp(val, AUTH_PREFIX_NTLM) == 0) - type = AUTH_TYPE_NTLM; - else if(strcasecmp(val, "any")) - type = AUTH_TYPE_ANY; - else - return "Invalid type in HttpAuthTypes"; - - if(conf->types == 0xFFFFFFFF) - conf->types = type; - else - conf->types |= type; - - return NULL; + httpauth_context_t* conf = (httpauth_context_t*)config; + int type = 0; + + if(strcasecmp(val, AUTH_PREFIX_BASIC) == 0) + type = AUTH_TYPE_BASIC; + else if(strcasecmp(val, AUTH_PREFIX_DIGEST) == 0) + type = AUTH_TYPE_DIGEST; + else if(strcasecmp(val, AUTH_PREFIX_NTLM) == 0) + type = AUTH_TYPE_NTLM; + else if(strcasecmp(val, "any")) + type = AUTH_TYPE_ANY; + else + return "Invalid type in HttpAuthTypes"; + + if(conf->types == 0xFFFFFFFF) + conf->types = type; + else + conf->types |= type; + + return NULL; } static const char* set_domain(cmd_parms* cmd, void* config, const char* val) { - httpauth_context_t* conf = (httpauth_context_t*)config; - conf->domain = trim_space(ap_pstrdup(cmd->pool, val)); - return NULL; + httpauth_context_t* conf = (httpauth_context_t*)config; + conf->domain = trim_space(ap_pstrdup(cmd->pool, val)); + return NULL; } static const command_rec httpauth_cmds[] = { - { "HttpAuthSocket", set_socket, NULL, OR_AUTHCFG, TAKE1, - "The socket that httpauthd is listening on" }, - { "HttpAuthHandler", set_handler, NULL, OR_AUTHCFG, TAKE1, - "The handler that httpauthd should use to authenticate" }, - { "HttpAuthTypes", set_types, NULL, OR_AUTHCFG, ITERATE, - "The types of authentiction allowed (Basic, Digest, NTLM ...)" }, - { "HttpAuthDigestDomain", set_domain, NULL, OR_AUTHCFG, RAW_ARGS, - "The domain for which digest authentication is relevant" }, - { NULL, NULL, NULL, 0, 0, NULL } + { "HttpAuthSocket", set_socket, NULL, OR_AUTHCFG, TAKE1, + "The socket that httpauthd is listening on" }, + { "HttpAuthHandler", set_handler, NULL, OR_AUTHCFG, TAKE1, + "The handler that httpauthd should use to authenticate" }, + { "HttpAuthTypes", set_types, NULL, OR_AUTHCFG, ITERATE, + "The types of authentiction allowed (Basic, Digest, NTLM ...)" }, + { "HttpAuthDigestDomain", set_domain, NULL, OR_AUTHCFG, RAW_ARGS, + "The domain for which digest authentication is relevant" }, + { NULL, NULL, NULL, 0, 0, NULL } }; /* ------------------------------------------------------------------------------- @@ -123,653 +123,653 @@ static const command_rec httpauth_cmds[] = void read_junk(httpauth_context_t* ctx, request_rec* r) { - char buf[16]; - const char* t; - int said = 0; - int l; - - if(ctx->socket == -1) - return; + char buf[16]; + const char* t; + int said = 0; + int l; - /* Make it non blocking */ - fcntl(ctx->socket, F_SETFL, fcntl(ctx->socket, F_GETFL, 0) | O_NONBLOCK); + if(ctx->socket == -1) + return; - for(;;) - { - l = read(ctx->socket, buf, sizeof(buf) - 1); - if(l <= 0) - break; + /* Make it non blocking */ + fcntl(ctx->socket, F_SETFL, fcntl(ctx->socket, F_GETFL, 0) | O_NONBLOCK); - buf[l] = 0; - t = trim_start(buf); - - if(!said && *t) + for(;;) { - ap_log_rerror(APLOG_MARK, APLOG_WARNING, r, - "httpauth: received junk data from daemon"); - said = 1; + l = read(ctx->socket, buf, sizeof(buf) - 1); + if(l <= 0) + break; + + buf[l] = 0; + t = trim_start(buf); + + if(!said && *t) + { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, r, + "httpauth: received junk data from daemon"); + said = 1; + } } - } - fcntl(ctx->socket, F_SETFL, fcntl(ctx->socket, F_GETFL, 0) & ~O_NONBLOCK); - errno = 0; + fcntl(ctx->socket, F_SETFL, fcntl(ctx->socket, F_GETFL, 0) & ~O_NONBLOCK); + errno = 0; } int read_line(httpauth_context_t* ctx, request_rec* r, char** line) { - int l; - int al = 128; - char* t; - const char* e; + int l; + int al = 128; + char* t; + const char* e; - e = t = NULL; - *line = NULL; + e = t = NULL; + *line = NULL; - for(;;) - { - if(!*line || t + 2 == e) + for(;;) { - char* n; - int d; - - n = (char*)ap_palloc(r->pool, al * 2); - - if(*line) - memcpy(n, *line, al); + if(!*line || t + 2 == e) + { + char* n; + int d; + + n = (char*)ap_palloc(r->pool, al * 2); + + if(*line) + memcpy(n, *line, al); + + al *= 2; + + /* The difference */ + d = t - *line; + + *line = n; + t = n + d; + e = n + al; + } + + l = read(ctx->socket, (void*)t, sizeof(char)); + + /* We got a character */ + if(l == 1) + { + /* Skip junky CRLFs */ + if(*t == '\r') + { + *t = ' '; + continue; + } + + /* End of line */ + else if(*t == '\n') + { + t++; + break; + } + + t++; + } + + /* If it's the end of file then return that */ + else if(l == 0) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "httpauth: unexpected end of data from daemon"); + return -1; + } + + /* Transient errors */ + else if(l == -1 && errno == EAGAIN) + continue; + + /* Fatal errors */ + else if(l == -1) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "httpauth: couldn't read data from daemon"); + return -1; + } + } - al *= 2; + *t = 0; + errno = 0; + return 0; +} - /* The difference */ - d = t - *line; +int read_response(httpauth_context_t* ctx, request_rec* r, + int* code, int* ccode, char** details) +{ + int c; + char* line; + char* t; + char* t2; - *line = n; - t = n + d; - e = n + al; - } + if(read_line(ctx, r, &line) == -1) + return -1; - l = read(ctx->socket, (void*)t, sizeof(char)); + line = trim_space(line); - /* We got a character */ - if(l == 1) - { - /* Skip junky CRLFs */ - if(*t == '\r') - { - *t = ' '; - continue; - } - - /* End of line */ - else if(*t == '\n') - { - t++; - break; - } - - t++; - } + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, + "httpauth: received response line from daemon: %s", line); - /* If it's the end of file then return that */ - else if(l == 0) + /* Get response code */ + t = ap_getword_nc(r->pool, &line, ' '); + c = strtol(t, &t2, 10); + if(*t2 || c < 100 || c > 999) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "httpauth: unexpected end of data from daemon"); - return -1; + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "httpauth: protocol error: invalid code: %s", t); + return -1; } - /* Transient errors */ - else if(l == -1 && errno == EAGAIN) - continue; + if(code) + *code = c; - /* Fatal errors */ - else if(l == -1) + if(c >= 400) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "httpauth: couldn't read data from daemon"); - return -1; + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "httpauth: received error from httpauthd: %d %s", c, line); + return -1; } - } - *t = 0; - errno = 0; - return 0; -} - -int read_response(httpauth_context_t* ctx, request_rec* r, - int* code, int* ccode, char** details) -{ - int c; - char* line; - char* t; - char* t2; - - if(read_line(ctx, r, &line) == -1) - return -1; - - line = trim_space(line); - - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, - "httpauth: received response line from daemon: %s", line); - - /* Get response code */ - t = ap_getword_nc(r->pool, &line, ' '); - c = strtol(t, &t2, 10); - if(*t2 || c < 100 || c > 999) - { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "httpauth: protocol error: invalid code: %s", t); - return -1; - } - - if(code) - *code = c; - - if(c >= 400) - { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "httpauth: received error from httpauthd: %d %s", c, line); - return -1; - } - - /* Get the second response code if we're a 200 */ - if(c == 200) - { - t = ap_getword_nc(r->pool, &line, ' '); - c = strtol(t, &t2, 10); - if(*t2 || c < 100 || c > 999) + /* Get the second response code if we're a 200 */ + if(c == 200) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "httpauth: protocol error: invalid code: %s", t); - return -1; + t = ap_getword_nc(r->pool, &line, ' '); + c = strtol(t, &t2, 10); + if(*t2 || c < 100 || c > 999) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "httpauth: protocol error: invalid code: %s", t); + return -1; + } + + if(ccode) + *ccode = c; } - if(ccode) - *ccode = c; - } + if(details) + *details = trim_space(line); - if(details) - *details = trim_space(line); - - return 0; + return 0; } int read_copy_headers(httpauth_context_t* ctx, int ccode, request_rec* r) { - char* line; - const char* name; - table* headers; - int c = 0; - - if(ccode > 299) - headers = r->err_headers_out; - else - headers = r->headers_out; - - for(;;) - { - if(read_line(ctx, r, &line) == -1) - return -1; + char* line; + const char* name; + table* headers; + int c = 0; - /* If that's it then break */ - if(!*line) - break; + if(ccode > 299) + headers = r->err_headers_out; + else + headers = r->headers_out; - if(ap_isspace(*line)) + for(;;) { - line = (char*)trim_start(line); + if(read_line(ctx, r, &line) == -1) + return -1; + + /* If that's it then break */ + if(!*line) + break; + + if(ap_isspace(*line)) + { + line = (char*)trim_start(line); + + /* End of headers */ + if(!*line) + break; + + if(c > 0) + { + /* + * TODO: We really should be supporting headers split + * across lines. But httpauthd doesn't currently produce + * headers like that, so we don't need to care about it. + */ + ap_log_rerror(APLOG_MARK, APLOG_WARNING, r, + "httpauth: protocol error: server sent us an split header, which we don't support."); + } + else + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "httpauth: protocol error: invalid headers."); + } + } + + name = ap_getword_nc(r->pool, &line, ':'); + if(!name || !*name) + break; - /* End of headers */ - if(!*line) - break; - - if(c > 0) - { /* - * TODO: We really should be supporting headers split - * across lines. But httpauthd doesn't currently produce - * headers like that, so we don't need to care about it. + * If that was the end of the line, then it's an + * invalid header :( */ - ap_log_rerror(APLOG_MARK, APLOG_WARNING, r, - "httpauth: protocol error: server sent us an split header, which we don't support."); - } - else - { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "httpauth: protocol error: invalid headers."); - } + if(!*line) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "httpauth: protocol header: invalid headers"); + return -1; + } + + line = trim_space(line); + + if(strcasecmp(name, "WWW-Authenticate") == 0) + { + if(strncasecmp(line, AUTH_PREFIX_BASIC, strlen(AUTH_PREFIX_BASIC)) == 0 && + !(ctx->types & AUTH_TYPE_BASIC)) + continue; + + else if(strncasecmp(line, AUTH_PREFIX_DIGEST, strlen(AUTH_PREFIX_DIGEST)) == 0 && + !(ctx->types & AUTH_TYPE_DIGEST)) + continue; + + else if(strncasecmp(line, AUTH_PREFIX_NTLM, strlen(AUTH_PREFIX_NTLM)) == 0 && + !(ctx->types & AUTH_TYPE_NTLM)) + continue; + + /* Only allow unknown if we don't have it */ + else if(!(ctx->types & AUTH_TYPE_ANY)) + continue; + + /* Fix up when we're a proxy */ + if(r->proxyreq == STD_PROXY) + name = "Proxy-Authenticate"; + } + + else if(strcasecmp(name, "Authentication-Info") == 0) + { + if(r->proxyreq == STD_PROXY) + name = "Proxy-Authentication-Info"; + } + + c++; + ap_table_addn(headers, name, line); } - name = ap_getword_nc(r->pool, &line, ':'); - if(!name || !*name) - break; - - /* - * If that was the end of the line, then it's an - * invalid header :( - */ - if(!*line) - { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "httpauth: protocol header: invalid headers"); - return -1; - } + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, + "httpauth: received %d headers from daemon", c); - line = trim_space(line); + return 0; +} - if(strcasecmp(name, "WWW-Authenticate") == 0) +void disconnect_socket(httpauth_context_t* ctx, server_rec* s) +{ + if(ctx->socket != -1) { - if(strncasecmp(line, AUTH_PREFIX_BASIC, strlen(AUTH_PREFIX_BASIC)) == 0 && - !(ctx->types & AUTH_TYPE_BASIC)) - continue; + ap_log_error(APLOG_MARK, APLOG_DEBUG, s, + "httpauth: disconnecting from daemon"); - else if(strncasecmp(line, AUTH_PREFIX_DIGEST, strlen(AUTH_PREFIX_DIGEST)) == 0 && - !(ctx->types & AUTH_TYPE_DIGEST)) - continue; - - else if(strncasecmp(line, AUTH_PREFIX_NTLM, strlen(AUTH_PREFIX_NTLM)) == 0 && - !(ctx->types & AUTH_TYPE_NTLM)) - continue; + /* TODO: Should we be closing this nicely somewhere? */ + ap_pclosesocket(ctx->child_pool, ctx->socket); + ctx->socket = -1; + errno = 0; + } +} - /* Only allow unknown if we don't have it */ - else if(!(ctx->types & AUTH_TYPE_ANY)) - continue; +int write_data(httpauth_context_t* ctx, server_rec* s, const char* data) +{ + int r; - /* Fix up when we're a proxy */ - if(r->proxyreq == STD_PROXY) - name = "Proxy-Authenticate"; + if(ctx->socket == -1) + { + ap_log_error(APLOG_MARK, APLOG_ERR, s, + "httpauth: Socket to httpauthd daemon closed. Can't write data."); + return -1; } - else if(strcasecmp(name, "Authentication-Info") == 0) + while(*data != 0) { - if(r->proxyreq == STD_PROXY) - name = "Proxy-Authentication-Info"; - } + r = write(ctx->socket, data, strlen(data)); - c++; - ap_table_addn(headers, name, line); - } + if(r > 0) + data += r; - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, - "httpauth: received %d headers from daemon", c); + else if(r == -1) + { + if(errno == EAGAIN) + continue; - return 0; -} + /* The other end closed. no message */ + if(errno == EPIPE) + disconnect_socket(ctx, s); -void disconnect_socket(httpauth_context_t* ctx, server_rec* s) -{ - if(ctx->socket != -1) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, s, - "httpauth: disconnecting from daemon"); + else + ap_log_error(APLOG_MARK, APLOG_ERR, s, + "httpauth: Couldn't write data to daemon"); + + errno = 0; + return -1; + } + } - /* TODO: Should we be closing this nicely somewhere? */ - ap_pclosesocket(ctx->child_pool, ctx->socket); - ctx->socket = -1; errno = 0; - } + return 0; } -int write_data(httpauth_context_t* ctx, server_rec* s, const char* data) +int connect_socket(httpauth_context_t* ctx, request_rec* r) { - int r; - - if(ctx->socket == -1) - { - ap_log_error(APLOG_MARK, APLOG_ERR, s, - "httpauth: Socket to httpauthd daemon closed. Can't write data."); - return -1; - } + struct sockaddr_any sany; + int ret = -1; - while(*data != 0) - { - r = write(ctx->socket, data, strlen(data)); - - if(r > 0) - data += r; + disconnect_socket(ctx, r->server); - else if(r == -1) + if(sock_any_pton(ctx->socketname, &sany, DEFAULT_PORT) == -1) { - if(errno == EAGAIN) - continue; - - /* The other end closed. no message */ - if(errno == EPIPE) - disconnect_socket(ctx, s); - - else - ap_log_error(APLOG_MARK, APLOG_ERR, s, - "httpauth: Couldn't write data to daemon"); + ap_log_rerror(APLOG_MARK, APLOG_CRIT, r, + "httpauth: Invalid socket name or ip."); + goto finally; + } - errno = 0; - return -1; + ctx->socket = ap_psocket(ctx->child_pool, SANY_TYPE(sany), SOCK_STREAM, 0); + if(ctx->socket == -1) + { + ap_log_rerror(APLOG_MARK, APLOG_CRIT, r, + "httpauth: Can't create socket: %s", ctx->socketname); + goto finally; } - } - errno = 0; - return 0; -} + if(connect(ctx->socket, &SANY_ADDR(sany), SANY_LEN(sany)) != 0) + { + ap_log_rerror(APLOG_MARK, APLOG_CRIT, r, + "httpauth: Can't connect to httpauthd"); + goto finally; + } -int connect_socket(httpauth_context_t* ctx, request_rec* r) -{ - struct sockaddr_any sany; - int ret = -1; - - disconnect_socket(ctx, r->server); - - if(sock_any_pton(ctx->socketname, &sany, DEFAULT_PORT) == -1) - { - ap_log_rerror(APLOG_MARK, APLOG_CRIT, r, - "httpauth: Invalid socket name or ip."); - goto finally; - } - - ctx->socket = ap_psocket(ctx->child_pool, SANY_TYPE(sany), SOCK_STREAM, 0); - if(ctx->socket == -1) - { - ap_log_rerror(APLOG_MARK, APLOG_CRIT, r, - "httpauth: Can't create socket: %s", ctx->socketname); - goto finally; - } - - if(connect(ctx->socket, &SANY_ADDR(sany), SANY_LEN(sany)) != 0) - { - ap_log_rerror(APLOG_MARK, APLOG_CRIT, r, - "httpauth: Can't connect to httpauthd"); - goto finally; - } - - ret = 0; + ret = 0; finally: - if(ret == -1) - disconnect_socket(ctx, r->server); + if(ret == -1) + disconnect_socket(ctx, r->server); - errno = 0; - return ret; + errno = 0; + return ret; } int connect_httpauth(httpauth_context_t* ctx, request_rec* r) { - int ret = -1; - int code; - char* details; - const char* t; - - if(connect_socket(ctx, r) == -1) - goto finally; - - if(read_response(ctx, r, &code, NULL, &details) == -1) - goto finally; - - if(code != 100) - { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "httpauth: protocol error (Expected 100, got %d)", code); - goto finally; - } - - /* Check theversion number */ - details = trim_space(details); - - if(strcmp(details, "HTTPAUTH/1.0") != 0) - { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "httpauth: Daemon speaking incompatible protocol version: %s", details); - goto finally; - } - - /* Send our handler */ - if(ctx->handler) - { - t = ap_pstrcat(r->pool, "SET Handler ", ctx->handler, "\n", NULL); + int ret = -1; + int code; + char* details; + const char* t; - if(write_data(ctx, r->server, t) == -1) - goto finally; + if(connect_socket(ctx, r) == -1) + goto finally; - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, - "httpauth: sent handler to daemon: %s", t); + if(read_response(ctx, r, &code, NULL, &details) == -1) + goto finally; - if(read_response(ctx, r, &code, NULL, NULL) == -1) - goto finally; + if(code != 100) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "httpauth: protocol error (Expected 100, got %d)", code); + goto finally; + } + + /* Check theversion number */ + details = trim_space(details); - if(code != 202) + if(strcmp(details, "HTTPAUTH/1.0") != 0) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "httpauth: protocol error (Expected 202, got %d)", code); - goto finally; + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "httpauth: Daemon speaking incompatible protocol version: %s", details); + goto finally; } - } - /* Send any setup info we have */ - if(ctx->domain) - { - t = ap_pstrcat(r->pool, "SET Domain ", ctx->domain, "\n", NULL); + /* Send our handler */ + if(ctx->handler) + { + t = ap_pstrcat(r->pool, "SET Handler ", ctx->handler, "\n", NULL); - if(write_data(ctx, r->server, t) == -1) - goto finally; + if(write_data(ctx, r->server, t) == -1) + goto finally; - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, - "httpauth: sent domains to daemon: %s", t); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, + "httpauth: sent handler to daemon: %s", t); - if(read_response(ctx, r, &code, NULL, NULL) == -1) - goto finally; + if(read_response(ctx, r, &code, NULL, NULL) == -1) + goto finally; - if(code != 202) + if(code != 202) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "httpauth: protocol error (Expected 202, got %d)", code); + goto finally; + } + } + + /* Send any setup info we have */ + if(ctx->domain) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "httpauth: protocol error (Expected 202, got %d)", code); - goto finally; + t = ap_pstrcat(r->pool, "SET Domain ", ctx->domain, "\n", NULL); + + if(write_data(ctx, r->server, t) == -1) + goto finally; + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, + "httpauth: sent domains to daemon: %s", t); + + if(read_response(ctx, r, &code, NULL, NULL) == -1) + goto finally; + + if(code != 202) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "httpauth: protocol error (Expected 202, got %d)", code); + goto finally; + } } - } - /* We're cool! */ - ret = 0; - ap_log_rerror(APLOG_MARK, APLOG_INFO, r, "httpauth: connected to daemon"); + /* We're cool! */ + ret = 0; + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, "httpauth: connected to daemon"); finally: - if(ret == -1) - disconnect_socket(ctx, r->server); + if(ret == -1) + disconnect_socket(ctx, r->server); - return ret; + return ret; } int write_request(httpauth_context_t* ctx, request_rec* r) { - int i, c = 0; - const char* t; - const array_header* hdrs_arr; - const table_entry* elts; + int i, c = 0; + const char* t; + const array_header* hdrs_arr; + const table_entry* elts; - /* - * TODO: We need to use a valid connection id for - * NTLM connections to work properly. - */ - - /* Send the request header to httpauthd */ - t = ap_pstrcat(r->pool, "AUTH XXX ", r->method, - " ", r->unparsed_uri, "\n", NULL); + /* + * TODO: We need to use a valid connection id for + * NTLM connections to work properly. + */ - if(write_data(ctx, r->server, t) == -1) - return -1; + /* Send the request header to httpauthd */ + t = ap_pstrcat(r->pool, "AUTH XXX ", r->method, + " ", r->unparsed_uri, "\n", NULL); - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, - "httpauth: sent auth request to daemon: %s", t); + if(write_data(ctx, r->server, t) == -1) + return -1; - /* Now send the headers to httpauthd */ + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, + "httpauth: sent auth request to daemon: %s", t); - hdrs_arr = ap_table_elts(r->headers_in); - elts = (const table_entry*)hdrs_arr->elts; + /* Now send the headers to httpauthd */ - for(i = 0; i < hdrs_arr->nelts; i++) - { - if(!elts[i].val) - continue; + hdrs_arr = ap_table_elts(r->headers_in); + elts = (const table_entry*)hdrs_arr->elts; - /* Filter out headers we don't want */ - if(strcasecmp(elts[i].key, r->proxyreq == STD_PROXY ? - "Proxy-Authorization" : "Authorization") == 0) + for(i = 0; i < hdrs_arr->nelts; i++) { - t = trim_start(elts[i].val); + if(!elts[i].val) + continue; - if(strncasecmp(t, AUTH_PREFIX_BASIC, strlen(AUTH_PREFIX_BASIC)) == 0 && - !(ctx->types & AUTH_TYPE_BASIC)) - continue; + /* Filter out headers we don't want */ + if(strcasecmp(elts[i].key, r->proxyreq == STD_PROXY ? + "Proxy-Authorization" : "Authorization") == 0) + { + t = trim_start(elts[i].val); - else if(strncasecmp(t, AUTH_PREFIX_DIGEST, strlen(AUTH_PREFIX_DIGEST)) == 0 && - !(ctx->types & AUTH_TYPE_DIGEST)) - continue; + if(strncasecmp(t, AUTH_PREFIX_BASIC, strlen(AUTH_PREFIX_BASIC)) == 0 && + !(ctx->types & AUTH_TYPE_BASIC)) + continue; - else if(strncasecmp(t, AUTH_PREFIX_NTLM, strlen(AUTH_PREFIX_NTLM)) == 0 && - !(ctx->types & AUTH_TYPE_NTLM)) - continue; + else if(strncasecmp(t, AUTH_PREFIX_DIGEST, strlen(AUTH_PREFIX_DIGEST)) == 0 && + !(ctx->types & AUTH_TYPE_DIGEST)) + continue; - /* Only allow unknown if we don't have it */ - else if(!(ctx->types & AUTH_TYPE_ANY)) - continue; + else if(strncasecmp(t, AUTH_PREFIX_NTLM, strlen(AUTH_PREFIX_NTLM)) == 0 && + !(ctx->types & AUTH_TYPE_NTLM)) + continue; - /* Extra blank line when at end */ - t = ap_pstrcat(r->pool, "Authorization: ", elts[i].val, "\n", NULL); + /* Only allow unknown if we don't have it */ + else if(!(ctx->types & AUTH_TYPE_ANY)) + continue; - if(write_data(ctx, r->server, t) == -1) - return SERVER_ERROR; + /* Extra blank line when at end */ + t = ap_pstrcat(r->pool, "Authorization: ", elts[i].val, "\n", NULL); - c++; + if(write_data(ctx, r->server, t) == -1) + return SERVER_ERROR; + + c++; + } } - } - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, - "httpauth: sent %d headers to daemon", c); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, + "httpauth: sent %d headers to daemon", c); - return write_data(ctx, r->server, "\n"); + return write_data(ctx, r->server, "\n"); } static int httpauth_authenticate(request_rec* r) { - httpauth_context_t* ctx; - const char* authtype; - int code = 0; - int ccode = 0; - char* details = NULL; - request_rec* mainreq; - int retried = 0; - - /* Make sure it's for us */ - if(!(authtype = ap_auth_type(r)) || strcasecmp(HTTPAUTH_AUTHTYPE, authtype) != 0) - return DECLINED; - - ctx = (httpauth_context_t*)ap_get_module_config(r->per_dir_config, + httpauth_context_t* ctx; + const char* authtype; + int code = 0; + int ccode = 0; + char* details = NULL; + request_rec* mainreq; + int retried = 0; + + /* Make sure it's for us */ + if(!(authtype = ap_auth_type(r)) || strcasecmp(HTTPAUTH_AUTHTYPE, authtype) != 0) + return DECLINED; + + ctx = (httpauth_context_t*)ap_get_module_config(r->per_dir_config, &httpauth_module); - if(!ctx->socketname || !ctx->handler) - return DECLINED; + if(!ctx->socketname || !ctx->handler) + return DECLINED; - mainreq = r; + mainreq = r; - while(mainreq->main != NULL) - mainreq = mainreq->main; + while(mainreq->main != NULL) + mainreq = mainreq->main; - while(mainreq->prev != NULL) - mainreq = mainreq->prev; + while(mainreq->prev != NULL) + mainreq = mainreq->prev; - /* Check if we've already authenticated this request */ - if(ap_get_module_config(mainreq->request_config, &httpauth_module)) - return OK; + /* Check if we've already authenticated this request */ + if(ap_get_module_config(mainreq->request_config, &httpauth_module)) + return OK; /* For jumping to when a connection has been closed */ retry: - if(ctx->socket == -1) - { - if(connect_httpauth(ctx, r) == -1) - return SERVER_ERROR; - } + if(ctx->socket == -1) + { + if(connect_httpauth(ctx, r) == -1) + return SERVER_ERROR; + } - /* Make sure we're starting on a clean slate */ - read_junk(ctx, r); + /* Make sure we're starting on a clean slate */ + read_junk(ctx, r); - /* Send off a request */ - if(write_request(ctx, r) == -1) - { - /* - * If our connection was closed by httpauthd then this - * is where we get the error. Just do one retry to - * try and reconnect. This happens often when restarting - * httpauthd. - */ - - if(ctx->socket == -1 && !retried) + /* Send off a request */ + if(write_request(ctx, r) == -1) { - retried = 1; - goto retry; - } + /* + * If our connection was closed by httpauthd then this + * is where we get the error. Just do one retry to + * try and reconnect. This happens often when restarting + * httpauthd. + */ - return SERVER_ERROR; - } + if(ctx->socket == -1 && !retried) + { + retried = 1; + goto retry; + } - /* Read a response line */ - if(read_response(ctx, r, &code, &ccode, &details) == -1) - return SERVER_ERROR; + return SERVER_ERROR; + } - if(code != 200) - { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "httpauth: protocol error: unexpected code: %d", code); - return SERVER_ERROR; - } + /* Read a response line */ + if(read_response(ctx, r, &code, &ccode, &details) == -1) + return SERVER_ERROR; - /* Copy over other headers */ - if(read_copy_headers(ctx, ccode, r) == -1) - return SERVER_ERROR; + if(code != 200) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "httpauth: protocol error: unexpected code: %d", code); + return SERVER_ERROR; + } - if(ccode == 200) - { - ap_log_rerror(APLOG_MARK, APLOG_INFO, r, - "httpauth: successful authentication for user: %s", details); + /* Copy over other headers */ + if(read_copy_headers(ctx, ccode, r) == -1) + return SERVER_ERROR; - (char*)(r->connection->user) = ap_pstrdup(r->connection->pool, details); - r->connection->ap_auth_type = HTTPAUTH_AUTHTYPE; + if(ccode == 200) + { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "httpauth: successful authentication for user: %s", details); - /* Mark request as successfully authenticated */ - ap_set_module_config(r->request_config, &httpauth_module, details); - return OK; - } + (char*)(r->connection->user) = ap_pstrdup(r->connection->pool, details); + r->connection->ap_auth_type = HTTPAUTH_AUTHTYPE; - return ccode; + /* Mark request as successfully authenticated */ + ap_set_module_config(r->request_config, &httpauth_module, details); + return OK; + } + + return ccode; } static int httpauth_access(request_rec *r) { - /* TODO: We need to support require directives */ - return OK; + /* TODO: We need to support require directives */ + return OK; } /* Dispatch list for API hooks */ module MODULE_VAR_EXPORT httpauth_module = { STANDARD_MODULE_STUFF, - NULL, /* module initializer */ - httpauth_dir_config, /* create per-dir config structures */ - NULL, /* merge per-dir config structures */ - NULL, /* create per-server config structures */ - NULL, /* merge per-server config structures */ - httpauth_cmds, /* table of config file commands */ - NULL, /* [#8] MIME-typed-dispatched handlers */ - NULL, /* [#1] URI to filename translation */ - httpauth_authenticate, /* [#4] validate user id from request */ - httpauth_access, /* [#5] check if the user is ok _here_ */ - NULL, /* [#3] check access by host address */ - NULL, /* [#6] determine MIME type */ - NULL, /* [#7] pre-run fixups */ - NULL, /* [#9] log a transaction */ - NULL, /* [#2] header parser */ - NULL, /* child_init */ - NULL, /* child_exit */ - NULL /* [#0] post read-request */ + NULL, /* module initializer */ + httpauth_dir_config, /* create per-dir config structures */ + NULL, /* merge per-dir config structures */ + NULL, /* create per-server config structures */ + NULL, /* merge per-server config structures */ + httpauth_cmds, /* table of config file commands */ + NULL, /* [#8] MIME-typed-dispatched handlers */ + NULL, /* [#1] URI to filename translation */ + httpauth_authenticate, /* [#4] validate user id from request */ + httpauth_access, /* [#5] check if the user is ok _here_ */ + NULL, /* [#3] check access by host address */ + NULL, /* [#6] determine MIME type */ + NULL, /* [#7] pre-run fixups */ + NULL, /* [#9] log a transaction */ + NULL, /* [#2] header parser */ + NULL, /* child_init */ + NULL, /* child_exit */ + NULL /* [#0] post read-request */ #ifdef EAPI - ,NULL, /* EAPI: add_module */ - NULL, /* EAPI: remove_module */ - NULL, /* EAPI: rewrite_command */ - NULL /* EAPI: new_connection */ + ,NULL, /* EAPI: add_module */ + NULL, /* EAPI: remove_module */ + NULL, /* EAPI: rewrite_command */ + NULL /* EAPI: new_connection */ #endif }; |