Skip to content

Commit 6cd7d2d

Browse files
authored
Merge pull request #1393 from evgenyz/offline-env
Offline mode support for environmentvariable58_probe
2 parents 716c7f4 + 4e17d67 commit 6cd7d2d

File tree

6 files changed

+54
-15
lines changed

6 files changed

+54
-15
lines changed

src/OVAL/probes/independent/environmentvariable58_probe.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,15 @@
5151
#include <sys/types.h>
5252
#include <dirent.h>
5353

54+
#include <probe/probe.h>
5455
#include "_seap.h"
5556
#include "probe-api.h"
5657
#include "probe/entcmp.h"
5758
#include "common/debug_priv.h"
5859
#include "environmentvariable58_probe.h"
5960

6061
#define BUFFER_SIZE 256
62+
#define VAR_OFFLINE_PREFIX "OSCAP_OFFLINE_"
6163

6264
extern char **environ;
6365

@@ -156,16 +158,28 @@ static int read_environment(SEXP_t *pid_ent, SEXP_t *name_ent, probe_ctx *ctx)
156158
continue;
157159
}
158160

159-
env_name_size = eq_char - buffer;
160-
env_name = SEXP_string_new(buffer, env_name_size);
161+
env_name_size = eq_char - buffer;
162+
if (ctx->offline_mode == PROBE_OFFLINE_OWN) {
163+
// We are not processing unprefixed (i.e. originated from the host) variables in offline mode
164+
if (memmem(buffer, env_name_size, VAR_OFFLINE_PREFIX, strlen(VAR_OFFLINE_PREFIX)) != buffer
165+
|| strlen(VAR_OFFLINE_PREFIX) >= env_name_size) {
166+
buffer_used -= null_char + 1 - buffer;
167+
memmove(buffer, null_char + 1, buffer_used);
168+
continue;
169+
}
170+
env_name = SEXP_string_new(buffer + strlen(VAR_OFFLINE_PREFIX), env_name_size - strlen(VAR_OFFLINE_PREFIX));
171+
} else {
172+
env_name = SEXP_string_new(buffer, env_name_size);
173+
}
161174
env_value = SEXP_string_newf("%s", buffer + env_name_size + 1);
175+
162176
if (probe_entobj_cmp(name_ent, env_name) == OVAL_RESULT_TRUE) {
163177
item = probe_item_create(
164178
OVAL_INDEPENDENT_ENVIRONMENT_VARIABLE58, NULL,
165179
"pid", OVAL_DATATYPE_INTEGER, (int64_t)pid,
166180
"name", OVAL_DATATYPE_SEXP, env_name,
167181
"value", OVAL_DATATYPE_SEXP, env_value,
168-
NULL);
182+
NULL);
169183
probe_item_collect(ctx, item);
170184
err = 0;
171185
}
@@ -192,6 +206,11 @@ static int read_environment(SEXP_t *pid_ent, SEXP_t *name_ent, probe_ctx *ctx)
192206
return err;
193207
}
194208

209+
int environmentvariable58_probe_offline_mode_supported(void)
210+
{
211+
return PROBE_OFFLINE_OWN;
212+
}
213+
195214
int environmentvariable58_probe_main(probe_ctx *ctx, void *arg)
196215
{
197216
SEXP_t *probe_in, *name_ent, *pid_ent;
@@ -229,9 +248,16 @@ int environmentvariable58_probe_main(probe_ctx *ctx, void *arg)
229248
SEXP_free(nref);
230249
SEXP_free(nval);
231250
pid_ent = new_pid_ent;
251+
} else {
252+
if (ctx->offline_mode != PROBE_OFFLINE_NONE) {
253+
err = PROBE_EINVAL;
254+
goto cleanup;
255+
}
232256
}
233257

234258
err = read_environment(pid_ent, name_ent, ctx);
259+
260+
cleanup:
235261
SEXP_free(name_ent);
236262
SEXP_free(pid_ent);
237263

src/OVAL/probes/independent/environmentvariable58_probe.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include "probe-api.h"
2727

28+
int environmentvariable58_probe_offline_mode_supported(void);
2829
int environmentvariable58_probe_main(probe_ctx *ctx, void *arg);
2930

3031
#endif /* OPENSCAP_ENVIRONMENTVARIABLE58_PROBE_H */

src/OVAL/probes/probe-table.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ static const probe_table_entry_t probe_table[] = {
213213
{OVAL_INDEPENDENT_ENVIRONMENT_VARIABLE, NULL, environmentvariable_probe_main, NULL, NULL},
214214
#endif
215215
#ifdef OPENSCAP_PROBE_INDEPENDENT_ENVIRONMENTVARIABLE58
216-
{OVAL_INDEPENDENT_ENVIRONMENT_VARIABLE58, NULL, environmentvariable58_probe_main, NULL, NULL},
216+
{OVAL_INDEPENDENT_ENVIRONMENT_VARIABLE58, NULL, environmentvariable58_probe_main, NULL, environmentvariable58_probe_offline_mode_supported},
217217
#endif
218218
#ifdef OPENSCAP_PROBE_INDEPENDENT_FAMILY
219219
{OVAL_INDEPENDENT_FAMILY, NULL, family_probe_main, NULL, family_probe_offline_mode_supported},

utils/oscap-podman

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,26 @@ function usage()
2828
echo "oscap-podman -- Tool for SCAP evaluation of Podman images and containers."
2929
echo
3030
echo "Compliance scan of Podman image:"
31-
echo "$ sudo oscap-podman IMAGE_NAME OSCAP_ARGUMENT [OSCAP_ARGUMENT...]"
31+
echo "$ sudo oscap-podman [--oscap=<OSCAP_BINARY>] IMAGE_NAME OSCAP_ARGUMENT [OSCAP_ARGUMENT...]"
3232
echo
3333
echo "Compliance scan of Podman container:"
34-
echo "$ sudo oscap-podman CONTAINER_NAME OSCAP_ARGUMENT [OSCAP_ARGUMENT...]"
34+
echo "$ sudo oscap-podman [--oscap=<OSCAP_BINARY>] CONTAINER_NAME OSCAP_ARGUMENT [OSCAP_ARGUMENT...]"
3535
echo
3636
echo "See \`man oscap\` to learn more about semantics of OSCAP_ARGUMENT options."
3737
}
3838

