proxy_util.c revision a6fc1f3e5f9a478080cea4715aba49d17a7ccbf8
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/* ====================================================================
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * The Apache Software License, Version 1.1
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * reserved.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Redistribution and use in source and binary forms, with or without
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * modification, are permitted provided that the following conditions
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * are met:
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * 1. Redistributions of source code must retain the above copyright
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * notice, this list of conditions and the following disclaimer.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * 2. Redistributions in binary form must reproduce the above copyright
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * notice, this list of conditions and the following disclaimer in
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * the documentation and/or other materials provided with the
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * distribution.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * 3. The end-user documentation included with the redistribution,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * if any, must include the following acknowledgment:
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * "This product includes software developed by the
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Apache Software Foundation (http://www.apache.org/)."
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Alternately, this acknowledgment may appear in the software itself,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * if and wherever such third-party acknowledgments normally appear.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * 4. The names "Apache" and "Apache Software Foundation" must
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * not be used to endorse or promote products derived from this
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * software without prior written permission. For written
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * permission, please contact apache@apache.org.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * 5. Products derived from this software may not be called "Apache",
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * nor may "Apache" appear in their name, without prior written
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * permission of the Apache Software Foundation.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * SUCH DAMAGE.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * ====================================================================
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * This software consists of voluntary contributions made by many
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * individuals on behalf of the Apache Software Foundation. For more
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * information on the Apache Software Foundation, please see
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * <http://www.apache.org/>.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Portions of this software are based upon public domain software
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * originally written at the National Center for Supercomputing Applications,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * University of Illinois, Urbana-Champaign.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/* Utility routines for Apache proxy */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "mod_proxy.h"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic int proxy_match_domainname(struct dirconn_entry *This, request_rec *r);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic int proxy_match_hostname(struct dirconn_entry *This, request_rec *r);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic int proxy_match_word(struct dirconn_entry *This, request_rec *r);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic struct per_thread_data *get_per_thread_data(void);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/* already called in the knowledge that the characters are hex digits */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbint ap_proxy_hex2c(const char *x)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int i, ch;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#if !APR_CHARSET_EBCDIC
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ch = x[0];
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (apr_isdigit(ch))
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb i = ch - '0';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else if (apr_isupper(ch))
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb i = ch - ('A' - 10);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb i = ch - ('a' - 10);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb i <<= 4;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ch = x[1];
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (apr_isdigit(ch))
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb i += ch - '0';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else if (apr_isupper(ch))
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb i += ch - ('A' - 10);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb i += ch - ('a' - 10);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return i;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#else /*APR_CHARSET_EBCDIC*/
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return (1 == sscanf(x, "%2x", &i)) ? os_toebcdic[i&0xFF] : 0;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#endif /*APR_CHARSET_EBCDIC*/
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbvoid ap_proxy_c2hex(int ch, char *x)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#if !APR_CHARSET_EBCDIC
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int i;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b45c1c292ff1fa635004ae81fa691f8cb3cdda85rbb x[0] = '%';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb i = (ch & 0xF0) >> 4;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (i >= 10)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb x[1] = ('A' - 10) + i;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb x[1] = '0' + i;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb i = ch & 0x0F;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (i >= 10)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb x[2] = ('A' - 10) + i;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb x[2] = '0' + i;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#else /*APR_CHARSET_EBCDIC*/
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb static const char ntoa[] = { "0123456789ABCDEF" };
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ch &= 0xFF;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb x[0] = '%';
c3e342e5b0b9fea6617ee16d2da02c3ef2108126dougm x[1] = ntoa[(os_toascii[ch]>>4)&0x0F];
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb x[2] = ntoa[os_toascii[ch]&0x0F];
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb x[3] = '\0';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#endif /*APR_CHARSET_EBCDIC*/
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/*
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * canonicalise a URL-encoded string
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/*
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Convert a URL-encoded string to canonical form.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * It decodes characters which need not be encoded,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * and encodes those which must be encoded, and does not touch
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * those which must not be touched.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbchar *ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int isenc)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int i, j, ch;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char *y;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char *allowed; /* characters which should not be encoded */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char *reserved; /* characters which much not be en/de-coded */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/* N.B. in addition to :@&=, this allows ';' in an http path
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * and '?' in an ftp path -- this may be revised
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Also, it makes a '+' character in a search string reserved, as
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * it may be form-encoded. (Although RFC 1738 doesn't allow this -
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * it only permits ; / ? : @ = & as reserved chars.)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (t == enc_path)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb allowed = "$-_.+!*'(),;:@&=";
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else if (t == enc_search)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb allowed = "$-_.!*'(),;:@&=";
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else if (t == enc_user)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb allowed = "$-_.+!*'(),;@&=";
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe else if (t == enc_fpath)
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe allowed = "$-_.+!*'(),?:@&=";
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe else /* if (t == enc_parm) */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe allowed = "$-_.+!*'(),?/:@&=";
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe if (t == enc_path)
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe reserved = "/";
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe else if (t == enc_search)
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe reserved = "+";
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe else
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe reserved = "";
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe y = apr_palloc(p, 3 * len + 1);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe for (i = 0, j = 0; i < len; i++, j++) {
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe/* always handle '/' first */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe ch = x[i];
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe if (strchr(reserved, ch)) {
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe y[j] = ch;
2f1949bb0e3c209db94c8d521cba7380b9d11421trawick continue;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe }
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe/* decode it if not already done */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe if (isenc && ch == '%') {
2f1949bb0e3c209db94c8d521cba7380b9d11421trawick if (!ap_isxdigit(x[i + 1]) || !ap_isxdigit(x[i + 2]))
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe return NULL;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe ch = ap_proxy_hex2c(&x[i + 1]);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe i += 2;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe if (ch != 0 && strchr(reserved, ch)) { /* keep it encoded */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe ap_proxy_c2hex(ch, &y[j]);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe j += 2;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe continue;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe }
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe }
2f1949bb0e3c209db94c8d521cba7380b9d11421trawick/* recode it, if necessary */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe if (!apr_isalnum(ch) && !strchr(allowed, ch)) {
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe ap_proxy_c2hex(ch, &y[j]);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe j += 2;
2f1949bb0e3c209db94c8d521cba7380b9d11421trawick }
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe else
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe y[j] = ch;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe }
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe y[j] = '\0';
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe return y;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe}
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe/*
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe * Parses network-location.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * urlp on input the URL; on output the path, after the leading /
8aefbd756763807188d2e3ce336a8680e4893066wrowe * user NULL if no user/password permitted
8aefbd756763807188d2e3ce336a8680e4893066wrowe * password holder for password
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * host holder for host
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * port port number; only set if one is supplied.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Returns an error string.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbchar *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char **passwordp, char **hostp, int *port)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int i;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char *strp, *host, *url = *urlp;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char *user = NULL, *password = NULL;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (url[0] != '/' || url[1] != '/')
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return "Malformed URL";
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb host = url + 2;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb url = strchr(host, '/');
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (url == NULL)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb url = "";
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *(url++) = '\0'; /* skip seperating '/' */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* find _last_ '@' since it might occur in user/password part */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb strp = strrchr(host, '@');
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (strp != NULL) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *strp = '\0';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb user = host;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb host = strp + 1;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/* find password */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb strp = strchr(user, ':');
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (strp != NULL) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *strp = '\0';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb password = ap_proxy_canonenc(p, strp + 1, strlen(strp + 1), enc_user, 1);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (password == NULL)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return "Bad %-escape in URL (password)";
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb user = ap_proxy_canonenc(p, user, strlen(user), enc_user, 1);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (user == NULL)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return "Bad %-escape in URL (username)";
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (userp != NULL) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *userp = user;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (passwordp != NULL) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *passwordp = password;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb strp = strrchr(host, ':');
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (strp != NULL) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *(strp++) = '\0';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb for (i = 0; strp[i] != '\0'; i++)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (!apr_isdigit(strp[i]))
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb break;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* if (i == 0) the no port was given; keep default */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (strp[i] != '\0') {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return "Bad port number in URL";
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb } else if (i > 0) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *port = atoi(strp);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (*port > 65535)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return "Port number in URL > 65535";
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ap_str_tolower(host); /* DNS names are case-insensitive */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (*host == '\0')
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return "Missing host in URL";
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/* check hostname syntax */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb for (i = 0; host[i] != '\0'; i++)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (!apr_isdigit(host[i]) && host[i] != '.')
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb break;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* must be an IP address */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#if defined(WIN32) || defined(NETWARE) || defined(TPF) || defined(BEOS)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (host[i] == '\0' && (inet_addr(host) == -1))
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#else
4ca6cbe768b4e0917ac0b76333c26a7d5396d454trawick if (host[i] == '\0' && (ap_inet_addr(host) == -1 || inet_network(host) == -1))
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#endif
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return "Bad IP address in URL";
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/* if (strchr(host,'.') == NULL && domain != NULL)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb host = pstrcat(p, host, domain, NULL);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *urlp = url;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *hostp = host;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return NULL;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic const char * const lwday[7] =
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/*
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * If the date is a valid RFC 850 date or asctime() date, then it
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * is converted to the RFC 1123 format, otherwise it is not modified.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * This routine is not very fast at doing conversions, as it uses
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * sscanf and sprintf. However, if the date is already correctly
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * formatted, then it exits very quickly.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbconst char *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ap_proxy_date_canon(apr_pool_t *p, const char *x1)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char *x = apr_pstrdup(p, x1);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int wk, mday, year, hour, min, sec, mon;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char *q, month[4], zone[4], week[4];
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb q = strchr(x, ',');
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* check for RFC 850 date */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (q != NULL && q - x > 3 && q[1] == ' ') {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *q = '\0';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb for (wk = 0; wk < 7; wk++)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (strcmp(x, lwday[wk]) == 0)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb break;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *q = ',';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (wk == 7)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return x; /* not a valid date */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (q[4] != '-' || q[8] != '-' || q[11] != ' ' || q[14] != ':' ||
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb q[17] != ':' || strcmp(&q[20], " GMT") != 0)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return x;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (sscanf(q + 2, "%u-%3s-%u %u:%u:%u %3s", &mday, month, &year,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb &hour, &min, &sec, zone) != 7)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return x;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (year < 70)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb year += 2000;
b29f87f4b6c6886a04dccc296177a7033f70dfedtrawick else
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb year += 1900;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/* check for acstime() date */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (x[3] != ' ' || x[7] != ' ' || x[10] != ' ' || x[13] != ':' ||
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb x[16] != ':' || x[19] != ' ' || x[24] != '\0')
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return x;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (sscanf(x, "%3s %3s %u %u:%u:%u %u", week, month, &mday, &hour,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb &min, &sec, &year) != 7)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return x;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb for (wk = 0; wk < 7; wk++)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (strcmp(week, ap_day_snames[wk]) == 0)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb break;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (wk == 7)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return x;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/* check date */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb for (mon = 0; mon < 12; mon++)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (strcmp(month, ap_month_snames[mon]) == 0)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb break;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (mon == 12)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return x;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb q = apr_palloc(p, 30);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb apr_snprintf(q, 30, "%s, %.2d %s %d %.2d:%.2d:%.2d GMT", ap_day_snames[wk],
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb mday, ap_month_snames[mon], year, hour, min, sec);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return q;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbrequest_rec *make_fake_req(conn_rec *c, request_rec *r)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb request_rec *rp = apr_pcalloc(c->pool, sizeof(*r));
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb core_request_config *req_cfg;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rp->pool = c->pool;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rp->status = HTTP_OK;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rp->headers_in = apr_table_make(r->pool, 50);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rp->subprocess_env = apr_table_make(r->pool, 50);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rp->headers_out = apr_table_make(r->pool, 12);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rp->err_headers_out = apr_table_make(r->pool, 5);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rp->notes = apr_table_make(r->pool, 5);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rp->server = r->server;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rp->request_time = r->request_time;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rp->connection = c;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rp->output_filters = c->output_filters;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rp->input_filters = c->input_filters;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rp->request_config = ap_create_request_config(rp->pool);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb req_cfg = apr_pcalloc(rp->pool, sizeof(core_request_config));
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb req_cfg->bb = apr_brigade_create(rp->pool);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ap_set_module_config(rp->request_config, &core_module, req_cfg);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return rp;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/*
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Reads headers from a buffer and returns an array of headers.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Returns NULL on file error
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * This routine tries to deal with too long lines and continuation lines.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * @@@: XXX: FIXME: currently the headers are passed thru un-merged.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Is that okay, or should they be collapsed where possible?
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbapr_table_t *ap_proxy_read_headers(request_rec *r, request_rec *rr, char *buffer, int size, conn_rec *c)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb apr_table_t *headers_out;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int len;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char *value, *end;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char field[MAX_STRING_LEN];
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb headers_out = ap_make_table(r->pool, 20);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /*
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Read header lines until we get the empty separator line, a read error,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * the connection closes (EOF), or we timeout.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb while ((len = ap_getline(buffer, size, rr, 1)) > 0) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (!(value = strchr(buffer, ':'))) { /* Find the colon separator */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* Buggy MS IIS servers sometimes return invalid headers
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * (an extra "HTTP/1.0 200, OK" line sprinkled in between
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * the usual MIME headers). Try to deal with it in a sensible
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * way, but log the fact.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * XXX: The mask check is buggy if we ever see an HTTP/1.10 */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (!ap_checkmask(buffer, "HTTP/#.# ###*")) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* Nope, it wasn't even an extra HTTP header. Give up. */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return NULL;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r->server,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb "proxy: Ignoring duplicate HTTP header "
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb "returned by %s (%s)", r->uri, r->method);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb continue;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *value = '\0';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ++value;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* XXX: RFC2068 defines only SP and HT as whitespace, this test is
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * wrong... and so are many others probably.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb while (apr_isspace(*value))
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ++value; /* Skip to start of value */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* should strip trailing whitespace as well */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); --end)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *end = '\0';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb apr_table_add(headers_out, buffer, value);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* the header was too long; at the least we should skip extra data */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (len >= size - 1) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb while ((len = ap_getline(field, MAX_STRING_LEN, rr, 1))
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb >= MAX_STRING_LEN - 1) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* soak up the extra data */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (len == 0) /* time to exit the larger loop as well */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb break;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return headers_out;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/*
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * list is a comma-separated list of case-insensitive tokens, with
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * optional whitespace around the tokens.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * The return returns 1 if the token val is found in the list, or 0
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * otherwise.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wroweint ap_proxy_liststr(const char *list, const char *val)
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe{
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe int len, i;
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe const char *p;
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe len = strlen(val);
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe while (list != NULL) {
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe p = ap_strchr_c(list, ',');
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe if (p != NULL) {
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe i = p - list;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb do
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe p++;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb while (apr_isspace(*p));
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe }
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe else
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe i = strlen(list);
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe while (i > 0 && apr_isspace(list[i - 1]))
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe i--;
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe if (i == len && strncasecmp(list, val, len) == 0)
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe return 1;
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe list = p;
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe }
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe return 0;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/*
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * list is a comma-separated list of case-insensitive tokens, with
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * optional whitespace around the tokens.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * The return returns 1 if the token val is found in the list, or 0
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * otherwise.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbchar *ap_proxy_removestr(apr_pool_t *pool, const char *list, const char *val)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int len, i;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb const char *p;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char *new = NULL;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb len = strlen(val);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb while (list != NULL) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb p = ap_strchr_c(list, ',');
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (p != NULL) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb i = p - list;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb do
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb p++;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb while (apr_isspace(*p));
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb i = strlen(list);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb while (i > 0 && apr_isspace(list[i - 1]))
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb i--;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (i == len && strncasecmp(list, val, len) == 0) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* do nothing */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (new)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb new = apr_pstrcat(pool, new, ",", apr_pstrndup(pool, list, i), NULL);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb new = apr_pstrndup(pool, list, i);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb list = p;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return new;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/*
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Converts 8 hex digits to a time integer
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbint ap_proxy_hex2sec(const char *x)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int i, ch;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb unsigned int j;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb for (i = 0, j = 0; i < 8; i++) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ch = x[i];
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb j <<= 4;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (apr_isdigit(ch))
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb j |= ch - '0';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else if (apr_isupper(ch))
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb j |= ch - ('A' - 10);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb j |= ch - ('a' - 10);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (j == 0xffffffff)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return -1; /* so that it works with 8-byte ints */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return j;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/*
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Converts a time integer to 8 hex digits
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbvoid ap_proxy_sec2hex(int t, char *y)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int i, ch;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb unsigned int j = t;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb for (i = 7; i >= 0; i--) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ch = j & 0xF;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb j >>= 4;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (ch >= 10)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb y[i] = ch + ('A' - 10);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb y[i] = ch + '0';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb y[8] = '\0';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbint ap_proxyerror(request_rec *r, int statuscode, const char *message)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb apr_table_setn(r->notes, "error-notes",
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb apr_pstrcat(r->pool,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb "The proxy server could not handle the request "
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb "<EM><A HREF=\"", ap_escape_uri(r->pool, r->uri),
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb "\">", ap_escape_html(r->pool, r->method),
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb "&nbsp;",
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ap_escape_html(r->pool, r->uri), "</A></EM>.<P>\n"
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb "Reason: <STRONG>",
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ap_escape_html(r->pool, message),
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb "</STRONG>", NULL));
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* Allow "error-notes" string to be printed by ap_send_error_response() */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb apr_table_setn(r->notes, "verbose-error-to", apr_pstrdup(r->pool, "*"));
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb r->status_line = apr_psprintf(r->pool, "%3.3u Proxy Error", statuscode);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return statuscode;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
c4f311d9c637c74c57ef51a1a3a610bb48af1ce8wrowe/*
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * This routine returns its own error message
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbconst char *ap_proxy_host2addr(const char *host, struct hostent *reqhp)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int i;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb struct hostent *hp;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb struct per_thread_data *ptd = get_per_thread_data();
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb for (i = 0; host[i] != '\0'; i++)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (!apr_isdigit(host[i]) && host[i] != '.')
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb break;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (host[i] != '\0') {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb hp = gethostbyname(host);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (hp == NULL)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return "Host not found";
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ptd->ipaddr = ap_inet_addr(host);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb hp = gethostbyaddr((char *) &ptd->ipaddr, sizeof(ptd->ipaddr), AF_INET);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (hp == NULL) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb memset(&ptd->hpbuf, 0, sizeof(ptd->hpbuf));
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ptd->hpbuf.h_name = 0;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ptd->hpbuf.h_addrtype = AF_INET;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ptd->hpbuf.h_length = sizeof(ptd->ipaddr);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ptd->hpbuf.h_addr_list = ptd->charpbuf;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ptd->hpbuf.h_addr_list[0] = (char *) &ptd->ipaddr;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ptd->hpbuf.h_addr_list[1] = 0;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb hp = &ptd->hpbuf;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *reqhp = *hp;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return NULL;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic const char *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb proxy_get_host_of_request(request_rec *r)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char *url, *user = NULL, *password = NULL, *err, *host;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int port = -1;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (r->hostname != NULL)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return r->hostname;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* Set url to the first char after "scheme://" */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if ((url = strchr(r->uri, ':')) == NULL
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb || url[1] != '/' || url[2] != '/')
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return NULL;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb url = apr_pstrdup(r->pool, &url[1]); /* make it point to "//", which is what proxy_canon_netloc expects */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb err = ap_proxy_canon_netloc(r->pool, &url, &user, &password, &host, &port);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (err != NULL)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb "%s", err);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb r->hostname = host;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return host; /* ought to return the port, too */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/* Return TRUE if addr represents an IP address (or an IP network address) */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbint ap_proxy_is_ipaddr(struct dirconn_entry *This, apr_pool_t *p)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb const char *addr = This->name;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb long ip_addr[4];
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb int i, quads;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb long bits;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* if the address is given with an explicit netmask, use that */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* Due to a deficiency in ap_inet_addr(), it is impossible to parse */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* "partial" addresses (with less than 4 quads) correctly, i.e. */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* 192.168.123 is parsed as 192.168.0.123, which is not what I want. */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* I therefore have to parse the IP address manually: */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /*if (proxy_readmask(This->name, &This->addr.s_addr, &This->mask.s_addr) == 0) */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* addr and mask were set by proxy_readmask() */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /*return 1; */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* Parse IP addr manually, optionally allowing */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* abbreviated net addresses like 192.168. */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* Iterate over up to 4 (dotted) quads. */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb for (quads = 0; quads < 4 && *addr != '\0'; ++quads) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char *tmp;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (*addr == '/' && quads > 0) /* netmask starts here. */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb break;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (!apr_isdigit(*addr))
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe return 0; /* no digit at start of quad */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ip_addr[quads] = strtol(addr, &tmp, 0);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (tmp == addr) /* expected a digit, found something else */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return 0;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (ip_addr[quads] < 0 || ip_addr[quads] > 255) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* invalid octet */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return 0;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb addr = tmp;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (*addr == '.' && quads != 3)
8aefbd756763807188d2e3ce336a8680e4893066wrowe ++addr; /* after the 4th quad, a dot would be illegal */
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (This->addr.s_addr = 0, i = 0; i < quads; ++i)
8aefbd756763807188d2e3ce336a8680e4893066wrowe This->addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i));
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (addr[0] == '/' && apr_isdigit(addr[1])) { /* net mask follows: */
8aefbd756763807188d2e3ce336a8680e4893066wrowe char *tmp;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe ++addr;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe bits = strtol(addr, &tmp, 0);
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (tmp == addr) /* expected a digit, found something else */
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe addr = tmp;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (bits < 0 || bits > 32) /* netmask must be between 0 and 32 */
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe else {
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* Determine (i.e., "guess") netmask by counting the */
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* number of trailing .0's; reduce #quads appropriately */
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* (so that 192.168.0.0 is equivalent to 192.168.) */
8aefbd756763807188d2e3ce336a8680e4893066wrowe while (quads > 0 && ip_addr[quads - 1] == 0)
8aefbd756763807188d2e3ce336a8680e4893066wrowe --quads;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* "IP Address should be given in dotted-quad form, optionally followed by a netmask (e.g., 192.168.111.0/24)"; */
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (quads < 1)
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* every zero-byte counts as 8 zero-bits */
8aefbd756763807188d2e3ce336a8680e4893066wrowe bits = 8 * quads;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (bits != 32) /* no warning for fully qualified IP address */
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "Warning: NetMask not supplied with IP-Addr; guessing: %s/%ld\n",
8aefbd756763807188d2e3ce336a8680e4893066wrowe inet_ntoa(This->addr), bits);
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe This->mask.s_addr = htonl(APR_INADDR_NONE << (32 - bits));
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (*addr == '\0' && (This->addr.s_addr & ~This->mask.s_addr) != 0) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "Warning: NetMask and IP-Addr disagree in %s/%ld\n",
8aefbd756763807188d2e3ce336a8680e4893066wrowe inet_ntoa(This->addr), bits);
8aefbd756763807188d2e3ce336a8680e4893066wrowe This->addr.s_addr &= This->mask.s_addr;
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe " Set to %s/%ld\n",
8aefbd756763807188d2e3ce336a8680e4893066wrowe inet_ntoa(This->addr), bits);
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (*addr == '\0') {
8aefbd756763807188d2e3ce336a8680e4893066wrowe This->matcher = proxy_match_ipaddr;
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 1;
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe else
8aefbd756763807188d2e3ce336a8680e4893066wrowe return (*addr == '\0'); /* okay iff we've parsed the whole string */
8aefbd756763807188d2e3ce336a8680e4893066wrowe}
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe/* Return TRUE if addr represents an IP address (or an IP network address) */
8aefbd756763807188d2e3ce336a8680e4893066wrowestatic int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r)
8aefbd756763807188d2e3ce336a8680e4893066wrowe{
8aefbd756763807188d2e3ce336a8680e4893066wrowe int i;
8aefbd756763807188d2e3ce336a8680e4893066wrowe int ip_addr[4];
8aefbd756763807188d2e3ce336a8680e4893066wrowe struct in_addr addr;
8aefbd756763807188d2e3ce336a8680e4893066wrowe struct in_addr *ip_list;
8aefbd756763807188d2e3ce336a8680e4893066wrowe char **ip_listptr;
8aefbd756763807188d2e3ce336a8680e4893066wrowe const char *found;
8aefbd756763807188d2e3ce336a8680e4893066wrowe const char *host = proxy_get_host_of_request(r);
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (host == NULL) /* oops! */
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe memset(&addr, '\0', sizeof addr);
8aefbd756763807188d2e3ce336a8680e4893066wrowe memset(ip_addr, '\0', sizeof ip_addr);
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (4 == sscanf(host, "%d.%d.%d.%d", &ip_addr[0], &ip_addr[1], &ip_addr[2], &ip_addr[3])) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (addr.s_addr = 0, i = 0; i < 4; ++i)
8aefbd756763807188d2e3ce336a8680e4893066wrowe addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i));
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (This->addr.s_addr == (addr.s_addr & This->mask.s_addr)) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe#if DEBUGGING
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "1)IP-Match: %s[%s] <-> ", host, inet_ntoa(addr));
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "%s/", inet_ntoa(This->addr));
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "%s", inet_ntoa(This->mask));
8aefbd756763807188d2e3ce336a8680e4893066wrowe#endif
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 1;
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe#if DEBUGGING
8aefbd756763807188d2e3ce336a8680e4893066wrowe else {
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "1)IP-NoMatch: %s[%s] <-> ", host, inet_ntoa(addr));
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "%s/", inet_ntoa(This->addr));
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "%s", inet_ntoa(This->mask));
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe#endif
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe else {
8aefbd756763807188d2e3ce336a8680e4893066wrowe struct hostent the_host;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe memset(&the_host, '\0', sizeof the_host);
8aefbd756763807188d2e3ce336a8680e4893066wrowe found = ap_proxy_host2addr(host, &the_host);
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (found != NULL) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe#if DEBUGGING
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "2)IP-NoMatch: hostname=%s msg=%s", host, found);
8aefbd756763807188d2e3ce336a8680e4893066wrowe#endif
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (the_host.h_name != NULL)
8aefbd756763807188d2e3ce336a8680e4893066wrowe found = the_host.h_name;
8aefbd756763807188d2e3ce336a8680e4893066wrowe else
8aefbd756763807188d2e3ce336a8680e4893066wrowe found = host;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* Try to deal with multiple IP addr's for a host */
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (ip_listptr = the_host.h_addr_list; *ip_listptr; ++ip_listptr) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe ip_list = (struct in_addr *) *ip_listptr;
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (This->addr.s_addr == (ip_list->s_addr & This->mask.s_addr)) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe#if DEBUGGING
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "3)IP-Match: %s[%s] <-> ", found, inet_ntoa(*ip_list));
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "%s/", inet_ntoa(This->addr));
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "%s", inet_ntoa(This->mask));
8aefbd756763807188d2e3ce336a8680e4893066wrowe#endif
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 1;
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe#if DEBUGGING
8aefbd756763807188d2e3ce336a8680e4893066wrowe else {
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "3)IP-NoMatch: %s[%s] <-> ", found, inet_ntoa(*ip_list));
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "%s/", inet_ntoa(This->addr));
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "%s", inet_ntoa(This->mask));
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe#endif
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe}
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe/* Return TRUE if addr represents a domain name */
8aefbd756763807188d2e3ce336a8680e4893066wroweint ap_proxy_is_domainname(struct dirconn_entry *This, apr_pool_t *p)
8aefbd756763807188d2e3ce336a8680e4893066wrowe{
8aefbd756763807188d2e3ce336a8680e4893066wrowe char *addr = This->name;
8aefbd756763807188d2e3ce336a8680e4893066wrowe int i;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* Domain name must start with a '.' */
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (addr[0] != '.')
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* rfc1035 says DNS names must consist of "[-a-zA-Z0-9]" and '.' */
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (i = 0; apr_isalnum(addr[i]) || addr[i] == '-' || addr[i] == '.'; ++i)
8aefbd756763807188d2e3ce336a8680e4893066wrowe continue;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe#if 0
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (addr[i] == ':') {
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "@@@@ handle optional port in proxy_is_domainname()");
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* @@@@ handle optional port */
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe#endif
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (addr[i] != '\0')
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* Strip trailing dots */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe for (i = strlen(addr) - 1; i > 0 && addr[i] == '.'; --i)
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe addr[i] = '\0';
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe This->matcher = proxy_match_domainname;
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 1;
8aefbd756763807188d2e3ce336a8680e4893066wrowe}
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe/* Return TRUE if host "host" is in domain "domain" */
8aefbd756763807188d2e3ce336a8680e4893066wrowestatic int proxy_match_domainname(struct dirconn_entry *This, request_rec *r)
8aefbd756763807188d2e3ce336a8680e4893066wrowe{
8aefbd756763807188d2e3ce336a8680e4893066wrowe const char *host = proxy_get_host_of_request(r);
8aefbd756763807188d2e3ce336a8680e4893066wrowe int d_len = strlen(This->name), h_len;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (host == NULL) /* some error was logged already */
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe h_len = strlen(host);
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* @@@ do this within the setup? */
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* Ignore trailing dots in domain comparison: */
8aefbd756763807188d2e3ce336a8680e4893066wrowe while (d_len > 0 && This->name[d_len - 1] == '.')
8aefbd756763807188d2e3ce336a8680e4893066wrowe --d_len;
8aefbd756763807188d2e3ce336a8680e4893066wrowe while (h_len > 0 && host[h_len - 1] == '.')
8aefbd756763807188d2e3ce336a8680e4893066wrowe --h_len;
8aefbd756763807188d2e3ce336a8680e4893066wrowe return h_len > d_len
8aefbd756763807188d2e3ce336a8680e4893066wrowe && strncasecmp(&host[h_len - d_len], This->name, d_len) == 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe}
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe/* Create a copy of a "struct hostent" record; it was presumably returned
8aefbd756763807188d2e3ce336a8680e4893066wrowe * from a call to gethostbyname() and lives in static storage.
8aefbd756763807188d2e3ce336a8680e4893066wrowe * By creating a copy we can tuck it away for later use.
8aefbd756763807188d2e3ce336a8680e4893066wrowe */
8aefbd756763807188d2e3ce336a8680e4893066wrowestatic struct hostent * pduphostent(apr_pool_t *p, const struct hostent *hp)
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe{
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe struct hostent *newent;
8aefbd756763807188d2e3ce336a8680e4893066wrowe char **ptrs;
8aefbd756763807188d2e3ce336a8680e4893066wrowe char **aliases;
8aefbd756763807188d2e3ce336a8680e4893066wrowe struct in_addr *addrs;
8aefbd756763807188d2e3ce336a8680e4893066wrowe int i = 0, j = 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (hp == NULL)
8aefbd756763807188d2e3ce336a8680e4893066wrowe return NULL;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* Count number of alias entries */
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (hp->h_aliases != NULL)
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (; hp->h_aliases[j] != NULL; ++j)
8aefbd756763807188d2e3ce336a8680e4893066wrowe continue;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* Count number of in_addr entries */
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (hp->h_addr_list != NULL)
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (; hp->h_addr_list[i] != NULL; ++i)
8aefbd756763807188d2e3ce336a8680e4893066wrowe continue;
b29f87f4b6c6886a04dccc296177a7033f70dfedtrawick
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* Allocate hostent structure, alias ptrs, addr ptrs, addrs */
b29f87f4b6c6886a04dccc296177a7033f70dfedtrawick newent = (struct hostent *) apr_palloc(p, sizeof(*hp));
8aefbd756763807188d2e3ce336a8680e4893066wrowe aliases = (char **) apr_palloc(p, (j+1) * sizeof(char*));
8aefbd756763807188d2e3ce336a8680e4893066wrowe ptrs = (char **) apr_palloc(p, (i+1) * sizeof(char*));
8aefbd756763807188d2e3ce336a8680e4893066wrowe addrs = (struct in_addr *) apr_palloc(p, (i+1) * sizeof(struct in_addr));
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe *newent = *hp;
8aefbd756763807188d2e3ce336a8680e4893066wrowe newent->h_name = apr_pstrdup(p, hp->h_name);
8aefbd756763807188d2e3ce336a8680e4893066wrowe newent->h_aliases = aliases;
8aefbd756763807188d2e3ce336a8680e4893066wrowe newent->h_addr_list = (char**) ptrs;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* Copy Alias Names: */
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (j = 0; hp->h_aliases[j] != NULL; ++j) {
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe aliases[j] = apr_pstrdup(p, hp->h_aliases[j]);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe aliases[j] = NULL;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* Copy address entries */
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (i = 0; hp->h_addr_list[i] != NULL; ++i) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe ptrs[i] = (char*) &addrs[i];
8aefbd756763807188d2e3ce336a8680e4893066wrowe addrs[i] = *(struct in_addr *) hp->h_addr_list[i];
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe ptrs[i] = NULL;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe return newent;
8aefbd756763807188d2e3ce336a8680e4893066wrowe}
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe/* Return TRUE if addr represents a host name */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwroweint ap_proxy_is_hostname(struct dirconn_entry *This, apr_pool_t *p)
8aefbd756763807188d2e3ce336a8680e4893066wrowe{
8aefbd756763807188d2e3ce336a8680e4893066wrowe struct hostent host;
8aefbd756763807188d2e3ce336a8680e4893066wrowe char *addr = This->name;
8aefbd756763807188d2e3ce336a8680e4893066wrowe int i;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* Host names must not start with a '.' */
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (addr[0] == '.')
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe /* rfc1035 says DNS names must consist of "[-a-zA-Z0-9]" and '.' */
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (i = 0; apr_isalnum(addr[i]) || addr[i] == '-' || addr[i] == '.'; ++i);
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (addr[i] != '\0' || ap_proxy_host2addr(addr, &host) != NULL)
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe This->hostentry = pduphostent (p, &host);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe /* Strip trailing dots */
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (i = strlen(addr) - 1; i > 0 && addr[i] == '.'; --i)
8aefbd756763807188d2e3ce336a8680e4893066wrowe addr[i] = '\0';
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe This->matcher = proxy_match_hostname;
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 1;
8aefbd756763807188d2e3ce336a8680e4893066wrowe}
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe/* Return TRUE if host "host" is equal to host2 "host2" */
8aefbd756763807188d2e3ce336a8680e4893066wrowestatic int proxy_match_hostname(struct dirconn_entry *This, request_rec *r)
8aefbd756763807188d2e3ce336a8680e4893066wrowe{
8aefbd756763807188d2e3ce336a8680e4893066wrowe char *host = This->name;
8aefbd756763807188d2e3ce336a8680e4893066wrowe const char *host2 = proxy_get_host_of_request(r);
8aefbd756763807188d2e3ce336a8680e4893066wrowe int h2_len;
8aefbd756763807188d2e3ce336a8680e4893066wrowe int h1_len;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (host == NULL || host2 == NULL)
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 0; /* oops! */
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe h2_len = strlen(host2);
8aefbd756763807188d2e3ce336a8680e4893066wrowe h1_len = strlen(host);
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe#if 0
8aefbd756763807188d2e3ce336a8680e4893066wrowe unsigned long *ip_list;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* Try to deal with multiple IP addr's for a host */
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (ip_list = *This->hostentry->h_addr_list; *ip_list != 0UL; ++ip_list)
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (*ip_list == ? ? ? ? ? ? ? ? ? ? ? ? ?)
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 1;
8aefbd756763807188d2e3ce336a8680e4893066wrowe#endif
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* Ignore trailing dots in host2 comparison: */
8aefbd756763807188d2e3ce336a8680e4893066wrowe while (h2_len > 0 && host2[h2_len - 1] == '.')
8aefbd756763807188d2e3ce336a8680e4893066wrowe --h2_len;
8aefbd756763807188d2e3ce336a8680e4893066wrowe while (h1_len > 0 && host[h1_len - 1] == '.')
8aefbd756763807188d2e3ce336a8680e4893066wrowe --h1_len;
8aefbd756763807188d2e3ce336a8680e4893066wrowe return h1_len == h2_len
8aefbd756763807188d2e3ce336a8680e4893066wrowe && strncasecmp(host, host2, h1_len) == 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe}
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe/* Return TRUE if addr is to be matched as a word */
8aefbd756763807188d2e3ce336a8680e4893066wroweint ap_proxy_is_word(struct dirconn_entry *This, apr_pool_t *p)
8aefbd756763807188d2e3ce336a8680e4893066wrowe{
8aefbd756763807188d2e3ce336a8680e4893066wrowe This->matcher = proxy_match_word;
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 1;
8aefbd756763807188d2e3ce336a8680e4893066wrowe}
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe/* Return TRUE if string "str2" occurs literally in "str1" */
8aefbd756763807188d2e3ce336a8680e4893066wrowestatic int proxy_match_word(struct dirconn_entry *This, request_rec *r)
8aefbd756763807188d2e3ce336a8680e4893066wrowe{
8aefbd756763807188d2e3ce336a8680e4893066wrowe const char *host = proxy_get_host_of_request(r);
8aefbd756763807188d2e3ce336a8680e4893066wrowe return host != NULL && ap_strstr_c(host, This->name) != NULL;
8aefbd756763807188d2e3ce336a8680e4893066wrowe}
8aefbd756763807188d2e3ce336a8680e4893066wrowe
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe/* checks whether a host in uri_addr matches proxyblock */
8aefbd756763807188d2e3ce336a8680e4893066wroweint ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf,
8aefbd756763807188d2e3ce336a8680e4893066wrowe apr_sockaddr_t *uri_addr)
8aefbd756763807188d2e3ce336a8680e4893066wrowe{
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe int j;
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* XXX FIXME: conf->noproxies->elts is part of an opaque structure */
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (j = 0; j < conf->noproxies->nelts; j++) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
8aefbd756763807188d2e3ce336a8680e4893066wrowe struct apr_sockaddr_t *conf_addr = npent[j].addr;
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "proxy: checking remote machine [%s] against [%s]", uri_addr->hostname, npent[j].name);
8aefbd756763807188d2e3ce336a8680e4893066wrowe if ((npent[j].name && ap_strstr_c(uri_addr->hostname, npent[j].name))
8aefbd756763807188d2e3ce336a8680e4893066wrowe || npent[j].name[0] == '*') {
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r->server,
8aefbd756763807188d2e3ce336a8680e4893066wrowe "proxy: connect to remote machine %s blocked: name %s matched", uri_addr->hostname, npent[j].name);
8aefbd756763807188d2e3ce336a8680e4893066wrowe return HTTP_FORBIDDEN;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb while (conf_addr) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb while (uri_addr) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char *conf_ip;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb char *uri_ip;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb apr_sockaddr_ip_get(&conf_ip, conf_addr);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb apr_sockaddr_ip_get(&uri_ip, uri_addr);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb "proxy: ProxyBlock comparing %s and %s", conf_ip, uri_ip);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (!apr_strnatcasecmp(conf_ip, uri_ip)) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r->server,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb "proxy: connect to remote machine %s blocked: IP %s matched", uri_addr->hostname, conf_ip);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return HTTP_FORBIDDEN;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb uri_addr = uri_addr->next;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb conf_addr = conf_addr->next;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return OK;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb/* set up the minimal filter set */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbint ap_proxy_pre_http_connection(conn_rec *c, request_rec *r)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ap_add_input_filter("HTTP_IN", NULL, r, c);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ap_add_input_filter("CORE_IN", NULL, r, c);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ap_add_output_filter("CORE", NULL, r, c);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return OK;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#if defined WIN32
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic DWORD tls_index;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbBOOL WINAPI DllMain (HINSTANCE dllhandle, DWORD reason, LPVOID reserved)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb LPVOID memptr;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb switch (reason) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb case DLL_PROCESS_ATTACH:
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb tls_index = TlsAlloc();
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb case DLL_THREAD_ATTACH: /* intentional no break */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb TlsSetValue (tls_index, malloc (sizeof (struct per_thread_data)));
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb break;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb case DLL_THREAD_DETACH:
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb memptr = TlsGetValue (tls_index);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (memptr) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb free (memptr);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb TlsSetValue (tls_index, 0);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb break;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return TRUE;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#endif
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic struct per_thread_data *get_per_thread_data(void)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return NULL;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb