Esempio n. 1
0
int create_https_socket(request_t *req, sock_t *cli_sock, sock_t *srv_sock, ssl_context_t* ctx, bool use_http_proxy)
{
        char *connect_buf = NULL;
        http_infos_t* http_infos = &req->http_infos;
        int retcode = -1;


        /* disable all interception if ssl intercept was explicitely disabled by config */
        if (cfg->ssl_intercept == false)
                req->do_intercept = false;

        if (use_http_proxy) {

                /* 0. set up proxy->proxy ssl session (i.e. forward CONNECT request) */
                retcode = proxenet_write(*cli_sock, req->data, req->size);
                if (retcode < 0) {
                        xlog(LOG_ERROR, "%s failed to CONNECT to proxy\n", PROGNAME);
                        return -1;
                }

                /* read response */
                retcode = proxenet_read_all(*cli_sock, &connect_buf, NULL);
                if (retcode < 0) {
                        xlog(LOG_ERROR, "%s Failed to read from proxy\n", PROGNAME);
                        proxenet_xfree(connect_buf);
                        return -1;
                }

                /* expect HTTP 200 */
                if (   (strncmp(connect_buf, "HTTP/1.0 200", 12) != 0)
                       && (strncmp(connect_buf, "HTTP/1.1 200", 12) != 0)) {
                        xlog(LOG_ERROR, "%s->proxy: bad HTTP version\n", PROGNAME);
                        proxenet_xfree(connect_buf);

                        if (cfg->verbose)
                                xlog(LOG_ERROR, "Received %s\n", connect_buf);

                        return -1;
                }

                proxenet_xfree(connect_buf);
        }

        if (req->do_intercept){

                /* 1. set up proxy->server ssl session with hostname */
                if(proxenet_ssl_init_client_context(&(ctx->client), http_infos->hostname) < 0) {
                        return -1;
                }

                proxenet_ssl_wrap_socket(&(ctx->client.context), cli_sock);

                retcode = proxenet_ssl_handshake(&(ctx->client.context));
                if (retcode < 0) {
                        xlog(LOG_ERROR, "handshake %s->server failed [code: %#x]\n", PROGNAME, retcode);
                        xlog(LOG_ERROR, "Client SSL handshake failed for '%s:%d'.\n",
                             http_infos->hostname, http_infos->port, retcode);
                        return -1;
                }

#ifdef DEBUG
                xlog(LOG_DEBUG, "SSL handshake with %s done, cli_sock=%d\n",
                     use_http_proxy?"proxy":"server", *cli_sock);
#endif
        }

        if (proxenet_write(*srv_sock, "HTTP/1.0 200 Connection established\r\n\r\n", 39) < 0){
                return -1;
        }

        if (req->do_intercept) {

                /* 2. set up proxy->browser ssl session with hostname */
                if(proxenet_ssl_init_server_context(&(ctx->server), http_infos->hostname) < 0) {
                        return -1;
                }

                proxenet_ssl_wrap_socket(&(ctx->server.context), srv_sock);

                retcode = proxenet_ssl_handshake(&(ctx->server.context));
                if (retcode < 0) {
                        xlog(LOG_ERROR, "handshake %s->client failed [code: %#x]\n", PROGNAME, retcode);
                        xlog(LOG_ERROR, "Server SSL handshake failed for '%s:%d'.\n",
                             http_infos->hostname, http_infos->port, retcode);
                        return -1;
                }

#ifdef DEBUG
                xlog(LOG_DEBUG, "SSL handshake with client done, srv_sock=%d\n", *srv_sock);
#endif
        }

        return 0;
}
Esempio n. 2
0
/**
 * Establish a connection from proxenet -> server. If proxy forwarding configured, then process
 * request to other proxy.
 * 
 */
