This commit is contained in:
Alex Young
2012-06-01 16:25:41 +01:00
4 changed files with 40 additions and 11 deletions

View File

@@ -48,6 +48,7 @@ void params_serve(
char* s_port,
char* s_file,
char *s_ctrl_sock,
int default_deny,
int acl_entries,
char** s_acl_entries /* first may actually be path to control socket */
)
@@ -71,6 +72,10 @@ void params_serve(
* we pass NULL. */
out->control_socket_name = s_ctrl_sock;
/* If this is true then an empty ACL means "nobody is allowed to connect",
* rather than "anybody is allowed to connect" */
out->default_deny = default_deny;
out->acl_entries = acl_entries;
parsed = parse_acl(&out->acl, acl_entries, s_acl_entries);
if (parsed != acl_entries)
@@ -161,7 +166,8 @@ void do_read(struct mode_readwrite_params* params);
void do_write(struct mode_readwrite_params* params);
void do_remote_command(char* command, char* mode, int argc, char** argv);
void read_serve_param( int c, char **ip_addr, char **ip_port, char **file, char **sock )
void read_serve_param( int c, char **ip_addr, char **ip_port, char **file, char **sock, int *default_deny )
{
switch(c){
case 'h':
@@ -182,6 +188,8 @@ void read_serve_param( int c, char **ip_addr, char **ip_port, char **file, char
break;
case 'd':
set_debug(1);
case 'D':
*default_deny = 1;
break;
default:
exit_err( serve_help_text );
@@ -279,14 +287,17 @@ int mode_serve( int argc, char *argv[] )
char *ip_port = NULL;
char *file = NULL;
char *sock = NULL;
int default_deny = 0; // not on by default
int err = 0;
struct mode_serve_params serve;
while (1) {
c = getopt_long(argc, argv, serve_short_options, serve_options, NULL);
if ( c == -1 ) break;
read_serve_param( c, &ip_addr, &ip_port, &file, &sock );
if ( c == -1 )
break;
read_serve_param( c, &ip_addr, &ip_port, &file, &sock, &default_deny );
}
if ( NULL == ip_addr || NULL == ip_port ) {
@@ -300,7 +311,7 @@ int mode_serve( int argc, char *argv[] )
if ( err ) { exit_err( serve_help_text ); }
memset( &serve, 0, sizeof( serve ) );
params_serve( &serve, ip_addr, ip_port, file, sock, argc - optind, argv + optind );
params_serve( &serve, ip_addr, ip_port, file, sock, default_deny, argc - optind, argv + optind );
do_serve( &serve );
return 0;

View File

@@ -8,6 +8,7 @@
#define OPT_SOCK "sock"
#define OPT_FROM "from"
#define OPT_SIZE "size"
#define OPT_DENY "default-deny"
#define CMD_SERVE "serve"
#define CMD_READ "read"
@@ -16,7 +17,7 @@
#define CMD_MIRROR "mirror"
#define CMD_STATUS "status"
#define CMD_HELP "help"
#define LEN_CMD_MAX 6
#define LEN_CMD_MAX 7
#define PATH_LEN_MAX 1024
#define ADDR_LEN_MAX 64
@@ -25,6 +26,8 @@
#define IS_CMD(x,c) (strncmp((x),(c),(LEN_CMD_MAX)) == 0)
#define GETOPT_HELP GETOPT_FLAG( OPT_HELP, 'h' )
#define GETOPT_DENY GETOPT_FLAG( OPT_DENY, 'D' )
#define GETOPT_ADDR GETOPT_ARG( OPT_ADDR, 'l' )
#define GETOPT_PORT GETOPT_ARG( OPT_PORT, 'p' )
#define GETOPT_FILE GETOPT_ARG( OPT_FILE, 'f' )
@@ -50,9 +53,10 @@ static struct option serve_options[] = {
GETOPT_FILE,
GETOPT_SOCK,
GETOPT_DEBUG,
GETOPT_DENY,
{0}
};
static char serve_short_options[] = "hl:p:f:s:";
static char serve_short_options[] = "Dhl:p:f:s:";
static char serve_help_text[] =
"Usage: flexnbd " CMD_SERVE " <options> [<acl address>*]\n\n"
"Serve FILE from ADDR:PORT, with an optional control socket at SOCK.\n\n"
@@ -60,6 +64,7 @@ static char serve_help_text[] =
"\t--" OPT_ADDR ",-l <ADDR>\tThe address to serve on.\n"
"\t--" OPT_PORT ",-p <PORT>\tThe port to serve on.\n"
"\t--" OPT_FILE ",-f <FILE>\tThe file to serve.\n"
"\t--" OPT_DENY ",-D\tDeny connections by default unless in ACL\n"
"\t--" OPT_SOCK ",-s <SOCK>\tPath to the control socket to open.\n"
DEBUG_LINE;

View File

@@ -37,6 +37,8 @@ struct control_params {
struct mode_serve_params {
/** address/port to bind to */
union mysockaddr bind_to;
/** does an empty ACL mean "deny all"? */
int default_deny;
/** number of entries in current access control list*/
int acl_entries;
/** pointer to access control list entries*/

View File

@@ -530,6 +530,8 @@ void accept_nbd_client(
struct client_params* client_params;
int slot = cleanup_and_find_client_slot(params);
char s_client_address[64];
int acl_passed = 0;
if (inet_ntop(client_address->generic.sa_family,
sockaddr_address_data(&client_address->generic),
@@ -539,12 +541,21 @@ void accept_nbd_client(
return;
}
if (params->acl &&
!is_included_in_acl(params->acl_entries, params->acl, client_address)) {
write(client_fd, "Access control error", 20);
close(client_fd);
return;
if (params->acl) {
if (is_included_in_acl(params->acl_entries, params->acl, client_address))
acl_passed = 1;
} else {
if (!params->default_deny)
acl_passed = 1;
}
if (!acl_passed) {
write(client_fd, "Access control error", 20);
close(client_fd);
return;
}
if (slot < 0) {
write(client_fd, "Too many clients", 16);