forked from osmocom/wireshark
sshdump: add option to select dumpcap as remote capture command
parent
af558f672b
commit
34ab3f308a
|
@ -28,6 +28,7 @@ sshdump - Provide interfaces to capture from a remote host through SSH using a r
|
|||
[ *--remote-password*=<password> ]
|
||||
[ *--sshkey*=<public key path> ]
|
||||
[ *--remote-interface*=<interface> ]
|
||||
[ *--remote-capture-command-select*=<capture command selection> ]
|
||||
[ *--remote-capture-command*=<capture command> ]
|
||||
[ *--remote-sudo* ]
|
||||
|
||||
|
@ -154,7 +155,7 @@ The SSH port of the remote host.
|
|||
--remote-username=<username>::
|
||||
+
|
||||
--
|
||||
The username for ssh authentication.
|
||||
The username for SSH authentication.
|
||||
--
|
||||
|
||||
--remote-password=<password>::
|
||||
|
@ -177,6 +178,17 @@ The path to a private key for authentication. NOTE: Only OPENSSH key/value pair
|
|||
The remote network interface to capture from.
|
||||
--
|
||||
|
||||
--remote-capture-command-select=<capture command-selection>::
|
||||
+
|
||||
--
|
||||
The selection of the build-in support for remote capture commands. Either *dumpcap* for a remote
|
||||
capture command using dumpcap, *tcpdump* for a remote capture command using tcpdump, or *other*,
|
||||
where the remote capture command is to be given with the *--remote-capture-command* option.
|
||||
|
||||
Note that selecting dumpcap allows for specifying multiple capture interfaces as a whitespace
|
||||
seperated list, while tcpdump does not.
|
||||
--
|
||||
|
||||
--remote-capture-command=<capture command>::
|
||||
+
|
||||
--
|
||||
|
@ -240,27 +252,37 @@ To see interface configuration options:
|
|||
arg {number=3}{call=--remote-password}{display=Remote SSH server password}{type=password}
|
||||
{tooltip=The SSH password, used when other methods (SSH agent or key files) are unavailable.}{group=Authentication}
|
||||
arg {number=4}{call=--sshkey}{display=Path to SSH private key}{type=fileselect}
|
||||
{tooltip=The path on the local filesystem of the private ssh key}{group=Authentication}
|
||||
{tooltip=The path on the local filesystem of the private SSH key (OpenSSH format)}{mustexist=true}{group=Authentication}
|
||||
arg {number=5}{call=--sshkey-passphrase}{display=SSH key passphrase}{type=password}
|
||||
{tooltip=Passphrase to unlock the SSH private key}{group=Authentication (OPENSSH format)}
|
||||
{tooltip=Passphrase to unlock the SSH private key}{group=Authentication}
|
||||
arg {number=6}{call=--proxycommand}{display=ProxyCommand}{type=string}
|
||||
{tooltip=The command to use as proxy for the SSH connection}{group=Authentication}
|
||||
arg {number=7}{call=--remote-interface}{display=Remote interface}{type=string}
|
||||
{tooltip=The remote network interface used for capture}{group=Capture}
|
||||
arg {number=8}{call=--remote-capture-command}{display=Remote capture command}{type=string}
|
||||
arg {number=8}{call=--remote-capture-command-select}{display=Remote capture command selection}{type=radio}
|
||||
{tooltip=The remote capture command to build a command line for}{group=Capture}
|
||||
value {arg=8}{value=dumpcap}{display=dumpcap}
|
||||
value {arg=8}{value=tcpdump}{display=tcpdump}{default=true}
|
||||
value {arg=8}{value=other}{display=Other:}
|
||||
arg {number=9}{call=--remote-capture-command}{display=Remote capture command}{type=string}
|
||||
{tooltip=The remote command used to capture}{group=Capture}
|
||||
arg {number=9}{call=--remote-sudo}{display=Use sudo on the remote machine}{type=boolean}
|
||||
arg {number=10}{call=--remote-sudo}{display=Use sudo on the remote machine}{type=boolflag}
|
||||
{tooltip=Prepend the capture command with sudo on the remote machine}{group=Capture}
|
||||
arg {number=10}{call=--remote-noprom}{display=No promiscuous mode}{type=boolflag}
|
||||
arg {number=11}{call=--remote-noprom}{display=No promiscuous mode}{type=boolflag}
|
||||
{tooltip=Don't use promiscuous mode on the remote machine}{group=Capture}
|
||||
arg {number=11}{call=--remote-filter}{display=Remote capture filter}{type=string}
|
||||
arg {number=12}{call=--remote-filter}{display=Remote capture filter}{type=string}
|
||||
{tooltip=The remote capture filter}{default=not ((host myhost) and port 22)}{group=Capture}
|
||||
arg {number=12}{call=--remote-count}{display=Packets to capture}{type=unsigned}{default=0}
|
||||
arg {number=13}{call=--remote-count}{display=Packets to capture}{type=unsigned}{default=0}
|
||||
{tooltip=The number of remote packets to capture. (Default: inf)}{group=Capture}
|
||||
arg {number=13}{call=--debug}{display=Run in debug mode}{type=boolflag}{default=false}
|
||||
{tooltip=Print debug messages}{required=false}{group=Debug}
|
||||
arg {number=14}{call=--debug-file}{display=Use a file for debug}{type=string}
|
||||
{tooltip=Set a file where the debug messages are written}{required=false}{group=Debug}
|
||||
arg {number=14}{call=--log-level}{display=Set the log level}{type=selector}
|
||||
{tooltip=Set the log level}{required=false}{group=Debug}
|
||||
value {arg=14}{value=message}{display=Message}{default=true}
|
||||
value {arg=14}{value=info}{display=Info}
|
||||
value {arg=14}{value=debug}{display=Debug}
|
||||
value {arg=14}{value=noisy}{display=Noisy}
|
||||
arg {number=15}{call=--log-file}{display=Use a file for logging}{type=fileselect}
|
||||
{tooltip=Set a file where log messages are written}{required=false}{group=Debug}
|
||||
|
||||
|
||||
To capture:
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ static gchar* sshdump_extcap_interface;
|
|||
#endif
|
||||
|
||||
#define SSHDUMP_VERSION_MAJOR "1"
|
||||
#define SSHDUMP_VERSION_MINOR "0"
|
||||
#define SSHDUMP_VERSION_MINOR "1"
|
||||
#define SSHDUMP_VERSION_RELEASE "0"
|
||||
|
||||
#define SSH_READ_BLOCK_SIZE 256
|
||||
|
@ -51,6 +51,7 @@ enum {
|
|||
OPT_REMOTE_USERNAME,
|
||||
OPT_REMOTE_PASSWORD,
|
||||
OPT_REMOTE_INTERFACE,
|
||||
OPT_REMOTE_CAPTURE_COMMAND_SELECT,
|
||||
OPT_REMOTE_CAPTURE_COMMAND,
|
||||
OPT_REMOTE_FILTER,
|
||||
OPT_SSHKEY,
|
||||
|
@ -66,6 +67,7 @@ static struct ws_option longopts[] = {
|
|||
{ "help", ws_no_argument, NULL, OPT_HELP},
|
||||
{ "version", ws_no_argument, NULL, OPT_VERSION},
|
||||
SSH_BASE_OPTIONS,
|
||||
{ "remote-capture-command-select", ws_required_argument, NULL, OPT_REMOTE_CAPTURE_COMMAND_SELECT},
|
||||
{ "remote-capture-command", ws_required_argument, NULL, OPT_REMOTE_CAPTURE_COMMAND},
|
||||
{ "remote-sudo", ws_no_argument, NULL, OPT_REMOTE_SUDO },
|
||||
{ "remote-noprom", ws_no_argument, NULL, OPT_REMOTE_NOPROM },
|
||||
|
@ -127,11 +129,16 @@ static char* local_interfaces_to_filter(const guint16 remote_port)
|
|||
return filter;
|
||||
}
|
||||
|
||||
static ssh_channel run_ssh_command(ssh_session sshs, const char* capture_command, const gboolean use_sudo, gboolean noprom,
|
||||
static ssh_channel run_ssh_command(ssh_session sshs, const char* capture_command_select,
|
||||
const char* capture_command, const gboolean use_sudo, gboolean noprom,
|
||||
const char* iface, const char* cfilter, const guint32 count)
|
||||
{
|
||||
gchar* cmdline;
|
||||
ssh_channel channel;
|
||||
char** ifaces_array = NULL;
|
||||
int ifaces_array_num = 0;
|
||||
GString *ifaces_string;
|
||||
gchar *ifaces;
|
||||
char* quoted_iface = NULL;
|
||||
char* quoted_filter = NULL;
|
||||
char* count_str = NULL;
|
||||
|
@ -151,11 +158,17 @@ static ssh_channel run_ssh_command(ssh_session sshs, const char* capture_command
|
|||
|
||||
ssh_options_get_port(sshs, &remote_port);
|
||||
|
||||
if (capture_command_select == NULL || g_strcmp0(capture_command_select, "other")) {
|
||||
if (capture_command && *capture_command) {
|
||||
cmdline = g_strdup(capture_command);
|
||||
ws_debug("Remote capture command has disabled other options");
|
||||
} else {
|
||||
capture_command_select = "tcpdump";
|
||||
}
|
||||
}
|
||||
|
||||
/* escape parameters to go save with the shell */
|
||||
if (capture_command && *capture_command) {
|
||||
cmdline = g_strdup(capture_command);
|
||||
ws_debug("Remote capture command has disabled other options");
|
||||
} else {
|
||||
if (!g_strcmp0(capture_command_select, "tcpdump")) {
|
||||
quoted_iface = iface ? g_shell_quote(iface) : NULL;
|
||||
quoted_filter = g_shell_quote(cfilter ? cfilter : "");
|
||||
if (count > 0)
|
||||
|
@ -168,6 +181,29 @@ static ssh_channel run_ssh_command(ssh_session sshs, const char* capture_command
|
|||
noprom ? "-p" : "",
|
||||
count_str ? count_str : "",
|
||||
quoted_filter);
|
||||
} else if (!g_strcmp0(capture_command_select, "dumpcap")) {
|
||||
ifaces_array = g_strsplit(iface, " ", -1);
|
||||
ifaces_string = g_string_new(NULL);
|
||||
while (ifaces_array[ifaces_array_num])
|
||||
{
|
||||
quoted_iface = g_shell_quote(ifaces_array[ifaces_array_num]);
|
||||
g_string_append_printf(ifaces_string, "-i %s ", quoted_iface);
|
||||
ifaces_array_num++;
|
||||
}
|
||||
ifaces = g_string_free(ifaces_string, FALSE);
|
||||
quoted_filter = g_shell_quote(cfilter ? cfilter : "");
|
||||
if (count > 0)
|
||||
count_str = ws_strdup_printf("-c %u", count);
|
||||
|
||||
cmdline = ws_strdup_printf("%s dumpcap %s %s -w - %s %s",
|
||||
use_sudo ? "sudo" : "",
|
||||
noprom ? "-p" : "",
|
||||
*ifaces ? ifaces : "",
|
||||
count_str ? count_str : "",
|
||||
quoted_filter);
|
||||
|
||||
g_free(ifaces);
|
||||
g_strfreev(ifaces_array);
|
||||
}
|
||||
|
||||
ws_debug("Running: %s", cmdline);
|
||||
|
@ -187,7 +223,8 @@ static ssh_channel run_ssh_command(ssh_session sshs, const char* capture_command
|
|||
}
|
||||
|
||||
static int ssh_open_remote_connection(const ssh_params_t* params, const char* iface, const char* cfilter,
|
||||
const char* capture_command, const gboolean use_sudo, gboolean noprom, const guint32 count, const char* fifo)
|
||||
const char* capture_command_select, const char* capture_command, const gboolean use_sudo,
|
||||
gboolean noprom, const guint32 count, const char* fifo)
|
||||
{
|
||||
ssh_session sshs = NULL;
|
||||
ssh_channel channel = NULL;
|
||||
|
@ -211,7 +248,7 @@ static int ssh_open_remote_connection(const ssh_params_t* params, const char* if
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
channel = run_ssh_command(sshs, capture_command, use_sudo, noprom, iface, cfilter, count);
|
||||
channel = run_ssh_command(sshs, capture_command_select, capture_command, use_sudo, noprom, iface, cfilter, count);
|
||||
|
||||
if (!channel) {
|
||||
ws_warning("Can't run ssh command.");
|
||||
|
@ -295,7 +332,7 @@ static int list_config(char *interface, unsigned int remote_port)
|
|||
"{type=password}{tooltip=The SSH password, used when other methods (SSH agent "
|
||||
"or key files) are unavailable.}{group=Authentication}\n", inc++);
|
||||
printf("arg {number=%u}{call=--sshkey}{display=Path to SSH private key}"
|
||||
"{type=fileselect}{tooltip=The path on the local filesystem of the private ssh key (OPENSSH format)}"
|
||||
"{type=fileselect}{tooltip=The path on the local filesystem of the private SSH key (OpenSSH format)}"
|
||||
"{mustexist=true}{group=Authentication}\n", inc++);
|
||||
printf("arg {number=%u}{call=--sshkey-passphrase}{display=SSH key passphrase}"
|
||||
"{type=password}{tooltip=Passphrase to unlock the SSH private key}{group=Authentication}\n",
|
||||
|
@ -306,6 +343,11 @@ static int list_config(char *interface, unsigned int remote_port)
|
|||
printf("arg {number=%u}{call=--remote-interface}{display=Remote interface}"
|
||||
"{type=string}{tooltip=The remote network interface used for capture"
|
||||
"}{group=Capture}\n", inc++);
|
||||
printf("arg {number=%u}{call=--remote-capture-command-select}{display=Remote capture command selection}"
|
||||
"{type=radio}{tooltip=The remote capture command to build a command line for}{group=Capture}\n", inc);
|
||||
printf("value {arg=%u}{value=dumpcap}{display=dumpcap}\n", inc);
|
||||
printf("value {arg=%u}{value=tcpdump}{display=tcpdump}{default=true}\n", inc);
|
||||
printf("value {arg=%u}{value=other}{display=Other:}\n", inc++);
|
||||
printf("arg {number=%u}{call=--remote-capture-command}{display=Remote capture command}"
|
||||
"{type=string}{tooltip=The remote command used to capture}{group=Capture}\n", inc++);
|
||||
printf("arg {number=%u}{call=--remote-sudo}{display=Use sudo on the remote machine}"
|
||||
|
@ -351,6 +393,7 @@ int main(int argc, char *argv[])
|
|||
int option_idx = 0;
|
||||
ssh_params_t* ssh_params = ssh_params_new();
|
||||
char* remote_interface = NULL;
|
||||
char* remote_capture_command_select = NULL;
|
||||
char* remote_capture_command = NULL;
|
||||
char* remote_filter = NULL;
|
||||
guint32 count = 0;
|
||||
|
@ -412,15 +455,15 @@ int main(int argc, char *argv[])
|
|||
extcap_help_add_option(extcap_conf, "--remote-port <port>", "the remote SSH port");
|
||||
extcap_help_add_option(extcap_conf, "--remote-username <username>", "the remote SSH username");
|
||||
extcap_help_add_option(extcap_conf, "--remote-password <password>", "the remote SSH password. If not specified, ssh-agent and ssh-key are used");
|
||||
extcap_help_add_option(extcap_conf, "--sshkey <public key path>", "the path of the ssh key (OPENSSH format)");
|
||||
extcap_help_add_option(extcap_conf, "--sshkey-passphrase <public key passphrase>", "the passphrase to unlock public ssh");
|
||||
extcap_help_add_option(extcap_conf, "--proxycommand <proxy command>", "the command to use as proxy for the ssh connection");
|
||||
extcap_help_add_option(extcap_conf, "--sshkey <private key path>", "the path of the SSH key (OpenSSH format)");
|
||||
extcap_help_add_option(extcap_conf, "--sshkey-passphrase <private key passphrase>", "the passphrase to unlock private SSH key");
|
||||
extcap_help_add_option(extcap_conf, "--proxycommand <proxy command>", "the command to use as proxy for the SSH connection");
|
||||
extcap_help_add_option(extcap_conf, "--remote-interface <iface>", "the remote capture interface");
|
||||
extcap_help_add_option(extcap_conf, "--remote-capture-command-select <selection>", "dumpcap, tcpdump or other remote capture command");
|
||||
extcap_help_add_option(extcap_conf, "--remote-capture-command <capture command>", "the remote capture command");
|
||||
extcap_help_add_option(extcap_conf, "--remote-sudo", "use sudo on the remote machine to capture");
|
||||
extcap_help_add_option(extcap_conf, "--remote-noprom", "don't use promiscuous mode on the remote machine");
|
||||
extcap_help_add_option(extcap_conf, "--remote-filter <filter>", "a filter for remote capture (default: don't "
|
||||
"listen on local interfaces IPs)");
|
||||
extcap_help_add_option(extcap_conf, "--remote-filter <filter>", "a filter for remote capture (default: don't listen on local interfaces IPs)");
|
||||
extcap_help_add_option(extcap_conf, "--remote-count <count>", "the number of packets to capture");
|
||||
|
||||
ws_opterr = 0;
|
||||
|
@ -489,6 +532,11 @@ int main(int argc, char *argv[])
|
|||
remote_interface = g_strdup(ws_optarg);
|
||||
break;
|
||||
|
||||
case OPT_REMOTE_CAPTURE_COMMAND_SELECT:
|
||||
g_free(remote_capture_command_select);
|
||||
remote_capture_command_select = g_strdup(ws_optarg);
|
||||
break;
|
||||
|
||||
case OPT_REMOTE_CAPTURE_COMMAND:
|
||||
g_free(remote_capture_command);
|
||||
remote_capture_command = g_strdup(ws_optarg);
|
||||
|
@ -557,7 +605,8 @@ int main(int argc, char *argv[])
|
|||
filter = concat_filters(extcap_conf->capture_filter, remote_filter);
|
||||
ssh_params->debug = extcap_conf->debug;
|
||||
ret = ssh_open_remote_connection(ssh_params, remote_interface,
|
||||
filter, remote_capture_command, use_sudo, noprom, count, extcap_conf->fifo);
|
||||
filter, remote_capture_command_select, remote_capture_command,
|
||||
use_sudo, noprom, count, extcap_conf->fifo);
|
||||
g_free(filter);
|
||||
} else {
|
||||
ws_debug("You should not come here... maybe some parameter missing?");
|
||||
|
@ -567,6 +616,7 @@ int main(int argc, char *argv[])
|
|||
end:
|
||||
/* clean up stuff */
|
||||
ssh_params_free(ssh_params);
|
||||
g_free(remote_capture_command_select);
|
||||
g_free(remote_capture_command);
|
||||
g_free(remote_interface);
|
||||
g_free(remote_filter);
|
||||
|
|
Loading…
Reference in New Issue