summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Sławiński2005-06-07 12:06:18 +0200
committerJoshua Judson Rosen2014-07-17 21:14:58 +0200
commit32aff2b27ccc3b3e51fb6f0bd77fe0073827c527 (patch)
treef2fc2530a6960f6fdf4d63eb80c4f61342250bbd /src
parentv0.6 (diff)
downloadapf-32aff2b27ccc3b3e51fb6f0bd77fe0073827c527.tar.gz
v0.7
- Added: http proxy tunnels between afserver and afclient - Fixed: sigint interception with threads enabled (in http proxy mode) - Fixed: FATAL ERROR in afclient in some situations after close of afserver when http proxy mode is enabled - Added: afclients can connect directly to afserver with enabled proxy mode - Fixed: timeout routine in http proxy tunnels - Added: 'rshow' command in ra mode displays 'tunneltype' - Fixed: printing IP of clients when http proxy mode is enabled - Added: 'tunneltype' per client in ra mode after 'cshow' command - Fixed: closing connection when http proxy mode is enabled - Fixed: threads initialization - Fixed: afserver closing after sigint - Fixed: afclient threads initialization - Added: 'version' option to display program version number - Modified: establishing afclient<->afserver connection - Added: 'keep-alive' option - Fixed: using 'proxyport' without 'proxyname' - Added: auto-reconnect feature to afclient - Added: 'ar-tries' and 'ar-delay' options - Modified: http proxy logging - Fixed: closing connection with afclient after receiving id - Fixed: thread closing due to wrong initialization sequence - Fixed: small bug in initialization process - Heavily Modified: logging routines - Added: audit option - Modified: default dateformat is now ISO 8601 - Modified: printing usage - Fixed: bug in threads' initialization in afclient - Added: 'timeout' and 'dateformat' options in ra mode - Modified: empty dateformat disables printing '[] ' - Added: 'audit' and 'dnslookups' options in ra mode - Fixed: afserver freeze bug - Added: 'kuser' and 'kclient' options in ra mode - Fixed: bug in starting afclient in ra mode - Added: audit log printed also after kicking the client
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am12
-rw-r--r--src/activefor.h13
-rw-r--r--src/afclient.c672
-rw-r--r--src/afclient.h14
-rw-r--r--src/afserver.c841
-rw-r--r--src/afserver.h9
-rw-r--r--src/audit.c69
-rw-r--r--src/audit.h39
-rw-r--r--src/buflist.c2
-rw-r--r--src/client_initialization.c212
-rw-r--r--src/client_initialization.h40
-rw-r--r--src/client_reverse_udp.c183
-rw-r--r--src/client_reverse_udp.h40
-rw-r--r--src/client_shutdown.c48
-rw-r--r--src/client_shutdown.h31
-rw-r--r--src/client_signals.c42
-rw-r--r--src/client_signals.h27
-rw-r--r--src/clientnames.c3
-rw-r--r--src/file.c59
-rw-r--r--src/http_proxy_client.c380
-rw-r--r--src/http_proxy_client.h27
-rw-r--r--src/http_proxy_functions.c267
-rw-r--r--src/http_proxy_functions.h80
-rw-r--r--src/http_proxy_server.c459
-rw-r--r--src/http_proxy_server.h29
-rw-r--r--src/logging.c391
-rw-r--r--src/logging.h78
-rw-r--r--src/make_ssl_handshake.c40
-rw-r--r--src/network.c7
-rw-r--r--src/network.h2
-rw-r--r--src/realmnames.c2
-rw-r--r--src/remoteadmin.c375
-rw-r--r--src/remoteadmin.h1
-rw-r--r--src/server_check.c29
-rw-r--r--src/server_check.h1
-rw-r--r--src/server_eval.c2
-rw-r--r--src/server_find.c2
-rw-r--r--src/server_get.c55
-rw-r--r--src/server_get.h31
-rw-r--r--src/server_signals.c66
-rw-r--r--src/server_signals.h27
-rw-r--r--src/stats.c96
-rw-r--r--src/stats.h10
-rw-r--r--src/thread_management.c70
-rw-r--r--src/thread_management.h34
-rw-r--r--src/usage.c168
-rw-r--r--src/usage.h30
-rw-r--r--src/usernames.c2
48 files changed, 4232 insertions, 885 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index a6ccd11..282b514 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,13 @@
bin_PROGRAMS = afserver afclient
+afserver_LDFLAGS = ${LINKED_PTHREADLIB}
afserver_SOURCES = afserver.c network.c file.c stats.c buflist.c remoteadmin.c \
server_check.c server_set.c server_eval.c server_find.c server_remove.c \
- make_ssl_handshake.c first_run.c inet_ntop.c realmnames.c clientnames.c usernames.c
-afclient_LDFLAGS = ${USE_RDYNAMIC} ${LINKED_LDLIB}
+ make_ssl_handshake.c first_run.c inet_ntop.c realmnames.c clientnames.c usernames.c \
+ http_proxy_functions.c http_proxy_server.c server_get.c thread_management.c \
+ server_signals.c usage.c logging.c audit.c
+afclient_LDFLAGS = ${USE_RDYNAMIC} ${LINKED_LDLIB} ${LINKED_PTHREADLIB}
afclient_SOURCES = afclient.c network.c stats.c buflist.c modules.c remoteadmin.c \
- make_ssl_handshake.c first_run.c inet_ntop.c realmnames.c clientnames.c usernames.c
+ make_ssl_handshake.c first_run.c inet_ntop.c realmnames.c clientnames.c usernames.c \
+ http_proxy_functions.c http_proxy_client.c thread_management.c \
+ client_reverse_udp.c server_check.c client_initialization.c client_shutdown.c \
+ client_signals.c usage.c logging.c audit.c
diff --git a/src/activefor.h b/src/activefor.h
index 8d07c8b..76564cb 100644
--- a/src/activefor.h
+++ b/src/activefor.h
@@ -23,6 +23,7 @@
#include "network.h"
#include "buflist.h"
+#include "audit.h"
#define AF_S_CONCLOSED 1
#define AF_S_CONOPEN 2
@@ -37,13 +38,15 @@
#define AF_S_ADMIN_LOGIN 14
#define AF_S_ADMIN_CMD 15
+#define AF_S_KEEP_ALIVE 16
+
#define S_STATE_CLEAR 0
#define S_STATE_CLOSING 5
#define S_STATE_OPENING 6
#define S_STATE_OPEN 7
#define S_STATE_STOPPED 11
-#define AF_VER(info) info" v0.6"
+#define AF_VER(info) info" v0.7"
#define TYPE_TCP 1
#define TYPE_UDP 3
@@ -110,6 +113,8 @@ typedef struct {
char* clientid;
char namebuf[128];
char portbuf[7];
+ char tunneltype;
+ alnodeT* head;
} ConnectclientT;
typedef struct {
@@ -135,8 +140,10 @@ typedef struct {
int clientcounter;
int usercounter;
char type;
+ char tunneltype;
char dnslookups;
char baseport;
+ char audit;
socklen_t addrlen;
struct sockaddr* cliaddr;
ConnectuserT* contable;
@@ -148,11 +155,7 @@ typedef struct {
typedef struct {
char* certif;
char* keys;
- char* logfnam;
- char* logsport;
char* dateformat;
- char logging;
- char socklogging;
int size;
time_t starttime;
RealmT* realmtable;
diff --git a/src/afclient.c b/src/afclient.c
index cc3c0c8..72f1f9c 100644
--- a/src/afclient.c
+++ b/src/afclient.c
@@ -32,10 +32,7 @@ static struct option long_options[] = {
{"portnum", 1, 0, 'p'},
{"verbose", 0, 0, 'v'},
{"keyfile", 1, 0, 'k'},
- {"heavylog", 1, 0, 'O'},
- {"lightlog", 1, 0, 'o'},
- {"heavysocklog", 1, 0, 'S'},
- {"lightsocklog", 1, 0, 's'},
+ {"log", 1, 0, 'o'},
{"pass", 1, 0, 301},
#ifdef AF_INET6
{"ipv4", 0, 0, '4'},
@@ -48,6 +45,14 @@ static struct option long_options[] = {
{"id", 1, 0, 'i'},
{"dateformat", 1, 0, 'D'},
{"remoteadmin", 0, 0, 'r'},
+#ifdef HAVE_LIBPTHREAD
+ {"proxyname", 1, 0, 'P'},
+ {"proxyport", 1, 0, 'X'},
+#endif
+ {"version", 0, 0, 'V'},
+ {"keep-alive", 1, 0, 'K'},
+ {"ar-tries", 1, 0, 'A'},
+ {"ar-delay", 1, 0, 'T'},
{0, 0, 0, 0}
};
@@ -63,23 +68,32 @@ main(int argc, char **argv)
socklen_t len, addrlen;
struct sockaddr* cliaddr;
fd_set rset, allset, wset, tmpset;
+ struct timeval keepalive;
+ int timeout = 0;
+ int delay = 5;
+ int tries = -1;
char verbose = 0;
char remote = 0;
- char logging = 0;
- char socklogging = 0;
+ char sendkapackets = 0;
char* name = NULL;
+#ifdef HAVE_LIBPTHREAD
+ char* proxyname = NULL;
+ char* proxyport = NULL;
+#endif
char* id = NULL;
char* manage = NULL;
char* desnam = NULL;
char* despor = NULL;
char* keys = NULL;
- char* logfname = NULL;
- char* logsport = NULL;
char* dateformat = NULL;
+ char* katimeout = NULL;
+ char* artries = NULL;
+ char* ardelay = NULL;
char ipfam = 0;
unsigned char pass[4] = {1, 2, 3, 4};
char udp = 0;
char reverse = 0;
+ char tunneltype = 0;
char type = 0;
struct sigaction act;
#ifdef HAVE_LIBDL
@@ -87,38 +101,58 @@ main(int argc, char **argv)
#endif
SSL_METHOD* method;
- SSL_CTX* ctx;
-
+ SSL_CTX* ctx = NULL;
+
sigfillset(&(act.sa_mask));
act.sa_flags = 0;
act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, NULL);
- act.sa_handler = sig_int;
+ act.sa_handler = client_sig_int;
sigaction(SIGINT, &act, NULL);
+
+#ifdef HAVE_LIBPTHREAD
+ remember_mainthread();
+#endif
#ifdef AF_INET6
-# ifdef HAVE_LIBDL
- while ((n = getopt_long(argc, argv, "huUn:m:d:p:vk:O:o:46l:L:i:D:S:s:r", long_options, 0)) != -1) {
-# else
- while ((n = getopt_long(argc, argv, "huUn:m:d:p:vk:O:o:46i:D:S:s:r", long_options, 0)) != -1) {
-# endif
+#define GETOPT_LONG_AF_INET6(x) "46"x
+#else
+#define GETOPT_LONG_AF_INET6(x) x
+#endif
+#ifdef HAVE_LIBPTHREAD
+#define GETOPT_LONG_LIBPTHREAD(x) "P:X:"x
+#else
+#define GETOPT_LONG_LIBPTHREAD(x) x
+#endif
+#ifdef HAVE_LIBDL
+#define GETOPT_LONG_LIBDL(x) "l:L:"x
#else
-# ifdef HAVE_LIBDL
- while ((n = getopt_long(argc, argv, "huUn:m:d:p:vk:O:o:l:L:i:D:S:s:r", long_options, 0)) != -1) {
-# else
- while ((n = getopt_long(argc, argv, "huUn:m:d:p:vk:O:o:i:D:S:s:r", long_options, 0)) != -1) {
-# endif
+#define GETOPT_LONG_LIBDL(x) x
#endif
+
+ while ((n = getopt_long(argc, argv,
+ GETOPT_LONG_LIBDL(GETOPT_LONG_LIBPTHREAD(GETOPT_LONG_AF_INET6("huUn:m:d:p:vk:o:i:D:rP:X:VK:A:T:")))
+ , long_options, 0)) != -1) {
switch (n) {
case 'h': {
- usage(AF_VER("Active port forwarder (client)"));
+ client_long_usage(AF_VER("Active port forwarder (client)"));
break;
}
case 'n': {
name = optarg;
break;
}
+#ifdef HAVE_LIBPTHREAD
+ case 'P': {
+ proxyname = optarg;
+ break;
+ }
+ case 'X': {
+ proxyport = optarg;
+ break;
+ }
+#endif
case 'i': {
id = optarg;
break;
@@ -151,24 +185,8 @@ main(int argc, char **argv)
keys = optarg;
break;
}
- case 'O': {
- logfname = optarg;
- logging = 3;
- break;
- }
case 'o': {
- logfname = optarg;
- logging = 1;
- break;
- }
- case 'S': {
- logsport = optarg;
- socklogging = 3;
- break;
- }
- case 's': {
- logsport = optarg;
- socklogging = 1;
+ addlogtarget(optarg);
break;
}
case 301: {
@@ -217,25 +235,58 @@ main(int argc, char **argv)
remote = 1;
break;
}
+ case 'V': {
+ printf("%s\n", (AF_VER("Active port forwarder (client)")));
+ exit(0);
+ break;
+ }
+ case 'K': {
+ katimeout = optarg;
+ sendkapackets = 1;
+ break;
+ }
+ case 'A': {
+ artries = optarg;
+ break;
+ }
+ case 'T': {
+ ardelay = optarg;
+ break;
+ }
case '?': {
- usage("");
+ client_short_usage("");
break;
}
}
}
if (optind < argc) {
- usage("Unrecognized non-option elements");
+ client_short_usage("Unrecognized non-option elements");
}
if (name == NULL) {
- usage("Name of the server is required");
+ client_short_usage("Name of the server is required");
}
if (manage == NULL) {
manage = "50126";
if (reverse)
- usage("Port on the server is required in reverse mode");
+ client_short_usage("Port on the server is required in reverse mode");
}
+#ifdef HAVE_LIBPTHREAD
+ if ((proxyname) || (proxyport)) {
+ if (tunneltype == 0) {
+ tunneltype = 1;
+ }
+ else {
+ tunneltype = -1;
+ }
+ }
+ if (tunneltype == 1) {
+ if (proxyport == NULL) {
+ proxyport = "8080";
+ }
+ }
+#endif
if (keys == NULL) {
keys = "client.rsa";
}
@@ -244,31 +295,32 @@ main(int argc, char **argv)
desnam = hostname;
}
if ((!remote) && (despor == NULL)) {
- usage("Destination port number is required");
+ client_short_usage("Destination port number is required");
}
- if ((temp2 = loginit(verbose, logging, socklogging, logfname, logsport, dateformat))) {
- switch (temp2) {
- case 1:
- printf("Can't open file to log to... exiting\n");
- break;
- case 2:
- printf("Can't connect to localhost:%s... exiting\n", logsport);
- break;
- case 3:
- printf("Can't open socket to log to... exiting\n");
- break;
- }
- exit(1);
+ if (sendkapackets) {
+ check_value(&timeout, katimeout, "Invalid timeout value");
+ keepalive.tv_sec = timeout;
+ keepalive.tv_usec = 0;
+ }
+ if (artries) {
+ tries = check_value_liberal(artries, "Invalid ar-tries value");
+ }
+ if (ardelay) {
+ check_value(&delay, ardelay, "Invalid ar-delay value");
}
+
+ initializelogging(verbose, dateformat);
#ifdef HAVE_LIBDL
if (loadmodule(&module)) {
- aflog(0, "Loading a module %s failed!", module.name);
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Loading a module %s failed!", module.name);
exit(1);
}
if (loadmodule(&secmodule)) {
- aflog(0, "Loading a module %s failed!", secmodule.name);
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Loading a module %s failed!", secmodule.name);
exit(1);
}
#endif
@@ -278,7 +330,8 @@ main(int argc, char **argv)
#ifdef AF_INET6
if (ipfam == -1) {
- aflog(0, "Conflicting types of ip protocol family... exiting");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Conflicting types of ip protocol family... exiting");
exit(1);
}
else if (ipfam == 4) {
@@ -303,252 +356,87 @@ main(int argc, char **argv)
method = SSLv3_client_method();
ctx = SSL_CTX_new(method);
if (SSL_CTX_set_cipher_list(ctx, "ALL:@STRENGTH") == 0) {
- aflog(0, "Setting cipher list failed... exiting");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Setting cipher list failed... exiting");
exit(1);
}
if ((temp2 = create_apf_dir())) {
- aflog(1, "Warning: Creating ~/.apf directory failed (%d)", temp2);
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: Creating ~/.apf directory failed (%d)", temp2);
}
if ((temp2 = generate_rsa_key(&keys))) {
- aflog(1, "Warning: Something bad happened when generating rsa keys... (%d)", temp2);
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: Something bad happened when generating rsa keys... (%d)", temp2);
}
if (SSL_CTX_use_RSAPrivateKey_file(ctx, keys, SSL_FILETYPE_PEM) != 1) {
- aflog(0, "Setting rsa key failed (%s)... exiting", keys);
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Setting rsa key failed (%s)... exiting", keys);
exit(1);
}
+ if ((!remote) && (!verbose))
+ daemon(0, 0);
+
if (remote) {
temp2 = -1;
if (despor) {
if (ip_listen(&n, desnam, despor, &addrlen, ipfam)) {
#ifdef AF_INET6
- aflog(0, "tcp_listen_%s error for %s, %s",
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "tcp_listen_%s error for %s, %s",
(ipfam & 0x02)?"ipv4":(ipfam & 0x04)?"ipv6":"unspec", desnam, despor);
#else
- aflog(0, "tcp_listen error for %s, %s", desnam, despor);
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "tcp_listen error for %s, %s", desnam, despor);
#endif
exit(1);
}
- if (!verbose)
- daemon(0, 0);
cliaddr = malloc(addrlen);
temp2 = accept(n, cliaddr, &addrlen);
}
}
- if (ip_connect(&(master.commfd), name, manage, ipfam)) {
-#ifdef AF_INET6
- aflog(0, "tcp_connect_%s error for %s, %s",
- (ipfam & 0x02)?"ipv4":(ipfam & 0x04)?"ipv6":"unspec", name, manage);
+#ifdef HAVE_LIBPTHREAD
+ initialize_client_stage1(tunneltype, &master, name, manage, proxyname, proxyport, ipfam, ctx, buff, pass, 1);
#else
- aflog(0, "tcp_connect error for %s, %s", name, manage);
+ initialize_client_stage1(tunneltype, &master, name, manage, NULL, NULL, ipfam, ctx, buff, pass, 1);
#endif
- exit(1);
- }
- master.ssl = SSL_new(ctx);
- if (SSL_set_fd(master.ssl, master.commfd) != 1) {
- aflog(0, "Problem with initializing ssl... exiting");
- exit(1);
- }
-
- aflog(1, "Trying SSL_connect");
- if ((n = SSL_connect(master.ssl)) == 1) {
- aflog(1, "SSL_connect successfull");
- }
- else {
- aflog(0, "SSL_connect has failed (%d)... exiting", n);
- exit(1);
- }
-
- buff[0] = AF_S_LOGIN;
- buff[1] = pass[0];
- buff[2] = pass[1];
- buff[3] = pass[2];
- buff[4] = pass[3];
if (remote) {
return client_admin(type, master, buff, temp2, id);
}
-
- send_message(type, master, buff, 5);
- buff[0] = 0;
- get_message(type, master, buff, -5);
-
- if ( buff[0] == 0 ) {
- aflog(0, "Wrong password");
- exit(1);
- }
- if ( buff[0] == AF_S_CANT_OPEN ) {
- aflog(0, "Server is full");
- exit(1);
- }
- if ( buff[0] != AF_S_LOGIN ) {
- aflog(0, "Incompatible server type or server full");
- exit(1);
- }
-
- type = buff[3];
- usernum = buff[1];
- usernum = usernum << 8;
- usernum += buff[2];
+
+ initialize_client_stage2(&type, &master, &usernum, buff, 1);
} /* !reverse */
else {
- usernum = 1;
- if (ip_connect(&(master.commfd), name, manage, ipfam)) {
-#ifdef AF_INET6
- aflog(0, "tcp_connect_%s error for %s, %s",
- (ipfam & 0x02)?"ipv4":(ipfam & 0x04)?"ipv6":"unspec", name, manage);
-#else
- aflog(0, "tcp_connect error for %s, %s", name, manage);
-#endif
- exit(1);
- }
- master.ssl = NULL;
+ initialize_client_reverse_udp(&usernum, &master, name, manage, ipfam);
}
- contable = calloc( usernum, sizeof(ConnectuserT));
- if (contable == NULL) {
- aflog(0, "Calloc error - unable to succesfully communicate with server");
- exit(1);
- }
-
- len = 4;
- if (getsockopt(master.commfd, SOL_SOCKET, SO_SNDBUF, &buflength, &len) == -1) {
- aflog(0, "Can't get socket send buffer size - exiting...");
- exit(1);
- }
-
- if (!verbose)
- daemon(0, 0);
-
- FD_ZERO(&allset);
- FD_ZERO(&wset);
-
- FD_SET(master.commfd, &allset);
- maxfdp1 = master.commfd + 1;
+ initialize_client_stage3(&contable, &master, usernum, &buflength, &len, &allset, &wset, &maxfdp1, 1);
/* UDP REVERSE MODE */
if (reverse) {
- ipfam = 0;
-#ifdef AF_INET6
- if (TYPE_IS_IPV4(type)) {
- ipfam |= 0x02;
- }
- else if (TYPE_IS_IPV6(type)) {
- ipfam |= 0x04;
- }
-#endif
- if (ip_listen(&(contable[0].connfd), desnam, despor, &addrlen, ipfam)) {
-#ifdef AF_INET6
- aflog(0, "udp_listen_%s error for %s, %s",
- (ipfam & 0x02)?"ipv4":(ipfam & 0x04)?"ipv6":"unspec", desnam, despor);
-#else
- aflog(0, "udp_listen error for %s, %s", desnam, despor);
-#endif
- exit(1);
- }
- cliaddr = malloc(addrlen);
- maxfdp1 = (maxfdp1>contable[0].connfd+1) ? maxfdp1 : contable[0].connfd+1;
- FD_SET(contable[0].connfd, &allset);
- aflog(1, "CLIENT STARTED mode: udp reverse");
- for ( ; ; ) {
- len = 4;
- if (getsockopt(master.commfd, SOL_SOCKET, SO_SNDBUF, &temp2, &len) != -1) {
- if (temp2 != buflength) {
- buflength = temp2;
- aflog(2, "Send buffer size changed...");
- }
- }
- len = addrlen;
- rset = allset;
- aflog(3, ">select");
- select(maxfdp1, &rset, NULL, NULL, NULL);
- aflog(3, " >>after select...");
-
- if (FD_ISSET(contable[0].connfd, &rset)) { /* FD_ISSET CONTABLE[0].CONNFD RSET*/
- n = recvfrom(contable[0].connfd, &buff[5], 8091, 0, cliaddr, &len);
-#ifdef HAVE_LINUX_SOCKIOS_H
-# ifdef SIOCOUTQ
- if (ioctl(master.commfd, SIOCOUTQ, &notsent)) {
- aflog(0, "ioctl error -> exiting...");
- exit(1);
- }
- if (buflength <= notsent + n + 5) { /* when we can't do this */
- aflog(2, "drop: size:%d, buf:%d, w:%d/%d", n, buflength, notsent, buflength);
-# else
- if (ioctl(master.commfd, TIOCOUTQ, &notsent)) {
- aflog(0, "ioctl error -> exiting...");
- exit(1);
- }
- if (notsent <= n + 5) { /* when we can't do this */
- aflog(2, "drop: size:%d, buf:%d, w:%d/%d", n, buflength, buflength - notsent, buflength);
-# endif
- }
- else {
-#endif
- if (n > 0) {
-#ifdef HAVE_LINUX_SOCKIOS_H
- aflog(2, "Sending %d bytes to service (w:%d/%d) (FROM:%s)", n,
-# ifdef SIOCOUTQ
- notsent
-# else
- buflength - notsent
-# endif
- , buflength, sock_ntop(cliaddr, len, NULL, NULL, 0));
-#else
- aflog(2, "Sending %d bytes to service (FROM:%s)", n, sock_ntop(cliaddr, len, NULL, NULL, 0));
-#endif
- buff[0] = AF_S_MESSAGE;
- buff[1] = AF_S_LOGIN;
- buff[2] = AF_S_MESSAGE;
- buff[3] = n >> 8;
- buff[4] = n;
- writen(master.commfd, buff, n + 5);
- }
-#ifdef HAVE_LINUX_SOCKIOS_H
- }
-#endif
- } /* - FD_ISSET CONTABLE[0].CONNFD RSET */
-
- if (FD_ISSET(master.commfd, &rset)) { /* FD_ISSET MASTER.COMMFD RSET */
- n = readn(master.commfd, buff, 5);
- if (n == 5) {
- if ((buff[0] != AF_S_MESSAGE) || (buff[1] != AF_S_LOGIN) || (buff[2] != AF_S_MESSAGE)) {
- aflog(0, "Incompatible server type (not udp?) or data corruption -> exiting...");
- exit(1);
- }
- length = buff[3];
- length = length << 8;
- length += buff[4]; /* this is length of message */
- n = readn(master.commfd, buff, length);
- }
- else {
- n = 0;
- }
- if (n == 0) { /* server quits -> we do the same... */
- aflog(0, "premature quit of the server -> exiting...");
- exit(1);
- }
- aflog(2, "Sending %d bytes to user (TO:%s)", n, sock_ntop(cliaddr, addrlen, NULL, NULL, 0));
- sendto(contable[0].connfd, buff, n, 0, cliaddr, addrlen);
- } /* - FD_ISSET MASTER.COMMFD RSET */
- }
- exit(0); /* we shouldn't get here */
+ client_reverse_udp(contable, &master, desnam, despor, type, buff, buflength);
}
/* NORMAL MODE */
- aflog(1, "CLIENT STARTED mode: %s", (udp)?"udp":"tcp");
- aflog(1, "SERVER SSL: %s, ZLIB: %s, MODE: %s", (TYPE_IS_SSL(type))?"yes":"no",
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "CLIENT STARTED mode: %s", (udp)?"udp":"tcp");
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "SERVER SSL: %s, ZLIB: %s, MODE: %s", (TYPE_IS_SSL(type))?"yes":"no",
(TYPE_IS_ZLIB(type))?"yes":"no", (TYPE_IS_TCP(type))?"tcp":"udp");
- aflog(2, "CIPHER: %s VER: %s", SSL_get_cipher_name(master.ssl), SSL_get_cipher_version(master.ssl));
+ aflog(LOG_T_CLIENT, LOG_I_NOTICE,
+ "CIPHER: %s VER: %s", SSL_get_cipher_name(master.ssl), SSL_get_cipher_version(master.ssl));
#ifdef HAVE_LIBDL
if (ismloaded(&module)) {
- aflog(1, "LOADED MODULE: %s INFO: %s", module.name, module.info());
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "LOADED MODULE: %s INFO: %s", module.name, module.info());
}
if (ismloaded(&secmodule)) {
- aflog(1, "LOADED MODULE (ser): %s INFO: %s", secmodule.name, secmodule.info());
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "LOADED MODULE (ser): %s INFO: %s", secmodule.name, secmodule.info());
}
#endif
if (id != NULL) {
@@ -559,29 +447,46 @@ main(int argc, char **argv)
buff[3] = n >> 8; /* high bits of message length */
buff[4] = n; /* low bits of message length */
send_message(type, master, buff, n+5);
- aflog(1, "ID SENT: %s", id);
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "ID SENT: %s", id);
}
for ( ; ; ) {
rset = allset;
tmpset = wset;
- aflog(3, ">select");
- select(maxfdp1, &rset, &tmpset, NULL, NULL);
- aflog(3, " >>after select...");
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "select");
+ if (sendkapackets) {
+ if (select(maxfdp1, &rset, &tmpset, NULL, &keepalive) == 0) {
+ aflog(LOG_T_CLIENT, LOG_I_DEBUG,
+ "timeout: sending keep-alive packet");
+ buff[0] = AF_S_KEEP_ALIVE;
+ send_message(type, master, buff, 5);
+ keepalive.tv_sec = timeout;
+ }
+ }
+ else {
+ select(maxfdp1, &rset, &tmpset, NULL, NULL);
+ }
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "after select...");
for (i = 0; i < usernum; ++i) {
if ((contable[i].state == S_STATE_OPEN)||(contable[i].state == S_STATE_STOPPED)) {
if (FD_ISSET(contable[i].connfd, &rset)) { /* FD_ISSET CONTABLE[i].CONNFD RSET */
- aflog(3, " user[%d]: FD_ISSET", i);
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "user[%d]: FD_ISSET", i);
n = read(contable[i].connfd, &buff[5], 8091);
if (n == -1) {
- aflog(0, " error (%d): while reading from service", n);
+ aflog(LOG_T_USER, LOG_I_ERR,
+ "error (%d): while reading from service", n);
n = 0;
}
#ifdef HAVE_LINUX_SOCKIOS_H
# ifdef SIOCOUTQ
if (ioctl(master.commfd, SIOCOUTQ, &notsent)) {
- aflog(0, "ioctl error -> exiting...");
+ aflog(LOG_T_USER, LOG_I_CRIT,
+ "ioctl error -> exiting...");
exit(1);
}
if (udp) {
@@ -589,14 +494,17 @@ main(int argc, char **argv)
if (getsockopt(master.commfd, SOL_SOCKET, SO_SNDBUF, &temp2, &len) != -1) {
if (temp2 != buflength) {
buflength = temp2;
- aflog(2, "Send buffer size changed...");
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "Send buffer size changed...");
}
}
if (buflength <= notsent + n + 5) { /* when we can't send this */
- aflog(2, " user[%d]: DROP size:%d, buf:%d, w:%d/%d", i, n+5, buflength, notsent, buflength);
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "user[%d]: DROP size:%d, buf:%d, w:%d/%d", i, n+5, buflength, notsent, buflength);
# else
if (ioctl(master.commfd, TIOCOUTQ, &notsent)) {
- aflog(0, "ioctl error -> exiting...");
+ aflog(LOG_T_USER, LOG_I_CRIT,
+ "ioctl error -> exiting...");
exit(1);
}
if (udp) {
@@ -604,11 +512,13 @@ main(int argc, char **argv)
if (getsockopt(master.commfd, SOL_SOCKET, SO_SNDBUF, &temp2, &len) != -1) {
if (temp2 != buflength) {
buflength = temp2;
- aflog(2, "Send buffer size changed...");
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "Send buffer size changed...");
}
}
if (notsent <= n + 5) { /* when we can't send this */
- aflog(2, " user[%d]: DROP size:%d, buf:%d, w:%d/%d",
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "user[%d]: DROP size:%d, buf:%d, w:%d/%d",
i, n+5, buflength, buflength-notsent, buflength);
# endif
continue; /* drop this packet */
@@ -620,16 +530,19 @@ main(int argc, char **argv)
if (ismloaded(&secmodule)) {
switch ((temp2 = secmodule.filter(contable[i].namebuf, &buff[5], &n))) {
case 1: case 4: {
- aflog(3, " user[%d] (by ser): PACKET IGNORED BY MODULE", i);
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "user[%d] (by ser): PACKET IGNORED BY MODULE", i);
if (temp2 == 4) {
- aflog(1, "RELEASED MODULE (ser): %s INFO: %s", secmodule.name, secmodule.info());
+ aflog(LOG_T_MAIN, LOG_I_INFO,
+ "RELEASED MODULE (ser): %s INFO: %s", secmodule.name, secmodule.info());
releasemodule(&secmodule);
}
continue;
break;
}
case 2: case 5: {
- aflog(2, " user[%d] (by ser): DROPPED BY MODULE", i);
+ aflog(LOG_T_USER, LOG_I_NOTICE,
+ "user[%d] (by ser): DROPPED BY MODULE", i);
close(contable[i].connfd);
FD_CLR(contable[i].connfd, &allset);
FD_CLR(contable[i].connfd, &wset);
@@ -640,14 +553,16 @@ main(int argc, char **argv)
buff[2] = i; /* low bits of user number */
send_message(type, master, buff, 5);
if (temp2 == 5) {
- aflog(1, "RELEASED MODULE (ser): %s INFO: %s", secmodule.name, secmodule.info());
+ aflog(LOG_T_MAIN, LOG_I_INFO,
+ "RELEASED MODULE (ser): %s INFO: %s", secmodule.name, secmodule.info());
releasemodule(&secmodule);
}
continue;
break;
}
case 3: {
- aflog(1, "RELEASED MODULE (ser): %s INFO: %s", secmodule.name, secmodule.info());
+ aflog(LOG_T_MAIN, LOG_I_INFO,
+ "RELEASED MODULE (ser): %s INFO: %s", secmodule.name, secmodule.info());
releasemodule(&secmodule);
break;
}
@@ -660,7 +575,8 @@ main(int argc, char **argv)
buff[3] = n >> 8; /* high bits of message length */
buff[4] = n; /* low bits of message length */
#ifdef HAVE_LINUX_SOCKIOS_H
- aflog(2, " user[%d]: TO msglen: %d [%d/%d]", i, n,
+ aflog(LOG_T_USER, LOG_I_DEBUG,
+ "user[%d]: TO msglen: %d [%d/%d]", i, n,
# ifdef SIOCOUTQ
notsent
# else
@@ -668,12 +584,14 @@ main(int argc, char **argv)
# endif
, buflength);
#else
- aflog(2, " user[%d]: TO msglen: %d", i, n);
+ aflog(LOG_T_USER, LOG_I_DEBUG,
+ "user[%d]: TO msglen: %d", i, n);
#endif
send_message(type, master, buff, n+5);
}
else if (!udp) {
- aflog(2, " user[%d]: CLOSING", i);
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "user[%d]: CLOSING", i);
close(contable[i].connfd);
FD_CLR(contable[i].connfd, &allset);
FD_CLR(contable[i].connfd, &wset);
@@ -690,14 +608,16 @@ main(int argc, char **argv)
for (i = 0; i < usernum; ++i) {
if (contable[i].state == S_STATE_STOPPED) {
if (FD_ISSET(contable[i].connfd, &tmpset)) { /* FD_ISSET CONTABLE[i].CONNFD TMPSET */
- aflog(3, " user[%d]: FD_ISSET - WRITE", i);
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "user[%d]: FD_ISSET - WRITE", i);
n = contable[i].head->msglen - contable[i].head->actptr;
temp2 = write(contable[i].connfd, &(contable[i].head->buff[contable[i].head->actptr]), n);
if ((temp2 > 0) && (temp2 != n)) {
contable[i].head->actptr+=temp2;
}
else if ((temp2 == -1) && (errno == EAGAIN)) {
- aflog(3, " user[%d]: Couldn't write?", i);
+ aflog(LOG_T_USER, LOG_I_DEBUG,
+ "user[%d]: Couldn't write?", i);
}
else if (temp2 == -1) {
close(contable[i].connfd);
@@ -717,7 +637,8 @@ main(int argc, char **argv)
buff[0] = AF_S_CAN_SEND; /* stopping transfer */
buff[1] = i >> 8; /* high bits of user number */
buff[2] = i; /* low bits of user number */
- aflog(3, " FROM user[%d]: BUFFERING MESSAGE ENDED", i);
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "FROM user[%d]: BUFFERING MESSAGE ENDED", i);
send_message(type, master, buff, 5);
}
}
@@ -725,10 +646,12 @@ main(int argc, char **argv)
}
}
if (FD_ISSET(master.commfd, &rset)) { /* FD_ISSET MASTER.COMMFD RSET */
- aflog(3, " masterfd: FD_ISSET");
+ aflog(LOG_T_CLIENT, LOG_I_DDEBUG,
+ "masterfd: FD_ISSET");
n = get_message(type, master, buff, 5);
if (n != 5) {
- aflog(2, " FATAL ERROR! (%d)", n);
+ aflog(LOG_T_CLIENT, LOG_I_ERR,
+ "FATAL ERROR! (%d)", n);
if (n == -1) {
if (TYPE_IS_SSL(type)) {
get_ssl_error(&master, "FE", n);
@@ -739,8 +662,59 @@ main(int argc, char **argv)
exit(1);
}
if (n == 0) { /* server quits -> we do the same... */
- aflog(0, " SERVER: premature quit -> exiting...");
- exit(1);
+ i = tries;
+ if (i) {
+ aflog(LOG_T_CLIENT, LOG_I_ERR,
+ "SERVER: premature quit -> auto-reconnect enabled");
+ }
+ while (i) {
+ close_connections(usernum, &contable);
+ clear_master_connection(&master);
+ mysleep(delay);
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "Trying to reconnect...");
+
+ temp2 = 0;
+ if (temp2 == 0) {
+#ifdef HAVE_LIBPTHREAD
+ if (initialize_client_stage1(tunneltype, &master, name, manage, proxyname, proxyport,
+ ipfam, ctx, buff, pass, 0)) {
+#else
+ if (initialize_client_stage1(tunneltype, &master, name, manage, NULL, NULL,
+ ipfam, ctx, buff, pass, 0)) {
+#endif
+ temp2 = 1;
+ }
+ }
+ if (temp2 == 0) {
+ if (initialize_client_stage2(&type, &master, &usernum, buff, 0)) {
+ temp2 = 1;
+ }
+ }
+ if (temp2 == 0) {
+ if (initialize_client_stage3(&contable, &master, usernum, &buflength, &len, &allset,
+ &wset, &maxfdp1, 0)) {
+ temp2 = 1;
+ }
+ }
+
+ if (temp2 == 0) {
+ n = 1;
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "Reconnected successfully...");
+ break;
+ }
+
+ if (i > 0) {
+ --i;
+ }
+ }
+ if (n == 0) {
+ aflog(LOG_T_CLIENT, LOG_I_CRIT,
+ "SERVER: premature quit -> exiting...");
+ exit(1);
+ }
+ continue;
}
numofcon = buff[1];
numofcon = numofcon << 8;
@@ -750,15 +724,18 @@ main(int argc, char **argv)
length += buff[4]; /* this is length of message */
switch (buff[0]) {
case AF_S_CONCLOSED : {
- aflog(4, " user[%d]: AF_S_CONCLOSED", numofcon);
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "user[%d]: AF_S_CONCLOSED", numofcon);
if ((numofcon>=0) && (numofcon<=usernum)) {
usercon--;
if (contable[numofcon].state == S_STATE_CLOSING) {
contable[numofcon].state = S_STATE_CLEAR;
- aflog(1, " user[%d]: CLOSED", numofcon);
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "user[%d]: CLOSED", numofcon);
}
else if ((contable[numofcon].state==S_STATE_OPEN) || (contable[numofcon].state==S_STATE_STOPPED)){
- aflog(1, " user[%d]: CLOSED", numofcon);
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "user[%d]: CLOSED", numofcon);
close(contable[numofcon].connfd);
FD_CLR(contable[numofcon].connfd, &allset);
FD_CLR(contable[numofcon].connfd, &wset);
@@ -773,19 +750,23 @@ main(int argc, char **argv)
break;
}
case AF_S_CONOPEN : {
- aflog(4, " user[%d]: AF_S_CONOPEN", numofcon);
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "user[%d]: AF_S_CONOPEN", numofcon);
if ((numofcon>=0) && (numofcon<=usernum)) {
usercon++;
if (contable[numofcon].state == S_STATE_CLEAR) {
n = get_message(type, master, buff, length);
memcpy(contable[numofcon].namebuf, buff, 128);
memcpy(contable[numofcon].portbuf,&buff[128],7);
- aflog(2, " user[%d]: OPENING", numofcon);
- aflog(1, "user[%d]: IP:%s PORT:%s", numofcon,
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "user[%d]: OPENING", numofcon);
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "user[%d]: IP:%s PORT:%s", numofcon,
contable[numofcon].namebuf, contable[numofcon].portbuf);
#ifdef HAVE_LIBDL
if (ismloaded(&module) && module.allow(contable[numofcon].namebuf, contable[numofcon].portbuf)) {
- aflog(2, " IT'S NOT ALLOWED - DROPPING", numofcon);
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "IT'S NOT ALLOWED - DROPPING", numofcon);
buff[0] = AF_S_CANT_OPEN; /* not opening connection */
buff[1] = numofcon >> 8; /* high bits of user number */
buff[2] = numofcon; /* low bits of user number */
@@ -809,7 +790,8 @@ main(int argc, char **argv)
}
#endif
if (ip_connect(&(contable[numofcon].connfd), desnam, despor, ipfam)) {
- aflog(2, " CAN'T OPEN - DROPPING", numofcon);
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "CAN'T OPEN - DROPPING", numofcon);
buff[0] = AF_S_CANT_OPEN; /* not opening connection */
buff[1] = numofcon >> 8; /* high bits of user number */
buff[2] = numofcon; /* low bits of user number */
@@ -831,8 +813,10 @@ main(int argc, char **argv)
break;
}
case AF_S_MESSAGE : {
- aflog(4, " user[%d]: AF_S_MESSAGE", numofcon);
- aflog(2, " user[%d]: FROM msglen: %d", numofcon, length);
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "user[%d]: AF_S_MESSAGE", numofcon);
+ aflog(LOG_T_USER, LOG_I_DEBUG,
+ "user[%d]: FROM msglen: %d", numofcon, length);
n = get_message(type, master, buff, length);
if ((numofcon>=0) && (numofcon<=usernum)) {
if (contable[numofcon].state == S_STATE_OPEN) {
@@ -840,16 +824,19 @@ main(int argc, char **argv)
if (ismloaded(&module)) {
switch ((temp2 = module.filter(contable[numofcon].namebuf, buff, &n))) {
case 1: case 4:{
- aflog(3, " user[%d]: PACKET IGNORED BY MODULE", numofcon);
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "user[%d]: PACKET IGNORED BY MODULE", numofcon);
if (temp2 == 4) {
- aflog(1, "RELEASED MODULE: %s INFO: %s", module.name, module.info());
+ aflog(LOG_T_MAIN, LOG_I_INFO,
+ "RELEASED MODULE: %s INFO: %s", module.name, module.info());
releasemodule(&module);
}
continue;
break;
}
case 2: case 5:{
- aflog(2, " user[%d]: DROPPED BY MODULE", numofcon);
+ aflog(LOG_T_USER, LOG_I_NOTICE,
+ "user[%d]: DROPPED BY MODULE", numofcon);
close(contable[numofcon].connfd);
FD_CLR(contable[numofcon].connfd, &allset);
FD_CLR(contable[numofcon].connfd, &wset);
@@ -860,21 +847,24 @@ main(int argc, char **argv)
buff[2] = numofcon; /* low bits of user number */
send_message(type, master, buff, 5);
if (temp2 == 5) {
- aflog(1, "RELEASED MODULE: %s INFO: %s", module.name, module.info());
+ aflog(LOG_T_MAIN, LOG_I_INFO,
+ "RELEASED MODULE: %s INFO: %s", module.name, module.info());
releasemodule(&module);
}
continue;
break;
}
case 3: {
- aflog(1, "RELEASED MODULE: %s INFO: %s", module.name, module.info());
+ aflog(LOG_T_MAIN, LOG_I_INFO,
+ "RELEASED MODULE: %s INFO: %s", module.name, module.info());
releasemodule(&module);
break;
}
}
}
#endif
- aflog(2, " user[%d]: FROM msglen: %d SENT", numofcon, n);
+ aflog(LOG_T_USER, LOG_I_DEBUG,
+ "user[%d]: FROM msglen: %d SENT", numofcon, n);
temp2 = write(contable[numofcon].connfd, buff, n);
if ((temp2 > 0) && (temp2 != n)) {
insertblnode(&(contable[numofcon].head), temp2, n, buff);
@@ -883,7 +873,8 @@ main(int argc, char **argv)
buff[0] = AF_S_DONT_SEND; /* stopping transfer */
buff[1] = numofcon >> 8; /* high bits of user number */
buff[2] = numofcon; /* low bits of user number */
- aflog(3, " FROM user[%d]: BUFFERING MESSAGE STARTED", numofcon);
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "FROM user[%d]: BUFFERING MESSAGE STARTED", numofcon);
send_message(type, master, buff, 5);
}
else if ((temp2 == -1) && (errno == EAGAIN)) {
@@ -893,7 +884,8 @@ main(int argc, char **argv)
buff[0] = AF_S_DONT_SEND; /* stopping transfer */
buff[1] = numofcon >> 8; /* high bits of user number */
buff[2] = numofcon; /* low bits of user number */
- aflog(3, " FROM user[%d]: BUFFERING MESSAGE STARTED", numofcon);
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "FROM user[%d]: BUFFERING MESSAGE STARTED", numofcon);
send_message(type, master, buff, 5);
}
else if (temp2 == -1) {
@@ -909,29 +901,34 @@ main(int argc, char **argv)
}
}
else if (contable[numofcon].state == S_STATE_STOPPED) {
- aflog(3, " FROM user[%d]: BUFFERING MESSAGE", numofcon);
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "FROM user[%d]: BUFFERING MESSAGE", numofcon);
insertblnode(&(contable[numofcon].head), 0, n, buff);
}
}
break;
}
case AF_S_CLOSING : { /* server shut down -> exiting... */
- aflog(0, " SERVER: CLOSED -> exiting... cg: %ld bytes", getcg());
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "SERVER: CLOSED -> exiting... cg: %ld bytes", getcg());
exit(1);
break;
}
case AF_S_DONT_SEND: {
- aflog(4, " user[%d]: AF_S_DONT_SEND", numofcon);
+ aflog(LOG_T_USER, LOG_I_DEBUG,
+ "user[%d]: AF_S_DONT_SEND", numofcon);
FD_CLR(contable[numofcon].connfd, &allset);
break;
}
case AF_S_CAN_SEND: {
- aflog(4, " user[%d]: AF_S_CAN_SEND", numofcon);
+ aflog(LOG_T_USER, LOG_I_DEBUG,
+ "user[%d]: AF_S_CAN_SEND", numofcon);
FD_SET(contable[numofcon].connfd, &allset);
break;
}
default : { /* unrecognized type of message -> exiting... */
- aflog(0, " SERVER: unrecognized message -> exiting... cg: %ld bytes", getcg());
+ aflog(LOG_T_CLIENT, LOG_I_ERR,
+ "SERVER: unrecognized message -> exiting... cg: %ld bytes", getcg());
exit(1);
break;
}
@@ -939,62 +936,3 @@ main(int argc, char **argv)
} /* - FD_ISSET MASTER.COMMFD RSET */
}
}
-
-static void
-usage(char* info)
-{
- printf("\n%s\n\n\n", info);
- printf(" Basic options:\n\n");
- printf(" -n, --servername - where the second part of the active\n");
- printf(" port forwarder is running (required)\n");
- printf(" -m, --manageport - manage port number - server must be\n");
- printf(" listening on it (default: 50126)\n");
- printf(" -d, --hostname - the name of this host/remote host - the final\n");
- printf(" destination of the packets (default: the name\n");
- printf(" returned by hostname function)\n");
- printf(" -p, --portnum - the port we are forwarding connection to (required)\n");
- printf(" -h, --help - prints this help\n\n");
- printf(" Authorization:\n\n");
- printf(" -i, --id - sends the id string to afserver\n");
- printf(" --pass - set the password used for client identification\n");
- printf(" (default: no password)\n\n");
- printf(" Configuration:\n\n");
- printf(" -k, --keyfile - the name of the file with RSA key (default: client.rsa)\n");
- printf(" -D, --dateformat - format of the date printed in logs (see 'man strftime'\n");
- printf(" for details) (default: %%d.%%m.%%Y %%H:%%M:%%S)\n\n");
- printf(" Modes:\n\n");
- printf(" -u, --udpmode - udp mode - client will use udp protocol to\n");
- printf(" communicate with the hostname:portnum (-p)\n");
- printf(" -U, --reverseudp - reverse udp forwarding. Udp packets will be forwarded\n");
- printf(" from hostname:portnum (-p) to the server name:portnum\n");
- printf(" (-m)\n");
- printf(" -r, --remoteadmin - remote administration mode. (using '-p #port' will\n");
- printf(" force afclient to use port rather then stdin-stdout)\n\n");
- printf(" Logging:\n\n");
- printf(" -O, --heavylog - logging everything to a logfile\n");
- printf(" -o, --lightlog - logging some data to a logfile\n");
- printf(" -S, --heavysocklog - logging everything to a localport\n");
- printf(" -s, --lightsocklog - logging some data to a localport\n");
- printf(" -v, --verbose - to be verbose - program won't enter the daemon mode\n");
- printf(" (use several times for greater effect)\n\n");
-#ifdef AF_INET6
- printf(" IP family:\n\n");
- printf(" -4, --ipv4 - use ipv4 only\n");
- printf(" -6, --ipv6 - use ipv6 only\n\n");
-#endif
-#ifdef HAVE_LIBDL
- printf(" Modules:\n\n");
- printf(" -l, --load - load a module for user's packets filtering\n");
- printf(" -L, --Load - load a module for service's packets filtering\n\n");
-#endif
-
- exit(0);
-}
-
-static void
-sig_int(int signo)
-{
- aflog(1, "CLIENT CLOSED cg: %ld bytes", getcg());
- exit(0);
-}
-
diff --git a/src/afclient.h b/src/afclient.h
index 108751b..c2b52bb 100644
--- a/src/afclient.h
+++ b/src/afclient.h
@@ -25,6 +25,17 @@
#include "remoteadmin.h"
#include "make_ssl_handshake.h"
#include "first_run.h"
+#include "http_proxy_client.h"
+#include "thread_management.h"
+#include "client_reverse_udp.h"
+#include "server_check.h"
+#include "client_initialization.h"
+#include "http_proxy_functions.h"
+#include "client_shutdown.h"
+#include "client_signals.h"
+#include "usage.h"
+#include "logging.h"
+#include "audit.h"
#include <openssl/rsa.h>
#include <openssl/ssl.h>
@@ -43,8 +54,5 @@
#ifndef _JS_AFCLIENT_H
#define _JS_AFCLIENT_H
-static void usage(char* info);
-static void sig_int(int);
-
#endif
diff --git a/src/afserver.c b/src/afserver.c
index d1e11b7..76f8ffc 100644
--- a/src/afserver.c
+++ b/src/afserver.c
@@ -39,10 +39,8 @@ static struct option long_options[] = {
{"keyfile", 1, 0, 'k'},
{"cfgfile", 1, 0, 'f'},
{"proto", 1, 0, 'p'},
- {"lightlog", 1, 0, 'o'},
- {"heavylog", 1, 0, 'O'},
- {"heavysocklog", 1, 0, 'S'},
- {"lightsocklog", 1, 0, 's'},
+ {"log", 1, 0, 'o'},
+ {"audit", 0, 0, 'a'},
{"nossl", 0, 0, 301},
{"nozlib", 0, 0, 302},
{"pass", 1, 0, 303},
@@ -53,10 +51,14 @@ static struct option long_options[] = {
{"baseport", 0, 0, 'b'},
{"dnslookups", 0, 0, 311},
{"dateformat", 1, 0, 'D'},
+#ifdef HAVE_LIBPTHREAD
+ {"enableproxy", 0, 0, 'P'},
+#endif
+ {"version", 0, 0, 'V'},
{0, 0, 0, 0}
};
-static ConfigurationT config;
+ConfigurationT config;
int
main(int argc, char **argv)
@@ -84,19 +86,20 @@ main(int argc, char **argv)
unsigned char pass[4] = {1, 2, 3, 4};
char verbose = 0;
char mode = 0;
+#ifdef HAVE_LIBPTHREAD
+ char tunneltype = 0;
+#endif
char ipfam = 0;
char baseport = 0;
+ char audit = 0;
char dnslookups = 0;
RealmT* pointer = NULL;
struct sigaction act;
+ time_t now;
char* certif = NULL;
char* keys = NULL;
- char* logfnam = NULL;
- char* logsport = NULL;
char* dateformat = NULL;
- char logging = 0;
- char socklogging = 0;
SSL_METHOD* method;
SSL_CTX* ctx;
@@ -107,30 +110,41 @@ main(int argc, char **argv)
act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, NULL);
- act.sa_handler = sig_int;
+ act.sa_handler = server_sig_int;
sigaction(SIGINT, &act, NULL);
TYPE_SET_SSL(mode);
TYPE_SET_ZLIB(mode);
+ memset(&config, 0, sizeof(config));
+
config.certif = NULL;
config.keys = NULL;
config.size = 0;
config.realmtable = NULL;
- config.logging = 0;
- config.socklogging = 0;
- config.logfnam = NULL;
- config.logsport = NULL;
config.dateformat = NULL;
+
+#ifdef HAVE_LIBPTHREAD
+ remember_mainthread();
+#endif
#ifdef AF_INET6
- while ((n = getopt_long(argc, argv, "hn:l:m:vu:c:k:f:p:o:O:46t:C:U:M:bD:S:s:R:r:", long_options, 0)) != -1) {
+#define GETOPT_LONG_AF_INET6(x) "46"x
+#else
+#define GETOPT_LONG_AF_INET6(x) x
+#endif
+#ifdef HAVE_LIBPTHREAD
+#define GETOPT_LONG_LIBPTHREAD(x) "P"x
#else
- while ((n = getopt_long(argc, argv, "hn:l:m:vu:c:k:f:p:o:O:t:C:U:M:bD:S:s:R:r:", long_options, 0)) != -1) {
+#define GETOPT_LONG_LIBPTHREAD(x) x
#endif
+
+ while ((n = getopt_long(argc, argv,
+ GETOPT_LONG_LIBPTHREAD(GETOPT_LONG_AF_INET6("hn:l:m:vu:c:k:f:p:o:t:C:U:M:abD:R:r:V"))
+ , long_options, 0)) != -1) {
switch (n) {
case 'h': {
- usage(AF_VER("Active port forwarder (server)"));
+ server_long_usage(AF_VER("Active port forwarder (server)"));
break;
}
case 'n': {
@@ -197,26 +211,10 @@ main(int argc, char **argv)
filenam = optarg;
break;
}
- case 'O': {
- logfnam = optarg;
- logging = 3;
- break;
- }
case 'o': {
- logfnam = optarg;
- logging = 1;
+ addlogtarget(optarg);
break;
}
- case 'S': {
- logsport = optarg;
- socklogging = 3;
- break;
- }
- case 's': {
- logsport = optarg;
- socklogging = 1;
- break;
- }
case 301: {
TYPE_UNSET_SSL(mode);
break;
@@ -258,6 +256,10 @@ main(int argc, char **argv)
baseport = 1;
break;
}
+ case 'a': {
+ audit = 1;
+ break;
+ }
case 311: {
dnslookups = 1;
break;
@@ -266,15 +268,31 @@ main(int argc, char **argv)
dateformat = optarg;
break;
}
+#ifdef HAVE_LIBPTHREAD
+ case 'P': {
+ if (tunneltype != 0) {
+ tunneltype = -1;
+ }
+ else {
+ tunneltype = 1;
+ }
+ break;
+ }
+#endif
+ case 'V': {
+ printf("%s\n", (AF_VER("Active port forwarder (server)")));
+ exit(0);
+ break;
+ }
case '?': {
- usage("");
+ server_short_usage("");
break;
}
}
}
if (optind < argc) {
- usage("Unrecognized non-option elements");
+ server_short_usage("Unrecognized non-option elements");
}
if (filenam != NULL) {
@@ -296,76 +314,38 @@ main(int argc, char **argv)
else {
config.keys = keys;
}
- if (logfnam != NULL) {
- config.logfnam = logfnam;
- }
- if (logsport != NULL) {
- config.logsport = logsport;
- }
if (dateformat != NULL) {
config.dateformat = dateformat;
}
- if (logging != 0) {
- config.logging = logging;
- }
- if (socklogging != 0) {
- config.socklogging = socklogging;
- }
-
- if ((k = loginit(verbose, config.logging, config.socklogging,
- config.logfnam, config.logsport, config.dateformat))) {
- switch (k) {
- case 1:
- printf("Can't open file to log to... exiting\n");
- break;
- case 2:
- printf("Can't connect to localhost:%s... exiting\n", logsport);
- break;
- case 3:
- printf("Can't open socket to log to... exiting\n");
- break;
- }
- exit(1);
- }
+
+ initializelogging(verbose, config.dateformat);
- aflog(1, "cfg file OK! (readed realms: %d)", config.size);
+ aflog(LOG_T_INIT, LOG_I_INFO,
+ "cfg file OK! (readed realms: %d)", config.size);
if (name != NULL)
- aflog(1, "Warning: hostname=%s will be ignored", name);
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: hostname=%s will be ignored", name);
if (listen != NULL)
- aflog(1, "Warning: listenport will be ignored");
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: listenport will be ignored");
if (manage != NULL)
- aflog(1, "Warning: manageport will be ignored");
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: manageport will be ignored");
if (realmname != NULL)
- aflog(1, "Warning: realmname=%s will be ignored", realmname);
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: realmname=%s will be ignored", realmname);
if (sent == 1)
- aflog(1, "Warning: password from command line will be ignored");
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: password from command line will be ignored");
}
}
else {
config.certif = certif;
config.keys = keys;
- config.logfnam = logfnam;
- config.logsport = logsport;
config.dateformat = dateformat;
- config.logging = logging;
- config.socklogging = socklogging;
- if ((k = loginit(verbose, config.logging, config.socklogging,
- config.logfnam, config.logsport, config.dateformat))) {
- switch (k) {
- case 1:
- printf("Can't open file to log to... exiting\n");
- break;
- case 2:
- printf("Can't connect to localhost:%s... exiting\n", logsport);
- break;
- case 3:
- printf("Can't open socket to log to... exiting\n");
- break;
- }
- exit(1);
- }
-
+ initializelogging(verbose, config.dateformat);
+
if (listen == NULL) {
listencount = 1;
listen = calloc(1, sizeof(char*));
@@ -377,7 +357,8 @@ main(int argc, char **argv)
manage[0] = "50126";
}
if (managecount != listencount) {
- aflog(0, "Number of listen and manage options are not the same... exiting");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Number of listen and manage options are not the same... exiting");
exit(1);
}
if (config.certif == NULL) {
@@ -405,6 +386,10 @@ main(int argc, char **argv)
config.realmtable[0].usrpcli = usrpcli;
config.realmtable[0].clim = clim;
config.realmtable[0].baseport = baseport;
+ config.realmtable[0].audit = audit;
+#ifdef HAVE_LIBPTHREAD
+ config.realmtable[0].tunneltype = tunneltype;
+#endif
config.realmtable[0].dnslookups = dnslookups;
config.realmtable[0].realmname = realmname;
memcpy(config.realmtable[0].pass, pass, 4);
@@ -419,7 +404,8 @@ main(int argc, char **argv)
}
#ifdef AF_INET6
if (ipfam == -1) {
- aflog(0, "Conflicting types of ip protocol family... exiting");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Conflicting types of ip protocol family... exiting");
exit(1);
}
else if (ipfam == 4) {
@@ -438,44 +424,56 @@ main(int argc, char **argv)
method = SSLv3_server_method();
ctx = SSL_CTX_new(method);
if (SSL_CTX_set_cipher_list(ctx, "ALL:@STRENGTH") == 0) {
- aflog(0, "Setting ciphers list failed... exiting");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Setting ciphers list failed... exiting");
exit(1);
}
if ((flags = create_apf_dir())) {
- aflog(1, "Warning: Creating ~/.apf directory failed (%d)", flags);
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: Creating ~/.apf directory failed (%d)", flags);
}
if ((flags = generate_rsa_key(&config.keys))) {
- aflog(1, "Warning: Something bad happened when generating rsa keys... (%d)", flags);
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: Something bad happened when generating rsa keys... (%d)", flags);
}
if (SSL_CTX_use_RSAPrivateKey_file(ctx, config.keys, SSL_FILETYPE_PEM) != 1) {
- aflog(0, "Setting rsa key failed (%s)... exiting", config.keys);
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Setting rsa key failed (%s)... exiting", config.keys);
exit(1);
}
if ((flags = generate_certificate(&config.certif, config.keys))) {
- aflog(1, "Warning: Something bad happened when generating certificate... (%d)", flags);
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: Something bad happened when generating certificate... (%d)", flags);
}
if (SSL_CTX_use_certificate_file(ctx, config.certif, SSL_FILETYPE_PEM) != 1) {
- aflog(0, "Setting certificate failed (%s)... exiting", config.certif);
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Setting certificate failed (%s)... exiting", config.certif);
exit(1);
}
if (config.size == 0) {
- aflog(0, "Working without sense is really without sense...");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Working without sense is really without sense...");
exit(1);
}
FD_ZERO(&allset);
FD_ZERO(&wset);
+ if (!verbose)
+ daemon(0, 0);
+
for (i = 0; i < config.size; ++i) {
if (config.realmtable[i].usrclinum == 0) {
- aflog(0, "You have to specify at least one listen port and one manage port in each realm");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "You have to specify at least one listen port and one manage port in each realm");
exit(1);
}
for (j = 0; j < config.realmtable[i].usrclinum; ++j) {
if ((config.realmtable[i].usrclitable[j].lisportnum == NULL) ||
(config.realmtable[i].usrclitable[j].manportnum == NULL)) {
- aflog(0, "Missing some of the variables...\nRealm: %d\nlistenport[%d]: %s\nmanageport[%d]: %s",
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Missing some of the variables...\nRealm: %d\nlistenport[%d]: %s\nmanageport[%d]: %s",
i, j, config.realmtable[i].usrclitable[j].lisportnum,
j, config.realmtable[i].usrclitable[j].manportnum);
exit(1);
@@ -502,7 +500,8 @@ main(int argc, char **argv)
/* using user's value for ipfam*/
if (TYPE_IS_UNSPEC(config.realmtable[i].type)) {
if (ipfam == -1) {
- aflog(0, "Conflicting types of ip protocol family... exiting");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Conflicting types of ip protocol family... exiting");
exit(1);
}
else if (ipfam == 4) {
@@ -524,6 +523,21 @@ main(int argc, char **argv)
if (config.realmtable[i].baseport == 0) {
config.realmtable[i].baseport = baseport;
}
+ /* using user's audit value*/
+ if (config.realmtable[i].audit == 0) {
+ config.realmtable[i].audit = audit;
+ }
+#ifdef HAVE_LIBPTHREAD
+ /* using user's tunneltype value*/
+ if (config.realmtable[i].tunneltype == 0) {
+ if (tunneltype == -1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Conflicting types of tunnel type... exiting");
+ exit(1);
+ }
+ config.realmtable[i].tunneltype = tunneltype;
+ }
+#endif
/* using user's dnslookups value*/
if (config.realmtable[i].dnslookups == 0) {
config.realmtable[i].dnslookups = dnslookups;
@@ -549,17 +563,20 @@ main(int argc, char **argv)
/* allocating memory*/
config.realmtable[i].contable = calloc( config.realmtable[i].usernum, sizeof(ConnectuserT));
if (config.realmtable[i].contable == NULL) {
- aflog(0, "Calloc error - try define smaller amount of users");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Calloc error - try define smaller amount of users");
exit(1);
}
config.realmtable[i].clitable = calloc( config.realmtable[i].clinum, sizeof(ConnectclientT));
if (config.realmtable[i].clitable == NULL) {
- aflog(0, "Calloc error - try define smaller amount of clients");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Calloc error - try define smaller amount of clients");
exit(1);
}
config.realmtable[i].raclitable = calloc( config.realmtable[i].raclinum, sizeof(ConnectclientT));
if (config.realmtable[i].raclitable == NULL) {
- aflog(0, "Calloc error - try define smaller amount of raclients");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Calloc error - try define smaller amount of raclients");
exit(1);
}
ipfam = 0x01;
@@ -575,7 +592,7 @@ main(int argc, char **argv)
for (j = 0; j < config.realmtable[i].usrclinum; ++j) {
if (ip_listen(&(config.realmtable[i].usrclitable[j].listenfd), config.realmtable[i].hostname,
config.realmtable[i].usrclitable[j].lisportnum, (&(config.realmtable[i].addrlen)), ipfam)) {
- aflog(0,
+ aflog(LOG_T_INIT, LOG_I_CRIT,
#ifdef AF_INET6
"tcp_listen_%s error for %s, %s",
(ipfam & 0x02)?"ipv4":(ipfam & 0x04)?"ipv6":"unspec",
@@ -585,28 +602,65 @@ main(int argc, char **argv)
config.realmtable[i].hostname, config.realmtable[i].usrclitable[j].lisportnum);
exit(1);
}
+ flags = fcntl(config.realmtable[i].usrclitable[j].listenfd, F_GETFL, 0);
+ fcntl(config.realmtable[i].usrclitable[j].listenfd, F_SETFL, flags | O_NONBLOCK);
}
}
for (j = 0; j < config.realmtable[i].usrclinum; ++j) {
- if (ip_listen(&(config.realmtable[i].usrclitable[j].managefd), config.realmtable[i].hostname,
- config.realmtable[i].usrclitable[j].manportnum, (&(config.realmtable[i].addrlen)), ipfam)) {
- aflog(0,
+ switch (config.realmtable[i].tunneltype) {
+ case 0: {
+ if (ip_listen(&(config.realmtable[i].usrclitable[j].managefd), config.realmtable[i].hostname,
+ config.realmtable[i].usrclitable[j].manportnum, (&(config.realmtable[i].addrlen)), ipfam)) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
#ifdef AF_INET6
- "tcp_listen_%s error for %s, %s",
- (ipfam & 0x02)?"ipv4":(ipfam & 0x04)?"ipv6":"unspec",
+ "tcp_listen_%s error for %s, %s",
+ (ipfam & 0x02)?"ipv4":(ipfam & 0x04)?"ipv6":"unspec",
#else
- "tcp_listen error for %s, %s",
+ "tcp_listen error for %s, %s",
#endif
- config.realmtable[i].hostname, config.realmtable[i].usrclitable[j].manportnum);
- exit(1);
- }
+ config.realmtable[i].hostname, config.realmtable[i].usrclitable[j].manportnum);
+ exit(1);
+ }
+ flags = fcntl(config.realmtable[i].usrclitable[j].managefd, F_GETFL, 0);
+ fcntl(config.realmtable[i].usrclitable[j].managefd, F_SETFL, flags | O_NONBLOCK);
+ break;
+ }
+#ifdef HAVE_LIBPTHREAD
+ case 1: {
+ if (initialize_http_proxy_server(&(config.realmtable[i].usrclitable[j].managefd),
+ config.realmtable[i].hostname, config.realmtable[i].usrclitable[j].manportnum,
+ (&(config.realmtable[i].addrlen)), ipfam,
+ config.realmtable[i].clinum + config.realmtable[i].raclinum)) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+#ifdef AF_INET6
+ "http_proxy_listen_%s error for %s, %s",
+ (ipfam & 0x02)?"ipv4":(ipfam & 0x04)?"ipv6":"unspec",
+#else
+ "http_proxy_listen error for %s, %s",
+#endif
+ config.realmtable[i].hostname, config.realmtable[i].usrclitable[j].manportnum);
+ exit(1);
+ }
+ flags = fcntl(config.realmtable[i].usrclitable[j].managefd, F_GETFL, 0);
+ fcntl(config.realmtable[i].usrclitable[j].managefd, F_SETFL, flags | O_NONBLOCK);
+ break;
+ }
+#endif
+ default: {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Unknown tunnel type");
+ exit(1);
+ break;
+ }
+ }
}
config.realmtable[i].cliaddr = malloc(config.realmtable[i].addrlen);
for (j=0; j<config.realmtable[i].clinum; ++j) {
config.realmtable[i].clitable[j].cliconn.ssl = SSL_new(ctx);
if (config.realmtable[i].clitable[j].cliconn.ssl == NULL) {
- aflog(0, "Creating of ssl object failed... exiting");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Creating of ssl object failed... exiting");
exit(1);
}
}
@@ -614,7 +668,8 @@ main(int argc, char **argv)
for (j=0; j<config.realmtable[i].raclinum; ++j) {
config.realmtable[i].raclitable[j].cliconn.ssl = SSL_new(ctx);
if (config.realmtable[i].raclitable[j].cliconn.ssl == NULL) {
- aflog(0, "Creating of ssl object failed... exiting");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Creating of ssl object failed... exiting");
exit(1);
}
}
@@ -639,7 +694,8 @@ main(int argc, char **argv)
config.realmtable[i].clitable[j].usernum = config.realmtable[i].upcnum;
config.realmtable[i].clitable[j].users = malloc( config.realmtable[i].clitable[j].usernum * sizeof(int));
if (config.realmtable[i].clitable[j].users == NULL) {
- aflog(0, "Calloc error - try define smaller amount of usrpcli (or users)");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Calloc error - try define smaller amount of usrpcli (or users)");
exit(1);
}
for (k=0; k<config.realmtable[i].clitable[j].usernum; ++k) {
@@ -651,16 +707,15 @@ main(int argc, char **argv)
}
}
- if (!verbose)
- daemon(0, 0);
-
- aflog(1, "SERVER STARTED realms: %d", config.size);
+ aflog(LOG_T_MAIN, LOG_I_INFO,
+ "SERVER STARTED realms: %d", config.size);
time(&config.starttime);
for ( ; ; ) {
rset = allset;
tmpset = wset;
- aflog(3, ">select, maxfdp1: %d", maxfdp1);
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "select, maxfdp1: %d", maxfdp1);
if (manconnecting) {
/* find out, in what realm client is trying to connect */
l = -1;
@@ -692,7 +747,8 @@ main(int argc, char **argv)
config.realmtable[i].clitable[j].ready = 0;
manconnecting--;
config.realmtable[i].clicon--;
- aflog(1, " realm[%s]: Client[%s]: SSL_accept failed (timeout)",
+ aflog(LOG_T_CLIENT, LOG_I_WARNING,
+ "realm[%s]: Client[%s]: SSL_accept failed (timeout)",
get_realmname(&config, i), get_clientname(pointer, j));
}
}
@@ -704,7 +760,8 @@ main(int argc, char **argv)
config.realmtable[i].raclitable[j].ready = 0;
manconnecting--;
config.realmtable[i].clicon--;
- aflog(1, " realm[%s]: Client[%s] (ra): SSL_accept failed (timeout)",
+ aflog(LOG_T_CLIENT, LOG_I_WARNING,
+ "realm[%s]: Client[%s] (ra): SSL_accept failed (timeout)",
get_realmname(&config, i), get_raclientname(pointer, j));
}
}
@@ -712,7 +769,8 @@ main(int argc, char **argv)
else {
select(maxfdp1, &rset, &tmpset, NULL, NULL);
}
- aflog(3, " >>after select...");
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "after select...");
for (j = 0; j < config.size; ++j) {
pointer = (&(config.realmtable[j]));
@@ -720,23 +778,27 @@ main(int argc, char **argv)
if ((pointer->contable[i].state == S_STATE_OPEN) || (pointer->contable[i].state == S_STATE_STOPPED))
if (FD_ISSET(pointer->contable[i].connfd, &rset)) {
k = eval_usernum(&(pointer->clitable[pointer->contable[i].whatcli]), i);
- aflog(3, " realm[%s]: Client[%s]: user[%d]: FD_ISSET", get_realmname(&config, j),
- get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, k));
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: user[%d]: FD_ISSET", get_realmname(&config, j),
+ get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, i));
if (TYPE_IS_TCP(pointer->type)) { /* forwarding tcp packets */
n = read(pointer->contable[i].connfd, &buff[5], 8091);
if (n == -1) {
if (errno == EAGAIN) {
continue;
}
- aflog(3, " realm[%s]: Client[%s]: user[%d]: READ ERROR (%d)", get_realmname(&config, j),
- get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, k), errno);
+ aflog(LOG_T_USER, LOG_I_ERR,
+ "realm[%s]: Client[%s]: user[%d]: READ ERROR (%d)", get_realmname(&config, j),
+ get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, i), errno);
n = 0;
}
if (n) {
- aflog(2, " realm[%s]: Client[%s]: FROM user[%d]: MESSAGE length=%d", get_realmname(&config, j),
- get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, k), n);
+ aflog(LOG_T_USER, LOG_I_DEBUG,
+ "realm[%s]: Client[%s]: FROM user[%d]: MESSAGE length=%d", get_realmname(&config, j),
+ get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, i), n);
if ((buff[5] == AF_S_MESSAGE) && (buff[6] == AF_S_LOGIN) && (buff[7] == AF_S_MESSAGE)) {
- aflog(2, " WARNING: got packet similiar to udp");
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "WARNING: got packet similiar to udp");
}
buff[0] = AF_S_MESSAGE; /* sending message */
buff[1] = k >> 8; /* high bits of user number */
@@ -746,10 +808,26 @@ main(int argc, char **argv)
send_message(pointer->type, pointer->clitable[pointer->contable[i].whatcli].cliconn, buff, n+5);
}
else {
- aflog(1, " realm[%s]: Client[%s]: user[%d]: CLOSED", get_realmname(&config, j),
- get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, k));
- aflog(2, " IP:%s PORT:%s", pointer->contable[i].namebuf,
- pointer->contable[i].portbuf);
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: Client[%s]: user[%d]: CLOSED", get_realmname(&config, j),
+ get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, i));
+ time(&now);
+ aflog(LOG_T_USER, LOG_I_NOTICE,
+ "REALM: %s CLIENT: %s USER: %d IP: %s PORT: %s DURATION: %s",
+ get_realmname(&config, j),
+ get_clientname(pointer, pointer->contable[i].whatcli),
+ get_username(pointer, i),
+ pointer->contable[i].namebuf,
+ pointer->contable[i].portbuf,
+ timeperiod(now - pointer->contable[i].connecttime));
+ if (pointer->audit) {
+ insertalnode(&(pointer->clitable[pointer->contable[i].whatcli].head),
+ get_username(pointer, i),
+ pointer->contable[i].namebuf,
+ pointer->contable[i].portbuf,
+ pointer->contable[i].connecttime,
+ now - pointer->contable[i].connecttime);
+ }
close(pointer->contable[i].connfd);
FD_CLR(pointer->contable[i].connfd, &allset);
FD_CLR(pointer->contable[i].connfd, &wset);
@@ -772,9 +850,10 @@ main(int argc, char **argv)
length = length << 8;
length += buff[4]; /* this is length of message */
if ((n = readn(pointer->contable[i].connfd, &buff[5], length)) != 0) {
- aflog(2, " realm[%s]: Client[%s]: FROM user[%d]: MESSAGE length=%d",
+ aflog(LOG_T_USER, LOG_I_DEBUG,
+ "realm[%s]: Client[%s]: FROM user[%d]: MESSAGE length=%d",
get_realmname(&config, j), get_clientname(pointer, pointer->contable[i].whatcli),
- get_username(pointer, k), n);
+ get_username(pointer, i), n);
buff[1] = k >> 8; /* high bits of user number */
buff[2] = k; /* low bits of user number */
send_message(pointer->type, pointer->clitable[pointer->contable[i].whatcli].cliconn,
@@ -787,10 +866,18 @@ main(int argc, char **argv)
}
if (n == 0) {
- aflog(1, " realm[%s]: Client[%s]: user[%d]: CLOSED (udp mode)", get_realmname(&config, j),
- get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, k));
- aflog(2, " IP:%s PORT:%s", pointer->contable[i].namebuf,
- pointer->contable[i].portbuf);
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: Client[%s]: user[%d]: CLOSED (udp mode)", get_realmname(&config, j),
+ get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, i));
+ time(&now);
+ aflog(LOG_T_USER, LOG_I_NOTICE,
+ "REALM: %s CLIENT: %s USER: %d IP: %s PORT: %s DURATION: %s",
+ get_realmname(&config, j),
+ get_clientname(pointer, pointer->contable[i].whatcli),
+ get_username(pointer, i),
+ pointer->contable[i].namebuf,
+ pointer->contable[i].portbuf,
+ timeperiod(now - pointer->contable[i].connecttime));
close(pointer->contable[i].connfd);
FD_CLR(pointer->contable[i].connfd, &allset);
FD_CLR(pointer->contable[i].connfd, &wset);
@@ -810,24 +897,36 @@ main(int argc, char **argv)
if (pointer->contable[i].state == S_STATE_STOPPED)
if (FD_ISSET(pointer->contable[i].connfd, &tmpset)) {
k = eval_usernum(&(pointer->clitable[pointer->contable[i].whatcli]), i);
- aflog(3, " realm[%s]: Client[%s]: user[%d]: FD_ISSET - WRITE", get_realmname(&config, j),
- get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, k));
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: user[%d]: FD_ISSET - WRITE", get_realmname(&config, j),
+ get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, i));
n = pointer->contable[i].head->msglen - pointer->contable[i].head->actptr;
sent = write(pointer->contable[i].connfd,
&(pointer->contable[i].head->buff[pointer->contable[i].head->actptr]), n);
if ((sent > 0) && (sent != n)) {
pointer->contable[i].head->actptr+=sent;
- aflog(3, " realm[%s]: Client[%s]: user[%d]: (%d/%d)", get_realmname(&config, j),
- get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, k), sent, n);
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: user[%d]: (%d/%d)", get_realmname(&config, j),
+ get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, i), sent, n);
}
else if ((sent == -1) && (errno == EAGAIN)) {
- aflog(3, " realm[%s]: Client[%s]: user[%d]: EAGAIN", get_realmname(&config, j),
- get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, k));
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: user[%d]: EAGAIN", get_realmname(&config, j),
+ get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, i));
}
else if (sent == -1) {
- aflog(1, " realm[%s]: Client[%s]: user[%d]: CLOSED", get_realmname(&config, j),
- get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, k));
- aflog(2, " IP:%s PORT:%s", pointer->contable[i].namebuf, pointer->contable[i].portbuf);
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: Client[%s]: user[%d]: CLOSED", get_realmname(&config, j),
+ get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, i));
+ time(&now);
+ aflog(LOG_T_USER, LOG_I_NOTICE,
+ "REALM: %s CLIENT: %s USER: %d IP: %s PORT: %s DURATION: %s",
+ get_realmname(&config, j),
+ get_clientname(pointer, pointer->contable[i].whatcli),
+ get_username(pointer, i),
+ pointer->contable[i].namebuf,
+ pointer->contable[i].portbuf,
+ timeperiod(now - pointer->contable[i].connecttime));
close(pointer->contable[i].connfd);
FD_CLR(pointer->contable[i].connfd, &allset);
FD_CLR(pointer->contable[i].connfd, &wset);
@@ -839,8 +938,9 @@ main(int argc, char **argv)
send_message(pointer->type, pointer->clitable[pointer->contable[i].whatcli].cliconn, buff, 5);
}
else {
- aflog(3, " realm[%s]: Client[%s]: user[%d]: (%d/%d)", get_realmname(&config, j),
- get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, k), sent, n);
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: user[%d]: (%d/%d)", get_realmname(&config, j),
+ get_clientname(pointer, pointer->contable[i].whatcli), get_username(pointer, i), sent, n);
deleteblnode(&pointer->contable[i].head);
if (pointer->contable[i].head == NULL) {
pointer->contable[i].state = S_STATE_OPEN;
@@ -848,9 +948,10 @@ main(int argc, char **argv)
buff[0] = AF_S_CAN_SEND; /* stopping transfer */
buff[1] = k >> 8; /* high bits of user number */
buff[2] = k; /* low bits of user number */
- aflog(3, " realm[%s]: Client[%s]: TO user[%d]: BUFFERING MESSAGE ENDED",
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: TO user[%d]: BUFFERING MESSAGE ENDED",
get_realmname(&config, j), get_clientname(pointer, pointer->contable[i].whatcli),
- get_username(pointer, k));
+ get_username(pointer, i));
send_message(pointer->type, pointer->clitable[pointer->contable[i].whatcli].cliconn, buff, 5);
}
}
@@ -862,18 +963,26 @@ main(int argc, char **argv)
if (FD_ISSET(pointer->usrclitable[l].listenfd, &rset)) {
len = pointer->addrlen;
sent = accept(pointer->usrclitable[l].listenfd, pointer->cliaddr, &len);
+ if (sent == -1) {
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: listenfd: FD_ISSET --> EAGAIN", get_realmname(&config, j));
+ continue;
+ }
flags = fcntl(sent, F_GETFL, 0);
fcntl(sent, F_SETFL, flags | O_NONBLOCK);
- aflog(3, " realm[%s]: listenfd: FD_ISSET", get_realmname(&config, j));
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: listenfd: FD_ISSET", get_realmname(&config, j));
k = find_client(pointer, pointer->climode, l);
if (pointer->clitable[k].ready == 3) {
if (pointer->usercon == pointer->usernum) {
close(sent);
- aflog(3, " realm[%s]: user limit EXCEEDED", get_realmname(&config, j));
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "realm[%s]: user limit EXCEEDED", get_realmname(&config, j));
}
else if(pointer->clitable[k].usercon == pointer->clitable[k].usernum) {
close(sent);
- aflog(3, " realm[%s]: Client[%s]: usrpcli limit EXCEEDED",
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "realm[%s]: Client[%s]: usrpcli limit EXCEEDED",
get_realmname(&config, j), get_clientname(pointer, k));
}
else {
@@ -881,7 +990,8 @@ main(int argc, char **argv)
if (pointer->contable[i].state == S_STATE_CLEAR) {
pointer->contable[i].userid = pointer->usercounter;
++(pointer->usercounter);
- aflog(1, " realm[%s]: Client[%s]: new user: CONNECTING from IP: %s",
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: Client[%s]: new user: CONNECTING from IP: %s",
get_realmname(&config, j), get_clientname(pointer, k),
sock_ntop(pointer->cliaddr, len, pointer->contable[i].namebuf,
pointer->contable[i].portbuf, pointer->dnslookups));
@@ -908,7 +1018,8 @@ main(int argc, char **argv)
}
else {
close(sent);
- aflog(3, " realm[%s]: Client(%d) is NOT CONNECTED",
+ aflog(LOG_T_USER, LOG_I_ERR,
+ "realm[%s]: Client(%d) is NOT CONNECTED",
get_realmname(&config, j), k);
}
}
@@ -921,18 +1032,26 @@ main(int argc, char **argv)
if (FD_ISSET(pointer->clitable[k].listenfd, &rset)) {
len = pointer->addrlen;
sent = accept(pointer->clitable[k].listenfd, pointer->cliaddr, &len);
+ if (sent == -1) {
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: listenfd: FD_ISSET --> EAGAIN", get_realmname(&config, j));
+ continue;
+ }
flags = fcntl(sent, F_GETFL, 0);
fcntl(sent, F_SETFL, flags | O_NONBLOCK);
- aflog(3, " realm[%s]: Client[%s]: listenfd: FD_ISSET",
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: listenfd: FD_ISSET",
get_realmname(&config, j), get_clientname(pointer, k));
if (pointer->clitable[k].ready == 3) {
if (pointer->usercon == pointer->usernum) {
close(sent);
- aflog(3, " realm[%s]: user limit EXCEEDED", get_realmname(&config, j));
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "realm[%s]: user limit EXCEEDED", get_realmname(&config, j));
}
else if(pointer->clitable[k].usercon == pointer->clitable[k].usernum) {
close(sent);
- aflog(3, " realm[%s]: Client[%s]: usrpcli limit EXCEEDED",
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "realm[%s]: Client[%s]: usrpcli limit EXCEEDED",
get_realmname(&config, j), get_clientname(pointer, k));
}
else {
@@ -940,7 +1059,8 @@ main(int argc, char **argv)
if (pointer->contable[i].state == S_STATE_CLEAR) {
pointer->contable[i].userid = pointer->usercounter;
++(pointer->usercounter);
- aflog(1, " realm[%s]: Client[%s]: new user: CONNECTING from IP: %s",
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: Client[%s]: new user: CONNECTING from IP: %s",
get_realmname(&config, j), get_clientname(pointer, k),
sock_ntop(pointer->cliaddr, len, pointer->contable[i].namebuf, pointer->contable[i].portbuf, pointer->dnslookups));
pointer->contable[i].connfd = sent;
@@ -970,7 +1090,8 @@ main(int argc, char **argv)
if ((pointer->clitable[k].ready != 0) && (FD_ISSET(pointer->clitable[k].cliconn.commfd, &rset))) {
if (pointer->clitable[k].ready == 1) {
make_ssl_initialize(&(pointer->clitable[k].cliconn));
- aflog(2, " realm[%s]: new Client[%s]: SSL_accept",
+ aflog(LOG_T_CLIENT, LOG_I_DDEBUG,
+ "realm[%s]: new Client[%s]: SSL_accept",
get_realmname(&config, j), get_clientname(pointer, k));
switch (make_ssl_accept(&(pointer->clitable[k].cliconn))) {
case 2: {
@@ -980,21 +1101,24 @@ main(int argc, char **argv)
pointer->clitable[k].ready = 0;
manconnecting--;
pointer->clicon--;
- aflog(1, " realm[%s]: new Client[%s]: DENIED by SSL_accept",
+ aflog(LOG_T_CLIENT, LOG_I_ERR,
+ "realm[%s]: new Client[%s]: DENIED by SSL_accept",
get_realmname(&config, j), get_clientname(pointer, k));
}
case 1: {
continue;
}
default: {
- aflog(1, " realm[%s]: new Client[%s]: ACCEPTED by SSL_accept",
+ aflog(LOG_T_CLIENT, LOG_I_DEBUG,
+ "realm[%s]: new Client[%s]: ACCEPTED by SSL_accept",
get_realmname(&config, j), get_clientname(pointer, k));
pointer->clitable[k].ready = 2;
continue;
}
}
}
- aflog(3, " realm[%s]: Client[%s]: commfd: FD_ISSET",
+ aflog(LOG_T_CLIENT, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: commfd: FD_ISSET",
get_realmname(&config, j), get_clientname(pointer, k));
if (pointer->clitable[k].ready == 2) {
n = get_message(pointer->type | TYPE_SSL | TYPE_ZLIB, pointer->clitable[k].cliconn, buff, -5);
@@ -1004,27 +1128,51 @@ main(int argc, char **argv)
}
if (n == -1) {
if (errno == EAGAIN) {
- aflog(4, " realm[%s]: Client[%s]: commfd: EAGAIN",
+ aflog(LOG_T_CLIENT, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: commfd: EAGAIN",
get_realmname(&config, j), get_clientname(pointer, k));
continue;
}
else {
- aflog(4, " realm[%s]: Client[%s]: commfd: ERROR: %d",
+ aflog(LOG_T_CLIENT, LOG_I_ERR,
+ "realm[%s]: Client[%s]: commfd: ERROR: %d",
get_realmname(&config, j), get_clientname(pointer, k), errno);
n = 0;
}
}
else if (n != 5) {
if (n != 0) {
- aflog(4, " realm[%s]: Client[%s]: header length = %d --> closing client",
+ aflog(LOG_T_CLIENT, LOG_I_ERR,
+ "realm[%s]: Client[%s]: header length = %d --> closing client",
get_realmname(&config, j), get_clientname(pointer, k), n);
}
n = 0;
}
if (n==0) {
- remove_client(pointer, k, &allset, &wset, &manconnecting);
- aflog(1, " realm[%s]: Client[%s]: commfd: CLOSED",
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "realm[%s]: Client[%s]: commfd: CLOSED",
get_realmname(&config, j), get_clientname(pointer, k));
+ time(&now);
+ aflog(LOG_T_CLIENT, LOG_I_NOTICE,
+ "REALM: %s CLIENT: %s IP: %s PORT: %s DURATION: %s",
+ get_realmname(&config, j),
+ get_clientname(pointer, k),
+ pointer->clitable[k].namebuf,
+ pointer->clitable[k].portbuf,
+ timeperiod(now - pointer->clitable[k].connecttime));
+ if (pointer->audit) {
+ while (pointer->clitable[k].head) {
+ aflog(LOG_T_CLIENT, LOG_I_NOTICE,
+ "USERID: %d IP: %s PORT: %s CONNECTED: %s DURATION: %s",
+ pointer->clitable[k].head->userid,
+ pointer->clitable[k].head->namebuf,
+ pointer->clitable[k].head->portbuf,
+ localdate(&(pointer->clitable[k].head->connecttime)),
+ timeperiod(pointer->clitable[k].head->duration));
+ deletealnode(&(pointer->clitable[k].head));
+ }
+ }
+ remove_client(pointer, k, &allset, &wset, &manconnecting);
continue;
}
@@ -1040,7 +1188,8 @@ main(int argc, char **argv)
buff[0] = AF_S_WRONG;
}
if (pointer->clitable[k].ready<2) {
- aflog(1, " realm[%s]: Client[%s]: Impossible behaviour --> ignoring",
+ aflog(LOG_T_CLIENT, LOG_I_WARNING,
+ "realm[%s]: Client[%s]: Impossible behaviour --> ignoring",
get_realmname(&config, j), get_clientname(pointer, k));
continue;
}
@@ -1058,15 +1207,23 @@ main(int argc, char **argv)
pointer->clitable[k].users[n] = -1;
if (pointer->contable[numofcon].state == S_STATE_CLOSING) {
pointer->contable[numofcon].state = S_STATE_CLEAR;
- aflog(3, " realm[%s]: user[%d]: CLOSE CONFIRMED",
+ aflog(LOG_T_USER, LOG_I_DEBUG,
+ "realm[%s]: user[%d]: CLOSE CONFIRMED",
get_realmname(&config, j), get_username(pointer, numofcon));
}
else if ((pointer->contable[numofcon].state == S_STATE_OPEN) ||
(pointer->contable[numofcon].state == S_STATE_STOPPED)) {
- aflog(1, " realm[%s]: user[%d]: KICKED",
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: user[%d]: KICKED",
get_realmname(&config, j), get_username(pointer, numofcon));
- aflog(2, " IP:%s PORT:%s", pointer->contable[numofcon].namebuf,
- pointer->contable[numofcon].portbuf);
+ time(&now);
+ aflog(LOG_T_USER, LOG_I_NOTICE,
+ "REALM: %s USER: %d IP: %s PORT: %s DURATION: %s",
+ get_realmname(&config, j),
+ get_username(pointer, numofcon),
+ pointer->contable[numofcon].namebuf,
+ pointer->contable[numofcon].portbuf,
+ timeperiod(now - pointer->contable[numofcon].connecttime));
close(pointer->contable[numofcon].connfd);
FD_CLR(pointer->contable[numofcon].connfd, &allset);
FD_CLR(pointer->contable[numofcon].connfd, &wset);
@@ -1087,7 +1244,8 @@ main(int argc, char **argv)
numofcon = eval_numofcon(pointer, k, numofcon);
if ((numofcon>=0) && (numofcon<(pointer->usernum)) && ((pointer->clitable[k].ready)==3)) {
if (pointer->contable[numofcon].state == S_STATE_OPENING) {
- aflog(2, " realm[%s]: user[%d]: NEW",
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: user[%d]: NEW",
get_realmname(&config, j), get_username(pointer, numofcon));
FD_SET(pointer->contable[numofcon].connfd, &allset);
maxfdp1 = (maxfdp1 > (pointer->contable[numofcon].connfd+1)) ?
@@ -1105,7 +1263,8 @@ main(int argc, char **argv)
numofcon = eval_numofcon(pointer, k, numofcon);
if ((numofcon>=0) && (numofcon<(pointer->usernum)) && ((pointer->clitable[k].ready)==3)) {
if (pointer->contable[numofcon].state == S_STATE_OPENING) {
- aflog(2, " realm[%s]: user[%d]: DROPPED",
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: user[%d]: DROPPED",
get_realmname(&config, j), get_username(pointer, numofcon));
pointer->usercon--;
pointer->clitable[k].usercon--;
@@ -1133,7 +1292,8 @@ main(int argc, char **argv)
numofcon = eval_numofcon(pointer, k, numofcon);
if ((numofcon>=0) && (numofcon<(pointer->usernum))) {
if (pointer->contable[numofcon].state == S_STATE_OPEN) {
- aflog(2, " realm[%s]: TO user[%d]: MESSAGE length=%d",
+ aflog(LOG_T_USER, LOG_I_DEBUG,
+ "realm[%s]: TO user[%d]: MESSAGE length=%d",
get_realmname(&config, j), get_username(pointer, numofcon), n);
if (TYPE_IS_UDP(pointer->type)) { /* udp */
buff[1] = AF_S_LOGIN;
@@ -1142,10 +1302,17 @@ main(int argc, char **argv)
buff[4] = n; /* low bits of message length */
sent = write(pointer->contable[numofcon].connfd, buff, n+5);
if (sent == -1) {
- aflog(1, " realm[%s]: user[%d]: CLOSED (write-udp)",
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: user[%d]: CLOSED (write-udp)",
get_realmname(&config, j), get_username(pointer, numofcon));
- aflog(2, " IP:%s PORT:%s", pointer->contable[numofcon].namebuf,
- pointer->contable[numofcon].portbuf);
+ time(&now);
+ aflog(LOG_T_USER, LOG_I_NOTICE,
+ "REALM: %s USER: %d IP: %s PORT: %s DURATION: %s",
+ get_realmname(&config, j),
+ get_username(pointer, numofcon),
+ pointer->contable[numofcon].namebuf,
+ pointer->contable[numofcon].portbuf,
+ timeperiod(now - pointer->contable[numofcon].connecttime));
close(pointer->contable[numofcon].connfd);
FD_CLR(pointer->contable[numofcon].connfd, &allset);
FD_CLR(pointer->contable[numofcon].connfd, &wset);
@@ -1166,7 +1333,8 @@ main(int argc, char **argv)
buff[0] = AF_S_DONT_SEND; /* stopping transfer */
buff[1] = numofcon >> 8; /* high bits of user number */
buff[2] = numofcon; /* low bits of user number */
- aflog(3, " realm[%s]: TO user[%d]: BUFFERING MESSAGE STARTED (%d/%d)",
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: TO user[%d]: BUFFERING MESSAGE STARTED (%d/%d)",
get_realmname(&config, j), get_username(pointer, numofcon), sent, n);
send_message(pointer->type, pointer->clitable[k].cliconn, buff, 5);
}
@@ -1177,15 +1345,23 @@ main(int argc, char **argv)
buff[0] = AF_S_DONT_SEND; /* stopping transfer */
buff[1] = numofcon >> 8; /* high bits of user number */
buff[2] = numofcon; /* low bits of user number */
- aflog(3, " realm[%s]: TO user[%d]: BUFFERING MESSAGE STARTED (%d/%d)",
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: TO user[%d]: BUFFERING MESSAGE STARTED (%d/%d)",
get_realmname(&config, j), get_username(pointer, numofcon), sent, n);
send_message(pointer->type, pointer->clitable[k].cliconn, buff, 5);
}
else if (sent == -1) {
- aflog(1, " realm[%s]: user[%d]: CLOSED (write-tcp)",
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: user[%d]: CLOSED (write-tcp)",
get_realmname(&config, j), get_username(pointer, numofcon));
- aflog(2, " IP:%s PORT:%s", pointer->contable[numofcon].namebuf,
- pointer->contable[numofcon].portbuf);
+ time(&now);
+ aflog(LOG_T_USER, LOG_I_NOTICE,
+ "REALM: %s USER: %d IP: %s PORT: %s DURATION: %s",
+ get_realmname(&config, j),
+ get_username(pointer, numofcon),
+ pointer->contable[numofcon].namebuf,
+ pointer->contable[numofcon].portbuf,
+ timeperiod(now - pointer->contable[numofcon].connecttime));
close(pointer->contable[numofcon].connfd);
FD_CLR(pointer->contable[numofcon].connfd, &allset);
FD_CLR(pointer->contable[numofcon].connfd, &wset);
@@ -1199,7 +1375,8 @@ main(int argc, char **argv)
}
}
else if (pointer->contable[numofcon].state == S_STATE_STOPPED) {
- aflog(3, " realm[%s]: TO user[%d]: BUFFERING MESSAGE (%d)",
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: TO user[%d]: BUFFERING MESSAGE (%d)",
get_realmname(&config, j), get_username(pointer, numofcon), n);
if (TYPE_IS_UDP(pointer->type)) { /* udp */
buff[1] = AF_S_LOGIN;
@@ -1213,7 +1390,8 @@ main(int argc, char **argv)
}
}
else if (pointer->contable[numofcon].state == S_STATE_CLOSING) {
- aflog(3, " realm[%s]: TO user[%d]: IGNORED message length=%d",
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "realm[%s]: TO user[%d]: IGNORED message length=%d",
get_realmname(&config, j), get_username(pointer, numofcon), n);
}
}
@@ -1224,7 +1402,8 @@ main(int argc, char **argv)
(length==(pointer->pass[2]*256+pointer->pass[3]))) {
if (k != pointer->clinum) {
pointer->clitable[k].ready = 3;
- aflog(1, " realm[%s]: Client[%s]: pass ok - ACCESS GRANTED",
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "realm[%s]: Client[%s]: pass ok - ACCESS GRANTED",
get_realmname(&config, j), get_clientname(pointer, k));
buff[0] = AF_S_LOGIN; /* sending message */
buff[1] = pointer->clitable[k].usernum >> 8;/* high bits of user number */
@@ -1236,7 +1415,8 @@ main(int argc, char **argv)
long tmp_val;
char tmp_tab[6];
if (check_long(pointer->usrclitable[pointer->clitable[k].whatusrcli].lisportnum, &tmp_val)) {
- aflog(1, " realm[%s]: INVALID listenport - removing Client[%s]",
+ aflog(LOG_T_CLIENT, LOG_I_ERR,
+ "realm[%s]: INVALID listenport - removing Client[%s]",
get_realmname(&config, j), get_clientname(pointer, k));
remove_client(pointer, k, &allset, &wset, &manconnecting);
break;
@@ -1262,12 +1442,14 @@ main(int argc, char **argv)
FD_SET(pointer->clitable[k].listenfd, &allset);
maxfdp1 = (maxfdp1 > (pointer->clitable[k].listenfd+1)) ?
maxfdp1 : (pointer->clitable[k].listenfd+1);
- aflog(1, " realm[%s]: Client[%s]: listenport=%s",
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "realm[%s]: Client[%s]: listenport=%s",
get_realmname(&config, j), get_clientname(pointer, k), tmp_tab);
}
}
else {
- aflog(3, " realm[%s]: client limit EXCEEDED", get_realmname(&config, j));
+ aflog(LOG_T_CLIENT, LOG_I_WARNING,
+ "realm[%s]: client limit EXCEEDED", get_realmname(&config, j));
buff[0] = AF_S_CANT_OPEN; /* sending message */
send_message(pointer->type | TYPE_SSL, pointer->clitable[k].cliconn, buff, 5);
remove_client(pointer, k, &allset, &wset, &manconnecting);
@@ -1276,7 +1458,8 @@ main(int argc, char **argv)
else if ((pointer->clitable[k].ready == 3) && (numofcon == 0)) {
n = get_message(pointer->type, pointer->clitable[k].cliconn, buff, length);
buff[n] = 0;
- aflog(1, " realm[%s]: Client[%s]: ID received: %s",
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "realm[%s]: Client[%s]: ID received: %s",
get_realmname(&config, j), get_clientname(pointer, k), buff);
if (pointer->clitable[k].clientid) {
free(pointer->clitable[k].clientid);
@@ -1287,26 +1470,32 @@ main(int argc, char **argv)
}
}
else {
- aflog(1, " realm[%s]: Client[%s]: Wrong password - CLOSING",
+ aflog(LOG_T_CLIENT, LOG_I_ERR,
+ "realm[%s]: Client[%s]: Wrong password - CLOSING",
get_realmname(&config, j), get_clientname(pointer, k));
+ buff[0] = AF_S_WRONG; /* sending message */
+ send_message(pointer->type | TYPE_SSL, pointer->clitable[k].cliconn, buff, 5);
remove_client(pointer, k, &allset, &wset, &manconnecting);
}
break;
}
case AF_S_DONT_SEND: {
- aflog(3, " realm[%s]: user[%d]: STOP READING",
+ aflog(LOG_T_CLIENT, LOG_I_DEBUG,
+ "realm[%s]: user[%d]: STOP READING",
get_realmname(&config, j), get_username(pointer, numofcon));
FD_CLR(pointer->contable[numofcon].connfd, &allset);
break;
}
case AF_S_CAN_SEND: {
- aflog(3, " realm[%s]: user[%d]: START READING",
+ aflog(LOG_T_CLIENT, LOG_I_DEBUG,
+ "realm[%s]: user[%d]: START READING",
get_realmname(&config, j), get_username(pointer, numofcon));
FD_SET(pointer->contable[numofcon].connfd, &allset);
break;
}
case AF_S_WRONG: {
- aflog(1, " realm[%s]: Client[%s]: Wrong message - CLOSING",
+ aflog(LOG_T_CLIENT, LOG_I_ERR,
+ "realm[%s]: Client[%s]: Wrong message - CLOSING",
get_realmname(&config, j), get_clientname(pointer, k));
remove_client(pointer, k, &allset, &wset, &manconnecting);
break;
@@ -1314,12 +1503,16 @@ main(int argc, char **argv)
case AF_S_ADMIN_LOGIN: {
if ((pointer->clitable[k].ready == 2) && (numofcon==(pointer->pass[0]*256+pointer->pass[1])) &&
(length==(pointer->pass[2]*256+pointer->pass[3]))) {
- aflog(1, " realm[%s]: Client[%s]: NEW remote admin -- pass OK",
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "realm[%s]: Client[%s]: NEW remote admin -- pass OK",
get_realmname(&config, j), get_clientname(pointer, k));
for (l = 0; l < pointer->raclinum; ++l) {
if (pointer->raclitable[l].ready == 0) {
pointer->raclitable[l].cliconn.commfd = pointer->clitable[k].cliconn.commfd;
pointer->raclitable[l].connecttime = pointer->clitable[k].connecttime;
+#ifdef HAVE_LIBPTHREAD
+ pointer->raclitable[l].tunneltype = pointer->clitable[k].tunneltype;
+#endif
pointer->raclitable[l].clientnum = pointer->clitable[k].clientnum;
memcpy(pointer->raclitable[l].namebuf, pointer->clitable[k].namebuf, 128);
memcpy(pointer->raclitable[l].portbuf, pointer->clitable[k].portbuf, 7);
@@ -1344,7 +1537,8 @@ main(int argc, char **argv)
send_message(pointer->type | TYPE_SSL, pointer->raclitable[l].cliconn, buff, n+5);
}
else {
- aflog(1, " realm[%s]: Client[%s]: remote admin -- limit EXCEEDED",
+ aflog(LOG_T_MANAGE, LOG_I_WARNING,
+ "realm[%s]: Client[%s]: remote admin -- limit EXCEEDED",
get_realmname(&config, j), get_clientname(pointer, k));
buff[0] = AF_S_CANT_OPEN; /* sending message */
send_message(pointer->type | TYPE_SSL | TYPE_ZLIB, pointer->clitable[k].cliconn, buff, 5);
@@ -1353,8 +1547,15 @@ main(int argc, char **argv)
}
break;
}
+ case AF_S_KEEP_ALIVE: {
+ aflog(LOG_T_CLIENT, LOG_I_DEBUG,
+ "realm[%s]: Client[%s]: Keep alive packet",
+ get_realmname(&config, j), get_clientname(pointer, k));
+ break;
+ }
default : {
- aflog(1, " realm[%s]: Client[%s]: Unrecognized message - CLOSING",
+ aflog(LOG_T_CLIENT, LOG_I_ERR,
+ "realm[%s]: Client[%s]: Unrecognized message - CLOSING",
get_realmname(&config, j), get_clientname(pointer, k));
remove_client(pointer, k, &allset, &wset, &manconnecting);
}
@@ -1365,7 +1566,8 @@ main(int argc, char **argv)
if ((pointer->raclitable[k].ready != 0) && (FD_ISSET(pointer->raclitable[k].cliconn.commfd, &rset))) {
if (pointer->raclitable[k].ready == 1) {
make_ssl_initialize(&(pointer->raclitable[k].cliconn));
- aflog(2, " realm[%s]: new Client[%s] (ra): SSL_accept",
+ aflog(LOG_T_MANAGE, LOG_I_DDEBUG,
+ "realm[%s]: new Client[%s] (ra): SSL_accept",
get_realmname(&config, j), get_raclientname(pointer, k));
switch (make_ssl_accept(&(pointer->raclitable[k].cliconn))) {
case 2: {
@@ -1375,45 +1577,52 @@ main(int argc, char **argv)
pointer->raclitable[k].ready = 0;
manconnecting--;
pointer->clicon--;
- aflog(1, " realm[%s]: new Client[%s] (ra): DENIED by SSL_accept",
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "realm[%s]: new Client[%s] (ra): DENIED by SSL_accept",
get_realmname(&config, j), get_raclientname(pointer, k));
}
case 1: {
continue;
}
default: {
- aflog(1, " realm[%s]: new Client[%s] (ra): ACCEPTED by SSL_accept",
+ aflog(LOG_T_MANAGE, LOG_I_DEBUG,
+ "realm[%s]: new Client[%s] (ra): ACCEPTED by SSL_accept",
get_realmname(&config, j), get_raclientname(pointer, k));
pointer->raclitable[k].ready = 2;
continue;
}
}
}
- aflog(3, " realm[%s]: Client[%s] (ra): commfd: FD_ISSET",
+ aflog(LOG_T_MANAGE, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s] (ra): commfd: FD_ISSET",
get_realmname(&config, j), get_raclientname(pointer, k));
n = get_message(pointer->type | TYPE_SSL | TYPE_ZLIB, pointer->raclitable[k].cliconn, buff, -5);
if (n == -1) {
if (errno == EAGAIN) {
- aflog(4, " realm[%s]: Client[%s] (ra): commfd: EAGAIN",
+ aflog(LOG_T_MANAGE, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s] (ra): commfd: EAGAIN",
get_realmname(&config, j), get_raclientname(pointer, k));
continue;
}
else {
- aflog(4, " realm[%s]: Client[%s] (ra): commfd: ERROR: %d",
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "realm[%s]: Client[%s] (ra): commfd: ERROR: %d",
get_realmname(&config, j), get_raclientname(pointer, k), errno);
n = 0;
}
}
else if (n != 5) {
if (n != 0) {
- aflog(4, " realm[%s]: Client[%s] (ra): header length = %d --> closing client",
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "realm[%s]: Client[%s] (ra): header length = %d --> closing client",
get_realmname(&config, j), get_raclientname(pointer, k), n);
}
n = 0;
}
if (n==0) {
remove_raclient(pointer, k, &allset, &wset, &manconnecting);
- aflog(1, " realm[%s]: Client[%s] (ra): commfd: CLOSED",
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "realm[%s]: Client[%s] (ra): commfd: CLOSED",
get_realmname(&config, j), get_raclientname(pointer, k));
continue;
}
@@ -1426,7 +1635,8 @@ main(int argc, char **argv)
length += buff[4]; /* this is length of message */
if (pointer->raclitable[k].ready<2) {
- aflog(1, " realm[%s]: Client[%s] (ra): Impossible behaviour --> ignoring",
+ aflog(LOG_T_MANAGE, LOG_I_WARNING,
+ "realm[%s]: Client[%s] (ra): Impossible behaviour --> ignoring",
get_realmname(&config, j), get_raclientname(pointer, k));
continue;
}
@@ -1440,10 +1650,14 @@ main(int argc, char **argv)
(length==(pointer->pass[2]*256+pointer->pass[3]))) {
for (l = 0; l < pointer->clinum; ++l) {
if (!(pointer->clitable[l].ready)) {
- aflog(1, " realm[%s]: Client[%s] (ra) --> Client[%s]",
+ aflog(LOG_T_MANAGE | LOG_T_CLIENT, LOG_I_INFO,
+ "realm[%s]: Client[%s] (ra) --> Client[%s]",
get_realmname(&config, j), get_raclientname(pointer, k), get_clientname(pointer, l));
pointer->clitable[l].cliconn.commfd = pointer->raclitable[k].cliconn.commfd;
pointer->clitable[l].connecttime = pointer->raclitable[k].connecttime;
+#ifdef HAVE_LIBPTHREAD
+ pointer->clitable[l].tunneltype = pointer->raclitable[k].tunneltype;
+#endif
pointer->clitable[l].clientnum = pointer->raclitable[k].clientnum;
memcpy(pointer->clitable[l].namebuf, pointer->raclitable[k].namebuf, 128);
memcpy(pointer->clitable[l].portbuf, pointer->raclitable[k].portbuf, 7);
@@ -1457,7 +1671,8 @@ main(int argc, char **argv)
}
if (l != pointer->clinum) {
pointer->clitable[l].ready = 3;
- aflog(1, " realm[%s]: Client[%s]: pass ok - ACCESS GRANTED",
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "realm[%s]: Client[%s]: pass ok - ACCESS GRANTED",
get_realmname(&config, j), get_clientname(pointer, l));
buff[0] = AF_S_LOGIN; /* sending message */
buff[1] = pointer->clitable[l].usernum >> 8;/* high bits of user number */
@@ -1469,7 +1684,8 @@ main(int argc, char **argv)
long tmp_val;
char tmp_tab[6];
if (check_long(pointer->usrclitable[pointer->clitable[l].whatusrcli].lisportnum, &tmp_val)) {
- aflog(1, " realm[%s]: INVALID listenport - removing Client[%s]",
+ aflog(LOG_T_CLIENT, LOG_I_ERR,
+ "realm[%s]: INVALID listenport - removing Client[%s]",
get_realmname(&config, j), get_clientname(pointer, l));
remove_client(pointer, l, &allset, &wset, &manconnecting);
break;
@@ -1495,12 +1711,14 @@ main(int argc, char **argv)
FD_SET(pointer->clitable[l].listenfd, &allset);
maxfdp1 = (maxfdp1 > (pointer->clitable[l].listenfd+1)) ?
maxfdp1 : (pointer->clitable[l].listenfd+1);
- aflog(1, " realm[%s]: Client[%s]: listenport=%s",
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "realm[%s]: Client[%s]: listenport=%s",
get_realmname(&config, j), get_clientname(pointer, l), tmp_tab);
}
}
else {
- aflog(3, " realm[%s]: client limit EXCEEDED", get_realmname(&config, j));
+ aflog(LOG_T_CLIENT, LOG_I_WARNING,
+ "realm[%s]: client limit EXCEEDED", get_realmname(&config, j));
buff[0] = AF_S_CANT_OPEN; /* sending message */
send_message(pointer->type | TYPE_SSL | TYPE_ZLIB, pointer->raclitable[k].cliconn, buff, 5);
remove_raclient(pointer, k, &allset, &wset, &manconnecting);
@@ -1509,7 +1727,8 @@ main(int argc, char **argv)
else if ((pointer->raclitable[k].ready == 3) && (numofcon == 0)) {
n = get_message(pointer->type, pointer->raclitable[k].cliconn, buff, length);
buff[n] = 0;
- aflog(1, " realm[%s]: Client[%s] (ra): ID received: %s",
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "realm[%s]: Client[%s] (ra): ID received: %s",
get_realmname(&config, j), get_raclientname(pointer, k), buff);
if (pointer->raclitable[k].clientid) {
free(pointer->raclitable[k].clientid);
@@ -1520,14 +1739,16 @@ main(int argc, char **argv)
}
}
else {
- aflog(1, " realm[%s]: Client[%s] (ra): Wrong password - CLOSING",
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "realm[%s]: Client[%s] (ra): Wrong password - CLOSING",
get_realmname(&config, j), get_raclientname(pointer, k));
remove_raclient(pointer, k, &allset, &wset, &manconnecting);
}
break;
}
case AF_S_WRONG: {
- aflog(1, " realm[%s]: Client[%s] (ra): Wrong message - CLOSING",
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "realm[%s]: Client[%s] (ra): Wrong message - CLOSING",
get_realmname(&config, j), get_raclientname(pointer, k));
remove_raclient(pointer, k, &allset, &wset, &manconnecting);
break;
@@ -1535,7 +1756,8 @@ main(int argc, char **argv)
case AF_S_ADMIN_LOGIN: {
if ((pointer->raclitable[k].ready == 2) && (numofcon==(pointer->pass[0]*256+pointer->pass[1])) &&
(length==(pointer->pass[2]*256+pointer->pass[3]))) {
- aflog(1, " realm[%s]: Client[%s] (ra): NEW remote admin -- pass OK",
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "realm[%s]: Client[%s] (ra): NEW remote admin -- pass OK",
get_realmname(&config, j), get_raclientname(pointer, k));
pointer->raclitable[k].ready = 3;
pointer->raclicon++;
@@ -1553,19 +1775,67 @@ main(int argc, char **argv)
}
case AF_S_ADMIN_CMD: {
if (pointer->raclitable[k].ready == 3) {
- if (serve_admin(&config, j, k, buff)) {
- remove_raclient(pointer, k, &allset, &wset, &manconnecting);
+ if ((n = serve_admin(&config, j, k, buff))) {
+ if (n == 1) {
+ aflog(LOG_T_MANAGE, LOG_I_NOTICE,
+ "realm[%s]: Client[%s] (ra): remote admin -- closing",
+ get_realmname(&config, j), get_raclientname(pointer, k));
+ remove_raclient(pointer, k, &allset, &wset, &manconnecting);
+ }
+ else {
+ for (i = 0; i < config.size; ++i) {
+ l = get_clientnumber(&(config.realmtable[i]), n-2);
+ if (l != -1) {
+ aflog(LOG_T_MANAGE, LOG_I_NOTICE,
+ "realm[%s]: Client[%s] (ra): remote admin: KICKING realm[%s]: Client[%s]",
+ get_realmname(&config, j), get_raclientname(pointer, k),
+ get_realmname(&config, i), get_clientname(&(config.realmtable[i]), l));
+ buff[0] = AF_S_CLOSING; /* closing */
+ send_message(config.realmtable[i].type,config.realmtable[i].clitable[l].cliconn,buff,5);
+ time(&now);
+ aflog(LOG_T_CLIENT, LOG_I_NOTICE,
+ "REALM: %s CLIENT: %s IP: %s PORT: %s DURATION: %s",
+ get_realmname(&config, j),
+ get_clientname(&(config.realmtable[i]), l),
+ config.realmtable[i].clitable[l].namebuf,
+ config.realmtable[i].clitable[l].portbuf,
+ timeperiod(now - config.realmtable[i].clitable[l].connecttime));
+ if (config.realmtable[i].audit) {
+ while (config.realmtable[i].clitable[l].head) {
+ aflog(LOG_T_CLIENT, LOG_I_NOTICE,
+ "USERID: %d IP: %s PORT: %s CONNECTED: %s DURATION: %s",
+ config.realmtable[i].clitable[l].head->userid,
+ config.realmtable[i].clitable[l].head->namebuf,
+ config.realmtable[i].clitable[l].head->portbuf,
+ localdate(&(config.realmtable[i].clitable[l].head->connecttime)),
+ timeperiod(config.realmtable[i].clitable[l].head->duration));
+ deletealnode(&(config.realmtable[i].clitable[l].head));
+ }
+ }
+ remove_client(&(config.realmtable[i]), l, &allset, &wset, &manconnecting);
+ break;
+ }
+ }
+ }
}
}
else {
- aflog(1, " realm[%s]: Client[%s] (ra): remote admin -- security VIOLATION",
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "realm[%s]: Client[%s] (ra): remote admin -- security VIOLATION",
get_realmname(&config, j), get_raclientname(pointer, k));
remove_raclient(pointer, k, &allset, &wset, &manconnecting);
}
break;
}
+ case AF_S_KEEP_ALIVE: {
+ aflog(LOG_T_MANAGE, LOG_I_DEBUG,
+ "realm[%s]: Client[%s] (ra): Keep alive packet",
+ get_realmname(&config, j), get_raclientname(pointer, k));
+ break;
+ }
default : {
- aflog(1, " realm[%s]: Client[%s] (ra): Unrecognized message - CLOSING",
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "realm[%s]: Client[%s] (ra): Unrecognized message - CLOSING",
get_realmname(&config, j), get_raclientname(pointer, k));
remove_raclient(pointer, k, &allset, &wset, &manconnecting);
}
@@ -1574,21 +1844,37 @@ main(int argc, char **argv)
/* ------------------------------------ */
for (l = 0; l < pointer->usrclinum; ++l) {
if (FD_ISSET(pointer->usrclitable[l].managefd, &rset)) {
- aflog(3, " realm[%s]: managefd: FD_ISSET", get_realmname(&config, j));
+ aflog(LOG_T_CLIENT, LOG_I_DDEBUG,
+ "realm[%s]: managefd: FD_ISSET", get_realmname(&config, j));
len = pointer->addrlen;
- sent = accept(pointer->usrclitable[l].managefd,pointer->cliaddr,&len);
+#ifdef HAVE_LIBPTHREAD
+ sent = get_new_socket(pointer->usrclitable[l].managefd,pointer->tunneltype,pointer->cliaddr,
+ &len,&tunneltype);
+#else
+ sent = accept(pointer->usrclitable[l].managefd, pointer->cliaddr, &len);
+#endif
+ if (sent == -1) {
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: listenfd: FD_ISSET --> EAGAIN", get_realmname(&config, j));
+ continue;
+ }
flags = fcntl(sent, F_GETFL, 0);
fcntl(sent, F_SETFL, flags | O_NONBLOCK);
for (k = 0; k < pointer->clinum; ++k) {
if (!(pointer->clitable[k].ready)) {
pointer->clitable[k].clientnum = pointer->clientcounter;
++(pointer->clientcounter);
- aflog(2, " realm[%s]: new Client[%s]: CONNECTING",
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "realm[%s]: new Client[%s]: CONNECTING",
get_realmname(&config, j), get_clientname(pointer, k));
pointer->clitable[k].cliconn.commfd = sent;
pointer->clitable[k].whatusrcli = l;
time(&pointer->clitable[k].connecttime);
- aflog(1, " realm[%s]: new Client[%s] IP:%s", get_realmname(&config, j), get_clientname(pointer, k),
+#ifdef HAVE_LIBPTHREAD
+ pointer->clitable[k].tunneltype = tunneltype;
+#endif
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "realm[%s]: new Client[%s] IP:%s", get_realmname(&config, j), get_clientname(pointer, k),
sock_ntop(pointer->cliaddr, len, pointer->clitable[k].namebuf,
pointer->clitable[k].portbuf, pointer->dnslookups));
FD_SET(pointer->clitable[k].cliconn.commfd, &allset);
@@ -1606,12 +1892,17 @@ main(int argc, char **argv)
if ((!pointer->raclitable[k].ready)) {
pointer->raclitable[k].clientnum = pointer->clientcounter;
++(pointer->clientcounter);
- aflog(2, " realm[%s]: new Client[%s] (ra): CONNECTING",
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "realm[%s]: new Client[%s] (ra): CONNECTING",
get_realmname(&config, j), get_raclientname(pointer, k));
pointer->raclitable[k].cliconn.commfd = sent;
pointer->raclitable[k].whatusrcli = l;
time(&pointer->raclitable[k].connecttime);
- aflog(1, " realm[%s]: new Client[%s] (ra) IP:%s",
+#ifdef HAVE_LIBPTHREAD
+ pointer->raclitable[k].tunneltype = tunneltype;
+#endif
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "realm[%s]: new Client[%s] (ra) IP:%s",
get_realmname(&config, j), get_raclientname(pointer, k),
sock_ntop(pointer->cliaddr, len, pointer->raclitable[k].namebuf,
pointer->raclitable[k].portbuf, pointer->dnslookups));
@@ -1626,7 +1917,8 @@ main(int argc, char **argv)
}
}
if (k == pointer->raclinum) {
- aflog(3, " realm[%s]: client limit EXCEEDED", get_realmname(&config, j));
+ aflog(LOG_T_CLIENT | LOG_T_MANAGE, LOG_I_WARNING,
+ "realm[%s]: client limit EXCEEDED", get_realmname(&config, j));
close(sent);
}
}
@@ -1635,86 +1927,3 @@ main(int argc, char **argv)
} /* realms loop */
}
}
-
-static void
-usage(char* info)
-{
- printf("\n%s\n\n\n", info);
- printf(" Basic options:\n\n");
- printf(" -n, --hostname - it's used when creating listening sockets\n");
- printf(" (default: '')\n");
- printf(" -l, --listenport - listening port number - users connect\n");
- printf(" to it (default: 50127)\n");
- printf(" -m, --manageport - manage port number - second part of the active\n");
- printf(" port forwarder connects to it (default: 50126)\n");
- printf(" -h, --help - prints this help\n\n");
- printf(" Authorization:\n\n");
- printf(" --pass - set the password used for client identification\n");
- printf(" (default: no password)\n\n");
- printf(" Configuration:\n\n");
- printf(" -c, --cerfile - the name of the file with certificate\n");
- printf(" (default: cacert.pem)\n");
- printf(" -k, --keyfile - the name of the file with RSA key (default: server.rsa)\n");
- printf(" -f, --cfgfile - the name of the file with the configuration for the\n");
- printf(" active forwarder (server)\n");
- printf(" -D, --dateformat - format of the date printed in logs (see 'man strftime'\n");
- printf(" for details) (default: %%d.%%m.%%Y %%H:%%M:%%S)\n\n");
- printf(" -t, --timeout - the timeout value for the client's connection\n");
- printf(" (default: 5)\n");
- printf(" -u, --users - the amount of users allowed to use this server\n");
- printf(" (default: 5)\n");
- printf(" -C, --clients - the number of allowed clients to use this server\n");
- printf(" (default: 1)\n");
- printf(" -r, --realm - set the realm name (default: none)\n");
- printf(" -R, --raclients - the number of allowed clients in remote administration\n");
- printf(" mode to use this server (default: 1)\n");
- printf(" -U, --usrpcli - the number of allowed users per client (default: $users)\n");
- printf(" -M, --climode - strategy used to connect users with clients (default: 1)\n");
- printf(" Available strategies:\n");
- printf(" 1. fill first client before go to next\n\n");
- printf(" -p, --proto - type of server (tcp|udp) - what protocol it will be\n");
- printf(" operating for (default: tcp)\n");
- printf(" -b, --baseport - listenports are temporary and differ for each client\n");
- printf(" --nossl - ssl is not used to transfer data (but it's still used\n");
- printf(" to establish a connection) (default: ssl is used)\n");
- printf(" --nozlib - zlib is not used to compress data (default: zlib is\n");
- printf(" used)\n");
- printf(" --dnslookups - try to obtain dns names of the computers rather than\n");
- printf(" their numeric IP\n\n");
- printf(" Logging:\n\n");
- printf(" -O, --heavylog - logging everything to a logfile\n");
- printf(" -o, --lightlog - logging some data to a logfile\n");
- printf(" -S, --heavysocklog - logging everything to a localport\n");
- printf(" -s, --lightsocklog - logging some data to a localport\n");
- printf(" -v, --verbose - to be verbose - program won't enter the daemon mode\n");
- printf(" (use several times for greater effect)\n\n");
-#ifdef AF_INET6
- printf(" IP family:\n\n");
- printf(" -4, --ipv4 - use ipv4 only\n");
- printf(" -6, --ipv6 - use ipv6 only\n\n");
-#endif
- exit(0);
-}
-
-static void
-sig_int(int signo)
-{
- int i, j;
- unsigned char buff[5];
- for (j = 0; j < config.size; ++j) {
- buff[0] = AF_S_CLOSING; /* closing */
- for (i = 0; i < config.realmtable[j].clinum+1; ++i) {
- if (config.realmtable[j].clitable[i].ready == 3) {
- if (config.realmtable[j].clinum == i) {
- send_message(config.realmtable[j].type | TYPE_SSL, config.realmtable[j].clitable[i].cliconn, buff, 5);
- }
- else {
- send_message(config.realmtable[j].type, config.realmtable[j].clitable[i].cliconn, buff, 5);
- }
- }
- }
- }
- aflog(1, "SERVER CLOSED cg: %ld bytes", getcg());
- exit(0);
-}
-
diff --git a/src/afserver.h b/src/afserver.h
index 6975af4..816185d 100644
--- a/src/afserver.h
+++ b/src/afserver.h
@@ -33,6 +33,12 @@
#include "realmnames.h"
#include "clientnames.h"
#include "usernames.h"
+#include "server_get.h"
+#include "http_proxy_server.h"
+#include "thread_management.h"
+#include "server_signals.h"
+#include "usage.h"
+#include "logging.h"
#include <openssl/ssl.h>
#include <openssl/err.h>
@@ -44,8 +50,5 @@
#ifndef _JS_AFSERVER_H
#define _JS_AFSERVER_H
-static void usage(char* info);
-static void sig_int(int);
-
#endif
diff --git a/src/audit.c b/src/audit.c
new file mode 100644
index 0000000..c74b619
--- /dev/null
+++ b/src/audit.c
@@ -0,0 +1,69 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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 <stdlib.h>
+#include <string.h>
+
+#include "audit.h"
+
+int
+insertalnode(alnodeT** headRef, int uid, char* nbuf, char* pbuf, time_t ctime, time_t dur)
+{
+ alnodeT* newnode, *lastnode;
+ lastnode = newnode = *headRef;
+ while (newnode) {
+ lastnode = newnode;
+ newnode = newnode->next;
+ }
+ newnode = calloc(1, sizeof(alnodeT));
+ newnode->userid = uid;
+ memcpy(newnode->namebuf, nbuf, 128);
+ memcpy(newnode->portbuf, pbuf, 7);
+ newnode->connecttime = ctime;
+ newnode->duration = dur;
+ newnode->next = NULL;
+ if (lastnode)
+ lastnode->next = newnode;
+ else
+ *headRef = newnode;
+ return 0;
+}
+
+int
+deletealnode(alnodeT** headRef)
+{
+ alnodeT* node = *headRef;
+ if (*headRef == NULL)
+ return 1;
+ *headRef = node->next;
+ free(node);
+ return 0;
+}
+
+int
+freeauditlist(alnodeT** headRef)
+{
+ while (*headRef) {
+ deletealnode(headRef);
+ }
+ return 0;
+}
diff --git a/src/audit.h b/src/audit.h
new file mode 100644
index 0000000..023fd94
--- /dev/null
+++ b/src/audit.h
@@ -0,0 +1,39 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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 <time.h>
+
+#ifndef _JS_AUDIT_H
+#define _JS_AUDIT_H
+
+typedef struct alnode {
+ int userid;
+ char namebuf[128];
+ char portbuf[7];
+ time_t connecttime;
+ time_t duration;
+ struct alnode* next;
+} alnodeT;
+
+int insertalnode(alnodeT** headRef, int uid, char* nbuf, char* pbuf, time_t ctime, time_t dur);
+int deletealnode(alnodeT** headRef);
+int freeauditlist(alnodeT** headRef);
+
+#endif
diff --git a/src/buflist.c b/src/buflist.c
index 7ee5ede..e199b11 100644
--- a/src/buflist.c
+++ b/src/buflist.c
@@ -18,6 +18,8 @@
*
*/
+#include <config.h>
+
#include <stdlib.h>
#include <string.h>
diff --git a/src/client_initialization.c b/src/client_initialization.c
new file mode 100644
index 0000000..a5ab560
--- /dev/null
+++ b/src/client_initialization.c
@@ -0,0 +1,212 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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 "client_initialization.h"
+#include "network.h"
+
+int
+initialize_client_stage1(char tunneltype, clifd* master, char* name, char* manage,
+ char* proxyname, char* proxyport, char ipfam, SSL_CTX* ctx, unsigned char* buff, unsigned char* pass,
+ char wanttoexit)
+{
+ int n;
+ switch (tunneltype) {
+ case 0: {
+ if (ip_connect(&(master->commfd), name, manage, ipfam)) {
+#ifdef AF_INET6
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "tcp_connect_%s error for %s, %s",
+ (ipfam & 0x02)?"ipv4":(ipfam & 0x04)?"ipv6":"unspec", name, manage);
+#else
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "tcp_connect error for %s, %s", name, manage);
+#endif
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ return 1;
+ }
+ }
+ break;
+ }
+#ifdef HAVE_LIBPTHREAD
+ case 1: {
+ if (initialize_http_proxy_client(&(master->commfd), name, manage, proxyname, proxyport, ipfam)) {
+#ifdef AF_INET6
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http_proxy_connect_%s error for %s, %s (proxy: %s, %s)",
+ (ipfam & 0x02)?"ipv4":(ipfam & 0x04)?"ipv6":"unspec", name, manage, proxyname, proxyport);
+#else
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http_proxy_connect error for %s, %s (proxy: %s, %s)", name, manage, proxyname, proxyport);
+#endif
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ return 1;
+ }
+ }
+ break;
+ }
+#endif
+ default: {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Unknown tunnel type");
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ return 1;
+ }
+ break;
+ }
+ }
+ master->ssl = SSL_new(ctx);
+ if (SSL_set_fd(master->ssl, master->commfd) != 1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Problem with initializing ssl... exiting");
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ return 2;
+ }
+ }
+
+ aflog(LOG_T_INIT, LOG_I_INFO,
+ "Trying SSL_connect");
+ if ((n = SSL_connect(master->ssl)) == 1) {
+ aflog(LOG_T_INIT, LOG_I_INFO,
+ "SSL_connect successful");
+ }
+ else {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "SSL_connect has failed (%d)... exiting", n);
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ return 3;
+ }
+ }
+
+ buff[0] = AF_S_LOGIN;
+ buff[1] = pass[0];
+ buff[2] = pass[1];
+ buff[3] = pass[2];
+ buff[4] = pass[3];
+
+ return 0;
+}
+
+int
+initialize_client_stage2(char *type, clifd* master, int* usernum, unsigned char* buff, char wanttoexit)
+{
+ send_message(*type, *master, buff, 5);
+ buff[0] = 0;
+ get_message(*type, *master, buff, -5);
+
+ if ( buff[0] == 0 ) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Connection with afserver failed");
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ return 1;
+ }
+ }
+ if ( buff[0] == AF_S_WRONG ) {
+ aflog(LOG_T_INIT, LOG_I_ERR,
+ "Wrong password");
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ return 1;
+ }
+ }
+ if ( buff[0] == AF_S_CANT_OPEN ) {
+ aflog(LOG_T_INIT, LOG_I_ERR,
+ "Server is full");
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ return 1;
+ }
+ }
+ if ( buff[0] != AF_S_LOGIN ) {
+ aflog(LOG_T_INIT, LOG_I_ERR,
+ "Incompatible server type or server full");
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ return 1;
+ }
+ }
+
+ *type = buff[3];
+ (*usernum) = buff[1];
+ (*usernum) = (*usernum) << 8;
+ (*usernum) += buff[2];
+ return 0;
+}
+
+int
+initialize_client_stage3(ConnectuserT** contable, clifd* master, int usernum, int* buflength, socklen_t* len,
+ fd_set* allset, fd_set* wset, int* maxfdp1, char wanttoexit)
+{
+ (*contable) = calloc( usernum, sizeof(ConnectuserT));
+ if ((*contable) == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Calloc error - unable to successfully communicate with server");
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ return 1;
+ }
+ }
+
+ (*len) = 4;
+ if (getsockopt(master->commfd, SOL_SOCKET, SO_SNDBUF, buflength, len) == -1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Can't get socket send buffer size - exiting...");
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ return 2;
+ }
+ }
+
+ FD_ZERO(allset);
+ FD_ZERO(wset);
+
+ FD_SET(master->commfd, allset);
+ (*maxfdp1) = master->commfd + 1;
+ return 0;
+}
diff --git a/src/client_initialization.h b/src/client_initialization.h
new file mode 100644
index 0000000..b8c534a
--- /dev/null
+++ b/src/client_initialization.h
@@ -0,0 +1,40 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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 "activefor.h"
+#include "stats.h"
+#include "logging.h"
+#include "http_proxy_client.h"
+
+#include <openssl/ssl.h>
+
+#ifndef _JS_CLIENT_INITIALIZATION_H
+#define _JS_CLIENT_INITIALIZATION_H
+
+int initialize_client_stage1(char tunneltype, clifd* master, char* name, char* manage,
+ char* proxyname, char* proxyport, char ipfam, SSL_CTX* ctx, unsigned char* buff, unsigned char* pass,
+ char wanttoexit);
+int initialize_client_stage2(char *type, clifd* master, int* usernum, unsigned char* buff, char wanttoexit);
+int initialize_client_stage3(ConnectuserT** contable, clifd* master, int usernum, int* buflength,
+ socklen_t* len, fd_set* allset, fd_set* wset, int* maxfdp1, char wanttoexit);
+
+#endif
diff --git a/src/client_reverse_udp.c b/src/client_reverse_udp.c
new file mode 100644
index 0000000..8c78386
--- /dev/null
+++ b/src/client_reverse_udp.c
@@ -0,0 +1,183 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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 "client_reverse_udp.h"
+
+#include <stdlib.h>
+
+void
+initialize_client_reverse_udp(int* usernum, clifd* master, char* name, char* manage, char ipfam)
+{
+ (*usernum) = 1;
+ if (ip_connect(&(master->commfd), name, manage, ipfam)) {
+#ifdef AF_INET6
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "tcp_connect_%s error for %s, %s",
+ (ipfam & 0x02)?"ipv4":(ipfam & 0x04)?"ipv6":"unspec", name, manage);
+#else
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "tcp_connect error for %s, %s", name, manage);
+#endif
+ exit(1);
+ }
+ master->ssl = NULL;
+}
+
+void
+client_reverse_udp(ConnectuserT* contable, clifd* master, char* desnam, char* despor, char type,
+ unsigned char* buff, int buflength)
+{
+ char ipfam;
+ socklen_t len, addrlen;
+ int maxfdp1, temp, notsent, n, length;
+ struct sockaddr* cliaddr;
+ fd_set rset, allset;
+
+ ipfam = 0;
+#ifdef AF_INET6
+ if (TYPE_IS_IPV4(type)) {
+ ipfam |= 0x02;
+ }
+ else if (TYPE_IS_IPV6(type)) {
+ ipfam |= 0x04;
+ }
+#endif
+ if (ip_listen(&(contable[0].connfd), desnam, despor, &addrlen, ipfam)) {
+#ifdef AF_INET6
+ aflog(LOG_T_INIT, LOG_I_DEBUG,
+ "udp_listen_%s error for %s, %s",
+ (ipfam & 0x02)?"ipv4":(ipfam & 0x04)?"ipv6":"unspec", desnam, despor);
+#else
+ aflog(LOG_T_INIT, LOG_I_DEBUG,
+ "udp_listen error for %s, %s", desnam, despor);
+#endif
+ exit(1);
+ }
+ cliaddr = malloc(addrlen);
+ FD_ZERO(&allset);
+
+ FD_SET(master->commfd, &allset);
+ maxfdp1 = master->commfd + 1;
+ maxfdp1 = (maxfdp1>contable[0].connfd+1) ? maxfdp1 : contable[0].connfd+1;
+ FD_SET(contable[0].connfd, &allset);
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "CLIENT STARTED mode: udp reverse");
+ for ( ; ; ) {
+ len = 4;
+ if (getsockopt(master->commfd, SOL_SOCKET, SO_SNDBUF, &temp, &len) != -1) {
+ if (temp != buflength) {
+ buflength = temp;
+ aflog(LOG_T_CLIENT, LOG_I_WARNING,
+ "Send buffer size changed...");
+ }
+ }
+ len = addrlen;
+ rset = allset;
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "select");
+ select(maxfdp1, &rset, NULL, NULL, NULL);
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "after select...");
+
+ if (FD_ISSET(contable[0].connfd, &rset)) { /* FD_ISSET CONTABLE[0].CONNFD RSET*/
+ n = recvfrom(contable[0].connfd, &buff[5], 8091, 0, cliaddr, &len);
+#ifdef HAVE_LINUX_SOCKIOS_H
+# ifdef SIOCOUTQ
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "SIOCOUTQ is defined");
+ if (ioctl(master->commfd, SIOCOUTQ, &notsent)) {
+ aflog(LOG_T_CLIENT, LOG_I_CRIT,
+ "ioctl error -> exiting...");
+ exit(1);
+ }
+ if (buflength <= notsent + n + 5) { /* when we can't do this */
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "drop: size:%d, buf:%d, w:%d/%d", n, buflength, notsent, buflength);
+# else
+ aflog(LOG_T_MAIN< LOG_I_DDEBUG,
+ "TIOCOUTQ is defined");
+ if (ioctl(master->commfd, TIOCOUTQ, &notsent)) {
+ aflog(LOG_T_CLIENT, LOG_I_CRIT,
+ "ioctl error -> exiting...");
+ exit(1);
+ }
+ if (notsent <= n + 5) { /* when we can't do this */
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "drop: size:%d, buf:%d, w:%d/%d", n, buflength, buflength - notsent, buflength);
+# endif
+ }
+ else {
+#endif
+ if (n > 0) {
+#ifdef HAVE_LINUX_SOCKIOS_H
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "Sending %d bytes to service (w:%d/%d) (FROM:%s)", n,
+# ifdef SIOCOUTQ
+ notsent
+# else
+ buflength - notsent
+# endif
+ , buflength, sock_ntop(cliaddr, len, NULL, NULL, 0));
+#else
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "Sending %d bytes to service (FROM:%s)", n, sock_ntop(cliaddr, len, NULL, NULL, 0));
+#endif
+ buff[0] = AF_S_MESSAGE;
+ buff[1] = AF_S_LOGIN;
+ buff[2] = AF_S_MESSAGE;
+ buff[3] = n >> 8;
+ buff[4] = n;
+ writen(master->commfd, buff, n + 5);
+ }
+#ifdef HAVE_LINUX_SOCKIOS_H
+ }
+#endif
+ } /* - FD_ISSET CONTABLE[0].CONNFD RSET */
+
+ if (FD_ISSET(master->commfd, &rset)) { /* FD_ISSET MASTER.COMMFD RSET */
+ n = readn(master->commfd, buff, 5);
+ if (n == 5) {
+ if ((buff[0] != AF_S_MESSAGE) || (buff[1] != AF_S_LOGIN) || (buff[2] != AF_S_MESSAGE)) {
+ aflog(LOG_T_CLIENT, LOG_I_CRIT,
+ "Incompatible server type (not udp?) or data corruption -> exiting...");
+ exit(1);
+ }
+ length = buff[3];
+ length = length << 8;
+ length += buff[4]; /* this is length of message */
+ n = readn(master->commfd, buff, length);
+ }
+ else {
+ n = 0;
+ }
+ if (n == 0) { /* server quits -> we do the same... */
+ aflog(LOG_T_CLIENT, LOG_I_CRIT,
+ "premature quit of the server -> exiting...");
+ exit(1);
+ }
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "Sending %d bytes to user (TO:%s)", n, sock_ntop(cliaddr, addrlen, NULL, NULL, 0));
+ sendto(contable[0].connfd, buff, n, 0, cliaddr, addrlen);
+ } /* - FD_ISSET MASTER.COMMFD RSET */
+ }
+ exit(0); /* we shouldn't get here */
+}
diff --git a/src/client_reverse_udp.h b/src/client_reverse_udp.h
new file mode 100644
index 0000000..c05f583
--- /dev/null
+++ b/src/client_reverse_udp.h
@@ -0,0 +1,40 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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>
+
+#ifdef HAVE_LINUX_SOCKIOS_H
+#include <linux/sockios.h>
+#endif
+
+#ifndef _JS_CLIENT_REVERSE_UDP_H
+#define _JS_CLIENT_REVERSE_UDP_H
+
+#include <sys/ioctl.h>
+
+#include "activefor.h"
+#include "stats.h"
+#include "logging.h"
+
+void initialize_client_reverse_udp(int* usernum, clifd* master, char* name, char* manage, char ipfam);
+void client_reverse_udp(ConnectuserT* contable, clifd* master, char* desnam, char* despor, char type,
+ unsigned char* buff, int buflength);
+
+#endif
diff --git a/src/client_shutdown.c b/src/client_shutdown.c
new file mode 100644
index 0000000..4828aeb
--- /dev/null
+++ b/src/client_shutdown.c
@@ -0,0 +1,48 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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 "client_shutdown.h"
+
+void
+close_connections(int usernum, ConnectuserT** contable)
+{
+ int i;
+ if (*contable) {
+ for (i = 0; i < usernum; ++i) {
+ if (((*contable)[i].state==S_STATE_OPEN) || ((*contable)[i].state==S_STATE_STOPPED)) {
+ close((*contable)[i].connfd);
+ freebuflist(&(*contable)[i].head);
+ }
+ }
+ free(*contable);
+ (*contable) = NULL;
+ }
+}
+
+void
+clear_master_connection(clifd* master)
+{
+ if (master->ssl) {
+ SSL_free(master->ssl);
+ master->ssl = NULL;
+ }
+}
diff --git a/src/client_shutdown.h b/src/client_shutdown.h
new file mode 100644
index 0000000..0572971
--- /dev/null
+++ b/src/client_shutdown.h
@@ -0,0 +1,31 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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>
+
+#ifndef _JS_CLIENT_SHUTDOWN_H
+#define _JS_CLIENT_SHUTDOWN_H
+
+#include "activefor.h"
+
+void close_connections(int usernum, ConnectuserT** contable);
+void clear_master_connection(clifd* master);
+
+#endif
diff --git a/src/client_signals.c b/src/client_signals.c
new file mode 100644
index 0000000..ed2c7fa
--- /dev/null
+++ b/src/client_signals.c
@@ -0,0 +1,42 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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 "client_signals.h"
+#include "thread_management.h"
+#include "stats.h"
+#include "logging.h"
+
+#include <stdlib.h>
+
+ void
+client_sig_int(int signo)
+{
+#ifdef HAVE_LIBPTHREAD
+ if (!is_this_a_mainthread()) {
+ return;
+ }
+#endif
+ aflog(LOG_T_MAIN, LOG_I_NOTICE,
+ "CLIENT CLOSED cg: %ld bytes", getcg());
+ exit(0);
+}
+
diff --git a/src/client_signals.h b/src/client_signals.h
new file mode 100644
index 0000000..06c280b
--- /dev/null
+++ b/src/client_signals.h
@@ -0,0 +1,27 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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.
+ *
+ */
+
+#ifndef _JS_CLIENT_SIGNALS_H
+#define _JS_CLIENT_SIGNALS_H
+
+void client_sig_int(int); /* INT signal handler for the afclient */
+
+#endif
+
diff --git a/src/clientnames.c b/src/clientnames.c
index 9658903..414c506 100644
--- a/src/clientnames.c
+++ b/src/clientnames.c
@@ -18,6 +18,8 @@
*
*/
+#include <config.h>
+
#include <stdio.h>
#include <string.h>
#include "clientnames.h"
@@ -58,7 +60,6 @@ get_clientid(RealmT* pointer, char* clientname)
}
}
}
-
return -1;
}
diff --git a/src/file.c b/src/file.c
index e4cde62..728b0c1 100644
--- a/src/file.c
+++ b/src/file.c
@@ -18,8 +18,12 @@
*
*/
+#include <config.h>
+
#include "file.h"
#include "activefor.h"
+#include "logging.h"
+#include "network.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -110,6 +114,7 @@ parsefile(char* name, int* status)
char buff[256];
char helpbuf1[256];
char helpbuf2[256];
+ char* tmpbuf;
*status = 1;
@@ -119,10 +124,6 @@ parsefile(char* name, int* status)
cfg.keys = NULL;
cfg.size = 0;
cfg.realmtable = NULL;
- cfg.logging = 0;
- cfg.socklogging = 0;
- cfg.logfnam = NULL;
- cfg.logsport = NULL;
cfg.dateformat = NULL;
state = F_UNKNOWN;
@@ -220,9 +221,23 @@ parsefile(char* name, int* status)
else if (strcmp(helpbuf1, "baseport")==0) {
cfg.realmtable[cfg.size-1].baseport = 1;
}
+ else if (strcmp(helpbuf1, "audit")==0) {
+ cfg.realmtable[cfg.size-1].audit = 1;
+ }
else if (strcmp(helpbuf1, "dnslookups")==0) {
cfg.realmtable[cfg.size-1].dnslookups = 1;
}
+#ifdef HAVE_LIBPTHREAD
+ else if (strcmp(helpbuf1, "enableproxy")==0) {
+ if (cfg.realmtable[cfg.size-1].tunneltype == 0) {
+ cfg.realmtable[cfg.size-1].tunneltype = 1;
+ }
+ else {
+ return cfg;
+ }
+ }
+#endif
+#ifdef AF_INET6
else if (strcmp(helpbuf1, "ipv4")==0) {
if (TYPE_IS_UNSPEC(cfg.realmtable[cfg.size-1].type)) {
TYPE_SET_IPV4(cfg.realmtable[cfg.size-1].type);
@@ -239,6 +254,7 @@ parsefile(char* name, int* status)
return cfg;
}
}
+#endif
else {
return cfg;
}
@@ -260,37 +276,10 @@ parsefile(char* name, int* status)
cfg.keys = calloc(strlen(helpbuf2)+1, sizeof(char));
strcpy(cfg.keys, helpbuf2);
}
- else if (strcmp(helpbuf1, "heavylog")==0) {
- if (cfg.logging) {
- return cfg;
- }
- cfg.logging = 3;
- cfg.logfnam = calloc(strlen(helpbuf2)+1, sizeof(char));
- strcpy(cfg.logfnam, helpbuf2);
- }
- else if (strcmp(helpbuf1, "lightlog")==0) {
- if (cfg.logging) {
- return cfg;
- }
- cfg.logging = 1;
- cfg.logfnam = calloc(strlen(helpbuf2)+1, sizeof(char));
- strcpy(cfg.logfnam, helpbuf2);
- }
- else if (strcmp(helpbuf1, "heavysocklog")==0) {
- if (cfg.socklogging) {
- return cfg;
- }
- cfg.socklogging = 3;
- cfg.logsport = calloc(strlen(helpbuf2)+1, sizeof(char));
- strcpy(cfg.logsport, helpbuf2);
- }
- else if (strcmp(helpbuf1, "lightsocklog")==0) {
- if (cfg.socklogging) {
- return cfg;
- }
- cfg.socklogging = 1;
- cfg.logsport = calloc(strlen(helpbuf2)+1, sizeof(char));
- strcpy(cfg.logsport, helpbuf2);
+ else if (strcmp(helpbuf1, "log")==0) {
+ tmpbuf = calloc(strlen(helpbuf2)+1, sizeof(char));
+ strcpy(tmpbuf, helpbuf2);
+ addlogtarget(tmpbuf);
}
else if (strcmp(helpbuf1, "dateformat")==0) {
cfg.dateformat = calloc(strlen(helpbuf2)+1, sizeof(char));
diff --git a/src/http_proxy_client.c b/src/http_proxy_client.c
new file mode 100644
index 0000000..2cd301a
--- /dev/null
+++ b/src/http_proxy_client.c
@@ -0,0 +1,380 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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"
+
+#ifdef HAVE_LIBPTHREAD
+typedef struct {
+ int sockfd;
+ char *host;
+ char *serv;
+ char *proxyname;
+ char *proxyport;
+ char type;
+} proxy_argT;
+
+static void
+clean_return(int sockfd)
+{
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: clean_return");
+ close(sockfd);
+ pthread_exit(NULL);
+}
+
+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;
+ char type;
+ proxy_argT *proxy_argptr;
+
+ start_critical_section();
+ proxy_argptr = (proxy_argT *) vptr;
+
+ host = proxy_argptr->host;
+ serv = proxy_argptr->serv;
+ proxyname = proxy_argptr->proxyname;
+ proxyport = proxy_argptr->proxyport;
+ type = proxy_argptr->type;
+ conn.sockfd = proxy_argptr->sockfd;
+
+ broadcast_condition();
+ end_critical_section();
+
+ 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 proxy: connecting (postfd)...");
+ if (ip_connect(&conn.postfd, proxyname, proxyport, type)) {
+ clean_return(conn.sockfd);
+ }
+
+
+ memset(tab, 0, 9000);
+ 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 proxy: writing POST request...");
+ if (writen(conn.postfd, (unsigned char*) tab, j) <= 0) {
+ clean_return(conn.sockfd);
+ }
+
+ /* getfd */
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: connecting (getfd)...");
+ if (ip_connect(&conn.getfd, proxyname, proxyport, type)) {
+ clean_return(conn.sockfd);
+ }
+
+ memset(tab, 0, 9000);
+ 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 proxy: writing GET request...");
+ if (writen(conn.getfd, (unsigned char*) tab, j) <= 0) {
+ clean_return(conn.sockfd);
+ }
+
+ set_fd(conn.sockfd, &maxfdp1, &allset);
+ set_fd(conn.postfd, &maxfdp1, &allset);
+ set_fd(conn.getfd, &maxfdp1, &allset);
+ conn.state = C_OPEN;
+
+ memset(tab, 0, 9000);
+
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: parsing header from getfd");
+ if (parse_header(conn.getfd, tab, &hdr)) {
+ clean_return(conn.sockfd);
+ }
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: checking hdr.type");
+ 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 proxy: reading message...");
+ if (read_message(conn.sockfd, hdr.length, &conn, tab, hdr.ptr)) {
+ clean_return(conn.sockfd);
+ }
+ }
+
+ while (1) {
+ rset = allset;
+
+ if (select(maxfdp1, &rset, NULL, NULL, &tv) == 0) {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http proxy: timeout");
+ tv.tv_sec = timeout;
+ if (conn.state == C_CLOSED) {
+ continue;
+ }
+ if (conn.sent_ptr+1 >= 90000) {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http proxy: send T");
+ writen(conn.postfd, (unsigned char*) "T", 1);
+ conn.sent_ptr = 0;
+ clear_fd(&conn.postfd, &allset);
+ /* postfd */
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: connecting (postfd)...");
+ if (ip_connect(&conn.postfd, proxyname, proxyport, type)) {
+ clean_return(conn.sockfd);
+ }
+
+ memset(tab, 0, 9000);
+ 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 proxy: writing POST request...");
+ if (writen(conn.postfd, (unsigned char *) tab, j) <= 0) {
+ clean_return(conn.sockfd);
+ }
+ conn.sent_ptr = 0;
+ conn.ptr = 0;
+ conn.length = 0;
+
+ set_fd(conn.postfd, &maxfdp1, &allset);
+ }
+ else {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http proxy: send T");
+ writen(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 proxy: FD_ISSET(conn.sockfd)");
+ if (conn.state == C_CLOSED) {
+ /* postfd */
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: connecting (postfd)...");
+ if (ip_connect(&conn.postfd, proxyname, proxyport, type)) {
+ clean_return(conn.sockfd);
+ }
+ conn.state = C_OPEN;
+ }
+ n = read(conn.sockfd, conn.buf+5, 8995);
+ if (n <= 0) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: send Q");
+ writen(conn.postfd, (unsigned char *) "Q", 1);
+ clean_return(conn.sockfd);
+ }
+ 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 proxy: send message");
+ writen(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_fd(&conn.postfd, &allset);
+
+ /* postfd */
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: connecting (postfd)...");
+ if (ip_connect(&conn.postfd, proxyname, proxyport, type)) {
+ clean_return(conn.sockfd);
+ }
+
+ memset(tab, 0, 9000);
+ 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 proxy: writing POST request...");
+ if (writen(conn.postfd, (unsigned char *) tab, j) <= 0) {
+ clean_return(conn.sockfd);
+ }
+ if (conn.length > 0) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: writing old data...");
+ if (writen(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;
+
+ set_fd(conn.postfd, &maxfdp1, &allset);
+ }
+ else {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: send message");
+ writen(conn.postfd, (unsigned char *) conn.buf, 5+n);
+ conn.sent_ptr += 5+n;
+ }
+ }
+
+ /* getfd */
+ if (FD_ISSET(conn.getfd, &rset)) {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http proxy: FD_ISSET(conn.getfd)");
+ n = read(conn.getfd, tab, 9000);
+ conn.received += n;
+ if (n == 0) {
+ conn.received = 0;
+ FD_CLR(conn.getfd, &allset);
+ close(conn.getfd);
+
+ /* getfd */
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: connecting (getfd)...");
+ if (ip_connect(&conn.getfd, proxyname, proxyport, type)) {
+ clean_return(conn.sockfd);
+ }
+
+ memset(tab, 0, 9000);
+ 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 proxy: writing GET request...");
+ if (writen(conn.getfd, (unsigned char *) tab, j) <= 0) {
+ clean_return(conn.sockfd);
+ }
+ memset(tab, 0, 9000);
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: parsing header from getfd");
+ if (parse_header(conn.getfd, tab, &hdr)) {
+ clean_return(conn.sockfd);
+ }
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: checking hdr.type");
+ if (hdr.type != H_TYPE_OK) {
+ clean_return(conn.sockfd);
+ }
+
+ set_fd(conn.getfd, &maxfdp1, &allset);
+ if (hdr.length) {
+ conn.received += hdr.length;
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: reading message...");
+ 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(conn.postfd, &rset)) {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http proxy: FD_ISSET(conn.postfd)");
+ clear_fd(&conn.postfd, &allset);
+ conn.state = C_CLOSED;
+ }
+ }
+ clean_return(conn.sockfd);
+}
+
+int
+initialize_http_proxy_client(int* sockfd, const char *host, const char *serv,
+ const char *proxyname, const char *proxyport, const char type)
+{
+ 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 (proxyname == NULL) {
+ return 1;
+ }
+
+ start_critical_section();
+
+ arg.host = (char*) host;
+ arg.serv = (char*) serv;
+ arg.proxyname = (char*) proxyname;
+ arg.proxyport = (char*) proxyport;
+ arg.type = (char) type;
+ arg.sockfd = sockets[1];
+
+ retval = pthread_create(&proxy_thread, NULL, &http_proxy_client, &arg);
+
+ wait_for_condition();
+
+ end_critical_section();
+
+ return retval;
+}
+
+#endif
diff --git a/src/http_proxy_client.h b/src/http_proxy_client.h
new file mode 100644
index 0000000..f8ec5b7
--- /dev/null
+++ b/src/http_proxy_client.h
@@ -0,0 +1,27 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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.
+ *
+ */
+
+#ifndef _JS_HTTP_PROXY_CLIENT_H
+#define _JS_HTTP_PROXY_CLIENT_H
+
+int initialize_http_proxy_client(int* sockfd, const char *host, const char *serv,
+ const char *proxyname, const char *proxyport, const char type);
+
+#endif
diff --git a/src/http_proxy_functions.c b/src/http_proxy_functions.c
new file mode 100644
index 0000000..b8e5849
--- /dev/null
+++ b/src/http_proxy_functions.c
@@ -0,0 +1,267 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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 "network.h"
+#include "stats.h"
+#include "logging.h"
+
+static char isseed;
+
+int
+myrand(int down, int up)
+{
+ struct timeval tv;
+ if (!isseed) {
+ gettimeofday(&tv, 0);
+ srand(tv.tv_sec);
+ isseed = 1;
+ }
+ return ( down + ( rand() % (up - down + 1) ) );
+}
+
+void
+mysleep(double time)
+{
+ struct timeval tv;
+ tv.tv_sec = (int) time;
+ tv.tv_usec = (int)(time * 1000000)%1000000;
+ select(0, NULL, NULL, NULL, &tv);
+}
+
+void
+delete_user(connection* cnts, int i, fd_set* allset)
+{
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: delete_user(%d)", i);
+ clear_fd(&(cnts[i].sockfd), allset);
+ if (!(cnts[i].state & C_POST_WAIT)) {
+ clear_fd(&(cnts[i].postfd), allset);
+ }
+ if ((cnts[i].type == 0) && (!(cnts[i].state & C_GET_WAIT))) {
+ clear_fd(&(cnts[i].getfd), allset);
+ }
+ cnts[i].state = C_CLOSED;
+ cnts[i].sent_ptr = cnts[i].ptr = cnts[i].length = 0;
+ cnts[i].type = 0;
+}
+
+int
+parse_header(int fd, char* tab, header* hdr)
+{
+ int n, i, j, state = 0;
+ char tmpt[100];
+ n = read(fd, tab, 9000);
+ hdr->allreaded = n;
+ i = j = 0;
+ memset(tmpt, 0, 100);
+ hdr->ptr = 0;
+ hdr->length = 0;
+ while (i < n) {
+ if (j == 99)
+ return 1;
+ switch (state) {
+ case 0:
+ if ((tab[i] != ' ') && (tab[i] != '\t')) {
+ tmpt[j] = tab[i];
+ ++j;
+ }
+ else {
+ tmpt[j] = 0;
+ if (strcmp(tmpt, "GET") == 0) {
+ hdr->type = H_TYPE_GET;
+ state = 1;
+ break;
+ }
+ if (strcmp(tmpt, "POST") == 0) {
+ hdr->type = H_TYPE_POST;
+ state = 1;
+ break;
+ }
+ if ((strcmp(tmpt, "HTTP/1.0") == 0) || (strcmp(tmpt, "HTTP/1.1") == 0)) {
+ hdr->type = H_TYPE_OK;
+ state = 6;
+ break;
+ }
+ return 1;
+ }
+ break;
+ case 1:
+ if ((tab[i] != ' ') && (tab[i] != '\t')) {
+ tmpt[0] = tab[i];
+ j = 1;
+ state = 2;
+ }
+ break;
+ case 2:
+ if (tab[i] != '=') {
+ tmpt[j] = tab[i];
+ ++j;
+ }
+ else {
+ tmpt[j] = 0;
+ if (strcmp(tmpt, "/yahpt.html?id")) {
+ return 1;
+ }
+ j = 0;
+ state = 3;
+ }
+ break;
+ case 3:
+ if ((tab[i] != ' ') && (tab[i] != '\t')) {
+ if (j == 9) {
+ return 1;
+ }
+ hdr->id[j] = tab[i];
+ ++j;
+ }
+ else {
+ if (j != 9) {
+ return 1;
+ }
+ hdr->id[j] = 0;
+ state = 4;
+ }
+ break;
+ case 4:
+ if (tab[i] == '\n')
+ state = 5;
+ break;
+ case 5:
+ if (tab[i] == '\n') {
+ hdr->ptr = i+1;
+ hdr->length = n - hdr->ptr;
+ return 0;
+ }
+ if (tab[i] != '\r') {
+ state = 4;
+ }
+ break;
+ case 6:
+ if ((tab[i] != ' ') && (tab[i] != '\t')) {
+ tmpt[0] = tab[i];
+ j = 1;
+ state = 7;
+ }
+ break;
+ case 7:
+ if ((tab[i] == ' ') || (tab[i] == '\t')) {
+ tmpt[j] = 0;
+ if (strcmp(tmpt, "200")) {
+ return 1;
+ }
+ state = 4;
+ }
+ else {
+ tmpt[j] = tab[i];
+ ++j;
+ }
+ break;
+ }
+ ++i;
+ }
+ return 1;
+}
+
+void
+set_fd(int fd, int* maxfdp1, fd_set* allset)
+{
+ FD_SET(fd, allset);
+ (*maxfdp1) = ((*maxfdp1) > fd) ? (*maxfdp1) : (fd + 1);
+}
+
+void
+close_fd(int* fd)
+{
+ close(*fd);
+}
+
+void
+clear_fd(int* fd, fd_set* set)
+{
+ FD_CLR(*fd, set);
+ close_fd(fd);
+}
+
+int
+read_message(int fd, int length, connection* client, char* tab, int ptr)
+{
+ int j = 0;
+ int tmp = 0;
+ while (j < length) {
+ if (client->curreceived + length-j > client->toreceive) {
+ writen(fd, (unsigned char*) (tab+ptr+j), client->toreceive - client->curreceived);
+ j += client->toreceive - client->curreceived;
+ client->curreceived += client->toreceive - client->curreceived;
+ if (client->read_state == 0) {
+ switch (tab[ptr + j]) {
+ case 'M': {
+ if (j + 5 <= length) {
+ memcpy(&tmp, &tab[ptr + j + 1], 4);
+ client->toreceive = ntohl(tmp);
+ client->curreceived = 0;
+ j += 5;
+ }
+ else if (j + 1 < length) {
+ memcpy(client->readed_length, &tab[ptr + j + 1], length - j - 1);
+ client->read_state = length - j;
+ j += length - j;
+ }
+ else {
+ ++j;
+ client->read_state = 1;
+ }
+ break;
+ }
+ case 'T': {
+ ++j;
+ break;
+ }
+ default: {
+ return 1;
+ }
+ }
+ }
+ else {
+ if (j + 5 - client->read_state <= length) {
+ memcpy(&client->readed_length[client->read_state-1], &tab[ptr + j], 5 - client->read_state);
+ memcpy(&tmp, client->readed_length, 4);
+ client->toreceive = ntohl(tmp);
+ client->curreceived = 0;
+ j += 5 - client->read_state;
+ client->read_state = 0;
+ }
+ else {
+ memcpy(&client->readed_length[client->read_state-1], &tab[ptr + j], length - j);
+ client->read_state += length - j;
+ j += length -j;
+ }
+ }
+ }
+ else {
+ client->curreceived += length-j;
+ writen(fd, (unsigned char*) (tab+ptr+j), length-j);
+ j += length-j;
+ }
+ }
+ return 0;
+}
diff --git a/src/http_proxy_functions.h b/src/http_proxy_functions.h
new file mode 100644
index 0000000..9c9b56d
--- /dev/null
+++ b/src/http_proxy_functions.h
@@ -0,0 +1,80 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/select.h>
+#include <unistd.h>
+
+#ifndef _JS_HTTP_PROXY_FUNCTIONS_H
+#define _JS_HTTP_PROXY_FUNCTIONS_H
+
+#define C_CLOSED 0
+#define C_POST_WAIT 1
+#define C_GET_WAIT 2
+#define C_OPEN 4
+
+#define H_TYPE_GET 0
+#define H_TYPE_POST 1
+#define H_TYPE_OK 2
+#define H_TYPE_ERROR 3
+
+typedef struct {
+ char type;
+ char id[10];
+ int ptr;
+ int length;
+ int allreaded;
+} header;
+
+typedef struct {
+ char read_state;
+ char readed_length[4];
+ char state;
+ char id[10];
+ int postfd;
+ int getfd;
+ int sent_ptr;
+ int sockfd;
+ char buf[9000];
+ char tmpbuf[9000];
+ char tmpstate;
+ int tmpfd;
+ char type;
+ header tmpheader;
+ int ptr;
+ int length;
+ int curreceived;
+ int toreceive;
+ int received;
+} connection;
+
+int myrand(int, int);
+void mysleep(double);
+int parse_header(int, char*, header*);
+int read_message(int, int, connection*, char*, int);
+void delete_user(connection*, int, fd_set*);
+void set_fd(int, int*, fd_set*);
+void close_fd(int*);
+void clear_fd(int*, fd_set*);
+
+#endif
diff --git a/src/http_proxy_server.c b/src/http_proxy_server.c
new file mode 100644
index 0000000..a07d6ce
--- /dev/null
+++ b/src/http_proxy_server.c
@@ -0,0 +1,459 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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_server.h"
+#include "thread_management.h"
+#include "stats.h"
+#include "logging.h"
+#include "network.h"
+
+#ifdef HAVE_LIBPTHREAD
+
+typedef struct {
+ int sockfd;
+ char *host;
+ char *serv;
+ socklen_t *addrlenp;
+ char type;
+ int limit;
+} sproxy_argT;
+
+int
+afserver_connect(int* sockfd, int afserverfd, struct sockaddr* cliaddr, socklen_t* addrlenp, char type)
+{
+ int sockets[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets)) {
+ return 1;
+ }
+ if (write(afserverfd, &sockets[0], 4) != 4) {
+ return 2;
+ }
+ if (write(afserverfd, &type, 1) != 1) {
+ return 3;
+ }
+ if (write(afserverfd, addrlenp, 4) != 4) {
+ return 3;
+ }
+ if (write(afserverfd, cliaddr, *addrlenp) != *addrlenp) {
+ return 5;
+ }
+ (*sockfd) = sockets[1];
+ return 0;
+}
+
+void*
+http_proxy_server(void *vptr)
+{
+ int listenfd, connfd, afserverfd;
+ struct sockaddr* cliaddr;
+ char tab[9000];
+ connection* table;
+ header hdr;
+ int i, n, maxfdp1;
+ fd_set rset, allset;
+ struct timeval tv;
+ int maxclients, tmp;
+ int timeout = 5;
+ socklen_t *addrlenp;
+ char type, nothttp;
+ char *host, *serv;
+ sproxy_argT *proxy_argptr;
+
+ start_critical_section();
+ proxy_argptr = (sproxy_argT *) vptr;
+
+ afserverfd = proxy_argptr->sockfd;
+ host = proxy_argptr->host;
+ serv = proxy_argptr->serv;
+ addrlenp = proxy_argptr->addrlenp;
+ type = proxy_argptr->type;
+ maxclients = proxy_argptr->limit+1;
+
+ broadcast_condition();
+ end_critical_section();
+
+ table = calloc(maxclients, sizeof(connection));
+ if (table == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http proxy: Can't allocate memory... exiting.");
+ 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);
+ exit(1);
+ }
+ cliaddr = malloc(*addrlenp);
+
+ FD_ZERO(&allset);
+ FD_SET(listenfd, &allset);
+ maxfdp1 = listenfd + 1;
+ tv.tv_usec = 0;
+ tv.tv_sec = timeout;
+
+ while (1) {
+ rset = allset;
+
+ if (select(maxfdp1, &rset, NULL, NULL, &tv) == 0) {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http proxy: timeout");
+ 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);
+ if (table[i].sent_ptr+1 >= 90000) {
+ writen(table[i].getfd, (unsigned char*) "T", 1);
+ table[i].sent_ptr = 0;
+ clear_fd(&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);
+ table[i].sent_ptr += 1;
+ }
+ }
+ continue;
+ }
+
+ /* http proxy tunnels */
+ for (i = 0; i < maxclients; ++i) {
+ if ((table[i].state == C_CLOSED) || (table[i].type == 1)) {
+ continue;
+ }
+
+ /* 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);
+ n = read(table[i].sockfd, table[i].buf+5, 8995);
+ if (n <= 0) {
+ writen(table[i].getfd, (unsigned char*) "Q", 1);
+ delete_user(table, i, &allset);
+ continue;
+ }
+ table[i].buf[0] = 'M';
+ 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);
+ 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);
+ 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);
+ table[i].sent_ptr += n+5;
+ }
+ }
+
+ /* getfd */
+ if (FD_ISSET(table[i].getfd, &rset)) {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http proxy: FD_ISSET(table[%d].getfd)", i);
+ delete_user(table, i, &allset);
+ continue;
+ }
+
+ /* postfd */
+ if (FD_ISSET(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);
+ if (n != 0) {
+ table[i].received += n;
+ if (read_message(table[i].sockfd, n, &table[i], tab, 0)) {
+ delete_user(table, i, &allset);
+ }
+ }
+ if ((n == 0) || (table[i].received == 90000)) {
+ table[i].received = 0;
+ clear_fd(&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...");
+ table[i].state &= ~C_POST_WAIT;
+ table[i].postfd = table[i].tmpfd;
+ set_fd(table[i].postfd, &maxfdp1, &allset);
+ table[i].tmpstate = 0;
+ if (table[i].tmpheader.length) {
+ table[i].received += table[i].tmpheader.length;
+ if (read_message(table[i].sockfd, table[i].tmpheader.length, &table[i],
+ table[i].tmpbuf, table[i].tmpheader.ptr)) {
+ delete_user(table, i, &allset);
+ }
+ }
+ }
+ continue;
+ }
+ }
+ }
+
+ /* direct tunnels */
+ for (i = 0; i < maxclients; ++i) {
+ if ((table[i].state == C_OPEN) && (table[i].type == 1)) {
+
+ 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);
+ }
+ else {
+ delete_user(table, i, &allset);
+ continue;
+ }
+ }
+
+ if (FD_ISSET(table[i].postfd, &rset)) {
+ n = read(table[i].postfd, tab, 9000);
+ if (n > 0) {
+ write(table[i].sockfd, tab, n);
+ }
+ else {
+ delete_user(table, i, &allset);
+ continue;
+ }
+ }
+
+ }
+ }
+
+ /* 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) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: New connection...");
+ }
+ else {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: New connection --> EAGAIN");
+ }
+ memset(tab, 0, 9000);
+ nothttp = 0;
+ if (parse_header(connfd, tab, &hdr)) {
+ nothttp = 1;
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: no http header...");
+ }
+ n = -1;
+ for (i = 0; i < maxclients; ++i) {
+ if (table[i].state == C_CLOSED) {
+ if (n == -1)
+ n = i;
+ }
+ else {
+ if ((!nothttp) && (strcmp(table[i].id, hdr.id) == 0)) {
+ break;
+ }
+ }
+ }
+ if (i < maxclients) { /* the client exists */
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: the client exist...");
+ if (hdr.type == H_TYPE_GET) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: type GET...");
+ if (!(table[i].state & C_GET_WAIT)) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: not waiting for GET...");
+ table[i].sent_ptr = 0;
+ FD_CLR(table[i].sockfd, &allset);
+ clear_fd(&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...");
+ 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);
+ table[i].state = C_CLOSED;
+ continue;
+ }
+ table[i].state |= C_OPEN;
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: OPEN...");
+ }
+ table[i].state &= ~C_GET_WAIT;
+ table[i].sent_ptr = 0;
+ table[i].getfd = connfd;
+ set_fd(table[i].sockfd, &maxfdp1, &allset);
+ set_fd(table[i].getfd, &maxfdp1, &allset);
+ memset(tab, 0, 9000);
+ sprintf(tab,
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 90000\r\n"
+ "Connection: close\r\n"
+ "Pragma: no-cache\r\n"
+ "Cache-Control: no-cache, no-store, must-revalidate\r\n"
+ "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) {
+ 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) {
+ delete_user(table, i, &allset);
+ continue;
+ }
+ }
+ table[i].sent_ptr = table[i].length;
+ table[i].ptr = 0;
+ table[i].length = 0;
+ }
+ else if (hdr.type == H_TYPE_POST) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: type POST...");
+ if (!(table[i].state & C_POST_WAIT)) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: unexpected POST request...");
+ if (table[i].tmpstate == 0) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: buffering POST request...");
+ table[i].tmpstate = 1;
+ 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)",
+ table[i].received);
+ delete_user(table, i, &allset);
+ }
+ }
+ else {
+ if (hdr.length) {
+ table[i].received += hdr.length;
+ if (read_message(table[i].sockfd, hdr.length, &table[i], tab, hdr.ptr)) {
+ delete_user(table, i, &allset);
+ }
+ }
+ table[i].state &= ~C_POST_WAIT;
+ table[i].postfd = connfd;
+ set_fd(table[i].postfd, &maxfdp1, &allset);
+ }
+ }
+ else {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: unrecognized type...");
+ 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...");
+ if (!nothttp) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: http header...");
+ if (hdr.type == H_TYPE_POST) { /* POST request must be first */
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: type POST...");
+ table[n].state = C_GET_WAIT;
+ memcpy(table[n].id,hdr.id, 9);
+ table[n].postfd = connfd;
+ set_fd(table[n].postfd, &maxfdp1, &allset);
+ }
+ else {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: closing this connection...");
+ close_fd(&connfd);
+ continue;
+ }
+ }
+ else {
+ table[n].state = C_OPEN;
+ table[n].postfd = connfd;
+ table[n].type = 1;
+ set_fd(table[n].postfd, &maxfdp1, &allset);
+ if (afserver_connect(&table[n].sockfd, afserverfd, cliaddr, addrlenp, 0)) {
+ clear_fd(&table[n].postfd, &allset);
+ table[n].state = C_CLOSED;
+ continue;
+ }
+ set_fd(table[n].sockfd, &maxfdp1, &allset);
+ write(table[n].sockfd, tab, hdr.allreaded);
+ }
+ }
+ else {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: closing this connection...");
+ close_fd(&connfd);
+ continue;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+int
+initialize_http_proxy_server(int* sockfd, const char *host, const char *serv, socklen_t *addrlenp, const char type, int limit)
+{
+ int retval;
+ int sockets[2];
+ pthread_t proxy_thread;
+ static sproxy_argT arg;
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets)) {
+ return 1;
+ }
+ (*sockfd) = sockets[0];
+
+ start_critical_section();
+
+ arg.host = (char*) host;
+ arg.serv = (char*) serv;
+ arg.addrlenp = addrlenp;
+ arg.limit = limit;
+ arg.type = (char) type;
+ arg.sockfd = sockets[1];
+
+ retval = pthread_create(&proxy_thread, NULL, &http_proxy_server, &arg);
+
+ wait_for_condition();
+
+ end_critical_section();
+
+ return retval;
+}
+
+#endif
diff --git a/src/http_proxy_server.h b/src/http_proxy_server.h
new file mode 100644
index 0000000..6e13549
--- /dev/null
+++ b/src/http_proxy_server.h
@@ -0,0 +1,29 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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.
+ *
+ */
+
+#ifndef _JS_HTTP_PROXY_SERVER_H
+#define _JS_HTTP_PROXY_SERVER_H
+
+#include "http_proxy_functions.h"
+#include "network.h"
+
+int initialize_http_proxy_server(int* sockfd, const char *host, const char *serv, socklen_t *addrlenp, const char type, int limit);
+
+#endif
diff --git a/src/logging.c b/src/logging.c
new file mode 100644
index 0000000..650ce9e
--- /dev/null
+++ b/src/logging.c
@@ -0,0 +1,391 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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 "logging.h"
+#include "network.h"
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include <stdarg.h>
+
+static llnodeT* head = NULL;
+static char verlev;
+static char format[51] = "%Y-%m-%d %H:%M:%S";
+
+void
+setdateformat(char* dateformat)
+{
+ if (dateformat) {
+ strncpy(format, dateformat, 50);
+ }
+}
+
+char*
+getdateformat()
+{
+ return format;
+}
+
+char*
+localdate(time_t* sec)
+{
+ struct tm* tm;
+ static char localdat[31];
+ tm = localtime(sec);
+ memset(localdat, 0, 31);
+ strftime(localdat, 30, format, tm);
+ return localdat;
+}
+
+char*
+datum(void)
+{
+ time_t sec;
+ struct tm* tm;
+ static char timedat[31];
+ time(&sec);
+ tm = localtime(&sec);
+ memset(timedat, 0, 31);
+ strftime(timedat, 30, format, tm);
+ return timedat;
+}
+
+llnodeT*
+getloglisthead()
+{
+ return head;
+}
+
+int
+checkmsgti(llnodeT* target, char* tab)
+{
+ if (strcmp(tab, "LOG_T_ALL") == 0) {
+ target->msgtype |= LOG_T_ALL;
+ }
+ else if (strcmp(tab, "LOG_T_USER") == 0) {
+ target->msgtype |= LOG_T_USER;
+ }
+ else if (strcmp(tab, "LOG_T_CLIENT") == 0) {
+ target->msgtype |= LOG_T_CLIENT;
+ }
+ else if (strcmp(tab, "LOG_T_INIT") == 0) {
+ target->msgtype |= LOG_T_INIT;
+ }
+ else if (strcmp(tab, "LOG_T_MANAGE") == 0) {
+ target->msgtype |= LOG_T_MANAGE;
+ }
+ else if (strcmp(tab, "LOG_T_MAIN") == 0) {
+ target->msgtype |= LOG_T_MAIN;
+ }
+ else if (strcmp(tab, "LOG_I_ALL") == 0) {
+ target->importance |= LOG_I_ALL;
+ }
+ else if (strcmp(tab, "LOG_I_CRIT") == 0) {
+ target->importance |= LOG_I_CRIT;
+ }
+ else if (strcmp(tab, "LOG_I_DEBUG") == 0) {
+ target->importance |= LOG_I_DEBUG;
+ }
+ else if (strcmp(tab, "LOG_I_INFO") == 0) {
+ target->importance |= LOG_I_INFO;
+ }
+ else if (strcmp(tab, "LOG_I_NOTICE") == 0) {
+ target->importance |= LOG_I_NOTICE;
+ }
+ else if (strcmp(tab, "LOG_I_WARNING") == 0) {
+ target->importance |= LOG_I_WARNING;
+ }
+ else if (strcmp(tab, "LOG_I_ERR") == 0) {
+ target->importance |= LOG_I_ERR;
+ }
+ else {
+ return 1; /* unknown msgtype/importance */
+ }
+ return 0;
+}
+
+int
+checklogtarget(llnodeT* target)
+{
+ char* ptr;
+ char desc[100];
+ char type = 0;
+ char tab[100];
+ int tmpfd;
+ int state, i;
+ if ((target == NULL) || (target->cmdline == NULL)) {
+ return 1; /* some of the important data is NULL */
+ }
+ state = 0; /* we are at the beginning of the cmdline */
+ memset(tab, 0, 100);
+ i = 0;
+ ptr = target->cmdline;
+ while ((*ptr) != 0) {
+ switch (state) {
+ /* beginning of the cmdline */
+ case 0: {
+ if ((*ptr) == ',') {
+ tab[i] = 0;
+ if (strcmp(tab, "file") == 0) {
+ type = LOG_L_FILE;
+ }
+ else if (strcmp(tab, "sock") == 0) {
+ type = LOG_L_SOCK;
+ }
+ else {
+ return 2; /* unknown type of the target */
+ }
+ state = 1; /* we are at the beginning of the file/sock description */
+ memset(tab, 0, 100);
+ memset(desc, 0, 100);
+ i = 0;
+ break;
+ }
+ if (i == 98) {
+ return 2; /* unknown type of the target (name too long) */
+ }
+ tab[i] = (*ptr);
+ ++i;
+ break;
+ }
+ /* beginning of the file/sock description */
+ case 1: {
+ if ((*ptr) == ',') {
+ tab[i] = 0;
+ switch (type) {
+ case LOG_L_FILE: {
+ target->logfd = fopen(tab, "a");
+ if (target->logfd == NULL) {
+ return 4; /* logging to a non-opened file? */
+ }
+ state = 3; /* we want to read msgtype and importance */
+ break;
+ }
+ case LOG_L_SOCK: {
+ strncpy(desc, tab, 99);
+ state = 2; /* we want to open a socket (read port first) */
+ break;
+ }
+ default: {
+ return 2; /* unknown type of the target */
+ }
+ }
+ memset(tab, 0, 100);
+ i = 0;
+ break;
+ }
+ if (i == 98) {
+ return 3; /* wrong file/sock description (name too long) */
+ }
+ tab[i] = (*ptr);
+ ++i;
+ break;
+ }
+ /* beginning of the sock port description */
+ case 2: {
+ if ((*ptr) == ',') {
+ tab[i] = 0;
+ if (ip_connect(&tmpfd, desc, tab, 1)) {
+ return 5; /* can't connect to host:port */
+ }
+ target->logfd = fdopen(tmpfd, "a");
+ if (target->logfd == NULL) {
+ return 4; /* can't create FILE* to log to */
+ }
+ state = 3; /* we want to read msgtype and importance */
+ memset(tab, 0, 100);
+ i = 0;
+ break;
+ }
+ if (i == 98) {
+ return 3; /* wrong file/sock description (name too long) */
+ }
+ tab[i] = (*ptr);
+ ++i;
+ break;
+ }
+ /* beginning of the msgtype and importance section */
+ case 3: {
+ if ((*ptr) == ',') {
+ tab[i] = 0;
+ if (checkmsgti(target, tab)) {
+ return 6;
+ }
+ memset(tab, 0, 100);
+ i = 0;
+ break;
+ }
+ if (i == 98) {
+ return 6; /* wrong msgtype/importance description (name too long) */
+ }
+ tab[i] = (*ptr);
+ ++i;
+ break;
+ }
+ }
+ ++ptr;
+ }
+ if (i != 0) {
+ if (state == 3) {
+ tab[i] = 0;
+ if (checkmsgti(target, tab)) {
+ return 6;
+ }
+ }
+ else {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void
+addlogtarget(char* cmdline)
+{
+ llnodeT* newnode = calloc(1, sizeof(llnodeT));
+ newnode->cmdline = cmdline;
+ newnode->next = head;
+ head = newnode;
+}
+
+int
+loginit(char verl, char* dateformat)
+{
+ llnodeT* ptr;
+ int n;
+
+ verlev = 0;
+ if (verl) {
+ switch (verl) {
+ case 1: {
+ verlev = LOG_I_NOTICE | LOG_I_CRIT;
+ break;
+ }
+ case 2: {
+ verlev = LOG_I_INFO | LOG_I_NOTICE | LOG_I_CRIT;
+ break;
+ }
+ case 3: {
+ verlev = LOG_I_INFO | LOG_I_NOTICE | LOG_I_WARNING | LOG_I_CRIT;
+ break;
+ }
+ case 4: {
+ verlev = LOG_I_INFO | LOG_I_NOTICE | LOG_I_WARNING | LOG_I_ERR | LOG_I_CRIT;
+ break;
+ }
+ case 5: {
+ verlev = LOG_I_INFO | LOG_I_NOTICE | LOG_I_WARNING | LOG_I_ERR | LOG_I_CRIT | LOG_I_DEBUG;
+ break;
+ }
+ default: {
+ verlev = LOG_I_ALL;
+ break;
+ }
+ }
+ }
+
+ setdateformat(dateformat);
+
+ ptr = head;
+ while (ptr) {
+ if ((n = checklogtarget(ptr)) != 0) {
+ return n;
+ }
+ ptr = ptr->next;
+ }
+
+ return 0;
+}
+
+void
+initializelogging(char verl, char* dateformat)
+{
+ int k;
+ if ((k = loginit(verl, dateformat)) != 0) {
+ switch (k) {
+ /* wrong format of the logcmd */
+ case 1: {
+ printf("Wrong format of the logcmd\n");
+ break;
+ }
+ /* unknown type of the logging target */
+ case 2: {
+ printf("Unknown type of the logging target\n");
+ break;
+ }
+ /* wrong description of the logging target (name too long) */
+ case 3: {
+ printf("Wrong description of the logging target (name too long)\n");
+ break;
+ }
+ /* can't open file to log to */
+ case 4: {
+ printf("Can't open file to log to\n");
+ break;
+ }
+ /* can't connect to target host */
+ case 5: {
+ printf("Can't connect to target host\n");
+ break;
+ }
+ /* wrong msgtype/importance description */
+ case 6: {
+ printf("Wrong msgtype/importance description\n");
+ break;
+ }
+ }
+ exit(1);
+ }
+}
+
+void
+aflog(char type, char importance, const char* form, ...)
+{
+ llnodeT* ptr;
+ va_list ap;
+
+ if (verlev & importance) {
+ if (format[0] != 0) {
+ printf("[%s] ", datum());
+ }
+ va_start(ap, form);
+ vfprintf(stdout, form, ap);
+ va_end(ap);
+ printf("\n");
+ }
+
+ ptr = head;
+ while (ptr) {
+ if ((type & ptr->msgtype) && (importance & ptr->importance)) {
+ if (format[0] != 0) {
+ fprintf(ptr->logfd, "[%s] ", datum());
+ }
+ va_start(ap, form);
+ vfprintf(ptr->logfd, form, ap);
+ va_end(ap);
+ fprintf(ptr->logfd, "\n");
+ fflush(ptr->logfd);
+ }
+ ptr = ptr->next;
+ }
+}
+
diff --git a/src/logging.h b/src/logging.h
new file mode 100644
index 0000000..ec9d110
--- /dev/null
+++ b/src/logging.h
@@ -0,0 +1,78 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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 <stdio.h>
+#include <time.h>
+
+#ifndef _JS_LOGGING_H
+#define _JS_LOGGING_H
+
+/* some constants for logging functions */
+ /* type of the message */
+
+#define LOG_T_ALL (LOG_T_USER | LOG_T_CLIENT | LOG_T_INIT | LOG_T_MANAGE | LOG_T_MAIN)
+#define LOG_T_USER 1
+#define LOG_T_CLIENT 2
+#define LOG_T_INIT 4
+#define LOG_T_MANAGE 8
+#define LOG_T_MAIN 16
+
+ /* importance of the message */
+
+#define LOG_I_ALL (LOG_I_CRIT | LOG_I_DEBUG | LOG_I_DDEBUG | LOG_I_INFO | LOG_I_NOTICE | LOG_I_WARNING | LOG_I_ERR)
+#define LOG_I_CRIT 1
+#define LOG_I_DEBUG 2
+#define LOG_I_DDEBUG 4
+#define LOG_I_INFO 8
+#define LOG_I_NOTICE 16
+#define LOG_I_WARNING 32
+#define LOG_I_ERR 64
+
+ /* type of the logging target */
+
+#define LOG_L_FILE 1
+#define LOG_L_SOCK 2
+
+/* a structure that keeps information about logging target */
+typedef struct llnode {
+ char* cmdline;
+ char msgtype;
+ char importance;
+ FILE* logfd;
+ struct llnode* next;
+} llnodeT;
+
+ /* set dateformat */
+void setdateformat(char* dateformat);
+ /* get dateformat */
+char* getdateformat();
+ /* get llnodeT head */
+llnodeT* getloglisthead();
+ /* add logging target */
+void addlogtarget(char* cmdline);
+ /* initialize logging routine */
+void initializelogging(char verlev, char* dateformat);
+ /* log to a file or|and screen */
+void aflog(char type, char importance, const char* format, ...);
+ /* get text representation of the date */
+char* localdate(time_t* sec);
+
+#endif
+
diff --git a/src/make_ssl_handshake.c b/src/make_ssl_handshake.c
index a5c97eb..d4cdd55 100644
--- a/src/make_ssl_handshake.c
+++ b/src/make_ssl_handshake.c
@@ -18,10 +18,11 @@
*
*/
+#include <config.h>
+
#include "make_ssl_handshake.h"
#include "stats.h"
-
-#include <config.h>
+#include "logging.h"
#include <errno.h>
#include <openssl/err.h>
@@ -30,7 +31,8 @@ void
make_ssl_initialize(clifd *cliconn)
{
if (SSL_set_fd(cliconn->ssl, cliconn->commfd) != 1) {
- aflog(0, "Problem with initializing ssl... exiting");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Problem with initializing ssl... exiting");
exit(1);
}
}
@@ -40,7 +42,7 @@ make_ssl_accept(clifd *cliconn)
{
int result;
if ((result = SSL_accept(cliconn->ssl)) != 1) {
- return get_ssl_error(cliconn, " SSL_accept has failed", result);
+ return get_ssl_error(cliconn, "SSL_accept has failed", result);
}
return 0;
}
@@ -55,45 +57,55 @@ get_ssl_error(clifd *cliconn, char* info, int result)
merror = SSL_get_error(cliconn->ssl, result);
switch (merror) {
case SSL_ERROR_NONE : {
- aflog(2, "%s(%d): none", info, result);
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): none", info, result);
break;
}
case SSL_ERROR_ZERO_RETURN : {
- aflog(2, "%s(%d): zero", info, result);
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): zero", info, result);
break;
}
case SSL_ERROR_WANT_READ : {
- aflog(2, "%s(%d): w_read", info, result);
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): w_read", info, result);
break;
}
case SSL_ERROR_WANT_WRITE : {
- aflog(2, "%s(%d): w_write", info, result);
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): w_write", info, result);
break;
}
case SSL_ERROR_WANT_CONNECT : {
- aflog(2, "%s(%d): w_connect", info, result);
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): w_connect", info, result);
break;
}
case SSL_ERROR_WANT_X509_LOOKUP : {
- aflog(2, "%s(%d): w_x509_lookup", info, result);
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): w_x509_lookup", info, result);
break;
}
case SSL_ERROR_SYSCALL : {
- aflog(2, "%s(%d): syscall", info, result);
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): syscall", info, result);
break;
}
case SSL_ERROR_SSL : {
SSL_load_error_strings();
#ifdef HAVE_ERR_ERROR_STRING
- aflog(2, "%s(%d): ssl:%s", info, result,
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): ssl:%s", info, result,
ERR_error_string(ERR_get_error(), err_buff));
#else
- aflog(2, "%s(%d): ssl", info, result);
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): ssl", info, result);
#endif
break;
}
default: {
- aflog(2, "%s(%d): unrecognized error (%d)", info, result, errno);
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): unrecognized error (%d)", info, result, errno);
}
}
if (merror == SSL_ERROR_WANT_READ) {
diff --git a/src/network.c b/src/network.c
index 7618c76..0903b4f 100644
--- a/src/network.c
+++ b/src/network.c
@@ -24,6 +24,7 @@
#include "network.h"
#include "activefor.h"
#include "stats.h"
+#include "logging.h"
#include <string.h>
#include <errno.h>
#include <zlib.h>
@@ -395,7 +396,8 @@ send_message(char type, clifd fd, unsigned char* buf, int amount)
unsigned long clen;
int length;
static unsigned char bufor[9000];
- aflog(4, " send_message: ssl:%s zlib:%s length:%d", (TYPE_IS_SSL(type))?"yes":"no",
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "send_message: ssl:%s zlib:%s length:%d", (TYPE_IS_SSL(type))?"yes":"no",
(TYPE_IS_ZLIB(type))?"yes":"no", amount);
clen = 8995;
length = amount - 5;
@@ -444,7 +446,8 @@ get_message(char type, clifd fd, unsigned char* buf, int amount)
int length;
unsigned long elen;
static unsigned char bufor[9000];
- aflog(4, " get_message: ssl:%s zlib:%s length:%d", (TYPE_IS_SSL(type))?"yes":"no",
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "get_message: ssl:%s zlib:%s length:%d", (TYPE_IS_SSL(type))?"yes":"no",
(TYPE_IS_ZLIB(type))?"yes":"no", amount);
if (amount == -5) {
if (TYPE_IS_SSL(type)) {
diff --git a/src/network.h b/src/network.h
index 401a627..ee03af6 100644
--- a/src/network.h
+++ b/src/network.h
@@ -30,7 +30,9 @@
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
+#ifdef HAVE_LIBPTHREAD
#include <pthread.h>
+#endif
#include <netdb.h>
#include <openssl/ssl.h>
diff --git a/src/realmnames.c b/src/realmnames.c
index 84d9f53..77065bf 100644
--- a/src/realmnames.c
+++ b/src/realmnames.c
@@ -18,6 +18,8 @@
*
*/
+#include <config.h>
+
#include <stdio.h>
#include <string.h>
#include "realmnames.h"
diff --git a/src/remoteadmin.c b/src/remoteadmin.c
index 4e777c1..c2ada6e 100644
--- a/src/remoteadmin.c
+++ b/src/remoteadmin.c
@@ -18,11 +18,51 @@
*
*/
+#include <config.h>
+
#include "remoteadmin.h"
static char newmessage;
static int
+parse_int(unsigned char* buff, int* ret)
+{
+ int intarg, i;
+ char guard;
+ if (((i = sscanf((char*) &buff[*ret], "%d%c", &intarg, &guard)) == 2) || (i == 1)) {
+ if (i == 1) {
+ guard = ' ';
+ }
+ if (!isspace(guard)) {
+ return -1;
+ }
+ guard = 0;
+ i = (*ret);
+ while (buff[i] != 0) {
+ if (guard == 0) {
+ if (isspace(buff[i])) {
+ guard = 1;
+ }
+ }
+ else {
+ if (!isspace(buff[i])) {
+ break;
+ }
+ }
+ ++i;
+ }
+ if (buff[i] == '.') {
+ ++i;
+ }
+ (*ret) = i;
+ return intarg;
+ }
+ else {
+ return -1;
+ }
+}
+
+static int
parse_cmd(unsigned char* buff, int* ret)
{
int i, j, state;
@@ -70,6 +110,12 @@ parse_cmd(unsigned char* buff, int* ret)
if (strcmp(cmd, "cshow") == 0) { return 5; }
if (strcmp(cmd, "ushow") == 0) { return 6; }
if (strcmp(cmd, "quit") == 0) { return 7; }
+ if (strcmp(cmd, "timeout") == 0) { return 8; }
+ if (strcmp(cmd, "audit") == 0) { return 9; }
+ if (strcmp(cmd, "dnslookups") == 0) { return 10; }
+ if (strcmp(cmd, "dateformat") == 0) { return 11; }
+ if (strcmp(cmd, "kuser") == 0) { return 12; }
+ if (strcmp(cmd, "kclient") == 0) { return 13; }
return 0;
}
@@ -134,12 +180,16 @@ serve_admin(ConfigurationT* config, int realm, int client, unsigned char* buff)
{
int length, n, i, j, ret;
time_t now, tmp;
+ llnodeT* llptr;
+ alnodeT* alptr;
+ char olddf[51], newdf[51];
char type = config->realmtable[realm].type | TYPE_SSL | TYPE_ZLIB;
clifd master = config->realmtable[realm].raclitable[client].cliconn;
+ olddf[50] = newdf[50] = 0;
length = buff[3];
length = length << 8;
- length += buff[4]; /* this is length of message */
+ length += buff[4]; /* this is the length of a message */
time(&now);
@@ -147,19 +197,26 @@ serve_admin(ConfigurationT* config, int realm, int client, unsigned char* buff)
case AF_RA_CMD: {
n = get_message(type, master, buff, length);
buff[n] = 0;
- aflog(2, " realm[%s]: admin: message length = %d [%s]",
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "realm[%s]: admin: message length = %d [%s]",
get_realmname(config, realm), n, buff);
switch (parse_cmd(buff, &ret)) {
case 1: { /* help */
add_to_message(buff, AF_VER("AFSERVER"));
add_to_message(buff, "\nValid commands are:");
- add_to_message(buff, " help display help");
- add_to_message(buff, " lcmd lists available commands");
- add_to_message(buff, " info prints info about server");
- add_to_message(buff, " rshow display realms");
- add_to_message(buff, " cshow X display clients in X realm");
- add_to_message(buff, " ushow X display users in X realm");
- add_to_message(buff, " quit quit connection");
+ add_to_message(buff, " help display help");
+ add_to_message(buff, " lcmd lists available commands");
+ add_to_message(buff, " info prints info about server");
+ add_to_message(buff, " rshow display realms");
+ add_to_message(buff, " cshow X display clients in X realm");
+ add_to_message(buff, " ushow X display users in X realm");
+ add_to_message(buff, " quit quit connection");
+ add_to_message(buff, " timeout N X set timeout value in X realm");
+ add_to_message(buff, " audit {0|1} X set audit mode in X realm");
+ add_to_message(buff, " dnslookups {0|1} X set dnslookups mode in X realm");
+ add_to_message(buff, " dateformat S set dateformat");
+ add_to_message(buff, " kuser S kick user named S");
+ add_to_message(buff, " kclient N kick client with number N");
send_adm_message(type, master, buff, AF_RA_STATUS_OK);
break;
}
@@ -171,6 +228,12 @@ serve_admin(ConfigurationT* config, int realm, int client, unsigned char* buff)
add_to_message(buff, "cshow");
add_to_message(buff, "ushow");
add_to_message(buff, "quit");
+ add_to_message(buff, "timeout");
+ add_to_message(buff, "audit");
+ add_to_message(buff, "dnslookups");
+ add_to_message(buff, "dateformat");
+ add_to_message(buff, "kuser");
+ add_to_message(buff, "kclient");
send_adm_message(type, master, buff, AF_RA_STATUS_OK);
break;
}
@@ -179,23 +242,17 @@ serve_admin(ConfigurationT* config, int realm, int client, unsigned char* buff)
add_to_message(buff, "Realms: %d", config->size);
add_to_message(buff, "Certificate: %s", config->certif);
add_to_message(buff, "Key: %s", config->keys);
- if (config->logging) {
- add_to_message(buff, "logfile: %s (verbosity:%d)",
- config->logfnam, config->logging);
- }
- else {
- add_to_message(buff, "no logfile");
- }
- if (config->socklogging) {
- add_to_message(buff, "logsocket: %s (verbosity:%d)",
- config->logsport, config->socklogging);
- }
- else {
- add_to_message(buff, "no logsocket");
+ llptr = getloglisthead();
+ i = 0;
+ while (llptr) {
+ add_to_message(buff, "log[%d]: %s", i, llptr->cmdline);
+ llptr = llptr->next;
+ ++i;
}
tmp = now - config->starttime;
add_uptime_to_message(buff, "Uptime", tmp);
add_to_message(buff, "Cg: %ld B", getcg());
+ add_to_message(buff, "Dateformat: %s", getdateformat());
send_adm_message(type, master, buff, AF_RA_STATUS_OK);
break;
}
@@ -219,13 +276,30 @@ serve_admin(ConfigurationT* config, int realm, int client, unsigned char* buff)
config->realmtable[i].usrclitable[j].manportnum);
}
add_to_message(buff, "climode: %s", config->realmtable[i].clim);
- add_to_message(buff, "timeout: %s", config->realmtable[i].timeout);
+ add_to_message(buff, "timeout: %d", config->realmtable[i].tmout);
add_to_message(buff, "baseport: %s", config->realmtable[i].baseport ?
"yes" : "no");
+ add_to_message(buff, "audit: %s", config->realmtable[i].audit ?
+ "yes" : "no");
+ add_to_message(buff, "dnslookups: %s", config->realmtable[i].dnslookups ?
+ "yes" : "no");
add_to_message(buff, "ssl: %s, zlib: %s, mode: %s",
(TYPE_IS_SSL(config->realmtable[i].type))?"yes":"no",
(TYPE_IS_ZLIB(config->realmtable[i].type))?"yes":"no",
(TYPE_IS_TCP(config->realmtable[i].type))?"tcp":"udp");
+ switch (config->realmtable[i].tunneltype) {
+ case 0: {
+ add_to_message(buff, "tunneltype: direct");
+ break;
+ }
+ case 1: {
+ add_to_message(buff, "tunneltype: http proxy");
+ break;
+ }
+ default: {
+ add_to_message(buff, "tunneltype: UNKNOWN");
+ }
+ }
}
send_adm_message(type, master, buff, AF_RA_STATUS_OK);
break;
@@ -264,15 +338,45 @@ serve_admin(ConfigurationT* config, int realm, int client, unsigned char* buff)
add_to_message(buff, "Id: %s",
(config->realmtable[n].clitable[i].clientid == NULL)?"":
config->realmtable[n].clitable[i].clientid);
+ add_to_message(buff, "Number: %d",
+ config->realmtable[n].clitable[i].clientnum);
add_to_message(buff, "IP: %s, port: %s",
config->realmtable[n].clitable[i].namebuf,
config->realmtable[n].clitable[i].portbuf);
+ switch (config->realmtable[n].clitable[i].tunneltype) {
+ case 0: {
+ add_to_message(buff, "tunneltype: direct");
+ break;
+ }
+ case 1: {
+ add_to_message(buff, "tunneltype: http proxy");
+ break;
+ }
+ default: {
+ add_to_message(buff, "tunneltype: UNKNOWN");
+ }
+ }
+ if (config->realmtable[n].audit) {
+ add_to_message(buff, "auditlog:");
+ alptr = config->realmtable[n].clitable[i].head;
+ while (alptr) {
+ add_to_message(buff,
+ "userid: %d ip: %s port: %s connected: %s duration: %s",
+ alptr->userid,
+ alptr->namebuf,
+ alptr->portbuf,
+ localdate(&(alptr->connecttime)),
+ timeperiod(alptr->duration));
+ alptr = alptr->next;
+ }
+ }
}
}
send_adm_message(type, master, buff, AF_RA_STATUS_OK);
break;
}
add_to_message(buff, "Wrong realm name");
+ add_to_message(buff, "Usage: cshow X , X - realm name");
send_adm_message(type, master, buff, AF_RA_FAILED);
break;
}
@@ -318,18 +422,179 @@ serve_admin(ConfigurationT* config, int realm, int client, unsigned char* buff)
break;
}
add_to_message(buff, "Wrong realm name");
+ add_to_message(buff, "Usage: ushow X , X - realm name");
send_adm_message(type, master, buff, AF_RA_FAILED);
break;
}
case 7: { /* quit */
- aflog(1, " realm[%s]: Client[%s] (ra): commfd: CLOSED",
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "realm[%s]: Client[%s] (ra): commfd: CLOSED",
get_realmname(config, realm),
get_raclientname(&(config->realmtable[realm]), client));
send_adm_message(type, master, buff, AF_RA_KICKED);
return 1;
}
+ case 8: { /* timeout */
+ i = parse_int(buff, &ret);
+ if (i <= 0) {
+ add_to_message(buff, "Invalid timeout value");
+ add_to_message(buff,
+ "Usage: timeout N X , N - new timeout value, X - realm name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ break;
+ }
+ n = get_realmnumber(config, (char*) &buff[ret]);
+ if ((n >= 0) && (n < config->size)) {
+ add_to_message(buff, "changed timeout: %d --> %d",
+ config->realmtable[n].tmout, i);
+ config->realmtable[n].tmout = i;
+ send_adm_message(type, master, buff, AF_RA_STATUS_OK);
+ break;
+ }
+ add_to_message(buff, "Wrong realm name");
+ add_to_message(buff,
+ "Usage: timeout N X , N - new timeout value, X - realm name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ break;
+ }
+ case 9: { /* audit */
+ i = parse_int(buff, &ret);
+ if ((i != 0) && (i != 1)) {
+ add_to_message(buff, "Invalid audit value");
+ add_to_message(buff,
+ "Usage: audit {0|1} X , N=0 off, N=1 on, X - realm name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ break;
+ }
+ n = get_realmnumber(config, (char*) &buff[ret]);
+ if ((n >= 0) && (n < config->size)) {
+ add_to_message(buff, "changed audit: %s --> %s",
+ config->realmtable[n].audit ? "yes" : "no", i ? "yes" : "no");
+ config->realmtable[n].audit = i;
+ if (i == 0) {
+ for (i = 0; i < config->realmtable[n].clinum; ++i) {
+ freeauditlist(&(config->realmtable[n].clitable[i].head));
+ }
+ }
+ send_adm_message(type, master, buff, AF_RA_STATUS_OK);
+ break;
+ }
+ add_to_message(buff, "Wrong realm name");
+ add_to_message(buff,
+ "Usage: audit {0|1} X , N=0 off, N=1 on, X - realm name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ break;
+ }
+ case 10: { /* dnslookups */
+ i = parse_int(buff, &ret);
+ if ((i != 0) && (i != 1)) {
+ add_to_message(buff, "Invalid dnslookups value");
+ add_to_message(buff,
+ "Usage: dnslookups {0|1} X , N=0 off, N=1 on, X - realm name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ break;
+ }
+ n = get_realmnumber(config, (char*) &buff[ret]);
+ if ((n >= 0) && (n < config->size)) {
+ add_to_message(buff, "changed dnslookups: %s --> %s",
+ config->realmtable[n].dnslookups ? "yes" : "no", i ? "yes" : "no");
+ config->realmtable[n].dnslookups = i;
+ send_adm_message(type, master, buff, AF_RA_STATUS_OK);
+ break;
+ }
+ add_to_message(buff, "Wrong realm name");
+ add_to_message(buff,
+ "Usage: dnslookups {0|1} X , N=0 off, N=1 on, X - realm name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ break;
+ }
+ case 11: { /* dateformat */
+ strncpy(olddf, getdateformat(), 50);
+ strncpy(newdf, (char*) &buff[ret], 50);
+ add_to_message(buff, "changed dateformat: %s --> %s",
+ olddf, newdf);
+ setdateformat(newdf);
+ send_adm_message(type, master, buff, AF_RA_STATUS_OK);
+ break;
+ }
+ case 12: { /* kuser */
+ i = parse_int(buff, &ret);
+ if (buff[ret] != 0) {
+ add_to_message(buff, "Invalid user name");
+ add_to_message(buff,
+ "Usage: kuser S , S - user name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ break;
+ }
+ j = -1;
+ for (n = 0; n < config->size; ++n) {
+ j = get_usernumber(&(config->realmtable[n]), i);
+ if (j != (-1)) {
+ if ((config->realmtable[n].contable[j].state == S_STATE_OPEN) ||
+ (config->realmtable[n].contable[j].state == S_STATE_STOPPED)) {
+ add_to_message(buff, "kicked: realm[%s] user[%d]",
+ get_realmname(config, n), get_username(&(config->realmtable[n]), i));
+ close(config->realmtable[n].contable[j].connfd);
+ send_adm_message(type, master, buff, AF_RA_STATUS_OK);
+ }
+ else {
+ add_to_message(buff, "Invalid user");
+ add_to_message(buff,
+ "Usage: kuser S , S - user name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ }
+ break;
+ }
+ }
+ if (j == (-1)) {
+ add_to_message(buff, "Invalid user name");
+ add_to_message(buff,
+ "Usage: kuser S , S - user name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ }
+ break;
+ }
+ case 13: { /* kclient */
+ i = parse_int(buff, &ret);
+ if (buff[ret] != 0) {
+ add_to_message(buff, "Invalid client number");
+ add_to_message(buff,
+ "Usage: kclient N , N - client number");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ break;
+ }
+ j = -1;
+ for (n = 0; n < config->size; ++n) {
+ j = get_clientnumber(&(config->realmtable[n]), i);
+ if (j != (-1)) {
+ if (config->realmtable[n].clitable[j].ready) {
+ add_to_message(buff, "kicked: realm[%s] client[%s]",
+ get_realmname(config, n),
+ get_clientname(&(config->realmtable[n]), j));
+ send_adm_message(type, master, buff, AF_RA_STATUS_OK);
+ return (i+2);
+ }
+ else {
+ add_to_message(buff, "Invalid client");
+ add_to_message(buff,
+ "Usage: kclient N , N - client number");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ }
+ break;
+ }
+ }
+ if (j == (-1)) {
+ add_to_message(buff, "Invalid client number");
+ add_to_message(buff,
+ "Usage: kclient N , N - client number");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ }
+ break;
+
+ }
default: {
- aflog(2, " realm[%s]: admin: cmd ignored", get_realmname(config, realm));
+ aflog(LOG_T_MANAGE, LOG_I_WARNING,
+ "realm[%s]: admin: cmd ignored", get_realmname(config, realm));
send_adm_message(type, master, buff, AF_RA_UNDEFINED);
}
}
@@ -339,7 +604,8 @@ serve_admin(ConfigurationT* config, int realm, int client, unsigned char* buff)
break;
}
default: {
- aflog(1, "Unrecognized message from remote admin --> closing");
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "Unrecognized message from remote admin --> closing");
return 1;
}
}
@@ -359,24 +625,29 @@ client_admin(char type, clifd master, unsigned char* buff, int connectfd, char*
get_message(type, master, buff, -5);
if ( buff[0] == 0 ) {
- aflog(0, "Wrong password");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Wrong password");
return 1;
}
if ( buff[0] == AF_S_CANT_OPEN ) {
- aflog(0, "Server is full");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Server is full");
return 1;
}
if ( buff[0] != AF_S_ADMIN_LOGIN ) {
- aflog(0, "Incompatible server type or server full");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Incompatible server type or server full");
return 1;
}
- aflog(1, "CLIENT STARTED mode: remote administration");
+ aflog(LOG_T_MAIN, LOG_I_INFO,
+ "CLIENT STARTED mode: remote administration");
if (connectfd > 0) {
outfp = fdopen(connectfd, "w");
if (outfp == NULL) {
- aflog(0, "Error in opening file descriptor for writing");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Error in opening file descriptor for writing");
return 1;
}
infd = connectfd;
@@ -387,7 +658,8 @@ client_admin(char type, clifd master, unsigned char* buff, int connectfd, char*
}
infp = fdopen(infd, "r");
if (infp == NULL) {
- aflog(0, "Error in opening file descriptor for reading");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Error in opening file descriptor for reading");
return 1;
}
@@ -414,7 +686,8 @@ client_admin(char type, clifd master, unsigned char* buff, int connectfd, char*
buff[3] = n >> 8; /* high bits of message length */
buff[4] = n; /* low bits of message length */
send_message(type, master, buff, n+5);
- aflog(1, "ID SENT: %s", id);
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "ID SENT: %s", id);
}
while (1) {
@@ -422,10 +695,12 @@ client_admin(char type, clifd master, unsigned char* buff, int connectfd, char*
select(maxfdp1, &rset, NULL, NULL, NULL);
if (FD_ISSET(master.commfd, &rset)) {
- aflog(3, " masterfd: FD_ISSET");
+ aflog(LOG_T_MANAGE, LOG_I_DEBUG,
+ "masterfd: FD_ISSET");
n = get_message(type, master, buff, 5);
if (n != 5) {
- aflog(2, " FATAL ERROR! (%d)", n);
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "FATAL ERROR! (%d)", n);
if (n == -1) {
if (TYPE_IS_SSL(type)) {
get_ssl_error(&master, "FE", n);
@@ -436,15 +711,18 @@ client_admin(char type, clifd master, unsigned char* buff, int connectfd, char*
return 1;
}
if (n == 0) { /* server quits -> we do the same... */
- aflog(0, " SERVER: premature quit --> exiting...");
+ aflog(LOG_T_MANAGE, LOG_I_CRIT,
+ "SERVER: premature quit --> exiting...");
return 1;
}
if (buff[0] == AF_S_CLOSING) {
- aflog(0, " SERVER: CLOSED -> exiting... cg: %ld bytes", getcg());
+ aflog(LOG_T_MANAGE, LOG_I_CRIT,
+ "SERVER: CLOSED -> exiting... cg: %ld bytes", getcg());
return 0;
}
if (buff[0] != AF_S_ADMIN_CMD) {
- aflog(0, " SERVER: wrong message --> exiting");
+ aflog(LOG_T_MANAGE, LOG_I_CRIT,
+ "SERVER: wrong message --> exiting");
return 1;
}
length = buff[3];
@@ -453,16 +731,19 @@ client_admin(char type, clifd master, unsigned char* buff, int connectfd, char*
switch (buff[1]) {
case AF_RA_STATUS_OK: {
- aflog(1, " SERVER: cmd successful");
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "SERVER: cmd successful");
}
case AF_RA_FAILED: {
if (buff[1] == AF_RA_FAILED) {
- aflog(1, " SERVER: cmd failed");
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "SERVER: cmd failed");
}
}
case AF_RA_UNDEFINED: {
if (buff[1] == AF_RA_UNDEFINED) {
- aflog(1, " SERVER: unknown cmd");
+ aflog(LOG_T_MANAGE, LOG_I_WARNING,
+ "SERVER: unknown cmd");
}
n = get_message(type, master, buff, length);
buff[n] = 0;
@@ -471,21 +752,25 @@ client_admin(char type, clifd master, unsigned char* buff, int connectfd, char*
break;
}
case AF_RA_KICKED: {
- aflog(0, " SERVER: kicked us -> exiting... cg: %ld bytes", getcg());
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "SERVER: kicked us -> exiting... cg: %ld bytes", getcg());
return 1;
break;
}
default: {
- aflog(0, " SERVER: unrecognized message -> exiting... cg: %ld bytes", getcg());
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "SERVER: unrecognized message -> exiting... cg: %ld bytes", getcg());
return 1;
}
}
}
if (FD_ISSET(infd, &rset)) {
- aflog(3, " infd: FD_ISSET");
+ aflog(LOG_T_MANAGE, LOG_I_DEBUG,
+ "infd: FD_ISSET");
if (fgets((char*) &buff[5], 8091, infp) == NULL) { /* client quits --> exiting */
- aflog(0, " CLIENT CLOSED cg: %ld bytes", getcg());
+ aflog(LOG_T_MANAGE, LOG_I_NOTICE,
+ "CLIENT CLOSED cg: %ld bytes", getcg());
return 0;
}
n = strlen((char*) &buff[5]);
diff --git a/src/remoteadmin.h b/src/remoteadmin.h
index cad9c76..5b176df 100644
--- a/src/remoteadmin.h
+++ b/src/remoteadmin.h
@@ -20,6 +20,7 @@
#include "file.h"
#include "stats.h"
+#include "logging.h"
#include "activefor.h"
#include "realmnames.h"
#include "clientnames.h"
diff --git a/src/server_check.c b/src/server_check.c
index 94069cc..3fd1091 100644
--- a/src/server_check.c
+++ b/src/server_check.c
@@ -18,30 +18,45 @@
*
*/
+#include <config.h>
+
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
+#include "server_check.h"
#include "stats.h"
+#include "logging.h"
void
check_value(int* where, char* what, char* info)
{
+ long tmp = check_value_liberal(what, info);
+
+ if (tmp <= 0) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "%s: %d\n", info, tmp);
+ exit(1);
+ }
+ (*where) = tmp;
+}
+
+int
+check_value_liberal(char* what, char* info)
+{
char* znak;
long tmp;
if ((tmp = strtol(what, &znak, 10)) >= INT_MAX) {
- aflog(0, "%s: %s\n", info, what);
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "%s: %s\n", info, what);
exit(1);
}
if (((*what) == '\0') || (*znak != '\0')) {
- aflog(0, "%s: %s\n", info, what);
- exit(1);
- }
- if (tmp <= 0) {
- aflog(0, "%s: %d\n", info, *where);
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "%s: %s\n", info, what);
exit(1);
}
- (*where) = tmp;
+ return tmp;
}
int
diff --git a/src/server_check.h b/src/server_check.h
index 3877426..0b4ddbf 100644
--- a/src/server_check.h
+++ b/src/server_check.h
@@ -22,6 +22,7 @@
#define _JS_SERVER_CHECK_H
void check_value(int* where, char* what, char* info);
+int check_value_liberal(char* what, char* info);
int check_long(char* text, long* number);
#endif
diff --git a/src/server_eval.c b/src/server_eval.c
index d487b01..373a310 100644
--- a/src/server_eval.c
+++ b/src/server_eval.c
@@ -18,6 +18,8 @@
*
*/
+#include <config.h>
+
#include "server_eval.h"
int
diff --git a/src/server_find.c b/src/server_find.c
index 1d67640..80148e4 100644
--- a/src/server_find.c
+++ b/src/server_find.c
@@ -18,6 +18,8 @@
*
*/
+#include <config.h>
+
#include "server_find.h"
int
diff --git a/src/server_get.c b/src/server_get.c
new file mode 100644
index 0000000..7ada39c
--- /dev/null
+++ b/src/server_get.c
@@ -0,0 +1,55 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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 "server_get.h"
+#include <stdlib.h>
+
+int
+get_new_socket(int sockfd, char type, struct sockaddr *addr, socklen_t *addrlen, char* tunneltype)
+{
+ int tmp;
+ switch (type) {
+ case 0: {
+ return accept(sockfd, addr, addrlen);
+ break;
+ }
+ case 1: {
+ if (read(sockfd, &tmp, 4) != 4) {
+ return -1;
+ }
+ if (read(sockfd, tunneltype, 1) != 1) {
+ return -1;
+ }
+ if (read(sockfd, addrlen, 4) != 4) {
+ return -1;
+ }
+ if (read(sockfd, addr, *addrlen) != *addrlen) {
+ return -1;
+ }
+ return tmp;
+ break;
+ }
+ default: {
+ return -1;
+ }
+ }
+}
diff --git a/src/server_get.h b/src/server_get.h
new file mode 100644
index 0000000..099e124
--- /dev/null
+++ b/src/server_get.h
@@ -0,0 +1,31 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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.
+ *
+ */
+
+#ifndef _JS_SERVER_GET_H
+#define _JS_SERVER_GET_H
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int get_new_socket(int sockfd, char type, struct sockaddr *addr, socklen_t *addrlen, char* tunneltype);
+
+#endif
+
diff --git a/src/server_signals.c b/src/server_signals.c
new file mode 100644
index 0000000..41cd31c
--- /dev/null
+++ b/src/server_signals.c
@@ -0,0 +1,66 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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 "server_signals.h"
+#include "activefor.h"
+#include "thread_management.h"
+#include "http_proxy_functions.h"
+#include "stats.h"
+#include "logging.h"
+
+extern ConfigurationT config;
+
+ void
+server_sig_int(int signo)
+{
+ int i, j;
+ unsigned char buff[5];
+
+#ifdef HAVE_LIBPTHREAD
+ if (!is_this_a_mainthread()) {
+ return;
+ }
+#endif
+
+ for (j = 0; j < config.size; ++j) {
+ buff[0] = AF_S_CLOSING; /* closing */
+ for (i = 0; i < config.realmtable[j].clinum; ++i) {
+ if (config.realmtable[j].clitable[i].ready == 3) {
+ send_message(config.realmtable[j].type,config.realmtable[j].clitable[i].cliconn,buff,5);
+ }
+ }
+ for (i = 0; i < config.realmtable[j].raclinum; ++i) {
+ if (config.realmtable[j].raclitable[i].ready == 3) {
+ send_message(config.realmtable[j].type | TYPE_SSL, config.realmtable[j].raclitable[i].cliconn, buff, 5);
+ }
+ }
+
+ }
+
+ /* FIXME: give a time to close all connections */
+ mysleep(0.1);
+
+ aflog(LOG_T_MAIN, LOG_I_NOTICE,
+ "SERVER CLOSED cg: %ld bytes", getcg());
+ exit(0);
+}
+
diff --git a/src/server_signals.h b/src/server_signals.h
new file mode 100644
index 0000000..babb131
--- /dev/null
+++ b/src/server_signals.h
@@ -0,0 +1,27 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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.
+ *
+ */
+
+#ifndef _JS_SERVER_SIGNALS_H
+#define _JS_SERVER_SIGNALS_H
+
+void server_sig_int(int); /* INT signal handler for the afserver */
+
+#endif
+
diff --git a/src/stats.c b/src/stats.c
index 82e90aa..4303a7e 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -18,94 +18,30 @@
*
*/
+#include <config.h>
+
#include "stats.h"
-#include "network.h"
-#include <stdio.h>
-#include <time.h>
-#include <string.h>
-#include <stdarg.h>
-static char verlev;
-static char loglev;
-static char logsocklev;
-static FILE* logfd;
-static FILE* logsockfd;
static signed long compressgained;
-static char* format = "%d.%m.%Y %H:%M:%S";
char*
-datum(void)
+timeperiod(time_t period)
{
- time_t sec;
- struct tm* tm;
- static char timedat[31];
- time(&sec);
- tm = localtime(&sec);
- memset(timedat, 0, 31);
- strftime(timedat, 30, format, tm);
- return timedat;
-}
+ int hours, minutes, seconds;
+ static char timeper[41];
+ memset(timeper, 0, 41);
-int
-loginit(char verl, char logl, char logsl, const char* logfname, const char* port, char* dateformat) {
- int tmpfd;
- verlev = loglev = 0;
- if (logfd)
- fclose(logfd);
- logfd = NULL;
- logsockfd = NULL;
- verlev = verl;
- loglev = logl;
- logsocklev = logsl;
- if (dateformat)
- format = dateformat;
- if (loglev) {
- logfd = fopen(logfname, "a");
- if (logfd == NULL)
- return 1; /* logging to a non-opened file? */
- }
- if (logsocklev) {
- if (ip_connect(&tmpfd, "localhost", port, 1))
- return 2; /* can't connect to localhost:port */
- logsockfd = fdopen(tmpfd, "a");
- if (logsockfd == NULL)
- return 3; /* can't create FILE* to log to */
- }
- return 0;
-}
-
-void
-aflog(char type, const char* format, ...)
-{
- va_list ap;
-
- if ((verlev) || (!type))
- if (type <= verlev) {
- printf("[%s] ", datum());
- va_start(ap, format);
- vfprintf(stdout, format, ap);
- va_end(ap);
- printf("\n");
- }
- if (loglev)
- if (type <= loglev) {
- fprintf(logfd, "[%s] ", datum());
- va_start(ap, format);
- vfprintf(logfd, format, ap);
- va_end(ap);
- fprintf(logfd, "\n");
- fflush(logfd);
- }
- if (logsocklev)
- if (type <= logsocklev) {
- fprintf(logsockfd, "[%s] ", datum());
- va_start(ap, format);
- vfprintf(logsockfd, format, ap);
- va_end(ap);
- fprintf(logsockfd, "\n");
- fflush(logsockfd);
- }
+ hours = period/3600;
+ minutes = (period/60)%60;
+ seconds = period%60;
+ if (hours) {
+ sprintf(timeper, "%d:%02d:%02d", hours, minutes, seconds);
+ }
+ else {
+ sprintf(timeper, "%d:%02d", minutes, seconds);
+ }
+ return timeper;
}
void
diff --git a/src/stats.h b/src/stats.h
index 08838ad..a774ae1 100644
--- a/src/stats.h
+++ b/src/stats.h
@@ -18,13 +18,15 @@
*
*/
+#include <time.h>
+#include <string.h>
+#include <stdio.h>
+
#ifndef _JS_STATS_H
#define _JS_STATS_H
- /* initializing logging routine */
-int loginit(char verlev, char loglev, char logsocklev, const char* logfname, const char* port, char* dateformat);
- /* log to a file or|and screen */
-void aflog(char type, const char* format, ...);
+ /* return time period description */
+char* timeperiod(time_t period);
/* add amount to compressgained value */
void addtocg(int amount);
/* reset the compressgained value */
diff --git a/src/thread_management.c b/src/thread_management.c
new file mode 100644
index 0000000..fcd53ab
--- /dev/null
+++ b/src/thread_management.c
@@ -0,0 +1,70 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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 "thread_management.h"
+
+#ifdef HAVE_LIBPTHREAD
+
+static pthread_t mainthread;
+static pthread_mutex_t mainmutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t maincond = PTHREAD_COND_INITIALIZER;
+
+void
+remember_mainthread(void)
+{
+ mainthread = pthread_self();
+}
+
+int
+is_this_a_mainthread(void)
+{
+ if (pthread_self() == mainthread) {
+ return 1;
+ }
+ return 0;
+}
+
+void
+start_critical_section(void)
+{
+ pthread_mutex_lock( &mainmutex);
+}
+
+void
+end_critical_section(void)
+{
+ pthread_mutex_unlock( &mainmutex);
+}
+
+void
+wait_for_condition(void)
+{
+ pthread_cond_wait(&maincond, &mainmutex);
+}
+
+void
+broadcast_condition(void)
+{
+ pthread_cond_broadcast(&maincond);
+}
+
+#endif
diff --git a/src/thread_management.h b/src/thread_management.h
new file mode 100644
index 0000000..f502d1e
--- /dev/null
+++ b/src/thread_management.h
@@ -0,0 +1,34 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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.
+ *
+ */
+
+#ifndef _JS_THREAD_MANAGEMENT_H
+#define _JS_THREAD_MANAGEMENT_H
+
+#include <pthread.h>
+
+void remember_mainthread(void);
+int is_this_a_mainthread(void);
+void start_critical_section(void);
+void end_critical_section(void);
+void wait_for_condition(void);
+void broadcast_condition(void);
+
+#endif
+
diff --git a/src/usage.c b/src/usage.c
new file mode 100644
index 0000000..4510781
--- /dev/null
+++ b/src/usage.c
@@ -0,0 +1,168 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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 "usage.h"
+#include "network.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+ void
+server_short_usage(char* info)
+{
+ printf("\n%s\n\n\n", info);
+ printf("Try `afserver --help' for more information.\n");
+
+ exit(1);
+}
+
+ void
+server_long_usage(char* info)
+{
+ printf("\n%s\n\n\n", info);
+ printf(" Basic options:\n\n");
+ printf(" -n, --hostname - it's used when creating listening sockets\n");
+ printf(" (default: '')\n");
+ printf(" -l, --listenport - listening port number - users connect\n");
+ printf(" to it (default: 50127)\n");
+ printf(" -m, --manageport - manage port number - second part of the active\n");
+ printf(" port forwarder connects to it (default: 50126)\n");
+ printf(" -V, --version - display version number\n");
+ printf(" -h, --help - prints this help\n\n");
+ printf(" Authorization:\n\n");
+ printf(" --pass - set the password used for client identification\n");
+ printf(" (default: no password)\n\n");
+ printf(" Configuration:\n\n");
+ printf(" -c, --cerfile - the name of the file with certificate\n");
+ printf(" (default: cacert.pem)\n");
+ printf(" -k, --keyfile - the name of the file with RSA key (default: server.rsa)\n");
+ printf(" -f, --cfgfile - the name of the file with the configuration for the\n");
+ printf(" active forwarder (server)\n");
+ printf(" -D, --dateformat - format of the date printed in logs (see 'man strftime'\n");
+ printf(" for details) (default: %%d.%%m.%%Y %%H:%%M:%%S)\n\n");
+ printf(" -t, --timeout - the timeout value for the client's connection\n");
+ printf(" (default: 5)\n");
+ printf(" -u, --users - the amount of users allowed to use this server\n");
+ printf(" (default: 5)\n");
+ printf(" -C, --clients - the number of allowed clients to use this server\n");
+ printf(" (default: 1)\n");
+ printf(" -r, --realm - set the realm name (default: none)\n");
+ printf(" -R, --raclients - the number of allowed clients in remote administration\n");
+ printf(" mode to use this server (default: 1)\n");
+ printf(" -U, --usrpcli - the number of allowed users per client (default: $users)\n");
+ printf(" -M, --climode - strategy used to connect users with clients (default: 1)\n");
+ printf(" Available strategies:\n");
+ printf(" 1. fill first client before go to next\n\n");
+ printf(" -p, --proto - type of server (tcp|udp) - what protocol it will be\n");
+ printf(" operating for (default: tcp)\n");
+ printf(" -b, --baseport - listenports are temporary and differ for each client\n");
+ printf(" -a, --audit - additional information about connections are logged\n");
+ printf(" --nossl - ssl is not used to transfer data (but it's still used\n");
+ printf(" to establish a connection) (default: ssl is used)\n");
+ printf(" --nozlib - zlib is not used to compress data (default: zlib is\n");
+ printf(" used)\n");
+ printf(" --dnslookups - try to obtain dns names of the computers rather than\n");
+ printf(" their numeric IP\n\n");
+ printf(" Logging:\n\n");
+ printf(" -o, --log - log choosen information to file/socket\n");
+ printf(" -v, --verbose - to be verbose - program won't enter the daemon mode\n");
+ printf(" (use several times for greater effect)\n\n");
+#ifdef AF_INET6
+ printf(" IP family:\n\n");
+ printf(" -4, --ipv4 - use ipv4 only\n");
+ printf(" -6, --ipv6 - use ipv6 only\n\n");
+#endif
+#ifdef HAVE_LIBPTHREAD
+ printf(" HTTP PROXY:\n\n");
+ printf(" -P, --enableproxy - enable http proxy mode\n\n");
+#endif
+
+ exit(0);
+}
+
+ void
+client_short_usage(char* info)
+{
+ printf("\n%s\n\n\n", info);
+ printf("Try `afclient --help' for more information.\n");
+
+ exit(1);
+}
+
+void
+client_long_usage(char* info)
+{
+ printf("\n%s\n\n\n", info);
+ printf(" Basic options:\n\n");
+ printf(" -n, --servername - where the second part of the active\n");
+ printf(" port forwarder is running (required)\n");
+ printf(" -m, --manageport - manage port number - server must be\n");
+ printf(" listening on it (default: 50126)\n");
+ printf(" -d, --hostname - the name of this host/remote host - the final\n");
+ printf(" destination of the packets (default: the name\n");
+ printf(" returned by hostname function)\n");
+ printf(" -p, --portnum - the port we are forwarding connection to (required)\n");
+ printf(" -V, --version - display version number\n");
+ printf(" -h, --help - prints this help\n\n");
+ printf(" Authorization:\n\n");
+ printf(" -i, --id - sends the id string to afserver\n");
+ printf(" --pass - set the password used for client identification\n");
+ printf(" (default: no password)\n\n");
+ printf(" Configuration:\n\n");
+ printf(" -k, --keyfile - the name of the file with RSA key (default: client.rsa)\n");
+ printf(" -D, --dateformat - format of the date printed in logs (see 'man strftime'\n");
+ printf(" for details) (default: %%d.%%m.%%Y %%H:%%M:%%S)\n");
+ printf(" -K, --keep-alive N - send keepalive packets every N seconds\n");
+ printf(" (default: not send keepalive packets)\n");
+ printf(" -A, --ar-tries N - try N times to reconnect to afserver after\n");
+ printf(" its premature quit (default: unlimited)\n");
+ printf(" -T, --ar-delay N - wait N seconds between reconnect tries (default: 5)\n\n");
+ printf(" Modes:\n\n");
+ printf(" -u, --udpmode - udp mode - client will use udp protocol to\n");
+ printf(" communicate with the hostname:portnum (-p)\n");
+ printf(" -U, --reverseudp - reverse udp forwarding. Udp packets will be forwarded\n");
+ printf(" from hostname:portnum (-p) to the server name:portnum\n");
+ printf(" (-m)\n");
+ printf(" -r, --remoteadmin - remote administration mode. (using '-p #port' will\n");
+ printf(" force afclient to use port rather than stdin-stdout)\n\n");
+ printf(" Logging:\n\n");
+ printf(" -o, --log - log choosen information to file/socket\n");
+ printf(" -v, --verbose - to be verbose - program won't enter the daemon mode\n");
+ printf(" (use several times for greater effect)\n\n");
+#ifdef AF_INET6
+ printf(" IP family:\n\n");
+ printf(" -4, --ipv4 - use ipv4 only\n");
+ printf(" -6, --ipv6 - use ipv6 only\n\n");
+#endif
+#ifdef HAVE_LIBDL
+ printf(" Modules:\n\n");
+ printf(" -l, --load - load a module for user's packets filtering\n");
+ printf(" -L, --Load - load a module for service's packets filtering\n\n");
+#endif
+#ifdef HAVE_LIBPTHREAD
+ printf(" HTTP PROXY:\n\n");
+ printf(" -P, --proxyname - the name of the machine with proxy server\n");
+ printf(" -X, --proxyport - the port used by proxy server (default: 8080)\n\n");
+#endif
+
+ exit(0);
+}
diff --git a/src/usage.h b/src/usage.h
new file mode 100644
index 0000000..6436020
--- /dev/null
+++ b/src/usage.h
@@ -0,0 +1,30 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003,2004,2005 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.
+ *
+ */
+
+#ifndef _JS_USAGE_H
+#define _JS_USAGE_H
+
+void server_short_usage(char* info); /* short usage info printed by afserver */
+void server_long_usage(char* info); /* long usage info printed by afserver */
+void client_short_usage(char* info); /* short usage info printed by afclient */
+void client_long_usage(char* info); /* long usage info printed by afclient */
+
+#endif
+
diff --git a/src/usernames.c b/src/usernames.c
index 3e4b24c..194bfa0 100644
--- a/src/usernames.c
+++ b/src/usernames.c
@@ -18,6 +18,8 @@
*
*/
+#include <config.h>
+
#include "usernames.h"
int