Skip to content

Commit 3f813a2

Browse files
committed
Refactored code to enable supply of ssh options via env var.
1 parent 618b9e3 commit 3f813a2

File tree

2 files changed

+86
-47
lines changed

2 files changed

+86
-47
lines changed

utils/oscap-ssh

Lines changed: 79 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,37 @@ function usage()
8080
echo "specific option for oscap-ssh (must be first argument):"
8181
echo " --sudo"
8282
echo
83+
echo "To supply additional options to ssh/scp, define the SSH_ADDITIONAL_OPTIONS variable"
84+
echo "For instance, to ignore known hosts records, define SSH_ADDITIONAL_OPTIONS='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'"
85+
echo
86+
echo "specific option for oscap-ssh (must be first argument):"
87+
echo
8388
echo "See \`man oscap\` to learn more about semantics of these options."
8489
}
8590

8691
OSCAP_SUDO=""
87-
SSH_ADDITIONAL_ARGS=""
92+
# SSH_ADDITIONAL_OPTIONS may be defined in the calling shell
93+
SSH_TTY_ALLOCATION_OPTION=""
94+
95+
# $1: The SSH command.
96+
# $2: More of additional options (optional, space-separated string)
97+
function ssh_execute_with_options {
98+
ssh -o ControlPath="$MASTER_SOCKET" $SSH_ADDITIONAL_OPTIONS $2 -p "$SSH_PORT" "$SSH_HOST" "$1"
99+
}
100+
101+
# $1: Local filename to copy
102+
# $2: Remote destination
103+
function scp_copy_to_temp_dir {
104+
scp -o ControlPath="$MASTER_SOCKET" -P "$SSH_PORT" $SSH_ADDITIONAL_OPTIONS "$1" "$SSH_HOST:$REMOTE_TEMP_DIR/$2"
105+
}
106+
107+
# $1: Remote filename to get
108+
# $2: Local destination
109+
function scp_retreive_from_temp_dir {
110+
scp -o ControlPath="$MASTER_SOCKET" -P "$SSH_PORT" $SSH_ADDITIONAL_OPTIONS "$SSH_HOST:$REMOTE_TEMP_DIR/$1" "$2"
111+
}
112+
113+
function sanity_check_arguments {
88114
if [ $# -lt 1 ]; then
89115
echo "No arguments provided."
90116
usage
@@ -95,46 +121,53 @@ elif [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
95121
elif [ "$1" == "sudo" ] || [ "$1" == "--sudo" ]; then
96122
OSCAP_SUDO="sudo"
97123
# force pseudo-tty allocation so that users can type their password if necessary
98-
SSH_ADDITIONAL_ARGS="-t"
124+
SSH_TTY_ALLOCATION_OPTION="-t"
99125
shift
100126
fi
101127
if [ $# -lt 2 ]; then
102128
echo "Missing ssh host and ssh port."
103129
usage
104130
die
105131
fi
132+
}
106133

107-
SSH_HOST="$1"
108-
SSH_PORT="$2"
109-
110-
if [ "$3" == "--v" ] || [ "$3" == "--version" ]; then
134+
function check_oscap_arguments {
135+
if [ "$1" == "--v" ] || [ "$1" == "--version" ]; then
111136
true
112-
elif [ "$3" == "-h" ] || [ "$3" == "--help" ]; then
137+
elif [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
113138
true
114-
elif [ "$3" == "info" ]; then
139+
elif [ "$1" == "info" ]; then
115140
true
116-
elif [ "$3 $4" == "xccdf eval" ]; then
141+
elif [ "$1 $2" == "xccdf eval" ]; then
117142
true
118-
elif [ "$3 $4" == "oval eval" ]; then
143+
elif [ "$1 $2" == "oval eval" ]; then
119144
true
120-
elif [ "$3 $4" == "oval collect" ]; then
145+
elif [ "$1 $2" == "oval collect" ]; then
121146
true
122147
else
123148
die "This script only supports '-h', '--help', '--v', '--version', 'info', 'xccdf eval', 'oval eval' and 'oval collect'."
124149
fi
150+
}
151+
152+
sanity_check_arguments "$@"
153+
154+
SSH_HOST="$1"
155+
SSH_PORT="$2"
125156

126157
shift 2
127158

159+
check_oscap_arguments "$@"
160+
128161
MASTER_SOCKET_DIR=$(mktemp -d)
129162
MASTER_SOCKET="$MASTER_SOCKET_DIR/ssh_socket"
130163

131164
echo "Connecting to '$SSH_HOST' on port '$SSH_PORT'..."
132-
ssh -M -f -N -o ServerAliveInterval=60 -o ControlPath="$MASTER_SOCKET" -p "$SSH_PORT" "$SSH_HOST" || die "Failed to connect!"
165+
ssh -M -f -N -o ServerAliveInterval=60 -o ControlPath="$MASTER_SOCKET" -p "$SSH_PORT" $SSH_ADDITIONAL_OPTIONS "$SSH_HOST" || die "Failed to connect!"
133166
echo "Connected!"
134167

135-
REMOTE_TEMP_DIR=$(ssh -o ControlPath="$MASTER_SOCKET" -p "$SSH_PORT" "$SSH_HOST" mktemp -d) || die "Failed to create remote temporary directory!"
168+
REMOTE_TEMP_DIR=$(ssh_execute_with_options "mktemp -d") || die "Failed to create remote temporary directory!"
136169

137-
args=("$@")
170+
oscap_args=("$@")
138171

139172
LOCAL_CONTENT_PATH=""
140173
LOCAL_TAILORING_PATH=""
@@ -151,38 +184,38 @@ OVAL_RESULTS=""
151184
for i in $(seq 0 `expr $# - 1`); do
152185
let j=i+1
153186

154-
case "${args[i]}" in
187+
case "${oscap_args[i]}" in
155188
("--tailoring-file")
156-
LOCAL_TAILORING_PATH=${args[j]}
157-
args[j]="$REMOTE_TEMP_DIR/tailoring.xml"
189+
LOCAL_TAILORING_PATH=${oscap_args[j]}
190+
oscap_args[j]="$REMOTE_TEMP_DIR/tailoring.xml"
158191
;;
159192
("--cpe")
160-
LOCAL_CPE_PATH=${args[j]}
161-
args[j]="$REMOTE_TEMP_DIR/cpe.xml"
193+
LOCAL_CPE_PATH=${oscap_args[j]}
194+
oscap_args[j]="$REMOTE_TEMP_DIR/cpe.xml"
162195
;;
163196
("--variables")
164-
LOCAL_VARIABLES_PATH=${args[j]}
165-
args[j]="$REMOTE_TEMP_DIR/variables.xml"
197+
LOCAL_VARIABLES_PATH=${oscap_args[j]}
198+
oscap_args[j]="$REMOTE_TEMP_DIR/variables.xml"
166199
;;
167200
("--directives")
168-
LOCAL_DIRECTIVES_PATH=${args[j]}
169-
args[j]="$REMOTE_TEMP_DIR/directives.xml"
201+
LOCAL_DIRECTIVES_PATH=${oscap_args[j]}
202+
oscap_args[j]="$REMOTE_TEMP_DIR/directives.xml"
170203
;;
171204
("--results")
172-
TARGET_RESULTS=${args[j]}
173-
args[j]="$REMOTE_TEMP_DIR/results.xml"
205+
TARGET_RESULTS=${oscap_args[j]}
206+
oscap_args[j]="$REMOTE_TEMP_DIR/results.xml"
174207
;;
175208
("--results-arf")
176-
TARGET_RESULTS_ARF=${args[j]}
177-
args[j]="$REMOTE_TEMP_DIR/results-arf.xml"
209+
TARGET_RESULTS_ARF=${oscap_args[j]}
210+
oscap_args[j]="$REMOTE_TEMP_DIR/results-arf.xml"
178211
;;
179212
("--report")
180-
TARGET_REPORT=${args[j]}
181-
args[j]="$REMOTE_TEMP_DIR/report.html"
213+
TARGET_REPORT=${oscap_args[j]}
214+
oscap_args[j]="$REMOTE_TEMP_DIR/report.html"
182215
;;
183216
("--syschar")
184-
TARGET_SYSCHAR=${args[j]}
185-
args[j]="$REMOTE_TEMP_DIR/syschar.xml"
217+
TARGET_SYSCHAR=${oscap_args[j]}
218+
oscap_args[j]="$REMOTE_TEMP_DIR/syschar.xml"
186219
;;
187220
("--oval-results")
188221
OVAL_RESULTS="yes"
@@ -194,8 +227,8 @@ done
194227

195228
if [ "$1" != "--v" ] && [ "$1" != "--version" ] && [ "$1" != "-h" ] && [ "$1" != "--help" ]; then
196229
# Last argument should be the content path
197-
LOCAL_CONTENT_PATH="${args[`expr $# - 1`]}"
198-
args[`expr $# - 1`]="$REMOTE_TEMP_DIR/input.xml"
230+
LOCAL_CONTENT_PATH="${oscap_args[`expr $# - 1`]}"
231+
oscap_args[`expr $# - 1`]="$REMOTE_TEMP_DIR/input.xml"
199232
fi
200233

201234
[ "$LOCAL_CONTENT_PATH" == "" ] || [ -f "$LOCAL_CONTENT_PATH" ] || die "Expected the last argument to be an input file, '$LOCAL_CONTENT_PATH' isn't a valid file path or the file doesn't exist!"
@@ -206,54 +239,54 @@ fi
206239

207240
if [ "$LOCAL_CONTENT_PATH" != "" ]; then
208241
echo "Copying input file '$LOCAL_CONTENT_PATH' to remote working directory '$REMOTE_TEMP_DIR'..."
209-
scp -o ControlPath="$MASTER_SOCKET" -P "$SSH_PORT" "$LOCAL_CONTENT_PATH" "$SSH_HOST:$REMOTE_TEMP_DIR/input.xml" || die "Failed to copy input file to remote temporary directory!"
242+
scp_copy_to_temp_dir "$LOCAL_CONTENT_PATH" input.xml || die "Failed to copy input file to remote temporary directory!"
210243
fi
211244
if [ "$LOCAL_TAILORING_PATH" != "" ]; then
212245
echo "Copying tailoring file '$LOCAL_TAILORING_PATH' to remote working directory '$REMOTE_TEMP_DIR'..."
213-
scp -o ControlPath="$MASTER_SOCKET" -P "$SSH_PORT" "$LOCAL_TAILORING_PATH" "$SSH_HOST:$REMOTE_TEMP_DIR/tailoring.xml" || die "Failed to copy tailoring file to remote temporary directory!"
246+
scp_copy_to_temp_dir "$LOCAL_TAILORING_PATH" tailoring.xml || die "Failed to copy tailoring file to remote temporary directory!"
214247
fi
215248
if [ "$LOCAL_CPE_PATH" != "" ]; then
216249
echo "Copying CPE file '$LOCAL_CPE_PATH' to remote working directory '$REMOTE_TEMP_DIR'..."
217-
scp -o ControlPath="$MASTER_SOCKET" -P "$SSH_PORT" "$LOCAL_CPE_PATH" "$SSH_HOST:$REMOTE_TEMP_DIR/cpe.xml" || die "Failed to copy CPE file to remote temporary directory!"
250+
scp_copy_to_temp_dir "$LOCAL_CPE_PATH" cpe.xml || die "Failed to copy CPE file to remote temporary directory!"
218251
fi
219252
if [ "$LOCAL_VARIABLES_PATH" != "" ]; then
220253
echo "Copying OVAL variables file '$LOCAL_VARIABLES_PATH' to remote working directory '$REMOTE_TEMP_DIR'..."
221-
scp -o ControlPath="$MASTER_SOCKET" -P "$SSH_PORT" "$LOCAL_VARIABLES_PATH" "$SSH_HOST:$REMOTE_TEMP_DIR/variables.xml" || die "Failed to copy OVAL variables file to remote temporary directory!"
254+
scp_copy_to_temp_dir "$LOCAL_VARIABLES_PATH" variables.xml || die "Failed to copy OVAL variables file to remote temporary directory!"
222255
fi
223256
if [ "$LOCAL_DIRECTIVES_PATH" != "" ]; then
224257
echo "Copying OVAL directives file '$LOCAL_DIRECTIVES_PATH' to remote working directory '$REMOTE_TEMP_DIR'..."
225-
scp -o ControlPath="$MASTER_SOCKET" -P "$SSH_PORT" "$LOCAL_DIRECTIVES_PATH" "$SSH_HOST:$REMOTE_TEMP_DIR/directives.xml" || die "Failed to copy OVAL directives file to remote temporary directory!"
258+
scp_copy_to_temp_dir "$LOCAL_DIRECTIVES_PATH" directives.xml || die "Failed to copy OVAL directives file to remote temporary directory!"
226259
fi
227260

228261
echo "Starting the evaluation..."
229262
# changing directory because of --oval-results support. oval results files are
230263
# dumped into PWD, and we can't be sure by the file names - we need controlled
231264
# environment
232-
ssh -o ControlPath="$MASTER_SOCKET" $SSH_ADDITIONAL_ARGS -p "$SSH_PORT" "$SSH_HOST" "cd $REMOTE_TEMP_DIR; $OSCAP_SUDO oscap ${args[*]}"
265+
ssh_execute_with_options "cd $REMOTE_TEMP_DIR; $OSCAP_SUDO oscap ${oscap_args[*]}" "$SSH_TTY_ALLOCATION_OPTION"
233266
OSCAP_EXIT_CODE=$?
234267
echo "oscap exit code: $OSCAP_EXIT_CODE"
235268

236269
echo "Copying back requested files..."
237270
if [ "$TARGET_RESULTS" != "" ]; then
238-
scp -o ControlPath="$MASTER_SOCKET" -P "$SSH_PORT" "$SSH_HOST:$REMOTE_TEMP_DIR/results.xml" "$TARGET_RESULTS" || die "Failed to copy the results file back to local machine!"
271+
scp_retreive_from_temp_dir results.xml "$TARGET_RESULTS" || die "Failed to copy the results file back to local machine!"
239272
fi
240273
if [ "$TARGET_RESULTS_ARF" != "" ]; then
241-
scp -o ControlPath="$MASTER_SOCKET" -P "$SSH_PORT" "$SSH_HOST:$REMOTE_TEMP_DIR/results-arf.xml" "$TARGET_RESULTS_ARF" || die "Failed to copy the ARF file back to local machine!"
274+
scp_retreive_from_temp_dir results-arf.xml "$TARGET_RESULTS_ARF" || die "Failed to copy the ARF file back to local machine!"
242275
fi
243276
if [ "$TARGET_REPORT" != "" ]; then
244-
scp -o ControlPath="$MASTER_SOCKET" -P "$SSH_PORT" "$SSH_HOST:$REMOTE_TEMP_DIR/report.html" "$TARGET_REPORT" || die "Failed to copy the HTML report back to local machine!"
277+
scp_retreive_from_temp_dir report.html "$TARGET_REPORT" || die "Failed to copy the HTML report back to local machine!"
245278
fi
246279
if [ "$TARGET_SYSCHAR" != "" ]; then
247-
scp -o ControlPath="$MASTER_SOCKET" -P "$SSH_PORT" "$SSH_HOST:$REMOTE_TEMP_DIR/syschar.xml" "$TARGET_SYSCHAR" || die "Failed to copy the OVAL syschar file back to local machine!"
280+
scp_retreive_from_temp_dir syschar.xml "$TARGET_SYSCHAR" || die "Failed to copy the OVAL syschar file back to local machine!"
248281
fi
249282
if [ "$OVAL_RESULTS" == "yes" ]; then
250-
scp -o ControlPath="$MASTER_SOCKET" -P "$SSH_PORT" "$SSH_HOST:$REMOTE_TEMP_DIR/*.result.xml" "./" || die "Failed to copy OVAL result files back to local machine!"
283+
scp_retreive_from_temp_dir '*.result.xml' "./" || die "Failed to copy OVAL result files back to local machine!"
251284
fi
252285

253286
echo "Removing remote temporary directory..."
254-
ssh -o ControlPath="$MASTER_SOCKET" -p "$SSH_PORT" "$SSH_HOST" "rm -r $REMOTE_TEMP_DIR" || die "Failed to remove remote temporary directory!"
287+
ssh_execute_with_options "rm -r $REMOTE_TEMP_DIR" || die "Failed to remove remote temporary directory!"
255288
echo "Disconnecting ssh and removing master ssh socket directory..."
256-
ssh -o ControlPath="$MASTER_SOCKET" -p "$SSH_PORT" "$SSH_HOST" -O exit || die "Failed to disconnect!"
289+
ssh -o ControlPath="$MASTER_SOCKET" $SSH_ADDITIONAL_OPTIONS -p "$SSH_PORT" "$SSH_HOST" -O exit || die "Failed to disconnect!"
257290
rm -r "$MASTER_SOCKET_DIR" || die "Failed to remove local master SSH socket directory!"
258291

259292
exit $OSCAP_EXIT_CODE

utils/oscap-ssh.8

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,16 @@ Supported options are:
6060
Specific option for oscap-ssh (must be first argument):
6161
--sudo
6262

63-
.SH EXEMPLARY USAGE
63+
.SS Environment variables
64+
oscap-ssh checks out the SSH_ADDITIONAL_OPTIONS environment variable, and pastes its contents into the command-line of ssh to the location where options are expected.
65+
Supply the variable in form of a string that corresponds to a section of the ssh command-line and that consists of options you want to pass.
66+
67+
.SH EXAMPLE USAGE
6468
.SS Simple XCCDF evaluation
6569
The following command evaluates a remote Fedora machine as root. HTML report is written out as report.html on the local machine. Can be executed from any machine that has ssh, scp and bash. The local machine does not need to have openscap installed.
70+
It also uses the SSH_ADDITIONAL_OPTIONS variable to configure ssh in such way that contents of the known_hosts file are ignored.
6671

72+
$ export SSH_ADDITIONAL_OPTIONS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
6773
$ oscap-ssh [email protected] 22 xccdf eval --profile xccdf_org.ssgproject.content_profile_common --report report.html /usr/share/xml/scap/ssg/content/ssg-fedora-ds.xml
6874

6975
.SS XCCDF Evaluation with tailoring file

0 commit comments

Comments
 (0)