summaryrefslogtreecommitdiff
path: root/modules/proxy/proxy_connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/proxy/proxy_connect.c')
-rw-r--r--modules/proxy/proxy_connect.c302
1 files changed, 0 insertions, 302 deletions
diff --git a/modules/proxy/proxy_connect.c b/modules/proxy/proxy_connect.c
deleted file mode 100644
index 9df39ee328..0000000000
--- a/modules/proxy/proxy_connect.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/* ====================================================================
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2000 The Apache Software Foundation. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Apache" and "Apache Software Foundation" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- * nor may "Apache" appear in their name, without prior written
- * permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- * Portions of this software are based upon public domain software
- * originally written at the National Center for Supercomputing Applications,
- * University of Illinois, Urbana-Champaign.
- */
-
-/* CONNECT method for Apache proxy */
-
-#include "mod_proxy.h"
-#include "http_log.h"
-#include "http_main.h"
-#include "apr_strings.h"
-
-#ifdef HAVE_BSTRING_H
-#include <bstring.h> /* for IRIX, FD_SET calls bzero() */
-#endif
-
-/*
- * This handles Netscape CONNECT method secure proxy requests.
- * A connection is opened to the specified host and data is
- * passed through between the WWW site and the browser.
- *
- * This code is based on the INTERNET-DRAFT document
- * "Tunneling SSL Through a WWW Proxy" currently at
- * http://www.mcom.com/newsref/std/tunneling_ssl.html.
- *
- * If proxyhost and proxyport are set, we send a CONNECT to
- * the specified proxy..
- *
- * FIXME: this is bad, because it does its own socket I/O
- * instead of using the I/O in buff.c. However,
- * the I/O in buff.c blocks on reads, and because
- * this function doesn't know how much data will
- * be sent either way (or when) it can't use blocking
- * I/O. This may be very implementation-specific
- * (to Linux). Any suggestions?
- * FIXME: this doesn't log the number of bytes sent, but
- * that may be okay, since the data is supposed to
- * be transparent. In fact, this doesn't log at all
- * yet. 8^)
- * FIXME: doesn't check any headers initally sent from the
- * client.
- * FIXME: should allow authentication, but hopefully the
- * generic proxy authentication is good enough.
- * FIXME: no check for r->assbackwards, whatever that is.
- */
-
-static int
-allowed_port(proxy_server_conf *conf, int port)
-{
- int i;
- int *list = (int *) conf->allowed_connect_ports->elts;
-
- for(i = 0; i < conf->allowed_connect_ports->nelts; i++) {
- if(port == list[i])
- return 1;
- }
- return 0;
-}
-
-
-int ap_proxy_connect_handler(request_rec *r, char *url,
- const char *proxyhost, int proxyport)
-{
- struct in_addr destaddr;
- const char *host;
- char *p;
- int port;
- apr_socket_t *sock;
- char buffer[HUGE_STRING_LEN];
- int nbytes, i;
-
- apr_socket_t *client_sock = NULL;
- apr_pollfd_t *pollfd;
- apr_int32_t pollcnt;
- apr_int16_t pollevent;
-
- void *sconf = r->server->module_config;
- proxy_server_conf *conf =
- (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
- struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
-
- /* Break the URL into host:port pairs */
- host = url;
- p = strchr(url, ':');
- if (p == NULL)
- port = DEFAULT_HTTPS_PORT;
- else {
- port = atoi(p + 1);
- *p = '\0';
- }
-
-/* check if ProxyBlock directive on this host */
- destaddr.s_addr = ap_inet_addr(host);
- for (i = 0; i < conf->noproxies->nelts; i++) {
- if ((npent[i].name != NULL && ap_strstr_c(host, npent[i].name) != NULL)
- || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] == '*')
- return ap_proxyerror(r, HTTP_FORBIDDEN,
- "Connect to remote machine blocked");
- }
-
- /* Check if it is an allowed port */
- if (conf->allowed_connect_ports->nelts == 0) {
- /* Default setting if not overridden by AllowCONNECT */
- switch (port) {
- case DEFAULT_HTTPS_PORT:
- case DEFAULT_SNEWS_PORT:
- break;
- default:
- return HTTP_FORBIDDEN;
- }
- } else if(!allowed_port(conf, port))
- return HTTP_FORBIDDEN;
-
- if (proxyhost) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "CONNECT to remote proxy %s on port %d", proxyhost, proxyport);
- }
- else {
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "CONNECT to %s on port %d", host, port);
- }
-
- if ((apr_socket_create(&sock, APR_INET, SOCK_STREAM, r->pool)) != APR_SUCCESS) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "proxy: error creating socket");
- return HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (ap_proxy_doconnect(sock, (char *)(proxyhost ? proxyhost : host),
- proxyport ? proxyport : port, r) != APR_SUCCESS) {
- apr_socket_close(sock);
- return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
- apr_pstrcat(r->pool, "Could not connect to remote machine:<br>",
- proxyhost, NULL));
- }
-
- /* If we are connecting through a remote proxy, we need to pass
- * the CONNECT request on to it.
- */
- if (proxyport) {
- /* FIXME: We should not be calling write() directly, but we currently
- * have no alternative. Error checking ignored. Also, we force
- * a HTTP/1.0 request to keep things simple.
- */
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "Sending the CONNECT request to the remote proxy");
- nbytes = apr_snprintf(buffer, sizeof(buffer),
- "CONNECT %s HTTP/1.0" CRLF, r->uri);
- apr_send(sock, buffer, &nbytes);
- nbytes = apr_snprintf(buffer, sizeof(buffer),
- "Proxy-agent: %s" CRLF CRLF, ap_get_server_version());
- apr_send(sock, buffer, &nbytes);
- }
- else {
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "Returning 200 OK Status");
- ap_rvputs(r, "HTTP/1.0 200 Connection established" CRLF, NULL);
- ap_rvputs(r, "Proxy-agent: ", ap_get_server_version(), CRLF CRLF, NULL);
- ap_rflush(r);
- }
-
- if(apr_poll_setup(&pollfd, 2, r->pool) != APR_SUCCESS)
- {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "proxy: error apr_poll_setup()");
- return HTTP_INTERNAL_SERVER_ERROR;
- }
-
- /* Add client side to the poll */
-#if 0
-/* FIXME !!!! SDM !!! If someone can figure out how to turn a conn_rec into a ap_sock_t or something
- this code might work. However if we must we can change r->connection->client to non-blocking and
- just see if a recv gives us anything and do the same to sock (server) side, I'll leave this as TBD so
- one can decide the best path to take
-*/
- if(apr_os_sock_put(&client_sock,
- (apr_os_sock_t *)get_socket(r->connection->client),
- r->pool) != APR_SUCCESS)
- {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "proxy: error creating client apr_socket_t");
- return HTTP_INTERNAL_SERVER_ERROR;
- }
- apr_poll_socket_add(pollfd, client_sock, APR_POLLIN);
-#endif
-
- /* Add the server side to the poll */
- apr_poll_socket_add(pollfd, sock, APR_POLLIN);
-
- while (1) { /* Infinite loop until error (one side closes the connection) */
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, "Going to sleep (poll)");
- if(apr_poll(pollfd, &pollcnt, -1) != APR_SUCCESS)
- {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "proxy: error apr_poll()");
- return HTTP_INTERNAL_SERVER_ERROR;
- }
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "Woke from select(), i=%d", pollcnt);
-
- if (pollcnt) {
- apr_poll_revents_get(&pollevent, sock, pollfd);
- if (pollevent & APR_POLLIN) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "sock was set");
- nbytes = HUGE_STRING_LEN;
- if(apr_recv(sock, buffer, &nbytes) == APR_SUCCESS) {
- int o = 0;
- while(nbytes)
- {
- i = nbytes;
- apr_send(r->connection->client_socket, buffer + o, &i);
- o += i;
- nbytes -= i;
- }
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, "Wrote %d bytes to client", nbytes);
- }
- else
- break;
- }
-
- apr_poll_revents_get(&pollevent, client_sock, pollfd);
- if (pollevent & APR_POLLIN) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "client was set");
- nbytes = HUGE_STRING_LEN;
- if(apr_recv(r->connection->client_socket, buffer, &nbytes) == APR_SUCCESS) {
- int o = 0;
- while(nbytes)
- {
- i = nbytes;
- apr_send(sock, buffer + o, &i);
- o += i;
- nbytes -= i;
- }
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
- NULL, "Wrote %d bytes to server", nbytes);
- }
- else
- break;
- }
- }
- else
- break;
- }
-
- apr_socket_close(sock);
-
- return OK;
-}