fixed the 'status' method of the encrypted_webinterface module

added a method 'create_misc_config_file' to cryptobox.core.settings
used this method to create the certificate file
improved the description on how to set up an encrypted webinterface connection
added description of the 'encrypted_webinterface' plugin to README.ssl
moved 'coding_guidelines.txt' to the wiki
This commit is contained in:
lars 2007-01-25 23:04:45 +00:00
parent 4e5b8e088f
commit 2ecc20e905
4 changed files with 93 additions and 60 deletions

View file

@ -4,7 +4,9 @@ This file describes how to encrypt your connection to the CryptoBox webserver.
This is highly recommended as the encryption password for your data could be
exposed to intruders in your local network otherwise.
There are several ways for setting up a SSL connection:
Below you will find detailed descriptions on how to set up an encrypted
connection to the webinterface:
- use the plugin "encrypted_webinterface"
- run the CryptoBox webserver behind an ssl-enabled webserver
- use stunnel to provide an SSL socket
- use the a proxy server (e.g. pound)
@ -17,7 +19,27 @@ need encrypted http connections.
-------------------------------------------------------------------
1) CryptoBox behind an ssl-enabled webserver
1) using the plugin 'encrypted_webinterface'
This plugin is disabled by default. You can enable it in your
cryptobox.conf file by removing it from the 'DisabledPlugins' setting.
The plugin does the following during startup of the CryptoBox:
- create a self-signed X.509 certificate if necessary
- run stunnel on port 443 (https) with this certificate
Now you just need to point your browser to the URL of the CryptoBox with
'https' instead of 'http' and to accept the certificate permanently
(the Internet Explorer is not capable of doing this - use Firefox,
Konqueror, Safari, ... instead, if you need this ability). That's it!
Of course, this will not work, if the port 443 is already in use by
another program - in this case, you should better choose one of the
other solutions described below.
-------------------------------------------------------------------
2) CryptoBox behind an ssl-enabled webserver
Read the documentation of your favourite webserver to learn how to enable
ssl encryption.
@ -38,16 +60,16 @@ need encrypted http connections.
-------------------------------------------------------------------
2) CryptoBox behind stunnel
3) CryptoBox behind stunnel (configured manually)
You may want to tunnel the traffic between the cryptobox-server
and your browser. "stunnel" is an excellent candidate for this job.
If you do not have an ssl certificate yet, then you should create
one first. On Debian: "apt-get install ssl-cert" and run the following
command (replace the <NAMES>; a default CERT_CONF is shipped with the
cryptobox-server package):
command (the supplied example openssl.conf file resides in the doc
directory of the cryptobox-server package):
make-ssl-cert <CERT_CONF> <CERT_FILE_NAME>
make-ssl-cert conf-examples/openssl.conf <CERT_FILE_NAME>
In case, that you already have a certificate just run this command:
@ -58,9 +80,10 @@ need encrypted http connections.
-------------------------------------------------------------------
3) CryptoBox behind a proxy server
4) CryptoBox behind a proxy server
As there are many proxy servers around, we cannot describe all of them. As
an example, we will explain the setup of the load-balancing proxy 'pound'.
an example, we will explain the setup of the load-balancing proxy 'pound'
(http://www.apsis.ch/pound/).
Just add the following lines to you /etc/pound/pound.cfg:
# Remove the X-SSL-Request header from incoming
@ -77,13 +100,15 @@ need encrypted http connections.
-------------------------------------------------------------------
4) Problems with SSL detection?
5) Problems with SSL detection?
If the CryptoBox continues to complain about the unencrypted connection, even
if it runs behind an ssl-enabled webserver or behind stunnel, then you can do
one of the following things:
- disable the plugin 'encypted_webinterface' in the cryptobox.conf file
if you do not need it
- set the request header value "X-SSL-Request" to "1" (the digit 'one')
- set the environment setting "HTTPS" to a non-empty value during the
startup of the CryptoBox webserver. Maybe /etc/default/cryptobox-server
would be the right place for this.
startup of the CryptoBox webserver. Maybe
/etc/default/cryptobox-server would be the right place for this.
- let the CryptoBox webserver listen to port 443

View file

