Test for acl rejection
This commit is contained in:
@@ -134,6 +134,7 @@ int control_accept( struct control * control )
|
|||||||
FD_ZERO( &fds );
|
FD_ZERO( &fds );
|
||||||
FD_SET( control->control_fd, &fds );
|
FD_SET( control->control_fd, &fds );
|
||||||
self_pipe_fd_set( control->close_signal, &fds );
|
self_pipe_fd_set( control->close_signal, &fds );
|
||||||
|
debug("Control thread selecting");
|
||||||
FATAL_UNLESS( 0 < select( FD_SETSIZE, &fds, NULL, NULL, NULL ),
|
FATAL_UNLESS( 0 < select( FD_SETSIZE, &fds, NULL, NULL, NULL ),
|
||||||
"Control select failed." );
|
"Control select failed." );
|
||||||
|
|
||||||
@@ -398,48 +399,43 @@ void control_cleanup(struct control_client* client,
|
|||||||
void control_respond(struct control_client * client)
|
void control_respond(struct control_client * client)
|
||||||
{
|
{
|
||||||
char **lines = NULL;
|
char **lines = NULL;
|
||||||
int finished=0;
|
|
||||||
|
|
||||||
error_set_handler((cleanup_handler*) control_cleanup, client);
|
error_set_handler((cleanup_handler*) control_cleanup, client);
|
||||||
|
|
||||||
while (!finished) {
|
|
||||||
int i, linesc;
|
int i, linesc;
|
||||||
linesc = read_lines_until_blankline(client->socket, 256, &lines);
|
linesc = read_lines_until_blankline(client->socket, 256, &lines);
|
||||||
|
|
||||||
if (linesc < 1)
|
if (linesc < 1)
|
||||||
{
|
{
|
||||||
write(client->socket, "9: missing command\n", 19);
|
write(client->socket, "9: missing command\n", 19);
|
||||||
finished = 1;
|
|
||||||
/* ignore failure */
|
/* ignore failure */
|
||||||
}
|
}
|
||||||
else if (strcmp(lines[0], "acl") == 0) {
|
else if (strcmp(lines[0], "acl") == 0) {
|
||||||
info("acl command received" );
|
info("acl command received" );
|
||||||
if (control_acl(client, linesc-1, lines+1) < 0) {
|
if (control_acl(client, linesc-1, lines+1) < 0) {
|
||||||
finished = 1;
|
debug("acl command failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strcmp(lines[0], "mirror") == 0) {
|
else if (strcmp(lines[0], "mirror") == 0) {
|
||||||
info("mirror command received" );
|
info("mirror command received" );
|
||||||
if (control_mirror(client, linesc-1, lines+1) < 0) {
|
if (control_mirror(client, linesc-1, lines+1) < 0) {
|
||||||
finished = 1;
|
debug("mirror command failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strcmp(lines[0], "status") == 0) {
|
else if (strcmp(lines[0], "status") == 0) {
|
||||||
info("status command received" );
|
info("status command received" );
|
||||||
if (control_status(client, linesc-1, lines+1) < 0) {
|
if (control_status(client, linesc-1, lines+1) < 0) {
|
||||||
finished = 1;
|
debug("status command failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
write(client->socket, "10: unknown command\n", 23);
|
write(client->socket, "10: unknown command\n", 23);
|
||||||
finished = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<linesc; i++) {
|
for (i=0; i<linesc; i++) {
|
||||||
free(lines[i]);
|
free(lines[i]);
|
||||||
}
|
}
|
||||||
free(lines);
|
free(lines);
|
||||||
}
|
|
||||||
|
|
||||||
control_cleanup(client, 0);
|
control_cleanup(client, 0);
|
||||||
debug("control command handled" );
|
debug("control command handled" );
|
||||||
|
@@ -299,6 +299,7 @@ int flexnbd_serve( struct flexnbd * flexnbd )
|
|||||||
if ( flexnbd->control ) {
|
if ( flexnbd->control ) {
|
||||||
debug( "Stopping control thread" );
|
debug( "Stopping control thread" );
|
||||||
flexnbd_stop_control( flexnbd );
|
flexnbd_stop_control( flexnbd );
|
||||||
|
debug("Control thread stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
|
23
tests/fakes/source/connect_from_banned_ip.rb
Executable file
23
tests/fakes/source/connect_from_banned_ip.rb
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
# We connect from a local address which should be blocked, sleep for a
|
||||||
|
# bit, then try to read from the socket. We should get an instant EOF
|
||||||
|
# as we've been cut off by the destination.
|
||||||
|
|
||||||
|
require 'timeout'
|
||||||
|
require 'flexnbd/fake_source'
|
||||||
|
include FlexNBD::FakeSource
|
||||||
|
|
||||||
|
addr, port = *ARGV
|
||||||
|
sock = connect( addr, port, "Timed out connecting", "127.0.0.6" )
|
||||||
|
sleep( 0.25 )
|
||||||
|
Timeout.timeout( 2 ) do
|
||||||
|
fail "Not disconnected" if sock.read(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
sock.close
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -265,6 +265,13 @@ class FlexNBD
|
|||||||
"#{@debug}"
|
"#{@debug}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def acl_cmd( *acl )
|
||||||
|
"#{@bin} acl " \
|
||||||
|
"--sock #{ctrl} "\
|
||||||
|
"#{@debug} "\
|
||||||
|
"#{acl.join " "}"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
def run_serve_cmd(cmd)
|
def run_serve_cmd(cmd)
|
||||||
File.unlink(ctrl) if File.exists?(ctrl)
|
File.unlink(ctrl) if File.exists?(ctrl)
|
||||||
@@ -354,6 +361,7 @@ class FlexNBD
|
|||||||
@wait_thread.join
|
@wait_thread.join
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def mirror_unchecked( dest_ip, dest_port, bandwidth=nil, action=nil, timeout=nil )
|
def mirror_unchecked( dest_ip, dest_port, bandwidth=nil, action=nil, timeout=nil )
|
||||||
cmd = mirror_cmd( dest_ip, dest_port)
|
cmd = mirror_cmd( dest_ip, dest_port)
|
||||||
debug( cmd )
|
debug( cmd )
|
||||||
@@ -361,6 +369,7 @@ class FlexNBD
|
|||||||
maybe_timeout( cmd, timeout )
|
maybe_timeout( cmd, timeout )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def maybe_timeout(cmd, timeout=nil )
|
def maybe_timeout(cmd, timeout=nil )
|
||||||
stdout, stderr = "",""
|
stdout, stderr = "",""
|
||||||
run = Proc.new do
|
run = Proc.new do
|
||||||
@@ -388,8 +397,12 @@ class FlexNBD
|
|||||||
stdout
|
stdout
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def acl(*acl)
|
def acl(*acl)
|
||||||
control_command("acl", *acl)
|
cmd = acl_cmd( *acl )
|
||||||
|
debug( cmd )
|
||||||
|
|
||||||
|
maybe_timeout( cmd, 2 )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -403,6 +416,11 @@ class FlexNBD
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def launched?
|
||||||
|
!!@pid
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
def control_command(*args)
|
def control_command(*args)
|
||||||
raise "Server not running" unless @pid
|
raise "Server not running" unless @pid
|
||||||
|
@@ -7,9 +7,9 @@ require 'flexnbd/constants'
|
|||||||
module FlexNBD
|
module FlexNBD
|
||||||
module FakeSource
|
module FakeSource
|
||||||
|
|
||||||
def connect( addr, port, err_msg )
|
def connect( addr, port, err_msg, source_addr=nil, source_port=0 )
|
||||||
timing_out( 2, err_msg ) do
|
timing_out( 2, err_msg ) do
|
||||||
TCPSocket.open( addr, port )
|
TCPSocket.new( addr, port, source_addr, source_port )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@@ -33,7 +33,7 @@ class Environment
|
|||||||
|
|
||||||
|
|
||||||
def listen1( *acl )
|
def listen1( *acl )
|
||||||
@nbd1.listen( @filename1, *acl )
|
@nbd1.listen( @filename1, *(acl.empty? ? @acl1: acl) )
|
||||||
end
|
end
|
||||||
|
|
||||||
def listen2( *acl )
|
def listen2( *acl )
|
||||||
@@ -41,6 +41,15 @@ class Environment
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def acl1( *acl )
|
||||||
|
@nbd1.acl( *acl )
|
||||||
|
end
|
||||||
|
|
||||||
|
def acl2( *acl )
|
||||||
|
@nbd2.acl( *acl )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
def status1
|
def status1
|
||||||
@nbd1.status.first
|
@nbd1.status.first
|
||||||
end
|
end
|
||||||
@@ -304,10 +313,16 @@ class NBDConnectDestFailureScenarios < Test::Unit::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def test_acl_rejection
|
||||||
|
@env.acl1("127.0.0.1")
|
||||||
|
run_fake( "source/connect_from_banned_ip")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
def run_fake( name )
|
def run_fake( name )
|
||||||
@env.run_fake( name, @env.ip, @env.port1 )
|
@env.run_fake( name, @env.ip, @env.port1 )
|
||||||
assert @env.fake_reports_success
|
assert @env.fake_reports_success, "#{name} failed."
|
||||||
end
|
end
|
||||||
|
|
||||||
def assert_no_control
|
def assert_no_control
|
||||||
|
Reference in New Issue
Block a user