summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDjLegolas <DjLegolas@protonmail.com>2020-05-01 11:37:11 +0300
committerCalum Lind <calumlind+deluge@gmail.com>2021-12-20 22:09:08 +0000
commit88ffd1b843c33402045bd2facde04be0a73027ec (patch)
tree2c3b95435cbebd5aca43e50a56ac273232a8ec57
parent6a10e57f7ea3b780e93f0b243a5ade2277fcb8d3 (diff)
downloaddeluge-88ffd1b843c33402045bd2facde04be0a73027ec.tar.gz
deluge-88ffd1b843c33402045bd2facde04be0a73027ec.tar.bz2
deluge-88ffd1b843c33402045bd2facde04be0a73027ec.zip
[Servers] Moved check_ssl_keys and generate_ssl_keys to crypto_utils.py
With this change, we drop a core dependency from the UI. This will help group together all related functionality in one place, i.e. all security related functions. Also updated testssl.sh version to 3.0.6 (SECURITY_TEST) Closes: deluge-torrent/deluge#288
-rw-r--r--.github/workflows/ci.yml15
-rw-r--r--deluge/core/rpcserver.py60
-rw-r--r--deluge/crypto_utils.py62
-rw-r--r--deluge/tests/test_security.py7
-rw-r--r--deluge/ui/web/server.py3
5 files changed, 82 insertions, 65 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b3c7dc990..206da5f58 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -41,12 +41,25 @@ jobs:
key-server: keyserver.ubuntu.com
install: python3-libtorrent-dbg
+ - name: Sets env var for security
+ if: (github.event_name == 'pull_request' && contains(github.event.pull_request.body, 'security_test')) || (github.event_name == 'push' && contains(github.event.head_commit.message, 'security_test'))
+ run: echo "SECURITY_TESTS=True" >> $GITHUB_ENV
+
- name: Install dependencies
run: |
pip install --upgrade pip wheel
pip install -r requirements.txt -r requirements-tests.txt
pip install -e .
+ - name: Install security dependencies
+ if: contains(env.SECURITY_TESTS, 'True')
+ run: |
+ wget -O- $TESTSSL_URL$TESTSSL_VER | tar xz
+ mv -t deluge/tests/data testssl.sh-$TESTSSL_VER/testssl.sh testssl.sh-$TESTSSL_VER/etc/;
+ env:
+ TESTSSL_VER: 3.0.6
+ TESTSSL_URL: https://codeload.github.com/drwetter/testssl.sh/tar.gz/refs/tags/v
+
- name: Setup core dump directory
run: |
sudo mkdir /cores/ && sudo chmod 777 /cores/
@@ -57,7 +70,7 @@ jobs:
ulimit -c unlimited # Enable core dumps to be captured
cp /usr/lib/python3/dist-packages/libtorrent*.so $GITHUB_WORKSPACE/deluge
python -c 'from deluge._libtorrent import lt; print(lt.__version__)';
- catchsegv python -X dev -m pytest -v -m "not (todo or gtkui or security)" deluge
+ catchsegv python -X dev -m pytest -v -m "not (todo or gtkui)" deluge
- uses: actions/upload-artifact@v2
# capture all crashes as build artifacts
diff --git a/deluge/core/rpcserver.py b/deluge/core/rpcserver.py
index adb521901..4fa94c387 100644
--- a/deluge/core/rpcserver.py
+++ b/deluge/core/rpcserver.py
@@ -12,13 +12,11 @@ from __future__ import unicode_literals
import logging
import os
-import stat
import sys
import traceback
from collections import namedtuple
from types import FunctionType
-from OpenSSL import crypto
from twisted.internet import defer, reactor
from twisted.internet.protocol import Factory, connectionDone
@@ -29,7 +27,7 @@ from deluge.core.authmanager import (
AUTH_LEVEL_DEFAULT,
AUTH_LEVEL_NONE,
)
-from deluge.crypto_utils import get_context_factory
+from deluge.crypto_utils import check_ssl_keys, get_context_factory
from deluge.error import (
DelugeError,
IncompatibleClient,
@@ -588,59 +586,3 @@ class RPCServer(component.Component):
def stop(self):
self.factory.state = 'stopping'
-
-
-def check_ssl_keys():
- """
- Check for SSL cert/key and create them if necessary
- """
- ssl_dir = deluge.configmanager.get_config_dir('ssl')
- if not os.path.exists(ssl_dir):
- # The ssl folder doesn't exist so we need to create it
- os.makedirs(ssl_dir)
- generate_ssl_keys()
- else:
- for f in ('daemon.pkey', 'daemon.cert'):
- if not os.path.exists(os.path.join(ssl_dir, f)):
- generate_ssl_keys()
- break
-
-
-def generate_ssl_keys():
- """
- This method generates a new SSL key/cert.
- """
- from deluge.common import PY2
-
- digest = 'sha256' if not PY2 else b'sha256'
-
- # Generate key pair
- pkey = crypto.PKey()
- pkey.generate_key(crypto.TYPE_RSA, 2048)
-
- # Generate cert request
- req = crypto.X509Req()
- subj = req.get_subject()
- setattr(subj, 'CN', 'Deluge Daemon')
- req.set_pubkey(pkey)
- req.sign(pkey, digest)
-
- # Generate certificate
- cert = crypto.X509()
- cert.set_serial_number(0)
- cert.gmtime_adj_notBefore(0)
- cert.gmtime_adj_notAfter(60 * 60 * 24 * 365 * 3) # Three Years
- cert.set_issuer(req.get_subject())
- cert.set_subject(req.get_subject())
- cert.set_pubkey(req.get_pubkey())
- cert.sign(pkey, digest)
-
- # Write out files
- ssl_dir = deluge.configmanager.get_config_dir('ssl')
- with open(os.path.join(ssl_dir, 'daemon.pkey'), 'wb') as _file:
- _file.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey))
- with open(os.path.join(ssl_dir, 'daemon.cert'), 'wb') as _file:
- _file.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
- # Make the files only readable by this user
- for f in ('daemon.pkey', 'daemon.cert'):
- os.chmod(os.path.join(ssl_dir, f), stat.S_IREAD | stat.S_IWRITE)
diff --git a/deluge/crypto_utils.py b/deluge/crypto_utils.py
index 7672efa71..978eb0410 100644
--- a/deluge/crypto_utils.py
+++ b/deluge/crypto_utils.py
@@ -9,6 +9,10 @@
from __future__ import division, print_function, unicode_literals
+import os
+import stat
+
+from OpenSSL import crypto
from OpenSSL.crypto import FILETYPE_PEM
from twisted.internet.ssl import (
AcceptableCiphers,
@@ -18,6 +22,8 @@ from twisted.internet.ssl import (
TLSVersion,
)
+import deluge.configmanager
+
# A TLS ciphers list.
# Sources for more information on TLS ciphers:
# - https://wiki.mozilla.org/Security/Server_Side_TLS
@@ -77,3 +83,59 @@ def get_context_factory(cert_path, pkey_path):
ctx.set_options(SSL_OP_NO_RENEGOTIATION)
return cert_options
+
+
+def check_ssl_keys():
+ """
+ Check for SSL cert/key and create them if necessary
+ """
+ ssl_dir = deluge.configmanager.get_config_dir('ssl')
+ if not os.path.exists(ssl_dir):
+ # The ssl folder doesn't exist so we need to create it
+ os.makedirs(ssl_dir)
+ generate_ssl_keys()
+ else:
+ for f in ('daemon.pkey', 'daemon.cert'):
+ if not os.path.exists(os.path.join(ssl_dir, f)):
+ generate_ssl_keys()
+ break
+
+
+def generate_ssl_keys():
+ """
+ This method generates a new SSL key/cert.
+ """
+ from deluge.common import PY2
+
+ digest = 'sha256' if not PY2 else b'sha256'
+
+ # Generate key pair
+ pkey = crypto.PKey()
+ pkey.generate_key(crypto.TYPE_RSA, 2048)
+
+ # Generate cert request
+ req = crypto.X509Req()
+ subj = req.get_subject()
+ setattr(subj, 'CN', 'Deluge Daemon')
+ req.set_pubkey(pkey)
+ req.sign(pkey, digest)
+
+ # Generate certificate
+ cert = crypto.X509()
+ cert.set_serial_number(0)
+ cert.gmtime_adj_notBefore(0)
+ cert.gmtime_adj_notAfter(60 * 60 * 24 * 365 * 3) # Three Years
+ cert.set_issuer(req.get_subject())
+ cert.set_subject(req.get_subject())
+ cert.set_pubkey(req.get_pubkey())
+ cert.sign(pkey, digest)
+
+ # Write out files
+ ssl_dir = deluge.configmanager.get_config_dir('ssl')
+ with open(os.path.join(ssl_dir, 'daemon.pkey'), 'wb') as _file:
+ _file.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey))
+ with open(os.path.join(ssl_dir, 'daemon.cert'), 'wb') as _file:
+ _file.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
+ # Make the files only readable by this user
+ for f in ('daemon.pkey', 'daemon.cert'):
+ os.chmod(os.path.join(ssl_dir, f), stat.S_IREAD | stat.S_IWRITE)
diff --git a/deluge/tests/test_security.py b/deluge/tests/test_security.py
index 700fc9967..4ad66ab51 100644
--- a/deluge/tests/test_security.py
+++ b/deluge/tests/test_security.py
@@ -45,6 +45,7 @@ class SecurityBaseTestCase(object):
get_test_data_file('testssl.sh'),
'--quiet',
'--nodns',
+ 'none',
'--color',
'0',
test,
@@ -55,11 +56,11 @@ class SecurityBaseTestCase(object):
def on_result(results):
if test == '-e':
- results = results[0].split('\n')[7:-6]
+ results = results[0].split(b'\n')[7:-6]
self.assertTrue(len(results) > 3)
else:
- self.assertIn('OK', results[0])
- self.assertNotIn('NOT ok', results[0])
+ self.assertIn(b'OK', results[0])
+ self.assertNotIn(b'NOT ok', results[0])
d.addCallback(on_result)
return d
diff --git a/deluge/ui/web/server.py b/deluge/ui/web/server.py
index ea2658071..2f8921b22 100644
--- a/deluge/ui/web/server.py
+++ b/deluge/ui/web/server.py
@@ -23,8 +23,7 @@ from twisted.web.resource import EncodingResourceWrapper
from deluge import common, component, configmanager
from deluge.common import is_ipv6
-from deluge.core.rpcserver import check_ssl_keys
-from deluge.crypto_utils import get_context_factory
+from deluge.crypto_utils import check_ssl_keys, get_context_factory
from deluge.i18n import set_language, setup_translation
from deluge.ui.tracker_icons import TrackerIcons
from deluge.ui.web.auth import Auth