int create_http_socket(request_t* req, sock_t* server_sock, sock_t* client_sock, ssl_context_t* ssl_ctx) 
{
	int retcode;
	char *host, *port;
	char sport[6] = {0, };
	http_request_t* http_infos = &req->http_infos;
	bool use_proxy = (cfg->proxy.host != NULL) ;

	/* get target from string and establish client socket to dest */
	if (get_url_information(req->data, http_infos) == false) {
		xlog(LOG_ERROR, "%s\n", "Failed to extract valid parameters from URL.");
		return -1;
	}

	
#ifdef DEBUG
	char* full_uri = get_request_full_uri(req);
	xlog(LOG_DEBUG, "URL: %s\n", full_uri);
	proxenet_xfree(full_uri);
#endif
	
	ssl_ctx->use_ssl = http_infos->is_ssl;
	snprintf(sport, 5, "%u", http_infos->port);

	/* do we forward to another proxy ? */
	if (use_proxy) {
		host = cfg->proxy.host;
		port = cfg->proxy.port;
		
	} else {
		host = http_infos->hostname;
		port = sport;
	}
	
	retcode = create_connect_socket(host, port);
	if (retcode < 0) {
		if (errno)
			generic_http_error_page(*server_sock, strerror(errno));
		else
			generic_http_error_page(*server_sock, "Unknown error in <i>create_connect_socket</i>");
		
		retcode = -1;
		
	} else {
		*client_sock = retcode;
		
		/* if ssl, set up ssl interception */
		if (http_infos->is_ssl) {

			if (use_proxy) {
				char *connect_buf = NULL;
				
				/* 0. set up proxy->proxy ssl session (i.e. forward CONNECT request) */ 
				retcode = proxenet_write(*client_sock, req->data, req->size);
				if (retcode < 0) {
					xlog(LOG_ERROR, "%s failed to CONNECT to proxy\n", PROGNAME);
					return -1;
				}

				/* read response */
				retcode = proxenet_read_all(*client_sock, &connect_buf, NULL);
				if (retcode < 0) {
					xlog(LOG_ERROR, "%s Failed to read from proxy\n", PROGNAME);
					return -1;
				}

				/* expect HTTP 200 */
				if (   (strncmp(connect_buf, "HTTP/1.0 200", 12) != 0) 
				    && (strncmp(connect_buf, "HTTP/1.1 200", 12) != 0)) {
					xlog(LOG_ERROR, "%s->proxy: bad HTTP version\n", PROGNAME);
					if (cfg->verbose)
							xlog(LOG_ERROR, "Received %s\n", connect_buf);
					
					return -1;
				}
			}

			/* 1. set up proxy->server ssl session */ 
			if(proxenet_ssl_init_client_context(&(ssl_ctx->client)) < 0) {
				return -1;
			}
			
			proxenet_ssl_wrap_socket(&(ssl_ctx->client.context), client_sock);
			if (proxenet_ssl_handshake(&(ssl_ctx->client.context)) < 0) {
				xlog(LOG_ERROR, "%s->server: handshake\n", PROGNAME);
				return -1;
			}

#ifdef DEBUG
			xlog(LOG_DEBUG, "%s %d %d\n", "SSL handshake with server done",
			     *client_sock,
			     *server_sock);
#endif
			if (proxenet_write(*server_sock,
					   "HTTP/1.0 200 Connection established\r\n\r\n",
					   39) < 0){
				return -1;
			}

			/* 2. set up proxy->browser ssl session  */
			if(proxenet_ssl_init_server_context(&(ssl_ctx->server)) < 0) {
				return -1;
			}

			proxenet_ssl_wrap_socket(&(ssl_ctx->server.context), server_sock);
			if (proxenet_ssl_handshake(&(ssl_ctx->server.context)) < 0) {
				xlog(LOG_ERROR, "handshake %s->client '%s:%d' failed\n",
				     PROGNAME, http_infos->hostname, http_infos->port);
				return -1;
			}

#ifdef DEBUG
			xlog(LOG_DEBUG, "%s\n", "SSL Handshake with client done");
#endif
		}
	}
	
	
	return retcode;
}
Esempio n. 3
0
int create_http_socket(char* http_request, sock_t* server_sock, sock_t* client_sock, ssl_context_t* ssl_ctx) 
{
	http_request_t http_infos;
	int retcode;
	char* err;
	char sport[7] = {0, };

	err = NULL;
	proxenet_xzero(&http_infos, sizeof(http_request_t));
	http_infos.method = NULL;
	http_infos.hostname = NULL;
	http_infos.request_uri = NULL;
	
	/* get target from string and establish client socket to dest */
	if (get_url_information(http_request, &http_infos) == false) {
		xlog(LOG_ERROR, "%s\n", "Failed to extract valid parameters from URL.");
		return -1;
	}

	ssl_ctx->use_ssl = http_infos.is_ssl;
	snprintf(sport, 6, "%d", http_infos.port);
	
	retcode = create_connect_socket(http_infos.hostname, sport, &err);
	if (retcode < 0) {
		if (err)
			generic_http_error_page(*server_sock, err);
		else
			generic_http_error_page(*server_sock, "Unknown error in <i>create_connect_socket</i>");
		
		retcode = -1;
		
	} else {
		*client_sock = retcode;
		
		/* if ssl, set up ssl interception */
		if (http_infos.is_ssl) {
			
			/* 1. set up proxy->server ssl session */ 
			if(proxenet_ssl_init_client_context(&(ssl_ctx->client)) < 0) {
				retcode = -1;
				goto http_sock_end;
			}

			proxenet_ssl_wrap_socket(&(ssl_ctx->client.context), client_sock);
			if (proxenet_ssl_handshake(&(ssl_ctx->client.context)) < 0) {
				xlog(LOG_ERROR, "%s\n", "proxy->server: handshake");
				retcode = -1;
				goto http_sock_end;
			}
#ifdef DEBUG
			xlog(LOG_DEBUG, "%s\n", "SSL handshake with server done");
#endif
			proxenet_write(*server_sock,
				       "HTTP/1.0 200 Connection established\r\n\r\n",
				       39);
			
			/* 2.set up proxy->browser ssl session  */
			if(proxenet_ssl_init_server_context(&(ssl_ctx->server)) < 0) {
				retcode = -1;
				goto http_sock_end;
			}

			proxenet_ssl_wrap_socket(&(ssl_ctx->server.context), server_sock);
			if (proxenet_ssl_handshake(&(ssl_ctx->server.context)) < 0) {
				xlog(LOG_ERROR, "handshake proxy->client '%s:%d' failed\n",
				     http_infos.hostname, http_infos.port);
				retcode = -1;
				goto http_sock_end;
			}
			
#ifdef DEBUG
			xlog(LOG_DEBUG, "%s\n", "SSL Handshake with client done");
#endif
		}
	}
	
http_sock_end:
	proxenet_xfree(http_infos.method);
	proxenet_xfree(http_infos.hostname);
	proxenet_xfree(http_infos.request_uri);
	
	return retcode;
}
Esempio n. 4
0
/**
 * Establish a connection from proxenet -> server.
 * If proxy forwarding configured, then this function performs the negociation with the other proxy.
 * If the host applies for SSL intercept rules, this function also handles the SSL handshake.
 *
 * @return 0 if successful, -1 otherwise
 */
