Skip to content

Commit

Permalink
Use default pwd hash from VPD in QEMU
Browse files Browse the repository at this point in the history
This commit does several things. Its end goal is to fetch the admin
password hash from VPD memory during factory bootstrap.

To accomplish this probe creates a new file /run/system.json with
information read from a fw_cfg QEMU partition. The data from
/run/system.json is then later used during config bootstrap to fill in
the factory administrator password.

The idea is to make QEMU behave the same way hardware does, i.e. a
default/factory password should be fetched and used from
"hardware memory". The hardware portion of this is yet to be done.

Signed-off-by: Richard Alpe <richard@bit42.se>
  • Loading branch information
rical committed Nov 22, 2023
1 parent fc65cfe commit b5ed507
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 17 deletions.
1 change: 1 addition & 0 deletions board/common/post-image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ if [ "$BR2_TARGET_ROOTFS_SQUASHFS" = "y" ]; then
fi

# Menuconfig support for modifying Qemu args in release tarballs
cp "$BR2_EXTERNAL_INFIX_PATH/board/common/rootfs/bin/onieprom" "$BINARIES_DIR/"
cp "$BR2_EXTERNAL_INFIX_PATH/board/common/qemu/qemu.sh" "$BINARIES_DIR/"
sed -e "s/@ARCH@/QEMU_$BR2_ARCH/" \
-e "s/@DISK_IMG@/$diskimg/" \
Expand Down
33 changes: 33 additions & 0 deletions board/common/qemu/qemu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,38 @@ net_args()
fi
}

# Vital Board Data, part of Vital Product data
vbd_args()
{
onieprom="$(dirname "$CONFIG_QEMU_ROOTFS")/onieprom"
vbd_file="$(dirname "$CONFIG_QEMU_ROOTFS")/vbd"

# This is you QEMU factory/default password:
pwhash=$(echo -n "admin" | mkpasswd -s -m sha256crypt)

# NOTE: This format will change!
json_data=$(cat <<EOF
{
"manufacture-date": "$(date +"%d/%m/%Y %H:%M:%S")",
"vendor-extension": [
[
65536,
"{\"pwhash\":\"$pwhash\"}"
]
]
}
EOF
)
:> "$vbd_file"

local tmp="$(mktemp --suffix=_infix_vbd)"
echo "$json_data" > "$tmp"
"$onieprom" "$tmp" "$vbd_file"
rm "$tmp"

echo -n "-fw_cfg name=opt/vbd,file=$vbd_file"
}

wdt_args()
{
echo -n "-device i6300esb -rtc clock=host"
Expand All @@ -209,6 +241,7 @@ run_qemu()
$(host_args) \
$(net_args) \
$(wdt_args) \
$(vbd_args) \
$CONFIG_QEMU_EXTRA
EOF

Expand Down
33 changes: 31 additions & 2 deletions board/common/rootfs/lib/infix/probe
Original file line number Diff line number Diff line change
@@ -1,6 +1,35 @@
#!/bin/sh
# Probe for various types of harware features

if dmesg |grep -q QEMU || test -d /sys/module/qemu_fw_cfg; then
initctl cond set qemu
#TODO Rewrite this script in python before extending it further
#TODO Remove fallback temporary development hash

gen_qemu_system_file() {
vbd_json="$(onieprom /sys/firmware/qemu_fw_cfg/by_name/opt/vbd/raw)"
if [ $? -ne 0 ]; then
logger -p user.crit -t "probe" "Error, running onieprom tool"
exit 1
fi

pwhash="$(echo "$vbd_json" | jq -r '.["vendor-extension"][0][1]' | jq -r '.pwhash')"
if [ -z "$pwhash" ] || [ "$pwhash" = "null" ]; then
logger -p user.crit -t "probe" "Error, didn't find password hash"
exit 1
fi

system_json="$(echo "$vbd_json" | jq -r 'del(."vendor-extension")')"
system_json="$(echo "$system_json" | jq --arg val "$pwhash" '. += {"pwhash": $val}')"
echo "$system_json" > /run/system.json
}

if dmesg | grep -q QEMU || test -d /sys/module/qemu_fw_cfg; then
initctl cond set qemu
gen_qemu_system_file
else
# NOTE: All this code will soon go away.
echo -e "\n\n\e[31mWARNING! Probe failed to get password hash from hardware\n" \
"Falling back to temporary hash\e[0m\n" > /dev/console
# Clear Test = admin
echo '{"pwhash": "$5$n2xoZAmITmPYjOTO$pbWHoa1Mu25a0e.akViAf9uWRvUgbq9BbcmzWWaNP0A"}' > /run/system.json
fi

2 changes: 1 addition & 1 deletion src/confd/bin/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
pkglibexec_SCRIPTS = bootstrap error load \
gen-hostkeys gen-hostname gen-interfaces
gen-hostkeys gen-admin-auth gen-hostname gen-interfaces
11 changes: 11 additions & 0 deletions src/confd/bin/bootstrap
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ collate()
fi
}

console_error()
{
logger -p user.crit -t "BOOTSTRAP" "CRITICAL ERROR! $1"
echo -e "\n\n\e[31mCRITICAL BOOTSTRAP ERROR\n$1\e[0m\n" > /dev/console
}

factory()
{
gen=$1
Expand All @@ -77,6 +83,11 @@ factory()
# shellcheck disable=SC2086
gen-interfaces $GEN_IFACE_OPTS >"$FACTORY_D/20-interfaces.json"

if ! gen-admin-auth >"$FACTORY_D/10-authentication.json"; then
console_error "Unable to create factory config, gen-admin-auth failed"
return
fi

[ -s "$FACTORY_D/20-hostkey.json" ] || gen-hostkeys >"$FACTORY_D/20-hostkey.json"

# Optional commands (from an overlay) to run for br2-externals
Expand Down
23 changes: 23 additions & 0 deletions src/confd/bin/gen-admin-auth
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/sh

pwhash="$(cat /run/system.json | jq '.pwhash')"

if [ -z "$pwhash" ] || [ "$pwhash" = "null" ]; then
exit 1
fi

cat <<EOF
{
"ietf-system:system": {
"authentication": {
"user": [
{
"name": "admin",
"password": $pwhash,
"infix-system:shell": "infix-shell-type:clish"
}
]
}
}
}
EOF
13 changes: 0 additions & 13 deletions src/confd/share/factory.d/10-authentication.json

This file was deleted.

2 changes: 1 addition & 1 deletion src/confd/share/factory.d/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
factorydir = $(pkgdatadir)/factory.d
dist_factory_DATA = 10-authentication.json 10-nacm.json \
dist_factory_DATA = 10-nacm.json \
10-netconf-server.json 10-system.json

0 comments on commit b5ed507

Please sign in to comment.