diff options
Diffstat (limited to 'svr-session.c')
-rw-r--r-- | svr-session.c | 73 |
1 files changed, 69 insertions, 4 deletions
diff --git a/svr-session.c b/svr-session.c index a816398..3ea7589 100644 --- a/svr-session.c +++ b/svr-session.c @@ -88,6 +88,18 @@ svr_session_cleanup(void) { m_free(svr_ses.remotehost); m_free(svr_ses.childpids); svr_ses.childpidsize = 0; + +#if DROPBEAR_EPKA + if (svr_ses.epka_plugin_handle != NULL) { + if (svr_ses.epka_instance) { + svr_ses.epka_instance->delete_plugin(svr_ses.epka_instance); + svr_ses.epka_instance = NULL; + } + + dlclose(svr_ses.epka_plugin_handle); + svr_ses.epka_plugin_handle = NULL; + } +#endif } void svr_session(int sock, int childpipe) { @@ -101,10 +113,6 @@ void svr_session(int sock, int childpipe) { #if DROPBEAR_VFORK svr_ses.server_pid = getpid(); #endif - svr_authinitialise(); - chaninitialise(svr_chantypes); - svr_chansessinitialise(); - svr_algos_initialise(); /* for logging the remote address */ get_socket_address(ses.sock_in, NULL, NULL, &host, &port, 0); @@ -114,6 +122,56 @@ void svr_session(int sock, int childpipe) { m_free(host); m_free(port); +#if DROPBEAR_EPKA + /* Initializes the EPKA Plugin */ + svr_ses.epka_plugin_handle = NULL; + svr_ses.epka_instance = NULL; + if (svr_opts.pubkey_plugin) { +#if DEBUG_TRACE + const int verbose = debug_trace; +#else + const int verbose = 0; +#endif + PubkeyExtPlugin_newFn pluginConstructor; + + /* RTLD_NOW: fails if not all the symbols are resolved now. Better fail now than at run-time */ + svr_ses.epka_plugin_handle = dlopen(svr_opts.pubkey_plugin, RTLD_NOW); + if (svr_ses.epka_plugin_handle == NULL) { + dropbear_exit("failed to load external pubkey plugin '%s': %s", svr_opts.pubkey_plugin, dlerror()); + } + pluginConstructor = (PubkeyExtPlugin_newFn)dlsym(svr_ses.epka_plugin_handle, DROPBEAR_PUBKEY_PLUGIN_FNNAME_NEW); + if (!pluginConstructor) { + dropbear_exit("plugin constructor method not found in external pubkey plugin"); + } + + /* Create an instance of the plugin */ + svr_ses.epka_instance = pluginConstructor(verbose, svr_opts.pubkey_plugin_options, svr_ses.addrstring); + if (svr_ses.epka_instance == NULL) { + dropbear_exit("external plugin initialization failed"); + } + /* Check if the plugin is compatible */ + if ( (svr_ses.epka_instance->api_version[0] != DROPBEAR_EPKA_VERSION_MAJOR) || + (svr_ses.epka_instance->api_version[1] < DROPBEAR_EPKA_VERSION_MINOR) ) { + dropbear_exit("plugin version check failed: " + "Dropbear=%d.%d, plugin=%d.%d", + DROPBEAR_EPKA_VERSION_MAJOR, DROPBEAR_EPKA_VERSION_MINOR, + svr_ses.epka_instance->api_version[0], svr_ses.epka_instance->api_version[1]); + } + if (svr_ses.epka_instance->api_version[1] > DROPBEAR_EPKA_VERSION_MINOR) { + dropbear_log(LOG_WARNING, "plugin API newer than dropbear API: " + "Dropbear=%d.%d, plugin=%d.%d", + DROPBEAR_EPKA_VERSION_MAJOR, DROPBEAR_EPKA_VERSION_MINOR, + svr_ses.epka_instance->api_version[0], svr_ses.epka_instance->api_version[1]); + } + dropbear_log(LOG_INFO, "successfully loaded and initialized pubkey plugin '%s'", svr_opts.pubkey_plugin); + } +#endif + + svr_authinitialise(); + chaninitialise(svr_chantypes); + svr_chansessinitialise(); + svr_algos_initialise(); + get_socket_address(ses.sock_in, NULL, NULL, &svr_ses.remotehost, NULL, 1); @@ -151,6 +209,13 @@ void svr_dropbear_exit(int exitcode, const char* format, va_list param) { char fullmsg[300]; int i; +#if DROPBEAR_EPKA + if ((ses.epka_session != NULL)) { + svr_ses.epka_instance->delete_session(ses.epka_session); + } + ses.epka_session = NULL; +#endif + /* Render the formatted exit message */ vsnprintf(exitmsg, sizeof(exitmsg), format, param); |