From 32aff2b27ccc3b3e51fb6f0bd77fe0073827c527 Mon Sep 17 00:00:00 2001 From: Jakub Sławiński Date: Tue, 7 Jun 2005 12:06:18 +0200 Subject: 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 --- src/afclient.c | 672 ++++++++++++++++++++++++++------------------------------- 1 file changed, 305 insertions(+), 367 deletions(-) (limited to 'src/afclient.c') 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, ¬sent)) { - 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, ¬sent)) { - 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, ¬sent)) { - 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, ¬sent)) { - 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); -} - -- cgit v1.1