Admin password check works with yescrypt; shorter Blancco version warning
chpasswd and passwd write yescrypt ($y$) hashes, which the openssl $6$ comparison could not read: every re-run set the pxe password again, and a box whose password was 'pxe' in yescrypt passed the pxe_admin_password requirement. Both Admin tasks now compare with crypt(), which handles every scheme. The config.img warning names the two Blancco versions instead of the staging guard's merge instructions.
This commit is contained in:
@@ -400,16 +400,24 @@
|
|||||||
the Blancco preferences). Fix them in playbook/site-vars.yml and re-run.
|
the Blancco preferences). Fix them in playbook/site-vars.yml and re-run.
|
||||||
quiet: yes
|
quiet: yes
|
||||||
|
|
||||||
|
# MATCH / DIFF / UNKNOWN: does pxe's shadow hash match $PW? crypt()
|
||||||
|
# handles every scheme (the autoinstall hash is $6$, chpasswd and passwd
|
||||||
|
# write yescrypt $y$). Used by the two Admin tasks below.
|
||||||
- name: "Admin: is the Linux pxe login still the shipped password?"
|
- name: "Admin: is the Linux pxe login still the shipped password?"
|
||||||
shell: |
|
shell: &pxe_pw_compare |
|
||||||
h=$(getent shadow pxe | cut -d: -f2)
|
python3 -W ignore - <<'PY'
|
||||||
case "$h" in
|
import os, subprocess
|
||||||
'$6$'*) salt=$(printf '%s' "$h" | cut -d'$' -f3)
|
try:
|
||||||
if [ "$(printf 'pxe' | openssl passwd -6 -salt "$salt" -stdin)" = "$h" ]; then echo DEFAULT; else echo SITE; fi ;;
|
import crypt
|
||||||
*) echo UNKNOWN ;;
|
except ImportError:
|
||||||
esac
|
print("UNKNOWN"); raise SystemExit
|
||||||
args:
|
h = subprocess.run(["getent", "shadow", "pxe"], capture_output=True, text=True).stdout.split(":")
|
||||||
executable: /bin/bash
|
h = h[1] if len(h) > 1 else ""
|
||||||
|
print("MATCH" if h.startswith("$") and crypt.crypt(os.environ["PW"], h) == h else
|
||||||
|
"DIFF" if h.startswith("$") else "UNKNOWN")
|
||||||
|
PY
|
||||||
|
environment:
|
||||||
|
PW: "pxe"
|
||||||
register: pxe_admin_state
|
register: pxe_admin_state
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
@@ -417,7 +425,7 @@
|
|||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- pxe_admin_password is string
|
- pxe_admin_password is string
|
||||||
- pxe_admin_password | length > 0 or pxe_admin_state.stdout != 'DEFAULT'
|
- pxe_admin_password | length > 0 or pxe_admin_state.stdout != 'MATCH'
|
||||||
- pxe_admin_password | length == 0 or (pxe_admin_password | length >= 8 and pxe_admin_password | length <= 128)
|
- pxe_admin_password | length == 0 or (pxe_admin_password | length >= 8 and pxe_admin_password | length <= 128)
|
||||||
- pxe_admin_password | length == 0 or pxe_admin_password is not search('[\x00-\x1f]')
|
- pxe_admin_password | length == 0 or pxe_admin_password is not search('[\x00-\x1f]')
|
||||||
- pxe_admin_password != 'pxe'
|
- pxe_admin_password != 'pxe'
|
||||||
@@ -1551,24 +1559,22 @@
|
|||||||
changed_when: "'created' in smb_users.stdout"
|
changed_when: "'created' in smb_users.stdout"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
- name: "Admin: set the Linux pxe password from pxe_admin_password"
|
- name: "Admin: does the Linux pxe password already match pxe_admin_password?"
|
||||||
shell: |
|
shell: *pxe_pw_compare
|
||||||
h=$(getent shadow pxe | cut -d: -f2)
|
|
||||||
salt=$(printf '%s' "$h" | cut -d'$' -f3)
|
|
||||||
if [ -n "$salt" ] && [ "$(printf '%s' "$PW" | openssl passwd -6 -salt "$salt" -stdin)" = "$h" ]; then
|
|
||||||
echo UNCHANGED
|
|
||||||
else
|
|
||||||
printf 'pxe:%s\n' "$PW" | chpasswd && echo CHANGED
|
|
||||||
fi
|
|
||||||
environment:
|
environment:
|
||||||
PW: "{{ pxe_admin_password }}"
|
PW: "{{ pxe_admin_password }}"
|
||||||
args:
|
register: pxe_admin_cur
|
||||||
executable: /bin/bash
|
changed_when: false
|
||||||
register: pxe_admin_set
|
|
||||||
changed_when: "'CHANGED' in pxe_admin_set.stdout"
|
|
||||||
when: pxe_admin_password | length > 0
|
when: pxe_admin_password | length > 0
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
|
- name: "Admin: set the Linux pxe password from pxe_admin_password"
|
||||||
|
shell: printf 'pxe:%s\n' "$PW" | chpasswd
|
||||||
|
environment:
|
||||||
|
PW: "{{ pxe_admin_password }}"
|
||||||
|
when: pxe_admin_password | length > 0 and pxe_admin_cur.stdout != 'MATCH'
|
||||||
|
no_log: true
|
||||||
|
|
||||||
- name: "Deploy nf_conntrack TCP timeout sysctl for PXE workload"
|
- name: "Deploy nf_conntrack TCP timeout sysctl for PXE workload"
|
||||||
copy:
|
copy:
|
||||||
src: "{{ usb_mount }}/pxe-server-helpers/99-pxe-conntrack.conf"
|
src: "{{ usb_mount }}/pxe-server-helpers/99-pxe-conntrack.conf"
|
||||||
|
|||||||
@@ -1011,10 +1011,15 @@ def refresh_live_prefs():
|
|||||||
ours = f.read()
|
ours = f.read()
|
||||||
try:
|
try:
|
||||||
new = patch_config_img(cfg, ours)
|
new = patch_config_img(cfg, ours)
|
||||||
except (StageBlocked, ValueError) as e:
|
except StageBlocked:
|
||||||
warning = (f"the live config.img (BIOS boot) was not updated: {e} "
|
live = prefs_version(cpio_member(cfg, "preferences.xml") or b"") or "?"
|
||||||
|
warning = (f"the live config.img (BIOS boot) is Blancco {live}, older than our "
|
||||||
|
f"{prefs_version(ours) or '?'} preferences, so it was not updated. "
|
||||||
"Stage a current release on Updates > Blancco releases.")
|
"Stage a current release on Updates > Blancco releases.")
|
||||||
new = cfg
|
new = cfg
|
||||||
|
except ValueError as e:
|
||||||
|
warning = f"the live config.img (BIOS boot) was not updated: {e}"
|
||||||
|
new = cfg
|
||||||
if new != cfg:
|
if new != cfg:
|
||||||
_atomic_write(cfg_path, new)
|
_atomic_write(cfg_path, new)
|
||||||
changed = True
|
changed = True
|
||||||
|
|||||||
@@ -190,7 +190,8 @@ class ShareAccounts(Fixture):
|
|||||||
with open(os.path.join(BU.blancco_root(), "config.img"), "wb") as f:
|
with open(os.path.join(BU.blancco_root(), "config.img"), "wb") as f:
|
||||||
f.write(cfg)
|
f.write(cfg)
|
||||||
done = SA.set_password("blancco", PW)
|
done = SA.set_password("blancco", PW)
|
||||||
self.assertTrue(any("WARNING" in d and "config.img" in d for d in done), done)
|
self.assertTrue(any("WARNING" in d and "config.img (BIOS boot) is Blancco 7.15" in d
|
||||||
|
and "older than our 7.20" in d for d in done), done)
|
||||||
with open(BP.served_prefs_path(), "rb") as f:
|
with open(BP.served_prefs_path(), "rb") as f:
|
||||||
self.assertEqual(self.prefs_share_pw(f.read()), PW)
|
self.assertEqual(self.prefs_share_pw(f.read()), PW)
|
||||||
with open(os.path.join(BU.blancco_root(), "config.img"), "rb") as f:
|
with open(os.path.join(BU.blancco_root(), "config.img"), "rb") as f:
|
||||||
|
|||||||
Reference in New Issue
Block a user