Exemplo n.º 1
0
void child_close_sock (void)
{
    ssize_t i;

    for (i = 0; i < vector_length(listen_fds); i++) {
        int *fd = (int *) vector_getentry(listen_fds, i, NULL);
        close (*fd);
    }

    vector_delete(listen_fds);

    listen_fds = NULL;
}
static void
free_added_headers (vector_t add_headers)
{
        ssize_t i;

        for (i = 0; i < vector_length (add_headers); i++) {
                http_header_t *header = (http_header_t *)
                        vector_getentry (add_headers, i, NULL);

                safefree (header->name);
                safefree (header->value);
        }

        vector_delete (add_headers);
}
Exemplo n.º 3
0
/**
 * Listen on the various configured interfaces
 */
int child_listening_sockets(vector_t listen_addrs, uint16_t port)
{
    int ret;
    ssize_t i;

    assert (port > 0);

    if (listen_fds == NULL) {
        listen_fds = vector_create();
        if (listen_fds == NULL) {
            log_message (LOG_ERR, "Could not create the list "
                         "of listening fds");
            return -1;
        }
    }

    if ((listen_addrs == NULL) ||
            (vector_length(listen_addrs) == 0))
    {
        /*
         * no Listen directive:
         * listen on the wildcard address(es)
         */
        ret = listen_sock(NULL, port, listen_fds);
        return ret;
    }

    for (i = 0; i < vector_length(listen_addrs); i++) {
        const char *addr;

        addr = (char *)vector_getentry(listen_addrs, i, NULL);
        if (addr == NULL) {
            log_message(LOG_WARNING,
                        "got NULL from listen_addrs - skipping");
            continue;
        }

        ret = listen_sock(addr, port, listen_fds);
        if (ret != 0) {
            return ret;
        }
    }

    return 0;
}
Exemplo n.º 4
0
/*
 * This routine checks to see if a port is allowed in the CONNECT method.
 *
 * Returns: 1 if allowed
 *          0 if denied
 */
int check_allowed_connect_ports (int port, vector_t connect_ports)
{
        size_t i;
        int *data;

        /*
	 * The absence of ConnectPort options in the config file
	 * meanas that all ports are allowed for CONNECT.
         */
        if (!connect_ports)
                return 1;

        for (i = 0; i != (size_t) vector_length (connect_ports); ++i) {
                data = (int *) vector_getentry (connect_ports, i, NULL);
                if (data && *data == port)
                        return 1;
        }

        return 0;
}
Exemplo n.º 5
0
Arquivo: reqs.c Projeto: OPSF/uClinux
/*
 * This routine checks to see if a port is allowed in the CONNECT method.
 *
 * Returns: 1 if allowed
 *          0 if denied
 *          negative upon error
 */
static int
check_allowed_connect_ports(int port)
{
	size_t i;
	int *data;

	/*
	 * If the port list doesn't exist, allow everything.  This might need
	 * to be changed in the future.
	 */
	if (!ports_allowed_by_connect)
		return 1;

	for (i = 0; i != vector_length(ports_allowed_by_connect); ++i) {
		data = vector_getentry(ports_allowed_by_connect, i, NULL);
		if (!data)
			return -1;

		if (*data == port)
			return 1;
	}

	return 0;
}
Exemplo n.º 6
0
static void initialize_with_defaults (struct config_s *conf,
                                      struct config_s *defaults)
{
        if (defaults->logf_name) {
                conf->logf_name = safestrdup (defaults->logf_name);
        }

        if (defaults->config_file) {
                conf->config_file = safestrdup (defaults->config_file);
        }

        conf->syslog = defaults->syslog;
        conf->port = defaults->port;

        if (defaults->stathost) {
                conf->stathost = safestrdup (defaults->stathost);
        }

        conf->godaemon = defaults->godaemon;
        conf->quit = defaults->quit;

        if (defaults->user) {
                conf->user = safestrdup (defaults->user);
        }

        if (defaults->group) {
                conf->group = safestrdup (defaults->group);
        }

        if (defaults->listen_addrs) {
                ssize_t i;

                conf->listen_addrs = vector_create();
                for (i=0; i < vector_length(defaults->listen_addrs); i++) {
                        char *addr;
                        size_t size;
                        addr = (char *)vector_getentry(defaults->listen_addrs,
                                                       i, &size);
                        vector_append(conf->listen_addrs, addr, size);
                }

        }

#ifdef FILTER_ENABLE
        if (defaults->filter) {
                conf->filter = safestrdup (defaults->filter);
        }

        conf->filter_url = defaults->filter_url;
        conf->filter_extended = defaults->filter_extended;
        conf->filter_casesensitive = defaults->filter_casesensitive;
#endif                          /* FILTER_ENABLE */

#ifdef XTINYPROXY_ENABLE
        conf->add_xtinyproxy = defaults->add_xtinyproxy;
#endif

#ifdef REVERSE_SUPPORT
        /* struct reversepath *reversepath_list; */
        conf->reverseonly = defaults->reverseonly;
        conf->reversemagic = defaults->reversemagic;

        if (defaults->reversebaseurl) {
                conf->reversebaseurl = safestrdup (defaults->reversebaseurl);
        }
#endif

#ifdef UPSTREAM_SUPPORT
        /* struct upstream *upstream_list; */
#endif                          /* UPSTREAM_SUPPORT */

        if (defaults->pidpath) {
                conf->pidpath = safestrdup (defaults->pidpath);
        }

        conf->idletimeout = defaults->idletimeout;

        if (defaults->bind_address) {
                conf->bind_address = safestrdup (defaults->bind_address);
        }

        conf->bindsame = defaults->bindsame;

        if (defaults->via_proxy_name) {
                conf->via_proxy_name = safestrdup (defaults->via_proxy_name);
        }

        conf->disable_viaheader = defaults->disable_viaheader;

        if (defaults->errorpage_undef) {
                conf->errorpage_undef = safestrdup (defaults->errorpage_undef);
        }

        if (defaults->statpage) {
                conf->statpage = safestrdup (defaults->statpage);
        }

        /* vector_t access_list; */
        /* vector_t connect_ports; */
        /* hashmap_t anonymous_map; */
}
Exemplo n.º 7
0
/*
 * This is the main (per child) loop.
 */
