proxy_util.c revision 88d088222c12b626d76069ecef91057b2a26122b
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';
f888346b48f5e5b5e3f0a47dedb8cefd2759a4e2gregames 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}
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantzvoid ap_proxy_c2hex(int ch, char *x)
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz{
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz#if !APR_CHARSET_EBCDIC
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz int i;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz x[0] = '%';
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz i = (ch & 0xF0) >> 4;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz if (i >= 10)
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb x[1] = ('A' - 10) + i;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb else
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb x[1] = '0' + i;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
a2a0abd88b19e042a3eb2a9fa1702c25ad51303dwrowe i = ch & 0x0F;
a2a0abd88b19e042a3eb2a9fa1702c25ad51303dwrowe 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] = '%';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb 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*/
c3e342e5b0b9fea6617ee16d2da02c3ef2108126dougm}
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe/*
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * canonicalise a URL-encoded string
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe/*
c2cf53a40a9814eb91db2cdf820f97d943f21628coar * Convert a URL-encoded string to canonical form.
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * It decodes characters which need not be encoded,
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * and encodes those which must be encoded, and does not touch
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar * those which must not be touched.
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe */
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoarchar *ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t,
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe int isenc)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe{
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe int i, j, ch;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe char *y;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe char *allowed; /* characters which should not be encoded */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe char *reserved; /* characters which much not be en/de-coded */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe/* N.B. in addition to :@&=, this allows ';' in an http path
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * and '?' in an ftp path -- this may be revised
3e392a5afd51526de3cb15d57ee46d8cb160ae65gregames *
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * Also, it makes a '+' character in a search string reserved, as
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * it may be form-encoded. (Although RFC 1738 doesn't allow this -
ea512a4af20e6b6e6931de4929d54d93f03a0139ianh * it only permits ; / ? : @ = & as reserved chars.)
ea512a4af20e6b6e6931de4929d54d93f03a0139ianh */
9e2e5b9bccb45b4a1bb9b747f15c7355e43be916ianh if (t == enc_path)
cbd8d35ca8d9780f1081f30ebfe4abda44cab7ebianh allowed = "$-_.+!*'(),;:@&=";
ea512a4af20e6b6e6931de4929d54d93f03a0139ianh else if (t == enc_search)
ea512a4af20e6b6e6931de4929d54d93f03a0139ianh allowed = "$-_.!*'(),;:@&=";
ea512a4af20e6b6e6931de4929d54d93f03a0139ianh else if (t == enc_user)
ea512a4af20e6b6e6931de4929d54d93f03a0139ianh allowed = "$-_.+!*'(),;@&=";
ea512a4af20e6b6e6931de4929d54d93f03a0139ianh else if (t == enc_fpath)
ea512a4af20e6b6e6931de4929d54d93f03a0139ianh allowed = "$-_.+!*'(),?:@&=";
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe else /* if (t == enc_parm) */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe allowed = "$-_.+!*'(),?/:@&=";
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz if (t == enc_path)
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz reserved = "/";
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz else if (t == enc_search)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe reserved = "+";
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe else
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe reserved = "";
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
3e392a5afd51526de3cb15d57ee46d8cb160ae65gregames y = apr_palloc(p, 3 * len + 1);
3e392a5afd51526de3cb15d57ee46d8cb160ae65gregames
3e392a5afd51526de3cb15d57ee46d8cb160ae65gregames for (i = 0, j = 0; i < len; i++, j++) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe/* always handle '/' first */
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar ch = x[i];
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (strchr(reserved, ch)) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe y[j] = ch;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe continue;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe/* decode it if not already done */
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (isenc && ch == '%') {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (!ap_isxdigit(x[i + 1]) || !ap_isxdigit(x[i + 2]))
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe return NULL;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ch = ap_proxy_hex2c(&x[i + 1]);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe i += 2;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (ch != 0 && strchr(reserved, ch)) { /* keep it encoded */
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe ap_proxy_c2hex(ch, &y[j]);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe j += 2;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar continue;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
4775dfc34c90fada8c7c4d6a57ed8a3114d55c2dtrawick }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe/* recode it, if necessary */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (!apr_isalnum(ch) && !strchr(allowed, ch)) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe ap_proxy_c2hex(ch, &y[j]);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe j += 2;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe else
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe y[j] = ch;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe y[j] = '\0';
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe return y;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe}
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe/*
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * Parses network-location.
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * urlp on input the URL; on output the path, after the leading /
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * user NULL if no user/password permitted
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * password holder for password
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * host holder for host
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * port port number; only set if one is supplied.
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe *
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe * Returns an error string.
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe */
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowechar *
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp,
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe char **passwordp, char **hostp, int *port)
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz{
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe int i;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe char *strp, *host, *url = *urlp;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe char *user = NULL, *password = NULL;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (url[0] != '/' || url[1] != '/')
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe return "Malformed URL";
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar host = url + 2;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe url = strchr(host, '/');
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (url == NULL)
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe url = "";
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe else
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe *(url++) = '\0'; /* skip seperating '/' */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe /* find _last_ '@' since it might occur in user/password part */
c2cf53a40a9814eb91db2cdf820f97d943f21628coar strp = strrchr(host, '@');
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (strp != NULL) {
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz *strp = '\0';
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz user = host;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz host = strp + 1;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
c2cf53a40a9814eb91db2cdf820f97d943f21628coar/* find password */
c2cf53a40a9814eb91db2cdf820f97d943f21628coar strp = strchr(user, ':');
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (strp != NULL) {
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz *strp = '\0';
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz password = ap_proxy_canonenc(p, strp + 1, strlen(strp + 1), enc_user, 1);
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz if (password == NULL)
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe return "Bad %-escape in URL (password)";
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe user = ap_proxy_canonenc(p, user, strlen(user), enc_user, 1);
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz if (user == NULL)
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz return "Bad %-escape in URL (username)";
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (userp != NULL) {
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz *userp = user;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz }
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz if (passwordp != NULL) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe *passwordp = password;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar }
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe strp = strrchr(host, ':');
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz if (strp != NULL) {
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz *(strp++) = '\0';
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe for (i = 0; strp[i] != '\0'; i++)
c2cf53a40a9814eb91db2cdf820f97d943f21628coar if (!apr_isdigit(strp[i]))
c2cf53a40a9814eb91db2cdf820f97d943f21628coar break;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz /* if (i == 0) the no port was given; keep default */
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz if (strp[i] != '\0') {
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz return "Bad port number in URL";
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe } else if (i > 0) {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe *port = atoi(strp);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (*port > 65535)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe return "Port number in URL > 65535";
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ap_str_tolower(host); /* DNS names are case-insensitive */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (*host == '\0')
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe return "Missing host in URL";
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe/* check hostname syntax */
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz for (i = 0; host[i] != '\0'; i++)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (!apr_isdigit(host[i]) && host[i] != '.')
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe break;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe /* must be an IP address */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#if defined(WIN32) || defined(NETWARE) || defined(TPF) || defined(BEOS)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (host[i] == '\0' && (inet_addr(host) == -1))
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#else
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (host[i] == '\0' && (ap_inet_addr(host) == -1 || inet_network(host) == -1))
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe#endif
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe return "Bad IP address in URL";
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe/* if (strchr(host,'.') == NULL && domain != NULL)
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe host = pstrcat(p, host, domain, NULL);
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe */
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe *urlp = url;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe *hostp = host;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe return NULL;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe}
0540a0b469147b52e858587270dba31c2aaa9e09wrowe
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowestatic const char * const lwday[7] =
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe/*
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe * If the date is a valid RFC 850 date or asctime() date, then it
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe * is converted to the RFC 1123 format, otherwise it is not modified.
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe * This routine is not very fast at doing conversions, as it uses
0f6fdc73136a064819585afe03bc3503826ee592wrowe * sscanf and sprintf. However, if the date is already correctly
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe * formatted, then it exits very quickly.
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe */
cc9582e53aead2a044077c4a92f3dfc3605590b3wroweconst char *
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe ap_proxy_date_canon(apr_pool_t *p, const char *x1)
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp{
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe char *x = apr_pstrdup(p, x1);
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe int wk, mday, year, hour, min, sec, mon;
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp char *q, month[4], zone[4], week[4];
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe q = strchr(x, ',');
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe /* check for RFC 850 date */
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe if (q != NULL && q - x > 3 && q[1] == ' ') {
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe *q = '\0';
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe for (wk = 0; wk < 7; wk++)
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe if (strcmp(x, lwday[wk]) == 0)
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp break;
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp *q = ',';
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp if (wk == 7)
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp return x; /* not a valid date */
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp if (q[4] != '-' || q[8] != '-' || q[11] != ' ' || q[14] != ':' ||
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp q[17] != ':' || strcmp(&q[20], " GMT") != 0)
7a2edaa0193cbb0d79a65a8461a609a9402aea49brianp return x;
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp if (sscanf(q + 2, "%u-%3s-%u %u:%u:%u %3s", &mday, month, &year,
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp &hour, &min, &sec, zone) != 7)
7a2edaa0193cbb0d79a65a8461a609a9402aea49brianp return x;
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp if (year < 70)
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp year += 2000;
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp else
7a2edaa0193cbb0d79a65a8461a609a9402aea49brianp year += 1900;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe else {
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe/* check for acstime() date */
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe if (x[3] != ' ' || x[7] != ' ' || x[10] != ' ' || x[13] != ':' ||
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe x[16] != ':' || x[19] != ' ' || x[24] != '\0')
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe return x;
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp if (sscanf(x, "%3s %3s %u %u:%u:%u %u", week, month, &mday, &hour,
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe &min, &sec, &year) != 7)
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe return x;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe for (wk = 0; wk < 7; wk++)
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe 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);
c2cf53a40a9814eb91db2cdf820f97d943f21628coar rp->notes = apr_table_make(r->pool, 5);
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rp->server = r->server;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rp->request_time = r->request_time;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rp->connection = c;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe rp->output_filters = c->output_filters;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe rp->input_filters = c->input_filters;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe rp->request_config = ap_create_request_config(rp->pool);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe req_cfg = apr_pcalloc(rp->pool, sizeof(core_request_config));
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe req_cfg->bb = apr_brigade_create(rp->pool);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe ap_set_module_config(rp->request_config, &core_module, req_cfg);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe return rp;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe}
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe/*
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe * Reads headers from a buffer and returns an array of headers.
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe * Returns NULL on file error
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe * This routine tries to deal with too long lines and continuation lines.
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe * @@@: XXX: FIXME: currently the headers are passed thru un-merged.
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe * Is that okay, or should they be collapsed where possible?
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwroweapr_table_t *ap_proxy_read_headers(request_rec *r, request_rec *rr, char *buffer, int size, conn_rec *c)
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar{
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe apr_table_t *headers_out;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar int len;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe char *value, *end;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe char field[MAX_STRING_LEN];
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe headers_out = ap_make_table(r->pool, 20);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
11fb2f3611e6ff9a541e10b13e3108934f828141gregames /*
11fb2f3611e6ff9a541e10b13e3108934f828141gregames * Read header lines until we get the empty separator line, a read error,
11fb2f3611e6ff9a541e10b13e3108934f828141gregames * the connection closes (EOF), or we timeout.
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe while ((len = ap_getline(buffer, size, rr, 1)) > 0) {
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe if (!(value = strchr(buffer, ':'))) { /* Find the colon separator */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe /* Buggy MS IIS servers sometimes return invalid headers
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe * (an extra "HTTP/1.0 200, OK" line sprinkled in between
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar * the usual MIME headers). Try to deal with it in a sensible
2f1949bb0e3c209db94c8d521cba7380b9d11421trawick * way, but log the fact.
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar * XXX: The mask check is buggy if we ever see an HTTP/1.10 */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar if (!ap_checkmask(buffer, "HTTP/#.# ###*")) {
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar /* Nope, it wasn't even an extra HTTP header. Give up. */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe return NULL;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar }
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r->server,
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe "proxy: Ignoring duplicate HTTP header "
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar "returned by %s (%s)", r->uri, r->method);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe continue;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar }
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe *value = '\0';
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe ++value;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe /* XXX: RFC2068 defines only SP and HT as whitespace, this test is
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe * wrong... and so are many others probably.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
8aefbd756763807188d2e3ce336a8680e4893066wrowe while (apr_isspace(*value))
8aefbd756763807188d2e3ce336a8680e4893066wrowe ++value; /* Skip to start of value */
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* should strip trailing whitespace as well */
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); --end)
8aefbd756763807188d2e3ce336a8680e4893066wrowe *end = '\0';
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe apr_table_add(headers_out, buffer, value);
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* the header was too long; at the least we should skip extra data */
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (len >= size - 1) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe while ((len = ap_getline(field, MAX_STRING_LEN, rr, 1))
8aefbd756763807188d2e3ce336a8680e4893066wrowe >= MAX_STRING_LEN - 1) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* soak up the extra data */
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (len == 0) /* time to exit the larger loop as well */
a2a0abd88b19e042a3eb2a9fa1702c25ad51303dwrowe break;
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe return headers_out;
8aefbd756763807188d2e3ce336a8680e4893066wrowe}
2fa5b5878e7567e2875807c3e2a2b3b0d3ef74bewrowe
2fa5b5878e7567e2875807c3e2a2b3b0d3ef74bewrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe/*
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * list is a comma-separated list of case-insensitive tokens, with
8aefbd756763807188d2e3ce336a8680e4893066wrowe * optional whitespace around the tokens.
8aefbd756763807188d2e3ce336a8680e4893066wrowe * The return returns 1 if the token val is found in the list, or 0
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe * otherwise.
a8d11d78181478da6a672f7fbc58b8d523351f49wrowe */
8aa5ca8ff2a4d8e56f62ea3d461e2799136da085trawickint ap_proxy_liststr(const char *list, const char *val)
23c6309e36a63b13b61c35999c978017521993d6wrowe{
23c6309e36a63b13b61c35999c978017521993d6wrowe int len, i;
23c6309e36a63b13b61c35999c978017521993d6wrowe const char *p;
23c6309e36a63b13b61c35999c978017521993d6wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe len = strlen(val);
23c6309e36a63b13b61c35999c978017521993d6wrowe
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe while (list != NULL) {
23c6309e36a63b13b61c35999c978017521993d6wrowe p = ap_strchr_c(list, ',');
23c6309e36a63b13b61c35999c978017521993d6wrowe if (p != NULL) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe i = p - list;
8aefbd756763807188d2e3ce336a8680e4893066wrowe do
8aefbd756763807188d2e3ce336a8680e4893066wrowe p++;
cf6ef072483172309861d06e85b1aeff4573c060wrowe while (apr_isspace(*p));
cf6ef072483172309861d06e85b1aeff4573c060wrowe }
cf6ef072483172309861d06e85b1aeff4573c060wrowe else
8aefbd756763807188d2e3ce336a8680e4893066wrowe i = strlen(list);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe while (i > 0 && apr_isspace(list[i - 1]))
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe i--;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (i == len && strncasecmp(list, val, len) == 0)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return 1;
a8d11d78181478da6a672f7fbc58b8d523351f49wrowe list = p;
a8d11d78181478da6a672f7fbc58b8d523351f49wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe}
8aefbd756763807188d2e3ce336a8680e4893066wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowe/*
cf6ef072483172309861d06e85b1aeff4573c060wrowe * list is a comma-separated list of case-insensitive tokens, with
cf6ef072483172309861d06e85b1aeff4573c060wrowe * optional whitespace around the tokens.
8aefbd756763807188d2e3ce336a8680e4893066wrowe * The return returns 1 if the token val is found in the list, or 0
cf6ef072483172309861d06e85b1aeff4573c060wrowe * otherwise.
cf6ef072483172309861d06e85b1aeff4573c060wrowe */
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianpchar *ap_proxy_removestr(apr_pool_t *pool, const char *list, const char *val)
cf6ef072483172309861d06e85b1aeff4573c060wrowe{
cf6ef072483172309861d06e85b1aeff4573c060wrowe int len, i;
cf6ef072483172309861d06e85b1aeff4573c060wrowe const char *p;
cf6ef072483172309861d06e85b1aeff4573c060wrowe char *new = NULL;
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowe len = strlen(val);
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowe while (list != NULL) {
cf6ef072483172309861d06e85b1aeff4573c060wrowe p = ap_strchr_c(list, ',');
cf6ef072483172309861d06e85b1aeff4573c060wrowe if (p != NULL) {
cf6ef072483172309861d06e85b1aeff4573c060wrowe i = p - list;
69adb3d949e3dd17c0492a01fc2cf298832c7eefwrowe do
69adb3d949e3dd17c0492a01fc2cf298832c7eefwrowe p++;
cf6ef072483172309861d06e85b1aeff4573c060wrowe while (apr_isspace(*p));
cf6ef072483172309861d06e85b1aeff4573c060wrowe }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar else
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe i = strlen(list);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar while (i > 0 && apr_isspace(list[i - 1]))
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe i--;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar if (i == len && strncasecmp(list, val, len) == 0) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* do nothing */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe else {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (new)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe new = apr_pstrcat(pool, new, ",", apr_pstrndup(pool, list, i), NULL);
23c6309e36a63b13b61c35999c978017521993d6wrowe else
23c6309e36a63b13b61c35999c978017521993d6wrowe new = apr_pstrndup(pool, list, i);
23c6309e36a63b13b61c35999c978017521993d6wrowe }
23c6309e36a63b13b61c35999c978017521993d6wrowe list = p;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar }
c2cf53a40a9814eb91db2cdf820f97d943f21628coar return new;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe/*
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * Converts 8 hex digits to a time integer
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe */
a9a4544168a37b43bd180b3703ccee995f27a80awroweint ap_proxy_hex2sec(const char *x)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe{
a9a4544168a37b43bd180b3703ccee995f27a80awrowe int i, ch;
a9a4544168a37b43bd180b3703ccee995f27a80awrowe unsigned int j;
a9a4544168a37b43bd180b3703ccee995f27a80awrowe
a9a4544168a37b43bd180b3703ccee995f27a80awrowe for (i = 0, j = 0; i < 8; i++) {
a9a4544168a37b43bd180b3703ccee995f27a80awrowe ch = x[i];
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar j <<= 4;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (apr_isdigit(ch))
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar j |= ch - '0';
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar else if (apr_isupper(ch))
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe j |= ch - ('A' - 10);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe else
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe j |= ch - ('a' - 10);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (j == 0xffffffff)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return -1; /* so that it works with 8-byte ints */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe else
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return j;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe/*
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * Converts a time integer to 8 hex digits
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowevoid ap_proxy_sec2hex(int t, char *y)
cf6ef072483172309861d06e85b1aeff4573c060wrowe{
cf6ef072483172309861d06e85b1aeff4573c060wrowe int i, ch;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe unsigned int j = t;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe for (i = 7; i >= 0; i--) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe ch = j & 0xF;
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz j >>= 4;
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz if (ch >= 10)
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz y[i] = ch + ('A' - 10);
cf6ef072483172309861d06e85b1aeff4573c060wrowe else
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe y[i] = ch + '0';
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe y[8] = '\0';
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wroweint ap_proxyerror(request_rec *r, int statuscode, const char *message)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe{
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe apr_table_setn(r->notes, "error-notes",
8aefbd756763807188d2e3ce336a8680e4893066wrowe apr_pstrcat(r->pool,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "The proxy server could not handle the request "
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "<EM><A HREF=\"", ap_escape_uri(r->pool, r->uri),
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "\">", ap_escape_html(r->pool, r->method),
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "&nbsp;",
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_escape_html(r->pool, r->uri), "</A></EM>.<P>\n"
8aefbd756763807188d2e3ce336a8680e4893066wrowe "Reason: <STRONG>",
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe ap_escape_html(r->pool, message),
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe "</STRONG>", NULL));
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe /* Allow "error-notes" string to be printed by ap_send_error_response() */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe apr_table_setn(r->notes, "verbose-error-to", apr_pstrdup(r->pool, "*"));
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe r->status_line = apr_psprintf(r->pool, "%3.3u Proxy Error", statuscode);
59513b1275fdc2021d4949ee03ae8229469abb86wrowe return statuscode;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe}
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe/*
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe * This routine returns its own error message
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe */
1b315ee865b0f11e582beb64127ca3a99a319d2fwroweconst char *ap_proxy_host2addr(const char *host, struct hostent *reqhp)
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe{
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe int i;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe struct hostent *hp;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe struct per_thread_data *ptd = get_per_thread_data();
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe for (i = 0; host[i] != '\0'; i++)
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (!apr_isdigit(host[i]) && host[i] != '.')
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe break;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (host[i] != '\0') {
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe hp = gethostbyname(host);
cf6ef072483172309861d06e85b1aeff4573c060wrowe if (hp == NULL)
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe return "Host not found";
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe else {
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe ptd->ipaddr = ap_inet_addr(host);
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe hp = gethostbyaddr((char *) &ptd->ipaddr, sizeof(ptd->ipaddr), AF_INET);
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (hp == NULL) {
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe memset(&ptd->hpbuf, 0, sizeof(ptd->hpbuf));
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe ptd->hpbuf.h_name = 0;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe ptd->hpbuf.h_addrtype = AF_INET;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe ptd->hpbuf.h_length = sizeof(ptd->ipaddr);
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe ptd->hpbuf.h_addr_list = ptd->charpbuf;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe ptd->hpbuf.h_addr_list[0] = (char *) &ptd->ipaddr;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe ptd->hpbuf.h_addr_list[1] = 0;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe hp = &ptd->hpbuf;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe *reqhp = *hp;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe return NULL;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe}
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowestatic const char *
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe proxy_get_host_of_request(request_rec *r)
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe{
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe char *url, *user = NULL, *password = NULL, *err, *host;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe int port = -1;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (r->hostname != NULL)
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe return r->hostname;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe /* Set url to the first char after "scheme://" */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if ((url = strchr(r->uri, ':')) == NULL
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe || url[1] != '/' || url[2] != '/')
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe return NULL;
cf6ef072483172309861d06e85b1aeff4573c060wrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe url = apr_pstrdup(r->pool, &url[1]); /* make it point to "//", which is what proxy_canon_netloc expects */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe err = ap_proxy_canon_netloc(r->pool, &url, &user, &password, &host, &port);
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (err != NULL)
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe "%s", err);
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe r->hostname = host;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe return host; /* ought to return the port, too */
38bcc87d9a06e8ba81165421403f275eca4e313btrawick}
38bcc87d9a06e8ba81165421403f275eca4e313btrawick
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe/* Return TRUE if addr represents an IP address (or an IP network address) */
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantzint ap_proxy_is_ipaddr(struct dirconn_entry *This, apr_pool_t *p)
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe{
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe const char *addr = This->name;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe long ip_addr[4];
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe int i, quads;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe long bits;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe /* if the address is given with an explicit netmask, use that */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe /* Due to a deficiency in ap_inet_addr(), it is impossible to parse */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe /* "partial" addresses (with less than 4 quads) correctly, i.e. */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe /* 192.168.123 is parsed as 192.168.0.123, which is not what I want. */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe /* I therefore have to parse the IP address manually: */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe /*if (proxy_readmask(This->name, &This->addr.s_addr, &This->mask.s_addr) == 0) */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe /* addr and mask were set by proxy_readmask() */
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz /*return 1; */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz /* Parse IP addr manually, optionally allowing */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* abbreviated net addresses like 192.168. */
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowe /* Iterate over up to 4 (dotted) quads. */
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (quads = 0; quads < 4 && *addr != '\0'; ++quads) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe char *tmp;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (*addr == '/' && quads > 0) /* netmask starts here. */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe break;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (!apr_isdigit(*addr))
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return 0; /* no digit at start of quad */
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowe ip_addr[quads] = strtol(addr, &tmp, 0);
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz if (tmp == addr) /* expected a digit, found something else */
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz return 0;
cf6ef072483172309861d06e85b1aeff4573c060wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (ip_addr[quads] < 0 || ip_addr[quads] > 255) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* invalid octet */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return 0;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe addr = tmp;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
4fca95918a9c0ae93593806544b425d0adc2fcc3wrowe if (*addr == '.' && quads != 3)
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz ++addr; /* after the 4th quad, a dot would be illegal */
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz }
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz for (This->addr.s_addr = 0, i = 0; i < quads; ++i)
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar This->addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i));
8aefbd756763807188d2e3ce336a8680e4893066wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (addr[0] == '/' && apr_isdigit(addr[1])) { /* net mask follows: */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe char *tmp;
4fca95918a9c0ae93593806544b425d0adc2fcc3wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ++addr;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe bits = strtol(addr, &tmp, 0);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (tmp == addr) /* expected a digit, found something else */
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 0;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe addr = tmp;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar if (bits < 0 || bits > 32) /* netmask must be between 0 and 32 */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return 0;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe else {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* Determine (i.e., "guess") netmask by counting the */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* number of trailing .0's; reduce #quads appropriately */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* (so that 192.168.0.0 is equivalent to 192.168.) */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe while (quads > 0 && ip_addr[quads - 1] == 0)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe --quads;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz /* "IP Address should be given in dotted-quad form, optionally followed by a netmask (e.g., 192.168.111.0/24)"; */
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz if (quads < 1)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return 0;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* every zero-byte counts as 8 zero-bits */
8aefbd756763807188d2e3ce336a8680e4893066wrowe bits = 8 * quads;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (bits != 32) /* no warning for fully qualified IP address */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "Warning: NetMask not supplied with IP-Addr; guessing: %s/%ld\n",
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe inet_ntoa(This->addr), bits);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe This->mask.s_addr = htonl(APR_INADDR_NONE << (32 - bits));
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (*addr == '\0' && (This->addr.s_addr & ~This->mask.s_addr) != 0) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "Warning: NetMask and IP-Addr disagree in %s/%ld\n",
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe inet_ntoa(This->addr), bits);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe This->addr.s_addr &= This->mask.s_addr;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
8aefbd756763807188d2e3ce336a8680e4893066wrowe " Set to %s/%ld\n",
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar inet_ntoa(This->addr), bits);
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (*addr == '\0') {
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar This->matcher = proxy_match_ipaddr;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar return 1;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar else
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return (*addr == '\0'); /* okay iff we've parsed the whole string */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe/* Return TRUE if addr represents an IP address (or an IP network address) */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowestatic int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe{
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe int i;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz int ip_addr[4];
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz struct in_addr addr;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe struct in_addr *ip_list;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe char **ip_listptr;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe const char *found;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe const char *host = proxy_get_host_of_request(r);
8aefbd756763807188d2e3ce336a8680e4893066wrowe
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar if (host == NULL) /* oops! */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return 0;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
8aefbd756763807188d2e3ce336a8680e4893066wrowe memset(&addr, '\0', sizeof addr);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe memset(ip_addr, '\0', sizeof ip_addr);
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz if (4 == sscanf(host, "%d.%d.%d.%d", &ip_addr[0], &ip_addr[1], &ip_addr[2], &ip_addr[3])) {
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz for (addr.s_addr = 0, i = 0; i < 4; ++i)
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i));
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (This->addr.s_addr == (addr.s_addr & This->mask.s_addr)) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe#if DEBUGGING
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz "1)IP-Match: %s[%s] <-> ", host, inet_ntoa(addr));
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "%s/", inet_ntoa(This->addr));
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "%s", inet_ntoa(This->mask));
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe#endif
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return 1;
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe#if DEBUGGING
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe else {
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "1)IP-NoMatch: %s[%s] <-> ", host, inet_ntoa(addr));
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "%s/", inet_ntoa(This->addr));
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "%s", inet_ntoa(This->mask));
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar#endif
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar else {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe struct hostent the_host;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe memset(&the_host, '\0', sizeof the_host);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe found = ap_proxy_host2addr(host, &the_host);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (found != NULL) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe#if DEBUGGING
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "2)IP-NoMatch: hostname=%s msg=%s", host, found);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe#endif
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return 0;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (the_host.h_name != NULL)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe found = the_host.h_name;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe else
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz found = host;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* Try to deal with multiple IP addr's for a host */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe for (ip_listptr = the_host.h_addr_list; *ip_listptr; ++ip_listptr) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ip_list = (struct in_addr *) *ip_listptr;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (This->addr.s_addr == (ip_list->s_addr & This->mask.s_addr)) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe#if DEBUGGING
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz "3)IP-Match: %s[%s] <-> ", found, inet_ntoa(*ip_list));
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "%s/", inet_ntoa(This->addr));
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar "%s", inet_ntoa(This->mask));
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe#endif
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar return 1;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe#if DEBUGGING
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe else {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "3)IP-NoMatch: %s[%s] <-> ", found, inet_ntoa(*ip_list));
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz "%s/", inet_ntoa(This->addr));
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz "%s", inet_ntoa(This->mask));
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe#endif
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
c2cf53a40a9814eb91db2cdf820f97d943f21628coar return 0;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
2787ef5edc27fa4f6777ba8d51aa48fd9fdf54bbwrowe/* Return TRUE if addr represents a domain name */
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantzint ap_proxy_is_domainname(struct dirconn_entry *This, apr_pool_t *p)
c2cf53a40a9814eb91db2cdf820f97d943f21628coar{
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz char *addr = This->name;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar int i;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
2787ef5edc27fa4f6777ba8d51aa48fd9fdf54bbwrowe /* Domain name must start with a '.' */
2787ef5edc27fa4f6777ba8d51aa48fd9fdf54bbwrowe if (addr[0] != '.')
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz return 0;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz /* rfc1035 says DNS names must consist of "[-a-zA-Z0-9]" and '.' */
2787ef5edc27fa4f6777ba8d51aa48fd9fdf54bbwrowe for (i = 0; apr_isalnum(addr[i]) || addr[i] == '-' || addr[i] == '.'; ++i)
2787ef5edc27fa4f6777ba8d51aa48fd9fdf54bbwrowe continue;
2787ef5edc27fa4f6777ba8d51aa48fd9fdf54bbwrowe
2787ef5edc27fa4f6777ba8d51aa48fd9fdf54bbwrowe#if 0
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (addr[i] == ':') {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "@@@@ handle optional port in proxy_is_domainname()");
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* @@@@ handle optional port */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe#endif
2520f59894a3e07fefa881ef68aaded763a8d447ben
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz if (addr[i] != '\0')
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar return 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* Strip trailing dots */
8aefbd756763807188d2e3ce336a8680e4893066wrowe for (i = strlen(addr) - 1; i > 0 && addr[i] == '.'; --i)
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar addr[i] = '\0';
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar This->matcher = proxy_match_domainname;
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 1;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe/* Return TRUE if host "host" is in domain "domain" */
8aefbd756763807188d2e3ce336a8680e4893066wrowestatic int proxy_match_domainname(struct dirconn_entry *This, request_rec *r)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe{
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz const char *host = proxy_get_host_of_request(r);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe int d_len = strlen(This->name), h_len;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz if (host == NULL) /* some error was logged already */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return 0;
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz h_len = strlen(host);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* @@@ do this within the setup? */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* Ignore trailing dots in domain comparison: */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe while (d_len > 0 && This->name[d_len - 1] == '.')
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz --d_len;
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz while (h_len > 0 && host[h_len - 1] == '.')
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz --h_len;
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz return h_len > d_len
8aefbd756763807188d2e3ce336a8680e4893066wrowe && strncasecmp(&host[h_len - d_len], This->name, d_len) == 0;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe/* Create a copy of a "struct hostent" record; it was presumably returned
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * from a call to gethostbyname() and lives in static storage.
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * By creating a copy we can tuck it away for later use.
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowestatic struct hostent * pduphostent(apr_pool_t *p, const struct hostent *hp)
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar{
8aefbd756763807188d2e3ce336a8680e4893066wrowe struct hostent *newent;
cf6ef072483172309861d06e85b1aeff4573c060wrowe char **ptrs;
cf6ef072483172309861d06e85b1aeff4573c060wrowe char **aliases;
cf6ef072483172309861d06e85b1aeff4573c060wrowe struct in_addr *addrs;
cf6ef072483172309861d06e85b1aeff4573c060wrowe int i = 0, j = 0;
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowe if (hp == NULL)
cf6ef072483172309861d06e85b1aeff4573c060wrowe return NULL;
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowe /* Count number of alias entries */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (hp->h_aliases != NULL)
cf6ef072483172309861d06e85b1aeff4573c060wrowe for (; hp->h_aliases[j] != NULL; ++j)
69adb3d949e3dd17c0492a01fc2cf298832c7eefwrowe continue;
69adb3d949e3dd17c0492a01fc2cf298832c7eefwrowe
69adb3d949e3dd17c0492a01fc2cf298832c7eefwrowe /* Count number of in_addr entries */
cf6ef072483172309861d06e85b1aeff4573c060wrowe if (hp->h_addr_list != NULL)
cf6ef072483172309861d06e85b1aeff4573c060wrowe for (; hp->h_addr_list[i] != NULL; ++i)
cf6ef072483172309861d06e85b1aeff4573c060wrowe continue;
cf6ef072483172309861d06e85b1aeff4573c060wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* Allocate hostent structure, alias ptrs, addr ptrs, addrs */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe newent = (struct hostent *) apr_palloc(p, sizeof(*hp));
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe aliases = (char **) apr_palloc(p, (j+1) * sizeof(char*));
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ptrs = (char **) apr_palloc(p, (i+1) * sizeof(char*));
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe addrs = (struct in_addr *) apr_palloc(p, (i+1) * sizeof(struct in_addr));
cf6ef072483172309861d06e85b1aeff4573c060wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe *newent = *hp;
cf6ef072483172309861d06e85b1aeff4573c060wrowe newent->h_name = apr_pstrdup(p, hp->h_name);
c2cf53a40a9814eb91db2cdf820f97d943f21628coar newent->h_aliases = aliases;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe newent->h_addr_list = (char**) ptrs;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
c2cf53a40a9814eb91db2cdf820f97d943f21628coar /* Copy Alias Names: */
c2cf53a40a9814eb91db2cdf820f97d943f21628coar for (j = 0; hp->h_aliases[j] != NULL; ++j) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe aliases[j] = apr_pstrdup(p, hp->h_aliases[j]);
cf6ef072483172309861d06e85b1aeff4573c060wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe aliases[j] = NULL;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* Copy address entries */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe for (i = 0; hp->h_addr_list[i] != NULL; ++i) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ptrs[i] = (char*) &addrs[i];
8aefbd756763807188d2e3ce336a8680e4893066wrowe addrs[i] = *(struct in_addr *) hp->h_addr_list[i];
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ptrs[i] = NULL;
cf6ef072483172309861d06e85b1aeff4573c060wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return newent;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe/* Return TRUE if addr represents a host name */
e4a3f3c2f080cac75a15a6454cca429b8161c050wroweint ap_proxy_is_hostname(struct dirconn_entry *This, apr_pool_t *p)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe{
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe struct hostent host;
69adb3d949e3dd17c0492a01fc2cf298832c7eefwrowe char *addr = This->name;
69adb3d949e3dd17c0492a01fc2cf298832c7eefwrowe int i;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* Host names must not start with a '.' */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (addr[0] == '.')
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 0;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* rfc1035 says DNS names must consist of "[-a-zA-Z0-9]" and '.' */
cf6ef072483172309861d06e85b1aeff4573c060wrowe for (i = 0; apr_isalnum(addr[i]) || addr[i] == '-' || addr[i] == '.'; ++i);
cf6ef072483172309861d06e85b1aeff4573c060wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (addr[i] != '\0' || ap_proxy_host2addr(addr, &host) != NULL)
cadddb2c31d24d48f4017db4df0a29687432326cwrowe return 0;
cadddb2c31d24d48f4017db4df0a29687432326cwrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe This->hostentry = pduphostent (p, &host);
cf6ef072483172309861d06e85b1aeff4573c060wrowe
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz /* Strip trailing dots */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe for (i = strlen(addr) - 1; i > 0 && addr[i] == '.'; --i)
8aefbd756763807188d2e3ce336a8680e4893066wrowe addr[i] = '\0';
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowe This->matcher = proxy_match_hostname;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return 1;
cf6ef072483172309861d06e85b1aeff4573c060wrowe}
cf6ef072483172309861d06e85b1aeff4573c060wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe/* Return TRUE if host "host" is equal to host2 "host2" */
c2cf53a40a9814eb91db2cdf820f97d943f21628coarstatic int proxy_match_hostname(struct dirconn_entry *This, request_rec *r)
c2cf53a40a9814eb91db2cdf820f97d943f21628coar{
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe char *host = This->name;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe const char *host2 = proxy_get_host_of_request(r);
8aefbd756763807188d2e3ce336a8680e4893066wrowe int h2_len;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe int h1_len;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowe if (host == NULL || host2 == NULL)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return 0; /* oops! */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe h2_len = strlen(host2);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe h1_len = strlen(host);
cf6ef072483172309861d06e85b1aeff4573c060wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe#if 0
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz unsigned long *ip_list;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* Try to deal with multiple IP addr's for a host */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe for (ip_list = *This->hostentry->h_addr_list; *ip_list != 0UL; ++ip_list)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (*ip_list == ? ? ? ? ? ? ? ? ? ? ? ? ?)
8aefbd756763807188d2e3ce336a8680e4893066wrowe return 1;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe#endif
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowe /* Ignore trailing dots in host2 comparison: */
cf6ef072483172309861d06e85b1aeff4573c060wrowe while (h2_len > 0 && host2[h2_len - 1] == '.')
cf6ef072483172309861d06e85b1aeff4573c060wrowe --h2_len;
cf6ef072483172309861d06e85b1aeff4573c060wrowe while (h1_len > 0 && host[h1_len - 1] == '.')
69adb3d949e3dd17c0492a01fc2cf298832c7eefwrowe --h1_len;
cf6ef072483172309861d06e85b1aeff4573c060wrowe return h1_len == h2_len
cf6ef072483172309861d06e85b1aeff4573c060wrowe && strncasecmp(host, host2, h1_len) == 0;
cf6ef072483172309861d06e85b1aeff4573c060wrowe}
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowe/* Return TRUE if addr is to be matched as a word */
cf6ef072483172309861d06e85b1aeff4573c060wroweint ap_proxy_is_word(struct dirconn_entry *This, apr_pool_t *p)
cf6ef072483172309861d06e85b1aeff4573c060wrowe{
cf6ef072483172309861d06e85b1aeff4573c060wrowe This->matcher = proxy_match_word;
cf6ef072483172309861d06e85b1aeff4573c060wrowe return 1;
cf6ef072483172309861d06e85b1aeff4573c060wrowe}
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowe/* Return TRUE if string "str2" occurs literally in "str1" */
cf6ef072483172309861d06e85b1aeff4573c060wrowestatic int proxy_match_word(struct dirconn_entry *This, request_rec *r)
cf6ef072483172309861d06e85b1aeff4573c060wrowe{
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe const char *host = proxy_get_host_of_request(r);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return host != NULL && ap_strstr_c(host, This->name) != NULL;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe/* checks whether a host in uri_addr matches proxyblock */
e4a3f3c2f080cac75a15a6454cca429b8161c050wroweint ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe apr_sockaddr_t *uri_addr)
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz{
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe int j;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe /* XXX FIXME: conf->noproxies->elts is part of an opaque structure */
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar for (j = 0; j < conf->noproxies->nelts; j++) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar struct apr_sockaddr_t *conf_addr = npent[j].addr;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar "proxy: checking remote machine [%s] against [%s]", uri_addr->hostname, npent[j].name);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if ((npent[j].name && ap_strstr_c(uri_addr->hostname, npent[j].name))
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar || npent[j].name[0] == '*') {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r->server,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "proxy: connect to remote machine %s blocked: name %s matched", uri_addr->hostname, npent[j].name);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return HTTP_FORBIDDEN;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe while (conf_addr) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe while (uri_addr) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe char *conf_ip;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe char *uri_ip;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe apr_sockaddr_ip_get(&conf_ip, conf_addr);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe apr_sockaddr_ip_get(&uri_ip, uri_addr);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "proxy: ProxyBlock comparing %s and %s", conf_ip, uri_ip);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (!apr_strnatcasecmp(conf_ip, uri_ip)) {
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r->server,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe "proxy: connect to remote machine %s blocked: IP %s matched", uri_addr->hostname, conf_ip);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return HTTP_FORBIDDEN;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar uri_addr = uri_addr->next;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz }
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe conf_addr = conf_addr->next;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar return OK;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe/* set up the minimal filter set */
e4a3f3c2f080cac75a15a6454cca429b8161c050wroweint ap_proxy_pre_http_connection(conn_rec *c, request_rec *r)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe{
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_add_input_filter("HTTP_IN", NULL, r, c);
8aefbd756763807188d2e3ce336a8680e4893066wrowe ap_add_input_filter("CORE_IN", NULL, r, c);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_add_output_filter("CORE", NULL, r, c);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return OK;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar/* converts a series of buckets into a string */
e4a3f3c2f080cac75a15a6454cca429b8161c050wroweapr_status_t ap_proxy_string_read(conn_rec *c, apr_bucket_brigade *bb, char *buff, size_t bufflen)
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar{
8aefbd756763807188d2e3ce336a8680e4893066wrowe apr_bucket *e;
8aefbd756763807188d2e3ce336a8680e4893066wrowe apr_status_t rv;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar char *pos = buff;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar char *response;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar int found = 0;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar size_t len;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* start with an empty string */
8aefbd756763807188d2e3ce336a8680e4893066wrowe buff[0] = 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* get line-at-a-time */
8aefbd756763807188d2e3ce336a8680e4893066wrowe c->remain = 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
5bb29f57ae0184d2b3c1cdf35132f8ceb011f882wrowe /* loop through each brigade */
8aefbd756763807188d2e3ce336a8680e4893066wrowe while (!found) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* get brigade from network */
c2cf53a40a9814eb91db2cdf820f97d943f21628coar if (APR_SUCCESS != (rv = ap_get_brigade(c->input_filters, bb, AP_MODE_BLOCKING))) {
c2cf53a40a9814eb91db2cdf820f97d943f21628coar return rv;
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* loop through each bucket */
8aefbd756763807188d2e3ce336a8680e4893066wrowe while (!found && !APR_BRIGADE_EMPTY(bb)) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe e = APR_BRIGADE_FIRST(bb);
8aefbd756763807188d2e3ce336a8680e4893066wrowe if (APR_SUCCESS != apr_bucket_read(e, (const char **)&response, &len, APR_BLOCK_READ)) {
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe return rv;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe /* is string LF terminated? */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (memchr(response, APR_ASCII_LF, len)) {
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe found = 1;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar /* concat strings until buff is full - then throw the data away */
0540a0b469147b52e858587270dba31c2aaa9e09wrowe if (len > ((bufflen-1)-(pos-buff))) {
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar len = (bufflen-1)-(pos-buff);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar }
0540a0b469147b52e858587270dba31c2aaa9e09wrowe if (len > 0) {
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar pos = apr_cpystrn(pos, response, len);
0540a0b469147b52e858587270dba31c2aaa9e09wrowe }
0540a0b469147b52e858587270dba31c2aaa9e09wrowe APR_BUCKET_REMOVE(e);
a9a4544168a37b43bd180b3703ccee995f27a80awrowe apr_bucket_destroy(e);
0540a0b469147b52e858587270dba31c2aaa9e09wrowe }
0540a0b469147b52e858587270dba31c2aaa9e09wrowe }
0540a0b469147b52e858587270dba31c2aaa9e09wrowe
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe return APR_SUCCESS;
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
0540a0b469147b52e858587270dba31c2aaa9e09wrowe}
0540a0b469147b52e858587270dba31c2aaa9e09wrowe
0540a0b469147b52e858587270dba31c2aaa9e09wrowe#if defined WIN32
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
0540a0b469147b52e858587270dba31c2aaa9e09wrowestatic DWORD tls_index;
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe
0540a0b469147b52e858587270dba31c2aaa9e09wroweBOOL WINAPI DllMain (HINSTANCE dllhandle, DWORD reason, LPVOID reserved)
8aefbd756763807188d2e3ce336a8680e4893066wrowe{
8aefbd756763807188d2e3ce336a8680e4893066wrowe LPVOID memptr;
0540a0b469147b52e858587270dba31c2aaa9e09wrowe
a2a0abd88b19e042a3eb2a9fa1702c25ad51303dwrowe switch (reason) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb case DLL_PROCESS_ATTACH:
948096a99010fccf648814fecf38f75c689172d7wrowe tls_index = TlsAlloc();
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb case DLL_THREAD_ATTACH: /* intentional no break */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb TlsSetValue (tls_index, malloc (sizeof (struct per_thread_data)));
0540a0b469147b52e858587270dba31c2aaa9e09wrowe break;
0540a0b469147b52e858587270dba31c2aaa9e09wrowe case DLL_THREAD_DETACH:
948096a99010fccf648814fecf38f75c689172d7wrowe memptr = TlsGetValue (tls_index);
948096a99010fccf648814fecf38f75c689172d7wrowe if (memptr) {
948096a99010fccf648814fecf38f75c689172d7wrowe free (memptr);
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp TlsSetValue (tls_index, 0);
3f5b4558f5410fdac5d6feed7aab0c3668f9cd13wrowe }
948096a99010fccf648814fecf38f75c689172d7wrowe break;
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe }
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe
053497224246c4dbef9af594cacf5c00ed271e6cwrowe return TRUE;
0540a0b469147b52e858587270dba31c2aaa9e09wrowe}
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#endif
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
948096a99010fccf648814fecf38f75c689172d7wrowestatic struct per_thread_data *get_per_thread_data(void)
948096a99010fccf648814fecf38f75c689172d7wrowe{
948096a99010fccf648814fecf38f75c689172d7wrowe return NULL;
948096a99010fccf648814fecf38f75c689172d7wrowe}
948096a99010fccf648814fecf38f75c689172d7wrowe