From 2fe8aba3a09b3e2a64ee1861d8eeb389efaf1eb0 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Fri, 12 May 2006 23:22:01 +0000 Subject: [lib] CID #39, fix leak in error path, vty_describe_command 2006-05-12 Paul Jakma * vty.c: (vty_describe_command) fix leak of describe vector in error path, CID #39. --- lib/vty.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'lib/vty.c') diff --git a/lib/vty.c b/lib/vty.c index 206af065..98f6494e 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -985,18 +985,12 @@ vty_describe_command (struct vty *vty) switch (ret) { case CMD_ERR_AMBIGUOUS: - cmd_free_strvec (vline); vty_out (vty, "%% Ambiguous command.%s", VTY_NEWLINE); - vty_prompt (vty); - vty_redraw_line (vty); - return; + goto out; break; case CMD_ERR_NO_MATCH: - cmd_free_strvec (vline); vty_out (vty, "%% There is no matched command.%s", VTY_NEWLINE); - vty_prompt (vty); - vty_redraw_line (vty); - return; + goto out; break; } @@ -1066,6 +1060,7 @@ vty_describe_command (struct vty *vty) vty_describe_fold (vty, width, desc_width, desc); } +out: cmd_free_strvec (vline); vector_free (describe); -- cgit v1.2.3 From d16e04335968ea05fda60cec01b48df8c345a8ce Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Mon, 15 May 2006 10:56:46 +0000 Subject: [lib] CID #39, Fix the vty completion leak-fix to only free when desired 2006-05-13 Paul Jakma * vty.c: (vty_describe_command) CID #39 fix was too hasty, just cause it /can/ leak doesn't mean it always will have, check first. --- lib/vty.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/vty.c') diff --git a/lib/vty.c b/lib/vty.c index 98f6494e..7696915a 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -1062,7 +1062,8 @@ vty_describe_command (struct vty *vty) out: cmd_free_strvec (vline); - vector_free (describe); + if (describe) + vector_free (describe); vty_prompt (vty); vty_redraw_line (vty); -- cgit v1.2.3 From a4b303038363185f60dfef7023cb02715a9a4315 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Sun, 28 May 2006 08:18:38 +0000 Subject: [lib] vty_log shouldn't crash if called when vty isn't initiliased 2006-05-28 Paul Jakma * vty.c: (vty_log/vty_log_fixed) dont crash if called when vty hasn't been initiliased. --- lib/vty.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/vty.c') diff --git a/lib/vty.c b/lib/vty.c index 7696915a..b037c70c 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -2404,6 +2404,9 @@ vty_log (const char *level, const char *proto_str, { unsigned int i; struct vty *vty; + + if (!vtyvec) + return; for (i = 0; i < vector_active (vtyvec); i++) if ((vty = vector_slot (vtyvec, i)) != NULL) @@ -2423,6 +2426,10 @@ vty_log_fixed (const char *buf, size_t len) unsigned int i; struct iovec iov[2]; + /* vty may not have been initialised */ + if (!vtyvec) + return; + iov[0].iov_base = (void *)buf; iov[0].iov_len = len; iov[1].iov_base = (void *)"\r\n"; -- cgit v1.2.3 From 08942da588b78f41916ebd6c75fa668b18160ee7 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Mon, 3 Jul 2006 20:58:29 +0000 Subject: [debug] Debug messages to terminal vty sessions should include timestamps 2006-07-03 Andrew J. Schorr * vty.c: (vty_log_out) Debug messages to terminal vty sessions should include timestamps. --- lib/vty.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'lib/vty.c') diff --git a/lib/vty.c b/lib/vty.c index b037c70c..8de32870 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -154,12 +154,18 @@ vty_log_out (struct vty *vty, const char *level, const char *proto_str, int ret; int len; char buf[1024]; + struct tm *tm; + + if ((tm = localtime(&recent_time.tv_sec)) != NULL) + len = strftime(buf, sizeof(buf), "%Y/%m/%d %H:%M:%S ", tm); + else + len = 0; if (level) - len = snprintf(buf, sizeof(buf), "%s: %s: ", level, proto_str); + ret = snprintf(buf+len, sizeof(buf)-len, "%s: %s: ", level, proto_str); else - len = snprintf(buf, sizeof(buf), "%s: ", proto_str); - if ((len < 0) || ((size_t)len >= sizeof(buf))) + ret = snprintf(buf+len, sizeof(buf)-len, "%s: ", proto_str); + if ((ret < 0) || ((size_t)(len += ret) >= sizeof(buf))) return -1; if (((ret = vsnprintf(buf+len, sizeof(buf)-len, format, va)) < 0) || -- cgit v1.2.3 From 74542d730198a37a872b7114643e29e99c551bcf Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Mon, 10 Jul 2006 18:09:42 +0000 Subject: [lib] Fix infinite recursion for errors on vtys with terminal monitor enabled 2006-07-10 Andrew J. Schorr * vty.c: (vty_log_out, vty_read, vty_flush, vtysh_flush, vtysh_read) After an I/O error, must set vty->monitor to 0 before calling zlog_warn, otherwise an infinite recursion could occur (since zlog_warn triggers a message to be written to the vty, and that in turn triggers another error message when it fails, etc.). --- lib/vty.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/vty.c') diff --git a/lib/vty.c b/lib/vty.c index 8de32870..98e75060 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -182,6 +182,7 @@ vty_log_out (struct vty *vty, const char *level, const char *proto_str, drop the data and ignore. */ return -1; /* Fatal I/O error. */ + vty->monitor = 0; /* disable monitoring to avoid infinite recursion */ zlog_warn("%s: write failed to vty client fd %d, closing: %s", __func__, vty->fd, safe_strerror(errno)); buffer_reset(vty->obuf); @@ -1349,6 +1350,7 @@ vty_read (struct thread *thread) vty_event (VTY_READ, vty_sock, vty); return 0; } + vty->monitor = 0; /* disable monitoring to avoid infinite recursion */ zlog_warn("%s: read error on vty client fd %d, closing: %s", __func__, vty->fd, safe_strerror(errno)); } @@ -1571,6 +1573,7 @@ vty_flush (struct thread *thread) switch (flushrc) { case BUFFER_ERROR: + vty->monitor = 0; /* disable monitoring to avoid infinite recursion */ zlog_warn("buffer_flush failed on vty client fd %d, closing", vty->fd); buffer_reset(vty->obuf); @@ -2018,6 +2021,7 @@ vtysh_flush(struct vty *vty) vty_event(VTYSH_WRITE, vty->fd, vty); break; case BUFFER_ERROR: + vty->monitor = 0; /* disable monitoring to avoid infinite recursion */ zlog_warn("%s: write error to fd %d, closing", __func__, vty->fd); buffer_reset(vty->obuf); vty_close(vty); @@ -2053,6 +2057,7 @@ vtysh_read (struct thread *thread) vty_event (VTYSH_READ, sock, vty); return 0; } + vty->monitor = 0; /* disable monitoring to avoid infinite recursion */ zlog_warn("%s: read failed on vtysh client fd %d, closing: %s", __func__, sock, safe_strerror(errno)); } -- cgit v1.2.3 From 9d0a3260b2d1b57b7edfd3f72885d861883d4621 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 11 Jul 2006 00:06:49 +0000 Subject: [lib] Do not call vty_close in vty_log_out to avoid possible free memory access 2006-07-10 Andrew J. Schorr * vty.c: (vty_log_out) Do not call vty_close, because this could result in a parent function's accessing the freed memory. Instead, set status VTY_CLOSE and call shutdown(vty->fd, SHUT_RDWR). And add a comment on vty_close. --- lib/vty.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'lib/vty.c') diff --git a/lib/vty.c b/lib/vty.c index 98e75060..4288e150 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -186,7 +186,10 @@ vty_log_out (struct vty *vty, const char *level, const char *proto_str, zlog_warn("%s: write failed to vty client fd %d, closing: %s", __func__, vty->fd, safe_strerror(errno)); buffer_reset(vty->obuf); - vty_close(vty); + /* cannot call vty_close, because a parent routine may still try + to access the vty struct */ + vty->status = VTY_CLOSE; + shutdown(vty->fd, SHUT_RDWR); return -1; } return 0; @@ -2141,7 +2144,10 @@ vty_serv_sock (const char *addr, unsigned short port, const char *path) #endif /* VTYSH */ } -/* Close vty interface. */ +/* Close vty interface. Warning: call this only from functions that + will be careful not to access the vty afterwards (since it has + now been freed). This is safest from top-level functions (called + directly by the thread dispatcher). */ void vty_close (struct vty *vty) { -- cgit v1.2.3 From 1ed72e0b3a643fa1be6f1efa904965798a575cd1 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Sat, 28 Apr 2007 22:14:10 +0000 Subject: [logging] Add new "log timestamp precision" command for subsecond timestamps 2007-04-28 Andrew J. Schorr * command.c: (config_write_host) Save "log timestamp precision" if not default value. (show_logging) Show configured timestamp precision. (config_log_timestamp_precision) Enable configuration of timestamp precision. (no_config_log_timestamp_precision) Restore default timestamp precision. (cmd_init) Install new timestamp precision commands. * log.h: (struct zlog) New timestamp_precision field. (quagga_timestamp) New function to generate a timestamp with the desired precision. (struct timestamp_control) Declare a structure for use in avoiding repeated duplicate calls to quagga_timestamp. * log.c: (quagga_timestamp) New function to generate a timestamp of the desired precision. (time_print) Call quagga_timestamp if the time hasn't already been calculated. (vzlog) Initialize a timestamp_control structure and pass it to time_print and vty_log. (zlog_backtrace) Fix 64-bit problem: cannot print size_t with %u. * vty.h: Must now include "log.h". (vty_log) Takes an additional struct timestamp_control argument. * vty.c: (vty_log_out) Use new struct timestamp_control and new quagga_timestamp function to print timestamps of the desired precision. (vty_time_print) Use new quagga_timestamp function. (vty_log) Accept new struct timestamp_control argument and pass it down to vty_log_out. --- lib/vty.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'lib/vty.c') diff --git a/lib/vty.c b/lib/vty.c index 4288e150..6cb8b487 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -149,17 +149,22 @@ vty_out (struct vty *vty, const char *format, ...) static int vty_log_out (struct vty *vty, const char *level, const char *proto_str, - const char *format, va_list va) + const char *format, struct timestamp_control *ctl, va_list va) { int ret; int len; char buf[1024]; - struct tm *tm; - if ((tm = localtime(&recent_time.tv_sec)) != NULL) - len = strftime(buf, sizeof(buf), "%Y/%m/%d %H:%M:%S ", tm); - else - len = 0; + if (!ctl->already_rendered) + { + ctl->len = quagga_timestamp(ctl->precision, ctl->buf, sizeof(ctl->buf)); + ctl->already_rendered = 1; + } + if (ctl->len+1 >= sizeof(buf)) + return -1; + memcpy(buf, ctl->buf, len = ctl->len); + buf[len++] = ' '; + buf[len] = '\0'; if (level) ret = snprintf(buf+len, sizeof(buf)-len, "%s: %s: ", level, proto_str); @@ -199,19 +204,11 @@ vty_log_out (struct vty *vty, const char *level, const char *proto_str, void vty_time_print (struct vty *vty, int cr) { - time_t clock; - struct tm *tm; -#define TIME_BUF 25 - char buf [TIME_BUF]; - int ret; + char buf [25]; - time (&clock); - tm = localtime (&clock); - - ret = strftime (buf, TIME_BUF, "%Y/%m/%d %H:%M:%S", tm); - if (ret == 0) + if (quagga_timestamp(0, buf, sizeof(buf)) == 0) { - zlog (NULL, LOG_INFO, "strftime error"); + zlog (NULL, LOG_INFO, "quagga_timestamp error"); return; } if (cr) @@ -2417,7 +2414,7 @@ vty_read_config (char *config_file, /* Small utility function which output log to the VTY. */ void vty_log (const char *level, const char *proto_str, - const char *format, va_list va) + const char *format, struct timestamp_control *ctl, va_list va) { unsigned int i; struct vty *vty; @@ -2431,7 +2428,7 @@ vty_log (const char *level, const char *proto_str, { va_list ac; va_copy(ac, va); - vty_log_out (vty, level, proto_str, format, ac); + vty_log_out (vty, level, proto_str, format, ctl, ac); va_end(ac); } } -- cgit v1.2.3 From 6f0e3f6e17687eb25b7b77c4fdc8324837d4700f Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Thu, 10 May 2007 02:38:51 +0000 Subject: [autoconf] bugs 162,303,178: Fix 'present but can not be compiled' warnings 2007-05-09 Paul Jakma * configure.ac: sys/conf.h depends on sys/param.h, at least on FBSD 6.2. (bug #363) Should check for in_pktinfo for IRDP 2006-05-27 Paul Jakma * configure.ac: General cleanup of header and type checks, introducing an internal define, QUAGGA_INCLUDES, to build up a list of stuff to include so as to avoid 'present but cant be compiled' warnings. Misc additional checks of things missing according to autoscan. Add LIBM, for bgpd's use of libm, so as to avoid burdening LIBS, and all the binaries, with libm linkage. Remove the bad practice of using m4 changequote(), just quote the []'s in the case statements properly. This should fix bugs 162, 303 and 178. * */*.{c,h}: Update all HAVE_* to the standard autoconf namespaced HAVE_* defines. I.e. HAVE_SA_LEN -> HAVE_STRUCT_SOCKADDR_SA_LEN, * bgpd/Makefile.am: Add LIBM to bgpd's LDADD, for pow(). --- lib/vty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/vty.c') diff --git a/lib/vty.c b/lib/vty.c index 6cb8b487..ccf66406 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -1924,11 +1924,11 @@ vty_serv_un (const char *path) memset (&serv, 0, sizeof (struct sockaddr_un)); serv.sun_family = AF_UNIX; strncpy (serv.sun_path, path, strlen (path)); -#ifdef HAVE_SUN_LEN +#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN len = serv.sun_len = SUN_LEN(&serv); #else len = sizeof (serv.sun_family) + strlen (serv.sun_path); -#endif /* HAVE_SUN_LEN */ +#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */ ret = bind (sock, (struct sockaddr *) &serv, len); if (ret < 0) -- cgit v1.2.3 From 7f794f2bb079c1a5bb0fdebb815921c168c00e90 Mon Sep 17 00:00:00 2001 From: Roy Date: Wed, 13 Aug 2008 17:27:38 +0100 Subject: [vty] Allow delete during password entry 2008-08-13 roy * lib/vty.c: (vty_delete_char) move check for authentication down a bit, so we do the delete, but still not re-write of line. Signed-off-by: Paul Jakma --- lib/vty.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/vty.c') diff --git a/lib/vty.c b/lib/vty.c index ccf66406..32084713 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -727,9 +727,6 @@ vty_delete_char (struct vty *vty) int i; int size; - if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE) - return; - if (vty->length == 0) { vty_down_level (vty); @@ -744,6 +741,9 @@ vty_delete_char (struct vty *vty) vty->length--; memmove (&vty->buf[vty->cp], &vty->buf[vty->cp + 1], size - 1); vty->buf[vty->length] = '\0'; + + if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE) + return; vty_write (vty, &vty->buf[vty->cp], size - 1); vty_write (vty, &telnet_space_char, 1); -- cgit v1.2.3 From 62687ff1cd3d4460cdbd4b0fbf1e3298fe277ad2 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Sat, 23 Aug 2008 14:27:06 +0100 Subject: [vty] Add support for a 'restricted mode' with anonymous vty connections * lib/command.h: Add a RESTRICTED_NODE, intended for use with anonymous, 'no login' vtys, to provide a subset of 'view' mode commands. * lib/command.c: Add RESTRICTED_NODE bits, nothing special, just following VIEW_NODE. * lib/vty.c: (vty_auth) enable authentication should fall back to restricted/view node as appropriate. (vty_create) init vty's to restricted/view node as appropriate, for the 'no login' case. (vty_{no_,}restricted_mode_cmd) config commands to enable 'anonymous restricted' in vty configuration. (vty_config_write) 'anonymous restricted' config. (vty_init) Install some commands to restricted mode, and the 'anonymous restricted' config commands into VTY_NODE. * bgpd/*.c: Install some of the safe(r) BGP commands into 'restricted mode', i.e. lookup commands of non-sensitive data. Useful with looking-glass route-servers. --- lib/vty.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) (limited to 'lib/vty.c') diff --git a/lib/vty.c b/lib/vty.c index 32084713..14a36c16 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -82,6 +82,10 @@ static int vty_config; /* Login password check. */ static int no_password_check = 0; +/* Restrict unauthenticated logins? */ +static const u_char restricted_mode_default = 0; +static u_char restricted_mode = 0; + /* Integrated configuration file path */ char integrate_default[] = SYSCONFDIR INTEGRATE_DEFAULT_CONFIG; @@ -383,7 +387,7 @@ vty_auth (struct vty *vty, char *buf) /* AUTH_ENABLE_NODE */ vty->fail = 0; vty_out (vty, "%% Bad enable passwords, too many failures!%s", VTY_NEWLINE); - vty->node = VIEW_NODE; + vty->node = restricted_mode ? RESTRICTED_NODE : VIEW_NODE; } } } @@ -687,6 +691,7 @@ vty_end_config (struct vty *vty) { case VIEW_NODE: case ENABLE_NODE: + case RESTRICTED_NODE: /* Nothing to do. */ break; case CONFIG_NODE: @@ -1094,6 +1099,7 @@ vty_stop_input (struct vty *vty) { case VIEW_NODE: case ENABLE_NODE: + case RESTRICTED_NODE: /* Nothing to do. */ break; case CONFIG_NODE: @@ -1613,7 +1619,9 @@ vty_create (int vty_sock, union sockunion *su) vty->address = sockunion_su2str (su); if (no_password_check) { - if (host.advanced) + if (restricted_mode) + vty->node = RESTRICTED_NODE; + else if (host.advanced) vty->node = ENABLE_NODE; else vty->node = VIEW_NODE; @@ -2715,6 +2723,26 @@ DEFUN (no_vty_login, return CMD_SUCCESS; } +/* initial mode. */ +DEFUN (vty_restricted_mode, + vty_restricted_mode_cmd, + "anonymous restricted", + "Restrict view commands available in anonymous, unauthenticated vty\n") +{ + restricted_mode = 1; + return CMD_SUCCESS; +} + +DEFUN (vty_no_restricted_mode, + vty_no_restricted_mode_cmd, + "no anonymous restricted", + NO_STR + "Enable password checking\n") +{ + restricted_mode = 0; + return CMD_SUCCESS; +} + DEFUN (service_advanced_vty, service_advanced_vty_cmd, "service advanced-vty", @@ -2812,7 +2840,15 @@ vty_config_write (struct vty *vty) /* login */ if (no_password_check) vty_out (vty, " no login%s", VTY_NEWLINE); - + + if (restricted_mode != restricted_mode_default) + { + if (restricted_mode_default) + vty_out (vty, " no anonymous restricted%s", VTY_NEWLINE); + else + vty_out (vty, " anonymous restricted%s", VTY_NEWLINE); + } + vty_out (vty, "!%s", VTY_NEWLINE); return CMD_SUCCESS; @@ -2923,6 +2959,8 @@ vty_init (struct thread_master *master_thread) /* Install bgp top node. */ install_node (&vty_node, vty_config_write); + install_element (RESTRICTED_NODE, &config_who_cmd); + install_element (RESTRICTED_NODE, &show_history_cmd); install_element (VIEW_NODE, &config_who_cmd); install_element (VIEW_NODE, &show_history_cmd); install_element (ENABLE_NODE, &config_who_cmd); @@ -2943,6 +2981,8 @@ vty_init (struct thread_master *master_thread) install_element (VTY_NODE, &no_vty_access_class_cmd); install_element (VTY_NODE, &vty_login_cmd); install_element (VTY_NODE, &no_vty_login_cmd); + install_element (VTY_NODE, &vty_restricted_mode_cmd); + install_element (VTY_NODE, &vty_no_restricted_mode_cmd); #ifdef HAVE_IPV6 install_element (VTY_NODE, &vty_ipv6_access_class_cmd); install_element (VTY_NODE, &no_vty_ipv6_access_class_cmd); -- cgit v1.2.3