session CHANGE init/destroy functions reworked

Now, if the user calls them the way one should,
there will be no memory left on application exit.
Quite an achievement...
diff --git a/src/netconf.h b/src/netconf.h
index 25fb9cb..338c5d6 100644
--- a/src/netconf.h
+++ b/src/netconf.h
@@ -113,20 +113,58 @@
     NC_PARAMTYPE_DUP_AND_FREE /**< make a copy of the argument, free afterwards */
 } NC_PARAMTYPE;
 
+#if defined(ENABLE_SSH) || defined(ENABLE_TLS)
+
+/**
+ * @brief Free all the dynamically allocated thread-specific libssl/libcrypto
+ *        resources.
+ *
+ *        This function should be called only if any of #nc_ssh_init(), #nc_tls_init(),
+ *        or #nc_ssh_tls_init() was called. Call it in every thread your application
+ *        creates just before the thread exits. In the last thread (usually the main one)
+ *        call only #nc_ssh_destroy(), #nc_ssh_tls_destroy(), or #nc_tls_destroy,
+ *        depending on what you used for initialization.
+ */
+void nc_thread_destroy(void);
+
+#endif /* ENABLE_SSH || ENABLE_TLS */
+
+#if defined(ENABLE_SSH) && defined(ENABLE_TLS)
+
+/**
+ * @brief Initialize both libssh and libssl/libcrypto libraries for thread-safe usage.
+ *        Call this function even if you, for instance, will use only SSH transport,
+ *        but want to use some libssl/libcrypto functions in your application.
+ *
+ *        Must be called before calling any libnetconf2 SSH and/or TLS function.
+ */
+void nc_ssh_tls_init(void);
+
+/**
+ * @brief Free all the dynamically allocated libssh and libssl/libcrypto resources.
+ *
+ *        No libnetconf2 SSH/TLS, libssh, and libcrypto/libssl function should be
+ *        called afterwards.
+ */
+void nc_ssh_tls_destroy(void);
+
+#endif /* ENABLE_SSH && ENABLE_TLS */
+
 #ifdef ENABLE_SSH
 
 /**
- * @brief Initialize libssh so that libnetconf2 can be safely used in a multi-threaded environment.
+ * @brief Initialize libssh for thread-safe usage. If you plan to use libcrypto/
+ *        /libssl in your application as well, please call #nc_ssh_tls_init()
+ *        instead.
  *
- * Must be called before using any other SSH functions. Afterwards can libssh be used in the application
- * as well.
+ *        Must be called before calling any libnetconf2 SSH function.
  */
 void nc_ssh_init(void);
 
 /**
- * @brief Free all the resources allocated by libssh.
+ * @brief Free all the dynamically allocated libssh resources.
  *
- * Must be called before #nc_tls_destroy() (if called) as libssh uses libcrypto as well.
+ *        No libnetconf2 SSH and libssh function should be called afterwards.
  */
 void nc_ssh_destroy(void);
 
@@ -135,15 +173,17 @@
 #ifdef ENABLE_TLS
 
 /**
- * @brief Initialize libcrypto so that libnetconf2 can be safely used in a multi-threaded environment.
+ * @brief Initialize libssl/libcrypto for thread-safe usage. If you plan to use libssh
+ *        in your application as well, please call #nc_ssh_tls_init() instead.
  *
- * Must be called before using any other TLS functions. Afterwards can libcrypto be used in the application
- * as well.
+ *        Must be called before calling any libnetconf2 TLS function.
  */
 void nc_tls_init(void);
 
 /**
- * @brief Free all the resources allocated by libcrypto and libssl.
+ * @brief Free all the dynamically allocated libssl/libcrypto resources.
+ *
+ *        No libnetconf2 TLS and libssl/libcrypto function should be called afterwards.
  */
 void nc_tls_destroy(void);
 
diff --git a/src/session.c b/src/session.c
index 21abf8b..090c7fc 100644
--- a/src/session.c
+++ b/src/session.c
@@ -27,6 +27,7 @@
 #include <time.h>
 #include <libyang/libyang.h>
 
+#include "session.h"
 #include "libnetconf.h"
 #include "session_server.h"
 
@@ -36,11 +37,13 @@
 
 #endif /* ENABLE_SSH */
 
-#ifdef ENABLE_TLS
+#if defined(ENABLE_SSH) || defined(ENABLE_TLS)
 
+#   include <openssl/engine.h>
+#   include <openssl/conf.h>
 #   include <openssl/err.h>
 
-#endif /* ENABLE_TLS */
+#endif /* ENABLE_SSH || ENABLE_TLS */
 
 /* in seconds */
 #define NC_CLIENT_HELLO_TIMEOUT 60
@@ -916,6 +919,9 @@
 API void
 nc_ssh_destroy(void)
 {
+    ENGINE_cleanup();
+    CONF_modules_unload(1);
+    ERR_remove_state(0);
     ssh_finalize();
 }
 
@@ -1005,14 +1011,12 @@
 nc_tls_destroy(void)
 {
     int i;
-    CRYPTO_THREADID crypto_tid;
 
-    EVP_cleanup();
     CRYPTO_cleanup_all_ex_data();
+    ERR_remove_state(0);
+    EVP_cleanup();
     ERR_free_strings();
     sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
-    CRYPTO_THREADID_current(&crypto_tid);
-    ERR_remove_thread_state(&crypto_tid);
 
     CRYPTO_set_id_callback(NULL);
     CRYPTO_set_locking_callback(NULL);
@@ -1027,3 +1031,48 @@
 }
 
 #endif /* ENABLE_TLS */
+
+#if defined(ENABLE_SSH) || defined(ENABLE_TLS)
+
+API void
+nc_thread_destroy(void) {
+    CRYPTO_THREADID crypto_tid;
+
+    CRYPTO_cleanup_all_ex_data();
+
+    CRYPTO_THREADID_current(&crypto_tid);
+    ERR_remove_thread_state(&crypto_tid);
+}
+
+#endif /* ENABLE_SSH || ENABLE_TLS */
+
+#if defined(ENABLE_SSH) && defined(ENABLE_TLS)
+
+API void
+nc_ssh_tls_init(void)
+{
+    SSL_load_error_strings();
+    ERR_load_BIO_strings();
+    SSL_library_init();
+
+    nc_ssh_init();
+
+    CRYPTO_set_dynlock_create_callback(tls_dyn_create_func);
+    CRYPTO_set_dynlock_lock_callback(tls_dyn_lock_func);
+    CRYPTO_set_dynlock_destroy_callback(tls_dyn_destroy_func);
+}
+
+API void
+nc_ssh_tls_destroy(void)
+{
+    ERR_free_strings();
+    sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
+
+    nc_ssh_destroy();
+
+    CRYPTO_set_dynlock_create_callback(NULL);
+    CRYPTO_set_dynlock_lock_callback(NULL);
+    CRYPTO_set_dynlock_destroy_callback(NULL);
+}
+
+#endif /* ENABLE_SSH && ENABLE_TLS */