UNIX socket UPDATE configurable with YANG data
Implemented the ability to create a UNIX socket server with YANG
data. Additionally all new tests timeouts are now unified.
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index ca85067..2a13145 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -9,7 +9,7 @@
# list of all the tests in each directory
#set(tests test_io test_fd_comm test_init_destroy_client test_init_destroy_server test_client_thread test_thread_messages)
-set(tests test_two_channels test_keystore)
+set(tests test_two_channels test_keystore test_unix_socket)
# only enable PAM tests if the version of PAM is greater than 1.4
if(LIBPAM_HAVE_CONFDIR)
diff --git a/tests/test_auth.c b/tests/test_auth.c
index 29b22b1..5511da9 100644
--- a/tests/test_auth.c
+++ b/tests/test_auth.c
@@ -31,13 +31,12 @@
#include "tests/config.h"
-#define NC_ACCEPT_TIMEOUT 100
-#define NC_PS_POLL_TIMEOUT 100
+#define NC_ACCEPT_TIMEOUT 2000
+#define NC_PS_POLL_TIMEOUT 2000
struct ly_ctx *ctx;
struct test_state {
- // bariera
pthread_barrier_t barrier;
};
diff --git a/tests/test_keystore.c b/tests/test_keystore.c
index 5f583ad..c7e8af8 100644
--- a/tests/test_keystore.c
+++ b/tests/test_keystore.c
@@ -31,13 +31,12 @@
#include "tests/config.h"
-#define NC_ACCEPT_TIMEOUT 100
-#define NC_PS_POLL_TIMEOUT 100
+#define NC_ACCEPT_TIMEOUT 2000
+#define NC_PS_POLL_TIMEOUT 2000
struct ly_ctx *ctx;
struct test_state {
- // bariera
pthread_barrier_t barrier;
};
diff --git a/tests/test_nc3.c b/tests/test_nc3.c
deleted file mode 100644
index f74ab25..0000000
--- a/tests/test_nc3.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/**
- * @file test_pam.c
- * @author Roman Janota <xjanot04@fit.vutbr.cz>
- * @brief libnetconf2 Linux PAM keyboard-interactive authentication test
- *
- * @copyright
- * Copyright (c) 2022 CESNET, z.s.p.o.
- *
- * This source code is licensed under BSD 3-Clause License (the "License").
- * You may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://opensource.org/licenses/BSD-3-Clause
- */
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <libyang/libyang.h>
-#include <log.h>
-#include <session_client.h>
-#include <session_server.h>
-#include "config_server.h"
-
-#include "tests/config.h"
-
-#define nc_assert(cond) if (!(cond)) { fprintf(stderr, "assert failed (%s:%d)\n", __FILE__, __LINE__); abort(); }
-
-#define NC_ACCEPT_TIMEOUT 5000
-#define NC_PS_POLL_TIMEOUT 5000
-
-const char *data =
- "<netconf-server xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-server\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">"
- "<listen yang:operation=\"create\">"
- "<idle-timeout>10</idle-timeout>"
- "<endpoint>"
- "<name>default-ssh</name>"
- "<ssh>"
- "<tcp-server-parameters>"
- "<local-address>127.0.0.1</local-address>"
- "<local-port>10005</local-port>"
- "</tcp-server-parameters>"
- "<ssh-server-parameters>"
- "<server-identity>"
- "<host-key>"
- "<name>key</name>"
- "<public-key>"
- "<local-definition>"
- "<public-key-format xmlns:ct=\"urn:ietf:params:xml:ns:yang:ietf-crypto-types\">ct:ssh-public-key-format</public-key-format>"
- "<public-key>MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA6ojtjfDmvyQP1ZkIwBpr"
- "97eKDuebvpoglRHRdvVuTpf/gU1VArAQmwGh05i6lm8TkVl1noMlIxLJDcWslaeV"
- "n6KyvsX0HhsQtXwqPqwka5UCv6alwf/ivAvcNpcX1j0t/uIGCI4dSiKnzQCyf0FT"
- "irzQkjrDZUd3meDhNQTruCalGV4gfNWIq3e1oGuwAn1tLlu9oTrE4HzMpgbNEU6w"
- "NmsSqpwGxUhYLoSaM7b0dLmqP+ZczSS0Uac0PFNkehGQ2CYIT80f580o4XGtoLCU"
- "UGkp6YCTL4Z2CeBEaJABWjDIDH+dKYIUBqUpz4Th12gXAP+h+3qI6+9eppeHrfrz"
- "ARDsfLjwUNxQJse1QSArjAytf0FKtGHrORc7W0TiCFvR0zaoUNLTKk7enTiRQ9rf"
- "WZOAu44fUvPCaXDE6zXXeaVgoKCo4VHlho36erUcjlEBM+jk28IykbZGtBb6igKv"
- "Ya1tPSgeYm/zJoFVjQcnr14uci/ft1+Na+hOIEoEEiKxcAPk2b2vBKNlRIW7WLJ3"
- "u7ZiuQEJTNm6+3cE4+lfwaBCBqBToE+dpzvoUXoMyFFReUFd1O5axu4fXgt00jMa"
- "OQxmE0v9OmR/pL/PWIflVF4Zz5yVONYaDVc7l+veY0oEZruEPJ0hlEgxuCzLrcMh"
- "jufl2qE2Q7fQIaav/1NqBVkCAwEAAQ==</public-key>"
- "<private-key-format xmlns:ct=\"urn:ietf:params:xml:ns:yang:ietf-crypto-types\">ct:rsa-private-key-format</private-key-format>"
- "<cleartext-private-key>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</cleartext-private-key>"
- "</local-definition>"
- "</public-key>"
- "</host-key>"
- "</server-identity>"
- "<client-authentication>"
- "<users>"
- "<user>"
- "<name>test</name>"
- "<public-keys>"
- "<local-definition>"
- "<public-key>"
- "<name>client</name>"
- "<public-key-format xmlns:ct=\"urn:ietf:params:xml:ns:yang:ietf-crypto-types\">ct:ssh-public-key-format</public-key-format>"
- "<public-key>MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvpKj6gy/Rm1pqlUIaeKp"
- "WuL2KOJBbodhxuPG+0S6f+Jf4LopOB76tmg1RQ/bAXLNxXkG46Cx9UOHaFK/Ixul"
- "cCbH6LxOUg90/HVS7NnbaVtDsl03HG9CPZTlQzM+n+iFAXv5ub5PFzW3VCCNDSfM"
- "tXUOdVR93u/OAc7uz0nWjGhWnOH5MPJCQPS8ZFpL9hQxQuyAXFY0YLW/9eRMDgx/"
- "OPTuvlTxIF+YHaMzY+Wy+Oaygwb78dCow+3RQRgCB20o5o6exx2nX2Cqr7UJzG/N"
- "30XCusKIcTT978td8AU7UjpbzoNehm/tmQdDq+8IDsNfWbxCHDYLMD8IR32UDXGD"
- "DVSwrtNgUs8HWNNCBKjTNCeQf1v/yiRd7hRf2aj+w9sDu8PI+VC9pabsRe2KxnnD"
- "U9Sq+4IB3ZM3C5XpJDbu8DVigGZSevim7p/D6mW2phlyxtlK9WmQ5Misg/Z8jM7E"
- "Z3gJcTvh20IS6I4plG7DJvsIC/Pc3IS2JC/w0prCZa8gOKob8x2mjjQcOA1eVIUm"
- "yw6WbV1X65/jAJvIS6an/oFAk4bBTfJA6fYfU4Pb9NWovYxm/eNR5BbRmFFh0uXa"
- "0s92S50iOotf8CnW7PZ7PWKgzKqtnN9Ob+Ye7WjDdG+NCrhkiDBOCuHDrHXwqaxW"
- "BmUICo2mnUMK7JuJNSZe5DMCAwEAAQ==</public-key>"
- "</public-key>"
- "</local-definition>"
- "</public-keys>"
- "<none/>"
- "</user>"
- "</users>"
- "</client-authentication>"
- "<transport-params>"
- "<host-key>"
- "<host-key-alg xmlns:sshpka=\"urn:ietf:params:xml:ns:yang:iana-ssh-public-key-algs\">sshpka:ssh-rsa</host-key-alg>"
- "<host-key-alg xmlns:sshpka=\"urn:ietf:params:xml:ns:yang:iana-ssh-public-key-algs\">sshpka:rsa-sha2-512</host-key-alg>"
- "</host-key>"
- "<key-exchange>"
- "<key-exchange-alg xmlns:sshkea=\"urn:ietf:params:xml:ns:yang:iana-ssh-key-exchange-algs\">sshkea:diffie-hellman-group18-sha512</key-exchange-alg>"
- "</key-exchange>"
- "<encryption>"
- "<encryption-alg xmlns:sshea=\"urn:ietf:params:xml:ns:yang:iana-ssh-encryption-algs\">sshea:aes256-cbc</encryption-alg>"
- "</encryption>"
- "<mac>"
- "<mac-alg xmlns:sshma=\"urn:ietf:params:xml:ns:yang:iana-ssh-mac-algs\">sshma:hmac-sha1</mac-alg>"
- "</mac>"
- "</transport-params>"
- "</ssh-server-parameters>"
- "</ssh>"
- "</endpoint>"
- "</listen>"
- "</netconf-server>";
-
-static int
-setup(struct ly_ctx *ctx)
-{
- int i;
- const char *all_features[] = {"*", NULL};
- /* no ssh-x509-certs */
- const char *ssh_common_features[] = {"transport-params", "public-key-generation", NULL};
- /* no ssh-server-keepalives and local-user-auth-hostbased */
- const char *ssh_server_features[] = {"local-users-supported", "local-user-auth-publickey", "local-user-auth-password", "local-user-auth-none", NULL};
- /* no private-key-encryption and csr-generation */
- const char *crypto_types_features[] = {
- "one-symmetric-key-format", "one-asymmetric-key-format", "symmetrically-encrypted-value-format",
- "asymmetrically-encrypted-value-format", "cms-enveloped-data-format", "cms-encrypted-data-format",
- "p10-based-csrs", "certificate-expiration-notification", "hidden-keys", "password-encryption",
- "symmetric-key-encryption", NULL
- };
-
- const char *module_names[] = {
- "ietf-netconf-server", "ietf-tls-common", "ietf-tls-server", "ietf-truststore", "iana-crypt-hash", "ietf-keystore",
- "ietf-tcp-server", "ietf-tcp-common", "ietf-tcp-client", "iana-ssh-public-key-algs",
- "iana-ssh-key-exchange-algs", "iana-ssh-encryption-algs", "iana-ssh-mac-algs", NULL
- };
-
- for (i = 0; module_names[i] != NULL; i++) {
- if (!ly_ctx_load_module(ctx, module_names[i], NULL, all_features)) {
- fprintf(stderr, "Loading module (%s) failed.\n", module_names[i]);
- goto error;
- }
- }
-
- if (!ly_ctx_load_module(ctx, "ietf-ssh-common", NULL, ssh_common_features)) {
- fprintf(stderr, "Loading module (ietf-ssh-common) failed.\n");
- goto error;
- }
- if (!ly_ctx_load_module(ctx, "ietf-ssh-server", NULL, ssh_server_features)) {
- fprintf(stderr, "Loading module (ietf-ssh-server) failed.\n");
- goto error;
- }
- if (!ly_ctx_load_module(ctx, "ietf-crypto-types", NULL, crypto_types_features)) {
- fprintf(stderr, "Loading module (ietf-crypto-types) failed.\n");
- goto error;
- }
-
- return 0;
-
-error:
- return 1;
-}
-
-int
-main(void)
-{
- int ret;
- struct ly_ctx *ctx;
- struct lyd_node *tree;
-
- nc_verbosity(NC_VERB_VERBOSE);
-
- ret = ly_ctx_new("/home/roman/Downloads/yang", 0, &ctx);
- nc_assert(!ret);
-
- ret = setup(ctx);
- nc_assert(!ret);
-
- ret = lyd_parse_data_mem(ctx, data, LYD_XML, LYD_PARSE_NO_STATE | LYD_PARSE_STRICT, LYD_VALIDATE_NO_STATE, &tree);
- nc_assert(!ret);
-
- ret = nc_server_config_setup(tree);
- nc_assert(!ret);
-
- nc_server_init();
-
- nc_server_destroy();
- lyd_free_all(tree);
- ly_ctx_destroy(ctx);
- return 0;
-}
diff --git a/tests/test_two_channels.c b/tests/test_two_channels.c
index 37ac20c..ac7550e 100644
--- a/tests/test_two_channels.c
+++ b/tests/test_two_channels.c
@@ -32,8 +32,8 @@
#include "tests/config.h"
-#define NC_ACCEPT_TIMEOUT 5000
-#define NC_PS_POLL_TIMEOUT 500
+#define NC_ACCEPT_TIMEOUT 2000
+#define NC_PS_POLL_TIMEOUT 2000
#define BACKOFF_TIMEOUT_USECS 100
struct ly_ctx *ctx;
diff --git a/tests/test_unix_socket.c b/tests/test_unix_socket.c
new file mode 100644
index 0000000..56c1f12
--- /dev/null
+++ b/tests/test_unix_socket.c
@@ -0,0 +1,198 @@
+/**
+ * @file test_keystore.c
+ * @author Roman Janota <xjanot04@fit.vutbr.cz>
+ * @brief libnetconf2 Linux PAM keyboard-interactive authentication test
+ *
+ * @copyright
+ * Copyright (c) 2022 CESNET, z.s.p.o.
+ *
+ * This source code is licensed under BSD 3-Clause License (the "License").
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <pthread.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <cmocka.h>
+
+#include <config_server.h>
+#include <libnetconf.h>
+#include <libyang/libyang.h>
+#include <log.h>
+#include <session_client.h>
+#include <session_server.h>
+
+#include "tests/config.h"
+
+#define NC_ACCEPT_TIMEOUT 2000
+#define NC_PS_POLL_TIMEOUT 2000
+
+struct ly_ctx *ctx;
+
+struct test_state {
+ pthread_barrier_t barrier;
+};
+
+const char *data =
+ "<netconf-server xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-server\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
+ " <listen yang:operation=\"create\">\n"
+ " <idle-timeout>10</idle-timeout>\n"
+ " <endpoint>\n"
+ " <name>default-unix-socket</name>\n"
+ " <unix-socket xmlns=\"urn:cesnet:libnetconf2-netconf-server\">\n"
+ " <path>/tmp/nc2_test_unix_sock</path>\n"
+ " </unix-socket>\n"
+ " </endpoint>\n"
+ " </listen>\n"
+ "</netconf-server>\n";
+
+static void *
+server_thread(void *arg)
+{
+ int ret;
+ NC_MSG_TYPE msgtype;
+ struct nc_session *session;
+ struct nc_pollsession *ps;
+ struct test_state *state = arg;
+
+ ps = nc_ps_new();
+ assert_non_null(ps);
+
+ /* accept a session and add it to the poll session structure */
+ pthread_barrier_wait(&state->barrier);
+ msgtype = nc_accept(NC_ACCEPT_TIMEOUT, ctx, &session);
+ assert_int_equal(msgtype, NC_MSG_HELLO);
+
+ ret = nc_ps_add_session(ps, session);
+ assert_int_equal(ret, 0);
+
+ do {
+ ret = nc_ps_poll(ps, NC_PS_POLL_TIMEOUT, NULL);
+ assert_int_equal(ret & NC_PSPOLL_RPC, NC_PSPOLL_RPC);
+ } while (!(ret & NC_PSPOLL_SESSION_TERM));
+
+ nc_ps_clear(ps, 1, NULL);
+ nc_ps_free(ps);
+ nc_thread_destroy();
+ return NULL;
+}
+
+static void *
+client_thread(void *arg)
+{
+ struct nc_session *session = NULL;
+ struct test_state *state = arg;
+
+ pthread_barrier_wait(&state->barrier);
+ session = nc_connect_unix("/tmp/nc2_test_unix_sock", NULL);
+ assert_non_null(session);
+
+ nc_session_free(session, NULL);
+ nc_thread_destroy();
+ return NULL;
+}
+
+static void
+test_nc_connect_unix_socket(void **state)
+{
+ int ret, i;
+ pthread_t tids[2];
+
+ assert_non_null(state);
+
+ ret = pthread_create(&tids[0], NULL, client_thread, *state);
+ assert_int_equal(ret, 0);
+ ret = pthread_create(&tids[1], NULL, server_thread, *state);
+ assert_int_equal(ret, 0);
+
+ for (i = 0; i < 2; i++) {
+ pthread_join(tids[i], NULL);
+ }
+}
+
+static int
+setup_f(void **state)
+{
+ int ret;
+ struct lyd_node *tree;
+ struct test_state *test_state;
+
+ nc_verbosity(NC_VERB_VERBOSE);
+
+ /* init barrier */
+ test_state = malloc(sizeof *test_state);
+ assert_non_null(test_state);
+
+ ret = pthread_barrier_init(&test_state->barrier, NULL, 2);
+ assert_int_equal(ret, 0);
+
+ *state = test_state;
+
+ ret = ly_ctx_new(MODULES_DIR, 0, &ctx);
+ assert_int_equal(ret, 0);
+
+ /* initialize context */
+ ret = nc_server_init_ctx(&ctx);
+ assert_int_equal(ret, 0);
+
+ /* load ietf-netconf-server module and it's dependencies into context */
+ ret = nc_server_config_load_modules(&ctx);
+ assert_int_equal(ret, 0);
+
+ /* parse yang data */
+ ret = lyd_parse_data_mem(ctx, data, LYD_XML, LYD_PARSE_NO_STATE | LYD_PARSE_STRICT, LYD_VALIDATE_NO_STATE, &tree);
+ assert_int_equal(ret, 0);
+
+ /* configure the server based on the data */
+ ret = nc_server_config_setup(tree);
+ assert_int_equal(ret, 0);
+
+ /* initialize client */
+ nc_client_init();
+
+ /* initialize server */
+ ret = nc_server_init();
+ assert_int_equal(ret, 0);
+
+ lyd_free_all(tree);
+
+ return 0;
+}
+
+static int
+teardown_f(void **state)
+{
+ int ret = 0;
+ struct test_state *test_state;
+
+ assert_non_null(state);
+ test_state = *state;
+
+ ret = pthread_barrier_destroy(&test_state->barrier);
+ assert_int_equal(ret, 0);
+
+ free(*state);
+ nc_client_destroy();
+ nc_server_destroy();
+ ly_ctx_destroy(ctx);
+
+ return 0;
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(test_nc_connect_unix_socket, setup_f, teardown_f),
+ };
+
+ setenv("CMOCKA_TEST_ABORT", "1", 1);
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}