@ -1,18 +0,0 @@
Maybe we can add some notes here to get a consistent coding experience :)
-------------------------------------------------------------------------------
comments:
- should be usable for pydoc
- ''' or """ at the beginning of every class/method
- ## for longterm comments, that are useful for understanding
- #blabla for codelines, that are out for experimenting and might be used later again
error handling:
- unspecific error handling is evil (try: "grep -r except: .")
unit testing:
- first write a unittest and then write the relating code until the unittest stops failing :)
- 'unittests.ClassName.py' should contain all tests for 'ClassName.py'
- commits with broken unit tests are evil (fix or disable the code (not the test ;) ))

View file

@ -69,9 +69,12 @@ class encrypted_webinterface(cryptobox.plugins.base.CryptoBoxPlugin):
def get_status(self):
"""Retrieve the status of the feature.
"""Retrieve the current state of the webinterface connection
"""
return "TODO"
if self.__is_encrypted():
return "1"
else:
return "0"
def get_warnings(self):
@ -85,21 +88,32 @@ class encrypted_webinterface(cryptobox.plugins.base.CryptoBoxPlugin):
warnings.append((45, "Plugins.%s.MissingModuleM2Crypto" % self.get_name()))
if not os.path.isfile(self.root_action.STUNNEL_BIN):
warnings.append((44, "Plugins.%s.MissingProgramStunnel" % self.get_name()))
## perform some checks for encrypted connections
## check an environment setting - this is quite common behind proxies
## check if it is a local connection (or via stunnel)
## the arbitrarily chosen header is documented in README.proxy
if (cherrypy.request.scheme != "https") \
and (not os.environ.has_key("HTTPS")) \
and (not (cherrypy.request.headers.has_key("Remote-Host") \
and (cherrypy.request.headers["Remote-Host"] == "127.0.0.1"))) \
and (not (cherrypy.request.headers.has_key("X-SSL-Request") \
and (cherrypy.request.headers["X-SSL-Request"] == "1"))):
if not self.__is_encrypted():
## plaintext connection -> "heavy security risk" (priority=20..39)
warnings.append((25, "Plugins.%s.NoSSL" % self.get_name()))
return warnings
def __is_encrypted(self):
"""perform some checks for encrypted connections
"""
if cherrypy.request.scheme == "https":
return True
## check an environment setting - this is quite common behind proxies
if os.environ.has_key("HTTPS"):
return True
## check if it is a local connection (or via stunnel)
if cherrypy.request.headers.has_key("Remote-Host") \
and (cherrypy.request.headers["Remote-Host"] == "127.0.0.1"):
return True
## the arbitrarily chosen header is documented in README.proxy
if cherrypy.request.headers.has_key("X-SSL-Request") \
and (cherrypy.request.headers["X-SSL-Request"] == "1"):
return True
## it looks like a plain connection
return False
def handle_event(self, event, event_info=None):
"""Create a certificate during startup (if it does not exist) and run stunnel
"""
@ -107,12 +121,14 @@ class encrypted_webinterface(cryptobox.plugins.base.CryptoBoxPlugin):
cert_abs_name = self.cbox.prefs.get_misc_config_filename(CERT_FILENAME)
if not os.path.isfile(cert_abs_name):
try:
self.__create_certificate(cert_abs_name)
self.cbox.log.info("Created new SSL certificate: %s" % cert_abs_name)
cert = self.__get_certificate()
self.cbox.prefs.create_misc_config_file(CERT_FILENAME, cert)
self.cbox.log.info("Created new SSL certificate: %s" % \
cert_abs_name)
except IOError, err_msg:
## do not run stunnel without a certificate
self.cbox.log.warn("Failed to create new SSL certificate (%s): %s" % \
(cert_abs_name, err_msg))
self.cbox.log.warn("Failed to create new SSL certificate (%s): %s" \
% (cert_abs_name, err_msg))
return
self.__run_stunnel(cert_abs_name)
elif event == "shutdown":
@ -181,8 +197,8 @@ class encrypted_webinterface(cryptobox.plugins.base.CryptoBoxPlugin):
return False
def __create_certificate(self, filename):
"""Create a self-signed certificate and store it in a file
def __get_certificate(self):
"""Create a self-signed certificate and return its pem content
The code is mainly inspired by:
https://dev.tribler.org/browser/m2crypto/trunk/contrib/SimpleX509create.py
@ -226,17 +242,5 @@ class encrypted_webinterface(cryptobox.plugins.base.CryptoBoxPlugin):
result = ""
result += cert.as_pem()
result += pkey.as_pem(cipher=None)
if not os.path.exists(os.path.dirname(filename)):
os.mkdir(os.path.dirname(filename))
try:
certfile = open(filename, "w")
except IOError:
raise
try:
certfile.write(result)
except IOError:
certfile.close()
raise
certfile.close()
os.chmod(filename, 0600)
return result

View file

@ -100,6 +100,28 @@ class CryptoBoxSettings:
'name' should not contain slashes (no directory part!)
"""
return os.path.join(self.prefs["Locations"]["SettingsDir"], "misc", name)
def create_misc_config_file(self, name, content):
"""Create a new configuration file in the 'settings' directory
"name" should be the basename (without a directory)
"content" will be directly written to the file
this method may throw an IOException
"""
misc_conf_file = self.get_misc_config_filename(name)
misc_conf_dir = os.path.dirname(misc_conf_file)
if not os.path.isdir(misc_conf_dir):
os.mkdir(misc_conf_dir)
cfile = open(misc_conf_file, "w")
try:
cfile.write(content)
except IOError:
cfile.close()
raise
cfile.close()
## reread all misc files automatically - this should be ok
self.reload_misc_files()
def requires_partition(self):