diff options
-rw-r--r-- | conf/confbase.Y | 1 | ||||
-rw-r--r-- | doc/bird.sgml | 5 | ||||
-rw-r--r-- | nest/cli.c | 6 | ||||
-rw-r--r-- | nest/cli.h | 3 | ||||
-rw-r--r-- | sysdep/unix/config.Y | 20 | ||||
-rw-r--r-- | sysdep/unix/main.c | 4 |
6 files changed, 28 insertions, 11 deletions
diff --git a/conf/confbase.Y b/conf/confbase.Y index 4bf70ccf..cdbdf1ce 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -100,7 +100,6 @@ CF_DECLS mpls_label_stack *mls; const struct adata *bs; struct aggr_item_node *ai; - struct cli_config *cli; } %token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT diff --git a/doc/bird.sgml b/doc/bird.sgml index 5acdf7c1..e2050c13 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1253,6 +1253,11 @@ socket multiple times and BIRD may behave weirdly if this happens. On shutdown, the additional sockets get removed immediately and only the main socket stays until the very end. +<p>The remote control socket can be also set as restricted by +<cf/cli "name" { restrict; };/ instead of sending the <cf/restrict/ command +after connecting. The user may still overload the daemon by requesting insanely +complex filters so you shouldn't expose this socket to public anyway. + <sect>Usage <label id="remote-control-usage"> @@ -306,7 +306,7 @@ cli_event(void *data) } cli * -cli_new(void *priv) +cli_new(void *priv, struct cli_config *cf) { pool *p = rp_new(cli_pool, "CLI"); cli *c = mb_alloc(p, sizeof(cli)); @@ -321,6 +321,10 @@ cli_new(void *priv) c->parser_pool = lp_new_default(c->pool); c->show_pool = lp_new_default(c->pool); c->rx_buf = mb_alloc(c->pool, CLI_RX_BUF_SIZE); + + if (cf->restricted) + c->restricted = 1; + ev_schedule(c->event); return c; } @@ -60,6 +60,7 @@ struct cli_config { const char *name; struct config *config; uint uid, gid, mode; + _Bool restricted; }; #include "lib/tlists.h" @@ -81,7 +82,7 @@ static inline void cli_separator(cli *c) /* Functions provided to sysdep layer */ -cli *cli_new(void *); +cli *cli_new(void *, struct cli_config *); void cli_init(void); void cli_free(cli *); void cli_kick(cli *); diff --git a/sysdep/unix/config.Y b/sysdep/unix/config.Y index 665b0b09..7607f34a 100644 --- a/sysdep/unix/config.Y +++ b/sysdep/unix/config.Y @@ -14,6 +14,7 @@ CF_HDR CF_DEFINES static struct log_config *this_log; +static struct cli_config *this_cli_config; CF_DECLS @@ -21,7 +22,6 @@ CF_KEYWORDS(LOG, SYSLOG, NAME, STDERR, UDP, PORT, CLI) CF_KEYWORDS(ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG) CF_KEYWORDS(DEBUG, LATENCY, LIMIT, WATCHDOG, WARNING, TIMEOUT, THREADS) -%type <cli> cli_opts %type <i> log_mask log_mask_list log_cat cfg_timeout %type <t> cfg_name %type <tf> timeformat_which @@ -127,18 +127,26 @@ mrtdump_base: conf: cli ; cli: CLI text cli_opts { - $3->name = $2; - cli_config_add_tail(&new_config->cli, $3); + this_cli_config->name = $2; + cli_config_add_tail(&new_config->cli, this_cli_config); + this_cli_config = NULL; } ; -cli_opts: ';' { - $$ = cfg_alloc(sizeof *$$); - *$$ = (typeof (*$$)) { +cli_opts: cli_opts_begin '{' cli_opts_block '}' ';' | cli_opts_begin ';' ; + +cli_opts_begin: { + this_cli_config = cfg_alloc(sizeof *this_cli_config); + *this_cli_config = (typeof (*this_cli_config)) { .config = new_config, .mode = 0660, }; }; +cli_opts_block: + /* EMPTY */ | + cli_opts_block RESTRICT { this_cli_config->restricted = 1; } +; + conf: debug_unix ; debug_unix: diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c index 17f7edb5..880cc3c4 100644 --- a/sysdep/unix/main.c +++ b/sysdep/unix/main.c @@ -538,7 +538,7 @@ cli_connect(sock *s, uint size UNUSED) s->rx_hook = cli_rx; s->tx_hook = cli_tx; s->err_hook = cli_err; - s->data = c = cli_new(s); + s->data = c = cli_new(s, ((struct cli_listener *) s->data)->config); s->pool = c->pool; /* We need to have all the socket buffers allocated in the cli pool */ s->fast_rx = 1; c->rx_pos = c->rx_buf; @@ -555,7 +555,7 @@ cli_listen(struct cli_config *cf) s->type = SK_UNIX_PASSIVE; s->rx_hook = cli_connect; s->err_hook = cli_connect_err; - s->data = cf; + s->data = l; s->rbsize = 1024; s->fast_rx = 1; |