Alon Bar-Lev has uploaded a new change for review.

Change subject: packaging: retrieve trust certificate from engine's ssl
......................................................................

packaging: retrieve trust certificate from engine's ssl

Currently the implementation assume that the internal certificate
authority is used to perform SSL, this is incorrect.

New implementation fetches the certificate chain from the engine ssl
session.

The utility ssl2jkstrust.py can be used to re-fetch if needed after
setup.

Not sure why we cannot perform SSO based on shared secret or database
OTP, which will make it much simpler to implement than current
implementation.

Change-Id: I64ab90925eabb3cf1c43c39693dfb082400c8ba4
Signed-off-by: Alon Bar-Lev <[email protected]>
---
M Makefile
M packaging/ovirt-engine-reports-setup.py
M packaging/ovirt-engine-reports.spec.in
A packaging/ssl2jkstrust.py
4 files changed, 150 insertions(+), 3 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-reports refs/changes/40/12740/1

diff --git a/Makefile b/Makefile
index 436101f..60afc30 100644
--- a/Makefile
+++ b/Makefile
@@ -145,6 +145,7 @@
 
 install_files:
        install -d $(DESTDIR)$(PKG_SYSCONF_DIR)/engine.conf.d
+       install -d $(DESTDIR)$(PKG_SYSCONF_DIR)/ovirt-engine-reports
        install -d $(DESTDIR)$(BIN_DIR)
        install -d $(DESTDIR)$(DATA_DIR)
        install -d $(DESTDIR)$(DATA_DIR)/reports
