forked from osmocom/wireshark
sshdump: add capability to use doas on remote host
parent
f6e6853dc4
commit
455b9a470f
|
@ -26,11 +26,17 @@ sshdump - Provide interfaces to capture from a remote host through SSH using a r
|
|||
[ *--remote-port*=<TCP port> ]
|
||||
[ *--remote-username*=<username> ]
|
||||
[ *--remote-password*=<password> ]
|
||||
[ *--sshkey*=<public key path> ]
|
||||
[ *--sshkey*=<private key path> ]
|
||||
[ *--sshkey-passphrase*=<private key passphrase> ]
|
||||
[ *--proxycommand*=<SSH proxy command> ]
|
||||
[ *--remote-interface*=<interface> ]
|
||||
[ *--remote-capture-command-select*=<capture command selection> ]
|
||||
[ *--remote-capture-command*=<capture command> ]
|
||||
[ *--remote-sudo* ]
|
||||
[ *--remote-priv*=<privilege elevation command selection> ]
|
||||
[ *--remote-priv-user*=<privileged user name> ]
|
||||
[ *--remote-noprom* ]
|
||||
[ *--remote-filter*=<remote capture filter> ]
|
||||
[ *--remote-count*=<number> ]
|
||||
|
||||
[manarg]
|
||||
*sshdump*
|
||||
|
@ -128,6 +134,14 @@ List DLTs of specified interface.
|
|||
List configuration options of specified interface.
|
||||
--
|
||||
|
||||
--extcap-capture-filter=<capture filter>::
|
||||
+
|
||||
--
|
||||
The capture filter. It corresponds to the value provided via the *tshark -f*
|
||||
option, and the Capture Filter field next to the interfaces list in the
|
||||
Wireshark interface.
|
||||
--
|
||||
|
||||
--capture::
|
||||
+
|
||||
--
|
||||
|
@ -172,6 +186,18 @@ recommended to use keyfiles with a SSH agent.
|
|||
The path to a private key for authentication. NOTE: Only OPENSSH key/value pair format is supported.
|
||||
--
|
||||
|
||||
--sshkey-passphrase=<SSH private key passphrase>::
|
||||
+
|
||||
--
|
||||
The passphrase for the private key for authentication.
|
||||
--
|
||||
|
||||
--proxycommand=<proxy command>::
|
||||
+
|
||||
--
|
||||
The command to use as proxy for the SSH connection.
|
||||
--
|
||||
|
||||
--remote-interface=<remote interface>::
|
||||
+
|
||||
--
|
||||
|
@ -204,14 +230,33 @@ When specified, this command will be used as is, options such as the capture
|
|||
filter (*--extcap-capture-filter*) will not be appended.
|
||||
--
|
||||
|
||||
--extcap-capture-filter=<capture filter>::
|
||||
--remote-priv=<privilege elevation command selection>::
|
||||
+
|
||||
--
|
||||
The capture filter. It corresponds to the value provided via the *tshark -f*
|
||||
The command to use to achieve privilege elevation to capture on the remote host. Either none, sudo or doas.
|
||||
--
|
||||
|
||||
--remote-priv-user=<privileged user name>::
|
||||
+
|
||||
--
|
||||
If a command is used to achieve privilege elevation to capture on the remote host this may require a user name.
|
||||
If needed use this option to give that user name.
|
||||
--
|
||||
|
||||
--remote-filter=<capture filter>::
|
||||
+
|
||||
--
|
||||
The remote capture filter. It corresponds to the value provided via the *tshark -f*
|
||||
option, and the Capture Filter field next to the interfaces list in the
|
||||
Wireshark interface.
|
||||
--
|
||||
|
||||
--remote-count=<number>::
|
||||
+
|
||||
--
|
||||
The number of packets to capture.
|
||||
--
|
||||
|
||||
== EXAMPLES
|
||||
|
||||
To see program arguments:
|
||||
|
@ -245,7 +290,7 @@ To see interface configuration options:
|
|||
.Example output
|
||||
arg {number=0}{call=--remote-host}{display=Remote SSH server address}{type=string}
|
||||
{tooltip=The remote SSH host. It can be both an IP address or a hostname}{required=true}{group=Server}
|
||||
arg {number=1}{call=--remote-port}{display=Remote SSH server port}{type=unsigned}
|
||||
arg {number=1}{call=--remote-port}{display=Remote SSH server port}{type=unsigned}{default=22}
|
||||
{tooltip=The remote SSH host port (1-65535)}{range=1,65535}{group=Server}
|
||||
arg {number=2}{call=--remote-username}{display=Remote SSH server username}{type=string}
|
||||
{tooltip=The remote SSH username. If not provided, the current user will be used}{group=Authentication}
|
||||
|
@ -266,21 +311,26 @@ To see interface configuration options:
|
|||
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=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=11}{call=--remote-noprom}{display=No promiscuous mode}{type=boolflag}
|
||||
arg {number=10}{call=--remote-priv}{display=Gain capture privilege on the remote machine}{type=radio}
|
||||
{tooltip=Optionally prepend the capture command with sudo or doas on the remote machine}{group=Capture}
|
||||
value {arg=10}{value=none}{display=none}{default=true}
|
||||
value {arg=10}{value=sudo}{display=sudo}
|
||||
value {arg=10}{value=doas -n}{display=doas}
|
||||
arg {number=11}{call=--remote-priv-user}{display=Privileged user name for sudo or doas}{type=string}
|
||||
{tooltip=User name of privileged user to execute the capture command on the remote machine}{group=Capture}
|
||||
arg {number=12}{call=--remote-noprom}{display=No promiscuous mode}{type=boolflag}
|
||||
{tooltip=Don't use promiscuous mode on the remote machine}{group=Capture}
|
||||
arg {number=12}{call=--remote-filter}{display=Remote capture filter}{type=string}
|
||||
arg {number=13}{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=13}{call=--remote-count}{display=Packets to capture}{type=unsigned}{default=0}
|
||||
arg {number=14}{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=14}{call=--log-level}{display=Set the log level}{type=selector}
|
||||
arg {number=15}{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}
|
||||
arg {number=16}{call=--log-file}{display=Use a file for logging}{type=fileselect}
|
||||
{tooltip=Set a file where log messages are written}{required=false}{group=Debug}
|
||||
|
||||
|
||||
|
@ -291,6 +341,10 @@ To capture:
|
|||
|
||||
To use different capture binaries:
|
||||
|
||||
sshdump --extcap-interface=sshdump --fifo=/tmp/ssh.pcap --capture --remote-host 192.168.1.10
|
||||
--remote-username user --remote-priv sudo --remote-capture-command-select tcpdump
|
||||
--remote-interface eth0 --remote-noprom
|
||||
|
||||
sshdump --extcap-interface=sshdump --fifo=/tmp/ssh.pcap --capture --remote-host 192.168.1.10
|
||||
--remote-capture-command='dumpcap -i eth0 -P -w -'
|
||||
|
||||
|
|
23
epan/prefs.c
23
epan/prefs.c
|
@ -6016,16 +6016,27 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_,
|
|||
} else if (strcmp(pref_name, "name_resolve_suppress_smi_errors") == 0) {
|
||||
pref = prefs_find_preference(nameres_module, "suppress_smi_errors");
|
||||
}
|
||||
} else if (strcmp(module->name, "extcap") == 0) {
|
||||
/* Handle the old "sshdump.remotesudo" preference; map it to the new
|
||||
"sshdump.remotepriv" preference, and map the boolean values to the
|
||||
appropriate strings of the new preference. */
|
||||
if (strcmp(dotp, "sshdump.remotesudo") == 0) {
|
||||
pref = prefs_find_preference(module, "sshdump.remotepriv");
|
||||
if (g_ascii_strcasecmp(value, "true") == 0)
|
||||
value = "sudo";
|
||||
else
|
||||
value = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pref == NULL ) {
|
||||
if (strcmp(module->name, "extcap") == 0 && g_list_length(module->prefs) <= 1) {
|
||||
/*
|
||||
* Assume that we've skipped extcap preference registration
|
||||
* and that only extcap.gui_save_on_start is loaded.
|
||||
*/
|
||||
return PREFS_SET_OK;
|
||||
}
|
||||
/*
|
||||
* Assume that we've skipped extcap preference registration
|
||||
* and that only extcap.gui_save_on_start is loaded.
|
||||
*/
|
||||
return PREFS_SET_OK;
|
||||
}
|
||||
return PREFS_SET_NO_SUCH_PREF; /* no such preference */
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ static gchar* sshdump_extcap_interface;
|
|||
#endif
|
||||
|
||||
#define SSHDUMP_VERSION_MAJOR "1"
|
||||
#define SSHDUMP_VERSION_MINOR "1"
|
||||
#define SSHDUMP_VERSION_MINOR "2"
|
||||
#define SSHDUMP_VERSION_RELEASE "0"
|
||||
|
||||
#define SSH_READ_BLOCK_SIZE 256
|
||||
|
@ -58,7 +58,9 @@ enum {
|
|||
OPT_SSHKEY_PASSPHRASE,
|
||||
OPT_PROXYCOMMAND,
|
||||
OPT_REMOTE_COUNT,
|
||||
OPT_REMOTE_SUDO,
|
||||
OPT_REMOTE_SUDO, // Deprecated
|
||||
OPT_REMOTE_PRIV,
|
||||
OPT_REMOTE_PRIV_USER,
|
||||
OPT_REMOTE_NOPROM
|
||||
};
|
||||
|
||||
|
@ -69,7 +71,9 @@ static struct ws_option longopts[] = {
|
|||
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-sudo", ws_no_argument, NULL, OPT_REMOTE_SUDO }, // Deprecated
|
||||
{ "remote-priv", ws_required_argument, NULL, OPT_REMOTE_PRIV },
|
||||
{ "remote-priv-user", ws_required_argument, NULL, OPT_REMOTE_PRIV_USER },
|
||||
{ "remote-noprom", ws_no_argument, NULL, OPT_REMOTE_NOPROM },
|
||||
{ 0, 0, 0, 0}
|
||||
};
|
||||
|
@ -130,7 +134,7 @@ static char* local_interfaces_to_filter(const guint16 remote_port)
|
|||
}
|
||||
|
||||
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* capture_command, const char* privilege, gboolean noprom,
|
||||
const char* iface, const char* cfilter, const guint32 count)
|
||||
{
|
||||
gchar* cmdline = NULL;
|
||||
|
@ -175,7 +179,7 @@ static ssh_channel run_ssh_command(ssh_session sshs, const char* capture_command
|
|||
count_str = ws_strdup_printf("-c %u", count);
|
||||
|
||||
cmdline = ws_strdup_printf("%s tcpdump -U %s%s %s -w - %s %s",
|
||||
use_sudo ? "sudo" : "",
|
||||
privilege,
|
||||
quoted_iface ? "-i " : "",
|
||||
quoted_iface ? quoted_iface : "",
|
||||
noprom ? "-p" : "",
|
||||
|
@ -196,7 +200,7 @@ static ssh_channel run_ssh_command(ssh_session sshs, const char* capture_command
|
|||
count_str = ws_strdup_printf("-c %u", count);
|
||||
|
||||
cmdline = ws_strdup_printf("%s dumpcap %s %s -w - %s -f %s",
|
||||
use_sudo ? "sudo" : "",
|
||||
privilege,
|
||||
noprom ? "-p" : "",
|
||||
*ifaces ? ifaces : "",
|
||||
count_str ? count_str : "",
|
||||
|
@ -223,7 +227,7 @@ 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_select, const char* capture_command, const gboolean use_sudo,
|
||||
const char* capture_command_select, const char* capture_command, const char* privilege,
|
||||
gboolean noprom, const guint32 count, const char* fifo)
|
||||
{
|
||||
ssh_session sshs = NULL;
|
||||
|
@ -248,7 +252,7 @@ static int ssh_open_remote_connection(const ssh_params_t* params, const char* if
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
channel = run_ssh_command(sshs, capture_command_select, capture_command, use_sudo, noprom, iface, cfilter, count);
|
||||
channel = run_ssh_command(sshs, capture_command_select, capture_command, privilege, noprom, iface, cfilter, count);
|
||||
|
||||
if (!channel) {
|
||||
ws_warning("Can't run ssh command.");
|
||||
|
@ -323,7 +327,7 @@ static int list_config(char *interface, unsigned int remote_port)
|
|||
"{type=string}{tooltip=The remote SSH host. It can be both "
|
||||
"an IP address or a hostname}{required=true}{group=Server}\n", inc++);
|
||||
printf("arg {number=%u}{call=--remote-port}{display=Remote SSH server port}"
|
||||
"{type=unsigned}{tooltip=The remote SSH host port (1-65535)}"
|
||||
"{type=unsigned}{default=22}{tooltip=The remote SSH host port (1-65535)}"
|
||||
"{range=1,65535}{group=Server}\n", inc++);
|
||||
printf("arg {number=%u}{call=--remote-username}{display=Remote SSH server username}"
|
||||
"{type=string}{tooltip=The remote SSH username. If not provided, "
|
||||
|
@ -350,8 +354,18 @@ static int list_config(char *interface, unsigned int remote_port)
|
|||
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}"
|
||||
"{type=boolflag}{tooltip=Prepend the capture command with sudo on the remote machine}"
|
||||
// Deprecated
|
||||
//printf("arg {number=%u}{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}\n", inc++);
|
||||
printf("arg {number=%u}{call=--remote-priv}{display=Gain capture privilege on the remote machine}"
|
||||
"{type=radio}{tooltip=Optionally prepend the capture command with sudo or doas on the remote machine}"
|
||||
"{group=Capture}\n", inc);
|
||||
printf("value {arg=%u}{value=none}{display=none}{default=true}\n", inc);
|
||||
printf("value {arg=%u}{value=sudo}{display=sudo}\n", inc);
|
||||
printf("value {arg=%u}{value=doas -n}{display=doas}\n", inc++);
|
||||
printf("arg {number=%u}{call=--remote-priv-user}{display=Privileged user name for sudo or doas}"
|
||||
"{type=string}{tooltip=User name of privileged user to execute the capture command on the remote machine}"
|
||||
"{group=Capture}\n", inc++);
|
||||
printf("arg {number=%u}{call=--remote-noprom}{display=No promiscuous mode}"
|
||||
"{type=boolflag}{tooltip=Don't use promiscuous mode on the remote machine}{group=Capture}"
|
||||
|
@ -401,7 +415,8 @@ int main(int argc, char *argv[])
|
|||
extcap_parameters* extcap_conf = g_new0(extcap_parameters, 1);
|
||||
char* help_url;
|
||||
char* help_header = NULL;
|
||||
gboolean use_sudo = FALSE;
|
||||
char* priv = NULL;
|
||||
char* priv_user = NULL;
|
||||
gboolean noprom = FALSE;
|
||||
gchar* interface_description = g_strdup("SSH remote capture");
|
||||
|
||||
|
@ -461,7 +476,9 @@ int main(int argc, char *argv[])
|
|||
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-sudo", "use sudo on the remote machine to capture"); // Deprecated
|
||||
extcap_help_add_option(extcap_conf, "--remote-priv <selection>", "none, sudo or doas");
|
||||
extcap_help_add_option(extcap_conf, "--remote-priv-user <username>", "privileged user name");
|
||||
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-count <count>", "the number of packets to capture");
|
||||
|
@ -543,7 +560,19 @@ int main(int argc, char *argv[])
|
|||
break;
|
||||
|
||||
case OPT_REMOTE_SUDO:
|
||||
use_sudo = TRUE;
|
||||
// Deprecated
|
||||
g_free(priv);
|
||||
priv = g_strdup("sudo");
|
||||
break;
|
||||
|
||||
case OPT_REMOTE_PRIV:
|
||||
g_free(priv);
|
||||
priv = g_strdup(ws_optarg);
|
||||
break;
|
||||
|
||||
case OPT_REMOTE_PRIV_USER:
|
||||
g_free(priv_user);
|
||||
priv_user = g_strdup(ws_optarg);
|
||||
break;
|
||||
|
||||
case OPT_REMOTE_FILTER:
|
||||
|
@ -597,17 +626,30 @@ int main(int argc, char *argv[])
|
|||
|
||||
if (extcap_conf->capture) {
|
||||
char* filter;
|
||||
char* privilege;
|
||||
|
||||
if (!ssh_params->host) {
|
||||
ws_warning("Missing parameter: --remote-host");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((priv) && g_strcmp0(priv, "none") && strlen(g_strstrip(priv))) {
|
||||
if ((priv_user) && strlen(g_strstrip(priv_user)))
|
||||
/* Both sudo and doas use the same command line option */
|
||||
privilege = g_strconcat(priv, " -u ", priv_user, NULL);
|
||||
else
|
||||
privilege = g_strdup(priv);
|
||||
} else {
|
||||
privilege = g_strdup("");
|
||||
}
|
||||
|
||||
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_select, remote_capture_command,
|
||||
use_sudo, noprom, count, extcap_conf->fifo);
|
||||
privilege, noprom, count, extcap_conf->fifo);
|
||||
g_free(filter);
|
||||
g_free(privilege);
|
||||
} else {
|
||||
ws_debug("You should not come here... maybe some parameter missing?");
|
||||
ret = EXIT_FAILURE;
|
||||
|
@ -620,6 +662,8 @@ end:
|
|||
g_free(remote_capture_command);
|
||||
g_free(remote_interface);
|
||||
g_free(remote_filter);
|
||||
g_free(priv);
|
||||
g_free(priv_user);
|
||||
extcap_base_cleanup(&extcap_conf);
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue