Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/OVAL/oval_recordField.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,8 @@ xmlNode *oval_record_field_to_dom(struct oval_record_field *rf, bool parent_mask
root_node = xmlDocGetRootElement(doc);
name = oval_record_field_get_name(rf);
rf_mask = oval_record_field_get_mask(rf);
if (!xmlStrcmp(root_node->name, BAD_CAST OVAL_ROOT_ELM_RESULTS)
if ((!xmlStrcmp(root_node->name, BAD_CAST OVAL_ROOT_ELM_RESULTS) ||
!xmlStrcmp(root_node->name, BAD_CAST OVAL_ROOT_ELM_SYSCHARS))
&& (rf_mask || parent_mask)) {
value = NULL;
masked = true;
Expand Down
5 changes: 3 additions & 2 deletions src/OVAL/oval_sysEnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,9 @@ void oval_sysent_to_dom(struct oval_sysent *sysent, xmlDoc * doc, xmlNode * pare
char *content = oval_sysent_get_value(sysent);
bool mask = oval_sysent_get_mask(sysent);

/* omit the value in oval_results if mask=true */
if (mask && !xmlStrcmp(root_node->name, BAD_CAST OVAL_ROOT_ELM_RESULTS)) {
/* omit the value in oval_results and oval_system_characteristics if mask=true */
if (mask && (!xmlStrcmp(root_node->name, BAD_CAST OVAL_ROOT_ELM_RESULTS) ||
!xmlStrcmp(root_node->name, BAD_CAST OVAL_ROOT_ELM_SYSCHARS))) {
sysent_tag = xmlNewTextChild(parent, ent_ns, BAD_CAST tagname, BAD_CAST "");
} else {
xmlChar *encoded_content = xmlEncodeEntitiesReentrant(doc, BAD_CAST content);
Expand Down
43 changes: 42 additions & 1 deletion src/OVAL/probes/unix/shadow_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,51 @@
SEXP_free_r(&se_flg_mem);
}

static const char *strip_hash(const char *raw, char *buf, size_t buf_len)
{
const char *p;
size_t prefix_len, prefix_with_id_len;

Check warning on line 188 in src/OVAL/probes/unix/shadow_probe.c

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define each identifier in a dedicated statement.

See more on https://sonarcloud.io/project/issues?id=OpenSCAP_openscap&issues=AaDTRleEYguKrrCASYmP&open=AaDTRleEYguKrrCASYmP&pullRequest=2415

if (raw == NULL || *raw == '\0' ||
strcmp(raw, "!") == 0 || strcmp(raw, "!!") == 0 ||
strcmp(raw, "!*") == 0 || strcmp(raw, "*") == 0 ||
strcmp(raw, "*LK*") == 0 || strcmp(raw, "x") == 0)
return raw;

p = raw;
prefix_len = 0;

/* crypt(3) hash ($id$salt$hash), keep lock prefix + method id ($id$) */
while (*p == '!')
p++, prefix_len++;

if (*p == '$') {
const char *id_end = strchr(p + 1, '$');
if (id_end != NULL) {
prefix_with_id_len = (size_t)(id_end + 1 - raw);
if (prefix_with_id_len < buf_len) {
memcpy(buf, raw, prefix_with_id_len);
buf[prefix_with_id_len] = '\0';
return buf;
}
}
}

/* locked account with non-crypt hash, keep lock prefix only */
if (prefix_len > 0 && prefix_len < buf_len) {
memcpy(buf, raw, prefix_len);
buf[prefix_len] = '\0';
return buf;
}

return "*";
}

static void _process_struct_shadow(struct spwd *sp, SEXP_t *un_ent, probe_ctx *ctx)
{
SEXP_t *un;
struct result_info r;
char stripped[8];

dI("Have user: %s", sp->sp_namp);
un = SEXP_string_newf("%s", sp->sp_namp);
Expand All @@ -195,7 +236,7 @@
}

r.username = sp->sp_namp;
r.password = sp->sp_pwdp;
r.password = strip_hash(sp->sp_pwdp, stripped, sizeof(stripped));
r.chg_lst = sp->sp_lstchg;
r.chg_allow = sp->sp_min;
r.chg_req = sp->sp_max;
Expand Down
1 change: 1 addition & 0 deletions tests/probes/shadow/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ if(ENABLE_PROBES_UNIX)
add_oscap_test("test_probes_shadow.sh" LABELS unix)
add_oscap_test("test_probes_shadow_offline.sh" LABELS unix)
add_oscap_test("test_probes_shadow_offline_unsupported.sh" LABELS unix macos)
add_oscap_test("test_probes_shadow_stripped.sh" LABELS unix)
endif()
22 changes: 21 additions & 1 deletion tests/probes/shadow/test_probes_shadow.xml.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,27 @@
echo $LINE | awk -F':' '{print $1}'
;;
'password' )
echo $LINE | awk -F':' '{print $2}'
local pwd=$(echo $LINE | awk -F':' '{print $2}')
case "$pwd" in
''|'!'|'!!'|'!*'|'*'|'*LK*'|'x')
echo "$pwd" ;;
*)
local lock=""
local rest="$pwd"
while [ "${rest:0:1}" = "!" ]; do

Check failure on line 19 in tests/probes/shadow/test_probes_shadow.xml.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=OpenSCAP_openscap&issues=AaDYyHBZ-1W2ofRnI9Cd&open=AaDYyHBZ-1W2ofRnI9Cd&pullRequest=2415
lock="${lock}!"
rest="${rest:1}"
done
if [ "${rest:0:1}" = '$' ]; then

Check failure on line 23 in tests/probes/shadow/test_probes_shadow.xml.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=OpenSCAP_openscap&issues=AaDYyHBZ-1W2ofRnI9Ce&open=AaDYyHBZ-1W2ofRnI9Ce&pullRequest=2415
local id_end=$(echo "$rest" | cut -d '$' -f1-2)
echo "${lock}${id_end}\$"
elif [ -n "$lock" ]; then

Check failure on line 26 in tests/probes/shadow/test_probes_shadow.xml.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=OpenSCAP_openscap&issues=AaDYyHBZ-1W2ofRnI9Cf&open=AaDYyHBZ-1W2ofRnI9Cf&pullRequest=2415
echo "$lock"
else
echo "*"
fi
;;
esac
;;
'chg_lst' )
local CHGLST=`echo $LINE | awk -F':' '{print $3}'`
Expand Down
2 changes: 1 addition & 1 deletion tests/probes/shadow/test_probes_shadow_offline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
<states>
<shadow_state version="1" id="oval:1:ste:1" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<username>root</username>
<password>!locked</password>
<password>!</password>
<chg_lst datatype="int">-1</chg_lst>
<chg_allow datatype="int">0</chg_allow>
<chg_req datatype="int">99999</chg_req>
Expand Down
53 changes: 53 additions & 0 deletions tests/probes/shadow/test_probes_shadow_stripped.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env bash

. $builddir/tests/test_common.sh

set -e -o pipefail

function test_probes_shadow_stripped {

probecheck "shadow" || return 255

local ret_val=0
local DF="${srcdir}/test_probes_shadow_stripped.xml"

Check warning on line 12 in tests/probes/shadow/test_probes_shadow_stripped.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Local variable 'DF' should use lower_case naming convention.

See more on https://sonarcloud.io/project/issues?id=OpenSCAP_openscap&issues=AaDTRljgYguKrrCASYmQ&open=AaDTRljgYguKrrCASYmQ&pullRequest=2415
local RF="$(mktemp results.XXXXXXX.xml)"

Check warning on line 13 in tests/probes/shadow/test_probes_shadow_stripped.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Local variable 'RF' should use lower_case naming convention.

See more on https://sonarcloud.io/project/issues?id=OpenSCAP_openscap&issues=AaDTRljgYguKrrCASYmR&open=AaDTRljgYguKrrCASYmR&pullRequest=2415

[ -f $RF ] && rm -f $RF

Check failure on line 15 in tests/probes/shadow/test_probes_shadow_stripped.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=OpenSCAP_openscap&issues=AaDTRljgYguKrrCASYmS&open=AaDTRljgYguKrrCASYmS&pullRequest=2415

tmpdir=$(make_temp_dir /tmp "test_probes_shadow_stripped")
mkdir -p "${tmpdir}/etc"
cat > "${tmpdir}/etc/shadow" << 'SHADOW'
sha512user:$6$saltsalt$longhashvaluethatneedstoberedacted:19000:0:99999:7:::
lockedhash:!!$6$anothersalt$anotherlonghashvalue:19000:0:99999:7:::
lockednohash:!:19000:0:99999:7:::
disabled:*:19000:0:99999:7:::
neverset:!!:19000:0:99999:7:::
SHADOW

export OSCAP_PROBE_ROOT="${tmpdir}"

$OSCAP oval eval --results $RF $DF

unset OSCAP_PROBE_ROOT
rm -rf "${tmpdir}"

if [ -f $RF ]; then

Check failure on line 34 in tests/probes/shadow/test_probes_shadow_stripped.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=OpenSCAP_openscap&issues=AaDTRljgYguKrrCASYmT&open=AaDTRljgYguKrrCASYmT&pullRequest=2415
verify_results "def" $DF $RF 5 && verify_results "tst" $DF $RF 5
ret_val=$?
else
ret_val=1
fi

if grep -q 'longhashvaluethatneedstoberedacted\|anotherlonghashvalue\|saltsalt\|anothersalt' $RF; then
ret_val=1
fi

rm -f $RF
return $ret_val
}

test_init

test_run "test_probes_shadow_stripped" test_probes_shadow_stripped

test_exit
139 changes: 139 additions & 0 deletions tests/probes/shadow/test_probes_shadow_stripped.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<?xml version="1.0"?>
<oval_definitions xmlns:oval-def="http://oval.mitre.org/XMLSchema/oval-definitions-5" xmlns:oval="http://oval.mitre.org/XMLSchema/oval-common-5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:unix-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5" xsi:schemaLocation="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix unix-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-definitions-5 oval-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-common-5 oval-common-schema.xsd">

<generator>
<oval:product_name>shadow-stripped-test</oval:product_name>
<oval:product_version>1.0</oval:product_version>
<oval:schema_version>5.8</oval:schema_version>
<oval:timestamp>2026-09-23T00:00:00-00:00</oval:timestamp>
</generator>

<definitions>
<definition class="compliance" version="1" id="oval:1:def:1"> <!-- comment="true" -->
<metadata>
<title>SHA-512 hash is stripped</title>
<description>Password hash should be stripped to method prefix only</description>
</metadata>
<criteria>
<criterion test_ref="oval:1:tst:1"/>
</criteria>
</definition>

<definition class="compliance" version="1" id="oval:1:def:2"> <!-- comment="true" -->
<metadata>
<title>Locked account with hash is stripped</title>
<description>Locked account should keep lock prefix and method id</description>
</metadata>
<criteria>
<criterion test_ref="oval:1:tst:2"/>
</criteria>
</definition>

<definition class="compliance" version="1" id="oval:1:def:3"> <!-- comment="true" -->
<metadata>
<title>Locked account marker preserved</title>
<description>Simple lock marker should be kept as-is</description>
</metadata>
<criteria>
<criterion test_ref="oval:1:tst:3"/>
</criteria>
</definition>

<definition class="compliance" version="1" id="oval:1:def:4"> <!-- comment="true" -->
<metadata>
<title>Disabled account marker preserved</title>
<description>Disabled account marker should be kept as-is</description>
</metadata>
<criteria>
<criterion test_ref="oval:1:tst:4"/>
</criteria>
</definition>

<definition class="compliance" version="1" id="oval:1:def:5"> <!-- comment="true" -->
<metadata>
<title>Never-set password marker preserved</title>
<description>Double-bang marker should be kept as-is</description>
</metadata>
<criteria>
<criterion test_ref="oval:1:tst:5"/>
</criteria>
</definition>
</definitions>

<tests>
<shadow_test version="1" id="oval:1:tst:1" check="all" comment="true" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<object object_ref="oval:1:obj:1"/>
<state state_ref="oval:1:ste:1"/>
</shadow_test>

<shadow_test version="1" id="oval:1:tst:2" check="all" comment="true" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<object object_ref="oval:1:obj:2"/>
<state state_ref="oval:1:ste:2"/>
</shadow_test>

<shadow_test version="1" id="oval:1:tst:3" check="all" comment="true" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<object object_ref="oval:1:obj:3"/>
<state state_ref="oval:1:ste:3"/>
</shadow_test>

<shadow_test version="1" id="oval:1:tst:4" check="all" comment="true" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<object object_ref="oval:1:obj:4"/>
<state state_ref="oval:1:ste:4"/>
</shadow_test>

<shadow_test version="1" id="oval:1:tst:5" check="all" comment="true" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<object object_ref="oval:1:obj:5"/>
<state state_ref="oval:1:ste:5"/>
</shadow_test>
</tests>

<objects>
<shadow_object version="1" id="oval:1:obj:1" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<username>sha512user</username>
</shadow_object>

<shadow_object version="1" id="oval:1:obj:2" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<username>lockedhash</username>
</shadow_object>

<shadow_object version="1" id="oval:1:obj:3" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<username>lockednohash</username>
</shadow_object>

<shadow_object version="1" id="oval:1:obj:4" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<username>disabled</username>
</shadow_object>

<shadow_object version="1" id="oval:1:obj:5" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<username>neverset</username>
</shadow_object>
</objects>

<states>
<shadow_state version="1" id="oval:1:ste:1" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<username>sha512user</username>
<password>$6$</password>
</shadow_state>

<shadow_state version="1" id="oval:1:ste:2" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<username>lockedhash</username>
<password>!!$6$</password>
</shadow_state>

<shadow_state version="1" id="oval:1:ste:3" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<username>lockednohash</username>
<password>!</password>
</shadow_state>

<shadow_state version="1" id="oval:1:ste:4" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<username>disabled</username>
<password>*</password>
</shadow_state>

<shadow_state version="1" id="oval:1:ste:5" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix">
<username>neverset</username>
<password>!!</password>
</shadow_state>
</states>

</oval_definitions>
Loading