39+
OSCAP_BINARY=oscap
40+
3941
if [ $# -lt 1 ]; then
4042
echo "No arguments provided."
4143
usage
4244
die
4345
elif [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
4446
usage
4547
die
48+
elif [[ "$1" == --oscap=* ]] && [ $# -gt 2 ]; then
49+
OSCAP_BINARY=${1#"--oscap="}
50+
shift
4651
elif [ "$#" -gt 1 ]; then
4752
true
4853
else
@@ -74,14 +79,18 @@ else
7479
fi
7580
DIR=$(podman mount $ID) || die
7681

82+
for VAR in `podman inspect $ID --format '{{join .Config.Env " "}}'`; do
83+
eval "export OSCAP_OFFLINE_$VAR"
84+
done
85+
7786
export OSCAP_PROBE_ROOT="$(cd "$DIR"; pwd)"
7887
export OSCAP_PROBE_OS_NAME="Linux"
7988
export OSCAP_PROBE_OS_VERSION="$(uname --kernel-release)"
8089
export OSCAP_PROBE_ARCHITECTURE="$(uname --hardware-platform)"
8190
export OSCAP_EVALUATION_TARGET="$TARGET"
8291
shift 1
8392

84-
oscap "$@"
93+
$OSCAP_BINARY "$@"
8594
EXIT_CODE=$?
8695
podman umount $ID > /dev/null || die
8796
if [ $CLEANUP -eq 1 ]; then

utils/oscap-podman.8

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ This script cannot run in rootless mode.
1212
Usage of the tool mimics usage and options of oscap(8) tool.
1313

1414
.SS Compliance scan of Podman container image:
15-
oscap-podman IMAGE_NAME OSCAP_ARGUMENT [OSCAP_ARGUMENT...]
15+
oscap-podman [--oscap=<OSCAP_BINARY>] IMAGE_NAME OSCAP_ARGUMENT [OSCAP_ARGUMENT...]
1616

1717
.SS Compliance scan of Podman container:
18-
oscap-podman CONTAINER_NAME OSCAP_ARGUMENT [OSCAP_ARGUMENT...]
18+
oscap-podman [--oscap=<OSCAP_BINARY>] CONTAINER_NAME OSCAP_ARGUMENT [OSCAP_ARGUMENT...]
1919

2020
Refer to oscap(8) to learn about OSCAP_ARGUMENT options.
2121

utils/oscap_docker_python/oscap_docker_util.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ def _get_dist(self, chroot, target):
115115
if "{0}{1}: true".format(self.CPE, dist) in result.stdout:
116116
return dist
117117

118-
def _get_target_name(self, target):
118+
def _get_target_name_and_config(self, target):
119119
'''
120120
Determines if target is image or container. For images returns full
121121
image name if exists or image ID otherwise. For containers returns
@@ -131,28 +131,31 @@ def _get_target_name(self, target):
131131
name = ", ".join(image["RepoTags"])
132132
else:
133133
name = image["Id"][len("sha256:"):][:10]
134-
return "docker-image://{}".format(name)
134+
return "docker-image://{}".format(name), image["Config"]
135135
except docker.errors.NotFound:
136136
try:
137137
container = client.inspect_container(target)
138138
if container["Name"]:
139139
name = container["Name"].lstrip("/")
140140
else:
141141
name = container["Id"][:10]
142-
return "docker-container://{}".format(name)
142+
return "docker-container://{}".format(name), container["Config"]
143143
except docker.errors.NotFound:
144-
return "unknown"
144+
return "unknown", {}
145145

146146
def oscap_chroot(self, chroot_path, target, *oscap_args):
147147
'''
148148
Wrapper function for executing oscap in a subprocess
149149
'''
150-
151150
os.environ["OSCAP_PROBE_ARCHITECTURE"] = platform.processor()
152151
os.environ["OSCAP_PROBE_ROOT"] = os.path.join(chroot_path)
153152
os.environ["OSCAP_PROBE_OS_NAME"] = platform.system()
154153
os.environ["OSCAP_PROBE_OS_VERSION"] = platform.release()
155-
os.environ["OSCAP_EVALUATION_TARGET"] = self._get_target_name(target)
154+
name, conf = self._get_target_name_and_config(target)
155+
os.environ["OSCAP_EVALUATION_TARGET"] = name
156+
for var in config.get("Env", []):
157+
vname, val = var.split("=", 1)
158+
os.environ["OSCAP_OFFLINE_"+vname] = val
156159
cmd = [self.oscap_binary] + [x for x in oscap_args]
157160
oscap_process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
158161
oscap_stdout, oscap_stderr = oscap_process.communicate()

0 commit comments

Comments
 (0)