1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-03-12 04:58:34 +03:00

Merge remote-tracking branch 'origin/v3.6'

This commit is contained in:
Adolfo Gómez García 2023-03-13 18:01:15 +01:00
commit 8ca5f611d2
No known key found for this signature in database
GPG Key ID: DD1ABF20724CDA23
5 changed files with 50 additions and 12 deletions

View File

@ -3,5 +3,6 @@ from .. import types
defaultCertificate = types.CertificateInfoType(
private_key='-----BEGIN ENCRYPTED PRIVATE KEY-----\nMIIFHTBPBgkqhkiG9w0BBQ0wQjApBgkqhkiG9w0BBQwwHAQIfG2+iMYJBswCAggA\nMAwGCCqGSIb3DQIJBQAwFQYJKwYBBAGXVQECBAhCusU5R8ulZQSCBMgheyZ81Qkq\n+TcbPeBlUGCFllSUOo7xQ/OuwYSmzLx8LpN0hQNv4azF6MYH+I8eMSPd3A547yW3\nJE4GjIBfRvcq2X1UZ2FQfECU9UP0ShPuPrVhIh6ZZklmlRjbIF8hGfSzXAuafQb+\n4wXXsofahi/SPgqK1Gw65nRiMcoeRZchJkx8pBgKVWED6Cbh6aAkeqkVKPnsebiV\n6kE+0C7+hgNUbyRd46R+/5NXzPjg4ItfSak+PLzQ1KeRv4Cu6DdzRKJ4V9/MlNdU\nNNEkSVSEaRn4sv+eByU4uxBMaSmD1tLc/A7OmaAeRpIQvls3Zcf2+V0+anAtjbjd\n6eIb2nceey+dKFm4ewlR4mXuzj1QowRTHceOIkvKIrOODxdy9M5hNBZ7VLum29tY\nRhqtmEH2BZZJ8SpM2SsEZzPxqJFiVZbvpeOKjxlMyn1dFWn1rP8uMnfuMKqBaj5D\nd5clOPlwebYw5UpM6Vvawu4nGqxECTSWcfNlDYO5U/0Fsm9+JIrJ7Buukgv2+rhs\nD/6oUK9NB8AW9qnDr7UxbC/ujhkKQG3woaZlPbiMs5WQaS+DrTg4N49wPzS0h+ME\nF8ZzuPnd6+sMGQioCIrQAZ08rk54oCijBhFh8/EQhQKGsMFw2swi9t6+FVU5Bvil\nlhmBd3LA5EuQ5y1X0jRL/+GDiUiZw1gOJP8d/XzhUJL9AmamdqJ6/rAU7lUTNWkM\ndzmFonUO2Mh2zgEEudHsTOH8udZ2l64LIHc6fCkDmM8QzghjrEFyci6R8333DSSM\nwbM0MvyTLM7TTqZUD60EgD+Ihyr/wJcBZY7GVn7hTq7ee14zeI+dZFmTMYOnt0mA\ngof19t0naPPZU+zyl/ambNF5mmSkGOAl4IBHNvPt5ztEVbNpwW3DHbmdYW71Ax+z\nCDlr4iKZahv21o1PCesPV2IlaHZFD6aBRt0DxzMqtq9cpWsI1g7aEaAjRbSvqhMY\npUeqFXz/GfR9rjRkufr48//ll0/Q/Ogx7m1TjQ6mAEQrklI7pa2W0u3H0BpSZSis\nR6ST3ulE+wfsp8cau6q2er+BSsDhBjSn9FeCUjHzY56u9ud/kb6/jLEdgxNpj0na\n3WVqCCCL/dAFSWznBmdracZsRMXapXInHCiiOEkXXbXIXvRKiTPJXdN+w2/U2j2B\nwXZuazVSpmM+xAZTAS9dtBUQJo+5px9b6P09uagvTA32ezbpPXf+hSfmTdUwbmAY\nrmE9SW85tzX+cD17loygBBRrjOr4uQy/s/9FqLx8bM73jly05rdOmX28ECKwEA05\n8aCFkfqrl9J9doVapaUlywpJVPFtE6W6tCF+ULMfb16vEjT1du1+epEnbGGLRQxg\n3aFLyKlvFaNvR38fiQFUGtBgGOaBN3rhGpbMwjch3oReXv9X/4UCL6sVIiOH2H3c\nVSZdC3O5g6CMVe4zckUe1k9mLDb5524IHDFfptZ6Bw+uzrqIy3GHW8dJF2AK471b\nMUnCojTpdbFHaUs2u/rNKVUyY+vLf8hkyP+znBUoPxSJtty53EWNukxjjsxx0lx3\niZGqN72lXlXuSFZAIxi307+xxE21cbzDsMidyJkbKKGm/F4BOKvX9jWmAyYmBG6A\n1L3yNRouFWsYDwYAX2nZ1is=\n-----END ENCRYPTED PRIVATE KEY-----\n',
server_certificate='-----BEGIN CERTIFICATE-----\nMIIDcTCCAlkCBDfnXU8wDQYJKoZIhvcNAQELBQAwfTELMAkGA1UEBhMCRVMxDzAN\nBgNVBAgMBk1hZHJpZDEPMA0GA1UEBwwGTWFkcmlkMREwDwYDVQQKDAhVRFMgQ2Vy\ndDERMA8GA1UECwwIVURTIENlcnQxEjAQBgNVBAMMCTEyNy4wLjAuMTESMBAGA1Ud\nEQwJMTI3LjAuMC4xMB4XDTIwMDIxNzExNTkzMloXDTMwMDIxNDExNTkzMlowfTEL\nMAkGA1UEBhMCRVMxDzANBgNVBAgMBk1hZHJpZDEPMA0GA1UEBwwGTWFkcmlkMREw\nDwYDVQQKDAhVRFMgQ2VydDERMA8GA1UECwwIVURTIENlcnQxEjAQBgNVBAMMCTEy\nNy4wLjAuMTESMBAGA1UdEQwJMTI3LjAuMC4xMIIBIjANBgkqhkiG9w0BAQEFAAOC\nAQ8AMIIBCgKCAQEA2e1cW7YtRpNLazR3f/LqLv8OB0rKh8cUPH4wuQhbBTkee8Wu\n5eMSadRCIyRbKj4b8dtVfI9QW0SrmhGuMx1KCh3CsYd9XsWiKbGkiRBHIDOn5pkF\n6PUayDJ8KjnGbfnZjp0AmxXP4r1OO8jUPqzKS9Ubf5PgwcwdFiUKVfVPwGwctwt5\nt9YpSRONw0rTsCjVHvO2dd9h6EopskLCWxpN8l9kNLwLM/6t0IqVKmn5/IYPKKN2\nCX8a7IXpxwoiUs4sBZYhUMBWikB1hKQRSYafp1Xvc5PeTFXTFqGANnqz0NoZ8tqL\n8qjQUN/PCdtzhfcP5RgT2g1qyS2RBCMYH7Zs0wIDAQABMA0GCSqGSIb3DQEBCwUA\nA4IBAQCUt+qlLA1N9VXMwDQAYG4Kt6/UlMHCXAajHQQGtjdyGJ4++m7EIjI96hMU\n3Cx2gp2ggR3JGnuSR+DdBvPl5iGku7J8KV0JiJg30gTY8JuUIy/PMLZWloYKrBHV\nlin2GujQ4OsIt3dbr4XtcKW1Wd7L6fBzHlq7Xyxh+gcTzTvTmq67Q9XKlBWsegMf\nv4FKy0lfcSFK3vTzswQtuTontG4TqLiT/4AnMt3D0cTQ6b6KoZwUUX/TDNhau06d\nQ4Ilz8X61ka+4HBkFSR5ahP9noCVhwO329h+6epO141E5Tep3OLc/GCF4oaKOlMR\nfqxf5f2bghU0fxmtEoNJTZkBsN1S\n-----END CERTIFICATE-----\n',
password='Pw7qbatz5u-y-Z5ora2D2ZuBCm95AHnKRcpze53k8tw'
password='Pw7qbatz5u-y-Z5ora2D2ZuBCm95AHnKRcpze53k8tw',
ciphers=''
)

