1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-11 12:46:49 +00:00

fix(deps): libpass instead of crypt-r; gstfsd's python3-libguestfs on a RHEL compute; PyYAML for the tests

- The root password's SHA-512 crypt hash comes from libpass (the maintained
  passlib fork, pure Python) instead of crypt-r, a copy of the stdlib crypt
  module gone in Python 3.13: crypt-r ships no wheels and its build needs
  crypt.h, which Ubuntu 26.04 no longer brings with python3-dev, so the
  installer and the manual installation failed there. The hash is the same
  format ($6$, now with libpass's 656000 rounds), checked with glibc's crypt.
- The README's RHEL compute packages left out python3-libguestfs, which
  gstfsd imports with the system python: setting the password or key of a
  shut-off VM failed there.
- The tests read YAML themselves and had PyYAML only through
  drf-spectacular.
This commit is contained in:
catborise 2026-11-07 17:19:40 +03:00
parent 25a2f22b90
commit f411659f40
5 changed files with 10 additions and 11 deletions

View file

@ -1,3 +1,4 @@
from passlib.hash import sha512_crypt
from unittest.mock import patch
from django.contrib.auth import get_user_model
@ -45,9 +46,10 @@ class SetRootPassTestCase(TestCase):
self.assertEqual(compute, self.compute)
self.assertEqual(data["action"], "password")
self.assertEqual(data["vname"], "renamed-on-host")
# SHA-512 crypt with a random salt, not the old fixed one
# SHA-512 crypt with a random salt, not the old fixed one, which the guest's crypt(3) checks
self.assertTrue(data["passwd"].startswith("$6$"))
self.assertFalse(data["passwd"].startswith("$6$kgPoiREy$"))
self.assertTrue(sha512_crypt.verify("newSecretPassword123", data["passwd"]))
def test_set_root_pass_get_not_allowed(self):
response = self.client.get(reverse("instances:rootpasswd", args=[self.instance.id]))

View file

@ -7,17 +7,10 @@ import os
import re
import secrets
import socket
import sys
import subprocess
import time
from ipaddress import ip_address
# the stdlib crypt is deprecated from Python 3.11 and gone in 3.13: crypt_r is the same module
if sys.version_info >= (3, 11):
import crypt_r as crypt
else:
import crypt
from accounts.models import UserInstance, UserSSHKey
from admin.decorators import superuser_only
from appsettings.models import AppSettings
@ -42,6 +35,7 @@ from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy, gettext_noop
from django.views.decorators.http import require_POST
from django.views.decorators.debug import sensitive_post_parameters
from passlib.hash import sha512_crypt
from libvirt import (VIR_DOMAIN_PAUSED,
VIR_DOMAIN_RUNNING,
VIR_DOMAIN_SHUTOFF,
@ -1076,7 +1070,7 @@ def set_root_pass(request, pk):
if request.method == "POST":
passwd = request.POST.get("passwd", None)
if passwd:
passwd_hash = crypt.crypt(passwd, crypt.mksalt(crypt.METHOD_SHA512))
passwd_hash = sha512_crypt.hash(passwd)
# gstfsd opens the domain by name: send the host's current one.
data = {"action": "password", "passwd": passwd_hash, "vname": instance.proxy.instance.name()}