From: Yu Jiung Date: Thu, 6 Apr 2017 09:13:55 +0000 (+0900) Subject: Add modules for ipsec RSA test X-Git-Tag: submit/tizen/20170612.082510^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F37%2F123637%2F7;p=platform%2Fcore%2Fapi%2Fvpn-setting.git Add modules for ipsec RSA test Change-Id: I35cf7fd0c6830e665a7aeea209c630a43170f94f Signed-off-by: Yu jiung --- diff --git a/dvpnlib/include/dvpnlib-vpn-connection.h b/dvpnlib/include/dvpnlib-vpn-connection.h index 20682ea..f6163ed 100755 --- a/dvpnlib/include/dvpnlib-vpn-connection.h +++ b/dvpnlib/include/dvpnlib-vpn-connection.h @@ -85,7 +85,7 @@ typedef void (*vpn_connection_property_changed_cb)( /* experimental */ GList *vpn_get_connections(void); struct vpn_connection *vpn_get_connection( - const char *host, const char *domain); + const char *name, const char *host, const char *domain); enum dvpnlib_err vpn_connection_clear_property( struct vpn_connection *connection); enum dvpnlib_err vpn_connection_connect(struct vpn_connection *connection, diff --git a/dvpnlib/src/dvpnlib-vpn-connnection.c b/dvpnlib/src/dvpnlib-vpn-connnection.c index 824e614..03cedfe 100755 --- a/dvpnlib/src/dvpnlib-vpn-connnection.c +++ b/dvpnlib/src/dvpnlib-vpn-connnection.c @@ -792,9 +792,9 @@ GList *vpn_get_connections(void) } struct vpn_connection *vpn_get_connection( - const char *host, const char *domain) + const char *name, const char *host, const char *domain) { - if (!host || !domain) + if (!name || !host || !domain) return NULL; GList *iter; @@ -804,7 +804,8 @@ struct vpn_connection *vpn_get_connection( struct vpn_connection *connection = (struct vpn_connection *)(iter->data); - if (g_str_equal(connection->host, host) && + if (g_str_equal(connection->name, name) && + g_str_equal(connection->host, host) && g_str_equal(connection->domain, domain)) return connection; } diff --git a/include/vpn.h b/include/vpn.h index ab6e7ea..90f2d20 100755 --- a/include/vpn.h +++ b/include/vpn.h @@ -314,7 +314,8 @@ int vpn_disconnect(vpn_h handle, vpn_disconnect_cb callback, void *user_data); GList *vpn_get_vpn_handle_list(void); /** -* @brief Get Specific VPN Handle based on host & domain. +* @brief Get Specific VPN Handle based on name, host & domain. +* @param[in] name The VPN Name Identifier. * @param[in] host The VPN Host Identifier. * @param[in] domain The VPN Domain Identifier. * @param[out] handle The VPN handle that matches host & domain. @@ -324,7 +325,7 @@ GList *vpn_get_vpn_handle_list(void); * @retval #VPN_ERROR_INVALID_PARAMETER Operation failed * @see vpn_get_vpn_handle_list() */ -int vpn_get_vpn_handle(const char *host, const char *domain, vpn_h *handle); +int vpn_get_vpn_handle(const char *name, const char *host, const char *domain, vpn_h *handle); /** * @brief Get VPN Info (Name) diff --git a/packaging/capi-network-vpn-setting.spec b/packaging/capi-network-vpn-setting.spec index f9d2a40..268e0ad 100755 --- a/packaging/capi-network-vpn-setting.spec +++ b/packaging/capi-network-vpn-setting.spec @@ -1,3 +1,5 @@ +%define ipsec_test no + Name: capi-network-vpn-setting Summary: Default VPN Library Version: 0.1.0_3 @@ -11,6 +13,18 @@ BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(capi-base-common) +BuildRequires: pkgconfig(libtzplatform-config) +%if "%{ipsec_test}" == "yes" +BuildRequires: openssl + +%global rw_app_dir %{?TZ_SYS_RW_APP:%TZ_SYS_RW_APP}%{!?TZ_SYS_RW_APP:/opt/usr/apps} +%global cert_examples %rw_app_dir/vpn-cert-examples +%define etc_dir %{?TZ_SYS_ETC:%TZ_SYS_ETC}%{!?TZ_SYS_ETC:/opt/etc} +%define ro_etc_dir %{?TZ_SYS_RO_ETC:%TZ_SYS_RO_ETC}%{!?TZ_SYS_RO_ETC:%_sysconfdir} +%global ca_certs_dir %{?TZ_SYS_CA_CERTS:%TZ_SYS_CA_CERTS}%{!?TZ_SYS_CA_CERTS:%etc_dir/ssl/certs} + +%global host_cert_examples %etc_dir/vpn-cert-examples +%endif %description Library code for CAPI's to interact with the Default VPN functionality on TIZEN platform. @@ -30,21 +44,41 @@ Requires: %{name} = %{version} %description test Test cases for Default VPN Functionality on TIZEN platform. +%if "%{ipsec_test}" == "yes" +%package host-cert +Summary: Certification for host +AutoReqProv: no + +%description host-cert +Certification and private key for strongswan responder +%endif + %prep %setup -q cp %{SOURCE1001} . - %build MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` -%cmake . -DFULLVER=%{version} -DMAJORVER=${MAJORVER} +%cmake . \ +%if "%{ipsec_test}" == "yes" + -DIPSEC_TEST=1 \ + -DCERT_EXAMPLES=%cert_examples \ + -DHOST_CERT_EXAMPLES=%host_cert_examples \ + -DCA_CERTS_DIR=%ca_certs_dir \ +%endif + -DFULLVER=%{version} \ + -DMAJORVER=${MAJORVER} make %{?_smp_mflags} - %install %make_install +%if "%{ipsec_test}" == "yes" +mkdir -p %buildroot%cert_examples +mkdir -p %buildroot%host_cert_examples +%endif + #License mkdir -p %{buildroot}%{_datadir}/license cp LICENSE.APLv2 %{buildroot}%{_datadir}/license/capi-network-vpn-setting @@ -69,3 +103,10 @@ cp LICENSE.APLv2 %{buildroot}%{_datadir}/license/capi-network-vpn-setting %manifest %{name}.manifest %{_libdir}/vpn_setting_test %{_bindir}/vpn_setting_test +%if "%{ipsec_test}" == "yes" +%{cert_examples}/* + +%files host-cert +%{host_cert_examples}/* +%endif + diff --git a/src/include/vpn-internal.h b/src/include/vpn-internal.h index 7669aa0..f1395f9 100755 --- a/src/include/vpn-internal.h +++ b/src/include/vpn-internal.h @@ -71,7 +71,7 @@ int _vpn_connect(vpn_h handle, vpn_removed_cb callback, void *user_data); int _vpn_disconnect(vpn_h handle); GList *_vpn_get_vpn_handle_list(void); -int _vpn_get_vpn_handle(const char *host, const char *domain, vpn_h *handle); +int _vpn_get_vpn_handle(const char *name, const char *host, const char *domain, vpn_h *handle); int _vpn_get_vpn_info_name(vpn_h handle, const char **name); int _vpn_get_vpn_info_type(vpn_h handle, const char **type); int _vpn_get_vpn_info_host(vpn_h handle, const char **host); diff --git a/src/vpn-internal.c b/src/vpn-internal.c index 63293ad..dd3ad57 100755 --- a/src/vpn-internal.c +++ b/src/vpn-internal.c @@ -331,16 +331,16 @@ GList *_vpn_get_vpn_handle_list(void) } /* - * Get a specific VPN Handle based on host & domain parameters + * Get a specific VPN Handle based on name, host & domain parameters */ -int _vpn_get_vpn_handle(const char *host, const char *domain, vpn_h *handle) +int _vpn_get_vpn_handle(const char *name, const char *host, const char *domain, vpn_h *handle) { VPN_LOG(VPN_INFO, ""); - struct vpn_connection *connection = vpn_get_connection(host, domain); + struct vpn_connection *connection = vpn_get_connection(name, host, domain); if (connection == NULL) { - VPN_LOG(VPN_ERROR, "host=%s domain=%s", host, domain); + VPN_LOG(VPN_ERROR, "name=%s host=%s domain=%s", name, host, domain); return VPN_ERROR_INVALID_PARAMETER; } diff --git a/src/vpn.c b/src/vpn.c index ec45d53..cfd7e31 100755 --- a/src/vpn.c +++ b/src/vpn.c @@ -282,7 +282,7 @@ GList *vpn_get_vpn_handle_list(void) } EXPORT_API -int vpn_get_vpn_handle(const char *host, const char *domain, vpn_h *handle) +int vpn_get_vpn_handle(const char *name, const char *host, const char *domain, vpn_h *handle) { int rv; @@ -291,10 +291,10 @@ int vpn_get_vpn_handle(const char *host, const char *domain, vpn_h *handle) return VPN_ERROR_INVALID_OPERATION; } - if (host == NULL || domain == NULL || handle == NULL) + if (name == NULL || host == NULL || domain == NULL || handle == NULL) return VPN_ERROR_INVALID_PARAMETER; - rv = _vpn_get_vpn_handle(host, domain, handle); + rv = _vpn_get_vpn_handle(name, host, domain, handle); if (rv != VPN_ERROR_NONE) VPN_LOG(VPN_ERROR, "Error!! VPN Get Handle failed.\n"); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7477e12..cb6896e 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,6 +2,8 @@ SET(fw_test "vpn_setting_test") SET(dependents "capi-base-common glib-2.0") +SET(VPN_SETTING_CAPI_TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + INCLUDE(FindPkgConfig) pkg_check_modules(${fw_test} REQUIRED ${dependents}) FOREACH(flag ${${fw_test}_CFLAGS}) @@ -11,6 +13,12 @@ ENDFOREACH(flag) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -fPIE") SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie") +IF(IPSEC_TEST) + ADD_DEFINITIONS(-DIPSEC_TEST) + ADD_DEFINITIONS("-DCERT_EXAMPLES_DIR=\"${CERT_EXAMPLES}/\"") + ADD_DEFINITIONS("-DCA_CERTS_DIR=\"${CA_CERTS_DIR}/\"") +ENDIF(IPSEC_TEST) + aux_source_directory(. sources) FOREACH(src ${sources}) GET_FILENAME_COMPONENT(src_name ${src} NAME_WE) @@ -20,3 +28,7 @@ FOREACH(src ${sources}) INSTALL(TARGETS ${fw_test} DESTINATION ${LIB_INSTALL_DIR}/vpn_setting_test/) INSTALL(TARGETS ${fw_test} RUNTIME DESTINATION bin/) ENDFOREACH() + +IF(IPSEC_TEST) + ADD_SUBDIRECTORY(ipsec_test) +ENDIF(IPSEC_TEST) \ No newline at end of file diff --git a/test/ipsec_test/CMakeLists.txt b/test/ipsec_test/CMakeLists.txt new file mode 100644 index 0000000..4b553a5 --- /dev/null +++ b/test/ipsec_test/CMakeLists.txt @@ -0,0 +1,65 @@ +MESSAGE("GENERATING....") +MESSAGE("current...." ${CMAKE_CURRENT_SOURCE_DIR}) + +SET(ROOT_CA_CERT "root-ca-cert.PEM") + +SET(HOST_PRIVATE "host-private.PEM") +SET(HOST_CERT "host-cert.PEM") +SET(HOST_CMD "ipsec_server") +SET(HOST_CONF "server.conf") + +SET(CLIENT_PRIVATE "client-private.PEM") +SET(CLIENT_DER_CERT "client-cert.DER") +SET(CLIENT_PEM_CERT "client-cert.PEM") +SET(CLIENT_PKCS12_CERT "client-cert.p12") + +ADD_CUSTOM_COMMAND(OUTPUT + ${ROOT_CA_CERT} + ${HOST_PRIVATE} + ${HOST_CERT} + ${CLIENT_PRIVATE} + ${CLIENT_DER_CERT} + ${CLIENT_PEM_CERT} + ${CLIENT_PKCS12_CERT} + + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/gen_cert.sh create_certs + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Generating custom certification" + ) + +ADD_CUSTOM_TARGET(cert_output ALL + DEPENDS + ${ROOT_CA_CERT} + ${HOST_PRIVATE} + ${HOST_CERT} + ${CLIENT_PRIVATE} + ${CLIENT_DER_CERT} + ${CLIENT_PEM_CERT} + ${CLIENT_PKCS12_CERT} + ) + +INSTALL(FILES + ${ROOT_CA_CERT} + ${CLIENT_PRIVATE} + ${CLIENT_DER_CERT} + ${CLIENT_PEM_CERT} + ${CLIENT_PKCS12_CERT} + + DESTINATION ${CERT_EXAMPLES} + PERMISSIONS OWNER_READ + GROUP_READ + WORLD_READ + ) + +INSTALL(FILES + ${ROOT_CA_CERT} + ${HOST_PRIVATE} + ${HOST_CERT} + ${HOST_CMD} + ${HOST_CONF} + + DESTINATION ${HOST_CERT_EXAMPLES} + PERMISSIONS OWNER_READ + GROUP_READ + WORLD_READ + ) \ No newline at end of file diff --git a/test/ipsec_test/README b/test/ipsec_test/README new file mode 100644 index 0000000..28958cc --- /dev/null +++ b/test/ipsec_test/README @@ -0,0 +1,22 @@ +[files] +gen_certs.sh=shell script for certification files + +root-ca-req.conf=configuration file to generate root certification + +root-ca.conf=configuration file for CA + +host-cert-req.conf=Configuration file to generate host certification. You should make CN and SubjectAltName same with the Ipsec VPN server's IP or DNS + +client-cert-req.conf=Configuration file to generate client certification + +ipsec_server=strongswan responder cmdline tool. Generated from x86_64 linux + +server.conf=strongswan responder configuration. + +ipsec_server_src=folder includes the source code of ipsec_server. + +[generated files] +root-ca folder=Folder for Root CA +host cert and private key=host-private.PEM, host-cert.PEM +client certs and private key=client-private.PEM, client-cert.DER, client-cert.PEM, client-cert.p12 + diff --git a/test/ipsec_test/client-cert-req.conf b/test/ipsec_test/client-cert-req.conf new file mode 100644 index 0000000..935eb4b --- /dev/null +++ b/test/ipsec_test/client-cert-req.conf @@ -0,0 +1,16 @@ +[ req ] +distinguished_name = req_distinguished_name +req_extensions = client_req +prompt = no + + +[ req_distinguished_name ] +C = KR +ST = Seocho-Gu +L = Seoul +O = Samsung Electronics .Inc +OU = . +CN = dave@samsung.com + +[ client_req ] +subjectAltName = email:dave@samsung.com diff --git a/test/ipsec_test/gen_cert.sh b/test/ipsec_test/gen_cert.sh new file mode 100755 index 0000000..3b3926c --- /dev/null +++ b/test/ipsec_test/gen_cert.sh @@ -0,0 +1,189 @@ +#! /bin/bash + +ROOT_CA_DIR=root-ca +CERT_DIR=cert +NEW_CERT_DIR=newcerts +DB_DIR=db +PRIVATE_DIR=private + +ROOT_CA_PRIVATE_NAME=root-ca-private.PEM +ROOT_CA_CERT_NAME=root-ca-cert.PEM +ROOT_CA_REQ_CONF_FILE_NAME=root-ca-req.conf + +HOST_PRIVATE_NAME=host-private.PEM +HOST_CERT_REQ_NAME=host-cert.csr +HOST_CERT_NAME=host-cert.PEM +HOST_REQ_CONF_FILE_NAME=host-cert-req.conf + +CLIENT_PRIVATE_NAME=client-private.PEM +CLIENT_CERT_REQ_NAME=client-cert.csr +CLIENT_DER_CERT_NAME=client-cert.DER +CLIENT_PEM_CERT_NAME=client-cert.PEM +CLIENT_PKCS12_CERT_NAME=client-cert.p12 +CLIENT_REQ_CONF_FILE_NAME=client-cert-req.conf + +CLIENT_CERT_NAME='"Dave Cert"' + +ROOT_CA_CONF_FILE_NAME=root-ca.conf + + +OPENSSL=/usr/bin/openssl + +make_root_ca_dir() +{ + echo "make_root_ca_dir" + CURRENT_DIR=$(cd "$(dirname "$0")" && pwd) + echo $CURRENT_DIR + + /bin/mkdir -p $CURRENT_DIR/$ROOT_CA_DIR + /bin/mkdir -p $CURRENT_DIR/$ROOT_CA_DIR/$CERT_DIR + /bin/mkdir -p $CURRENT_DIR/$ROOT_CA_DIR/$NEW_CERT_DIR + /bin/mkdir -p $CURRENT_DIR/$ROOT_CA_DIR/$DB_DIR + /bin/mkdir -p $CURRENT_DIR/$ROOT_CA_DIR/$PRIVATE_DIR + + /bin/chmod 700 $CURRENT_DIR/$ROOT_CA_DIR/$PRIVATE_DIR + /bin/touch $CURRENT_DIR/$ROOT_CA_DIR/$DB_DIR/index.txt + $OPENSSL rand -hex 16 > $CURRENT_DIR/$ROOT_CA_DIR/$DB_DIR/serial + echo 1001 > $CURRENT_DIR/$ROOT_CA_DIR/$DB_DIR/crlnumber + +} + +root_ca_generation() +{ + echo "root_ca_generation" + CURRENT_DIR=$(cd "$(dirname "$0")" && pwd) + echo $CURRENT_DIR + + ROOT_CA_PRIVATE=$CURRENT_DIR/$ROOT_CA_DIR/$PRIVATE_DIR/$ROOT_CA_PRIVATE_NAME + ROOT_CA_REQ_CONFIG=$CURRENT_DIR/$ROOT_CA_REQ_CONF_FILE_NAME + ROOT_CA_CERT=$CURRENT_DIR/$ROOT_CA_DIR/$CERT_DIR/$ROOT_CA_CERT_NAME + + echo "root CA private key" + $OPENSSL genrsa -aes128 -passout pass:1234 -out $ROOT_CA_PRIVATE 2048 + $OPENSSL rsa -in $ROOT_CA_PRIVATE -passin pass:1234 -out $ROOT_CA_PRIVATE + + echo "root CA cert" + $OPENSSL req -new -x509 -config $ROOT_CA_REQ_CONFIG -key $ROOT_CA_PRIVATE -out $ROOT_CA_CERT +} + +host_cert_generation() +{ + echo "host_cert_generation" + CURRENT_DIR=$(cd "$(dirname "$0")" && pwd) + echo $CURRENT_DIR + + ROOT_CA_CONFIG=$CURRENT_DIR/$ROOT_CA_CONF_FILE_NAME + + HOST_PRIVATE=$CURRENT_DIR/$HOST_PRIVATE_NAME + HOST_CONFIG=$CURRENT_DIR/$HOST_REQ_CONF_FILE_NAME + HOST_CERT_REQ=$CURRENT_DIR/$HOST_CERT_REQ_NAME + HOST_CERT=$CURRENT_DIR/$HOST_CERT_NAME + + echo "host private key" + $OPENSSL genrsa -aes128 -passout pass:1234 -out $HOST_PRIVATE 2048 + $OPENSSL rsa -in $HOST_PRIVATE -passin pass:1234 -out $HOST_PRIVATE + + echo "host cert" + $OPENSSL req -new -config $HOST_CONFIG -reqexts host_req -key $HOST_PRIVATE -out $HOST_CERT_REQ + $OPENSSL ca -batch -config $ROOT_CA_CONFIG -in $HOST_CERT_REQ -out $HOST_CERT + + /bin/rm $HOST_CERT_REQ +} + +client_cert_generation() +{ + echo "client_cert_generation" + CURRENT_DIR=$(cd "$(dirname "$0")" && pwd) + echo $CURRENT_DIR + + ROOT_CA_CONFIG=$CURRENT_DIR/$ROOT_CA_CONF_FILE_NAME + ROOT_CA_CERT=$CURRENT_DIR/$ROOT_CA_DIR/$CERT_DIR/$ROOT_CA_CERT_NAME + + CLIENT_PRIVATE=$CURRENT_DIR/$CLIENT_PRIVATE_NAME + CLIENT_CONFIG=$CURRENT_DIR/$CLIENT_REQ_CONF_FILE_NAME + CLIENT_CERT_REQ=$CURRENT_DIR/$CLIENT_CERT_REQ_NAME + CLIENT_DER_CERT=$CURRENT_DIR/$CLIENT_DER_CERT_NAME + CLIENT_PEM_CERT=$CURRENT_DIR/$CLIENT_PEM_CERT_NAME + CLIENT_PKCS12_CERT=$CURRENT_DIR/$CLIENT_PKCS12_CERT_NAME + + echo "client private key" + $OPENSSL genrsa -aes128 -passout pass:1234 -out $CLIENT_PRIVATE 2048 + $OPENSSL rsa -in $CLIENT_PRIVATE -passin pass:1234 -out $CLIENT_PRIVATE + + echo "client cert" + $OPENSSL req -new -config $CLIENT_CONFIG -reqexts client_req -key $CLIENT_PRIVATE -out $CLIENT_CERT_REQ + $OPENSSL ca -batch -config $ROOT_CA_CONFIG -in $CLIENT_CERT_REQ -out $CLIENT_PEM_CERT + + $OPENSSL x509 -in $CLIENT_PEM_CERT -outform der -out $CLIENT_DER_CERT + + $OPENSSL pkcs12 -in $CLIENT_PEM_CERT -inkey $CLIENT_PRIVATE -certfile $ROOT_CA_CERT -passout pass:1234 -export -out $CLIENT_PKCS12_CERT -name "Dave Cert" + + /bin/rm $CLIENT_CERT_REQ +} + +copying_root_ca() +{ + echo "copying_root_ca" + CURRENT_DIR=$(cd "$(dirname "$0")" && pwd) + echo $CURRENT_DIR + + ROOT_CA_PRIVATE=$CURRENT_DIR/$ROOT_CA_DIR/$PRIVATE_DIR/$ROOT_CA_PRIVATE_NAME + ROOT_CA_CERT=$CURRENT_DIR/$ROOT_CA_DIR/$CERT_DIR/$ROOT_CA_CERT_NAME + + /bin/cp $ROOT_CA_CERT $CURRENT_DIR + + /bin/rm $ROOT_CA_CERT + /bin/rm -r $CURRENT_DIR/$ROOT_CA_DIR/$CERT_DIR + + /bin/rm $CURRENT_DIR/$ROOT_CA_DIR/$DB_DIR/index.txt + /bin/rm $CURRENT_DIR/$ROOT_CA_DIR/$DB_DIR/serial + /bin/rm $CURRENT_DIR/$ROOT_CA_DIR/$DB_DIR/crlnumber + /bin/rm -r $CURRENT_DIR/$ROOT_CA_DIR/$DB_DIR + + /bin/rm $ROOT_CA_PRIVATE + /bin/rm -r $CURRENT_DIR/$ROOT_CA_DIR/$PRIVATE_DIR + + /bin/rm -r $CURRENT_DIR/$ROOT_CA_DIR +} + +clear_all() +{ + echo "clean_all" + CURRENT_DIR=$(cd "$(dirname "$0")" && pwd) + echo $CURRENT_DIR + + HOST_PRIVATE=$CURRENT_DIR/$HOST_PRIVATE_NAME + HOST_CERT_REQ=$CURRENT_DIR/$HOST_CERT_REQ_NAME + HOST_CERT=$CURRENT_DIR/$HOST_CERT_NAME + + CLIENT_PRIVATE=$CURRENT_DIR/$CLIENT_PRIVATE_NAME + CLIENT_DER_CERT=$CURRENT_DIR/$CLIENT_DER_CERT_NAME + CLIENT_PEM_CERT=$CURRENT_DIR/$CLIENT_PEM_CERT_NAME + CLIENT_PKCS12_CERT=$CURRENT_DIR/$CLIENT_PKCS12_CERT_NAME + + /bin/rm $CURRENT_DIR/$ROOT_CA_CERT_NAME + /bin/rm $HOST_CERT + /bin/rm $HOST_PRIVATE + /bin/rm $CLIENT_PRIVATE + /bin/rm $CLIENT_DER_CERT + /bin/rm $CLIENT_PEM_CERT + /bin/rm $CLIENT_PKCS12_CERT +} + +case $1 in +"clear_all") +clear_all +;; +"create_certs") +make_root_ca_dir +root_ca_generation +host_cert_generation +client_cert_generation +copying_root_ca +;; +*) +/bin/echo gen_cert.sh [create_certs] [clear_all] +exit 1 +;; +esac + diff --git a/test/ipsec_test/host-cert-req.conf b/test/ipsec_test/host-cert-req.conf new file mode 100644 index 0000000..608786f --- /dev/null +++ b/test/ipsec_test/host-cert-req.conf @@ -0,0 +1,22 @@ +[ req ] +distinguished_name = req_distinguished_name +req_extensions = host_req +prompt = no + + +[ req_distinguished_name ] +C = KR +ST = Seocho-Gu +L = Seoul +O = Samsung Electronics .Inc +OU = . +CN = 192.168.0.108 +emailAddress = test@email.adress + +[ host_req ] +basicConstraints=CA:FALSE +subjectKeyIdentifier=hash +subjectAltName = DNS:192.168.0.108 +subjectAltName = IP:192.168.0.108 +extendedKeyUsage = serverAuth, 1.3.6.1.5.5.8.2.2 + diff --git a/test/ipsec_test/ipsec_server b/test/ipsec_test/ipsec_server new file mode 100755 index 0000000..84fbec8 Binary files /dev/null and b/test/ipsec_test/ipsec_server differ diff --git a/test/ipsec_test/ipsec_server_src/compile.sh b/test/ipsec_test/ipsec_server_src/compile.sh new file mode 100755 index 0000000..a38cdb0 --- /dev/null +++ b/test/ipsec_test/ipsec_server_src/compile.sh @@ -0,0 +1,2 @@ +#!/bin/bash +gcc -o ipsec_server server.c `pkg-config --cflags --libs glib-2.0` diff --git a/test/ipsec_test/ipsec_server_src/server.c b/test/ipsec_test/ipsec_server_src/server.c new file mode 100755 index 0000000..07fd35f --- /dev/null +++ b/test/ipsec_test/ipsec_server_src/server.c @@ -0,0 +1,2581 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* Compile Flags */ + +#define ENABLE_DEBUG_MODE_DEBUG 1 + +/* global utils */ + +#define MAX_SIZE_ERROR_BUFFER 256 +#define MAX_STD_INPUT_BUF 1024 + +#define SOCK_FD_MIN 3 +#define VICI_REQUEST_TIMEOUT 5000 + +#define VICI_DEFAULT_URI "/var/run/charon.vici" + +#define RESET_COLOR "\e[m" +#define MAKE_RED "\e[31m" +#define MAKE_GREEN "\e[32m" + +#if 0 +#define __FUNC_ENTER__ printf("%s() entering...\n", __func__) +#define __FUNC_EXIT__ printf("%s() leaving...\n", __func__) +#else +#define __FUNC_ENTER__ +#define __FUNC_EXIT__ +#endif + +/* loop data */ + +GMainLoop *main_loop; + + +/* setting data */ + +#define STRONGSWAN_CONF_PATH "./server.conf" +#define CONF_GROUP_NAME "strongswan" + +typedef enum { + IPSEC_HYBRID_RSA, + IPSEC_XAUTH_PSK, + IPSEC_XAUTH_RSA, + IPSEC_IKEV2_PSK, + IPSEC_IKEV2_RSA, +} ipsec_type_e; + +struct { + int type; + const char *type_str; +} ipsec_type_str[] = +{ + {IPSEC_HYBRID_RSA, "IPSEC_HYBRID_RSA"}, + {IPSEC_XAUTH_PSK, "IPSEC_XAUTH_PSK"}, + {IPSEC_XAUTH_RSA, "IPSEC_XAUTH_RSA"}, + {IPSEC_IKEV2_PSK, "IPSEC_IKEV2_PSK"}, + {IPSEC_IKEV2_RSA, "IPSEC_IKEV2_RSA"}, +}; + +enum strongswan_conf_key { + STRONGSWAN_CONF_KEY_NONE, + LOCAL_IP, + LOCAL_TS, + CERT_PATH, + CA_CERT_PATH, + PRIVATE_PATH, + IKE_DATA, + IKE_OWNER, + XAUTH_DATA, + XAUTH_OWNER, + HYBRID_POOL, + XAUTH_PSK_POOL, + XAUTH_RSA__POOL, + IKEV2_PSK_POOL, + IKEV2_RSA_POOL, + STRONGSWAN_CONF_KEY_MAX, +}; + +struct key_value { + int key; + const char *key_name; + char *value; +} strongswan_conf[] = { + {STRONGSWAN_CONF_KEY_NONE, NULL, NULL}, + {LOCAL_IP, "local_ip", NULL}, + {LOCAL_TS, "local_ts", NULL}, + {CERT_PATH, "cert_path", NULL}, + {CA_CERT_PATH, "ca_cert_path", NULL}, + {PRIVATE_PATH, "private_path", NULL}, + {IKE_DATA, "ike_data", NULL}, + {IKE_OWNER, "ike_owner", NULL}, + {XAUTH_DATA, "xauth_data", NULL}, + {XAUTH_OWNER, "xauth_owner", NULL}, + {HYBRID_POOL, "hybrid_pool", NULL}, + {XAUTH_PSK_POOL, "xauth_psk_pool", NULL}, + {XAUTH_RSA__POOL, "xauth_rsa_pool", NULL}, + {IKEV2_PSK_POOL, "ikev2_psk_pool", NULL}, + {IKEV2_RSA_POOL, "ikev2_rsa_pool", NULL}, +}; + +GKeyFile *g_conf_key_file; + +/* socket data */ + +enum vici_packet_type { + VICI_CMD_REQUEST = 0, + VICI_CMD_RESPONSE = 1, + VICI_CMD_UNKNOWN = 2, + VICI_EVENT_REGISTER = 3, + VICI_EVENT_UNREGISTER = 4, + VICI_EVENT_CONFIRM = 5, + VICI_EVENT_UNKNOWN = 6, + VICI_EVENT = 7, +}; + +int g_client_sock; + +unsigned int g_pkt_size = 0; + +/* req data */ + +typedef void (*process_return)(unsigned char *buf, unsigned int size); + +struct request { + unsigned int allocated; + unsigned int used; + unsigned int hdr_len; + char *buf; + int err; + /* io data */ + int client_sock; + int client_source_sock_id; + int client_source_idle_id; + int client_source_timeout_id; + /* process reply */ + unsigned int rcv_pkt_size; + process_return handler; + /* davici_cb cb; */ + void *user; +}; + +GSList *g_req_list = NULL; + +/* message data */ + +enum vici_element { + /** valid end of message */ + VICI_END = 0, + /** begin of a section */ + VICI_SECTION_START = 1, + /** end of a section */ + VICI_SECTION_END = 2, + /** key/value pair */ + VICI_KEY_VALUE = 3, + /** begin of a list */ + VICI_LIST_START = 4, + /** list item */ + VICI_LIST_ITEM = 5, + /** end of a list */ + VICI_LIST_END = 6, +}; + +GSList *msg_list = NULL; + +/* declaration */ + +void __process_packet(unsigned char *buf, unsigned int size); + + +/* sock func */ + +static int __str_to_sock_addr(const char *uri, struct sockaddr_un *addr) +{ + memset(addr, 0, sizeof(*addr)); + addr->sun_family = AF_UNIX; + strncpy(addr->sun_path, uri, sizeof(addr->sun_path)); + + addr->sun_path[sizeof(addr->sun_path)-1] = '\0'; + + return offsetof(struct sockaddr_un, sun_path) + strlen(addr->sun_path); +} + +static int __check_socket(int sock) +{ + struct pollfd p_fd; + char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, }; + int res = 0; + + p_fd.fd = sock; + p_fd.events = POLLIN | POLLOUT | POLLERR | POLLHUP | POLLNVAL; + res = poll((struct pollfd *) &p_fd, 1, 1); + + if (res < 0) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + printf("Polling error from socket[%d]. [%s]\n", sock, error_buf); + return -1; + } else if (res == 0) { + printf( "poll timeout. socket is busy\n"); + return 1; + } else { + + if (p_fd.revents & POLLERR) { + printf("Error! POLLERR from socket[%d]\n", sock); + return -1; + } else if (p_fd.revents & POLLHUP) { + printf("Error! POLLHUP from socket[%d]\n", sock); + return -1; + } else if (p_fd.revents & POLLNVAL) { + printf("Error! POLLNVAL from socket[%d]\n", sock); + return -1; + } else if (p_fd.revents & POLLIN) { +#ifdef ENABLE_DEBUG_MODE_INFO + printf("POLLIN from socket [%d]\n", sock); +#endif + return 0; + } else if (p_fd.revents & POLLOUT) { +#ifdef ENABLE_DEBUG_MODE_INFO + printf("POLLOUT from socket [%d]\n", sock); +#endif + return 0; + } + } + + printf("Unknown poll event [%d]\n", p_fd.revents); + return -1; +} + +static int __write_sock(int sock, char *data, int data_len) +{ + char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, }; + int wbytes = 0; + int left_len = data_len; + char *ptr = data; + int res = 0; + + if (sock < SOCK_FD_MIN || !data || data_len < 0) { + printf("Invalid parameter\n"); + return -1; + } + + res = __check_socket(sock); + if (res < 0) { + printf("Socket error\n"); + return -1; + } else if (res > 0) { + printf("Socket is busy\n"); + return -2; + } + + errno = 0; + while (left_len) { + wbytes = write(sock, ptr, left_len); + if (wbytes <= 0) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + printf("Failed to write data into socket[%d]. [error=%s]\n", sock, error_buf); + break; + }else if (wbytes < left_len) { +#ifdef ENABLE_DEBUG_MODE_INFO + printf("%d bytes left. Continue sending...\n", left_len - wbytes); +#endif + left_len -= wbytes; + ptr += wbytes; + } else if (wbytes == left_len) { +#ifdef ENABLE_DEBUG_MODE_INFO + printf("Succeeded to write data[%d bytes] into socket [%d]\n", wbytes, sock); +#endif + left_len = 0; + } else { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + printf("Unknown error occurred. [%s]\n", error_buf); + break; + } + } + + if (left_len) + return -1; + else + return 0; +} + +static int __read_sock(int sock, unsigned char *data, unsigned int data_len) +{ + int rbytes = 0; + int total_rbytes = 0; + + if (sock < SOCK_FD_MIN || !data || data_len <= 0) { + printf("Invalid parameter\n"); + return -1; + } + + + while (data_len > 0) { + errno = 0; + rbytes = read(sock, data, data_len); + printf("read [%d]\n", rbytes); + if (rbytes <= 0) { + printf("Failed to read data from socket[%d]\n", sock); + return -1; + } + total_rbytes += rbytes; + data += rbytes; + data_len -= rbytes; +#ifdef ENABLE_DEBUG_MODE_INFO + printf("data_len %u total_rbytes %d rbytes %d\n", data_len, total_rbytes, rbytes); +#endif + } + +#ifdef ENABLE_DEBUG_MODE_INFO + printf("exit while data_len %u total_rbytes %d rbytes %d\n", data_len, total_rbytes, rbytes); +#endif + return total_rbytes; +} + +int connect_sock(const char *uri) +{ + struct sockaddr_un addr; + char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, }; + int len, fd; + + len = __str_to_sock_addr(uri, &addr); + if (len == -1) + { + printf("invalid stream URI: '%s'", uri); + return -1; + } + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + printf("Failed to get socket. [%s]\n", error_buf); + return -1; + } + + if (connect(fd, (struct sockaddr*)&addr, len) < 0) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + printf("Failed to connect client. [%s]\n", error_buf); + close(fd); + return -1; + } + + return fd; +} + +void disconnect() +{ + GSList *list = NULL; + struct request *req = NULL; + + printf("list length [%d]\n", g_slist_length(g_req_list)); + + for (list = g_req_list; list != NULL; list = list->next) { + req = list->data; + if (req == NULL) + continue; + +#ifdef ENABLE_DEBUG_MODE_INFO + printf("destroy_request [%s]\n", req->buf + 2); +#endif + g_req_list = g_slist_remove(g_req_list, req); + g_free(req->buf); + g_free(req); + req = NULL; + } + close(g_client_sock); +} + +/* req func */ + +void destroy_request(gpointer user_data) +{ + struct request *req = NULL; + req = (struct request *)user_data; + if (!req) { + printf("Invalid parameter\n"); + return; + } + +#ifdef ENABLE_DEBUG_MODE_INFO + printf("destroy_request [%s]\n", req->buf + 2); +#endif + g_req_list = g_slist_remove(g_req_list, req); + close(req->client_sock); + g_free(req->buf); + g_free(req); + req = NULL; + return; +} + +gboolean end_connect(gpointer user_data) +{ + disconnect(); + return FALSE; +} + +gboolean send_request(gpointer user_data) +{ + struct request *req = NULL; + unsigned int size = 0; + int res = 0; + + req = (struct request *)user_data; + if (req == NULL) { + printf("request is NULL\n"); + return FALSE; + } + + printf("send_request [%s]\n", req->buf + 2); + size = htonl(req->used); + res = __write_sock(g_client_sock, (unsigned char *)&size, sizeof(size)); + if (res != 0) { + printf("failed to send size with network byte order\n"); + } + + res = __write_sock(g_client_sock, req->buf, req->used); + if (res != 0) { + printf("failed to send pkt\n"); + } + + return FALSE; +} + +static void* add_element(struct request *r, enum vici_element type, + unsigned int size) +{ + unsigned int newlen; + void *ret, *new; + + if (r->used + size + 1 > r->allocated) + { + newlen = r->allocated; + while (newlen < r->used + size + 1) + { + newlen *= 2; + } + new = realloc(r->buf, newlen); + if (!new) + { + r->err = -errno; + return NULL; + } + r->buf = new; + r->allocated = newlen; + } + r->buf[r->used++] = type; + ret = r->buf + r->used; + r->used += size; + return ret; +} + +void vici_section_start(struct request *r, const char *name) +{ + uint8_t nlen; + char *pos; + + nlen = strlen(name); + pos = add_element(r, VICI_SECTION_START, 1 + nlen); + if (pos) + { + pos[0] = nlen; + memcpy(pos + 1, name, nlen); + } +} + +void vici_section_end(struct request *r) +{ + add_element(r, VICI_SECTION_END, 0); +} + +void vici_kv(struct request *r, const char *name, + const void *buf, unsigned int buflen) +{ + uint8_t nlen; + uint16_t vlen; + char *pos; + + nlen = strlen(name); + pos = add_element(r, VICI_KEY_VALUE, 1 + nlen + sizeof(vlen) + buflen); + if (pos) + { + pos[0] = nlen; + memcpy(pos + 1, name, nlen); + vlen = htons(buflen); + memcpy(pos + 1 + nlen, &vlen, sizeof(vlen)); + memcpy(pos + 1 + nlen + sizeof(vlen), buf, buflen); + } +} + + +void vici_list_start(struct request *r, const char *name) +{ + uint8_t nlen; + char *pos; + + nlen = strlen(name); + pos = add_element(r, VICI_LIST_START, 1 + nlen); + if (pos) + { + pos[0] = nlen; + memcpy(pos + 1, name, nlen); + } +} + +void vici_list_item(struct request *r, const void *buf, + unsigned int buflen) +{ + uint16_t vlen; + char *pos; + + pos = add_element(r, VICI_LIST_ITEM, sizeof(vlen) + buflen); + if (pos) + { + vlen = htons(buflen); + memcpy(pos, &vlen, sizeof(vlen)); + memcpy(pos + sizeof(vlen), buf, buflen); + } +} + +void vici_list_end(struct request *r) +{ + add_element(r, VICI_LIST_END, 0); +} + +int create_request(enum vici_packet_type type, const char *name, + struct request **rp) +{ + struct request *req; + char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, }; + int err; + __FUNC_ENTER__; + + if (!name || !rp) { + printf("Invalid parameter\n"); + return -1; + } + + req = (struct request *)g_try_malloc0(sizeof(*req)); + if (!req) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + printf("Failed allocate memory. [%s]\n", error_buf); + return -1; + } + + req->used = 2; + req->used += strlen(name); + req->allocated = MIN(32, req->used); + req->buf = (char *)g_try_malloc0(req->allocated); + if (!req->buf) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + printf("Failed allocate memory. [%s]\n", error_buf); + g_free(req); + return -1; + } + req->buf[0] = type; + req->buf[1] = req->used - 2; /* except for type and name length */ + memcpy(req->buf + 2, name, req->used - 2); + req->hdr_len = req->used; + + req->handler = __process_packet; + + req->client_sock = connect_sock(VICI_DEFAULT_URI); + if (req->client_sock <= 0) { + printf("error on connect_sock\n"); + g_free(req); + return -1; + } + + *rp = req; + g_req_list = g_slist_append(g_req_list, req); + + __FUNC_EXIT__; + return 0; +} + +/* need to add several functionalities */ + +void __process_message(int elem_type, char *value, int sections) +{ + int i = 0; + + switch(elem_type) { + case VICI_SECTION_START: + { + for (i = 0; i < sections - 1; i++) + printf("\t"); + printf("%s = {\n", value); + } + break; + case VICI_SECTION_END: + { + for (i = 0; i < sections; i++) + printf("\t"); + printf("}\n"); + } + break; + case VICI_KEY_VALUE: + { + for (i = 0; i < sections; i++) + printf("\t"); + printf("%s\n", value); + } + break; + case VICI_LIST_START: + { + for (i = 0; i < sections; i++) + printf("\t"); + printf("%s = [", value); + } + break; + case VICI_LIST_ITEM: + { + printf("%s, ", value); + } + break; + case VICI_LIST_END: + { + printf("]\n"); + } + break; + default: + break; + } +} + +void __process_response(unsigned char *buf, unsigned int size) +{ + struct request *req = NULL; + char temp[255]; + unsigned int pos = 0; + int len = 0; + int sections = 0; + int list_elems = 0; + int type = -1; + + if (buf == NULL || size == 0) + return; + + pos = 1; + while (pos < size) { + + type = buf[pos]; + pos++; + switch (type) { + case VICI_SECTION_START: + { + len = buf[pos]; + pos++; + g_strlcpy(temp, (const gchar *)&buf[pos], len + 1); + pos+=len; + sections++; + } + break; + case VICI_SECTION_END: + { + sections--; + } + break; + case VICI_KEY_VALUE: + { + int key_len = 0; + int value_len = 0; + + key_len = buf[pos]; + pos++; + g_strlcpy(temp, (const gchar *)&buf[pos], key_len + 1); + temp[key_len] = '='; + pos+=(key_len + 1); + value_len = buf[pos]; + pos++; + g_strlcpy(temp + key_len + 1, (const gchar *)&buf[pos], value_len + 1); + pos+=value_len; + len = key_len + 1 + value_len; + } + break; + case VICI_LIST_START: + { + len = buf[pos]; + pos++; + g_strlcpy(temp, (const gchar *)&buf[pos], len + 1); + pos+=len; + } + break; + case VICI_LIST_ITEM: + { + pos++; + len = buf[pos]; + pos++; + g_strlcpy(temp, (const gchar *)&buf[pos], len + 1); + pos+=len; + } + break; + case VICI_LIST_END: + { + } + break; + default: + break; + } + __process_message(type, temp, sections); + } + printf("end process\n"); + return; +} + + +void __process_packet(unsigned char *buf, unsigned int size) +{ + + int i = 0; + +#ifdef ENABLE_DEBUG_MODE_INFO + for (i = 0; i < size; i++) + printf("%02x ", buf[i]); + printf("\n"); +#endif + switch (buf[0]) + { + case VICI_CMD_REQUEST: + { + printf("VICI_CMD_REQUEST\n"); + } + break; + case VICI_CMD_RESPONSE: + { + printf("VICI_CMD_RESPONSE\n"); + __process_response(buf, size); + } + break; + case VICI_CMD_UNKNOWN: + { + printf("VICI_CMD_UNKNOWN\n"); + } + break; + case VICI_EVENT_REGISTER: + { + printf("VICI_EVENT_REGISTER\n"); + } + break; + case VICI_EVENT_UNREGISTER: + { + printf("VICI_EVENT_UNREGISTER\n"); + } + break; + case VICI_EVENT_CONFIRM: + { + printf("VICI_EVENT_CONFIRM\n"); + } + break; + case VICI_EVENT_UNKNOWN: + { + printf("VICI_EVENT_UNKNOWN\n"); + } + break; + case VICI_EVENT: + { + printf("VICI_EVENT\n"); + } + break; + default: + printf("default\n"); + break; + } + return; +} + + +/* glib2.0-IO function */ + +int send_request_gio(GIOFunc process_reply, GSourceFunc send_request, GSourceFunc destroy_req, gpointer user_data); + +gboolean destroy_source_gio(gpointer user_data); +gboolean send_request_gio_in_idle(gpointer user_data); +static gboolean process_gio_source_sock(GIOChannel *source, + GIOCondition condition, + gpointer user_data); + +int send_request_gio(GIOFunc process_reply, GSourceFunc send_request, GSourceFunc destroy_req_gio, gpointer user_data) +{ + struct request *req = NULL; + int ret = 0; + __FUNC_ENTER__; + + req = (struct request *)user_data; + if (!req) { + printf("Invalid parameter\n"); + return -1; + } + GIOChannel *gio = g_io_channel_unix_new(req->client_sock); + req->client_source_sock_id = g_io_add_watch_full(gio, + G_PRIORITY_LOW, + G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, + (GIOFunc)process_reply, + (gpointer)req, + NULL); + g_io_channel_unref(gio); + + req->client_source_idle_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, (GSourceFunc)send_request, + (gpointer)req, NULL); + + /* TODO: think more on destroy function */ + req->client_source_timeout_id = g_timeout_add(VICI_REQUEST_TIMEOUT, (GSourceFunc)destroy_req_gio, (gpointer)req); + + __FUNC_EXIT__; + return ret; +} + +gboolean destroy_source_gio(gpointer user_data) +{ + struct request *req = NULL; + __FUNC_ENTER__; + + req = (struct request *)user_data; + if (!req) { + printf("Invalid parameter\n"); + return FALSE; + } + + if (req->client_source_idle_id != 0) + g_source_remove(req->client_source_idle_id); + if (req->client_source_sock_id != 0) + g_source_remove(req->client_source_sock_id); + g_source_remove(req->client_source_timeout_id); + destroy_request(req); + + __FUNC_EXIT__; + return FALSE; +} + +gboolean send_request_gio_in_idle(gpointer user_data) +{ + struct request *req = NULL; + unsigned int size = 0; + int res = 0; + __FUNC_ENTER__; + + req = (struct request *)user_data; + if (req == NULL) { + printf("request is NULL\n"); + __FUNC_EXIT__; + return FALSE; + } + + req->client_source_idle_id = 0; + printf("send_request [%s]\n", req->buf + 2); + size = htonl(req->used); + res = __write_sock(req->client_sock, (unsigned char *)&size, sizeof(size)); + if (res != 0) { + printf("failed to send size with network byte order\n"); + destroy_source_gio(req); + __FUNC_EXIT__; + return FALSE; + } + + res = __write_sock(req->client_sock, req->buf, req->used); + if (res != 0) { + printf("failed to send pkt\n"); + destroy_source_gio(req); + __FUNC_EXIT__; + return FALSE; + } + + return FALSE; +} + +static gboolean process_gio_source_sock(GIOChannel *source, + GIOCondition condition, + gpointer user_data) +{ + struct request *req = NULL; + unsigned int pkt_size = 0; + unsigned char *buf = NULL; + int sock = 0; + int res = 0; + __FUNC_ENTER__; + + req = (struct request *)user_data; + if (!req) { + printf("Invalid parameter\n"); + __FUNC_EXIT__; + return FALSE; + } + + sock = g_io_channel_unix_get_fd(source); + if (sock < SOCK_FD_MIN) { + printf("Invalid argument\n"); + __FUNC_EXIT__; + return FALSE; + } + + if ((condition & G_IO_ERR) || (condition & G_IO_HUP) || (condition & G_IO_NVAL)) { + printf("G_IO_ERR/G_IO_HUP/G_IO_NVAL received sock [%d] condition [%d]\n", sock, condition); + req->client_source_idle_id = 0; + destroy_source_gio(req); + __FUNC_EXIT__; + return FALSE; + } +#ifdef ENABLE_DEBUG_MODE_INFO + printf("condition [%d] sock [%d]\n",condition, sock); +#endif + if (req->rcv_pkt_size == 0) { +#ifdef ENABLE_DEBUG_MODE_INFO + printf("read packet size\n"); +#endif + if (__read_sock(sock, (unsigned char *)&pkt_size, sizeof(pkt_size)) < 0) { + printf("read packet size failed\n"); + req->client_source_idle_id = 0; + destroy_source_gio(req); + __FUNC_EXIT__; + return FALSE; + } + + req->rcv_pkt_size = ntohl(pkt_size); +#ifdef ENABLE_DEBUG_MODE_INFO + printf("packet size [%u]\n", req->rcv_pkt_size); +#endif + } else { + buf = g_try_malloc0(req->rcv_pkt_size); + if (buf == NULL) { + printf("Failed to allocate memory\n"); + req->client_source_idle_id = 0; + destroy_source_gio(req); + __FUNC_EXIT__; + return FALSE; + } +#ifdef ENABLE_DEBUG_MODE_INFO + printf("read packet\n"); +#endif + if (__read_sock(sock, buf, req->rcv_pkt_size) < 0) { + printf("read packet failed\n"); + req->client_source_idle_id = 0; + destroy_source_gio(req); + g_free(buf); + __FUNC_EXIT__; + return FALSE; + } +#ifdef ENABLE_DEBUG_MODE_INFO + printf("[%s]\n", req->buf + 2); +#endif + req->handler(buf, req->rcv_pkt_size); + g_free(buf); + req->rcv_pkt_size = 0; + } + __FUNC_EXIT__; + return TRUE; +} + +/* test load-conn */ + +typedef void (*destroy_data)(void *data); + +typedef struct section { + char *id_str; + GHashTable *kv; + GHashTable *kvl; + void *data; + destroy_data destroy_func; +} section_s; + +typedef struct conn { + GSList *locals; + GSList *remotes; + GSList *children; +} conn_s; + +typedef enum +{ + EAP, + XAUTH, + IKE, + PRIVATE, + RSA, + ECDSA, + PKCS8, + PKCS12, +} secret_type_e; + +typedef struct secret { + secret_type_e type; +} secret_s; + +typedef struct setting { + GSList *conns; + GSList *secrets; + GSList *pools; + GSList *authorities; +} setting_s; + + +/* create swanctl.conf */ +/* add */ +/* add local */ +/* add remote */ +/* add children */ +/* add secrets */ +/* add pools */ +/* add authorities */ + +static void __remove_list(gpointer data) +{ + GSList *list = NULL; + char *value = NULL; + + if (data == NULL) + return; + + g_slist_free_full(list, g_free); +} + +section_s *get_section(GSList *list, const char *id_str) +{ + section_s *section = NULL; + __FUNC_ENTER__; + + if (list == NULL) + return NULL; + + for (; list; list = list->next) { + section = list->data; + if (section && g_strcmp0(id_str, section->id_str) == 0) + break; + section = NULL; + } + + __FUNC_EXIT__; + return section; +} + +section_s *add_section(GSList **list, const char *id_str) +{ + section_s *section = NULL; + int ret = 0; + __FUNC_ENTER__; + + section = get_section(*list, id_str); + if (section) + return section; + + section = g_try_malloc0(sizeof(section_s)); + if (section == NULL) + return section; + + section->id_str = g_strdup(id_str); + section->kv = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + section->kvl = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, __remove_list); + *list = g_slist_prepend(*list, section); + printf("%s %d\n", id_str, g_slist_length(*list)); + __FUNC_EXIT__; + return section; +} + +void del_section(GSList *list, const char *id_str) +{ + section_s *section = NULL; + __FUNC_ENTER__; + + section = get_section(list, id_str); + if (section == NULL) + return; + + list = g_slist_remove(list, section); + g_hash_table_remove_all(section->kv); + g_hash_table_remove_all(section->kvl); + g_free(section->id_str); + if (section->destroy_func) + section->destroy_func(section->data); + g_free(section); + + __FUNC_EXIT__; + return; +} + +void add_section_kv(section_s *section, char *key, char *value) +{ + if (section == NULL || key == NULL || value == NULL) + return; + g_hash_table_insert(section->kv, g_strdup(key), g_strdup(value)); + return; +} + +void add_section_kvl(section_s *section, char *key, GSList *list) +{ + if (section == NULL || key == NULL || list == NULL) + return; + + g_hash_table_insert(section->kvl, g_strdup(key), g_slist_copy(list)); + return; +} + +void add_section_kv_args(section_s *section, char *key, int num_args, ...) +{ + GSList *list = NULL; + va_list args_ptr; + char *temp = NULL; + int i = 0; + __FUNC_ENTER__; + + if (section == NULL || key == NULL || num_args == 0) + return; + + va_start(args_ptr, num_args); + for(i = 0; i < num_args; i++) { + temp = va_arg(args_ptr, char *); + list = g_slist_prepend(list, g_strdup(temp)); + } + + g_hash_table_insert(section->kvl, g_strdup(key), list); + __FUNC_EXIT__; + return; +} + +/* write section into req */ + +typedef void (*handle_data)(void *data, struct request *req); + +void write_section_kv(section_s *section, struct request *req) +{ + GHashTableIter iter; + gpointer key, value; + int ret = 0; + __FUNC_ENTER__; + + if (section == NULL || req == NULL) + return; + + g_hash_table_iter_init (&iter, section->kv); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + if (!key || !value) + continue; + vici_kv(req, (const char*)key, (const void *)value, strlen((char *)value)); + } + __FUNC_EXIT__; + return; +} + +static void __write_vl(gpointer data, gpointer user_data) +{ + struct request *req = NULL; + char *value = NULL; + __FUNC_ENTER__; + + if (!data || !user_data) + return; + + value = (char *)data; + req = (struct request *)user_data; + vici_list_item(req, value, strlen(value)); + + __FUNC_EXIT__; + return; +} + +void write_section_kvl(section_s *section, struct request *req) +{ + GHashTableIter iter; + gpointer key, value; + int ret = 0; + __FUNC_ENTER__; + + if (section == NULL || req == NULL) + return; + + g_hash_table_iter_init (&iter, section->kvl); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + if (!key || !value) + continue; + + vici_list_start(req, key); + g_slist_foreach((GSList *)value, (GFunc)__write_vl, (gpointer)req); + vici_list_end(req); + } + __FUNC_EXIT__; + return; +} + +void write_section(section_s *section, handle_data handler, struct request *req) +{ + if (section == NULL || req == NULL) + return; + vici_section_start(req, section->id_str); + write_section_kv(section, req); + if(handler) + handler(section->data, req); + vici_section_end(req); + return; +} + +void write_section_list(GSList *list, handle_data handler, struct request *req) +{ + GSList *temp = NULL; + section_s *section = NULL; + __FUNC_ENTER__; + + if(list == NULL || req == NULL) + return; + + for (; list; list = list->next) { + section = list->data; + if (!section) + continue; + + vici_section_start(req, section->id_str); + write_section_kv(section, req); + write_section_kvl(section, req); + if(handler) + handler(section->data, req); + vici_section_end(req); + } + + __FUNC_EXIT__; + return; +} + +void handle_conns(void *data, struct request *req) +{ + conn_s *conn = NULL; + __FUNC_ENTER__; + + if (data == NULL || req == NULL) + return; + + conn = (conn_s *)data; + write_section_list(conn->locals, NULL, req); + write_section_list(conn->remotes, NULL, req); + vici_section_start(req, "children"); + write_section_list(conn->children, NULL, req); + vici_section_end(req); + __FUNC_EXIT__; + return; +} + +static unsigned char *get_file(const char *file_path, unsigned long long *size) +{ + struct stat st; + FILE *fp = NULL; + int fd = 0; + unsigned long long file_size = 0; + unsigned char *file_buff = NULL; + + if (!file_path) { + printf("Invalid file_path!\n"); + return NULL; + } + + fp = fopen(file_path, "rb"); + if (!fp) { + printf("fopen for %s failed!\n", file_path); + return NULL; + } + fd = fileno(fp); + fstat(fd, &st); + file_size = st.st_size; + file_buff = g_try_malloc0(sizeof(char)*st.st_size); + if (file_buff == NULL) { + printf("g_try_malloc0 failed\n"); + fclose(fp); + __FUNC_EXIT__; + return NULL; + } + fread(file_buff, 1, file_size, fp); + fclose(fp); + fp = NULL; + fd = 0; + + *size = file_size; + return file_buff; +} + +typedef conn_s *(*create_conn)(setting_s *setting); +typedef void (*destroy_conn)(conn_s *conn); + +static conn_s * create_conn_for_hybrid(setting_s *setting); +static conn_s * create_conn_for_xauth_psk(setting_s *setting); +static conn_s * create_conn_for_xauth_rsa(setting_s *setting); +static conn_s * create_conn_for_ikev2_psk(setting_s *setting); +static conn_s * create_conn_for_ikev2_rsa(setting_s *setting); + +static void destroy_conn_for_hybrid(conn_s *conn); +static void destroy_conn_for_xauth_psk(conn_s *conn); +static void destroy_conn_for_xauth_rsa(conn_s *conn); +static void destroy_conn_for_ikev2_psk(conn_s *conn); +static void destroy_conn_for_ikev2_rsa(conn_s *conn); + +struct ipsec_type_id_value { + int id; + const char *head; + const char *conn_name; + const char *child_name; + const char *pool_name; + create_conn create; + destroy_conn destroy; +} ipsec_info[] = { + {IPSEC_HYBRID_RSA, "IPsec Hybrid RSA", + "conn_hybrid", "child_hybrid", "pool_hybrid", + create_conn_for_hybrid, destroy_conn_for_hybrid}, + + {IPSEC_XAUTH_PSK, "IPsec Xauth PSK", + "conn_xauth_psk", "child_xauth_psk", "pool_xauth_psk", + create_conn_for_xauth_psk, destroy_conn_for_xauth_psk}, + + {IPSEC_XAUTH_RSA, "IPsec Xauth RSA", + "conn_xauth_rsa", "child_xauth_rsa", "pool_xauth_rsa", + create_conn_for_xauth_rsa, destroy_conn_for_xauth_rsa}, + + {IPSEC_IKEV2_PSK, "IPsec IKEv2 PSK", + "conn_ikev2_psk", "child_ikev2_psk", "pool_ikev2_psk", + create_conn_for_ikev2_psk, destroy_conn_for_ikev2_psk}, + + {IPSEC_IKEV2_RSA, "IPsec IKEv2 RSA", + "conn_ikev2_rsa", "child_ikev2_rsa", "pool_ikev2_rsa", + create_conn_for_ikev2_rsa, destroy_conn_for_ikev2_rsa}, +}; + +static void add_default_conn_value(section_s *section) +{ + add_section_kv_args(section, "local_addrs", 1, strongswan_conf[LOCAL_IP].value); + add_section_kv_args(section, "remote_addrs", 1, "%any"); + + add_section_kv(section, "keyingtries", "1"); + add_section_kv(section, "reauth_time", "0"); + add_section_kv(section, "rekey_time", "4h"); + + return; +} + +static void add_default_child_value(section_s *section) +{ + add_section_kv_args(section, "local_ts", 1, strongswan_conf[LOCAL_TS].value); + add_section_kv(section, "start_action", "none"); + add_section_kv(section, "updown", "/usr/local/libexec/ipsec/_updown iptables"); + add_section_kv(section, "rekey_time", "10m"); + + return; +} + +static void add_proposals_for_ikev1(section_s *section) +{ + GSList *list = NULL; + list = g_slist_append(list, g_strdup("aes256-sha256-modp1024")); + list = g_slist_append(list, g_strdup("aes128-sha256-modp1024")); + list = g_slist_append(list, g_strdup("aes256-sha1-modp1024")); + list = g_slist_append(list, g_strdup("aes128-sha1-modp1024")); + list = g_slist_append(list, g_strdup("aes256-md5-modp1024")); + list = g_slist_append(list, g_strdup("aes128-md5-modp1024")); + list = g_slist_append(list, g_strdup("3des-sha1-modp1024")); + list = g_slist_append(list, g_strdup("3des-md5-modp1024")); + add_section_kvl(section, "proposals", list); + list = NULL; + + return; +} + +static void add_esp_proposals_for_ikev1(section_s *section) +{ + GSList *list = NULL; + list = g_slist_append(list, g_strdup("aes256-sha256")); + list = g_slist_append(list, g_strdup("aes128-sha256")); + list = g_slist_append(list, g_strdup("aes256-sha1")); + list = g_slist_append(list, g_strdup("aes128-sha1")); + list = g_slist_append(list, g_strdup("aes256-md5")); + list = g_slist_append(list, g_strdup("aes128-md5")); + list = g_slist_append(list, g_strdup("3des-sha1")); + list = g_slist_append(list, g_strdup("3des-md5")); + add_section_kvl(section, "esp_proposals", list); + list = NULL; + + return; +} + +static void add_proposals_for_ikev2(section_s *section) +{ + GSList *list = NULL; + list = g_slist_append(list, g_strdup("aes256-aes128-sha512-sha384-sha256-sha1-modp2048s256-ecp384-ecp256-modp2048-modp1536-modp1024")); + //list = g_slist_append(list, g_strdup("aes256gcm16-aes128gcm16-prfsha512-prfsha384-prfsha256-prfsha1-modp2048s256-ecp384-ecp256-modp2048-modp1536-modp1024")); + add_section_kvl(section, "proposals", list); + list = NULL; + + return; +} + +static void add_esp_proposals_for_ikev2(section_s *section) +{ + GSList *list = NULL; + list = g_slist_append(list, g_strdup("aes256-aes128-sha512-sha384-sha256-sha1")); + //list = g_slist_append(list, g_strdup("aes256gcm16-aes128gcm16-prfsha512-prfsha384-prfsha256-prfsha1-modp2048s256-ecp384-ecp256-modp2048-modp1536-modp1024")); + add_section_kvl(section, "esp_proposals", list); + list = NULL; + + return; +} + +static void add_auth_for_hybrid(conn_s *conn) +{ + section_s *section = NULL; + unsigned char *file_buff; + unsigned long long file_size = 0; + + /* add local */ + section = add_section(&(conn->locals), "local"); + section->destroy_func = NULL; + + add_section_kv(section, "auth", "pubkey"); + add_section_kv(section, "id", strongswan_conf[LOCAL_IP].value); + + file_buff = get_file(strongswan_conf[CERT_PATH].value, &file_size); + if (file_buff) + add_section_kv_args(section, "certs", 1, file_buff); + + /* add remote */ + + section = add_section(&(conn->remotes), "remote"); + section->destroy_func = NULL; + + add_section_kv(section, "auth", "xauth"); + + return; +} + +static void add_auth_for_xauth_psk(conn_s *conn) +{ + section_s *section = NULL; + + /* add local */ + section = add_section(&(conn->locals), "local"); + section->destroy_func = NULL; + + add_section_kv(section, "auth", "psk"); + + /* add remote-xauth */ + section = add_section(&(conn->remotes), "remote-xauth"); + section->destroy_func = NULL; + + add_section_kv(section, "auth", "xauth"); + + /* add remote */ + + section = add_section(&(conn->remotes), "remote"); + section->destroy_func = NULL; + + add_section_kv(section, "auth", "psk"); + + return; +} + +static void add_auth_for_xauth_rsa(conn_s *conn) +{ + section_s *section = NULL; + unsigned char *file_buff; + unsigned long long file_size = 0; + + /* add local */ + section = add_section(&(conn->locals), "local"); + section->destroy_func = NULL; + + add_section_kv(section, "auth", "pubkey"); + add_section_kv(section, "id", strongswan_conf[LOCAL_IP].value); + + file_buff = get_file(strongswan_conf[CERT_PATH].value, &file_size); + if (file_buff) + add_section_kv_args(section, "certs", 1, file_buff); + + /* add remote-xauth */ + section = add_section(&(conn->remotes), "remote-xauth"); + section->destroy_func = NULL; + + add_section_kv(section, "auth", "xauth"); + + /* add remote */ + + section = add_section(&(conn->remotes), "remote"); + section->destroy_func = NULL; + + add_section_kv(section, "auth", "pubkey"); + + return; +} + +static void add_auth_for_ikev2_psk(conn_s *conn) +{ + section_s *section = NULL; + + /* add local */ + section = add_section(&(conn->locals), "local"); + section->destroy_func = NULL; + + add_section_kv(section, "auth", "psk"); + + /* add remote */ + + section = add_section(&(conn->remotes), "remote"); + section->destroy_func = NULL; + + add_section_kv(section, "auth", "psk"); + + return; +} + +static void add_auth_for_ikev2_rsa(conn_s *conn) +{ + section_s *section = NULL; + unsigned char *file_buff; + unsigned long long file_size = 0; + + /* add local */ + section = add_section(&(conn->locals), "local"); + section->destroy_func = NULL; + + add_section_kv(section, "auth", "pubkey"); + add_section_kv(section, "id", strongswan_conf[LOCAL_IP].value); + + file_buff = get_file(strongswan_conf[CERT_PATH].value, &file_size); + if (file_buff) + add_section_kv_args(section, "certs", 1, file_buff); + + /* add remote */ + + section = add_section(&(conn->remotes), "remote"); + section->destroy_func = NULL; + + add_section_kv(section, "auth", "pubkey"); + + return; +} + +static void create_child_for_hybrid(conn_s *conn) +{ + section_s *section = NULL; + + section = add_section(&(conn->children), + ipsec_info[IPSEC_HYBRID_RSA].child_name); + /* TODO: handle memory fault */ + section->destroy_func = NULL; + + add_default_child_value(section); + add_esp_proposals_for_ikev1(section); + + return; +} + +static conn_s *create_conn_for_hybrid(setting_s *setting) +{ + section_s *section = NULL; + conn_s *conn = NULL; + + /* add */ + section = add_section(&(setting->conns), + ipsec_info[IPSEC_HYBRID_RSA].conn_name); + /* TODO: handle memory fault */ + + conn = g_try_malloc0(sizeof(conn_s)); + /* TODO: handle memory fault */ + section->data = conn; + section->destroy_func = g_free; + + add_section_kv_args(section, "pools", 1, + ipsec_info[IPSEC_HYBRID_RSA].pool_name); + add_section_kv(section, "version", "1"); + add_section_kv(section, "send_cert", "always"); + + add_default_conn_value(section); + add_proposals_for_ikev1(section); + + add_auth_for_hybrid(conn); + create_child_for_hybrid(conn); + + return conn; +} + +static void destroy_conn_for_hybrid(conn_s *conn) +{ + del_section(conn->children, ipsec_info[IPSEC_HYBRID_RSA].child_name); + del_section(conn->locals, "local"); + del_section(conn->remotes, "remote"); + + return; +} + +static void create_child_for_xauth_psk(conn_s *conn) +{ + section_s *section = NULL; + + section = add_section(&(conn->children), ipsec_info[IPSEC_XAUTH_PSK].child_name); + section->destroy_func = NULL; + + add_default_child_value(section); + add_esp_proposals_for_ikev1(section); + + return; +} + +static conn_s *create_conn_for_xauth_psk(setting_s *setting) +{ + section_s *section = NULL; + conn_s *conn = NULL; + + /* add */ + section = add_section(&(setting->conns), + ipsec_info[IPSEC_XAUTH_PSK].conn_name); + /* TODO: handle memory fault */ + + conn = g_try_malloc0(sizeof(conn_s)); + /* TODO: handle memory fault */ + section->data = conn; + section->destroy_func = g_free; + + add_section_kv_args(section, "pools", 1, + ipsec_info[IPSEC_XAUTH_PSK].pool_name); + + add_section_kv(section, "version", "1"); + add_section_kv(section, "send_certreq", "no"); + add_section_kv(section, "aggressive", "yes"); + + add_default_conn_value(section); + add_proposals_for_ikev1(section); + + add_auth_for_xauth_psk(conn); + create_child_for_xauth_psk(conn); + + return conn; +} + +static void destroy_conn_for_xauth_psk(conn_s *conn) +{ + del_section(conn->children, ipsec_info[IPSEC_XAUTH_PSK].child_name); + del_section(conn->locals, "local"); + del_section(conn->remotes, "remote"); + del_section(conn->remotes, "remote-xauth"); + +} + +static void create_child_for_xauth_rsa(conn_s *conn) +{ + section_s *section = NULL; + + /* add children */ + section = add_section(&(conn->children), + ipsec_info[IPSEC_XAUTH_RSA].child_name); + /* TODO: handle memory fault */ + section->destroy_func = NULL; + + add_default_child_value(section); + add_esp_proposals_for_ikev1(section); + + return; +} + +static conn_s *create_conn_for_xauth_rsa(setting_s *setting) +{ + section_s *section = NULL; + conn_s *conn = NULL; + + /* add */ + section = add_section(&(setting->conns), + ipsec_info[IPSEC_XAUTH_RSA].conn_name); + /* TODO: handle memory fault */ + + conn = g_try_malloc0(sizeof(conn_s)); + /* TODO: handle memory fault */ + section->data = conn; + section->destroy_func = g_free; + + add_section_kv_args(section, "pools", 1, + ipsec_info[IPSEC_XAUTH_RSA].pool_name); + add_section_kv(section, "version", "1"); + + add_default_conn_value(section); + add_proposals_for_ikev1(section); + + add_auth_for_xauth_rsa(conn); + create_child_for_xauth_rsa(conn); + + return conn; +} + +static void destroy_conn_for_xauth_rsa(conn_s *conn) +{ + del_section(conn->children, ipsec_info[IPSEC_XAUTH_RSA].child_name); + del_section(conn->locals, "local"); + del_section(conn->remotes, "remote"); + del_section(conn->remotes, "remote-xauth"); + return; +} + + +static void create_child_for_ikev2_psk(conn_s *conn) +{ + section_s *section = NULL; + + section = add_section(&(conn->children), + ipsec_info[IPSEC_IKEV2_PSK].child_name); + /* TODO: handle memory fault */ + section->destroy_func = NULL; + + add_default_child_value(section); + add_esp_proposals_for_ikev2(section); + + return; +} + +static conn_s *create_conn_for_ikev2_psk(setting_s *setting) +{ + section_s *section = NULL; + conn_s *conn = NULL; + + /* add */ + section = add_section(&(setting->conns), + ipsec_info[IPSEC_IKEV2_PSK].conn_name); + /* TODO: handle memory fault */ + + conn = g_try_malloc0(sizeof(conn_s)); + /* TODO: handle memory fault */ + section->data = conn; + section->destroy_func = g_free; + + add_section_kv_args(section, "pools", 1, + ipsec_info[IPSEC_IKEV2_PSK].pool_name); + add_section_kv(section, "version", "2"); + add_section_kv(section, "send_certreq", "no"); + + add_default_conn_value(section); + add_proposals_for_ikev2(section); + + add_auth_for_ikev2_psk(conn); + create_child_for_ikev2_psk(conn); + + return conn; +} + +static void destroy_conn_for_ikev2_psk(conn_s *conn) +{ + del_section(conn->children, ipsec_info[IPSEC_IKEV2_PSK].child_name); + del_section(conn->locals, "local"); + del_section(conn->remotes, "remote"); + + return; +} + +static void create_child_for_ikev2_rsa(conn_s *conn) +{ + section_s *section = NULL; + + /* add children */ + + section = add_section(&(conn->children), + ipsec_info[IPSEC_IKEV2_RSA].child_name); + /* TODO: handle memory fault */ + section->destroy_func = NULL; + + add_default_child_value(section); + add_esp_proposals_for_ikev2(section); + + return; +} + +static conn_s *create_conn_for_ikev2_rsa(setting_s *setting) +{ + section_s *section = NULL; + conn_s *conn = NULL; + + /* add */ + section = add_section(&(setting->conns), + ipsec_info[IPSEC_IKEV2_RSA].conn_name); + /* TODO: handle memory fault */ + + conn = g_try_malloc0(sizeof(conn_s)); + /* TODO: handle memory fault */ + section->data = conn; + section->destroy_func = g_free; + + add_section_kv_args(section, "pools", 1, + ipsec_info[IPSEC_IKEV2_RSA].pool_name); + add_section_kv(section, "version", "2"); + + add_default_conn_value(section); + add_proposals_for_ikev2(section); + + add_auth_for_ikev2_rsa(conn); + create_child_for_ikev2_rsa(conn); + + return conn; +} + +static void destroy_conn_for_ikev2_rsa(conn_s *conn) +{ + del_section(conn->children, ipsec_info[IPSEC_IKEV2_RSA].child_name); + del_section(conn->locals, "local"); + del_section(conn->remotes, "remote"); + + return; +} + +static int send_vici_request(struct request *req) +{ + int res = + send_request_gio((GIOFunc)process_gio_source_sock, + (GSourceFunc)send_request_gio_in_idle, + (GSourceFunc)destroy_source_gio, + (gpointer)req); + return res; +} + +static void check_vici_request(struct request *req) +{ + __process_response(req->buf + req->hdr_len - 1, req->used - req->hdr_len + 1); +} + +static int test_load_conn(int ipsec_type) +{ + setting_s *setting = NULL; + section_s *section = NULL; + conn_s * conn = NULL; + struct request *req = NULL; + int ret = 0; + __FUNC_ENTER__; + + printf("load-conn ipsec type [%s]\n", ipsec_info[ipsec_type].head); + + ret = create_request(VICI_CMD_REQUEST, "load-conn", &req); + if (ret < 0) { + printf("error on create_request\n"); + return -1; + } + + setting = g_try_malloc0(sizeof(setting_s)); + if (setting == NULL) { + printf("error on memory\n"); + destroy_request(req); + return -1; + } + + conn = ipsec_info[ipsec_type].create(setting); + if (conn == NULL) { + printf("error on memory\n"); + destroy_request(req); + g_free(setting); + return -1; + } + + /* create request for load-conn with setting */ + write_section_list(setting->conns, handle_conns, req); + + /* clear setting */ + ipsec_info[ipsec_type].destroy(conn); + del_section(setting->conns, ipsec_info[ipsec_type].conn_name); + g_free(setting); + +/* send request */ + check_vici_request(req); + send_vici_request(req); + if (ret < 0) { + printf("error on send_vici_request\n"); + destroy_request(req); + } + + __FUNC_EXIT__; + return ret; +} + +int test_unload_conn(int ipsec_type) +{ + struct request *req = NULL; + int ret = 0; + __FUNC_ENTER__; + + printf("unload-conn ipsec type [%s]\n", ipsec_info[ipsec_type].head); + + ret = create_request(VICI_CMD_REQUEST, "unload-conn", &req); + if (ret < 0) { + printf("error on create_request\n"); + return -1; + } + + vici_kv(req, "name", (const void *)ipsec_info[ipsec_type].conn_name, + strlen((char *)ipsec_info[ipsec_type].conn_name)); + + check_vici_request(req); + send_vici_request(req); + if (ret < 0) { + printf("error on send_vici_request\n"); + destroy_request(req); + } + + __FUNC_EXIT__; + return ret; +} + +int test_get_conns() +{ + struct request *req = NULL; + int ret = 0; + __FUNC_ENTER__; + + ret = create_request(VICI_CMD_REQUEST, "get-conns", &req); + if (ret < 0) { + printf("error on create_request\n"); + return -1; + } + + check_vici_request(req); + send_vici_request(req); + if (ret < 0) { + printf("error on send_vici_request\n"); + destroy_request(req); + } + + __FUNC_EXIT__; + return ret; +} + +int test_list_conns(int ipsec_type) +{ + struct request *req = NULL; + int ret = 0; + __FUNC_ENTER__; + + printf("list-conn ipsec type [%s]\n", ipsec_info[ipsec_type].head); + + ret = create_request(VICI_CMD_REQUEST, "list-conns", &req); + if (ret < 0) { + printf("error on create_request\n"); + return -1; + } + + vici_list_start(req, (const char *)"ike"); + vici_list_item(req, (const void *)ipsec_info[ipsec_type].conn_name, + strlen((char *)ipsec_info[ipsec_type].conn_name)); + vici_list_end(req); + + check_vici_request(req); + send_vici_request(req); + if (ret < 0) { + printf("error on send_vici_request\n"); + destroy_request(req); + } + + __FUNC_EXIT__; + return ret; +} + +/* test initiate */ + +int test_initiate() +{ + struct request *req = NULL; + int ret = 0; + __FUNC_ENTER__; +/* + ret = create_request(VICI_CMD_REQUEST, "initiate", &req); + if (ret < 0) { + printf("error on create_request\n"); + return -1; + } + + vici_kv(req, "child", (const void *)CHILD_SA_NAME, strlen((char *)CHILD_SA_NAME)); + + check_vici_request(req); + send_vici_request(req); +*/ + __FUNC_EXIT__; + return ret; +} + +/* test terminate */ + +int test_terminate(int ipsec_type) +{ + struct request *req = NULL; + int ret = 0; + __FUNC_ENTER__; + + printf("terminate ipsec type [%s]\n", ipsec_info[ipsec_type].head); + + ret = create_request(VICI_CMD_REQUEST, "terminate", &req); + if (ret < 0) { + printf("error on create_request\n"); + return -1; + } + + vici_kv(req, "child", (const void *)ipsec_info[ipsec_type].child_name, + strlen((char *)ipsec_info[ipsec_type].child_name)); + + check_vici_request(req); + send_vici_request(req); + if (ret < 0) { + printf("error on send_vici_request\n"); + destroy_request(req); + } + + __FUNC_EXIT__; + return ret; +} + +int test_load_shared_psk() +{ + struct request *req = NULL; + int ret = 0; + __FUNC_ENTER__; + + ret = create_request(VICI_CMD_REQUEST, "load-shared", &req); + if (ret < 0) { + printf("error on create_request\n"); + return -1; + } + + vici_kv(req, "type", (const void *)"ike", strlen((char *)"ike")); + vici_kv(req, "data", (const void *)strongswan_conf[IKE_DATA].value, + strlen((char *)strongswan_conf[IKE_DATA].value)); + + vici_list_start(req, (const char *)"owners"); + vici_list_item(req, (const void *)strongswan_conf[IKE_OWNER].value, + strlen((char *)strongswan_conf[IKE_OWNER].value)); + + vici_list_end(req); + + check_vici_request(req); + send_vici_request(req); + if (ret < 0) { + printf("error on send_vici_request\n"); + destroy_request(req); + } + + __FUNC_EXIT__; + return ret; +} + +int test_load_shared_xauth() +{ + struct request *req = NULL; + int ret = 0; + __FUNC_ENTER__; + + ret = create_request(VICI_CMD_REQUEST, "load-shared", &req); + if (ret < 0) { + printf("error on create_request\n"); + return -1; + } + + vici_kv(req, "type", (const void *)"xauth", strlen((char *)"xauth")); + vici_kv(req, "data", (const void *)strongswan_conf[XAUTH_DATA].value, + strlen((char *)strongswan_conf[XAUTH_DATA].value)); + + vici_list_start(req, (const char *)"owners"); + vici_list_item(req, (const void *)strongswan_conf[XAUTH_OWNER].value, + strlen((char *)strongswan_conf[XAUTH_OWNER].value)); + + vici_list_end(req); + + check_vici_request(req); + send_vici_request(req); + if (ret < 0) { + printf("error on send_vici_request\n"); + destroy_request(req); + } + + __FUNC_EXIT__; + return ret; +} + +int test_load_pool(int ipsec_type) +{ + GSList *list = NULL; + section_s *section = NULL; + conn_s * conn = NULL; + struct request *req = NULL; + int ret = 0; + __FUNC_ENTER__; + + printf("load-pool ipsec type [%s]\n", ipsec_info[ipsec_type].head); + + ret = create_request(VICI_CMD_REQUEST, "load-pool", &req); + if (ret < 0) { + printf("error on create_request\n"); + return -1; + } + +/* add */ + section = add_section(&(list), ipsec_info[ipsec_type].pool_name); + /* TODO: handle memory fault */ + + add_section_kv(section, "addrs", strongswan_conf[HYBRID_POOL + ipsec_type].value); + +/* create request for load-pool with list */ + + write_section_list(list, NULL, req); + +/* clear setting */ + del_section(list, ipsec_info[ipsec_type].pool_name); + + check_vici_request(req); + send_vici_request(req); + if (ret < 0) { + printf("error on send_vici_request\n"); + destroy_request(req); + } + + __FUNC_EXIT__; + return ret; +} + +int test_load_ca_cert() +{ + struct request *req = NULL; + unsigned char *file_buff = NULL; + unsigned long long file_size = 0; + int ret = 0; + __FUNC_ENTER__; + + file_buff = get_file(strongswan_conf[CA_CERT_PATH].value, &file_size); + if (!file_buff) { + return -1; + } + + ret = create_request(VICI_CMD_REQUEST, "load-cert", &req); + if (ret < 0) { + printf("error on create_request\n"); + g_free(file_buff); + return -1; + } + + vici_kv(req, "type", (const void *)"X509", strlen((char *)"X509")); + vici_kv(req, "type", (const void *)"flag", strlen((char *)"CA")); + vici_kv(req, "data", (const void *)file_buff, file_size); + + check_vici_request(req); + send_vici_request(req); + if (ret < 0) { + printf("error on send_vici_request\n"); + destroy_request(req); + } + g_free(file_buff); + + __FUNC_EXIT__; + return ret; +} + +int test_load_private() +{ + struct request *req = NULL; + unsigned char *file_buff = NULL; + unsigned long long file_size = 0; + int ret = 0; + __FUNC_ENTER__; + + file_buff = get_file(strongswan_conf[PRIVATE_PATH].value, &file_size); + if (!file_buff) { + return -1; + } + + ret = create_request(VICI_CMD_REQUEST, "load-key", &req); + if (ret < 0) { + printf("error on create_request\n"); + g_free(file_buff); + return -1; + } + + vici_kv(req, "type", (const void *)"RSA", strlen((char *)"RSA")); + vici_kv(req, "data", (const void *)file_buff, file_size); + + check_vici_request(req); + send_vici_request(req); + ret = send_vici_request(req); + if (ret < 0) { + printf("error on send_vici_request\n"); + destroy_request(req); + } + + g_free(file_buff); + + __FUNC_EXIT__; + return ret; +} + +/* test version */ + +int test_version() +{ + struct request *req = NULL; + int ret = 0; + __FUNC_ENTER__; + + ret = create_request(VICI_CMD_REQUEST, "version", &req); + if (ret < 0) { + printf("error on create_request\n"); + return -1; + } + + check_vici_request(req); + ret = send_vici_request(req); + if (ret < 0) { + printf("error on send_vici_request\n"); + destroy_request(req); + return -1; + } + + __FUNC_EXIT__; + return ret; +} + +enum { + CMD_QUIT, + CMD_FULL_MENU, + CMD_VERSION, + CMD_LOAD_CONN, + CMD_UNLOAD_CONN, + CMD_GET_CONNS, + CMD_LIST_CONNS, + CMD_LOAD_SHARED_PSK, + CMD_LOAD_SHARED_XAUTH, + CMD_LOAD_POOL, + CMD_LOAD_CA_CERT, + CMD_LOAD_PRIVATE, + CMD_INITIATE, + CMD_TERMINATE, + + CMD_INVALID, +}; + +typedef struct { + int cmd; + char* menu_str; +} menu_str_t; + +menu_str_t g_menu_str[] = { + { CMD_QUIT, "CMD_QUIT" }, + { CMD_FULL_MENU, "CMD_FULL_MENU" }, + { CMD_VERSION, "CMD_VERSION" }, + { CMD_LOAD_CONN, "CMD_LOAD_CONN" }, + { CMD_UNLOAD_CONN, "CMD_UNLOAD_CONN" }, + { CMD_GET_CONNS, "CMD_GET_CONNS" }, + { CMD_LIST_CONNS, "CMD_LIST_CONNS" }, + { CMD_LOAD_SHARED_PSK, "CMD_LOAD_SHARED_PSK" }, + { CMD_LOAD_SHARED_XAUTH, "CMD_LOAD_SHARED_XAUTH" }, + { CMD_LOAD_POOL, "CMD_LOAD_POOL" }, + { CMD_LOAD_CA_CERT, "CMD_LOAD_CA_CERT" }, + { CMD_LOAD_PRIVATE, "CMD_LOAD_PRIVATE" }, + { CMD_INITIATE, "CMD_INITIATE" }, + { CMD_TERMINATE, "CMD_TERMINATE" }, + { -1, NULL }, }; + +void usage() +{ + printf("Call Test Program\n"); + printf(" %d: quit\n", CMD_QUIT); + printf(" %d: Full menu\n", CMD_FULL_MENU); +} + +char* +cmd_transform(char*str) +{ + int i, j; + int len; + static char static_buffer[255]; + + if (str == NULL) + return ""; + + len = strlen(str); + if (len == 0) + return ""; + + /* remove "CMD_" */ + /* lower char */ + /* replance "_" to space */ + for (i = 0, j = 4; i < len; i++, j++) { + if (str[j] >= 'A' && str[j] <= 'Z') + static_buffer[i] = str[j] + 'a' - 'A'; + else if (str[j] == '_') + static_buffer[i] = ' '; + else + static_buffer[i] = str[j]; + } + static_buffer[j] = '\0'; + + return static_buffer; +} + +void usage_full() +{ + int i; + printf("Call Test Program\n"); + + for (i = 0; g_menu_str[i].cmd != -1; i++) { + if (i % 4 == 0) + printf("\n"); + printf(" %02d: %-32s ", g_menu_str[i].cmd, + cmd_transform(g_menu_str[i].menu_str)); + + } + printf("\n"); +} + +int is_digit(const char* str) +{ + int len; + int i; + + if (str == NULL) + return -1; + + if (strlen(str) == 0) + return -1; + + len = strlen(str); + for (i = 0; i < len; i++) { + if (str[i] < '0' || str[i] > '9') + return -2; + } + + return 0; +} + +void print_result(int cmd, int ret) +{ + if (ret != 0) + printf(MAKE_RED"%s failed\n", g_menu_str[cmd].menu_str); + else + printf(MAKE_GREEN"%s succeeded\n", g_menu_str[cmd].menu_str); + printf(RESET_COLOR); + +} + +int get_ipsec_type(int cmd) +{ + int type = IPSEC_HYBRID_RSA; + int i = 0; + printf("Please enter #of ipsec type for [%s]:\n", g_menu_str[cmd].menu_str); + + for (type = IPSEC_HYBRID_RSA; type <= IPSEC_IKEV2_RSA; type++) + printf("[%d] : [%s]\n", type, ipsec_type_str[type].type_str); + scanf("%d", &type); + + if (type < IPSEC_HYBRID_RSA || type > IPSEC_IKEV2_RSA) + type = -1; + return type; + +} + + +void process_std_input(const char *input, gpointer user_data) +{ + int ret = -1; + int cmd = strtol(input, NULL, 0); + + if (is_digit(input) < 0 || strlen(input) == 0 || errno == ERANGE || errno + == EINVAL) + cmd = CMD_INVALID; + + printf("cmd=[%d]\n", cmd); + + switch (cmd) { + case CMD_FULL_MENU: + { + usage_full(); + } + break; + case CMD_QUIT: + { + printf("Bye\n"); + g_main_loop_quit(main_loop); + } + break; + case CMD_VERSION: + { + ret = test_version(); + print_result(cmd, ret); + } + break; + case CMD_LOAD_CONN: + { + int type; + type = get_ipsec_type(cmd); + if (type < 0) + break; + ret = test_load_conn(type); + print_result(cmd, ret); + } + break; + case CMD_UNLOAD_CONN: + { + int type; + type = get_ipsec_type(cmd); + if (type < 0) + break; + ret = test_unload_conn(type); + print_result(cmd, ret); + } + break; + case CMD_GET_CONNS: + { + ret = test_get_conns(); + print_result(cmd, ret); + } + break; + case CMD_LIST_CONNS: + { + int type; + type = get_ipsec_type(cmd); + if (type < 0) + break; + ret = test_list_conns(type); + print_result(cmd, ret); + } + break; + case CMD_LOAD_SHARED_PSK: + { + ret = test_load_shared_psk(); + print_result(cmd, ret); + } + break; + case CMD_LOAD_SHARED_XAUTH: + { + ret = test_load_shared_xauth(); + print_result(cmd, ret); + } + break; + case CMD_LOAD_POOL: + { + int type; + type = get_ipsec_type(cmd); + if (type < 0) + break; + ret = test_load_pool(type); + print_result(cmd, ret); + } + break; + case CMD_LOAD_CA_CERT: + { + ret = test_load_ca_cert(); + print_result(cmd, ret); + } + break; + case CMD_LOAD_PRIVATE: + { + ret = test_load_private(); + print_result(cmd, ret); + } + break; + case CMD_INITIATE: + { + ret = test_initiate(); + print_result(cmd, ret); + } + break; + case CMD_TERMINATE: + { + int type; + type = get_ipsec_type(cmd); + if (type < 0) + break; + ret = test_terminate(type); + print_result(cmd, ret); + } + break; + default: + usage_full(); + break; + } + + return; +} + +static gboolean read_std_input(GIOChannel * source, + GIOCondition condition, gpointer user_data) +{ + int fd = 0; + + static char buf[MAX_STD_INPUT_BUF]; + int n; + + errno = 0; + n = read(fd, buf, MAX_STD_INPUT_BUF); + + buf[n - 1] = '\0'; /* remove new line... */ + if (n == 0) { + printf("Error: read() from stdin returns 0.\n"); + } else if (n < 0) { + printf("input: read, err=%s\n", strerror(errno)); + } else { + printf("\n\n"); + } + + process_std_input(buf, user_data); + + return TRUE; +} + +static GKeyFile *load_key_file(const char *path_name) +{ + GKeyFile *key_file = NULL; + GError *error = NULL; + + key_file = g_key_file_new(); + if (!g_key_file_load_from_file(key_file, path_name, 0, &error)) { + printf("Unable to load %s: %s", path_name, error->message); + g_clear_error(&error); + + g_key_file_free(key_file); + key_file = NULL; + } + return key_file; +} + +int load_strongswan_config(const char *path_name) +{ + GKeyFile *key_file = NULL; + int i = 0; + + key_file = load_key_file(path_name); + if (!key_file) + return -1; + + for (i = LOCAL_IP; i < STRONGSWAN_CONF_KEY_MAX; i++) { + strongswan_conf[i].value = g_key_file_get_string(key_file, CONF_GROUP_NAME, + strongswan_conf[i].key_name, NULL); + + if (strlen(strongswan_conf[i].value) == 0) + strongswan_conf[i].value = NULL; + + printf ("key [%s] value [%s]\n", + strongswan_conf[i].key_name, strongswan_conf[i].value); + } + + g_conf_key_file = key_file; + return 0; +} + +void unload_strongswan_config() +{ + int i = 0; + + for (i = LOCAL_IP; i < STRONGSWAN_CONF_KEY_MAX; i++) + g_free(strongswan_conf[i].value); + + g_key_file_free(g_conf_key_file); + g_conf_key_file = NULL; +} + +/* Run Mainloop */ +int main(int argc, char *argv[]) +{ + int std_input_fd = 0; + int ret = 0; + __FUNC_ENTER__; + + ret = load_strongswan_config(STRONGSWAN_CONF_PATH); + if (ret != 0) { + printf("Failed to load configuration. Terminate...\n"); + return -1; + } + + main_loop = g_main_loop_new(NULL, FALSE); + if (main_loop == NULL) { + printf("Failed to create GMainLoop structure\n"); + return -1; + } + + GIOChannel *unix_channel = g_io_channel_unix_new(std_input_fd); + g_io_add_watch(unix_channel, G_IO_IN, (GIOFunc)read_std_input, NULL); + g_io_channel_unref(unix_channel); + + g_main_loop_run(main_loop); + + unload_strongswan_config(); + + __FUNC_EXIT__; + return ret; +} diff --git a/test/ipsec_test/ipsec_server_src/server.conf b/test/ipsec_test/ipsec_server_src/server.conf new file mode 100644 index 0000000..99d0e00 --- /dev/null +++ b/test/ipsec_test/ipsec_server_src/server.conf @@ -0,0 +1,16 @@ +[strongswan] +local_ip=192.168.0.108 +local_ts=10.113.62.0/24 +cert_path= +ca_cert_path= +private_path= +ike_data=ABCDEFGH +ike_owner=0.0.0.0/0 +xauth_data=12345678 +xauth_owner=dave +hybrid_pool=10.113.62.137 +xauth_psk_pool=10.113.62.138 +xauth_rsa_pool=10.113.62.139 +ikev2_psk_pool=10.113.62.140 +ikev2_rsa_pool=10.113.62.141 + diff --git a/test/ipsec_test/root-ca-req.conf b/test/ipsec_test/root-ca-req.conf new file mode 100644 index 0000000..2956969 --- /dev/null +++ b/test/ipsec_test/root-ca-req.conf @@ -0,0 +1,23 @@ +[ req ] +default_bits = 2048 +distinguished_name = req_distinguished_name +prompt = no +x509_extensions = v3_ca + +[ req_distinguished_name ] + +C = KR +ST = Seocho-Gu +L = Seoul +O = Samsung Electronics .Inc +OU = . +CN = Jiung Yu +emailAddress = test@email.adress + + +[ v3_ca ] + +basicConstraints = critical, CA:true +keyUsage =cRLSign, keyCertSign +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always diff --git a/test/ipsec_test/root-ca.conf b/test/ipsec_test/root-ca.conf new file mode 100644 index 0000000..26c9ef6 --- /dev/null +++ b/test/ipsec_test/root-ca.conf @@ -0,0 +1,68 @@ + [ ca ] + default_ca = CA_default # The default ca section + + [ CA_default ] + + dir = ./root-ca # top dir + database = $dir/db/index.txt # index file. + new_certs_dir = $dir/newcerts # new certs dir + + certificate = $dir/cert/root-ca-cert.PEM # The CA cert + serial = $dir/db/serial # serial no file + private_key = $dir/private/root-ca-private.PEM# CA private key + RANDFILE = $dir/private/.rand # random number file + + x509_extensions= usr_cert # The extentions to add to the cert + + default_days = 36500 # how long to certify for + default_crl_days= 30 # how long before next CRL + default_md = sha256 # md to use + + policy = policy_any # default policy + email_in_dn = no # Don't add the email into cert DN + + name_opt = ca_default # Subject name display option + cert_opt = ca_default # Certificate display option + copy_extensions = copy # Don't copy extensions from request + + [ policy_any ] + countryName = supplied + stateOrProvinceName = optional + organizationName = optional + organizationalUnitName = optional + commonName = supplied + emailAddress = optional + +[ usr_cert ] + +# These extensions are added when 'ca' signs a request. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType = server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "OpenSSL Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer diff --git a/test/ipsec_test/server.conf b/test/ipsec_test/server.conf new file mode 100644 index 0000000..5a595bd --- /dev/null +++ b/test/ipsec_test/server.conf @@ -0,0 +1,16 @@ +[strongswan] +local_ip=192.168.0.108 +local_ts=10.113.62.0/24 +cert_path=./host-cert.PEM +ca_cert_path=./root-ca-cert.PEM +private_path=./host-private.PEM +ike_data=ABCDEFGH +ike_owner=0.0.0.0/0 +xauth_data=12345678 +xauth_owner=dave +hybrid_pool=10.113.62.137 +xauth_psk_pool=10.113.62.138 +xauth_rsa_pool=10.113.62.139 +ikev2_psk_pool=10.113.62.140 +ikev2_rsa_pool=10.113.62.141 + diff --git a/test/vpn_test.c b/test/vpn_test.c index 97a4828..45a87cf 100755 --- a/test/vpn_test.c +++ b/test/vpn_test.c @@ -30,6 +30,15 @@ #include #include +#if defined(IPSEC_TEST) +#define CA_CERT "root-ca-cert.PEM" +#define CLIENT_CERT_DER "client-cert.crt" +#define CLIENT_CERT_PEM "client-cert.PEM" +#define CLIENT_CERT_PKCS12 "client-cert.p12" +#define HOST_CERT "host-cert.PEM" +#define CLIENT_PRIVATE_KEY "client-private.PEM" +#endif + gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data); @@ -70,6 +79,7 @@ static const char *__test_convert_error_to_string(vpn_error_e err_type) return "UNKNOWN"; } +#if defined(IPSEC_TEST) typedef enum { IPSEC_HYBRID_RSA, IPSEC_XAUTH_PSK, @@ -134,6 +144,7 @@ typedef enum { IPSEC_CERT_PASS, IPSEC_PKEY_TYPE, IPSEC_PKEY_DATA, + IPSEC_CA_CERTS_DIR, IPSEC_KVS_MAX, } ipsec_kv_e; @@ -160,17 +171,19 @@ kv_s ipsec_setting_kvs[] = { {"IPsec.IKEData", NULL}, {"IPsec.IKEOwners", NULL}, {"IPsec.XauthData", NULL}, - {"IPsec.XautOwners", NULL}, + {"IPsec.XauthOwners", NULL}, {"IPsec.CertType", NULL}, {"IPsec.CertFlag", NULL}, {"IPsec.CertData", NULL}, {"IPsec.CertPass", NULL}, {"IPsec.PKeyType", NULL}, {"IPsec.PKeyData", NULL}, + {"IPsec.CACertsDir", NULL}, {NULL, NULL}, }; typedef void (*gen_ipsec_settings_f)(void); +#endif static void __test_created_callback(vpn_error_e result, void *user_data) @@ -216,6 +229,7 @@ static void _test_get_vpn_handle(vpn_h *handle_ptr) { assert(handle_ptr != NULL); + char name_str[128] = { 0 }; char host_str[128] = { 0 }; char domain_str[128] = { 0 }; const char *name = NULL; @@ -237,6 +251,11 @@ static void _test_get_vpn_handle(vpn_h *handle_ptr) printf(" Domain[%p] - %s\n", iter->data, domain); } + printf("==================================\n"); + printf(" Please ENTER Name: "); + if (scanf(" %127s", name_str) < 0) + printf("Error in Reading Host String\n"); + printf("==================================\n"); printf(" Please ENTER Host: "); if (scanf(" %127s", host_str) < 0) @@ -246,7 +265,7 @@ static void _test_get_vpn_handle(vpn_h *handle_ptr) if (scanf(" %127s", domain_str) < 0) printf("Error in Reading Domain String\n"); - vpn_get_vpn_handle(host_str, domain_str, handle_ptr); + vpn_get_vpn_handle(name_str, host_str, domain_str, handle_ptr); } static void _test_get_user_input(char *buf, char *what) @@ -459,6 +478,7 @@ int test_vpn_disconnect(void) return 1; } +#if defined(IPSEC_TEST) static int __test_init() { int rv = 0; @@ -502,7 +522,7 @@ static int __test_deinit() return rv; } -static int __test_add() +static int __test_add(ipsec_type_e type) { int rv = 0; @@ -513,7 +533,7 @@ static int __test_add() return -1; } - rv = vpn_settings_set_name("TEST_IPSEC"); + rv = vpn_settings_set_name(__get_ipsec_name(type)); if (rv != VPN_ERROR_NONE) { printf("Fail to VPN Settings Name[%s]\n", __test_convert_error_to_string(rv)); @@ -573,8 +593,11 @@ static void __gen_ipsec_hybrid_rsa_kvs(void) //ipsec_setting_kvs[IPSEC_REMOTE_CERTS].value = __get_user_input("File path for remote cert"); ipsec_setting_kvs[IPSEC_CHILDREN_REMOTE_TS].value = g_strdup("0.0.0.0/0"); ipsec_setting_kvs[IPSEC_CHILDREN_LOCAL_TS].value = g_strdup("0.0.0.0/0"); - ipsec_setting_kvs[IPSEC_XAUTH_DATA].value = g_strdup("ABCDEFGH"); + ipsec_setting_kvs[IPSEC_XAUTH_DATA].value = g_strdup("12345678"); ipsec_setting_kvs[IPSEC_XAUTH_OWNERS].value = g_strdup("dave"); + ipsec_setting_kvs[IPSEC_CERT_TYPE].value = g_strdup("X509"); + ipsec_setting_kvs[IPSEC_CERT_FLAG].value = g_strdup("CA"); + ipsec_setting_kvs[IPSEC_CERT_DATA].value = g_strdup_printf("%s%s", CERT_EXAMPLES_DIR, CA_CERT); return; } @@ -593,7 +616,7 @@ static void __gen_ipsec_xauth_psk_kvs(void) ipsec_setting_kvs[IPSEC_CHILDREN_LOCAL_TS].value = g_strdup("0.0.0.0/0"); ipsec_setting_kvs[IPSEC_IKE_DATA].value = g_strdup("ABCDEFGH"); ipsec_setting_kvs[IPSEC_IKE_OWNERS].value = g_strdup("0.0.0.0/0"); - ipsec_setting_kvs[IPSEC_XAUTH_DATA].value = g_strdup("ABCDEFGH"); + ipsec_setting_kvs[IPSEC_XAUTH_DATA].value = g_strdup("12345678"); ipsec_setting_kvs[IPSEC_XAUTH_OWNERS].value = g_strdup("dave"); return; } @@ -605,22 +628,21 @@ static void __gen_ipsec_xauth_rsa_kvs(void) ipsec_setting_kvs[IPSEC_LEFT_ADDRS].value = __get_user_input("Local Address for IPsec"); ipsec_setting_kvs[IPSEC_RIGHT_ADDRS].value = __get_user_input("Remote Address for IPsec"); ipsec_setting_kvs[IPSEC_LOCAL_AUTH].value = g_strdup("pubkey"); - ipsec_setting_kvs[IPSEC_LOCAL_CERTS].value = __get_user_input("File path for local cert"); - ipsec_setting_kvs[IPSEC_LOCAL_CERT_PASS].value = __get_user_input("Local Certificate passwd"); + ipsec_setting_kvs[IPSEC_LOCAL_CERTS].value = g_strdup_printf("%s%s", CERT_EXAMPLES_DIR, CLIENT_CERT_PEM); + //ipsec_setting_kvs[IPSEC_LOCAL_CERT_PASS].value = __get_user_input("Local Certificate passwd"); ipsec_setting_kvs[IPSEC_LOCAL_XAUTH_AUTH].value = g_strdup("xauth"); ipsec_setting_kvs[IPSEC_LOCAL_XAUTH_XAUTH_ID].value = g_strdup("dave"); ipsec_setting_kvs[IPSEC_REMOTE_AUTH].value = g_strdup("pubkey"); //ipsec_setting_kvs[IPSEC_REMOTE_CERTS].value = __get_user_input("File path for remote cert"); ipsec_setting_kvs[IPSEC_CHILDREN_REMOTE_TS].value = g_strdup("0.0.0.0/0"); ipsec_setting_kvs[IPSEC_CHILDREN_LOCAL_TS].value = g_strdup("0.0.0.0/0"); - ipsec_setting_kvs[IPSEC_XAUTH_DATA].value = g_strdup("ABCDEFGH"); + ipsec_setting_kvs[IPSEC_XAUTH_DATA].value = g_strdup("12345678"); ipsec_setting_kvs[IPSEC_XAUTH_OWNERS].value = g_strdup("dave"); ipsec_setting_kvs[IPSEC_CERT_TYPE].value = g_strdup("X509"); ipsec_setting_kvs[IPSEC_CERT_FLAG].value = g_strdup("CA"); - ipsec_setting_kvs[IPSEC_CERT_PASS].value = __get_user_input("Certificate passwd"); - ipsec_setting_kvs[IPSEC_CERT_DATA].value = __get_user_input("File path for CA cert"); + ipsec_setting_kvs[IPSEC_CERT_DATA].value = g_strdup_printf("%s%s", CERT_EXAMPLES_DIR, CA_CERT); ipsec_setting_kvs[IPSEC_PKEY_TYPE].value = g_strdup("RSA"); - ipsec_setting_kvs[IPSEC_PKEY_DATA].value = __get_user_input("File path for private key"); + ipsec_setting_kvs[IPSEC_PKEY_DATA].value = g_strdup_printf("%s%s", CERT_EXAMPLES_DIR, CLIENT_PRIVATE_KEY); return; } static void __gen_ipsec_ikev2_psk_kvs(void) @@ -646,18 +668,18 @@ static void __gen_ipsec_ikev2_rsa_kvs() ipsec_setting_kvs[IPSEC_LEFT_ADDRS].value = __get_user_input("Local Address for IPsec"); ipsec_setting_kvs[IPSEC_RIGHT_ADDRS].value = __get_user_input("Remote Address for IPsec"); ipsec_setting_kvs[IPSEC_LOCAL_AUTH].value = g_strdup("pubkey"); - ipsec_setting_kvs[IPSEC_LOCAL_CERTS].value = __get_user_input("File path for local cert"); - ipsec_setting_kvs[IPSEC_LOCAL_CERT_PASS].value = __get_user_input("Local Certificate passwd"); + ipsec_setting_kvs[IPSEC_LOCAL_CERTS].value = g_strdup_printf("%s%s", CERT_EXAMPLES_DIR, CLIENT_CERT_PEM); + //ipsec_setting_kvs[IPSEC_LOCAL_CERT_PASS].value = __get_user_input("Local Certificate passwd"); ipsec_setting_kvs[IPSEC_REMOTE_AUTH].value = g_strdup("pubkey"); //ipsec_setting_kvs[IPSEC_REMOTE_CERTS].value = __get_user_input("File path for remote cert"); ipsec_setting_kvs[IPSEC_CHILDREN_REMOTE_TS].value = g_strdup("0.0.0.0/0"); ipsec_setting_kvs[IPSEC_CHILDREN_LOCAL_TS].value = g_strdup("0.0.0.0/0"); ipsec_setting_kvs[IPSEC_CERT_TYPE].value = g_strdup("X509"); ipsec_setting_kvs[IPSEC_CERT_FLAG].value = g_strdup("CA"); - ipsec_setting_kvs[IPSEC_CERT_DATA].value = __get_user_input("File path for CA cert"); - ipsec_setting_kvs[IPSEC_CERT_PASS].value = __get_user_input("Certificate passwd"); + ipsec_setting_kvs[IPSEC_CERT_DATA].value = g_strdup_printf("%s%s", CERT_EXAMPLES_DIR, CA_CERT); + //ipsec_setting_kvs[IPSEC_CERT_PASS].value = __get_user_input("Certificate passwd"); ipsec_setting_kvs[IPSEC_PKEY_TYPE].value = g_strdup("RSA"); - ipsec_setting_kvs[IPSEC_PKEY_DATA].value = __get_user_input("File path for private key"); + ipsec_setting_kvs[IPSEC_PKEY_DATA].value = g_strdup_printf("%s%s", CERT_EXAMPLES_DIR, CLIENT_PRIVATE_KEY); return; } @@ -685,7 +707,7 @@ int test_create_ipsec(gpointer data, ipsec_type_e type) if (rv != VPN_ERROR_NONE) return -1; - rv = __test_add(); + rv = __test_add(type); if (rv != VPN_ERROR_NONE) return -1; @@ -717,23 +739,32 @@ int test_create_ipsec(gpointer data, ipsec_type_e type) return 1; } +#endif int main(int argc, char **argv) { - gen_ipsec_settings_f gen_ipsec_settings[IPSEC_MAX]; GMainLoop *mainloop; +#if defined(IPSEC_TEST) + gen_ipsec_settings_f gen_ipsec_settings[IPSEC_MAX]; + gen_ipsec_settings[IPSEC_HYBRID_RSA] = __gen_ipsec_hybrid_rsa_kvs; gen_ipsec_settings[IPSEC_XAUTH_PSK] = __gen_ipsec_xauth_psk_kvs; gen_ipsec_settings[IPSEC_XAUTH_RSA] = __gen_ipsec_xauth_rsa_kvs; gen_ipsec_settings[IPSEC_IKEV2_PSK] = __gen_ipsec_ikev2_psk_kvs; gen_ipsec_settings[IPSEC_IKEV2_RSA] = __gen_ipsec_ikev2_rsa_kvs; +#endif mainloop = g_main_loop_new(NULL, FALSE); GIOChannel *channel = g_io_channel_unix_new(0); +#if defined(IPSEC_TEST) g_io_add_watch(channel, (G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL), test_thread, gen_ipsec_settings); +#else + g_io_add_watch(channel, (G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL), + test_thread, NULL); +#endif printf("Test Thread created...\n"); @@ -773,11 +804,13 @@ gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data) printf("8\t- VPN Remove - Removes the VPN profile\n"); printf("9\t- VPN Connect - Connect the VPN profile\n"); printf("a\t- VPN Disconnect - Disconnect the VPN profile\n"); +#if defined(IPSEC_TEST) printf("b\t- VPN Test Create IPSec Hybrid RSA - Create IPSec Hybrid RSA\n"); printf("c\t- VPN Test Create IPSec Xauth PSK - Create IPSec Xauth PSK\n"); printf("d\t- VPN Test Create IPSec Xauth RSA - Create IPSec Xauth RSA\n"); printf("e\t- VPN Test Create IPSec IKEv2 PSK - Create IPSec IKEv2 PSK\n"); printf("f\t- VPN Test Create IPSec IKEv2 RSA - Create IPSec IKEv2 RSA\n"); +#endif printf("0\t- Exit\n"); printf("ENTER - Show options menu.......\n"); @@ -814,6 +847,7 @@ gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data) case 'a': rv = test_vpn_disconnect(); break; +#if defined(IPSEC_TEST) case 'b': rv = test_create_ipsec(data, IPSEC_HYBRID_RSA); break; @@ -829,6 +863,7 @@ gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data) case 'f': rv = test_create_ipsec(data, IPSEC_IKEV2_RSA); break; +#endif default: break; }