httpd-modules-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Nebergall, Christopher" <cneb...@sandia.gov>
Subject secure use of ap_get_server_name/port
Date Thu, 06 Mar 2008 19:09:37 GMT
I'm looking for secure versions of ap_get_server_name and ap_get_server_port which can be trusted
to always evaluate to the correct host and port for re-constructing the original URL the user
requested.   I've removed all of the code below which seemed to rely on DNS, or info sent
from the client.  Is the code below a sufficient minimal set to get working secure versions
of those functions?  I'm confused why there are so many different ways to get the hostname
or port.  It seems that if the ServerName directive is there it should return a value and
that would be it.   Also why would code like cport below ever be zero?

API_EXPORT(const char *) ap_get_server_name2(request_rec *r)
{
        return r->hostname?r->hostname:r->server->server_hostname;
}

API_EXPORT(unsigned) ap_get_server_port2(const request_rec *r)
{
    unsigned port;
    unsigned cport = ntohs(r->connection->local_addr.sin_port);
    port = cport ? cport : r->server->port ? r->server->port : ap_default_port(r);
    return port;
}

-Christopher

Original apache 1.3 code

-----------------------------------------------------------------------------------------------------------------
API_EXPORT(const char *) ap_get_server_name(request_rec *r)
{
    conn_rec *conn = r->connection;
    core_dir_config *d;

    d = (core_dir_config *)ap_get_module_config(r->per_dir_config,
                                                &core_module);

    if (d->use_canonical_name == USE_CANONICAL_NAME_OFF) {
        return r->hostname ? r->hostname : r->server->server_hostname;
    }
    if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
        if (conn->local_host == NULL) {
            struct in_addr *iaddr;
            struct hostent *hptr;
            int old_stat;
            old_stat = ap_update_child_status(conn->child_num,
                                              SERVER_BUSY_DNS, r);
            iaddr = &(conn->local_addr.sin_addr);
            hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr),
                                 AF_INET);
            if (hptr != NULL) {
                conn->local_host = ap_pstrdup(conn->pool,
                                              (void *)hptr->h_name);
                ap_str_tolower(conn->local_host);
            }
            else {
                conn->local_host = ap_pstrdup(conn->pool,
                                              r->server->server_hostname);
            }
            (void) ap_update_child_status(conn->child_num, old_stat, r);
        }
        return conn->local_host;
    }
    /* default */
    return r->server->server_hostname;
}

API_EXPORT(unsigned) ap_get_server_port(const request_rec *r)
{
    unsigned port;
    unsigned cport = ntohs(r->connection->local_addr.sin_port);
    core_dir_config *d =
      (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module);

    if (d->use_canonical_name == USE_CANONICAL_NAME_OFF
        || d->use_canonical_name == USE_CANONICAL_NAME_DNS) {

        /* With UseCanonicalName Off Apache will form self-referential
         * URLs using the hostname and port supplied by the client if
         * any are supplied (otherwise it will use the canonical name).
         */
        port = r->parsed_uri.port_str ? r->parsed_uri.port :
          cport ? cport :
            r->server->port ? r->server->port :
              ap_default_port(r);
    } else { /* d->use_canonical_name == USE_CANONICAL_NAME_ON */
        port = r->server->port ? r->server->port :
          cport ? cport :
            ap_default_port(r);
    }

    /* default */
    return port;
}


Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message