summaryrefslogtreecommitdiff
path: root/src/http_proxy_server.c
diff options
context:
space:
mode:
authorJakub Sławiński2005-08-05 21:45:31 +0200
committerJoshua Judson Rosen2014-07-17 21:14:59 +0200
commit43e8714797d40bcf63efab428dcd25f9caf1d52b (patch)
tree796974a873a97f2a44f872f3dd3587508e35aa64 /src/http_proxy_server.c
parentv0.7.1 (diff)
downloadapf-43e8714797d40bcf63efab428dcd25f9caf1d52b.tar.gz
v0.7.2
- Added: http proxy basic authorization - Fixed: logging initialization after some value checking - Fixed: auto-reconnect failure when --nossl option is set - Added: auto-reconnect when afserver is not reachable on start - Added: auto-reconnect after normal afserver quit - Added: per user statistics: idle time, amount of downloaded/uploaded bytes and current download/upload rate - Added: support for https proxies - Added: possibility to bind sockets on different interfaces - Fixed: receiving incomplete headers from afclient - Fixed: close user connections by afclient
Diffstat (limited to 'src/http_proxy_server.c')
-rw-r--r--src/http_proxy_server.c201
1 files changed, 132 insertions, 69 deletions
diff --git a/src/http_proxy_server.c b/src/http_proxy_server.c
index f98026c..45db302 100644
--- a/src/http_proxy_server.c
+++ b/src/http_proxy_server.c
@@ -20,6 +20,7 @@
#include <config.h>
+#include "make_ssl_handshake.h"
#include "http_proxy_server.h"
#include "thread_management.h"
#include "stats.h"
@@ -35,6 +36,8 @@ typedef struct {
socklen_t *addrlenp;
char type;
int limit;
+ char https;
+ SSL_CTX* ctx;
} sproxy_argT;
int
@@ -63,7 +66,8 @@ afserver_connect(int* sockfd, int afserverfd, struct sockaddr* cliaddr, socklen_
void*
http_proxy_server(void *vptr)
{
- int listenfd, connfd, afserverfd;
+ int listenfd, afserverfd;
+ SslFd* connFd;
struct sockaddr* cliaddr;
char tab[9000];
connection* table;
@@ -74,8 +78,9 @@ http_proxy_server(void *vptr)
int maxclients, tmp;
int timeout = 5;
socklen_t *addrlenp;
- char type, nothttp;
- char *host, *serv;
+ char type, nothttp, https;
+ char *host, *serv, *name = "";
+ SSL_CTX* ctx;
sproxy_argT *proxy_argptr;
start_critical_section();
@@ -87,20 +92,62 @@ http_proxy_server(void *vptr)
addrlenp = proxy_argptr->addrlenp;
type = proxy_argptr->type;
maxclients = proxy_argptr->limit+1;
+ https = proxy_argptr->https;
+ ctx = proxy_argptr->ctx;
broadcast_condition();
end_critical_section();
+ if (https) {
+ name = "s";
+ }
+
table = calloc(maxclients, sizeof(connection));
if (table == NULL) {
aflog(LOG_T_INIT, LOG_I_CRIT,
- "http proxy: Can't allocate memory... exiting.");
+ "http%s proxy: Can't allocate memory... exiting.", name);
exit(1);
}
+ for (i = 0; i < maxclients; ++i) {
+ table[i].postFd = SslFd_new();
+ table[i].getFd = SslFd_new();
+ table[i].tmpFd = SslFd_new();
+ if ((table[i].postFd == NULL) || (table[i].getFd == NULL) || (table[i].tmpFd == NULL)) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http%s proxy: Can't allocate memory... exiting.", name);
+ exit(1);
+ }
+ if (https) {
+ SslFd_set_ssl(table[i].postFd, SSL_new(ctx));
+ SslFd_set_ssl(table[i].getFd, SSL_new(ctx));
+ SslFd_set_ssl(table[i].tmpFd, SSL_new(ctx));
+ if ((SslFd_get_ssl(table[i].postFd) == NULL) ||
+ (SslFd_get_ssl(table[i].getFd) == NULL) ||
+ (SslFd_get_ssl(table[i].tmpFd) == NULL)) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http%s proxy: Can't allocate memory... exiting.", name);
+ exit(1);
+ }
+ }
+ }
+ connFd = SslFd_new();
+ if (connFd == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http%s proxy: Can't allocate memory... exiting.", name);
+ exit(1);
+ }
+ if (https) {
+ SslFd_set_ssl(connFd, SSL_new(ctx));
+ if (SslFd_get_ssl(connFd) == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http%s proxy: Can't allocate memory... exiting.", name);
+ exit(1);
+ }
+ }
if (ip_listen(&listenfd, host, serv, addrlenp, type)) {
aflog(LOG_T_INIT, LOG_I_CRIT,
- "http proxy: Can't listen on %s:%s", host, serv);
+ "http%s proxy: Can't listen on %s:%s", name, host, serv);
exit(1);
}
cliaddr = malloc(*addrlenp);
@@ -116,23 +163,23 @@ http_proxy_server(void *vptr)
if (select(maxfdp1, &rset, NULL, NULL, &tv) == 0) {
aflog(LOG_T_MAIN, LOG_I_DDEBUG,
- "http proxy: timeout");
+ "http%s proxy: timeout", name);
tv.tv_sec = timeout;
for (i = 0; i < maxclients; ++i) {
if ((table[i].state == C_CLOSED) || (table[i].state & C_GET_WAIT) || (table[i].type == 1)) {
continue;
}
aflog(LOG_T_MAIN, LOG_I_DDEBUG,
- "http proxy: send T to table[%d].getfd", i);
+ "http%s proxy: send T to table[%d].getfd", name, i);
if (table[i].sent_ptr+1 >= 90000) {
- writen(table[i].getfd, (unsigned char*) "T", 1);
+ http_write(https, table[i].getFd, (unsigned char*) "T", 1);
table[i].sent_ptr = 0;
- clear_fd(&table[i].getfd, &allset);
+ clear_sslFd(table[i].getFd, &allset);
FD_CLR(table[i].sockfd, &allset);
table[i].state |= C_GET_WAIT;
}
else {
- writen(table[i].getfd, (unsigned char*) "T", 1);
+ http_write(https, table[i].getFd, (unsigned char*) "T", 1);
table[i].sent_ptr += 1;
}
}
@@ -148,10 +195,10 @@ http_proxy_server(void *vptr)
/* sockfd */
if ((!(table[i].state & C_GET_WAIT)) && (FD_ISSET(table[i].sockfd, &rset))) {
aflog(LOG_T_MAIN, LOG_I_DDEBUG,
- "http proxy: FD_ISSET(table[%d].sockfd)", i);
+ "http%s proxy: FD_ISSET(table[%d].sockfd)", name, i);
n = read(table[i].sockfd, table[i].buf+5, 8995);
if (n <= 0) {
- writen(table[i].getfd, (unsigned char*) "Q", 1);
+ http_write(https, table[i].getFd, (unsigned char*) "Q", 1);
delete_user(table, i, &allset);
continue;
}
@@ -159,34 +206,34 @@ http_proxy_server(void *vptr)
tmp = htonl(n);
memcpy(&table[i].buf[1], &tmp, 4);
if (table[i].sent_ptr+5 + n >= 90000) {
- writen(table[i].getfd, (unsigned char*) table[i].buf, 90000 - table[i].sent_ptr);
+ http_write(https, table[i].getFd, (unsigned char*) table[i].buf, 90000 - table[i].sent_ptr);
table[i].ptr = 90000 - table[i].sent_ptr;
table[i].length = 5+n - table[i].ptr;
table[i].sent_ptr = 0;
- clear_fd(&table[i].getfd, &allset);
+ clear_sslFd(table[i].getFd, &allset);
FD_CLR(table[i].sockfd, &allset);
table[i].state |= C_GET_WAIT;
continue;
}
else {
- writen(table[i].getfd, (unsigned char*) table[i].buf, n+5);
+ http_write(https, table[i].getFd, (unsigned char*) table[i].buf, n+5);
table[i].sent_ptr += n+5;
}
}
/* getfd */
- if (FD_ISSET(table[i].getfd, &rset)) {
+ if (FD_ISSET(SslFd_get_fd(table[i].getFd), &rset)) {
aflog(LOG_T_MAIN, LOG_I_DDEBUG,
- "http proxy: FD_ISSET(table[%d].getfd)", i);
+ "http%s proxy: FD_ISSET(table[%d].getfd)", name, i);
delete_user(table, i, &allset);
continue;
}
/* postfd */
- if (FD_ISSET(table[i].postfd, &rset)) {
+ if (FD_ISSET(SslFd_get_fd(table[i].postFd), &rset)) {
aflog(LOG_T_MAIN, LOG_I_DDEBUG,
- "http proxy: FD_ISSET(table[%d].postfd)", i);
- n = read(table[i].postfd, tab, 9000);
+ "http%s proxy: FD_ISSET(table[%d].postfd)", name, i);
+ n = http_read(https, table[i].postFd, (unsigned char*) tab, 9000);
if (n != 0) {
table[i].received += n;
if (read_message(table[i].sockfd, n, &table[i], tab, 0)) {
@@ -195,14 +242,14 @@ http_proxy_server(void *vptr)
}
if ((n == 0) || (table[i].received == 90000)) {
table[i].received = 0;
- clear_fd(&table[i].postfd, &allset);
+ clear_sslFd(table[i].postFd, &allset);
table[i].state |= C_POST_WAIT;
if (table[i].tmpstate == 1) {
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: get old POST request...");
+ "http%s proxy: get old POST request...", name);
table[i].state &= ~C_POST_WAIT;
- table[i].postfd = table[i].tmpfd;
- set_fd(table[i].postfd, &maxfdp1, &allset);
+ SslFd_swap_content(table[i].postFd, table[i].tmpFd);
+ set_fd(SslFd_get_fd(table[i].postFd), &maxfdp1, &allset);
table[i].tmpstate = 0;
if (table[i].tmpheader.length) {
table[i].received += table[i].tmpheader.length;
@@ -224,7 +271,7 @@ http_proxy_server(void *vptr)
if (FD_ISSET(table[i].sockfd, &rset)) {
n = read(table[i].sockfd, table[i].buf, 9000);
if (n > 0) {
- write(table[i].postfd, table[i].buf, n);
+ writen(SslFd_get_fd(table[i].postFd), (unsigned char*) table[i].buf, n);
}
else {
delete_user(table, i, &allset);
@@ -232,10 +279,10 @@ http_proxy_server(void *vptr)
}
}
- if (FD_ISSET(table[i].postfd, &rset)) {
- n = read(table[i].postfd, tab, 9000);
+ if (FD_ISSET(SslFd_get_fd(table[i].postFd), &rset)) {
+ n = read(SslFd_get_fd(table[i].postFd), tab, 9000);
if (n > 0) {
- write(table[i].sockfd, tab, n);
+ writen(table[i].sockfd, (unsigned char*) tab, n);
}
else {
delete_user(table, i, &allset);
@@ -249,23 +296,34 @@ http_proxy_server(void *vptr)
/* listen */
if (FD_ISSET(listenfd, &rset)) {
aflog(LOG_T_MAIN, LOG_I_DDEBUG,
- "http proxy: FD_ISSET(listenfd)");
- connfd = accept(listenfd, cliaddr, addrlenp);
- if (connfd != -1) {
+ "http%s proxy: FD_ISSET(listenfd)", name);
+ tmp = accept(listenfd, cliaddr, addrlenp);
+ if (tmp != -1) {
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: New connection...");
+ "http%s proxy: New connection...", name);
+ SslFd_set_fd(connFd, tmp);
+ if (https) {
+ make_ssl_initialize(connFd);
+ if (make_ssl_accept(connFd)) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "https proxy: DENIED by SSL_accept");
+ close(SslFd_get_fd(connFd));
+ SSL_clear(SslFd_get_ssl(connFd));
+ continue;
+ }
+ }
}
else {
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: New connection --> EAGAIN");
+ "http%s proxy: New connection --> EAGAIN", name);
continue;
}
memset(tab, 0, 9000);
nothttp = 0;
- if (parse_header(connfd, tab, &hdr)) {
+ if (parse_header(connFd, tab, &hdr, https)) {
nothttp = 1;
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: no http header...");
+ "http%s proxy: no http header...", name);
}
n = -1;
for (i = 0; i < maxclients; ++i) {
@@ -281,40 +339,41 @@ http_proxy_server(void *vptr)
}
if (i < maxclients) { /* the client exists */
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: the client exist...");
+ "http%s proxy: the client exist...", name);
if (hdr.type == H_TYPE_GET) {
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: type GET...");
+ "http%s proxy: type GET...", name);
if (!(table[i].state & C_GET_WAIT)) {
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: not waiting for GET...");
+ "http%s proxy: not waiting for GET...", name);
table[i].sent_ptr = 0;
FD_CLR(table[i].sockfd, &allset);
- clear_fd(&table[i].getfd, &allset);
+ clear_sslFd(table[i].getFd, &allset);
table[i].state |= C_GET_WAIT;
}
if (!(table[i].state & C_OPEN)) {
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: not opened...");
+ "http%s proxy: not opened...", name);
if (afserver_connect(&table[i].sockfd, afserverfd, cliaddr, addrlenp, 1)) {
memset(tab, 0, 9000);
sprintf(tab,"HTTP/1.1 400 Bad Request\r\n\r\n");
n = strlen (tab);
- write(connfd, tab, n);
- close_fd(&connfd);
- clear_fd(&table[i].postfd, &allset);
+ http_write(https, connFd, (unsigned char*) tab, n);
+ close_fd((&(connFd->fd)));
+ SSL_clear(SslFd_get_ssl(connFd));
+ clear_sslFd(table[i].postFd, &allset);
table[i].state = C_CLOSED;
continue;
}
table[i].state |= C_OPEN;
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: OPEN...");
+ "http%s proxy: OPEN...", name);
}
table[i].state &= ~C_GET_WAIT;
table[i].sent_ptr = 0;
- table[i].getfd = connfd;
+ SslFd_swap_content(table[i].getFd, connFd);
set_fd(table[i].sockfd, &maxfdp1, &allset);
- set_fd(table[i].getfd, &maxfdp1, &allset);
+ set_fd(SslFd_get_fd(table[i].getFd), &maxfdp1, &allset);
memset(tab, 0, 9000);
sprintf(tab,
"HTTP/1.1 200 OK\r\n"
@@ -325,12 +384,13 @@ http_proxy_server(void *vptr)
"Expires: 0\r\n"
"Content-Type: text/html\r\n\r\n");
n = strlen(tab);
- if (writen(table[i].getfd, (unsigned char*) tab, n) <= 0) {
+ if (writen(SslFd_get_fd(table[i].getFd), (unsigned char*) tab, n) <= 0) {
delete_user(table, i, &allset);
continue;
}
if (table[i].length) {
- if (writen(table[i].getfd, (unsigned char*) (table[i].buf+table[i].ptr), table[i].length) <= 0) {
+ if (writen(SslFd_get_fd(table[i].getFd),
+ (unsigned char*) (table[i].buf+table[i].ptr), table[i].length) <= 0) {
delete_user(table, i, &allset);
continue;
}
@@ -341,21 +401,21 @@ http_proxy_server(void *vptr)
}
else if (hdr.type == H_TYPE_POST) {
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: type POST...");
+ "http%s proxy: type POST...", name);
if (!(table[i].state & C_POST_WAIT)) {
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: unexpected POST request...");
+ "http%s proxy: unexpected POST request...", name);
if (table[i].tmpstate == 0) {
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: buffering POST request...");
+ "http%s proxy: buffering POST request...", name);
table[i].tmpstate = 1;
- table[i].tmpfd = connfd;
+ SslFd_swap_content(table[i].tmpFd, connFd);
memcpy(table[i].tmpbuf, tab, 9000);
table[i].tmpheader = hdr;
}
else {
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: no space to buffer POST request (received from first postfd: %d)",
+ "http%s proxy: no space to buffer POST request (received from first postfd: %d)", name,
table[i].received);
delete_user(table, i, &allset);
}
@@ -368,44 +428,45 @@ http_proxy_server(void *vptr)
}
}
table[i].state &= ~C_POST_WAIT;
- table[i].postfd = connfd;
- set_fd(table[i].postfd, &maxfdp1, &allset);
+ SslFd_swap_content(table[i].postFd, connFd);
+ set_fd(SslFd_get_fd(table[i].postFd), &maxfdp1, &allset);
}
}
else {
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: unrecognized type...");
+ "http%s proxy: unrecognized type...", name);
delete_user(table, i, &allset);
}
}
else if (n != -1) { /* there are free slots */
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: there are free slots...");
+ "http%s proxy: there are free slots...", name);
if (!nothttp) {
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: http header...");
+ "http%s proxy: http header...", name);
if (hdr.type == H_TYPE_POST) { /* POST request must be first */
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: type POST...");
+ "http%s proxy: type POST...", name);
table[n].state = C_GET_WAIT;
memcpy(table[n].id,hdr.id, 9);
- table[n].postfd = connfd;
- set_fd(table[n].postfd, &maxfdp1, &allset);
+ SslFd_swap_content(table[n].postFd, connFd);
+ set_fd(SslFd_get_fd(table[n].postFd), &maxfdp1, &allset);
}
else {
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: closing this connection...");
- close_fd(&connfd);
+ "http%s proxy: closing this connection...", name);
+ close_fd((&(connFd->fd)));
+ SSL_clear(SslFd_get_ssl(connFd));
continue;
}
}
else {
table[n].state = C_OPEN;
- table[n].postfd = connfd;
+ SslFd_set_fd(table[n].postFd, SslFd_get_fd(connFd));
table[n].type = 1;
- set_fd(table[n].postfd, &maxfdp1, &allset);
+ set_fd(SslFd_get_fd(table[n].postFd), &maxfdp1, &allset);
if (afserver_connect(&table[n].sockfd, afserverfd, cliaddr, addrlenp, 0)) {
- clear_fd(&table[n].postfd, &allset);
+ clear_sslFd(table[n].postFd, &allset);
table[n].state = C_CLOSED;
continue;
}
@@ -415,8 +476,8 @@ http_proxy_server(void *vptr)
}
else {
aflog(LOG_T_MAIN, LOG_I_DEBUG,
- "http proxy: closing this connection...");
- close_fd(&connfd);
+ "http%s proxy: closing this connection...", name);
+ close_fd((&(connFd->fd)));
continue;
}
}
@@ -427,7 +488,7 @@ http_proxy_server(void *vptr)
int
-initialize_http_proxy_server(int* sockfd, const char *host, const char *serv, socklen_t *addrlenp, const char type, int limit)
+initialize_http_proxy_server(int* sockfd, const char *host, const char *serv, socklen_t *addrlenp, const char type, int limit, char https, SSL_CTX* ctx)
{
int retval;
int sockets[2];
@@ -447,6 +508,8 @@ initialize_http_proxy_server(int* sockfd, const char *host, const char *serv, so
arg.limit = limit;
arg.type = (char) type;
arg.sockfd = sockets[1];
+ arg.https = https;
+ arg.ctx = ctx;
retval = pthread_create(&proxy_thread, NULL, &http_proxy_server, &arg);