#include "libcli/smb/smbXcli_base.h"
/*
- * INPUT
+ * OUTPUT
* |
- * -----> SAMBA_INPUT
+ * -----> SMBTORTURE_OUTPUT
* |
- * -----> SAMBA_INPUT_transportname1
- * -----> SAMBA_INPUT_transportname2
+ * -----> SMBTORTURE_transportname1
+ * -----> SMBTORTURE_transportname2
*/
return true;
}
-int smbrun(const char *cmd, int *outfd, char * const *env);
-
-static bool run_cmd_return_buf(TALLOC_CTX *mem_ctx,
- const char *cmd,
- int *num_lines, char ***buf)
-{
- int ret;
- int fd = -1;
-
- DEBUG(10, ("%s will call '%s'\n", __location__, cmd));
-
- ret = smbrun(cmd, &fd, NULL);
- if (ret) {
- DEBUG(1, ("%s failed to execute system call: %s: %d\n",
- __location__, cmd, ret));
- if (fd != -1) {
- close(fd);
- }
- return false;
- }
-
- *buf = fd_lines_load(fd, num_lines, 0, mem_ctx);
- if (fd != -1) {
- close(fd);
- }
- if (*buf == NULL) {
- return false;
- }
-
- return true;
-}
-
static const char *iptables_command(struct torture_context *tctx)
{
return torture_setting_string(tctx, "iptables_command",
char *escape_shell_string(const char *src);
/*
- * iptables v1.6.1: chain name `SAMBA_INPUT_tree1->session->transport'
+ * iptables v1.6.1: chain name `SMBTORTURE_INPUT_tree1->session->transport'
* too long (must be under 29 chars)
*
* maybe truncate chainname ?
return s;
}
-static bool filter_tcp_setup(struct torture_context *tctx,
- bool unblock)
+static bool iptables_setup_chain(struct torture_context *tctx,
+ const char *parent_chain,
+ const char *chain,
+ bool unblock)
{
- const char *cmd_in, *cmd_out;
const char *ipt = iptables_command(tctx);
+ const char *cmd;
if (unblock) {
- cmd_in = talloc_asprintf(tctx,
- "%s -L SAMBA_INPUT > /dev/null 2>&1 && "
- "("
- "%s -F SAMBA_INPUT; "
- "%s -D INPUT -j SAMBA_INPUT; "
- "%s -X SAMBA_INPUT;"
- ")",
- ipt, ipt, ipt, ipt);
- cmd_out = talloc_asprintf(tctx,
- "%s -L SAMBA_OUTPUT > /dev/null 2>&1 && "
+ cmd = talloc_asprintf(tctx,
+ "%s -L %s > /dev/null 2>&1 && "
"("
- "%s -F SAMBA_OUTPUT;"
- "%s -D OUTPUT -j SAMBA_OUTPUT;"
- "%s -X SAMBA_OUTPUT;"
- ")",
- ipt, ipt, ipt, ipt);
+ "%s -F %s;"
+ "%s -D %s -j %s > /dev/null 2>&1 || true;"
+ "%s -X %s;"
+ ");"
+ "%s -L %s > /dev/null 2>&1 || true;",
+ ipt, chain,
+ ipt, chain,
+ ipt, parent_chain, chain,
+ ipt, chain,
+ ipt, chain);
} else {
- cmd_in = talloc_asprintf(tctx,
- "%s -L SAMBA_INPUT > /dev/null 2>&1 || "
+ cmd = talloc_asprintf(tctx,
+ "%s -L %s > /dev/null 2>&1 || "
"("
- "%s -N SAMBA_INPUT && "
- "%s -I INPUT -j SAMBA_INPUT "
- ")",
- ipt, ipt, ipt);
- cmd_out = talloc_asprintf(tctx,
- "%s -L SAMBA_OUTPUT > /dev/null 2>&1 || "
- "("
- "%s -N SAMBA_OUTPUT && "
- "%s -I OUTPUT -j SAMBA_OUTPUT;"
- ")",
- ipt, ipt, ipt);
+ "%s -N %s && "
+ "%s -I %s -j %s;"
+ ");"
+ "%s -F %s;",
+ ipt, chain,
+ ipt, chain,
+ ipt, parent_chain, chain,
+ ipt, chain);
}
- if (cmd_in == NULL || cmd_out == NULL) {
- return false;
- }
-
- if (!run_cmd(cmd_in)) {
- return false;
- }
- /* if (!run_cmd(cmd_out)) { return false; } */
-
- return true;
-}
-
-static bool filter_tcp_setup_name(struct torture_context *tctx,
- const char *name, bool unblock)
-{
- const char *cmd_in, *cmd_out;
- const char *chain_in, *chain_out;
- const char *ipt = iptables_command(tctx);
-
- chain_in = samba_chain_name(tctx, name, "SAMBA_INPUT");
- chain_out = samba_chain_name(tctx, name, "SAMBA_OUTPUT");
- if (chain_in == NULL || chain_out == NULL) {
- return false;
- }
-
- if (unblock) {
- cmd_in = talloc_asprintf(tctx, "%s -F %s; "
- "%s -D SAMBA_INPUT -j %s; "
- "%s -X %s",
- ipt, chain_in,
- ipt, chain_in,
- ipt, chain_in);
- cmd_out = talloc_asprintf(tctx, "%s -F %s; "
- "%s -D SAMBA_OUTPUT -j %s; "
- "%s -X %s",
- ipt, chain_out,
- ipt, chain_out,
- ipt, chain_out);
- } else {
- cmd_in = talloc_asprintf(tctx, "%s -L %s > /dev/null 2>&1 || "
- "%s -N %s && "
- "%s -I SAMBA_INPUT -j %s",
- ipt, chain_in,
- ipt, chain_in,
- ipt, chain_in);
- cmd_out = talloc_asprintf(tctx, "%s -L %s > /dev/null 2>&1 || "
- "%s -N %s && "
- "%s -I SAMBA_OUTPUT -j %s",
- ipt, chain_out,
- ipt, chain_out,
- ipt, chain_out);
- }
-
- if (cmd_in == NULL || cmd_out == NULL) {
- return false;
- }
-
- if (!run_cmd(cmd_in)) {
- return false;
- }
- /* if (!run_cmd(cmd_out)) return false; */
-
- return true;
-}
-
-/* '11 452 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:43062' */
-static bool get_packet_count(const char *s, uint32_t *count)
-{
- int i = 0;
- char *p;
-
- if (s == NULL) {
- return false;
- }
-
- while (s[i] == ' ') {
- s++;
- }
-
- p = strchr(s, ' ');
- if (p == NULL) {
- return false;
- }
- *p = '\0';
-
- *count = atoi(s);
-
- return true;
-}
-
-bool torture_list_tcp_transport_name(struct torture_context *tctx,
- const char *name,
- uint32_t *_packets)
-{
- const char *chain_in, *cmd;
- int num_lines;
- char **buf;
- uint32_t packets = 0;
- const char *ipt = iptables_command(tctx);
-
- chain_in = samba_chain_name(tctx, name, "SAMBA_INPUT");
- if (chain_in == NULL) {
- return false;
- }
-
- cmd = talloc_asprintf(tctx, "%s -L %s -v -n", ipt, chain_in);
if (cmd == NULL) {
return false;
}
- if (!run_cmd_return_buf(tctx, cmd, &num_lines, &buf)) {
+ if (!run_cmd(cmd)) {
return false;
}
- SMB_ASSERT(num_lines >= 3);
-
- if (!get_packet_count(buf[2], &packets)) {
- return false;
- }
-
- torture_comment(tctx, "chain: '%s', packets: %d\n", name, (int)packets);
-
- if (_packets != NULL) {
- *_packets = packets;
- }
return true;
}
return get_sockaddr_port(local_ss);
}
-static bool torture_block_tcp_transport_name_internal(
+static bool torture_block_tcp_output_port_internal(
struct torture_context *tctx,
- struct smb2_transport *t,
const char *name,
+ uint16_t port,
bool unblock)
{
- char *cmd_in;
- char *cmd_out;
- const char *chain_in, *chain_out;
- uint16_t port = torture_get_local_port_from_transport(t);
const char *ipt = iptables_command(tctx);
+ const char *chain_out = NULL;
+ char *cmd_out = NULL;
- chain_in = samba_chain_name(tctx, name, "SAMBA_INPUT");
- chain_out = samba_chain_name(tctx, name, "SAMBA_OUTPUT");
- if (chain_in == NULL || chain_out == NULL) {
+ chain_out = samba_chain_name(tctx, name, "SMBTORTURE");
+ if (chain_out == NULL) {
return false;
}
- if (!unblock) {
- filter_tcp_setup(tctx, false);
- filter_tcp_setup_name(tctx, name, false);
- }
-
torture_comment(tctx, "%sblocking %s dport %d\n",
unblock ? "un" : "", name, port);
- cmd_in = talloc_asprintf(tctx,
- "%s %s %s -p tcp --dport %d -j DROP",
- ipt, unblock ? "-D" : "-I", chain_in, port);
+ if (!unblock) {
+ bool ok;
+
+ iptables_setup_chain(tctx,
+ "SMBTORTURE_OUTPUT",
+ chain_out,
+ true);
+ ok = iptables_setup_chain(tctx,
+ "SMBTORTURE_OUTPUT",
+ chain_out,
+ false);
+ if (!ok) {
+ return false;
+ }
+ }
+
cmd_out = talloc_asprintf(tctx,
"%s %s %s -p tcp --sport %d -j DROP",
ipt, unblock ? "-D" : "-I", chain_out, port);
- if (cmd_in == NULL || cmd_out == NULL) {
+ if (cmd_out == NULL) {
return false;
}
- if (!run_cmd(cmd_in)) {
+ if (!run_cmd(cmd_out)) {
return false;
}
- /* if (!run_cmd(cmd_out)) return false; */
if (unblock) {
- filter_tcp_setup_name(tctx, name, true);
- /* better don't cleanup here */
- /* filter_tcp_setup(tctx, true); */
+ bool ok;
+
+ ok = iptables_setup_chain(tctx,
+ "SMBTORTURE_OUTPUT",
+ chain_out,
+ true);
+ if (!ok) {
+ return false;
+ }
}
return true;
}
-bool torture_block_tcp_transport_name(struct torture_context *tctx,
- struct smb2_transport *t,
- const char *name)
+bool torture_block_tcp_output_port(struct torture_context *tctx,
+ const char *name,
+ uint16_t port)
+{
+ return torture_block_tcp_output_port_internal(tctx, name, port, false);
+}
+
+bool torture_unblock_tcp_output_port(struct torture_context *tctx,
+ const char *name,
+ uint16_t port)
{
- return torture_block_tcp_transport_name_internal(tctx, t, name, false);
+ return torture_block_tcp_output_port_internal(tctx, name, port, true);
}
-bool torture_unblock_tcp_transport_name(struct torture_context *tctx,
- struct smb2_transport *t,
- const char *name)
+bool torture_block_tcp_output_setup(struct torture_context *tctx)
{
- return torture_block_tcp_transport_name_internal(tctx, t, name, true);
+ return iptables_setup_chain(tctx, "OUTPUT", "SMBTORTURE_OUTPUT", false);
}
-void torture_unblock_cleanup(struct torture_context *tctx)
+bool torture_unblock_tcp_output_cleanup(struct torture_context *tctx)
{
- filter_tcp_setup(tctx, true);
+ return iptables_setup_chain(tctx, "OUTPUT", "SMBTORTURE_OUTPUT", true);
}
bool ret;
local_port = torture_get_local_port_from_transport(transport);
- torture_comment(tctx, "transport uses tcp port: %d\n", local_port);
- ret = torture_block_tcp_transport_name(tctx, transport, name);
+ torture_comment(tctx, "transport[%s] uses tcp port: %d\n", name, local_port);
+ ret = torture_block_tcp_output_port(tctx, name, local_port);
torture_assert(tctx, ret, "we could not block tcp transport");
return ret;
bool ret;
local_port = torture_get_local_port_from_transport(transport);
- torture_comment(tctx, "transport uses tcp port: %d\n", local_port);
- ret = torture_unblock_tcp_transport_name(tctx, transport, name);
+ torture_comment(tctx, "transport[%s] uses tcp port: %d\n", name, local_port);
+ ret = torture_unblock_tcp_output_port(tctx, name, local_port);
torture_assert(tctx, ret, "we could not block tcp transport");
return ret;
}
}
+static bool test_setup_blocked_channels(struct torture_context *tctx)
+{
+ bool use_iptables = torture_setting_bool(tctx,
+ "use_iptables", false);
+
+ if (use_iptables) {
+ return torture_block_tcp_output_setup(tctx);
+ }
+
+ return true;
+}
+
static void test_cleanup_blocked_channels(struct torture_context *tctx)
{
bool use_iptables = torture_setting_bool(tctx,
"use_iptables", false);
if (use_iptables) {
- torture_unblock_cleanup(tctx);
+ torture_unblock_tcp_output_cleanup(tctx);
}
}
struct smb2_session *session1 = tree1->session;
uint16_t local_port = 0;
DATA_BLOB blob;
+ bool block_setup = false;
bool block_ok = false;
bool unblock_ok = false;
transport2 = break_info.received_transport;
torture_reset_break_info(tctx, &break_info);
+ block_setup = test_setup_blocked_channels(tctx);
+ torture_assert(tctx, block_setup, "test_setup_blocked_channels");
+
/* block channel */
block_ok = test_block_channel(tctx, transport2);
struct smb2_lease ls1;
struct smb2_lease ls2;
struct smb2_lease ls3;
+ bool block_setup = false;
bool block_ok = false;
bool unblock_ok = false;
CHECK_VAL(io2.out.durable_open, false);
CHECK_VAL(lease_break_info.count, 0);
+ block_setup = test_setup_blocked_channels(tctx);
+ torture_assert(tctx, block_setup, "test_setup_blocked_channels");
torture_comment(tctx, "Blocking 2A\n");
/* Block 2A */
if (block_ok && !unblock_ok) {
test_unblock_channel(tctx, transport2A);
}
- test_cleanup_blocked_channels(tctx);
+ if (block_setup) {
+ test_cleanup_blocked_channels(tctx);
+ }
tree1->session = session1;