int create_http_socket(request_t* req, sock_t* server_sock, sock_t* client_sock, ssl_context_t* ssl_ctx)
{
        int retcode;
        char *host, *port;
        char sport[7] = {0, };
        http_request_t* http_infos = &req->http_infos;
        bool use_proxy = (cfg->proxy.host != NULL);
        bool use_http_proxy = use_proxy && (cfg->is_socks_proxy == false);
        bool use_socks_proxy = use_proxy && cfg->is_socks_proxy;
        char errmsg[512]={0,};

        if (update_http_infos(req) < 0){
                xlog(LOG_ERROR, "%s\n", "Failed to extract valid parameters from URL.");
                return -1;
        }

        ssl_ctx->use_ssl = req->is_ssl;
        proxenet_xsnprintf(sport, sizeof(sport), "%hu", http_infos->port);

        /* do we forward to another proxy ? */
        if (use_proxy) {
                host = cfg->proxy.host;
                port = cfg->proxy.port;
        } else {
                host = http_infos->hostname;
                port = sport;
        }


#ifdef DEBUG
        xlog(LOG_DEBUG, "Relay request %s to '%s:%s'\n",
             use_http_proxy ? "via HTTP proxy" : "direct",
             host, port);
#endif

        retcode = proxenet_open_socket(host, port);
        if (retcode < 0) {
                proxenet_xsnprintf(errmsg, sizeof(errmsg), "Cannot connect to %s:%s<br><br>Reason: %s",
                         host, port, errno?strerror(errno):"<i>proxenet_open_socket()</i> failed");

                generic_http_error_page(*server_sock, errmsg);
                return -1;
        }

#ifdef DEBUG
        xlog(LOG_DEBUG, "Socket to %s '%s:%s': fd=%d\n",
             use_http_proxy?"HTTP proxy":(use_socks_proxy?"SOCKS4 proxy":"server"),
             host, port, retcode);
#endif

        *client_sock = retcode;

        req->do_intercept = ( (cfg->intercept_mode==INTERCEPT_ONLY && \
                               fnmatch(cfg->intercept_pattern, http_infos->hostname, 0)==0) || \
                              (cfg->intercept_mode==INTERCEPT_EXCEPT && \
                               fnmatch(cfg->intercept_pattern, http_infos->hostname, 0)==FNM_NOMATCH) );

#ifdef DEBUG
        xlog(LOG_DEBUG, "Server '%s' %s match interception '%s' with pattern '%s'\n",
             http_infos->hostname,
             req->do_intercept?"do":"do not",
             cfg->intercept_mode==INTERCEPT_ONLY?"INTERCEPT_ONLY":"INTERCEPT_EXCEPT",
             cfg->intercept_pattern);
#endif

        if(use_socks_proxy){
                char*rhost = http_infos->hostname;
                int  rport = http_infos->port;
                retcode = proxenet_socks_connect(*client_sock, rhost, rport, true);
                if( retcode<0 ){
                        proxenet_xsnprintf(errmsg, sizeof(errmsg), "Failed to open SOCKS4 tunnel to %s:%s.\n",
                                 host, port);
                        generic_http_error_page(*server_sock, errmsg);
                        xlog(LOG_ERROR, "%s", errmsg);
                        return -1;
                }
        }

        /* set up ssl layer */
        if (req->is_ssl) {

                /* adjust do_intercept if we do not SSL intercept was explicitely disabled */
                req->do_intercept = cfg->ssl_intercept;

                if (use_http_proxy) {
                        char *connect_buf = NULL;

                        /* 0. set up proxy->proxy ssl session (i.e. forward CONNECT request) */
                        retcode = proxenet_write(*client_sock, req->data, req->size);
                        if (retcode < 0) {
                                xlog(LOG_ERROR, "%s failed to CONNECT to proxy\n", PROGNAME);
                                return -1;
                        }

                        /* read response */
                        retcode = proxenet_read_all(*client_sock, &connect_buf, NULL);
                        if (retcode < 0) {
                                xlog(LOG_ERROR, "%s Failed to read from proxy\n", PROGNAME);
                                return -1;
                        }

                        /* expect HTTP 200 */
                        if (   (strncmp(connect_buf, "HTTP/1.0 200", 12) != 0)
                               && (strncmp(connect_buf, "HTTP/1.1 200", 12) != 0)) {
                                xlog(LOG_ERROR, "%s->proxy: bad HTTP version\n", PROGNAME);
                                if (cfg->verbose)
                                        xlog(LOG_ERROR, "Received %s\n", connect_buf);

                                return -1;
                        }
#ifdef DEBUG
                        xlog(LOG_DEBUG, "HTTP Connect Ok with '%s:%s', cli_sock=%d\n", host, port, *client_sock);
#endif
                }

                if (req->do_intercept){

                        /* 1. set up proxy->server ssl session with hostname */
                        if(proxenet_ssl_init_client_context(&(ssl_ctx->client), http_infos->hostname) < 0) {
                                return -1;
                        }

                        proxenet_ssl_wrap_socket(&(ssl_ctx->client.context), client_sock);

                        retcode = proxenet_ssl_handshake(&(ssl_ctx->client.context));
                        if (retcode < 0) {
                                xlog(LOG_ERROR, "handshake %s->server failed [code: %#x]\n", PROGNAME, retcode);
                                xlog(LOG_ERROR, "Client SSL handshake failed for '%s:%d'.\n",
                                     http_infos->hostname, http_infos->port, retcode);
                                return -1;
                        }

#ifdef DEBUG
                        xlog(LOG_DEBUG, "SSL handshake with %s done, cli_sock=%d\n",
                             use_http_proxy?"proxy":"server", *client_sock);
#endif
                }

                if (proxenet_write(*server_sock, "HTTP/1.0 200 Connection established\r\n\r\n", 39) < 0){
                        return -1;
                }

                if (req->do_intercept) {

                        /* 2. set up proxy->browser ssl session with hostname */
                        if(proxenet_ssl_init_server_context(&(ssl_ctx->server), http_infos->hostname) < 0) {
                                return -1;
                        }

                        proxenet_ssl_wrap_socket(&(ssl_ctx->server.context), server_sock);

                        retcode = proxenet_ssl_handshake(&(ssl_ctx->server.context));
                        if (retcode < 0) {
                                xlog(LOG_ERROR, "handshake %s->client failed [code: %#x]\n", PROGNAME, retcode);
                                xlog(LOG_ERROR, "Server SSL handshake failed for '%s:%d'.\n",
                                     http_infos->hostname, http_infos->port, retcode);
                                return -1;
                        }

#ifdef DEBUG
                        xlog(LOG_DEBUG, "SSL handshake with client done, srv_sock=%d\n", *server_sock);
#endif
                }
        }


        return retcode;
}