diff --git a/Makefile.am b/Makefile.am index a389ebe7..b887de85 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,25 +1,25 @@ MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure depcomp \ config.guess config.sub missing install-sh \ ltmain.sh compile config.h.in config.h.in~ \ autoscan.log configure.scan AUTOMAKE_OPTIONS = foreign ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = libtap libknet kronosnetd tests +SUBDIRS = init libtap libknet kronosnetd tests if BUILD_DOCS SUBDIRS += docs endif dist_doc_DATA = \ COPYING.applications \ COPYING.libraries \ COPYRIGHT \ README.licence \ README \ TODO maintainer-clean-local: rm -rf m4 diff --git a/TODO b/TODO index 943c2e4b..4e705b11 100644 --- a/TODO +++ b/TODO @@ -1,92 +1,92 @@ 0.1 --- compress: should only compress user data, we will add a bit in the data header to indicate if the pckt is compressed or not (save time). this approach allow runtime change of compress. open questions are: methods? level? zlib? lzo? bz? lzma? xz? how much do we save by compressin our header? cryto: expand API to support dual key for rekey process compress must happen before encrypt Look into link status changes notification (maybe a signal to a thread? or write to a pipe) Fix link_id handling between config and libknet Implement link auth via user/passwd ring: * support 8 listener per node. * index pointer list general: * what to log log to file: who logins, config changes and link status changes log to vty: cmd execution failure * consider splitting tests/* based on what they test (tap_test -> libtap/) ? vty: * split cmd_files * fix check_param for ip/prefix/crypto * add description commands for various levels 0.2 --- libtap: * add man pages * improve tests to cover thread safety and more error codes 0.3 --- * benchmark tests: - all critical paths in ring.c 0.4 --- general: * add statistics -* add init script / spec file +* add spec file * v4/v6 (bindv6only check via cli) vty: * add optional options * tab completion on options 0.5 --- * pong count 0.7 --- * review ring api for libknetring shared lib * review tap api for libknettap shared lib * review vty api for libknetvty shared lib 1.0-pre ------- tests: * coverity * unit test: - test all public APIs - write ad-doc tests for internal complex functions - not required to test return codes from external libs directly (we are not testing glibc) - test all code paths we write - no 0.9/1.0 release without max testing coverage for the core diff --git a/configure.ac b/configure.ac index 4aecaf8e..c5fac439 100644 --- a/configure.ac +++ b/configure.ac @@ -1,290 +1,304 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.63]) AC_INIT([kronosnetd], [0.1], [fabbione@kronosnet.org]) AC_USE_SYSTEM_EXTENSIONS AM_INIT_AUTOMAKE([1.11.1 dist-bzip2 dist-xz color-tests -Wno-portability]) LT_PREREQ([2.2.6]) LT_INIT AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([kronosnetd/main.c]) AC_CONFIG_HEADERS([config.h]) AC_CANONICAL_HOST AC_PROG_LIBTOOL AC_LANG([C]) if test "$prefix" = "NONE"; then prefix="/usr" if test "$localstatedir" = "\${prefix}/var"; then localstatedir="/var" fi if test "$sysconfdir" = "\${prefix}/etc"; then sysconfdir="/etc" fi fi # Checks for programs. if ! ${MAKE-make} --version /cannot/make/this >/dev/null 2>&1; then AC_MSG_ERROR(["you don't seem to have GNU make; it is required"]) fi AC_PROG_CC AM_PROG_CC_C_O AC_PROG_LN_S AC_PROG_INSTALL AC_PROG_MAKE_SET AC_PROG_CXX AC_PROG_RANLIB AC_CHECK_PROGS([PUBLICAN], [publican], [:]) AC_CHECK_PROGS([PKGCONFIG], [pkg-config]) ## local helper functions # this function checks if CC support options passed as # args. Global CFLAGS are ignored during this test. cc_supports_flag() { saveCPPFLAGS="$CPPFLAGS" CPPFLAGS="$@" AC_MSG_CHECKING([whether $CC supports "$@"]) AC_PREPROC_IFELSE([AC_LANG_PROGRAM([])], [RC=0; AC_MSG_RESULT([yes])], [RC=1; AC_MSG_RESULT([no])]) CPPFLAGS="$saveCPPFLAGS" return $RC } # helper macro to check libs without adding them to LIBS check_lib_no_libs() { lib_no_libs_arg1=$1 shift lib_no_libs_arg2=$1 shift lib_no_libs_args=$@ AC_CHECK_LIB([$lib_no_libs_arg1], [$lib_no_libs_arg2],,, [$lib_no_libs_args]) LIBS=$ac_check_lib_save_LIBS } # Checks for C features AC_C_INLINE # Checks for libraries. AC_CHECK_LIB([pthread], [pthread_create]) AC_CHECK_LIB([rt], [clock_gettime]) PKG_CHECK_MODULES([nss],[nss]) PKG_CHECK_MODULES([libqb], [libqb]) AC_CHECK_LIB([qb], [qb_log_thread_priority_set], [have_qb_log_thread_priority_set="yes"], [have_qb_log_thread_priority_set="no"]) if test "x${have_qb_log_thread_priority_set}" = xyes; then AC_DEFINE_UNQUOTED([HAVE_QB_LOG_THREAD_PRIORITY_SET], 1, [have qb_log_thread_priority_set]) fi # Checks for header files. AC_CHECK_HEADERS([fcntl.h]) AC_CHECK_HEADERS([stdlib.h]) AC_CHECK_HEADERS([string.h]) AC_CHECK_HEADERS([sys/ioctl.h]) AC_CHECK_HEADERS([syslog.h]) AC_CHECK_HEADERS([unistd.h]) AC_CHECK_HEADERS([netinet/in.h]) AC_CHECK_HEADERS([sys/socket.h]) AC_CHECK_HEADERS([arpa/inet.h]) AC_CHECK_HEADERS([netdb.h]) AC_CHECK_HEADERS([limits.h]) # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_SIZE_T AC_TYPE_PID_T AC_TYPE_SSIZE_T AC_TYPE_UINT8_T AC_TYPE_UINT16_T AC_TYPE_UINT32_T # Checks for library functions. AC_FUNC_ALLOCA AC_FUNC_FORK AC_FUNC_MALLOC AC_FUNC_REALLOC AC_CHECK_FUNCS([memset]) AC_CHECK_FUNCS([strdup]) AC_CHECK_FUNCS([strerror]) AC_CHECK_FUNCS([dup2]) AC_CHECK_FUNCS([select]) AC_CHECK_FUNCS([socket]) AC_CHECK_FUNCS([inet_ntoa]) AC_CHECK_FUNCS([memmove]) AC_CHECK_FUNCS([strchr]) AC_CHECK_FUNCS([atexit]) AC_CHECK_FUNCS([ftruncate]) AC_CHECK_FUNCS([strrchr]) AC_CHECK_FUNCS([strstr]) AC_CHECK_FUNCS([clock_gettime]) # PAM check AC_CHECK_HEADERS([security/pam_appl.h], [AC_CHECK_LIB([pam], [pam_start])], [AC_MSG_ERROR([Unable to find LinuxPAM devel files])]) AC_CHECK_HEADERS([security/pam_misc.h], [AC_CHECK_LIB([pam_misc], [misc_conv])], [AC_MSG_ERROR([Unable to find LinuxPAM MISC devel files])]) # local options AC_ARG_ENABLE([debug], [ --enable-debug enable debug build. ], [ default="no" ]) AC_ARG_ENABLE([publicandocs], [ --enable-publicandocs enable docs build. ], [ default="no" ]) +AC_ARG_WITH([initddir], + [ --with-initddir=DIR : path to init script directory. ], + [ INITDDIR="$withval" ], + [ INITDDIR="$sysconfdir/init.d" ]) + +AC_ARG_WITH([systemddir], + [ --with-systemddir=DIR : path to systemd unit files directory. ], + [ SYSTEMDDIR="$withval" ], + [ SYSTEMDDIR="/lib/systemd/system" ]) + AC_ARG_WITH([syslogfacility], [ --with-syslogfacility=FACILITY default syslog facility. ], [ SYSLOGFACILITY="$withval" ], [ SYSLOGFACILITY="LOG_DAEMON" ]) AC_ARG_WITH([sysloglevel], [ --with-sysloglevel=LEVEL default syslog level. ], [ SYSLOGLEVEL="$withval" ], [ SYSLOGLEVEL="LOG_INFO" ]) AC_ARG_WITH([defaultadmgroup], [ --with-defaultadmgroup=GROUP define PAM group. Users part of this group will be allowed to configure kronosnet. Others will only receive read-only rights. ], [ DEFAULTADMGROUP="$withval" ], [ DEFAULTADMGROUP="kronosnetadm" ]) ## random vars LOGDIR=${localstatedir}/log/ RUNDIR=${localstatedir}/run/ DEFAULT_CONFIG_DIR=${sysconfdir}/kronosnet ## do subst AM_CONDITIONAL([BUILD_DOCS], [test "x${enable_publicandocs}" = xyes]) AC_SUBST([DEFAULT_CONFIG_DIR]) +AC_SUBST([INITDDIR]) +AC_SUBST([SYSTEMDDIR]) + AC_DEFINE_UNQUOTED([DEFAULT_CONFIG_DIR], ["$(eval echo ${DEFAULT_CONFIG_DIR})"], [Default config directory]) AC_DEFINE_UNQUOTED([DEFAULT_CONFIG_FILE], ["$(eval echo ${DEFAULT_CONFIG_DIR}/kronosnetd.conf)"], [Default config file]) AC_DEFINE_UNQUOTED([LOGDIR], ["$(eval echo ${LOGDIR})"], [Default logging directory]) AC_DEFINE_UNQUOTED([DEFAULT_LOG_FILE], ["$(eval echo ${LOGDIR}/kronosnetd.log)"], [Default log file]) AC_DEFINE_UNQUOTED([RUNDIR], ["$(eval echo ${RUNDIR})"], [Default run directory]) AC_DEFINE_UNQUOTED([SYSLOGFACILITY], [$(eval echo ${SYSLOGFACILITY})], [Default syslog facility]) AC_DEFINE_UNQUOTED([SYSLOGLEVEL], [$(eval echo ${SYSLOGLEVEL})], [Default syslog level]) AC_DEFINE_UNQUOTED([DEFAULTADMGROUP], ["$(eval echo ${DEFAULTADMGROUP})"], [Default admin group]) ## *FLAGS handling ENV_CFLAGS="$CFLAGS" ENV_CPPFLAGS="$CPPFLAGS" ENV_LDFLAGS="$LDFLAGS" # debug build stuff if test "x${enable_debug}" = xyes; then AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code]) OPT_CFLAGS="-O0" else OPT_CFLAGS="-O3" fi # gdb flags if test "x${GCC}" = xyes; then GDB_FLAGS="-ggdb3" else GDB_FLAGS="-g" fi # extra warnings EXTRA_WARNINGS="" WARNLIST=" all shadow missing-prototypes missing-declarations strict-prototypes declaration-after-statement pointer-arith write-strings cast-align bad-function-cast missing-format-attribute format=2 format-security format-nonliteral no-long-long unsigned-char gnu89-inline no-strict-aliasing error address cpp overflow parentheses sequence-point switch uninitialized unused-but-set-variable unused-function unused-result unused-value unused-variable " for j in $WARNLIST; do if cc_supports_flag -W$j; then EXTRA_WARNINGS="$EXTRA_WARNINGS -W$j"; fi done CFLAGS="$ENV_CFLAGS $lt_prog_compiler_pic $OPT_CFLAGS $GDB_FLAGS \ $EXTRA_WARNINGS $WERROR_CFLAGS" CPPFLAGS="$ENV_CPPFLAGS" LDFLAGS="$ENV_LDFLAGS $lt_prog_compiler_pic" AC_CONFIG_FILES([ Makefile + init/Makefile libtap/Makefile libtap/libtap.pc kronosnetd/Makefile libknet/Makefile libknet/libknet.pc docs/Makefile tests/Makefile ]) AC_OUTPUT diff --git a/init/Makefile.am b/init/Makefile.am new file mode 100644 index 00000000..cc3c73da --- /dev/null +++ b/init/Makefile.am @@ -0,0 +1,23 @@ +MAINTAINERCLEANFILES = Makefile.in + +EXTRA_DIST = kronosnetd.in kronosnetd.service.in + +systemdconfdir = $(SYSTEMDDIR) +systemdconf_DATA = kronosnetd.service +initscriptdir = $(INITDDIR) +initscript_SCRIPTS = kronosnetd + +%: %.in Makefile + rm -f $@-t $@ + cat $< | sed \ + -e 's#@''SBINDIR@#$(sbindir)#g' \ + -e 's#@''SYSCONFDIR@#$(sysconfdir)#g' \ + -e 's#@''INITDDIR@#$(INITDDIR)#g' \ + -e 's#@''LOCALSTATEDIR@#$(localstatedir)#g' \ + > $@-t + mv $@-t $@ + +all-local: $(initscript_SCRIPTS) $(systemdconf_DATA) + +clean-local: + rm -rf $(initscript_SCRIPTS) $(systemdconf_DATA) diff --git a/init/kronosnetd.in b/init/kronosnetd.in new file mode 100644 index 00000000..a8fbc732 --- /dev/null +++ b/init/kronosnetd.in @@ -0,0 +1,140 @@ +#!/bin/bash + +# chkconfig: - 20 80 +# description: kronosnetd vpn daemon +# processname: kronosnetd +# +### BEGIN INIT INFO +# Provides: kronosnetd +# Required-Start: $network $syslog +# Required-Stop: $network $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: +# Short-Description: Starts and stops kronosnetd vpn daemon. +# Description: Starts and stops kronosnetd vpn daemon. +### END INIT INFO + +desc="kronosnetd" +prog="kronosnetd" + +# set secure PATH +PATH="/sbin:/bin:/usr/sbin:/usr/bin:@SBINDIR@" + +success() +{ + echo -ne "[ OK ]\r" +} + +failure() +{ + echo -ne "[FAILED]\r" +} + +status() +{ + pid=$(pidof $1 2>/dev/null) + rtrn=$? + if [ $rtrn -ne 0 ]; then + echo "$1 is stopped" + else + echo "$1 (pid $pid) is running..." + fi + return $rtrn +} + +# rpm based distros +if [ -d @SYSCONFDIR@/sysconfig ]; then + [ -f @INITDDIR@/functions ] && . @INITDDIR@/functions + [ -f @SYSCONFDIR@/sysconfig/$prog ] && . @SYSCONFDIR@/sysconfig/$prog + [ -z "$LOCK_FILE" ] && LOCK_FILE="@LOCALSTATEDIR@/lock/subsys/$prog" +fi + +# deb based distros +if [ -d @SYSCONFDIR@/default ]; then + [ -f @SYSCONFDIR@/default/$prog ] && . @SYSCONFDIR@/default/$prog + [ -z "$LOCK_FILE" ] && LOCK_FILE="@LOCALSTATEDIR@/lock/$prog" +fi + +# The version of __pids_pidof in /etc/init.d/functions calls pidof with -x +# This means it matches scripts, including this one. +# Redefine it here so that status (from the same file) works. +# Otherwise simultaneous calls to stop() will loop forever +__pids_pidof() { + pidof -c -o $$ -o $PPID -o %PPID "$1" || \ + pidof -c -o $$ -o $PPID -o %PPID "${1##*/}" +} + +start() +{ + echo -n "Starting $desc ($prog): " + + # most recent distributions use tmpfs for @LOCALSTATEDIR@/run + # to avoid to clean it up on every boot. + # they also assume that init scripts will create + # required subdirectories for proper operations + mkdir -p @LOCALSTATEDIR@/run + + if status $prog > /dev/null 2>&1; then + success + else + $prog $KNETD_OPTS > /dev/null 2>&1 + touch $LOCK_FILE + success + fi + echo +} + +stop() +{ + ! status $prog > /dev/null 2>&1 && return + + echo -n "Signaling $desc ($prog) to terminate: " + kill -TERM $(pidof $prog) > /dev/null 2>&1 + success + echo + + echo -n "Waiting for $prog to unload:" + while status $prog > /dev/null 2>&1; do + sleep 1 + echo -n "." + done + + rm -f $LOCK_FILE + success + echo +} + +restart() +{ + stop + start +} + +rtrn=0 + +case "$1" in +start) + start +;; +restart|reload|force-reload) + restart +;; +condrestart|try-restart) + if status $prog > /dev/null 2>&1; then + restart + fi +;; +status) + status $prog + rtrn=$? +;; +stop) + stop +;; +*) + echo "usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}" + rtrn=2 +;; +esac + +exit $rtrn diff --git a/init/kronosnetd.service.in b/init/kronosnetd.service.in new file mode 100644 index 00000000..866ee29f --- /dev/null +++ b/init/kronosnetd.service.in @@ -0,0 +1,12 @@ +[Unit] +Description=kronosnetd +Requires=network.target +After=network.target syslog.target + +[Service] +Type=forking +EnvironmentFile=/etc/sysconfig/kronosnetd +ExecStart=@SBINDIR@/kronosnetd + +[Install] +WantedBy=multi-user.target