@@ -152,6 +153,7 @@
 
        cp -a  reports/repository_files/* $(DESTDIR)$(DATA_DIR)/reports
        install -p -m 644 packaging/50-ovirt-engine-reports.conf  
$(DESTDIR)$(PKG_SYSCONF_DIR)/engine.conf.d
+       install -p -m 755 packaging/ssl2jkstrust.py $(DESTDIR)$(DATA_DIR)
        install -p -m 755 packaging/ovirt-engine-reports-setup.py 
$(DESTDIR)$(DATA_DIR)
        install -p -m 755 packaging/common_utils.py $(DESTDIR)$(DATA_DIR)
        install -p -m 755 packaging/decorators.py $(DESTDIR)$(DATA_DIR)
diff --git a/packaging/ovirt-engine-reports-setup.py 
b/packaging/ovirt-engine-reports-setup.py
index 7d8bc06..22da336 100755
--- a/packaging/ovirt-engine-reports-setup.py
+++ b/packaging/ovirt-engine-reports-setup.py
@@ -42,6 +42,7 @@
 FILE_JASPER_DB_CONN = "%s/default_master.properties" % 
REPORTS_SERVER_BUILDOMATIC_DIR
 
 REPORTS_PACKAGE_DIR = "/usr/share/ovirt-engine-reports"
+SSL2JKSTRUST = "%s/ssl2jkstrust.py" % REPORTS_PACKAGE_DIR
 FILE_DB_DATA_SOURCE = 
"%s/reports/resources/reports_resources/JDBC/data_sources/ovirt.xml" % 
REPORTS_PACKAGE_DIR
 DIR_REPORTS_CUSTOMIZATION="%s/server-customizations" % REPORTS_PACKAGE_DIR
 DIR_OVIRT_THEME="%s/reports/resources/themes/ovirt-002dreports-002dtheme" % 
REPORTS_PACKAGE_DIR
@@ -52,6 +53,10 @@
 FILE_ENGINE_CONF_DEFAULTS = "/usr/share/ovirt-engine/conf/engine.conf.defaults"
 FILE_ENGINE_CONF = "/etc/ovirt-engine/engine.conf"
 DIR_PKI = "/etc/pki/ovirt-engine"
+OVIRT_REPORTS_ETC="/etc/ovirt-engine/ovirt-engine-reports"
+OVIRT_REPORTS_TRUST_STORE="%s/trust.jks" % OVIRT_REPORTS_ETC
+OVIRT_REPORTS_TRUST_STORE_PASS="mypass"
+
 DB_EXIST = False
 MUCK_PASSWORD="oVirtadmin2009!"
 PGDUMP_EXEC = "/usr/bin/pg_dump"
@@ -575,8 +580,22 @@
     """
         Setting the SSO solution
     """
-    logging.debug("editing applicationContext-security-web file")
     (protocol, fqdn, port) = getHostParams()
+    logging.debug("downloading certificates %s://%s:%s" % (protocol, fqdn, 
port))
+    if protocol == 'https':
+        utils.execExternalCmd(
+            ' '.join(
+                (
+                    SSL2JKSTRUST,
+                    '--host=%s' % fqdn,
+                    '--port=%s' % port,
+                    '--keystore=%s' % OVIRT_REPORTS_TRUST_STORE,
+                    '--storepass=%s' % OVIRT_REPORTS_TRUST_STORE_PASS,
+                )
+            ),
+            fail_on_error=True,
+        )
+    logging.debug("editing applicationContext-security-web file")
     hostValidateSessionUrl = "%s://%s:%s/OvirtEngineWeb/ValidateSession" % 
(protocol, fqdn, port)
     fd = open(FILE_APPLICATION_SECURITY_WEB, "r")
     file_content = fd.read()
@@ -584,8 +603,14 @@
     logging.debug("replace servlet URL")
     file_content = 
file_content.replace("http://localhost/OvirtEngineWeb/ValidateSession";, 
hostValidateSessionUrl)
     logging.debug("replace trust store path and pass")
-    file_content = file_content.replace("name=\"trustStorePath\" 
value=\"/usr/local/jboss-as/truststore\"", "name=\"trustStorePath\" value=\"" + 
utils.getVDCOption("TruststoreUrl") + "\"")
-    file_content = file_content.replace("name=\"trustStorePassword\" 
value=\"NoSoup4U\"", "name=\"trustStorePassword\" value=\"" + 
utils.getVDCOption("TruststorePass") + "\"")
+    file_content = file_content.replace(
+        "name=\"trustStorePath\" value=\"/usr/local/jboss-as/truststore\"",
+        "name=\"trustStorePath\" value=\"%s\"" % OVIRT_REPORTS_TRUST_STORE
+    )
+    file_content = file_content.replace(
+        "name=\"trustStorePassword\" value=\"NoSoup4U\"",
+        "name=\"trustStorePassword\" value=\"%s\"" % 
OVIRT_REPORTS_TRUST_STORE_PASS
+    )
     logging.debug("writing replaced content to %s" % 
FILE_APPLICATION_SECURITY_WEB)
     fd = open(FILE_APPLICATION_SECURITY_WEB, "w")
     fd.write(file_content)
diff --git a/packaging/ovirt-engine-reports.spec.in 
b/packaging/ovirt-engine-reports.spec.in
index 25c2a29..91791de 100644
--- a/packaging/ovirt-engine-reports.spec.in
+++ b/packaging/ovirt-engine-reports.spec.in
@@ -41,6 +41,7 @@
 Requires: ovirt-engine >= 3.2.0
 Requires: ovirt-engine-dwh >= 3.2.0
 Requires: jasperreports-server >= 4.7.0
+Requires: m2crypto
 
 # We need some packages installed in order to workaround
 # bug 862355:
@@ -112,6 +113,7 @@
 
 %files
 %{_sysconfdir}/ovirt-engine/engine.conf.d/50-ovirt-engine-reports.conf
+%{_sysconfdir}/ovirt-engine/ovirt-engine-reports
 %{reports_java}
 %{_datadir}/%{reports_name}
 %if "%{name}" != "%{reports_name}"
diff --git a/packaging/ssl2jkstrust.py b/packaging/ssl2jkstrust.py
new file mode 100755
index 0000000..962ac04
--- /dev/null
+++ b/packaging/ssl2jkstrust.py
@@ -0,0 +1,118 @@
+#!/usr/bin/python
+
+
+import os
+import optparse
+import subprocess
+
+
+from M2Crypto import SSL, X509
+
+
+def getChainFromSSL(host):
+    '''Return certificate from SSL handlshake
+
+    Parameters:
+    host -- (host, port)
+
+    '''
+    # openssl verify callback does not
+    # accept context, so we collect the chain
+    # in semi-global dictionary
+    #
+    # a certificate may be revisit more than one time.
+    #
+    # format:
+    #   depth: certificate
+    chain = {}
+
+    def verify(ok, store):
+        chain[store.get_error_depth()] = store.get_current_cert().as_pem()
+        return True
+
+    def check_ignore(*args, **kw):
+        return True
+
+    ctx = SSL.Context()
+    ctx.set_verify(
+        SSL.verify_peer | SSL.verify_fail_if_no_peer_cert,
+        depth=10,
+        callback=verify
+    )
+    sock = SSL.Connection(ctx)
+    # we would like to ignore any issue with certificates
+    sock.set_post_connection_check_callback(check_ignore)
+    sock.connect(host)
+    sock.close()
+
+    # return sorted by depth
+    # first is end certificate
+    return [chain[depth] for depth in sorted(chain.keys())]
+
+
+def main():
+    parser = optparse.OptionParser()
+    parser.add_option(
+        '--host',
+        dest='host',
+        default='localhost',
+        help='host to connect to [localhost]',
+    )
+    parser.add_option(
+        '--port',
+        dest='port',
+        default='443',
+        help='port to connect to [443]',
+    )
+    parser.add_option(
+        '--keystore',
+        dest='keystore',
+        metavar='FILE',
+        help='key store to write',
+    )
+    parser.add_option(
+        '--storepass',
+        dest='storepass',
+        default='changeit',
+        help='key store password [changeit]',
+    )
+    parser.add_option(
+        '--keytool',
+        dest='keytool',
+        metavar='FILE',
+        default='keytool',
+        help='keytool path [keytool]',
+    )
+    (options, args) = parser.parse_args()
+    if len(args) != 0:
+        parser.error('incorrect number of arguments')
+    if options.keystore is None:
+        parser.error('please specify store to write into')
+
+    tmp = "%s.tmp" % options.keystore
+    if os.path.exists(tmp):
+        os.unlink(tmp)
+    for c in getChainFromSSL((options.host, int(options.port)))[1:]:
+        cert = X509.load_cert_string(c, X509.FORMAT_PEM)
+        p = subprocess.Popen(
+            (
+                options.keytool,
+                '-import',
+                '-noprompt',
+                '-trustcacerts',
+                '-storetype', 'JKS',
+                '-keystore', tmp,
+                '-storepass', options.storepass,
+                '-alias', str(cert.get_subject()),
+            ),
+            stdin=subprocess.PIPE,
+            close_fds=True,
+        )
+        p.communicate(input=c)
+        if p.returncode != 0:
+            raise RuntimeError('keytool failed')
+    os.rename(tmp, options.keystore)
+
+main()
+
+# vim: expandtab tabstop=4 shiftwidth=4


--
To view, visit http://gerrit.ovirt.org/12740
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I64ab90925eabb3cf1c43c39693dfb082400c8ba4
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-reports
Gerrit-Branch: master
Gerrit-Owner: Alon Bar-Lev <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to