Skip to content

Commit 5ea9968

Browse files
committed
bin: backport fixes to shell/cli copy command
This is a backport of the following commits from origin/main: 3b24fab e6a04fb 92e80b4 ad96965 3e03ece 21256a8 b7d91e4 d26e311 0977ab4 f83fbc6 --- cli: fix 'copy FILE running-config' use-case When copying to the running datastore we cannot use sr_copy_config(), instead we must use sr_replace_config(). This fix covers both the case of 'copy startup-config running-config' and 'copy FILE running-config'. Fixes #1203 --- cli: add 'validate', or '-n', dry run to copy command This commit adds config file validation to the copy command, discussed in #373. Allowing users to test their config files before restoring a backup. The feature could also be used for the automatic rollback when downgrading to an earlier version of the OS. Fixes #373 --- cli: fix copy to missing startup-config file Fixes #981 --- cli: restrict copy and erase commands This is a follow-up to PR #717 where path traversal protection was discussed. A year later and it's clear that having a user-friendly copy tool in the shell is a good thing, but that we proably want to restrict what it can do when called from the CLI. A sanitize flag (-s) is added to control the behavior, when used in the shell without -s, both commands act like traditional UNIX tools and do assume . for relative paths, and allow ../, whereas when running from the CLI only /media/ is allowed and otherwise files are assumed to be in $HOME or /cfg --- cli: sanitize regular file to file copy The regular file-to-file copy, was missing calls to cfg_adjust(), this commit fixes that and adds some helpful comments for each use-case. Also, drop insecure mktemp() in favor of our own version which uses the basename of the remote source file. --- bin: add bash completion for copy command Add bash completion for the common datastores, like we already do in the CLI, and update the usage text accordingly. Also, make sure to install to /usr/bin, not /bin since we've now merged the hierarchies since a while back. --- bin: copy: Refactor copy() made some...creative...use of control flow that made it quite difficult to follow. Take a first priciples approach to simplify the logic. --- bin: copy: Always get startup from sysrepo This will make sure to apply NACM rules for all the data. It also makes it possible for a luser access a subset of the data, even if they to do not have read access to /cfg/startup-config.cfg. Signed-off-by: Joachim Wiberg <[email protected]>
1 parent 55b038d commit 5ea9968

File tree

10 files changed

+648
-295
lines changed

10 files changed

+648
-295
lines changed

package/bin/bin.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ BIN_LICENSE = BSD-3-Clause
1111
BIN_LICENSE_FILES = LICENSE
1212
BIN_REDISTRIBUTE = NO
1313
BIN_DEPENDENCIES = sysrepo libite
14-
BIN_CONF_OPTS = --prefix= --disable-silent-rules
14+
BIN_CONF_OPTS = --disable-silent-rules
1515
BIN_AUTORECONF = YES
1616

1717
define BIN_CONF_ENV

src/bin/Makefile.am

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@ ACLOCAL_AMFLAGS = -I m4
33

44
bin_PROGRAMS = copy erase files
55

6+
# Bash completion
7+
bashcompdir = $(datadir)/bash-completion/completions
8+
dist_bashcomp_DATA = copy.bash
9+
610
copy_SOURCES = copy.c util.c util.h
711
copy_CPPFLAGS = -D_DEFAULT_SOURCE -D_GNU_SOURCE
812
copy_CFLAGS = -W -Wall -Wextra
9-
copy_CFLAGS += $(libite_CFLAGS) $(sysrepo_CFLAGS)
10-
copy_LDADD = $(libite_LIBS) $(sysrepo_LIBS)
13+
copy_CFLAGS += $(libite_CFLAGS) $(libyang_CFLAGS) $(sysrepo_CFLAGS)
14+
copy_LDADD = $(libite_LIBS) $(libyang_LIBS) $(sysrepo_LIBS)
1115

1216
erase_SOURCES = erase.c util.c util.h
1317
erase_CPPFLAGS = -D_DEFAULT_SOURCE -D_GNU_SOURCE

src/bin/configure.ac

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ AC_PROG_INSTALL
1515
PKG_PROG_PKG_CONFIG
1616