View File

@ -42,11 +42,20 @@ from .. import rest
from .public import PublicProvider
from .local import LocalProvider
DEFAULT_CIPHERS = (
'ECDHE-RSA-AES256-GCM-SHA384'
':ECDHE-ECDSA-AES256-GCM-SHA384'
':ECDHE-ECDSA-AES256-GCM-SHA384'
':ECDHE-ECDSA-AES256-CCM'
':DHE-RSA-AES256-SHA256'
)
# Not imported at runtime, just for type checking
if typing.TYPE_CHECKING:
from ..service import CommonService
from .handler import Handler
class HTTPServerHandler(http.server.BaseHTTPRequestHandler):
protocol_version = 'HTTP/1.0'
server_version = 'UDS Actor Server'
@ -54,7 +63,12 @@ class HTTPServerHandler(http.server.BaseHTTPRequestHandler):
_service: typing.Optional['CommonService'] = None
def sendJsonResponse(self, result: typing.Optional[typing.Any] = None, error: typing.Optional[str] = None, code: int = 200) -> None:
def sendJsonResponse(
self,
result: typing.Optional[typing.Any] = None,
error: typing.Optional[str] = None,
code: int = 200,
) -> None:
data = json.dumps({'result': result, 'error': error})
self.send_response(code)
self.send_header('Content-type', 'application/json')
@ -75,7 +89,9 @@ class HTTPServerHandler(http.server.BaseHTTPRequestHandler):
handlerType: typing.Optional[typing.Type['Handler']] = None
if len(path) == 3 and path[0] == 'actor' and path[1] == self._service._secret: # pylint: disable=protected-access
if (
len(path) == 3 and path[0] == 'actor' and path[1] == self._service._secret
): # pylint: disable=protected-access
# public method
handlerType = PublicProvider
elif len(path) == 2 and path[0] == 'ui':
@ -88,12 +104,18 @@ class HTTPServerHandler(http.server.BaseHTTPRequestHandler):
return
try:
result = getattr(handlerType(self._service, method, params), method + '_' + path[-1])() # last part of path is method
result = getattr(
handlerType(self._service, method, params), method + '_' + path[-1]
)() # last part of path is method
except AttributeError:
self.sendJsonResponse(error='Method not found', code=404)
return
except Exception as e:
logger.error('Got exception executing {} {}: {}'.format(method, '/'.join(path), str(e)))
logger.error(
'Got exception executing {} {}: {}'.format(
method, '/'.join(path), str(e)
)
)
self.sendJsonResponse(error=str(e), code=500)
return
@ -101,7 +123,10 @@ class HTTPServerHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self) -> None:
try:
params = {v.split('=')[0]: v.split('=')[1] for v in self.path.split('?')[1].split('&')}
params = {
v.split('=')[0]: v.split('=')[1]
for v in self.path.split('?')[1].split('&')
}
except Exception:
params = {}
@ -113,7 +138,9 @@ class HTTPServerHandler(http.server.BaseHTTPRequestHandler):
content = self.rfile.read(length)
params: typing.MutableMapping[str, str] = json.loads(content)
except Exception as e:
logger.error('Got exception executing POST {}: {}'.format(self.path, str(e)))
logger.error(
'Got exception executing POST {}: {}'.format(self.path, str(e))
)
self.sendJsonResponse(error='Invalid parameters', code=400)
return
@ -125,6 +152,7 @@ class HTTPServerHandler(http.server.BaseHTTPRequestHandler):
def log_message(self, format, *args): # pylint: disable=redefined-builtin
logger.debug(format, *args)
class HTTPServerThread(threading.Thread):
_server: typing.Optional[http.server.HTTPServer]
_service: 'CommonService'
@ -153,16 +181,21 @@ class HTTPServerThread(threading.Thread):
def run(self):
HTTPServerHandler._service = self._service # pylint: disable=protected-access
self._certFile, password = certs.saveCertificate(self._service._certificate) # pylint: disable=protected-access
self._certFile, password = certs.saveCertificate(
self._service._certificate
) # pylint: disable=protected-access
self._server = http.server.HTTPServer(('0.0.0.0', rest.LISTEN_PORT), HTTPServerHandler)
self._server = http.server.HTTPServer(
('0.0.0.0', rest.LISTEN_PORT), HTTPServerHandler
)
# self._server.socket = ssl.wrap_socket(self._server.socket, certfile=self.certFile, server_side=True)
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
# Disable TLSv1.0 and TLSv1.1, disable TLSv1.2, use only TLSv1.3
context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_2
context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
context.set_ciphers('ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-CCM:DHE-RSA-AES256-SHA256')
# If a configures ciphers are provided, use them, otherwise use the default ones
context.set_ciphers(self._service._certificate.ciphers or DEFAULT_CIPHERS)
context.load_cert_chain(certfile=self._certFile, password=password)
self._server.socket = context.wrap_socket(self._server.socket, server_side=True)

