summaryrefslogtreecommitdiff
path: root/src/charon-cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon-cmd')
-rw-r--r--src/charon-cmd/Makefile.am32
-rw-r--r--src/charon-cmd/Makefile.in812
-rw-r--r--src/charon-cmd/charon-cmd.8161
-rw-r--r--src/charon-cmd/charon-cmd.8.in161
-rw-r--r--src/charon-cmd/charon-cmd.c404
-rw-r--r--src/charon-cmd/cmd/cmd_connection.c498
-rw-r--r--src/charon-cmd/cmd/cmd_connection.h60
-rw-r--r--src/charon-cmd/cmd/cmd_creds.c291
-rw-r--r--src/charon-cmd/cmd/cmd_creds.h55
-rw-r--r--src/charon-cmd/cmd/cmd_options.c65
-rw-r--r--src/charon-cmd/cmd/cmd_options.h76
11 files changed, 2615 insertions, 0 deletions
diff --git a/src/charon-cmd/Makefile.am b/src/charon-cmd/Makefile.am
new file mode 100644
index 000000000..9ed82be5e
--- /dev/null
+++ b/src/charon-cmd/Makefile.am
@@ -0,0 +1,32 @@
+sbin_PROGRAMS = charon-cmd
+CLEANFILES = charon-cmd.8
+dist_man8_MANS = charon-cmd.8
+EXTRA_DIST = charon-cmd.8.in
+
+charon_cmd_SOURCES = \
+ cmd/cmd_options.h cmd/cmd_options.c \
+ cmd/cmd_connection.h cmd/cmd_connection.c \
+ cmd/cmd_creds.h cmd/cmd_creds.c \
+ charon-cmd.c
+
+charon-cmd.o : $(top_builddir)/config.status
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon \
+ -DIPSEC_DIR=\"${ipsecdir}\" \
+ -DIPSEC_PIDDIR=\"${piddir}\" \
+ -DPLUGINS=\""${cmd_plugins}\""
+
+charon_cmd_LDADD = \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libhydra/libhydra.la \
+ $(top_builddir)/src/libcharon/libcharon.la \
+ -lm $(PTHREADLIB) $(DLLIB)
+
+charon-cmd.8 : charon-cmd.8.in
+ $(AM_V_GEN) \
+ sed \
+ -e "s:@IPSEC_VERSION@:$(PACKAGE_VERSION):" \
+ $(srcdir)/$@.in > $@
diff --git a/src/charon-cmd/Makefile.in b/src/charon-cmd/Makefile.in
new file mode 100644
index 000000000..aa18e05c7
--- /dev/null
+++ b/src/charon-cmd/Makefile.in
@@ -0,0 +1,812 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+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 = :
+build_triplet = @build@
+host_triplet = @host@
+sbin_PROGRAMS = charon-cmd$(EXEEXT)
+subdir = src/charon-cmd
+DIST_COMMON = $(dist_man8_MANS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.m4 \
+ $(top_srcdir)/m4/macros/with.m4 \
+ $(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
+PROGRAMS = $(sbin_PROGRAMS)
+am_charon_cmd_OBJECTS = cmd_options.$(OBJEXT) cmd_connection.$(OBJEXT) \
+ cmd_creds.$(OBJEXT) charon-cmd.$(OBJEXT)
+charon_cmd_OBJECTS = $(am_charon_cmd_OBJECTS)
+am__DEPENDENCIES_1 =
+charon_cmd_DEPENDENCIES = \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libhydra/libhydra.la \
+ $(top_builddir)/src/libcharon/libcharon.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(charon_cmd_SOURCES)
+DIST_SOURCES = $(charon_cmd_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man8_MANS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHECK_CFLAGS = @CHECK_CFLAGS@
+CHECK_LIBS = @CHECK_LIBS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GENHTML = @GENHTML@
+GPERF = @GPERF@
+GPRBUILD = @GPRBUILD@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREADLIB = @PTHREADLIB@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
+clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+dev_headers = @dev_headers@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+fips_mode = @fips_mode@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
+oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+CLEANFILES = charon-cmd.8
+dist_man8_MANS = charon-cmd.8
+EXTRA_DIST = charon-cmd.8.in
+charon_cmd_SOURCES = \
+ cmd/cmd_options.h cmd/cmd_options.c \
+ cmd/cmd_connection.h cmd/cmd_connection.c \
+ cmd/cmd_creds.h cmd/cmd_creds.c \
+ charon-cmd.c
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon \
+ -DIPSEC_DIR=\"${ipsecdir}\" \
+ -DIPSEC_PIDDIR=\"${piddir}\" \
+ -DPLUGINS=\""${cmd_plugins}\""
+
+charon_cmd_LDADD = \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libhydra/libhydra.la \
+ $(top_builddir)/src/libcharon/libcharon.la \
+ -lm $(PTHREADLIB) $(DLLIB)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .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 ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon-cmd/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/charon-cmd/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
+$(am__aclocal_m4_deps):
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+charon-cmd$(EXEEXT): $(charon_cmd_OBJECTS) $(charon_cmd_DEPENDENCIES) $(EXTRA_charon_cmd_DEPENDENCIES)
+ @rm -f charon-cmd$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(charon_cmd_OBJECTS) $(charon_cmd_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/charon-cmd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_connection.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_creds.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd_options.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+cmd_options.o: cmd/cmd_options.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cmd_options.o -MD -MP -MF $(DEPDIR)/cmd_options.Tpo -c -o cmd_options.o `test -f 'cmd/cmd_options.c' || echo '$(srcdir)/'`cmd/cmd_options.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cmd_options.Tpo $(DEPDIR)/cmd_options.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmd/cmd_options.c' object='cmd_options.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cmd_options.o `test -f 'cmd/cmd_options.c' || echo '$(srcdir)/'`cmd/cmd_options.c
+
+cmd_options.obj: cmd/cmd_options.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cmd_options.obj -MD -MP -MF $(DEPDIR)/cmd_options.Tpo -c -o cmd_options.obj `if test -f 'cmd/cmd_options.c'; then $(CYGPATH_W) 'cmd/cmd_options.c'; else $(CYGPATH_W) '$(srcdir)/cmd/cmd_options.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cmd_options.Tpo $(DEPDIR)/cmd_options.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmd/cmd_options.c' object='cmd_options.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cmd_options.obj `if test -f 'cmd/cmd_options.c'; then $(CYGPATH_W) 'cmd/cmd_options.c'; else $(CYGPATH_W) '$(srcdir)/cmd/cmd_options.c'; fi`
+
+cmd_connection.o: cmd/cmd_connection.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cmd_connection.o -MD -MP -MF $(DEPDIR)/cmd_connection.Tpo -c -o cmd_connection.o `test -f 'cmd/cmd_connection.c' || echo '$(srcdir)/'`cmd/cmd_connection.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cmd_connection.Tpo $(DEPDIR)/cmd_connection.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmd/cmd_connection.c' object='cmd_connection.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cmd_connection.o `test -f 'cmd/cmd_connection.c' || echo '$(srcdir)/'`cmd/cmd_connection.c
+
+cmd_connection.obj: cmd/cmd_connection.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cmd_connection.obj -MD -MP -MF $(DEPDIR)/cmd_connection.Tpo -c -o cmd_connection.obj `if test -f 'cmd/cmd_connection.c'; then $(CYGPATH_W) 'cmd/cmd_connection.c'; else $(CYGPATH_W) '$(srcdir)/cmd/cmd_connection.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cmd_connection.Tpo $(DEPDIR)/cmd_connection.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmd/cmd_connection.c' object='cmd_connection.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cmd_connection.obj `if test -f 'cmd/cmd_connection.c'; then $(CYGPATH_W) 'cmd/cmd_connection.c'; else $(CYGPATH_W) '$(srcdir)/cmd/cmd_connection.c'; fi`
+
+cmd_creds.o: cmd/cmd_creds.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cmd_creds.o -MD -MP -MF $(DEPDIR)/cmd_creds.Tpo -c -o cmd_creds.o `test -f 'cmd/cmd_creds.c' || echo '$(srcdir)/'`cmd/cmd_creds.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cmd_creds.Tpo $(DEPDIR)/cmd_creds.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmd/cmd_creds.c' object='cmd_creds.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cmd_creds.o `test -f 'cmd/cmd_creds.c' || echo '$(srcdir)/'`cmd/cmd_creds.c
+
+cmd_creds.obj: cmd/cmd_creds.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cmd_creds.obj -MD -MP -MF $(DEPDIR)/cmd_creds.Tpo -c -o cmd_creds.obj `if test -f 'cmd/cmd_creds.c'; then $(CYGPATH_W) 'cmd/cmd_creds.c'; else $(CYGPATH_W) '$(srcdir)/cmd/cmd_creds.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cmd_creds.Tpo $(DEPDIR)/cmd_creds.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmd/cmd_creds.c' object='cmd_creds.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cmd_creds.obj `if test -f 'cmd/cmd_creds.c'; then $(CYGPATH_W) 'cmd/cmd_creds.c'; else $(CYGPATH_W) '$(srcdir)/cmd/cmd_creds.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man8_MANS)
+ @$(NORMAL_INSTALL)
+ @list1='$(dist_man8_MANS)'; \
+ list2=''; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_man8_MANS)'; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ 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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ 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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @list='$(MANS)'; if test -n "$$list"; then \
+ list=`for p in $$list; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
+ if test -n "$$list" && \
+ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
+ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
+ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \
+ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \
+ echo " typically \`make maintainer-clean' will remove them" >&2; \
+ exit 1; \
+ else :; fi; \
+ else :; fi
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$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) $(MANS)
+installdirs:
+ for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; 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:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-generic clean-libtool clean-sbinPROGRAMS \
+ 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
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-sbinPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+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 \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-sbinPROGRAMS
+
+uninstall-man: uninstall-man8
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-sbinPROGRAMS ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-man8 install-pdf install-pdf-am install-ps \
+ install-ps-am install-sbinPROGRAMS install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-man uninstall-man8 \
+ uninstall-sbinPROGRAMS
+
+
+charon-cmd.o : $(top_builddir)/config.status
+
+charon-cmd.8 : charon-cmd.8.in
+ $(AM_V_GEN) \
+ sed \
+ -e "s:@IPSEC_VERSION@:$(PACKAGE_VERSION):" \
+ $(srcdir)/$@.in > $@
+
+# 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/charon-cmd/charon-cmd.8 b/src/charon-cmd/charon-cmd.8
new file mode 100644
index 000000000..e93cbcf6f
--- /dev/null
+++ b/src/charon-cmd/charon-cmd.8
@@ -0,0 +1,161 @@
+.TH CHARON\-CMD 8 "2013-06-21" "5.1.0" "strongSwan"
+.SH "NAME"
+charon\-cmd \- Simple IKE client (IPsec VPN client)
+.SH SYNOPSIS
+.B charon\-cmd
+.B \-\-host
+.I hostname
+.B \-\-identity
+.I identity
+.B [ options ]
+.PP
+.SH "DESCRIPTION"
+.B charon\-cmd
+is a program for setting up IPsec VPN connections using the Internet Key
+Exchange protocol (IKE) in version 1 and 2. It supports a number of different
+road-warrior scenarios.
+.PP
+Like the IKE daemon
+.BR charon ,
+.B charon\-cmd
+has to be run as
+.B root
+(or more specifically as a user with
+.B CAP_NET_ADMIN
+capability).
+.PP
+Of the following options at least
+.I \-\-host
+and
+.I \-\-identity
+are required. Depending on the selected authentication
+.I profile
+credentials also have to be provided with their respective options.
+.PP
+Many of the
+.BR charon -specific
+configuration options in
+.I strongswan.conf
+also apply to
+.BR charon\-cmd .
+For instance, to configure customized logging to
+.B stdout
+the following snippet can be used:
+.PP
+.EX
+ charon-cmd {
+ filelog {
+ stdout {
+ default = 1
+ ike = 2
+ cfg = 2
+ }
+ }
+ }
+.EE
+.PP
+.SH "OPTIONS"
+.TP
+.B "\-\-help"
+Prints usage information and a short summary of the available options.
+.TP
+.B "\-\-version"
+Prints the strongSwan version.
+.TP
+.BI "\-\-debug " level
+Sets the default log level (defaults to 1).
+.I level
+is a number between -1 and 4.
+Refer to
+.I strongswan.conf
+for options that allow a more fine-grained configuration of the logging
+output.
+.TP
+.BI "\-\-host " hostname
+DNS name or IP address to connect to.
+.TP
+.BI "\-\-identity " identity
+Identity the client uses for the IKE exchange.
+.TP
+.BI "\-\-eap\-identity " identity
+Identity the client uses for EAP authentication.
+.TP
+.BI "\-\-xauth\-username " username
+Username the client uses for XAuth authentication.
+.TP
+.BI "\-\-remote\-identity " identity
+Server identity to expect, defaults to
+.IR hostname .
+.TP
+.BI "\-\-cert " path
+Trusted certificate, either for authentication or trust chain validation.
+To provide more than one certificate multiple
+.B \-\-cert
+options can be used.
+.TP
+.BI "\-\-rsa " path
+RSA private key to use for authentication (if a password is required, it will
+be requested on demand).
+.TP
+.BI "\-\-p12 " path
+PKCS#12 file with private key and certificates to use for authentication and
+trust chain validation (if a password is required it will be requested on
+demand).
+.TP
+.RI "\fB\-\-agent\fR[=" socket ]
+Use SSH agent for authentication. If
+.I socket
+is not specified it is read from the
+.B SSH_AUTH_SOCK
+environment variable.
+.TP
+.BI "\-\-local\-ts " subnet
+Additional traffic selector to propose for our side, the requested virtual IP
+address will always be proposed.
+.TP
+.BI "\-\-remote\-ts " subnet
+Traffic selector to propose for remote side, defaults to 0.0.0.0/0.
+.TP
+.BI "\-\-profile " name
+Authentication profile to use, the list of supported profiles can be found
+in the
+.B Authentication Profiles
+sections below. Defaults to
+.B ikev2\-pub
+if a private key was supplied, and to
+.B ikev2\-eap
+otherwise.
+.PP
+.SS "IKEv2 Authentication Profiles"
+.TP
+.B "ikev2\-pub"
+IKEv2 with public key client and server authentication
+.TP
+.B "ikev2\-eap"
+IKEv2 with EAP client authentication and public key server authentication
+.TP
+.B "ikev2\-pub\-eap"
+IKEv2 with public key and EAP client authentication (RFC 4739) and public key
+server authentication
+.PP
+.SS "IKEv1 Authentication Profiles"
+The following authentication profiles use either Main Mode or Aggressive Mode,
+the latter is denoted with a \fB\-am\fR suffix.
+.TP
+.BR "ikev1\-pub" ", " "ikev1\-pub\-am"
+IKEv1 with public key client and server authentication
+.TP
+.BR "ikev1\-xauth" ", " "ikev1\-xauth\-am"
+IKEv1 with public key client and server authentication, followed by client XAuth
+authentication
+.TP
+.BR "ikev1\-xauth\-psk" ", " "ikev1\-xauth\-psk\-am"
+IKEv1 with pre-shared key (PSK) client and server authentication, followed by
+client XAuth authentication (INSECURE!)
+.TP
+.BR "ikev1\-hybrid" ", " "ikev1\-hybrid\-am"
+IKEv1 with public key server authentication only, followed by client XAuth
+authentication
+.PP
+.SH "SEE ALSO"
+\fBstrongswan.conf\fR(5), \fBipsec\fR(8)
diff --git a/src/charon-cmd/charon-cmd.8.in b/src/charon-cmd/charon-cmd.8.in
new file mode 100644
index 000000000..c9d52c92f
--- /dev/null
+++ b/src/charon-cmd/charon-cmd.8.in
@@ -0,0 +1,161 @@
+.TH CHARON\-CMD 8 "2013-06-21" "@IPSEC_VERSION@" "strongSwan"
+.SH "NAME"
+charon\-cmd \- Simple IKE client (IPsec VPN client)
+.SH SYNOPSIS
+.B charon\-cmd
+.B \-\-host
+.I hostname
+.B \-\-identity
+.I identity
+.B [ options ]
+.PP
+.SH "DESCRIPTION"
+.B charon\-cmd
+is a program for setting up IPsec VPN connections using the Internet Key
+Exchange protocol (IKE) in version 1 and 2. It supports a number of different
+road-warrior scenarios.
+.PP
+Like the IKE daemon
+.BR charon ,
+.B charon\-cmd
+has to be run as
+.B root
+(or more specifically as a user with
+.B CAP_NET_ADMIN
+capability).
+.PP
+Of the following options at least
+.I \-\-host
+and
+.I \-\-identity
+are required. Depending on the selected authentication
+.I profile
+credentials also have to be provided with their respective options.
+.PP
+Many of the
+.BR charon -specific
+configuration options in
+.I strongswan.conf
+also apply to
+.BR charon\-cmd .
+For instance, to configure customized logging to
+.B stdout
+the following snippet can be used:
+.PP
+.EX
+ charon-cmd {
+ filelog {
+ stdout {
+ default = 1
+ ike = 2
+ cfg = 2
+ }
+ }
+ }
+.EE
+.PP
+.SH "OPTIONS"
+.TP
+.B "\-\-help"
+Prints usage information and a short summary of the available options.
+.TP
+.B "\-\-version"
+Prints the strongSwan version.
+.TP
+.BI "\-\-debug " level
+Sets the default log level (defaults to 1).
+.I level
+is a number between -1 and 4.
+Refer to
+.I strongswan.conf
+for options that allow a more fine-grained configuration of the logging
+output.
+.TP
+.BI "\-\-host " hostname
+DNS name or IP address to connect to.
+.TP
+.BI "\-\-identity " identity
+Identity the client uses for the IKE exchange.
+.TP
+.BI "\-\-eap\-identity " identity
+Identity the client uses for EAP authentication.
+.TP
+.BI "\-\-xauth\-username " username
+Username the client uses for XAuth authentication.
+.TP
+.BI "\-\-remote\-identity " identity
+Server identity to expect, defaults to
+.IR hostname .
+.TP
+.BI "\-\-cert " path
+Trusted certificate, either for authentication or trust chain validation.
+To provide more than one certificate multiple
+.B \-\-cert
+options can be used.
+.TP
+.BI "\-\-rsa " path
+RSA private key to use for authentication (if a password is required, it will
+be requested on demand).
+.TP
+.BI "\-\-p12 " path
+PKCS#12 file with private key and certificates to use for authentication and
+trust chain validation (if a password is required it will be requested on
+demand).
+.TP
+.RI "\fB\-\-agent\fR[=" socket ]
+Use SSH agent for authentication. If
+.I socket
+is not specified it is read from the
+.B SSH_AUTH_SOCK
+environment variable.
+.TP
+.BI "\-\-local\-ts " subnet
+Additional traffic selector to propose for our side, the requested virtual IP
+address will always be proposed.
+.TP
+.BI "\-\-remote\-ts " subnet
+Traffic selector to propose for remote side, defaults to 0.0.0.0/0.
+.TP
+.BI "\-\-profile " name
+Authentication profile to use, the list of supported profiles can be found
+in the
+.B Authentication Profiles
+sections below. Defaults to
+.B ikev2\-pub
+if a private key was supplied, and to
+.B ikev2\-eap
+otherwise.
+.PP
+.SS "IKEv2 Authentication Profiles"
+.TP
+.B "ikev2\-pub"
+IKEv2 with public key client and server authentication
+.TP
+.B "ikev2\-eap"
+IKEv2 with EAP client authentication and public key server authentication
+.TP
+.B "ikev2\-pub\-eap"
+IKEv2 with public key and EAP client authentication (RFC 4739) and public key
+server authentication
+.PP
+.SS "IKEv1 Authentication Profiles"
+The following authentication profiles use either Main Mode or Aggressive Mode,
+the latter is denoted with a \fB\-am\fR suffix.
+.TP
+.BR "ikev1\-pub" ", " "ikev1\-pub\-am"
+IKEv1 with public key client and server authentication
+.TP
+.BR "ikev1\-xauth" ", " "ikev1\-xauth\-am"
+IKEv1 with public key client and server authentication, followed by client XAuth
+authentication
+.TP
+.BR "ikev1\-xauth\-psk" ", " "ikev1\-xauth\-psk\-am"
+IKEv1 with pre-shared key (PSK) client and server authentication, followed by
+client XAuth authentication (INSECURE!)
+.TP
+.BR "ikev1\-hybrid" ", " "ikev1\-hybrid\-am"
+IKEv1 with public key server authentication only, followed by client XAuth
+authentication
+.PP
+.SH "SEE ALSO"
+\fBstrongswan.conf\fR(5), \fBipsec\fR(8)
diff --git a/src/charon-cmd/charon-cmd.c b/src/charon-cmd/charon-cmd.c
new file mode 100644
index 000000000..5f4787b58
--- /dev/null
+++ b/src/charon-cmd/charon-cmd.c
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 2006-2013 Tobias Brunner
+ * Copyright (C) 2005-2013 Martin Willi
+ * Copyright (C) 2006 Daniel Roethlisberger
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#define _POSIX_PTHREAD_SEMANTICS /* for two param sigwait on OpenSolaris */
+#include <signal.h>
+#undef _POSIX_PTHREAD_SEMANTICS
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include <library.h>
+#include <hydra.h>
+#include <daemon.h>
+#include <utils/backtrace.h>
+#include <threading/thread.h>
+
+#include "cmd/cmd_options.h"
+#include "cmd/cmd_connection.h"
+#include "cmd/cmd_creds.h"
+
+/**
+ * Default loglevel
+ */
+static level_t default_loglevel = LEVEL_CTRL;
+
+/**
+ * Loglevel configuration
+ */
+static level_t levels[DBG_MAX];
+
+/**
+ * Connection to initiate
+ */
+static cmd_connection_t *conn;
+
+/**
+ * Credential backend
+ */
+static cmd_creds_t *creds;
+
+/**
+ * hook in library for debugging messages
+ */
+extern void (*dbg) (debug_t group, level_t level, char *fmt, ...);
+
+/**
+ * Logging hook for library logs, using stderr output
+ */
+static void dbg_stderr(debug_t group, level_t level, char *fmt, ...)
+{
+ va_list args;
+
+ if (level <= default_loglevel)
+ {
+ va_start(args, fmt);
+ fprintf(stderr, "00[%N] ", debug_names, group);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+ va_end(args);
+ }
+}
+
+/**
+ * Clean up connection definition atexit()
+ */
+static void cleanup_conn()
+{
+ DESTROY_IF(conn);
+}
+
+/**
+ * Clean up credentials atexit()
+ */
+static void cleanup_creds()
+{
+ DESTROY_IF(creds);
+}
+
+/**
+ * Run the daemon and handle unix signals
+ */
+static int run()
+{
+ sigset_t set;
+
+ /* handle SIGINT, SIGHUP and SIGTERM in this handler */
+ sigemptyset(&set);
+ sigaddset(&set, SIGINT);
+ sigaddset(&set, SIGHUP);
+ sigaddset(&set, SIGTERM);
+ sigaddset(&set, SIGUSR1);
+ sigprocmask(SIG_BLOCK, &set, NULL);
+
+ while (TRUE)
+ {
+ int sig;
+ int error;
+
+ error = sigwait(&set, &sig);
+ if (error)
+ {
+ DBG1(DBG_DMN, "error %d while waiting for a signal", error);
+ return 1;
+ }
+ switch (sig)
+ {
+ case SIGHUP:
+ {
+ DBG1(DBG_DMN, "signal of type SIGHUP received. Reloading "
+ "configuration");
+ if (lib->settings->load_files(lib->settings, NULL, FALSE))
+ {
+ charon->load_loggers(charon, levels, TRUE);
+ lib->plugins->reload(lib->plugins, NULL);
+ }
+ else
+ {
+ DBG1(DBG_DMN, "reloading config failed, keeping old");
+ }
+ break;
+ }
+ case SIGINT:
+ {
+ DBG1(DBG_DMN, "signal of type SIGINT received. Shutting down");
+ charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
+ return 0;
+ }
+ case SIGTERM:
+ {
+ DBG1(DBG_DMN, "signal of type SIGTERM received. Shutting down");
+ charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
+ return 0;
+ }
+ case SIGUSR1:
+ { /* an error occurred */
+ charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
+ return 1;
+ }
+ default:
+ {
+ DBG1(DBG_DMN, "unknown signal %d received. Ignored", sig);
+ break;
+ }
+ }
+ }
+}
+
+/**
+ * lookup UID and GID
+ */
+static bool lookup_uid_gid()
+{
+#ifdef IPSEC_USER
+ if (!lib->caps->resolve_uid(lib->caps, IPSEC_USER))
+ {
+ return FALSE;
+ }
+#endif
+#ifdef IPSEC_GROUP
+ if (!lib->caps->resolve_gid(lib->caps, IPSEC_GROUP))
+ {
+ return FALSE;
+ }
+#endif
+ return TRUE;
+}
+
+/**
+ * Handle SIGSEGV/SIGILL signals raised by threads
+ */
+static void segv_handler(int signal)
+{
+ backtrace_t *backtrace;
+
+ DBG1(DBG_DMN, "thread %u received %d", thread_current_id(), signal);
+ backtrace = backtrace_create(2);
+ backtrace->log(backtrace, stderr, TRUE);
+ backtrace->destroy(backtrace);
+
+ DBG1(DBG_DMN, "killing ourself, received critical signal");
+ abort();
+}
+
+/**
+ * Print command line usage and exit
+ */
+static void usage(FILE *out, char *msg, char *binary)
+{
+ static const int padto = 18;
+ char cmd[64], *pre, *post;
+ int i, line, pad;
+
+ if (msg)
+ {
+ fprintf(out, "%s\n", msg);
+ }
+ fprintf(out, "Usage: %s\n", binary);
+ for (i = 0; i < CMD_OPT_COUNT; i++)
+ {
+ switch (cmd_options[i].has_arg)
+ {
+ case required_argument:
+ pre = " <";
+ post = ">";
+ break;
+ case optional_argument:
+ pre = "[=";
+ post = "]";
+ break;
+ case no_argument:
+ default:
+ pre = " ";
+ post = " ";
+ break;
+ }
+ snprintf(cmd, sizeof(cmd), " --%s%s%s%s", cmd_options[i].name,
+ pre, cmd_options[i].arg, post);
+ pad = padto - strlen(cmd);
+ if (pad >= 1)
+ {
+ fprintf(out, "%s%-*s%s\n", cmd, pad, "", cmd_options[i].desc);
+ }
+ else
+ { /* write description to a separate line */
+ fprintf(out, "%s\n%-*s%s\n", cmd, padto, "", cmd_options[i].desc);
+ }
+ for (line = 0; line < countof(cmd_options[i].lines); line++)
+ {
+ if (cmd_options[i].lines[line])
+ {
+ fprintf(out, "%-*s%s\n", padto, "", cmd_options[i].lines[line]);
+ }
+ }
+ }
+}
+
+/**
+ * Handle command line options, if simple is TRUE only arguments like --help
+ * and --version are handled.
+ */
+static void handle_arguments(int argc, char *argv[], bool simple)
+{
+ struct option long_opts[CMD_OPT_COUNT + 1] = {};
+ int i, opt;
+
+ for (i = 0; i < CMD_OPT_COUNT; i++)
+ {
+ long_opts[i].name = cmd_options[i].name;
+ long_opts[i].val = cmd_options[i].id;
+ long_opts[i].has_arg = cmd_options[i].has_arg;
+ }
+ /* reset option parser */
+ optind = 1;
+ while (TRUE)
+ {
+ bool handled = FALSE;
+
+ opt = getopt_long(argc, argv, "", long_opts, NULL);
+ switch (opt)
+ {
+ case EOF:
+ break;
+ case CMD_OPT_HELP:
+ usage(stdout, NULL, argv[0]);
+ exit(0);
+ case CMD_OPT_VERSION:
+ printf("%s, strongSwan %s\n", "charon-cmd", VERSION);
+ exit(0);
+ case CMD_OPT_DEBUG:
+ default_loglevel = atoi(optarg);
+ continue;
+ default:
+ if (simple)
+ {
+ continue;
+ }
+ handled |= conn->handle(conn, opt, optarg);
+ handled |= creds->handle(creds, opt, optarg);
+ if (handled)
+ {
+ continue;
+ }
+ /* fall-through */
+ case '?':
+ /* missing argument, unrecognized option */
+ usage(stderr, NULL, argv[0]);
+ exit(1);
+ }
+ break;
+ }
+}
+
+/**
+ * Main function, starts the daemon.
+ */
+int main(int argc, char *argv[])
+{
+ struct sigaction action;
+ struct utsname utsname;
+ int group;
+
+ /* handle simple arguments */
+ handle_arguments(argc, argv, TRUE);
+
+ dbg = dbg_stderr;
+ atexit(library_deinit);
+ if (!library_init(NULL))
+ {
+ exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
+ }
+ if (lib->integrity)
+ {
+ if (!lib->integrity->check_file(lib->integrity, "charon-cmd", argv[0]))
+ {
+ exit(SS_RC_DAEMON_INTEGRITY);
+ }
+ }
+ atexit(libhydra_deinit);
+ if (!libhydra_init("charon-cmd"))
+ {
+ exit(SS_RC_INITIALIZATION_FAILED);
+ }
+ atexit(libcharon_deinit);
+ if (!libcharon_init("charon-cmd"))
+ {
+ exit(SS_RC_INITIALIZATION_FAILED);
+ }
+ for (group = 0; group < DBG_MAX; group++)
+ {
+ levels[group] = default_loglevel;
+ }
+ charon->load_loggers(charon, levels, TRUE);
+
+ if (!lookup_uid_gid())
+ {
+ exit(SS_RC_INITIALIZATION_FAILED);
+ }
+ lib->settings->set_default_str(lib->settings, "charon-cmd.port", "0");
+ lib->settings->set_default_str(lib->settings, "charon-cmd.port_nat_t", "0");
+ if (!charon->initialize(charon,
+ lib->settings->get_str(lib->settings, "charon-cmd.load", PLUGINS)))
+ {
+ exit(SS_RC_INITIALIZATION_FAILED);
+ }
+ if (!lib->caps->drop(lib->caps))
+ {
+ exit(SS_RC_INITIALIZATION_FAILED);
+ }
+
+ conn = cmd_connection_create();
+ atexit(cleanup_conn);
+ creds = cmd_creds_create();
+ atexit(cleanup_creds);
+
+ /* handle all arguments */
+ handle_arguments(argc, argv, FALSE);
+
+ if (uname(&utsname) != 0)
+ {
+ memset(&utsname, 0, sizeof(utsname));
+ }
+ DBG1(DBG_DMN, "Starting charon-cmd IKE client (strongSwan %s, %s %s, %s)",
+ VERSION, utsname.sysname, utsname.release, utsname.machine);
+ lib->plugins->status(lib->plugins, LEVEL_CTRL);
+
+ /* add handler for SEGV and ILL,
+ * INT, TERM and HUP are handled by sigwait() in run() */
+ action.sa_handler = segv_handler;
+ action.sa_flags = 0;
+ sigemptyset(&action.sa_mask);
+ sigaddset(&action.sa_mask, SIGINT);
+ sigaddset(&action.sa_mask, SIGTERM);
+ sigaddset(&action.sa_mask, SIGHUP);
+ sigaction(SIGSEGV, &action, NULL);
+ sigaction(SIGILL, &action, NULL);
+ sigaction(SIGBUS, &action, NULL);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &action, NULL);
+
+ pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL);
+
+ /* start daemon with thread-pool */
+ charon->start(charon);
+ /* wait for signal */
+ return run();
+}
diff --git a/src/charon-cmd/cmd/cmd_connection.c b/src/charon-cmd/cmd/cmd_connection.c
new file mode 100644
index 000000000..5c459f99f
--- /dev/null
+++ b/src/charon-cmd/cmd/cmd_connection.c
@@ -0,0 +1,498 @@
+/*
+ * Copyright (C) 2013 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ */
+
+#include "cmd_connection.h"
+
+#include <signal.h>
+#include <unistd.h>
+
+#include <utils/debug.h>
+#include <processing/jobs/callback_job.h>
+#include <threading/thread.h>
+#include <daemon.h>
+
+typedef enum profile_t profile_t;
+typedef struct private_cmd_connection_t private_cmd_connection_t;
+
+/**
+ * Connection profiles we support
+ */
+enum profile_t {
+ PROF_UNDEF,
+ PROF_V2_PUB,
+ PROF_V2_EAP,
+ PROF_V2_PUB_EAP,
+ PROF_V1_PUB,
+ PROF_V1_PUB_AM,
+ PROF_V1_XAUTH,
+ PROF_V1_XAUTH_AM,
+ PROF_V1_XAUTH_PSK,
+ PROF_V1_XAUTH_PSK_AM,
+ PROF_V1_HYBRID,
+ PROF_V1_HYBRID_AM,
+};
+
+ENUM(profile_names, PROF_V2_PUB, PROF_V1_HYBRID_AM,
+ "ikev2-pub",
+ "ikev2-eap",
+ "ikev2-pub-eap",
+ "ikev1-pub",
+ "ikev1-pub-am",
+ "ikev1-xauth",
+ "ikev1-xauth-am",
+ "ikev1-xauth-psk",
+ "ikev1-xauth-psk-am",
+ "ikev1-hybrid",
+ "ikev1-hybrid-am",
+);
+
+/**
+ * Private data of an cmd_connection_t object.
+ */
+struct private_cmd_connection_t {
+
+ /**
+ * Public cmd_connection_t interface.
+ */
+ cmd_connection_t public;
+
+ /**
+ * Process ID to terminate on failure
+ */
+ pid_t pid;
+
+ /**
+ * List of local traffic selectors
+ */
+ linked_list_t *local_ts;
+
+ /**
+ * List of remote traffic selectors
+ */
+ linked_list_t *remote_ts;
+
+ /**
+ * Hostname to connect to
+ */
+ char *host;
+
+ /**
+ * Server identity, or NULL to use host
+ */
+ char *server;
+
+ /**
+ * Local identity
+ */
+ char *identity;
+
+ /**
+ * XAuth/EAP identity
+ */
+ char *xautheap;
+
+ /**
+ * Is a private key configured
+ */
+ bool key_seen;
+
+ /**
+ * Selected connection profile
+ */
+ profile_t profile;
+};
+
+/**
+ * Shut down application
+ */
+static void terminate(pid_t pid)
+{
+ kill(pid, SIGUSR1);
+}
+
+/**
+ * Create peer config with associated ike config
+ */
+static peer_cfg_t* create_peer_cfg(private_cmd_connection_t *this)
+{
+ ike_cfg_t *ike_cfg;
+ peer_cfg_t *peer_cfg;
+ u_int16_t local_port, remote_port = IKEV2_UDP_PORT;
+ ike_version_t version = IKE_ANY;
+ bool aggressive = FALSE;
+
+ switch (this->profile)
+ {
+ case PROF_UNDEF:
+ case PROF_V2_PUB:
+ case PROF_V2_EAP:
+ case PROF_V2_PUB_EAP:
+ version = IKEV2;
+ break;
+ case PROF_V1_PUB_AM:
+ case PROF_V1_XAUTH_AM:
+ case PROF_V1_XAUTH_PSK_AM:
+ case PROF_V1_HYBRID_AM:
+ aggressive = TRUE;
+ /* FALL */
+ case PROF_V1_PUB:
+ case PROF_V1_XAUTH:
+ case PROF_V1_XAUTH_PSK:
+ case PROF_V1_HYBRID:
+ version = IKEV1;
+ break;
+ }
+
+ local_port = charon->socket->get_port(charon->socket, FALSE);
+ if (local_port != IKEV2_UDP_PORT)
+ {
+ remote_port = IKEV2_NATT_PORT;
+ }
+ ike_cfg = ike_cfg_create(version, TRUE, FALSE, "0.0.0.0", FALSE, local_port,
+ this->host, FALSE, remote_port, FRAGMENTATION_NO, 0);
+ ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
+ peer_cfg = peer_cfg_create("cmd", ike_cfg,
+ CERT_SEND_IF_ASKED, UNIQUE_REPLACE, 1, /* keyingtries */
+ 36000, 0, /* rekey 10h, reauth none */
+ 600, 600, /* jitter, over 10min */
+ TRUE, aggressive, /* mobike, aggressive */
+ 30, 0, /* DPD delay, timeout */
+ FALSE, NULL, NULL); /* mediation */
+ peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("0.0.0.0", 0));
+
+ return peer_cfg;
+}
+
+/**
+ * Add a single auth cfg of given class to peer cfg
+ */
+static void add_auth_cfg(private_cmd_connection_t *this, peer_cfg_t *peer_cfg,
+ bool local, auth_class_t class)
+{
+ identification_t *id;
+ auth_cfg_t *auth;
+
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, class);
+ if (local)
+ {
+ id = identification_create_from_string(this->identity);
+ if (this->xautheap)
+ {
+ switch (class)
+ {
+ case AUTH_CLASS_EAP:
+ auth->add(auth, AUTH_RULE_EAP_IDENTITY,
+ identification_create_from_string(this->xautheap));
+ break;
+ case AUTH_CLASS_XAUTH:
+ auth->add(auth, AUTH_RULE_XAUTH_IDENTITY,
+ identification_create_from_string(this->xautheap));
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (this->server)
+ {
+ id = identification_create_from_string(this->server);
+ }
+ else
+ {
+ id = identification_create_from_string(this->host);
+ }
+ auth->add(auth, AUTH_RULE_IDENTITY_LOOSE, TRUE);
+ }
+ auth->add(auth, AUTH_RULE_IDENTITY, id);
+ peer_cfg->add_auth_cfg(peer_cfg, auth, local);
+}
+
+/**
+ * Attach authentication configs to peer config
+ */
+static bool add_auth_cfgs(private_cmd_connection_t *this, peer_cfg_t *peer_cfg)
+{
+ if (this->profile == PROF_UNDEF)
+ {
+ if (this->key_seen)
+ {
+ this->profile = PROF_V2_PUB;
+ }
+ else
+ {
+ this->profile = PROF_V2_EAP;
+ }
+ }
+ switch (this->profile)
+ {
+ case PROF_V2_PUB:
+ case PROF_V2_PUB_EAP:
+ case PROF_V1_PUB:
+ case PROF_V1_XAUTH:
+ case PROF_V1_PUB_AM:
+ case PROF_V1_XAUTH_AM:
+ if (!this->key_seen)
+ {
+ DBG1(DBG_CFG, "missing private key for profile %N",
+ profile_names, this->profile);
+ return FALSE;
+ }
+ break;
+ default:
+ break;
+ }
+
+ switch (this->profile)
+ {
+ case PROF_V2_PUB:
+ add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_PUBKEY);
+ add_auth_cfg(this, peer_cfg, FALSE, AUTH_CLASS_ANY);
+ break;
+ case PROF_V2_EAP:
+ add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_EAP);
+ add_auth_cfg(this, peer_cfg, FALSE, AUTH_CLASS_ANY);
+ break;
+ case PROF_V2_PUB_EAP:
+ add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_PUBKEY);
+ add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_EAP);
+ add_auth_cfg(this, peer_cfg, FALSE, AUTH_CLASS_ANY);
+ break;
+ case PROF_V1_PUB:
+ case PROF_V1_PUB_AM:
+ add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_PUBKEY);
+ add_auth_cfg(this, peer_cfg, FALSE, AUTH_CLASS_PUBKEY);
+ break;
+ case PROF_V1_XAUTH:
+ case PROF_V1_XAUTH_AM:
+ add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_PUBKEY);
+ add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_XAUTH);
+ add_auth_cfg(this, peer_cfg, FALSE, AUTH_CLASS_PUBKEY);
+ break;
+ case PROF_V1_XAUTH_PSK:
+ case PROF_V1_XAUTH_PSK_AM:
+ add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_PSK);
+ add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_XAUTH);
+ add_auth_cfg(this, peer_cfg, FALSE, AUTH_CLASS_PSK);
+ break;
+ case PROF_V1_HYBRID:
+ case PROF_V1_HYBRID_AM:
+ add_auth_cfg(this, peer_cfg, TRUE, AUTH_CLASS_XAUTH);
+ add_auth_cfg(this, peer_cfg, FALSE, AUTH_CLASS_PUBKEY);
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Attach child config to peer config
+ */
+static child_cfg_t* create_child_cfg(private_cmd_connection_t *this)
+{
+ child_cfg_t *child_cfg;
+ traffic_selector_t *ts;
+ lifetime_cfg_t lifetime = {
+ .time = {
+ .life = 10800 /* 3h */,
+ .rekey = 10200 /* 2h50min */,
+ .jitter = 300 /* 5min */
+ }
+ };
+
+ child_cfg = child_cfg_create("cmd", &lifetime,
+ NULL, FALSE, MODE_TUNNEL, /* updown, hostaccess */
+ ACTION_NONE, ACTION_NONE, ACTION_NONE, FALSE,
+ 0, 0, NULL, NULL, 0);
+ child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
+ while (this->local_ts->remove_first(this->local_ts, (void**)&ts) == SUCCESS)
+ {
+ child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
+ }
+ if (this->remote_ts->get_count(this->remote_ts) == 0)
+ {
+ /* add a 0.0.0.0/0 TS for remote side if none given */
+ ts = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE,
+ "0.0.0.0", 0, "255.255.255.255", 65535);
+ this->remote_ts->insert_last(this->remote_ts, ts);
+ }
+ while (this->remote_ts->remove_first(this->remote_ts,
+ (void**)&ts) == SUCCESS)
+ {
+ child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
+ }
+
+ return child_cfg;
+}
+
+/**
+ * Initiate the configured connection
+ */
+static job_requeue_t initiate(private_cmd_connection_t *this)
+{
+ peer_cfg_t *peer_cfg;
+ child_cfg_t *child_cfg;
+ pid_t pid = this->pid;
+
+ if (!this->host)
+ {
+ DBG1(DBG_CFG, "unable to initiate, missing --host option");
+ terminate(pid);
+ return JOB_REQUEUE_NONE;
+ }
+ if (!this->identity)
+ {
+ DBG1(DBG_CFG, "unable to initiate, missing --identity option");
+ terminate(pid);
+ return JOB_REQUEUE_NONE;
+ }
+
+ peer_cfg = create_peer_cfg(this);
+
+ if (!add_auth_cfgs(this, peer_cfg))
+ {
+ peer_cfg->destroy(peer_cfg);
+ terminate(pid);
+ return JOB_REQUEUE_NONE;
+ }
+
+ child_cfg = create_child_cfg(this);
+ peer_cfg->add_child_cfg(peer_cfg, child_cfg->get_ref(child_cfg));
+
+ if (charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
+ controller_cb_empty, NULL, 0) != SUCCESS)
+ {
+ terminate(pid);
+ }
+ return JOB_REQUEUE_NONE;
+}
+
+/**
+ * Create a traffic selector from string, add to list
+ */
+static void add_ts(private_cmd_connection_t *this,
+ linked_list_t *list, char *string)
+{
+ traffic_selector_t *ts;
+
+ ts = traffic_selector_create_from_cidr(string, 0, 0, 65535);
+ if (!ts)
+ {
+ DBG1(DBG_CFG, "invalid traffic selector: %s", string);
+ exit(1);
+ }
+ list->insert_last(list, ts);
+}
+
+/**
+ * Parse profile name identifier
+ */
+static void set_profile(private_cmd_connection_t *this, char *name)
+{
+ int profile;
+
+ profile = enum_from_name(profile_names, name);
+ if (profile == -1)
+ {
+ DBG1(DBG_CFG, "unknown connection profile: %s", name);
+ exit(1);
+ }
+ this->profile = profile;
+}
+
+METHOD(cmd_connection_t, handle, bool,
+ private_cmd_connection_t *this, cmd_option_type_t opt, char *arg)
+{
+ switch (opt)
+ {
+ case CMD_OPT_HOST:
+ this->host = arg;
+ break;
+ case CMD_OPT_REMOTE_IDENTITY:
+ this->server = arg;
+ break;
+ case CMD_OPT_IDENTITY:
+ this->identity = arg;
+ break;
+ case CMD_OPT_EAP_IDENTITY:
+ case CMD_OPT_XAUTH_USER:
+ this->xautheap = arg;
+ break;
+ case CMD_OPT_RSA:
+ case CMD_OPT_AGENT:
+ case CMD_OPT_PKCS12:
+ this->key_seen = TRUE;
+ break;
+ case CMD_OPT_LOCAL_TS:
+ add_ts(this, this->local_ts, arg);
+ break;
+ case CMD_OPT_REMOTE_TS:
+ add_ts(this, this->remote_ts, arg);
+ break;
+ case CMD_OPT_PROFILE:
+ set_profile(this, arg);
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+METHOD(cmd_connection_t, destroy, void,
+ private_cmd_connection_t *this)
+{
+ this->local_ts->destroy_offset(this->local_ts,
+ offsetof(traffic_selector_t, destroy));
+ this->remote_ts->destroy_offset(this->remote_ts,
+ offsetof(traffic_selector_t, destroy));
+ free(this);
+}
+
+/**
+ * See header
+ */
+cmd_connection_t *cmd_connection_create()
+{
+ private_cmd_connection_t *this;
+
+ INIT(this,
+ .public = {
+ .handle = _handle,
+ .destroy = _destroy,
+ },
+ .pid = getpid(),
+ .local_ts = linked_list_create(),
+ .remote_ts = linked_list_create(),
+ .profile = PROF_UNDEF,
+ );
+
+ /* always include the virtual IP in traffic selector list */
+ this->local_ts->insert_last(this->local_ts,
+ traffic_selector_create_dynamic(0, 0, 65535));
+
+ /* queue job, gets initiated as soon as we are up and running */
+ lib->processor->queue_job(lib->processor,
+ (job_t*)callback_job_create_with_prio(
+ (callback_job_cb_t)initiate, this, NULL,
+ (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL));
+
+ return &this->public;
+}
diff --git a/src/charon-cmd/cmd/cmd_connection.h b/src/charon-cmd/cmd/cmd_connection.h
new file mode 100644
index 000000000..221802617
--- /dev/null
+++ b/src/charon-cmd/cmd/cmd_connection.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup charon-cmd charon-cmd
+ *
+ * @defgroup cmd cmd
+ * @ingroup charon-cmd
+ *
+ * @defgroup cmd_connection cmd_connection
+ * @{ @ingroup cmd
+ */
+
+#ifndef CMD_CONNECTION_H_
+#define CMD_CONNECTION_H_
+
+#include <library.h>
+
+#include "cmd_options.h"
+
+typedef struct cmd_connection_t cmd_connection_t;
+
+/**
+ * Connection definition to construct and initiate.
+ */
+struct cmd_connection_t {
+
+ /**
+ * Handle a command line option.
+ *
+ * @param opt option to handle
+ * @param arg option argument
+ * @return TRUE if option handled
+ */
+ bool (*handle)(cmd_connection_t *this, cmd_option_type_t opt, char *arg);
+
+ /**
+ * Destroy a cmd_connection_t.
+ */
+ void (*destroy)(cmd_connection_t *this);
+};
+
+/**
+ * Create a cmd_connection instance.
+ */
+cmd_connection_t *cmd_connection_create();
+
+#endif /** CMD_CONNECTION_H_ @}*/
diff --git a/src/charon-cmd/cmd/cmd_creds.c b/src/charon-cmd/cmd/cmd_creds.c
new file mode 100644
index 000000000..526ff7c9c
--- /dev/null
+++ b/src/charon-cmd/cmd/cmd_creds.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2013 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ */
+
+#include "cmd_creds.h"
+
+#include <unistd.h>
+
+#include <utils/debug.h>
+#include <credentials/sets/mem_cred.h>
+#include <credentials/containers/pkcs12.h>
+#include <credentials/sets/callback_cred.h>
+
+typedef struct private_cmd_creds_t private_cmd_creds_t;
+
+/**
+ * Private data of an cmd_creds_t object.
+ */
+struct private_cmd_creds_t {
+
+ /**
+ * Public cmd_creds_t interface.
+ */
+ cmd_creds_t public;
+
+ /**
+ * Reused in-memory credential set
+ */
+ mem_cred_t *creds;
+
+ /**
+ * Callback credential set to get secrets
+ */
+ callback_cred_t *cb;
+
+ /**
+ * Already prompted for password?
+ */
+ bool prompted;
+
+ /**
+ * Path to ssh-agent socket
+ */
+ char *agent;
+
+ /**
+ * Local identity
+ */
+ char *identity;
+};
+
+/**
+ * Callback function to prompt for secret
+ */
+static shared_key_t* callback_shared(private_cmd_creds_t *this,
+ shared_key_type_t type,
+ identification_t *me, identification_t *other,
+ id_match_t *match_me, id_match_t *match_other)
+{
+ shared_key_t *shared;
+ char *label, *pwd;
+
+ if (this->prompted)
+ {
+ return NULL;
+ }
+ switch (type)
+ {
+ case SHARED_EAP:
+ label = "EAP password: ";
+ break;
+ case SHARED_IKE:
+ label = "Preshared Key: ";
+ break;
+ case SHARED_PRIVATE_KEY_PASS:
+ label = "Password: ";
+ break;
+ default:
+ return NULL;
+ }
+ pwd = getpass(label);
+ if (!pwd || strlen(pwd) == 0)
+ {
+ return NULL;
+ }
+ this->prompted = TRUE;
+ if (match_me)
+ {
+ *match_me = ID_MATCH_PERFECT;
+ }
+ if (match_other)
+ {
+ *match_other = ID_MATCH_PERFECT;
+ }
+ shared = shared_key_create(type, chunk_clone(chunk_from_str(pwd)));
+ /* cache password in case it is required more than once */
+ this->creds->add_shared(this->creds, shared, NULL);
+ return shared->get_ref(shared);
+}
+
+/**
+ * Load a trusted certificate from path
+ */
+static void load_cert(private_cmd_creds_t *this, char *path)
+{
+ certificate_t *cert;
+
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, path, BUILD_END);
+ if (!cert)
+ {
+ DBG1(DBG_CFG, "loading certificate from '%s' failed", path);
+ exit(1);
+ }
+ this->creds->add_cert(this->creds, TRUE, cert);
+}
+
+/**
+ * Load a private key of given kind from path
+ */
+static void load_key(private_cmd_creds_t *this, key_type_t type, char *path)
+{
+ private_key_t *privkey;
+
+ privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
+ BUILD_FROM_FILE, path, BUILD_END);
+ if (!privkey)
+ {
+ DBG1(DBG_CFG, "loading %N private key from '%s' failed",
+ key_type_names, type, path);
+ exit(1);
+ }
+ this->creds->add_key(this->creds, privkey);
+}
+
+/**
+ * Load a private and public key via ssh-agent
+ */
+static void load_agent(private_cmd_creds_t *this)
+{
+ private_key_t *privkey;
+ public_key_t *pubkey;
+ identification_t *id;
+ certificate_t *cert;
+
+ privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
+ BUILD_AGENT_SOCKET, this->agent, BUILD_END);
+ if (!privkey)
+ {
+ DBG1(DBG_CFG, "failed to load private key from ssh-agent");
+ exit(1);
+ }
+ pubkey = privkey->get_public_key(privkey);
+ if (!pubkey)
+ {
+ DBG1(DBG_CFG, "failed to load public key from ssh-agent");
+ privkey->destroy(privkey);
+ exit(1);
+ }
+ id = identification_create_from_string(this->identity);
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,
+ CERT_TRUSTED_PUBKEY, BUILD_PUBLIC_KEY, pubkey,
+ BUILD_SUBJECT, id, BUILD_END);
+ pubkey->destroy(pubkey);
+ id->destroy(id);
+ if (!cert)
+ {
+ DBG1(DBG_CFG, "failed to create certificate for ssh-agent public key");
+ privkey->destroy(privkey);
+ exit(1);
+ }
+ this->creds->add_cert(this->creds, TRUE, cert);
+ this->creds->add_key(this->creds, privkey);
+}
+
+/**
+ * Load a PKCS#12 file from path
+ */
+static void load_pkcs12(private_cmd_creds_t *this, char *path)
+{
+ enumerator_t *enumerator;
+ certificate_t *cert;
+ private_key_t *key;
+ container_t *container;
+ pkcs12_t *pkcs12;
+
+ container = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12,
+ BUILD_FROM_FILE, path, BUILD_END);
+ if (!container)
+ {
+ DBG1(DBG_CFG, "loading PKCS#12 file '%s' failed", path);
+ exit(1);
+ }
+ pkcs12 = (pkcs12_t*)container;
+ enumerator = pkcs12->create_cert_enumerator(pkcs12);
+ while (enumerator->enumerate(enumerator, &cert))
+ {
+ this->creds->add_cert(this->creds, TRUE, cert->get_ref(cert));
+ }
+ enumerator->destroy(enumerator);
+ enumerator = pkcs12->create_key_enumerator(pkcs12);
+ while (enumerator->enumerate(enumerator, &key))
+ {
+ this->creds->add_key(this->creds, key->get_ref(key));
+ }
+ enumerator->destroy(enumerator);
+ container->destroy(container);
+}
+
+METHOD(cmd_creds_t, handle, bool,
+ private_cmd_creds_t *this, cmd_option_type_t opt, char *arg)
+{
+ switch (opt)
+ {
+ case CMD_OPT_CERT:
+ load_cert(this, arg);
+ break;
+ case CMD_OPT_RSA:
+ load_key(this, KEY_RSA, arg);
+ break;
+ case CMD_OPT_PKCS12:
+ load_pkcs12(this, arg);
+ break;
+ case CMD_OPT_IDENTITY:
+ this->identity = arg;
+ break;
+ case CMD_OPT_AGENT:
+ this->agent = arg ?: getenv("SSH_AUTH_SOCK");
+ if (!this->agent)
+ {
+ DBG1(DBG_CFG, "no ssh-agent socket defined");
+ exit(1);
+ }
+ break;
+ default:
+ return FALSE;
+ }
+ if (this->agent && this->identity)
+ {
+ load_agent(this);
+ /* only do this once */
+ this->agent = NULL;
+ }
+ return TRUE;
+}
+
+METHOD(cmd_creds_t, destroy, void,
+ private_cmd_creds_t *this)
+{
+ lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
+ lib->credmgr->remove_set(lib->credmgr, &this->cb->set);
+ this->creds->destroy(this->creds);
+ this->cb->destroy(this->cb);
+ free(this);
+}
+
+/**
+ * See header
+ */
+cmd_creds_t *cmd_creds_create()
+{
+ private_cmd_creds_t *this;
+
+ INIT(this,
+ .public = {
+ .handle = _handle,
+ .destroy = _destroy,
+ },
+ .creds = mem_cred_create(),
+ );
+ this->cb = callback_cred_create_shared((void*)callback_shared, this);
+
+ lib->credmgr->add_set(lib->credmgr, &this->creds->set);
+ lib->credmgr->add_set(lib->credmgr, &this->cb->set);
+
+ return &this->public;
+}
diff --git a/src/charon-cmd/cmd/cmd_creds.h b/src/charon-cmd/cmd/cmd_creds.h
new file mode 100644
index 000000000..053e596a5
--- /dev/null
+++ b/src/charon-cmd/cmd/cmd_creds.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup cmd_creds cmd_creds
+ * @{ @ingroup cmd
+ */
+
+#ifndef CMD_CREDS_H_
+#define CMD_CREDS_H_
+
+#include <library.h>
+
+#include "cmd_options.h"
+
+typedef struct cmd_creds_t cmd_creds_t;
+
+/**
+ * Credential backend providing certificates, private keys and shared secrets.
+ */
+struct cmd_creds_t {
+
+ /**
+ * Handle a command line options related to credentials.
+ *
+ * @param opt option to handle
+ * @param arg option argument
+ * @return TRUE if option handled
+ */
+ bool (*handle)(cmd_creds_t *this, cmd_option_type_t opt, char *arg);
+
+ /**
+ * Destroy a cmd_creds_t.
+ */
+ void (*destroy)(cmd_creds_t *this);
+};
+
+/**
+ * Create a cmd_creds instance.
+ */
+cmd_creds_t *cmd_creds_create();
+
+#endif /** CMD_CREDS_H_ @}*/
diff --git a/src/charon-cmd/cmd/cmd_options.c b/src/charon-cmd/cmd/cmd_options.c
new file mode 100644
index 000000000..597ccda1f
--- /dev/null
+++ b/src/charon-cmd/cmd/cmd_options.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2013 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ */
+
+#include "cmd_options.h"
+
+#include <getopt.h>
+
+/**
+ * See header.
+ */
+cmd_option_t cmd_options[CMD_OPT_COUNT] = {
+ { CMD_OPT_HELP, "help", no_argument, "",
+ "print this usage information and exit", {}},
+ { CMD_OPT_VERSION, "version", no_argument, "",
+ "show version information and exit", {}},
+ { CMD_OPT_DEBUG, "debug", required_argument, "level",
+ "set the default log level (-1..4, default: 1)", {}},
+ { CMD_OPT_HOST, "host", required_argument, "hostname",
+ "DNS name or address to connect to", {}},
+ { CMD_OPT_IDENTITY, "identity", required_argument, "identity",
+ "identity the client uses for the IKE exchange", {}},
+ { CMD_OPT_EAP_IDENTITY, "eap-identity", required_argument, "eap-identity",
+ "identity the client uses for EAP authentication", {}},
+ { CMD_OPT_XAUTH_USER, "xauth-username", required_argument, "xauth-username",
+ "username the client uses for XAuth authentication", {}},
+ { CMD_OPT_REMOTE_IDENTITY, "remote-identity", required_argument, "identity",
+ "server identity to expect, defaults to host", {}},
+ { CMD_OPT_CERT, "cert", required_argument, "path",
+ "certificate for authentication or trust chain validation", {}},
+ { CMD_OPT_RSA, "rsa", required_argument, "path",
+ "RSA private key to use for authentication", {}},
+ { CMD_OPT_PKCS12, "p12", required_argument, "path",
+ "PKCS#12 file with private key and certificates to use for ", {
+ "authentication and trust chain validation"
+ }},
+ { CMD_OPT_AGENT, "agent", optional_argument, "socket",
+ "use SSH agent for authentication. If socket is not specified", {
+ "it is read from the SSH_AUTH_SOCK environment variable",
+ }},
+ { CMD_OPT_LOCAL_TS, "local-ts", required_argument, "subnet",
+ "additional traffic selector to propose for our side", {}},
+ { CMD_OPT_REMOTE_TS, "remote-ts", required_argument, "subnet",
+ "traffic selector to propose for remote side", {}},
+ { CMD_OPT_PROFILE, "profile", required_argument, "name",
+ "authentication profile to use, where name is one of:", {
+ " ikev2-pub, ikev2-eap, ikev2-pub-eap",
+ " ikev1-pub[-am], ikev1-xauth[-am],",
+ " ikev1-xauth-psk[-am], ikev1-hybrid[-am]",
+ }},
+};
diff --git a/src/charon-cmd/cmd/cmd_options.h b/src/charon-cmd/cmd/cmd_options.h
new file mode 100644
index 000000000..6b8b04cdf
--- /dev/null
+++ b/src/charon-cmd/cmd/cmd_options.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2013 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup cmd_option cmd_option
+ * @{ @ingroup cmd
+ */
+
+#ifndef CMD_OPTION_H_
+#define CMD_OPTION_H_
+
+typedef struct cmd_option_t cmd_option_t;
+typedef enum cmd_option_type_t cmd_option_type_t;
+
+/**
+ * Command line options
+ */
+enum cmd_option_type_t {
+ CMD_OPT_HELP,
+ CMD_OPT_VERSION,
+ CMD_OPT_DEBUG,
+ CMD_OPT_HOST,
+ CMD_OPT_IDENTITY,
+ CMD_OPT_EAP_IDENTITY,
+ CMD_OPT_XAUTH_USER,
+ CMD_OPT_REMOTE_IDENTITY,
+ CMD_OPT_CERT,
+ CMD_OPT_RSA,
+ CMD_OPT_PKCS12,
+ CMD_OPT_AGENT,
+ CMD_OPT_LOCAL_TS,
+ CMD_OPT_REMOTE_TS,
+ CMD_OPT_PROFILE,
+
+ CMD_OPT_COUNT
+};
+
+/**
+ * Command line arguments, similar to "struct option", but with descriptions
+ */
+struct cmd_option_t {
+ /** option identifier */
+ cmd_option_type_t id;
+ /** long option name */
+ const char *name;
+ /** takes argument */
+ int has_arg;
+ /** decription of argument */
+ const char *arg;
+ /** short description to option */
+ const char *desc;
+ /** additional description lines */
+ const char *lines[12];
+};
+
+/**
+ * Registered CMD options.
+ */
+extern cmd_option_t cmd_options[CMD_OPT_COUNT];
+
+#endif /** CMD_OPTION_H_ @}*/