Commits

clach04 committed 2066f9f

Initial SSL support.

Comments (0)

Files changed (2)

 
 If "server_dir_whitelist_policy" is not "silent" the server will terminate
 the client connection if "server_dir_whitelist" is set.
+
+
+Enabling SSL support
+
+How to generate an SSL certificate suitable for protecting traffic.
+
+This will generate a certificate that is good for 1 year.
+
+    #!/bin/sh
+    
+    rm server.key server.csr key.pem cert.pem
+    
+    openssl genrsa -des3 -out server.key 1024
+    openssl req -new -key server.key -out server.csr
+    openssl rsa -in server.key -out key.pem  # remove passphrase
+    openssl x509 -req -days 365 -in server.csr -signkey key.pem -out cert.pem
+
+Then set config to enable ssl support and use the certificate/key generated
+above:
+
+    {
+        "use_ssl": true,
+        "ssl_certfile": "cert.pem",
+        "ssl_keyfile": "key.pem",
+    }
+
+If the client config sets "ssl_certfile", the server certificate will be
+checked and the connection will be encrypted. If "ssl_certfile" is not set
+client side, the connection will be encrypted but the certificate will not
+be checked.
+
+The server needs both the certificate and key file. Note if the key file is
+protected by a pass phrase the server process will prompt on the console!
+For convenience, consider removing the pass phrase from the key file.
 import os
 import sys
 import socket
+import ssl
 import SocketServer
 import threading
 import select
 SKSYNC_PROTOCOL_NON_RECURSIVE = '1\n'
 
 
+SSL_VERSION = ssl.PROTOCOL_TLSv1
+
+
 class BaseSkSyncException(Exception):
     '''Base SK Sync exception'''
 
 
         sync_timer = SimpleTimer()
         sync_timer.start()
-        
+
         # self.request is the TCP socket connected to the client
+        if config.get('use_ssl'):
+            try:
+                logger.info('Attempting SSL session')
+                ssl_certfile = config.get('ssl_certfile')
+                ssl_keyfile = config.get('ssl_keyfile')
+                logger.info('using SSL certificate file  %r' % ssl_certfile)
+                logger.info('using SSL key file  %r' % ssl_keyfile)
+
+                self.request = ssl.wrap_socket(self.request,
+                                    server_side=True,
+                                    certfile=ssl_certfile,
+                                    keyfile=ssl_keyfile,
+                                    ssl_version=SSL_VERSION)
+            except ssl.SSLError, info:
+                logger.error('Error starting SSL, check certificate and key are valid. %r' % info)
+                # could be a bad client....
+                return
         reader = SKBufferedSocket(self.request)
         response = reader.next()
         logger.debug('Received: %r' % response)
     server.serve_forever()
 
 
-def client_start_sync(ip, port, server_path, client_path, sync_type=SKSYNC_PROTOCOL_TYPE_FROM_SERVER_USE_TIME, recursive=False):
+def client_start_sync(ip, port, server_path, client_path, sync_type=SKSYNC_PROTOCOL_TYPE_FROM_SERVER_USE_TIME, recursive=False, use_ssl=None, ssl_certfile=None):
     """Implements SK Client, currently only supports:
        * direction =  "from server (use time)" ONLY
     """
 
     # Connect to the server
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    s.connect((ip, port))
+
+    if use_ssl:
+        try:
+            logger.info('Attempting SSL session')
+            if ssl_certfile:
+                logger.info('using SSL certificate file  %r' % ssl_certfile)
+                s = ssl.wrap_socket(s,
+                               ca_certs=ssl_certfile,
+                               cert_reqs=ssl.CERT_REQUIRED,
+                               ssl_version=SSL_VERSION)
+            else:
+                logger.info('ignoring SSL certificate')
+                s = ssl.wrap_socket(s,
+                               cert_reqs=ssl.CERT_NONE,
+                               ssl_version=SSL_VERSION)
+            s.connect((ip, port))
+        except ssl.SSLError, info:
+            logger.error('Error starting SSL connection, check SSL is enabled on server and certificate and key are valid. %r' % info)
+            return
+    else:
+        s.connect((ip, port))
     logger.info('connected')
 
     message = SKSYNC_PROTOCOL_01
 
     client_config = config[config_name]
     server_path, client_path = client_config['server_path'], client_config['client_path']
-    client_start_sync(host, port, server_path, client_path)
+    use_ssl = config.get('use_ssl')
+    ssl_certfile = config.get('ssl_certfile')
+    client_start_sync(host, port, server_path, client_path, use_ssl=use_ssl, ssl_certfile=ssl_certfile)
 
 
 def main(argv=None):