From 46f96ed5e3127394a0cd4dcb961404b792f743b4 Mon Sep 17 00:00:00 2001 From: Jakub Slawinski Date: Thu, 10 Jul 2014 10:24:59 +0200 Subject: Initial project structure based on Active Port Forwarder 0.8.4. --- src/afclient.c | 1500 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1500 insertions(+) create mode 100644 src/afclient.c (limited to 'src/afclient.c') diff --git a/src/afclient.c b/src/afclient.c new file mode 100644 index 0000000..fbafcc1 --- /dev/null +++ b/src/afclient.c @@ -0,0 +1,1500 @@ +/* + * active port forwarder - software for secure forwarding + * Copyright (C) 2003-2007 jeremian + * + * 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 + +#include "afclient.h" + +static struct option long_options[] = { + {"help", 0, 0, 'h'}, + {"udpmode", 0, 0, 'u'}, + {"reverseudp", 0, 0, 'U'}, + {"servername", 1, 0, 'n'}, + {"manageport", 1, 0, 'm'}, + {"hostname", 1, 0, 'd'}, + {"portnum", 1, 0, 'p'}, + {"verbose", 0, 0, 'v'}, + {"keyfile", 1, 0, 'k'}, + {"cerfile", 1, 0, 'c'}, + {"storefile", 1, 0, 's'}, + {"cfgfile", 1, 0, 'f'}, + {"log", 1, 0, 'o'}, + {"pass", 1, 0, 301}, + {"ignorepkeys", 0, 0, 302}, +#ifdef AF_INET6 + {"ipv4", 0, 0, '4'}, + {"ipv6", 0, 0, '6'}, +#endif +#ifdef HAVE_LIBDL + {"load", 1, 0, 'l'}, + {"Load", 1, 0, 'L'}, +#endif + {"id", 1, 0, 'i'}, + {"dateformat", 1, 0, 'D'}, + {"remoteadmin", 0, 0, 'r'}, +#ifdef HAVE_LIBPTHREAD + {"use-https", 0, 0, 'S'}, + {"proxyname", 1, 0, 'P'}, + {"proxyport", 1, 0, 'X'}, + {"pa-t-basic", 0, 0, 'B'}, + {"pa-cred", 1, 0, 'C'}, +#endif + {"version", 0, 0, 'V'}, + {"keep-alive", 1, 0, 'K'}, + {"ar-tries", 1, 0, 'A'}, + {"ar-delay", 1, 0, 'T'}, + {"ar-start", 0, 0, 305}, + {"ar-quit", 0, 0, 306}, + {"noar", 0, 0, 307}, + {"localname", 1, 0, 311}, + {"localport", 1, 0, 312}, + {"localdesname", 1, 0, 313}, + {0, 0, 0, 0} +}; + +ClientConfiguration* cconfig; + +int +main(int argc, char **argv) +{ + + /* + * variables + */ + + int i, n, numofcon, length, buflength, temp, temp2 = 0; +#ifdef HAVE_LINUX_SOCKIOS_H + int notsent; + socklen_t aLength; +#endif + ConnectUser** usersTable = NULL; + unsigned char buff[9000]; + char hostname[100]; + int maxfdp1; + socklen_t addressLength; + struct sockaddr* clientAddress; + fd_set rset, allset, wset, tmpset; + struct timeval keepAlive; + char verbose = 0; + HttpProxyOptions* hpo = HttpProxyOptions_new(); + char hpoUsed = 0; + ArOptions* ao = ArOptions_new(); + ClientRealm* pointer; + char aoUsed = 0; + char passwordWasSet = 0; + char* realmId = NULL; + char* serverName = NULL; + char* managePort = NULL; + char* hostName = NULL; + PortList* destinationPorts = PortList_new(); + char* localName = NULL; + char* localPort = NULL; + char* localDestinationName = NULL; + char* keys = NULL; + char* certif = NULL; + char* store = NULL; + char* dateformat = NULL; + char* kaTimeout = NULL; + char* filenam = NULL; + char ipFamily = 0; + unsigned char password[4] = {1, 2, 3, 4}; + char udpMode = 0; + char reverseMode = 0; + char remoteMode = 0; + char realmType = 0; + char ignorePublicKeys = 0; + struct sigaction act; +#ifdef HAVE_LIBDL + Module *moduleA = Module_new(), *moduleB = Module_new(); +#endif + SSL_METHOD* method; + SSL_CTX* ctx = NULL; + + /* + * initialization + */ + +#ifdef HAVE_LIBPTHREAD + if (hpo == NULL) { + printf("Problems with memory allocation... exiting\n"); + exit(1); + } +#endif + + if (ao == NULL) { + printf("Problems with memory allocation... exiting\n"); + exit(1); + } + +#ifdef HAVE_LIBDL + if ((moduleA == NULL) || (moduleB == NULL)) { + printf("Problems with memory allocation... exiting\n"); + exit(1); + } +#endif + sigfillset(&(act.sa_mask)); + act.sa_flags = 0; + + act.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &act, NULL); + act.sa_handler = client_sig_int; + sigaction(SIGINT, &act, NULL); + sigaction(SIGTERM, &act, NULL); + act.sa_handler = client_sig_alrm; + sigaction(SIGALRM, &act, NULL); + +#ifdef HAVE_LIBPTHREAD + remember_mainthread(); +#endif + +#ifdef AF_INET6 +#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) "SP:X:BC:"x +#else +#define GETOPT_LONG_LIBPTHREAD(x) x +#endif +#ifdef HAVE_LIBDL +#define GETOPT_LONG_LIBDL(x) "l:L:"x +#else +#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:c:s:o:i:D:rP:X:VK:A:T:f:"))) + , long_options, 0)) != -1) { + switch (n) { + case 'h': { + client_long_usage(AF_VER("Active port forwarder (client)")); + break; + } + case 'n': { + serverName = optarg; + break; + } +#ifdef HAVE_LIBPTHREAD + case 'S': { + HttpProxyOptions_use_https(hpo); + hpoUsed = 1; + break; + } + case 'P': { + HttpProxyOptions_set_proxyname(hpo, optarg); + hpoUsed = 1; + break; + } + case 'X': { + HttpProxyOptions_set_proxyport(hpo, optarg); + hpoUsed = 1; + break; + } + case 'B': { + HttpProxyOptions_set_proxyauth_type(hpo, PROXYAUTH_TYPE_BASIC); + hpoUsed = 1; + break; + } + case 'C': { + HttpProxyOptions_set_proxyauth_cred(hpo, optarg); + hpoUsed = 1; + break; + } +#endif + case 'i': { + realmId = optarg; + break; + } + case 'm': { + managePort = optarg; + break; + } + case 'd': { + hostName = optarg; + break; + } + case 'p': { + PortList_insert_back(destinationPorts, PortListNode_new(optarg)); + break; + } + case 'v': { + ++verbose; + break; + } + case 'u': { + udpMode = 1; + break; + } + case 'U': { + reverseMode = 1; + break; + } + case 'k': { + keys = optarg; + break; + } + case 'c': { + certif = optarg; + break; + } + case 's': { + store = optarg; + break; + } + case 'f': { + filenam = optarg; + break; + } + case 'o': { + addlogtarget(optarg); + break; + } + case 301: { + n = strlen(optarg); + memset(password, 0, 4); + for (i = 0; i < n; ++i) { + password[i%4] += optarg[i]; + } + passwordWasSet = 1; + break; + } + case 302: { + ignorePublicKeys = 1; + break; + } + case 305: { + ArOptions_set_arStart(ao, AR_OPTION_ENABLED); + aoUsed = 1; + break; + } + case 306: { + ArOptions_set_arQuit(ao, AR_OPTION_ENABLED); + aoUsed = 1; + break; + } + case 307: { + ArOptions_set_arPremature(ao, AR_OPTION_DISABLED); + aoUsed = 1; + break; + } + case 311: { + localName = optarg; + break; + } + case 312: { + localPort = optarg; + break; + } + case 313: { + localDestinationName = optarg; + break; + } +#ifdef AF_INET6 + case '4': { + if (ipFamily != 0) { + ipFamily = -1; + } + else { + ipFamily = 4; + } + break; + } + case '6': { + if (ipFamily != 0) { + ipFamily = -1; + } + else { + ipFamily = 6; + } + break; + } +#endif +#ifdef HAVE_LIBDL + case 'l': { + Module_set_fileName(moduleA, optarg); + break; + } + case 'L': { + Module_set_fileName(moduleB, optarg); + break; + } +#endif + case 'D': { + dateformat = optarg; + break; + } + case 'r': { + remoteMode = 1; + break; + } + case 'V': { + printf("%s\n", (AF_VER("Active port forwarder (client)"))); + exit(0); + break; + } + case 'K': { + kaTimeout = optarg; + break; + } + case 'A': { + ArOptions_set_s_arTries(ao, optarg); + aoUsed = 1; + break; + } + case 'T': { + ArOptions_set_s_arDelay(ao, optarg); + aoUsed = 1; + break; + } + case '?': { + client_short_usage(""); + break; + } + } + } + + if (optind < argc) { + client_short_usage("Unrecognized non-option elements"); + } + + if (filenam != NULL) { + cconfig = cparsefile(filenam, &n); + if (n) { + printf("parsing failed! line:%d\n", n); + exit(1); + } + else { + if (keys == NULL) { + if (ClientConfiguration_get_keysFile(cconfig) == NULL) { + ClientConfiguration_set_keysFile(cconfig, "client.rsa"); + } + } + else { + ClientConfiguration_set_keysFile(cconfig, keys); + } + if (certif != NULL) { + ClientConfiguration_set_certificateFile(cconfig, certif); + } + if (store == NULL) { + if (ClientConfiguration_get_storeFile(cconfig) == NULL) { + ClientConfiguration_set_storeFile(cconfig, "known_hosts"); + } + } + else { + ClientConfiguration_set_storeFile(cconfig, store); + } + if (dateformat != NULL) { + ClientConfiguration_set_dateFormat(cconfig, dateformat); + } + if (ignorePublicKeys) { + ClientConfiguration_set_ignorePublicKeys(cconfig, ignorePublicKeys); + } + + initializelogging(verbose, ClientConfiguration_get_dateFormat(cconfig)); + + aflog(LOG_T_INIT, LOG_I_INFO, + "client's cfg file OK! (readed realms: %d)", ClientConfiguration_get_realmsNumber(cconfig)); + if ((ClientConfiguration_get_realmsNumber(cconfig) == 0) || + (ClientConfiguration_get_realmsTable(cconfig) == NULL) || + ((pointer = ClientConfiguration_get_realmsTable(cconfig)[0]) == NULL)) { + aflog(LOG_T_INIT, LOG_I_CRIT, + "Working without sense is really without sense..."); + exit(1); + } + if (hpoUsed) { + ClientRealm_set_httpProxyOptions(pointer, hpo); + } + else { + HttpProxyOptions_free(&hpo); + } + if (aoUsed) { + ClientRealm_set_arOptions(pointer, ao); + } + else { + ArOptions_free(&ao); + } + if ((serverName != NULL) && (ClientRealm_get_serverName(pointer) == NULL)) { + ClientRealm_set_serverName(pointer, serverName); + } + if ((managePort != NULL) && (ClientRealm_get_managePort(pointer) == NULL)) { + ClientRealm_set_managePort(pointer, managePort); + } + if ((hostName != NULL) && (ClientRealm_get_hostName(pointer) == NULL)) { + ClientRealm_set_hostName(pointer, hostName); + } + if ((PortList_get_size(destinationPorts) != 0) && + (PortList_get_size(ClientRealm_get_destinationPorts(pointer)) == 0)) { + ClientRealm_set_destinationPorts(pointer, destinationPorts); + } + if ((realmId != NULL) && (ClientRealm_get_realmId(pointer) == NULL)) { + ClientRealm_set_realmId(pointer, realmId); + } + if ((localName != NULL) && (ClientRealm_get_localName(pointer) == NULL)) { + ClientRealm_set_localName(pointer, localName); + } + if ((localPort != NULL) && (ClientRealm_get_localPort(pointer) == NULL)) { + ClientRealm_set_localPort(pointer, localPort); + } + if ((localDestinationName != NULL) & (ClientRealm_get_localDestinationName(pointer) == NULL)) { + ClientRealm_set_localDestinationName(pointer, localDestinationName); + } + if ((kaTimeout != NULL) && (ClientRealm_get_sKeepAliveTimeout(pointer) == NULL)) { + ClientRealm_set_sKeepAliveTimeout(pointer, kaTimeout); + } + if (reverseMode) { + aflog(LOG_T_INIT, LOG_I_WARNING, + "Warning: reverseudp will be ignored"); + } + if (udpMode) { + aflog(LOG_T_INIT, LOG_I_WARNING, + "Warning: udpmode will be ignored"); + } + if (remoteMode) { + aflog(LOG_T_INIT, LOG_I_WARNING, + "Warning: remoteadmin will be ignored"); + } + if (passwordWasSet) { + aflog(LOG_T_INIT, LOG_I_WARNING, + "Warning: pass will be ignored"); + } +#ifdef HAVE_LIBDL + if (Module_get_fileName(moduleA)) { + aflog(LOG_T_INIT, LOG_I_WARNING, + "Warning: load will be ignored"); + } + if (Module_get_fileName(moduleB)) { + aflog(LOG_T_INIT, LOG_I_WARNING, + "Warning: Load will be ignored"); + } +#endif + } + } + else { + cconfig = ClientConfiguration_new(); + if (cconfig == NULL) { + printf("Can't allocate memory for client configuration... exiting\n"); + exit(1); + } + ClientConfiguration_set_keysFile(cconfig, keys); + ClientConfiguration_set_certificateFile(cconfig, certif); + ClientConfiguration_set_storeFile(cconfig, store); + ClientConfiguration_set_dateFormat(cconfig, dateformat); + ClientConfiguration_set_realmsNumber(cconfig, 1); + ClientConfiguration_set_ignorePublicKeys(cconfig, ignorePublicKeys); + + initializelogging(verbose, ClientConfiguration_get_dateFormat(cconfig)); + + if (ClientConfiguration_get_keysFile(cconfig) == NULL) { + ClientConfiguration_set_keysFile(cconfig, "client.rsa"); + } + if (ClientConfiguration_get_storeFile(cconfig) == NULL) { + ClientConfiguration_set_storeFile(cconfig, "known_hosts"); + } + ClientConfiguration_set_realmsTable(cconfig, + calloc(ClientConfiguration_get_realmsNumber(cconfig), sizeof(ClientRealm*))); + if (ClientConfiguration_get_realmsTable(cconfig) == NULL) { + aflog(LOG_T_INIT, LOG_I_CRIT, + "Can't allocate memory for ClientRealm* table... exiting"); + exit(1); + } + pointer = ClientRealm_new(); + if (pointer == NULL) { + aflog(LOG_T_INIT, LOG_I_CRIT, + "Can't allocate memory for ClientRealm structure... exiting"); + exit(1); + } + + ClientConfiguration_get_realmsTable(cconfig)[0] = pointer; + ClientRealm_set_serverName(pointer, serverName); + ClientRealm_set_managePort(pointer, managePort); + ClientRealm_set_hostName(pointer, hostName); + ClientRealm_set_destinationPorts(pointer, destinationPorts); + ClientRealm_set_realmId(pointer, realmId); + ClientRealm_set_httpProxyOptions(pointer, hpo); + ClientRealm_set_arOptions(pointer, ao); + ClientRealm_set_password(pointer, password); + ClientRealm_set_localName(pointer, localName); + ClientRealm_set_localPort(pointer, localPort); + ClientRealm_set_localDestinationName(pointer, localDestinationName); + ClientRealm_set_realmId(pointer, realmId); + ClientRealm_set_sKeepAliveTimeout(pointer, kaTimeout); +#ifdef HAVE_LIBDL + ClientRealm_set_userModule(pointer, moduleA); + ClientRealm_set_serviceModule(pointer, moduleB); +#endif + + if (reverseMode) { + if (ClientRealm_get_clientMode(pointer) == CLIENTREALM_MODE_TCP) { + ClientRealm_set_clientMode(pointer, CLIENTREALM_MODE_REVERSE); + } + else { + ClientRealm_set_clientMode(pointer, CLIENTREALM_MODE_UNKNOWN); + } + } + if (udpMode) { + if (ClientRealm_get_clientMode(pointer) == CLIENTREALM_MODE_TCP) { + ClientRealm_set_clientMode(pointer, CLIENTREALM_MODE_UDP); + } + else { + ClientRealm_set_clientMode(pointer, CLIENTREALM_MODE_UNKNOWN); + } + } + if (remoteMode) { + if (ClientRealm_get_clientMode(pointer) == CLIENTREALM_MODE_TCP) { + ClientRealm_set_clientMode(pointer, CLIENTREALM_MODE_REMOTE); + } + else { + ClientRealm_set_clientMode(pointer, CLIENTREALM_MODE_UNKNOWN); + } + } + } + + /* + * WARNING: we have only one ClientRealm at the moment + */ + + if (ClientRealm_get_serverName(pointer) == NULL) { + client_short_usage("Name of the server is required"); + } + if (ClientRealm_get_clientMode(pointer) == CLIENTREALM_MODE_UNKNOWN) { + aflog(LOG_T_INIT, LOG_I_CRIT, + "Conflicting/unknown client modes... exiting"); + exit(1); + } + if (ClientRealm_get_managePort(pointer) == NULL) { + ClientRealm_set_managePort(pointer, "50126"); + if (ClientRealm_get_clientMode(pointer) == CLIENTREALM_MODE_REVERSE) + client_short_usage("Port on the server is required in reverse mode"); + } +#ifdef HAVE_LIBPTHREAD + if ((HttpProxyOptions_get_proxyname(ClientRealm_get_httpProxyOptions(pointer))) || + (HttpProxyOptions_get_proxyport(ClientRealm_get_httpProxyOptions(pointer)))) { + if (ClientRealm_get_tunnelType(pointer) == CLIENTREALM_TUNNELTYPE_DIRECT) { + ClientRealm_set_tunnelType(pointer, CLIENTREALM_TUNNELTYPE_HTTPPROXY); + } + else { + ClientRealm_set_tunnelType(pointer, CLIENTREALM_TUNNELTYPE_UNKNOWN); + } + } + if (ClientRealm_get_tunnelType(pointer) == CLIENTREALM_TUNNELTYPE_HTTPPROXY) { + if (HttpProxyOptions_get_proxyport(ClientRealm_get_httpProxyOptions(pointer)) == NULL) { + HttpProxyOptions_set_proxyport(ClientRealm_get_httpProxyOptions(pointer), "8080"); + } + } +#endif + if ((ClientRealm_get_clientMode(pointer) != CLIENTREALM_MODE_REVERSE) && + (ClientRealm_get_clientMode(pointer) != CLIENTREALM_MODE_REMOTE) && + (ClientRealm_get_hostName(pointer) == NULL)) { + gethostname(hostname, 100); + ClientRealm_set_hostName(pointer, hostname); + } + if ((ClientRealm_get_clientMode(pointer) != CLIENTREALM_MODE_REMOTE) && + (PortList_get_size(ClientRealm_get_destinationPorts(pointer)) == 0)) { + client_short_usage("Destination port number is required"); + } + + if (ClientRealm_get_sKeepAliveTimeout(pointer)) { + ClientRealm_set_keepAliveTimeout(pointer, + check_value(ClientRealm_get_sKeepAliveTimeout(pointer), "Invalid timeout value")); + keepAlive.tv_sec = ClientRealm_get_keepAliveTimeout(pointer); + keepAlive.tv_usec = 0; + ClientRealm_set_keepAlive(pointer, keepAlive); + } + ArOptions_evaluate_values(ClientRealm_get_arOptions(pointer)); + + if (ignorePublicKeys) { + ClientConfiguration_set_ignorePublicKeys(cconfig, ignorePublicKeys); + } + +#ifdef HAVE_LIBDL + if (Module_loadModule(ClientRealm_get_userModule(pointer))) { + aflog(LOG_T_INIT, LOG_I_CRIT, + "Loading a module %s failed!", Module_get_fileName(ClientRealm_get_userModule(pointer))); + exit(1); + } + if (Module_loadModule(ClientRealm_get_serviceModule(pointer))) { + aflog(LOG_T_INIT, LOG_I_CRIT, + "Loading a module %s failed!", Module_get_fileName(ClientRealm_get_serviceModule(pointer))); + exit(1); + } +#endif + + TYPE_SET_ZERO(realmType); + TYPE_SET_SSL(realmType); + TYPE_SET_ZLIB(realmType); + +#ifdef AF_INET6 + if ((ipFamily != 0) && (ClientRealm_get_ipFamily(pointer) <= 0)) { + ClientRealm_set_ipFamily(pointer, ipFamily); + } + if (ClientRealm_get_ipFamily(pointer) == -1) { + aflog(LOG_T_INIT, LOG_I_CRIT, + "Conflicting types of ip protocol family... exiting"); + exit(1); + } + else if (ClientRealm_get_ipFamily(pointer) == 4) { + TYPE_SET_IPV4(realmType); + } + else if (ClientRealm_get_ipFamily(pointer) == 6) { + TYPE_SET_IPV6(realmType); + } +#endif + ipFamily = 0x01; +#ifdef AF_INET6 + if (TYPE_IS_IPV4(realmType)) { + ipFamily |= 0x02; + } + else if (TYPE_IS_IPV6(realmType)) { + ipFamily |= 0x04; + } +#endif + + ClientRealm_set_ipFamily(pointer, ipFamily); + ClientRealm_set_realmType(pointer, realmType); + + if (ClientRealm_get_clientMode(pointer) != CLIENTREALM_MODE_REVERSE) { + SSL_library_init(); + method = SSLv3_client_method(); + ctx = SSL_CTX_new(method); + if (SSL_CTX_set_cipher_list(ctx, "ALL:@STRENGTH") == 0) { + aflog(LOG_T_INIT, LOG_I_CRIT, + "Setting cipher list failed... exiting"); + exit(1); + } + if ((temp2 = create_apf_dir(0))) { + aflog(LOG_T_INIT, LOG_I_WARNING, + "Warning: Creating ~/.apf directory failed (%d)", temp2); + if ((temp2 = create_apf_dir(1))) { + aflog(LOG_T_INIT, LOG_I_WARNING, + "Warning: Creating ./apf directory failed (%d)", temp2); + } + } + store = ClientConfiguration_get_storeFile(cconfig); + if ((temp2 = create_publickey_store(&store))) { + aflog(LOG_T_INIT, LOG_I_WARNING, + "Warning: Something bad happened when creating public key store... (%d)", temp2); + } + ClientConfiguration_set_storeFile(cconfig, store); + keys = ClientConfiguration_get_keysFile(cconfig); + if ((temp2 = generate_rsa_key(&keys))) { + aflog(LOG_T_INIT, LOG_I_WARNING, + "Warning: Something bad happened when generating rsa keys... (%d)", temp2); + } + ClientConfiguration_set_keysFile(cconfig, keys); + if (SSL_CTX_use_RSAPrivateKey_file(ctx, keys, SSL_FILETYPE_PEM) != 1) { + aflog(LOG_T_INIT, LOG_I_CRIT, + "Setting rsa key failed (%s)... exiting", keys); + exit(1); + } + + certif = ClientConfiguration_get_certificateFile(cconfig); + if (certif) { + if (SSL_CTX_use_certificate_file(ctx, certif, SSL_FILETYPE_PEM) != 1) { + aflog(LOG_T_INIT, LOG_I_CRIT, + "Setting certificate failed (%s)... exiting", certif); + exit(1); + } + } + + if ((ClientRealm_get_clientMode(pointer) != CLIENTREALM_MODE_REMOTE) && + (!verbose)) + daemon(0, 0); + + if (ClientRealm_get_clientMode(pointer) == CLIENTREALM_MODE_REMOTE) { + temp2 = -1; + if (PortList_get_size(ClientRealm_get_destinationPorts(pointer)) > 0) { + if (ip_listen(&n, ClientRealm_get_serverName(pointer), + PortListNode_get_portName(PortList_get_nth(ClientRealm_get_destinationPorts(pointer), 0)), + &addressLength, + ClientRealm_get_ipFamily(pointer))) { +#ifdef AF_INET6 + aflog(LOG_T_INIT, LOG_I_CRIT, + "tcp_listen_%s error for %s, %s", + (ClientRealm_get_ipFamily(pointer) & 0x02) ? + "ipv4" : + (ClientRealm_get_ipFamily(pointer) & 0x04) ? + "ipv6" : + "unspec", + ClientRealm_get_serverName(pointer), + PortListNode_get_portName(PortList_get_nth(ClientRealm_get_destinationPorts(pointer), 0))); +#else + aflog(LOG_T_INIT, LOG_I_CRIT, + "tcp_listen error for %s, %s", ClientRealm_get_serverName(pointer), + PortListNode_get_portName(PortList_get_nth(ClientRealm_get_destinationPorts(pointer), 0))); +#endif + exit(1); + } + clientAddress = malloc(addressLength); + if (clientAddress == NULL) { + aflog(LOG_T_INIT, LOG_I_CRIT, + "Can't allocate memory for sockaddr structure... exiting"); + exit(1); + } + ClientRealm_set_addressLength(pointer, addressLength); + ClientRealm_set_clientAddress(pointer, clientAddress); + temp2 = accept(n, ClientRealm_get_clientAddress(pointer), &addressLength); + } + } + + } + + i = ArOptions_get_arTries(ClientRealm_get_arOptions(pointer)); + SslFd_set_fd(ClientRealm_get_masterSslFd(pointer), -1); + + do { + temp = 0; + if (SslFd_get_fd(ClientRealm_get_masterSslFd(pointer)) != -1) { + close(SslFd_get_fd(ClientRealm_get_masterSslFd(pointer))); + } + ClientRealm_closeUsersConnections(pointer); + SslFd_set_ssl(ClientRealm_get_masterSslFd(pointer), NULL); + + if (ClientRealm_get_clientMode(pointer) != CLIENTREALM_MODE_REVERSE) { + if (temp == 0) { + if (initialize_client_stage1(pointer, ctx, buff, + (ArOptions_get_arStart(ClientRealm_get_arOptions(pointer)) == AR_OPTION_ENABLED) ? 0 : 1, + ClientConfiguration_get_ignorePublicKeys(cconfig))) { + temp = 1; + } + } + + if ((temp == 0) && (ClientRealm_get_clientMode(pointer) == CLIENTREALM_MODE_REMOTE)) { + return client_admin(ClientRealm_get_realmType(pointer), + ClientRealm_get_masterSslFd(pointer), buff, temp2, + ClientRealm_get_realmId(pointer)); + } + + if (temp == 0) { + realmType = ClientRealm_get_realmType(pointer); + if (initialize_client_stage2(pointer, buff, + (ArOptions_get_arStart(ClientRealm_get_arOptions(pointer)) == AR_OPTION_ENABLED) ? 0 : 1)) { + temp = 1; + } + } + } /* !reverse */ + else { + if (initialize_client_reverse_udp(pointer)) { + temp = 1; + } + } + + if (temp == 0) { + if (initialize_client_stage3(pointer, &buflength, &allset, &wset, &maxfdp1, + (ArOptions_get_arStart(ClientRealm_get_arOptions(pointer)) == AR_OPTION_ENABLED) ? 0 : 1)) { + temp = 1; + } + } + + /* UDP REVERSE MODE */ + + if ((temp == 0) && (ClientRealm_get_clientMode(pointer) == CLIENTREALM_MODE_REVERSE)) { + client_reverse_udp(pointer, buff, buflength); + } + + if (i > 0) { + --i; + } + if ((i != 0) && (temp == 1)) { + aflog(LOG_T_INIT, LOG_I_INFO, + "Trying to reconnect..."); + mysleep(ArOptions_get_arDelay(ClientRealm_get_arOptions(pointer))); + ClientRealm_set_realmType(pointer, realmType); + } + if (temp == 0) { + break; + } + } while (i); + + /* NORMAL MODE */ + + aflog(LOG_T_CLIENT, LOG_I_INFO, + "CLIENT STARTED mode: %s", (ClientRealm_get_clientMode(pointer) == CLIENTREALM_MODE_UDP) ? "udp" : "tcp"); + aflog(LOG_T_CLIENT, LOG_I_INFO, + "SERVER SSL: %s, ZLIB: %s, MODE: %s", (TYPE_IS_SSL(ClientRealm_get_realmType(pointer))) ? "yes" : "no", + (TYPE_IS_ZLIB(ClientRealm_get_realmType(pointer))) ? "yes" : "no", + (TYPE_IS_TCP(ClientRealm_get_realmType(pointer))) ? "tcp" : "udp"); + aflog(LOG_T_CLIENT, LOG_I_INFO, + "SERVER MULTI: %s", (TYPE_IS_SUPPORTED_MULTI(ClientRealm_get_realmType(pointer))) ? "yes" : "no"); + aflog(LOG_T_CLIENT, LOG_I_NOTICE, + "CIPHER: %s VER: %s", SSL_get_cipher_name(SslFd_get_ssl(ClientRealm_get_masterSslFd(pointer))), + SSL_get_cipher_version(SslFd_get_ssl(ClientRealm_get_masterSslFd(pointer)))); +#ifdef HAVE_LIBDL + if (Module_isModuleLoaded(ClientRealm_get_userModule(pointer))) { + aflog(LOG_T_CLIENT, LOG_I_INFO, + "LOADED MODULE: %s INFO: %s", Module_get_fileName(ClientRealm_get_userModule(pointer)), + Module_function_info(ClientRealm_get_userModule(pointer))); + } + if (Module_isModuleLoaded(ClientRealm_get_serviceModule(pointer))) { + aflog(LOG_T_CLIENT, LOG_I_INFO, + "LOADED MODULE (ser): %s INFO: %s", Module_get_fileName(ClientRealm_get_serviceModule(pointer)), + Module_function_info(ClientRealm_get_serviceModule(pointer))); + } +#endif + + ClientRealm_send_realmId(pointer, buff); + ClientRealm_enable_multi(pointer); + + for ( ; ; ) { + rset = allset; + tmpset = wset; + aflog(LOG_T_MAIN, LOG_I_DDEBUG, + "select"); + if (ClientRealm_get_sKeepAliveTimeout(pointer)) { + if (select(maxfdp1, &rset, &tmpset, NULL, ClientRealm_get_keepAlivePointer(pointer)) == 0) { + aflog(LOG_T_CLIENT, LOG_I_DEBUG, + "timeout: sending keep-alive packet"); + buff[0] = AF_S_KEEP_ALIVE; + SslFd_send_message(ClientRealm_get_realmType(pointer), + ClientRealm_get_masterSslFd(pointer), buff, 5); + keepAlive.tv_sec = ClientRealm_get_keepAliveTimeout(pointer); + keepAlive.tv_usec = 0; + ClientRealm_set_keepAlive(pointer, keepAlive); + } + } + else { + select(maxfdp1, &rset, &tmpset, NULL, NULL); + } + aflog(LOG_T_MAIN, LOG_I_DDEBUG, + "after select..."); + + usersTable = ClientRealm_get_usersTable(pointer); + for (i = 0; i < ClientRealm_get_usersLimit(pointer); ++i) { + if ((ConnectUser_get_state(usersTable[i]) == S_STATE_OPEN) || + (ConnectUser_get_state(usersTable[i]) == S_STATE_STOPPED) || + (ConnectUser_get_state(usersTable[i]) == S_STATE_KICKING)) { + if (FD_ISSET(ConnectUser_get_connFd(usersTable[i]), &rset)) { /* FD_ISSET CONTABLE[i].CONNFD RSET */ + aflog(LOG_T_USER, LOG_I_DDEBUG, + "user[%d]: FD_ISSET", i); + n = read(ConnectUser_get_connFd(usersTable[i]), &buff[5], 8091); + if (n == -1) { + if (errno == EAGAIN) { + continue; + } + aflog(LOG_T_USER, LOG_I_ERR, + "error (%d): while reading from service", errno); + n = 0; + } +#ifdef HAVE_LINUX_SOCKIOS_H +# ifdef SIOCOUTQ + if (ioctl(SslFd_get_fd(ClientRealm_get_masterSslFd(pointer)), SIOCOUTQ, ¬sent)) { + aflog(LOG_T_USER, LOG_I_CRIT, + "ioctl error -> exiting..."); + exit(1); + } + if (ClientRealm_get_clientMode(pointer) == CLIENTREALM_MODE_UDP) { + aLength = 4; + if (getsockopt(SslFd_get_fd(ClientRealm_get_masterSslFd(pointer)), + SOL_SOCKET, SO_SNDBUF, &temp2, &aLength) != -1) { + if (temp2 != buflength) { + buflength = temp2; + aflog(LOG_T_USER, LOG_I_WARNING, + "Send buffer size changed..."); + } + } + if (buflength <= notsent + n + 5) { /* when we can't send this */ + 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(LOG_T_USER, LOG_I_CRIT, + "ioctl error -> exiting..."); + exit(1); + } + if (ClientRealm_get_clientMode(pointer) == CLIENTREALM_MODE_UDP) { + len = 4; + if (getsockopt(master.commfd, SOL_SOCKET, SO_SNDBUF, &temp2, &len) != -1) { + if (temp2 != buflength) { + buflength = temp2; + aflog(LOG_T_USER, LOG_I_WARNING, + "Send buffer size changed..."); + } + } + if (notsent <= n + 5) { /* when we can't send this */ + 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 */ + } + } +#endif + if (n) { +#ifdef HAVE_LIBDL + if (Module_isModuleLoaded(ClientRealm_get_serviceModule(pointer))) { + switch ((temp2 = Module_function_filter(ClientRealm_get_serviceModule(pointer), + ConnectUser_get_nameBuf(usersTable[i]), &buff[5], &n))) { + case 1: case 4: { + aflog(LOG_T_USER, LOG_I_WARNING, + "user[%d] (by ser): PACKET IGNORED BY MODULE", i); + if (temp2 == 4) { + aflog(LOG_T_MAIN, LOG_I_INFO, + "RELEASED MODULE (ser): %s INFO: %s", + Module_get_fileName(ClientRealm_get_serviceModule(pointer)), + Module_function_info(ClientRealm_get_serviceModule(pointer))); + Module_releaseModule(ClientRealm_get_serviceModule(pointer)); + } + continue; + break; + } + case 2: case 5: { + aflog(LOG_T_USER, LOG_I_NOTICE, + "user[%d] (by ser): DROPPED BY MODULE", i); + close(ConnectUser_get_connFd(usersTable[i])); + aflog(LOG_T_USER, LOG_I_DDEBUG, + "user[%d]: Closing connFd: %d", i, ConnectUser_get_connFd(usersTable[i])); + FD_CLR(ConnectUser_get_connFd(usersTable[i]), &allset); + FD_CLR(ConnectUser_get_connFd(usersTable[i]), &wset); + ConnectUser_set_state(usersTable[i], S_STATE_CLOSING); + BufList_clear(ConnectUser_get_bufList(usersTable[i])); + buff[0] = AF_S_CONCLOSED; /* closing connection */ + buff[1] = i >> 8; /* high bits of user number */ + buff[2] = i; /* low bits of user number */ + SslFd_send_message(ClientRealm_get_realmType(pointer), ClientRealm_get_masterSslFd(pointer), buff, 5); + if (temp2 == 5) { + aflog(LOG_T_MAIN, LOG_I_INFO, + "RELEASED MODULE (ser): %s INFO: %s", + Module_get_fileName(ClientRealm_get_serviceModule(pointer)), + Module_function_info(ClientRealm_get_serviceModule(pointer))); + Module_releaseModule(ClientRealm_get_serviceModule(pointer)); + } + continue; + break; + } + case 3: { + aflog(LOG_T_MAIN, LOG_I_INFO, + "RELEASED MODULE (ser): %s INFO: %s", + Module_get_fileName(ClientRealm_get_serviceModule(pointer)), + Module_function_info(ClientRealm_get_serviceModule(pointer))); + Module_releaseModule(ClientRealm_get_serviceModule(pointer)); + break; + } + } + } +#endif + buff[0] = AF_S_MESSAGE; /* sending message */ + buff[1] = i >> 8; /* high bits of user number */ + buff[2] = i; /* low bits of user number */ + buff[3] = n >> 8; /* high bits of message length */ + buff[4] = n; /* low bits of message length */ +#ifdef HAVE_LINUX_SOCKIOS_H + aflog(LOG_T_USER, LOG_I_DEBUG, + "user[%d]: TO msglen: %d [%d/%d]", i, n, +# ifdef SIOCOUTQ + notsent +# else + buflength - notsent +# endif + , buflength); +#else + aflog(LOG_T_USER, LOG_I_DEBUG, + "user[%d]: TO msglen: %d", i, n); +#endif + SslFd_send_message(ClientRealm_get_realmType(pointer), ClientRealm_get_masterSslFd(pointer), buff, n+5); + } + else if (ClientRealm_get_clientMode(pointer) != CLIENTREALM_MODE_UDP) { + aflog(LOG_T_USER, LOG_I_INFO, + "user[%d]: CLOSING", i); + close(ConnectUser_get_connFd(usersTable[i])); + aflog(LOG_T_USER, LOG_I_DDEBUG, + "user[%d]: Closing connFd: %d", i, ConnectUser_get_connFd(usersTable[i])); + FD_CLR(ConnectUser_get_connFd(usersTable[i]), &allset); + FD_CLR(ConnectUser_get_connFd(usersTable[i]), &wset); + if (ConnectUser_get_state(usersTable[i]) == S_STATE_KICKING) { + ConnectUser_set_state(usersTable[i], S_STATE_CLEAR); + } + else { + ConnectUser_set_state(usersTable[i], S_STATE_CLOSING); + } + BufList_clear(ConnectUser_get_bufList(usersTable[i])); + buff[0] = AF_S_CONCLOSED; /* closing connection */ + buff[1] = i >> 8; /* high bits of user number */ + buff[2] = i; /* low bits of user number */ + SslFd_send_message(ClientRealm_get_realmType(pointer), ClientRealm_get_masterSslFd(pointer), buff, 5); + } + } /* - FD_ISSET CONTABLE[i].CONNFD RSET */ + } + } + for (i = 0; i < ClientRealm_get_usersLimit(pointer); ++i) { + if ((ConnectUser_get_state(usersTable[i]) == S_STATE_STOPPED) || + (ConnectUser_get_state(usersTable[i]) == S_STATE_KICKING)) { + if (FD_ISSET(ConnectUser_get_connFd(usersTable[i]), &tmpset)) { /* FD_ISSET CONTABLE[i].CONNFD TMPSET */ + aflog(LOG_T_USER, LOG_I_DDEBUG, + "user[%d]: FD_ISSET - WRITE", i); + n = BufListNode_readMessageLength(BufList_get_first(ConnectUser_get_bufList(usersTable[i]))); + temp2 = write(ConnectUser_get_connFd(usersTable[i]), + BufListNode_readMessage(BufList_get_first(ConnectUser_get_bufList(usersTable[i]))), n); + if ((temp2 > 0) && (temp2 != n)) { + BufListNode_set_actPtr(BufList_get_first(ConnectUser_get_bufList(usersTable[i])), + BufListNode_get_actPtr(BufList_get_first(ConnectUser_get_bufList(usersTable[i]))) + temp2); + } + else if ((temp2 == -1) && (errno == EAGAIN)) { + aflog(LOG_T_USER, LOG_I_DEBUG, + "user[%d]: Couldn't write?", i); + } + else if (temp2 == -1) { + close(ConnectUser_get_connFd(usersTable[i])); + aflog(LOG_T_USER, LOG_I_DDEBUG, + "user[%d]: Closing connFd: %d", i, ConnectUser_get_connFd(usersTable[i])); + FD_CLR(ConnectUser_get_connFd(usersTable[i]), &allset); + FD_CLR(ConnectUser_get_connFd(usersTable[i]), &wset); + if (ConnectUser_get_state(usersTable[i]) == S_STATE_KICKING) { + ConnectUser_set_state(usersTable[i], S_STATE_CLEAR); + } + else { + ConnectUser_set_state(usersTable[i], S_STATE_CLOSING); + } + buff[0] = AF_S_CONCLOSED; /* closing connection */ + buff[1] = i >> 8; /* high bits of user number */ + buff[2] = i; /* low bits of user number */ + SslFd_send_message(ClientRealm_get_realmType(pointer), + ClientRealm_get_masterSslFd(pointer), buff, 5); + } + else { + BufList_delete_first(ConnectUser_get_bufList(usersTable[i])); + if (BufList_get_first(ConnectUser_get_bufList(usersTable[i])) == NULL) { + FD_CLR(ConnectUser_get_connFd(usersTable[i]), &wset); + 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(LOG_T_USER, LOG_I_DDEBUG, + "FROM user[%d]: BUFFERING MESSAGE ENDED", i); + SslFd_send_message(ClientRealm_get_realmType(pointer), + ClientRealm_get_masterSslFd(pointer), buff, 5); + if (ConnectUser_get_state(usersTable[i]) == S_STATE_KICKING) { + close(ConnectUser_get_connFd(usersTable[i])); + aflog(LOG_T_USER, LOG_I_DDEBUG, + "user[%d]: Closing connFd: %d", i, ConnectUser_get_connFd(usersTable[i])); + FD_CLR(ConnectUser_get_connFd(usersTable[i]), &allset); + FD_CLR(ConnectUser_get_connFd(usersTable[i]), &wset); + ConnectUser_set_state(usersTable[i], S_STATE_CLEAR); + buff[0] = AF_S_CONCLOSED; /* closing connection */ + buff[1] = i >> 8; /* high bits of user number */ + buff[2] = i; /* low bits of user number */ + SslFd_send_message(ClientRealm_get_realmType(pointer), + ClientRealm_get_masterSslFd(pointer), buff, 5); + } + else { + ConnectUser_set_state(usersTable[i], S_STATE_OPEN); + } + } + } + } /* - FD_ISSET CONTABLE[i].CONNFD TMPSET */ + } + } + if (FD_ISSET(SslFd_get_fd(ClientRealm_get_masterSslFd(pointer)), &rset)) { /* FD_ISSET MASTER.COMMFD RSET */ + aflog(LOG_T_CLIENT, LOG_I_DDEBUG, + "masterfd: FD_ISSET"); + n = SslFd_get_message(ClientRealm_get_realmType(pointer), ClientRealm_get_masterSslFd(pointer), buff, 5); + if (n != 5) { + aflog(LOG_T_CLIENT, LOG_I_ERR, + "FATAL ERROR! (%d)", n); + if (n == -1) { + if (TYPE_IS_SSL(ClientRealm_get_realmType(pointer))) { + get_ssl_error(ClientRealm_get_masterSslFd(pointer), "FE", n); + continue; /* what happened? */ + } + } + if (n != 0) + exit(1); + } + if (n == 0) { /* server quits -> we do the same... */ + i = ArOptions_get_arTries(ClientRealm_get_arOptions(pointer)); + if (ArOptions_get_arPremature(ClientRealm_get_arOptions(pointer)) == AR_OPTION_DISABLED) { + i = 0; + } + if (i) { + aflog(LOG_T_CLIENT, LOG_I_ERR, + "SERVER: premature quit -> auto-reconnect enabled"); + } + while (i) { + ClientRealm_closeUsersConnections(pointer); + close(SslFd_get_fd(ClientRealm_get_masterSslFd(pointer))); + SslFd_set_ssl(ClientRealm_get_masterSslFd(pointer), NULL); + mysleep(ArOptions_get_arDelay(ClientRealm_get_arOptions(pointer))); + aflog(LOG_T_CLIENT, LOG_I_INFO, + "Trying to reconnect..."); + + temp2 = 0; + if (temp2 == 0) { + if (initialize_client_stage1(pointer, ctx, buff, 0, + ClientConfiguration_get_ignorePublicKeys(cconfig))) { + temp2 = 1; + } + } + if (temp2 == 0) { + if (initialize_client_stage2(pointer, buff, 0)) { + temp2 = 1; + } + } + if (temp2 == 0) { + if (initialize_client_stage3(pointer, &buflength, &allset, &wset, &maxfdp1, 0)) { + temp2 = 1; + } + } + + if (temp2 == 0) { + n = 1; + aflog(LOG_T_CLIENT, LOG_I_INFO, + "Reconnected successfully..."); + usersTable = ClientRealm_get_usersTable(pointer); + + ClientRealm_send_realmId(pointer, buff); + ClientRealm_enable_multi(pointer); + + 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; + numofcon += buff[2]; /* this is id of user */ + length = buff[3]; + length = length << 8; + length += buff[4]; /* this is length of message */ + switch (buff[0]) { + case AF_S_CONCLOSED : { + aflog(LOG_T_USER, LOG_I_DDEBUG, + "user[%d]: AF_S_CONCLOSED", numofcon); + if ((numofcon>=0) && (numofcon<=ClientRealm_get_usersLimit(pointer))) { + if (ConnectUser_get_state(usersTable[numofcon]) == S_STATE_CLOSING) { + ConnectUser_set_state(usersTable[numofcon], S_STATE_CLEAR); + aflog(LOG_T_USER, LOG_I_INFO, + "user[%d]: CLOSE CONFIRMED", numofcon); + } + else if (ConnectUser_get_state(usersTable[numofcon]) == S_STATE_OPEN) { + aflog(LOG_T_USER, LOG_I_INFO, + "user[%d]: CLOSED", numofcon); + close(ConnectUser_get_connFd(usersTable[numofcon])); + aflog(LOG_T_USER, LOG_I_DDEBUG, + "user[%d]: Closing connFd: %d", numofcon, ConnectUser_get_connFd(usersTable[numofcon])); + FD_CLR(ConnectUser_get_connFd(usersTable[numofcon]), &allset); + FD_CLR(ConnectUser_get_connFd(usersTable[numofcon]), &wset); + ConnectUser_set_state(usersTable[numofcon], S_STATE_CLEAR); + BufList_clear(ConnectUser_get_bufList(usersTable[numofcon])); + buff[0] = AF_S_CONCLOSED; /* closing connection */ + buff[1] = numofcon >> 8; /* high bits of user number */ + buff[2] = numofcon; /* low bits of user number */ + SslFd_send_message(ClientRealm_get_realmType(pointer), ClientRealm_get_masterSslFd(pointer), buff, 5); + } + else if (ConnectUser_get_state(usersTable[numofcon]) == S_STATE_STOPPED) { + ConnectUser_set_state(usersTable[numofcon], S_STATE_KICKING); + aflog(LOG_T_USER, LOG_I_INFO, + "user[%d]: CLOSING...", numofcon); + } + } + break; + } + case AF_S_CONOPEN : { + aflog(LOG_T_USER, LOG_I_DDEBUG, + "user[%d]: AF_S_CONOPEN", numofcon); + if ((numofcon>=0) && (numofcon<=ClientRealm_get_usersLimit(pointer))) { + if (ConnectUser_get_state(usersTable[numofcon]) == S_STATE_CLEAR) { + n = SslFd_get_message(ClientRealm_get_realmType(pointer), ClientRealm_get_masterSslFd(pointer), buff, length); + ConnectUser_set_nameBuf(usersTable[numofcon], (char*) buff); + ConnectUser_set_portBuf(usersTable[numofcon], (char*) &buff[128]); + 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, + ConnectUser_get_nameBuf(usersTable[numofcon]), ConnectUser_get_portBuf(usersTable[numofcon])); +#ifdef HAVE_LIBDL + if (Module_isModuleLoaded(ClientRealm_get_userModule(pointer)) && + Module_function_allow(ClientRealm_get_userModule(pointer), + ConnectUser_get_nameBuf(usersTable[numofcon]), + ConnectUser_get_portBuf(usersTable[numofcon]))) { + aflog(LOG_T_USER, LOG_I_WARNING, + "user[%d]: 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 */ + SslFd_send_message(ClientRealm_get_realmType(pointer), ClientRealm_get_masterSslFd(pointer), buff, 5); + continue; + } +#endif + if (ClientRealm_get_clientMode(pointer) == CLIENTREALM_MODE_UDP) { + ipFamily = 0; + } + else { + ipFamily = 0x01; + } +#ifdef AF_INET6 + if (TYPE_IS_IPV4(ClientRealm_get_realmType(pointer))) { + ipFamily |= 0x02; + } + else if (TYPE_IS_IPV6(ClientRealm_get_realmType(pointer))) { + ipFamily |= 0x04; + } +#endif + temp2 = 0; + if (n == 136) { + if (PortList_get_size(ClientRealm_get_destinationPorts(pointer)) == 1) { + temp2 = 0; + } + else { + temp2 = buff[135] % PortList_get_size(ClientRealm_get_destinationPorts(pointer)); + } + } + if (ip_connect(&temp, ClientRealm_get_hostName(pointer), + PortListNode_get_portName(PortList_get_nth(ClientRealm_get_destinationPorts(pointer), temp2)), ipFamily, + ClientRealm_get_localDestinationName(pointer), NULL)) { + aflog(LOG_T_USER, LOG_I_WARNING, + "user[%d]: CAN'T CONNECT to %s:%s - DROPPING", numofcon, + ClientRealm_get_hostName(pointer), + PortListNode_get_portName(PortList_get_nth(ClientRealm_get_destinationPorts(pointer), temp2))); + 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 */ + SslFd_send_message(ClientRealm_get_realmType(pointer), ClientRealm_get_masterSslFd(pointer), buff, 5); + continue; + } + ConnectUser_set_connFd(usersTable[numofcon], temp); + aflog(LOG_T_USER, LOG_I_DDEBUG, + "user[%d]: Setting connFd: %d", numofcon, temp); + temp2 = fcntl(ConnectUser_get_connFd(usersTable[numofcon]), F_GETFL, 0); + fcntl(ConnectUser_get_connFd(usersTable[numofcon]), F_SETFL, temp2 | O_NONBLOCK); + FD_SET(ConnectUser_get_connFd(usersTable[numofcon]), &allset); + maxfdp1 = (maxfdp1 > (ConnectUser_get_connFd(usersTable[numofcon]) + 1)) ? + maxfdp1 : (ConnectUser_get_connFd(usersTable[numofcon]) + 1); + buff[0] = AF_S_CONOPEN; /* opening connection */ + buff[1] = numofcon >> 8; /* high bits of user number */ + buff[2] = numofcon; /* low bits of user number */ + SslFd_send_message(ClientRealm_get_realmType(pointer), ClientRealm_get_masterSslFd(pointer), buff, 5); + ConnectUser_set_state(usersTable[numofcon], S_STATE_OPEN); + } + } + break; + } + case AF_S_MESSAGE : { + 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 = SslFd_get_message(ClientRealm_get_realmType(pointer), ClientRealm_get_masterSslFd(pointer), buff, length); + if ((numofcon>=0) && (numofcon<=ClientRealm_get_usersLimit(pointer))) { + if (ConnectUser_get_state(usersTable[numofcon]) == S_STATE_OPEN) { +#ifdef HAVE_LIBDL + if (Module_isModuleLoaded(ClientRealm_get_userModule(pointer))) { + switch ((temp2 = Module_function_filter(ClientRealm_get_userModule(pointer), + ConnectUser_get_nameBuf(usersTable[numofcon]), buff, &n))) { + case 1: case 4:{ + aflog(LOG_T_USER, LOG_I_WARNING, + "user[%d]: PACKET IGNORED BY MODULE", numofcon); + if (temp2 == 4) { + aflog(LOG_T_MAIN, LOG_I_INFO, + "RELEASED MODULE: %s INFO: %s", + Module_get_fileName(ClientRealm_get_userModule(pointer)), + Module_function_info(ClientRealm_get_userModule(pointer))); + Module_releaseModule(ClientRealm_get_userModule(pointer)); + } + continue; + break; + } + case 2: case 5:{ + aflog(LOG_T_USER, LOG_I_NOTICE, + "user[%d]: DROPPED BY MODULE", numofcon); + close(ConnectUser_get_connFd(usersTable[numofcon])); + aflog(LOG_T_USER, LOG_I_DDEBUG, + "user[%d]: Closing connFd: %d", numofcon, ConnectUser_get_connFd(usersTable[numofcon])); + FD_CLR(ConnectUser_get_connFd(usersTable[numofcon]), &allset); + FD_CLR(ConnectUser_get_connFd(usersTable[numofcon]), &wset); + ConnectUser_set_state(usersTable[numofcon], S_STATE_CLOSING); + BufList_clear(ConnectUser_get_bufList(usersTable[numofcon])); + buff[0] = AF_S_CONCLOSED; /* closing connection */ + buff[1] = numofcon >> 8; /* high bits of user number */ + buff[2] = numofcon; /* low bits of user number */ + SslFd_send_message(ClientRealm_get_realmType(pointer), ClientRealm_get_masterSslFd(pointer), buff, 5); + if (temp2 == 5) { + aflog(LOG_T_MAIN, LOG_I_INFO, + "RELEASED MODULE: %s INFO: %s", + Module_get_fileName(ClientRealm_get_userModule(pointer)), + Module_function_info(ClientRealm_get_userModule(pointer))); + Module_releaseModule(ClientRealm_get_userModule(pointer)); + } + continue; + break; + } + case 3: { + aflog(LOG_T_MAIN, LOG_I_INFO, + "RELEASED MODULE: %s INFO: %s", + Module_get_fileName(ClientRealm_get_userModule(pointer)), + Module_function_info(ClientRealm_get_userModule(pointer))); + Module_releaseModule(ClientRealm_get_userModule(pointer)); + break; + } + } + } +#endif + aflog(LOG_T_USER, LOG_I_DEBUG, + "user[%d]: FROM msglen: %d SENT", numofcon, n); + temp2 = write(ConnectUser_get_connFd(usersTable[numofcon]), buff, n); + if ((temp2 > 0) && (temp2 != n)) { + BufList_insert_back(ConnectUser_get_bufList(usersTable[numofcon]), + BufListNode_new_message(temp2, n, buff)); + ConnectUser_set_state(usersTable[numofcon], S_STATE_STOPPED); + FD_SET(ConnectUser_get_connFd(usersTable[numofcon]), &wset); + 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(LOG_T_USER, LOG_I_DDEBUG, + "FROM user[%d]: BUFFERING MESSAGE STARTED", numofcon); + SslFd_send_message(ClientRealm_get_realmType(pointer), ClientRealm_get_masterSslFd(pointer), buff, 5); + } + else if ((temp2 == -1) && (errno == EAGAIN)) { + BufList_insert_back(ConnectUser_get_bufList(usersTable[numofcon]), + BufListNode_new_message(0, n, buff)); + ConnectUser_set_state(usersTable[numofcon], S_STATE_STOPPED); + FD_SET(ConnectUser_get_connFd(usersTable[numofcon]), &wset); + 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(LOG_T_USER, LOG_I_DDEBUG, + "FROM user[%d]: BUFFERING MESSAGE STARTED", numofcon); + SslFd_send_message(ClientRealm_get_realmType(pointer), ClientRealm_get_masterSslFd(pointer), buff, 5); + } + else if (temp2 == -1) { + close(ConnectUser_get_connFd(usersTable[numofcon])); + aflog(LOG_T_USER, LOG_I_DDEBUG, + "user[%d]: Closing connFd: %d", numofcon, ConnectUser_get_connFd(usersTable[numofcon])); + FD_CLR(ConnectUser_get_connFd(usersTable[numofcon]), &allset); + FD_CLR(ConnectUser_get_connFd(usersTable[numofcon]), &wset); + ConnectUser_set_state(usersTable[numofcon], S_STATE_CLOSING); + BufList_clear(ConnectUser_get_bufList(usersTable[numofcon])); + buff[0] = AF_S_CONCLOSED; /* closing connection */ + buff[1] = numofcon >> 8; /* high bits of user number */ + buff[2] = numofcon; /* low bits of user number */ + SslFd_send_message(ClientRealm_get_realmType(pointer), ClientRealm_get_masterSslFd(pointer), buff, 5); + } + } + else if (ConnectUser_get_state(usersTable[numofcon]) == S_STATE_STOPPED) { + aflog(LOG_T_USER, LOG_I_DDEBUG, + "FROM user[%d]: BUFFERING MESSAGE", numofcon); + BufList_insert_back(ConnectUser_get_bufList(usersTable[numofcon]), + BufListNode_new_message(0, n, buff)); + } + } + break; + } + case AF_S_CLOSING : { /* server shut down */ + n = 0; + i = ArOptions_get_arTries(ClientRealm_get_arOptions(pointer)); + if (ArOptions_get_arQuit(ClientRealm_get_arOptions(pointer)) == AR_OPTION_DISABLED) { + i = 0; + } + if (i) { + aflog(LOG_T_CLIENT, LOG_I_ERR, + "SERVER: CLOSED -> auto-reconnect enabled"); + } + while (i) { + ClientRealm_closeUsersConnections(pointer); + close(SslFd_get_fd(ClientRealm_get_masterSslFd(pointer))); + SslFd_set_ssl(ClientRealm_get_masterSslFd(pointer), NULL); + mysleep(ArOptions_get_arDelay(ClientRealm_get_arOptions(pointer))); + aflog(LOG_T_CLIENT, LOG_I_INFO, + "Trying to reconnect..."); + + temp2 = 0; + if (temp2 == 0) { + if (initialize_client_stage1(pointer, ctx, buff, 0, + ClientConfiguration_get_ignorePublicKeys(cconfig))) { + temp2 = 1; + } + } + if (temp2 == 0) { + if (initialize_client_stage2(pointer, buff, 0)) { + temp2 = 1; + } + } + if (temp2 == 0) { + if (initialize_client_stage3(pointer, &buflength, &allset, &wset, &maxfdp1, 0)) { + temp2 = 1; + } + } + + if (temp2 == 0) { + n = 1; + aflog(LOG_T_CLIENT, LOG_I_INFO, + "Reconnected successfully..."); + usersTable = ClientRealm_get_usersTable(pointer); + + ClientRealm_send_realmId(pointer, buff); + ClientRealm_enable_multi(pointer); + + break; + } + + if (i > 0) { + --i; + } + } + if (n == 0) { + aflog(LOG_T_CLIENT, LOG_I_INFO, + "SERVER: CLOSED -> exiting... cg: %ld bytes", getcg()); + exit(1); + } + break; + } + case AF_S_DONT_SEND: { + if ((ConnectUser_get_state(usersTable[numofcon]) == S_STATE_OPEN) || + (ConnectUser_get_state(usersTable[numofcon]) == S_STATE_STOPPED)) { + aflog(LOG_T_USER, LOG_I_DEBUG, + "user[%d]: AF_S_DONT_SEND", numofcon); + FD_CLR(ConnectUser_get_connFd(usersTable[numofcon]), &allset); + } + else { + aflog(LOG_T_USER, LOG_I_DEBUG, + "user[%d]: AF_S_DONT_SEND - ignored", numofcon); + } + break; + } + case AF_S_CAN_SEND: { + if ((ConnectUser_get_state(usersTable[numofcon]) == S_STATE_OPEN) || + (ConnectUser_get_state(usersTable[numofcon]) == S_STATE_STOPPED)) { + aflog(LOG_T_USER, LOG_I_DEBUG, + "user[%d]: AF_S_CAN_SEND", numofcon); + FD_SET(ConnectUser_get_connFd(usersTable[numofcon]), &allset); + } + else { + aflog(LOG_T_USER, LOG_I_DEBUG, + "user[%d]: AF_S_CAN_SEND - ignored", numofcon); + } + break; + } + default : { /* unrecognized type of message -> exiting... */ + aflog(LOG_T_CLIENT, LOG_I_ERR, + "SERVER: unrecognized message -> exiting... cg: %ld bytes", getcg()); + exit(1); + break; + } + } + } /* - FD_ISSET MASTER.COMMFD RSET */ + } +} -- cgit v1.1