mirror of https://github.com/huashengdun/webssh
Support https server
parent
deef92fe66
commit
827a0d8a9d
|
@ -0,0 +1,21 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDYDCCAkigAwIBAgIJAPPORA/o2Zd4MA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
|
||||
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
||||
aWRnaXRzIFB0eSBMdGQwHhcNMTgxMDE0MDgwNTQzWhcNMjExMDEzMDgwNTQzWjBF
|
||||
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
|
||||
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEAvSFaffq6ExFCPN4cApRopGEqVIipAYb6Ky3VHVu4pW0tOdrdKafGGYkN
|
||||
GWQdsLV0AAzzxmCAPpXmmAx0m0mgtPaJp3iW8NUibkISxdEO/QJOA7y8O9iWhDdb
|
||||
l9ghjwPI5AwURQkDkXbcBBBzQksYDaYseL2NGDGXkKCUQQoLzV0H+SV3vCPrbOXH
|
||||
t50HKgKzEOGoT8LcI7BRCTXk1xTlK0b/4ylKUwKIsfNPH0a9RkukBjMFkpXG/2CV
|
||||
VWb89+TkMzQwhcpIVn6rUCJQW5pHVRYLACP32Zki7xPUJb9OfF7XDK54v6Cwo3Fi
|
||||
aZWxN6rYhnn8wRTufY3PYzv5f3XiZwIDAQABo1MwUTAdBgNVHQ4EFgQUq0kfpU/m
|
||||
WQwNk3ymwm7fuVwYhJ0wHwYDVR0jBBgwFoAUq0kfpU/mWQwNk3ymwm7fuVwYhJ0w
|
||||
DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAf2xudhAeOTUpNpw+
|
||||
XZWLBXBKZXINd7PrUDgEG4bB0/0kYZN+T7bMJEtmv6+9t57y6jSni9sQzpbvT2tJ
|
||||
TrbZgwhDvyTm3mw5n5RpAB9ZK+lnMcasa5N4qSd6wmpXjkC+kcEs7oQ8PwgIf3xT
|
||||
/aGdoswNTWCz0W8vs8yRynLB4MKx1d20IMlDkfGu5n7wXhNK0ymcT8pa6iqEYl6X
|
||||
bhPVTlELl8bM/OKktFc42VXoRghLRnfl8yM/9t7HVHKfHXZrLpIdtEOvnKwtzX5r
|
||||
fBMs4IPa0OIPHGCcbLGT4rIbSvSaI8yOPA93G1XXbMF1VKdKyzdGjMS6aFKfbrhV
|
||||
lnaUOA==
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,28 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9IVp9+roTEUI8
|
||||
3hwClGikYSpUiKkBhvorLdUdW7ilbS052t0pp8YZiQ0ZZB2wtXQADPPGYIA+leaY
|
||||
DHSbSaC09omneJbw1SJuQhLF0Q79Ak4DvLw72JaEN1uX2CGPA8jkDBRFCQORdtwE
|
||||
EHNCSxgNpix4vY0YMZeQoJRBCgvNXQf5JXe8I+ts5ce3nQcqArMQ4ahPwtwjsFEJ
|
||||
NeTXFOUrRv/jKUpTAoix808fRr1GS6QGMwWSlcb/YJVVZvz35OQzNDCFykhWfqtQ
|
||||
IlBbmkdVFgsAI/fZmSLvE9Qlv058XtcMrni/oLCjcWJplbE3qtiGefzBFO59jc9j
|
||||
O/l/deJnAgMBAAECggEAZSwcblvbgiuvVUQzk6W0PIrFzCa20dxUoxiHcocIRWYb
|
||||
1WEhAhF/xVUtLrIBt++5N/W1yh8BO3mQuzGehxth3qwrguzdQcOiAX1S8YMeE3ZS
|
||||
KWmjABiim+PJGXdCrHCH3IYhqbRitkPw+jOalJH7MgH8tDIh8hlFTNa5t/kZyybW
|
||||
uGFbqF6OFmyHSDIPvjPALzSlmd5po+EywnA5oa3sObj4n5xuaFB2l/IaF3ix38vT
|
||||
geo517L15cCuAa7x42i1cAGn5H/hdeO/Dw+MGk+0sXRRPooCMBzKztxpsB+7kNhk
|
||||
jbsVHmTkE5UG/T7Uc0PsthZNjFwouPOrQQVUFYTnwQKBgQDwBvpmc9vX4gnADa7p
|
||||
L2lgMVo6KccPFeFr4DIAYmwS0Vl0sB2j6nPVEBg3PatGLKGNMCIlcj+A3z6KQ+4o
|
||||
n7pnekRwX+2+m3OPX4Rbw8c/+E0CiRPtmYp9BISKNgPoSRGsI6s/L3wzagsDsQ3v
|
||||
xhKCohvfyY8JwUEPX6Hosmu/UQKBgQDJt0/ihWn0g/2uOKnXlXthxvkXFoR45sO7
|
||||
lY/yoyJB+Z4yGAjJlbyra+5xnReqYyBnf34/2AoddjT45dPCaFucMInQFINdMGF1
|
||||
NeVNzC6xa/7jjbgwf4kGqHsLC85Mrq3wyK5hwhMmfEPmRs6w+CRzM/Q78Bsr5P/T
|
||||
zEa13jFINwKBgQC50L0ieUjVDKD9s9oXnWOXWz19T4BRtl+nco1i7M67lqQJCJo5
|
||||
njQD2ozUnwIrtjtuoLeeg56Ttr+krEf/3P+iQe4fjLPxXkiM0qYVoC9s311GvDXY
|
||||
N4gVllzA3mYR+hcbSxW0OZ+N8ecK+ZNPbug/hx3LFi+MnrYuH5upGA7/sQKBgCRk
|
||||
nlUQHP2wkqRMNNhgb9JEQ8yWk2/8snO1mDL+m7+reY8wJuW3zkJfRrXY0dw75izG
|
||||
I9EA+VI3cXc2f+4jReP4HeUczlaR1AOBpc1TeVkpUuNbPlABsocw/oIPrzjGiztV
|
||||
+aBJk4ruAJIbVE85ddoTFY161Gwm9MERqfBGFj4hAoGAN/ry0KC9/QkLkuPjs3uL
|
||||
AU3xjBJt1SMB7KZq1yt8mBo8M4q/E3ulynBK7G3f+hS2aj7OAhU4IcPRPGqjsLO1
|
||||
dZTIOMeVyOAr0TAaioCCIyvf8hEjA7cXddnWBJYi3WiUpOc6J0uINoSlrAX2UXtw
|
||||
/Aq5PmJKn4D4a75f+ue2Sw8=
|
||||
-----END PRIVATE KEY-----
|
|
@ -1,4 +1,5 @@
|
|||
import io
|
||||
import ssl
|
||||
import sys
|
||||
import os.path
|
||||
import unittest
|
||||
|
@ -8,7 +9,8 @@ import tornado.options as options
|
|||
from tests.utils import make_tests_data_path
|
||||
from webssh.policy import load_host_keys
|
||||
from webssh.settings import (
|
||||
get_host_keys_settings, get_policy_setting, base_dir, print_version
|
||||
get_host_keys_settings, get_policy_setting, base_dir, print_version,
|
||||
get_ssl_context
|
||||
)
|
||||
from webssh.utils import UnicodeType
|
||||
from webssh._version import __version__
|
||||
|
@ -78,3 +80,43 @@ class TestSettings(unittest.TestCase):
|
|||
)
|
||||
else:
|
||||
self.assertIsInstance(instance, paramiko.client.RejectPolicy)
|
||||
|
||||
def test_get_ssl_context(self):
|
||||
options.certfile = ''
|
||||
options.keyfile = ''
|
||||
ssl_ctx = get_ssl_context(options)
|
||||
self.assertIsNone(ssl_ctx)
|
||||
|
||||
options.certfile = 'provided'
|
||||
options.keyfile = ''
|
||||
with self.assertRaises(ValueError) as ctx:
|
||||
ssl_ctx = get_ssl_context(options)
|
||||
self.assertEqual('keyfile is not provided', str(ctx.exception))
|
||||
|
||||
options.certfile = ''
|
||||
options.keyfile = 'provided'
|
||||
with self.assertRaises(ValueError) as ctx:
|
||||
ssl_ctx = get_ssl_context(options)
|
||||
self.assertEqual('certfile is not provided', str(ctx.exception))
|
||||
|
||||
options.certfile = 'FileDoesNotExist'
|
||||
options.keyfile = make_tests_data_path('cert.key')
|
||||
with self.assertRaises(ValueError) as ctx:
|
||||
ssl_ctx = get_ssl_context(options)
|
||||
self.assertIn('does not exist', str(ctx.exception))
|
||||
|
||||
options.certfile = make_tests_data_path('cert.key')
|
||||
options.keyfile = 'FileDoesNotExist'
|
||||
with self.assertRaises(ValueError) as ctx:
|
||||
ssl_ctx = get_ssl_context(options)
|
||||
self.assertIn('does not exist', str(ctx.exception))
|
||||
|
||||
options.certfile = make_tests_data_path('cert.key')
|
||||
options.keyfile = make_tests_data_path('cert.key')
|
||||
with self.assertRaises(ssl.SSLError) as ctx:
|
||||
ssl_ctx = get_ssl_context(options)
|
||||
|
||||
options.certfile = make_tests_data_path('cert.crt')
|
||||
options.keyfile = make_tests_data_path('cert.key')
|
||||
ssl_ctx = get_ssl_context(options)
|
||||
self.assertIsNotNone(ssl_ctx)
|
||||
|
|
|
@ -4,8 +4,10 @@ import tornado.ioloop
|
|||
|
||||
from tornado.options import options
|
||||
from webssh.handler import IndexHandler, WsockHandler
|
||||
from webssh.settings import (get_app_settings, get_host_keys_settings,
|
||||
get_policy_setting, max_body_size)
|
||||
from webssh.settings import (
|
||||
get_app_settings, get_host_keys_settings, get_policy_setting,
|
||||
get_ssl_context, max_body_size, xheaders
|
||||
)
|
||||
|
||||
|
||||
def make_handlers(loop, options):
|
||||
|
@ -28,9 +30,15 @@ def main():
|
|||
options.parse_command_line()
|
||||
loop = tornado.ioloop.IOLoop.current()
|
||||
app = make_app(make_handlers(loop, options), get_app_settings(options))
|
||||
server_settings = dict(xheaders=True, max_body_size=max_body_size)
|
||||
app.listen(options.port, options.address, **server_settings)
|
||||
ssl_ctx = get_ssl_context(options)
|
||||
kwargs = dict(xheaders=xheaders, max_body_size=max_body_size)
|
||||
app.listen(options.port, options.address, **kwargs)
|
||||
logging.info('Listening on {}:{}'.format(options.address, options.port))
|
||||
if ssl_ctx:
|
||||
kwargs.update(ssl_options=ssl_ctx)
|
||||
app.listen(options.sslPort, options.sslAddress, **kwargs)
|
||||
logging.info('Listening on ssl {}:{}'.format(options.sslAddress,
|
||||
options.sslPort))
|
||||
loop.start()
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import logging
|
||||
import os.path
|
||||
import ssl
|
||||
import sys
|
||||
|
||||
from tornado.options import define
|
||||
|
@ -17,6 +18,10 @@ def print_version(flag):
|
|||
|
||||
define('address', default='127.0.0.1', help='Listen address')
|
||||
define('port', type=int, default=8888, help='Listen port')
|
||||
define('sslAddress', default='0.0.0.0', help='SSL listen address')
|
||||
define('sslPort', type=int, default=4433, help='SSL listen port')
|
||||
define('certfile', default='', help='SSL certificate file')
|
||||
define('keyfile', default='', help='SSL key file')
|
||||
define('debug', type=bool, default=False, help='Debug mode')
|
||||
define('policy', default='warning',
|
||||
help='Missing host key policy, reject|autoadd|warning')
|
||||
|
@ -30,6 +35,7 @@ define('version', type=bool, help='Show version information',
|
|||
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
max_body_size = 1 * 1024 * 1024
|
||||
swallow_http_errors = True
|
||||
xheaders = True
|
||||
|
||||
|
||||
def get_app_settings(options):
|
||||
|
@ -69,3 +75,20 @@ def get_policy_setting(options, host_keys_settings):
|
|||
logging.info(policy_class.__name__)
|
||||
check_policy_setting(policy_class, host_keys_settings)
|
||||
return policy_class()
|
||||
|
||||
|
||||
def get_ssl_context(options):
|
||||
if not options.certfile and not options.keyfile:
|
||||
return None
|
||||
elif not options.certfile:
|
||||
raise ValueError('certfile is not provided')
|
||||
elif not options.keyfile:
|
||||
raise ValueError('keyfile is not provided')
|
||||
elif not os.path.isfile(options.certfile):
|
||||
raise ValueError('File {!r} does not exist'.format(options.certfile))
|
||||
elif not os.path.isfile(options.keyfile):
|
||||
raise ValueError('File {!r} does not exist'.format(options.keyfile))
|
||||
else:
|
||||
ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
||||
ssl_ctx.load_cert_chain(options.certfile, options.keyfile)
|
||||
return ssl_ctx
|
||||
|
|
Loading…
Reference in New Issue