1717
PKG_CHECK_MODULES([libite], [libite >= 2.5.0])
18+
PKG_CHECK_MODULES([libyang], [libyang >= 3.0.0])
1819
PKG_CHECK_MODULES([sysrepo], [sysrepo >= 2.2.36])
1920

2021
# Misc variable replacements for below Summary
@@ -55,8 +56,8 @@ cat <<EOF
5556
System environment....: ${sysconfig_path:-${sysconfig}}
5657
C Compiler............: $CC $CFLAGS $CPPFLAGS $LDFLAGS $LIBS
5758
Linker................: $LD $LLDP_LDFLAGS $LLDP_BIN_LDFLAGS $LDFLAGS $LIBS
58-
CFLAGS................: $libite_CFLAGS $sysrepo_CFLAGS
59-
LIBS..................: $libite_LIBS $sysrepo_LIBS
59+
CFLAGS................: $libite_CFLAGS $libyang_CFLAGS $sysrepo_CFLAGS
60+
LIBS..................: $libite_LIBS $libyang_LIBS $sysrepo_LIBS
6061

6162
------------- Compiler version --------------
6263
$($CC --version || true)

src/bin/copy.bash

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# bash completion for copy command
2+
# SPDX-License-Identifier: ISC
3+
4+
_copy_completion()
5+
{
6+
local cur prev opts
7+
COMPREPLY=()
8+
cur="${COMP_WORDS[COMP_CWORD]}"
9+
prev="${COMP_WORDS[COMP_CWORD-1]}"
10+
11+
# Options for the copy command
12+
opts="-h -n -q -s -t -u -v"
13+
14+
local datastores_dst="running-config startup-config"
15+
local datastores_src="factory-config operational-state running-config"
16+
17+
case "${prev}" in
18+
-t)
19+
# Timeout expects a number, no completion
20+
return 0
21+
;;
22+
-u)
23+
# Username, could complete with getent passwd but keep it simple
24+
return 0
25+
;;
26+
esac
27+
28+
# If current word starts with -, complete options
29+
if [[ ${cur} == -* ]]; then
30+
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
31+
return 0
32+
fi
33+
34+
# Determine position (source or destination)
35+
# Count non-option arguments before current position
36+
local arg_count=0
37+
local i
38+
for ((i=1; i < COMP_CWORD; i++)); do
39+
case "${COMP_WORDS[i]}" in
40+
-h|-n|-q|-s|-v)
41+
# Flag without argument
42+
;;
43+
-t|-u)
44+
# Flag with argument, skip next word
45+
((i++))
46+
;;
47+
-*)
48+
# Unknown flag, might have argument
49+
;;
50+
*)
51+
# Non-option argument
52+
((arg_count++))
53+
;;
54+
esac
55+
done
56+
57+
# Helper function to add non-hidden files/dirs, filtering out dotfiles unless explicitly requested
58+
_add_files() {
59+
local IFS=$'\n'
60+
local files
61+
62+
# If user is explicitly typing a dotfile path, include dotfiles
63+
if [[ ${cur} == .* || ${cur} == */.* ]]; then
64+
files=( $(compgen -f -- "${cur}") )
65+
else
66+
# Only show non-hidden files and directories
67+
files=( $(compgen -f -- "${cur}" | grep -v '/\.[^/]*$' | grep -v '^\.[^/]') )
68+
fi
69+
70+
COMPREPLY+=( "${files[@]}" )
71+
}
72+
73+
case ${arg_count} in
74+
0)
75+
# First argument (source): complete with files and all datastores including factory-config
76+
COMPREPLY=( $(compgen -W "${datastores_src}" -- ${cur}) )
77+
_add_files
78+
;;
79+
1)
80+
# Second argument (destination): complete with files and limited datastores (no factory-config)
81+
COMPREPLY=( $(compgen -W "${datastores_dst}" -- ${cur}) )
82+
_add_files
83+
;;
84+
*)
85+
# No more arguments expected
86+
return 0
87+
;;
88+
esac
89+
90+
return 0
91+
}
92+
93+
complete -F _copy_completion copy

0 commit comments

Comments
 (0)