From: André Malo Date: Sat, 18 Jan 2003 03:37:55 +0000 (+0000) Subject: move rfc1413 code to a new module "metadata:mod_ident". X-Git-Tag: pre_ajp_proxy~2263 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fe5980e40909c180e2630c7a0dd833d35e854d70;p=apache move rfc1413 code to a new module "metadata:mod_ident". The rfc1413 code itself is mostly c&p, but can still bear some rework ... This patch removes the global ap_rfc1413 function and the ap_rfc1413_timeout variable. It also introduces a new config directive IdentityCheckTimeout (default 30 sec). Reviewed by: Justin Erenkrantz git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@98320 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/http_core.h b/include/http_core.h index 320d420429..86a8dd380a 100644 --- a/include/http_core.h +++ b/include/http_core.h @@ -464,8 +464,6 @@ typedef struct { #define HOSTNAME_LOOKUP_UNSET 3 unsigned int hostname_lookups : 4; - signed int do_rfc1413 : 2; /* See if client is advertising a username? */ - signed int content_md5 : 2; /* calculate Content-MD5? */ #define USE_CANONICAL_NAME_OFF (0) @@ -635,6 +633,14 @@ AP_DECLARE_HOOK(int, get_mgmt_items, APR_DECLARE_OPTIONAL_FN(void, ap_logio_add_bytes_out, (conn_rec *c, apr_off_t bytes)); +/* ---------------------------------------------------------------------- + * + * ident lookups with mod_ident + */ + +APR_DECLARE_OPTIONAL_FN(const char *, ap_ident_lookup, + (request_rec *r)); + /* ---------------------------------------------------------------------- */ #ifdef __cplusplus diff --git a/include/httpd.h b/include/httpd.h index 3e026243bf..3fae59e73f 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -168,11 +168,6 @@ extern "C" { #define SERVER_CONFIG_FILE "conf/httpd.conf" #endif -/* Whether we should enable rfc1413 identity checking */ -#ifndef DEFAULT_RFC1413 -#define DEFAULT_RFC1413 0 -#endif - /* The default path for CGI scripts if none is currently set */ #ifndef DEFAULT_PATH #define DEFAULT_PATH "/bin:/usr/bin:/usr/ucb:/usr/bsd:/usr/local/bin" diff --git a/include/rfc1413.h b/include/rfc1413.h deleted file mode 100644 index a03dd83d2b..0000000000 --- a/include/rfc1413.h +++ /dev/null @@ -1,84 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000-2002 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - * Portions of this software are based upon public domain software - * originally written at the National Center for Supercomputing Applications, - * University of Illinois, Urbana-Champaign. - */ - -#ifndef APACHE_RFC1413_H -#define APACHE_RFC1413_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @package RFC1413 package - */ - -/** - * Retrieve the remote user name, given socket structures. This implements - * RFC1413, which involves querying the client's identd or auth daemon. - * @param conn The current connection - * @param srv The current server - * @return The remote user name - * @deffunc char *ap_rfc1413(conn_rec *conn, server_rec *srv) - */ -extern char *ap_rfc1413(conn_rec *conn, server_rec *srv); - -#ifdef __cplusplus -} -#endif - -#endif /* !APACHE_RFC1413_H */ diff --git a/modules/metadata/config.m4 b/modules/metadata/config.m4 index cd08b42876..e20e1dd612 100644 --- a/modules/metadata/config.m4 +++ b/modules/metadata/config.m4 @@ -9,6 +9,7 @@ APACHE_MODULE(mime_magic, automagically determining MIME type) APACHE_MODULE(cern_meta, CERN-type meta files) APACHE_MODULE(expires, Expires header control, , , most) APACHE_MODULE(headers, HTTP header control, , , most) +APACHE_MODULE(ident, RFC 1413 identity check, , , most) APACHE_MODULE(usertrack, user-session tracking, , , , [ AC_CHECK_HEADERS(sys/times.h) diff --git a/server/rfc1413.c b/modules/metadata/mod_ident.c similarity index 63% rename from server/rfc1413.c rename to modules/metadata/mod_ident.c index 76bc606516..4d1682016e 100644 --- a/server/rfc1413.c +++ b/modules/metadata/mod_ident.c @@ -1,7 +1,7 @@ /* ==================================================================== * The Apache Software License, Version 1.1 * - * Copyright (c) 2000-2002 The Apache Software Foundation. All rights + * Copyright (c) 2000-2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -56,15 +56,17 @@ * University of Illinois, Urbana-Champaign. */ -/* TODO - put timeouts back in */ /* + * mod_ident: Handle RFC 1413 ident request + * obtained from rfc1413.c + * * rfc1413() speaks a common subset of the RFC 1413, AUTH, TAP and IDENT * protocols. The code queries an RFC 1413 etc. compatible daemon on a remote * host to look up the owner of a connection. The information should not be * used for authentication purposes. This routine intercepts alarm signals. - * + * * Diagnostics are reported through syslog(3). - * + * * Author: Wietse Venema, Eindhoven University of Technology, * The Netherlands. */ @@ -82,42 +84,57 @@ #include "apr.h" #include "apr_network_io.h" #include "apr_strings.h" -#include "apr_lib.h" -#include "apr_inherit.h" +#include "apr_optional.h" #define APR_WANT_STDIO #define APR_WANT_STRFUNC #include "apr_want.h" -#include "ap_config.h" -#include "httpd.h" /* for server_rec, conn_rec, etc. */ -#include "http_log.h" /* for aplog_error */ -#include "rfc1413.h" -#include "http_main.h" /* set_callback_and_alarm */ +#include "httpd.h" /* for server_rec, conn_rec, etc. */ +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" /* for aplog_error */ #include "util_ebcdic.h" +/* Whether we should enable rfc1413 identity checking */ +#ifndef DEFAULT_RFC1413 +#define DEFAULT_RFC1413 0 +#endif + +#define RFC1413_UNSET 2 + +/* request timeout (sec) */ +#ifndef RFC1413_TIMEOUT +#define RFC1413_TIMEOUT 30 +#endif + /* Local stuff. */ + /* Semi-well-known port */ -#define RFC1413_PORT 113 +#define RFC1413_PORT 113 + /* maximum allowed length of userid */ -#define RFC1413_USERLEN 512 +#define RFC1413_USERLEN 512 + /* rough limit on the amount of data we accept. */ #define RFC1413_MAXDATA 1000 -#ifndef RFC1413_TIMEOUT -#define RFC1413_TIMEOUT 30 -#endif +/* default username, if it could not determined */ #define FROM_UNKNOWN "unknown" -int ap_rfc1413_timeout = RFC1413_TIMEOUT; /* Global so it can be changed */ +typedef struct { + int do_rfc1413; + int timeout_unset; + apr_time_t timeout; +} ident_config_rec; static apr_status_t rfc1413_connect(apr_socket_t **newsock, conn_rec *conn, - server_rec *srv) + server_rec *srv, apr_time_t timeout) { apr_status_t rv; apr_sockaddr_t *localsa, *destsa; - if ((rv = apr_sockaddr_info_get(&localsa, conn->local_ip, APR_UNSPEC, + if ((rv = apr_sockaddr_info_get(&localsa, conn->local_ip, APR_UNSPEC, 0, /* ephemeral port */ 0, conn->pool)) != APR_SUCCESS) { /* This should not fail since we have a numeric address string @@ -127,8 +144,8 @@ static apr_status_t rfc1413_connect(apr_socket_t **newsock, conn_rec *conn, conn->local_ip); return rv; } - - if ((rv = apr_sockaddr_info_get(&destsa, conn->remote_ip, + + if ((rv = apr_sockaddr_info_get(&destsa, conn->remote_ip, localsa->family, /* has to match */ RFC1413_PORT, 0, conn->pool)) != APR_SUCCESS) { /* This should not fail since we have a numeric address string @@ -139,16 +156,15 @@ static apr_status_t rfc1413_connect(apr_socket_t **newsock, conn_rec *conn, return rv; } - if ((rv = apr_socket_create(newsock, + if ((rv = apr_socket_create(newsock, localsa->family, /* has to match */ SOCK_STREAM, conn->pool)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, "rfc1413: error creating query socket"); return rv; } - if ((rv = apr_socket_timeout_set(*newsock, apr_time_from_sec(ap_rfc1413_timeout))) - != APR_SUCCESS) { + if ((rv = apr_socket_timeout_set(*newsock, timeout)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, "rfc1413: error setting query socket timeout"); apr_socket_close(*newsock); @@ -165,10 +181,10 @@ static apr_status_t rfc1413_connect(apr_socket_t **newsock, conn_rec *conn, */ if ((rv = apr_bind(*newsock, localsa)) != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, "rfc1413: Error binding query socket to local port"); apr_socket_close(*newsock); - return rv; + return rv; } /* @@ -183,7 +199,7 @@ static apr_status_t rfc1413_connect(apr_socket_t **newsock, conn_rec *conn, return APR_SUCCESS; } -static apr_status_t rfc1413_query(apr_socket_t *sock, conn_rec *conn, +static apr_status_t rfc1413_query(apr_socket_t *sock, conn_rec *conn, server_rec *srv) { apr_port_t rmt_port, our_port; @@ -191,7 +207,7 @@ static apr_status_t rfc1413_query(apr_socket_t *sock, conn_rec *conn, apr_size_t i; char *cp; char buffer[RFC1413_MAXDATA + 1]; - char user[RFC1413_USERLEN + 1]; /* XXX */ + char user[RFC1413_USERLEN + 1]; /* XXX */ apr_size_t buflen; apr_sockaddr_port_get(&sav_our_port, conn->local_addr); @@ -207,19 +223,19 @@ static apr_status_t rfc1413_query(apr_socket_t *sock, conn_rec *conn, while (i < buflen) { apr_size_t j = strlen(buffer + i); apr_status_t status; - status = apr_send(sock, buffer+i, &j); - if (status != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, status, srv, - "write: rfc1413: error sending request"); - return status; - } - else if (j > 0) { - i+=j; - } + status = apr_send(sock, buffer+i, &j); + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, status, srv, + "write: rfc1413: error sending request"); + return status; + } + else if (j > 0) { + i+=j; + } } /* - * Read response from server. - the response should be newline + * Read response from server. - the response should be newline * terminated according to rfc - make sure it doesn't stomp its * way out of the buffer. */ @@ -233,15 +249,15 @@ static apr_status_t rfc1413_query(apr_socket_t *sock, conn_rec *conn, while((cp = strchr(buffer, '\012')) == NULL && i < sizeof(buffer) - 1) { apr_size_t j = sizeof(buffer) - 1 - i; apr_status_t status; - status = apr_recv(sock, buffer+i, &j); - if (status != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_CRIT, status, srv, - "read: rfc1413: error reading response"); - return status; - } - else if (j > 0) { - i+=j; - } + status = apr_recv(sock, buffer+i, &j); + if (status != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, status, srv, + "read: rfc1413: error reading response"); + return status; + } + else if (j > 0) { + i+=j; + } else if (status == APR_SUCCESS && j == 0) { /* Oops... we ran out of data before finding newline */ return APR_EINVAL; @@ -251,9 +267,9 @@ static apr_status_t rfc1413_query(apr_socket_t *sock, conn_rec *conn, /* RFC1413_USERLEN = 512 */ ap_xlate_proto_from_ascii(buffer, i); if (sscanf(buffer, "%hu , %hu : USERID :%*[^:]:%512s", &rmt_port, &our_port, - user) != 3 || sav_rmt_port != rmt_port - || sav_our_port != our_port) - return APR_EINVAL; + user) != 3 || sav_rmt_port != rmt_port + || sav_our_port != our_port) + return APR_EINVAL; /* * Strip trailing carriage return. It is part of the @@ -261,19 +277,97 @@ static apr_status_t rfc1413_query(apr_socket_t *sock, conn_rec *conn, */ if ((cp = strchr(user, '\r'))) - *cp = '\0'; + *cp = '\0'; conn->remote_logname = apr_pstrdup(conn->pool, user); return APR_SUCCESS; } -char *ap_rfc1413(conn_rec *conn, server_rec *srv) +static const char *set_idcheck(cmd_parms *cmd, void *d_, int arg) { + ident_config_rec *d = d_; + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + + if (!err) { + d->do_rfc1413 = arg ? 1 : 0; + } + + return err; +} + +static const char *set_timeout(cmd_parms *cmd, void *d_, const char *arg) +{ + ident_config_rec *d = d_; + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + + if (!err) { + d->timeout = apr_time_from_sec(atoi(arg)); + d->timeout_unset = 0; + } + + return err; +} + +static void *create_ident_dir_config(apr_pool_t *p, char *d) +{ + ident_config_rec *conf = apr_palloc(p, sizeof(*conf)); + + conf->do_rfc1413 = DEFAULT_RFC1413 | RFC1413_UNSET; + conf->timeout = apr_time_from_sec(RFC1413_TIMEOUT); + conf->timeout_unset = 1; + + return (void *)conf; +} + +static void *merge_ident_dir_config(apr_pool_t *p, void *old_, void *new_) +{ + ident_config_rec *conf = (ident_config_rec *)apr_pcalloc(p, sizeof(*conf)); + ident_config_rec *old = (ident_config_rec *) old_; + ident_config_rec *new = (ident_config_rec *) new_; + + conf->timeout = new->timeout_unset + ? old->timeout + : new->timeout; + + conf->do_rfc1413 = new->do_rfc1413 & RFC1413_UNSET + ? old->do_rfc1413 + : new->do_rfc1413; + + return (void *)conf; +} + +static const command_rec ident_cmds[] = +{ + AP_INIT_FLAG("IdentityCheck", set_idcheck, NULL, RSRC_CONF|ACCESS_CONF, + "Enable identd (RFC 1413) user lookups - SLOW"), + AP_INIT_TAKE1("IdentityCheckTimeout", set_timeout, NULL, + RSRC_CONF|ACCESS_CONF, + "Identity check (RFC 1413) timeout duration (sec)"), + {NULL} +}; + +module AP_MODULE_DECLARE_DATA ident_module; + +/* + * Optional function for the core to to the actual ident request + */ +static const char *ap_ident_lookup(request_rec *r) +{ + ident_config_rec *conf; apr_socket_t *sock; apr_status_t rv; + conn_rec *conn = r->connection; + server_rec *srv = r->server; + + conf = ap_get_module_config(r->per_dir_config, &ident_module); + + /* return immediately if ident requests are disabled */ + if (!(conf->do_rfc1413 & ~RFC1413_UNSET)) { + return NULL; + } - rv = rfc1413_connect(&sock, conn, srv); + rv = rfc1413_connect(&sock, conn, srv, conf->timeout); if (rv == APR_SUCCESS) { rv = rfc1413_query(sock, conn, srv); apr_socket_close(sock); @@ -281,5 +375,22 @@ char *ap_rfc1413(conn_rec *conn, server_rec *srv) if (rv != APR_SUCCESS) { conn->remote_logname = FROM_UNKNOWN; } - return conn->remote_logname; + + return (const char *)conn->remote_logname; } + +static void register_hooks(apr_pool_t *p) +{ + APR_REGISTER_OPTIONAL_FN(ap_ident_lookup); +} + +module AP_MODULE_DECLARE_DATA ident_module = +{ + STANDARD20_MODULE_STUFF, + create_ident_dir_config, /* dir config creater */ + merge_ident_dir_config, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server config */ + ident_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; diff --git a/server/Makefile.in b/server/Makefile.in index d4ccf7a277..91416ebb2c 100644 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -11,7 +11,7 @@ LTLIBRARY_SOURCES = \ test_char.h \ config.c log.c main.c vhost.c util.c \ util_script.c util_md5.c util_cfgtree.c util_ebcdic.c util_time.c \ - rfc1413.c connection.c listen.c \ + connection.c listen.c \ mpm_common.c util_charset.c util_debug.c util_xml.c \ util_filter.c $(top_builddir)/server/exports.c buildmark.c \ scoreboard.c error_bucket.c protocol.c core.c request.c provider.c diff --git a/server/core.c b/server/core.c index cc9ba9e00f..62b2fa509a 100644 --- a/server/core.c +++ b/server/core.c @@ -79,7 +79,6 @@ #include "http_vhost.h" #include "http_main.h" /* For the default_handler below... */ #include "http_log.h" -#include "rfc1413.h" #include "util_md5.h" #include "http_connection.h" #include "apr_buckets.h" @@ -144,7 +143,6 @@ static void *create_core_dir_config(apr_pool_t *a, char *dir) conf->use_canonical_name = USE_CANONICAL_NAME_UNSET; conf->hostname_lookups = HOSTNAME_LOOKUP_UNSET; - conf->do_rfc1413 = DEFAULT_RFC1413 | 2; /* set bit 1 to indicate default */ conf->satisfy = SATISFY_NOSPEC; #ifdef RLIMIT_CPU @@ -323,10 +321,6 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv) conf->hostname_lookups = new->hostname_lookups; } - if ((new->do_rfc1413 & 2) == 0) { - conf->do_rfc1413 = new->do_rfc1413; - } - if ((new->content_md5 & 2) == 0) { conf->content_md5 = new->content_md5; } @@ -827,24 +821,22 @@ AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config, } } +/* + * Optional function coming from mod_ident, used for looking up ident user + */ +static APR_OPTIONAL_FN_TYPE(ap_ident_lookup) *ident_lookup; + AP_DECLARE(const char *) ap_get_remote_logname(request_rec *r) { - core_dir_config *dir_conf; - if (r->connection->remote_logname != NULL) { return r->connection->remote_logname; } - /* If we haven't checked the identity, and we want to */ - dir_conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, - &core_module); - - if (dir_conf->do_rfc1413 & 1) { - return ap_rfc1413(r->connection, r->server); - } - else { - return NULL; + if (ident_lookup) { + return ident_lookup(r); } + + return NULL; } /* There are two options regarding what the "name" of a server is. The @@ -2074,19 +2066,6 @@ static const char *set_timeout(cmd_parms *cmd, void *dummy, const char *arg) return NULL; } -static const char *set_idcheck(cmd_parms *cmd, void *d_, int arg) -{ - core_dir_config *d = d_; - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - - if (err != NULL) { - return err; - } - - d->do_rfc1413 = arg != 0; - return NULL; -} - static const char *set_hostname_lookups(cmd_parms *cmd, void *d_, const char *arg) { @@ -3000,8 +2979,6 @@ AP_INIT_TAKE1("ServerPath", set_serverpath, NULL, RSRC_CONF, "The pathname the server can be reached at"), AP_INIT_TAKE1("Timeout", set_timeout, NULL, RSRC_CONF, "Timeout duration (sec)"), -AP_INIT_FLAG("IdentityCheck", set_idcheck, NULL, RSRC_CONF|ACCESS_CONF, - "Enable identd (RFC 1413) user lookups - SLOW"), AP_INIT_FLAG("ContentDigest", set_content_md5, NULL, OR_OPTIONS, "whether or not to send a Content-MD5 header with each request"), AP_INIT_TAKE1("UseCanonicalName", set_use_canonical_name, NULL, @@ -4054,6 +4031,7 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b) static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { logio_add_bytes_out = APR_RETRIEVE_OPTIONAL_FN(ap_logio_add_bytes_out); + ident_lookup = APR_RETRIEVE_OPTIONAL_FN(ap_ident_lookup); ap_set_version(pconf); ap_setup_make_content_type(pconf);