]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
restful: Use fixed cert/pkey files
authorBoris Ranto <branto@redhat.com>
Tue, 9 May 2017 11:38:38 +0000 (13:38 +0200)
committerBoris Ranto <branto@redhat.com>
Mon, 22 May 2017 17:20:37 +0000 (19:20 +0200)
This allows users to create their own certificates that are signed by a
CA. If the keys are not present then a self-signed certificate will be
created and distributed amongst all the mgr nodes.

It also allows us to get rid of the pyOpenSSL dependency.

Signed-off-by: Boris Ranto <branto@redhat.com>
ceph.spec.in
debian/control
src/pybind/mgr/restful/decorators.py
src/pybind/mgr/restful/module.py

index 130a4bb579e7af13d9076f2f9fce69646fdef1cf..2fae0b1072c1dbf6c7d8b6daebb626a982f642a0 100644 (file)
@@ -313,12 +313,10 @@ Group:          System/Filesystems
 Requires:       ceph-base = %{epoch}:%{version}-%{release}
 %if 0%{?fedora} || 0%{?rhel}
 Requires:       python-cherrypy
-Requires:       pyOpenSSL
 Requires:       python-werkzeug
 %endif
 %if 0%{?suse_version}
 Requires:      python-CherryPy
-Requires:       python-pyOpenSSL
 Requires:       python-Werkzeug
 %endif
 Requires:       python-pecan
index b34e778046aa0b287adb4c87d1e50bbe199a8d0b..cc4351d7c652b65a2abf87ad92f0c70059fe9dcc 100644 (file)
@@ -161,9 +161,8 @@ Description: debugging symbols for ceph-mds
 Package: ceph-mgr
 Architecture: linux-any
 Depends: ceph-base (= ${binary:Version}),
-         python-openssl
-         python-pecan
-         python-werkzeug
+         python-pecan,
+         python-werkzeug,
          ${misc:Depends},
          ${python:Depends},
         python-cherrypy3,
index 8399449bafaa31147c7108e005ef86d5872a5a3e..fd12b0202017a544987af4663a848744d04400c2 100644 (file)
@@ -4,10 +4,6 @@ from functools import wraps
 
 import traceback
 
-## We need this to access the instance of the module
-#
-# We can't use 'from module import instance' because
-# the instance is not ready, yet (would be None)
 import module
 
 
index 0d286eb71ddb125bcb05d81fdf3db880bef256c1..96c53e4809ce54fd3e246c003fd815f3e0abd139 100644 (file)
@@ -2,6 +2,7 @@
 A RESTful API for Ceph
 """
 
+import os
 import json
 import time
 import errno
@@ -13,11 +14,8 @@ import common
 
 from uuid import uuid4
 from pecan import jsonify, make_app
-from OpenSSL import crypto
-from tempfile import NamedTemporaryFile
 from pecan.rest import RestController
-from werkzeug.serving import make_server
-
+from werkzeug.serving import make_server, make_ssl_devcert
 
 from mgr_module import MgrModule, CommandResult
 
@@ -211,9 +209,6 @@ class Module(MgrModule):
 
         self.server = None
 
-        self.cert_file = None
-        self.pkey_file = None
-
 
     def serve(self):
         try:
@@ -232,29 +227,12 @@ class Module(MgrModule):
             separators=(',', ': '),
         )
 
-        self.cert = self.get_config_json('cert')
-        self.pkey = self.get_config_json('pkey')
-
-        # Create a new shared cert if it does not exist, yet
-        if not self.cert or not self.pkey:
-            (self.cert, self.pkey) = self.create_cert()
-            self.set_config_json('cert', self.cert)
-            self.set_config_json('pkey', self.pkey)
-
-        self.cert_file = NamedTemporaryFile()
-        self.cert_file.write(self.cert)
-        self.cert_file.flush()
-
-        self.pkey_file = NamedTemporaryFile()
-        self.pkey_file.write(self.pkey)
-        self.pkey_file.flush()
-
         # Create the HTTPS werkzeug server serving pecan app
         self.server = make_server(
             host='0.0.0.0',
             port=8002,
             app=make_app('restful.api.Root'),
-            ssl_context=(self.cert_file.name, self.pkey_file.name),
+            ssl_context=self.load_cert(),
         )
 
         self.server.serve_forever()
@@ -264,10 +242,6 @@ class Module(MgrModule):
         try:
             if self.server:
                 self.server.shutdown()
-            if self.cert_file:
-                self.cert_file.close()
-            if self.pkey_file:
-                self.pkey_file.close()
         except:
             self.log.error(str(traceback.format_exc()))
 
@@ -343,29 +317,41 @@ class Module(MgrModule):
             )
 
 
-    def create_cert(self):
-        # create a key pair
-        pkey = crypto.PKey()
-        pkey.generate_key(crypto.TYPE_RSA, 2048)
-
-        # create a self-signed cert
-        cert = crypto.X509()
-        cert.get_subject().C = "US"
-        cert.get_subject().ST = "Oregon"
-        cert.get_subject().L = "Portland"
-        cert.get_subject().O = "IT"
-        cert.get_subject().CN = "ceph-restful"
-        cert.set_serial_number(int(uuid4()))
-        cert.gmtime_adj_notBefore(0)
-        cert.gmtime_adj_notAfter(10*365*24*60*60)
-        cert.set_issuer(cert.get_subject())
-        cert.set_pubkey(pkey)
-        cert.sign(pkey, 'sha512')
-
-        return (
-            crypto.dump_certificate(crypto.FILETYPE_PEM, cert),
-            crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)
-        )
+    def load_cert(self):
+        cert_base = '/etc/ceph/ceph-mgr-restful'
+        cert_file = cert_base + '.crt'
+        pkey_file = cert_base + '.key'
+
+        # If the files are already there, we are good
+        if os.access(cert_file, os.R_OK) and os.access(pkey_file, os.R_OK):
+            return (cert_file, pkey_file)
+
+        # If the certificate is in the ceph config db, write it to the files
+        cert = self.get_config_json('cert')
+        pkey = self.get_config_json('pkey')
+
+        if cert and pkey:
+            f = file(cert_file, 'w')
+            f.write(cert)
+            f.close()
+
+            f = file(pkey_file, 'w')
+            f.write(pkey)
+            f.close()
+            return (cert_file, pkey_file)
+
+        # Otherwise, generate the certificate and save it in the config db
+        make_ssl_devcert(cert_base, host='localhost')
+
+        f = file(cert_file, 'r')
+        self.set_config_json('cert', f.read())
+        f.close()
+
+        f = file(pkey_file, 'r')
+        self.set_config_json('pkey', f.read())
+        f.close()
+
+        return (cert_file, pkey_file)
 
 
     def get_doc_api(self, root, prefix=''):