diff --git a/Containerfile.tests.el7 b/Containerfile.tests.el7 index 06a9b789..5d32a3c5 100644 --- a/Containerfile.tests.el7 +++ b/Containerfile.tests.el7 @@ -4,7 +4,7 @@ FROM quay.io/centos/centos:7 RUN set -exo pipefail \ && yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \ - && yum install -y python-requests m2crypto libvirt-python python-lxml python-libguestfs pytest python-monotonic libvirt \ + && yum install -y python-requests python-cryptography libvirt-python python-lxml python-libguestfs pytest python-monotonic libvirt \ && yum clean all \ && rm -rf /var/cache/* /var/log/yum* diff --git a/Containerfile.tests.fedora b/Containerfile.tests.fedora index 7dd3e414..d2315505 100644 --- a/Containerfile.tests.fedora +++ b/Containerfile.tests.fedora @@ -4,7 +4,7 @@ FROM quay.io/fedora/fedora:latest RUN set -exo pipefail \ && dnf install -y --setopt install_weak_deps=false --nodocs \ - python3-requests python3-m2crypto python3-setuptools python3-libvirt python3-lxml python3-libguestfs python3-pytest python3-monotonic \ + python3-requests python3-cryptography python3-setuptools python3-libvirt python3-lxml python3-libguestfs python3-pytest python3-monotonic \ libvirt-daemon libvirt-daemon-kvm libvirt-daemon-qemu libvirt-daemon-config-network systemd \ && dnf clean all \ && rm -rf /var/cache/* /var/log/dnf* diff --git a/README b/README index 5f2c983c..770e7cea 100644 --- a/README +++ b/README @@ -24,11 +24,11 @@ guestfs Python module, which is not available from pypi, and needs a running libvirtd for most of the tests to run. To install all the test requirements on Fedora: -dnf install python3-requests python3-m2crypto python3-libvirt python3-lxml python3-libguestfs python3-pytest python3-monotonic +dnf install python3-requests python3-cryptography python3-libvirt python3-lxml python3-libguestfs python3-pytest python3-monotonic If you wish to test on EL 7, make that: -yum install python-requests m2crypto libvirt-python python-lxml python-libguestfs pytest python-monotonic +yum install python-requests python-cryptography libvirt-python python-lxml python-libguestfs pytest python-monotonic then run the tests: @@ -37,7 +37,7 @@ py.test tests/ You can try `make virtualenv` then `make unittests` to run the tests in a virtualenv if you like, but this still requires at least the libguestfs library installed on the host, and a running libvirtd. You may also want to install -m2crypto and libvirt libraries on the host, as otherwise pip will have to +cryptography and libvirt libraries on the host, as otherwise pip will have to compile them, and you'll need their build dependencies. You can use `make pylint` and `make flake8` to run lint checks. diff --git a/debian/control b/debian/control index a02ab576..62fcb041 100644 --- a/debian/control +++ b/debian/control @@ -20,7 +20,7 @@ Depends: ${misc:Depends}, ${python:Depends}, python-lxml, python-libvirt (>= 0.9.7), python-requests, - python-m2crypto, + python-cryptography, python-monotonic, Description: installing guest OSs with only minimal input the user Oz is a tool for automatically installing guest OSs with only minimal diff --git a/oz.spec.in b/oz.spec.in index b83ccf1a..e2134b4d 100644 --- a/oz.spec.in +++ b/oz.spec.in @@ -16,7 +16,7 @@ Requires: python3 Requires: python3-lxml Requires: python3-libguestfs >= 1.18 Requires: python3-libvirt -Requires: python3-m2crypto +Requires: python3-cryptography Requires: python3-monotonic Requires: python3-requests # in theory, oz doesn't really require libvirtd to be local to operate diff --git a/oz/Guest.py b/oz/Guest.py index 249cce04..7d97e460 100644 --- a/oz/Guest.py +++ b/oz/Guest.py @@ -38,7 +38,8 @@ import urlparse import uuid -import M2Crypto +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import rsa import guestfs @@ -1282,34 +1283,28 @@ def _generate_openssh_key(self, privname): # when we get here, either both the private and public key exist, or # neither exist. If they don't exist, generate them if not os.access(privname, os.F_OK) and not os.access(pubname, os.F_OK): - def _null_callback(p, n, out): # pylint: disable=unused-argument - """ - Method to silence the default M2Crypto.RSA.gen_key output. - """ - pass pubname = privname + '.pub' - key = M2Crypto.RSA.gen_key(2048, 65537, _null_callback) + key = rsa.generate_private_key(65537, 2048) - # this is the binary public key, in ssh "BN" (BigNumber) MPI format. - # The ssh BN MPI format consists of 4 bytes that describe the length - # of the following data, followed by the data itself in big-endian - # format. The start of the string is 0x0007, which represent the 7 - # bytes following that make up 'ssh-rsa'. The key exponent and - # modulus as fetched out of M2Crypto are already in MPI format, so - # we can just use them as-is. We then have to base64 encode the - # result, add a little header information, and then we have a - # full public key. - pubkey = b'\x00\x00\x00\x07' + b'ssh-rsa' + key.e + key.n + pubkey = key.public_key().public_bytes( + serialization.Encoding.OpenSSH, + serialization.PublicFormat.OpenSSH + ) username = os.getlogin() hostname = os.uname()[1] - keystring = 'ssh-rsa %s %s@%s\n' % (base64.b64encode(pubkey).decode('utf-8'), - username, hostname) + keystring = '%s %s@%s\n' % (pubkey.decode('utf-8'), username, hostname) oz.ozutil.mkdir_p(os.path.dirname(privname)) - key.save_key(privname, cipher=None) + privkeystring = key.private_bytes( + serialization.Encoding.PEM, + serialization.PrivateFormat.TraditionalOpenSSL, + serialization.NoEncryption() + ) + with open(privname, 'wb') as f: + f.write(privkeystring) os.chmod(privname, 0o600) with open(pubname, 'w') as f: f.write(keystring) diff --git a/requirements.txt b/requirements.txt index c0a8d464..1eabb08f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ requests -m2crypto +cryptography libvirt-python lxml monotonic