diff options
author | Dario Lombardo <lomato@gmail.com> | 2016-03-01 14:13:41 +0100 |
---|---|---|
committer | Roland Knall <rknall@gmail.com> | 2016-03-04 07:14:09 +0000 |
commit | d8f541c89b94ae0fe6233bd93dbd0d910a65ccdd (patch) | |
tree | 29f1d6b486240c321848ddae964a1145f82d1e0b | |
parent | 68d4ba212c839631c639974b36fc283a9e90bc5e (diff) | |
download | wireshark-d8f541c89b94ae0fe6233bd93dbd0d910a65ccdd.tar.gz |
extcap: move ssh common functions to ssh-base.
Change-Id: Ic06882a4f914b4f89d936d5d942b50552ae4abb3
Reviewed-on: https://code.wireshark.org/review/14264
Petri-Dish: Roland Knall <rknall@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Roland Knall <rknall@gmail.com>
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | extcap/Makefile.common | 6 | ||||
-rw-r--r-- | extcap/Makefile.nmake | 4 | ||||
-rw-r--r-- | extcap/ssh-base.c | 162 | ||||
-rw-r--r-- | extcap/ssh-base.h | 50 | ||||
-rw-r--r-- | extcap/sshdump.c | 133 |
6 files changed, 227 insertions, 129 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f722b8234..d0052d0162 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2391,6 +2391,7 @@ if(BUILD_sshdump AND LIBSSH_FOUND) set(sshdump_FILES extcap/sshdump.c extcap/extcap-base.c + extcap/ssh-base.c ) add_executable(sshdump WIN32 ${sshdump_FILES}) diff --git a/extcap/Makefile.common b/extcap/Makefile.common index 345872f832..22ca1dc7b3 100644 --- a/extcap/Makefile.common +++ b/extcap/Makefile.common @@ -34,7 +34,9 @@ randpktdump_SOURCES = \ # sshdump specifics sshdump_SOURCES = \ sshdump.c \ - extcap-base.c + extcap-base.c \ + ssh-base.c noinst_HEADERS = \ - extcap-base.h + extcap-base.h \ + ssh-base.h diff --git a/extcap/Makefile.nmake b/extcap/Makefile.nmake index 52d35c7c73..6fffad7599 100644 --- a/extcap/Makefile.nmake +++ b/extcap/Makefile.nmake @@ -88,10 +88,10 @@ randpktdump.exe : $(LIBS_CHECK) ..\config.h randpktdump.obj extcap-base.obj $(ra !ENDIF !IFDEF LIBSSH_DIR -sshdump.exe : $(LIBS_CHECK) ..\config.h sshdump.obj extcap-base.obj $(sshdump_WSLIBS) +sshdump.exe : $(LIBS_CHECK) ..\config.h sshdump.obj extcap-base.obj ssh-base.obj $(sshdump_WSLIBS) @echo Linking $@ $(LINK) @<< - /OUT:sshdump.exe $(conflags) $(conlibsdll) $(LDFLAGS) /SUBSYSTEM:WINDOWS sshdump.obj extcap-base.obj $(sshdump_LIBS) + /OUT:sshdump.exe $(conflags) $(conlibsdll) $(LDFLAGS) /SUBSYSTEM:WINDOWS sshdump.obj extcap-base.obj ssh-base.obj $(sshdump_LIBS) << !IFDEF MANIFEST_INFO_REQUIRED mt.exe -nologo -manifest "sshdump.exe.manifest" -outputresource:sshdump.exe;1 diff --git a/extcap/ssh-base.c b/extcap/ssh-base.c new file mode 100644 index 0000000000..10fefd2577 --- /dev/null +++ b/extcap/ssh-base.c @@ -0,0 +1,162 @@ +/* ssh-base.c + * ssh-base has base utility functions to connect to hosts via ssh + * + * Copyright 2016, Dario Lombardo + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "ssh-base.h" + +#include <extcap/extcap-base.h> +#include <log.h> + +#define verbose_print(...) { if (verbose) printf(__VA_ARGS__); } + +ssh_session create_ssh_connection(const char* hostname, const unsigned int port, const char* username, + const char* password, const char* sshkey_path, const char* sshkey_passphrase, char** err_info) +{ + ssh_session sshs; + + /* Open session and set options */ + sshs = ssh_new(); + if (sshs == NULL) { + *err_info = g_strdup_printf("Can't create ssh session"); + return NULL; + } + + if (!hostname) { + *err_info = g_strdup_printf("Hostname needed"); + goto failure; + } + + if (ssh_options_set(sshs, SSH_OPTIONS_HOST, hostname)) { + *err_info = g_strdup_printf("Can't set the hostname: %s", hostname); + goto failure; + } + + if (port != 0) { + if (ssh_options_set(sshs, SSH_OPTIONS_PORT, &port)) { + *err_info = g_strdup_printf("Can't set the port: %d", port); + goto failure; + } + } + + if (!username) + username = g_get_user_name(); + + if (ssh_options_set(sshs, SSH_OPTIONS_USER, username)) { + *err_info = g_strdup_printf("Can't set the username: %s", username); + goto failure; + } + + g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "Opening ssh connection to %s@%s:%u", username, hostname, port); + + /* Connect to server */ + if (ssh_connect(sshs) != SSH_OK) { + *err_info = g_strdup_printf("Error connecting to %s@%s:%u (%s)", username, hostname, port, + ssh_get_error(sshs)); + goto failure; + } + +#ifdef HAVE_LIBSSH_USERAUTH_AGENT + g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, ("Connecting using ssh-agent..."); + /* Try to authenticate using ssh agent */ + if (ssh_userauth_agent(sshs, NULL) == SSH_AUTH_SUCCESS) { + g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "done"); + return sshs; + } + g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, ("failed"); +#endif + + /* If a public key path has been provided, try to authenticate using it */ + if (sshkey_path) { + ssh_key pkey = ssh_key_new(); + int ret; + + g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "Connecting using public key in %s...", sshkey_path); + ret = ssh_pki_import_privkey_file(sshkey_path, sshkey_passphrase, NULL, NULL, &pkey); + + if (ret == SSH_OK) { + if (ssh_userauth_publickey(sshs, NULL, pkey) == SSH_AUTH_SUCCESS) { + g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "done"); + ssh_key_free(pkey); + return sshs; + } + } + ssh_key_free(pkey); + g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "failed (%s)", ssh_get_error(sshs)); + } + + /* Try to authenticate using standard public key */ + g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "Connecting using standard public key..."); + if (ssh_userauth_publickey_auto(sshs, NULL, NULL) == SSH_AUTH_SUCCESS) { + g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "done"); + return sshs; + } + g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "failed"); + + /* If a password has been provided and all previous attempts failed, try to use it */ + if (password) { + g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "Connecting using password..."); + if (ssh_userauth_password(sshs, username, password) == SSH_AUTH_SUCCESS) { + g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "done"); + return sshs; + } + g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "failed"); + } + + *err_info = g_strdup_printf("Can't find a valid authentication. Disconnecting."); + + /* All authentication failed. Disconnect and return */ + ssh_disconnect(sshs); + +failure: + ssh_free(sshs); + return NULL; +} + +void ssh_cleanup(ssh_session* sshs, ssh_channel* channel) +{ + if (*channel) { + ssh_channel_send_eof(*channel); + ssh_channel_close(*channel); + ssh_channel_free(*channel); + *channel = NULL; + } + + if (*sshs) { + ssh_disconnect(*sshs); + ssh_free(*sshs); + *sshs = NULL; + } +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: t + * End: + * + * vi: set shiftwidth=8 tabstop=8 noexpandtab: + * :indentSize=8:tabSize=8:noTabs=false: + */
\ No newline at end of file diff --git a/extcap/ssh-base.h b/extcap/ssh-base.h new file mode 100644 index 0000000000..07c3e3305a --- /dev/null +++ b/extcap/ssh-base.h @@ -0,0 +1,50 @@ +/* ssh-base.h + * ssh-base has base utility functions to connect to hosts via ssh + * + * Copyright 2016, Dario Lombardo + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __SSHBASE_H__ +#define __SSHBASE_H__ + +#include <libssh/libssh.h> + +/* Create a ssh connection using all the possible authentication menthods */ +ssh_session create_ssh_connection(const char* hostname, const unsigned int port, const char* username, + const char* password, const char* sshkey_path, const char* sshkey_passphrase, char** err_info); + +/* Clean the current ssh session and channel. */ +void ssh_cleanup(ssh_session* sshs, ssh_channel* channel); + +#endif + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: t + * End: + * + * vi: set shiftwidth=8 tabstop=8 noexpandtab: + * :indentSize=8:tabSize=8:noTabs=false: + */
\ No newline at end of file diff --git a/extcap/sshdump.c b/extcap/sshdump.c index f0055fc40e..814328c1ab 100644 --- a/extcap/sshdump.c +++ b/extcap/sshdump.c @@ -26,18 +26,11 @@ #include <extcap/extcap-base.h> #include <wsutil/interface.h> +#include <extcap/ssh-base.h> -#include <glib/gstdio.h> -#include <stdio.h> -#include <stdint.h> -#include <stdarg.h> #include <errno.h> -#include <time.h> #include <string.h> -#include <sys/types.h> -#include <sys/stat.h> #include <fcntl.h> -#include <libssh/libssh.h> #ifndef STDERR_FILENO #define STDERR_FILENO 2 @@ -97,121 +90,6 @@ static struct option longopts[] = { static char* interfaces_list_to_filter(GSList* if_list, const unsigned int remote_port); -static void ssh_cleanup(ssh_session sshs, ssh_channel channel) -{ - if (channel) { - ssh_channel_send_eof(channel); - ssh_channel_close(channel); - ssh_channel_free(channel); - } - - if (sshs) { - ssh_disconnect(sshs); - ssh_free(sshs); - } -} - -static ssh_session create_ssh_connection(const char* hostname, const unsigned int port, const char* username, - const char* password, const char* sshkey_path, const char* sshkey_passphrase) -{ - ssh_session sshs; - - /* Open session and set options */ - sshs = ssh_new(); - if (sshs == NULL) { - errmsg_print("Can't create ssh session"); - return NULL; - } - - if (!hostname) - return NULL; - - if (ssh_options_set(sshs, SSH_OPTIONS_HOST, hostname)) { - errmsg_print("Can't set the hostname: %s", hostname); - goto failure; - } - - if (port != 0) { - if (ssh_options_set(sshs, SSH_OPTIONS_PORT, &port)) { - errmsg_print("Can't set the port: %d", port); - goto failure; - } - } - - if (!username) - username = g_get_user_name(); - - if (ssh_options_set(sshs, SSH_OPTIONS_USER, username)) { - errmsg_print("Can't set the username: %s", username); - goto failure; - } - - verbose_print("Opening ssh connection to %s@%s:%u", username, hostname, port); - - /* Connect to server */ - if (ssh_connect(sshs) != SSH_OK) { - errmsg_print("Error connecting to %s@%s:%u (%s)", username, hostname, port, - ssh_get_error(sshs)); - goto failure; - } - -#ifdef HAVE_LIBSSH_USERAUTH_AGENT - verbose_print("Connecting using ssh-agent..."); - /* Try to authenticate using ssh agent */ - if (ssh_userauth_agent(sshs, NULL) == SSH_AUTH_SUCCESS) { - verbose_print("done\n"); - return sshs; - } - verbose_print("failed\n"); -#endif - - /* If a public key path has been provided, try to authenticate using it */ - if (sshkey_path) { - ssh_key pkey = ssh_key_new(); - int ret; - - verbose_print("Connecting using public key in %s...", sshkey_path); - ret = ssh_pki_import_privkey_file(sshkey_path, sshkey_passphrase, NULL, NULL, &pkey); - - if (ret == SSH_OK) { - if (ssh_userauth_publickey(sshs, NULL, pkey) == SSH_AUTH_SUCCESS) { - verbose_print("done\n"); - ssh_key_free(pkey); - return sshs; - } - } - ssh_key_free(pkey); - verbose_print("failed (%s)\n", ssh_get_error(sshs)); - } - - /* Try to authenticate using standard public key */ - verbose_print("Connecting using standard public key..."); - if (ssh_userauth_publickey_auto(sshs, NULL, NULL) == SSH_AUTH_SUCCESS) { - verbose_print("done\n"); - return sshs; - } - verbose_print("failed\n"); - - /* If a password has been provided and all previous attempts failed, try to use it */ - if (password) { - verbose_print("Connecting using password..."); - if (ssh_userauth_password(sshs, username, password) == SSH_AUTH_SUCCESS) { - verbose_print("done\n"); - return sshs; - } - verbose_print("failed\n"); - } - - errmsg_print("Can't find a valid authentication. Disconnecting."); - - /* All authentication failed. Disconnect and return */ - ssh_disconnect(sshs); - -failure: - ssh_free(sshs); - return NULL; -} - static void ssh_loop_read(ssh_channel channel, int fd) { int nbytes; @@ -314,6 +192,7 @@ static int ssh_open_remote_connection(const char* hostname, const unsigned int p ssh_channel channel = NULL; int fd = STDOUT_FILENO; int ret = EXIT_FAILURE; + char* err_info = NULL; if (g_strcmp0(fifo, "-")) { /* Open or create the output file */ @@ -327,7 +206,7 @@ static int ssh_open_remote_connection(const char* hostname, const unsigned int p } } - sshs = create_ssh_connection(hostname, port, username, password, sshkey, sshkey_passphrase); + sshs = create_ssh_connection(hostname, port, username, password, sshkey, sshkey_passphrase, &err_info); if (!sshs) goto cleanup; @@ -341,8 +220,12 @@ static int ssh_open_remote_connection(const char* hostname, const unsigned int p ret = EXIT_SUCCESS; cleanup: + if (err_info) + errmsg_print("%s", err_info); + g_free(err_info); + /* clean up and exit */ - ssh_cleanup(sshs, channel); + ssh_cleanup(&sshs, &channel); if (g_strcmp0(fifo, "-")) close(fd); |