View File

@ -284,6 +284,7 @@ class UDSServerApi(UDSApi):
private_key=result['private_key'],
server_certificate=result['server_certificate'],
password=result['password'],
ciphers=result.get('ciphers', ''),
)
def notifyIpChange(
@ -296,6 +297,7 @@ class UDSServerApi(UDSApi):
private_key=result['private_key'],
server_certificate=result['server_certificate'],
password=result['password'],
ciphers=result.get('ciphers', ''),
)
def notifyUnmanagedCallback(
@ -317,6 +319,7 @@ class UDSServerApi(UDSApi):
private_key=result['private_key'],
server_certificate=result['server_certificate'],
password=result['password'],
ciphers=result.get('ciphers', ''),
)
def login(

View File

@ -72,3 +72,4 @@ class CertificateInfoType(typing.NamedTuple):
private_key: str
server_certificate: str
password: str
ciphers: str

View File

@ -253,7 +253,7 @@ class Authenticators(ModelHandler):
# And ensure small_name chars are valid [a-zA-Z0-9:-]+
if fields['small_name'] and not re.match(r'^[a-zA-Z0-9:-]+$', fields['small_name']):
raise self.invalidRequestException(
_('Label must contain only letters, numbers, ":" and "-"')
_('Label must contain only letters, numbers, or symbols: - : .')
)
def deleteItem(self, item: Authenticator):