Alon Bar-Lev has uploaded a new change for review. Change subject: packaging: setup: extract ssh public key logic to script ......................................................................
packaging: setup: extract ssh public key logic to script rhel-6 is missing functionality to export public key out of PKCS#8, this is required for setup but soon to pki. Change-Id: Id07ef97cdff510a95c6946e413450de32db631ee Signed-off-by: Alon Bar-Lev <alo...@redhat.com> --- M ovirt-engine.spec.in A packaging/bin/pki-ssh-keygen.py M packaging/setup/ovirt_engine_setup/engine/constants.py M packaging/setup/plugins/ovirt-engine-setup/ovirt-engine/pki/ssh.py 4 files changed, 119 insertions(+), 30 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/92/38092/8 diff --git a/ovirt-engine.spec.in b/ovirt-engine.spec.in index 7427446..4d3501c 100644 --- a/ovirt-engine.spec.in +++ b/ovirt-engine.spec.in @@ -1017,6 +1017,7 @@ %{engine_data}/bin/pki-enroll-pkcs12.sh %{engine_data}/bin/pki-enroll-request.sh %{engine_data}/bin/pki-pkcs12-extract.sh +%{engine_data}/bin/pki-ssh-keygen.py* # backward compatibly (pre-3.3.0) # force rpm not to remove pki files diff --git a/packaging/bin/pki-ssh-keygen.py b/packaging/bin/pki-ssh-keygen.py new file mode 100755 index 0000000..0419808 --- /dev/null +++ b/packaging/bin/pki-ssh-keygen.py @@ -0,0 +1,90 @@ +#!/usr/bin/python +# +# rhel-6 does not have valid ssh-keygen so we do this +# our selves. +# +import base64 +import optparse +import re +import struct +import sys + + +from M2Crypto import EVP +from M2Crypto import RSA + + +def _getSSHPublicKeyRaw(key): + ALGO = 'ssh-rsa' + return { + 'algo': ALGO, + 'blob': ( + struct.pack('!l', len(ALGO)) + ALGO.encode('ascii') + + key.pub()[0] + + key.pub()[1] + ), + } + + +def _getSSHPublicKey(key): + sshkey = _getSSHPublicKeyRaw(key) + return '%s %s' % (sshkey['algo'], base64.b64encode(sshkey['blob'])) + + +def _getSSHPublicKeyFingerprint(key, f): + sshkey = _getSSHPublicKeyRaw(key) + md5 = EVP.MessageDigest('md5') + md5.update(sshkey['blob']) + return '%s %s %s (%s)' % ( + len(key), + re.sub(r'(..)', r':\1', base64.b16encode(md5.digest()))[1:].lower(), + f, + sshkey['algo'].replace('ssh-', '').upper(), + ) + + +def _getPublicKey(f): + return RSA.load_pub_key(f) + + +def main(): + ret = 1 + try: + parser = optparse.OptionParser() + parser.add_option('-i', action='store_true', default=False) + parser.add_option('-l', action='store_true', default=False) + parser.add_option('-m') + parser.add_option('-f') + options, args = parser.parse_args(sys.argv) + if options.i: + if not options.m or not options.f: + raise RuntimeError('Missing -m or -f') + if options.m != 'PKCS8': + raise RuntimeError('Unsupported format') + print(_getSSHPublicKey(_getPublicKey(options.f))) + ret = 0 + elif options.l: + if not options.f: + raise RuntimeError('Missing -m or -f') + print( + _getSSHPublicKeyFingerprint( + _getPublicKey(options.f), + options.f, + ) + ) + ret = 0 + else: + raise RuntimeError('Unsupported operation') + except Exception as e: + # import traceback + # traceback.print_exc() + sys.stderr.write('FATAL: %s\n' % (e,)) + + return ret + + +if __name__ == '__main__': + sys.exit(main()) + + +# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/packaging/setup/ovirt_engine_setup/engine/constants.py b/packaging/setup/ovirt_engine_setup/engine/constants.py index 2dab6b3..c34acb0 100644 --- a/packaging/setup/ovirt_engine_setup/engine/constants.py +++ b/packaging/setup/ovirt_engine_setup/engine/constants.py @@ -148,6 +148,10 @@ OVIRT_ENGINE_BINDIR, 'pki-pkcs12-extract.sh', ) + OVIRT_ENGINE_PKI_SSH_KEYGEN = os.path.join( + OVIRT_ENGINE_BINDIR, + 'pki-ssh-keygen.py', + ) OVIRT_ENGINE_PKI_ENGINE_STORE = os.path.join( OVIRT_ENGINE_PKIKEYSDIR, diff --git a/packaging/setup/plugins/ovirt-engine-setup/ovirt-engine/pki/ssh.py b/packaging/setup/plugins/ovirt-engine-setup/ovirt-engine/pki/ssh.py index 5ebe4fb..ade70e1 100644 --- a/packaging/setup/plugins/ovirt-engine-setup/ovirt-engine/pki/ssh.py +++ b/packaging/setup/plugins/ovirt-engine-setup/ovirt-engine/pki/ssh.py @@ -19,12 +19,10 @@ """ssh plugin.""" -import base64 import gettext -import re -import struct -from M2Crypto import EVP, X509 +from M2Crypto import X509 + from otopi import constants as otopicons from otopi import filetransaction, plugin, util @@ -41,26 +39,29 @@ class Plugin(plugin.PluginBase): """CA plugin.""" - def _getSSHPublicKeyRaw(self, key): - ALGO = 'ssh-rsa' - return { - 'algo': ALGO, - 'blob': ( - struct.pack('!l', len(ALGO)) + ALGO.encode('ascii') + - key.pub()[0] + - key.pub()[1] - ), - } - def _getSSHPublicKey(self, key): - sshkey = self._getSSHPublicKeyRaw(key) - return '%s %s' % (sshkey['algo'], base64.b64encode(sshkey['blob'])) + rc, stdout, stderr = self.execute( + ( + oenginecons.FileLocations.OVIRT_ENGINE_PKI_SSH_KEYGEN, + '-l', + '-i', + '-m', 'PKCS8', + '-f', '/proc/self/fd/0', + ), + stdin=key.split('\n'), + ) + return stdout[0] def _getSSHPublicKeyFingerprint(self, key): - sshkey = self._getSSHPublicKeyRaw(key) - md5 = EVP.MessageDigest('md5') - md5.update(sshkey['blob']) - return re.sub(r'(..)', r':\1', base64.b16encode(md5.digest()))[1:] + rc, stdout, stderr = self.execute( + ( + oenginecons.FileLocations.OVIRT_ENGINE_PKI_SSH_KEYGEN, + '-l', + '-f', '/proc/self/fd/0', + ), + stdin=key.split('\n'), + ) + return stdout[0].split()[1] def _getEnginePublicKey(self): rc, cert, stderr = self.execute( @@ -74,20 +75,13 @@ ), ) - x509 = X509.load_cert_string( + return X509.load_cert_string( string='\n'.join(cert).encode('ascii'), format=X509.FORMAT_PEM, - ) - return x509.get_pubkey().get_rsa() + ).get_pubkey().get_rsa().as_pem() def __init__(self, context): super(Plugin, self).__init__(context=context) - - @plugin.event( - stage=plugin.Stages.STAGE_SETUP, - ) - def _setup(self): - self.command.detect('ssh-keygen') @plugin.event( stage=plugin.Stages.STAGE_MISC, -- To view, visit https://gerrit.ovirt.org/38092 To unsubscribe, visit https://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id07ef97cdff510a95c6946e413450de32db631ee Gerrit-PatchSet: 8 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Alon Bar-Lev <alo...@redhat.com> Gerrit-Reviewer: Alon Bar-Lev <alo...@redhat.com> Gerrit-Reviewer: Francesco Romani <from...@redhat.com> Gerrit-Reviewer: Jenkins CI Gerrit-Reviewer: Sandro Bonazzola <sbona...@redhat.com> Gerrit-Reviewer: Yedidyah Bar David <d...@redhat.com> Gerrit-Reviewer: automat...@ovirt.org _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches