summaryrefslogtreecommitdiff
path: root/src/http_proxy_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/http_proxy_client.c')
-rw-r--r--src/http_proxy_client.c565
1 files changed, 0 insertions, 565 deletions
diff --git a/src/http_proxy_client.c b/src/http_proxy_client.c
deleted file mode 100644
index 157d009..0000000
--- a/src/http_proxy_client.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * active port forwarder - software for secure forwarding
- * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- */
-
-#include <config.h>
-
-#include "http_proxy_functions.h"
-#include "http_proxy_client.h"
-#include "thread_management.h"
-#include "network.h"
-#include "stats.h"
-#include "logging.h"
-#include "base64.h"
-
-#ifdef HAVE_LIBPTHREAD
-typedef struct {
- int sockfd;
- char *host;
- char *serv;
- HttpProxyOptions* hpo;
- char type;
- SSL_CTX* ctx;
-} proxy_argT;
-
-/*
- * Function name: clean_return
- * Description: Closes the connection and exits the thread.
- * Arguments: sockfd - the descriptor of the connection
- */
-
-static void
-clean_return(int sockfd)
-{
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: clean_return");
- close(sockfd);
- pthread_exit(NULL);
-}
-
-/*
- * Function name: http_proxy_client
- * Description: Function responsible for the client part of the http proxy connection.
- * Arguments: vptr - the structure with all the information needed for http proxy tunnel
- */
-
-void*
-http_proxy_client(void *vptr)
-{
- char tab[9000];
- connection conn;
- header hdr;
- int j, n, maxfdp1;
- fd_set rset, allset;
- struct timeval tv;
- int timeout = 5;
- int tmp;
- char *host, *serv, *proxyname, *proxyport, *credentials, *name = "";
- char b64cred[100];
- char type, authtype, https;
- SSL_CTX* ctx;
- proxy_argT *proxy_argptr;
-
- start_critical_section();
- proxy_argptr = (proxy_argT *) vptr;
-
- host = proxy_argptr->host;
- serv = proxy_argptr->serv;
- proxyname = HttpProxyOptions_get_proxyname(proxy_argptr->hpo);
- proxyport = HttpProxyOptions_get_proxyport(proxy_argptr->hpo);
- credentials = HttpProxyOptions_get_proxyauth_cred(proxy_argptr->hpo);
- type = proxy_argptr->type;
- authtype = HttpProxyOptions_get_proxyauth_type(proxy_argptr->hpo);
- conn.sockfd = proxy_argptr->sockfd;
- https = HttpProxyOptions_is_https(proxy_argptr->hpo);
- ctx = proxy_argptr->ctx;
-
- broadcast_condition();
- end_critical_section();
-
- conn.postFd = SslFd_new();
- conn.getFd = SslFd_new();
- conn.tmpFd = SslFd_new();
- if ((conn.postFd == NULL) || (conn.getFd == NULL) || (conn.tmpFd == NULL)) {
- aflog(LOG_T_INIT, LOG_I_CRIT,
- "http%s proxy: Can't allocate memory... exiting.", name);
- exit(1);
- }
-
- if (https) {
- name = "s";
- SslFd_set_ssl(conn.postFd, SSL_new(ctx));
- SslFd_set_ssl(conn.getFd, SSL_new(ctx));
- SslFd_set_ssl(conn.tmpFd, SSL_new(ctx));
- if ((SslFd_get_ssl(conn.postFd) == NULL) ||
- (SslFd_get_ssl(conn.getFd) == NULL) ||
- (SslFd_get_ssl(conn.tmpFd) == NULL)) {
- aflog(LOG_T_INIT, LOG_I_CRIT,
- "http%s proxy: Can't allocate memory... exiting.", name);
- exit(1);
- }
- }
-
- if (authtype == PROXYAUTH_TYPE_WRONG) {
- aflog(LOG_T_MAIN, LOG_I_WARNING,
- "Wrong type of proxy authorizaton --> switching to no authorization");
- credentials = NULL;
- }
-
- if (credentials) {
- if (b64_ntop((unsigned char*)credentials, strlen(credentials), b64cred, 100) == -1) {
- aflog(LOG_T_MAIN, LOG_I_ERR,
- "Cannot encode credentials for proxy authorization");
- b64cred[0] = 0;
- }
- else {
- if (authtype == PROXYAUTH_TYPE_NOTSET) {
- authtype = PROXYAUTH_TYPE_BASIC;
- }
- }
- }
-
- FD_ZERO(&allset);
- tv.tv_usec = 0;
- tv.tv_sec = timeout;
-
- memset(conn.id, 0, 10);
- for (j = 0; j < 9; ++j) {
- conn.id[j] = myrand(65, 90);
- }
- conn.id[9] = 0;
-
- /* postfd */
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: connecting (postfd)...", name);
- if (ip_connect(&tmp, proxyname, proxyport, type, NULL, NULL)) {
- clean_return(conn.sockfd);
- }
- SslFd_set_fd(conn.postFd, tmp);
- if (https) {
- if (SSL_set_fd(SslFd_get_ssl(conn.postFd), SslFd_get_fd(conn.postFd)) != 1) {
- aflog(LOG_T_INIT, LOG_I_CRIT,
- "https proxy: Problem with initializing ssl");
- clean_return(conn.sockfd);
- }
- if (SSL_connect(SslFd_get_ssl(conn.postFd)) != 1) {
- aflog(LOG_T_INIT, LOG_I_CRIT,
- "https proxy: SSL_connect has failed");
- clean_return(conn.sockfd);
- }
- }
-
- memset(tab, 0, 9000);
- switch (authtype) {
- case PROXYAUTH_TYPE_BASIC:
- sprintf(tab,
- "POST http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
- "Host: %s:%s\r\n"
- "Content-Length: 90000\r\n"
- "Connection: close\r\n"
- "Proxy-Authorization: Basic %s\r\n\r\n", host, serv, conn.id, host, serv, b64cred);
- break;
- default:
- sprintf(tab,
- "POST http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
- "Host: %s:%s\r\n"
- "Content-Length: 90000\r\n"
- "Connection: close\r\n\r\n", host, serv, conn.id, host, serv);
- }
- j = strlen (tab);
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: writing POST request...", name);
- if (http_write(https, conn.postFd, (unsigned char*) tab, j) <= 0) {
- clean_return(conn.sockfd);
- }
-
- /* getfd */
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: connecting (getfd)...", name);
- if (ip_connect(&tmp, proxyname, proxyport, type, NULL, NULL)) {
- clean_return(conn.sockfd);
- }
- SslFd_set_fd(conn.getFd, tmp);
- if (https) {
- if (SSL_set_fd(SslFd_get_ssl(conn.getFd), SslFd_get_fd(conn.getFd)) != 1) {
- aflog(LOG_T_INIT, LOG_I_CRIT,
- "https proxy: Problem with initializing ssl");
- clean_return(conn.sockfd);
- }
- if (SSL_connect(SslFd_get_ssl(conn.getFd)) != 1) {
- aflog(LOG_T_INIT, LOG_I_CRIT,
- "https proxy: SSL_connect has failed");
- clean_return(conn.sockfd);
- }
- }
-
- memset(tab, 0, 9000);
- switch (authtype) {
- case PROXYAUTH_TYPE_BASIC:
- sprintf(tab,
- "GET http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
- "Host: %s:%s\r\n"
- "Connection: close\r\n"
- "Proxy-Authorization: Basic %s\r\n\r\n", host, serv, conn.id, host, serv, b64cred);
- break;
- default:
- sprintf(tab,
- "GET http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
- "Host: %s:%s\r\n"
- "Connection: close\r\n\r\n", host, serv, conn.id, host, serv);
- }
- j = strlen (tab);
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: writing GET request...", name);
- if (http_write(https, conn.getFd, (unsigned char*) tab, j) <= 0) {
- clean_return(conn.sockfd);
- }
-
- set_fd(conn.sockfd, &maxfdp1, &allset);
- set_fd(SslFd_get_fd(conn.postFd), &maxfdp1, &allset);
- set_fd(SslFd_get_fd(conn.getFd), &maxfdp1, &allset);
- conn.state = C_OPEN;
-
- memset(tab, 0, 9000);
-
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: parsing header from getfd", name);
- if (parse_header(conn.getFd, tab, &hdr, https)) {
- clean_return(conn.sockfd);
- }
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: checking hdr.type", name);
- if (hdr.type != H_TYPE_OK) {
- clean_return(conn.sockfd);
- }
- if (hdr.length) {
- conn.received += hdr.length;
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: reading message...", name);
- if (read_message(conn.sockfd, hdr.length, &conn, tab, hdr.ptr)) {
- clean_return(conn.sockfd);
- }
- }
-
- while (1) {
- if ((conn.state == C_OPEN) && (!(FD_ISSET(conn.sockfd, &allset)))) {
- FD_SET(conn.sockfd, &allset);
- }
- rset = allset;
-
- if (select(maxfdp1, &rset, NULL, NULL, &tv) == 0) {
- aflog(LOG_T_MAIN, LOG_I_DDEBUG,
- "http%s proxy: timeout", name);
- tv.tv_sec = timeout;
- if (conn.sent_ptr+1 >= 90000) {
- if (conn.state == C_CLOSED) {
- continue;
- }
- aflog(LOG_T_MAIN, LOG_I_DDEBUG,
- "http%s proxy: send T", name);
- http_write(https, conn.postFd, (unsigned char*) "T", 1);
- conn.sent_ptr = 0;
- clear_sslFd(conn.postFd, &allset);
- /* postfd */
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: connecting (postfd)...", name);
- if (ip_connect(&tmp, proxyname, proxyport, type, NULL, NULL)) {
- clean_return(conn.sockfd);
- }
- SslFd_set_fd(conn.postFd, tmp);
- if (https) {
- if (SSL_set_fd(SslFd_get_ssl(conn.postFd), SslFd_get_fd(conn.postFd)) != 1) {
- aflog(LOG_T_INIT, LOG_I_CRIT,
- "https proxy: Problem with initializing ssl");
- clean_return(conn.sockfd);
- }
- if (SSL_connect(SslFd_get_ssl(conn.postFd)) != 1) {
- aflog(LOG_T_INIT, LOG_I_CRIT,
- "https proxy: SSL_connect has failed");
- clean_return(conn.sockfd);
- }
- }
-
- memset(tab, 0, 9000);
- switch (authtype) {
- case PROXYAUTH_TYPE_BASIC:
- sprintf(tab,
- "POST http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
- "Host: %s:%s\r\n"
- "Content-Length: 90000\r\n"
- "Connection: close\r\n"
- "Proxy-Authorization: Basic %s\r\n\r\n", host, serv, conn.id, host, serv, b64cred);
- break;
- default:
- sprintf(tab,
- "POST http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
- "Host: %s:%s\r\n"
- "Content-Length: 90000\r\n"
- "Connection: close\r\n\r\n", host, serv, conn.id, host, serv);
- }
- j = strlen (tab);
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: writing POST request...", name);
- if (http_write(https, conn.postFd, (unsigned char *) tab, j) <= 0) {
- clean_return(conn.sockfd);
- }
- conn.sent_ptr = 0;
- conn.ptr = 0;
- conn.length = 0;
- conn.state = C_CLOSED;
-
- set_fd(SslFd_get_fd(conn.postFd), &maxfdp1, &allset);
- }
- else {
- aflog(LOG_T_MAIN, LOG_I_DDEBUG,
- "http%s proxy: send T", name);
- http_write(https, conn.postFd, (unsigned char *) "T", 1);
- conn.sent_ptr += 1;
- }
- continue;
- }
-
- /* sockfd */
- if (FD_ISSET(conn.sockfd, &rset)) {
- aflog(LOG_T_MAIN, LOG_I_DDEBUG,
- "http%s proxy: FD_ISSET(conn.sockfd)", name);
- n = read(conn.sockfd, conn.buf+5, 8995);
- if (n <= 0) {
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: send Q", name);
- http_write(https, conn.postFd, (unsigned char *) "Q", 1);
- clean_return(conn.sockfd);
- }
- if ((conn.state == C_CLOSED) && (conn.sent_ptr > 70000)) {
- FD_CLR(conn.sockfd, &allset);
- }
- conn.buf[0] = 'M';
- tmp = htonl(n);
- memcpy(&conn.buf[1], &tmp, 4);
- if (conn.sent_ptr+5 + n >= 90000) {
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: send message", name);
- http_write(https, conn.postFd, (unsigned char *) conn.buf, 90000 - conn.sent_ptr);
- conn.ptr = 90000 - conn.sent_ptr;
- conn.length = 5+n - conn.ptr;
- conn.sent_ptr = 0;
- clear_sslFd(conn.postFd, &allset);
-
- /* postfd */
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: connecting (postfd)...", name);
- if (ip_connect(&tmp, proxyname, proxyport, type, NULL, NULL)) {
- clean_return(conn.sockfd);
- }
- SslFd_set_fd(conn.postFd, tmp);
- if (https) {
- if (SSL_set_fd(SslFd_get_ssl(conn.postFd), SslFd_get_fd(conn.postFd)) != 1) {
- aflog(LOG_T_INIT, LOG_I_CRIT,
- "https proxy: Problem with initializing ssl");
- clean_return(conn.sockfd);
- }
- if (SSL_connect(SslFd_get_ssl(conn.postFd)) != 1) {
- aflog(LOG_T_INIT, LOG_I_CRIT,
- "https proxy: SSL_connect has failed");
- clean_return(conn.sockfd);
- }
- }
-
- memset(tab, 0, 9000);
- switch (authtype) {
- case PROXYAUTH_TYPE_BASIC:
- sprintf(tab,
- "POST http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
- "Host: %s:%s\r\n"
- "Content-Length: 90000\r\n"
- "Connection: close\r\n"
- "Proxy-Authorization: Basic %s\r\n\r\n", host, serv, conn.id, host, serv, b64cred);
- break;
- default:
- sprintf(tab,
- "POST http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
- "Host: %s:%s\r\n"
- "Content-Length: 90000\r\n"
- "Connection: close\r\n\r\n", host, serv, conn.id, host, serv);
- }
- j = strlen (tab);
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: writing POST request...", name);
- if (http_write(https, conn.postFd, (unsigned char *) tab, j) <= 0) {
- clean_return(conn.sockfd);
- }
- if (conn.length > 0) {
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: writing old data...", name);
- if (http_write(https, conn.postFd, (unsigned char *) (conn.buf+conn.ptr), conn.length) <= 0) {
- clean_return(conn.sockfd);
- }
- }
- conn.sent_ptr = conn.length;
- conn.ptr = 0;
- conn.length = 0;
- conn.state = C_CLOSED;
-
- set_fd(SslFd_get_fd(conn.postFd), &maxfdp1, &allset);
- }
- else {
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: send message", name);
- http_write(https, conn.postFd, (unsigned char *) conn.buf, 5+n);
- conn.sent_ptr += 5+n;
- }
- }
-
- /* getfd */
- if (FD_ISSET(SslFd_get_fd(conn.getFd), &rset)) {
- aflog(LOG_T_MAIN, LOG_I_DDEBUG,
- "http%s proxy: FD_ISSET(conn.getfd)", name);
- n = http_read(https, conn.getFd, (unsigned char*) tab, 9000);
- conn.received += n;
- if (n == 0) {
- conn.received = 0;
- clear_sslFd(conn.getFd, &allset);
-
- /* getfd */
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: connecting (getfd)...", name);
- if (ip_connect(&tmp, proxyname, proxyport, type, NULL, NULL)) {
- clean_return(conn.sockfd);
- }
- SslFd_set_fd(conn.getFd, tmp);
- if (https) {
- if (SSL_set_fd(SslFd_get_ssl(conn.getFd), SslFd_get_fd(conn.getFd)) != 1) {
- aflog(LOG_T_INIT, LOG_I_CRIT,
- "https proxy: Problem with initializing ssl");
- clean_return(conn.sockfd);
- }
- if (SSL_connect(SslFd_get_ssl(conn.getFd)) != 1) {
- aflog(LOG_T_INIT, LOG_I_CRIT,
- "https proxy: SSL_connect has failed");
- clean_return(conn.sockfd);
- }
- }
-
- memset(tab, 0, 9000);
- switch (authtype) {
- case PROXYAUTH_TYPE_BASIC:
- sprintf(tab,
- "GET http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
- "Host: %s:%s\r\n"
- "Connection: close\r\n"
- "Proxy-Authorization: Basic %s\r\n\r\n", host, serv, conn.id, host, serv, b64cred);
- break;
- default:
- sprintf(tab,
- "GET http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
- "Host: %s:%s\r\n"
- "Connection: close\r\n\r\n", host, serv, conn.id, host, serv);
- }
- j = strlen (tab);
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: writing GET request...", name);
- if (http_write(https, conn.getFd, (unsigned char *) tab, j) <= 0) {
- clean_return(conn.sockfd);
- }
- memset(tab, 0, 9000);
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: parsing header from getfd", name);
- if (parse_header(conn.getFd, tab, &hdr, https)) {
- clean_return(conn.sockfd);
- }
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: checking hdr.type", name);
- if (hdr.type != H_TYPE_OK) {
- clean_return(conn.sockfd);
- }
-
- set_fd(SslFd_get_fd(conn.getFd), &maxfdp1, &allset);
- if (hdr.length) {
- conn.received += hdr.length;
- aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http%s proxy: reading message...", name);
- if (read_message(conn.sockfd, hdr.length, &conn, tab, hdr.ptr)) {
- clean_return(conn.sockfd);
- }
- }
- }
- else {
- if (read_message(conn.sockfd, n, &conn, tab, 0)) {
- clean_return(conn.sockfd);
- }
- }
- }
-
- /* postfd */
- if (FD_ISSET(SslFd_get_fd(conn.postFd), &rset)) {
- aflog(LOG_T_MAIN, LOG_I_DDEBUG,
- "http%s proxy: FD_ISSET(conn.postfd) --> clean_return", name);
- clear_sslFd(conn.postFd, &allset);
- clean_return(conn.sockfd);
- }
- }
- clean_return(conn.sockfd);
-}
-
-/*
- * Function name: initialize_http_proxy_client
- * Description: Initializes the thread responsible for http proxy connection.
- * Arguments: sockfd - the new connection descriptor will be stored here
- * cr - the pointer to ClientRealm structure
- * ctx - the pointer to SSL_CTX structure
- * Returns: 0 - success,
- * !0 - failure.
- */
-
-int
-initialize_http_proxy_client(int* sockfd, ClientRealm* cr, SSL_CTX* ctx)
-{
- int retval;
- int sockets[2];
- pthread_t proxy_thread;
- static proxy_argT arg;
-
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets)) {
- return 1;
- }
- (*sockfd) = sockets[0];
-
- if (HttpProxyOptions_get_proxyname(ClientRealm_get_httpProxyOptions(cr)) == NULL) {
- return 1;
- }
-
- start_critical_section();
-
- arg.host = ClientRealm_get_serverName(cr);
- arg.serv = ClientRealm_get_managePort(cr);
- arg.hpo = ClientRealm_get_httpProxyOptions(cr);
- arg.type = ClientRealm_get_ipFamily(cr);
- arg.sockfd = sockets[1];
- arg.ctx = ctx;
-
- retval = pthread_create(&proxy_thread, NULL, &http_proxy_client, &arg);
-
- wait_for_condition();
-
- end_critical_section();
-
- return retval;
-}
-
-#endif