summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am20
-rw-r--r--src/Makefile.in521
-rw-r--r--src/activefor.h97
-rw-r--r--src/afclient.c1500
-rw-r--r--src/afclient.h63
-rw-r--r--src/afserver.c2617
-rw-r--r--src/afserver.h57
-rw-r--r--src/ar_options_struct.c313
-rw-r--r--src/ar_options_struct.h59
-rw-r--r--src/audit_list_node_struct.c316
-rw-r--r--src/audit_list_node_struct.h58
-rw-r--r--src/audit_list_struct.c152
-rw-r--r--src/audit_list_struct.h41
-rw-r--r--src/base64.c250
-rw-r--r--src/base64.h41
-rw-r--r--src/buf_list_node_struct.c289
-rw-r--r--src/buf_list_node_struct.h50
-rw-r--r--src/buf_list_struct.c152
-rw-r--r--src/buf_list_struct.h41
-rw-r--r--src/client_configuration_struct.c336
-rw-r--r--src/client_configuration_struct.h58
-rw-r--r--src/client_initialization.c343
-rw-r--r--src/client_initialization.h42
-rw-r--r--src/client_realm_struct.c1205
-rw-r--r--src/client_realm_struct.h146
-rw-r--r--src/client_remoteadmin.c210
-rw-r--r--src/client_remoteadmin.h38
-rw-r--r--src/client_reverse_udp.c213
-rw-r--r--src/client_reverse_udp.h41
-rw-r--r--src/client_shutdown.c48
-rw-r--r--src/client_shutdown.h30
-rw-r--r--src/client_signals.c60
-rw-r--r--src/client_signals.h28
-rw-r--r--src/clientnames.c173
-rw-r--r--src/clientnames.h36
-rw-r--r--src/connect_client_struct.c863
-rw-r--r--src/connect_client_struct.h119
-rw-r--r--src/connect_user_struct.c398
-rw-r--r--src/connect_user_struct.h67
-rw-r--r--src/daemon.c73
-rw-r--r--src/daemon.h39
-rw-r--r--src/file.c117
-rw-r--r--src/file.h41
-rw-r--r--src/file_client.c281
-rw-r--r--src/file_server.c390
-rw-r--r--src/first_run.c403
-rw-r--r--src/first_run.h33
-rw-r--r--src/header_buffer_struct.c127
-rw-r--r--src/header_buffer_struct.h39
-rw-r--r--src/http_proxy_client.c565
-rw-r--r--src/http_proxy_client.h29
-rw-r--r--src/http_proxy_functions.c410
-rw-r--r--src/http_proxy_functions.h86
-rw-r--r--src/http_proxy_options_struct.c254
-rw-r--r--src/http_proxy_options_struct.h58
-rw-r--r--src/http_proxy_server.c585
-rw-r--r--src/http_proxy_server.h29
-rw-r--r--src/inet_ntop.c231
-rw-r--r--src/inet_ntop.h36
-rw-r--r--src/logging.c471
-rw-r--r--src/logging.h78
-rw-r--r--src/make_ssl_handshake.c139
-rw-r--r--src/make_ssl_handshake.h32
-rw-r--r--src/module_struct.c224
-rw-r--r--src/module_struct.h55
-rw-r--r--src/network.c561
-rw-r--r--src/network.h49
-rw-r--r--src/port_list_node_struct.c140
-rw-r--r--src/port_list_node_struct.h40
-rw-r--r--src/port_list_struct.c167
-rw-r--r--src/port_list_struct.h42
-rw-r--r--src/realmnames.c86
-rw-r--r--src/realmnames.h31
-rw-r--r--src/remoteadmin_codes.h32
-rw-r--r--src/remove_client_task.c134
-rw-r--r--src/remove_client_task.h47
-rw-r--r--src/server_check.c112
-rw-r--r--src/server_check.h29
-rw-r--r--src/server_configuration_struct.c421
-rw-r--r--src/server_configuration_struct.h67
-rw-r--r--src/server_eval.c123
-rw-r--r--src/server_eval.h32
-rw-r--r--src/server_find.c138
-rw-r--r--src/server_find.h32
-rw-r--r--src/server_get.c123
-rw-r--r--src/server_get.h31
-rw-r--r--src/server_realm_struct.c1471
-rw-r--r--src/server_realm_struct.h147
-rw-r--r--src/server_remoteadmin.c762
-rw-r--r--src/server_remoteadmin.h37
-rw-r--r--src/server_remove.c121
-rw-r--r--src/server_remove.h31
-rw-r--r--src/server_set.c48
-rw-r--r--src/server_set.h27
-rw-r--r--src/server_signals.c86
-rw-r--r--src/server_signals.h27
-rw-r--r--src/ssl_fd_struct.c329
-rw-r--r--src/ssl_fd_struct.h48
-rw-r--r--src/ssl_routines.c108
-rw-r--r--src/ssl_routines.h34
-rw-r--r--src/stats.c87
-rw-r--r--src/stats.h38
-rw-r--r--src/string_functions.c72
-rw-r--r--src/string_functions.h27
-rw-r--r--src/task_list_node_struct.c124
-rw-r--r--src/task_list_node_struct.h42
-rw-r--r--src/task_scheduler_struct.c321
-rw-r--r--src/task_scheduler_struct.h47
-rw-r--r--src/task_struct.c122
-rw-r--r--src/task_struct.h39
-rw-r--r--src/thread_management.c102
-rw-r--r--src/thread_management.h34
-rw-r--r--src/timeval_functions.c134
-rw-r--r--src/timeval_functions.h32
-rw-r--r--src/usage.c227
-rw-r--r--src/usage.h30
-rw-r--r--src/user_stats_struct.c391
-rw-r--r--src/user_stats_struct.h59
-rw-r--r--src/usernames.c63
-rw-r--r--src/usernames.h31
-rw-r--r--src/usr_cli_struct.c299
-rw-r--r--src/usr_cli_struct.h54
122 files changed, 24004 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..f16461a
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,20 @@
+bin_PROGRAMS = afserver afclient
+afserver_SOURCES = afserver.c network.c file.c stats.c buf_list_node_struct.c buf_list_struct.c \
+ server_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 http_proxy_functions.c http_proxy_server.c server_get.c \
+ thread_management.c server_signals.c usage.c logging.c daemon.c ssl_fd_struct.c \
+ user_stats_struct.c usr_cli_struct.c connect_user_struct.c string_functions.c \
+ audit_list_node_struct.c audit_list_struct.c connect_client_struct.c timeval_functions.c \
+ header_buffer_struct.c server_realm_struct.c server_configuration_struct.c file_server.c \
+ task_struct.c task_list_node_struct.c task_scheduler_struct.c remove_client_task.c
+afclient_LDFLAGS = ${USE_RDYNAMIC} ${LINKED_LDLIB}
+afclient_SOURCES = afclient.c network.c file.c stats.c buf_list_node_struct.c buf_list_struct.c \
+ module_struct.c client_remoteadmin.c make_ssl_handshake.c first_run.c inet_ntop.c \
+ http_proxy_functions.c http_proxy_client.c http_proxy_options_struct.c \
+ thread_management.c client_reverse_udp.c server_check.c client_initialization.c \
+ client_shutdown.c client_signals.c usage.c logging.c daemon.c base64.c ssl_routines.c \
+ connect_user_struct.c user_stats_struct.c string_functions.c ar_options_struct.c \
+ audit_list_node_struct.c audit_list_struct.c ssl_fd_struct.c timeval_functions.c \
+ usr_cli_struct.c header_buffer_struct.c client_configuration_struct.c file_client.c \
+ client_realm_struct.c port_list_node_struct.c port_list_struct.c
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..23a517c
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,521 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+bin_PROGRAMS = afserver$(EXEEXT) afclient$(EXEEXT)
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_afclient_OBJECTS = afclient.$(OBJEXT) network.$(OBJEXT) \
+ file.$(OBJEXT) stats.$(OBJEXT) buf_list_node_struct.$(OBJEXT) \
+ buf_list_struct.$(OBJEXT) module_struct.$(OBJEXT) \
+ client_remoteadmin.$(OBJEXT) make_ssl_handshake.$(OBJEXT) \
+ first_run.$(OBJEXT) inet_ntop.$(OBJEXT) \
+ http_proxy_functions.$(OBJEXT) http_proxy_client.$(OBJEXT) \
+ http_proxy_options_struct.$(OBJEXT) \
+ thread_management.$(OBJEXT) client_reverse_udp.$(OBJEXT) \
+ server_check.$(OBJEXT) client_initialization.$(OBJEXT) \
+ client_shutdown.$(OBJEXT) client_signals.$(OBJEXT) \
+ usage.$(OBJEXT) logging.$(OBJEXT) daemon.$(OBJEXT) \
+ base64.$(OBJEXT) ssl_routines.$(OBJEXT) \
+ connect_user_struct.$(OBJEXT) user_stats_struct.$(OBJEXT) \
+ string_functions.$(OBJEXT) ar_options_struct.$(OBJEXT) \
+ audit_list_node_struct.$(OBJEXT) audit_list_struct.$(OBJEXT) \
+ ssl_fd_struct.$(OBJEXT) timeval_functions.$(OBJEXT) \
+ usr_cli_struct.$(OBJEXT) header_buffer_struct.$(OBJEXT) \
+ client_configuration_struct.$(OBJEXT) file_client.$(OBJEXT) \
+ client_realm_struct.$(OBJEXT) port_list_node_struct.$(OBJEXT) \
+ port_list_struct.$(OBJEXT)
+afclient_OBJECTS = $(am_afclient_OBJECTS)
+afclient_LDADD = $(LDADD)
+am_afserver_OBJECTS = afserver.$(OBJEXT) network.$(OBJEXT) \
+ file.$(OBJEXT) stats.$(OBJEXT) buf_list_node_struct.$(OBJEXT) \
+ buf_list_struct.$(OBJEXT) server_remoteadmin.$(OBJEXT) \
+ server_check.$(OBJEXT) server_set.$(OBJEXT) \
+ server_eval.$(OBJEXT) server_find.$(OBJEXT) \
+ server_remove.$(OBJEXT) make_ssl_handshake.$(OBJEXT) \
+ first_run.$(OBJEXT) inet_ntop.$(OBJEXT) realmnames.$(OBJEXT) \
+ clientnames.$(OBJEXT) usernames.$(OBJEXT) \
+ http_proxy_functions.$(OBJEXT) http_proxy_server.$(OBJEXT) \
+ server_get.$(OBJEXT) thread_management.$(OBJEXT) \
+ server_signals.$(OBJEXT) usage.$(OBJEXT) logging.$(OBJEXT) \
+ daemon.$(OBJEXT) ssl_fd_struct.$(OBJEXT) \
+ user_stats_struct.$(OBJEXT) usr_cli_struct.$(OBJEXT) \
+ connect_user_struct.$(OBJEXT) string_functions.$(OBJEXT) \
+ audit_list_node_struct.$(OBJEXT) audit_list_struct.$(OBJEXT) \
+ connect_client_struct.$(OBJEXT) timeval_functions.$(OBJEXT) \
+ header_buffer_struct.$(OBJEXT) server_realm_struct.$(OBJEXT) \
+ server_configuration_struct.$(OBJEXT) file_server.$(OBJEXT) \
+ task_struct.$(OBJEXT) task_list_node_struct.$(OBJEXT) \
+ task_scheduler_struct.$(OBJEXT) remove_client_task.$(OBJEXT)
+afserver_OBJECTS = $(am_afserver_OBJECTS)
+afserver_LDADD = $(LDADD)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(afclient_SOURCES) $(afserver_SOURCES)
+DIST_SOURCES = $(afclient_SOURCES) $(afserver_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GREP = @GREP@
+HAVE_OPENSSL = @HAVE_OPENSSL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LINKED_LDLIB = @LINKED_LDLIB@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_RDYNAMIC = @USE_RDYNAMIC@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+afserver_SOURCES = afserver.c network.c file.c stats.c buf_list_node_struct.c buf_list_struct.c \
+ server_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 http_proxy_functions.c http_proxy_server.c server_get.c \
+ thread_management.c server_signals.c usage.c logging.c daemon.c ssl_fd_struct.c \
+ user_stats_struct.c usr_cli_struct.c connect_user_struct.c string_functions.c \
+ audit_list_node_struct.c audit_list_struct.c connect_client_struct.c timeval_functions.c \
+ header_buffer_struct.c server_realm_struct.c server_configuration_struct.c file_server.c \
+ task_struct.c task_list_node_struct.c task_scheduler_struct.c remove_client_task.c
+
+afclient_LDFLAGS = ${USE_RDYNAMIC} ${LINKED_LDLIB}
+afclient_SOURCES = afclient.c network.c file.c stats.c buf_list_node_struct.c buf_list_struct.c \
+ module_struct.c client_remoteadmin.c make_ssl_handshake.c first_run.c inet_ntop.c \
+ http_proxy_functions.c http_proxy_client.c http_proxy_options_struct.c \
+ thread_management.c client_reverse_udp.c server_check.c client_initialization.c \
+ client_shutdown.c client_signals.c usage.c logging.c daemon.c base64.c ssl_routines.c \
+ connect_user_struct.c user_stats_struct.c string_functions.c ar_options_struct.c \
+ audit_list_node_struct.c audit_list_struct.c ssl_fd_struct.c timeval_functions.c \
+ usr_cli_struct.c header_buffer_struct.c client_configuration_struct.c file_client.c \
+ client_realm_struct.c port_list_node_struct.c port_list_struct.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+afclient$(EXEEXT): $(afclient_OBJECTS) $(afclient_DEPENDENCIES)
+ @rm -f afclient$(EXEEXT)
+ $(LINK) $(afclient_LDFLAGS) $(afclient_OBJECTS) $(afclient_LDADD) $(LIBS)
+afserver$(EXEEXT): $(afserver_OBJECTS) $(afserver_DEPENDENCIES)
+ @rm -f afserver$(EXEEXT)
+ $(LINK) $(afserver_LDFLAGS) $(afserver_OBJECTS) $(afserver_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afclient.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/afserver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar_options_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audit_list_node_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audit_list_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/base64.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buf_list_node_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buf_list_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client_configuration_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client_initialization.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client_realm_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client_remoteadmin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client_reverse_udp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client_shutdown.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client_signals.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clientnames.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connect_client_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connect_user_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/daemon.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_client.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_server.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/first_run.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/header_buffer_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http_proxy_client.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http_proxy_functions.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http_proxy_options_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http_proxy_server.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inet_ntop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logging.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/make_ssl_handshake.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/module_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/network.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/port_list_node_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/port_list_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/realmnames.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/remove_client_task.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_check.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_configuration_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_eval.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_find.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_get.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_realm_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_remoteadmin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_remove.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_set.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_signals.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_fd_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_routines.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stats.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_functions.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/task_list_node_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/task_scheduler_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/task_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread_management.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timeval_functions.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/user_stats_struct.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usernames.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usr_cli_struct.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic ctags distclean distclean-compile \
+ distclean-generic distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-data install-data-am install-exec install-exec-am \
+ install-info install-info-am install-man install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-binPROGRAMS uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/activefor.h b/src/activefor.h
new file mode 100644
index 0000000..6a73c69
--- /dev/null
+++ b/src/activefor.h
@@ -0,0 +1,97 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_ACTIVEFOR_H
+#define _JS_ACTIVEFOR_H
+
+#include "network.h"
+#include "buf_list_struct.h"
+#include "audit_list_struct.h"
+#include "usr_cli_struct.h"
+#include "connect_user_struct.h"
+#include "ssl_fd_struct.h"
+#include "connect_client_struct.h"
+
+#define AF_S_CONCLOSED 1
+#define AF_S_CONOPEN 2
+#define AF_S_MESSAGE 3
+#define AF_S_CLOSING 4
+#define AF_S_LOGIN 8
+#define AF_S_DONT_SEND 9
+#define AF_S_CAN_SEND 10
+#define AF_S_CANT_OPEN 12
+#define AF_S_ENABLE_MULTI 18
+
+#define AF_S_WRONG 13
+#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 S_STATE_OPENING_CLOSED 17
+#define S_STATE_KICKING 19
+
+#define AF_VER(info) info" v0.8.4"
+
+#define TYPE_TCP 1
+#define TYPE_UDP 3
+#define TYPE_SSL 4
+#define TYPE_ZLIB 8
+#define TYPE_IPV4 16
+#define TYPE_IPV6 32
+#define TYPE_SUPPORTS_MULTI 64
+#define TYPE_COMP 0x4000
+
+#define TYPE_SET_ZERO(type) (type=0)
+#define TYPE_IS_SET(type) (type&1)
+#define TYPE_IS_UDP(type) TYPE_IS_SET(type)&&(type&2)
+#define TYPE_IS_TCP(type) TYPE_IS_SET(type)&&(!(type&2))
+#define TYPE_SET_UDP(type) (type|=TYPE_UDP)
+#define TYPE_SET_TCP(type) (type|=TYPE_TCP)
+#define TYPE_SET_SSL(type) (type|=TYPE_SSL)
+#define TYPE_UNSET_SSL(type) (type&=(~TYPE_SSL))
+#define TYPE_IS_SSL(type) (type&TYPE_SSL)
+#define TYPE_SET_ZLIB(type) (type|=TYPE_ZLIB)
+#define TYPE_UNSET_ZLIB(type) (type&=(~TYPE_ZLIB))
+#define TYPE_IS_ZLIB(type) (type&TYPE_ZLIB)
+
+#define TYPE_SET_IPV4(type) (type|=TYPE_IPV4)
+#define TYPE_UNSET_IPV4(type) (type&=(~TYPE_IPV4))
+#define TYPE_IS_IPV4(type) (type&TYPE_IPV4)
+#define TYPE_SET_IPV6(type) (type|=TYPE_IPV6)
+#define TYPE_UNSET_IPV6(type) (type&=(~TYPE_IPV6))
+#define TYPE_IS_IPV6(type) (type&TYPE_IPV6)
+#define TYPE_SET_UNSPEC(type) (type&=(~(TYPE_IPV4|TYPE_IPV6)))
+#define TYPE_IS_UNSPEC(type) (!(type&(TYPE_IPV4|TYPE_IPV6)))
+
+#define TYPE_SET_SUPPORTED_MULTI(type) (type|=TYPE_SUPPORTS_MULTI)
+#define TYPE_UNSET_SUPPORTED_MULTI(type) (type&=(~TYPE_SUPPORTS_MULTI))
+#define TYPE_IS_SUPPORTED_MULTI(type) (type&TYPE_SUPPORTS_MULTI)
+
+#define TYPE_SET_COMP(type) (type|=TYPE_COMP)
+#define TYPE_IS_COMP(type) (type&TYPE_COMP)
+
+#endif
+
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 <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 "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, &notsent)) {
+ 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, &notsent)) {
+ 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 */
+ }
+}
diff --git a/src/afclient.h b/src/afclient.h
new file mode 100644
index 0000000..1be222d
--- /dev/null
+++ b/src/afclient.h
@@ -0,0 +1,63 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "activefor.h"
+#include "network.h"
+#include "file.h"
+#include "stats.h"
+#include "module_struct.h"
+#include "client_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 "http_proxy_options_struct.h"
+#include "client_shutdown.h"
+#include "client_signals.h"
+#include "usage.h"
+#include "logging.h"
+#include "audit_list_struct.h"
+#include "daemon.h"
+#include "ar_options_struct.h"
+#include "port_list_struct.h"
+
+#include <openssl/rsa.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#ifdef HAVE_LINUX_SOCKIOS_H
+#include <linux/sockios.h>
+#endif
+#include <signal.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include <getopt.h>
+
+#ifndef _JS_AFCLIENT_H
+#define _JS_AFCLIENT_H
+
+#endif
+
diff --git a/src/afserver.c b/src/afserver.c
new file mode 100644
index 0000000..f509404
--- /dev/null
+++ b/src/afserver.c
@@ -0,0 +1,2617 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "afserver.h"
+
+static struct option long_options[] = {
+ {"help", 0, 0, 'h'},
+ {"hostname", 1, 0, 'n'},
+ {"listenport", 1, 0, 'l'},
+ {"manageport", 1, 0, 'm'},
+ {"timeout", 1, 0, 't'},
+ {"maxidle", 1, 0, 321},
+ {"verbose", 0, 0, 'v'},
+ {"users", 1, 0, 'u'},
+ {"clients", 1, 0, 'C'},
+ {"realm", 1, 0, 'r'},
+ {"raclients", 1, 0, 'R'},
+ {"usrpcli", 1, 0, 'U'},
+ {"climode", 1, 0, 'M'},
+ {"cerfile", 1, 0, 'c'},
+ {"cacerfile", 1, 0, 'A'},
+ {"cerdepth", 1, 0, 'd'},
+ {"keyfile", 1, 0, 'k'},
+ {"cfgfile", 1, 0, 'f'},
+ {"proto", 1, 0, 'p'},
+ {"log", 1, 0, 'o'},
+ {"audit", 0, 0, 'a'},
+ {"nossl", 0, 0, 301},
+ {"nozlib", 0, 0, 302},
+ {"pass", 1, 0, 303},
+#ifdef AF_INET6
+ {"ipv4", 0, 0, '4'},
+ {"ipv6", 0, 0, '6'},
+#endif
+ {"baseport", 0, 0, 'b'},
+ {"dnslookups", 0, 0, 311},
+ {"dateformat", 1, 0, 'D'},
+#ifdef HAVE_LIBPTHREAD
+ {"enableproxy", 0, 0, 'P'},
+ /* FIXME: don't need it now
+ {"use-https", 0, 0, 'S'},
+ */
+#endif
+ {"version", 0, 0, 'V'},
+ {0, 0, 0, 0}
+};
+
+ServerConfiguration* config;
+
+int
+main(int argc, char **argv)
+{
+ int i, j=0, k, l, n, flags, sent = 0, temp;
+ socklen_t len;
+ unsigned char buff[9000];
+ int maxfdp1;
+ fd_set rset, allset, wset, tmpset;
+ int numofcon, length;
+ char* name = NULL;
+ char** listen = NULL;
+ int listencount = 0;
+ char** manage = NULL;
+ int managecount = 0;
+ char* amount = NULL;
+ char* clients = NULL;
+ char* raclients = NULL;
+ char* usrpcli = NULL;
+ char* clim = NULL;
+ char* filenam = NULL;
+ char* type = NULL;
+ char* timeout = NULL;
+ char* maxidle = NULL;
+ char* realmname = NULL;
+ 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;
+ ServerRealm* pointer = NULL;
+ TaskScheduler* scheduler;
+ Task* task;
+ struct sigaction act;
+ time_t now;
+ ServerRealm** scRealmsTable;
+ UsrCli** srUsersClientsTable;
+ ConnectUser** srUsersTable;
+ ConnectClient** srClientsTable;
+ ConnectClient** srRaClientsTable;
+
+ char* certif = NULL;
+ char* cacertif = NULL;
+ char* cerdepth = NULL;
+ char* keys = NULL;
+ char* dateformat = NULL;
+ static char* stemp = NULL;
+
+ SSL_METHOD* method;
+ SSL_CTX* ctx;
+ SSL* tmp_ssl;
+
+ sigfillset(&(act.sa_mask));
+ act.sa_flags = 0;
+
+ act.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &act, NULL);
+ act.sa_handler = server_sig_int;
+ sigaction(SIGINT, &act, NULL);
+ sigaction(SIGTERM, &act, NULL);
+
+ TYPE_SET_SSL(mode);
+ TYPE_SET_ZLIB(mode);
+ TYPE_SET_SUPPORTED_MULTI(mode);
+
+#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
+/* FIXME: 'S' option is not needed now
+#define GETOPT_LONG_LIBPTHREAD(x) "PS"x
+*/
+#define GETOPT_LONG_LIBPTHREAD(x) "P"x
+#else
+#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:A:d:k:f:p:o:t:C:U:M:abD:R:r:V"))
+ , long_options, 0)) != -1) {
+ switch (n) {
+ case 'h': {
+ server_long_usage(AF_VER("Active port forwarder (server)"));
+ break;
+ }
+ case 'n': {
+ name = optarg;
+ break;
+ }
+ case 'l': {
+ ++listencount;
+ listen = realloc(listen, sizeof(char*));
+ listen[listencount-1] = optarg;
+ break;
+ }
+ case 'm': {
+ ++managecount;
+ manage = realloc(manage, sizeof(char*));
+ manage[managecount-1] = optarg;
+ break;
+ }
+ case 't': {
+ timeout = optarg;
+ break;
+ }
+ case 321: {
+ maxidle = optarg;
+ break;
+ }
+ case 'v': {
+ ++verbose;
+ break;
+ }
+ case 'u': {
+ amount = optarg;
+ break;
+ }
+ case 'C': {
+ clients = optarg;
+ break;
+ }
+ case 'r': {
+ realmname = optarg;
+ break;
+ }
+ case 'R': {
+ raclients = optarg;
+ break;
+ }
+ case 'U': {
+ usrpcli = optarg;
+ break;
+ }
+ case 'M': {
+ clim = optarg;
+ break;
+ }
+ case 'c': {
+ certif = optarg;
+ break;
+ }
+ case 'A': {
+ cacertif = optarg;
+ break;
+ }
+ case 'd': {
+ cerdepth = optarg;
+ break;
+ }
+ case 'k': {
+ keys = optarg;
+ break;
+ }
+ case 'p': {
+ type = optarg;
+ break;
+ }
+ case 'f': {
+ filenam = optarg;
+ break;
+ }
+ case 'o': {
+ addlogtarget(optarg);
+ break;
+ }
+ case 301: {
+ TYPE_UNSET_SSL(mode);
+ break;
+ }
+ case 302: {
+ TYPE_UNSET_ZLIB(mode);
+ break;
+ }
+ case 303: {
+ n = strlen(optarg);
+ memset(pass, 0, 4);
+ for (i = 0; i < n; ++i) {
+ pass[i%4] += optarg[i];
+ }
+ sent = 1;
+ break;
+ }
+#ifdef AF_INET6
+ case '4': {
+ if (ipfam != 0) {
+ ipfam = -1;
+ }
+ else {
+ ipfam = 4;
+ }
+ break;
+ }
+ case '6': {
+ if (ipfam != 0) {
+ ipfam = -1;
+ }
+ else {
+ ipfam = 6;
+ }
+ break;
+ }
+#endif
+ case 'b': {
+ baseport = 1;
+ break;
+ }
+ case 'a': {
+ audit = 1;
+ break;
+ }
+ case 311: {
+ dnslookups = 1;
+ break;
+ }
+ case 'D': {
+ dateformat = optarg;
+ break;
+ }
+#ifdef HAVE_LIBPTHREAD
+ case 'P': {
+ if ((tunneltype < 0) || (tunneltype > 2)) {
+ tunneltype = -1;
+ }
+ else {
+ if (tunneltype != 2) {
+ tunneltype = 1;
+ }
+ }
+ break;
+ }
+ /* FIXME: don't need it now
+ case 'S': {
+ if ((tunneltype < 0) || (tunneltype > 2)) {
+ tunneltype = -1;
+ }
+ else {
+ tunneltype = 2;
+ }
+ break;
+ }
+ */
+#endif
+ case 'V': {
+ printf("%s\n", (AF_VER("Active port forwarder (server)")));
+ exit(0);
+ break;
+ }
+ case '?': {
+ server_short_usage("");
+ break;
+ }
+ }
+ }
+
+ if (optind < argc) {
+ server_short_usage("Unrecognized non-option elements");
+ }
+
+ if (filenam != NULL) {
+ config = parsefile(filenam, &n);
+ if (n) {
+ printf("parsing failed! line:%d\n", n);
+ exit(1);
+ }
+ else {
+ if (certif == NULL) {
+ if (ServerConfiguration_get_certificateFile(config) == NULL) {
+ ServerConfiguration_set_certificateFile(config, "server-cert.pem");
+ }
+ }
+ else {
+ ServerConfiguration_set_certificateFile(config, certif);
+ }
+ if (cacertif != NULL) {
+ ServerConfiguration_set_cacertificateFile(config, cacertif);
+ }
+ if (cerdepth != NULL) {
+ ServerConfiguration_set_sCertificateDepth(config, cerdepth);
+ }
+ if (keys == NULL) {
+ if (ServerConfiguration_get_keysFile(config) == NULL) {
+ ServerConfiguration_set_keysFile(config, "server.rsa");
+ }
+ }
+ else {
+ ServerConfiguration_set_keysFile(config, keys);
+ }
+ if (dateformat != NULL) {
+ ServerConfiguration_set_dateFormat(config, dateformat);
+ }
+
+ initializelogging(verbose, ServerConfiguration_get_dateFormat(config));
+
+ aflog(LOG_T_INIT, LOG_I_INFO,
+ "cfg file OK! (readed realms: %d)", ServerConfiguration_get_realmsNumber(config));
+ if (name != NULL)
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: hostname=%s will be ignored", name);
+ if (listen != NULL)
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: listenport will be ignored");
+ if (manage != NULL)
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: manageport will be ignored");
+ if (realmname != NULL)
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: realmname=%s will be ignored", realmname);
+ if (sent == 1)
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: password from command line will be ignored");
+ }
+ }
+ else {
+ config = ServerConfiguration_new();
+ if (config == NULL) {
+ printf("Can't allocate memory for server configuration... exiting\n");
+ exit(1);
+ }
+ ServerConfiguration_set_certificateFile(config, certif);
+ ServerConfiguration_set_cacertificateFile(config, cacertif);
+ ServerConfiguration_set_sCertificateDepth(config, cerdepth);
+ ServerConfiguration_set_keysFile(config, keys);
+ ServerConfiguration_set_dateFormat(config, dateformat);
+
+ initializelogging(verbose, ServerConfiguration_get_dateFormat(config));
+
+ if (listen == NULL) {
+ listencount = 1;
+ listen = calloc(1, sizeof(char*));
+ listen[0] = "50127";
+ }
+ if (manage == NULL) {
+ managecount = 1;
+ manage = calloc(1, sizeof(char*));
+ manage[0] = "50126";
+ }
+ if (managecount != listencount) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Number of listen and manage options are not the same... exiting");
+ exit(1);
+ }
+ if (ServerConfiguration_get_certificateFile(config) == NULL) {
+ ServerConfiguration_set_certificateFile(config, "server-cert.pem");
+ }
+ if (ServerConfiguration_get_keysFile(config) == NULL) {
+ ServerConfiguration_set_keysFile(config, "server.rsa");
+ }
+ if (type == NULL) {
+ type = "tcp";
+ }
+ ServerConfiguration_set_realmsNumber(config, 1);
+ scRealmsTable = calloc(1, sizeof(ServerRealm*));
+ if (scRealmsTable == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Problem with allocating memory for ServerRealm* table... exiting");
+ exit(1);
+ }
+ ServerConfiguration_set_realmsTable(config, scRealmsTable);
+ pointer = ServerRealm_new();
+ if (pointer == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Problem with allocating memory for ServerRealm structure... exiting");
+ exit(1);
+ }
+ scRealmsTable[0] = pointer;
+ ServerRealm_set_hostName(pointer, name);
+ ServerRealm_set_userClientPairs(pointer, managecount);
+ srUsersClientsTable = calloc(managecount, sizeof(UsrCli*));
+ if (srUsersClientsTable == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Problem with allocating memory for UsrCli* table... exiting");
+ exit(1);
+ }
+ ServerRealm_set_usersClientsTable(pointer, srUsersClientsTable);
+ for (i = 0; i < managecount; ++i) {
+ srUsersClientsTable[i] = UsrCli_new();
+ if (srUsersClientsTable[i] == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Problem with allocating memory for UsrCli structure... exiting");
+ exit(1);
+ }
+ UsrCli_set_listenPortName(srUsersClientsTable[i], listen[i]);
+ UsrCli_set_managePortName(srUsersClientsTable[i], manage[i]);
+ }
+ ServerRealm_set_sUsersLimit(pointer, amount);
+ ServerRealm_set_sClientsLimit(pointer, clients);
+ ServerRealm_set_sRaClientsLimit(pointer, raclients);
+ ServerRealm_set_sTimeout(pointer, timeout);
+ ServerRealm_set_sMaxIdle(pointer, maxidle);
+ ServerRealm_set_sUsersPerClient(pointer, usrpcli);
+ ServerRealm_set_sClientMode(pointer, clim);
+ ServerRealm_set_basePortOn(pointer, baseport);
+ ServerRealm_set_auditOn(pointer, audit);
+#ifdef HAVE_LIBPTHREAD
+ ServerRealm_set_tunnelType(pointer, tunneltype);
+#endif
+ ServerRealm_set_dnsLookupsOn(pointer, dnslookups);
+ ServerRealm_set_realmName(pointer, realmname);
+ ServerRealm_set_password(pointer, pass);
+ if (strcmp(type, "tcp") == 0) {
+ temp = ServerRealm_get_realmType(pointer);
+ TYPE_SET_TCP(temp);
+ ServerRealm_set_realmType(pointer, temp);
+ }
+ else if (strcmp(type, "udp") == 0) {
+ temp = ServerRealm_get_realmType(pointer);
+ TYPE_SET_UDP(temp);
+ ServerRealm_set_realmType(pointer, temp);
+ }
+ else {
+ temp = ServerRealm_get_realmType(pointer);
+ TYPE_SET_ZERO(temp);
+ ServerRealm_set_realmType(pointer, temp);
+ }
+#ifdef AF_INET6
+ if (ipfam == -1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Conflicting types of ip protocol family... exiting");
+ exit(1);
+ }
+ else if (ipfam == 4) {
+ temp = ServerRealm_get_realmType(pointer);
+ TYPE_SET_IPV4(temp);
+ ServerRealm_set_realmType(pointer, temp);
+ }
+ else if (ipfam == 6) {
+ temp = ServerRealm_get_realmType(pointer);
+ TYPE_SET_IPV6(temp);
+ ServerRealm_set_realmType(pointer, temp);
+ }
+#endif
+ temp = ServerRealm_get_realmType(pointer);
+ temp |= mode;
+ ServerRealm_set_realmType(pointer, temp);
+ }
+
+ maxfdp1 = 0;
+
+ SSL_library_init();
+ method = SSLv3_server_method();
+ ctx = SSL_CTX_new(method);
+ if (SSL_CTX_set_cipher_list(ctx, "ALL:@STRENGTH") == 0) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Setting ciphers list failed... exiting");
+ exit(1);
+ }
+ if ((flags = create_apf_dir(0))) {
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: Creating ~/.apf directory failed (%d)", flags);
+ if ((flags = create_apf_dir(1))) {
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: Creating ./apf directory failed (%d)", flags);
+ }
+ }
+ keys = ServerConfiguration_get_keysFile(config);
+ if ((flags = generate_rsa_key(&keys))) {
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: Something bad happened when generating rsa keys... (%d)", flags);
+ }
+ ServerConfiguration_set_keysFile(config, keys);
+ if (SSL_CTX_use_RSAPrivateKey_file(ctx, ServerConfiguration_get_keysFile(config), SSL_FILETYPE_PEM) != 1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Setting rsa key failed (%s)... exiting", ServerConfiguration_get_keysFile(config));
+ exit(1);
+ }
+ certif = ServerConfiguration_get_certificateFile(config);
+ if ((flags = generate_certificate(&certif, ServerConfiguration_get_keysFile(config)))) {
+ aflog(LOG_T_INIT, LOG_I_WARNING,
+ "Warning: Something bad happened when generating certificate... (%d)", flags);
+ }
+ ServerConfiguration_set_certificateFile(config, certif);
+ if (SSL_CTX_use_certificate_file(ctx,
+ ServerConfiguration_get_certificateFile(config), SSL_FILETYPE_PEM) != 1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Setting certificate failed (%s)... exiting", ServerConfiguration_get_certificateFile(config));
+ exit(1);
+ }
+
+ cacertif = ServerConfiguration_get_cacertificateFile(config);
+ if (cacertif) {
+ if (SSL_CTX_load_verify_locations(ctx,
+ cacertif,
+ NULL)
+ != 1)
+ {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Setting CA certificate failed (%s)... exiting", cacertif);
+ exit(1);
+ }
+
+ SSL_CTX_set_verify (ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+ NULL);
+
+ cerdepth = ServerConfiguration_get_sCertificateDepth (config);
+ if (cerdepth == NULL) {
+ cerdepth = "9";
+ }
+ SSL_CTX_set_verify_depth(ctx, check_value_liberal (cerdepth, "Invalid max certificate-depth"));
+ }
+
+ if (ServerConfiguration_get_realmsNumber(config) == 0) {
+ 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);
+
+ scheduler = TaskScheduler_new();
+ if (scheduler == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Problems with creating task scheduler... exiting");
+ exit(1);
+ }
+
+ scRealmsTable = ServerConfiguration_get_realmsTable(config);
+ for (i = 0; i < ServerConfiguration_get_realmsNumber(config); ++i) {
+ if (ServerRealm_get_userClientPairs(scRealmsTable[i]) == 0) {
+ 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);
+ }
+ srUsersClientsTable = ServerRealm_get_usersClientsTable(scRealmsTable[i]);
+ for (j = 0; j < ServerRealm_get_userClientPairs(scRealmsTable[i]); ++j) {
+ if ((UsrCli_get_listenPortName(srUsersClientsTable[j]) == NULL) ||
+ (UsrCli_get_managePortName(srUsersClientsTable[j]) == NULL)) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Missing some of the variables...\nRealm: %d\nlistenport[%d]: %s\nmanageport[%d]: %s",
+ i, j, UsrCli_get_listenPortName(srUsersClientsTable[j]),
+ j, UsrCli_get_managePortName(srUsersClientsTable[j]));
+ exit(1);
+ }
+ }
+ /* checking type of the realm */
+ if (!TYPE_IS_SET(ServerRealm_get_realmType(scRealmsTable[i]))) {
+ if (type != NULL) {
+ if (strcmp(type, "tcp") == 0) {
+ temp = ServerRealm_get_realmType(scRealmsTable[i]);
+ TYPE_SET_TCP(temp);
+ ServerRealm_set_realmType(scRealmsTable[i], temp);
+ }
+ else if (strcmp(type, "udp") == 0) {
+ temp = ServerRealm_get_realmType(scRealmsTable[i]);
+ TYPE_SET_UDP(temp);
+ ServerRealm_set_realmType(scRealmsTable[i], temp);
+ }
+ else {
+ temp = ServerRealm_get_realmType(scRealmsTable[i]);
+ TYPE_SET_TCP(temp);
+ ServerRealm_set_realmType(scRealmsTable[i], temp);
+ }
+ }
+ else {
+ temp = ServerRealm_get_realmType(scRealmsTable[i]);
+ TYPE_SET_TCP(temp);
+ ServerRealm_set_realmType(scRealmsTable[i], temp);
+ }
+ }
+#ifdef AF_INET6
+ /* using user's value for ipfam*/
+ if (TYPE_IS_UNSPEC(ServerRealm_get_realmType(scRealmsTable[i]))) {
+ if (ipfam == -1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Conflicting types of ip protocol family... exiting");
+ exit(1);
+ }
+ else if (ipfam == 4) {
+ temp = ServerRealm_get_realmType(scRealmsTable[i]);
+ TYPE_SET_IPV4(temp);
+ ServerRealm_set_realmType(scRealmsTable[i], temp);
+ }
+ else if (ipfam == 6) {
+ temp = ServerRealm_get_realmType(scRealmsTable[i]);
+ TYPE_SET_IPV6(temp);
+ ServerRealm_set_realmType(scRealmsTable[i], temp);
+ }
+ }
+#endif
+ /* using user's values for zlib and ssl mode*/
+ if (!TYPE_IS_SSL(mode)) {
+ temp = ServerRealm_get_realmType(scRealmsTable[i]);
+ TYPE_UNSET_SSL(temp);
+ ServerRealm_set_realmType(scRealmsTable[i], temp);
+ }
+ if (!TYPE_IS_ZLIB(mode)) {
+ temp = ServerRealm_get_realmType(scRealmsTable[i]);
+ TYPE_UNSET_ZLIB(temp);
+ ServerRealm_set_realmType(scRealmsTable[i], temp);
+ }
+ /* using user's baseport value*/
+ if (ServerRealm_get_basePortOn(scRealmsTable[i]) == 0) {
+ ServerRealm_set_basePortOn(scRealmsTable[i], baseport);
+ }
+ /* using user's audit value*/
+ if (ServerRealm_get_auditOn(scRealmsTable[i]) == 0) {
+ ServerRealm_set_auditOn(scRealmsTable[i], audit);
+ }
+#ifdef HAVE_LIBPTHREAD
+ /* using user's tunneltype value*/
+ if (ServerRealm_get_tunnelType(scRealmsTable[i]) == 0) {
+ if (tunneltype == -1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Conflicting types of tunnel type... exiting");
+ exit(1);
+ }
+ ServerRealm_set_tunnelType(scRealmsTable[i], tunneltype);
+ }
+#endif
+ /* using user's dnslookups value*/
+ if (ServerRealm_get_dnsLookupsOn(scRealmsTable[i]) == 0) {
+ ServerRealm_set_dnsLookupsOn(scRealmsTable[i], dnslookups);
+ }
+ /* checking users amount */
+ stemp = ServerRealm_get_sUsersLimit(scRealmsTable[i]);
+ set_value(&stemp, amount, "5");
+ ServerRealm_set_sUsersLimit(scRealmsTable[i], stemp);
+ ServerRealm_set_usersLimit(scRealmsTable[i],
+ check_value(ServerRealm_get_sUsersLimit(scRealmsTable[i]), "Invalid users amount"));
+ /* checking clients amount */
+ stemp = ServerRealm_get_sClientsLimit(scRealmsTable[i]);
+ set_value(&stemp, clients, "1");
+ ServerRealm_set_sClientsLimit(scRealmsTable[i], stemp);
+ ServerRealm_set_clientsLimit(scRealmsTable[i],
+ check_value(ServerRealm_get_sClientsLimit(scRealmsTable[i]), "Invalid clients amount"));
+ /* checking raclients amount */
+ stemp = ServerRealm_get_sRaClientsLimit(scRealmsTable[i]);
+ set_value(&stemp, raclients, "1");
+ ServerRealm_set_sRaClientsLimit(scRealmsTable[i], stemp);
+ ServerRealm_set_raClientsLimit(scRealmsTable[i],
+ check_value(ServerRealm_get_sRaClientsLimit(scRealmsTable[i]), "Invalid raclients amount"));
+ /* checking usrpcli value */
+ stemp = ServerRealm_get_sUsersPerClient(scRealmsTable[i]);
+ set_value(&stemp, usrpcli, ServerRealm_get_sUsersLimit(scRealmsTable[i]));
+ ServerRealm_set_sUsersPerClient(scRealmsTable[i], stemp);
+ ServerRealm_set_usersPerClient(scRealmsTable[i],
+ check_value(ServerRealm_get_sUsersPerClient(scRealmsTable[i]), "Invalid usrpcli value"));
+ /* checking timeout value */
+ stemp = ServerRealm_get_sTimeout(scRealmsTable[i]);
+ set_value(&stemp, timeout, "5");
+ ServerRealm_set_sTimeout(scRealmsTable[i], stemp);
+ ServerRealm_set_timeout(scRealmsTable[i],
+ check_value(ServerRealm_get_sTimeout(scRealmsTable[i]), "Invalid timeout value"));
+ /* checking maxidle value */
+ stemp = ServerRealm_get_sMaxIdle(scRealmsTable[i]);
+ set_value(&stemp, maxidle, "0");
+ ServerRealm_set_sMaxIdle(scRealmsTable[i], stemp);
+ temp = check_value_liberal(ServerRealm_get_sMaxIdle(scRealmsTable[i]), "Invalid maxidle value");
+ if (temp < 0) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Invalid maxidle value: %d\n", temp);
+ exit(1);
+ }
+ ServerRealm_set_maxIdle(scRealmsTable[i], temp);
+ /* checking climode value */
+ stemp = ServerRealm_get_sClientMode(scRealmsTable[i]);
+ set_value(&stemp, clim, "1");
+ ServerRealm_set_sClientMode(scRealmsTable[i], stemp);
+ ServerRealm_set_clientMode(scRealmsTable[i],
+ check_value(ServerRealm_get_sClientMode(scRealmsTable[i]), "Invalid climode value"));
+ /* allocating memory*/
+ srUsersTable = calloc(ServerRealm_get_usersLimit(scRealmsTable[i]), sizeof(ConnectUser*));
+ if (srUsersTable == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Calloc error - try define smaller amount of users");
+ exit(1);
+ }
+ ServerRealm_set_usersTable(scRealmsTable[i], srUsersTable);
+ for (j = 0; j < ServerRealm_get_usersLimit(scRealmsTable[i]); ++j) {
+ srUsersTable[j] = ConnectUser_new();
+ if (srUsersTable[j] == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Calloc error - try define smaller amount of users");
+ exit(1);
+ }
+ }
+ srClientsTable = calloc(ServerRealm_get_clientsLimit(scRealmsTable[i]), sizeof(ConnectClient*));
+ if (srClientsTable == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Calloc error - try define smaller amount of clients");
+ exit(1);
+ }
+ ServerRealm_set_clientsTable(scRealmsTable[i], srClientsTable);
+ for (j = 0; j < ServerRealm_get_clientsLimit(scRealmsTable[i]); ++j) {
+ srClientsTable[j] = ConnectClient_new();
+ if (srClientsTable[j] == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Calloc error - try define smaller amount of clients");
+ exit(1);
+ }
+ }
+ srRaClientsTable = calloc(ServerRealm_get_raClientsLimit(scRealmsTable[i]), sizeof(ConnectClient*));
+ if (srRaClientsTable == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Calloc error - try define smaller amount of raclients");
+ exit(1);
+ }
+ ServerRealm_set_raClientsTable(scRealmsTable[i], srRaClientsTable);
+ for (j = 0; j < ServerRealm_get_raClientsLimit(scRealmsTable[i]); ++j) {
+ srRaClientsTable[j] = ConnectClient_new();
+ if (srRaClientsTable[j] == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Calloc error - try define smaller amount of raclients");
+ exit(1);
+ }
+ }
+ ipfam = 0x01;
+#ifdef AF_INET6
+ if (TYPE_IS_IPV4(ServerRealm_get_realmType(scRealmsTable[i]))) {
+ ipfam |= 0x02;
+ }
+ else if (TYPE_IS_IPV6(ServerRealm_get_realmType(scRealmsTable[i]))) {
+ ipfam |= 0x04;
+ }
+#endif
+ if (ServerRealm_get_basePortOn(scRealmsTable[i]) == 0) {
+ for (j = 0; j < ServerRealm_get_userClientPairs(scRealmsTable[i]); ++j) {
+ if (ip_listen(&temp, UsrCli_get_listenHostName(srUsersClientsTable[j]) ?
+ UsrCli_get_listenHostName(srUsersClientsTable[j]) :
+ ServerRealm_get_hostName(scRealmsTable[i]),
+ UsrCli_get_listenPortName(srUsersClientsTable[j]),
+ (&len), 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",
+#else
+ "tcp_listen error for %s, %s",
+#endif
+ UsrCli_get_listenHostName(srUsersClientsTable[j]) ?
+ UsrCli_get_listenHostName(srUsersClientsTable[j]) :
+ ServerRealm_get_hostName(scRealmsTable[i]),
+ UsrCli_get_listenPortName(srUsersClientsTable[j]));
+ exit(1);
+ }
+ ServerRealm_set_addressLength(scRealmsTable[i], len);
+ UsrCli_set_listenFd(srUsersClientsTable[j], temp);
+ flags = fcntl(UsrCli_get_listenFd(srUsersClientsTable[j]), F_GETFL, 0);
+ fcntl(UsrCli_get_listenFd(srUsersClientsTable[j]), F_SETFL, flags | O_NONBLOCK);
+ }
+ }
+
+ for (j = 0; j < ServerRealm_get_userClientPairs(scRealmsTable[i]); ++j) {
+ switch (ServerRealm_get_tunnelType(scRealmsTable[i])) {
+ case 0: {
+ temp = find_previousFd(srUsersClientsTable, j,
+ UsrCli_get_manageHostName(srUsersClientsTable[j]),
+ UsrCli_get_managePortName(srUsersClientsTable[j]));
+ if (temp == -1) {
+ if (ip_listen(&temp, UsrCli_get_manageHostName(srUsersClientsTable[j]) ?
+ UsrCli_get_manageHostName(srUsersClientsTable[j]) :
+ ServerRealm_get_hostName(scRealmsTable[i]),
+ UsrCli_get_managePortName(srUsersClientsTable[j]),
+ (&len), 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",
+#else
+ "tcp_listen error for %s, %s",
+#endif
+ UsrCli_get_manageHostName(srUsersClientsTable[j]) ?
+ UsrCli_get_manageHostName(srUsersClientsTable[j]) :
+ ServerRealm_get_hostName(scRealmsTable[i]),
+ UsrCli_get_managePortName(srUsersClientsTable[j]));
+ exit(1);
+ }
+ }
+ ServerRealm_set_addressLength(scRealmsTable[i], len);
+ UsrCli_set_manageFd(srUsersClientsTable[j], temp);
+ flags = fcntl(UsrCli_get_manageFd(srUsersClientsTable[j]), F_GETFL, 0);
+ fcntl(UsrCli_get_manageFd(srUsersClientsTable[j]), F_SETFL, flags | O_NONBLOCK);
+ UsrCli_set_number(srUsersClientsTable[j], eval_UsrCliPair(srUsersClientsTable, j,
+ UsrCli_get_manageHostName(srUsersClientsTable[j]),
+ UsrCli_get_managePortName(srUsersClientsTable[j])));
+ break;
+ }
+#ifdef HAVE_LIBPTHREAD
+ case 1:
+ case 2: {
+ temp = find_previousFd(srUsersClientsTable, j,
+ UsrCli_get_manageHostName(srUsersClientsTable[j]),
+ UsrCli_get_managePortName(srUsersClientsTable[j]));
+ if (temp == -1) {
+ if (initialize_http_proxy_server(&temp,
+ UsrCli_get_manageHostName(srUsersClientsTable[j]) ?
+ UsrCli_get_manageHostName(srUsersClientsTable[j]) :
+ ServerRealm_get_hostName(scRealmsTable[i]),
+ UsrCli_get_managePortName(srUsersClientsTable[j]),
+ (&len), ipfam,
+ ServerRealm_get_clientsLimit(scRealmsTable[i]) +
+ ServerRealm_get_raClientsLimit(scRealmsTable[i]),
+ (ServerRealm_get_tunnelType(scRealmsTable[i]) - 1),
+ ctx)) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+#ifdef AF_INET6
+ "http%s_proxy_listen_%s error for %s, %s",
+ (ServerRealm_get_tunnelType(scRealmsTable[i]) == 2) ? "s" : "",
+ (ipfam & 0x02)?"ipv4":(ipfam & 0x04)?"ipv6":"unspec",
+#else
+ "http%s_proxy_listen error for %s, %s",
+ (ServerRealm_get_tunnelType(scRealmsTable[i]) == 2) ? "s" : "",
+#endif
+ UsrCli_get_manageHostName(srUsersClientsTable[j]) ?
+ UsrCli_get_manageHostName(srUsersClientsTable[j]) :
+ ServerRealm_get_hostName(scRealmsTable[i]),
+ UsrCli_get_managePortName(srUsersClientsTable[j]));
+ exit(1);
+ }
+ }
+ ServerRealm_set_addressLength(scRealmsTable[i], len);
+ UsrCli_set_manageFd(srUsersClientsTable[j], temp);
+ flags = fcntl(UsrCli_get_manageFd(srUsersClientsTable[j]), F_GETFL, 0);
+ fcntl(UsrCli_get_manageFd(srUsersClientsTable[j]), F_SETFL, flags | O_NONBLOCK);
+ UsrCli_set_number(srUsersClientsTable[j], eval_UsrCliPair(srUsersClientsTable, j,
+ UsrCli_get_manageHostName(srUsersClientsTable[j]),
+ UsrCli_get_managePortName(srUsersClientsTable[j])));
+ break;
+ }
+#endif
+ default: {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Unknown tunnel type");
+ exit(1);
+ break;
+ }
+ }
+ }
+
+ ServerRealm_set_clientAddress(scRealmsTable[i], malloc(ServerRealm_get_addressLength(scRealmsTable[i])));
+ if (ServerRealm_get_clientAddress(scRealmsTable[i]) == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Allocating memory for client addresses failed... exiting");
+ exit(1);
+ }
+
+ for (j = 0; j < ServerRealm_get_clientsLimit(scRealmsTable[i]); ++j) {
+ SslFd_set_ssl(ConnectClient_get_sslFd(srClientsTable[j]), SSL_new(ctx));
+ if (SslFd_get_ssl(ConnectClient_get_sslFd(srClientsTable[j])) == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Creation of ssl object failed... exiting");
+ exit(1);
+ }
+ }
+
+ for (j = 0; j < ServerRealm_get_raClientsLimit(scRealmsTable[i]); ++j) {
+ SslFd_set_ssl(ConnectClient_get_sslFd(srRaClientsTable[j]), SSL_new(ctx));
+ if (SslFd_get_ssl(ConnectClient_get_sslFd(srRaClientsTable[j])) == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Creation of ssl object failed... exiting");
+ exit(1);
+ }
+ }
+
+ for (j = 0; j < ServerRealm_get_userClientPairs(scRealmsTable[i]); ++j) {
+ FD_SET(UsrCli_get_manageFd(srUsersClientsTable[j]), &allset);
+ maxfdp1 = (maxfdp1 > (UsrCli_get_manageFd(srUsersClientsTable[j]) + 1)) ?
+ maxfdp1 : (UsrCli_get_manageFd(srUsersClientsTable[j]) + 1);
+ }
+ if (ServerRealm_get_basePortOn(scRealmsTable[i]) == 0) {
+ for (j = 0; j < ServerRealm_get_userClientPairs(scRealmsTable[i]); ++j) {
+ FD_SET(UsrCli_get_listenFd(srUsersClientsTable[j]), &allset);
+ maxfdp1 = (maxfdp1 > (UsrCli_get_listenFd(srUsersClientsTable[j]) + 1)) ?
+ maxfdp1 : (UsrCli_get_listenFd(srUsersClientsTable[j]) + 1);
+ }
+ }
+ ServerRealm_set_connectedUsers(scRealmsTable[i], 0);
+ ServerRealm_set_connectedClients(scRealmsTable[i], 0);
+ ServerRealm_set_connectedRaClients(scRealmsTable[i], 0);
+ for (j = 0; j < ServerRealm_get_clientsLimit(scRealmsTable[i]); ++j) {
+ ConnectClient_set_timer(srClientsTable[j], timeval_create(ServerRealm_get_timeout(scRealmsTable[i]), 0));
+ ConnectClient_set_limit(srClientsTable[j], ServerRealm_get_usersPerClient(scRealmsTable[i]));
+ if (ConnectClient_create_users(srClientsTable[j])) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Calloc error - try define smaller amount of usrpcli (or users)");
+ exit(1);
+ }
+ }
+ for (j = 0; j < ServerRealm_get_raClientsLimit(scRealmsTable[i]); ++j) {
+ ConnectClient_set_timer(srRaClientsTable[j],
+ timeval_create(ServerRealm_get_timeout(scRealmsTable[i]), 0));
+ }
+ }
+
+ aflog(LOG_T_MAIN, LOG_I_INFO,
+ "SERVER STARTED realms: %d", ServerConfiguration_get_realmsNumber(config));
+ time(&now);
+ ServerConfiguration_set_startTime(config, now);
+
+ for ( ; ; ) {
+ rset = allset;
+ tmpset = wset;
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "select, maxfdp1: %d", maxfdp1);
+ if (TaskScheduler_hasMoreTasks(scheduler)) {
+ TaskScheduler_startWatching(scheduler);
+ select(maxfdp1, &rset, &tmpset, NULL, TaskScheduler_get_actualTimer(scheduler));
+ TaskScheduler_stopWatching(scheduler);
+ }
+ else {
+ select(maxfdp1, &rset, &tmpset, NULL, NULL);
+ }
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "after select...");
+
+ for (j = 0; j < ServerConfiguration_get_realmsNumber(config); ++j) {
+ pointer = scRealmsTable[j];
+ srUsersTable = ServerRealm_get_usersTable(pointer);
+ srClientsTable = ServerRealm_get_clientsTable(pointer);
+ srRaClientsTable = ServerRealm_get_raClientsTable(pointer);
+ srUsersClientsTable = ServerRealm_get_usersClientsTable(pointer);
+ for (i = 0; i < ServerRealm_get_usersLimit(pointer); ++i) {
+ if ((ConnectUser_get_state(srUsersTable[i]) == S_STATE_OPEN) ||
+ (ConnectUser_get_state(srUsersTable[i]) == S_STATE_STOPPED) ||
+ (ConnectUser_get_state(srUsersTable[i]) == S_STATE_KICKING)) {
+ if (FD_ISSET(ConnectUser_get_connFd(srUsersTable[i]), &rset)) {
+ k = eval_usernum(srClientsTable[ConnectUser_get_whatClient(srUsersTable[i])], i);
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: user[%d]: FD_ISSET", get_realmname(config, j),
+ get_clientname(pointer, ConnectUser_get_whatClient(srUsersTable[i])),
+ get_username(pointer,i));
+ if (TYPE_IS_TCP(ServerRealm_get_realmType(pointer))) { /* forwarding tcp packets */
+ n = read(ConnectUser_get_connFd(srUsersTable[i]), &buff[5], 8091);
+ if (n == -1) {
+ if (errno == EAGAIN) {
+ continue;
+ }
+ aflog(LOG_T_USER, LOG_I_ERR,
+ "realm[%s]: Client[%s]: user[%d]: READ ERROR (%d)", get_realmname(config, j),
+ get_clientname(pointer, ConnectUser_get_whatClient(srUsersTable[i])),
+ get_username(pointer, i), errno);
+ n = 0;
+ }
+ if (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, ConnectUser_get_whatClient(srUsersTable[i])),
+ get_username(pointer, i), n);
+ UserStats_add_upload(ConnectUser_get_stats(srUsersTable[i]), n);
+ if ((buff[5] == AF_S_MESSAGE) && (buff[6] == AF_S_LOGIN) && (buff[7] == AF_S_MESSAGE)) {
+ 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 */
+ buff[2] = k; /* low bits of user number */
+ buff[3] = n >> 8; /* high bits of message length */
+ buff[4] = n; /* low bits of message length */
+ SslFd_send_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[ConnectUser_get_whatClient(srUsersTable[i])]),
+ buff, n+5);
+ }
+ else {
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: Client[%s]: user[%d]: CLOSED", get_realmname(config, j),
+ get_clientname(pointer, ConnectUser_get_whatClient(srUsersTable[i])),
+ 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, ConnectUser_get_whatClient(srUsersTable[i])),
+ get_username(pointer, i),
+ ConnectUser_get_nameBuf(srUsersTable[i]),
+ ConnectUser_get_portBuf(srUsersTable[i]),
+ timeperiod(now - ConnectUser_get_connectTime(srUsersTable[i])));
+ if (ServerRealm_get_auditOn(pointer)) {
+ AuditList_insert_back(
+ ConnectClient_get_auditList(
+ srClientsTable[ConnectUser_get_whatClient(srUsersTable[i])]),
+ AuditListNode_new_entry(
+ get_username(pointer, i),
+ ConnectUser_get_nameBuf(srUsersTable[i]),
+ ConnectUser_get_portBuf(srUsersTable[i]),
+ ConnectUser_get_connectTime(srUsersTable[i]),
+ now - ConnectUser_get_connectTime(srUsersTable[i]))
+ );
+ }
+ close(ConnectUser_get_connFd(srUsersTable[i]));
+ FD_CLR(ConnectUser_get_connFd(srUsersTable[i]), &allset);
+ FD_CLR(ConnectUser_get_connFd(srUsersTable[i]), &wset);
+ if (ConnectUser_get_state(srUsersTable[i]) == S_STATE_KICKING) {
+ ConnectUser_set_state(srUsersTable[i], S_STATE_CLEAR);
+ ServerRealm_decrease_connectedUsers(pointer);
+ ConnectClient_decrease_connected(srClientsTable[ConnectUser_get_whatClient(srUsersTable[i])]);
+ ConnectClient_get_users(srClientsTable[ConnectUser_get_whatClient(srUsersTable[i])])[k] = -1;
+ }
+ else {
+ ConnectUser_set_state(srUsersTable[i], S_STATE_CLOSING);
+ }
+ BufList_clear(ConnectUser_get_bufList(srUsersTable[i]));
+ buff[0] = AF_S_CONCLOSED; /* closing connection */
+ buff[1] = k >> 8; /* high bits of user number */
+ buff[2] = k; /* low bits of user number */
+ SslFd_send_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[ConnectUser_get_whatClient(srUsersTable[i])]),
+ buff, 5);
+ }
+ }
+ else { /* when forwarding udp packets */
+ n = readn(ConnectUser_get_connFd(srUsersTable[i]), buff, 5 );
+ if (n != 5) {
+ n = 0;
+ }
+ if (n) {
+ if ((buff[0] == AF_S_MESSAGE) && (buff[1] == AF_S_LOGIN) && (buff[2] == AF_S_MESSAGE)) {
+ length = buff[3];
+ length = length << 8;
+ length += buff[4]; /* this is length of message */
+ if ((n = readn(ConnectUser_get_connFd(srUsersTable[i]), &buff[5], length)) != 0) {
+ aflog(LOG_T_USER, LOG_I_DEBUG,
+ "realm[%s]: Client[%s]: FROM user[%d]: MESSAGE length=%d",
+ get_realmname(config, j),
+ get_clientname(pointer, ConnectUser_get_whatClient(srUsersTable[i])),
+ get_username(pointer, i), n);
+ buff[1] = k >> 8; /* high bits of user number */
+ buff[2] = k; /* low bits of user number */
+ SslFd_send_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[ConnectUser_get_whatClient(srUsersTable[i])]),
+ buff, n+5);
+ }
+ }
+ else {
+ n = 0;
+ }
+ }
+
+ if (n == 0) {
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: Client[%s]: user[%d]: CLOSED (udp mode)", get_realmname(config, j),
+ get_clientname(pointer,
+ ConnectUser_get_whatClient(srUsersTable[i])), 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, ConnectUser_get_whatClient(srUsersTable[i])),
+ get_username(pointer, i),
+ ConnectUser_get_nameBuf(srUsersTable[i]),
+ ConnectUser_get_portBuf(srUsersTable[i]),
+ timeperiod(now - ConnectUser_get_connectTime(srUsersTable[i])));
+ close(ConnectUser_get_connFd(srUsersTable[i]));
+ FD_CLR(ConnectUser_get_connFd(srUsersTable[i]), &allset);
+ FD_CLR(ConnectUser_get_connFd(srUsersTable[i]), &wset);
+ ConnectUser_set_state(srUsersTable[i], S_STATE_CLOSING);
+ BufList_clear(ConnectUser_get_bufList(srUsersTable[i]));
+ buff[0] = AF_S_CONCLOSED; /* closing connection */
+ buff[1] = k >> 8; /* high bits of user number */
+ buff[2] = k; /* low bits of user number */
+ SslFd_send_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[ConnectUser_get_whatClient(srUsersTable[i])]),
+ buff, 5);
+ }
+
+ }
+ }
+ }
+ }
+ /* ------------------------------------ */
+ for (i = 0; i < ServerRealm_get_usersLimit(pointer); ++i) {
+ if ((ConnectUser_get_state(srUsersTable[i]) == S_STATE_STOPPED) ||
+ (ConnectUser_get_state(srUsersTable[i]) == S_STATE_KICKING))
+ if (FD_ISSET(ConnectUser_get_connFd(srUsersTable[i]), &tmpset)) {
+ k = eval_usernum(srClientsTable[ConnectUser_get_whatClient(srUsersTable[i])], i);
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: user[%d]: FD_ISSET - WRITE", get_realmname(config, j),
+ get_clientname(pointer, ConnectUser_get_whatClient(srUsersTable[i])),
+ get_username(pointer, i));
+ n = BufListNode_readMessageLength(BufList_get_first(ConnectUser_get_bufList(srUsersTable[i])));
+ sent = write(ConnectUser_get_connFd(srUsersTable[i]),
+ BufListNode_readMessage(BufList_get_first(ConnectUser_get_bufList(srUsersTable[i]))), n);
+ if ((sent > 0) && (sent != n)) {
+ BufListNode_set_actPtr(BufList_get_first(ConnectUser_get_bufList(srUsersTable[i])),
+ BufListNode_get_actPtr(BufList_get_first(ConnectUser_get_bufList(srUsersTable[i]))) + sent);
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: user[%d]: (%d/%d)", get_realmname(config, j),
+ get_clientname(pointer, ConnectUser_get_whatClient(srUsersTable[i])),
+ get_username(pointer, i), sent, n);
+ }
+ else if ((sent == -1) && (errno == EAGAIN)) {
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: user[%d]: EAGAIN", get_realmname(config, j),
+ get_clientname(pointer, ConnectUser_get_whatClient(srUsersTable[i])),
+ get_username(pointer, i));
+ }
+ else if (sent == -1) {
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: Client[%s]: user[%d]: CLOSED", get_realmname(config, j),
+ get_clientname(pointer, ConnectUser_get_whatClient(srUsersTable[i])),
+ 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, ConnectUser_get_whatClient(srUsersTable[i])),
+ get_username(pointer, i),
+ ConnectUser_get_nameBuf(srUsersTable[i]),
+ ConnectUser_get_portBuf(srUsersTable[i]),
+ timeperiod(now - ConnectUser_get_connectTime(srUsersTable[i])));
+ close(ConnectUser_get_connFd(srUsersTable[i]));
+ FD_CLR(ConnectUser_get_connFd(srUsersTable[i]), &allset);
+ FD_CLR(ConnectUser_get_connFd(srUsersTable[i]), &wset);
+ if (ConnectUser_get_state(srUsersTable[i]) == S_STATE_KICKING) {
+ ConnectUser_set_state(srUsersTable[i], S_STATE_CLEAR);
+ ServerRealm_decrease_connectedUsers(pointer);
+ ConnectClient_decrease_connected(srClientsTable[ConnectUser_get_whatClient(srUsersTable[i])]);
+ ConnectClient_get_users(srClientsTable[ConnectUser_get_whatClient(srUsersTable[i])])[k] = -1;
+ }
+ else {
+ ConnectUser_set_state(srUsersTable[i], S_STATE_CLOSING);
+ }
+ BufList_clear(ConnectUser_get_bufList(srUsersTable[i]));
+ buff[0] = AF_S_CONCLOSED; /* closing connection */
+ buff[1] = k >> 8; /* high bits of user number */
+ buff[2] = k; /* low bits of user number */
+ SslFd_send_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[ConnectUser_get_whatClient(srUsersTable[i])]),
+ buff, 5);
+ }
+ else {
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: user[%d]: (%d/%d)", get_realmname(config, j),
+ get_clientname(pointer, ConnectUser_get_whatClient(srUsersTable[i])),
+ get_username(pointer, i), sent, n);
+ BufList_delete_first(ConnectUser_get_bufList(srUsersTable[i]));
+ if (BufList_get_first(ConnectUser_get_bufList(srUsersTable[i])) == NULL) {
+ FD_CLR(ConnectUser_get_connFd(srUsersTable[i]), &wset);
+ 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(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: TO user[%d]: BUFFERING MESSAGE ENDED",
+ get_realmname(config, j),
+ get_clientname(pointer, ConnectUser_get_whatClient(srUsersTable[i])),
+ get_username(pointer, i));
+ SslFd_send_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[ConnectUser_get_whatClient(srUsersTable[i])]),
+ buff, 5);
+ if (ConnectUser_get_state(srUsersTable[i]) == S_STATE_KICKING) {
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: Client[%s]: user[%d]: delayed CLOSED", get_realmname(config, j),
+ get_clientname(pointer, ConnectUser_get_whatClient(srUsersTable[i])),
+ 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, ConnectUser_get_whatClient(srUsersTable[i])),
+ get_username(pointer, i),
+ ConnectUser_get_nameBuf(srUsersTable[i]),
+ ConnectUser_get_portBuf(srUsersTable[i]),
+ timeperiod(now - ConnectUser_get_connectTime(srUsersTable[i])));
+ close(ConnectUser_get_connFd(srUsersTable[i]));
+ FD_CLR(ConnectUser_get_connFd(srUsersTable[i]), &allset);
+ FD_CLR(ConnectUser_get_connFd(srUsersTable[i]), &wset);
+ ConnectUser_set_state(srUsersTable[i], S_STATE_CLEAR);
+ ServerRealm_decrease_connectedUsers(pointer);
+ ConnectClient_decrease_connected(srClientsTable[ConnectUser_get_whatClient(srUsersTable[i])]);
+ ConnectClient_get_users(srClientsTable[ConnectUser_get_whatClient(srUsersTable[i])])[k] = -1;
+ BufList_clear(ConnectUser_get_bufList(srUsersTable[i]));
+ buff[0] = AF_S_CONCLOSED; /* closing connection */
+ buff[1] = k >> 8; /* high bits of user number */
+ buff[2] = k; /* low bits of user number */
+ SslFd_send_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[ConnectUser_get_whatClient(srUsersTable[i])]),
+ buff, 5);
+ }
+ else {
+ ConnectUser_set_state(srUsersTable[i], S_STATE_OPEN);
+ }
+ }
+ }
+ }
+ }
+ /* ------------------------------------ */
+ if (ServerRealm_get_basePortOn(pointer) == 0) {
+ for (l = 0; l < ServerRealm_get_userClientPairs(pointer); ++l) {
+ if (FD_ISSET(UsrCli_get_listenFd(srUsersClientsTable[l]), &rset)) {
+ len = ServerRealm_get_addressLength(pointer);
+ sent = accept(UsrCli_get_listenFd(srUsersClientsTable[l]), ServerRealm_get_clientAddress(pointer), &len);
+ if (sent == -1) {
+ if (errno == EAGAIN) {
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: listenfd: FD_ISSET --> EAGAIN", get_realmname(config, j));
+ }
+ else {
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: listenfd: FD_ISSET --> errno=%d", get_realmname(config, j), errno);
+ }
+ continue;
+ }
+ flags = fcntl(sent, F_GETFL, 0);
+ fcntl(sent, F_SETFL, flags | O_NONBLOCK);
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: listenfd: FD_ISSET", get_realmname(config, j));
+ k = find_client(pointer, ServerRealm_get_clientMode(pointer), l);
+
+ if (ConnectClient_get_state(srClientsTable[k]) == CONNECTCLIENT_STATE_ACCEPTED) {
+ if (ServerRealm_get_connectedUsers(pointer) == ServerRealm_get_usersLimit(pointer)) {
+ close(sent);
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "realm[%s]: user limit EXCEEDED", get_realmname(config, j));
+ }
+ else if (ConnectClient_get_connected(srClientsTable[k]) ==
+ ConnectClient_get_limit(srClientsTable[k])) {
+ close(sent);
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "realm[%s]: Client[%s]: usrpcli limit EXCEEDED",
+ get_realmname(config, j), get_clientname(pointer, k));
+ }
+ else {
+ for (i = 0; i < ServerRealm_get_usersLimit(pointer); ++i) {
+ if (ConnectUser_get_state(srUsersTable[i]) == S_STATE_CLEAR) {
+ ConnectUser_set_userId(srUsersTable[i], ServerRealm_get_usersCounter(pointer));
+ ServerRealm_increase_usersCounter(pointer);
+ 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(ServerRealm_get_clientAddress(pointer), len, ConnectUser_get_nameBuf(srUsersTable[i]),
+ ConnectUser_get_portBuf(srUsersTable[i]), ServerRealm_get_dnsLookupsOn(pointer)));
+ ConnectUser_set_connFd(srUsersTable[i], sent);
+ ConnectUser_set_state(srUsersTable[i], S_STATE_OPENING);
+ ConnectUser_set_whatClient(srUsersTable[i], k);
+ time(&now);
+ ConnectUser_set_connectTime(srUsersTable[i], now);
+ UserStats_clear(ConnectUser_get_stats(srUsersTable[i]));
+ UserStats_set_lastActivity(ConnectUser_get_stats(srUsersTable[i]), now);
+ ServerRealm_increase_connectedUsers(pointer);
+ ConnectClient_increase_connected(srClientsTable[k]);
+ memcpy(&buff[5], ConnectUser_get_nameBuf(srUsersTable[i]), 128);
+ memcpy(&buff[133], ConnectUser_get_portBuf(srUsersTable[i]), 7);
+ n = 135;
+ if (ConnectClient_get_multi(srClientsTable[k]) == CONNECTCLIENT_MULTI_ENABLED) {
+ n = 136;
+ buff[140] = UsrCli_get_number(srUsersClientsTable[l]);
+ }
+ i = find_usernum(srClientsTable[k], i);
+ buff[0] = AF_S_CONOPEN; /* opening connection */
+ 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 */
+ SslFd_send_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[k]),
+ buff, n+5);
+ break;
+ }
+ }
+ }
+ }
+ else {
+ close(sent);
+ aflog(LOG_T_USER, LOG_I_ERR,
+ "realm[%s]: Client(%d) is NOT CONNECTED",
+ get_realmname(config, j), k);
+ }
+ }
+ }
+ }
+ /* ------------------------------------ */
+ if (ServerRealm_get_basePortOn(pointer) == 1) {
+ for (k = 0; k < ServerRealm_get_clientsLimit(pointer); ++k) {
+ if (ConnectClient_get_state(srClientsTable[k]) == CONNECTCLIENT_STATE_ACCEPTED) {
+ if (FD_ISSET(ConnectClient_get_listenFd(srClientsTable[k]), &rset)) {
+
+ len = ServerRealm_get_addressLength(pointer);
+ sent = accept(ConnectClient_get_listenFd(srClientsTable[k]), ServerRealm_get_clientAddress(pointer), &len);
+ if (sent == -1) {
+ if (errno == EAGAIN) {
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: listenfd: FD_ISSET --> EAGAIN", get_realmname(config, j));
+ }
+ else {
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: listenfd: FD_ISSET --> errno=%d", get_realmname(config, j), errno);
+ }
+ continue;
+ }
+ flags = fcntl(sent, F_GETFL, 0);
+ fcntl(sent, F_SETFL, flags | O_NONBLOCK);
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: listenfd: FD_ISSET",
+ get_realmname(config, j), get_clientname(pointer, k));
+ if (ServerRealm_get_connectedUsers(pointer) == ServerRealm_get_usersLimit(pointer)) {
+ close(sent);
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "realm[%s]: user limit EXCEEDED", get_realmname(config, j));
+ }
+ else if(ConnectClient_get_connected(srClientsTable[k]) ==
+ ConnectClient_get_limit(srClientsTable[k])) {
+ close(sent);
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "realm[%s]: Client[%s]: usrpcli limit EXCEEDED",
+ get_realmname(config, j), get_clientname(pointer, k));
+ }
+ else {
+ for (i = 0; i < ServerRealm_get_usersLimit(pointer); ++i) {
+ if (ConnectUser_get_state(srUsersTable[i]) == S_STATE_CLEAR) {
+ ConnectUser_set_userId(srUsersTable[i], ServerRealm_get_usersCounter(pointer));
+ ServerRealm_increase_usersCounter(pointer);
+ 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(ServerRealm_get_clientAddress(pointer), len,
+ ConnectUser_get_nameBuf(srUsersTable[i]),
+ ConnectUser_get_portBuf(srUsersTable[i]), ServerRealm_get_dnsLookupsOn(pointer)));
+ ConnectUser_set_connFd(srUsersTable[i], sent);
+ ConnectUser_set_state(srUsersTable[i], S_STATE_OPENING);
+ ConnectUser_set_whatClient(srUsersTable[i], k);
+ time(&now);
+ ConnectUser_set_connectTime(srUsersTable[i], now);
+ UserStats_clear(ConnectUser_get_stats(srUsersTable[i]));
+ UserStats_set_lastActivity(ConnectUser_get_stats(srUsersTable[i]), now);
+ ServerRealm_increase_connectedUsers(pointer);
+ ConnectClient_increase_connected(srClientsTable[k]);
+ memcpy(&buff[5], ConnectUser_get_nameBuf(srUsersTable[i]), 128);
+ memcpy(&buff[133], ConnectUser_get_portBuf(srUsersTable[i]), 7);
+ n = 135;
+ i = find_usernum(srClientsTable[k], i);
+ buff[0] = AF_S_CONOPEN; /* opening connection */
+ 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 */
+ SslFd_send_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[k]),
+ buff, n+5);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* ------------------------------------ */
+ for (k = 0; k < ServerRealm_get_clientsLimit(pointer); ++k)
+ if ((ConnectClient_get_state(srClientsTable[k]) > CONNECTCLIENT_STATE_FREE) &&
+ (FD_ISSET(SslFd_get_fd(ConnectClient_get_sslFd(srClientsTable[k])), &rset))) {
+ if (ConnectClient_get_state(srClientsTable[k]) == CONNECTCLIENT_STATE_CONNECTING) {
+ make_ssl_initialize(ConnectClient_get_sslFd(srClientsTable[k]));
+ 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(ConnectClient_get_sslFd(srClientsTable[k]))) {
+ case 2: {
+ close(SslFd_get_fd(ConnectClient_get_sslFd(srClientsTable[k])));
+ FD_CLR(SslFd_get_fd(ConnectClient_get_sslFd(srClientsTable[k])), &allset);
+
+ /* This SSL-object is busted; don't reuse it
+ (SSL_clear isn't sufficient because ssl->new_session is set): */
+ SslFd_set_ssl(ConnectClient_get_sslFd(srClientsTable[k]),
+ SSL_new (ctx));
+
+ ConnectClient_set_state(srClientsTable[k], CONNECTCLIENT_STATE_FREE);
+ if ((task = ConnectClient_get_task(srClientsTable[k]))) {
+ TaskScheduler_removeTask(scheduler, task);
+ ConnectClient_set_task(srClientsTable[k], NULL);
+ }
+ ServerRealm_decrease_connectedClients(pointer);
+ 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(LOG_T_CLIENT, LOG_I_DEBUG,
+ "realm[%s]: new Client[%s]: ACCEPTED by SSL_accept",
+ get_realmname(config, j), get_clientname(pointer, k));
+ ConnectClient_set_state(srClientsTable[k], CONNECTCLIENT_STATE_AUTHORIZING);
+ continue;
+ }
+ }
+ }
+ aflog(LOG_T_CLIENT, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s]: commfd: FD_ISSET",
+ get_realmname(config, j), get_clientname(pointer, k));
+ if (ConnectClient_get_state(srClientsTable[k]) == CONNECTCLIENT_STATE_AUTHORIZING) {
+ n = SslFd_get_message(ServerRealm_get_realmType(pointer) | TYPE_SSL | TYPE_ZLIB,
+ ConnectClient_get_sslFd(srClientsTable[k]),
+ buff, (-1) * HeaderBuffer_to_read(ConnectClient_get_header(srClientsTable[k])));
+ }
+ else {
+ n = SslFd_get_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(srClientsTable[k]),
+ buff, (-1) * HeaderBuffer_to_read(ConnectClient_get_header(srClientsTable[k])));
+ }
+ if (n == -1) {
+ if (errno == 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(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(LOG_T_CLIENT, LOG_I_DEBUG,
+ "realm[%s]: Client[%s]: header length = %d --> buffering",
+ get_realmname(config, j), get_clientname(pointer, k), n);
+ HeaderBuffer_store(ConnectClient_get_header(srClientsTable[k]), buff, n);
+ if (HeaderBuffer_to_read(ConnectClient_get_header(srClientsTable[k])) == 0) {
+ HeaderBuffer_restore(ConnectClient_get_header(srClientsTable[k]), buff);
+ n = 5;
+ }
+ else {
+ continue;
+ }
+ }
+ }
+ if (n==0) {
+ 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),
+ ConnectClient_get_nameBuf(srClientsTable[k]),
+ ConnectClient_get_portBuf(srClientsTable[k]),
+ timeperiod(now - ConnectClient_get_connectTime(srClientsTable[k])));
+ if (ServerRealm_get_auditOn(pointer)) {
+ while (AuditList_get_first(ConnectClient_get_auditList(srClientsTable[k]))) {
+ aflog(LOG_T_CLIENT, LOG_I_NOTICE,
+ "USERID: %d IP: %s PORT: %s CONNECTED: %s DURATION: %s",
+ AuditListNode_get_userId(
+ AuditList_get_first(
+ ConnectClient_get_auditList(srClientsTable[k]))),
+ AuditListNode_get_nameBuf(
+ AuditList_get_first(
+ ConnectClient_get_auditList(srClientsTable[k]))),
+ AuditListNode_get_portBuf(
+ AuditList_get_first(
+ ConnectClient_get_auditList(srClientsTable[k]))),
+ localdate(AuditListNode_get_connectTimep(
+ AuditList_get_first(
+ ConnectClient_get_auditList(srClientsTable[k])))),
+ timeperiod(AuditListNode_get_duration(
+ AuditList_get_first(
+ ConnectClient_get_auditList(srClientsTable[k])))));
+ AuditList_delete_first(ConnectClient_get_auditList(srClientsTable[k]));
+ }
+ }
+ remove_client(pointer, k, &allset, &wset, scheduler);
+ 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 */
+
+ if ((k == ServerRealm_get_clientsLimit(pointer)) && (buff[0] != AF_S_LOGIN) &&
+ (buff[0] != AF_S_ADMIN_LOGIN) && (buff[0] != AF_S_ADMIN_CMD)) {
+ buff[0] = AF_S_WRONG;
+ }
+ if (ConnectClient_get_state(srClientsTable[k]) < CONNECTCLIENT_STATE_AUTHORIZING) {
+ aflog(LOG_T_CLIENT, LOG_I_WARNING,
+ "realm[%s]: Client[%s]: Impossible behaviour --> ignoring",
+ get_realmname(config, j), get_clientname(pointer, k));
+ continue;
+ }
+ if ((ConnectClient_get_state(srClientsTable[k]) == CONNECTCLIENT_STATE_AUTHORIZING) &&
+ (buff[0] != AF_S_LOGIN) && (buff[0] != AF_S_ADMIN_LOGIN)) {
+ buff[0] = AF_S_WRONG;
+ }
+
+ time(&now);
+ ConnectClient_set_lastActivity(srClientsTable[k], now);
+ if (ServerRealm_get_maxIdle(pointer)) {
+ ConnectClient_set_timer(srClientsTable[k], timeval_create(ServerRealm_get_maxIdle(pointer), 0));
+ TaskScheduler_update(scheduler);
+ }
+
+ switch (buff[0]) {
+ case AF_S_CONCLOSED : {
+ n = numofcon;
+ numofcon = eval_numofcon(pointer, k, numofcon);
+ if ((numofcon>=0) && (numofcon<(ServerRealm_get_usersLimit(pointer))) &&
+ (ConnectClient_get_state(srClientsTable[k]) ==
+ CONNECTCLIENT_STATE_ACCEPTED)) {
+ if (ConnectUser_get_state(srUsersTable[numofcon]) ==
+ S_STATE_STOPPED) {
+ ConnectUser_set_state(srUsersTable[numofcon], S_STATE_KICKING);
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: user[%d]: KICKING...",
+ get_realmname(config, j), get_username(pointer, numofcon));
+ }
+ else {
+ ServerRealm_decrease_connectedUsers(pointer);
+ ConnectClient_decrease_connected(srClientsTable[k]);
+ ConnectClient_get_users(srClientsTable[k])[n] = -1;
+ if (ConnectUser_get_state(srUsersTable[numofcon]) == S_STATE_CLOSING) {
+ ConnectUser_set_state(srUsersTable[numofcon], S_STATE_CLEAR);
+ aflog(LOG_T_USER, LOG_I_DEBUG,
+ "realm[%s]: user[%d]: CLOSE CONFIRMED",
+ get_realmname(config, j), get_username(pointer, numofcon));
+ }
+ else if (ConnectUser_get_state(srUsersTable[numofcon]) == S_STATE_OPEN) {
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: user[%d]: KICKED",
+ get_realmname(config, j), get_username(pointer, numofcon));
+ 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),
+ ConnectUser_get_nameBuf(srUsersTable[numofcon]),
+ ConnectUser_get_portBuf(srUsersTable[numofcon]),
+ timeperiod(now -
+ ConnectUser_get_connectTime(srUsersTable[numofcon])));
+ close(ConnectUser_get_connFd(srUsersTable[numofcon]));
+ FD_CLR(ConnectUser_get_connFd(srUsersTable[numofcon]), &allset);
+ FD_CLR(ConnectUser_get_connFd(srUsersTable[numofcon]), &wset);
+ ConnectUser_set_state(srUsersTable[numofcon], S_STATE_CLEAR);
+ BufList_clear(ConnectUser_get_bufList(srUsersTable[numofcon]));
+ buff[0] = AF_S_CONCLOSED; /* closing connection */
+ buff[1] = n >> 8; /* high bits of user number */
+ buff[2] = n; /* low bits of user number */
+ SslFd_send_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[k]),
+ buff, 5);
+ }
+ }
+ }
+ else {
+ remove_client(pointer, k, &allset, &wset, scheduler);
+ }
+ break;
+ }
+ case AF_S_CONOPEN : {
+ n = numofcon;
+ numofcon = eval_numofcon(pointer, k, numofcon);
+ if ((numofcon>=0) && (numofcon<(ServerRealm_get_usersLimit(pointer))) &&
+ (ConnectClient_get_state(srClientsTable[k]) ==
+ CONNECTCLIENT_STATE_ACCEPTED)) {
+ if (ConnectUser_get_state(srUsersTable[numofcon]) ==
+ S_STATE_OPENING) {
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: user[%d]: NEW",
+ get_realmname(config, j), get_username(pointer, numofcon));
+ FD_SET(ConnectUser_get_connFd(srUsersTable[numofcon]), &allset);
+ maxfdp1 = (maxfdp1 > (ConnectUser_get_connFd(srUsersTable[numofcon]) + 1)) ?
+ maxfdp1 : (ConnectUser_get_connFd(srUsersTable[numofcon]) + 1);
+ ConnectUser_set_state(srUsersTable[numofcon], S_STATE_OPEN);
+ }
+ if (ConnectUser_get_state(srUsersTable[numofcon]) ==
+ S_STATE_OPENING_CLOSED) {
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: user[%d]: delayed CLOSING",
+ get_realmname(config, j), get_username(pointer, numofcon));
+ ConnectUser_set_state(srUsersTable[numofcon], S_STATE_CLOSING);
+ buff[0] = AF_S_CONCLOSED; /* closing connection */
+ buff[1] = n >> 8; /* high bits of user number */
+ buff[2] = n; /* low bits of user number */
+ SslFd_send_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[k]),
+ buff, 5);
+ }
+ }
+ else {
+ remove_client(pointer, k, &allset, &wset, scheduler);
+ }
+ break;
+ }
+ case AF_S_CANT_OPEN : {
+ n = numofcon;
+ numofcon = eval_numofcon(pointer, k, numofcon);
+ if ((numofcon>=0) && (numofcon<(ServerRealm_get_usersLimit(pointer))) &&
+ (ConnectClient_get_state(srClientsTable[k]) ==
+ CONNECTCLIENT_STATE_ACCEPTED)) {
+ if ((ConnectUser_get_state(srUsersTable[numofcon]) ==
+ S_STATE_OPENING) ||
+ (ConnectUser_get_state(srUsersTable[numofcon]) ==
+ S_STATE_OPENING_CLOSED)) {
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: user[%d]: DROPPED",
+ get_realmname(config, j), get_username(pointer, numofcon));
+ ServerRealm_decrease_connectedUsers(pointer);
+ ConnectClient_decrease_connected(srClientsTable[k]);
+ ConnectClient_get_users(srClientsTable[k])[n] = -1;
+ if (ConnectUser_get_state(srUsersTable[numofcon]) ==
+ S_STATE_OPENING) {
+ close(ConnectUser_get_connFd(srUsersTable[numofcon]));
+ }
+ ConnectUser_set_state(srUsersTable[numofcon], S_STATE_CLEAR);
+ }
+ }
+ else {
+ remove_client(pointer, k, &allset, &wset, scheduler);
+ }
+ break;
+ }
+ case AF_S_MESSAGE : {
+ if (ConnectClient_get_state(srClientsTable[k]) !=
+ CONNECTCLIENT_STATE_ACCEPTED) {
+ remove_client(pointer, k, &allset, &wset, scheduler);
+ break;
+ }
+ if (TYPE_IS_UDP(ServerRealm_get_realmType(pointer))) { /* udp */
+ n = SslFd_get_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[k]),
+ &buff[5], length);
+ }
+ else {
+ n = SslFd_get_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[k]),
+ buff, length);
+ }
+ temp = numofcon;
+ numofcon = eval_numofcon(pointer, k, numofcon);
+ if ((numofcon>=0) && (numofcon<(ServerRealm_get_usersLimit(pointer)))) {
+ if (ConnectUser_get_state(srUsersTable[numofcon]) == S_STATE_OPEN) {
+ aflog(LOG_T_USER, LOG_I_DEBUG,
+ "realm[%s]: TO user[%d]: MESSAGE length=%d",
+ get_realmname(config, j), get_username(pointer, numofcon), n);
+ UserStats_add_download(ConnectUser_get_stats(srUsersTable[numofcon]), n);
+ if (TYPE_IS_UDP(ServerRealm_get_realmType(pointer))) { /* udp */
+ buff[1] = AF_S_LOGIN;
+ buff[2] = AF_S_MESSAGE;
+ buff[3] = n >> 8; /* high bits of message length */
+ buff[4] = n; /* low bits of message length */
+ sent = write(ConnectUser_get_connFd(srUsersTable[numofcon]), buff, n+5);
+ if (sent == -1) {
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: user[%d]: CLOSED (write-udp)",
+ get_realmname(config, j), get_username(pointer, numofcon));
+ 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),
+ ConnectUser_get_nameBuf(srUsersTable[numofcon]),
+ ConnectUser_get_portBuf(srUsersTable[numofcon]),
+ timeperiod(now - ConnectUser_get_connectTime(srUsersTable[numofcon])));
+ close(ConnectUser_get_connFd(srUsersTable[numofcon]));
+ FD_CLR(ConnectUser_get_connFd(srUsersTable[numofcon]), &allset);
+ FD_CLR(ConnectUser_get_connFd(srUsersTable[numofcon]), &wset);
+ ConnectUser_set_state(srUsersTable[numofcon], S_STATE_CLOSING);
+ BufList_clear(ConnectUser_get_bufList(srUsersTable[numofcon]));
+ buff[0] = AF_S_CONCLOSED; /* closing connection */
+ buff[1] = temp >> 8; /* high bits of user number */
+ buff[2] = temp; /* low bits of user number */
+ SslFd_send_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[k]),
+ buff, 5);
+ }
+ }
+ else { /* tcp */
+ sent = write(ConnectUser_get_connFd(srUsersTable[numofcon]), buff, n);
+ if ((sent > 0) && (sent != n)) {
+ BufList_insert_back(ConnectUser_get_bufList(srUsersTable[numofcon]),
+ BufListNode_new_message(sent, n, buff));
+ ConnectUser_set_state(srUsersTable[numofcon], S_STATE_STOPPED);
+ FD_SET(ConnectUser_get_connFd(srUsersTable[numofcon]), &wset);
+ buff[0] = AF_S_DONT_SEND; /* stopping transfer */
+ buff[1] = temp >> 8; /* high bits of user number */
+ buff[2] = temp; /* low bits of user number */
+ 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);
+ SslFd_send_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[k]),
+ buff, 5);
+ }
+ else if ((sent == -1) && (errno == EAGAIN)) {
+ BufList_insert_back(ConnectUser_get_bufList(srUsersTable[numofcon]),
+ BufListNode_new_message(0, n, buff));
+ ConnectUser_set_state(srUsersTable[numofcon], S_STATE_STOPPED);
+ FD_SET(ConnectUser_get_connFd(srUsersTable[numofcon]), &wset);
+ buff[0] = AF_S_DONT_SEND; /* stopping transfer */
+ buff[1] = temp >> 8; /* high bits of user number */
+ buff[2] = temp; /* low bits of user number */
+ 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);
+ SslFd_send_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[k]),
+ buff, 5);
+ }
+ else if (sent == -1) {
+ aflog(LOG_T_USER, LOG_I_INFO,
+ "realm[%s]: user[%d]: CLOSED (write-tcp)",
+ get_realmname(config, j), get_username(pointer, numofcon));
+ 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),
+ ConnectUser_get_nameBuf(srUsersTable[numofcon]),
+ ConnectUser_get_portBuf(srUsersTable[numofcon]),
+ timeperiod(now - ConnectUser_get_connectTime(srUsersTable[numofcon])));
+ close(ConnectUser_get_connFd(srUsersTable[numofcon]));
+ FD_CLR(ConnectUser_get_connFd(srUsersTable[numofcon]), &allset);
+ FD_CLR(ConnectUser_get_connFd(srUsersTable[numofcon]), &wset);
+ ConnectUser_set_state(srUsersTable[numofcon], S_STATE_CLOSING);
+ BufList_clear(ConnectUser_get_bufList(srUsersTable[numofcon]));
+ buff[0] = AF_S_CONCLOSED; /* closing connection */
+ buff[1] = temp >> 8; /* high bits of user number */
+ buff[2] = temp; /* low bits of user number */
+ SslFd_send_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[k]),
+ buff, 5);
+ }
+ }
+ }
+ else if (ConnectUser_get_state(srUsersTable[numofcon]) == S_STATE_STOPPED) {
+ 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(ServerRealm_get_realmType(pointer))) { /* udp */
+ buff[1] = AF_S_LOGIN;
+ buff[2] = AF_S_MESSAGE;
+ buff[3] = n >> 8; /* high bits of message length */
+ buff[4] = n; /* low bits of message length */
+ BufList_insert_back(ConnectUser_get_bufList(srUsersTable[numofcon]),
+ BufListNode_new_message(0, n+5, buff));
+ }
+ else {
+ BufList_insert_back(ConnectUser_get_bufList(srUsersTable[numofcon]),
+ BufListNode_new_message(0, n, buff));
+ }
+ }
+ else if (ConnectUser_get_state(srUsersTable[numofcon]) == S_STATE_CLOSING) {
+ 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);
+ }
+ else {
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "realm[%s]: TO user[%d]: user in wrong state - IGNORED",
+ get_realmname(config, j), get_username(pointer, numofcon));
+ }
+ }
+ else {
+ aflog(LOG_T_USER, LOG_I_WARNING,
+ "realm[%s]: message to non-existing user - IGNORED",
+ get_realmname(config, j));
+ }
+ break;
+ }
+ case AF_S_LOGIN : {
+ if ((ConnectClient_get_state(srClientsTable[k]) ==
+ CONNECTCLIENT_STATE_AUTHORIZING) &&
+ (numofcon==(ServerRealm_get_password(pointer)[0]*256+ServerRealm_get_password(pointer)[1])) &&
+ (length==(ServerRealm_get_password(pointer)[2]*256+ServerRealm_get_password(pointer)[3]))) {
+ ConnectClient_set_multi(srClientsTable[k], CONNECTCLIENT_MULTI_DISABLED);
+ if (k != ServerRealm_get_clientsLimit(pointer)) {
+ ConnectClient_set_state(srClientsTable[k], CONNECTCLIENT_STATE_ACCEPTED);
+ 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] = ConnectClient_get_limit(
+ srClientsTable[k]) >> 8;/* high bits of user number */
+ buff[2] = ConnectClient_get_limit(
+ srClientsTable[k]); /* low bits of user number */
+ buff[3] = ServerRealm_get_realmType(pointer); /* type of connection */
+ SslFd_send_message(ServerRealm_get_realmType(pointer) | TYPE_SSL | TYPE_ZLIB,
+ ConnectClient_get_sslFd(
+ srClientsTable[k]),
+ buff, 5);
+ if ((task = ConnectClient_get_task(srClientsTable[k]))) {
+ TaskScheduler_removeTask(scheduler, task);
+ ConnectClient_set_task(srClientsTable[k], NULL);
+ }
+ if (ServerRealm_get_maxIdle(pointer)) {
+ ConnectClient_set_timer(srClientsTable[k],
+ timeval_create(ServerRealm_get_maxIdle(pointer), 0));
+ task = Task_new(ConnectClient_get_timerp(srClientsTable[k]),
+ RCTfunction,
+ RCTdata_new(config, j, k, 0, RCT_REASON_MAXIDLE, &allset, &wset),
+ RCTdata_free);
+ ConnectClient_set_task(srClientsTable[k], task);
+ TaskScheduler_addTask(scheduler, task);
+ }
+ if (ServerRealm_get_basePortOn(pointer) == 1) {
+ long tmp_val;
+ char tmp_tab[6];
+ if (check_long(
+ UsrCli_get_listenPortName(
+ srUsersClientsTable[
+ ConnectClient_get_usrCliPair(srClientsTable[k])]),
+ &tmp_val)) {
+ 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, scheduler);
+ break;
+ }
+ tmp_val = tmp_val%65536;
+ memset(tmp_tab, 0, 6);
+ sprintf(tmp_tab, "%d", (int)tmp_val);
+ ipfam = 0x01;
+#ifdef AF_INET6
+ if (TYPE_IS_IPV4(ServerRealm_get_realmType(pointer))) {
+ ipfam |= 0x02;
+ }
+ else if (TYPE_IS_IPV6(ServerRealm_get_realmType(pointer))) {
+ ipfam |= 0x04;
+ }
+#endif
+ while (ip_listen(ConnectClient_get_listenFdp(srClientsTable[k]),
+ UsrCli_get_listenHostName(srUsersClientsTable[
+ ConnectClient_get_usrCliPair(srClientsTable[k])]) ?
+ UsrCli_get_listenHostName(srUsersClientsTable[
+ ConnectClient_get_usrCliPair(srClientsTable[k])]) :
+ ServerRealm_get_hostName(pointer),
+ tmp_tab, (&len), ipfam)) {
+ tmp_val = (tmp_val+1)%65536;
+ memset(tmp_tab, 0, 6);
+ sprintf(tmp_tab, "%d", (int)tmp_val);
+ }
+ ServerRealm_set_addressLength(pointer, len);
+ FD_SET(ConnectClient_get_listenFd(srClientsTable[k]), &allset);
+ maxfdp1 = (maxfdp1>(ConnectClient_get_listenFd(srClientsTable[k])+1)) ?
+ maxfdp1 : (ConnectClient_get_listenFd(srClientsTable[k]) + 1);
+ 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(LOG_T_CLIENT, LOG_I_WARNING,
+ "realm[%s]: client limit EXCEEDED", get_realmname(config, j));
+ buff[0] = AF_S_CANT_OPEN; /* sending message */
+ SslFd_send_message(ServerRealm_get_realmType(pointer) | TYPE_SSL,
+ ConnectClient_get_sslFd(
+ srClientsTable[k]),
+ buff, 5);
+ remove_client(pointer, k, &allset, &wset, scheduler);
+ }
+ }
+ else if ((ConnectClient_get_state(srClientsTable[k]) ==
+ CONNECTCLIENT_STATE_ACCEPTED) && (numofcon == 0)) {
+ n = SslFd_get_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srClientsTable[k]),
+ buff, length);
+ buff[n] = 0;
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "realm[%s]: Client[%s]: ID received: %s",
+ get_realmname(config, j), get_clientname(pointer, k), buff);
+ ConnectClient_set_sClientId(srClientsTable[k], (char*) buff);
+ }
+ else {
+ 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 */
+ SslFd_send_message(ServerRealm_get_realmType(pointer) | TYPE_SSL,
+ ConnectClient_get_sslFd(
+ srClientsTable[k]),
+ buff, 5);
+ remove_client(pointer, k, &allset, &wset, scheduler);
+ }
+ break;
+ }
+ case AF_S_DONT_SEND: {
+ if ((ConnectUser_get_state(srUsersTable[numofcon]) == S_STATE_OPEN) ||
+ (ConnectUser_get_state(srUsersTable[numofcon]) == S_STATE_STOPPED)) {
+ aflog(LOG_T_CLIENT, LOG_I_DEBUG,
+ "realm[%s]: user[%d]: STOP READING",
+ get_realmname(config, j), get_username(pointer, numofcon));
+ FD_CLR(ConnectUser_get_connFd(srUsersTable[numofcon]), &allset);
+ }
+ else {
+ aflog(LOG_T_CLIENT, LOG_I_DDEBUG,
+ "realm[%s]: user[%d]: STOP READING - ignored",
+ get_realmname(config, j), get_username(pointer, numofcon));
+ }
+ break;
+ }
+ case AF_S_CAN_SEND: {
+ if ((ConnectUser_get_state(srUsersTable[numofcon]) == S_STATE_OPEN) ||
+ (ConnectUser_get_state(srUsersTable[numofcon]) == S_STATE_STOPPED)) {
+ aflog(LOG_T_CLIENT, LOG_I_DEBUG,
+ "realm[%s]: user[%d]: START READING",
+ get_realmname(config, j), get_username(pointer, numofcon));
+ FD_SET(ConnectUser_get_connFd(srUsersTable[numofcon]), &allset);
+ }
+ else {
+ aflog(LOG_T_CLIENT, LOG_I_DDEBUG,
+ "realm[%s]: user[%d]: START READING - ignored",
+ get_realmname(config, j), get_username(pointer, numofcon));
+ }
+ break;
+ }
+ case AF_S_WRONG: {
+ 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, scheduler);
+ break;
+ }
+ case AF_S_ADMIN_LOGIN: {
+ if ((ConnectClient_get_state(srClientsTable[k]) ==
+ CONNECTCLIENT_STATE_AUTHORIZING) &&
+ (numofcon == (ServerRealm_get_password(pointer)[0]*256 + ServerRealm_get_password(pointer)[1])) &&
+ (length == (ServerRealm_get_password(pointer)[2]*256 + ServerRealm_get_password(pointer)[3]))) {
+ 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 < ServerRealm_get_raClientsLimit(pointer); ++l) {
+ if (ConnectClient_get_state(srRaClientsTable[l]) ==
+ CONNECTCLIENT_STATE_FREE) {
+ SslFd_set_fd(
+ ConnectClient_get_sslFd(srRaClientsTable[l]),
+ SslFd_get_fd(
+ ConnectClient_get_sslFd(srClientsTable[k])));
+ ConnectClient_set_connectTime(
+ srRaClientsTable[l],
+ ConnectClient_get_connectTime(srClientsTable[k]));
+ ConnectClient_set_lastActivity(
+ srRaClientsTable[l],
+ ConnectClient_get_lastActivity(srClientsTable[k]));
+#ifdef HAVE_LIBPTHREAD
+ ConnectClient_set_tunnelType(
+ srRaClientsTable[l],
+ ConnectClient_get_tunnelType(srClientsTable[k]));
+#endif
+ ConnectClient_set_clientId(
+ srRaClientsTable[l],
+ ConnectClient_get_clientId(srClientsTable[k]));
+ ConnectClient_set_nameBuf(
+ srRaClientsTable[l],
+ ConnectClient_get_nameBuf(srClientsTable[k]));
+ ConnectClient_set_portBuf(
+ srRaClientsTable[l],
+ ConnectClient_get_portBuf(srClientsTable[k]));
+ tmp_ssl = SslFd_get_ssl(
+ ConnectClient_get_sslFd(srRaClientsTable[l]));
+ SslFd_set_ssl_nf(
+ ConnectClient_get_sslFd(srRaClientsTable[l]),
+ SslFd_get_ssl(
+ ConnectClient_get_sslFd(srClientsTable[k])));
+ SslFd_set_ssl_nf(
+ ConnectClient_get_sslFd(srClientsTable[k]),
+ tmp_ssl);
+ ConnectClient_set_state(
+ srClientsTable[k],
+ CONNECTCLIENT_STATE_FREE);
+ break;
+ }
+ }
+ if (l != ServerRealm_get_raClientsLimit(pointer)) {
+ ConnectClient_set_state(
+ srRaClientsTable[l],
+ CONNECTCLIENT_STATE_ACCEPTED);
+ ServerRealm_increase_connectedRaClients(pointer);
+ if ((task = ConnectClient_get_task(srClientsTable[k]))) {
+ TaskScheduler_removeTask(scheduler, task);
+ ConnectClient_set_task(srClientsTable[k], NULL);
+ }
+ sprintf((char*) &buff[5], AF_VER("AFSERVER"));
+ n = strlen((char*) &buff[5]);
+ buff[0] = AF_S_ADMIN_LOGIN; /* sending message */
+ buff[1] = ServerRealm_get_realmType(pointer); /* type of connection */
+ buff[2] = AF_RA_UNDEFINED;
+ buff[3] = n >> 8; /* high bits of message length */
+ buff[4] = n; /* low bits of message length */
+ SslFd_send_message(ServerRealm_get_realmType(pointer) | TYPE_SSL,
+ ConnectClient_get_sslFd(
+ srRaClientsTable[l]),
+ buff, n+5);
+ }
+ else {
+ 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 */
+ SslFd_send_message(ServerRealm_get_realmType(pointer) | TYPE_SSL | TYPE_ZLIB,
+ ConnectClient_get_sslFd(
+ srClientsTable[k]),
+ buff, 5);
+ remove_client(pointer, k, &allset, &wset, scheduler);
+ }
+ }
+ 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;
+ }
+ case AF_S_ENABLE_MULTI: {
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "realm[%s]: Client[%s]: MULTI enabled: %d",
+ get_realmname(config, j), get_clientname(pointer, k), buff[1]);
+ ConnectClient_set_multi(srClientsTable[k], CONNECTCLIENT_MULTI_ENABLED);
+ break;
+ }
+ default : {
+ 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, scheduler);
+ }
+ }
+ }
+ /* ------------------------------------ */
+ for (k = 0; k < ServerRealm_get_raClientsLimit(pointer); ++k)
+ if ((ConnectClient_get_state(srRaClientsTable[k]) > CONNECTCLIENT_STATE_FREE) &&
+ (FD_ISSET(SslFd_get_fd(ConnectClient_get_sslFd(srRaClientsTable[k])), &rset))) {
+ if (ConnectClient_get_state(srRaClientsTable[k]) == CONNECTCLIENT_STATE_CONNECTING) {
+ make_ssl_initialize(ConnectClient_get_sslFd(srRaClientsTable[k]));
+ 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(ConnectClient_get_sslFd(srRaClientsTable[k]))) {
+ case 2: {
+ close (SslFd_get_fd(ConnectClient_get_sslFd(srRaClientsTable[k])));
+ FD_CLR(SslFd_get_fd(ConnectClient_get_sslFd(srRaClientsTable[k])), &allset);
+ SSL_clear(SslFd_get_ssl(ConnectClient_get_sslFd(srRaClientsTable[k])));
+ ConnectClient_set_state(srRaClientsTable[k], CONNECTCLIENT_STATE_FREE);
+ if ((task = ConnectClient_get_task(srRaClientsTable[k]))) {
+ TaskScheduler_removeTask(scheduler, task);
+ ConnectClient_set_task(srRaClientsTable[k], NULL);
+ }
+ ServerRealm_decrease_connectedClients(pointer);
+ 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(LOG_T_MANAGE, LOG_I_DEBUG,
+ "realm[%s]: new Client[%s] (ra): ACCEPTED by SSL_accept",
+ get_realmname(config, j), get_raclientname(pointer, k));
+ ConnectClient_set_state(srRaClientsTable[k], CONNECTCLIENT_STATE_AUTHORIZING);
+ continue;
+ }
+ }
+ }
+ aflog(LOG_T_MANAGE, LOG_I_DDEBUG,
+ "realm[%s]: Client[%s] (ra): commfd: FD_ISSET",
+ get_realmname(config, j), get_raclientname(pointer, k));
+ n = SslFd_get_message(ServerRealm_get_realmType(pointer) | TYPE_SSL | TYPE_ZLIB,
+ ConnectClient_get_sslFd(
+ srRaClientsTable[k]),
+ buff, (-1) * HeaderBuffer_to_read(ConnectClient_get_header(srRaClientsTable[k])));
+ if (n == -1) {
+ if (errno == 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(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(LOG_T_MANAGE, LOG_I_WARNING,
+ "realm[%s]: Client[%s] (ra): header length = %d --> buffering",
+ get_realmname(config, j), get_raclientname(pointer, k), n);
+ HeaderBuffer_store(ConnectClient_get_header(srRaClientsTable[k]), buff, n);
+ if (HeaderBuffer_to_read(ConnectClient_get_header(srRaClientsTable[k])) == 0) {
+ HeaderBuffer_restore(ConnectClient_get_header(srRaClientsTable[k]), buff);
+ n = 5;
+ }
+ else {
+ continue;
+ }
+ }
+ }
+ if (n==0) {
+ remove_raclient(pointer, k, &allset, &wset, scheduler);
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "realm[%s]: Client[%s] (ra): commfd: CLOSED",
+ get_realmname(config, j), get_raclientname(pointer, k));
+ 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 */
+
+ if (ConnectClient_get_state(srRaClientsTable[k]) < CONNECTCLIENT_STATE_AUTHORIZING) {
+ aflog(LOG_T_MANAGE, LOG_I_WARNING,
+ "realm[%s]: Client[%s] (ra): Impossible behaviour --> ignoring",
+ get_realmname(config, j), get_raclientname(pointer, k));
+ continue;
+ }
+ if ((ConnectClient_get_state(srRaClientsTable[k]) == CONNECTCLIENT_STATE_AUTHORIZING) &&
+ (buff[0] != AF_S_LOGIN) && (buff[0] != AF_S_ADMIN_LOGIN)) {
+ buff[0] = AF_S_WRONG;
+ }
+
+ time(&now);
+ ConnectClient_set_lastActivity(srRaClientsTable[k], now);
+
+ switch (buff[0]) {
+ case AF_S_LOGIN : {
+ if ((ConnectClient_get_state(srRaClientsTable[k]) ==
+ CONNECTCLIENT_STATE_AUTHORIZING) &&
+ (numofcon==(ServerRealm_get_password(pointer)[0]*256+ServerRealm_get_password(pointer)[1])) &&
+ (length==(ServerRealm_get_password(pointer)[2]*256+ServerRealm_get_password(pointer)[3]))) {
+ ConnectClient_set_multi(srRaClientsTable[k], CONNECTCLIENT_MULTI_DISABLED);
+ for (l = 0; l < ServerRealm_get_clientsLimit(pointer); ++l) {
+ if (ConnectClient_get_state(srClientsTable[l]) ==
+ CONNECTCLIENT_STATE_FREE) {
+ 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));
+ SslFd_set_fd(
+ ConnectClient_get_sslFd(srClientsTable[l]),
+ SslFd_get_fd(
+ ConnectClient_get_sslFd(srRaClientsTable[k])));
+ ConnectClient_set_connectTime(
+ srClientsTable[l],
+ ConnectClient_get_connectTime(srRaClientsTable[k]));
+ ConnectClient_set_lastActivity(
+ srClientsTable[l],
+ ConnectClient_get_lastActivity(srRaClientsTable[k]));
+#ifdef HAVE_LIBPTHREAD
+ ConnectClient_set_tunnelType(
+ srClientsTable[l],
+ ConnectClient_get_tunnelType(srRaClientsTable[k]));
+#endif
+ ConnectClient_set_clientId(
+ srClientsTable[l],
+ ConnectClient_get_clientId(srRaClientsTable[k]));
+ ConnectClient_set_nameBuf(
+ srClientsTable[l],
+ ConnectClient_get_nameBuf(srRaClientsTable[k]));
+ ConnectClient_set_portBuf(
+ srClientsTable[l],
+ ConnectClient_get_portBuf(srRaClientsTable[k]));
+ tmp_ssl = SslFd_get_ssl(
+ ConnectClient_get_sslFd(srClientsTable[l]));
+ SslFd_set_ssl_nf(
+ ConnectClient_get_sslFd(srClientsTable[l]),
+ SslFd_get_ssl(
+ ConnectClient_get_sslFd(srRaClientsTable[k])));
+ SslFd_set_ssl_nf(
+ ConnectClient_get_sslFd(srRaClientsTable[k]),
+ tmp_ssl);
+ ConnectClient_set_usrCliPair(
+ srClientsTable[l],
+ ConnectClient_get_usrCliPair(srRaClientsTable[k]));
+ ConnectClient_set_state(srRaClientsTable[k], CONNECTCLIENT_STATE_FREE);
+ break;
+ }
+ }
+ if (l != ServerRealm_get_clientsLimit(pointer)) {
+ ConnectClient_set_state(srClientsTable[l], CONNECTCLIENT_STATE_ACCEPTED);
+ 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] = ConnectClient_get_limit(
+ srClientsTable[l]) >> 8;/* high bits of user number */
+ buff[2] = ConnectClient_get_limit(
+ srClientsTable[l]); /* low bits of user number */
+ buff[3] = ServerRealm_get_realmType(pointer); /* type of connection */
+ SslFd_send_message(ServerRealm_get_realmType(pointer) | TYPE_SSL | TYPE_ZLIB,
+ ConnectClient_get_sslFd(
+ srClientsTable[l]),
+ buff, 5);
+ if ((task = ConnectClient_get_task(srRaClientsTable[k]))) {
+ TaskScheduler_removeTask(scheduler, task);
+ ConnectClient_set_task(srRaClientsTable[k], NULL);
+ }
+ if (ServerRealm_get_maxIdle(pointer)) {
+ ConnectClient_set_timer(srClientsTable[l],
+ timeval_create(ServerRealm_get_maxIdle(pointer), 0));
+ task = Task_new(ConnectClient_get_timerp(srClientsTable[l]),
+ RCTfunction,
+ RCTdata_new(config, j, l, 0, RCT_REASON_MAXIDLE, &allset, &wset),
+ RCTdata_free);
+ ConnectClient_set_task(srClientsTable[l], task);
+ TaskScheduler_addTask(scheduler, task);
+ }
+ if (ServerRealm_get_basePortOn(pointer) == 1) {
+ long tmp_val;
+ char tmp_tab[6];
+ if (check_long(
+ UsrCli_get_listenPortName(
+ srUsersClientsTable[
+ ConnectClient_get_usrCliPair(srClientsTable[l])]),
+ &tmp_val)) {
+ 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, scheduler);
+ break;
+ }
+ tmp_val = tmp_val%65536;
+ memset(tmp_tab, 0, 6);
+ sprintf(tmp_tab, "%d", (int)tmp_val);
+ ipfam = 0x01;
+#ifdef AF_INET6
+ if (TYPE_IS_IPV4(ServerRealm_get_realmType(pointer))) {
+ ipfam |= 0x02;
+ }
+ else if (TYPE_IS_IPV6(ServerRealm_get_realmType(pointer))) {
+ ipfam |= 0x04;
+ }
+#endif
+ while (ip_listen(ConnectClient_get_listenFdp(srClientsTable[l]),
+ UsrCli_get_listenHostName(srUsersClientsTable[
+ ConnectClient_get_usrCliPair(srClientsTable[l])]) ?
+ UsrCli_get_listenHostName(srUsersClientsTable[
+ ConnectClient_get_usrCliPair(srClientsTable[l])]) :
+ ServerRealm_get_hostName(pointer),
+ tmp_tab, (&len), ipfam)) {
+ tmp_val = (tmp_val+1)%65536;
+ memset(tmp_tab, 0, 6);
+ sprintf(tmp_tab, "%d", (int)tmp_val);
+ }
+ ServerRealm_set_addressLength(pointer, len);
+ FD_SET(ConnectClient_get_listenFd(srClientsTable[l]), &allset);
+ maxfdp1 = (maxfdp1>(ConnectClient_get_listenFd(srClientsTable[l])+1)) ?
+ maxfdp1 : (ConnectClient_get_listenFd(srClientsTable[l])+1);
+ 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(LOG_T_CLIENT, LOG_I_WARNING,
+ "realm[%s]: client limit EXCEEDED", get_realmname(config, j));
+ buff[0] = AF_S_CANT_OPEN; /* sending message */
+ SslFd_send_message(ServerRealm_get_realmType(pointer) | TYPE_SSL | TYPE_ZLIB,
+ ConnectClient_get_sslFd(
+ srRaClientsTable[k]),
+ buff, 5);
+ remove_raclient(pointer, k, &allset, &wset, scheduler);
+ }
+ }
+ else if ((ConnectClient_get_state(srRaClientsTable[k]) ==
+ CONNECTCLIENT_STATE_ACCEPTED) && (numofcon == 0)) {
+ n = SslFd_get_message(ServerRealm_get_realmType(pointer),
+ ConnectClient_get_sslFd(
+ srRaClientsTable[k]),
+ buff, length);
+ buff[n] = 0;
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "realm[%s]: Client[%s] (ra): ID received: %s",
+ get_realmname(config, j), get_raclientname(pointer, k), buff);
+ ConnectClient_set_sClientId(srRaClientsTable[k], (char*) buff);
+ }
+ else {
+ 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, scheduler);
+ }
+ break;
+ }
+ case AF_S_WRONG: {
+ 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, scheduler);
+ break;
+ }
+ case AF_S_ADMIN_LOGIN: {
+ if ((ConnectClient_get_state(srRaClientsTable[k]) ==
+ CONNECTCLIENT_STATE_AUTHORIZING) &&
+ (numofcon==(ServerRealm_get_password(pointer)[0]*256+ServerRealm_get_password(pointer)[1])) &&
+ (length==(ServerRealm_get_password(pointer)[2]*256+ServerRealm_get_password(pointer)[3]))) {
+ 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));
+ ConnectClient_set_state(
+ srRaClientsTable[k],
+ CONNECTCLIENT_STATE_ACCEPTED);
+ ServerRealm_increase_connectedRaClients(pointer);
+ if ((task = ConnectClient_get_task(srRaClientsTable[k]))) {
+ TaskScheduler_removeTask(scheduler, task);
+ ConnectClient_set_task(srRaClientsTable[k], NULL);
+ }
+ sprintf((char*) &buff[5], AF_VER("AFSERVER"));
+ n = strlen((char*) &buff[5]);
+ buff[0] = AF_S_ADMIN_LOGIN; /* sending message */
+ buff[1] = ServerRealm_get_realmType(pointer); /* type of connection */
+ buff[2] = AF_RA_UNDEFINED;
+ buff[3] = n >> 8; /* high bits of message length */
+ buff[4] = n; /* low bits of message length */
+ SslFd_send_message(ServerRealm_get_realmType(pointer) | TYPE_SSL | TYPE_ZLIB,
+ ConnectClient_get_sslFd(
+ srRaClientsTable[k]),
+ buff, n+5);
+ }
+ break;
+ }
+ case AF_S_ADMIN_CMD: {
+ if (ConnectClient_get_state(srRaClientsTable[k]) ==
+ CONNECTCLIENT_STATE_ACCEPTED) {
+ 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, scheduler);
+ }
+ else {
+ for (i = 0; i < ServerConfiguration_get_realmsNumber(config); ++i) {
+ srClientsTable = ServerRealm_get_clientsTable(scRealmsTable[i]);
+ l = get_clientnumber(scRealmsTable[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(scRealmsTable[i], l));
+ buff[0] = AF_S_CLOSING; /* closing */
+ SslFd_send_message(ServerRealm_get_realmType(scRealmsTable[i]),
+ ConnectClient_get_sslFd(
+ srClientsTable[l]),
+ 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(scRealmsTable[i], l),
+ ConnectClient_get_nameBuf(srClientsTable[l]),
+ ConnectClient_get_portBuf(srClientsTable[l]),
+ timeperiod(now - ConnectClient_get_connectTime(
+ srClientsTable[l])));
+ if (ServerRealm_get_auditOn(scRealmsTable[i])) {
+ while (AuditList_get_first(
+ ConnectClient_get_auditList(
+ srClientsTable[l]))) {
+ aflog(LOG_T_CLIENT, LOG_I_NOTICE,
+ "USERID: %d IP: %s PORT: %s CONNECTED: %s DURATION: %s",
+ AuditListNode_get_userId(
+ AuditList_get_first(
+ ConnectClient_get_auditList(
+ srClientsTable[l]))),
+ AuditListNode_get_nameBuf(
+ AuditList_get_first(
+ ConnectClient_get_auditList(
+ srClientsTable[l]))),
+ AuditListNode_get_portBuf(
+ AuditList_get_first(
+ ConnectClient_get_auditList(
+ srClientsTable[l]))),
+ localdate(
+ AuditListNode_get_connectTimep(
+ AuditList_get_first(
+ ConnectClient_get_auditList(
+ srClientsTable[l])))),
+ timeperiod(
+ AuditListNode_get_duration(
+ AuditList_get_first(
+ ConnectClient_get_auditList(
+ srClientsTable[l])))));
+ AuditList_delete_first(
+ ConnectClient_get_auditList(
+ srClientsTable[l]));
+ }
+ }
+ remove_client(scRealmsTable[i], l,
+ &allset, &wset, scheduler);
+ break;
+ }
+ }
+ }
+ }
+ }
+ else {
+ 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, scheduler);
+ }
+ 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(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, scheduler);
+ }
+ }
+ }
+ /* ------------------------------------ */
+ for (l = 0; l < ServerRealm_get_userClientPairs(pointer); ++l) {
+ if (FD_ISSET(UsrCli_get_manageFd(srUsersClientsTable[l]), &rset)) {
+
+ aflog(LOG_T_CLIENT, LOG_I_DDEBUG,
+ "realm[%s]: managefd: FD_ISSET", get_realmname(config, j));
+ len = ServerRealm_get_addressLength(pointer);
+#ifdef HAVE_LIBPTHREAD
+ sent = get_new_socket(UsrCli_get_manageFd(srUsersClientsTable[l]),
+ ServerRealm_get_tunnelType(pointer),ServerRealm_get_clientAddress(pointer), &len, &tunneltype);
+#else
+ sent = accept(UsrCli_get_manageFd(srUsersClientsTable[l]), ServerRealm_get_clientAddress(pointer), &len);
+#endif
+ if (sent == -1) {
+ if (errno == EAGAIN) {
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: managefd: FD_ISSET --> EAGAIN", get_realmname(config, j));
+ }
+ else {
+ aflog(LOG_T_USER, LOG_I_DDEBUG,
+ "realm[%s]: managefd: FD_ISSET --> errno=%d", get_realmname(config, j), errno);
+ }
+ break;
+ }
+ flags = fcntl(sent, F_GETFL, 0);
+ fcntl(sent, F_SETFL, flags | O_NONBLOCK);
+ for (k = 0; k < ServerRealm_get_clientsLimit(pointer); ++k) {
+ if (ConnectClient_get_state(srClientsTable[k]) == CONNECTCLIENT_STATE_FREE) {
+ ConnectClient_set_clientId(srClientsTable[k], ServerRealm_get_clientsCounter(pointer));
+ ServerRealm_increase_clientsCounter(pointer);
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "realm[%s]: new Client[%s]: CONNECTING",
+ get_realmname(config, j), get_clientname(pointer, k));
+ SslFd_set_fd(ConnectClient_get_sslFd(srClientsTable[k]), sent);
+ ConnectClient_set_usrCliPair(srClientsTable[k], l);
+ time(&now);
+ ConnectClient_set_connectTime(srClientsTable[k], now);
+ ConnectClient_set_lastActivity(srClientsTable[k], now);
+#ifdef HAVE_LIBPTHREAD
+ ConnectClient_set_tunnelType(srClientsTable[k], 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(ServerRealm_get_clientAddress(pointer), len, ConnectClient_get_nameBuf(srClientsTable[k]),
+ ConnectClient_get_portBuf(srClientsTable[k]), ServerRealm_get_dnsLookupsOn(pointer)));
+ FD_SET(SslFd_get_fd(ConnectClient_get_sslFd(srClientsTable[k])), &allset);
+ maxfdp1 = (maxfdp1 > (SslFd_get_fd(ConnectClient_get_sslFd(srClientsTable[k])) + 1)) ?
+ maxfdp1 : (SslFd_get_fd(ConnectClient_get_sslFd(srClientsTable[k])) + 1);
+ ServerRealm_increase_connectedClients(pointer);
+ ConnectClient_set_timer(srClientsTable[k], timeval_create(ServerRealm_get_timeout(pointer), 0));
+ task = Task_new(ConnectClient_get_timerp(srClientsTable[k]),
+ RCTfunction,
+ RCTdata_new(config, j, k, 0, RCT_REASON_TIMEOUT, &allset, &wset),
+ RCTdata_free);
+ ConnectClient_set_task(srClientsTable[k], task);
+ TaskScheduler_addTask(scheduler, task);
+ ConnectClient_set_state(srClientsTable[k], CONNECTCLIENT_STATE_CONNECTING);
+ break;
+ }
+ }
+ if (k == ServerRealm_get_clientsLimit(pointer)) {
+ for (k = 0; k < ServerRealm_get_raClientsLimit(pointer); ++k) {
+ if (ConnectClient_get_state(srRaClientsTable[k]) ==
+ CONNECTCLIENT_STATE_FREE) {
+ ConnectClient_set_clientId(srRaClientsTable[k], ServerRealm_get_clientsCounter(pointer));
+ ServerRealm_increase_clientsCounter(pointer);
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "realm[%s]: new Client[%s] (ra): CONNECTING",
+ get_realmname(config, j), get_raclientname(pointer, k));
+ SslFd_set_fd(ConnectClient_get_sslFd(srRaClientsTable[k]), sent);
+ ConnectClient_set_usrCliPair(srRaClientsTable[k], l);
+ time(&now);
+ ConnectClient_set_connectTime(srRaClientsTable[k], now);
+ ConnectClient_set_lastActivity(srRaClientsTable[k], now);
+#ifdef HAVE_LIBPTHREAD
+ ConnectClient_set_tunnelType(srRaClientsTable[k], 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(ServerRealm_get_clientAddress(pointer), len,
+ ConnectClient_get_nameBuf(srRaClientsTable[k]),
+ ConnectClient_get_portBuf(srRaClientsTable[k]),
+ ServerRealm_get_dnsLookupsOn(pointer)));
+ FD_SET(SslFd_get_fd(ConnectClient_get_sslFd(srRaClientsTable[k])), &allset);
+ maxfdp1 = (maxfdp1 > (SslFd_get_fd(ConnectClient_get_sslFd(srRaClientsTable[k])) + 1)) ?
+ maxfdp1 : (SslFd_get_fd(ConnectClient_get_sslFd(srRaClientsTable[k])) + 1);
+ ServerRealm_increase_connectedClients(pointer);
+ ConnectClient_set_timer(srRaClientsTable[k],
+ timeval_create(ServerRealm_get_timeout(pointer), 0));
+ task = Task_new(ConnectClient_get_timerp(srRaClientsTable[k]),
+ RCTfunction,
+ RCTdata_new(config, j, k, 1, RCT_REASON_TIMEOUT, &allset, &wset),
+ RCTdata_free);
+ ConnectClient_set_task(srRaClientsTable[k], task);
+ TaskScheduler_addTask(scheduler, task);
+ ConnectClient_set_state(srRaClientsTable[k], CONNECTCLIENT_STATE_CONNECTING);
+ break;
+ }
+ }
+ if (k == ServerRealm_get_raClientsLimit(pointer)) {
+ aflog(LOG_T_CLIENT | LOG_T_MANAGE, LOG_I_WARNING,
+ "realm[%s]: client limit EXCEEDED", get_realmname(config, j));
+ close(sent);
+ }
+ }
+ break;
+ }
+ }
+ } /* realms loop */
+ }
+}
diff --git a/src/afserver.h b/src/afserver.h
new file mode 100644
index 0000000..bc23e75
--- /dev/null
+++ b/src/afserver.h
@@ -0,0 +1,57 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "activefor.h"
+#include "network.h"
+#include "file.h"
+#include "stats.h"
+#include "server_remoteadmin.h"
+#include "server_check.h"
+#include "server_set.h"
+#include "server_eval.h"
+#include "server_find.h"
+#include "server_remove.h"
+#include "make_ssl_handshake.h"
+#include "first_run.h"
+#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 "daemon.h"
+#include "timeval_functions.h"
+#include "remove_client_task.h"
+
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <string.h>
+#include <getopt.h>
+
+#ifndef _JS_AFSERVER_H
+#define _JS_AFSERVER_H
+
+#endif
+
diff --git a/src/ar_options_struct.c b/src/ar_options_struct.c
new file mode 100644
index 0000000..093ddb9
--- /dev/null
+++ b/src/ar_options_struct.c
@@ -0,0 +1,313 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "ar_options_struct.h"
+#include "string_functions.h"
+#include "server_check.h"
+
+/*
+ * Function name: ArOptions_new
+ * Description: Create and initialize new ArOptions structure.
+ * Returns: Pointer to newly created ArOptions structure.
+ */
+
+ArOptions*
+ArOptions_new()
+{
+ ArOptions* tmp = calloc(1, sizeof(ArOptions));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ tmp->premature = AR_OPTION_ENABLED;
+ tmp->delay = 5;
+ tmp->tries = -1;
+ return tmp;
+}
+
+/*
+ * Function name: ArOptions_free
+ * Description: Free the memory allocated for ArOptions structure.
+ * Arguments: ao - pointer to pointer to ArOptions structure
+ */
+
+void
+ArOptions_free(ArOptions** ao)
+{
+ assert(ao != NULL);
+ if (ao == NULL) {
+ return;
+ }
+ assert((*ao) != NULL);
+ if ((*ao) == NULL) {
+ return;
+ }
+ if ((*ao)->artries) {
+ free((*ao)->artries);
+ (*ao)->artries = NULL;
+ }
+ if ((*ao)->ardelay) {
+ free((*ao)->ardelay);
+ (*ao)->ardelay = NULL;
+ }
+ free((*ao));
+ (*ao) = NULL;
+}
+
+/*
+ * Function name: ArOptions_set_asTries
+ * Description: Set how many times afclient will try to reconnect.
+ * Arguments: ao - pointer to ArOptions structure
+ * tries - how many times afclient will try to reconnect
+ * <0 - unlimited
+ * 0 - disabled
+ * >0 - exact number
+ */
+
+void
+ArOptions_set_arTries(ArOptions* ao, int tries)
+{
+ assert(ao != NULL);
+ if (ao == NULL) {
+ return;
+ }
+ ao->tries = tries;
+}
+
+/*
+ * Function name: ArOptions_set_s_arTries
+ * Description: Set string describing how many times afclient will try to reconnect.
+ * This string has to be evaluated later in order to really set arTries value.
+ * Arguments: ao - pointer to ArOptions structure
+ * tries - string describing how many times afclient will try to reconnect.
+ */
+
+void
+ArOptions_set_s_arTries(ArOptions* ao, char* tries)
+{
+ assert(ao != NULL);
+ if (ao == NULL) {
+ return;
+ }
+ string_cp(&(ao->artries), tries);
+}
+
+/*
+ * Function name: ArOptions_set_arDelay
+ * Description: Set how long afclient will wait between reconnect tries.
+ * Arguments: ao - pointer to ArOptions structure
+ * delay - how long afclient will wait between reconnect tries
+ */
+
+void
+ArOptions_set_arDelay(ArOptions* ao, int delay)
+{
+ assert(ao != NULL);
+ if (ao == NULL) {
+ return;
+ }
+ ao->delay = delay;
+}
+
+/*
+ * Function name: ArOptions_set_s_arDelay
+ * Description: Set string describing how long afclient will wait between reconnect tries.
+ * This string has to be evaluated later in order to really set arDelay value.
+ * Arguments: ao - pointer to ArOptions structure
+ * delay - string describing how long afclient will wait between reconnect tries.
+ */
+
+void
+ArOptions_set_s_arDelay(ArOptions* ao, char* delay)
+{
+ assert(ao != NULL);
+ if (ao == NULL) {
+ return;
+ }
+ string_cp(&(ao->ardelay), delay);
+}
+
+/*
+ * Function name: ArOptions_set_arStart
+ * Description: Enable/disable auto-reconnection when afserver is not reachable on start.
+ * Arguments: ao - pointer to ArOptions structure
+ * start - value which enable (AR_OPTION_ENABLED) or disable (AR_OPTION_DISABLED)
+ * auto-reconnection when afserver is not reachable on start
+ */
+
+void
+ArOptions_set_arStart(ArOptions* ao, char start)
+{
+ assert(ao != NULL);
+ if (ao == NULL) {
+ return;
+ }
+ ao->start = start;
+}
+
+/*
+ * Function name: ArOptions_set_arQuit
+ * Description: Enable/disable auto-reconnection after normal afserver quit.
+ * Arguments: ao - pointer to ArOptions structure
+ * quit - value which enable (AR_OPTION_ENABLED) or disable (AR_OPTION_DISABLED)
+ * auto-reconnection after normal afserver quit
+ */
+
+void
+ArOptions_set_arQuit(ArOptions* ao, char quit)
+{
+ assert(ao != NULL);
+ if (ao == NULL) {
+ return;
+ }
+ ao->quit = quit;
+}
+
+/*
+ * Function name: ArOptions_set_arPremature
+ * Description: Enable/disable auto-reconnection after premature afserver quit.
+ * Arguments: ao - pointer to ArOptions structure
+ * premature - value which enable (AR_OPTION_ENABLED) or disable (AR_OPTION_DISABLED)
+ * auto-reconnection after premature afserver quit
+ */
+
+void
+ArOptions_set_arPremature(ArOptions* ao, char premature)
+{
+ assert(ao != NULL);
+ if (ao == NULL) {
+ return;
+ }
+ ao->premature = premature;
+}
+
+/*
+ * Function name: ArOptions_get_arTries
+ * Description: Get how many times afclient will try to reconnect.
+ * Arguments: ao - pointer to ArOptions structure
+ * Returns: How many times afclient will try to reconnect.
+ */
+
+int
+ArOptions_get_arTries(ArOptions* ao)
+{
+ assert(ao != NULL);
+ if (ao == NULL) {
+ return 0;
+ }
+ return ao->tries;
+}
+
+/*
+ * Function name: ArOptions_get_arDelay
+ * Description: Get how long afclient will wait between reconnect tries.
+ * Arguments: ao - pointer to ArOptions structure
+ * Returns: How long afclient will wait between reconnect time.
+ */
+
+int
+ArOptions_get_arDelay(ArOptions* ao)
+{
+ assert(ao != NULL);
+ if (ao == NULL) {
+ return 0;
+ }
+ return ao->delay;
+}
+
+/*
+ * Function name: ArOptions_get_arStart
+ * Description: Get status of the auto-reconnection when afserver is not reachable on start.
+ * Arguments: ao - pointer to ArOptions structure
+ * Returns: Status of the auto-reconnection when afserver is not reachable on start.
+ */
+
+char
+ArOptions_get_arStart(ArOptions* ao)
+{
+ assert(ao != NULL);
+ if (ao == NULL) {
+ return AR_OPTION_DISABLED;
+ }
+ return ao->start;
+}
+
+/*
+ * Function name: ArOptions_get_arQuit
+ * Description: Get status of the auto-reconnection after normal afserver quit.
+ * Arguments: ao - pointer to ArOptions structure
+ * Returns: Status of the auto-reconnection after normal afserver quit.
+ */
+
+char
+ArOptions_get_arQuit(ArOptions* ao)
+{
+ assert(ao != NULL);
+ if (ao == NULL) {
+ return AR_OPTION_DISABLED;
+ }
+ return ao->quit;
+}
+
+/*
+ * Function name: ArOptions_get_arPremature
+ * Description: Get status of the auto-reconnection after premature afserver quit.
+ * Arguments: ao - pointer to ArOptions structure
+ * Returns: Status of the auto-reconnection after premature afserver quit.
+ */
+
+char
+ArOptions_get_arPremature(ArOptions* ao)
+{
+ assert(ao != NULL);
+ if (ao == NULL) {
+ return AR_OPTION_DISABLED;
+ }
+ return ao->premature;
+}
+
+/*
+ * Function name: ArOptions_evaluate_values
+ * Description: Evaluate arTries and arDelay values. These values are checked, when are not NULL.
+ * arTries have to be an integer, arDelay have to be an integer >0. If any of the
+ * variables is wrong, program terminates abnormally.
+ * Arguments: ao - pointer to ArOptions structure
+ */
+
+void
+ArOptions_evaluate_values(ArOptions* ao)
+{
+ assert(ao != NULL);
+ if (ao == NULL) {
+ return;
+ }
+ if (ao->artries) {
+ ao->tries = check_value_liberal(ao->artries, "Invalid ar-tries value");
+ }
+ if (ao->ardelay) {
+ ao->delay = check_value(ao->ardelay, "Invalid ar-delay value");
+ }
+}
diff --git a/src/ar_options_struct.h b/src/ar_options_struct.h
new file mode 100644
index 0000000..2d0c59e
--- /dev/null
+++ b/src/ar_options_struct.h
@@ -0,0 +1,59 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef _JS_AR_OPTIONS_STRUCT_H
+#define _JS_AR_OPTIONS_STRUCT_H
+
+#define AR_OPTION_DISABLED 0
+#define AR_OPTION_ENABLED 1
+
+typedef struct {
+ char* artries;
+ int tries;
+ char* ardelay;
+ int delay;
+ char start;
+ char quit;
+ char premature;
+} ArOptions;
+
+/* 'constructor' */
+ArOptions* ArOptions_new();
+/* 'destructor' */
+void ArOptions_free(ArOptions** ao);
+/* setters */
+void ArOptions_set_arTries(ArOptions* ao, int tries);
+void ArOptions_set_s_arTries(ArOptions* ao, char* tries);
+void ArOptions_set_arDelay(ArOptions* ao, int delay);
+void ArOptions_set_s_arDelay(ArOptions* ao, char* delay);
+void ArOptions_set_arStart(ArOptions* ao, char start);
+void ArOptions_set_arQuit(ArOptions* ao, char quit);
+void ArOptions_set_arPremature(ArOptions* ao, char premature);
+/* getters */
+int ArOptions_get_arTries(ArOptions* ao);
+int ArOptions_get_arDelay(ArOptions* ao);
+char ArOptions_get_arStart(ArOptions* ao);
+char ArOptions_get_arQuit(ArOptions* ao);
+char ArOptions_get_arPremature(ArOptions* ao);
+/* other */
+void ArOptions_evaluate_values(ArOptions* ao);
+
+#endif
diff --git a/src/audit_list_node_struct.c b/src/audit_list_node_struct.c
new file mode 100644
index 0000000..5e7a674
--- /dev/null
+++ b/src/audit_list_node_struct.c
@@ -0,0 +1,316 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "audit_list_node_struct.h"
+
+/*
+ * Function name: AuditListNode_new
+ * Description: Create and initialize new AuditListNode structure.
+ * Returns: Newly created AuditListNode structure.
+ */
+
+AuditListNode*
+AuditListNode_new()
+{
+ AuditListNode* tmp = calloc(1, sizeof(AuditListNode));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ return tmp;
+}
+
+/*
+ * Function name: AuditListNode_new_entry
+ * Description: Create and initialize new AuditListNode structure from given arguments.
+ * Arguments: userId - identification number of the user
+ * nameBuf - name of the user
+ * portBuf - port from which user is connected
+ * connectTime - start time of the connection
+ * duration - duration of the connection
+ * Returns: Newly created and initialized AuditListNode structure.
+ */
+
+AuditListNode*
+AuditListNode_new_entry(int userId, char* nameBuf, char* portBuf,
+ time_t connectTime, time_t duration)
+{
+ AuditListNode* tmp = calloc(1, sizeof(AuditListNode));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ AuditListNode_set_userId(tmp, userId);
+ AuditListNode_set_nameBuf(tmp, nameBuf);
+ AuditListNode_set_portBuf(tmp, portBuf);
+ AuditListNode_set_connectTime(tmp, connectTime);
+ AuditListNode_set_duration(tmp, duration);
+ return tmp;
+}
+
+/*
+ * Function name: AuditListNode_free
+ * Description: Free the memory allocated for AuditListNode structure.
+ * Arguments: aln - pointer to pointer to AuditListNode structure
+ */
+
+void
+AuditListNode_free(AuditListNode** aln)
+{
+ assert(aln != NULL);
+ if (aln == NULL) {
+ return;
+ }
+ assert((*aln) != NULL);
+ if ((*aln) == NULL) {
+ return;
+ }
+ free((*aln));
+ (*aln) = NULL;
+}
+
+/*
+ * Function name: AuditListNode_set_userId
+ * Description: Set user identification number.
+ * Arguments: aln - pointer to AuditListNode structure
+ * userId - user identification number
+ */
+
+void
+AuditListNode_set_userId(AuditListNode* aln, int userId)
+{
+ assert(aln != NULL);
+ if (aln == NULL) {
+ return;
+ }
+ aln->userId = userId;
+}
+
+/*
+ * Function name: AuditListNode_set_nameBuf
+ * Description: Set user name.
+ * Arguments: aln - pointer to AuditListNode structure
+ * nameBuf - user name
+ */
+
+void
+AuditListNode_set_nameBuf(AuditListNode* aln, char* nameBuf)
+{
+ assert(aln != NULL);
+ if (aln == NULL) {
+ return;
+ }
+ memset(aln->nameBuf, 0, 7);
+ strncpy(aln->nameBuf, nameBuf, 6);
+}
+
+/*
+ * Function name: AuditListNode_set_portBuf
+ * Description: Set port from which user is connected.
+ * Arguments: aln - pointer to AuditListNode structure
+ * portBuf - port from which user is connected
+ */
+
+void
+AuditListNode_set_portBuf(AuditListNode* aln, char* portBuf)
+{
+ assert(aln != NULL);
+ if (aln == NULL) {
+ return;
+ }
+ memset(aln->portBuf, 0, 7);
+ strncpy(aln->portBuf, portBuf, 6);
+}
+
+/*
+ * Function name: AuditListNode_set_connectTime
+ * Description: Set start time of the connection.
+ * Arguments: aln - pointer to AuditListNode structure
+ * connectTime - start time of the connection
+ */
+
+void
+AuditListNode_set_connectTime(AuditListNode* aln, time_t connectTime)
+{
+ assert(aln != NULL);
+ if (aln == NULL) {
+ return;
+ }
+ aln->connectTime = connectTime;
+}
+
+/*
+ * Function name: AuditListNode_set_duration
+ * Description: Set duration of the connection.
+ * Arguments: aln - pointer to AuditListNode structure
+ * duration - duration of the connection
+ */
+
+void
+AuditListNode_set_duration(AuditListNode* aln, time_t duration)
+{
+ assert(aln != NULL);
+ if (aln == NULL) {
+ return;
+ }
+ aln->duration = duration;
+}
+
+/*
+ * Function name: AuditListNode_set_nextNode
+ * Description: Set next node pointer.
+ * Arguments: aln - pointer to AuditListNode structure
+ * nextNode - next node pointer
+ */
+
+void
+AuditListNode_set_nextNode(AuditListNode* aln, AuditListNode* nextNode)
+{
+ assert(aln != NULL);
+ if (aln == NULL) {
+ return;
+ }
+ aln->nextNode = nextNode;
+}
+
+/*
+ * Function name: AuditListNode_get_userId
+ * Description: Get user identification number.
+ * Arguments: aln - pointer to AuditListNode structure
+ * Returns: User identification number.
+ */
+
+int
+AuditListNode_get_userId(AuditListNode* aln)
+{
+ assert(aln != NULL);
+ if (aln == NULL) {
+ return -1;
+ }
+ return aln->userId;
+}
+
+/*
+ * Function name: AuditListNode_get_nameBuf
+ * Description: Get user name.
+ * Arguments: aln - pointer to AuditListNode structure
+ * Returns: User name.
+ */
+
+char*
+AuditListNode_get_nameBuf(AuditListNode* aln)
+{
+ assert(aln != NULL);
+ if (aln == NULL) {
+ return NULL;
+ }
+ return aln->nameBuf;
+}
+
+/*
+ * Function name: AuditListNode_get_portBuf
+ * Description: Get port from which user is connected.
+ * Arguments: aln - pointer to AuditListNode structure
+ * Returns: Port from which user is connected.
+ */
+
+char*
+AuditListNode_get_portBuf(AuditListNode* aln)
+{
+ assert(aln != NULL);
+ if (aln == NULL) {
+ return NULL;
+ }
+ return aln->portBuf;
+}
+
+/*
+ * Function name: AuditListNode_get_connectTime
+ * Description: Get start time of the connection.
+ * Arguments: aln - pointer to AuditListNode structure
+ * Returns: Start time of the connection.
+ */
+
+time_t
+AuditListNode_get_connectTime(AuditListNode* aln)
+{
+ assert(aln != NULL);
+ if (aln == NULL) {
+ return 0;
+ }
+ return aln->connectTime;
+}
+
+/*
+ * Function name: AuditListNode_get_duration
+ * Description: Get duration of the connection.
+ * Arguments: aln - pointer to AuditListNode structure
+ * Returns: Duration of the connection.
+ */
+
+time_t
+AuditListNode_get_duration(AuditListNode* aln)
+{
+ assert(aln != NULL);
+ if (aln == NULL) {
+ return 0;
+ }
+ return aln->duration;
+}
+
+/*
+ * Function name: AuditListNode_get_nextNode
+ * Description: Get next node pointer.
+ * Arguments: aln - pointer to AuditListNode structure
+ * Returns: Next node pointer.
+ */
+
+AuditListNode*
+AuditListNode_get_nextNode(AuditListNode* aln)
+{
+ assert(aln != NULL);
+ if (aln == NULL) {
+ return NULL;
+ }
+ return aln->nextNode;
+}
+
+/*
+ * Function name: AuditListNode_get_connectTimep
+ * Description: Get pointer to time_t variable holding start time of the connection.
+ * Arguments: aln - pointer to AuditListNode structure
+ * Returns: Pointer to time_t variable holding start time of the connection.
+ */
+
+time_t*
+AuditListNode_get_connectTimep(AuditListNode* aln)
+{
+ assert(aln != NULL);
+ if (aln == NULL) {
+ return 0;
+ }
+ return (&(aln->connectTime));
+}
diff --git a/src/audit_list_node_struct.h b/src/audit_list_node_struct.h
new file mode 100644
index 0000000..37c085c
--- /dev/null
+++ b/src/audit_list_node_struct.h
@@ -0,0 +1,58 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <time.h>
+
+#ifndef _JS_AUDIT_LIST_NODE_STRUCT_H
+#define _JS_AUDIT_LIST_NODE_STRUCT_H
+
+typedef struct alnode {
+ int userId;
+ char nameBuf[128];
+ char portBuf[7];
+ time_t connectTime;
+ time_t duration;
+ struct alnode* nextNode;
+} AuditListNode;
+
+/* 'constructors' */
+AuditListNode* AuditListNode_new();
+AuditListNode* AuditListNode_new_entry(int userId, char* nameBuf, char* portBuf,
+ time_t connectTime, time_t duration);
+/* 'destructor' */
+void AuditListNode_free(AuditListNode** aln);
+/* setters */
+void AuditListNode_set_userId(AuditListNode* aln, int userId);
+void AuditListNode_set_nameBuf(AuditListNode* aln, char* nameBuf);
+void AuditListNode_set_portBuf(AuditListNode* aln, char* portBuf);
+void AuditListNode_set_connectTime(AuditListNode* aln, time_t connectTime);
+void AuditListNode_set_duration(AuditListNode* aln, time_t duration);
+void AuditListNode_set_nextNode(AuditListNode* aln, AuditListNode* nextNode);
+/* getters */
+int AuditListNode_get_userId(AuditListNode* aln);
+char* AuditListNode_get_nameBuf(AuditListNode* aln);
+char* AuditListNode_get_portBuf(AuditListNode* aln);
+time_t AuditListNode_get_connectTime(AuditListNode* aln);
+time_t AuditListNode_get_duration(AuditListNode* aln);
+AuditListNode* AuditListNode_get_nextNode(AuditListNode* aln);
+/* other */
+time_t* AuditListNode_get_connectTimep(AuditListNode* aln);
+
+#endif
diff --git a/src/audit_list_struct.c b/src/audit_list_struct.c
new file mode 100644
index 0000000..dca58d3
--- /dev/null
+++ b/src/audit_list_struct.c
@@ -0,0 +1,152 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "audit_list_struct.h"
+
+/*
+ * Function name: AuditList_new
+ * Description: Create and initialize new AuditList structure.
+ * Returns: Newly created AuditList structure.
+ */
+
+AuditList*
+AuditList_new()
+{
+ AuditList* tmp = calloc(1, sizeof(AuditList));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ return tmp;
+}
+
+/*
+ * Function name: AuditList_free
+ * Description: Free the memory allocated for AuditList structure.
+ * Arguments: al - pointer to pointer to AuditList structure.
+ */
+
+void
+AuditList_free(AuditList** al)
+{
+ assert(al != NULL);
+ if (al == NULL) {
+ return;
+ }
+ assert((*al) != NULL);
+ if ((*al) == NULL) {
+ return;
+ }
+ AuditList_clear((*al));
+ free((*al));
+ (*al) = NULL;
+}
+
+/*
+ * Function name: AuditList_insert_back
+ * Description: Insert new node at the end of the list.
+ * Arguments: al - pointer to AuditList structure
+ * aln - pointer to AuditListNode structure
+ */
+
+void
+AuditList_insert_back(AuditList* al, AuditListNode* aln)
+{
+ assert(al != NULL);
+ if (al == NULL) {
+ return;
+ }
+ assert(aln != NULL);
+ if (aln == NULL) {
+ return;
+ }
+ if (al->tail) {
+ al->tail->nextNode = aln;
+ }
+ else {
+ al->head = aln;
+ }
+ al->tail = aln;
+ aln->nextNode = NULL;
+}
+
+/*
+ * Function name: AuditList_get_first
+ * Description: Get first node from the beginning of the list.
+ * Arguments: al - pointer to AuditList structure
+ * Returns: First node from the beginning of the list.
+ */
+
+AuditListNode*
+AuditList_get_first(AuditList* al)
+{
+ assert(al != NULL);
+ if (al == NULL) {
+ return NULL;
+ }
+ return al->head;
+}
+
+/*
+ * Function name: AuditList_delete_first
+ * Description: Deletes first node from the beginning of the list.
+ * Arguments: al - pointer to AuditList structure
+ */
+
+void
+AuditList_delete_first(AuditList* al)
+{
+ AuditListNode* tmp = AuditList_get_first(al);
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return;
+ }
+ if (tmp == al->tail) { /* this is the last node in the list */
+ al->head = al->tail = NULL;
+ }
+ else { /* there are other nodes*/
+ al->head = AuditListNode_get_nextNode(tmp);
+ }
+ AuditListNode_free(&tmp);
+}
+
+/*
+ * Function name: AuditList_clear
+ * Description: Deletes all nodes from the list.
+ * Arguments: al - pointer to AuditList structure
+ */
+
+void
+AuditList_clear(AuditList* al)
+{
+ assert(al != NULL);
+ if (al == NULL) {
+ return;
+ }
+ while (AuditList_get_first(al)) {
+ AuditList_delete_first(al);
+ }
+}
diff --git a/src/audit_list_struct.h b/src/audit_list_struct.h
new file mode 100644
index 0000000..c70f510
--- /dev/null
+++ b/src/audit_list_struct.h
@@ -0,0 +1,41 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_AUDIT_LIST_STRUCT_H
+#define _JS_AUDIT_LIST_STRUCT_H
+
+#include "audit_list_node_struct.h"
+
+typedef struct auditlist {
+ AuditListNode* head;
+ AuditListNode* tail;
+} AuditList;
+
+/* 'constructor' */
+AuditList* AuditList_new();
+/* 'destructor' */
+void AuditList_free(AuditList** al);
+/* other */
+void AuditList_insert_back(AuditList* al, AuditListNode* aln);
+AuditListNode* AuditList_get_first(AuditList* al);
+void AuditList_delete_first(AuditList* al);
+void AuditList_clear(AuditList* al);
+
+#endif
diff --git a/src/base64.c b/src/base64.c
new file mode 100644
index 0000000..42eb42c
--- /dev/null
+++ b/src/base64.c
@@ -0,0 +1,250 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "base64.h"
+
+/*
+ * Copyright (c) 1996, 1998 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software. No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+static const char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static const char Pad64 = '=';
+
+int
+b64_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize)
+{
+ size_t datalength = 0;
+ uint8_t input[3];
+ uint8_t output[4];
+ size_t i;
+
+ while (2 < srclength) {
+ input[0] = *src++;
+ input[1] = *src++;
+ input[2] = *src++;
+ srclength -= 3;
+
+ output[0] = input[0] >> 2;
+ output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+ output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+ output[3] = input[2] & 0x3f;
+ if (output[0] >= 64) return -1;
+ if (output[1] >= 64) return -1;
+ if (output[2] >= 64) return -1;
+ if (output[3] >= 64) return -1;
+
+ if (datalength + 4 > targsize)
+ return (-1);
+ target[datalength++] = Base64[output[0]];
+ target[datalength++] = Base64[output[1]];
+ target[datalength++] = Base64[output[2]];
+ target[datalength++] = Base64[output[3]];
+ }
+
+ /* Now we worry about padding. */
+ if (0 != srclength) {
+ /* Get what's left. */
+ input[0] = input[1] = input[2] = (uint8_t) '\0';
+ for (i = 0; i < srclength; i++)
+ input[i] = *src++;
+
+ output[0] = input[0] >> 2;
+ output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+ output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+ if (output[0] >= 64) return -1;
+ if (output[1] >= 64) return -1;
+ if (output[2] >= 64) return -1;
+
+ if (datalength + 4 > targsize)
+ return (-1);
+ target[datalength++] = Base64[output[0]];
+ target[datalength++] = Base64[output[1]];
+ if (srclength == 1)
+ target[datalength++] = Pad64;
+ else
+ target[datalength++] = Base64[output[2]];
+ target[datalength++] = Pad64;
+ }
+ if (datalength >= targsize)
+ return (-1);
+ target[datalength] = '\0'; /* Returned value doesn't count \0. */
+ return (int) (datalength);
+}
+
+int
+b64_pton(char const *src, uint8_t *target, size_t targsize)
+{
+ int tarindex, state, ch;
+ char *pos;
+
+ state = 0;
+ tarindex = 0;
+
+ while ((ch = *src++) != '\0') {
+ if (isspace((unsigned char)ch)) /* Skip whitespace anywhere. */
+ continue;
+
+ if (ch == Pad64)
+ break;
+
+ pos = strchr(Base64, ch);
+ if (pos == 0) {
+ /* A non-base64 character. */
+ return (-1);
+ }
+
+ switch (state) {
+ case 0:
+ if (target) {
+ if ((size_t)tarindex >= targsize)
+ return (-1);
+ target[tarindex] = (pos - Base64) << 2;
+ }
+ state = 1;
+ break;
+ case 1:
+ if (target) {
+ if ((size_t)tarindex + 1 >= targsize)
+ return (-1);
+ target[tarindex] |= (pos - Base64) >> 4;
+ target[tarindex+1] = ((pos - Base64) & 0x0f)
+ << 4 ;
+ }
+ tarindex++;
+ state = 2;
+ break;
+ case 2:
+ if (target) {
+ if ((size_t)tarindex + 1 >= targsize)
+ return (-1);
+ target[tarindex] |= (pos - Base64) >> 2;
+ target[tarindex+1] = ((pos - Base64) & 0x03)
+ << 6;
+ }
+ tarindex++;
+ state = 3;
+ break;
+ case 3:
+ if (target) {
+ if ((size_t)tarindex >= targsize)
+ return (-1);
+ target[tarindex] |= (pos - Base64);
+ }
+ tarindex++;
+ state = 0;
+ break;
+ default:
+ abort();
+ }
+ }
+
+ /*
+ * We are done decoding Base-64 chars. Let's see if we ended
+ * on a byte boundary, and/or with erroneous trailing characters.
+ */
+
+ if (ch == Pad64) { /* We got a pad char. */
+ ch = *src++; /* Skip it, get next. */
+ switch (state) {
+ case 0: /* Invalid = in first position */
+ case 1: /* Invalid = in second position */
+ return (-1);
+
+ case 2: /* Valid, means one byte of info */
+ /* Skip any number of spaces. */
+ for ((void)NULL; ch != '\0'; ch = *src++)
+ if (!isspace((unsigned char)ch))
+ break;
+ /* Make sure there is another trailing = sign. */
+ if (ch != Pad64)
+ return (-1);
+ ch = *src++; /* Skip the = */
+ /* Fall through to "single trailing =" case. */
+ /* FALLTHROUGH */
+
+ case 3: /* Valid, means two bytes of info */
+ /*
+ * We know this char is an =. Is there anything but
+ * whitespace after it?
+ */
+ for ((void)NULL; ch != '\0'; ch = *src++)
+ if (!isspace((unsigned char)ch))
+ return (-1);
+
+ /*
+ * Now make sure for cases 2 and 3 that the "extra"
+ * bits that slopped past the last full byte were
+ * zeros. If we don't check them, they become a
+ * subliminal channel.
+ */
+ if (target && target[tarindex] != 0)
+ return (-1);
+ }
+ } else {
+ /*
+ * We ended by seeing the end of the string. Make sure we
+ * have no partial bytes lying around.
+ */
+ if (state != 0)
+ return (-1);
+ }
+
+ return (tarindex);
+}
diff --git a/src/base64.h b/src/base64.h
new file mode 100644
index 0000000..442b550
--- /dev/null
+++ b/src/base64.h
@@ -0,0 +1,41 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef _JS_BASE64_H
+#define _JS_BASE64_H
+
+/* routine to encode src with base64 algorithm */
+int b64_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize);
+/* routine to decode src with base64 algorithm */
+int b64_pton(char const *src, uint8_t *target, size_t targsize);
+
+#endif
diff --git a/src/buf_list_node_struct.c b/src/buf_list_node_struct.c
new file mode 100644
index 0000000..5416ce3
--- /dev/null
+++ b/src/buf_list_node_struct.c
@@ -0,0 +1,289 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "buf_list_node_struct.h"
+
+/*
+ * Function name: BufListNode_new
+ * Description: Creates and initializes new BufListNode structure.
+ * Returns: Newly created BufListNode structure.
+ */
+
+BufListNode*
+BufListNode_new()
+{
+ BufListNode* tmp = calloc(1, sizeof(BufListNode));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ return tmp;
+}
+
+/*
+ * Function name: BufListNode_new_message
+ * Description: Create and initialize new BufListNode structure from given message
+ * with actual buffer pointer and message length.
+ * Arguments: actPtr - actual buffer pointer
+ * msgLen - length of the message
+ * message - message to be stored
+ * Returns: Newly created and initialized BufListNode structure.
+ */
+
+BufListNode*
+BufListNode_new_message(int actPtr, int msgLen, unsigned char* message)
+{
+ BufListNode* tmp = calloc(1, sizeof(BufListNode));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ BufListNode_set_message(tmp, message, msgLen);
+ BufListNode_set_actPtr(tmp, actPtr);
+ return tmp;
+}
+
+/*
+ * Function name: BufListNode_free
+ * Description: Frees the memory allocated for BufListNode structure.
+ * Arguments: bln - pointer to pointer to BufListNode structure
+ */
+
+void
+BufListNode_free(BufListNode** bln)
+{
+ assert(bln != NULL);
+ if (bln == NULL) {
+ return;
+ }
+ assert((*bln) != NULL);
+ if ((*bln) == NULL) {
+ return;
+ }
+ if ((*bln)->message) {
+ free((*bln)->message);
+ (*bln)->message = NULL;
+ }
+ free((*bln));
+ (*bln) = NULL;
+}
+
+/*
+ * Function name: BufListNode_set_actPtr
+ * Description: Sets actual buffer pointer.
+ * Arguments: bln - pointer to BufListNode structure
+ * actPtr - actual buffer pointer
+ */
+
+void
+BufListNode_set_actPtr(BufListNode* bln, int actPtr)
+{
+ assert(bln != NULL);
+ if (bln == NULL) {
+ return;
+ }
+ bln->actPtr = actPtr;
+}
+
+/*
+ * Function name: BufListNode_set_msgLen
+ * Description: Sets length of the message.
+ * Arguments: bln - pointer to BufListNode structure
+ * msgLen - length of the message
+ */
+
+void
+BufListNode_set_msgLen(BufListNode* bln, int msgLen)
+{
+ assert(bln != NULL);
+ if (bln == NULL) {
+ return;
+ }
+ bln->msgLen = msgLen;
+}
+
+/*
+ * Function name: BufListNode_set_message
+ * Description: Sets message to be stored.
+ * Arguments: bln - pointer to BufListNode structure
+ * message - message to be stored
+ * msgLen - length of the message
+ */
+
+void
+BufListNode_set_message(BufListNode* bln, unsigned char* message, int msgLen)
+{
+ assert(bln != NULL);
+ if (bln == NULL) {
+ return;
+ }
+ if (bln->message) {
+ free(bln->message);
+ bln->message = NULL;
+ }
+ BufListNode_set_actPtr(bln, 0);
+ BufListNode_set_msgLen(bln, 0);
+ assert(message != NULL);
+ if (message == NULL) {
+ return;
+ }
+ bln->message = calloc(1, msgLen);
+ assert(bln->message != NULL);
+ if (bln->message == NULL) {
+ return;
+ }
+ memcpy(bln->message, message, msgLen);
+ BufListNode_set_msgLen(bln, msgLen);
+}
+
+/*
+ * Function name: BufListNode_set_nextNode
+ * Description: Sets next node pointer.
+ * Arguments: bln - pointer to BufListNode structure
+ * nextNode - next node pointer
+ */
+
+void
+BufListNode_set_nextNode(BufListNode* bln, BufListNode* nextNode)
+{
+ assert(bln != NULL);
+ if (bln == NULL) {
+ return;
+ }
+ bln->nextNode = nextNode;
+}
+
+/*
+ * Function name: BufListNode_get_actPtr
+ * Description: Gets actual buffer pointer.
+ * Aguments: bln - pointer to BufListNode structure
+ * Returns: Actual buffer pointer.
+ */
+
+int
+BufListNode_get_actPtr(BufListNode* bln)
+{
+ assert(bln != NULL);
+ if (bln == NULL) {
+ return -1;
+ }
+ return bln->actPtr;
+}
+
+/*
+ * Function name: BufListNode_get_msgLen
+ * Description: Gets length of the message.
+ * Arguments: bln - pointer to BufListNode structure
+ * Returns: Length of the message.
+ */
+
+int
+BufListNode_get_msgLen(BufListNode* bln)
+{
+ assert(bln != NULL);
+ if (bln == NULL) {
+ return -1;
+ }
+ return bln->msgLen;
+}
+
+/*
+ * Function name: BufListNode_get_message
+ * Description: Gets stored message.
+ * Arguments: bln - pointer to BufListNode structure
+ * Returns: Stored message.
+ */
+
+unsigned char*
+BufListNode_get_message(BufListNode* bln)
+{
+ assert(bln != NULL);
+ if (bln == NULL) {
+ return NULL;
+ }
+ return bln->message;
+}
+
+/*
+ * Function name: BufListNode_get_nextNode
+ * Description: Gets next node pointer.
+ * Arguments: bln - pointer to BufListNode structure
+ * Returns: Next BufListNode structure pointer or NULL, if there is no next one.
+ */
+
+BufListNode*
+BufListNode_get_nextNode(BufListNode* bln)
+{
+ assert(bln != NULL);
+ if (bln == NULL) {
+ return NULL;
+ }
+ return bln->nextNode;
+}
+
+/*
+ * Function name: BufListNode_readMessage
+ * Description: Reads the message from actual buffer pointer.
+ * Arguments: bln - pointer to BufListNode structure
+ * Returns: Tail of the message from actual buffer pointer.
+ */
+
+unsigned char*
+BufListNode_readMessage(BufListNode* bln)
+{
+ assert(bln != NULL);
+ if (bln == NULL) {
+ return NULL;
+ }
+ return (&bln->message[BufListNode_get_actPtr(bln)]);
+}
+
+/*
+ * Function name: BufListNode_readMessageLength
+ * Description: Gets the amount of unread bytes in the message.
+ * Arguments: bln - pointer to BufListNode structure
+ * Returns: The amount of unread bytes in the message.
+ */
+
+int
+BufListNode_readMessageLength(BufListNode* bln)
+{
+ int tmp = 0;
+ assert(bln != NULL);
+ if (bln == NULL) {
+ return -1;
+ }
+ assert(BufListNode_get_message(bln) != NULL);
+ if (BufListNode_get_message(bln) == NULL) {
+ return -1;
+ }
+ tmp = BufListNode_get_msgLen(bln) - BufListNode_get_actPtr(bln);
+ assert(tmp >= 0);
+ if (tmp < 0) {
+ return 0;
+ }
+ return tmp;
+}
diff --git a/src/buf_list_node_struct.h b/src/buf_list_node_struct.h
new file mode 100644
index 0000000..08a4cfb
--- /dev/null
+++ b/src/buf_list_node_struct.h
@@ -0,0 +1,50 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_BUF_LIST_NODE_STRUCT_H
+#define _JS_BUF_LIST_NODE_STRUCT_H
+
+typedef struct blnode {
+ int actPtr;
+ int msgLen;
+ unsigned char* message;
+ struct blnode* nextNode;
+} BufListNode;
+
+/* 'constructors' */
+BufListNode* BufListNode_new();
+BufListNode* BufListNode_new_message(int actPtr, int msgLen, unsigned char* message);
+/* 'destructor' */
+void BufListNode_free(BufListNode** bln);
+/* setters */
+void BufListNode_set_actPtr(BufListNode* bln, int actPtr);
+void BufListNode_set_msgLen(BufListNode* bln, int msgLen);
+void BufListNode_set_message(BufListNode* bln, unsigned char* message, int msgLen);
+void BufListNode_set_nextNode(BufListNode* bln, BufListNode* nextNode);
+/* getters */
+int BufListNode_get_actPtr(BufListNode* bln);
+int BufListNode_get_msgLen(BufListNode* bln);
+unsigned char* BufListNode_get_message(BufListNode* bln);
+BufListNode* BufListNode_get_nextNode(BufListNode* bln);
+/* other methods */
+unsigned char* BufListNode_readMessage(BufListNode* bln);
+int BufListNode_readMessageLength(BufListNode* bln);
+
+#endif
diff --git a/src/buf_list_struct.c b/src/buf_list_struct.c
new file mode 100644
index 0000000..cbdbe09
--- /dev/null
+++ b/src/buf_list_struct.c
@@ -0,0 +1,152 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "buf_list_struct.h"
+
+/*
+ * Function name: BufList_new
+ * Description: Creates and initializes new BufList structure.
+ * Returns: Newly created BufList structure.
+ */
+
+BufList*
+BufList_new()
+{
+ BufList* tmp = calloc(1, sizeof(BufList));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ return tmp;
+}
+
+/*
+ * Function name: BufList_free
+ * Description: Frees the memory allocated for BufList structure.
+ * Arguments: bl - pointer to pointer to BufList structure.
+ */
+
+void
+BufList_free(BufList** bl)
+{
+ assert(bl != NULL);
+ if (bl == NULL) {
+ return;
+ }
+ assert((*bl) != NULL);
+ if ((*bl) == NULL) {
+ return;
+ }
+ BufList_clear((*bl));
+ free((*bl));
+ (*bl) = NULL;
+}
+
+/*
+ * Function name: BufList_insert_back
+ * Description: Inserts new node at the end of the list.
+ * Arguments: bl - pointer to BufList structure
+ * bln - pointer to BufListNode structure
+ */
+
+void
+BufList_insert_back(BufList* bl, BufListNode* bln)
+{
+ assert(bl != NULL);
+ if (bl == NULL) {
+ return;
+ }
+ assert(bln != NULL);
+ if (bln == NULL) {
+ return;
+ }
+ if (bl->tail) {
+ bl->tail->nextNode = bln;
+ }
+ else {
+ bl->head = bln;
+ }
+ bl->tail = bln;
+ bln->nextNode = NULL;
+}
+
+/*
+ * Function name: BufList_get_first
+ * Description: Get first node from the beginning of the list.
+ * Arguments: bl - pointer to BufList structure
+ * Returns: First node from the beginning of the list.
+ */
+
+BufListNode*
+BufList_get_first(BufList* bl)
+{
+ assert(bl != NULL);
+ if (bl == NULL) {
+ return NULL;
+ }
+ return bl->head;
+}
+
+/*
+ * Function name: BufList_delete_first
+ * Description: Deletes first node from the beginning of the list.
+ * Arguments: bl - pointer to BufList structure
+ */
+
+void
+BufList_delete_first(BufList* bl)
+{
+ BufListNode* tmp = BufList_get_first(bl);
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return;
+ }
+ if (tmp == bl->tail) { /* this is the last node in the list */
+ bl->head = bl->tail = NULL;
+ }
+ else { /* there are other nodes*/
+ bl->head = BufListNode_get_nextNode(tmp);
+ }
+ BufListNode_free(&tmp);
+}
+
+/*
+ * Function name: BufList_clear
+ * Description: Deletes all nodes from the list.
+ * Arguments: bl - pointer to BufList structure
+ */
+
+void
+BufList_clear(BufList* bl)
+{
+ assert(bl != NULL);
+ if (bl == NULL) {
+ return;
+ }
+ while (BufList_get_first(bl)) {
+ BufList_delete_first(bl);
+ }
+}
diff --git a/src/buf_list_struct.h b/src/buf_list_struct.h
new file mode 100644
index 0000000..d2bce00
--- /dev/null
+++ b/src/buf_list_struct.h
@@ -0,0 +1,41 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_BUF_LIST_STRUCT_H
+#define _JS_BUF_LIST_STRUCT_H
+
+#include "buf_list_node_struct.h"
+
+typedef struct buflist {
+ BufListNode* head;
+ BufListNode* tail;
+} BufList;
+
+/* 'constructor' */
+BufList* BufList_new();
+/* 'destructor' */
+void BufList_free(BufList** bl);
+/* other */
+void BufList_insert_back(BufList* bl, BufListNode* bln);
+BufListNode* BufList_get_first(BufList* bl);
+void BufList_delete_first(BufList* bl);
+void BufList_clear(BufList* bl);
+
+#endif
diff --git a/src/client_configuration_struct.c b/src/client_configuration_struct.c
new file mode 100644
index 0000000..6edb6f1
--- /dev/null
+++ b/src/client_configuration_struct.c
@@ -0,0 +1,336 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "string_functions.h"
+#include "client_configuration_struct.h"
+
+/*
+ * Function name: ClientConfiguration_new
+ * Description: Create and initialize new ClientConfiguration structure.
+ * Returns: Pointer to newly created ClientConfiguration structure.
+ */
+
+ClientConfiguration*
+ClientConfiguration_new()
+{
+ ClientConfiguration* tmp = calloc(1, sizeof(ClientConfiguration));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ return tmp;
+}
+
+/*
+ * Function name: ClientConfiguration_free
+ * Description: Free the memory allocated for ClientConfiguration structure.
+ * Arguments: cc - pointer to pointer to ClientConfiguration structure
+ */
+
+void
+ClientConfiguration_free(ClientConfiguration** cc)
+{
+ int i;
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ assert((*cc) != NULL);
+ if ((*cc) == NULL) {
+ return;
+ }
+ if ((*cc)->keysFile) {
+ free((*cc)->keysFile);
+ (*cc)->keysFile = NULL;
+ }
+ if ((*cc)->certificateFile) {
+ free((*cc)->certificateFile);
+ (*cc)->certificateFile = NULL;
+ }
+ if ((*cc)->storeFile) {
+ free((*cc)->storeFile);
+ (*cc)->storeFile = NULL;
+ }
+ if ((*cc)->realmsTable) {
+ for (i = 0; i < (*cc)->realmsNumber; ++i) {
+ if ((*cc)->realmsTable[i]) {
+ ClientRealm_free(&((*cc)->realmsTable[i]));
+ }
+ }
+ free((*cc)->realmsTable);
+ (*cc)->realmsTable = NULL;
+ }
+ free((*cc));
+ (*cc) = NULL;
+}
+
+/*
+ * Function name: ClientConfiguration_set_keysFile
+ * Description: Set keys filename.
+ * Arguments: cc - pointer to ClientConfiguration structure
+ * keysFile - keys filename
+ */
+
+void
+ClientConfiguration_set_keysFile(ClientConfiguration* cc, char* keysFile)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ string_cp(&(cc->keysFile), keysFile);
+}
+
+/*
+ * Function name: ClientConfiguration_set_certificateFile
+ * Description: Set certs filename.
+ * Arguments: cc - pointer to ClientConfiguration structure
+ * certificateFile - certs filename
+ */
+
+void
+ClientConfiguration_set_certificateFile(ClientConfiguration* cc, char* certificateFile)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ string_cp(&(cc->certificateFile), certificateFile);
+}
+
+/*
+ * Function name: ClientConfiguration_set_storeFile
+ * Description: Set store filename.
+ * Arguments: cc - pointer to ClientConfiguration structure
+ * storeFile - store filename
+ */
+
+void
+ClientConfiguration_set_storeFile(ClientConfiguration* cc, char* storeFile)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ string_cp(&(cc->storeFile), storeFile);
+}
+
+/*
+ * Function name: ClientConfiguration_set_dateFormat
+ * Description: Set format of the date string.
+ * Arguments: cc - pointer to ClientConfiguration structure
+ * dateFormat - format of the date string
+ */
+
+void
+ClientConfiguration_set_dateFormat(ClientConfiguration* cc, char* dateFormat)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ string_cp(&(cc->dateFormat), dateFormat);
+}
+
+/*
+ * Function name: ClientConfiguration_set_realmsNumber
+ * Description: Set number of realms.
+ * Arguments: cc - pointer to ClientConfiguration structure
+ * realmsNumber - number of realms
+ */
+
+void
+ClientConfiguration_set_realmsNumber(ClientConfiguration* cc, int realmsNumber)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ cc->realmsNumber = realmsNumber;
+}
+
+/*
+ * Function name: ClientConfiguration_set_realmsTable
+ * Description: Set table of realms.
+ * Arguments: cc - pointer to ClientConfiguration structure
+ * realmsTable - table of realms
+ */
+
+void
+ClientConfiguration_set_realmsTable(ClientConfiguration* cc, ClientRealm** realmsTable)
+{
+ int i;
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ if (cc->realmsTable) {
+ for (i = 0; i < cc->realmsNumber; ++i) {
+ if (cc->realmsTable[i]) {
+ ClientRealm_free(&(cc->realmsTable[i]));
+ }
+ }
+ free(cc->realmsTable);
+ cc->realmsTable = NULL;
+ }
+ cc->realmsTable = realmsTable;
+}
+
+/*
+ * Function name: ClientConfiguration_set_ignorePublicKeys
+ * Description: Enable/disable the public keys checking.
+ * Arguments: cc - pointer to ClientConfiguration structure
+ * ignorePublicKeys - if the public keys checking is enabled/disabled
+ */
+
+void
+ClientConfiguration_set_ignorePublicKeys(ClientConfiguration* cc, char ignorePublicKeys)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ cc->ignorePublicKeys = ignorePublicKeys;
+}
+
+/*
+ * Function name: ClientConfiguration_get_keysFile
+ * Description: Get keys filename.
+ * Arguments: cc - pointer to ClientConfiguration structure
+ * Returns: Keys filename.
+ */
+
+char*
+ClientConfiguration_get_keysFile(ClientConfiguration* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return NULL;
+ }
+ return cc->keysFile;
+}
+
+/*
+ * Function name: ClientConfiguration_get_certificateFile
+ * Description: Get certs filename.
+ * Arguments: cc - pointer to ClientConfiguration structure
+ * Returns: Certs filename.
+ */
+
+char*
+ClientConfiguration_get_certificateFile(ClientConfiguration* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return NULL;
+ }
+ return cc->certificateFile;
+}
+
+/*
+ * Function name: ClientConfiguration_get_storeFile
+ * Description: Get store filename.
+ * Arguments: cc - pointer to ClientConfiguration structure
+ * Returns: Store filename.
+ */
+
+char*
+ClientConfiguration_get_storeFile(ClientConfiguration* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return NULL;
+ }
+ return cc->storeFile;
+}
+
+/*
+ * Function name: ClientConfiguration_get_dateFormat
+ * Description: Get format of the date string.
+ * Arguments: cc - pointer to ClientConfiguration structure
+ * Returns: Format of the date string.
+ */
+
+char*
+ClientConfiguration_get_dateFormat(ClientConfiguration* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return NULL;
+ }
+ return cc->dateFormat;
+}
+
+/*
+ * Function name: ClientConfiguration_get_realmsNumber
+ * Description: Get number of realms.
+ * Arguments: cc - pointer to ClientConfiguration structure
+ * Returns: Number of realms.
+ */
+
+int
+ClientConfiguration_get_realmsNumber(ClientConfiguration* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return -1;
+ }
+ return cc->realmsNumber;
+}
+
+/*
+ * Function name: ClientConfiguration_get_realmsTable
+ * Description: Get table of realms.
+ * Arguments: cc - pointer to ClientConfiguration structure
+ * Returns: Table of realms.
+ */
+
+ClientRealm**
+ClientConfiguration_get_realmsTable(ClientConfiguration* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return NULL;
+ }
+ return cc->realmsTable;
+}
+
+/*
+ * Function name: ClientConfiguration_get_ignorePublicKeys
+ * Description: Check if the public keys checking is enabled/disabled
+ * Arguments: cc - pointer to ClientConfiguration structure
+ * Returns: If the public keys checking is enabled/disabled.
+ */
+
+char
+ClientConfiguration_get_ignorePublicKeys(ClientConfiguration* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return 0;
+ }
+ return cc->ignorePublicKeys;
+}
diff --git a/src/client_configuration_struct.h b/src/client_configuration_struct.h
new file mode 100644
index 0000000..15e590d
--- /dev/null
+++ b/src/client_configuration_struct.h
@@ -0,0 +1,58 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef _JS_CLIENT_CONFIGURATION_STRUCT_H
+#define _JS_CLIENT_CONFIGURATION_STRUCT_H
+
+#include "client_realm_struct.h"
+
+typedef struct {
+ char* keysFile;
+ char* certificateFile;
+ char* storeFile;
+ char* dateFormat;
+ int realmsNumber;
+ char ignorePublicKeys;
+ ClientRealm** realmsTable;
+} ClientConfiguration;
+
+/* 'constructor' */
+ClientConfiguration* ClientConfiguration_new();
+/* 'destructor' */
+void ClientConfiguration_free(ClientConfiguration** cc);
+/* setters */
+void ClientConfiguration_set_keysFile(ClientConfiguration* cc, char* keysFile);
+void ClientConfiguration_set_certificateFile(ClientConfiguration* cc, char* certificateFile);
+void ClientConfiguration_set_storeFile(ClientConfiguration* cc, char* storeFile);
+void ClientConfiguration_set_dateFormat(ClientConfiguration* cc, char* dateFormat);
+void ClientConfiguration_set_realmsNumber(ClientConfiguration* cc, int realmsNumber);
+void ClientConfiguration_set_realmsTable(ClientConfiguration* cc, ClientRealm** realmsTable);
+void ClientConfiguration_set_ignorePublicKeys(ClientConfiguration* cc, char ignorePublicKeys);
+/* getters */
+char* ClientConfiguration_get_keysFile(ClientConfiguration* cc);
+char* ClientConfiguration_get_certificateFile(ClientConfiguration* cc);
+char* ClientConfiguration_get_storeFile(ClientConfiguration* cc);
+char* ClientConfiguration_get_dateFormat(ClientConfiguration* cc);
+int ClientConfiguration_get_realmsNumber(ClientConfiguration* cc);
+ClientRealm** ClientConfiguration_get_realmsTable(ClientConfiguration* cc);
+char ClientConfiguration_get_ignorePublicKeys(ClientConfiguration* cc);
+
+#endif
diff --git a/src/client_initialization.c b/src/client_initialization.c
new file mode 100644
index 0000000..efde9a9
--- /dev/null
+++ b/src/client_initialization.c
@@ -0,0 +1,343 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+#include <assert.h>
+
+#include "client_initialization.h"
+#include "first_run.h"
+#include "network.h"
+#include "base64.h"
+#include "ssl_routines.h"
+#include "client_configuration_struct.h"
+#include "client_signals.h"
+
+int
+initialize_client_stage1(ClientRealm* cr, SSL_CTX* ctx, unsigned char* buff, char wanttoexit,
+ char ignorePublicKeys)
+{
+ int n, nlen, elen, len, tmp;
+ unsigned int olen;
+ X509* server_cert;
+ const EVP_MD *md;
+ EVP_PKEY* pkey;
+ EVP_MD_CTX md_ctx;
+ unsigned char *encoded = NULL;
+ char b64_encoded[100];
+ unsigned char *key_buf = NULL;
+ assert((ClientRealm_get_tunnelType(cr) == 0) || (ClientRealm_get_tunnelType(cr) == 1));
+ switch (ClientRealm_get_tunnelType(cr)) {
+ case 0: {
+ if (ip_connect(&tmp, ClientRealm_get_serverName(cr),
+ ClientRealm_get_managePort(cr),
+ ClientRealm_get_ipFamily(cr),
+ ClientRealm_get_localName(cr),
+ ClientRealm_get_localPort(cr))) {
+#ifdef AF_INET6
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "tcp_connect_%s error for %s, %s",
+ (ClientRealm_get_ipFamily(cr) & 0x02) ?
+ "ipv4":(ClientRealm_get_ipFamily(cr) & 0x04) ?
+ "ipv6":"unspec", ClientRealm_get_serverName(cr), ClientRealm_get_managePort(cr));
+#else
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "tcp_connect error for %s, %s", ClientRealm_get_serverName(cr), ClientRealm_get_managePort(cr));
+#endif
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ return 1;
+ }
+ }
+ SslFd_set_fd(ClientRealm_get_masterSslFd(cr), tmp);
+ break;
+ }
+#ifdef HAVE_LIBPTHREAD
+ case 1: {
+ if (initialize_http_proxy_client(&tmp, cr, ctx)) {
+#ifdef AF_INET6
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http_proxy_connect_%s error for %s, %s (proxy: %s, %s)",
+ (ClientRealm_get_ipFamily(cr) & 0x02) ?
+ "ipv4":(ClientRealm_get_ipFamily(cr) & 0x04) ?
+ "ipv6":"unspec", ClientRealm_get_serverName(cr),
+ ClientRealm_get_managePort(cr),
+ HttpProxyOptions_get_proxyname(ClientRealm_get_httpProxyOptions(cr)),
+ HttpProxyOptions_get_proxyport(ClientRealm_get_httpProxyOptions(cr)));
+#else
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http_proxy_connect error for %s, %s (proxy: %s, %s)", ClientRealm_get_serverName(cr),
+ ClientRealm_get_managePort(cr),
+ HttpProxyOptions_get_proxyname(ClientRealm_get_httpProxyOptions(cr)),
+ HttpProxyOptions_get_proxyport(ClientRealm_get_httpProxyOptions(cr)));
+#endif
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ return 1;
+ }
+ }
+ SslFd_set_fd(ClientRealm_get_masterSslFd(cr), tmp);
+ break;
+ }
+#endif
+ default: {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Unknown tunnel type");
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ return 1;
+ }
+ break;
+ }
+ }
+
+ SslFd_set_ssl(ClientRealm_get_masterSslFd(cr), SSL_new(ctx));
+ if (SSL_set_fd(SslFd_get_ssl(ClientRealm_get_masterSslFd(cr)),
+ SslFd_get_fd(ClientRealm_get_masterSslFd(cr))) != 1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Problem with initializing ssl... exiting");
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ close(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)));
+ return 2;
+ }
+ }
+
+ alarm(60);
+
+ aflog(LOG_T_INIT, LOG_I_INFO,
+ "Trying SSL_connect");
+ if ((n = SSL_connect(SslFd_get_ssl(ClientRealm_get_masterSslFd(cr)))) == 1) {
+ if ((server_cert = SSL_get_peer_certificate(SslFd_get_ssl(ClientRealm_get_masterSslFd(cr)))) == NULL) {
+ aflog(LOG_T_MAIN, LOG_I_CRIT,
+ "Server did not present a certificate... exiting");
+ exit(1);
+ }
+ /* FIXME: change almost everything here */
+ pkey = X509_get_pubkey(server_cert);
+ if (pkey == NULL) {
+ aflog(LOG_T_MAIN, LOG_I_CRIT,
+ "Server's public key is invalid... exiting");
+ exit(1);
+ }
+ nlen = BN_num_bytes(pkey->pkey.rsa->n);
+ elen = BN_num_bytes(pkey->pkey.rsa->e);
+ len = nlen + elen;
+ key_buf = malloc(len);
+ if (key_buf == NULL) {
+ aflog(LOG_T_MAIN, LOG_I_CRIT,
+ "Cannot allocate memory for server's public key checking... exiting");
+ exit(1);
+ }
+ BN_bn2bin(pkey->pkey.rsa->n, key_buf);
+ BN_bn2bin(pkey->pkey.rsa->e, key_buf + nlen);
+ md = EVP_md5();
+ EVP_DigestInit(&md_ctx, md);
+ EVP_DigestUpdate(&md_ctx, key_buf, len);
+ encoded = calloc(1, EVP_MAX_MD_SIZE+1);
+ if (encoded == NULL) {
+ aflog(LOG_T_MAIN, LOG_I_CRIT,
+ "Cannot allocate memory for server's public key checking... exiting");
+ exit(1);
+ }
+ EVP_DigestFinal(&md_ctx, encoded, &olen);
+
+ if (b64_ntop(encoded, olen, b64_encoded, 100) == -1) {
+ aflog(LOG_T_MAIN, LOG_I_CRIT,
+ "Problem with base64 encoding... exiting");
+ exit(1);
+ }
+
+ switch (check_public_key(get_store_filename(), ClientRealm_get_serverName(cr), b64_encoded)) {
+ case SSL_PUBLIC_KEY_VALID:
+ /* public key is ok - do nothing */
+ break;
+ case SSL_PUBLIC_KEY_NOT_KNOWN:
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "WARNING: implicitly added new server's public key to the list of known hosts");
+ add_public_key(get_store_filename(), ClientRealm_get_serverName(cr), b64_encoded);
+ break;
+ default:
+ if (ignorePublicKeys) {
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "WARNING: Invalid server's public key... ignoring");
+ }
+ else {
+ aflog(LOG_T_MAIN, LOG_I_CRIT,
+ "Invalid server's public key... exiting");
+ aflog(LOG_T_MAIN, LOG_I_CRIT,
+ "Please delete conflicting entry in %s or use '--ignorepkeys' option",
+ get_store_filename());
+ exit(1);
+ }
+ }
+
+ memset(key_buf, 0, len);
+ free(key_buf);
+ free(encoded);
+
+ aflog(LOG_T_INIT, LOG_I_INFO,
+ "SSL_connect successful");
+ }
+ else {
+ alarm(0);
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "SSL_connect has failed (%d | %d)... exiting", n,
+ SSL_get_error(SslFd_get_ssl(ClientRealm_get_masterSslFd(cr)), n));
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ close(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)));
+ return 3;
+ }
+ }
+ alarm(0);
+
+ buff[0] = AF_S_LOGIN;
+ buff[1] = ClientRealm_get_password(cr)[0];
+ buff[2] = ClientRealm_get_password(cr)[1];
+ buff[3] = ClientRealm_get_password(cr)[2];
+ buff[4] = ClientRealm_get_password(cr)[3];
+
+ return 0;
+}
+
+int
+initialize_client_stage2(ClientRealm* cr, unsigned char* buff, char wanttoexit)
+{
+ SslFd_send_message(ClientRealm_get_realmType(cr) | TYPE_SSL | TYPE_ZLIB,
+ ClientRealm_get_masterSslFd(cr), buff, 5);
+ buff[0] = 0;
+ SslFd_get_message(ClientRealm_get_realmType(cr) | TYPE_SSL | TYPE_ZLIB,
+ ClientRealm_get_masterSslFd(cr), buff, -5);
+
+ if ( buff[0] == 0 ) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Connection with afserver failed");
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ close(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)));
+ return 1;
+ }
+ }
+ if ( buff[0] == AF_S_WRONG ) {
+ aflog(LOG_T_INIT, LOG_I_ERR,
+ "Wrong password");
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ close(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)));
+ return 1;
+ }
+ }
+ if ( buff[0] == AF_S_CANT_OPEN ) {
+ aflog(LOG_T_INIT, LOG_I_ERR,
+ "Server is full");
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ close(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)));
+ 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 {
+ close(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)));
+ return 1;
+ }
+ }
+
+ ClientRealm_set_realmType(cr, buff[3]);
+ ClientRealm_set_usersLimit(cr, buff[1] * 256 + buff[2]);
+ return 0;
+}
+
+int
+initialize_client_stage3(ClientRealm* cr, int* buflength, fd_set* allset, fd_set* wset, int* maxfdp1,
+ char wanttoexit)
+{
+ int i;
+ socklen_t len;
+ ConnectUser** usersTable;
+ usersTable = calloc(ClientRealm_get_usersLimit(cr), sizeof(ConnectUser*));
+ if (usersTable == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Calloc error - unable to successfully communicate with server");
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ close(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)));
+ return 1;
+ }
+ }
+ ClientRealm_set_usersTable(cr, usersTable);
+ for (i = 0; i < ClientRealm_get_usersLimit(cr); ++i) {
+ usersTable[i] = ConnectUser_new();
+ if (usersTable[i] == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Calloc error - unable to successfully communicate with server");
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ close(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)));
+ return 1;
+ }
+ }
+ }
+
+ len = 4;
+ if (getsockopt(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)), 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 {
+ close(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)));
+ return 2;
+ }
+ }
+
+ FD_ZERO(allset);
+ FD_ZERO(wset);
+
+ FD_SET(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)), allset);
+ (*maxfdp1) = SslFd_get_fd(ClientRealm_get_masterSslFd(cr)) + 1;
+ return 0;
+}
diff --git a/src/client_initialization.h b/src/client_initialization.h
new file mode 100644
index 0000000..390568f
--- /dev/null
+++ b/src/client_initialization.h
@@ -0,0 +1,42 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "activefor.h"
+#include "stats.h"
+#include "logging.h"
+#include "http_proxy_client.h"
+#include "http_proxy_options_struct.h"
+#include "ssl_fd_struct.h"
+#include "client_realm_struct.h"
+
+#include <openssl/ssl.h>
+
+#ifndef _JS_CLIENT_INITIALIZATION_H
+#define _JS_CLIENT_INITIALIZATION_H
+
+int initialize_client_stage1(ClientRealm* cr, SSL_CTX* ctx, unsigned char* buff, char wanttoexit,
+ char ignorePublicKeys);
+int initialize_client_stage2(ClientRealm* cr, unsigned char* buff, char wanttoexit);
+int initialize_client_stage3(ClientRealm* cr, int* buflength, fd_set* allset, fd_set* wset, int* maxfdp1,
+ char wanttoexit);
+
+#endif
diff --git a/src/client_realm_struct.c b/src/client_realm_struct.c
new file mode 100644
index 0000000..5b4477e
--- /dev/null
+++ b/src/client_realm_struct.c
@@ -0,0 +1,1205 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "string_functions.h"
+#include "client_realm_struct.h"
+#include "client_shutdown.h"
+#include "logging.h"
+
+/*
+ * Function name: ClientRealm_new
+ * Description: Create and initialize new ClientRealm structure.
+ * Returns: Pointer to newly created ClientRealm structure.
+ */
+
+ClientRealm*
+ClientRealm_new()
+{
+ ClientRealm* tmp = calloc(1, sizeof(ClientRealm));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ tmp->password[0] = 1;
+ tmp->password[1] = 2;
+ tmp->password[2] = 3;
+ tmp->password[3] = 4;
+ tmp->masterSslFd = SslFd_new();
+ assert(tmp->masterSslFd != NULL);
+ if (tmp->masterSslFd == NULL) {
+ ClientRealm_free(&tmp);
+ return NULL;
+ }
+ tmp->arOptions = ArOptions_new();
+ assert(tmp->arOptions != NULL);
+ if (tmp->arOptions == NULL) {
+ ClientRealm_free(&tmp);
+ return NULL;
+ }
+ tmp->httpProxyOptions = HttpProxyOptions_new();
+ assert(tmp->httpProxyOptions != NULL);
+ if (tmp->httpProxyOptions == NULL) {
+ ClientRealm_free(&tmp);
+ return NULL;
+ }
+#ifdef HAVE_LIBDL
+ tmp->userModule = Module_new();
+ assert(tmp->userModule != NULL);
+ if (tmp->userModule == NULL) {
+ ClientRealm_free(&tmp);
+ return NULL;
+ }
+ tmp->serviceModule = Module_new();
+ assert(tmp->serviceModule != NULL);
+ if (tmp->serviceModule == NULL) {
+ ClientRealm_free(&tmp);
+ return NULL;
+ }
+#endif
+ return tmp;
+}
+
+/*
+ * Function name: ClientRealm_free
+ * Description: Free the memory allocated for ClientRealm structure.
+ * Arguments: cr - pointer to pointer to ClientRealm structure
+ */
+
+void
+ClientRealm_free(ClientRealm** cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ assert((*cr) != NULL);
+ if ((*cr) == NULL) {
+ return;
+ }
+ ClientRealm_set_serverName((*cr), NULL);
+ ClientRealm_set_managePort((*cr), NULL);
+ ClientRealm_set_hostName((*cr), NULL);
+ ClientRealm_set_realmName((*cr), NULL);
+ ClientRealm_set_sKeepAliveTimeout((*cr), NULL);
+ ClientRealm_set_realmId((*cr), NULL);
+ ClientRealm_set_localName((*cr), NULL);
+ ClientRealm_set_localPort((*cr), NULL);
+ ClientRealm_set_localDestinationName((*cr), NULL);
+ ClientRealm_set_clientAddress((*cr), NULL);
+ ClientRealm_set_masterSslFd((*cr), NULL);
+ ClientRealm_set_httpProxyOptions((*cr), NULL);
+ ClientRealm_set_arOptions((*cr), NULL);
+ ClientRealm_set_destinationPorts((*cr), NULL);
+ ClientRealm_set_usersTable((*cr), NULL);
+#ifdef HAVE_LIBDL
+ ClientRealm_set_userModule((*cr), NULL);
+ ClientRealm_set_serviceModule((*cr), NULL);
+#endif
+ free((*cr));
+ (*cr) = NULL;
+}
+
+/*
+ * Function name: ClientRealm_set_serverName
+ * Description: Set realm's server name.
+ * Arguments: cr - pointer to ClientRealm structure
+ * serverName - realm's host name
+ */
+
+void
+ClientRealm_set_serverName(ClientRealm* cr, char* serverName)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ string_cp(&(cr->serverName), serverName);
+}
+
+/*
+ * Function name: ClientRealm_set_managePort
+ * Description: Set realm's manage port description.
+ * Arguments: cr - pointer to ClientRealm structure
+ * managePort - realm's manage port description
+ */
+
+void
+ClientRealm_set_managePort(ClientRealm* cr, char* managePort)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ string_cp(&(cr->managePort), managePort);
+}
+
+/*
+ * Function name: ClientRealm_set_hostName
+ * Description: Set realm's host name.
+ * Arguments: cr - pointer to ClientRealm structure
+ * hostName - realm's host name
+ */
+
+void
+ClientRealm_set_hostName(ClientRealm* cr, char* hostName)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ string_cp(&(cr->hostName), hostName);
+}
+
+/*
+ * Function name: ClientRealm_set_destinationPorts
+ * Description: Set realm's destination ports list.
+ * Arguments: cr - pointer to ClientRealm structure
+ * destinationPorts - realm's destination ports list
+ */
+
+void
+ClientRealm_set_destinationPorts(ClientRealm* cr, PortList* destinationPorts)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ if (cr->destinationPorts) {
+ PortList_free(&(cr->destinationPorts));
+ }
+ cr->destinationPorts = destinationPorts;
+}
+
+/*
+ * Function name: ClientRealm_set_sKeepAliveTimeout
+ * Description: Set keep-alive timeout value description.
+ * Arguments: cr - pointer to ClientRealm structure
+ * sKeepAliveTimeout - keep-alive timeout value description
+ */
+
+void
+ClientRealm_set_sKeepAliveTimeout(ClientRealm* cr, char* sKeepAliveTimeout)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ string_cp(&(cr->sKeepAliveTimeout), sKeepAliveTimeout);
+}
+
+/*
+ * Function name: ClientRealm_set_realmName
+ * Description: Set realm's name.
+ * Arguments: cr - pointer to ClientRealm structure
+ * realmName - realm's name
+ */
+
+void
+ClientRealm_set_realmName(ClientRealm* cr, char* realmName)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ string_cp(&(cr->realmName), realmName);
+}
+
+/*
+ * Function name: ClientRealm_set_realmId
+ * Description: Set realm's id.
+ * Arguments: cr - pointer to ClientRealm structure
+ * realmId - realm's id
+ */
+
+void
+ClientRealm_set_realmId(ClientRealm* cr, char* realmId)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ string_cp(&(cr->realmId), realmId);
+}
+
+/*
+ * Function name: ClientRealm_set_localName
+ * Description: Set realm's local name.
+ * Arguments: cr - pointer to ClientRealm structure
+ * localName - realm's local name
+ */
+
+void
+ClientRealm_set_localName(ClientRealm* cr, char* localName)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ string_cp(&(cr->localName), localName);
+}
+
+/*
+ * Function name: ClientRealm_set_localPort
+ * Description: Set realm's local port description.
+ * Arguments: cr - pointer to ClientRealm structure
+ * localPort - realm's local port description
+ */
+
+void
+ClientRealm_set_localPort(ClientRealm* cr, char* localPort)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ string_cp(&(cr->localPort), localPort);
+}
+
+/*
+ * Function name: ClientRealm_set_localDestinationName
+ * Description: Set realm's local destination name.
+ * Arguments: cr - pointer to ClientRealm structure
+ * localDestinationName - realm's local destination name
+ */
+
+void
+ClientRealm_set_localDestinationName(ClientRealm* cr, char* localDestinationName)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ string_cp(&(cr->localDestinationName), localDestinationName);
+}
+
+/*
+ * Function name: ClientRealm_set_password
+ * Description: Set realm's password.
+ * Arguments: cr - pointer to ClientRealm structure
+ * password - realm's password
+ */
+
+void
+ClientRealm_set_password(ClientRealm* cr, unsigned char* password)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ memcpy(cr->password, password, 4);
+}
+
+/*
+ * Function name: ClientRealm_set_connectedUsers
+ * Description: Set number of connected users.
+ * Arguments: cr - pointer to ClientRealm structure
+ * connectedUsers - number of connected users
+ */
+
+void
+ClientRealm_set_connectedUsers(ClientRealm* cr, int connectedUsers)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ cr->connectedUsers = connectedUsers;
+}
+
+/*
+ * Function name: ClientRealm_set_usersLimit
+ * Description: Set limit of connected users.
+ * Arguments: cr - pointer to ClientRealm structure
+ * usersLimit - limit of connected users
+ */
+
+void
+ClientRealm_set_usersLimit(ClientRealm* cr, int usersLimit)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ cr->usersLimit = usersLimit;
+}
+
+/*
+ * Function name: ClientRealm_set_keepAliveTimeout
+ * Description: Set keep-alive timeout value.
+ * Arguments: cr - pointer to ClientRealm structure
+ * keepAliveTimeout - keep-alive timeout value
+ */
+
+void
+ClientRealm_set_keepAliveTimeout(ClientRealm* cr, int keepAliveTimeout)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ cr->keepAliveTimeout = keepAliveTimeout;
+}
+
+/*
+ * Function name: ClientRealm_set_clientMode
+ * Description: Set client mode.
+ * Arguments: cr - pointer to ClientRealm structure
+ * clientMode - client mode
+ */
+
+void
+ClientRealm_set_clientMode(ClientRealm* cr, int clientMode)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ cr->clientMode = clientMode;
+}
+
+/*
+ * Function name: ClientRealm_set_ipFamily
+ * Description: Set IP family.
+ * Arguments: cr - pointer to ClientRealm structure
+ * ipFamily - IP family
+ */
+
+void
+ClientRealm_set_ipFamily(ClientRealm* cr, char ipFamily)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ cr->ipFamily = ipFamily;
+}
+
+/*
+ * Function name: ClientRealm_set_realmType
+ * Description: Set type of the realm.
+ * Arguments: cr - pointer to ClientRealm structure
+ * realmType - type of the realm
+ */
+
+void
+ClientRealm_set_realmType(ClientRealm* cr, char realmType)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ cr->realmType = realmType;
+}
+
+/*
+ * Function name: ClientRealm_set_tunnelType
+ * Description: Set type of the tunnel.
+ * Arguments: cr - pointer to ClientRealm structure
+ * tunnelType - type of the tunnel
+ */
+
+void
+ClientRealm_set_tunnelType(ClientRealm* cr, char tunnelType)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ cr->tunnelType = tunnelType;
+}
+
+/*
+ * Function name: ClientRealm_set_keepAlive
+ * Description: Set keep-alive timeval struct.
+ * Arguments: cr - pointer to ClientRealm structure
+ * keepAlive - keep-alive timeval struct
+ */
+
+void
+ClientRealm_set_keepAlive(ClientRealm* cr, struct timeval keepAlive)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ cr->keepAlive = keepAlive;
+}
+
+/*
+ * Function name: ClientRealm_set_addressLength
+ * Description: Set client's address length.
+ * Arguments: cr - pointer to ClientRealm structure
+ * addressLength - client's address length
+ */
+
+void
+ClientRealm_set_addressLength(ClientRealm* cr, socklen_t addressLength)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ cr->addressLength = addressLength;
+}
+
+/*
+ * Function name: ClientRealm_set_clientAddress
+ * Description: Set client's network address.
+ * Arguments: cr - pointer to ClientRealm structure
+ * clientAddress - client's network address
+ */
+
+void
+ClientRealm_set_clientAddress(ClientRealm* cr, struct sockaddr* clientAddress)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ if (cr->clientAddress) {
+ free(cr->clientAddress);
+ cr->clientAddress = NULL;
+ }
+ cr->clientAddress = clientAddress;
+}
+
+/*
+ * Function name: ClientRealm_set_masterSslFd
+ * Description: Set client realm's master sslfd.
+ * Arguments: cr - pointer to ClientRealm structure
+ * masterSslFd - client realm's master sslfd
+ */
+
+void
+ClientRealm_set_masterSslFd(ClientRealm* cr, SslFd* masterSslFd)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ if (cr->masterSslFd) {
+ SslFd_free(&(cr->masterSslFd));
+ }
+ cr->masterSslFd = masterSslFd;
+}
+
+/*
+ * Function name: ClientRealm_set_httpProxyOptions
+ * Description: Set client realm's http proxy options.
+ * Arguments: cr - pointer to ClientRealm structure
+ * httpProxyOptions - client realm's http proxy options
+ */
+
+void
+ClientRealm_set_httpProxyOptions(ClientRealm* cr, HttpProxyOptions* httpProxyOptions)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ if (cr->httpProxyOptions) {
+ HttpProxyOptions_free(&(cr->httpProxyOptions));
+ }
+ cr->httpProxyOptions = httpProxyOptions;
+}
+
+/*
+ * Function name: ClientRealm_set_arOptions
+ * Description: Set client realm's auto-reconnect options.
+ * Arguments: cr - pointer to ClientRealm structure
+ * arOptions - client realm's auto-reconnect options
+ */
+
+void
+ClientRealm_set_arOptions(ClientRealm* cr, ArOptions* arOptions)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ if (cr->arOptions) {
+ ArOptions_free(&(cr->arOptions));
+ }
+ cr->arOptions = arOptions;
+}
+
+/*
+ * Function name: ClientRealm_set_usersTable
+ * Description: Set table of users.
+ * Arguments: cr - pointer to ClientRealm structure
+ * usersTable - table of users
+ */
+
+void
+ClientRealm_set_usersTable(ClientRealm* cr, ConnectUser** usersTable)
+{
+ int i;
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ if (cr->usersTable) {
+ for (i = 0; i < cr->usersLimit; ++i) {
+ if (cr->usersTable[i]) {
+ ConnectUser_free(&(cr->usersTable[i]));
+ }
+ }
+ free(cr->usersTable);
+ cr->usersTable = NULL;
+ }
+ cr->usersTable = usersTable;
+}
+
+#ifdef HAVE_LIBDL
+/*
+ * Function name: ClientRealm_set_userModule
+ * Description: Set a module for user's packets filtering.
+ * Arguments: cr - pointer to ClientRealm structure
+ * userModule - module for user's packets filtering
+ */
+
+void
+ClientRealm_set_userModule(ClientRealm* cr, Module* userModule)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ if (cr->userModule) {
+ Module_free(&(cr->userModule));
+ }
+ cr->userModule = userModule;
+}
+
+/*
+ * Function name: ClientRealm_set_serviceModule
+ * Description: Set a module for service's packets filtering.
+ * Arguments: cr - pointer to ClientRealm structure
+ * serviceModule - module for service's packets filtering
+ */
+
+void
+ClientRealm_set_serviceModule(ClientRealm* cr, Module* serviceModule)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ if (cr->serviceModule) {
+ Module_free(&(cr->serviceModule));
+ }
+ cr->serviceModule = serviceModule;
+}
+#endif
+
+/*
+ * Function name: ClientRealm_get_serverName
+ * Description: Get realm's server name.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Realm's server name.
+ */
+
+char*
+ClientRealm_get_serverName(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->serverName;
+}
+
+/*
+ * Function name: ClientRealm_get_managePort
+ * Description: Get realm's manage port description.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Realm's manage port description.
+ */
+
+char*
+ClientRealm_get_managePort(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->managePort;
+}
+
+/*
+ * Function name: ClientRealm_get_hostName
+ * Description: Get realm's host name.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Realm's host name.
+ */
+
+char*
+ClientRealm_get_hostName(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->hostName;
+}
+
+/*
+ * Function name: ClientRealm_get_destinationPorts
+ * Description: Get realm's destination ports list.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Realm's destination ports list.
+ */
+
+PortList*
+ClientRealm_get_destinationPorts(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->destinationPorts;
+}
+
+/*
+ * Function name: ClientRealm_get_sKeepAliveTimeout
+ * Description: Get keep-alive timeout value description.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Keep-alive timeout value description.
+ */
+
+char*
+ClientRealm_get_sKeepAliveTimeout(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->sKeepAliveTimeout;
+}
+
+/*
+ * Function name: ClientRealm_get_realmName
+ * Description: Get realm's name.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Realm's name.
+ */
+
+char*
+ClientRealm_get_realmName(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->realmName;
+}
+
+/*
+ * Function name: ClientRealm_get_realmId
+ * Description: Get realm's id.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Realm's id.
+ */
+
+char*
+ClientRealm_get_realmId(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->realmId;
+}
+
+
+/*
+ * Function name: ClientRealm_get_localName
+ * Description: Get realm's local name.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Realm's local name.
+ */
+
+char*
+ClientRealm_get_localName(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->localName;
+}
+
+
+/*
+ * Function name: ClientRealm_get_localPort
+ * Description: Get realm's local port description.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Realm's local port description.
+ */
+
+char*
+ClientRealm_get_localPort(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->localPort;
+}
+
+
+/*
+ * Function name: ClientRealm_get_localDestinationName
+ * Description: Get realm's local destination name.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Realm's local destination name.
+ */
+
+char*
+ClientRealm_get_localDestinationName(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->localDestinationName;
+}
+
+/*
+ * Function name: ClientRealm_get_password
+ * Description: Get realm's password.
+ * Arguments: sr - pointer to ClientRealm structure
+ * Returns: Realm's password.
+ */
+
+unsigned char*
+ClientRealm_get_password(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->password;
+}
+
+/*
+ * Function name: ClientRealm_get_connectedUsers
+ * Description: Get number of connected users.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Number of connected users.
+ */
+
+int
+ClientRealm_get_connectedUsers(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return -1;
+ }
+ return cr->connectedUsers;
+}
+
+/*
+ * Function name: ClientRealm_get_usersLimit
+ * Description: Get limit of connected users.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Limit of connected users.
+ */
+
+int
+ClientRealm_get_usersLimit(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return -1;
+ }
+ return cr->usersLimit;
+}
+
+/*
+ * Function name: ClientRealm_get_keepAliveTimeout
+ * Description: Get keep-alive timeout value.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Keep-alive timeout value.
+ */
+
+int
+ClientRealm_get_keepAliveTimeout(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return 0;
+ }
+ return cr->keepAliveTimeout;
+}
+
+/*
+ * Function name: ClientRealm_get_clientMode
+ * Description: Get client mode.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Client mode.
+ */
+
+int
+ClientRealm_get_clientMode(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return 0;
+ }
+ return cr->clientMode;
+}
+
+/*
+ * Function name: ClientRealm_get_ipFamily
+ * Description: Get IP family.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: IP family.
+ */
+
+char
+ClientRealm_get_ipFamily(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return 0;
+ }
+ return cr->ipFamily;
+}
+
+/*
+ * Function name: ClientRealm_get_realmType
+ * Description: Get type of the realm.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Type of the realm.
+ */
+
+char
+ClientRealm_get_realmType(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return 0;
+ }
+ return cr->realmType;
+}
+
+/*
+ * Function name: ClientRealm_get_tunnelType
+ * Description: Get type of the tunnel.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Type of the tunnel.
+ */
+
+char
+ClientRealm_get_tunnelType(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return 0;
+ }
+ return cr->tunnelType;
+}
+
+/*
+ * Function name: ClientRealm_get_keepAlive
+ * Description: Get keep-alive timeval struct.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Keep-alive timeval struct.
+ */
+
+struct timeval
+ClientRealm_get_keepAlive(ClientRealm* cr)
+{
+ struct timeval tmp = {0, 0};
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return tmp;
+ }
+ return cr->keepAlive;
+}
+
+/*
+ * Function name: ClientRealm_get_addressLength
+ * Description: Get client's address length.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Client's address length.
+ */
+
+socklen_t
+ClientRealm_get_addressLength(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return 0;
+ }
+ return cr->addressLength;
+}
+
+/*
+ * Function name: ClientRealm_get_clientAddress
+ * Description: Get client's network address.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Client's network address.
+ */
+
+struct sockaddr*
+ClientRealm_get_clientAddress(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->clientAddress;
+}
+
+/*
+ * Function name: ClientRealm_get_masterSslFd
+ * Description: Get client realm's master sslfd.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Client realm's master sslfd.
+ */
+
+SslFd*
+ClientRealm_get_masterSslFd(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->masterSslFd;
+}
+
+/*
+ * Function name: ClientRealm_get_httpProxyOptions
+ * Description: Get client realm's http proxy options.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Client realm's http proxy options.
+ */
+
+HttpProxyOptions*
+ClientRealm_get_httpProxyOptions(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->httpProxyOptions;
+}
+
+/*
+ * Function name: ClientRealm_get_arOptions
+ * Description: Get client realm's auto-reconnect options.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Client realm's auto-reconnect options.
+ */
+
+ArOptions*
+ClientRealm_get_arOptions(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->arOptions;
+}
+
+/*
+ * Function name: ClientRealm_get_usersTable
+ * Description: Get table of users.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Table of users.
+ */
+
+ConnectUser**
+ClientRealm_get_usersTable(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->usersTable;
+}
+
+#ifdef HAVE_LIBDL
+/*
+ * Function name: ClientRealm_get_userModule
+ * Description: Get a module for user's packets filtering.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: A module for user's packets filtering.
+ */
+
+Module*
+ClientRealm_get_userModule(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->userModule;
+}
+
+/*
+ * Function name: ClientRealm_get_serviceModule
+ * Description: Get a module for service's packets filtering.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: A module for service's packets filtering.
+ */
+
+Module*
+ClientRealm_get_serviceModule(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return cr->serviceModule;
+}
+#endif
+
+/*
+ * Function name: ClientRealm_increase_connectedUsers
+ * Description: Increase number of connected users.
+ * Arguments: cr - pointer to ClientRealm structure
+ */
+
+void
+ClientRealm_increase_connectedUsers(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ ClientRealm_set_connectedUsers(cr, ClientRealm_get_connectedUsers(cr) + 1);
+}
+
+/*
+ * Function name: ClientRealm_decrease_connectedUsers
+ * Description: Decrease number of connected users.
+ * Arguments: cr - pointer to ClientRealm structure
+ */
+
+void
+ClientRealm_decrease_connectedUsers(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ ClientRealm_set_connectedUsers(cr, ClientRealm_get_connectedUsers(cr) - 1);
+}
+
+/*
+ * Function name: ClientRealm_closeUsersConnections
+ * Description: Close all users' connections and free usersTable.
+ * Arguments: cr - pointer to ClientRealm structure
+ */
+
+void
+ClientRealm_closeUsersConnections(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ close_connections(ClientRealm_get_usersLimit(cr), &(cr->usersTable));
+}
+
+/*
+ * Function name: ClientRealm_get_keepAlivePointer
+ * Description: Get pointer to keep-alive structure.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: Pointer to keep-alive structure.
+ */
+
+struct timeval*
+ClientRealm_get_keepAlivePointer(ClientRealm* cr)
+{
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return NULL;
+ }
+ return (&(cr->keepAlive));
+}
+
+/*
+ * Function name: ClientRealm_send_realmId
+ * Description: Sends the realm's id to the afserver.
+ * Arguments: cr - pointer to ClientRealm structure
+ * buff - buffer used for message creation
+ */
+
+void
+ClientRealm_send_realmId(ClientRealm* cr, unsigned char* buff)
+{
+ int n;
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ assert(buff != NULL);
+ if (buff == NULL) {
+ return;
+ }
+ if (ClientRealm_get_realmId(cr) != NULL) {
+ buff[0] = AF_S_LOGIN;
+ buff[1] = buff[2] = 0;
+ n = strlen(ClientRealm_get_realmId(cr));
+ memcpy(&buff[5], ClientRealm_get_realmId(cr), n);
+ buff[3] = n >> 8; /* high bits of message length */
+ buff[4] = n; /* low bits of message length */
+ SslFd_send_message(ClientRealm_get_realmType(cr),
+ ClientRealm_get_masterSslFd(cr), buff, n+5);
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "ID SENT: %s", ClientRealm_get_realmId(cr));
+ }
+}
+
+/*
+ * Function name: ClientRealm_enable_multi
+ * Description: Enables the MULTI mode on the afserver, if supported.
+ * Arguments: cr - pointer to ClientRealm structure
+ */
+
+void
+ClientRealm_enable_multi(ClientRealm* cr)
+{
+ unsigned char buff[5];
+ assert(cr != NULL);
+ if (cr == NULL) {
+ return;
+ }
+ if ((TYPE_IS_SUPPORTED_MULTI(ClientRealm_get_realmType(cr))) &&
+ (PortList_get_size(ClientRealm_get_destinationPorts(cr)) > 1)) {
+ buff[0] = AF_S_ENABLE_MULTI;
+ buff[1] = PortList_get_size(ClientRealm_get_destinationPorts(cr));
+ buff[2] = buff[3] = buff[4] = 0;
+ SslFd_send_message(ClientRealm_get_realmType(cr),
+ ClientRealm_get_masterSslFd(cr), buff, 5);
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "ENABLED: MULTI (multiple tunnels managed by one afclient)");
+ }
+}
diff --git a/src/client_realm_struct.h b/src/client_realm_struct.h
new file mode 100644
index 0000000..0fd1789
--- /dev/null
+++ b/src/client_realm_struct.h
@@ -0,0 +1,146 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "activefor.h"
+#include "ssl_fd_struct.h"
+#include "http_proxy_options_struct.h"
+#include "ar_options_struct.h"
+#include "module_struct.h"
+#include "port_list_struct.h"
+
+#ifndef _JS_CLIENT_REALM_STRUCT_H
+#define _JS_CLIENT_REALM_STRUCT_H
+
+#define CLIENTREALM_MODE_UNKNOWN -1
+#define CLIENTREALM_MODE_TCP 0
+#define CLIENTREALM_MODE_UDP 1
+#define CLIENTREALM_MODE_REMOTE 2
+#define CLIENTREALM_MODE_REVERSE 3
+
+#define CLIENTREALM_TUNNELTYPE_UNKNOWN -1
+#define CLIENTREALM_TUNNELTYPE_DIRECT 0
+#define CLIENTREALM_TUNNELTYPE_HTTPPROXY 1
+#define CLIENTREALM_TUNNELTYPE_HTTPSPROXY 2
+
+typedef struct {
+ char* serverName;
+ char* managePort;
+ char* hostName;
+ char* realmName;
+ char* sKeepAliveTimeout;
+ char* realmId;
+ char* localName;
+ char* localPort;
+ char* localDestinationName;
+ unsigned char password[4];
+ int connectedUsers;
+ int usersLimit;
+ int clientMode;
+ int keepAliveTimeout;
+ char ipFamily;
+ char realmType;
+ char tunnelType;
+ struct timeval keepAlive;
+ socklen_t addressLength;
+ struct sockaddr* clientAddress;
+ SslFd* masterSslFd;
+ HttpProxyOptions* httpProxyOptions;
+ ArOptions* arOptions;
+ PortList* destinationPorts;
+ ConnectUser** usersTable;
+#ifdef HAVE_LIBDL
+ Module* userModule;
+ Module* serviceModule;
+#endif
+} ClientRealm;
+
+/* 'constructor' */
+ClientRealm* ClientRealm_new();
+/* 'destructor' */
+void ClientRealm_free(ClientRealm** cr);
+/* setters */
+void ClientRealm_set_serverName(ClientRealm* cr, char* serverName);
+void ClientRealm_set_managePort(ClientRealm* cr, char* managePort);
+void ClientRealm_set_hostName(ClientRealm* cr, char* hostName);
+void ClientRealm_set_realmName(ClientRealm* cr, char* realmName);
+void ClientRealm_set_sKeepAliveTimeout(ClientRealm* cr, char* sKeepAliveTimeout);
+void ClientRealm_set_realmId(ClientRealm* cr, char* realmId);
+void ClientRealm_set_localName(ClientRealm* cr, char* localName);
+void ClientRealm_set_localPort(ClientRealm* cr, char* localPort);
+void ClientRealm_set_localDestinationName(ClientRealm* cr, char* localDestinationName);
+void ClientRealm_set_password(ClientRealm* cr, unsigned char* password);
+void ClientRealm_set_connectedUsers(ClientRealm* cr, int connectedUsers);
+void ClientRealm_set_usersLimit(ClientRealm* cr, int usersLimit);
+void ClientRealm_set_keepAliveTimeout(ClientRealm* cr, int keepAliveTimeout);
+void ClientRealm_set_clientMode(ClientRealm* cr, int clientMode);
+void ClientRealm_set_ipFamily(ClientRealm* cr, char ipFamily);
+void ClientRealm_set_realmType(ClientRealm* cr, char realmType);
+void ClientRealm_set_tunnelType(ClientRealm* cr, char tunnelType);
+void ClientRealm_set_keepAlive(ClientRealm* cr, struct timeval keepAlive);
+void ClientRealm_set_addressLength(ClientRealm* cr, socklen_t addressLength);
+void ClientRealm_set_clientAddress(ClientRealm* cr, struct sockaddr* clientAddress);
+void ClientRealm_set_masterSslFd(ClientRealm* cr, SslFd* masterSslFd);
+void ClientRealm_set_httpProxyOptions(ClientRealm* cr, HttpProxyOptions* httpProxyOptions);
+void ClientRealm_set_arOptions(ClientRealm* cr, ArOptions* arOptions);
+void ClientRealm_set_destinationPorts(ClientRealm* cr, PortList* destinationPorts);
+void ClientRealm_set_usersTable(ClientRealm* cr, ConnectUser** usersTable);
+#ifdef HAVE_LIBDL
+void ClientRealm_set_userModule(ClientRealm* cr, Module* userModule);
+void ClientRealm_set_serviceModule(ClientRealm* cr, Module* serviceModule);
+#endif
+/* getters */
+char* ClientRealm_get_serverName(ClientRealm* cr);
+char* ClientRealm_get_managePort(ClientRealm* cr);
+char* ClientRealm_get_hostName(ClientRealm* cr);
+char* ClientRealm_get_realmName(ClientRealm* cr);
+char* ClientRealm_get_sKeepAliveTimeout(ClientRealm* cr);
+char* ClientRealm_get_realmId(ClientRealm* cr);
+char* ClientRealm_get_localName(ClientRealm* cr);
+char* ClientRealm_get_localPort(ClientRealm* cr);
+char* ClientRealm_get_localDestinationName(ClientRealm* cr);
+unsigned char* ClientRealm_get_password(ClientRealm* cr);
+int ClientRealm_get_connectedUsers(ClientRealm* cr);
+int ClientRealm_get_usersLimit(ClientRealm* cr);
+int ClientRealm_get_keepAliveTimeout(ClientRealm* cr);
+int ClientRealm_get_clientMode(ClientRealm* cr);
+char ClientRealm_get_ipFamily(ClientRealm* cr);
+char ClientRealm_get_realmType(ClientRealm* cr);
+char ClientRealm_get_tunnelType(ClientRealm* cr);
+struct timeval ClientRealm_get_keepAlive(ClientRealm* cr);
+socklen_t ClientRealm_get_addressLength(ClientRealm* cr);
+struct sockaddr* ClientRealm_get_clientAddress(ClientRealm* cr);
+SslFd* ClientRealm_get_masterSslFd(ClientRealm* cr);
+HttpProxyOptions* ClientRealm_get_httpProxyOptions(ClientRealm* cr);
+ArOptions* ClientRealm_get_arOptions(ClientRealm* cr);
+PortList* ClientRealm_get_destinationPorts(ClientRealm* cr);
+ConnectUser** ClientRealm_get_usersTable(ClientRealm* cr);
+#ifdef HAVE_LIBDL
+Module* ClientRealm_get_userModule(ClientRealm* cr);
+Module* ClientRealm_get_serviceModule(ClientRealm* cr);
+#endif
+/* other */
+void ClientRealm_increase_connectedUsers(ClientRealm* cr);
+void ClientRealm_decrease_connectedUsers(ClientRealm* cr);
+void ClientRealm_closeUsersConnections(ClientRealm* cr);
+struct timeval* ClientRealm_get_keepAlivePointer(ClientRealm* cr);
+void ClientRealm_send_realmId(ClientRealm* cr, unsigned char* buff);
+void ClientRealm_enable_multi(ClientRealm* cr);
+
+#endif
diff --git a/src/client_remoteadmin.c b/src/client_remoteadmin.c
new file mode 100644
index 0000000..bcac860
--- /dev/null
+++ b/src/client_remoteadmin.c
@@ -0,0 +1,210 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "client_remoteadmin.h"
+
+/*
+ * Function name: client_admin
+ * Description: This function is responsible for client part of the admin panel.
+ * Arguments: type - the type of the realm
+ * master - pointer to the SslFd structure representing the connection with afserver
+ * buff - buffer which will be used for communication
+ * connectfd - the optional descriptor which can be used instead of the stdin
+ * id - the realm's id
+ * Returns: 0 - connection was closed normally,
+ * 1 - something went bad.
+ */
+
+int
+client_admin(char type, SslFd* master, unsigned char* buff, int connectfd, char* id)
+{
+ fd_set rset, allset;
+ int maxfdp1, n, length, infd;
+ FILE *outfp, *infp;
+
+ buff[0] = AF_S_ADMIN_LOGIN;
+ SslFd_send_message(type, master, buff, 5);
+ buff[0] = 0;
+ SslFd_get_message(type, master, buff, -5);
+
+ if ( buff[0] == 0 ) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Wrong password");
+ return 1;
+ }
+ if ( buff[0] == AF_S_CANT_OPEN ) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Server is full");
+ return 1;
+ }
+ if ( buff[0] != AF_S_ADMIN_LOGIN ) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Incompatible server type or server full");
+ return 1;
+ }
+
+ aflog(LOG_T_MAIN, LOG_I_INFO,
+ "CLIENT STARTED mode: remote administration");
+
+ if (connectfd > 0) {
+ outfp = fdopen(connectfd, "w");
+ if (outfp == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Error in opening file descriptor for writing");
+ return 1;
+ }
+ infd = connectfd;
+ }
+ else {
+ infd = STDIN_FILENO;
+ outfp = stdout;
+ }
+ infp = fdopen(infd, "r");
+ if (infp == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Error in opening file descriptor for reading");
+ return 1;
+ }
+
+ length = buff[3];
+ length = length << 8;
+ length += buff[4]; /* this is length of message */
+ n = SslFd_get_message(type, master, buff, length);
+ buff[n] = 0;
+ fprintf(outfp, "%s\n", (char*) buff);
+ fflush(outfp);
+
+ FD_ZERO(&allset);
+
+ FD_SET(SslFd_get_fd(master), &allset);
+ FD_SET(infd, &allset);
+
+ maxfdp1 = (infd > SslFd_get_fd(master)) ? infd + 1 : SslFd_get_fd(master) + 1;
+
+ if (id != NULL) {
+ buff[0] = AF_S_LOGIN;
+ buff[1] = buff[2] = 0;
+ n = strlen(id);
+ memcpy(&buff[5], id, n);
+ buff[3] = n >> 8; /* high bits of message length */
+ buff[4] = n; /* low bits of message length */
+ SslFd_send_message(type, master, buff, n+5);
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "ID SENT: %s", id);
+ }
+
+ while (1) {
+ rset = allset;
+ select(maxfdp1, &rset, NULL, NULL, NULL);
+
+ if (FD_ISSET(SslFd_get_fd(master), &rset)) {
+ aflog(LOG_T_MANAGE, LOG_I_DEBUG,
+ "masterfd: FD_ISSET");
+ n = SslFd_get_message(type, master, buff, 5);
+ if (n != 5) {
+ 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);
+ continue; /* what happened? */
+ }
+ }
+ if (n != 0)
+ return 1;
+ }
+ if (n == 0) { /* server quits -> we do the same... */
+ aflog(LOG_T_MANAGE, LOG_I_CRIT,
+ "SERVER: premature quit --> exiting...");
+ return 1;
+ }
+ if (buff[0] == AF_S_CLOSING) {
+ aflog(LOG_T_MANAGE, LOG_I_CRIT,
+ "SERVER: CLOSED -> exiting... cg: %ld bytes", getcg());
+ return 0;
+ }
+ if (buff[0] != AF_S_ADMIN_CMD) {
+ aflog(LOG_T_MANAGE, LOG_I_CRIT,
+ "SERVER: wrong message --> exiting");
+ return 1;
+ }
+ length = buff[3];
+ length = length << 8;
+ length += buff[4]; /* this is length of message */
+
+ switch (buff[1]) {
+ case AF_RA_STATUS_OK: {
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "SERVER: cmd successful");
+ }
+ case AF_RA_FAILED: {
+ if (buff[1] == AF_RA_FAILED) {
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "SERVER: cmd failed");
+ }
+ }
+ case AF_RA_UNDEFINED: {
+ if (buff[1] == AF_RA_UNDEFINED) {
+ aflog(LOG_T_MANAGE, LOG_I_WARNING,
+ "SERVER: unknown cmd");
+ }
+ n = SslFd_get_message(type, master, buff, length);
+ buff[n] = 0;
+ fprintf(outfp, "%s", (char*) buff);
+ fflush(outfp);
+ break;
+ }
+ case AF_RA_KICKED: {
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "SERVER: kicked us -> exiting... cg: %ld bytes", getcg());
+ return 1;
+ break;
+ }
+ default: {
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "SERVER: unrecognized message -> exiting... cg: %ld bytes", getcg());
+ return 1;
+ }
+ }
+ }
+
+ if (FD_ISSET(infd, &rset)) {
+ aflog(LOG_T_MANAGE, LOG_I_DEBUG,
+ "infd: FD_ISSET");
+ if (fgets((char*) &buff[5], 8091, infp) == NULL) { /* client quits --> exiting */
+ aflog(LOG_T_MANAGE, LOG_I_NOTICE,
+ "CLIENT CLOSED cg: %ld bytes", getcg());
+ return 0;
+ }
+ n = strlen((char*) &buff[5]);
+ if ((n > 0) && (buff[n+4] == '\n')) {
+ --n;
+ }
+ buff[0] = AF_S_ADMIN_CMD;
+ buff[1] = AF_RA_CMD;
+ buff[2] = AF_RA_UNDEFINED;
+ buff[3] = n >> 8; /* high bits of message length */
+ buff[4] = n; /* low bits of message length */
+ SslFd_send_message(type, master, buff, n+5);
+ }
+ }
+}
diff --git a/src/client_remoteadmin.h b/src/client_remoteadmin.h
new file mode 100644
index 0000000..f20af13
--- /dev/null
+++ b/src/client_remoteadmin.h
@@ -0,0 +1,38 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_CLIENT_REMOTEADMIN_H
+#define _JS_CLIENT_REMOTEADMIN_H
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "remoteadmin_codes.h"
+#include "activefor.h"
+#include "network.h"
+#include "logging.h"
+#include "stats.h"
+#include "make_ssl_handshake.h"
+#include "ssl_fd_struct.h"
+
+int client_admin(char, SslFd*, unsigned char*, int, char*);
+
+#endif
+
diff --git a/src/client_reverse_udp.c b/src/client_reverse_udp.c
new file mode 100644
index 0000000..882a6f9
--- /dev/null
+++ b/src/client_reverse_udp.c
@@ -0,0 +1,213 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "client_reverse_udp.h"
+
+#include <stdlib.h>
+
+/*
+ * Function name: initialize_client_reverse_udp
+ * Description: Initializes the realm for reverse udp connection.
+ * Arguments: cr - pointer to ClientRealm structure
+ * Returns: 0 - connection was initialized successfully,
+ * 1 - connection initialization failed.
+ */
+
+int
+initialize_client_reverse_udp(ClientRealm* cr)
+{
+ int tmp;
+ int wanttoexit = (ArOptions_get_arStart(ClientRealm_get_arOptions(cr)) == AR_OPTION_ENABLED) ? 0 : 1;
+ ClientRealm_set_usersLimit(cr, 1);
+ if (ip_connect(&tmp, ClientRealm_get_serverName(cr),
+ ClientRealm_get_managePort(cr),
+ ClientRealm_get_ipFamily(cr), NULL, NULL)) {
+#ifdef AF_INET6
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "tcp_connect_%s error for %s, %s",
+ (ClientRealm_get_ipFamily(cr) & 0x02) ?
+ "ipv4" : (ClientRealm_get_ipFamily(cr) & 0x04) ?
+ "ipv6":"unspec", ClientRealm_get_serverName(cr), ClientRealm_get_managePort(cr));
+#else
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "tcp_connect error for %s, %s", ClientRealm_get_serverName(cr), ClientRealm_get_managePort(cr));
+#endif
+ if (wanttoexit) {
+ exit(1);
+ }
+ else {
+ return 1;
+ }
+
+ }
+ SslFd_set_fd(ClientRealm_get_masterSslFd(cr), tmp);
+ SslFd_set_ssl(ClientRealm_get_masterSslFd(cr), NULL);
+ return 0;
+}
+
+/*
+ * Function name: client_reverse_udp
+ * Description: This function is responsible for the client part of the reverse udp tunnel.
+ * Arguments: cr - pointer to ClientRealm structure
+ * buff - buffer which will be used for communication
+ * buflength - socket send buffer size
+ */
+
+void
+client_reverse_udp(ClientRealm* cr, unsigned char* buff, int buflength)
+{
+ socklen_t len, addrlen;
+ int maxfdp1, temp, n, length;
+#ifdef HAVE_LINUX_SOCKIOS_H
+ int notsent;
+#endif
+ struct sockaddr* cliaddr;
+ fd_set rset, allset;
+
+ if (ip_listen(&temp, ClientRealm_get_hostName(cr),
+ PortListNode_get_portName(PortList_get_nth(ClientRealm_get_destinationPorts(cr), 0)), &addrlen,
+ ClientRealm_get_ipFamily(cr) & 0xfe)) {
+#ifdef AF_INET6
+ aflog(LOG_T_INIT, LOG_I_DEBUG,
+ "udp_listen_%s error for %s, %s",
+ (ClientRealm_get_ipFamily(cr) & 0x02) ?
+ "ipv4":(ClientRealm_get_ipFamily(cr) & 0x04) ?
+ "ipv6":"unspec", ClientRealm_get_hostName(cr),
+ PortListNode_get_portName(PortList_get_nth(ClientRealm_get_destinationPorts(cr), 0)));
+#else
+ aflog(LOG_T_INIT, LOG_I_DEBUG,
+ "udp_listen error for %s, %s", ClientRealm_get_hostName(cr),
+ PortListNode_get_portName(PortList_get_nth(ClientRealm_get_destinationPorts(cr), 0)));
+#endif
+ exit(1);
+ }
+ ConnectUser_set_connFd(ClientRealm_get_usersTable(cr)[0], temp);
+ cliaddr = malloc(addrlen);
+ FD_ZERO(&allset);
+
+ FD_SET(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)), &allset);
+ maxfdp1 = SslFd_get_fd(ClientRealm_get_masterSslFd(cr)) + 1;
+ maxfdp1 = (maxfdp1 > (ConnectUser_get_connFd(ClientRealm_get_usersTable(cr)[0]) + 1)) ?
+ maxfdp1 : (ConnectUser_get_connFd(ClientRealm_get_usersTable(cr)[0]) + 1);
+ FD_SET(ConnectUser_get_connFd(ClientRealm_get_usersTable(cr)[0]), &allset);
+ aflog(LOG_T_CLIENT, LOG_I_INFO,
+ "CLIENT STARTED mode: udp reverse");
+ for ( ; ; ) {
+ len = 4;
+ if (getsockopt(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)), 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(ConnectUser_get_connFd(ClientRealm_get_usersTable(cr)[0]), &rset)) { /* FD_ISSET CONTABLE[0].CONNFD RSET*/
+ n = recvfrom(ConnectUser_get_connFd(ClientRealm_get_usersTable(cr)[0]), &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(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)), 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(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)), 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(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)), buff, n + 5);
+ }
+#ifdef HAVE_LINUX_SOCKIOS_H
+ }
+#endif
+ } /* - FD_ISSET CONTABLE[0].CONNFD RSET */
+
+ if (FD_ISSET(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)), &rset)) { /* FD_ISSET MASTER.COMMFD RSET */
+ n = readn(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)), 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(SslFd_get_fd(ClientRealm_get_masterSslFd(cr)), 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(ConnectUser_get_connFd(ClientRealm_get_usersTable(cr)[0]), 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..b1f9590
--- /dev/null
+++ b/src/client_reverse_udp.h
@@ -0,0 +1,41 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#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"
+#include "ssl_fd_struct.h"
+#include "client_realm_struct.h"
+
+int initialize_client_reverse_udp(ClientRealm* cr);
+void client_reverse_udp(ClientRealm* cr, unsigned char* buff, int buflength);
+
+#endif
diff --git a/src/client_shutdown.c b/src/client_shutdown.c
new file mode 100644
index 0000000..1847899
--- /dev/null
+++ b/src/client_shutdown.c
@@ -0,0 +1,48 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+#include <assert.h>
+
+#include "client_shutdown.h"
+
+void
+close_connections(int usernum, ConnectUser*** contable)
+{
+ int i;
+
+ assert(contable != NULL);
+ if (contable == NULL) {
+ return;
+ }
+
+ if (*contable) {
+ for (i = 0; i < usernum; ++i) {
+ if ((ConnectUser_get_state((*contable)[i]) == S_STATE_OPEN) ||
+ (ConnectUser_get_state((*contable)[i]) == S_STATE_STOPPED)) {
+ close(ConnectUser_get_connFd((*contable)[i]));
+ }
+ ConnectUser_free(&(*contable)[i]);
+ }
+ free(*contable);
+ (*contable) = NULL;
+ }
+}
+
diff --git a/src/client_shutdown.h b/src/client_shutdown.h
new file mode 100644
index 0000000..959fae0
--- /dev/null
+++ b/src/client_shutdown.h
@@ -0,0 +1,30 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#ifndef _JS_CLIENT_SHUTDOWN_H
+#define _JS_CLIENT_SHUTDOWN_H
+
+#include "activefor.h"
+
+void close_connections(int usernum, ConnectUser*** contable);
+
+#endif
diff --git a/src/client_signals.c b/src/client_signals.c
new file mode 100644
index 0000000..04c344e
--- /dev/null
+++ b/src/client_signals.c
@@ -0,0 +1,60 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "client_signals.h"
+#include "thread_management.h"
+#include "stats.h"
+#include "logging.h"
+
+#include <stdlib.h>
+
+/*
+ * Function name: client_sig_int
+ * Description: Function responsible for handling SIG_INT.
+ * Arguments: signo - the signal number
+ */
+
+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);
+}
+
+/*
+ * Function name: client_sig_alrm
+ * Description: Function responsible for handling SIG_ALRM.
+ * Arguments: signo - the signal number
+ */
+
+void
+client_sig_alrm(int signo)
+{
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "Received SIGALRM");
+}
diff --git a/src/client_signals.h b/src/client_signals.h
new file mode 100644
index 0000000..03c14cf
--- /dev/null
+++ b/src/client_signals.h
@@ -0,0 +1,28 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_CLIENT_SIGNALS_H
+#define _JS_CLIENT_SIGNALS_H
+
+void client_sig_int(int); /* INT signal handler for the afclient */
+void client_sig_alrm(int); /* ALRM signal handler for the afclient */
+
+#endif
+
diff --git a/src/clientnames.c b/src/clientnames.c
new file mode 100644
index 0000000..750b9c9
--- /dev/null
+++ b/src/clientnames.c
@@ -0,0 +1,173 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "clientnames.h"
+
+char*
+get_clientname(ServerRealm* pointer, int client)
+{
+ static char clientname[10];
+
+ assert(pointer != NULL);
+ if (pointer == NULL) {
+ return NULL;
+ }
+
+ if (ConnectClient_get_sClientId(ServerRealm_get_clientsTable(pointer)[client]) == NULL) {
+ memset(clientname, 0, 10);
+ sprintf(clientname, "%d", ConnectClient_get_clientId(ServerRealm_get_clientsTable(pointer)[client]));
+ return clientname;
+ }
+
+ return ConnectClient_get_sClientId(ServerRealm_get_clientsTable(pointer)[client]);
+}
+
+int
+get_clientid(ServerRealm* pointer, char* clientname)
+{
+ int i, n;
+ char guard;
+
+ assert(pointer != NULL);
+ if (pointer == NULL) {
+ return -1;
+ }
+
+ assert(clientname != NULL);
+ if (clientname == NULL) {
+ return -1;
+ }
+
+ for (i = 0; i < ServerRealm_get_clientsLimit(pointer); ++i) {
+ if (ConnectClient_get_sClientId(ServerRealm_get_clientsTable(pointer)[i]) != NULL) {
+ if (strcmp(clientname, ConnectClient_get_sClientId(ServerRealm_get_clientsTable(pointer)[i])) == 0) {
+ return ConnectClient_get_clientId(ServerRealm_get_clientsTable(pointer)[i]);
+ }
+ }
+ }
+
+ if (sscanf(clientname, "%d%c", &i, &guard) == 1) {
+ n = get_clientnumber(pointer, i);
+ if ((n >= 0) && (n < ServerRealm_get_clientsLimit(pointer))) {
+ if (ConnectClient_get_sClientId(ServerRealm_get_clientsTable(pointer)[n]) == NULL) {
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+int
+get_clientnumber(ServerRealm* pointer, int clientid)
+{
+ int i;
+
+ assert(pointer != NULL);
+ if (pointer == NULL) {
+ return -1;
+ }
+
+ for (i = 0; i < ServerRealm_get_clientsLimit(pointer); ++i) {
+ if (ConnectClient_get_clientId(ServerRealm_get_clientsTable(pointer)[i]) == clientid) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+char*
+get_raclientname(ServerRealm* pointer, int client)
+{
+ static char clientname[10];
+
+ assert(pointer != NULL);
+ if (pointer == NULL) {
+ return NULL;
+ }
+
+ if (ConnectClient_get_sClientId(ServerRealm_get_raClientsTable(pointer)[client]) == NULL) {
+ memset(clientname, 0, 10);
+ sprintf(clientname, "%d", ConnectClient_get_clientId(ServerRealm_get_raClientsTable(pointer)[client]));
+ return clientname;
+ }
+
+ return ConnectClient_get_sClientId(ServerRealm_get_raClientsTable(pointer)[client]);
+}
+
+int
+get_raclientid(ServerRealm* pointer, char* clientname)
+{
+ int i, n;
+ char guard;
+
+ assert(pointer != NULL);
+ if (pointer == NULL) {
+ return -1;
+ }
+
+ assert(clientname != NULL);
+ if (clientname == NULL) {
+ return -1;
+ }
+
+ for (i = 0; i < ServerRealm_get_raClientsLimit(pointer); ++i) {
+ if (ConnectClient_get_sClientId(ServerRealm_get_raClientsTable(pointer)[i]) != NULL) {
+ if (strcmp(clientname, ConnectClient_get_sClientId(ServerRealm_get_raClientsTable(pointer)[i])) == 0) {
+ return ConnectClient_get_clientId(ServerRealm_get_raClientsTable(pointer)[i]);
+ }
+ }
+ }
+
+ if (sscanf(clientname, "%d%c", &i, &guard) == 1) {
+ n = get_raclientnumber(pointer, i);
+ if ((n >= 0) && (n < ServerRealm_get_raClientsLimit(pointer))) {
+ if (ConnectClient_get_sClientId(ServerRealm_get_raClientsTable(pointer)[n]) == NULL) {
+ return i;
+ }
+ }
+ }
+
+ return -1;
+}
+
+int
+get_raclientnumber(ServerRealm* pointer, int clientid)
+{
+ int i;
+
+ assert(pointer != NULL);
+ if (pointer == NULL) {
+ return -1;
+ }
+
+ for (i = 0; i < ServerRealm_get_raClientsLimit(pointer); ++i) {
+ if (ConnectClient_get_clientId(ServerRealm_get_raClientsTable(pointer)[i]) == clientid) {
+ return i;
+ }
+ }
+
+ return -1;
+}
diff --git a/src/clientnames.h b/src/clientnames.h
new file mode 100644
index 0000000..9f93596
--- /dev/null
+++ b/src/clientnames.h
@@ -0,0 +1,36 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "activefor.h"
+#include "server_realm_struct.h"
+
+#ifndef _JS_CLIENTNAMES_H
+#define _JS_CLIENTNAMES_H
+
+char* get_clientname(ServerRealm*, int);
+int get_clientid(ServerRealm*, char*);
+int get_clientnumber(ServerRealm*, int);
+
+char* get_raclientname(ServerRealm*, int);
+int get_raclientid(ServerRealm*, char*);
+int get_raclientnumber(ServerRealm*, int);
+
+#endif
+
diff --git a/src/connect_client_struct.c b/src/connect_client_struct.c
new file mode 100644
index 0000000..7d57b4b
--- /dev/null
+++ b/src/connect_client_struct.c
@@ -0,0 +1,863 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "string_functions.h"
+#include "timeval_functions.h"
+#include "connect_client_struct.h"
+
+/*
+ * Function name: ConnectClient_new
+ * Description: Creates and initializes new ConnectClient structure.
+ * Returns: Pointer to newly created ConnectClient structure.
+ */
+
+ConnectClient*
+ConnectClient_new()
+{
+ ConnectClient* tmp = calloc(1, sizeof(ConnectClient));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ tmp->sslFd = SslFd_new();
+ assert(tmp->sslFd != NULL);
+ if (tmp->sslFd == NULL) {
+ ConnectClient_free(&tmp);
+ return NULL;
+ }
+ tmp->auditList = AuditList_new();
+ assert(tmp->auditList != NULL);
+ if (tmp->auditList == NULL) {
+ ConnectClient_free(&tmp);
+ return NULL;
+ }
+ tmp->header = HeaderBuffer_new();
+ assert(tmp->header != NULL);
+ if (tmp->header == NULL) {
+ ConnectClient_free(&tmp);
+ return NULL;
+ }
+ return tmp;
+}
+
+/*
+ * Function name: ConnectClient_free
+ * Description: Frees the memory allocated for ConnectClient structure.
+ * Arguments: cc - pointer to pointer to ConnectClient structure
+ */
+
+void
+ConnectClient_free(ConnectClient** cc)
+{
+ SslFd* sftmp;
+ AuditList* altmp;
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ assert((*cc) != NULL);
+ if ((*cc) == NULL) {
+ return;
+ }
+ sftmp = ConnectClient_get_sslFd((*cc));
+ altmp = ConnectClient_get_auditList((*cc));
+ SslFd_free(&sftmp);
+ AuditList_free(&altmp);
+ if ((*cc)->users) {
+ free((*cc)->users);
+ (*cc)->users = NULL;
+ }
+ if ((*cc)->sClientId) {
+ free((*cc)->sClientId);
+ (*cc)->sClientId = NULL;
+ }
+ free((*cc));
+ (*cc) = NULL;
+}
+
+/*
+ * Function name: ConnectClient_set_state
+ * Description: Sets state of the connected client.
+ * Arguments: cc - pointer to ConnectClient structure
+ * state - state of the connected client
+ */
+
+void
+ConnectClient_set_state(ConnectClient* cc, char state)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ cc->state = state;
+}
+
+/*
+ * Function name: ConnectClient_set_sslFd
+ * Description: Sets SslFd structure.
+ * Arguments: cc - pointer to ConnectClient structure
+ * sf - SslFd structure
+ */
+
+void
+ConnectClient_set_sslFd(ConnectClient* cc, SslFd* sf)
+{
+ SslFd* sftmp;
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ sftmp = ConnectClient_get_sslFd(cc);
+ SslFd_free(&sftmp);
+ cc->sslFd = sf;
+}
+
+/*
+ * Function name: ConnectClient_set_timer
+ * Description: Sets timer of the client used for internal time counting.
+ * Arguments: cc - pointer to ConnectClient structure
+ * timer - timer of the client used for internal time counting
+ */
+
+void
+ConnectClient_set_timer(ConnectClient* cc, struct timeval timer)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ cc->timer = timer;
+}
+
+/*
+ * Function name: ConnectClient_set_users
+ * Description: Sets users descriptor table.
+ * Arguments: cc - pointer to ConnectClient structure
+ * users - users descriptor table
+ */
+
+void
+ConnectClient_set_users(ConnectClient* cc, int* users)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ if (cc->users) {
+ free(cc->users);
+ }
+ cc->users = users;
+}
+
+/*
+ * Functions name: ConnectClient_set_connected
+ * Description: Sets number of connected users.
+ * Arguments: cc - pointer to ConnectClient structure
+ * connected - number of connected users
+ */
+
+void
+ConnectClient_set_connected(ConnectClient* cc, int connected)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ cc->connected = connected;
+}
+
+/*
+ * Function name: ConnectClient_set_limit
+ * Description: Sets limit of connected users.
+ * Arguments: cc - pointer to ConnectClient structure
+ * limit - limit of connected users
+ */
+
+void
+ConnectClient_set_limit(ConnectClient* cc, int limit)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ cc->limit = limit;
+}
+
+/*
+ * Function name: ConnectClient_set_listenFd
+ * Description: Sets listen socket descriptor.
+ * Arguments: cc - pointer to ConnectClient structure
+ * listenFd - listen socket descriptor
+ */
+
+void
+ConnectClient_set_listenFd(ConnectClient* cc, int listenFd)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ cc->listenFd = listenFd;
+}
+
+/*
+ * Function name: ConnectClient_set_usrCliPair
+ * Description: Sets user-client pair number.
+ * Arguments: cc - pointer to ConnectClient structure
+ * usrCliPair - user-client pair number
+ */
+
+void
+ConnectClient_set_usrCliPair(ConnectClient* cc, int usrCliPair)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ cc->usrCliPair = usrCliPair;
+}
+
+/*
+ * Function name: ConnectClient_set_clientId
+ * Description: Sets client identification number.
+ * Arguments: cc - pointer to ConnectClient structure
+ * clientId - client identification number
+ */
+
+void
+ConnectClient_set_clientId(ConnectClient* cc, int clientId)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ cc->clientId = clientId;
+}
+
+/*
+ * Function name: ConnectClient_set_connectTime
+ * Description: Sets start time of the connection.
+ * Arguments: cc - pointer to ConnectClient structure
+ * connectTime - start time of the connection
+ */
+
+void
+ConnectClient_set_connectTime(ConnectClient* cc, time_t connectTime)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ cc->connectTime = connectTime;
+}
+
+/*
+ * Function name: ConnectClient_set_lastActivity
+ * Description: Sets time of the last client activity (when last packet from afclient has arrived)
+ * Arguments: cc - pointer to ConnectClient structure
+ * lastActivity - time of the last client activity
+ */
+
+void
+ConnectClient_set_lastActivity(ConnectClient* cc, time_t lastActivity)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ cc->lastActivity = lastActivity;
+}
+
+/*
+ * Function name: ConnectClient_set_sClientId
+ * Description: Sets client identification string.
+ * Arguments: cc - pointer to ConnectClient structure
+ * sClientId - client identification string
+ */
+
+void
+ConnectClient_set_sClientId(ConnectClient* cc, char* sClientId)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ string_cp(&(cc->sClientId), sClientId);
+}
+
+/*
+ * Function name: ConnectClient_set_nameBuf
+ * Description: Sets name of the client.
+ * Arguments: cc - pointer to ConnectClient structure
+ * nameBuf - name of the client
+ */
+
+void
+ConnectClient_set_nameBuf(ConnectClient* cc, char* nameBuf)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ memset(cc->nameBuf, 0, 128);
+ strncpy(cc->nameBuf, nameBuf, 127);
+}
+
+/*
+ * Function name: ConnectClient_set_portBuf
+ * Description: Sets port from which client is connected.
+ * Arguments: cc - pointer to ConnectClient structure
+ * portBuf - port from which client is connected
+ */
+
+void
+ConnectClient_set_portBuf(ConnectClient* cc, char* portBuf)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ memset(cc->portBuf, 0, 7);
+ strncpy(cc->portBuf, portBuf, 6);
+}
+
+/*
+ * Function name: ConnectClient_set_tunnelType
+ * Description: Sets tupe of the client tunnel.
+ * Arguments: cc - pointer to ConnectClient structure
+ * tunnelType - tupe of the client tunnel
+ */
+
+void
+ConnectClient_set_tunnelType(ConnectClient* cc, char tunnelType)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ cc->tunnelType = tunnelType;
+}
+
+/*
+ * Function name: ConnectClient_set_multi
+ * Description: Sets the status of the multi option.
+ * Arguments: cc - pointer to ConnectClient structure
+ * multi - the status of the multi option
+ */
+
+void
+ConnectClient_set_multi(ConnectClient* cc, char multi)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ assert((multi == CONNECTCLIENT_MULTI_ENABLED) || (multi == CONNECTCLIENT_MULTI_DISABLED));
+ cc->multi = multi;
+}
+
+/*
+ * Function name: ConnectClient_set_auditList
+ * Description: Sets audit list for the audit feature.
+ * Arguments: cc - pointer to ConnectClient structure
+ * al - audit list for the audit feature
+ */
+
+void
+ConnectClient_set_auditList(ConnectClient* cc, AuditList* al)
+{
+ AuditList* altmp;
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ altmp = ConnectClient_get_auditList(cc);
+ AuditList_free(&altmp);
+ cc->auditList = al;
+}
+
+/*
+ * Function name: ConnectClient_set_header
+ * Description: Sets header buffer for incomplete headers.
+ * Arguments: cc - pointer to ConnectClient structure
+ * hb - header buffer for incomplete headers
+ */
+
+void
+ConnectClient_set_header(ConnectClient* cc, HeaderBuffer* hb)
+{
+ HeaderBuffer* hbtmp;
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ hbtmp = ConnectClient_get_header(cc);
+ HeaderBuffer_free(&hbtmp);
+ cc->header = hb;
+}
+
+/*
+ * Function name: ConnectClient_set_task
+ * Description: Sets the client task.
+ * Arguments: cc - pointer to ConnectClient structure
+ * task - the task to set
+ */
+
+void
+ConnectClient_set_task(ConnectClient* cc, Task* task)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ if (cc->task) {
+ Task_free(&(cc->task));
+ }
+ cc->task = task;
+}
+
+/*
+ * Function name: ConnectClient_get_state
+ * Description: Gets state of the connected client.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: State of the connected client.
+ */
+
+char
+ConnectClient_get_state(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return CONNECTCLIENT_STATE_UNKNOWN;
+ }
+ return cc->state;
+}
+
+/*
+ * Function name: ConnectClient_get_sslFd
+ * Description: Gets SslFd structure.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: SslFd structure.
+ */
+
+SslFd*
+ConnectClient_get_sslFd(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return NULL;
+ }
+ return cc->sslFd;
+}
+
+/*
+ * Function name: ConnectClient_get_timer
+ * Description: Gets timer of the client used for internal time counting.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: Timer of the client used for internal time counting.
+ */
+
+struct timeval
+ConnectClient_get_timer(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return timeval_create(0, 0);
+ }
+ return cc->timer;
+}
+
+/*
+ * Function name: ConnectClient_get_users
+ * Description: Gets users descriptor table.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: Users descriptor table.
+ */
+
+int*
+ConnectClient_get_users(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return NULL;
+ }
+ return cc->users;
+}
+
+/*
+ * Function name: ConnectClient_get_connected
+ * Description: Gets number of connected users.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: Number of connected users.
+ */
+
+int
+ConnectClient_get_connected(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return -1;
+ }
+ return cc->connected;
+}
+
+/*
+ * Function name: ConnectClient_get_limit
+ * Description: Gets limit of connected users.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: Limit of connected users.
+ */
+
+int
+ConnectClient_get_limit(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return -1;
+ }
+ return cc->limit;
+}
+
+/*
+ * Function name: ConnectClient_get_listenFd
+ * Description: Gets listen socket descriptor.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: Listen socket descriptor.
+ */
+
+int
+ConnectClient_get_listenFd(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return -1;
+ }
+ return cc->listenFd;
+}
+
+/*
+ * Function name: ConnectClient_get_usrCliPair
+ * Description: Gets user-client pair number.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: User-client pair number.
+ */
+
+int
+ConnectClient_get_usrCliPair(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return -1;
+ }
+ return cc->usrCliPair;
+}
+
+/*
+ * Function name: ConnectClient_get_clientId
+ * Description: Gets client identification number.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: Client identification number.
+ */
+
+int
+ConnectClient_get_clientId(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return -1;
+ }
+ return cc->clientId;
+}
+
+/*
+ * Function name: ConnectClient_get_connectTime
+ * Description: Gets start time of the connection.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: Start time of the connection.
+ */
+
+time_t
+ConnectClient_get_connectTime(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return 0;
+ }
+ return cc->connectTime;
+}
+
+/*
+ * Function name: ConnectClient_get_lastActivity
+ * Description: Gets time of the last client activity (when last packet from afclient has arrived)
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: Time of the last client activity.
+ */
+
+time_t
+ConnectClient_get_lastActivity(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return 0;
+ }
+ return cc->lastActivity;
+}
+
+/*
+ * Function name: ConnectClient_get_sClientId
+ * Description: Gets client identification string.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: Client identification string.
+ */
+
+char*
+ConnectClient_get_sClientId(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return NULL;
+ }
+ return cc->sClientId;
+}
+
+/*
+ * Function name: ConnectClient_get_nameBuf
+ * Description: Gets name of the client.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: Name of the client.
+ */
+
+char*
+ConnectClient_get_nameBuf(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return NULL;
+ }
+ return cc->nameBuf;
+}
+
+/*
+ * Function name: ConnectClient_get_portBuf
+ * Description: Gets port from which client is connected.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: Port from which client is connected.
+ */
+
+char*
+ConnectClient_get_portBuf(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return NULL;
+ }
+ return cc->portBuf;
+}
+
+/*
+ * Function name: ConnectClient_get_tunnelType
+ * Description: Gets tupe of the client tunnel.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: Tupe of the client tunnel.
+ */
+
+char
+ConnectClient_get_tunnelType(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return CONNECTCLIENT_TUNNELTYPE_UNKNOWN;
+ }
+ return cc->tunnelType;
+}
+
+/*
+ * Function name: ConnectClient_get_multi
+ * Description: Gets the status of the multi option.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: CONNECTCLIENT_MULTI_ENABLED - the option is enabled,
+ * CONNECTCLIENT_MULTI_DISABLED - the option is disabled.
+ */
+
+char
+ConnectClient_get_multi(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return CONNECTCLIENT_MULTI_DISABLED;
+ }
+ return cc->multi;
+}
+
+/*
+ * Function name: ConnectClient_get_auditList
+ * Description: Gets audit list for the audit feature.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: Audit list for the audit feature.
+ */
+
+AuditList*
+ConnectClient_get_auditList(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return NULL;
+ }
+ return cc->auditList;
+}
+
+/*
+ * Function name: ConnectClient_get_header
+ * Description: Gets header buffer for incomplete headers.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: Header buffer for incomplete headers.
+ */
+
+HeaderBuffer*
+ConnectClient_get_header(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return NULL;
+ }
+ return cc->header;
+}
+
+/*
+ * Function name: ConnectClient_get_task
+ * Description: Gets the client task.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: The client task.
+ */
+
+Task*
+ConnectClient_get_task(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return NULL;
+ }
+ return cc->task;
+}
+
+/*
+ * Function name: ConnectClient_create_users
+ * Description: Creates user descriptor table. Memory for the table is allocated according
+ * to the previously set 'limit' value. All the descriptors are set to -1.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: >0 - there were some problems with memory allocation
+ * 0 - everything was ok
+ */
+
+int
+ConnectClient_create_users(ConnectClient* cc)
+{
+ int i, limit;
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return 1;
+ }
+ limit = ConnectClient_get_limit(cc);
+ assert(limit != -1);
+ if (limit == -1) {
+ return 2;
+ }
+ cc->users = malloc(limit * sizeof(int));
+ assert(cc->users != NULL);
+ if (cc->users == NULL) {
+ return 3;
+ }
+ for (i = 0; i < limit; ++i) {
+ cc->users[i] = -1;
+ }
+ return 0;
+}
+
+/*
+ * Function name: ConnectClient_get_timerp
+ * Description: Gets pointer to timer of the client used for internal time counting.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: Pointer to timer of the client used for internal time counting.
+ */
+
+struct timeval*
+ConnectClient_get_timerp(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return NULL;
+ }
+ return (&(cc->timer));
+}
+
+/*
+ * Function name: ConnectClient_increase_connected
+ * Description: Increases number of connected users.
+ * Arguments: cc - pointer to ConnectClient structure
+ */
+
+void
+ConnectClient_increase_connected(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ ConnectClient_set_connected(cc, ConnectClient_get_connected(cc) + 1);
+}
+
+/*
+ * Function name: ConnectClient_decrease_connected
+ * Description: Decreases number of connected users.
+ * Arguments: cc - pointer to ConnectClient structure
+ */
+
+void
+ConnectClient_decrease_connected(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return;
+ }
+ ConnectClient_set_connected(cc, ConnectClient_get_connected(cc) - 1);
+}
+
+/*
+ * Function name: ConnectClient_get_listenFdp
+ * Description: Gets pointer to listen socket descriptor.
+ * Arguments: cc - pointer to ConnectClient structure
+ * Returns: Pointer to listen socket descriptor.
+ */
+
+int*
+ConnectClient_get_listenFdp(ConnectClient* cc)
+{
+ assert(cc != NULL);
+ if (cc == NULL) {
+ return NULL;
+ }
+ return (&(cc->listenFd));
+}
diff --git a/src/connect_client_struct.h b/src/connect_client_struct.h
new file mode 100644
index 0000000..9cf2e6d
--- /dev/null
+++ b/src/connect_client_struct.h
@@ -0,0 +1,119 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef _JS_CONNECT_CLIENT_STRUCT_H
+#define _JS_CONNECT_CLIENT_STRUCT_H
+
+#include <time.h>
+
+#include "ssl_fd_struct.h"
+#include "audit_list_struct.h"
+#include "header_buffer_struct.h"
+#include "task_struct.h"
+
+#define CONNECTCLIENT_STATE_UNKNOWN -1
+#define CONNECTCLIENT_STATE_FREE 0
+#define CONNECTCLIENT_STATE_CONNECTING 1
+#define CONNECTCLIENT_STATE_AUTHORIZING 2
+#define CONNECTCLIENT_STATE_ACCEPTED 3
+
+#define CONNECTCLIENT_TUNNELTYPE_UNKNOWN -1
+#define CONNECTCLIENT_TUNNELTYPE_DIRECT 0
+#define CONNECTCLIENT_TUNNELTYPE_HTTPPROXY 1
+#define CONNECTCLIENT_TUNNELTYPE_HTTPSPROXY 2
+
+#define CONNECTCLIENT_MULTI_ENABLED 1
+#define CONNECTCLIENT_MULTI_DISABLED 0
+
+typedef struct {
+ char state;
+ SslFd* sslFd;
+ struct timeval timer;
+ int* users;
+ int connected;
+ int limit;
+ int listenFd;
+ int usrCliPair;
+ int clientId;
+ time_t connectTime;
+ time_t lastActivity;
+ char* sClientId;
+ char nameBuf[128];
+ char portBuf[7];
+ char tunnelType;
+ char multi;
+ AuditList* auditList;
+ HeaderBuffer* header;
+ Task* task;
+} ConnectClient;
+
+/* 'constructor' */
+ConnectClient* ConnectClient_new();
+/* 'destructor' */
+void ConnectClient_free(ConnectClient** cc);
+/* setters */
+void ConnectClient_set_state(ConnectClient* cc, char state);
+void ConnectClient_set_sslFd(ConnectClient* cc, SslFd* sf);
+void ConnectClient_set_timer(ConnectClient* cc, struct timeval timer);
+void ConnectClient_set_users(ConnectClient* cc, int* users);
+void ConnectClient_set_connected(ConnectClient* cc, int connected);
+void ConnectClient_set_limit(ConnectClient* cc, int limit);
+void ConnectClient_set_listenFd(ConnectClient* cc, int listenFd);
+void ConnectClient_set_usrCliPair(ConnectClient* cc, int usrCliPair);
+void ConnectClient_set_clientId(ConnectClient* cc, int clientId);
+void ConnectClient_set_connectTime(ConnectClient* cc, time_t connectTime);
+void ConnectClient_set_lastActivity(ConnectClient* cc, time_t lastActivity);
+void ConnectClient_set_sClientId(ConnectClient* cc, char* sClientId);
+void ConnectClient_set_nameBuf(ConnectClient* cc, char* nameBuf);
+void ConnectClient_set_portBuf(ConnectClient* cc, char* portBuf);
+void ConnectClient_set_tunnelType(ConnectClient* cc, char tunnelType);
+void ConnectClient_set_multi(ConnectClient* cc, char multi);
+void ConnectClient_set_auditList(ConnectClient* cc, AuditList* al);
+void ConnectClient_set_header(ConnectClient* cc, HeaderBuffer* hb);
+void ConnectClient_set_task(ConnectClient* cc, Task* task);
+/* getters */
+char ConnectClient_get_state(ConnectClient* cc);
+SslFd* ConnectClient_get_sslFd(ConnectClient* cc);
+struct timeval ConnectClient_get_timer(ConnectClient* cc);
+int* ConnectClient_get_users(ConnectClient* cc);
+int ConnectClient_get_connected(ConnectClient* cc);
+int ConnectClient_get_limit(ConnectClient* cc);
+int ConnectClient_get_listenFd(ConnectClient* cc);
+int ConnectClient_get_usrCliPair(ConnectClient* cc);
+int ConnectClient_get_clientId(ConnectClient* cc);
+time_t ConnectClient_get_connectTime(ConnectClient* cc);
+time_t ConnectClient_get_lastActivity(ConnectClient* cc);
+char* ConnectClient_get_sClientId(ConnectClient* cc);
+char* ConnectClient_get_nameBuf(ConnectClient* cc);
+char* ConnectClient_get_portBuf(ConnectClient* cc);
+char ConnectClient_get_tunnelType(ConnectClient* cc);
+char ConnectClient_get_multi(ConnectClient* cc);
+AuditList* ConnectClient_get_auditList(ConnectClient* cc);
+HeaderBuffer* ConnectClient_get_header(ConnectClient* cc);
+Task* ConnectClient_get_task(ConnectClient* cc);
+/* other */
+int ConnectClient_create_users(ConnectClient* cc);
+struct timeval* ConnectClient_get_timerp(ConnectClient* cc);
+void ConnectClient_increase_connected(ConnectClient* cc);
+void ConnectClient_decrease_connected(ConnectClient* cc);
+int* ConnectClient_get_listenFdp(ConnectClient* cc);
+
+#endif
diff --git a/src/connect_user_struct.c b/src/connect_user_struct.c
new file mode 100644
index 0000000..ac6fe3c
--- /dev/null
+++ b/src/connect_user_struct.c
@@ -0,0 +1,398 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "activefor.h"
+#include "connect_user_struct.h"
+
+/*
+ * Function name: ConnectUser_new
+ * Description: Create and initialize new ConnectUser structure.
+ * Returns: Newly created ConnectUser structure.
+ */
+
+ConnectUser*
+ConnectUser_new()
+{
+ ConnectUser* tmp = calloc(1, sizeof(ConnectUser));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ tmp->bufList = BufList_new();
+ assert(tmp->bufList != NULL);
+ if (tmp->bufList == NULL) {
+ ConnectUser_free(&tmp);
+ return NULL;
+ }
+ tmp->stats = UserStats_new();
+ assert(tmp->stats != NULL);
+ if (tmp->stats == NULL) {
+ ConnectUser_free(&tmp);
+ return NULL;
+ }
+ return tmp;
+}
+
+/*
+ * Function name: ConnectUser_free
+ * Description: Free the memory allocated for ConnectUser structure.
+ * Arguments: cu - pointer to pointer to ConnectUser structure
+ */
+
+void
+ConnectUser_free(ConnectUser** cu)
+{
+ BufList* bftmp;
+ UserStats* ustmp;
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return;
+ }
+ assert((*cu) != NULL);
+ if ((*cu) == NULL) {
+ return;
+ }
+ bftmp = ConnectUser_get_bufList((*cu));
+ ustmp = ConnectUser_get_stats((*cu));
+ BufList_free(&bftmp);
+ UserStats_free(&ustmp);
+ free((*cu));
+ (*cu) = NULL;
+}
+
+/*
+ * Function name: ConnectUser_set_state
+ * Description: Set state of the connected user.
+ * Arguments: cu - pointer to ConnectUser structure
+ * state - state of the connected User
+ */
+
+void
+ConnectUser_set_state(ConnectUser* cu, char state)
+{
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return;
+ }
+ cu->state = state;
+}
+
+/*
+ * Function name: ConnectUser_set_connFd
+ * Description: Set connection's file descriptor.
+ * Arguments: cu - pointer to ConnectUser structure
+ * connFd - connection's file descriptor
+ */
+
+void
+ConnectUser_set_connFd(ConnectUser* cu, int connFd)
+{
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return;
+ }
+ cu->connFd = connFd;
+}
+
+/*
+ * Function name: ConnectUser_set_whatClient
+ * Description: Set client number, to which this user is connected to.
+ * Arguments: cu - pointer to ConnectUser structure
+ * whatClient - client number, to which this user is connected to
+ */
+
+void
+ConnectUser_set_whatClient(ConnectUser* cu, int whatClient)
+{
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return;
+ }
+ cu->whatClient = whatClient;
+}
+
+/*
+ * Function name: ConnectUser_set_userId
+ * Description: Set user identification number.
+ * Arguments: cu - pointer to ConnectUser structure
+ * userId - user identification number
+ */
+
+void
+ConnectUser_set_userId(ConnectUser* cu, int userId)
+{
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return;
+ }
+ cu->userId = userId;
+}
+
+/*
+ * Function name: ConnectUser_set_connectTime
+ * Description: Set connect time of the user.
+ * Arguments: cu - pointer to ConnectUser structure
+ * connectTime - connect time of the user
+ */
+
+void
+ConnectUser_set_connectTime(ConnectUser* cu, time_t connectTime)
+{
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return;
+ }
+ cu->connectTime = connectTime;
+}
+
+/*
+ * Function name: ConnectUser_set_nameBuf
+ * Description: Set name of the user.
+ * Arguments: cu - pointer to ConnectUser structure
+ * nameBuf - name of the user
+ */
+
+void
+ConnectUser_set_nameBuf(ConnectUser* cu, char* nameBuf)
+{
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return;
+ }
+ memset(cu->nameBuf, 0, 128);
+ strncpy(cu->nameBuf, nameBuf, 127);
+}
+
+/*
+ * Function name: ConnectUser_set_portBuf
+ * Description: Set port from which user is connected.
+ * Arguments: cu - pointer to ConnectUser structure
+ * portBuf - port from which user is connected
+ */
+
+void
+ConnectUser_set_portBuf(ConnectUser* cu, char* portBuf)
+{
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return;
+ }
+ memset(cu->portBuf, 0, 7);
+ strncpy(cu->portBuf, portBuf, 6);
+}
+
+/*
+ * Function name: ConnectUser_set_bufList
+ * Description: Set buffer list for incoming packets.
+ * Arguments: cu - pointer to ConnectUser structure
+ * bufList - buffer list for incoming packets
+ */
+
+void
+ConnectUser_set_bufList(ConnectUser* cu, BufList* bufList)
+{
+ BufList* bftmp;
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return;
+ }
+ bftmp = ConnectUser_get_bufList(cu);
+ BufList_free(&bftmp);
+ cu->bufList = bufList;
+}
+
+/*
+ * Function name: ConnectUser_set_stats
+ * Description: Set stats object for this user.
+ * Arguments: cu - pointer to ConnectUser structure
+ * stats - stats object for this user
+ */
+
+void
+ConnectUser_set_stats(ConnectUser* cu, UserStats* stats)
+{
+ UserStats* ustmp;
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return;
+ }
+ ustmp = ConnectUser_get_stats(cu);
+ UserStats_free(&ustmp);
+ cu->stats = stats;
+}
+
+/*
+ * Function name: ConnectUser_get_state
+ * Description: Get state of the connected user.
+ * Arguments: cu - pointer to ConnectUser structure
+ * Returns: State of the connected user.
+ */
+
+char
+ConnectUser_get_state(ConnectUser* cu)
+{
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return S_STATE_CLEAR;
+ }
+ return cu->state;
+}
+
+/*
+ * Function name: ConnectUser_get_connFd
+ * Description: Get connection's file descriptor.
+ * Arguments: cu - pointer to ConnectUser structure
+ * Returns: Connection's file descriptor.
+ */
+
+int
+ConnectUser_get_connFd(ConnectUser* cu)
+{
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return -1;
+ }
+ return cu->connFd;
+}
+
+/*
+ * Function name: ConnectUser_get_whatClient
+ * Description: Get client number, to which this user is connected to.
+ * Arguments: cu - pointer to ConnectUser structure
+ * Returns: Client number, to which this user is connected to.
+ */
+
+int
+ConnectUser_get_whatClient(ConnectUser* cu)
+{
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return -1;
+ }
+ return cu->whatClient;
+}
+
+/*
+ * Function name: ConnectUser_get_userId
+ * Description: Get user identification number.
+ * Arguments: cu - pointer to ConnectUser structure
+ * Returns: User identification number.
+ */
+
+int
+ConnectUser_get_userId(ConnectUser* cu)
+{
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return -1;
+ }
+ return cu->userId;
+}
+
+/*
+ * Function name: ConnectUser_get_connectTime
+ * Description: Get connect time of the user.
+ * Arguments: cu - pointer to ConnectUser structure
+ * Returns: Connect time of the user.
+ */
+
+time_t
+ConnectUser_get_connectTime(ConnectUser* cu)
+{
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return 0;
+ }
+ return cu->connectTime;
+}
+
+/*
+ * Function name: ConnectUser_get_nameBuf
+ * Description: Get name of the user.
+ * Arguments: cu - pointer to ConnectUser structure
+ * Returns: Name of the user.
+ */
+
+char*
+ConnectUser_get_nameBuf(ConnectUser* cu)
+{
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return NULL;
+ }
+ return cu->nameBuf;
+}
+
+/*
+ * Function name: ConnectUser_get_portBuf
+ * Description: Get port from which user is connected.
+ * Arguments: cu - pointer to ConnectUser structure
+ * Returns: Port from which user is connected.
+ */
+
+char*
+ConnectUser_get_portBuf(ConnectUser* cu)
+{
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return NULL;
+ }
+ return cu->portBuf;
+}
+
+/*
+ * Function name: ConnectUser_get_bufList
+ * Description: Get buffer list for incoming packets.
+ * Arguments: cu - pointer to ConnectUser structure
+ * Returns: Buffer list for incoming packets.
+ */
+
+BufList*
+ConnectUser_get_bufList(ConnectUser* cu)
+{
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return NULL;
+ }
+ return cu->bufList;
+}
+
+/*
+ * Function name: ConnectUser_get_stats
+ * Description: Get stats object for this user.
+ * Arguments: cu - pointer to ConnectUser structure
+ * Returns: Stats object for this user.
+ */
+
+UserStats*
+ConnectUser_get_stats(ConnectUser* cu)
+{
+ assert(cu != NULL);
+ if (cu == NULL) {
+ return NULL;
+ }
+ return cu->stats;
+}
diff --git a/src/connect_user_struct.h b/src/connect_user_struct.h
new file mode 100644
index 0000000..8e424d2
--- /dev/null
+++ b/src/connect_user_struct.h
@@ -0,0 +1,67 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef _JS_CONNECT_USER_STRUCT_H
+#define _JS_CONNECT_USER_STRUCT_H
+
+#include <sys/types.h>
+
+#include "buf_list_struct.h"
+#include "user_stats_struct.h"
+
+typedef struct {
+ char state;
+ int connFd;
+ int whatClient;
+ int userId;
+ time_t connectTime;
+ char nameBuf[128];
+ char portBuf[7];
+ BufList* bufList;
+ UserStats* stats;
+} ConnectUser;
+
+/* 'constructor' */
+ConnectUser* ConnectUser_new();
+/* 'destructor' */
+void ConnectUser_free(ConnectUser** cu);
+/* setters */
+void ConnectUser_set_state(ConnectUser* cu, char state);
+void ConnectUser_set_connFd(ConnectUser* cu, int connFd);
+void ConnectUser_set_whatClient(ConnectUser* cu, int whatClient);
+void ConnectUser_set_userId(ConnectUser* cu, int userId);
+void ConnectUser_set_connectTime(ConnectUser* cu, time_t connectTime);
+void ConnectUser_set_nameBuf(ConnectUser* cu, char* nameBuf);
+void ConnectUser_set_portBuf(ConnectUser* cu, char* portBuf);
+void ConnectUser_set_bufList(ConnectUser* cu, BufList* bufList);
+void ConnectUser_set_stats(ConnectUser* cu, UserStats* stats);
+/* getters */
+char ConnectUser_get_state(ConnectUser* cu);
+int ConnectUser_get_connFd(ConnectUser* cu);
+int ConnectUser_get_whatClient(ConnectUser* cu);
+int ConnectUser_get_userId(ConnectUser* cu);
+time_t ConnectUser_get_connectTime(ConnectUser* cu);
+char* ConnectUser_get_nameBuf(ConnectUser* cu);
+char* ConnectUser_get_portBuf(ConnectUser* cu);
+BufList* ConnectUser_get_bufList(ConnectUser* cu);
+UserStats* ConnectUser_get_stats(ConnectUser* cu);
+
+#endif
diff --git a/src/daemon.c b/src/daemon.c
new file mode 100644
index 0000000..db2195d
--- /dev/null
+++ b/src/daemon.c
@@ -0,0 +1,73 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "daemon.h"
+
+#ifndef HAVE_DAEMON
+
+#ifndef HAVE_THIS_DAEMON
+#define HAVE_THIS_DAEMON
+
+/*
+ * Function name: daemon
+ * Description: Enters into daemon mode. It's the emulation of the daemon
+ * function from the system.
+ * Arguments: nochdir - when 0, the directory will be changed to /, otherwise
+ * the directory will be unchanged
+ * noclose - when 0, the standard streams will be closed, otherwise
+ * the streams will be unchanged
+ * Returns: 0 - success,
+ * -1 - failure.
+ */
+
+int
+daemon(int nochdir, int noclose)
+{
+ int retval;
+ if ((retval = fork()) == 0) {
+ /* child process */
+ setsid();
+ if (nochdir == 0) {
+ chdir("/");
+ }
+ if (noclose == 0) {
+ retval = open("/dev/null", O_RDWR);
+ if (retval == -1) {
+ return retval;
+ }
+ dup2(retval, STDIN_FILENO);
+ dup2(retval, STDOUT_FILENO);
+ dup2(retval, STDERR_FILENO);
+ close(retval);
+ }
+ }
+ else {
+ /* parent process */
+ if (retval == -1) {
+ return retval;
+ }
+ _exit(0);
+ }
+ return 0;
+}
+
+#endif
+
+#endif
diff --git a/src/daemon.h b/src/daemon.h
new file mode 100644
index 0000000..e2de517
--- /dev/null
+++ b/src/daemon.h
@@ -0,0 +1,39 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifndef HAVE_DAEMON
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+# ifndef _JS_DAEMON_H
+# define _JS_DAEMON_H
+
+int daemon(int nochdir, int noclose);
+
+# endif
+
+#endif
diff --git a/src/file.c b/src/file.c
new file mode 100644
index 0000000..70080c8
--- /dev/null
+++ b/src/file.c
@@ -0,0 +1,117 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "file.h"
+#include "activefor.h"
+#include "logging.h"
+#include "network.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <ctype.h>
+
+/*
+ * Function name: parse_line
+ * Description: Splits the buffer into two parts: option and value.
+ * Arguments: buff - the buffer to split
+ * tab1 - the place where option part will be stored
+ * tab2 - the place where value part will be stored
+ * Returns: 0 - the buffer was empty,
+ * 1 - the buffer contains only option name,
+ * 2 - the buffer contains only value of the option.
+ */
+
+int
+parse_line(char* buff, char* tab1, char* tab2)
+{
+ int state, i, j, lastDot;
+ state = i = j = 0;
+ lastDot = -1;
+ while (buff[i] != 0) {
+ if (buff[i] == '#') {
+ if ((i > 0) && (buff[i-1] == '\\')) {
+ --j;
+ }
+ else {
+ break;
+ }
+ }
+ switch (state) {
+ case 0: { /* before option name */
+ if (!isspace(buff[i])) {
+ tab1[j] = buff[i];
+ j = 1;
+ state = 1;
+ }
+ break;
+ }
+ case 1: { /* option */
+ if (isspace(buff[i])) {
+ tab1[j] = 0;
+ state = 2;
+ j = 0;
+ }
+ else {
+ tab1[j] = buff[i];
+ ++j;
+ }
+ break;
+ }
+ case 2: { /* before option value */
+ if (!isspace(buff[i])) {
+ if (buff[i] != '.') {
+ tab2[j] = buff[i];
+ j = 1;
+ }
+ state = 3;
+ }
+ break;
+ }
+ case 3: { /* option value */
+ if (buff[i] == '.') {
+ lastDot = j;
+ }
+ else if (!isspace(buff[i])) {
+ lastDot = -1;
+ }
+ else if (lastDot == -1) {
+ lastDot = j;
+ }
+ tab2[j] = buff[i];
+ ++j;
+ break;
+ }
+ }
+ ++i;
+ }
+ if (lastDot != -1) {
+ tab2[lastDot] = 0;
+ }
+ if (state == 3) {
+ return 2;
+ }
+ if (state == 0) {
+ return 0;
+ }
+ return 1;
+}
diff --git a/src/file.h b/src/file.h
new file mode 100644
index 0000000..8aada50
--- /dev/null
+++ b/src/file.h
@@ -0,0 +1,41 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "activefor.h"
+#include "network.h"
+#include "server_configuration_struct.h"
+#include "client_configuration_struct.h"
+#include <openssl/ssl.h>
+
+#ifndef _JS_FILE_H
+#define _JS_FILE_H
+
+#define F_UNKNOWN 1
+#define F_IGNORE 2
+#define F_ROPTION 3
+#define F_RVALUE 4
+#define F_MIDDLE 5
+
+int parse_line(char* buff, char* tab1, char* tab2); /* parse one line of the file */
+ServerConfiguration* parsefile(char*, int*); /* parse the cfg file */
+ClientConfiguration* cparsefile(char*, int*); /* parse the client's cfg file */
+
+#endif
+
diff --git a/src/file_client.c b/src/file_client.c
new file mode 100644
index 0000000..672eeaf
--- /dev/null
+++ b/src/file_client.c
@@ -0,0 +1,281 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include "file.h"
+#include "activefor.h"
+#include "logging.h"
+#include "network.h"
+
+/*
+ * Function name: cparsefile
+ * Description: Parses the client config file.
+ * Arguments: name - the name of the file with client's config
+ * status - the status returned from this function:
+ * 0 - file was parsed successfully
+ * n>0 - there was an error in the n-th line
+ * Returns: Pointer to ClientConfiguration structure.
+ */
+
+ClientConfiguration*
+cparsefile(char* name, int* status)
+{
+ ClientConfiguration* cfg;
+ FILE* file = NULL;
+ int state, i, n;
+#ifdef AF_INET6
+ int temp;
+#endif
+ char buff[256];
+ char helpbuf1[256];
+ char helpbuf2[256];
+ char* tmpbuf;
+ unsigned char pass[4] = {1, 2, 3, 4};
+
+ assert(name != NULL);
+ assert(status != NULL);
+
+ *status = 1;
+
+ memset(buff, 0, 256);
+
+ cfg = ClientConfiguration_new();
+
+ if (cfg == NULL) {
+ printf("Can't allocate memory for client configuration... exiting\n");
+ exit(1);
+ }
+
+ state = F_UNKNOWN;
+
+ file = fopen(name, "r");
+ if (file == NULL) {
+ return cfg;
+ }
+
+ ClientConfiguration_set_realmsNumber(cfg, 1);
+
+ ClientConfiguration_set_realmsTable(cfg,
+ calloc(ClientConfiguration_get_realmsNumber(cfg), sizeof(ClientRealm*)));
+ if (ClientConfiguration_get_realmsTable(cfg) == NULL) {
+ printf("Can't allocate memory for ClientRealm* table... exiting\n");
+ exit(1);
+ }
+ for (i = 0; i < ClientConfiguration_get_realmsNumber(cfg); ++i) {
+ ClientConfiguration_get_realmsTable(cfg)[i] = ClientRealm_new();
+ if (ClientConfiguration_get_realmsTable(cfg)[i] == NULL) {
+ printf("Problem with allocating memory for ClientRealm structure... exiting");
+ exit(1);
+ }
+ ClientRealm_set_password(ClientConfiguration_get_realmsTable(cfg)[i], pass);
+ ClientRealm_set_destinationPorts(ClientConfiguration_get_realmsTable(cfg)[i], PortList_new());
+ }
+ *status = 0;
+
+ while (fgets(buff, 256, file) != NULL) { /* loop - parsing file */
+ (*status)++;
+ state = parse_line(buff, helpbuf1, helpbuf2);
+ if (helpbuf1[0] == '#') {
+ memset(buff, 0, 256);
+ continue;
+ }
+ if (state == 1) {
+ if (strcmp(helpbuf1, "ignorepkeys") == 0) {
+ ClientConfiguration_set_ignorePublicKeys(cfg, 1);
+ }
+ else if (strcmp(helpbuf1, "ar-start") == 0) {
+ ArOptions_set_arStart(ClientRealm_get_arOptions(ClientConfiguration_get_realmsTable(cfg)[0]),
+ AR_OPTION_ENABLED);
+ }
+ else if (strcmp(helpbuf1, "ar-quit") == 0) {
+ ArOptions_set_arQuit(ClientRealm_get_arOptions(ClientConfiguration_get_realmsTable(cfg)[0]),
+ AR_OPTION_ENABLED);
+ }
+ else if (strcmp(helpbuf1, "noar") == 0) {
+ ArOptions_set_arPremature(ClientRealm_get_arOptions(ClientConfiguration_get_realmsTable(cfg)[0]),
+ AR_OPTION_DISABLED);
+ }
+ else if ((strcmp(helpbuf1, "u") == 0) || (strcmp(helpbuf1, "udpmode") == 0)) {
+ if (ClientRealm_get_clientMode(ClientConfiguration_get_realmsTable(cfg)[0]) == CLIENTREALM_MODE_TCP) {
+ ClientRealm_set_clientMode(ClientConfiguration_get_realmsTable(cfg)[0], CLIENTREALM_MODE_UDP);
+ }
+ else {
+ ClientRealm_set_clientMode(ClientConfiguration_get_realmsTable(cfg)[0], CLIENTREALM_MODE_UNKNOWN);
+ }
+ }
+ else if ((strcmp(helpbuf1, "U") == 0) || (strcmp(helpbuf1, "reverseudp") == 0)) {
+ if (ClientRealm_get_clientMode(ClientConfiguration_get_realmsTable(cfg)[0]) == CLIENTREALM_MODE_TCP) {
+ ClientRealm_set_clientMode(ClientConfiguration_get_realmsTable(cfg)[0], CLIENTREALM_MODE_REVERSE);
+ }
+ else {
+ ClientRealm_set_clientMode(ClientConfiguration_get_realmsTable(cfg)[0], CLIENTREALM_MODE_UNKNOWN);
+ }
+ }
+ else if ((strcmp(helpbuf1, "r") == 0) || (strcmp(helpbuf1, "remoteadmin") == 0)) {
+ if (ClientRealm_get_clientMode(ClientConfiguration_get_realmsTable(cfg)[0]) == CLIENTREALM_MODE_TCP) {
+ ClientRealm_set_clientMode(ClientConfiguration_get_realmsTable(cfg)[0], CLIENTREALM_MODE_REMOTE);
+ }
+ else {
+ ClientRealm_set_clientMode(ClientConfiguration_get_realmsTable(cfg)[0], CLIENTREALM_MODE_UNKNOWN);
+ }
+ }
+ else if ((strcmp(helpbuf1, "S") == 0) || (strcmp(helpbuf1, "use-https") == 0)) {
+ HttpProxyOptions_use_https(ClientRealm_get_httpProxyOptions(
+ ClientConfiguration_get_realmsTable(cfg)[0]));
+ }
+ else if ((strcmp(helpbuf1, "B") == 0) || (strcmp(helpbuf1, "pa-t-basic") == 0)) {
+ HttpProxyOptions_set_proxyauth_type(ClientRealm_get_httpProxyOptions(
+ ClientConfiguration_get_realmsTable(cfg)[0]), PROXYAUTH_TYPE_BASIC);
+ }
+#ifdef HAVE_LIBPTHREAD
+ else if (strcmp(helpbuf1, "enableproxy")==0) {
+ if (ClientRealm_get_tunnelType(
+ ClientConfiguration_get_realmsTable(cfg)[0]) == 0) {
+ ClientRealm_set_tunnelType(
+ ClientConfiguration_get_realmsTable(cfg)[0],
+ 1);
+ }
+ else {
+ return cfg;
+ }
+ }
+#endif
+#ifdef AF_INET6
+ else if (strcmp(helpbuf1, "ipv4")==0) {
+ if (TYPE_IS_UNSPEC(ClientRealm_get_realmType(
+ ClientConfiguration_get_realmsTable(cfg)[0]))) {
+ temp = ClientRealm_get_realmType(ClientConfiguration_get_realmsTable(cfg)[0]);
+ TYPE_SET_IPV4(temp);
+ ClientRealm_set_realmType(ClientConfiguration_get_realmsTable(cfg)[0], temp);
+ }
+ else {
+ return cfg;
+ }
+ }
+ else if (strcmp(helpbuf1, "ipv6")==0) {
+ if (TYPE_IS_UNSPEC(ClientRealm_get_realmType(
+ ClientConfiguration_get_realmsTable(cfg)[0]))) {
+ temp = ClientRealm_get_realmType(ClientConfiguration_get_realmsTable(cfg)[0]);
+ TYPE_SET_IPV6(temp);
+ ClientRealm_set_realmType(ClientConfiguration_get_realmsTable(cfg)[0], temp);
+ }
+ else {
+ return cfg;
+ }
+ }
+#endif
+ else {
+ return cfg;
+ }
+ }
+ else if (state == 2) {
+ if ((strcmp(helpbuf1, "k") == 0) || (strcmp(helpbuf1, "keyfile") == 0)) {
+ ClientConfiguration_set_keysFile(cfg, helpbuf2);
+ }
+ else if ((strcmp(helpbuf1, "c") == 0) || (strcmp(helpbuf1, "certificate") == 0) || (strcmp(helpbuf1, "cerfile") == 0)) {
+ ClientConfiguration_set_certificateFile(cfg, helpbuf2);
+ }
+ else if ((strcmp(helpbuf1, "s") == 0) || (strcmp(helpbuf1, "storefile") == 0)) {
+ ClientConfiguration_set_storeFile(cfg, helpbuf2);
+ }
+ else if ((strcmp(helpbuf1, "o") == 0) || (strcmp(helpbuf1, "log") == 0)) {
+ tmpbuf = calloc(strlen(helpbuf2)+1, sizeof(char));
+ strcpy(tmpbuf, helpbuf2);
+ addlogtarget(tmpbuf);
+ }
+ else if ((strcmp(helpbuf1, "D") == 0) || (strcmp(helpbuf1, "dateformat") == 0)) {
+ ClientConfiguration_set_dateFormat(cfg, helpbuf2);
+ }
+ else if ((strcmp(helpbuf1, "n") == 0) || (strcmp(helpbuf1, "servername") == 0)) {
+ ClientRealm_set_serverName(ClientConfiguration_get_realmsTable(cfg)[0], helpbuf2);
+ }
+ else if ((strcmp(helpbuf1, "m") == 0) || (strcmp(helpbuf1, "manageport") == 0)) {
+ ClientRealm_set_managePort(ClientConfiguration_get_realmsTable(cfg)[0], helpbuf2);
+ }
+ else if ((strcmp(helpbuf1, "d") == 0) || (strcmp(helpbuf1, "hostname") == 0)) {
+ ClientRealm_set_hostName(ClientConfiguration_get_realmsTable(cfg)[0], helpbuf2);
+ }
+ else if ((strcmp(helpbuf1, "p") == 0) || (strcmp(helpbuf1, "portnum") == 0)) {
+ PortList_insert_back(ClientRealm_get_destinationPorts(ClientConfiguration_get_realmsTable(cfg)[0]),
+ PortListNode_new(helpbuf2));
+ }
+ else if (strcmp(helpbuf1, "localname") == 0) {
+ ClientRealm_set_localName(ClientConfiguration_get_realmsTable(cfg)[0], helpbuf2);
+ }
+ else if (strcmp(helpbuf1, "localport") == 0) {
+ ClientRealm_set_localPort(ClientConfiguration_get_realmsTable(cfg)[0], helpbuf2);
+ }
+ else if (strcmp(helpbuf1, "localdesname") == 0) {
+ ClientRealm_set_localDestinationName(ClientConfiguration_get_realmsTable(cfg)[0], helpbuf2);
+ }
+ else if ((strcmp(helpbuf1, "i") == 0) || (strcmp(helpbuf1, "id") == 0)) {
+ ClientRealm_set_realmId(ClientConfiguration_get_realmsTable(cfg)[0], helpbuf2);
+ }
+ else if (strcmp(helpbuf1, "pass") == 0) {
+ n = strlen(helpbuf2);
+ memset(pass, 0, 4);
+ for (i = 0; i < n; ++i) {
+ pass[i%4] += helpbuf2[i];
+ }
+ ClientRealm_set_password(ClientConfiguration_get_realmsTable(cfg)[0], pass);
+ }
+ else if ((strcmp(helpbuf1, "K") == 0) || (strcmp(helpbuf1, "keep-alive") == 0)) {
+ ClientRealm_set_sKeepAliveTimeout(ClientConfiguration_get_realmsTable(cfg)[0], helpbuf2);
+ }
+ else if ((strcmp(helpbuf1, "A") == 0) || (strcmp(helpbuf1, "ar-tries") == 0)) {
+ ArOptions_set_s_arTries(ClientRealm_get_arOptions(ClientConfiguration_get_realmsTable(cfg)[0]),
+ helpbuf2);
+ }
+ else if ((strcmp(helpbuf1, "T") == 0) || (strcmp(helpbuf1, "ar-delay") == 0)) {
+ ArOptions_set_s_arDelay(ClientRealm_get_arOptions(ClientConfiguration_get_realmsTable(cfg)[0]),
+ helpbuf2);
+ }
+ else if ((strcmp(helpbuf1, "P") == 0) || (strcmp(helpbuf1, "proxyname") == 0)) {
+ HttpProxyOptions_set_proxyname(ClientRealm_get_httpProxyOptions(
+ ClientConfiguration_get_realmsTable(cfg)[0]), helpbuf2);
+ }
+ else if ((strcmp(helpbuf1, "X") == 0) || (strcmp(helpbuf1, "proxyport") == 0)) {
+ HttpProxyOptions_set_proxyport(ClientRealm_get_httpProxyOptions(
+ ClientConfiguration_get_realmsTable(cfg)[0]), helpbuf2);
+ }
+ else if ((strcmp(helpbuf1, "C") == 0) || (strcmp(helpbuf1, "pa-cred") == 0)) {
+ HttpProxyOptions_set_proxyauth_cred(ClientRealm_get_httpProxyOptions(
+ ClientConfiguration_get_realmsTable(cfg)[0]), helpbuf2);
+ }
+ else {
+ return cfg;
+ }
+ }
+ memset(buff, 0, 256);
+ }
+
+ fclose(file);
+
+ *status = 0;
+ return cfg;
+}
diff --git a/src/file_server.c b/src/file_server.c
new file mode 100644
index 0000000..3abfc57
--- /dev/null
+++ b/src/file_server.c
@@ -0,0 +1,390 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "file.h"
+#include "activefor.h"
+#include "logging.h"
+#include "network.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <ctype.h>
+
+/*
+ * Function name: parsefile
+ * Description: Parses the server config file.
+ * Arguments: name - the name of the file with client's config
+ * status - the status returned from this function:
+ * 0 - file was parsed successfully
+ * n>0 - there was an error in the n-th line
+ * Returns: Pointer to ServerConfiguration structure.
+ */
+
+ServerConfiguration*
+parsefile(char* name, int* status)
+{
+ ServerConfiguration* cfg;
+ FILE* file = NULL;
+ int state, i, j, n, listencount, managecount, temp;
+ char buff[256];
+ char helpbuf1[256];
+ char helpbuf2[256];
+ char* tmpbuf;
+ unsigned char pass[4] = {1, 2, 3, 4};
+
+ *status = 1;
+
+ memset(buff, 0, 256);
+
+ cfg = ServerConfiguration_new();
+
+ if (cfg == NULL) {
+ printf("Can't allocate memory for server configuration... exiting\n");
+ exit(1);
+ }
+
+ state = F_UNKNOWN;
+
+ file = fopen(name, "r");
+ if (file == NULL) {
+ return cfg;
+ }
+
+ while (fgets(buff, 256, file) != NULL) { /* first loop - counting realm */
+ helpbuf1[0] = 0;
+ parse_line(buff, helpbuf1, helpbuf2);
+ if (strcmp(helpbuf1, "realm")==0) {
+ ServerConfiguration_set_realmsNumber(cfg, ServerConfiguration_get_realmsNumber(cfg) + 1);
+ }
+ }
+ rewind(file);
+
+ ServerConfiguration_set_realmsTable(cfg,
+ calloc(ServerConfiguration_get_realmsNumber(cfg), sizeof(ServerRealm*)));
+ if (ServerConfiguration_get_realmsTable(cfg) == NULL) {
+ printf("Can't allocate memory for ServerRealm* table... exiting\n");
+ exit(1);
+ }
+ for (i = 0; i < ServerConfiguration_get_realmsNumber(cfg); ++i) {
+ ServerConfiguration_get_realmsTable(cfg)[i] = ServerRealm_new();
+ if (ServerConfiguration_get_realmsTable(cfg)[i] == NULL) {
+ printf("Problem with allocating memory for ServerRealm structure... exiting");
+ exit(1);
+ }
+ ServerRealm_set_password(ServerConfiguration_get_realmsTable(cfg)[i], pass);
+ }
+ ServerConfiguration_set_realmsNumber(cfg, 0);
+ *status = 0;
+
+ listencount = managecount = 0;
+
+
+ while (fgets(buff, 256, file) != NULL) { /* second loop - counting listen */
+ (*status)++;
+ state = parse_line(buff, helpbuf1, helpbuf2);
+ if (state) {
+ if (strcmp(helpbuf1, "realm") == 0) {
+ ServerConfiguration_set_realmsNumber(cfg, ServerConfiguration_get_realmsNumber(cfg) + 1);
+ if (listencount != managecount) {
+ return cfg;
+ }
+ listencount = managecount = 0;
+ }
+ else if ((strcmp(helpbuf1, "listen") == 0) || (strcmp(helpbuf1, "listenport") == 0)) {
+ if (ServerConfiguration_get_realmsNumber(cfg) == 0) {
+ return cfg;
+ }
+ ServerRealm_set_userClientPairs(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1],
+ ServerRealm_get_userClientPairs(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1]) +
+ 1);
+ ++listencount;
+ }
+ else if ((strcmp(helpbuf1, "manage") == 0) || (strcmp(helpbuf1, "manageport") == 0)) {
+ if (ServerConfiguration_get_realmsNumber(cfg) == 0) {
+ return cfg;
+ }
+ ++managecount;
+ }
+ }
+ }
+ rewind(file);
+
+ if (listencount != managecount) {
+ return cfg;
+ }
+
+ for (i = 0; i < ServerConfiguration_get_realmsNumber(cfg); ++i) {
+ ServerRealm_set_usersClientsTable(ServerConfiguration_get_realmsTable(cfg)[i],
+ calloc(ServerRealm_get_userClientPairs(ServerConfiguration_get_realmsTable(cfg)[i]), sizeof(UsrCli*)));
+ if (ServerRealm_get_usersClientsTable(ServerConfiguration_get_realmsTable(cfg)[i]) == NULL) {
+ printf("Problem with allocating memory for UsrCli* table... exiting");
+ return cfg;
+ }
+ for (j = 0; j < ServerRealm_get_userClientPairs(ServerConfiguration_get_realmsTable(cfg)[i]); ++j) {
+ ServerRealm_get_usersClientsTable(ServerConfiguration_get_realmsTable(cfg)[i])[j] = UsrCli_new();
+ if (ServerRealm_get_usersClientsTable(ServerConfiguration_get_realmsTable(cfg)[i])[j] == NULL) {
+ printf("Problem with allocating memory for UsrCli structure... exiting");
+ return cfg;
+ }
+ }
+ }
+
+ ServerConfiguration_set_realmsNumber(cfg, 0);
+ *status = 0;
+
+
+ while (fgets(buff, 256, file) != NULL) { /* third loop - parsing file */
+ (*status)++;
+ state = parse_line(buff, helpbuf1, helpbuf2);
+ if (helpbuf1[0] == '#') {
+ memset(buff, 0, 256);
+ continue;
+ }
+ if (state == 1) {
+ if (strcmp(helpbuf1, "realm")==0) {
+ ServerConfiguration_set_realmsNumber(cfg, ServerConfiguration_get_realmsNumber(cfg) + 1);
+ temp = ServerRealm_get_realmType(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1]);
+ TYPE_SET_SSL(temp);
+ TYPE_SET_ZLIB(temp);
+ TYPE_SET_SUPPORTED_MULTI(temp);
+ ServerRealm_set_realmType(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1], temp);
+ listencount = managecount = 0;
+ }
+ else if (ServerConfiguration_get_realmsNumber(cfg) == 0) {
+ return cfg;
+ }
+ else if (strcmp(helpbuf1, "nossl")==0) {
+ temp = ServerRealm_get_realmType(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1]);
+ TYPE_UNSET_SSL(temp);
+ ServerRealm_set_realmType(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1], temp);
+ }
+ else if (strcmp(helpbuf1, "nozlib")==0) {
+ temp = ServerRealm_get_realmType(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1]);
+ TYPE_UNSET_ZLIB(temp);
+ ServerRealm_set_realmType(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1], temp);
+ }
+ else if (strcmp(helpbuf1, "baseport")==0) {
+ ServerRealm_set_basePortOn(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1],
+ 1);
+ }
+ else if (strcmp(helpbuf1, "audit")==0) {
+ ServerRealm_set_auditOn(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1],
+ 1);
+ }
+ else if (strcmp(helpbuf1, "dnslookups")==0) {
+ ServerRealm_set_dnsLookupsOn(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1],
+ 1);
+ }
+#ifdef HAVE_LIBPTHREAD
+ else if (strcmp(helpbuf1, "enableproxy")==0) {
+ if (ServerRealm_get_tunnelType(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1]) == 0) {
+ ServerRealm_set_tunnelType(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1],
+ 1);
+ }
+ else {
+ return cfg;
+ }
+ }
+#endif
+#ifdef AF_INET6
+ else if (strcmp(helpbuf1, "ipv4")==0) {
+ if (TYPE_IS_UNSPEC(ServerRealm_get_realmType(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1]))) {
+ temp = ServerRealm_get_realmType(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1]);
+ TYPE_SET_IPV4(temp);
+ ServerRealm_set_realmType(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1], temp);
+ }
+ else {
+ return cfg;
+ }
+ }
+ else if (strcmp(helpbuf1, "ipv6")==0) {
+ if (TYPE_IS_UNSPEC(ServerRealm_get_realmType(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1]))) {
+ temp = ServerRealm_get_realmType(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1]);
+ TYPE_SET_IPV6(temp);
+ ServerRealm_set_realmType(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1], temp);
+ }
+ else {
+ return cfg;
+ }
+ }
+#endif
+ else {
+ return cfg;
+ }
+ }
+ else if (state == 2) {
+ if (strcmp(helpbuf1, "realm")==0) {
+ ServerConfiguration_set_realmsNumber(cfg, ServerConfiguration_get_realmsNumber(cfg) + 1);
+ temp = ServerRealm_get_realmType(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1]);
+ TYPE_SET_SSL(temp);
+ TYPE_SET_ZLIB(temp);
+ TYPE_SET_SUPPORTED_MULTI(temp);
+ ServerRealm_set_realmType(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1], temp);
+ listencount = managecount = 0;
+ ServerRealm_set_realmName(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1],
+ helpbuf2);
+ }
+ else if ((strcmp(helpbuf1, "certificate") == 0) || (strcmp(helpbuf1, "cerfile") == 0)) {
+ ServerConfiguration_set_certificateFile(cfg, helpbuf2);
+ }
+ else if (strcmp(helpbuf1, "cacerfile") == 0) {
+ ServerConfiguration_set_cacertificateFile(cfg, helpbuf2);
+ }
+ else if (strcmp(helpbuf1, "cerdepth") == 0) {
+ ServerConfiguration_set_sCertificateDepth(cfg, helpbuf2);
+ }
+ else if ((strcmp(helpbuf1, "key") == 0) || (strcmp(helpbuf1, "keyfile") == 0)) {
+ ServerConfiguration_set_keysFile(cfg, 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) {
+ ServerConfiguration_set_dateFormat(cfg, helpbuf2);
+ }
+ else if (ServerConfiguration_get_realmsNumber(cfg) == 0) {
+ return cfg;
+ }
+ else if (strcmp(helpbuf1, "hostname")==0) {
+ ServerRealm_set_hostName(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1],
+ helpbuf2);
+ }
+ else if ((strcmp(helpbuf1, "listen") == 0) || (strcmp(helpbuf1, "listenport") == 0)) {
+ UsrCli_set_listenPortName(
+ ServerRealm_get_usersClientsTable(
+ ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1])[listencount], helpbuf2);
+ ++listencount;
+ }
+ else if (strcmp(helpbuf1, "pass")==0) {
+ n = strlen(helpbuf2);
+ memset(pass, 0, 4);
+ for (i = 0; i < n; ++i) {
+ pass[i%4] += helpbuf2[i];
+ }
+ ServerRealm_set_password(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1],
+ pass);
+ }
+ else if ((strcmp(helpbuf1, "manage") == 0) || (strcmp(helpbuf1, "manageport") == 0)) {
+ UsrCli_set_managePortName(
+ ServerRealm_get_usersClientsTable(
+ ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1])[managecount], helpbuf2);
+ ++managecount;
+ }
+ else if (strcmp(helpbuf1, "users")==0) {
+ ServerRealm_set_sUsersLimit(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1],
+ helpbuf2);
+ }
+ else if (strcmp(helpbuf1, "timeout")==0) {
+ ServerRealm_set_sTimeout(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1],
+ helpbuf2);
+ }
+ else if (strcmp(helpbuf1, "maxidle")==0) {
+ ServerRealm_set_sMaxIdle(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1],
+ helpbuf2);
+ }
+ else if (strcmp(helpbuf1, "clients")==0) {
+ ServerRealm_set_sClientsLimit(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1],
+ helpbuf2);
+ }
+ else if (strcmp(helpbuf1, "raclients")==0) {
+ ServerRealm_set_sRaClientsLimit(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1],
+ helpbuf2);
+ }
+ else if (strcmp(helpbuf1, "usrpcli")==0) {
+ ServerRealm_set_sUsersPerClient(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1],
+ helpbuf2);
+ }
+ else if (strcmp(helpbuf1, "climode")==0) {
+ ServerRealm_set_sClientMode(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1],
+ helpbuf2);
+ }
+ else if (strcmp(helpbuf1, "proto")==0) {
+ if (TYPE_IS_SET(ServerRealm_get_realmType(
+ ServerConfiguration_get_realmsTable(cfg)[ServerConfiguration_get_realmsNumber(cfg) - 1]))) {
+ return cfg;
+ }
+ if (strcmp(helpbuf2, "tcp")==0) {
+ temp = ServerRealm_get_realmType(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1]);
+ TYPE_SET_TCP(temp);
+ ServerRealm_set_realmType(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1], temp);
+ }
+ else if (strcmp(helpbuf2, "udp")==0) {
+ temp = ServerRealm_get_realmType(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1]);
+ TYPE_SET_UDP(temp);
+ ServerRealm_set_realmType(ServerConfiguration_get_realmsTable(cfg)[
+ ServerConfiguration_get_realmsNumber(cfg) - 1], temp);
+ }
+ else {
+ return cfg;
+ }
+ }
+ else {
+ return cfg;
+ }
+ }
+ memset(buff, 0, 256);
+ }
+
+ fclose(file);
+
+ *status = 0;
+ return cfg;
+}
diff --git a/src/first_run.c b/src/first_run.c
new file mode 100644
index 0000000..a023306
--- /dev/null
+++ b/src/first_run.c
@@ -0,0 +1,403 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <pwd.h>
+#include <openssl/rsa.h>
+#include <openssl/pem.h>
+#include <assert.h>
+
+static char* home_dir = NULL;
+static char* home_dir_store = NULL;
+static char* home_dir_key = NULL;
+static char* home_dir_cer = NULL;
+
+typedef struct entry
+{
+ char *key;
+ unsigned char *value;
+} entryT;
+
+static
+entryT entries[6] = {
+ {"countryName", (unsigned char*) "PL"},
+ {"stateOrProvinceName", (unsigned char*) "War-Maz"},
+ {"localityName", (unsigned char*) "Olsztyn"},
+ {"organizationName", (unsigned char*) "gray-world.net"},
+ {"organizationalUnitName", (unsigned char*) "APF team"},
+ {"commonName", (unsigned char*) "Jeremian <jeremian [at] poczta [dot] fm>"},
+};
+
+/*
+ * Function name: callback
+ * Description: Prints the info about rsa key generation events.
+ * Arguments: i, j, k - described in the manual page about RSA_generate_key
+ */
+
+static void
+callback(int i, int j, void* k)
+{
+ if (k == NULL) {
+ printf("%d", i);
+ fflush(stdout);
+ }
+}
+
+/*
+ * Function name: create_apf_dir
+ * Description: Creates .apf directory in ~/ or apf directory locally.
+ * Arguments: type - type of the directory to create:
+ * 0 - .apf in ~/
+ * 1 - apf in current dir
+ * Returns: 0 - success,
+ * 1 - problems with fetching user info,
+ * 2 - home directory is not set,
+ * 3 - calloc failure,
+ * 4 - directory creation failure.
+ */
+
+int
+create_apf_dir(char type)
+{
+ int length;
+ struct stat buf;
+ struct passwd *user = getpwuid(getuid());
+ if (type == 0) {
+ if (user == NULL) {
+ return 1; /* some problems with fetching user info*/
+ }
+ if (user->pw_dir == NULL) {
+ return 2; /* home directory is not set? */
+ }
+ if (home_dir) {
+ free(home_dir);
+ home_dir = NULL;
+ }
+ length = strlen(user->pw_dir);
+ home_dir = calloc(1, length + 6);
+ if (home_dir == NULL) {
+ return 3; /* calloc failed */
+ }
+ strcpy(home_dir, user->pw_dir);
+ if (home_dir[length] == '/') {
+ strcpy(&home_dir[length], ".apf");
+ }
+ else {
+ strcpy(&home_dir[length], "/.apf");
+ }
+ if (stat(home_dir, &buf)) {
+ if (mkdir(home_dir, 0700)) {
+ return 4; /* creating directory failed */
+ }
+ }
+ }
+ else {
+ if (home_dir) {
+ free(home_dir);
+ home_dir = NULL;
+ }
+ home_dir = calloc(1, 4);
+ if (home_dir == NULL) {
+ return 3; /* calloc failed */
+ }
+ strcpy(home_dir, "apf");
+ if (stat(home_dir, &buf)) {
+ if (mkdir(home_dir, 0700)) {
+ return 4; /* creating directory failed */
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ * Function name: create_publickey_store
+ * Description: Creates the file to store information about public keys.
+ * Arguments: storefile - the pointer to filename
+ * Returns: 0 - success,
+ * >0 - failure.
+ */
+
+int
+create_publickey_store(char** storefile)
+{
+ int store_length, home_length;
+ struct stat buf;
+ FILE* store_file;
+ assert(storefile != NULL);
+ assert((*storefile) != NULL);
+ /* check in local directory first */
+ if (stat(*storefile, &buf) == 0) {
+ return 0;
+ }
+ /* check in home_dir */
+ store_length = strlen(*storefile);
+ home_length = strlen(home_dir);
+ if (home_dir_store) {
+ free(home_dir_store);
+ home_dir_store = NULL;
+ }
+ home_dir_store = calloc(1, home_length + store_length + 2);
+ if (home_dir_store == NULL) {
+ return 1; /* calloc failed */
+ }
+ strcpy(home_dir_store, home_dir);
+ home_dir_store[home_length] = '/';
+ strcpy(&home_dir_store[home_length+1], *storefile);
+ *storefile = home_dir_store;
+ store_file = fopen(home_dir_store, "a");
+ if (store_file == NULL) {
+ return 1;
+ }
+ fclose(store_file);
+ if (stat(home_dir_store, &buf) == 0) {
+ return 0;
+ }
+ return 2;
+}
+
+/*
+ * Function name: generate_rsa_key
+ * Description: Generates the RSA key.
+ * Arguments: keyfile - the pointer to filename
+ * Returns: 0 - success,
+ * >0 - failure.
+ */
+
+int
+generate_rsa_key(char** keyfile)
+{
+ int key_length, home_length;
+ RSA* rsa_key;
+ FILE* rsa_file;
+ struct stat buf;
+ assert(keyfile != NULL);
+ assert((*keyfile) != NULL);
+ /* check in local directory first */
+ if (stat(*keyfile, &buf) == 0) {
+ return 0;
+ }
+ /* check in home_dir */
+ key_length = strlen(*keyfile);
+ home_length = strlen(home_dir);
+ if (home_dir_key) {
+ free(home_dir_key);
+ home_dir_key = NULL;
+ }
+ home_dir_key = calloc(1, home_length + key_length + 2);
+ if (home_dir_key == NULL) {
+ return 1; /* calloc failed */
+ }
+ strcpy(home_dir_key, home_dir);
+ home_dir_key[home_length] = '/';
+ strcpy(&home_dir_key[home_length+1], *keyfile);
+ *keyfile = home_dir_key;
+ if (stat(home_dir_key, &buf) == 0) {
+ return 0;
+ }
+ /* have to generate the key */
+ printf("generating rsa key: 2048 bits\n");
+ rsa_key = RSA_generate_key(2048, 65537, callback, NULL);
+ if (RSA_check_key(rsa_key)==1) {
+ printf(" OK!\n");
+ }
+ else {
+ printf(" FAILED!\n");
+ return 1;
+ }
+
+ rsa_file = fopen(home_dir_key, "a");
+ PEM_write_RSAPrivateKey(rsa_file, rsa_key, NULL, NULL, 0, NULL, NULL);
+ fclose(rsa_file);
+ return 0;
+}
+
+/*
+ * Function name: generate_certificate
+ * Description: Generates X509 certificate.
+ * Arguments: cerfile - the pointer to filename
+ * keyfile - the name of the file with key
+ * Returns: 0 - success,
+ * >0 - failure.
+ */
+
+int
+generate_certificate(char** cerfile, char* keyfile)
+{
+ int cer_length, home_length, i;
+ struct stat buf;
+ X509* cert;
+ X509_REQ* req;
+ X509_NAME* subj;
+ RSA* rsa_key;
+ EVP_PKEY* pkey;
+ const EVP_MD *digest;
+ FILE* fp;
+ assert(cerfile != NULL);
+ assert((*cerfile) != NULL);
+ assert(keyfile != NULL);
+ /* check in local directory first */
+ if (stat(*cerfile, &buf) == 0) {
+ return 0;
+ }
+ /* check in home_dir */
+ cer_length = strlen(*cerfile);
+ home_length = strlen(home_dir);
+ if (home_dir_cer) {
+ free(home_dir_cer);
+ home_dir_cer = NULL;
+ }
+ home_dir_cer = calloc(1, home_length + cer_length + 2);
+ if (home_dir_cer == NULL) {
+ return 1; /* calloc failed */
+ }
+ strcpy(home_dir_cer, home_dir);
+ home_dir_cer[home_length] = '/';
+ strcpy(&home_dir_cer[home_length+1], *cerfile);
+ *cerfile = home_dir_cer;
+ if (stat(home_dir_cer, &buf) == 0) {
+ return 0;
+ }
+ /* have to generate the certificate */
+ printf("generating self signed certificate\n");
+ fp = fopen(keyfile, "r");
+ if (fp == NULL) {
+ return 2; /* can't open keyfile */
+ }
+ rsa_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
+ fclose(fp);
+ if (rsa_key == NULL) {
+ return 3; /* can't read RSAPrivateKey */
+ }
+ pkey = EVP_PKEY_new();
+ if (pkey == NULL) {
+ return 4; /* creating new pkey failed */
+ }
+ if (EVP_PKEY_set1_RSA(pkey, rsa_key) == 0) {
+ return 5; /* setting rsa key failed */
+ }
+ req = X509_REQ_new();
+ if (req == NULL) {
+ return 6; /* creating new request failed */
+ }
+ X509_REQ_set_pubkey(req, pkey);
+ subj = X509_NAME_new();
+ if (subj == NULL) {
+ return 7; /* creating new subject name failed */
+ }
+
+ for (i = 0; i < 6; i++)
+ {
+ int nid;
+ X509_NAME_ENTRY *ent;
+
+ if ((nid = OBJ_txt2nid(entries[i].key)) == NID_undef)
+ {
+ return 8; /* finding NID for a key failed */
+ }
+ ent = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_ASC,entries[i].value, -1);
+ if (ent == NULL) {
+ return 9; /* creating name entry from NID failed */
+ }
+ if (X509_NAME_add_entry(subj, ent, -1, 0) == 0) {
+ return 10; /* adding entry to name failed */
+ }
+ }
+ if (X509_REQ_set_subject_name(req, subj) == 0) {
+ return 11; /* adding subject to request failed */
+ }
+
+ digest = EVP_sha1();
+
+ if (X509_REQ_sign(req, pkey, digest) == 0) {
+ return 12; /* signing request failed */
+ }
+
+ cert = X509_REQ_to_X509(req, 1000, pkey);
+
+ if (X509_set_version(cert, 2L) == 0) {
+ return 13; /* setting certificate version failed */
+ }
+ ASN1_INTEGER_set(X509_get_serialNumber(cert), 1);
+
+ if (cert == NULL) {
+ return 14; /* creating certificate failed */
+ }
+
+ if (X509_sign(cert, pkey, digest) == 0) {
+ return 15; /* signing failed */
+ }
+
+ fp = fopen(home_dir_cer, "w");
+ if (fp == NULL) {
+ return 16; /* writing certificate failed */
+ }
+ PEM_write_X509(fp, cert);
+ fclose(fp);
+
+ EVP_PKEY_free(pkey);
+ X509_REQ_free(req);
+ X509_free(cert);
+ return 0;
+}
+
+/*
+ * Function name: get_store_filename
+ * Description: Returns the name of the file for storing information about public keys.
+ * Returns: The name of the file for storing information about public keys.
+ */
+
+char*
+get_store_filename()
+{
+ return home_dir_store;
+}
+
+/*
+ * Function name: get_key_filename
+ * Description: Returns the name of the file with key.
+ * Returns: The name of the file with key.
+ */
+
+char*
+get_key_filename()
+{
+ return home_dir_key;
+}
+
+/*
+ * Function name: get_cer_filename
+ * Description: Returns the name of the file with certificate.
+ * Returns: The name of the file with certificate.
+ */
+
+char*
+get_cer_filename()
+{
+ return home_dir_cer;
+}
diff --git a/src/first_run.h b/src/first_run.h
new file mode 100644
index 0000000..4fcb5d8
--- /dev/null
+++ b/src/first_run.h
@@ -0,0 +1,33 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_FIRST_RUN_H
+#define _JS_FIRST_RUN_H
+
+int create_apf_dir(char type);
+int create_publickey_store(char**);
+int generate_rsa_key(char**);
+int generate_certificate(char**, char*);
+char* get_store_filename();
+char* get_key_filename();
+char* get_cer_filename();
+
+#endif
+
diff --git a/src/header_buffer_struct.c b/src/header_buffer_struct.c
new file mode 100644
index 0000000..94f852b
--- /dev/null
+++ b/src/header_buffer_struct.c
@@ -0,0 +1,127 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "header_buffer_struct.h"
+
+/*
+ * Function name: HeaderBuffer_new
+ * Description: Create and initialize new HeaderBuffer structure.
+ * Returns: Pointer to newly created HeaderBuffer structure.
+ */
+
+HeaderBuffer*
+HeaderBuffer_new()
+{
+ HeaderBuffer* tmp = calloc(1, sizeof(HeaderBuffer));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ return tmp;
+}
+
+/*
+ * Function name: HeaderBuffer_free
+ * Description: Free the memory allocated for HeaderBuffer structure.
+ * Arguments: hb - pointer to pointer to HeaderBuffer structure
+ */
+
+void
+HeaderBuffer_free(HeaderBuffer** hb)
+{
+ assert(hb != NULL);
+ if (hb == NULL) {
+ return;
+ }
+ assert((*hb) != NULL);
+ if ((*hb) == NULL) {
+ return;
+ }
+ free((*hb));
+ (*hb) = NULL;
+}
+
+/*
+ * Function name: HeaderBuffer_to_read
+ * Description: Evaluate how much bytes are needed to fill the header buffer.
+ * Arguments: hb - pointer to HeaderBuffer structure
+ * Returns: How much bytes are needed to fill the header buffer.
+ */
+
+int
+HeaderBuffer_to_read(HeaderBuffer* hb)
+{
+ assert(hb != NULL);
+ if (hb == NULL) {
+ return -1;
+ }
+ return (5 - hb->readed);
+}
+
+/*
+ * Function name: HeaderBuffer_store
+ * Description: Store readed part of the header in the buffer.
+ * Arguments: hb - pointer to HeaderBuffer structure
+ * buff - reader bytes
+ * n - how much bytes were readed
+ */
+
+void
+HeaderBuffer_store(HeaderBuffer* hb, unsigned char* buff, int n)
+{
+ assert(hb != NULL);
+ if (hb == NULL) {
+ return;
+ }
+ assert((hb->readed + n) <= 5);
+ if ((hb->readed + n) > 5) {
+ return;
+ }
+ assert(n > 0);
+ if (n <= 0) {
+ return;
+ }
+ memcpy(&hb->tab[hb->readed], buff, n);
+ hb->readed += n;
+}
+
+/*
+ * Function name: HeaderBuffer_restore
+ * Description: Restore the full header from the buffer. It's not checked, if the full header is in the buffer.
+ * Arguments: hb - pointer to HeaderBuffer structure
+ * buff - place to restore the full header to
+ */
+
+void
+HeaderBuffer_restore(HeaderBuffer* hb, unsigned char* buff)
+{
+ assert(hb != NULL);
+ if (hb == NULL) {
+ return;
+ }
+ memcpy(buff, hb->tab, 5);
+ hb->readed = 0;
+}
diff --git a/src/header_buffer_struct.h b/src/header_buffer_struct.h
new file mode 100644
index 0000000..f186dfd
--- /dev/null
+++ b/src/header_buffer_struct.h
@@ -0,0 +1,39 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_HEADER_BUFFER_STRUCT_H
+#define _JS_HEADER_BUFFER_STRUCT_H
+
+typedef struct {
+ unsigned char tab[5];
+ int readed;
+} HeaderBuffer;
+
+/* 'constructor' */
+HeaderBuffer* HeaderBuffer_new();
+/* 'destructor' */
+void HeaderBuffer_free(HeaderBuffer** hb);
+/* other */
+int HeaderBuffer_to_read(HeaderBuffer* hb);
+void HeaderBuffer_store(HeaderBuffer* hb, unsigned char* buff, int n);
+void HeaderBuffer_restore(HeaderBuffer* hb, unsigned char* buff);
+
+#endif
+
diff --git a/src/http_proxy_client.c b/src/http_proxy_client.c
new file mode 100644
index 0000000..157d009
--- /dev/null
+++ b/src/http_proxy_client.c
@@ -0,0 +1,565 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "http_proxy_functions.h"
+#include "http_proxy_client.h"
+#include "thread_management.h"
+#include "network.h"
+#include "stats.h"
+#include "logging.h"
+#include "base64.h"
+
+#ifdef HAVE_LIBPTHREAD
+typedef struct {
+ int sockfd;
+ char *host;
+ char *serv;
+ HttpProxyOptions* hpo;
+ char type;
+ SSL_CTX* ctx;
+} proxy_argT;
+
+/*
+ * Function name: clean_return
+ * Description: Closes the connection and exits the thread.
+ * Arguments: sockfd - the descriptor of the connection
+ */
+
+static void
+clean_return(int sockfd)
+{
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http proxy: clean_return");
+ close(sockfd);
+ pthread_exit(NULL);
+}
+
+/*
+ * Function name: http_proxy_client
+ * Description: Function responsible for the client part of the http proxy connection.
+ * Arguments: vptr - the structure with all the information needed for http proxy tunnel
+ */
+
+void*
+http_proxy_client(void *vptr)
+{
+ char tab[9000];
+ connection conn;
+ header hdr;
+ int j, n, maxfdp1;
+ fd_set rset, allset;
+ struct timeval tv;
+ int timeout = 5;
+ int tmp;
+ char *host, *serv, *proxyname, *proxyport, *credentials, *name = "";
+ char b64cred[100];
+ char type, authtype, https;
+ SSL_CTX* ctx;
+ proxy_argT *proxy_argptr;
+
+ start_critical_section();
+ proxy_argptr = (proxy_argT *) vptr;
+
+ host = proxy_argptr->host;
+ serv = proxy_argptr->serv;
+ proxyname = HttpProxyOptions_get_proxyname(proxy_argptr->hpo);
+ proxyport = HttpProxyOptions_get_proxyport(proxy_argptr->hpo);
+ credentials = HttpProxyOptions_get_proxyauth_cred(proxy_argptr->hpo);
+ type = proxy_argptr->type;
+ authtype = HttpProxyOptions_get_proxyauth_type(proxy_argptr->hpo);
+ conn.sockfd = proxy_argptr->sockfd;
+ https = HttpProxyOptions_is_https(proxy_argptr->hpo);
+ ctx = proxy_argptr->ctx;
+
+ broadcast_condition();
+ end_critical_section();
+
+ conn.postFd = SslFd_new();
+ conn.getFd = SslFd_new();
+ conn.tmpFd = SslFd_new();
+ if ((conn.postFd == NULL) || (conn.getFd == NULL) || (conn.tmpFd == NULL)) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http%s proxy: Can't allocate memory... exiting.", name);
+ exit(1);
+ }
+
+ if (https) {
+ name = "s";
+ SslFd_set_ssl(conn.postFd, SSL_new(ctx));
+ SslFd_set_ssl(conn.getFd, SSL_new(ctx));
+ SslFd_set_ssl(conn.tmpFd, SSL_new(ctx));
+ if ((SslFd_get_ssl(conn.postFd) == NULL) ||
+ (SslFd_get_ssl(conn.getFd) == NULL) ||
+ (SslFd_get_ssl(conn.tmpFd) == NULL)) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http%s proxy: Can't allocate memory... exiting.", name);
+ exit(1);
+ }
+ }
+
+ if (authtype == PROXYAUTH_TYPE_WRONG) {
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "Wrong type of proxy authorizaton --> switching to no authorization");
+ credentials = NULL;
+ }
+
+ if (credentials) {
+ if (b64_ntop((unsigned char*)credentials, strlen(credentials), b64cred, 100) == -1) {
+ aflog(LOG_T_MAIN, LOG_I_ERR,
+ "Cannot encode credentials for proxy authorization");
+ b64cred[0] = 0;
+ }
+ else {
+ if (authtype == PROXYAUTH_TYPE_NOTSET) {
+ authtype = PROXYAUTH_TYPE_BASIC;
+ }
+ }
+ }
+
+ FD_ZERO(&allset);
+ tv.tv_usec = 0;
+ tv.tv_sec = timeout;
+
+ memset(conn.id, 0, 10);
+ for (j = 0; j < 9; ++j) {
+ conn.id[j] = myrand(65, 90);
+ }
+ conn.id[9] = 0;
+
+ /* postfd */
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: connecting (postfd)...", name);
+ if (ip_connect(&tmp, proxyname, proxyport, type, NULL, NULL)) {
+ clean_return(conn.sockfd);
+ }
+ SslFd_set_fd(conn.postFd, tmp);
+ if (https) {
+ if (SSL_set_fd(SslFd_get_ssl(conn.postFd), SslFd_get_fd(conn.postFd)) != 1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "https proxy: Problem with initializing ssl");
+ clean_return(conn.sockfd);
+ }
+ if (SSL_connect(SslFd_get_ssl(conn.postFd)) != 1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "https proxy: SSL_connect has failed");
+ clean_return(conn.sockfd);
+ }
+ }
+
+ memset(tab, 0, 9000);
+ switch (authtype) {
+ case PROXYAUTH_TYPE_BASIC:
+ sprintf(tab,
+ "POST http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
+ "Host: %s:%s\r\n"
+ "Content-Length: 90000\r\n"
+ "Connection: close\r\n"
+ "Proxy-Authorization: Basic %s\r\n\r\n", host, serv, conn.id, host, serv, b64cred);
+ break;
+ default:
+ sprintf(tab,
+ "POST http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
+ "Host: %s:%s\r\n"
+ "Content-Length: 90000\r\n"
+ "Connection: close\r\n\r\n", host, serv, conn.id, host, serv);
+ }
+ j = strlen (tab);
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: writing POST request...", name);
+ if (http_write(https, conn.postFd, (unsigned char*) tab, j) <= 0) {
+ clean_return(conn.sockfd);
+ }
+
+ /* getfd */
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: connecting (getfd)...", name);
+ if (ip_connect(&tmp, proxyname, proxyport, type, NULL, NULL)) {
+ clean_return(conn.sockfd);
+ }
+ SslFd_set_fd(conn.getFd, tmp);
+ if (https) {
+ if (SSL_set_fd(SslFd_get_ssl(conn.getFd), SslFd_get_fd(conn.getFd)) != 1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "https proxy: Problem with initializing ssl");
+ clean_return(conn.sockfd);
+ }
+ if (SSL_connect(SslFd_get_ssl(conn.getFd)) != 1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "https proxy: SSL_connect has failed");
+ clean_return(conn.sockfd);
+ }
+ }
+
+ memset(tab, 0, 9000);
+ switch (authtype) {
+ case PROXYAUTH_TYPE_BASIC:
+ sprintf(tab,
+ "GET http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
+ "Host: %s:%s\r\n"
+ "Connection: close\r\n"
+ "Proxy-Authorization: Basic %s\r\n\r\n", host, serv, conn.id, host, serv, b64cred);
+ break;
+ default:
+ sprintf(tab,
+ "GET http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
+ "Host: %s:%s\r\n"
+ "Connection: close\r\n\r\n", host, serv, conn.id, host, serv);
+ }
+ j = strlen (tab);
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: writing GET request...", name);
+ if (http_write(https, conn.getFd, (unsigned char*) tab, j) <= 0) {
+ clean_return(conn.sockfd);
+ }
+
+ set_fd(conn.sockfd, &maxfdp1, &allset);
+ set_fd(SslFd_get_fd(conn.postFd), &maxfdp1, &allset);
+ set_fd(SslFd_get_fd(conn.getFd), &maxfdp1, &allset);
+ conn.state = C_OPEN;
+
+ memset(tab, 0, 9000);
+
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: parsing header from getfd", name);
+ if (parse_header(conn.getFd, tab, &hdr, https)) {
+ clean_return(conn.sockfd);
+ }
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: checking hdr.type", name);
+ if (hdr.type != H_TYPE_OK) {
+ clean_return(conn.sockfd);
+ }
+ if (hdr.length) {
+ conn.received += hdr.length;
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: reading message...", name);
+ if (read_message(conn.sockfd, hdr.length, &conn, tab, hdr.ptr)) {
+ clean_return(conn.sockfd);
+ }
+ }
+
+ while (1) {
+ if ((conn.state == C_OPEN) && (!(FD_ISSET(conn.sockfd, &allset)))) {
+ FD_SET(conn.sockfd, &allset);
+ }
+ rset = allset;
+
+ if (select(maxfdp1, &rset, NULL, NULL, &tv) == 0) {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http%s proxy: timeout", name);
+ tv.tv_sec = timeout;
+ if (conn.sent_ptr+1 >= 90000) {
+ if (conn.state == C_CLOSED) {
+ continue;
+ }
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http%s proxy: send T", name);
+ http_write(https, conn.postFd, (unsigned char*) "T", 1);
+ conn.sent_ptr = 0;
+ clear_sslFd(conn.postFd, &allset);
+ /* postfd */
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: connecting (postfd)...", name);
+ if (ip_connect(&tmp, proxyname, proxyport, type, NULL, NULL)) {
+ clean_return(conn.sockfd);
+ }
+ SslFd_set_fd(conn.postFd, tmp);
+ if (https) {
+ if (SSL_set_fd(SslFd_get_ssl(conn.postFd), SslFd_get_fd(conn.postFd)) != 1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "https proxy: Problem with initializing ssl");
+ clean_return(conn.sockfd);
+ }
+ if (SSL_connect(SslFd_get_ssl(conn.postFd)) != 1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "https proxy: SSL_connect has failed");
+ clean_return(conn.sockfd);
+ }
+ }
+
+ memset(tab, 0, 9000);
+ switch (authtype) {
+ case PROXYAUTH_TYPE_BASIC:
+ sprintf(tab,
+ "POST http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
+ "Host: %s:%s\r\n"
+ "Content-Length: 90000\r\n"
+ "Connection: close\r\n"
+ "Proxy-Authorization: Basic %s\r\n\r\n", host, serv, conn.id, host, serv, b64cred);
+ break;
+ default:
+ sprintf(tab,
+ "POST http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
+ "Host: %s:%s\r\n"
+ "Content-Length: 90000\r\n"
+ "Connection: close\r\n\r\n", host, serv, conn.id, host, serv);
+ }
+ j = strlen (tab);
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: writing POST request...", name);
+ if (http_write(https, conn.postFd, (unsigned char *) tab, j) <= 0) {
+ clean_return(conn.sockfd);
+ }
+ conn.sent_ptr = 0;
+ conn.ptr = 0;
+ conn.length = 0;
+ conn.state = C_CLOSED;
+
+ set_fd(SslFd_get_fd(conn.postFd), &maxfdp1, &allset);
+ }
+ else {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http%s proxy: send T", name);
+ http_write(https, conn.postFd, (unsigned char *) "T", 1);
+ conn.sent_ptr += 1;
+ }
+ continue;
+ }
+
+ /* sockfd */
+ if (FD_ISSET(conn.sockfd, &rset)) {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http%s proxy: FD_ISSET(conn.sockfd)", name);
+ n = read(conn.sockfd, conn.buf+5, 8995);
+ if (n <= 0) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: send Q", name);
+ http_write(https, conn.postFd, (unsigned char *) "Q", 1);
+ clean_return(conn.sockfd);
+ }
+ if ((conn.state == C_CLOSED) && (conn.sent_ptr > 70000)) {
+ FD_CLR(conn.sockfd, &allset);
+ }
+ conn.buf[0] = 'M';
+ tmp = htonl(n);
+ memcpy(&conn.buf[1], &tmp, 4);
+ if (conn.sent_ptr+5 + n >= 90000) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: send message", name);
+ http_write(https, conn.postFd, (unsigned char *) conn.buf, 90000 - conn.sent_ptr);
+ conn.ptr = 90000 - conn.sent_ptr;
+ conn.length = 5+n - conn.ptr;
+ conn.sent_ptr = 0;
+ clear_sslFd(conn.postFd, &allset);
+
+ /* postfd */
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: connecting (postfd)...", name);
+ if (ip_connect(&tmp, proxyname, proxyport, type, NULL, NULL)) {
+ clean_return(conn.sockfd);
+ }
+ SslFd_set_fd(conn.postFd, tmp);
+ if (https) {
+ if (SSL_set_fd(SslFd_get_ssl(conn.postFd), SslFd_get_fd(conn.postFd)) != 1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "https proxy: Problem with initializing ssl");
+ clean_return(conn.sockfd);
+ }
+ if (SSL_connect(SslFd_get_ssl(conn.postFd)) != 1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "https proxy: SSL_connect has failed");
+ clean_return(conn.sockfd);
+ }
+ }
+
+ memset(tab, 0, 9000);
+ switch (authtype) {
+ case PROXYAUTH_TYPE_BASIC:
+ sprintf(tab,
+ "POST http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
+ "Host: %s:%s\r\n"
+ "Content-Length: 90000\r\n"
+ "Connection: close\r\n"
+ "Proxy-Authorization: Basic %s\r\n\r\n", host, serv, conn.id, host, serv, b64cred);
+ break;
+ default:
+ sprintf(tab,
+ "POST http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
+ "Host: %s:%s\r\n"
+ "Content-Length: 90000\r\n"
+ "Connection: close\r\n\r\n", host, serv, conn.id, host, serv);
+ }
+ j = strlen (tab);
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: writing POST request...", name);
+ if (http_write(https, conn.postFd, (unsigned char *) tab, j) <= 0) {
+ clean_return(conn.sockfd);
+ }
+ if (conn.length > 0) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: writing old data...", name);
+ if (http_write(https, conn.postFd, (unsigned char *) (conn.buf+conn.ptr), conn.length) <= 0) {
+ clean_return(conn.sockfd);
+ }
+ }
+ conn.sent_ptr = conn.length;
+ conn.ptr = 0;
+ conn.length = 0;
+ conn.state = C_CLOSED;
+
+ set_fd(SslFd_get_fd(conn.postFd), &maxfdp1, &allset);
+ }
+ else {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: send message", name);
+ http_write(https, conn.postFd, (unsigned char *) conn.buf, 5+n);
+ conn.sent_ptr += 5+n;
+ }
+ }
+
+ /* getfd */
+ if (FD_ISSET(SslFd_get_fd(conn.getFd), &rset)) {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http%s proxy: FD_ISSET(conn.getfd)", name);
+ n = http_read(https, conn.getFd, (unsigned char*) tab, 9000);
+ conn.received += n;
+ if (n == 0) {
+ conn.received = 0;
+ clear_sslFd(conn.getFd, &allset);
+
+ /* getfd */
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: connecting (getfd)...", name);
+ if (ip_connect(&tmp, proxyname, proxyport, type, NULL, NULL)) {
+ clean_return(conn.sockfd);
+ }
+ SslFd_set_fd(conn.getFd, tmp);
+ if (https) {
+ if (SSL_set_fd(SslFd_get_ssl(conn.getFd), SslFd_get_fd(conn.getFd)) != 1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "https proxy: Problem with initializing ssl");
+ clean_return(conn.sockfd);
+ }
+ if (SSL_connect(SslFd_get_ssl(conn.getFd)) != 1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "https proxy: SSL_connect has failed");
+ clean_return(conn.sockfd);
+ }
+ }
+
+ memset(tab, 0, 9000);
+ switch (authtype) {
+ case PROXYAUTH_TYPE_BASIC:
+ sprintf(tab,
+ "GET http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
+ "Host: %s:%s\r\n"
+ "Connection: close\r\n"
+ "Proxy-Authorization: Basic %s\r\n\r\n", host, serv, conn.id, host, serv, b64cred);
+ break;
+ default:
+ sprintf(tab,
+ "GET http://%s:%s/yahpt.html?id=%s HTTP/1.1\r\n"
+ "Host: %s:%s\r\n"
+ "Connection: close\r\n\r\n", host, serv, conn.id, host, serv);
+ }
+ j = strlen (tab);
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: writing GET request...", name);
+ if (http_write(https, conn.getFd, (unsigned char *) tab, j) <= 0) {
+ clean_return(conn.sockfd);
+ }
+ memset(tab, 0, 9000);
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: parsing header from getfd", name);
+ if (parse_header(conn.getFd, tab, &hdr, https)) {
+ clean_return(conn.sockfd);
+ }
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: checking hdr.type", name);
+ if (hdr.type != H_TYPE_OK) {
+ clean_return(conn.sockfd);
+ }
+
+ set_fd(SslFd_get_fd(conn.getFd), &maxfdp1, &allset);
+ if (hdr.length) {
+ conn.received += hdr.length;
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: reading message...", name);
+ if (read_message(conn.sockfd, hdr.length, &conn, tab, hdr.ptr)) {
+ clean_return(conn.sockfd);
+ }
+ }
+ }
+ else {
+ if (read_message(conn.sockfd, n, &conn, tab, 0)) {
+ clean_return(conn.sockfd);
+ }
+ }
+ }
+
+ /* postfd */
+ if (FD_ISSET(SslFd_get_fd(conn.postFd), &rset)) {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http%s proxy: FD_ISSET(conn.postfd) --> clean_return", name);
+ clear_sslFd(conn.postFd, &allset);
+ clean_return(conn.sockfd);
+ }
+ }
+ clean_return(conn.sockfd);
+}
+
+/*
+ * Function name: initialize_http_proxy_client
+ * Description: Initializes the thread responsible for http proxy connection.
+ * Arguments: sockfd - the new connection descriptor will be stored here
+ * cr - the pointer to ClientRealm structure
+ * ctx - the pointer to SSL_CTX structure
+ * Returns: 0 - success,
+ * !0 - failure.
+ */
+
+int
+initialize_http_proxy_client(int* sockfd, ClientRealm* cr, SSL_CTX* ctx)
+{
+ int retval;
+ int sockets[2];
+ pthread_t proxy_thread;
+ static proxy_argT arg;
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets)) {
+ return 1;
+ }
+ (*sockfd) = sockets[0];
+
+ if (HttpProxyOptions_get_proxyname(ClientRealm_get_httpProxyOptions(cr)) == NULL) {
+ return 1;
+ }
+
+ start_critical_section();
+
+ arg.host = ClientRealm_get_serverName(cr);
+ arg.serv = ClientRealm_get_managePort(cr);
+ arg.hpo = ClientRealm_get_httpProxyOptions(cr);
+ arg.type = ClientRealm_get_ipFamily(cr);
+ arg.sockfd = sockets[1];
+ arg.ctx = ctx;
+
+ retval = pthread_create(&proxy_thread, NULL, &http_proxy_client, &arg);
+
+ wait_for_condition();
+
+ end_critical_section();
+
+ return retval;
+}
+
+#endif
diff --git a/src/http_proxy_client.h b/src/http_proxy_client.h
new file mode 100644
index 0000000..15506c7
--- /dev/null
+++ b/src/http_proxy_client.h
@@ -0,0 +1,29 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "http_proxy_options_struct.h"
+#include "client_realm_struct.h"
+
+#ifndef _JS_HTTP_PROXY_CLIENT_H
+#define _JS_HTTP_PROXY_CLIENT_H
+
+int initialize_http_proxy_client(int* sockfd, ClientRealm* cr, SSL_CTX* ctx);
+
+#endif
diff --git a/src/http_proxy_functions.c b/src/http_proxy_functions.c
new file mode 100644
index 0000000..e7bef6f
--- /dev/null
+++ b/src/http_proxy_functions.c
@@ -0,0 +1,410 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "http_proxy_functions.h"
+#include "network.h"
+#include "stats.h"
+#include "logging.h"
+
+static char isseed;
+
+/*
+ * Function name: myrand
+ * Description: Returns the pseudo-random number from the given range.
+ * If the lower and upper bounds are the same, the pseudo-random
+ * number is returned from the range (-RAND_MAX, -RAND_MAX+down)
+ * or (down, RAND_MAX).
+ * Arguments: down - the lower bound of the range
+ * up - the upper bound of the range
+ * Returns: The pseudo-random number from the given range.
+ */
+
+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) ) );
+}
+
+/*
+ * Function name: mysleep
+ * Description: Sleeps for the given amount of milliseconds.
+ * Arguments: time - the amount of milliseconds to sleep for
+ */
+
+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);
+}
+
+/*
+ * Function name: delete_user
+ * Description: Deletes the user's connection from the http proxy connections.
+ * Arguments: cnts - the connection to remove
+ * i - the user's number
+ * allset - the set of file descriptors
+ */
+
+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_sslFd(cnts[i].postFd, allset);
+ }
+ if ((cnts[i].type == 0) && (!(cnts[i].state & C_GET_WAIT))) {
+ clear_sslFd(cnts[i].getFd, allset);
+ }
+ cnts[i].state = C_CLOSED;
+ cnts[i].sent_ptr = cnts[i].ptr = cnts[i].length = 0;
+ cnts[i].type = 0;
+}
+
+/*
+ * Function name: parse_header
+ * Description: Reads and parses the http header.
+ * Arguments: sf - the pointer to SslFd structure
+ * tab - the buffer used for reading the data
+ * hdr - the pointer to header structure
+ * https - the flag indicating if the connection is http/https
+ * Returns: 0 - success,
+ * 1 - failure.
+ */
+
+int
+parse_header(SslFd* sf, char* tab, header* hdr, char https)
+{
+ int n, i, j, state = 0;
+ char tmpt[100];
+ if (https) {
+ n = SSL_read(SslFd_get_ssl(sf), tab, 9000);
+ }
+ else {
+ n = read(SslFd_get_fd(sf), 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;
+}
+
+/*
+ * Function name: set_fd
+ * Description: Starts watching the file descriptor.
+ * Arguments: fd - the file descriptor
+ * maxfdp1 - the upper limit of the file descriptor numbers
+ * allset - the set of file descriptors
+ */
+
+void
+set_fd(int fd, int* maxfdp1, fd_set* allset)
+{
+ FD_SET(fd, allset);
+ (*maxfdp1) = ((*maxfdp1) > fd) ? (*maxfdp1) : (fd + 1);
+}
+
+/*
+ * Function name: close_fd
+ * Description: Closes the file descriptor.
+ * Arguments: fd - the file descriptor to close
+ */
+
+void
+close_fd(int* fd)
+{
+ close(*fd);
+}
+
+/*
+ * Function name: clear_fd
+ * Description: Removes the file descriptor from the set and closes it.
+ * Arguments: fd - the file descriptor to remove and close
+ * set - the set of file descriptors
+ */
+
+void
+clear_fd(int* fd, fd_set* set)
+{
+ FD_CLR(*fd, set);
+ close_fd(fd);
+}
+
+/*
+ * Function name: read_message
+ * Description: Reads the message from the http proxy connection and writes it
+ * to the file descriptor.
+ * Arguments: fd - the file descriptor
+ * length - the length of the buffer
+ * client - the http proxy connection
+ * tab - the buffer with the readed data
+ * ptr - the offset from which the data reading will start
+ * Returns: 0 - success,
+ * 1 - failure.
+ */
+
+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) {
+ if (client->toreceive - client->curreceived > 0) {
+ 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;
+ }
+ case 'A': {
+ ++j;
+ if (client->state == C_CLOSED) {
+ client->state = C_OPEN;
+ }
+ 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 if (length-j > 0) {
+ client->curreceived += length-j;
+ writen(fd, (unsigned char*) (tab+ptr+j), length-j);
+ j += length-j;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Function name: clear_sslFd
+ * Description: Close the socket encapsulated in SslFd structure, remove this file descriptor
+ * from fd_set and clear ssl structure.
+ * Arguments: sf - pointer to SslFd structure
+ * set - pointer to fd_set structure
+ */
+
+void
+clear_sslFd(SslFd* sf, fd_set* set)
+{
+ clear_fd((&(sf->fd)), set);
+ if (SslFd_get_ssl(sf)) {
+ SSL_clear(SslFd_get_ssl(sf));
+ }
+}
+
+/*
+ * Function name: http_write
+ * Description: Write the message via http/https proxy.
+ * Arguments: https - if the https proxy will be used instead of http proxy
+ * sf - pointer to SslFd structure
+ * buf - buffer containing the data to send
+ * amount - how much butes will be send
+ * Returns: The result of writen or SSL_writen function, depending on 'https' value.
+ */
+
+int
+http_write(char https, SslFd* sf, unsigned char* buf, int amount)
+{
+ if (https) {
+ return SSL_writen(SslFd_get_ssl(sf), buf, amount);
+ }
+ else {
+ return writen(SslFd_get_fd(sf), buf, amount);
+ }
+}
+
+/*
+ * Function name: http_read
+ * Description: Read the message via http/https proxy.
+ * Arguments: https - if the https proxy will be used instead of http proxy
+ * sf - pointer to SslFd structure
+ * buf - buffer for the received data
+ * amount - how much bytes will be received
+ * Returns: The result of read or SSL_read function, depending on 'https' value.
+ */
+
+int
+http_read(char https, SslFd* sf, unsigned char* buf, int amount)
+{
+ if (https) {
+ return SSL_read(SslFd_get_ssl(sf), buf, amount);
+ }
+ else {
+ return read(SslFd_get_fd(sf), buf, amount);
+ }
+}
diff --git a/src/http_proxy_functions.h b/src/http_proxy_functions.h
new file mode 100644
index 0000000..3d29699
--- /dev/null
+++ b/src/http_proxy_functions.h
@@ -0,0 +1,86 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/select.h>
+#include <unistd.h>
+
+#include "ssl_fd_struct.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 C_DELAYED_A 8
+
+#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];
+ SslFd* postFd;
+ SslFd* getFd;
+ int sent_ptr;
+ int sockfd;
+ char buf[9000];
+ char tmpbuf[9000];
+ char tmpstate;
+ SslFd* 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(SslFd*, char*, header*, char);
+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*);
+void clear_sslFd(SslFd*, fd_set*);
+int http_write(char, SslFd*, unsigned char*, int);
+int http_read(char, SslFd*, unsigned char*, int);
+
+#endif
diff --git a/src/http_proxy_options_struct.c b/src/http_proxy_options_struct.c
new file mode 100644
index 0000000..e1dcc4d
--- /dev/null
+++ b/src/http_proxy_options_struct.c
@@ -0,0 +1,254 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "http_proxy_options_struct.h"
+#include "string_functions.h"
+
+/*
+ * Function name: HttpProxyOptions_new
+ * Description: Create and initialize new HttpProxyOptions structure.
+ * Returns: Pointer to newly created HttpProxyOptions structure.
+ */
+
+HttpProxyOptions*
+HttpProxyOptions_new()
+{
+ HttpProxyOptions* tmp = calloc(1, sizeof(HttpProxyOptions));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ tmp->proxyauth_type = PROXYAUTH_TYPE_NOTSET;
+ return tmp;
+}
+
+/*
+ * Function name: HttpProxyOptions_free
+ * Description: Free the memory allocated for HttpProxyOptions structure.
+ * Arguments: hpo - pointer to pointer to HttpProxyOptions structure
+ */
+
+void
+HttpProxyOptions_free(HttpProxyOptions** hpo)
+{
+ assert(hpo != NULL);
+ if (hpo == NULL) {
+ return;
+ }
+ assert((*hpo) != NULL);
+ if ((*hpo) == NULL) {
+ return;
+ }
+ if ((*hpo)->proxyname) {
+ free((*hpo)->proxyname);
+ (*hpo)->proxyname = NULL;
+ }
+ if ((*hpo)->proxyport) {
+ free((*hpo)->proxyport);
+ (*hpo)->proxyport = NULL;
+ }
+ if ((*hpo)->proxyauth_cred) {
+ free((*hpo)->proxyauth_cred);
+ (*hpo)->proxyauth_cred = NULL;
+ }
+ free((*hpo));
+ (*hpo) = NULL;
+}
+
+/*
+ * Function name: HttpProxyOptions_set_proxyname
+ * Description: Set name of the http proxy server.
+ * Arguments: hpo - pointer to HttpProxyOptions structure
+ * proxyname - name of the http proxy server
+ */
+
+void
+HttpProxyOptions_set_proxyname(HttpProxyOptions* hpo, char* proxyname)
+{
+ assert(hpo != NULL);
+ if (hpo == NULL) {
+ return;
+ }
+ string_cp(&(hpo->proxyname), proxyname);
+}
+
+/*
+ * Function name: HttpProxyOptions_set_proxyport
+ * Description: Set port on which http proxy server is listening.
+ * Arguments: hpo - pointer to HttpProxyOptions structure
+ * proxyport - port on which http proxy server is listening
+ */
+
+void
+HttpProxyOptions_set_proxyport(HttpProxyOptions* hpo, char* proxyport)
+{
+ assert(hpo != NULL);
+ if (hpo == NULL) {
+ return;
+ }
+ string_cp(&(hpo->proxyport), proxyport);
+}
+
+/*
+ * Function name: HttpProxyOptions_set_proxyauth_cred
+ * Description: Set credentials for http proxy server.
+ * Arguments: hpo - pointer to HttpProxyOptions structure
+ * proxyauth_cred - credentials for http proxy server
+ */
+
+void
+HttpProxyOptions_set_proxyauth_cred(HttpProxyOptions* hpo, char* proxyauth_cred)
+{
+ assert(hpo != NULL);
+ if (hpo == NULL) {
+ return;
+ }
+ string_cp(&(hpo->proxyauth_cred), proxyauth_cred);
+}
+
+/*
+ * Function name: HttpProxyOptions_set_proxyauth_type
+ * Description: Set type of the proxy authorization.
+ * Arguments: hpo - pointer to HttpProxyOptions structure
+ * proxyauth_type - type of the proxy authorization
+ */
+
+void
+HttpProxyOptions_set_proxyauth_type(HttpProxyOptions* hpo, char proxyauth_type)
+{
+ assert(hpo != NULL);
+ if (hpo == NULL) {
+ return;
+ }
+ assert(hpo->proxyauth_type == PROXYAUTH_TYPE_NOTSET);
+ if (hpo->proxyauth_type != PROXYAUTH_TYPE_NOTSET) {
+ hpo->proxyauth_type = PROXYAUTH_TYPE_WRONG;
+ return;
+ }
+ hpo->proxyauth_type = proxyauth_type;
+}
+
+/*
+ * Function name: HttpProxyOptions_get_proxyname
+ * Description: Get name of the http proxy server
+ * Arguments: hpo - pointer to HttpProxyOptions structure
+ * Returns: Name of the http proxy server or NULL, if name not set.
+ */
+
+char*
+HttpProxyOptions_get_proxyname(HttpProxyOptions* hpo)
+{
+ assert(hpo != NULL);
+ if (hpo == NULL) {
+ return NULL;
+ }
+ return hpo->proxyname;
+}
+
+/*
+ * Function name: HttpProxyOptions_get_proxyport
+ * Description: Get port on which http proxy server is listening.
+ * Arguments: hpo - pointer to HttpProxyOptions structure
+ * Returns: Port on which http proxy server is listening or NULL, if port not set.
+ */
+
+char*
+HttpProxyOptions_get_proxyport(HttpProxyOptions* hpo)
+{
+ assert(hpo != NULL);
+ if (hpo == NULL) {
+ return NULL;
+ }
+ return hpo->proxyport;
+}
+
+/*
+ * Function name: HttpProxyOptions_get_proxyauth_cred
+ * Description: Get credentials for http proxy server.
+ * Arguments: hpo - pointer to HttpProxyOptions structure
+ * Returns: Credentials for http proxy server or NULL, if not set.
+ */
+
+char*
+HttpProxyOptions_get_proxyauth_cred(HttpProxyOptions* hpo)
+{
+ assert(hpo != NULL);
+ if (hpo == NULL) {
+ return NULL;
+ }
+ return hpo->proxyauth_cred;
+}
+
+/*
+ * Function name: HttpProxyOptions_get_proxyauth_type
+ * Description: Get type of the proxy authorization.
+ * Arguments: hpo - pointer to HttpProxyOptions structure
+ * Returns: Type of the proxy authorization.
+ */
+
+char
+HttpProxyOptions_get_proxyauth_type(HttpProxyOptions* hpo)
+{
+ assert(hpo != NULL);
+ if (hpo == NULL) {
+ return PROXYAUTH_TYPE_WRONG;
+ }
+ return hpo->proxyauth_type;
+}
+
+/*
+ * Function name: HttpProxyOptions_use_https
+ * Description: Enable use of https proxy instead of http proxy.
+ * Arguments: hpo - pointer to HttpProxyOptions structure
+ */
+
+void
+HttpProxyOptions_use_https(HttpProxyOptions* hpo)
+{
+ assert(hpo != NULL);
+ if (hpo == NULL) {
+ return;
+ }
+ hpo->useHttps = USEHTTPS_ON;
+}
+
+/*
+ * Function name: HttpProxyOptions_is_https
+ * Description: Check if the use of https proxy is enabled.
+ * Arguments: hpo - pointer to HttpProxyOptions structure
+ * Returns: USEHTTPS_OFF - http proxy will be used
+ * USEHTTPS_ON - https proxy will be used
+ */
+
+char
+HttpProxyOptions_is_https(HttpProxyOptions* hpo)
+{
+ assert(hpo != NULL);
+ if (hpo == NULL) {
+ return USEHTTPS_OFF;
+ }
+ return hpo->useHttps;
+}
diff --git a/src/http_proxy_options_struct.h b/src/http_proxy_options_struct.h
new file mode 100644
index 0000000..db0208c
--- /dev/null
+++ b/src/http_proxy_options_struct.h
@@ -0,0 +1,58 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_HTTP_PROXY_OPTIONS_STRUCT_H
+#define _JS_HTTP_PROXY_OPTIONS_STRUCT_H
+
+#define PROXYAUTH_TYPE_NOTSET 0
+#define PROXYAUTH_TYPE_WRONG -1
+#define PROXYAUTH_TYPE_BASIC 1
+
+#define USEHTTPS_OFF 0
+#define USEHTTPS_ON 1
+
+typedef struct {
+ char* proxyname;
+ char* proxyport;
+ char* proxyauth_cred;
+ char proxyauth_type;
+ char useHttps;
+} HttpProxyOptions;
+
+/* 'constructor' */
+HttpProxyOptions* HttpProxyOptions_new();
+/* 'destructor' */
+void HttpProxyOptions_free(HttpProxyOptions** hpo);
+/* setters */
+void HttpProxyOptions_set_proxyname(HttpProxyOptions* hpo, char* proxyname);
+void HttpProxyOptions_set_proxyport(HttpProxyOptions* hpo, char* proxyport);
+void HttpProxyOptions_set_proxyauth_cred(HttpProxyOptions* hpo, char* proxyauth_cred);
+void HttpProxyOptions_set_proxyauth_type(HttpProxyOptions* hpo, char proxyauth_type);
+/* getters */
+char* HttpProxyOptions_get_proxyname(HttpProxyOptions* hpo);
+char* HttpProxyOptions_get_proxyport(HttpProxyOptions* hpo);
+char* HttpProxyOptions_get_proxyauth_cred(HttpProxyOptions* hpo);
+char HttpProxyOptions_get_proxyauth_type(HttpProxyOptions* hpo);
+/* other */
+void HttpProxyOptions_use_https(HttpProxyOptions* hpo);
+char HttpProxyOptions_is_https(HttpProxyOptions* hpo);
+
+#endif
+
diff --git a/src/http_proxy_server.c b/src/http_proxy_server.c
new file mode 100644
index 0000000..17baf5a
--- /dev/null
+++ b/src/http_proxy_server.c
@@ -0,0 +1,585 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "make_ssl_handshake.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;
+ char https;
+ SSL_CTX* ctx;
+} sproxy_argT;
+
+/*
+ * Function name: afserver_connect
+ * Description: Connects new http proxy connection to the afserver.
+ * Arguments: sockfd - the file descriptor which will be used for communication with afserver
+ * afserverfd - the afserver's file descriptor
+ * cliaddr - pointer to sockaddr structure
+ * addrlenp - pointer to the length of the sockaddr structure
+ * type - the type of the connection
+ */
+
+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 4;
+ }
+ if (write(afserverfd, cliaddr, *addrlenp) != *addrlenp) {
+ return 5;
+ }
+ (*sockfd) = sockets[1];
+ return 0;
+}
+
+/*
+ * Function name: http_proxy_server
+ * Description: Function responsible for the server part of the http proxy connection.
+ * Arguments: vptr - the structure with all the information needed for http proxy tunnel.
+ */
+
+void*
+http_proxy_server(void *vptr)
+{
+ int listenfd, afserverfd;
+ SslFd* connFd;
+ 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;
+ socklen_t addrlen;
+ char type, nothttp, https;
+ char *host, *serv, *name = "";
+ SSL_CTX* ctx;
+ 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;
+ https = proxy_argptr->https;
+ ctx = proxy_argptr->ctx;
+
+ if (https) {
+ name = "s";
+ }
+
+ table = calloc(maxclients, sizeof(connection));
+ if (table == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http%s proxy: Can't allocate memory... exiting.", name);
+ exit(1);
+ }
+ for (i = 0; i < maxclients; ++i) {
+ table[i].postFd = SslFd_new();
+ table[i].getFd = SslFd_new();
+ table[i].tmpFd = SslFd_new();
+ if ((table[i].postFd == NULL) || (table[i].getFd == NULL) || (table[i].tmpFd == NULL)) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http%s proxy: Can't allocate memory... exiting.", name);
+ exit(1);
+ }
+ if (https) {
+ SslFd_set_ssl(table[i].postFd, SSL_new(ctx));
+ SslFd_set_ssl(table[i].getFd, SSL_new(ctx));
+ SslFd_set_ssl(table[i].tmpFd, SSL_new(ctx));
+ if ((SslFd_get_ssl(table[i].postFd) == NULL) ||
+ (SslFd_get_ssl(table[i].getFd) == NULL) ||
+ (SslFd_get_ssl(table[i].tmpFd) == NULL)) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http%s proxy: Can't allocate memory... exiting.", name);
+ exit(1);
+ }
+ }
+ }
+ connFd = SslFd_new();
+ if (connFd == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http%s proxy: Can't allocate memory... exiting.", name);
+ exit(1);
+ }
+ if (https) {
+ SslFd_set_ssl(connFd, SSL_new(ctx));
+ if (SslFd_get_ssl(connFd) == NULL) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http%s proxy: Can't allocate memory... exiting.", name);
+ exit(1);
+ }
+ }
+
+ if (ip_listen(&listenfd, host, serv, addrlenp, type)) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "http%s proxy: Can't listen on %s:%s", name, host, serv);
+ exit(1);
+ }
+ cliaddr = malloc(*addrlenp);
+ addrlen = (*addrlenp);
+ addrlenp = &addrlen;
+
+ broadcast_condition();
+ end_critical_section();
+
+ 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%s proxy: timeout", name);
+ tv.tv_sec = timeout;
+ for (i = 0; i < maxclients; ++i) {
+ if ((table[i].state == C_CLOSED) || (table[i].state & C_GET_WAIT) || (table[i].type == 1)) {
+ continue;
+ }
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http%s proxy: send T to table[%d].getfd", name, i);
+ if (table[i].sent_ptr+1 >= 90000) {
+ http_write(https, table[i].getFd, (unsigned char*) "T", 1);
+ table[i].sent_ptr = 0;
+ clear_sslFd(table[i].getFd, &allset);
+ FD_CLR(table[i].sockfd, &allset);
+ table[i].state |= C_GET_WAIT;
+ }
+ else {
+ http_write(https, 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%s proxy: FD_ISSET(table[%d].sockfd)", name, i);
+ n = read(table[i].sockfd, table[i].buf+5, 8995);
+ if (n <= 0) {
+ http_write(https, 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) {
+ http_write(https, table[i].getFd, (unsigned char*) table[i].buf, 90000 - table[i].sent_ptr);
+ table[i].ptr = 90000 - table[i].sent_ptr;
+ table[i].length = 5+n - table[i].ptr;
+ table[i].sent_ptr = 0;
+ clear_sslFd(table[i].getFd, &allset);
+ FD_CLR(table[i].sockfd, &allset);
+ table[i].state |= C_GET_WAIT;
+ continue;
+ }
+ else {
+ http_write(https, table[i].getFd, (unsigned char*) table[i].buf, n+5);
+ table[i].sent_ptr += n+5;
+ }
+ }
+
+ /* getfd */
+ if (FD_ISSET(SslFd_get_fd(table[i].getFd), &rset)) {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http%s proxy: FD_ISSET(table[%d].getfd)", name, i);
+ delete_user(table, i, &allset);
+ continue;
+ }
+
+ /* postfd */
+ if (FD_ISSET(SslFd_get_fd(table[i].postFd), &rset)) {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http%s proxy: FD_ISSET(table[%d].postfd)", name, i);
+ n = http_read(https, table[i].postFd, (unsigned char*) tab, 9000);
+ if (n != 0) {
+ table[i].received += n;
+ if (read_message(table[i].sockfd, n, &table[i], tab, 0)) {
+ delete_user(table, i, &allset);
+ }
+ }
+ if ((n == 0) || (table[i].received == 90000)) {
+ table[i].received = 0;
+ clear_sslFd(table[i].postFd, &allset);
+ table[i].state |= C_POST_WAIT;
+
+ if (!(table[i].state & C_GET_WAIT)) {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http%s proxy: send A to table[%d].getfd", name, i);
+ if (table[i].sent_ptr+1 >= 90000) {
+ http_write(https, table[i].getFd, (unsigned char*) "A", 1);
+ table[i].sent_ptr = 0;
+ clear_sslFd(table[i].getFd, &allset);
+ FD_CLR(table[i].sockfd, &allset);
+ table[i].state |= C_GET_WAIT;
+ }
+ else {
+ http_write(https, table[i].getFd, (unsigned char*) "A", 1);
+ table[i].sent_ptr += 1;
+ }
+ }
+ else {
+ table[i].state |= C_DELAYED_A;
+ }
+
+ if (table[i].tmpstate == 1) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: get old POST request...", name);
+ table[i].state &= ~C_POST_WAIT;
+ SslFd_swap_content(table[i].postFd, table[i].tmpFd);
+ set_fd(SslFd_get_fd(table[i].postFd), &maxfdp1, &allset);
+ table[i].tmpstate = 0;
+ if (table[i].tmpheader.length) {
+ table[i].received += table[i].tmpheader.length;
+ 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) {
+ writen(SslFd_get_fd(table[i].postFd), (unsigned char*) table[i].buf, n);
+ }
+ else {
+ delete_user(table, i, &allset);
+ continue;
+ }
+ }
+
+ if (FD_ISSET(SslFd_get_fd(table[i].postFd), &rset)) {
+ n = read(SslFd_get_fd(table[i].postFd), tab, 9000);
+ if (n > 0) {
+ writen(table[i].sockfd, (unsigned char*) tab, n);
+ }
+ else {
+ delete_user(table, i, &allset);
+ continue;
+ }
+ }
+
+ }
+ }
+
+ /* listen */
+ if (FD_ISSET(listenfd, &rset)) {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http%s proxy: FD_ISSET(listenfd)", name);
+ tmp = accept(listenfd, cliaddr, addrlenp);
+ if (tmp != -1) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: New connection...", name);
+ SslFd_set_fd(connFd, tmp);
+ if (https) {
+ make_ssl_initialize(connFd);
+ if (make_ssl_accept(connFd)) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "https proxy: DENIED by SSL_accept");
+ close(SslFd_get_fd(connFd));
+ SSL_clear(SslFd_get_ssl(connFd));
+ continue;
+ }
+ }
+ }
+ else {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: New connection --> EAGAIN", name);
+ continue;
+ }
+ memset(tab, 0, 9000);
+ nothttp = 0;
+ if (parse_header(connFd, tab, &hdr, https)) {
+ nothttp = 1;
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: no http header...", name);
+ }
+ 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%s proxy: the client exist...", name);
+ if (hdr.type == H_TYPE_GET) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: type GET...", name);
+ if (!(table[i].state & C_GET_WAIT)) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: not waiting for GET...", name);
+ table[i].sent_ptr = 0;
+ FD_CLR(table[i].sockfd, &allset);
+ clear_sslFd(table[i].getFd, &allset);
+ table[i].state |= C_GET_WAIT;
+ }
+ if (!(table[i].state & C_OPEN)) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: not opened...", name);
+ if (afserver_connect(&table[i].sockfd, afserverfd, cliaddr, addrlenp, 1)) {
+ memset(tab, 0, 9000);
+ sprintf(tab,"HTTP/1.1 400 Bad Request\r\n\r\n");
+ n = strlen (tab);
+ http_write(https, connFd, (unsigned char*) tab, n);
+ close_fd((&(connFd->fd)));
+ SSL_clear(SslFd_get_ssl(connFd));
+ clear_sslFd(table[i].postFd, &allset);
+ table[i].state = C_CLOSED;
+ continue;
+ }
+ table[i].state |= C_OPEN;
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: OPEN...", name);
+ }
+ table[i].state &= ~C_GET_WAIT;
+ table[i].sent_ptr = 0;
+ SslFd_swap_content(table[i].getFd, connFd);
+ set_fd(table[i].sockfd, &maxfdp1, &allset);
+ set_fd(SslFd_get_fd(table[i].getFd), &maxfdp1, &allset);
+ memset(tab, 0, 9000);
+ sprintf(tab,
+ "HTTP/1.1 200 OK\r\n"
+ "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(SslFd_get_fd(table[i].getFd), (unsigned char*) tab, n) <= 0) {
+ delete_user(table, i, &allset);
+ continue;
+ }
+ if (table[i].length) {
+ if (writen(SslFd_get_fd(table[i].getFd),
+ (unsigned char*) (table[i].buf+table[i].ptr), table[i].length) <= 0) {
+ delete_user(table, i, &allset);
+ continue;
+ }
+ }
+ table[i].sent_ptr = table[i].length;
+ table[i].ptr = 0;
+ table[i].length = 0;
+ if (table[i].state & C_DELAYED_A) {
+ aflog(LOG_T_MAIN, LOG_I_DDEBUG,
+ "http%s proxy: send A to table[%d].getfd", name, i);
+ http_write(https, table[i].getFd, (unsigned char*) "A", 1);
+ table[i].sent_ptr += 1;
+ table[i].state &= ~C_DELAYED_A;
+ }
+ }
+ else if (hdr.type == H_TYPE_POST) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: type POST...", name);
+ if (!(table[i].state & C_POST_WAIT)) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: unexpected POST request...", name);
+ if (table[i].tmpstate == 0) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: buffering POST request...", name);
+ table[i].tmpstate = 1;
+ SslFd_swap_content(table[i].tmpFd, connFd);
+ memcpy(table[i].tmpbuf, tab, 9000);
+ table[i].tmpheader = hdr;
+ }
+ else {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: no space to buffer POST request (received from first postfd: %d)", name,
+ 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;
+ SslFd_swap_content(table[i].postFd, connFd);
+ set_fd(SslFd_get_fd(table[i].postFd), &maxfdp1, &allset);
+ }
+ }
+ else {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: unrecognized type...", name);
+ delete_user(table, i, &allset);
+ }
+ }
+ else if (n != -1) { /* there are free slots */
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: there are free slots...", name);
+ if (!nothttp) {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: http header...", name);
+ if (hdr.type == H_TYPE_POST) { /* POST request must be first */
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: type POST...", name);
+ table[n].state = C_GET_WAIT;
+ memcpy(table[n].id,hdr.id, 9);
+ SslFd_swap_content(table[n].postFd, connFd);
+ set_fd(SslFd_get_fd(table[n].postFd), &maxfdp1, &allset);
+ }
+ else {
+ aflog(LOG_T_MAIN, LOG_I_DEBUG,
+ "http%s proxy: closing this connection... (not POST type)", name);
+ close_fd((&(connFd->fd)));
+ if (https) {
+ SSL_clear(SslFd_get_ssl(connFd));
+ }
+ continue;
+ }
+ }
+ else {
+ table[n].state = C_OPEN;
+ SslFd_set_fd(table[n].postFd, SslFd_get_fd(connFd));
+ table[n].type = 1;
+ set_fd(SslFd_get_fd(table[n].postFd), &maxfdp1, &allset);
+ if (afserver_connect(&table[n].sockfd, afserverfd, cliaddr, addrlenp, 0)) {
+ clear_sslFd(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%s proxy: closing this connection... (no free slots)", name);
+ close_fd((&(connFd->fd)));
+ continue;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Function name: initialize_http_proxy_server
+ * Description: Initializes the thread responsible for http proxy connection.
+ * Arguments: sockfd - the new connection descriptor will be stored here
+ * host - the name of the host on which we will be listening on
+ * serv - the port on which we will be listening on
+ * addrlenp - pointer to the length of the sockaddr structure
+ * type - the type of the connection
+ * limit - the limit for user's connections
+ * https - if the connection should be https instead of http
+ * ctx - the pointer to SSL_CTX structure
+ * Returns: 0 - success,
+ * !0 - failure.
+ */
+
+int
+initialize_http_proxy_server(int* sockfd, const char *host, const char *serv, socklen_t *addrlenp, const char type, int limit, char https, SSL_CTX* ctx)
+{
+ int retval;
+ int sockets[2];
+ 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];
+ arg.https = https;
+ arg.ctx = ctx;
+
+ 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..22c121c
--- /dev/null
+++ b/src/http_proxy_server.h
@@ -0,0 +1,29 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#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, char https, SSL_CTX* ctx);
+
+#endif
diff --git a/src/inet_ntop.c b/src/inet_ntop.c
new file mode 100644
index 0000000..77e3e40
--- /dev/null
+++ b/src/inet_ntop.c
@@ -0,0 +1,231 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+/* This is from the BIND 4.9.4 release, modified to compile by itself */
+
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#include "inet_ntop.h"
+
+#ifndef HAVE_INET_NTOP
+
+#ifndef HAVE_THIS_INET_NTOP
+#define HAVE_THIS_INET_NTOP
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id: inet_ntop.c,v 8.5 1996/05/22 04:56:30 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#define IN6ADDRSZ 16
+#define INT16SZ 2
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
+#ifdef AF_INET6
+static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
+#endif
+
+/* char *
+ * inet_ntop(af, src, dst, size)
+ * convert a network format address to presentation format.
+ * return:
+ * pointer to presentation format address (`dst'), or NULL (see errno).
+ * author:
+ * Paul Vixie, 1996.
+ */
+const char *
+inet_ntop(af, src, dst, size)
+ int af;
+ const void *src;
+ char *dst;
+ size_t size;
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_ntop4(src, dst, size));
+#ifdef AF_INET6
+ case AF_INET6:
+ return (inet_ntop6(src, dst, size));
+#endif
+ default:
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+ /* NOTREACHED */
+}
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ * format an IPv4 address, more or less like inet_ntoa()
+ * return:
+ * `dst' (as a const)
+ * notes:
+ * (1) uses no statics
+ * (2) takes a u_char* not an in_addr as input
+ * author:
+ * Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(src, dst, size)
+ const u_char *src;
+ char *dst;
+ size_t size;
+{
+ static const char fmt[] = "%u.%u.%u.%u";
+ char tmp[sizeof "255.255.255.255"];
+
+ sprintf(tmp, fmt, src[0], src[1], src[2], src[3]);
+ if (strlen(tmp) > size) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ strcpy(dst, tmp);
+ return (dst);
+}
+
+#ifdef AF_INET6
+/* const char *
+ * inet_ntop6(src, dst, size)
+ * convert IPv6 binary address into presentation (printable) format
+ * author:
+ * Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop6(src, dst, size)
+ const u_char *src;
+ char *dst;
+ size_t size;
+{
+ /*
+ * Note that int32_t and int16_t need only be "at least" large enough
+ * to contain a value of the specified size. On some systems, like
+ * Crays, there is no such thing as an integer variable with 16 bits.
+ * Keep this in mind if you think this function should have been coded
+ * to use pointer overlays. All the world's not a VAX.
+ */
+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
+ struct { int base, len; } best, cur;
+ u_int words[IN6ADDRSZ / INT16SZ];
+ int i;
+
+ /*
+ * Preprocess:
+ * Copy the input (bytewise) array into a wordwise array.
+ * Find the longest run of 0x00's in src[] for :: shorthanding.
+ */
+ memset(words, 0, sizeof words);
+ for (i = 0; i < IN6ADDRSZ; i++)
+ words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+ best.base = -1;
+ cur.base = -1;
+ for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+ if (words[i] == 0) {
+ if (cur.base == -1)
+ cur.base = i, cur.len = 1;
+ else
+ cur.len++;
+ } else {
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ cur.base = -1;
+ }
+ }
+ }
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ }
+ if (best.base != -1 && best.len < 2)
+ best.base = -1;
+
+ /*
+ * Format the result.
+ */
+ tp = tmp;
+ for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+ /* Are we inside the best run of 0x00's? */
+ if (best.base != -1 && i >= best.base &&
+ i < (best.base + best.len)) {
+ if (i == best.base)
+ *tp++ = ':';
+ continue;
+ }
+ /* Are we following an initial run of 0x00s or any real hex? */
+ if (i != 0)
+ *tp++ = ':';
+ /* Is this address an encapsulated IPv4? */
+ if (i == 6 && best.base == 0 &&
+ (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+ if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
+ return (NULL);
+ tp += strlen(tp);
+ break;
+ }
+ sprintf(tp, "%x", words[i]);
+ tp += strlen(tp);
+ }
+ /* Was it a trailing run of 0x00's? */
+ if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
+ *tp++ = ':';
+ *tp++ = '\0';
+
+ /*
+ * Check for overflow, copy, and we're done.
+ */
+ if ((tp - tmp) > size) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ strcpy(dst, tmp);
+ return (dst);
+}
+#endif
+
+#endif
+
+#endif
diff --git a/src/inet_ntop.h b/src/inet_ntop.h
new file mode 100644
index 0000000..e473896
--- /dev/null
+++ b/src/inet_ntop.h
@@ -0,0 +1,36 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifndef HAVE_INET_NTOP
+
+#include <sys/types.h>
+
+# ifndef _JS_INET_NTOP_H
+# define _JS_INET_NTOP_H
+
+const char* inet_ntop(int af, const void *src, char *dst, size_t size);
+
+# endif
+
+#endif
diff --git a/src/logging.c b/src/logging.c
new file mode 100644
index 0000000..d1836cf
--- /dev/null
+++ b/src/logging.c
@@ -0,0 +1,471 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "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";
+
+/*
+ * Function name: setdateformat
+ * Description: Sets the new date format based on the given string.
+ * Arguments: dateformat - the new date format
+ */
+
+void
+setdateformat(char* dateformat)
+{
+ if (dateformat) {
+ strncpy(format, dateformat, 50);
+ }
+}
+
+/*
+ * Function name: getdateformat
+ * Description: Returns the date format.
+ * Returns: The date format.
+ */
+
+char*
+getdateformat()
+{
+ return format;
+}
+
+/*
+ * Function name: localdate
+ * Description: Returns the formatted date string.
+ * Arguments: sec - the date in seconds
+ * Returns: The formatted date.
+ */
+
+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;
+}
+
+/*
+ * Function name: datum
+ * Description: Returns the formatted date string.
+ * Returns: The formatted date.
+ */
+
+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;
+}
+
+/*
+ * Function name: getloglisthead
+ * Description: Returns the head of the log targets list.
+ * Returns: The head of the log targets list.
+ */
+
+llnodeT*
+getloglisthead()
+{
+ return head;
+}
+
+/*
+ * Function name: checkmsgti
+ * Description: Adds the given msgtype/importance to the log target.
+ * Arguments: target - the log target
+ * tab - the name of the msttype/importance
+ * Returns: 0 - success,
+ * 1 - failure.
+ */
+
+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;
+}
+
+/*
+ * Function name: checklogtarget
+ * Description: Parses the command line and sets all the options.
+ * Arguments: target - the log target
+ * Returns 0 - success,
+ * !0 - failure.
+ */
+
+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, NULL, NULL)) {
+ 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;
+}
+
+/*
+ * Function name: addlogtarget
+ * Description: Adds the new non-initialized log target with the specified command line.
+ * Arguments: cmdline - the command line
+ */
+
+void
+addlogtarget(char* cmdline)
+{
+ llnodeT* newnode = calloc(1, sizeof(llnodeT));
+ newnode->cmdline = cmdline;
+ newnode->next = head;
+ head = newnode;
+}
+
+/*
+ * Function name: loginit
+ * Description: Initializes the logging system.
+ * Arguments: verl - level of verbosity
+ * dateformat - date format
+ * Returns: 0 - success,
+ * !0 - failure.
+ */
+
+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;
+}
+
+/*
+ * Function name: initializelogging
+ * Description: The opaque function for loginit. If the logging initialization
+ * failed, it prints the appropriate message and exits.
+ * Arguments: verl - level of verbosity
+ * dateformat - date format
+ */
+
+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);
+ }
+}
+
+/*
+ * Function name: aflog
+ * Description: Logs the given message.
+ * Arguments: type - the type of the message
+ * importance - the importance of the message
+ * form - the format of the message
+ * ... - the additional arguments
+ */
+
+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..4db250e
--- /dev/null
+++ b/src/logging.h
@@ -0,0 +1,78 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <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
new file mode 100644
index 0000000..6ebb859
--- /dev/null
+++ b/src/make_ssl_handshake.c
@@ -0,0 +1,139 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "make_ssl_handshake.h"
+#include "stats.h"
+#include "logging.h"
+
+#include <errno.h>
+#include <openssl/err.h>
+
+/*
+ * Function name: make_ssl_initialize
+ * Description: Initializes the file descriptor of the SSL connection.
+ * Arguments: sf - pointer to SslFd structure
+ */
+
+void
+make_ssl_initialize(SslFd* sf)
+{
+ if (SSL_set_fd(SslFd_get_ssl(sf), SslFd_get_fd(sf)) != 1) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Problem with initializing ssl... exiting");
+ exit(1);
+ }
+}
+
+/*
+ * Function name: make_ssl_accept
+ * Description: Accepts new SSL connection.
+ * Arguments: sf - pointer to SslFd structure
+ * Returns: 0 - success,
+ * !0 - failure.
+ */
+
+int
+make_ssl_accept(SslFd* sf)
+{
+ int result;
+ if ((result = SSL_accept(SslFd_get_ssl(sf))) != 1) {
+ return get_ssl_error(sf, "SSL_accept has failed", result);
+ }
+ return 0;
+}
+
+/*
+ * Function name: get_ssl_error
+ * Description: Decodes and logs SSL errors.
+ * Arguments: sf - pointer to SslFd structure
+ * info - the header of the warning message
+ * result - the result from the SSL_accept function
+ * Returns: 1 - more i/o operations are needed to accomplish handshake,
+ * 2 - the error was fatal for the handshake.
+ */
+
+int
+get_ssl_error(SslFd* sf, char* info, int result)
+{
+ int merror;
+#ifdef HAVE_ERR_ERROR_STRING
+ char err_buff[200];
+#endif
+ merror = SSL_get_error(SslFd_get_ssl(sf), result);
+ switch (merror) {
+ case SSL_ERROR_NONE : {
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): none", info, result);
+ break;
+ }
+ case SSL_ERROR_ZERO_RETURN : {
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): zero", info, result);
+ break;
+ }
+ case SSL_ERROR_WANT_READ : {
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): w_read", info, result);
+ break;
+ }
+ case SSL_ERROR_WANT_WRITE : {
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): w_write", info, result);
+ break;
+ }
+ case SSL_ERROR_WANT_CONNECT : {
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): w_connect", info, result);
+ break;
+ }
+ case SSL_ERROR_WANT_X509_LOOKUP : {
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): w_x509_lookup", info, result);
+ break;
+ }
+ case SSL_ERROR_SYSCALL : {
+ 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(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): ssl:%s", info, result,
+ ERR_error_string(ERR_get_error(), err_buff));
+#else
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): ssl", info, result);
+#endif
+ break;
+ }
+ default: {
+ aflog(LOG_T_MAIN, LOG_I_WARNING,
+ "%s(%d): unrecognized error (%d)", info, result, errno);
+ }
+ }
+ if ((merror == SSL_ERROR_WANT_READ) || (merror == SSL_ERROR_WANT_WRITE)) {
+ return 1;
+ }
+ return 2;
+}
diff --git a/src/make_ssl_handshake.h b/src/make_ssl_handshake.h
new file mode 100644
index 0000000..b326968
--- /dev/null
+++ b/src/make_ssl_handshake.h
@@ -0,0 +1,32 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "network.h"
+#include "ssl_fd_struct.h"
+
+#ifndef _JS_MAKE_SSL_HANDSHAKE_H
+#define _JS_MAKE_SSL_HANDSHAKE_H
+
+void make_ssl_initialize(SslFd* sf);
+int make_ssl_accept(SslFd* sf);
+int get_ssl_error(SslFd* sf, char* info, int result);
+
+#endif
+
diff --git a/src/module_struct.c b/src/module_struct.c
new file mode 100644
index 0000000..ab1d2f8
--- /dev/null
+++ b/src/module_struct.c
@@ -0,0 +1,224 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#ifdef HAVE_LIBDL
+
+#include "string_functions.h"
+#include "module_struct.h"
+
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <assert.h>
+
+/*
+ * Function name: Module_new
+ * Description: Create and initialize new Module structure.
+ * Returns: Pointer to newly created Module structure.
+ */
+
+Module*
+Module_new()
+{
+ Module* tmp = calloc(1, sizeof(Module));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ return tmp;
+}
+
+/*
+ * Function name: Module_free
+ * Description: Free the memory allocated for Module structure.
+ * Arguments: m - pointer to pointer to Module structure
+ */
+
+void
+Module_free(Module** m)
+{
+ assert(m != NULL);
+ if (m == NULL) {
+ return;
+ }
+ assert((*m) != NULL);
+ if ((*m) == NULL) {
+ return;
+ }
+ Module_releaseModule(*m);
+ if ((*m)->fileName) {
+ free((*m)->fileName);
+ (*m)->fileName = NULL;
+ }
+ free((*m));
+ (*m) = NULL;
+}
+
+/*
+ * Function name: Module_set_fileName
+ * Description: Set the filename of the module.
+ * Arguments: m - pointer to Module structure
+ * fileName - the filename of the module
+ */
+
+void
+Module_set_fileName(Module* m, char* fileName)
+{
+ assert(m != NULL);
+ if (m == NULL) {
+ return;
+ }
+ string_cp(&(m->fileName), fileName);
+}
+
+/*
+ * Function name: Module_get_fileName
+ * Description: Get the filename of the module.
+ * Arguments: m - pointer to Module structure
+ * Returns: The filename of the module.
+ */
+
+char*
+Module_get_fileName(Module* m)
+{
+ assert(m != NULL);
+ if (m == NULL) {
+ return NULL;
+ }
+ return m->fileName;
+}
+
+/*
+ * Function name: Module_loadModule
+ * Description: Load the module into the memory.
+ * Arguments: m - pointer to Module structure
+ * Returns: 0 - successful/filename not set
+ * 1/2 - some errors occured.
+ */
+
+int
+Module_loadModule(Module* m)
+{
+ if (Module_get_fileName(m)) {
+ m->handle = dlopen(Module_get_fileName(m), RTLD_NOW);
+ if (!m->handle) {
+ return 1;
+ }
+ dlerror();
+ *(void**) (&m->info) = dlsym(m->handle, "info");
+ *(void**) (&m->allow) = dlsym(m->handle, "allow");
+ *(void**) (&m->filter) = dlsym(m->handle, "filter");
+ if (dlerror() != NULL) {
+ return 2;
+ }
+ m->loaded = 1;
+ }
+ return 0;
+}
+
+/*
+ * Function name: Module_releaseModule
+ * Description: Unload the module from the memory.
+ * Arguments: m - pointer to Module structure
+ * Returns: 0 - successful/module was not loaded
+ * !0 - some errors occured.
+ */
+
+int
+Module_releaseModule(Module* m)
+{
+ if (Module_isModuleLoaded(m)) {
+ m->loaded = 0;
+ m->info = NULL;
+ m->allow = NULL;
+ m->filter = NULL;
+ return dlclose(m->handle);
+ }
+ return 0;
+}
+
+/*
+ * Function name: Module_isModuleLoaded
+ * Description: Check if the module is loaded into the memory.
+ * Arguments: m - pointer to Module structure
+ * Returns: 0 - module is not loaded
+ * 1 - module is loaded.
+ */
+
+int
+Module_isModuleLoaded(Module* m)
+{
+ assert(m != NULL);
+ if (m == NULL) {
+ return 0;
+ }
+ return m->loaded;
+}
+
+/*
+ * Function name: Module_function_info
+ * Description: Exec the info function of the module.
+ * Arguments: m - pointer to Module structure
+ * Returns: Result of the info function of the module.
+ */
+
+char*
+Module_function_info(Module* m)
+{
+ if (!Module_isModuleLoaded(m)) {
+ return NULL;
+ }
+ return m->info();
+}
+
+/*
+ * Function name: Module_function_allow
+ * Description: Exec the allow function of the module.
+ * Arguments: m - pointer to Module structure
+ * Returns: Result of the allow function of the module.
+ */
+
+int
+Module_function_allow(Module* m, char* host, char* port)
+{
+ if (!Module_isModuleLoaded(m)) {
+ return 0;
+ }
+ return m->allow(host, port);
+}
+
+/*
+ * Function name: Module_function_filter
+ * Description: Exec the filter function of the module.
+ * Arguments: m - pointer to Module structure
+ * Returns: Result of the filter function of the module.
+ */
+
+int
+Module_function_filter(Module* m, char* host, unsigned char* message, int* messageLength)
+{
+ if (!Module_isModuleLoaded(m)) {
+ return 0;
+ }
+ return m->filter(host, message, messageLength);
+}
+
+#endif
diff --git a/src/module_struct.h b/src/module_struct.h
new file mode 100644
index 0000000..cd8ef10
--- /dev/null
+++ b/src/module_struct.h
@@ -0,0 +1,55 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#ifdef HAVE_LIBDL
+
+# ifndef _JS_MODULE_STRUCT_H
+# define _JS_MODULE_STRUCT_H
+
+typedef struct {
+ char loaded;
+ char* fileName;
+ void* handle;
+ char* (*info)(void);
+ int (*allow)(char*, char*);
+ int (*filter)(char*, unsigned char*, int*);
+} Module;
+
+/* 'constructor' */
+Module* Module_new();
+/* 'destructor' */
+void Module_free(Module** m);
+/* setters */
+void Module_set_fileName(Module* m, char* fileName);
+/* getters */
+char* Module_get_fileName(Module* m);
+/* other */
+int Module_loadModule(Module* m);
+int Module_releaseModule(Module* m);
+int Module_isModuleLoaded(Module* m);
+char* Module_function_info(Module* m);
+int Module_function_allow(Module* m, char* host, char* port);
+int Module_function_filter(Module* m, char* host, unsigned char* message, int* messageLength);
+
+# endif
+
+#endif
diff --git a/src/network.c b/src/network.c
new file mode 100644
index 0000000..4d2e051
--- /dev/null
+++ b/src/network.c
@@ -0,0 +1,561 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "inet_ntop.h"
+#include "network.h"
+#include "activefor.h"
+#include "stats.h"
+#include "logging.h"
+#include <string.h>
+#include <errno.h>
+#include <zlib.h>
+#include <assert.h>
+
+/*
+ * Function name: ip_listen
+ * Description: Creates the listening socket.
+ * Arguments: sockfd - the created socket
+ * host - the name of the host
+ * serv - the name of the service (port)
+ * addrlenp - pointer to the length of the sockaddr structure
+ * type - the type of the socket
+ * Returns: 0 - success,
+ * !0 - failure.
+ */
+
+int
+ip_listen(int* sockfd, const char *host, const char *serv, socklen_t *addrlenp, const char type)
+{
+ const int on = 1;
+#if defined(HAVE_GETADDRINFO) && defined(AF_INET6)
+ int n;
+ struct addrinfo hints, *res, *ressave;
+
+ aflog(LOG_T_INIT, LOG_I_DDEBUG,
+ "ip_listen: host=[%s] serv=[%s], type=[%d]", host, serv, type);
+
+ bzero(&hints, sizeof(struct addrinfo));
+ hints.ai_flags = AI_PASSIVE;
+ if (type & 0x02) {
+ hints.ai_family = AF_INET;
+ }
+ else if (type & 0x04) {
+ hints.ai_family = AF_INET6;
+ }
+ else {
+ hints.ai_family = AF_UNSPEC;
+ }
+
+ if (type & 0x01) {
+ hints.ai_socktype = SOCK_STREAM;
+ }
+ else {
+ hints.ai_socktype = SOCK_DGRAM;
+ }
+
+ if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0) {
+ return n;
+ }
+ ressave = res;
+
+ do {
+ (*sockfd) = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if ((*sockfd) < 0) {
+ continue; /* error, try next one */
+ }
+
+ if (type & 0x01) { /* tcp_listen */
+ setsockopt((*sockfd), SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+ setsockopt((*sockfd), SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
+ }
+
+ if (bind((*sockfd), res->ai_addr, res->ai_addrlen) == 0) {
+ break; /* success */
+ }
+
+ close((*sockfd)); /* bind error, close and try next one */
+ } while ( (res = res->ai_next) != NULL);
+
+ if (res == NULL) { /* errno from final socket() or bind() */
+ return 1;
+ }
+
+ if (type & 0x01) { /* tcp_listen */
+ listen((*sockfd), 1);
+ }
+
+ if (addrlenp) {
+ *addrlenp = res->ai_addrlen; /* return size of protocol address */
+ }
+
+ freeaddrinfo(ressave);
+#else
+ struct sockaddr_in servaddr;
+ struct hostent* hostaddr = NULL;
+ int port;
+
+ aflog(LOG_T_INIT, LOG_I_DDEBUG,
+ "ip_listen: host=[%s] serv=[%s], type=[%d]", host, serv, type);
+
+ if (type & 0x01) {
+ (*sockfd) = socket(AF_INET, SOCK_STREAM, 0);
+ }
+ else {
+ (*sockfd) = socket(AF_INET, SOCK_DGRAM, 0);
+ }
+
+ if ((*sockfd) == -1) {
+ return 1;
+ }
+ port = atoi(serv);
+
+ if (host) {
+ hostaddr = gethostbyname(host);
+ if (hostaddr == NULL) {
+ return 2;
+ }
+ }
+
+ memset(&servaddr, 0, sizeof(servaddr));
+ servaddr.sin_family = AF_INET;
+ if (host) {
+ memcpy(&servaddr.sin_addr.s_addr, hostaddr->h_addr_list[0], hostaddr->h_length);
+ }
+ else {
+ servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ }
+ servaddr.sin_port = htons(port);
+
+ if (type & 0x01) { /* tcp_listen */
+ setsockopt((*sockfd), SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+ setsockopt((*sockfd), SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
+ }
+
+ if (bind((*sockfd), (struct sockaddr*) &servaddr, sizeof(servaddr))){
+ printf("bind failed\n");
+ return 4;
+ }
+
+ if (type & 0x01) { /* tcp_listen */
+ if (listen((*sockfd), 5)){
+ return 5;
+ }
+ }
+
+ if (addrlenp) {
+ *addrlenp = sizeof(servaddr); /* return size of protocol address */
+ }
+#endif
+
+ return(0);
+}
+
+/*
+ * Function name: ip_connect
+ * Description: Creates the connected socket.
+ * Arguments: sockfd - the connected socket
+ * host - the name of the host
+ * serv - the name of the service (port)
+ * type - the type of the socket
+ * lhost - the name of the local host (used for local bind of the socket)
+ * lserv - the name of the local service (port) (used for local bind of the socket)
+ * Returns: 0 - success,
+ * !0 - failure.
+ */
+
+int
+ip_connect(int* sockfd, const char *host, const char *serv, const char type,
+ const char *lhost, const char *lserv)
+{
+ const int on = 1;
+#if defined(HAVE_GETADDRINFO) && defined(AF_INET6)
+ int n;
+ int bindFailed;
+ struct addrinfo hints, *res, *ressave;
+ struct addrinfo lhints, *lres, *lressave = NULL;
+
+ aflog(LOG_T_INIT, LOG_I_DDEBUG,
+ "ip_connect: host=[%s] serv=[%s], type=[%d], lhost=[%s], lserv=[%s]", host, serv, type, lhost, lserv);
+
+ bzero(&hints, sizeof(struct addrinfo));
+ if (type & 0x02) {
+ hints.ai_family = AF_INET;
+ }
+ else if (type & 0x04) {
+ hints.ai_family = AF_INET6;
+ }
+ else {
+ hints.ai_family = AF_UNSPEC;
+ }
+ if (type & 0x01) {
+ hints.ai_socktype = SOCK_STREAM;
+ }
+ else {
+ hints.ai_socktype = SOCK_DGRAM;
+ }
+
+ lhints = hints;
+
+ if (lhost || lserv) {
+ if ( (n = getaddrinfo(lhost, lserv, &lhints, &lres)) != 0) {
+ return n;
+ }
+ lressave = lres;
+ }
+
+ if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0) {
+ return n;
+ }
+ ressave = res;
+
+ do {
+ (*sockfd) = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if ((*sockfd) < 0) {
+ continue; /* ignore this one */
+ }
+
+ if (type & 0x01) { /* tcp_connect */
+ setsockopt((*sockfd), SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
+ }
+
+ bindFailed = 0;
+ if (lhost || lserv) {
+ bindFailed = 1;
+ lres = lressave;
+ do {
+ if (bind((*sockfd), lres->ai_addr, lres->ai_addrlen) == 0) {
+ bindFailed = 0;
+ break; /* success */
+ }
+ } while ( (lres = lres->ai_next) != NULL);
+ }
+
+ if (bindFailed == 1) {
+ close((*sockfd)); /* ignore this one */
+ continue;
+ }
+
+ if (connect((*sockfd), res->ai_addr, res->ai_addrlen) == 0) {
+ break; /* success */
+ }
+
+ close((*sockfd)); /* ignore this one */
+ } while ( (res = res->ai_next) != NULL);
+
+ if (res == NULL) { /* errno set from final connect() */
+ return 1;
+ }
+
+ if (lhost || lserv) {
+ freeaddrinfo(lressave);
+ }
+ freeaddrinfo(ressave);
+#else
+ struct sockaddr_in servaddr, lservaddr;
+ struct hostent* hostaddr;
+ struct hostent* lhostaddr;
+ int port, lport;
+
+ aflog(LOG_T_INIT, LOG_I_DDEBUG,
+ "ip_connect: host=[%s] serv=[%s], type=[%d], lhost=[%s], lserv=[%s]", host, serv, type, lhost, lserv);
+
+ if (type & 0x01) {
+ (*sockfd) = socket(AF_INET, SOCK_STREAM, 0);
+ }
+ else {
+ (*sockfd) = socket(AF_INET, SOCK_DGRAM, 0);
+ }
+
+ if ((*sockfd) == -1) {
+ return 1;
+ }
+ port = atoi(serv);
+
+ hostaddr = gethostbyname(host);
+ if (hostaddr == NULL) {
+ return 2;
+ }
+
+ memset(&servaddr, 0, sizeof(servaddr));
+ servaddr.sin_family = AF_INET;
+ servaddr.sin_port = htons(port);
+ memcpy(&servaddr.sin_addr.s_addr, hostaddr->h_addr_list[0], hostaddr->h_length);
+
+ if (type & 0x01) { /* tcp_connect */
+ setsockopt((*sockfd), SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
+ }
+
+ if (lhost || lserv) {
+ memset(&lservaddr, 0, sizeof(lservaddr));
+ lservaddr.sin_family = AF_INET;
+ if (lserv) {
+ lport = atoi(lserv);
+ lservaddr.sin_port = htons(lport);
+ }
+ if (lhost) {
+ lhostaddr = gethostbyname(lhost);
+ if (lhostaddr == NULL) {
+ return 3;
+ }
+ memcpy(&lservaddr.sin_addr.s_addr, lhostaddr->h_addr_list[0], lhostaddr->h_length);
+ }
+ else {
+ lservaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ }
+ if (bind((*sockfd), (struct sockaddr*) &lservaddr, sizeof(lservaddr))){
+ return 4;
+ }
+ }
+
+ if (connect((*sockfd), (struct sockaddr*) &servaddr, sizeof(servaddr))){
+ return 5;
+ }
+#endif
+
+ return(0);
+}
+
+/*
+ * Function name: sock_ntop
+ * Description: Returns the string representing given socket address.
+ * Arguments: sa - pointer to sockaddr structure
+ * salen - size of the sockaddr structure
+ * namebuf - buffer for string representation of the host name
+ * portbuf - buffer for string representation of the host port
+ * type - if the socket address should be resolved to the the DNS name
+ * Returns: The string representing given socket address or NULL, if the address
+ * can't be established.
+ */
+
+char *
+sock_ntop(const struct sockaddr *sa, socklen_t salen, char* namebuf, char* portbuf, char type)
+{
+ char portstr[7];
+ static char str[136]; /* Unix domain is largest */
+
+ switch (sa->sa_family) {
+ case AF_INET: {
+ struct sockaddr_in *sin = (struct sockaddr_in *) sa;
+
+ if (type) {
+#ifdef HAVE_GETNAMEINFO
+ if (getnameinfo(sa, salen, str, 128, NULL, 0, 0)) {
+ return NULL;
+ }
+#else
+ struct hostent* hostname;
+ if ((hostname = gethostbyaddr((void*) &sin->sin_addr, sizeof(struct in_addr), AF_INET))) {
+ strncpy(str, hostname->h_name, 127);
+ str[127] = 0;
+ }
+ else {
+ if (inet_ntop(AF_INET, (void*) &sin->sin_addr, str, sizeof(str)) == NULL) {
+ return NULL;
+ }
+ }
+#endif
+
+ }
+ else {
+ if (inet_ntop(AF_INET, (void*) &sin->sin_addr, str, sizeof(str)) == NULL) {
+ return NULL;
+ }
+ }
+ if (namebuf) {
+ memcpy(namebuf, str, 128);
+ }
+ if (ntohs(sin->sin_port) != 0) {
+ snprintf(portstr, sizeof(portstr), ".%d", ntohs(sin->sin_port));
+ if (portbuf) {
+ snprintf(portbuf, 7, "%d", ntohs(sin->sin_port));
+ }
+ strcat(str, portstr);
+ }
+ return(str);
+ }
+#ifdef AF_INET6
+ case AF_INET6: {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
+
+ if (type) {
+#ifdef HAVE_GETNAMEINFO
+ if (getnameinfo(sa, salen, str, 128, NULL, 0, 0)) {
+ return NULL;
+ }
+#else
+ struct hostent* hostname;
+ if ((hostname = gethostbyaddr(&sin6->sin6_addr, sizeof(struct in6_addr), AF_INET6))) {
+ strncpy(str, hostname->h_name, 127);
+ str[127] = 0;
+ }
+ else {
+ if (inet_ntop(AF_INET6, &sin6->sin6_addr, str, sizeof(str)) == NULL) {
+ return NULL;
+ }
+ }
+#endif
+
+ }
+ else {
+ if (inet_ntop(AF_INET6, &sin6->sin6_addr, str, sizeof(str)) == NULL) {
+ return NULL;
+ }
+ }
+ if (namebuf) {
+ memcpy(namebuf, str, 128);
+ }
+ if (ntohs(sin6->sin6_port) != 0) {
+ snprintf(portstr, sizeof(portstr), ".%d", ntohs(sin6->sin6_port));
+ if (portbuf) {
+ snprintf(portbuf, 7, "%d", ntohs(sin6->sin6_port));
+ }
+ strcat(str, portstr);
+ }
+ return(str);
+ }
+#endif
+ default: {
+ snprintf(str, sizeof(str), "sock_ntop: unknown AF_xxx: %d, len %d", sa->sa_family, salen);
+ return(str);
+ }
+ }
+ return NULL;
+}
+
+/*
+ * Function name: SSL_writen
+ * Description: Writes the given amount of data to the SSL connection.
+ * Arguments: fd - the SSL connection
+ * buf - buffer with data to write
+ * amount - the size of the data
+ * Returns: The amount of bytes written to the SSL connection.
+ */
+
+int
+SSL_writen(SSL* fd, unsigned char* buf, int amount)
+{
+ int sent, n;
+ sent = 0;
+ assert(amount > 0);
+ while (sent < amount) {
+ n = SSL_write(fd, buf+sent, amount - sent);
+ assert(n != 0);
+ if (n != -1) {
+ sent += n;
+ }
+ if (n == -1) {
+ if (errno != EAGAIN)
+ return 0;
+ }
+ }
+ return amount;
+}
+
+/*
+ * Function name: SSL_readn
+ * Description: Reads the given amount of data from the SSL connection.
+ * Arguments: fd - the SSL connection
+ * buf - buffer for data
+ * amount - the size of the data to read
+ * Returns: The amount of bytes read from the SSL connection.
+ */
+
+int
+SSL_readn(SSL* fd, unsigned char* buf, int amount)
+{
+ int sent, n;
+ sent = 0;
+ assert(amount > 0);
+ while (sent < amount) {
+ n = SSL_read(fd, buf+sent, amount - sent);
+ if (n != -1) {
+ sent += n;
+ }
+ if (n == 0)
+ return 0;
+ if (n == -1) {
+ if (errno != EAGAIN)
+ return 0;
+ }
+ }
+ return amount;
+}
+
+/*
+ * Function name: writen
+ * Description: Writes the given amount of data to the file descriptor.
+ * Arguments: fd - the file descriptor
+ * buf - buffer with data to write
+ * amount - the size of the data
+ * Returns: The amount of bytes written to the file descriptor
+ */
+
+int
+writen(int fd, unsigned char* buf, int amount)
+{
+ int sent, n;
+ sent = 0;
+ assert(amount > 0);
+ while (sent < amount) {
+ n = write(fd, buf+sent, amount - sent);
+ assert(n != 0);
+ if (n != -1) {
+ sent += n;
+ }
+ if (n == -1) {
+ if (errno != EAGAIN)
+ return 0;
+ }
+ }
+ return amount;
+}
+
+/*
+ * Function name: readn
+ * Description: Reads the given amount of data from the file descriptor.
+ * Arguments: fd - the file descriptor
+ * buf - buffer for data
+ * amount - the size of the data to read
+ * Returns: The amount of bytes read from the file descriptor.
+ */
+
+int
+readn(int fd, unsigned char* buf, int amount)
+{
+ int sent, n;
+ sent = 0;
+ assert(amount > 0);
+ while (sent < amount) {
+ n = read(fd, buf+sent, amount - sent);
+ if (n != -1) {
+ sent += n;
+ }
+ if (n == 0)
+ return 0;
+ if (n == -1) {
+ if (errno != EAGAIN)
+ return 0;
+ }
+ }
+ return amount;
+
+}
diff --git a/src/network.h b/src/network.h
new file mode 100644
index 0000000..b8c0273
--- /dev/null
+++ b/src/network.h
@@ -0,0 +1,49 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_NETWORK_H
+#define _JS_NETWORK_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#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>
+
+int ip_listen(int* sockfd, const char *host, const char *serv, socklen_t *addrlenp, const char type); /* socket, bind, listen... */
+int ip_connect(int* sockfd, const char *host, const char *serv, const char type,
+ const char *lhost, const char *lserv); /* socket[, bind], connect... */
+char* sock_ntop(const struct sockaddr* sa, socklen_t salen, char* namebuf, char* portbuf, char type); /* return the IP of connected user */
+
+int SSL_writen(SSL* fd, unsigned char* buf, int amount);
+int SSL_readn(SSL* fd, unsigned char* buf, int amount);
+int writen(int fd, unsigned char* buf, int amount);
+int readn(int fd, unsigned char* buf, int amount);
+
+#endif
diff --git a/src/port_list_node_struct.c b/src/port_list_node_struct.c
new file mode 100644
index 0000000..cc171a4
--- /dev/null
+++ b/src/port_list_node_struct.c
@@ -0,0 +1,140 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "port_list_node_struct.h"
+#include "string_functions.h"
+
+/*
+ * Function name: PortListNode_new
+ * Description: Creates and initializes new PortListNode structure from the
+ * given port name.
+ * Arguments: portName - the port name
+ * Returns: Newly created PortListNode structure.
+ */
+
+PortListNode*
+PortListNode_new(char* portName)
+{
+ PortListNode* tmp = calloc(1, sizeof(PortListNode));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ PortListNode_set_portName(tmp, portName);
+ return tmp;
+}
+
+/*
+ * Function name: PortListNode_free
+ * Description: Frees the memory allocated for PortListNode structure.
+ * Arguments: pln - pointer to pointer to PortListNode structure
+ */
+
+void
+PortListNode_free(PortListNode** pln)
+{
+ assert(pln != NULL);
+ if (pln == NULL) {
+ return;
+ }
+ assert((*pln) != NULL);
+ if ((*pln) == NULL) {
+ return;
+ }
+ if ((*pln)->portName) {
+ free((*pln)->portName);
+ (*pln)->portName = NULL;
+ }
+ free((*pln));
+ (*pln) = NULL;
+}
+
+/*
+ * Function name: PortListNode_set_portName
+ * Description: Sets the port name.
+ * Arguments: pln - pointer to PortListNode structure
+ * portName - the port name
+ */
+
+void
+PortListNode_set_portName(PortListNode* pln, char* portName)
+{
+ assert(pln != NULL);
+ if (pln == NULL) {
+ return;
+ }
+ string_cp(&(pln->portName), portName);
+}
+
+/*
+ * Function name: PortListNode_set_nextNode
+ * Description: Sets next node pointer.
+ * Arguments: pln - pointer to PortListNode structure
+ * nextNode - next node pointer
+ */
+
+void
+PortListNode_set_nextNode(PortListNode* pln, PortListNode* nextNode)
+{
+ assert(pln != NULL);
+ if (pln == NULL) {
+ return;
+ }
+ pln->nextNode = nextNode;
+}
+
+/*
+ * Function name: PortListNode_get_portName
+ * Description: Gets the port name.
+ * Arguments: pln - pointer to PortListNode structure
+ * Returns: The port name.
+ */
+
+char*
+PortListNode_get_portName(PortListNode* pln)
+{
+ assert(pln != NULL);
+ if (pln == NULL) {
+ return NULL;
+ }
+ return pln->portName;
+}
+
+/*
+ * Function name: PortListNode_get_nextNode
+ * Description: Gets next node pointer.
+ * Arguments: pln - pointer to PortListNode structure
+ * Returns: Next PortListNode structure pointer or NULL, if there is no next one.
+ */
+
+PortListNode*
+PortListNode_get_nextNode(PortListNode* pln)
+{
+ assert(pln != NULL);
+ if (pln == NULL) {
+ return NULL;
+ }
+ return pln->nextNode;
+}
diff --git a/src/port_list_node_struct.h b/src/port_list_node_struct.h
new file mode 100644
index 0000000..f4b1de6
--- /dev/null
+++ b/src/port_list_node_struct.h
@@ -0,0 +1,40 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_PORT_LIST_NODE_STRUCT_H
+#define _JS_PORT_LIST_NODE_STRUCT_H
+
+typedef struct plnode {
+ char* portName;
+ struct plnode* nextNode;
+} PortListNode;
+
+/* 'constructor' */
+PortListNode* PortListNode_new(char* portName);
+/* 'destructor' */
+void PortListNode_free(PortListNode** pln);
+/* setters */
+void PortListNode_set_portName(PortListNode* pln, char* portName);
+void PortListNode_set_nextNode(PortListNode* pln, PortListNode* nextNode);
+/* getters */
+char* PortListNode_get_portName(PortListNode* pln);
+PortListNode* PortListNode_get_nextNode(PortListNode* pln);
+
+#endif
diff --git a/src/port_list_struct.c b/src/port_list_struct.c
new file mode 100644
index 0000000..f464044
--- /dev/null
+++ b/src/port_list_struct.c
@@ -0,0 +1,167 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "port_list_struct.h"
+
+/*
+ * Function name: PortList_new
+ * Description: Creates and initialies new PortList structure.
+ * Returns: Newly created PortList structure.
+ */
+
+PortList*
+PortList_new()
+{
+ PortList* tmp = calloc(1, sizeof(PortList));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ return tmp;
+}
+
+/*
+ * Function name: PortList_free
+ * Description: Frees the memory allocated for PortList structure.
+ * Arguments: pl - pointer to pointer to PortList structure
+ */
+
+void
+PortList_free(PortList** pl)
+{
+ assert(pl != NULL);
+ if (pl == NULL) {
+ return;
+ }
+ assert((*pl) != NULL);
+ if ((*pl) == NULL) {
+ return;
+ }
+ PortList_clear((*pl));
+ free((*pl));
+ (*pl) = NULL;
+}
+
+/*
+ * Function name: PortList_insert_back
+ * Description: Inserts new node at the end of the list.
+ * Arguments: pl - pointer to PortList structure
+ * pln - pointer to PortListNode structure
+ */
+
+void
+PortList_insert_back(PortList* pl, PortListNode* pln)
+{
+ assert(pl != NULL);
+ if (pl == NULL) {
+ return;
+ }
+ assert(pln != NULL);
+ if (pln == NULL) {
+ return;
+ }
+ if (pl->tail) {
+ pl->tail->nextNode = pln;
+ }
+ else {
+ pl->head = pln;
+ }
+ pl->tail = pln;
+ pln->nextNode = NULL;
+ pl->size += 1;
+}
+
+/*
+ * Function name: PortList_get_nth
+ * Description: Get the nth node from the beginning of the list.
+ * Arguments: pl - pointer to PortList structure
+ * n - the number of the node
+ * Returns: Nth node from the beginning of the list.
+ */
+
+PortListNode*
+PortList_get_nth(PortList* pl, int n)
+{
+ PortListNode* tmp;
+ assert(pl != NULL);
+ if (pl == NULL) {
+ return NULL;
+ }
+ assert(n >= 0);
+ assert(n < PortList_get_size(pl));
+ tmp = pl->head;
+ while (tmp) {
+ if (n <= 0) {
+ return tmp;
+ }
+ n -= 1;
+ tmp = PortListNode_get_nextNode(tmp);
+ }
+ return NULL;
+}
+
+/*
+ * Function name: PortList_get_size
+ * Description: Returns the size of the list.
+ * Arguments: pl - pointer to PortList structure
+ * Returns: The size of the list.
+ */
+
+int
+PortList_get_size(PortList* pl)
+{
+ assert(pl != NULL);
+ if (pl == NULL) {
+ return -1;
+ }
+ return pl->size;
+}
+
+/*
+ * Function name: PortList_clear
+ * Description: Deletes all nodes from the list.
+ * Arguments: pl - pointer to PortList structure
+ */
+
+void
+PortList_clear(PortList* pl)
+{
+ PortListNode* tmp;
+ assert(pl != NULL);
+ if (pl == NULL) {
+ return;
+ }
+ while (pl->head) {
+ tmp = pl->head;
+ if (tmp == pl->tail) {
+ pl->head = pl->tail = NULL;
+ }
+ else {
+ pl->head = PortListNode_get_nextNode(pl->head);
+ }
+ PortListNode_free(&tmp);
+ }
+ pl->size = 0;
+}
diff --git a/src/port_list_struct.h b/src/port_list_struct.h
new file mode 100644
index 0000000..175f06b
--- /dev/null
+++ b/src/port_list_struct.h
@@ -0,0 +1,42 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_PORT_LIST_STRUCT_H
+#define _JS_PORT_LIST_STRUCT_H
+
+#include "port_list_node_struct.h"
+
+typedef struct portlist {
+ int size;
+ PortListNode* head;
+ PortListNode* tail;
+} PortList;
+
+/* 'constructor' */
+PortList* PortList_new();
+/* 'destructor' */
+void PortList_free(PortList** pl);
+/* other */
+void PortList_insert_back(PortList* pl, PortListNode* pln);
+PortListNode* PortList_get_nth(PortList* pl, int n);
+int PortList_get_size(PortList* pl);
+void PortList_clear(PortList* pl);
+
+#endif
diff --git a/src/realmnames.c b/src/realmnames.c
new file mode 100644
index 0000000..db9cfdf
--- /dev/null
+++ b/src/realmnames.c
@@ -0,0 +1,86 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "realmnames.h"
+
+/*
+ * Function name: get_realmname
+ * Description: Returns the name of the realm.
+ * Arguments: config - the server configuration
+ * realm - the realm number
+ * Returns: The name of the realm.
+ */
+
+char*
+get_realmname(ServerConfiguration* config, int realm)
+{
+ static char realmname[10];
+
+ assert(config != NULL);
+
+ if (ServerRealm_get_realmName(ServerConfiguration_get_realmsTable(config)[realm]) == NULL) {
+ memset(realmname, 0, 10);
+ sprintf(realmname, "%d", realm);
+ return realmname;
+ }
+
+ return ServerRealm_get_realmName(ServerConfiguration_get_realmsTable(config)[realm]);
+}
+
+/*
+ * Function name: get_realmnumber
+ * Description: Returns the realm number.
+ * Arguments: config - the server configuration
+ * realmname - the name of the realm
+ * Returns: The realm number or -1, if there is no realm with such name.
+ */
+
+int
+get_realmnumber(ServerConfiguration* config, char* realmname)
+{
+ int i;
+ char guard;
+
+ assert(config != NULL);
+ assert(realmname != NULL);
+
+ for (i = 0; i < ServerConfiguration_get_realmsNumber(config); ++i) {
+ if (ServerRealm_get_realmName(ServerConfiguration_get_realmsTable(config)[i]) != NULL) {
+ if (strcmp(realmname, ServerRealm_get_realmName(ServerConfiguration_get_realmsTable(config)[i])) == 0) {
+ return i;
+ }
+ }
+ }
+
+ if (sscanf(realmname, "%d%c", &i, &guard) == 1) {
+ if ((i >= 0) && (i < ServerConfiguration_get_realmsNumber(config))) {
+ if (ServerRealm_get_realmName(ServerConfiguration_get_realmsTable(config)[i]) == NULL) {
+ return i;
+ }
+ }
+ }
+
+ return -1;
+}
diff --git a/src/realmnames.h b/src/realmnames.h
new file mode 100644
index 0000000..8974488
--- /dev/null
+++ b/src/realmnames.h
@@ -0,0 +1,31 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "activefor.h"
+#include "server_configuration_struct.h"
+
+#ifndef _JS_REALMNAMES_H
+#define _JS_REALMNAMES_H
+
+char* get_realmname(ServerConfiguration*, int);
+int get_realmnumber(ServerConfiguration*, char*);
+
+#endif
+
diff --git a/src/remoteadmin_codes.h b/src/remoteadmin_codes.h
new file mode 100644
index 0000000..65038eb
--- /dev/null
+++ b/src/remoteadmin_codes.h
@@ -0,0 +1,32 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_REMOTEADMIN_CODES_H
+#define _JS_REMOTEADMIN_CODES_H
+
+#define AF_RA_UNDEFINED 0
+#define AF_RA_CMD 1
+#define AF_RA_REPEAT 2
+#define AF_RA_STATUS_OK 3
+#define AF_RA_NOT_KNOWN 4
+#define AF_RA_FAILED 5
+#define AF_RA_KICKED 6
+
+#endif
diff --git a/src/remove_client_task.c b/src/remove_client_task.c
new file mode 100644
index 0000000..a223c43
--- /dev/null
+++ b/src/remove_client_task.c
@@ -0,0 +1,134 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "logging.h"
+#include "realmnames.h"
+#include "clientnames.h"
+#include "server_remove.h"
+#include "remove_client_task.h"
+
+/*
+ * Function name: RCTdata_new
+ * Description: Creates and initializes new data for remove client task.
+ * Arguments: config - server configuration
+ * realm - the realm id
+ * client - the client id
+ * ra - if the client is in remote administration mode
+ * fdset - the descriptor set watched for read
+ * Returns: Pointer to newly created RCTdata structure.
+ */
+
+RCTdata*
+RCTdata_new(ServerConfiguration* config, int realm, int client, char ra, char reason, fd_set* set, fd_set* wset)
+{
+ RCTdata* tmp;
+ assert(config != NULL);
+ if (config == NULL) {
+ return NULL;
+ }
+ tmp = calloc(1, sizeof(RCTdata));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ tmp->config = config;
+ tmp->realm = realm;
+ tmp->client = client;
+ tmp->ra = ra;
+ tmp->reason = reason;
+ tmp->set = set;
+ tmp->wset = wset;
+
+ return tmp;
+}
+
+/*
+ * Function name: RCTdata_free
+ * Description: Frees the memory allocated for RCTdata structure.
+ * Arguments: ptr - pointer to pointer to RCTdata structure
+ */
+
+void
+RCTdata_free(void** ptr)
+{
+ RCTdata** data = (RCTdata**) ptr;
+ assert(data != NULL);
+ if (data == NULL) {
+ return;
+ }
+ assert((*data) != NULL);
+ if ((*data) == NULL) {
+ return;
+ }
+ free((*data));
+ (*data) = NULL;
+}
+
+/*
+ * Function name: RCTfunction
+ * Description: Function executed in the task by the task scheduler.
+ * Arguments: Pointer to the memory containing RCTdata structure.
+ */
+
+void
+RCTfunction(void* data)
+{
+ ConnectClient** clientsTable;
+ ServerRealm** realmsTable;
+ RCTdata* ptr;
+ assert(data != NULL);
+ if (data == NULL) {
+ return;
+ }
+ ptr = (RCTdata*) data;
+ realmsTable = ServerConfiguration_get_realmsTable(ptr->config);
+ if (ptr->ra) {
+ clientsTable = ServerRealm_get_raClientsTable(realmsTable[ptr->realm]);
+ }
+ else {
+ clientsTable = ServerRealm_get_clientsTable(realmsTable[ptr->realm]);
+ }
+ switch (ptr->reason) {
+ case RCT_REASON_TIMEOUT:
+ close(SslFd_get_fd(ConnectClient_get_sslFd(clientsTable[ptr->client])));
+ FD_CLR(SslFd_get_fd(ConnectClient_get_sslFd(clientsTable[ptr->client])), ptr->set);
+ SSL_clear(SslFd_get_ssl(ConnectClient_get_sslFd(clientsTable[ptr->client])));
+ ConnectClient_set_state(clientsTable[ptr->client], CONNECTCLIENT_STATE_FREE);
+ ServerRealm_decrease_connectedClients(realmsTable[ptr->realm]);
+ aflog(LOG_T_CLIENT, LOG_I_WARNING,
+ "realm[%s]: Client[%s]%s: SSL_accept failed (timeout)",
+ get_realmname(ptr->config, ptr->realm),
+ ptr->ra ? get_raclientname(realmsTable[ptr->realm], ptr->client) :
+ get_clientname(realmsTable[ptr->realm], ptr->client),
+ ptr->ra ? " (ra)" : "");
+ break;
+ case RCT_REASON_MAXIDLE:
+ aflog(LOG_T_CLIENT, LOG_I_WARNING,
+ "realm[%s]: Client[%s]: too long idle --> DROPPING", get_realmname(ptr->config, ptr->realm),
+ get_clientname(realmsTable[ptr->realm], ptr->client));
+ remove_client(realmsTable[ptr->realm], ptr->client, ptr->set, ptr->wset, NULL);
+ }
+ ConnectClient_set_task(clientsTable[ptr->client], NULL);
+}
diff --git a/src/remove_client_task.h b/src/remove_client_task.h
new file mode 100644
index 0000000..f229d2d
--- /dev/null
+++ b/src/remove_client_task.h
@@ -0,0 +1,47 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_REMOVE_CLIENT_TASK_H
+#define _JS_REMOVE_CLIENT_TASK_H
+
+#define RCT_REASON_TIMEOUT 0
+#define RCT_REASON_MAXIDLE 1
+
+#include "server_configuration_struct.h"
+
+typedef struct {
+ ServerConfiguration* config;
+ int realm;
+ int client;
+ char ra;
+ char reason;
+ fd_set* set;
+ fd_set* wset;
+} RCTdata;
+
+/* 'constructor' */
+RCTdata* RCTdata_new(ServerConfiguration* config, int realm, int client, char ra, char reason,
+ fd_set* set, fd_set* wset);
+/* 'destructor' */
+void RCTdata_free(void** data);
+/* other */
+void RCTfunction(void*);
+
+#endif
diff --git a/src/server_check.c b/src/server_check.c
new file mode 100644
index 0000000..4c20be1
--- /dev/null
+++ b/src/server_check.c
@@ -0,0 +1,112 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <assert.h>
+
+#include "server_check.h"
+#include "stats.h"
+#include "logging.h"
+
+/*
+ * Function name: check_value
+ * Description: Checks if the string is a valid positive int number.
+ * Arguments: what - the string representing number
+ * info - the information string printed on failure
+ * Returns: The decoded int number.
+ */
+
+int
+check_value(char* what, char* info)
+{
+ long tmp;
+
+ assert(what != NULL);
+ assert(info != NULL);
+
+ tmp = check_value_liberal(what, info);
+
+ if (tmp <= 0) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "%s: %d\n", info, tmp);
+ exit(1);
+ }
+ return tmp;
+}
+
+/*
+ * Function name: check_value_liberal
+ * Description: Checks if the string is a valid int number.
+ * Arguments: what - the string representing number
+ * info - the information string printed on failure
+ * Returns: The decoded int number.
+ */
+
+int
+check_value_liberal(char* what, char* info)
+{
+ char* znak;
+ long tmp;
+
+ assert(what != NULL);
+ assert(info != NULL);
+
+ if ((tmp = strtol(what, &znak, 10)) >= INT_MAX) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "%s: %s\n", info, what);
+ exit(1);
+ }
+ if (((*what) == '\0') || (*znak != '\0')) {
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "%s: %s\n", info, what);
+ exit(1);
+ }
+ return tmp;
+}
+
+/*
+ * Function name: check_long
+ * Description: Checks if the string is a valid long number.
+ * Arguments: text - the string representing number
+ * number - the pointer where decoded number will be stored
+ * Returns: 0 - success,
+ * 1 - value from outside the long number range,
+ * 2 - not the valid long number.
+ */
+
+int
+check_long(char* text, long* number)
+{
+ char* tmp;
+ if (((*number = strtol(text, &tmp, 10)) == LONG_MAX) || (*number == LONG_MIN)) {
+ return 1;
+ }
+ if ((*text != '\0') && (*tmp == '\0')) {
+ return 0;
+ }
+ else {
+ return 2;
+ }
+}
+
diff --git a/src/server_check.h b/src/server_check.h
new file mode 100644
index 0000000..fd4f03b
--- /dev/null
+++ b/src/server_check.h
@@ -0,0 +1,29 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_SERVER_CHECK_H
+#define _JS_SERVER_CHECK_H
+
+int check_value(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_configuration_struct.c b/src/server_configuration_struct.c
new file mode 100644
index 0000000..7f88275
--- /dev/null
+++ b/src/server_configuration_struct.c
@@ -0,0 +1,421 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "string_functions.h"
+#include "server_configuration_struct.h"
+
+/*
+ * Function name: ServerConfiguration_new
+ * Description: Create and initialize new ServerConfiguration structure.
+ * Returns: Pointer to newly created ServerConfiguration structure.
+ */
+
+ServerConfiguration*
+ServerConfiguration_new()
+{
+ ServerConfiguration* tmp = calloc(1, sizeof(ServerConfiguration));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ return tmp;
+}
+
+/*
+ * Function name: ServerConfiguration_free
+ * Description: Free the memory allocated for ServerConfiguration structure.
+ * Arguments: sc - pointer to pointer to ServerConfiguration structure
+ */
+
+void
+ServerConfiguration_free(ServerConfiguration** sc)
+{
+ int i;
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return;
+ }
+ assert((*sc) != NULL);
+ if ((*sc) == NULL) {
+ return;
+ }
+ if ((*sc)->certificateFile) {
+ free((*sc)->certificateFile);
+ (*sc)->certificateFile = NULL;
+ }
+ if ((*sc)->cacertificateFile) {
+ free((*sc)->cacertificateFile);
+ (*sc)->cacertificateFile = NULL;
+ }
+ if ((*sc)->cacertificatePath) {
+ free((*sc)->cacertificatePath);
+ (*sc)->cacertificatePath = NULL;
+ }
+ if ((*sc)->sCertificateDepth) {
+ free((*sc)->sCertificateDepth);
+ (*sc)->sCertificateDepth = NULL;
+ }
+ if ((*sc)->keysFile) {
+ free((*sc)->keysFile);
+ (*sc)->keysFile = NULL;
+ }
+ if ((*sc)->dateFormat) {
+ free((*sc)->dateFormat);
+ (*sc)->dateFormat = NULL;
+ }
+ if ((*sc)->realmsTable) {
+ for (i = 0; i < (*sc)->realmsNumber; ++i) {
+ if ((*sc)->realmsTable[i]) {
+ ServerRealm_free(&((*sc)->realmsTable[i]));
+ }
+ }
+ free((*sc)->realmsTable);
+ (*sc)->realmsTable = NULL;
+ }
+ free((*sc));
+ (*sc) = NULL;
+}
+
+/*
+ * Function name: ServerConfiguration_set_certificateFile
+ * Description: Set certificate filename.
+ * Arguments: sc - pointer to ServerConfiguration structure
+ * certificateFile - certificate filename
+ */
+
+void
+ServerConfiguration_set_certificateFile(ServerConfiguration* sc, char* certificateFile)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return;
+ }
+ string_cp(&(sc->certificateFile), certificateFile);
+}
+
+/*
+ * Function name: ServerConfiguration_set_cacertificateFile
+ * Description: Set CA certificate filename.
+ * Arguments: sc - pointer to ServerConfiguration structure
+ * certificateFile - CA certificate filename
+ */
+
+void
+ServerConfiguration_set_cacertificateFile(ServerConfiguration* sc, char* cacertificateFile)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return;
+ }
+ string_cp(&(sc->cacertificateFile), cacertificateFile);
+}
+
+/*
+ * Function name: ServerConfiguration_set_cacertificatePath
+ * Description: Set CA certificate filename.
+ * Arguments: sc - pointer to ServerConfiguration structure
+ * cacertificateFile - CA certificate path
+ */
+
+void
+ServerConfiguration_set_cacertificatePath(ServerConfiguration* sc, char* cacertificatePath)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return;
+ }
+ string_cp(&(sc->cacertificatePath), cacertificatePath);
+}
+
+void
+ServerConfiguration_set_sCertificateDepth(ServerConfiguration* sc, char* sCertificateDepth)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return;
+ }
+ string_cp(&(sc->sCertificateDepth), sCertificateDepth);
+}
+void
+ServerConfiguration_set_certificateDepth(ServerConfiguration* sc, int certificateDepth)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return;
+ }
+ sc->certificateDepth = certificateDepth;
+}
+
+/*
+ * Function name: ServerConfiguration_set_keysFile
+ * Description: Set keys filename.
+ * Arguments: sc - pointer to ServerConfiguration structure
+ * keysFile - keys filename
+ */
+
+void
+ServerConfiguration_set_keysFile(ServerConfiguration* sc, char* keysFile)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return;
+ }
+ string_cp(&(sc->keysFile), keysFile);
+}
+
+/*
+ * Function name: ServerConfiguration_set_dateFormat
+ * Description: Set format of the date string.
+ * Arguments: sc - pointer to ServerConfiguration structure
+ * dateFormat - format of the date string
+ */
+
+void
+ServerConfiguration_set_dateFormat(ServerConfiguration* sc, char* dateFormat)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return;
+ }
+ string_cp(&(sc->dateFormat), dateFormat);
+}
+
+/*
+ * Function name: ServerConfiguration_set_realmsNumber
+ * Description: Set number of realms.
+ * Arguments: sc - pointer to ServerConfiguration structure
+ * realmsNumber - number of realms
+ */
+
+void
+ServerConfiguration_set_realmsNumber(ServerConfiguration* sc, int realmsNumber)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return;
+ }
+ sc->realmsNumber = realmsNumber;
+}
+
+/*
+ * Function name: ServerConfiguration_set_startTime
+ * Description: Set start time of the server.
+ * Arguments: sc - pointer to ServerConfiguration structure
+ * startTime - start time of the server
+ */
+
+void
+ServerConfiguration_set_startTime(ServerConfiguration* sc, time_t startTime)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return;
+ }
+ sc->startTime = startTime;
+}
+
+/*
+ * Function name: ServerConfiguration_set_realmsTable
+ * Description: Set table of realms.
+ * Arguments: sc - pointer to ServerConfiguration structure
+ * realmsTable - table of realms
+ */
+
+void
+ServerConfiguration_set_realmsTable(ServerConfiguration* sc, ServerRealm** realmsTable)
+{
+ int i;
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return;
+ }
+ if (sc->realmsTable) {
+ for (i = 0; i < sc->realmsNumber; ++i) {
+ if (sc->realmsTable[i]) {
+ ServerRealm_free(&(sc->realmsTable[i]));
+ }
+ }
+ free(sc->realmsTable);
+ sc->realmsTable = NULL;
+ }
+ sc->realmsTable = realmsTable;
+}
+
+/*
+ * Function name: ServerConfiguration_get_certificateFile
+ * Description: Get certificate filename.
+ * Arguments: sc - pointer to ServerConfiguration structure
+ * Returns: Certificate filename.
+ */
+
+char*
+ServerConfiguration_get_certificateFile(ServerConfiguration* sc)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return NULL;
+ }
+ return sc->certificateFile;
+}
+
+/*
+ * Function name: ServerConfiguration_get_cacertificateFile
+ * Description: Get CA certificate filename.
+ * Arguments: sc - pointer to ServerConfiguration structure
+ * Returns: CA Certificate filename.
+ */
+
+char*
+ServerConfiguration_get_cacertificateFile(ServerConfiguration* sc)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return NULL;
+ }
+ return sc->cacertificateFile;
+}
+
+/*
+ * Function name: ServerConfiguration_get_cacertificatePath
+ * Description: Get CA certificate path
+ * Arguments: sc - pointer to ServerConfiguration structure
+ * Returns: CA Certificate path.
+ */
+
+char*
+ServerConfiguration_get_cacertificatePath(ServerConfiguration* sc)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return NULL;
+ }
+ return sc->cacertificatePath;
+}
+
+char*
+ServerConfiguration_get_sCertificateDepth(ServerConfiguration* sc)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return NULL;
+ }
+ return sc->sCertificateDepth;
+}
+
+int
+ServerConfiguration_get_certificateDepth(ServerConfiguration* sc)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return -1;
+ }
+ return sc->certificateDepth;
+}
+
+/*
+ * Function name: ServerConfiguration_get_keysFile
+ * Description: Get keys filename.
+ * Arguments: sc - pointer to ServerConfiguration structure
+ * Returns: Keys filename.
+ */
+
+char*
+ServerConfiguration_get_keysFile(ServerConfiguration* sc)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return NULL;
+ }
+ return sc->keysFile;
+}
+
+/*
+ * Function name: ServerConfiguration_get_dateFormat
+ * Description: Get format of the date string.
+ * Arguments: sc - pointer to ServerConfiguration structure
+ * Returns: Format of the date string.
+ */
+
+char*
+ServerConfiguration_get_dateFormat(ServerConfiguration* sc)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return NULL;
+ }
+ return sc->dateFormat;
+}
+
+/*
+ * Function name: ServerConfiguration_get_realmsNumber
+ * Description: Get number of realms.
+ * Arguments: sc - pointer to ServerConfiguration structure
+ * Returns: Number of realms.
+ */
+
+int
+ServerConfiguration_get_realmsNumber(ServerConfiguration* sc)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return -1;
+ }
+ return sc->realmsNumber;
+}
+
+/*
+ * Function name: ServerConfiguration_get_startTime
+ * Description: Get start time of the server.
+ * Arguments: sc - pointer to ServerConfiguration structure
+ * Returns: Start time of the server.
+ */
+
+time_t
+ServerConfiguration_get_startTime(ServerConfiguration* sc)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return 0;
+ }
+ return sc->startTime;
+}
+
+/*
+ * Function name: ServerConfiguration_get_realmsTable
+ * Description: Get table of realms.
+ * Arguments: sc - pointer to ServerConfiguration structure
+ * Returns: Table of realms.
+ */
+
+ServerRealm**
+ServerConfiguration_get_realmsTable(ServerConfiguration* sc)
+{
+ assert(sc != NULL);
+ if (sc == NULL) {
+ return NULL;
+ }
+ return sc->realmsTable;
+}
diff --git a/src/server_configuration_struct.h b/src/server_configuration_struct.h
new file mode 100644
index 0000000..caf7a9e
--- /dev/null
+++ b/src/server_configuration_struct.h
@@ -0,0 +1,67 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef _JS_SERVER_CONFIGURATION_STRUCT_H
+#define _JS_SERVER_CONFIGURATION_STRUCT_H
+
+#include "server_realm_struct.h"
+
+typedef struct {
+ char* cacertificateFile;
+ char* cacertificatePath;
+ char* sCertificateDepth;
+ int certificateDepth;
+ char* certificateFile;
+ char* keysFile;
+ char* dateFormat;
+ int realmsNumber;
+ time_t startTime;
+ ServerRealm** realmsTable;
+} ServerConfiguration;
+
+/* 'constructor' */
+ServerConfiguration* ServerConfiguration_new();
+/* 'destructor' */
+void ServerConfiguration_free(ServerConfiguration** sc);
+/* setters */
+void ServerConfiguration_set_certificateFile(ServerConfiguration* sc, char* certificateFile);
+void ServerConfiguration_set_cacertificateFile(ServerConfiguration* sc, char* cacertificateFile);
+void ServerConfiguration_set_cacertificatePath(ServerConfiguration* sc, char* cacertificatePath);
+void ServerConfiguration_set_sCertificateDepth(ServerConfiguration* sc, char* sCertificateDepth);
+void ServerConfiguration_set_certificateDepth(ServerConfiguration* sc, int certificateDepth);
+void ServerConfiguration_set_keysFile(ServerConfiguration* sc, char* keysFile);
+void ServerConfiguration_set_dateFormat(ServerConfiguration* sc, char* dateFormat);
+void ServerConfiguration_set_realmsNumber(ServerConfiguration* sc, int realmsNumber);
+void ServerConfiguration_set_startTime(ServerConfiguration* sc, time_t startTime);
+void ServerConfiguration_set_realmsTable(ServerConfiguration* sc, ServerRealm** realmsTable);
+/* getters */
+char* ServerConfiguration_get_certificateFile(ServerConfiguration* sc);
+char* ServerConfiguration_get_cacertificateFile(ServerConfiguration* sc);
+char* ServerConfiguration_get_cacertificatePath(ServerConfiguration* sc);
+char* ServerConfiguration_get_sCertificateDepth(ServerConfiguration* sc);
+int ServerConfiguration_get_certificateDepth(ServerConfiguration* sc);
+char* ServerConfiguration_get_keysFile(ServerConfiguration* sc);
+char* ServerConfiguration_get_dateFormat(ServerConfiguration* sc);
+int ServerConfiguration_get_realmsNumber(ServerConfiguration* sc);
+time_t ServerConfiguration_get_startTime(ServerConfiguration* sc);
+ServerRealm** ServerConfiguration_get_realmsTable(ServerConfiguration* sc);
+
+#endif
diff --git a/src/server_eval.c b/src/server_eval.c
new file mode 100644
index 0000000..c4c69ce
--- /dev/null
+++ b/src/server_eval.c
@@ -0,0 +1,123 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+#include <assert.h>
+#include <string.h>
+
+#include "server_eval.h"
+
+/*
+ * Function name: eval_numofcon
+ * Description: Returns the real connection number on the afserver.
+ * Arguments: ptr - the server realm
+ * client - client number
+ * numofcon - the connection number on the afclient
+ * Returns: The real connection number on the afserver.
+ */
+
+int
+eval_numofcon(ServerRealm* ptr, int client, int numofcon)
+{
+ assert(ptr != NULL);
+ if ((numofcon >= 0) && (numofcon < ConnectClient_get_limit(ServerRealm_get_clientsTable(ptr)[client]))) {
+ numofcon = ConnectClient_get_users(ServerRealm_get_clientsTable(ptr)[client])[numofcon];
+ }
+ else {
+ numofcon = -1;
+ }
+ return numofcon;
+}
+
+/*
+ * Function name: eval_usernum
+ * Description: Returns the user number in the connected client on the afserver side.
+ * Arguments: ptr - the connected client
+ * usernum - the connection number on the afserver
+ * Returns: The user number in the connected client on the afserver side.
+ */
+
+int
+eval_usernum(ConnectClient* ptr, int usernum)
+{
+ int i;
+ assert(ptr != NULL);
+ for (i = 0; i < ConnectClient_get_limit(ptr); ++i) {
+ if (ConnectClient_get_users(ptr)[i] == usernum)
+ return i;
+ }
+ return -1;
+}
+
+/*
+ * Function name: eval_UsrCliPair
+ * Description: Returns how many UsrCli structures are connected with the current manage port.
+ * Arguments: table - the table of UsrCli structures
+ * index - the current index of the evaluation
+ * host - the name of the host
+ * serv - the name of the service (port)
+ * Returns: How many UsrCli structures are connected with the current manage port.
+ */
+
+int
+eval_UsrCliPair(UsrCli** table, int index, char* host, char* serv)
+{
+ int i;
+ int result = 0;
+ assert(table != NULL);
+ assert(index >= 0);
+ for (i = 0; i < index; ++i) {
+
+ if (UsrCli_get_manageHostName(table[i])) {
+ if (host) {
+ if (strcmp(UsrCli_get_listenHostName(table[i]), host)) {
+ continue;
+ }
+ }
+ else {
+ continue;
+ }
+ }
+ else {
+ if (host) {
+ continue;
+ }
+ }
+
+ if (UsrCli_get_managePortName(table[i])) {
+ if (serv) {
+ if (strcmp(UsrCli_get_managePortName(table[i]), serv)) {
+ continue;
+ }
+ }
+ else {
+ continue;
+ }
+ }
+ else {
+ if (serv) {
+ continue;
+ }
+ }
+
+ result++;
+ }
+ return result;
+}
diff --git a/src/server_eval.h b/src/server_eval.h
new file mode 100644
index 0000000..a5471b1
--- /dev/null
+++ b/src/server_eval.h
@@ -0,0 +1,32 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "file.h"
+#include "activefor.h"
+
+#ifndef _JS_SERVER_EVAL_H
+#define _JS_SERVER_EVAL_H
+
+int eval_numofcon(ServerRealm*, int, int);
+int eval_usernum(ConnectClient*, int);
+int eval_UsrCliPair(UsrCli**, int, char*, char*);
+
+#endif
+
diff --git a/src/server_find.c b/src/server_find.c
new file mode 100644
index 0000000..a2934a8
--- /dev/null
+++ b/src/server_find.c
@@ -0,0 +1,138 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+#include <assert.h>
+#include <string.h>
+
+#include "server_find.h"
+
+/*
+ * Function name: find_client
+ * Description: Returns the client number with free user slots.
+ * Arguments: ptr - the server realm
+ * mode - the strategy of client choosing
+ * usrclipair - the number of usrclipair
+ * Returns: The client number with free user slots.
+ */
+
+int
+find_client(ServerRealm* ptr, char mode, int usrclipair)
+{
+ int i;
+ assert(ptr != NULL);
+ switch(mode) {
+ case 1: { /* fill first client before go to next */
+ for (i = 0; i < ServerRealm_get_clientsLimit(ptr); ++i) {
+ if ((ConnectClient_get_state(ServerRealm_get_clientsTable(ptr)[i]) ==
+ CONNECTCLIENT_STATE_ACCEPTED) &&
+ (ConnectClient_get_usrCliPair(ServerRealm_get_clientsTable(ptr)[i]) == usrclipair)) {
+ if (ConnectClient_get_connected(ServerRealm_get_clientsTable(ptr)[i]) <
+ ConnectClient_get_limit(ServerRealm_get_clientsTable(ptr)[i])) {
+ return i;
+ }
+ }
+ }
+ break;
+ }
+ default: {
+ return 0;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Function name: find_usernum
+ * Description: Finds the free user slot, fill it and returns its number.
+ * Arguments: ptr - the connected client
+ * usernum - the connection number on the afserver
+ * Returns: The user number in the connected client on the afserver side.
+ */
+
+int
+find_usernum(ConnectClient* ptr, int usernum)
+{
+ int i;
+ assert(ptr != NULL);
+ for (i = 0; i < ConnectClient_get_limit(ptr); ++i) {
+ if (ConnectClient_get_users(ptr)[i] == -1) {
+ ConnectClient_get_users(ptr)[i] = usernum;
+ return i;
+ }
+ }
+ return -1;
+}
+
+/*
+ * Function name: find_previousFd
+ * Description: Finds the file descriptor bound previously to the given
+ * host:serv.
+ * Arguments: table - the table of UsrCli structures
+ * index - the current index of the search
+ * host - the name of the host
+ * serv - the name of the service (port)
+ * Returns: The previously bound file descriptor.
+ */
+
+int
+find_previousFd(UsrCli** table, int index, char* host, char* serv)
+{
+ int i;
+ assert(table != NULL);
+ assert(index >= 0);
+ for (i = 0; i < index; ++i) {
+
+ if (UsrCli_get_manageHostName(table[i])) {
+ if (host) {
+ if (strcmp(UsrCli_get_listenHostName(table[i]), host)) {
+ continue;
+ }
+ }
+ else {
+ continue;
+ }
+ }
+ else {
+ if (host) {
+ continue;
+ }
+ }
+
+ if (UsrCli_get_managePortName(table[i])) {
+ if (serv) {
+ if (strcmp(UsrCli_get_managePortName(table[i]), serv)) {
+ continue;
+ }
+ }
+ else {
+ continue;
+ }
+ }
+ else {
+ if (serv) {
+ continue;
+ }
+ }
+
+ return UsrCli_get_manageFd(table[i]);
+ }
+ return -1;
+}
diff --git a/src/server_find.h b/src/server_find.h
new file mode 100644
index 0000000..83ad4d4
--- /dev/null
+++ b/src/server_find.h
@@ -0,0 +1,32 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "activefor.h"
+#include "file.h"
+
+#ifndef _JS_SERVER_FIND_H
+#define _JS_SERVER_FIND_H
+
+int find_client(ServerRealm*, char, int);
+int find_usernum(ConnectClient*, int);
+int find_previousFd(UsrCli**, int, char*, char*);
+
+#endif
+
diff --git a/src/server_get.c b/src/server_get.c
new file mode 100644
index 0000000..cd13a75
--- /dev/null
+++ b/src/server_get.c
@@ -0,0 +1,123 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "server_get.h"
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+
+/*
+ * Function name: get_new_socket
+ * Description: Returns new accepted socket.
+ * Arguments: sockfd - the file descriptor of the listening socket
+ * type - the type of the listening socket
+ * addr - pointer to sockaddr structure
+ * addrlen - pointer to the length of the sockaddr structure
+ * tunneltype - the type of the connection
+ * Returns: The new accepted socket.
+ */
+
+int
+get_new_socket(int sockfd, char type, struct sockaddr *addr, socklen_t *addrlen, char* tunneltype)
+{
+ int tmp;
+ int n, i;
+
+ assert(addr != NULL);
+ assert(addrlen != NULL);
+ assert(tunneltype != NULL);
+
+ switch (type) {
+ case 0: {
+ return accept(sockfd, addr, addrlen);
+ break;
+ }
+ case 1: {
+ i = 0;
+ while (i < 4) {
+ if ((n = read(sockfd, &tmp+i, 4-i)) != (4-i)) {
+ sleep(2);
+ if ((n > 0) && (n < 4)) {
+ i += n;
+ continue;
+ }
+ if ((n == -1) && (errno == EAGAIN)) {
+ continue;
+ }
+ return -1;
+ }
+ else {
+ break;
+ }
+ }
+ i = 0;
+ while (i < 1) {
+ if ((n = read(sockfd, tunneltype+i, 1-i)) != (1-i)) {
+ if ((n == -1) && (errno == EAGAIN)) {
+ continue;
+ }
+ return -1;
+ }
+ else {
+ break;
+ }
+ }
+ i = 0;
+ while (i < 4) {
+ if ((n = read(sockfd, addrlen+i, 4-i)) != (4-i)) {
+ if ((n > 0) && (n < 4)) {
+ i += n;
+ continue;
+ }
+ if ((n == -1) && (errno == EAGAIN)) {
+ continue;
+ }
+ return -1;
+ }
+ else {
+ break;
+ }
+ }
+ i = 0;
+ while (i < *addrlen) {
+ if ((n = read(sockfd, addr+i, (*addrlen)-i)) != ((*addrlen)-i)) {
+ if ((n > 0) && (n < *addrlen)) {
+ i += n;
+ continue;
+ }
+ if ((n == -1) && (errno == EAGAIN)) {
+ continue;
+ }
+ return -1;
+ }
+ else {
+ break;
+ }
+ }
+ return tmp;
+ break;
+ }
+ default: {
+ return -1;
+ }
+ }
+}
diff --git a/src/server_get.h b/src/server_get.h
new file mode 100644
index 0000000..2ad2656
--- /dev/null
+++ b/src/server_get.h
@@ -0,0 +1,31 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#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_realm_struct.c b/src/server_realm_struct.c
new file mode 100644
index 0000000..c816ae3
--- /dev/null
+++ b/src/server_realm_struct.c
@@ -0,0 +1,1471 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "string_functions.h"
+#include "server_realm_struct.h"
+
+/*
+ * Function name: ServerRealm_new
+ * Description: Create and initialize new ServerRealm structure.
+ * Returns: Pointer to newly created ServerRealm structure.
+ */
+
+ServerRealm*
+ServerRealm_new()
+{
+ ServerRealm* tmp = calloc(1, sizeof(ServerRealm));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ tmp->password[0] = 1;
+ tmp->password[1] = 2;
+ tmp->password[2] = 3;
+ tmp->password[3] = 4;
+ return tmp;
+}
+
+/*
+ * Function name: ServerRealm_free
+ * Description: Free the memory allocated for ServerRealm structure.
+ * Arguments: sr - pointer to pointer to ServerRealm structure
+ */
+
+void
+ServerRealm_free(ServerRealm** sr)
+{
+ int i;
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ assert((*sr) != NULL);
+ if ((*sr) == NULL) {
+ return;
+ }
+ if ((*sr)->hostName) {
+ free((*sr)->hostName);
+ (*sr)->hostName = NULL;
+ }
+ if ((*sr)->sUsersLimit) {
+ free((*sr)->sUsersLimit);
+ (*sr)->sUsersLimit = NULL;
+ }
+ if ((*sr)->sClientsLimit) {
+ free((*sr)->sClientsLimit);
+ (*sr)->sClientsLimit = NULL;
+ }
+ if ((*sr)->sRaClientsLimit) {
+ free((*sr)->sRaClientsLimit);
+ (*sr)->sRaClientsLimit = NULL;
+ }
+ if ((*sr)->sUsersPerClient) {
+ free((*sr)->sUsersPerClient);
+ (*sr)->sUsersPerClient = NULL;
+ }
+ if ((*sr)->sClientMode) {
+ free((*sr)->sClientMode);
+ (*sr)->sClientMode = NULL;
+ }
+ if ((*sr)->sTimeout) {
+ free((*sr)->sTimeout);
+ (*sr)->sTimeout = NULL;
+ }
+ if ((*sr)->realmName) {
+ free((*sr)->realmName);
+ (*sr)->realmName = NULL;
+ }
+ if ((*sr)->clientAddress) {
+ free((*sr)->clientAddress);
+ (*sr)->clientAddress = NULL;
+ }
+ if ((*sr)->usersTable) {
+ for (i = 0; i < (*sr)->usersLimit; ++i) {
+ if ((*sr)->usersTable[i]) {
+ ConnectUser_free(&((*sr)->usersTable[i]));
+ }
+ }
+ free((*sr)->usersTable);
+ (*sr)->usersTable = NULL;
+ }
+ if ((*sr)->clientsTable) {
+ for (i = 0; i < (*sr)->clientsLimit; ++i) {
+ if ((*sr)->clientsTable[i]) {
+ ConnectClient_free(&((*sr)->clientsTable[i]));
+ }
+ }
+ free((*sr)->clientsTable);
+ (*sr)->clientsTable = NULL;
+ }
+ if ((*sr)->raClientsTable) {
+ for (i = 0; i < (*sr)->raClientsLimit; ++i) {
+ if ((*sr)->raClientsTable[i]) {
+ ConnectClient_free(&((*sr)->raClientsTable[i]));
+ }
+ }
+ free((*sr)->raClientsTable);
+ (*sr)->raClientsTable = NULL;
+ }
+ if ((*sr)->usersClientsTable) {
+ for (i = 0; i < (*sr)->userClientPairs; ++i) {
+ if ((*sr)->usersClientsTable[i]) {
+ UsrCli_free(&((*sr)->usersClientsTable[i]));
+ }
+ }
+ free((*sr)->usersClientsTable);
+ (*sr)->usersClientsTable = NULL;
+ }
+ free((*sr));
+ (*sr) = NULL;
+}
+
+/*
+ * Function name: ServerRealm_set_hostName
+ * Description: Set realm's host name.
+ * Arguments: sr - pointer to ServerRealm structure
+ * hostName - realm's host name
+ */
+
+void
+ServerRealm_set_hostName(ServerRealm* sr, char* hostName)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ string_cp(&(sr->hostName), hostName);
+}
+
+/*
+ * Function name: ServerRealm_set_sUsersLimit
+ * Description: Set users limit description.
+ * Arguments: sr - pointer to ServerRealm structure
+ * sUsersLimit - users limit description
+ */
+
+void
+ServerRealm_set_sUsersLimit(ServerRealm* sr, char* sUsersLimit)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ string_cp(&(sr->sUsersLimit), sUsersLimit);
+}
+
+/*
+ * Function name: ServerRealm_set_sClientsLimit
+ * Description: Set clients limit description.
+ * Arguments: sr - pointer to ServerRealm structure
+ * sClientsLimit - clients limit description
+ */
+
+void
+ServerRealm_set_sClientsLimit(ServerRealm* sr, char* sClientsLimit)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ string_cp(&(sr->sClientsLimit), sClientsLimit);
+}
+
+/*
+ * Function name: ServerRealm_set_sRaClientsLimit
+ * Description: Set raClients limit description.
+ * Arguments: sr - pointer to ServerRealm structure
+ * sRaClientsLimit - raClients limit description
+ */
+
+void
+ServerRealm_set_sRaClientsLimit(ServerRealm* sr, char* sRaClientsLimit)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ string_cp(&(sr->sRaClientsLimit), sRaClientsLimit);
+}
+
+/*
+ * Function name: ServerRealm_set_sUsersPerClient
+ * Description: Set users per client description.
+ * Arguments: sr - pointer to ServerRealm structure
+ * sUsersPerClient - users per client description
+ */
+
+void
+ServerRealm_set_sUsersPerClient(ServerRealm* sr, char* sUsersPerClient)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ string_cp(&(sr->sUsersPerClient), sUsersPerClient);
+}
+
+/*
+ * Function name: ServerRealm_set_sClientMode
+ * Description: Set client mode description.
+ * Arguments: sr - pointer to ServerRealm structure
+ * sClientMode - client mode description
+ */
+
+void
+ServerRealm_set_sClientMode(ServerRealm* sr, char* sClientMode)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ string_cp(&(sr->sClientMode), sClientMode);
+}
+
+/*
+ * Function name: ServerRealm_set_sTimeout
+ * Description: Set timeout value description.
+ * Arguments: sr - pointer to ServerRealm structure
+ * sTimeout - timeout value description
+ */
+
+void
+ServerRealm_set_sTimeout(ServerRealm* sr, char* sTimeout)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ string_cp(&(sr->sTimeout), sTimeout);
+}
+
+/*
+ * Function name: ServerRealm_set_sMaxIdle
+ * Description: Sets max idle value description.
+ * Arguments: sr - pointer to ServerRealm structure
+ * sMaxIdle - max idle value description
+ */
+
+void
+ServerRealm_set_sMaxIdle(ServerRealm* sr, char* sMaxIdle)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ string_cp(&(sr->sMaxIdle), sMaxIdle);
+}
+
+/*
+ * Function name: ServerRealm_set_realmName
+ * Description: Set realm's name.
+ * Arguments: sr - pointer to ServerRealm structure
+ * realmName - realm's name
+ */
+
+void
+ServerRealm_set_realmName(ServerRealm* sr, char* realmName)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ string_cp(&(sr->realmName), realmName);
+}
+
+/*
+ * Function name: ServerRealm_set_password
+ * Description: Set realm's password.
+ * Arguments: sr - pointer to ServerRealm structure
+ * password - realm's password
+ */
+
+void
+ServerRealm_set_password(ServerRealm* sr, unsigned char* password)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ memcpy(sr->password, password, 4);
+}
+
+/*
+ * Function name: ServerRealm_set_connectedUsers
+ * Description: Set number of connected users.
+ * Arguments: sr - pointer to ServerRealm structure
+ * connectedUsers - number of connected users
+ */
+
+void
+ServerRealm_set_connectedUsers(ServerRealm* sr, int connectedUsers)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->connectedUsers = connectedUsers;
+}
+
+/*
+ * Function name: ServerRealm_set_usersLimit
+ * Description: Set limit of connected users.
+ * Arguments: sr - pointer to ServerRealm structure
+ * usersLimit - limit of connected users
+ */
+
+void
+ServerRealm_set_usersLimit(ServerRealm* sr, int usersLimit)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->usersLimit = usersLimit;
+}
+
+/*
+ * Function name: ServerRealm_set_connectedClients
+ * Description: Set number of connected clients.
+ * Arguments: sr - pointer to ServerRealm structure
+ * connectedClients - number of connected clients
+ */
+
+void
+ServerRealm_set_connectedClients(ServerRealm* sr, int connectedClients)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->connectedClients = connectedClients;
+}
+
+/*
+ * Function name: ServerRealm_set_clientsLimit
+ * Description: Set limit of connected clients.
+ * Arguments: sr - pointer to ServerRealm structure
+ * clientsLimit - limit of connected clients
+ */
+
+void
+ServerRealm_set_clientsLimit(ServerRealm* sr, int clientsLimit)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->clientsLimit = clientsLimit;
+}
+
+/*
+ * Function name: ServerRealm_set_connectedRaClients
+ * Description: Set number of connected raClients.
+ * Arguments: sr - pointer to ServerRealm structure
+ * connectedRaClients - number of connected raClients
+ */
+
+void
+ServerRealm_set_connectedRaClients(ServerRealm* sr, int connectedRaClients)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->connectedRaClients = connectedRaClients;
+}
+
+/*
+ * Function name: ServerRealm_set_raClientsLimit
+ * Description: Set limit of connected raClients.
+ * Arguments: sr - pointer to ServerRealm structure
+ * raClientsLimit - limit of connected raClients
+ */
+
+void
+ServerRealm_set_raClientsLimit(ServerRealm* sr, int raClientsLimit)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->raClientsLimit = raClientsLimit;
+}
+
+/*
+ * Function name: ServerRealm_set_usersPerClient
+ * Description: Set users per client limit.
+ * Arguments: sr - pointer to ServerRealm structure
+ * usersPerClient - users per client limit
+ */
+
+void
+ServerRealm_set_usersPerClient(ServerRealm* sr, int usersPerClient)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->usersPerClient = usersPerClient;
+}
+
+/*
+ * Function name: ServerRealm_set_timeout
+ * Description: Set timeout value.
+ * Arguments: sr - pointer to ServerRealm structure
+ * timeout - timeout value
+ */
+
+void
+ServerRealm_set_timeout(ServerRealm* sr, int timeout)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->timeout = timeout;
+}
+
+/*
+ * Function name: ServerRealm_set_maxIdle
+ * Description: Sets mas idle value.
+ * Arguments: sr - pointer to ServerRealm structure
+ * maxIdle - max idle value
+ */
+
+void
+ServerRealm_set_maxIdle(ServerRealm* sr, int maxIdle)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->maxIdle = maxIdle;
+}
+
+/*
+ * Function name: ServerRealm_set_clientMode
+ * Description: Set client mode.
+ * Arguments: sr - pointer to ServerRealm structure
+ * clientMode - client mode
+ */
+
+void
+ServerRealm_set_clientMode(ServerRealm* sr, int clientMode)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->clientMode = clientMode;
+}
+
+/*
+ * Function name: ServerRealm_set_userClientPairs
+ * Description: Set user-client pairs amount.
+ * Arguments: sr - pointer to ServerRealm structure
+ * userClientPairs - user-client pairs amount
+ */
+
+void
+ServerRealm_set_userClientPairs(ServerRealm* sr, int userClientPairs)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->userClientPairs = userClientPairs;
+}
+
+/*
+ * Function name: ServerRealm_set_clientsCounter
+ * Description: Set clients counter state.
+ * Arguments: sr - pointer to ServerRealm structure
+ * clientsCounter - clients counter state
+ */
+
+void
+ServerRealm_set_clientsCounter(ServerRealm* sr, int clientsCounter)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->clientsCounter = clientsCounter;
+}
+
+/*
+ * Function name: ServerRealm_set_usersCounter
+ * Description: Set users counter state.
+ * Arguments: sr - pointer to ServerRealm structure
+ * usersCounter - users counter state
+ */
+
+void
+ServerRealm_set_usersCounter(ServerRealm* sr, int usersCounter)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->usersCounter = usersCounter;
+}
+
+/*
+ * Function name: ServerRealm_set_realmType
+ * Description: Set type of the realm.
+ * Arguments: sr - pointer to ServerRealm structure
+ * realmType - type of the realm
+ */
+
+void
+ServerRealm_set_realmType(ServerRealm* sr, char realmType)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->realmType = realmType;
+}
+
+/*
+ * Function name: ServerRealm_set_tunnelType
+ * Description: Set type of the tunnel.
+ * Arguments: sr - pointer to ServerRealm structure
+ * tunnelType - type of the tunnel
+ */
+
+void
+ServerRealm_set_tunnelType(ServerRealm* sr, char tunnelType)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->tunnelType = tunnelType;
+}
+
+/*
+ * Function name: ServerRealm_set_dnsLookupsOn
+ * Description: Set dns lookups functionality on/off.
+ * Arguments: sr - pointer to ServerRealm structure
+ * dnsLookupsOn - dns lookups functionality on/off
+ */
+
+void
+ServerRealm_set_dnsLookupsOn(ServerRealm* sr, char dnsLookupsOn)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->dnsLookupsOn = dnsLookupsOn;
+}
+
+/*
+ * Function name: ServerRealm_set_basePortOn
+ * Description: Set base port functionality on/off.
+ * Arguments: sr - pointer to ServerRealm structure
+ * basePortOn - base port functionality on/off
+ */
+
+void
+ServerRealm_set_basePortOn(ServerRealm* sr, char basePortOn)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->basePortOn = basePortOn;
+}
+
+/*
+ * Function name: ServerRealm_set_auditOn
+ * Description: Set audit functionality on/off.
+ * Arguments: sr - pointer to ServerRealm structure
+ * auditOn - audit functionality on/off
+ */
+
+void
+ServerRealm_set_auditOn(ServerRealm* sr, char auditOn)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->auditOn = auditOn;
+}
+
+/*
+ * Function name: ServerRealm_set_addressLength
+ * Description: Set client's address length.
+ * Arguments: sr - pointer to ServerRealm structure
+ * addressLength - client's address length
+ */
+
+void
+ServerRealm_set_addressLength(ServerRealm* sr, socklen_t addressLength)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ sr->addressLength = addressLength;
+}
+
+/*
+ * Function name: ServerRealm_set_clientAddress
+ * Description: Set client's network address.
+ * Arguments: sr - pointer to ServerRealm structure
+ * clientAddress - client's network address
+ */
+
+void
+ServerRealm_set_clientAddress(ServerRealm* sr, struct sockaddr* clientAddress)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ if (sr->clientAddress) {
+ free(sr->clientAddress);
+ sr->clientAddress = NULL;
+ }
+ sr->clientAddress = clientAddress;
+}
+
+/*
+ * Function name: ServerRealm_set_usersTable
+ * Description: Set table of users.
+ * Arguments: sr - pointer to ServerRealm structure
+ * usersTable - table of users
+ */
+
+void
+ServerRealm_set_usersTable(ServerRealm* sr, ConnectUser** usersTable)
+{
+ int i;
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ if (sr->usersTable) {
+ for (i = 0; i < sr->usersLimit; ++i) {
+ if (sr->usersTable[i]) {
+ ConnectUser_free(&(sr->usersTable[i]));
+ }
+ }
+ free(sr->usersTable);
+ sr->usersTable = NULL;
+ }
+ sr->usersTable = usersTable;
+}
+
+/*
+ * Function name: ServerRealm_set_clientsTable
+ * Description: Set table of clients.
+ * Arguments: sr - pointer to ServerRealm structure
+ * clientsTable - table of clients
+ */
+
+void
+ServerRealm_set_clientsTable(ServerRealm* sr, ConnectClient** clientsTable)
+{
+ int i;
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ if (sr->clientsTable) {
+ for (i = 0; i < sr->clientsLimit; ++i) {
+ if (sr->clientsTable[i]) {
+ ConnectClient_free(&(sr->clientsTable[i]));
+ }
+ }
+ free(sr->clientsTable);
+ sr->clientsTable = NULL;
+ }
+ sr->clientsTable = clientsTable;
+}
+
+/*
+ * Function name: ServerRealm_set_raClientsTable
+ * Description: Set table of raClients.
+ * Arguments: sr - pointer to ServerRealm structure
+ * raClientsTable - table of raClients
+ */
+
+void
+ServerRealm_set_raClientsTable(ServerRealm* sr, ConnectClient** raClientsTable)
+{
+ int i;
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ if (sr->raClientsTable) {
+ for (i = 0; i < sr->raClientsLimit; ++i) {
+ if (sr->raClientsTable[i]) {
+ ConnectClient_free(&(sr->raClientsTable[i]));
+ }
+ }
+ free(sr->raClientsTable);
+ sr->raClientsTable = NULL;
+ }
+ sr->raClientsTable = raClientsTable;
+}
+
+/*
+ * Function name: ServerRealm_set_usersClientsTable
+ * Description: Set table of user-client pairs.
+ * Arguments: sr - pointer to ServerRealm structure
+ * usersClientsTable - table of user-client pairs
+ */
+
+void
+ServerRealm_set_usersClientsTable(ServerRealm* sr, UsrCli** usersClientsTable)
+{
+ int i;
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ if (sr->usersClientsTable) {
+ for (i = 0; i < sr->userClientPairs; ++i) {
+ if (sr->usersClientsTable[i]) {
+ UsrCli_free(&(sr->usersClientsTable[i]));
+ }
+ }
+ free(sr->usersClientsTable);
+ sr->usersClientsTable = NULL;
+ }
+ sr->usersClientsTable = usersClientsTable;
+}
+
+/*
+ * Function name: ServerRealm_get_hostName
+ * Description: Get realm's host name.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Realm's host name.
+ */
+
+char*
+ServerRealm_get_hostName(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return NULL;
+ }
+ return sr->hostName;
+}
+
+/*
+ * Function name: ServerRealm_get_sUsersLimit
+ * Description: Get users limit description.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Users limit description.
+ */
+
+char*
+ServerRealm_get_sUsersLimit(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return NULL;
+ }
+ return sr->sUsersLimit;
+}
+
+/*
+ * Function name: ServerRealm_get_sClientsLimit
+ * Description: Get clients limit description.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Clients limit description.
+ */
+
+char*
+ServerRealm_get_sClientsLimit(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return NULL;
+ }
+ return sr->sClientsLimit;
+}
+
+/*
+ * Function name: ServerRealm_get_sRaClientsLimit
+ * Description: Get raClients limit description.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: RaClients limit description.
+ */
+
+char*
+ServerRealm_get_sRaClientsLimit(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return NULL;
+ }
+ return sr->sRaClientsLimit;
+}
+
+/*
+ * Function name: ServerRealm_get_sUsersPerClient
+ * Description: Get users per client description.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Users per client description.
+ */
+
+char*
+ServerRealm_get_sUsersPerClient(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return NULL;
+ }
+ return sr->sUsersPerClient;
+}
+
+/*
+ * Function name: ServerRealm_get_sClientMode
+ * Description: Get client mode description.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Client mode description.
+ */
+
+char*
+ServerRealm_get_sClientMode(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return NULL;
+ }
+ return sr->sClientMode;
+}
+
+/*
+ * Function name: ServerRealm_get_sTimeout
+ * Description: Get timeout value description.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Timeout value description.
+ */
+
+char*
+ServerRealm_get_sTimeout(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return NULL;
+ }
+ return sr->sTimeout;
+}
+
+/*
+ * Function name: ServerRealm_get_sMaxIdle
+ * Description: Gets max idle value description.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Max idle value description.
+ */
+
+char*
+ServerRealm_get_sMaxIdle(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return NULL;
+ }
+ return sr->sMaxIdle;
+}
+
+/*
+ * Function name: ServerRealm_get_realmName
+ * Description: Get realm's name.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Realm's name.
+ */
+
+char*
+ServerRealm_get_realmName(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return NULL;
+ }
+ return sr->realmName;
+}
+
+/*
+ * Function name: ServerRealm_get_password
+ * Description: Get realm's password.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Realm's password.
+ */
+
+unsigned char*
+ServerRealm_get_password(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return NULL;
+ }
+ return sr->password;
+}
+
+/*
+ * Function name: ServerRealm_get_connectedUsers
+ * Description: Get number of connected users.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Number of connected users.
+ */
+
+int
+ServerRealm_get_connectedUsers(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return -1;
+ }
+ return sr->connectedUsers;
+}
+
+/*
+ * Function name: ServerRealm_get_usersLimit
+ * Description: Get limit of connected users.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Limit of connected users.
+ */
+
+int
+ServerRealm_get_usersLimit(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return -1;
+ }
+ return sr->usersLimit;
+}
+
+/*
+ * Function name: ServerRealm_get_connectedClients
+ * Description: Get number of connected clients.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Number of connected clients.
+ */
+
+int
+ServerRealm_get_connectedClients(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return -1;
+ }
+ return sr->connectedClients;
+}
+
+/*
+ * Function name: ServerRealm_get_clientsLimit
+ * Description: Get limit of connected clients.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Limit of connected clients.
+ */
+
+int
+ServerRealm_get_clientsLimit(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return -1;
+ }
+ return sr->clientsLimit;
+}
+
+/*
+ * Function name: ServerRealm_get_connectedRaClients
+ * Description: Get number of connected raClients.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Number of connected raClients.
+ */
+
+int
+ServerRealm_get_connectedRaClients(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return -1;
+ }
+ return sr->connectedRaClients;
+}
+
+/*
+ * Function name: ServerRealm_get_raClientsLimit
+ * Description: Get limit of connected raClients.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Limit of connected raClients.
+ */
+
+int
+ServerRealm_get_raClientsLimit(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return -1;
+ }
+ return sr->raClientsLimit;
+}
+
+/*
+ * Function name: ServerRealm_get_usersPerClient
+ * Description: Get users per client limit.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Users per client limit.
+ */
+
+int
+ServerRealm_get_usersPerClient(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return -1;
+ }
+ return sr->usersPerClient;
+}
+
+/*
+ * Function name: ServerRealm_get_timeout
+ * Description: Get timeout value.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Timeout value.
+ */
+
+int
+ServerRealm_get_timeout(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return 0;
+ }
+ return sr->timeout;
+}
+
+/*
+ * Function name: ServerRealm_get_maxIdle
+ * Description: Gets max idle value.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Max idle value.
+ */
+
+int
+ServerRealm_get_maxIdle(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return 0;
+ }
+ return sr->maxIdle;
+}
+
+/*
+ * Function name: ServerRealm_get_clientMode
+ * Description: Get client mode.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Client mode.
+ */
+
+int
+ServerRealm_get_clientMode(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return 0;
+ }
+ return sr->clientMode;
+}
+
+/*
+ * Function name: ServerRealm_get_userClientPairs
+ * Description: Get user-client pairs amount.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: User-client pairs amount.
+ */
+
+int
+ServerRealm_get_userClientPairs(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return 0;
+ }
+ return sr->userClientPairs;
+}
+
+/*
+ * Function name: ServerRealm_get_clientsCounter
+ * Description: Get clients counter state.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Clients counter state.
+ */
+
+int
+ServerRealm_get_clientsCounter(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return -1;
+ }
+ return sr->clientsCounter;
+}
+
+/*
+ * Function name: ServerRealm_get_usersCounter
+ * Description: Get users counter state.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Users counter state.
+ */
+
+int
+ServerRealm_get_usersCounter(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return -1;
+ }
+ return sr->usersCounter;
+}
+
+/*
+ * Function name: ServerRealm_get_realmType
+ * Description: Get type of the realm.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Type of the realm.
+ */
+
+char
+ServerRealm_get_realmType(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return 0;
+ }
+ return sr->realmType;
+}
+
+/*
+ * Function name: ServerRealm_get_tunnelType
+ * Description: Get type of the tunnel.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Type of the tunnel.
+ */
+
+char
+ServerRealm_get_tunnelType(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return 0;
+ }
+ return sr->tunnelType;
+}
+
+/*
+ * Function name: ServerRealm_get_dnsLookupsOn
+ * Description: Get dns lookups functionality on/off.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Dns lookups functionality on/off.
+ */
+
+char
+ServerRealm_get_dnsLookupsOn(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return 0;
+ }
+ return sr->dnsLookupsOn;
+}
+
+/*
+ * Function name: ServerRealm_get_basePortOn
+ * Description: Get base port functionality on/off.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Base port functionality on/off.
+ */
+
+char
+ServerRealm_get_basePortOn(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return 0;
+ }
+ return sr->basePortOn;
+}
+
+/*
+ * Function name: ServerRealm_get_auditOn
+ * Description: Get audit functionality on/off.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Audit functionality on/off.
+ */
+
+char
+ServerRealm_get_auditOn(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return 0;
+ }
+ return sr->auditOn;
+}
+
+/*
+ * Function name: ServerRealm_get_addressLength
+ * Description: Get client's address length.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Client's address length.
+ */
+
+socklen_t
+ServerRealm_get_addressLength(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return 0;
+ }
+ return sr->addressLength;
+}
+
+/*
+ * Function name: ServerRealm_get_clientAddress
+ * Description: Get client's network address.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Client's network address.
+ */
+
+struct sockaddr*
+ServerRealm_get_clientAddress(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return NULL;
+ }
+ return sr->clientAddress;
+}
+
+/*
+ * Function name: ServerRealm_get_usersTable
+ * Description: Get table of users.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Table of users.
+ */
+
+ConnectUser**
+ServerRealm_get_usersTable(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return NULL;
+ }
+ return sr->usersTable;
+}
+
+/*
+ * Function name: ServerRealm_get_clientsTable
+ * Description: Get table of clients.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Table of clients.
+ */
+
+ConnectClient**
+ServerRealm_get_clientsTable(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return NULL;
+ }
+ return sr->clientsTable;
+}
+
+/*
+ * Function name: ServerRealm_get_raClientsTable
+ * Description: Get table of raClients.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Table of raClients.
+ */
+
+ConnectClient**
+ServerRealm_get_raClientsTable(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return NULL;
+ }
+ return sr->raClientsTable;
+}
+
+/*
+ * Function name: ServerRealm_get_usersClientsTable
+ * Description: Get table of user-client pairs.
+ * Arguments: sr - pointer to ServerRealm structure
+ * Returns: Table of user-client pairs.
+ */
+
+UsrCli**
+ServerRealm_get_usersClientsTable(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return NULL;
+ }
+ return sr->usersClientsTable;
+}
+
+/*
+ * Function name: ServerRealm_increase_connectedUsers
+ * Description: Increase number of connected users.
+ * Arguments: sr - pointer to ServerRealm structure
+ */
+
+void
+ServerRealm_increase_connectedUsers(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ ServerRealm_set_connectedUsers(sr, ServerRealm_get_connectedUsers(sr) + 1);
+}
+
+/*
+ * Function name: ServerRealm_decrease_connectedUsers
+ * Description: Decrease number of connected users.
+ * Arguments: sr - pointer to ServerRealm structure
+ */
+
+void
+ServerRealm_decrease_connectedUsers(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ ServerRealm_set_connectedUsers(sr, ServerRealm_get_connectedUsers(sr) - 1);
+}
+
+/*
+ * Function name: ServerRealm_increase_connectedClients
+ * Description: Increase number of connected clients.
+ * Arguments: sr - pointer to ServerRealm structure
+ */
+
+void
+ServerRealm_increase_connectedClients(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ ServerRealm_set_connectedClients(sr, ServerRealm_get_connectedClients(sr) + 1);
+}
+
+/*
+ * Function name: ServerRealm_decrease_connectedClients
+ * Description: Decrease number of connected clients.
+ * Arguments: sr - pointer to ServerRealm structure
+ */
+
+void
+ServerRealm_decrease_connectedClients(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ ServerRealm_set_connectedClients(sr, ServerRealm_get_connectedClients(sr) - 1);
+}
+
+/*
+ * Function name: ServerRealm_increase_connectedRaClients
+ * Description: Increase number of connected raClients.
+ * Arguments: sr - pointer to ServerRealm structure
+ */
+
+void
+ServerRealm_increase_connectedRaClients(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ ServerRealm_set_connectedRaClients(sr, ServerRealm_get_connectedRaClients(sr) + 1);
+}
+
+/*
+ * Function name: ServerRealm_decrease_connectedRaClients
+ * Description: Decrease number of connected raClients.
+ * Arguments: sr - pointer to ServerRealm structure
+ */
+
+void
+ServerRealm_decrease_connectedRaClients(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ ServerRealm_set_connectedRaClients(sr, ServerRealm_get_connectedRaClients(sr) - 1);
+}
+
+/*
+ * Function name: ServerRealm_increase_usersCounter
+ * Description: Increase users counter state.
+ * Arguments: sr - pointer to ServerRealm structure
+ */
+
+void
+ServerRealm_increase_usersCounter(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ ServerRealm_set_usersCounter(sr, ServerRealm_get_usersCounter(sr) + 1);
+}
+
+/*
+ * Function name: ServerRealm_increase_clientsCounter
+ * Description: Increase clients counter state.
+ * Arguments: sr - pointer to ServerRealm structure
+ */
+
+void
+ServerRealm_increase_clientsCounter(ServerRealm* sr)
+{
+ assert(sr != NULL);
+ if (sr == NULL) {
+ return;
+ }
+ ServerRealm_set_clientsCounter(sr, ServerRealm_get_clientsCounter(sr) + 1);
+}
diff --git a/src/server_realm_struct.h b/src/server_realm_struct.h
new file mode 100644
index 0000000..e057c99
--- /dev/null
+++ b/src/server_realm_struct.h
@@ -0,0 +1,147 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "activefor.h"
+
+#ifndef _JS_SERVER_REALM_STRUCT_H
+#define _JS_SERVER_REALM_STRUCT_H
+
+typedef struct {
+ char* hostName;
+ char* sUsersLimit;
+ char* sClientsLimit;
+ char* sRaClientsLimit;
+ char* sUsersPerClient;
+ char* sClientMode;
+ char* sTimeout;
+ char* sMaxIdle;
+ char* realmName;
+ unsigned char password[4];
+ int connectedUsers;
+ int usersLimit;
+ int connectedClients;
+ int clientsLimit;
+ int connectedRaClients;
+ int raClientsLimit;
+ int usersPerClient;
+ int timeout;
+ int maxIdle;
+ int clientMode;
+ int userClientPairs;
+ int clientsCounter;
+ int usersCounter;
+ char realmType;
+ char tunnelType;
+ char dnsLookupsOn;
+ char basePortOn;
+ char auditOn;
+ socklen_t addressLength;
+ struct sockaddr* clientAddress;
+ ConnectUser** usersTable;
+ ConnectClient** clientsTable;
+ ConnectClient** raClientsTable;
+ UsrCli** usersClientsTable;
+} ServerRealm;
+
+/* 'constructor' */
+ServerRealm* ServerRealm_new();
+/* 'destructor' */
+void ServerRealm_free(ServerRealm** sr);
+/* setters */
+void ServerRealm_set_hostName(ServerRealm* sr, char* hostName);
+void ServerRealm_set_sUsersLimit(ServerRealm* sr, char* sUsersLimit);
+void ServerRealm_set_sClientsLimit(ServerRealm* sr, char* sClientsLimit);
+void ServerRealm_set_sRaClientsLimit(ServerRealm* sr, char* sRaClientsLimit);
+void ServerRealm_set_sUsersPerClient(ServerRealm* sr, char* sUsersPerClient);
+void ServerRealm_set_sClientMode(ServerRealm* sr, char* sClientMode);
+void ServerRealm_set_sTimeout(ServerRealm* sr, char* sTimeout);
+void ServerRealm_set_sMaxIdle(ServerRealm* sr, char* sMaxIdle);
+void ServerRealm_set_realmName(ServerRealm* sr, char* realmName);
+void ServerRealm_set_password(ServerRealm* sr, unsigned char* password);
+void ServerRealm_set_connectedUsers(ServerRealm* sr, int connectedUsers);
+void ServerRealm_set_usersLimit(ServerRealm* sr, int usersLimit);
+void ServerRealm_set_connectedClients(ServerRealm* sr, int connectedClients);
+void ServerRealm_set_clientsLimit(ServerRealm* sr, int clientsLimit);
+void ServerRealm_set_connectedRaClients(ServerRealm* sr, int connectedRaClients);
+void ServerRealm_set_raClientsLimit(ServerRealm* sr, int raClientsLimit);
+void ServerRealm_set_usersPerClient(ServerRealm* sr, int usersPerClient);
+void ServerRealm_set_timeout(ServerRealm* sr, int timeout);
+void ServerRealm_set_maxIdle(ServerRealm* sr, int maxIdle);
+void ServerRealm_set_clientMode(ServerRealm* sr, int clientMode);
+void ServerRealm_set_userClientPairs(ServerRealm* sr, int userClientPairs);
+void ServerRealm_set_clientsCounter(ServerRealm* sr, int clientsCounter);
+void ServerRealm_set_usersCounter(ServerRealm* sr, int usersCounter);
+void ServerRealm_set_realmType(ServerRealm* sr, char realmType);
+void ServerRealm_set_tunnelType(ServerRealm* sr, char tunnelType);
+void ServerRealm_set_dnsLookupsOn(ServerRealm* sr, char dnsLookupsOn);
+void ServerRealm_set_basePortOn(ServerRealm* sr, char basePortOn);
+void ServerRealm_set_auditOn(ServerRealm* sr, char auditOn);
+void ServerRealm_set_addressLength(ServerRealm* sr, socklen_t addressLength);
+void ServerRealm_set_clientAddress(ServerRealm* sr, struct sockaddr* clientAddress);
+void ServerRealm_set_usersTable(ServerRealm* sr, ConnectUser** usersTable);
+void ServerRealm_set_clientsTable(ServerRealm* sr, ConnectClient** clientsTable);
+void ServerRealm_set_raClientsTable(ServerRealm* sr, ConnectClient** raClientsTable);
+void ServerRealm_set_usersClientsTable(ServerRealm* sr, UsrCli** usersClientsTable);
+/* getters */
+char* ServerRealm_get_hostName(ServerRealm* sr);
+char* ServerRealm_get_sUsersLimit(ServerRealm* sr);
+char* ServerRealm_get_sClientsLimit(ServerRealm* sr);
+char* ServerRealm_get_sRaClientsLimit(ServerRealm* sr);
+char* ServerRealm_get_sUsersPerClient(ServerRealm* sr);
+char* ServerRealm_get_sClientMode(ServerRealm* sr);
+char* ServerRealm_get_sTimeout(ServerRealm* sr);
+char* ServerRealm_get_sMaxIdle(ServerRealm* sr);
+char* ServerRealm_get_realmName(ServerRealm* sr);
+unsigned char* ServerRealm_get_password(ServerRealm* sr);
+int ServerRealm_get_connectedUsers(ServerRealm* sr);
+int ServerRealm_get_usersLimit(ServerRealm* sr);
+int ServerRealm_get_connectedClients(ServerRealm* sr);
+int ServerRealm_get_clientsLimit(ServerRealm* sr);
+int ServerRealm_get_connectedRaClients(ServerRealm* sr);
+int ServerRealm_get_raClientsLimit(ServerRealm* sr);
+int ServerRealm_get_usersPerClient(ServerRealm* sr);
+int ServerRealm_get_timeout(ServerRealm* sr);
+int ServerRealm_get_maxIdle(ServerRealm* sr);
+int ServerRealm_get_clientMode(ServerRealm* sr);
+int ServerRealm_get_userClientPairs(ServerRealm* sr);
+int ServerRealm_get_clientsCounter(ServerRealm* sr);
+int ServerRealm_get_usersCounter(ServerRealm* sr);
+char ServerRealm_get_realmType(ServerRealm* sr);
+char ServerRealm_get_tunnelType(ServerRealm* sr);
+char ServerRealm_get_dnsLookupsOn(ServerRealm* sr);
+char ServerRealm_get_basePortOn(ServerRealm* sr);
+char ServerRealm_get_auditOn(ServerRealm* sr);
+socklen_t ServerRealm_get_addressLength(ServerRealm* sr);
+struct sockaddr* ServerRealm_get_clientAddress(ServerRealm* sr);
+ConnectUser** ServerRealm_get_usersTable(ServerRealm* sr);
+ConnectClient** ServerRealm_get_clientsTable(ServerRealm* sr);
+ConnectClient** ServerRealm_get_raClientsTable(ServerRealm* sr);
+UsrCli** ServerRealm_get_usersClientsTable(ServerRealm* sr);
+/* other */
+void ServerRealm_increase_connectedUsers(ServerRealm* sr);
+void ServerRealm_decrease_connectedUsers(ServerRealm* sr);
+void ServerRealm_increase_connectedClients(ServerRealm* sr);
+void ServerRealm_decrease_connectedClients(ServerRealm* sr);
+void ServerRealm_increase_connectedRaClients(ServerRealm* sr);
+void ServerRealm_decrease_connectedRaClients(ServerRealm* sr);
+void ServerRealm_increase_usersCounter(ServerRealm* sr);
+void ServerRealm_increase_clientsCounter(ServerRealm* sr);
+
+#endif
diff --git a/src/server_remoteadmin.c b/src/server_remoteadmin.c
new file mode 100644
index 0000000..1d10520
--- /dev/null
+++ b/src/server_remoteadmin.c
@@ -0,0 +1,762 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+#include <assert.h>
+
+#include "server_remoteadmin.h"
+
+static char newmessage;
+
+/*
+ * Function name: parse_int
+ * Description: This function parses the string as an integer and updates the buffer's
+ * parse pointer.
+ * Arguments: buff - string to parse
+ * ret - buffer's parse pointer
+ * Returns: Parsed integer value or -1, if something went wrong.
+ */
+
+static int
+parse_int(unsigned char* buff, int* ret)
+{
+ int intarg, i;
+ char guard;
+
+ assert(buff != NULL);
+ assert(ret != NULL);
+
+ 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;
+ }
+}
+
+/*
+ * Function name: parse_cmd
+ * Description: This function parses the string as a command and updates the buffer's
+ * parse pointer.
+ * Arguments: buff - string to parse
+ * ret - buffer's parse pointer
+ * Returns: Parsed command number or 0, if something went wrong.
+ */
+
+static int
+parse_cmd(unsigned char* buff, int* ret)
+{
+ int i, j, state;
+ char cmd[31];
+
+ assert(buff != NULL);
+ assert(ret != NULL);
+
+ i = j = state = 0;
+ newmessage = 1;
+ while (buff[i] != 0) {
+ if (state == 1) {
+ if (isspace(buff[i])) {
+ break;
+ }
+ else {
+ if (j == 30) {
+ return 0;
+ }
+ cmd[j] = buff[i];
+ ++j;
+ }
+ }
+ if (state == 0) {
+ if (!isspace(buff[i])) {
+ cmd[j] = buff[i];
+ j = 1;
+ state = 1;
+ }
+ }
+ ++i;
+ }
+ if (state == 0) {
+ return 0;
+ }
+ while (isspace(buff[i])) {
+ ++i;
+ }
+ if (buff[i] == '.') {
+ ++i;
+ }
+ (*ret) = i;
+ cmd[j] = 0;
+ if (strcmp(cmd, "help") == 0) { return 1; }
+ if (strcmp(cmd, "lcmd") == 0) { return 2; }
+ if (strcmp(cmd, "info") == 0) { return 3; }
+ if (strcmp(cmd, "rshow") == 0) { return 4; }
+ 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;
+}
+
+/*
+ * Function name: send_adm_message
+ * Description: Sends the message via the network.
+ * Arguments: type - the type of the connection
+ * master - pointer to SslFd structure
+ * buff - the message to send
+ * st - the result of the command
+ */
+
+static void
+send_adm_message(char type, SslFd* master, unsigned char* buff, unsigned char st)
+{
+ int n;
+
+ assert(master != NULL);
+ assert(buff != NULL);
+
+ if (!newmessage) {
+ n = strlen((char*) &buff[5]);
+ }
+ else {
+ n = 0;
+ }
+ buff[0] = AF_S_ADMIN_CMD;
+ buff[1] = st;
+ buff[2] = AF_RA_UNDEFINED;
+ buff[3] = n >> 8; /* high bits of message length */
+ buff[4] = n; /* low bits of message length */
+ SslFd_send_message(type, master, buff, n+5);
+}
+
+/*
+ * Function name: add_to_message
+ * Description: Adds text to the message.
+ * Arguments: buff - the message we are adding text to
+ * format - the format of the text
+ * ... - additional arguments
+ */
+
+static void
+add_to_message(unsigned char* buff, const char* format, ...)
+{
+ va_list ap;
+ int n;
+
+ assert(buff != NULL);
+ assert(format != NULL);
+
+ if (!newmessage) {
+ n = strlen((char*) &buff[5]);
+ }
+ else {
+ n = 0;
+ }
+ newmessage = 0;
+ va_start(ap, format);
+
+ vsprintf((char*) &buff[5+n], format, ap);
+ n = strlen((char*) &buff[5]);
+ sprintf((char*) &buff[5+n], "\n");
+
+ va_end(ap);
+}
+
+/*
+ * Function name: add_uptime_to_message
+ * Description: Adds the formatted time period to the message.
+ * Arguments: buff - the message we are adding formatted time period to
+ * info - the info which will be added to the message just before the time
+ * period - the time period we are adding to the message
+ */
+
+static void
+add_uptime_to_message(unsigned char* buff, char* info, time_t period)
+{
+ int hours, minutes, seconds;
+
+ assert(buff != NULL);
+ assert(info != NULL);
+
+ hours = period/3600;
+ minutes = (period/60)%60;
+ seconds = period%60;
+
+ if (hours) {
+ add_to_message(buff, "%s: %d:%02d:%02d", info, hours, minutes, seconds);
+ }
+ else {
+ add_to_message(buff, "%s: %d:%02d", info, minutes, seconds);
+ }
+}
+
+/*
+ * Function name: serve_admin
+ * Description: Function responsible for the reaction for user's admin commands.
+ * Arguments: config - the server configuration
+ * realm - the realm number
+ * client - the client number
+ * buff - buffer containing the user's command
+ * Returns: 0 - do nothing,
+ * 1 - kick this client,
+ * >1 - kick the specified client.
+ */
+
+int
+serve_admin(ServerConfiguration* config, int realm, int client, unsigned char* buff)
+{
+ int length, n, i, j, ret;
+ time_t now, tmp;
+ llnodeT* llptr;
+ AuditListNode* alptr;
+ char olddf[51], newdf[51];
+ ConnectClient* cpointer;
+ ConnectUser* upointer;
+ ServerRealm* pointer = ServerConfiguration_get_realmsTable(config)[realm];
+ char type = ServerRealm_get_realmType(pointer) | TYPE_SSL | TYPE_ZLIB;
+ SslFd* master = ConnectClient_get_sslFd(ServerRealm_get_raClientsTable(pointer)[client]);
+
+ assert(config != NULL);
+ assert(buff != NULL);
+
+ olddf[50] = newdf[50] = 0;
+ length = buff[3];
+ length = length << 8;
+ length += buff[4]; /* this is the length of a message */
+
+ time(&now);
+
+ switch (buff[1]) {
+ case AF_RA_CMD: {
+ n = SslFd_get_message(type, master, buff, length);
+ buff[n] = 0;
+ 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, " 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;
+ }
+ case 2: { /* lcmd */
+ add_to_message(buff, "help");
+ add_to_message(buff, "lcmd");
+ add_to_message(buff, "info");
+ add_to_message(buff, "rshow");
+ 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;
+ }
+ case 3: { /* info */
+ add_to_message(buff, AF_VER("Version:"));
+ add_to_message(buff, "Realms: %d",
+ ServerConfiguration_get_realmsNumber(config));
+ add_to_message(buff, "Certificate: %s",
+ ServerConfiguration_get_certificateFile(config));
+ add_to_message(buff, "Key: %s",
+ ServerConfiguration_get_keysFile(config));
+ llptr = getloglisthead();
+ i = 0;
+ while (llptr) {
+ add_to_message(buff, "log[%d]: %s", i, llptr->cmdline);
+ llptr = llptr->next;
+ ++i;
+ }
+ tmp = now - ServerConfiguration_get_startTime(config);
+ 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;
+ }
+ case 4: { /* rshow */
+ for (i = 0; i < ServerConfiguration_get_realmsNumber(config); ++i) {
+ pointer = ServerConfiguration_get_realmsTable(config)[i];
+ add_to_message(buff, "\nRealm[%s]:", get_realmname(config, i));
+ add_to_message(buff, "hostname: %s", ServerRealm_get_hostName(pointer));
+ add_to_message(buff, "users: %d (max: %d)",
+ ServerRealm_get_connectedUsers(pointer),
+ ServerRealm_get_usersLimit(pointer));
+ add_to_message(buff, "clients: %d (max: %d)",
+ ServerRealm_get_connectedClients(pointer) -
+ ServerRealm_get_connectedRaClients(pointer),
+ ServerRealm_get_clientsLimit(pointer));
+ add_to_message(buff, "raclients: %d (max: %d)",
+ ServerRealm_get_connectedRaClients(pointer),
+ ServerRealm_get_raClientsLimit(pointer));
+ add_to_message(buff, "users per client: %s",
+ ServerRealm_get_sUsersPerClient(pointer));
+ add_to_message(buff, "user-client pairs: %d",
+ ServerRealm_get_userClientPairs(pointer));
+ for (j = 0; j < ServerRealm_get_userClientPairs(pointer); ++j) {
+ add_to_message(buff, " pair[%d]: listenport: %s, manageport: %s", j,
+ UsrCli_get_listenPortName(
+ ServerRealm_get_usersClientsTable(pointer)[j]),
+ UsrCli_get_managePortName(
+ ServerRealm_get_usersClientsTable(pointer)[j]));
+ }
+ add_to_message(buff, "climode: %s", ServerRealm_get_sClientMode(pointer));
+ add_to_message(buff, "timeout: %d", ServerRealm_get_timeout(pointer));
+ if (ServerRealm_get_maxIdle(pointer)) {
+ add_to_message(buff, "max idle: %d", ServerRealm_get_maxIdle(pointer));
+ }
+ else {
+ add_to_message(buff, "max idle: disabled");
+ }
+ add_to_message(buff, "baseport: %s", ServerRealm_get_basePortOn(pointer) ?
+ "yes" : "no");
+ add_to_message(buff, "audit: %s", ServerRealm_get_auditOn(pointer) ?
+ "yes" : "no");
+ add_to_message(buff, "dnslookups: %s",
+ ServerRealm_get_dnsLookupsOn(pointer) ? "yes" : "no");
+ add_to_message(buff, "ssl: %s, zlib: %s, mode: %s",
+ (TYPE_IS_SSL(ServerRealm_get_realmType(pointer))) ? "yes" : "no",
+ (TYPE_IS_ZLIB(ServerRealm_get_realmType(pointer))) ? "yes" : "no",
+ (TYPE_IS_TCP(ServerRealm_get_realmType(pointer))) ? "tcp" : "udp");
+ switch (ServerRealm_get_tunnelType(pointer)) {
+ case CONNECTCLIENT_TUNNELTYPE_DIRECT: {
+ add_to_message(buff, "tunneltype: direct");
+ break;
+ }
+ case CONNECTCLIENT_TUNNELTYPE_HTTPPROXY: {
+ add_to_message(buff, "tunneltype: http proxy");
+ break;
+ }
+ case CONNECTCLIENT_TUNNELTYPE_HTTPSPROXY: {
+ add_to_message(buff, "tunneltype: https proxy");
+ break;
+ }
+ default: {
+ add_to_message(buff, "tunneltype: UNKNOWN");
+ }
+ }
+ }
+ send_adm_message(type, master, buff, AF_RA_STATUS_OK);
+ break;
+ }
+ case 5: { /* cshow*/
+ n = get_realmnumber(config, (char*) &buff[ret]);
+ if ((n >= 0) && (n < ServerConfiguration_get_realmsNumber(config))) {
+ pointer = ServerConfiguration_get_realmsTable(config)[n];
+ for (i = 0; i < ServerRealm_get_clientsLimit(pointer); ++i) {
+ cpointer = ServerRealm_get_clientsTable(pointer)[i];
+ if (ConnectClient_get_state(cpointer) != CONNECTCLIENT_STATE_FREE) {
+ add_to_message(buff, "\nClient[%s]:",
+ get_clientname(pointer, i));
+ switch (ConnectClient_get_state(cpointer)) {
+ case CONNECTCLIENT_STATE_CONNECTING: {
+ add_to_message(buff, "state: ssl handshake");
+ break;
+ }
+ case CONNECTCLIENT_STATE_AUTHORIZING: {
+ add_to_message(buff, "state: authorization");
+ break;
+ }
+ case CONNECTCLIENT_STATE_ACCEPTED: {
+ add_to_message(buff, "state: running");
+ break;
+ }
+ default: {
+ add_to_message(buff, "state: unknown");
+ }
+ }
+ add_to_message(buff, "users: %d (max: %d)",
+ ConnectClient_get_connected(cpointer),
+ ConnectClient_get_limit(cpointer));
+ add_to_message(buff, "user-client pair: %d",
+ ConnectClient_get_usrCliPair(cpointer));
+ tmp = now - ConnectClient_get_connectTime(cpointer);
+ add_uptime_to_message(buff, "Connection time", tmp);
+ tmp = now - ConnectClient_get_lastActivity(cpointer);
+ add_uptime_to_message(buff, "Idle time", tmp);
+ add_to_message(buff, "Id: %s",
+ (ConnectClient_get_sClientId(cpointer) == NULL) ? "" :
+ ConnectClient_get_sClientId(cpointer));
+ add_to_message(buff, "Number: %d",
+ ConnectClient_get_clientId(cpointer));
+ add_to_message(buff, "IP: %s, port: %s",
+ ConnectClient_get_nameBuf(cpointer),
+ ConnectClient_get_portBuf(cpointer));
+ switch (ConnectClient_get_tunnelType(cpointer)) {
+ case CONNECTCLIENT_TUNNELTYPE_DIRECT: {
+ add_to_message(buff, "tunneltype: direct");
+ break;
+ }
+ case CONNECTCLIENT_TUNNELTYPE_HTTPPROXY: {
+ add_to_message(buff, "tunneltype: http proxy");
+ break;
+ }
+ case CONNECTCLIENT_TUNNELTYPE_HTTPSPROXY: {
+ add_to_message(buff, "tunneltype: https proxy");
+ break;
+ }
+ default: {
+ add_to_message(buff, "tunneltype: UNKNOWN");
+ }
+ }
+ if (ServerRealm_get_auditOn(pointer)) {
+ add_to_message(buff, "auditlog:");
+ alptr = AuditList_get_first(
+ ConnectClient_get_auditList(cpointer));
+ while (alptr) {
+ add_to_message(buff,
+ "userid: %d ip: %s port: %s connected: %s duration: %s",
+ AuditListNode_get_userId(alptr),
+ AuditListNode_get_nameBuf(alptr),
+ AuditListNode_get_portBuf(alptr),
+ localdate(AuditListNode_get_connectTimep(alptr)),
+ timeperiod(AuditListNode_get_duration(alptr)));
+ alptr = AuditListNode_get_nextNode(alptr);
+ }
+ }
+ }
+ }
+ 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;
+ }
+ case 6: { /* ushow */
+ n = get_realmnumber(config, (char*) &buff[ret]);
+ if ((n >= 0) && (n < ServerConfiguration_get_realmsNumber(config))) {
+ pointer = ServerConfiguration_get_realmsTable(config)[n];
+ for (i = 0; i < ServerRealm_get_usersLimit(pointer); ++i) {
+ upointer = ServerRealm_get_usersTable(pointer)[i];
+ if (ConnectUser_get_state(upointer) != S_STATE_CLEAR) {
+ add_to_message(buff, "\nUser[%d]:",
+ get_username(pointer, i));
+ switch (ConnectUser_get_state(upointer)) {
+ case S_STATE_CLOSING: {
+ add_to_message(buff, "state: closing");
+ break;
+ }
+ case S_STATE_OPENING: {
+ add_to_message(buff, "state: opening");
+ break;
+ }
+ case S_STATE_OPENING_CLOSED: {
+ add_to_message(buff, "state: opening (closed)");
+ break;
+ }
+ case S_STATE_OPEN: {
+ add_to_message(buff, "state: running");
+ break;
+ }
+ case S_STATE_STOPPED: {
+ add_to_message(buff, "state: stopped");
+ break;
+ }
+ default: {
+ add_to_message(buff, "state: unknown");
+ }
+ }
+ add_to_message(buff, "connected to: Client[%s]",
+ get_clientname(pointer, ConnectUser_get_whatClient(upointer)));
+ tmp = now-ConnectUser_get_connectTime(upointer);
+ add_uptime_to_message(buff, "Connection time", tmp);
+ tmp = now - UserStats_get_lastActivity(
+ ConnectUser_get_stats(upointer));
+ add_uptime_to_message(buff, "Idle time", tmp);
+ add_to_message(buff, "IP: %s, port: %s",
+ ConnectUser_get_nameBuf(upointer),
+ ConnectUser_get_portBuf(upointer));
+ add_to_message(buff, "Downloaded: %d bytes",
+ UserStats_get_totalDownloadedBytes(
+ ConnectUser_get_stats(upointer)));
+ add_to_message(buff, "download speed: %.2f B/s",
+ UserStats_get_downloadSpeed(
+ ConnectUser_get_stats(upointer)));
+ add_to_message(buff, "Uploaded: %d bytes",
+ UserStats_get_totalUploadedBytes(
+ ConnectUser_get_stats(upointer)));
+ add_to_message(buff, "upload speed: %.2f B/s",
+ UserStats_get_uploadSpeed(
+ ConnectUser_get_stats(upointer)));
+ }
+ }
+ send_adm_message(type, master, buff, AF_RA_STATUS_OK);
+ 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(LOG_T_MANAGE, LOG_I_INFO,
+ "realm[%s]: Client[%s] (ra): commfd: CLOSED",
+ get_realmname(config, realm),
+ get_raclientname(pointer, 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 < ServerConfiguration_get_realmsNumber(config))) {
+ add_to_message(buff, "changed timeout: %d --> %d",
+ ServerRealm_get_timeout(
+ ServerConfiguration_get_realmsTable(config)[n]), i);
+ ServerRealm_set_timeout(ServerConfiguration_get_realmsTable(config)[n], 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 < ServerConfiguration_get_realmsNumber(config))) {
+ add_to_message(buff, "changed audit: %s --> %s",
+ ServerRealm_get_auditOn(
+ ServerConfiguration_get_realmsTable(config)[n]) ? "yes" : "no",
+ i ? "yes" : "no");
+ ServerRealm_set_auditOn(ServerConfiguration_get_realmsTable(config)[n], i);
+ if (i == 0) {
+ for (i = 0; i < ServerRealm_get_clientsLimit(
+ ServerConfiguration_get_realmsTable(config)[n]); ++i) {
+ AuditList_clear(
+ ConnectClient_get_auditList(
+ ServerRealm_get_clientsTable(
+ ServerConfiguration_get_realmsTable(config)[n])[i]));
+ }
+ }
+ 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 < ServerConfiguration_get_realmsNumber(config))) {
+ add_to_message(buff, "changed dnslookups: %s --> %s",
+ ServerRealm_get_dnsLookupsOn(
+ ServerConfiguration_get_realmsTable(config)[n]) ? "yes" : "no",
+ i ? "yes" : "no");
+ ServerRealm_set_dnsLookupsOn(
+ ServerConfiguration_get_realmsTable(config)[n], 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 < ServerConfiguration_get_realmsNumber(config); ++n) {
+ pointer = ServerConfiguration_get_realmsTable(config)[n];
+ j = get_usernumber(pointer, i);
+ if (j != (-1)) {
+ upointer = ServerRealm_get_usersTable(pointer)[j];
+ if ((ConnectUser_get_state(upointer) == S_STATE_OPEN) ||
+ (ConnectUser_get_state(upointer) == S_STATE_OPENING) ||
+ (ConnectUser_get_state(upointer) == S_STATE_STOPPED)) {
+ add_to_message(buff, "kicked: realm[%s] user[%d]",
+ get_realmname(config, n), get_username(pointer, j));
+ if (ConnectUser_get_state(upointer) == S_STATE_OPENING) {
+ ConnectUser_set_state(upointer, S_STATE_OPENING_CLOSED);
+ }
+ else {
+ close(ConnectUser_get_connFd(upointer));
+ }
+ 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 < ServerConfiguration_get_realmsNumber(config); ++n) {
+ pointer = ServerConfiguration_get_realmsTable(config)[n];
+ j = get_clientnumber(pointer, i);
+ if (j != (-1)) {
+ if (ConnectClient_get_state(ServerRealm_get_clientsTable(pointer)[j]) >
+ CONNECTCLIENT_STATE_FREE) {
+ add_to_message(buff, "kicked: realm[%s] client[%s]",
+ get_realmname(config, n),
+ get_clientname(pointer, 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(LOG_T_MANAGE, LOG_I_WARNING,
+ "realm[%s]: admin: cmd ignored", get_realmname(config, realm));
+ send_adm_message(type, master, buff, AF_RA_UNDEFINED);
+ }
+ }
+ break;
+ }
+ case AF_RA_REPEAT: {
+ break;
+ }
+ default: {
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "Unrecognized message from remote admin --> closing");
+ return 1;
+ }
+ }
+ return 0;
+}
diff --git a/src/server_remoteadmin.h b/src/server_remoteadmin.h
new file mode 100644
index 0000000..4b74b5d
--- /dev/null
+++ b/src/server_remoteadmin.h
@@ -0,0 +1,37 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_SERVER_REMOTEADMIN_H
+#define _JS_SERVER_REMOTEADMIN_H
+
+#include <ctype.h>
+#include <string.h>
+
+#include "remoteadmin_codes.h"
+#include "activefor.h"
+#include "logging.h"
+#include "stats.h"
+#include "clientnames.h"
+#include "realmnames.h"
+#include "usernames.h"
+
+int serve_admin(ServerConfiguration*, int, int, unsigned char*);
+
+#endif
diff --git a/src/server_remove.c b/src/server_remove.c
new file mode 100644
index 0000000..c8f78f1
--- /dev/null
+++ b/src/server_remove.c
@@ -0,0 +1,121 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <assert.h>
+
+#include "server_remove.h"
+
+/*
+ * Function name: remove_client
+ * Description: Removes the client.
+ * Arguments: ptr - the server realm
+ * client - the client number
+ * set - the set of file descriptors for reading
+ * wset - the set of file descriptors for writing
+ * scheduler - the task scheduler
+ */
+
+void
+remove_client(ServerRealm* ptr, int client, fd_set* set, fd_set* wset, TaskScheduler* scheduler)
+{
+ int i;
+ Task* task;
+
+ assert(ptr != NULL);
+ assert(client >= 0);
+ assert(set != NULL);
+ assert(wset != NULL);
+
+ if (ConnectClient_get_state(ServerRealm_get_clientsTable(ptr)[client]) == CONNECTCLIENT_STATE_ACCEPTED) {
+ for (i = 0; i < ServerRealm_get_usersLimit(ptr); ++i) {
+ if (ConnectUser_get_whatClient(ServerRealm_get_usersTable(ptr)[i]) == client) {
+ if (ConnectUser_get_state(ServerRealm_get_usersTable(ptr)[i]) != S_STATE_CLEAR) {
+ ConnectUser_set_state(ServerRealm_get_usersTable(ptr)[i], S_STATE_CLEAR);
+ FD_CLR(ConnectUser_get_connFd(ServerRealm_get_usersTable(ptr)[i]), set);
+ FD_CLR(ConnectUser_get_connFd(ServerRealm_get_usersTable(ptr)[i]), wset);
+ close(ConnectUser_get_connFd(ServerRealm_get_usersTable(ptr)[i]));
+ ServerRealm_decrease_connectedUsers(ptr);
+ }
+ }
+ }
+ }
+ for (i = 0; i < ConnectClient_get_limit(ServerRealm_get_clientsTable(ptr)[client]); ++i) {
+ ConnectClient_get_users(ServerRealm_get_clientsTable(ptr)[client])[i] = -1;
+ }
+ if ((ServerRealm_get_clientsLimit(ptr) != client) && (ServerRealm_get_basePortOn(ptr) == 1)) {
+ close(ConnectClient_get_listenFd(ServerRealm_get_clientsTable(ptr)[client]));
+ FD_CLR(ConnectClient_get_listenFd(ServerRealm_get_clientsTable(ptr)[client]), set);
+ }
+ ConnectClient_set_sClientId(ServerRealm_get_clientsTable(ptr)[client], NULL);
+ ConnectClient_set_connected(ServerRealm_get_clientsTable(ptr)[client], 0);
+ close(SslFd_get_fd(ConnectClient_get_sslFd(ServerRealm_get_clientsTable(ptr)[client])));
+ FD_CLR(SslFd_get_fd(ConnectClient_get_sslFd(ServerRealm_get_clientsTable(ptr)[client])), set);
+ if (scheduler) {
+ if ((task = ConnectClient_get_task(ServerRealm_get_clientsTable(ptr)[client]))) {
+ TaskScheduler_removeTask(scheduler, task);
+ ConnectClient_set_task(ServerRealm_get_clientsTable(ptr)[client], NULL);
+ }
+ }
+ SSL_clear(SslFd_get_ssl(ConnectClient_get_sslFd(ServerRealm_get_clientsTable(ptr)[client])));
+ ConnectClient_set_state(ServerRealm_get_clientsTable(ptr)[client], CONNECTCLIENT_STATE_FREE);
+ ServerRealm_decrease_connectedClients(ptr);
+}
+
+/*
+ * Function name: remove_raclient
+ * Description: Removes the remote admin client.
+ * Arguments: ptr - the server realm
+ * client - the client number
+ * set - the set of file descriptors for reading
+ * wset - the set of file descriptors for writing
+ * scheduler - the task scheduler
+ */
+
+void
+remove_raclient(ServerRealm* ptr, int client, fd_set* set, fd_set* wset, TaskScheduler* scheduler)
+{
+ int i;
+ Task* task;
+
+ assert(ptr != NULL);
+ assert(client >= 0);
+ assert(set != NULL);
+ assert(wset != NULL);
+
+ for (i = 0; i < ConnectClient_get_limit(ServerRealm_get_raClientsTable(ptr)[client]); ++i) {
+ ConnectClient_get_users(ServerRealm_get_raClientsTable(ptr)[client])[i] = -1;
+ }
+ ConnectClient_set_sClientId(ServerRealm_get_raClientsTable(ptr)[client], NULL);
+ ConnectClient_set_connected(ServerRealm_get_raClientsTable(ptr)[client], 0);
+ close(SslFd_get_fd(ConnectClient_get_sslFd(ServerRealm_get_raClientsTable(ptr)[client])));
+ FD_CLR(SslFd_get_fd(ConnectClient_get_sslFd(ServerRealm_get_raClientsTable(ptr)[client])), set);
+ if (scheduler) {
+ if ((task = ConnectClient_get_task(ServerRealm_get_raClientsTable(ptr)[client]))) {
+ TaskScheduler_removeTask(scheduler, task);
+ ConnectClient_set_task(ServerRealm_get_raClientsTable(ptr)[client], NULL);
+ }
+ }
+ SSL_clear(SslFd_get_ssl(ConnectClient_get_sslFd(ServerRealm_get_raClientsTable(ptr)[client])));
+ ServerRealm_decrease_connectedClients(ptr);
+ if (ConnectClient_get_state(ServerRealm_get_raClientsTable(ptr)[client]) == CONNECTCLIENT_STATE_ACCEPTED) {
+ ServerRealm_decrease_connectedRaClients(ptr);
+ }
+ ConnectClient_set_state(ServerRealm_get_raClientsTable(ptr)[client], CONNECTCLIENT_STATE_FREE);
+}
diff --git a/src/server_remove.h b/src/server_remove.h
new file mode 100644
index 0000000..65d4f99
--- /dev/null
+++ b/src/server_remove.h
@@ -0,0 +1,31 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "file.h"
+#include "task_scheduler_struct.h"
+
+#ifndef _JS_SERVER_REMOVE_H
+#define _JS_SERVER_REMOVE_H
+
+void remove_client(ServerRealm*, int, fd_set*, fd_set*, TaskScheduler* scheduler);
+void remove_raclient(ServerRealm*, int, fd_set*, fd_set*, TaskScheduler* scheduler);
+
+#endif
+
diff --git a/src/server_set.c b/src/server_set.c
new file mode 100644
index 0000000..07fa069
--- /dev/null
+++ b/src/server_set.c
@@ -0,0 +1,48 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "string_functions.h"
+
+/*
+ * Function name: set_value
+ * Description: If the variable has no value, set it from the given string.
+ * If the given string is NULL, use default value.
+ * Arguments: dest - the destination variable
+ * from - the given string
+ * def - the default value
+ */
+
+void
+set_value(char** dest, char* from, char* def)
+{
+ assert(dest != NULL);
+
+ if ((*dest) == NULL) {
+ if (from != NULL) {
+ string_cp(dest, from);
+ }
+ else {
+ (*dest) = def;
+ }
+ }
+}
diff --git a/src/server_set.h b/src/server_set.h
new file mode 100644
index 0000000..7d74de9
--- /dev/null
+++ b/src/server_set.h
@@ -0,0 +1,27 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_SERVER_SET_H
+#define _JS_SERVER_SET_H
+
+void set_value(char** dest, char* from, char* def);
+
+#endif
+
diff --git a/src/server_signals.c b/src/server_signals.c
new file mode 100644
index 0000000..00f69bd
--- /dev/null
+++ b/src/server_signals.c
@@ -0,0 +1,86 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "server_signals.h"
+#include "activefor.h"
+#include "thread_management.h"
+#include "http_proxy_functions.h"
+#include "stats.h"
+#include "logging.h"
+#include "server_configuration_struct.h"
+
+extern ServerConfiguration* config;
+
+/*
+ * Function name: server_sig_int
+ * Description: Function responsible for handling SIG_INT.
+ * Arguments: signo - the signal number
+ */
+
+void
+server_sig_int(int signo)
+{
+ int i, j;
+ unsigned char buff[5];
+ ServerRealm** scRealmsTable;
+
+#ifdef HAVE_LIBPTHREAD
+ if (!is_this_a_mainthread()) {
+ return;
+ }
+#endif
+
+ for (j = 0; j < ServerConfiguration_get_realmsNumber(config); ++j) {
+ scRealmsTable = ServerConfiguration_get_realmsTable(config);
+ buff[0] = AF_S_CLOSING; /* closing */
+ for (i = 0; i < ServerRealm_get_clientsLimit(scRealmsTable[j]); ++i) {
+ if (ConnectClient_get_state(ServerRealm_get_clientsTable(scRealmsTable[j])[i]) ==
+ CONNECTCLIENT_STATE_ACCEPTED) {
+ SslFd_send_message(ServerRealm_get_realmType(scRealmsTable[j]),
+ ConnectClient_get_sslFd(
+ ServerRealm_get_clientsTable(scRealmsTable[j])[i]),
+ buff, 5);
+ close(SslFd_get_fd(ConnectClient_get_sslFd(
+ ServerRealm_get_clientsTable(scRealmsTable[j])[i])));
+ }
+ }
+ for (i = 0; i < ServerRealm_get_raClientsLimit(scRealmsTable[j]); ++i) {
+ if (ConnectClient_get_state(ServerRealm_get_raClientsTable(scRealmsTable[j])[i]) ==
+ CONNECTCLIENT_STATE_ACCEPTED) {
+ SslFd_send_message(ServerRealm_get_realmType(scRealmsTable[j]) | TYPE_SSL,
+ ConnectClient_get_sslFd(
+ ServerRealm_get_raClientsTable(scRealmsTable[j])[i]),
+ buff, 5);
+ close(SslFd_get_fd(ConnectClient_get_sslFd(ServerRealm_get_raClientsTable(scRealmsTable[j])[i])));
+ }
+ }
+
+ }
+
+ /* 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..7a55a1c
--- /dev/null
+++ b/src/server_signals.h
@@ -0,0 +1,27 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#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/ssl_fd_struct.c b/src/ssl_fd_struct.c
new file mode 100644
index 0000000..056f089
--- /dev/null
+++ b/src/ssl_fd_struct.c
@@ -0,0 +1,329 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+#include <zlib.h>
+#include <assert.h>
+
+#include "activefor.h"
+#include "stats.h"
+#include "logging.h"
+#include "ssl_fd_struct.h"
+
+/*
+ * Function name: SslFd_new
+ * Description: Create and initialize new SslFd structure.
+ * Returns: Pointer to newly created SslFd structure.
+ */
+
+SslFd*
+SslFd_new()
+{
+ SslFd* tmp = calloc(1, sizeof(SslFd));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ return tmp;
+}
+
+/*
+ * Function name: SslFd_free
+ * Description: Free the memory allocated for SslFd structure.
+ * Arguments: sf - pointer to pointer to SslFd structure
+ */
+
+void
+SslFd_free(SslFd** sf)
+{
+ assert(sf != NULL);
+ if (sf == NULL) {
+ return;
+ }
+ assert((*sf) != NULL);
+ if ((*sf) == NULL) {
+ return;
+ }
+ if ((*sf)->ssl) {
+ SSL_free((*sf)->ssl);
+ (*sf)->ssl = NULL;
+ }
+ free((*sf));
+ (*sf) = NULL;
+}
+
+/*
+ * Function name: SslFd_set_fd
+ * Description: Set file descriptor of the used socket.
+ * Arguments: sf - pointer to SslFd structure
+ * fd - file descriptor of the used socket
+ */
+
+void
+SslFd_set_fd(SslFd* sf, int fd)
+{
+ assert(sf != NULL);
+ if (sf == NULL) {
+ return;
+ }
+ sf->fd = fd;
+}
+
+/*
+ * Function name: SslFd_set_ssl_general
+ * Description: Set ssl object for the used socket. Free previous ssl object if 'free' argument is not 0.
+ * Arguments: sf - pointer to SslFd structure
+ * fd - ssl object for the used socket
+ * free - free previous ssl object
+ */
+
+void
+SslFd_set_ssl_general(SslFd* sf, SSL* ssl, int free)
+{
+ assert(sf != NULL);
+ if (sf == NULL) {
+ return;
+ }
+ if ((free) && (sf->ssl)) {
+ SSL_free(sf->ssl);
+ }
+ sf->ssl = ssl;
+}
+
+
+/*
+ * Function name: SslFd_set_ssl
+ * Description: Set ssl object for the used socket.
+ * Arguments: sf - pointer to SslFd structure
+ * fd - ssl object for the used socket
+ */
+
+void
+SslFd_set_ssl(SslFd* sf, SSL* ssl)
+{
+ SslFd_set_ssl_general(sf, ssl, 1);
+}
+
+/*
+ * Function name: SslFd_set_ssl_nf
+ * Description: Set ssl object for the used socket. Don't free previous ssl object
+ * Arguments: sf - pointer to SslFd structure
+ * fd - ssl object for the used socket
+ */
+
+void
+SslFd_set_ssl_nf(SslFd* sf, SSL* ssl)
+{
+ SslFd_set_ssl_general(sf, ssl, 0);
+}
+
+/*
+ * Function name: SslFd_set_ssl
+ * Description: Get file descriptor of the used socket.
+ * Arguments: sf - pointer to SslFd structure
+ * Returns: File descriptor of the used socket.
+ */
+
+int
+SslFd_get_fd(SslFd* sf)
+{
+ assert(sf != NULL);
+ if (sf == NULL) {
+ return -1;
+ }
+ return sf->fd;
+}
+
+/*
+ * Function name: SslFd_get_ssl
+ * Description: Get ssl object for the used socket.
+ * Arguments: sf - pointer to SslFd structure
+ * Returns: Ssl object for the used socket.
+ */
+
+SSL*
+SslFd_get_ssl(SslFd* sf)
+{
+ assert(sf != NULL);
+ if (sf == NULL) {
+ return NULL;
+ }
+ return sf->ssl;
+}
+
+/*
+ * Function name: SslFd_send_message
+ * Description: Send message from 'buf' of the length 'amount' to the socket
+ * encapsulated in SslFd structure. 'type' is used to keep
+ * information about ip family, using of ssl, using of zlib and more.
+ * Arguments: type - type of the connection
+ * sf - pointer to SslFd structure
+ * buf - buffer which keeps data to send
+ * amount - amount of data to send
+ * Returns: Amount of bytes written or -1, if some error occured.
+ */
+
+int
+SslFd_send_message(char type, SslFd* sf, unsigned char* buf, int amount)
+{
+ unsigned long clen;
+ int length;
+ static unsigned char buffer[9000];
+
+ assert(sf != NULL);
+ assert(buf != NULL);
+
+ if ((sf == NULL) || (buf == NULL)) {
+ return -1;
+ }
+
+ 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;
+ if (TYPE_IS_ZLIB(type)) {
+ memcpy(buffer, buf, 5);
+ if (amount > 5) {
+ compress(&buffer[5], &clen, &buf[5], length);
+ if (clen < length) {
+ length = clen;
+ TYPE_SET_COMP(length);
+ buffer[3] = length >> 8; /* high bits of message length */
+ buffer[4] = length; /* low bits of message length */
+ addtocg(amount-5 - clen);
+ }
+ }
+ if (TYPE_IS_SSL(type)) {
+ if (TYPE_IS_COMP(length)) {
+ return SSL_writen(sf->ssl, buffer, clen+5);
+ }
+ else {
+ return SSL_writen(sf->ssl, buf, amount);
+ }
+ }
+ else {
+ if (TYPE_IS_COMP(length)) {
+ return writen(sf->fd, buffer, clen+5);
+ }
+ else {
+ return writen(sf->fd, buf, amount);
+ }
+ }
+ }
+ else {
+ if (TYPE_IS_SSL(type)) {
+ return SSL_writen(sf->ssl, buf, amount);
+ }
+ else {
+ return writen(sf->fd, buf, amount);
+ }
+ }
+}
+
+/*
+ * Function name: SslFd_get_message
+ * Description: Get message from the socket encapsulated in SslFd structure
+ * and write it to the 'buf'. Message is 'amount' butes long.
+ * 'type' is used to keep information about ip family, using of
+ * ssl, using of zlib and more.
+ * Arguments: type - type of the connection
+ * sf - pointer to SslFd structure
+ * buf - buffer which will keep received data
+ * amount - length of the message to receive
+ * Returns: Amount of bytes received or -1, if some error occured.
+ */
+
+int
+SslFd_get_message(char type, SslFd* sf, unsigned char* buf, int amount)
+{
+ int length;
+ unsigned long elen;
+ static unsigned char bufor[9000];
+
+ assert(sf != NULL);
+ assert(buf != NULL);
+
+ if ((sf == NULL) || (buf == NULL)) {
+ return -1;
+ }
+ 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 < 0) {
+ if (TYPE_IS_SSL(type)) {
+ return SSL_read(sf->ssl, buf, -amount);
+ }
+ else {
+ return read(sf->fd, buf, -amount);
+ }
+ }
+ if (TYPE_IS_ZLIB(type)) {
+ if (TYPE_IS_SSL(type)) {
+ length = SSL_readn(sf->ssl, bufor, amount&0xBFFF);
+ }
+ else {
+ length = readn(sf->fd, bufor, amount&0xBFFF);
+ }
+ if (length <= 0) return length;
+ elen = 8096;
+ if (TYPE_IS_COMP(amount)) {
+ uncompress(buf, &elen, bufor, length);
+ }
+ else {
+ memcpy(buf, bufor, length);
+ elen = length;
+ }
+ return elen;
+ }
+ else
+ {
+ if (TYPE_IS_SSL(type)) {
+ return SSL_readn(sf->ssl, buf, amount);
+ }
+ else {
+ return readn(sf->fd, buf, amount);
+ }
+ }
+}
+
+/*
+ * Function name: SslFd_swap_content
+ * Description: Swap the content of two SslFd structures.
+ * Arguments: sf1 - first pointer to SslFd structure
+ * sf2 - second pointer to SslFd structure
+ */
+
+void
+SslFd_swap_content(SslFd* sf1, SslFd* sf2)
+{
+ int tmpfd;
+ SSL* tmpssl;
+
+ assert(sf1 != NULL);
+ assert(sf2 != NULL);
+
+ tmpfd = SslFd_get_fd(sf1);
+ tmpssl = SslFd_get_ssl(sf2);
+ SslFd_set_fd(sf1, SslFd_get_fd(sf2));
+ SslFd_set_ssl(sf1, SslFd_get_ssl(sf2));
+ SslFd_set_fd(sf2, tmpfd);
+ SslFd_set_ssl(sf2, tmpssl);
+}
diff --git a/src/ssl_fd_struct.h b/src/ssl_fd_struct.h
new file mode 100644
index 0000000..da3cc3f
--- /dev/null
+++ b/src/ssl_fd_struct.h
@@ -0,0 +1,48 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef _JS_SSL_FD_STRUCT_H
+#define _JS_SSL_FD_STRUCT_H
+
+#include <openssl/ssl.h>
+
+typedef struct {
+ int fd;
+ SSL* ssl;
+} SslFd;
+
+/* 'constructor' */
+SslFd* SslFd_new();
+/* 'destructor' */
+void SslFd_free(SslFd** sf);
+/* setters */
+void SslFd_set_fd(SslFd* sf, int fd);
+void SslFd_set_ssl(SslFd* sf, SSL* ssl);
+void SslFd_set_ssl_nf(SslFd* sf, SSL* ssl);
+/* getters */
+int SslFd_get_fd(SslFd* sf);
+SSL* SslFd_get_ssl(SslFd* sf);
+/* other */
+int SslFd_send_message(char type, SslFd* sf, unsigned char* buf, int amount);
+int SslFd_get_message(char type, SslFd* sf, unsigned char* buf, int amount);
+void SslFd_swap_content(SslFd* sf1, SslFd* sf2);
+
+#endif
diff --git a/src/ssl_routines.c b/src/ssl_routines.c
new file mode 100644
index 0000000..7275e92
--- /dev/null
+++ b/src/ssl_routines.c
@@ -0,0 +1,108 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "ssl_routines.h"
+
+/*
+ * Function name: check_public_key
+ * Description: Checks if the public key is trusted.
+ * Arguments: filename - the name of the file with stored keys
+ * hostname - the name of the host
+ * keyhash - the hash of the key
+ * Returns: The result of the check.
+ */
+
+int
+check_public_key(char* filename, char* hostname, char* keyhash)
+{
+ FILE* storefile;
+ char buff[256];
+ int lspaceind, i;
+
+ assert(filename != NULL);
+ assert(hostname != NULL);
+ assert(keyhash != NULL);
+
+ memset(buff, 0, 256);
+
+ storefile = fopen(filename, "r");
+ if (storefile == NULL) {
+ return SSL_PUBLIC_KEY_NOT_KNOWN;
+ }
+
+ while (fgets(buff, 256, storefile) != NULL) {
+ lspaceind = -1;
+ for (i = 0; i < 256; ++i) {
+ if (buff[i] == 0) {
+ break;
+ }
+ if (buff[i] == ' ') {
+ lspaceind = i;
+ }
+ }
+ if (lspaceind == -1) {
+ continue;
+ }
+ if (buff[strlen(buff)-1] == '\n') {
+ buff[strlen(buff)-1] = 0;
+ }
+ buff[lspaceind] = 0;
+ if (strcmp(buff, hostname) == 0) {
+ if (strcmp(&buff[lspaceind+1], keyhash) == 0) {
+ return SSL_PUBLIC_KEY_VALID;
+ }
+ else {
+ return SSL_PUBLIC_KEY_INVALID;
+ }
+ }
+ }
+ return SSL_PUBLIC_KEY_NOT_KNOWN;
+}
+
+/*
+ * Function name: add_public_key
+ * Description: Adds the key to the store file.
+ * Arguments: filename - the name of the file with stored keys
+ * hostname - the name of the host
+ * keyhash - the hash of the key
+ */
+
+void
+add_public_key(char* filename, char* hostname, char* keyhash)
+{
+ FILE* storefile;
+
+ assert(filename != NULL);
+ assert(hostname != NULL);
+ assert(keyhash != NULL);
+
+ storefile = fopen(filename, "a");
+ if (storefile == NULL) {
+ return;
+ }
+ fprintf(storefile, "%s %s\n", hostname, keyhash);
+ fclose(storefile);
+}
diff --git a/src/ssl_routines.h b/src/ssl_routines.h
new file mode 100644
index 0000000..77a2fff
--- /dev/null
+++ b/src/ssl_routines.h
@@ -0,0 +1,34 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#define SSL_PUBLIC_KEY_INVALID 0
+#define SSL_PUBLIC_KEY_VALID 1
+#define SSL_PUBLIC_KEY_NOT_KNOWN 2
+
+#ifndef _JS_SSL_ROUTINES_H
+#define _JS_SSL_ROUTINES_H
+
+/* check if hostname and keyhash is known */
+int check_public_key(char* filename, char* hostname, char* keyhash);
+/* add hostname and keyhash to known_hosts file */
+void add_public_key(char* filename, char* hostname, char* keyhash);
+
+#endif
+
diff --git a/src/stats.c b/src/stats.c
new file mode 100644
index 0000000..91f2611
--- /dev/null
+++ b/src/stats.c
@@ -0,0 +1,87 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "stats.h"
+
+static signed long compressgained;
+
+/*
+ * Function name: timeperiod
+ * Description: Returns the formatted time period string.
+ * Arguments: period - the time period
+ * Returns: The formatted time period string.
+ */
+
+char*
+timeperiod(time_t period)
+{
+ int hours, minutes, seconds;
+ static char timeper[41];
+ memset(timeper, 0, 41);
+
+ 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;
+}
+
+/*
+ * Function name: addtocg
+ * Description: Adds the given number to the bytes gained by the use of compression.
+ * Arguments: amount - the number to add
+ */
+
+void
+addtocg(int amount)
+{
+ compressgained += amount;
+}
+
+/*
+ * Function name: getcg
+ * Description: Returns the number of bytes gained by the use of compression.
+ * Returns: The number of bytes gained by the use of compression.
+ */
+
+signed long
+getcg(void)
+{
+ return compressgained;
+}
+
+/*
+ * Function name: resetcg
+ * Description: Resets the counter of bytes gained by the use of compression.
+ */
+
+void
+resetcg(void)
+{
+ compressgained = 0;
+}
diff --git a/src/stats.h b/src/stats.h
new file mode 100644
index 0000000..009b047
--- /dev/null
+++ b/src/stats.h
@@ -0,0 +1,38 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <time.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifndef _JS_STATS_H
+#define _JS_STATS_H
+
+ /* return time period description */
+char* timeperiod(time_t period);
+ /* add amount to compressgained value */
+void addtocg(int amount);
+ /* reset the compressgained value */
+void resetcg(void);
+ /* returns the compressgained value */
+signed long getcg(void);
+
+#endif
+
diff --git a/src/string_functions.c b/src/string_functions.c
new file mode 100644
index 0000000..bcf42ae
--- /dev/null
+++ b/src/string_functions.c
@@ -0,0 +1,72 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "string_functions.h"
+
+/*
+ * Function name: string_cp
+ * Description: Firstly, the memory allocated for *dest is released. After this, new memory is allocated
+ * and string from src is copied to newly created location. *dest is pointing to new string.
+ * Arguments: dest - pointer to pointer to string previously allocated by malloc family functions.
+ * If dest is NULL, memory will be allocated and returned from the function. In the
+ * latter case dest will be unchanged
+ * src - string containing data for copying. If src is NULL, new memory is not allocated, but
+ * the old one is still released.
+ * Returns: The newly allocated string.
+ */
+
+char*
+string_cp(char** dest, char* src)
+{
+ char* tmp;
+ int len = 0;
+
+ /* 1. releasing memory allocated by *dest */
+ if (dest != NULL) {
+ if ((*dest) != NULL) {
+ /* if *dest points to the same memory as src - we shouldn't do anything */
+ if ((*dest) == src) {
+ return (*dest);
+ }
+ free((*dest));
+ (*dest) = NULL;
+ }
+ }
+ /* if src is null, there is nothing more to do */
+ if (src == NULL) {
+ return NULL;
+ }
+ /* 2. allocating new memory */
+ len = strlen(src);
+ tmp = calloc(1, len + 1);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ /* 3. copying data from src */
+ strncpy(tmp, src, len);
+ if (dest != NULL) {
+ (*dest) = tmp;
+ }
+ return tmp;
+}
diff --git a/src/string_functions.h b/src/string_functions.h
new file mode 100644
index 0000000..914935c
--- /dev/null
+++ b/src/string_functions.h
@@ -0,0 +1,27 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_STRING_FUNCTIONS_H
+#define _JS_STRING_FUNCTIONS_H
+
+char* string_cp(char** dest, char* src);
+
+#endif
+
diff --git a/src/task_list_node_struct.c b/src/task_list_node_struct.c
new file mode 100644
index 0000000..eb80369
--- /dev/null
+++ b/src/task_list_node_struct.c
@@ -0,0 +1,124 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "task_list_node_struct.h"
+
+/*
+ * Function name: TaskListNode_new
+ * Description: Creates and initializes new task list node. The task must point
+ * at previously allocated Task structure.
+ * Arguments: task - pointer to Task structure, which must be previously initialized
+ * Returns: Pointer to newly created TaskListNode structure.
+ */
+
+TaskListNode*
+TaskListNode_new(Task* task)
+{
+ TaskListNode* tmp = calloc(1, sizeof(TaskListNode));
+ assert(task != NULL);
+ if (task == NULL) {
+ return NULL;
+ }
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ tmp->task = task;
+
+ return tmp;
+}
+
+/*
+ * Function name: TaskListNode_free
+ * Description: Frees the memory allocated for TaskListNode structure.
+ * Arguments: node - pointer to pointer to TaskListNode structure
+ */
+
+void
+TaskListNode_free(TaskListNode** node)
+{
+ assert(node != NULL);
+ if (node == NULL) {
+ return;
+ }
+ assert((*node) != NULL);
+ if ((*node) == NULL) {
+ return;
+ }
+
+ free((*node));
+ (*node) = NULL;
+}
+
+/*
+ * Function name: TaskListNode_set_next
+ * Description: Sets the next pointer of the task list node.
+ * Arguments: node - pointer to TaskListNode structure
+ * next - the new next pointer
+ */
+
+void
+TaskListNode_set_next(TaskListNode* node, TaskListNode* next)
+{
+ assert(node != NULL);
+ if (node == NULL) {
+ return;
+ }
+ node->next = next;
+}
+
+/*
+ * Function name: TaskListNode_set_previous
+ * Description: Sets the previous pointer of the task list node.
+ * Arguments: node - pointer to TaskListNode structure
+ * next - the new previous pointer
+ */
+
+void
+TaskListNode_set_previous(TaskListNode* node, TaskListNode* previous)
+{
+ assert(node != NULL);
+ if (node == NULL) {
+ return;
+ }
+ node->previous = previous;
+}
+
+/*
+ * Function name: TaskListNode_get_task
+ * Description: Returns the task contained in this node.
+ * Arguments: node - pointer to TaskListNode structure
+ * Returns: The task contained in this node.
+ */
+
+Task*
+TaskListNode_get_task(TaskListNode* node)
+{
+ assert(node != NULL);
+ if (node == NULL) {
+ return NULL;
+ }
+ return node->task;
+}
diff --git a/src/task_list_node_struct.h b/src/task_list_node_struct.h
new file mode 100644
index 0000000..4588f13
--- /dev/null
+++ b/src/task_list_node_struct.h
@@ -0,0 +1,42 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_TASK_LIST_NODE_STRUCT_H
+#define _JS_TASK_LIST_NODE_STRUCT_H
+
+#include "task_struct.h"
+
+typedef struct tlnode{
+ Task* task;
+ struct tlnode* previous;
+ struct tlnode* next;
+} TaskListNode;
+
+/* 'constructor' */
+TaskListNode* TaskListNode_new(Task* task);
+/* 'destructor' */
+void TaskListNode_free(TaskListNode** node);
+/* setters */
+void TaskListNode_set_next(TaskListNode* node, TaskListNode* next);
+void TaskListNode_set_previous(TaskListNode* node, TaskListNode* previous);
+/* getters */
+Task* TaskListNode_get_task(TaskListNode* node);
+
+#endif
diff --git a/src/task_scheduler_struct.c b/src/task_scheduler_struct.c
new file mode 100644
index 0000000..99b22bb
--- /dev/null
+++ b/src/task_scheduler_struct.c
@@ -0,0 +1,321 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "timeval_functions.h"
+#include "task_scheduler_struct.h"
+
+/*
+ * Function name: TaskScheduler_new
+ * Description: Creates and initializes task scheduler.
+ * Returns: Pointer to newly created TaskScheduler structure.
+ */
+
+TaskScheduler*
+TaskScheduler_new()
+{
+ TaskScheduler* tmp = calloc(1, sizeof(TaskScheduler));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+
+ return tmp;
+}
+
+/*
+ * Function name: TaskScheduler_free
+ * Description: Frees the memory allocated for TaskScheduler structure.
+ * Arguments: scheduler - pointer to pointer to TaskScheduler structure
+ */
+
+void
+TaskScheduler_free(TaskScheduler** scheduler)
+{
+ assert(scheduler != NULL);
+ if (scheduler == NULL) {
+ return;
+ }
+ assert((*scheduler) != NULL);
+ if ((*scheduler) == NULL) {
+ return;
+ }
+
+ while ((*scheduler)->head) {
+ TaskScheduler_removeTask((*scheduler), TaskListNode_get_task((*scheduler)->head));
+ }
+
+ free((*scheduler));
+ (*scheduler) = NULL;
+}
+
+/*
+ * Function name: TaskScheduler_get_actualTimer
+ * Description: Returns the smallest timeval structure in the scheduler.
+ * Arguments: scheduler - pointer to TaskScheduler structure
+ * Returns: The smallest timeval structure in the scheduler.
+ */
+
+struct timeval*
+TaskScheduler_get_actualTimer(TaskScheduler* scheduler)
+{
+ assert(scheduler != NULL);
+ if (scheduler == NULL) {
+ return NULL;
+ }
+ return Task_get_timer(TaskListNode_get_task(scheduler->actualTask));
+}
+
+/*
+ * Function name: TaskScheduler_hasMoreTasks
+ * Description: Checks if there is more tasks in the scheduler.
+ * Arguments: scheduler - pointer to TaskScheduler structure
+ * Returns: 0 - there is no more tasks in the scheduler,
+ * n>0 - there is more (n) tasks in the scheduler.
+ */
+
+int
+TaskScheduler_hasMoreTasks(TaskScheduler* scheduler)
+{
+ assert(scheduler != NULL);
+ if (scheduler == NULL) {
+ return 0;
+ }
+ return scheduler->numberOfTasks;
+}
+
+/*
+ * Function name: TaskScheduler_addTask
+ * Description: Adds the task to the scheduler.
+ * Arguments: scheduler - pointer to TaskScheduler structure
+ * task - the task to add to the scheduler
+ * Returns: 0 - the task has been added successfully,
+ * 1 - the task has NOT been added.
+ */
+
+int
+TaskScheduler_addTask(TaskScheduler* scheduler, Task* task)
+{
+ TaskListNode* tmp;
+ assert(scheduler != NULL);
+ if (scheduler == NULL) {
+ return 1;
+ }
+ assert(task != NULL);
+ if (task == NULL) {
+ return 1;
+ }
+ tmp = TaskListNode_new(task);
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return 1;
+ }
+ if (scheduler->head) {
+ TaskListNode_set_next(tmp, scheduler->head);
+ TaskListNode_set_previous(scheduler->head, tmp);
+ }
+ scheduler->head = tmp;
+ scheduler->numberOfTasks += 1;
+ if (scheduler->actualTask) {
+ if (timeval_compare(TaskScheduler_get_actualTimer(scheduler), Task_get_timer(task)) > 0) {
+ scheduler->actualTask = tmp;
+ }
+ }
+ else {
+ scheduler->actualTask = tmp;
+ }
+ return 0;
+}
+
+/*
+ * Function name: find_tasknode_with_minimal_timer
+ * Description: Finds the task list node with minimal timer.
+ * Arguments: scheduler - pointer to TaskScheduler structure
+ * Returns: The task list node with minimal timer.
+ */
+static TaskListNode*
+find_tasknode_with_minimal_timer(TaskScheduler* scheduler)
+{
+ TaskListNode* iterator;
+ TaskListNode* candidate;
+ assert(scheduler != NULL);
+ if (scheduler == NULL) {
+ return NULL;
+ }
+ if (scheduler->head == NULL) {
+ return NULL;
+ }
+ candidate = scheduler->head;
+ iterator = scheduler->head;
+ iterator = iterator->next;
+ while (iterator) {
+ if (timeval_compare(Task_get_timer(TaskListNode_get_task(iterator)),
+ Task_get_timer(TaskListNode_get_task(candidate))) == -1) {
+ candidate = iterator;
+ }
+ iterator = iterator->next;
+ }
+ return candidate;
+}
+
+/*
+ * Function name: TaskScheduler_removeTask
+ * Description: Removes the task from the scheduler.
+ * Arguments: scheduler - pointer to TaskScheduler structure
+ * task - the task to remove from the scheduler
+ * Returns: 0 - the task has been removed successfully,
+ * 1 - the task has NOT been removed (probably there was no such task in the scheduler).
+ */
+
+int
+TaskScheduler_removeTask(TaskScheduler* scheduler, Task* task)
+{
+ TaskListNode* iterator;
+ Task* tmp;
+ assert(scheduler != NULL);
+ if (scheduler == NULL) {
+ return 1;
+ }
+ assert(task != NULL);
+ if (task == NULL) {
+ return 1;
+ }
+ iterator = scheduler->head;
+ while (iterator) {
+ tmp = TaskListNode_get_task(iterator);
+ if (tmp == task) {
+ if (iterator->previous) {
+ TaskListNode_set_next(iterator->previous, iterator->next);
+ }
+ if (iterator->next) {
+ TaskListNode_set_previous(iterator->next, iterator->previous);
+ }
+ if (iterator == scheduler->head) {
+ scheduler->head = iterator->next;
+ }
+ if (iterator == scheduler->actualTask) {
+ scheduler->actualTask = find_tasknode_with_minimal_timer(scheduler);
+ }
+ scheduler->numberOfTasks -= 1;
+ TaskListNode_free(&iterator);
+ return 0;
+ }
+ iterator = iterator->next;
+ }
+ return 1;
+}
+
+/*
+ * Function name: TaskScheduler_startWatching
+ * Description: Starts counting the time for the actual timer.
+ * Arguments: scheduler - pointer to TaskScheduler structure
+ * Returns: 0 - success,
+ * 1 - failure.
+ */
+
+int
+TaskScheduler_startWatching(TaskScheduler* scheduler)
+{
+ struct timeval* tmp;
+ assert(scheduler != NULL);
+ if (scheduler == NULL) {
+ return 1;
+ }
+ tmp = TaskScheduler_get_actualTimer(scheduler);
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return 1;
+ }
+ scheduler->delta = *tmp;
+ return 0;
+}
+
+/*
+ * Function name: TaskScheduler_stopWatching
+ * Description: Stops counting the time for the actual timer.
+ * Updates all the timers and destroys them if needed.
+ * Arguments: scheduler - pointer to TaskScheduler structure
+ * Returns: 0 - success,
+ * 1 - failure.
+ */
+
+int
+TaskScheduler_stopWatching(TaskScheduler* scheduler)
+{
+ TaskListNode* iterator;
+ TaskListNode* actualTask;
+ Task* backup;
+ struct timeval* tmp;
+ int result;
+ assert(scheduler != NULL);
+ if (scheduler == NULL) {
+ return 1;
+ }
+ tmp = TaskScheduler_get_actualTimer(scheduler);
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return 1;
+ }
+ if (timeval_subtract(&(scheduler->delta), tmp)) {
+ return 1;
+ }
+ actualTask = scheduler->actualTask;
+ assert(scheduler->actualTask != NULL);
+ iterator = scheduler->head;
+ while (iterator) {
+ if (iterator != actualTask) {
+ result = timeval_subtract(Task_get_timer(TaskListNode_get_task(iterator)), &(scheduler->delta));
+ assert(result == 0);
+ }
+ if (timeval_lq_zero(Task_get_timer(TaskListNode_get_task(iterator)))) {
+ Task_exec(TaskListNode_get_task(iterator));
+ backup = TaskListNode_get_task(iterator);
+ iterator = iterator->next;
+ TaskScheduler_removeTask(scheduler, backup);
+ continue;
+ }
+ iterator = iterator->next;
+ }
+ TaskScheduler_update(scheduler);
+ return 0;
+}
+
+/*
+ * Function name: TaskScheduler_update
+ * Description: Updates the actual timer.
+ * Arguments: scheduler - pointer to TaskScheduler structure
+ * Returns: 0 - success,
+ * 1 - failure.
+ */
+
+int
+TaskScheduler_update(TaskScheduler* scheduler)
+{
+ assert(scheduler != NULL);
+ if (scheduler == NULL) {
+ return 1;
+ }
+ scheduler->actualTask = find_tasknode_with_minimal_timer(scheduler);
+ return 0;
+}
diff --git a/src/task_scheduler_struct.h b/src/task_scheduler_struct.h
new file mode 100644
index 0000000..d62405a
--- /dev/null
+++ b/src/task_scheduler_struct.h
@@ -0,0 +1,47 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_TASK_SCHEDULER_STRUCT_H
+#define _JS_TASK_SCHEDULER_STRUCT_H
+
+#include "task_list_node_struct.h"
+
+typedef struct {
+ TaskListNode* head;
+ int numberOfTasks;
+ TaskListNode* actualTask;
+ struct timeval delta;
+} TaskScheduler;
+
+/* 'constructor' */
+TaskScheduler* TaskScheduler_new();
+/* 'destructor' */
+void TaskScheduler_free(TaskScheduler** scheduler);
+/* getters */
+struct timeval* TaskScheduler_get_actualTimer(TaskScheduler* scheduler);
+/* other */
+int TaskScheduler_hasMoreTasks(TaskScheduler* scheduler);
+int TaskScheduler_addTask(TaskScheduler* scheduler, Task* task);
+int TaskScheduler_removeTask(TaskScheduler* scheduler, Task* task);
+int TaskScheduler_startWatching(TaskScheduler* scheduler);
+int TaskScheduler_stopWatching(TaskScheduler* scheduler);
+int TaskScheduler_update(TaskScheduler* scheduler);
+
+#endif
diff --git a/src/task_struct.c b/src/task_struct.c
new file mode 100644
index 0000000..283bbe8
--- /dev/null
+++ b/src/task_struct.c
@@ -0,0 +1,122 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "task_struct.h"
+
+/*
+ * Function name: Task_new
+ * Description: Creates and initializes new task. User is responsible for
+ * allocating/freeing memory pointed by the pointers.
+ * Arguments: timerp - pointer to timeval structure used to counte time (required)
+ * function - pointer to function executed when the time is out (optional)
+ * data - pointer to data passed to function executed when the time is out (optional)
+ * clean - pointer to function that frees the data
+ * Returns: Pointer to newly created Task structure.
+ */
+
+Task*
+Task_new(struct timeval* timerp, void (*function)(void*), void* data, void (*clean)(void**))
+{
+ Task* tmp;
+ assert(timerp != NULL);
+ if (timerp == NULL) {
+ return NULL;
+ }
+ tmp = calloc(1, sizeof(Task));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ tmp->timerp = timerp;
+ tmp->function = function;
+ tmp->data = data;
+ tmp->clean = clean;
+
+ return tmp;
+}
+
+/*
+ * Function name: Task_free
+ * Description: Frees the memory allocated for Task structure. User has to free the memory at the
+ * pointers by his own.
+ * Arguments: task - pointer to pointer to Task structure
+ */
+
+void
+Task_free(Task** task)
+{
+ assert(task != NULL);
+ if (task == NULL) {
+ return;
+ }
+ assert((*task) != NULL);
+ if ((*task) == NULL) {
+ return;
+ }
+
+ if ((*task)->clean) {
+ if ((*task)->data) {
+ (*task)->clean(&((*task)->data));
+ }
+ }
+
+ free((*task));
+ (*task) = NULL;
+}
+
+/*
+ * Function name: Task_get_timer
+ * Description: Returns the timer of the task.
+ * Arguments: task - pointer to Task structure
+ * Returns: The timer of the task.
+ */
+
+struct timeval*
+Task_get_timer(Task* task)
+{
+ assert(task != NULL);
+ if (task == NULL) {
+ return NULL;
+ }
+ return task->timerp;
+}
+
+/*
+ * Function name: Task_exec
+ * Description: Executes the function encapsulated in the task.
+ * Arguments: task - pointer to Task structure
+ */
+
+void
+Task_exec(Task* task)
+{
+ assert(task != NULL);
+ if (task == NULL) {
+ return;
+ }
+ if (task->function) {
+ task->function(task->data);
+ }
+}
diff --git a/src/task_struct.h b/src/task_struct.h
new file mode 100644
index 0000000..fac4582
--- /dev/null
+++ b/src/task_struct.h
@@ -0,0 +1,39 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_TASK_STRUCT_H
+#define _JS_TASK_STRUCT_H
+
+typedef struct {
+ struct timeval* timerp;
+ void (*function)(void*);
+ void* data;
+ void (*clean)(void**);
+} Task;
+
+/* 'constructor' */
+Task* Task_new(struct timeval*, void (*function)(void*), void*, void (*clean)(void**));
+/* 'destructor' */
+void Task_free(Task** task);
+/* getters */
+struct timeval* Task_get_timer(Task* task);
+void Task_exec(Task* task);
+
+#endif
diff --git a/src/thread_management.c b/src/thread_management.c
new file mode 100644
index 0000000..d423ca6
--- /dev/null
+++ b/src/thread_management.c
@@ -0,0 +1,102 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include "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;
+
+/*
+ * Function name: remember_mainthread
+ * Description: Remembers the current thread as a main thread.
+ */
+
+void
+remember_mainthread(void)
+{
+ mainthread = pthread_self();
+}
+
+/*
+ * Function name: is_this_a_mainthread
+ * Description: Checks, if the current thread is a main thread.
+ * Returns: 0 - this is not a main thread,
+ * 1 - this is a main thread.
+ */
+
+int
+is_this_a_mainthread(void)
+{
+ if (pthread_self() == mainthread) {
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Function name: start_critical_section
+ * Description: Starts the critical section of the code by locking the mutex.
+ */
+
+void
+start_critical_section(void)
+{
+ pthread_mutex_lock( &mainmutex);
+}
+
+/*
+ * Function name: end_critical_section
+ * Description: Ends the critical section of the code by unlocking the mutex.
+ */
+
+void
+end_critical_section(void)
+{
+ pthread_mutex_unlock( &mainmutex);
+}
+
+/*
+ * Function name: wait_for_condition
+ * Description: Starts waiting for the condition.
+ */
+
+void
+wait_for_condition(void)
+{
+ pthread_cond_wait(&maincond, &mainmutex);
+}
+
+/*
+ * Function name: broadcast_condition
+ * Description: Broadcast the met of the condition.
+ */
+
+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..9ea87fb
--- /dev/null
+++ b/src/thread_management.h
@@ -0,0 +1,34 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#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/timeval_functions.c b/src/timeval_functions.c
new file mode 100644
index 0000000..122e03a
--- /dev/null
+++ b/src/timeval_functions.c
@@ -0,0 +1,134 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "timeval_functions.h"
+
+/*
+ * Function name: timeval_create
+ * Description: Initialize and return timeval structure.
+ * Arguments: tv_sec - seconds
+ * tv_usec - microseconds
+ * Returns: Initialized timeval structure.
+ */
+
+struct timeval
+timeval_create(long tv_sec, long tv_usec)
+{
+ struct timeval tmp;
+ tmp.tv_sec = tv_sec;
+ tmp.tv_usec = tv_usec;
+ return tmp;
+}
+
+/*
+ * Function name: timeval_compare
+ * Description: Compares two pointers to timeval structures.
+ * Arguments: first - the first timeval structure to compare
+ * second - the second timeval structure to compare
+ * Returns: -1 - the second structure is bigger
+ * 0 - structures are equals
+ * 1 - the first structure is bigger
+ */
+
+int
+timeval_compare(struct timeval* first, struct timeval* second)
+{
+ if (first == NULL) {
+ if (second == NULL) {
+ return 0;
+ }
+ else {
+ return -1;
+ }
+ }
+ if (second == NULL) {
+ return 1;
+ }
+ if (first->tv_sec < second->tv_sec) {
+ return -1;
+ }
+ if (first->tv_sec > second->tv_sec) {
+ return 1;
+ }
+ if (first->tv_usec < second->tv_usec) {
+ return -1;
+ }
+ if (first->tv_usec > second->tv_usec) {
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Function name: timeval_subtract
+ * Description: Substracts second timeval structure from the first, updating the latter one.
+ * Arguments: first - the first timeval structure to subtract operation
+ * second - the second timeval structure to subtract operation
+ * Returns: 0 - success,
+ * 1 - failure.
+ */
+
+int
+timeval_subtract(struct timeval* first, struct timeval* second)
+{
+ assert(first != NULL);
+ assert(second != NULL);
+ if ((first == NULL) || (second == NULL)) {
+ return 1;
+ }
+ if (first->tv_usec < second->tv_usec) {
+ first->tv_sec -= 1;
+ first->tv_usec = 1000000 - second->tv_usec + first->tv_usec;
+ }
+ else {
+ first->tv_usec -= second->tv_usec;
+ }
+ first->tv_sec -= second->tv_sec;
+ return 0;
+}
+
+/*
+ * Function name: timeval_lq_zero
+ * Description: Checks if the timer is less or equiv zero.
+ * Arguments: timer - the timeval structure to check
+ * Returns: 1 - the timer is less or equiv zero,
+ * 0 - the timer is bigger than zero.
+ */
+
+int
+timeval_lq_zero(struct timeval* timer)
+{
+ assert(timer != NULL);
+ if (timer == NULL) {
+ return 0;
+ }
+ if (timer->tv_sec < 0) {
+ return 1;
+ }
+ if ((timer->tv_sec == 0) && (timer->tv_usec == 0)) {
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/timeval_functions.h b/src/timeval_functions.h
new file mode 100644
index 0000000..52b1582
--- /dev/null
+++ b/src/timeval_functions.h
@@ -0,0 +1,32 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _JS_TIMEVAL_FUNCTIONS_H
+#define _JS_TIMEVAL_FUNCTIONS_H
+
+#include <sys/time.h>
+
+struct timeval timeval_create(long tv_sec, long tv_usec);
+int timeval_compare(struct timeval* first, struct timeval* second);
+int timeval_subtract(struct timeval* first, struct timeval* second);
+int timeval_lq_zero(struct timeval* timer);
+
+#endif
+
diff --git a/src/usage.c b/src/usage.c
new file mode 100644
index 0000000..08a85b8
--- /dev/null
+++ b/src/usage.c
@@ -0,0 +1,227 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "usage.h"
+#include "network.h"
+
+/*
+ * Function name: server_short_usage
+ * Description: Prints the short usage of the afserver.
+ * Arguments: info - the text printed in the first line
+ */
+
+void
+server_short_usage(char* info)
+{
+ assert(info != NULL);
+ printf("\n%s\n\n\n", info);
+ printf("Try `afserver --help' for more information.\n");
+
+ exit(1);
+}
+
+/*
+ * Function name: server_long_usage
+ * Description: Prints the long usage of the afserver.
+ * Arguments: info - the text printed in the first line
+ */
+
+void
+server_long_usage(char* info)
+{
+ assert(info != NULL);
+ 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 [host:]port - users connect to it\n");
+ printf(" (default: 50127)\n");
+ printf(" -m, --manageport - manage [host:]port - afclient connects to it\n");
+ printf(" (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: server-cert.pem)\n");
+ printf(" -A, --cacerfile - the name of the file with CA certificates\n");
+ printf(" (if used, require clients to have valid certificates)\n");
+ printf(" -d, --cerdepth - the maximum depth of valid certificate-chains\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: %%Y-%%m-%%d %%H:%%M:%%S)\n");
+ printf(" -t, --timeout - the timeout value for the client's connection\n");
+ printf(" (default: 5)\n");
+ printf(" --maxidle - the maximum idle time for the client's connection\n");
+ printf(" (default: disabled)\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");
+ /* FIXME: afclient is always trying to get http page, so this option is not needed now
+ printf(" -S, --use-https - use https proxy instead of http proxy. '-P' option\n");
+ printf(" will be set implicitly\n\n");
+ */
+#endif
+
+ exit(0);
+}
+
+/*
+ * Function name: client_short_usage
+ * Description: Prints the short usage of the afclient.
+ * Arguments: info - the text printed in the first line
+ */
+
+void
+client_short_usage(char* info)
+{
+ assert(info != NULL);
+ printf("\n%s\n\n\n", info);
+ printf("Try `afclient --help' for more information.\n");
+
+ exit(1);
+}
+
+/*
+ * Function name: client_long_usage
+ * Description: Prints the long usage of the afclient.
+ * Arguments: info - the text printed in the first line
+ */
+
+void
+client_long_usage(char* info)
+{
+ assert(info != NULL);
+ 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(" --localname - local machine name for connection with afserver\n");
+ printf(" (used to bind socket to different interfaces)\n");
+ printf(" --localport - local port name for connection with afserver\n");
+ printf(" (used to bind socket to different addressees)\n");
+ printf(" --localdesname - local machine name for connections with destination\n");
+ printf(" application (used to bind socket to different interfaces)\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");
+ printf(" --ignorepkeys - ignore invalid server's public keys\n\n");
+ printf(" Configuration:\n\n");
+ printf(" -k, --keyfile - the name of the file with RSA key (default: client.rsa)\n");
+ printf(" -c, --cerfile - the name of the file with certificate\n");
+ printf(" (default: no certificate used)\n");
+ printf(" -f, --cfgfile - the name of the file with the configuration for the\n");
+ printf(" active forwarder (client)\n");
+ printf(" -s, --storefile - the name of the file with stored public keys\n");
+ printf(" (default: known_hosts)\n");
+ printf(" -D, --dateformat - format of the date printed in logs (see 'man strftime'\n");
+ printf(" for details) (default: %%Y-%%m-%%d %%H:%%M:%%S)\n");
+ printf(" -K, --keep-alive N - send keepalive packets every N seconds\n");
+ printf(" (default: not send keepalive packets)\n\n");
+ printf(" Auto-reconnection:\n\n");
+ printf(" --ar-start - enable auto-reconnection when afserver is not\n");
+ printf(" reachable on start (default: disabled)\n");
+ printf(" --ar-quit - enable auto-reconnection after normal afserver quit\n");
+ printf(" (default: disabled)\n");
+ printf(" --noar - disable auto-reconnection after premature afserver\n");
+ printf(" quit (default: enabled)\n");
+ printf(" -A, --ar-tries N - try N times to reconnect (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\n");
+ printf(" -U, --reverseudp - reverse udp forwarding. Udp packets will be forwarded\n");
+ printf(" from hostname:portnum to the server name:manageport\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/HTTPS PROXY:\n\n");
+ printf(" -S, --use-https - use https proxy instead of http proxy\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");
+ printf(" -C, --pa-cred U:P - the user (U) and password (P) used in proxy\n");
+ printf(" authorization\n");
+ printf(" -B, --pa-t-basic - the Basic type of proxy authorization (default)\n\n");
+#endif
+
+ exit(0);
+}
diff --git a/src/usage.h b/src/usage.h
new file mode 100644
index 0000000..eded3fd
--- /dev/null
+++ b/src/usage.h
@@ -0,0 +1,30 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#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/user_stats_struct.c b/src/user_stats_struct.c
new file mode 100644
index 0000000..0df384c
--- /dev/null
+++ b/src/user_stats_struct.c
@@ -0,0 +1,391 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <time.h>
+#include <assert.h>
+
+#include "user_stats_struct.h"
+
+/*
+ * Function name: UserStats_new
+ * Descriotion: Create and initialize new UserStats structure.
+ * Returns: Pointer to newly created UserStats structure.
+ */
+
+UserStats*
+UserStats_new()
+{
+ UserStats* tmp = calloc(1, sizeof(UserStats));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ return tmp;
+}
+
+/*
+ * Function name: UserStats_free
+ * Description: Free the memory allocated for UserStats structure.
+ * Arguments: us - pointer to pointer to UserStats structure
+ */
+
+void
+UserStats_free(UserStats** us)
+{
+ assert(us != NULL);
+ if (us == NULL) {
+ return;
+ }
+ assert((*us) != NULL);
+ if ((*us) == NULL) {
+ return;
+ }
+ free((*us));
+ (*us) = NULL;
+}
+
+/*
+ * Function name: UserStats_set_lastActivity
+ * Description: Set time of the last user activity (upload or download).
+ * Arguments: us - pointer to UserStats structure
+ * lastActivity - time of the last user activity
+ */
+
+void
+UserStats_set_lastActivity(UserStats* us, time_t lastActivity)
+{
+ assert(us != NULL);
+ if (us == NULL) {
+ return;
+ }
+ us->lastActivity = lastActivity;
+}
+
+/*
+ * Function name: UserStats_set_totalDownloadedBytes
+ * Description: Set total amount of downloaded bytes by the user.
+ * Arguments: us - pointer to UserStats structure
+ * totalDownloadedBytes - total amount of downloaded bytes by the user
+ */
+
+void
+UserStats_set_totalDownloadedBytes(UserStats* us, int totalDownloadedBytes)
+{
+ assert(us != NULL);
+ if (us == NULL) {
+ return;
+ }
+ us->totalDownloadedBytes = totalDownloadedBytes;
+}
+
+/*
+ * Function name: UserStats_set_totalUploadedBytes
+ * Description: Set total amount of uploaded byte by the user.
+ * Arguments: us - pointer to UserStats structure
+ * totalUploadedBytes - total amount of uploaded bytes by the user
+ */
+
+void
+UserStats_set_totalUploadedBytes(UserStats* us, int totalUploadedBytes)
+{
+ assert(us != NULL);
+ if (us == NULL) {
+ return;
+ }
+ us->totalUploadedBytes = totalUploadedBytes;
+}
+
+/*
+ * Function name: UserStats_get_lastActivity
+ * Description: Get time of the last user activity (upload or download).
+ * Arguments: us - pointer to UserStats structure
+ * Returns: Time of the last user activity.
+ */
+
+time_t
+UserStats_get_lastActivity(UserStats* us)
+{
+ assert(us != NULL);
+ if (us == NULL) {
+ return 0;
+ }
+ return us->lastActivity;
+}
+
+/*
+ * Function name: UserStats_get_totalDownloadedBytes
+ * Description: Get total amount of downloaded bytes by the user.
+ * Arguments: us - pointer to UserStats structure
+ * Returns: Total amount of downloaded bytes by the user.
+ */
+
+int
+UserStats_get_totalDownloadedBytes(UserStats* us)
+{
+ assert(us != NULL);
+ if (us == NULL) {
+ return 0;
+ }
+ return us->totalDownloadedBytes;
+}
+
+/*
+ * Function name: UserStats_get_totalUploadedBytes
+ * Description: Get total amount of uploaded bytes by the user.
+ * Arguments: us - pointer to UserStats structure
+ * Returns: Total amount of uploaded bytes by the user.
+ */
+
+int
+UserStats_get_totalUploadedBytes(UserStats* us)
+{
+ assert(us != NULL);
+ if (us == NULL) {
+ return 0;
+ }
+ return us->totalUploadedBytes;
+}
+
+/*
+ * Function name: UserStats_add_download
+ * Description: Add bytes to the totalDownloadedBytes, update the lastActivity
+ * and downloadSpeed.
+ * Arguments: us - pointer to UserStats structure
+ * bytes - amount of bytes to add
+ */
+
+void
+UserStats_add_download(UserStats* us, int bytes)
+{
+ time_t now;
+
+ assert(us != NULL);
+
+ if (us == NULL) {
+ return;
+ }
+
+ /* get the current time */
+ time(&now);
+
+ /* update counters */
+ switch (now - us->lastDSQChange) {
+ case 0: {
+ us->downloadSpeedQueue[us->downloadSQP] += bytes;
+ break;
+ }
+ case 2: {
+ us->downloadSQP = (us->downloadSQP + 1) % 3;
+ us->downloadSpeedQueue[us->downloadSQP] = 0;
+ }
+ case 1: {
+ us->downloadSQP = (us->downloadSQP + 1) % 3;
+ us->downloadSpeedQueue[us->downloadSQP] = bytes;
+ break;
+ }
+ default: {
+ us->downloadSpeedQueue[0] = us->downloadSpeedQueue[1] = us->downloadSpeedQueue[2] = 0;
+ us->downloadSpeedQueue[us->downloadSQP] = bytes;
+ }
+ }
+
+ /* update total upload */
+ us->totalDownloadedBytes += bytes;
+
+ /* update last activity */
+ us->lastActivity = now;
+
+ /* update last speed queue change */
+ us->lastDSQChange = now;
+}
+
+/*
+ * Function name: UserStats_add_upload
+ * Description: Add bytes to the totalUploadedBytes, update the lastActivity
+ * and uploadSpeed.
+ * Arguments: us - pointer to UserStats structure
+ * bytes - amount of bytes to add
+ */
+
+void
+UserStats_add_upload(UserStats* us, int bytes)
+{
+ time_t now;
+
+ assert(us != NULL);
+
+ if (us == NULL) {
+ return;
+ }
+
+ /* get the current time */
+ time(&now);
+
+ /* update counters */
+ switch (now - us->lastUSQChange) {
+ case 0: {
+ us->uploadSpeedQueue[us->uploadSQP] += bytes;
+ break;
+ }
+ case 2: {
+ us->uploadSQP = (us->uploadSQP + 1) % 3;
+ us->uploadSpeedQueue[us->uploadSQP] = 0;
+ }
+ case 1: {
+ us->uploadSQP = (us->uploadSQP + 1) % 3;
+ us->uploadSpeedQueue[us->uploadSQP] = bytes;
+ break;
+ }
+ default: {
+ us->uploadSpeedQueue[0] = us->uploadSpeedQueue[1] = us->uploadSpeedQueue[2] = 0;
+ us->uploadSpeedQueue[us->uploadSQP] = bytes;
+ }
+ }
+
+ /* update total upload */
+ us->totalUploadedBytes += bytes;
+
+ /* update last activity */
+ us->lastActivity = now;
+
+ /* update last speed queue change */
+ us->lastUSQChange = now;
+}
+
+/*
+ * Function name: UserStats_get_downloadSpeed
+ * Description: Get the average download speed from the last three seconds.
+ * Arguments: us - pointer to UserStats structure
+ * Returns: The average download speed from the last three seconds.
+ */
+
+double
+UserStats_get_downloadSpeed(UserStats* us)
+{
+ time_t now;
+
+ assert(us != NULL);
+
+ if (us == NULL) {
+ return 0.0;
+ }
+
+ /* get the current time */
+ time(&now);
+
+ /* update pointer */
+ switch (now - us->lastDSQChange) {
+ case 0: {
+ break;
+ }
+ case 2: {
+ us->downloadSQP = (us->downloadSQP + 1) % 3;
+ us->downloadSpeedQueue[us->downloadSQP] = 0;
+ }
+ case 1: {
+ us->downloadSQP = (us->downloadSQP + 1) % 3;
+ us->downloadSpeedQueue[us->downloadSQP] = 0;
+ break;
+ }
+ default: {
+ us->downloadSpeedQueue[0] = us->downloadSpeedQueue[1] = us->downloadSpeedQueue[2] = 0;
+ }
+ }
+
+ /* update last speed queue change */
+ us->lastDSQChange = now;
+
+ /* return current download speed */
+ return (((double)(us->downloadSpeedQueue[0] + us->downloadSpeedQueue[1] + us->downloadSpeedQueue[2])) / 3.0);
+}
+
+/*
+ * Function name: UserStats_get_uploadSpeed
+ * Description: Get the average upload speed from the last three seconds.
+ * Arguments: us - pointer to UserStats structure
+ * Returns: The average upload speed from the last three seconds.
+ */
+
+double
+UserStats_get_uploadSpeed(UserStats* us)
+{
+ time_t now;
+
+ assert(us != NULL);
+
+ if (us == NULL) {
+ return 0.0;
+ }
+
+ /* get the current time */
+ time(&now);
+
+ /* update pointer */
+ switch (now - us->lastUSQChange) {
+ case 0: {
+ break;
+ }
+ case 2: {
+ us->uploadSQP = (us->uploadSQP + 1) % 3;
+ us->uploadSpeedQueue[us->uploadSQP] = 0;
+ }
+ case 1: {
+ us->uploadSQP = (us->uploadSQP + 1) % 3;
+ us->uploadSpeedQueue[us->uploadSQP] = 0;
+ break;
+ }
+ default: {
+ us->uploadSpeedQueue[0] = us->uploadSpeedQueue[1] = us->uploadSpeedQueue[2] = 0;
+ }
+ }
+
+ /* update last speed queue change */
+ us->lastUSQChange = now;
+
+ /* return current download speed */
+ return (((double)(us->uploadSpeedQueue[0] + us->uploadSpeedQueue[1] + us->uploadSpeedQueue[2])) / 3.0);
+}
+
+/*
+ * Function name: UserStats_clear
+ * Description: Clear the UserStats structure. Set all variables to default values.
+ * Arguments: us - pointer to UserStats structure
+ */
+
+void
+UserStats_clear(UserStats* us)
+{
+ assert(us != NULL);
+ if (us == NULL) {
+ return;
+ }
+ us->lastActivity = 0;
+ us->lastUSQChange = 0;
+ us->lastDSQChange = 0;
+ us->totalDownloadedBytes = 0;
+ us->totalUploadedBytes = 0;
+ us->uploadSQP = 0;
+ us->uploadSpeedQueue[0] = us->uploadSpeedQueue[1] = us->uploadSpeedQueue[2] = 0;
+ us->downloadSQP = 0;
+ us->downloadSpeedQueue[0] = us->downloadSpeedQueue[1] = us->downloadSpeedQueue[2] = 0;
+}
diff --git a/src/user_stats_struct.h b/src/user_stats_struct.h
new file mode 100644
index 0000000..dc33dd4
--- /dev/null
+++ b/src/user_stats_struct.h
@@ -0,0 +1,59 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef _JS_USER_STATS_STRUCT_H
+#define _JS_USER_STATS_STRUCT_H
+
+#include <sys/types.h>
+
+typedef struct {
+ time_t lastActivity;
+ time_t lastUSQChange;
+ time_t lastDSQChange;
+ int totalDownloadedBytes;
+ int totalUploadedBytes;
+ int uploadSQP;
+ int uploadSpeedQueue[3];
+ int downloadSQP;
+ int downloadSpeedQueue[3];
+} UserStats;
+
+/* 'constructor' */
+UserStats* UserStats_new();
+/* 'destructor' */
+void UserStats_free(UserStats** us);
+/* setters */
+void UserStats_set_lastActivity(UserStats* us, time_t lastActivity);
+void UserStats_set_totalDownloadedBytes(UserStats* us, int totalDownloadedBytes);
+void UserStats_set_totalUploadedBytes(UserStats* us, int totalUploadedBytes);
+/* getters */
+time_t UserStats_get_lastActivity(UserStats* us);
+int UserStats_get_totalDownloadedBytes(UserStats* us);
+int UserStats_get_totalUploadedBytes(UserStats* us);
+/* other methods */
+void UserStats_add_download(UserStats* us, int bytes);
+void UserStats_add_upload(UserStats* us, int bytes);
+double UserStats_get_downloadSpeed(UserStats* us);
+double UserStats_get_uploadSpeed(UserStats* us);
+/* other */
+void UserStats_clear(UserStats* us);
+
+#endif
diff --git a/src/usernames.c b/src/usernames.c
new file mode 100644
index 0000000..4f0b14d
--- /dev/null
+++ b/src/usernames.c
@@ -0,0 +1,63 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+#include <assert.h>
+
+#include "usernames.h"
+
+/*
+ * Function name: get_username
+ * Description: Returns the id of the user.
+ * Arguments: pointer - the server realm
+ * user - the number of the user
+ * Returns: The id of the user.
+ */
+
+int
+get_username(ServerRealm* pointer, int user)
+{
+ assert(pointer != NULL);
+ return ConnectUser_get_userId(ServerRealm_get_usersTable(pointer)[user]);
+}
+
+/*
+ * Function name: get_usernumber
+ * Description: Returns the number of the user.
+ * Arguments: pointer - the server realm
+ * user - the id of the user
+ * Returns: The number of the user.
+ */
+
+int
+get_usernumber(ServerRealm* pointer, int userid)
+{
+ int i;
+
+ assert(pointer != NULL);
+
+ for (i = 0; i < ServerRealm_get_usersLimit(pointer); ++i) {
+ if (userid == ConnectUser_get_userId(ServerRealm_get_usersTable(pointer)[i])) {
+ return i;
+ }
+ }
+
+ return -1;
+}
diff --git a/src/usernames.h b/src/usernames.h
new file mode 100644
index 0000000..d7f358f
--- /dev/null
+++ b/src/usernames.h
@@ -0,0 +1,31 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "activefor.h"
+#include "server_realm_struct.h"
+
+#ifndef _JS_USERNAMES_H
+#define _JS_USERNAMES_H
+
+int get_username(ServerRealm*, int);
+int get_usernumber(ServerRealm*, int);
+
+#endif
+
diff --git a/src/usr_cli_struct.c b/src/usr_cli_struct.c
new file mode 100644
index 0000000..439fb62
--- /dev/null
+++ b/src/usr_cli_struct.c
@@ -0,0 +1,299 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "usr_cli_struct.h"
+#include "string_functions.h"
+
+/*
+ * Function name: UsrCli_new
+ * Description: Create and initialize new UsrCli structure.
+ * Returns: Newly created UsrCli structure.
+ */
+
+UsrCli*
+UsrCli_new()
+{
+ UsrCli* tmp = calloc(1, sizeof(UsrCli));
+ assert(tmp != NULL);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ return tmp;
+}
+
+/*
+ * Function name: UsrCli_free
+ * Description: Free the memory allocated for UsrCli structure.
+ * Arguments: uc - pointer to pointer to UsrCli structure
+ */
+
+void
+UsrCli_free(UsrCli** uc)
+{
+ assert(uc != NULL);
+ if (uc == NULL) {
+ return;
+ }
+ assert((*uc) != NULL);
+ if ((*uc) == NULL) {
+ return;
+ }
+ if ((*uc)->listenPortName) {
+ free((*uc)->listenPortName);
+ (*uc)->listenPortName = NULL;
+ }
+ if ((*uc)->managePortName) {
+ free((*uc)->managePortName);
+ (*uc)->managePortName = NULL;
+ }
+ free((*uc));
+ (*uc) = NULL;
+}
+
+/* Function name: UsrCli_set_listenPortName
+ * Description: Set listen port name.
+ * Arguments: uc - pointer to UsrCli structure
+ * listenPortName - listen port name
+ */
+
+void
+UsrCli_set_listenPortName(UsrCli* uc, char* listenPortName)
+{
+ char* tmp;
+
+ assert(uc != NULL);
+
+ if (uc == NULL) {
+ return;
+ }
+ if ((tmp = rindex(listenPortName, ':')) != NULL) {
+ (*tmp) = 0;
+ ++tmp;
+ string_cp(&(uc->listenHostName), listenPortName);
+ string_cp(&(uc->listenPortName), tmp);
+ }
+ else {
+ string_cp(&(uc->listenPortName), listenPortName);
+ }
+}
+
+/*
+ * Function name: UsrCli_set_managePortName
+ * Description: Set manage port name.
+ * Arguments: uc - pointer to UsrCli structure
+ * managePortName - manage port name
+ */
+
+void
+UsrCli_set_managePortName(UsrCli* uc, char* managePortName)
+{
+ char* tmp;
+
+ assert(uc != NULL);
+
+ if (uc == NULL) {
+ return;
+ }
+ if ((tmp = rindex(managePortName, ':')) != NULL) {
+ (*tmp) = 0;
+ ++tmp;
+ string_cp(&(uc->manageHostName), managePortName);
+ string_cp(&(uc->managePortName), tmp);
+ }
+ else {
+ string_cp(&(uc->managePortName), managePortName);
+ }
+}
+
+/*
+ * Function name: UsrCli_set_listenFd
+ * Description: Set listen file descriptor.
+ * Arguments: uc - pointer to UsrCli structure
+ * listenFd - listen file descriptor
+ */
+
+void
+UsrCli_set_listenFd(UsrCli* uc, int listenFd)
+{
+ assert(uc != NULL);
+ if (uc == NULL) {
+ return;
+ }
+ uc->listenFd = listenFd;
+}
+
+/*
+ * Function name: UsrCli_set_manageFd
+ * Description: Set manage file descriptor.
+ * Arguments: uc - pointer to UsrCli structure
+ * manageFd - manage file descriptor
+ */
+
+void
+UsrCli_set_manageFd(UsrCli* uc, int manageFd)
+{
+ assert(uc != NULL);
+ if (uc == NULL) {
+ return;
+ }
+ uc->manageFd = manageFd;
+}
+
+/*
+ * Function name: UsrCli_set_number
+ * Description: Sets the UsrCli number in the structures connected with manage port.
+ * Arguments: uc - pointer to UsrCli structure
+ * number - the number of the UsrCli structure
+ */
+
+void
+UsrCli_set_number(UsrCli* uc, int number)
+{
+ assert(uc != NULL);
+ assert(number >= 0);
+ if (uc == NULL) {
+ return;
+ }
+ uc->number = number;
+}
+
+/* Function name: UsrCli_get_listenPortName
+ * Description: Get listen port name.
+ * Arguments: uc - pointer to UsrCli structure
+ * Returns: Listen port name.
+ */
+
+char*
+UsrCli_get_listenPortName(UsrCli* uc)
+{
+ assert(uc != NULL);
+ if (uc == NULL) {
+ return NULL;
+ }
+ return uc->listenPortName;
+}
+
+/*
+ * Function name: UsrCli_get_managePortName
+ * Description: Get manage port name.
+ * Arguments: uc - pointer to UsrCli structure
+ * Returns: Manage port name.
+ */
+
+char*
+UsrCli_get_managePortName(UsrCli* uc)
+{
+ assert(uc != NULL);
+ if (uc == NULL) {
+ return NULL;
+ }
+ return uc->managePortName;
+}
+
+/*
+ * Function name: UsrCli_get_listenFd
+ * Description: Get listen file descriptor.
+ * Arguments: uc - pointer to UsrCli structure
+ * Returns: Listen file descriptor.
+ */
+
+int
+UsrCli_get_listenFd(UsrCli* uc)
+{
+ assert(uc != NULL);
+ if (uc == NULL) {
+ return -1;
+ }
+ return uc->listenFd;
+}
+
+/*
+ * Function name: UsrCli_get_manageFd
+ * Description: Get manage file descriptor.
+ * Arguments: uc - pointer to UsrCli structure
+ * Returns: Manage file desciptor.
+ */
+
+int
+UsrCli_get_manageFd(UsrCli* uc)
+{
+ assert(uc != NULL);
+ if (uc == NULL) {
+ return -1;
+ }
+ return uc->manageFd;
+}
+
+/*
+ * Function name: UsrCli_get_listenHostName
+ * Description: Get host name used for listenFd in ip_connect function or NULL, if not set.
+ * Arguments: uc - pointer to UsrCli structure
+ * Returns: Host name used for listenFd in ip_connect function or NULL, if not set.
+ */
+
+char*
+UsrCli_get_listenHostName(UsrCli* uc)
+{
+ assert(uc != NULL);
+ if (uc == NULL) {
+ return NULL;
+ }
+ return uc->listenHostName;
+}
+
+/*
+ * Function name: UsrCli_get_manageHostName
+ * Description: Get host name used for manageFd in ip_connect function or NULL, if not set.
+ * Arguments: uc - pointer to UsrCli structure
+ * Returns: Host name used for manageFd in ip_connect function or NULL, if not set.
+ */
+
+char*
+UsrCli_get_manageHostName(UsrCli* uc)
+{
+ assert(uc != NULL);
+ if (uc == NULL) {
+ return NULL;
+ }
+ return uc->manageHostName;
+}
+
+/*
+ * Function name: UsrCli_get_number
+ * Description: Gets the number of the UsrCli structure.
+ * Arguments: uc - pointer to UsrCli structure
+ * Returns: The number of the UsrCli structure.
+ */
+
+int
+UsrCli_get_number(UsrCli* uc)
+{
+ assert(uc != NULL);
+ if (uc == NULL) {
+ return -1;
+ }
+ return uc->number;
+}
diff --git a/src/usr_cli_struct.h b/src/usr_cli_struct.h
new file mode 100644
index 0000000..ddbbe97
--- /dev/null
+++ b/src/usr_cli_struct.h
@@ -0,0 +1,54 @@
+/*
+ * active port forwarder - software for secure forwarding
+ * Copyright (C) 2003-2007 jeremian <jeremian [at] poczta.fm>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef _JS_USR_CLI_STRUCT_H
+#define _JS_USR_CLI_STRUCT_H
+
+typedef struct {
+ char* listenHostName;
+ char* manageHostName;
+ char* listenPortName;
+ char* managePortName;
+ int listenFd;
+ int manageFd;
+ int number;
+} UsrCli;
+
+/* 'constructor' */
+UsrCli* UsrCli_new();
+/* 'destructor' */
+void UsrCli_free(UsrCli** uc);
+/* setters */
+void UsrCli_set_listenPortName(UsrCli* uc, char* listenPortName);
+void UsrCli_set_managePortName(UsrCli* uc, char* managePortName);
+void UsrCli_set_listenFd(UsrCli* uc, int listenFd);
+void UsrCli_set_manageFd(UsrCli* uc, int manageFd);
+void UsrCli_set_number(UsrCli* uc, int number);
+/* getters */
+char* UsrCli_get_listenPortName(UsrCli* uc);
+char* UsrCli_get_managePortName(UsrCli* uc);
+int UsrCli_get_listenFd(UsrCli* uc);
+int UsrCli_get_manageFd(UsrCli* uc);
+char* UsrCli_get_listenHostName(UsrCli* uc);
+char* UsrCli_get_manageHostName(UsrCli* uc);
+int UsrCli_get_number(UsrCli* uc);
+
+#endif