static void child_main (struct child_s *ptr)
{
    int connfd;
    struct sockaddr *cliaddr;
    socklen_t clilen;
    fd_set rfds;
    int maxfd = 0;
    ssize_t i;
    int ret;

    cliaddr = (struct sockaddr *)
              safemalloc (sizeof(struct sockaddr_storage));
    if (!cliaddr) {
        log_message (LOG_CRIT,
                     "Could not allocate memory for child address.");
        exit (0);
    }

    ptr->connects = 0;

    /*
     * We have to wait for connections on multiple fds,
     * so use select.
     */

    FD_ZERO(&rfds);

    for (i = 0; i < vector_length(listen_fds); i++) {
        int *fd = (int *) vector_getentry(listen_fds, i, NULL);

        ret = socket_nonblocking(*fd);
        if (ret != 0) {
            log_message(LOG_ERR, "Failed to set the listening "
                        "socket %d to non-blocking: %s",
                        fd, strerror(errno));
            exit(1);
        }

        FD_SET(*fd, &rfds);
        maxfd = max(maxfd, *fd);
    }

    while (!config.quit) {
        int listenfd = -1;

        ptr->status = T_WAITING;

        clilen = sizeof(struct sockaddr_storage);

        ret = select(maxfd + 1, &rfds, NULL, NULL, NULL);
        if (ret == -1) {
            log_message (LOG_ERR, "error calling select: %s",
                         strerror(errno));
            exit(1);
        } else if (ret == 0) {
            log_message (LOG_WARNING, "Strange: select returned 0 "
                         "but we did not specify a timeout...");
            continue;
        }

        for (i = 0; i < vector_length(listen_fds); i++) {
            int *fd = (int *) vector_getentry(listen_fds, i, NULL);

            if (FD_ISSET(*fd, &rfds)) {
                /*
                 * only accept the connection on the first
                 * fd that we find readable. - fair?
                 */
                listenfd = *fd;
                break;
            }
        }

        if (listenfd == -1) {
            log_message(LOG_WARNING, "Strange: None of our listen "
                        "fds was readable after select");
            continue;
        }

        ret = socket_blocking(listenfd);
        if (ret != 0) {
            log_message(LOG_ERR, "Failed to set listening "
                        "socket %d to blocking for accept: %s",
                        listenfd, strerror(errno));
            exit(1);
        }

        /*
         * We have a socket that is readable.
         * Continue handling this connection.
         */

        connfd = accept (listenfd, cliaddr, &clilen);

#ifndef NDEBUG
        /*
         * Enable the TINYPROXY_DEBUG environment variable if you
         * want to use the GDB debugger.
         */
        if (getenv ("TINYPROXY_DEBUG")) {
            /* Pause for 10 seconds to allow us to connect debugger */
            fprintf (stderr,
                     "Process has accepted connection: %ld\n",
                     (long int) ptr->tid);
            sleep (10);
            fprintf (stderr, "Continuing process: %ld\n",
                     (long int) ptr->tid);
        }
#endif

        /*
         * Make sure no error occurred...
         */
        if (connfd < 0) {
            log_message (LOG_ERR,
                         "Accept returned an error (%s) ... retrying.",
                         strerror (errno));
            continue;
        }

        ptr->status = T_CONNECTED;

        SERVER_DEC ();

        handle_connection (connfd);
        ptr->connects++;

        if (child_config.maxrequestsperchild != 0) {
            DEBUG2 ("%u connections so far...", ptr->connects);

            if (ptr->connects == child_config.maxrequestsperchild) {
                log_message (LOG_NOTICE,
                             "Child has reached MaxRequestsPerChild (%u). "
                             "Killing child.", ptr->connects);
                break;
            }
        }

        SERVER_COUNT_LOCK ();
        if (*servers_waiting > child_config.maxspareservers) {
            /*
             * There are too many spare children, kill ourself
             * off.
             */
            log_message (LOG_NOTICE,
                         "Waiting servers (%d) exceeds MaxSpareServers (%d). "
                         "Killing child.",
                         *servers_waiting,
                         child_config.maxspareservers);
            SERVER_COUNT_UNLOCK ();

            break;
        } else {
            SERVER_COUNT_UNLOCK ();
        }

        SERVER_INC ();
    }

    ptr->status = T_EMPTY;

    safefree (cliaddr);
    exit (0);
}
Exemplo n.º 8
0
int
do_transparent_proxy (struct conn_s *connptr, hashmap_t hashofheaders,
                      struct request_s *request, struct config_s *conf,
                      char **url)
{
        socklen_t length;
        char *data;
        size_t ulen = strlen (*url);
        ssize_t i;

        length = hashmap_entry_by_key (hashofheaders, "host", (void **) &data);
        if (length <= 0) {
                struct sockaddr_in dest_addr;

                if (getsockname
                    (connptr->client_fd, (struct sockaddr *) &dest_addr,
                     &length) < 0) {
                        log_message (LOG_ERR,
                                     "process_request: cannot get destination IP for %d",
                                     connptr->client_fd);
                        indicate_http_error (connptr, 400, "Bad Request",
                                             "detail", "Unknown destination",
                                             "url", *url, NULL);
                        return 0;
                }

                request->host = (char *) safemalloc (17);
                strlcpy (request->host, inet_ntoa (dest_addr.sin_addr), 17);

                request->port = ntohs (dest_addr.sin_port);

                request->path = (char *) safemalloc (ulen + 1);
                strlcpy (request->path, *url, ulen + 1);

                build_url (url, request->host, request->port, request->path);
                log_message (LOG_INFO,
                             "process_request: trans IP %s %s for %d",
                             request->method, *url, connptr->client_fd);
        } else {
                request->host = (char *) safemalloc (length + 1);
                if (sscanf (data, "%[^:]:%hu", request->host, &request->port) !=
                    2) {
                        strlcpy (request->host, data, length + 1);
                        request->port = HTTP_PORT;
                }

                request->path = (char *) safemalloc (ulen + 1);
                strlcpy (request->path, *url, ulen + 1);

                build_url (url, request->host, request->port, request->path);
                log_message (LOG_INFO,
                             "process_request: trans Host %s %s for %d",
                             request->method, *url, connptr->client_fd);
        }

        if (conf->listen_addrs == NULL) {
                return 1;
        }

        for (i = 0; i < vector_length(conf->listen_addrs); i++) {
                const char *addr;

                addr = (char *)vector_getentry(conf->listen_addrs, i, NULL);

                if (addr && strcmp(request->host, addr) == 0) {
                        log_message(LOG_ERR,
                                    "transparent: destination IP %s is local "
                                    "on socket fd %d",
                                    request->host, connptr->client_fd);
                        indicate_http_error(connptr, 400, "Bad Request",
                                            "detail",
                                            "You tried to connect to the "
                                            "machine the proxy is running on",
                                            "url", *url, NULL);
                        return 0;
                }
        }

        return 1;
}