commit 3d74690209a014b552ceea1691768ac7c715574c Author: Florian Best Date: Wed Oct 28 12:49:42 2020 +0100 Bug #52273: run UMC-Server with addditional UNIX socket To prevent the long runnning TLS handshake. diff --git management/univention-management-console/scripts/univention-management-console-server management/univention-management-console/scripts/univention-management-console-server index ead7972f52..fa1be9483e 100755 --- management/univention-management-console/scripts/univention-management-console-server +++ management/univention-management-console/scripts/univention-management-console-server @@ -67,6 +67,10 @@ class UMC_Daemon(DaemonRunner): '-p', '--port', action='store', type=int, dest='port', default=6670, help='defines an alternative port number [default %(default)s]') + self.parser.add_argument( + '-u', '--unix-socket', action='store', + default='/var/run/univention-management-console/server.socket', + help='defines an alternative UNIX socket [default %(default)s]') self.parser.add_argument( '-l', '--language', action='store', dest='language', default=default_locale, @@ -211,7 +215,7 @@ class UMC_Daemon(DaemonRunner): notifier.init(notifier.GENERIC) notifier.dispatch.MIN_TIMER = get_int('umc/server/dispatch-interval', notifier.dispatch.MIN_TIMER) - with Server(port=self.options.port) as self.server: + with Server(port=self.options.port, unix=self.options.unix_socket) as self.server: CORE.process('Server started') notifier.loop() diff --git management/univention-management-console/src/univention/management/console/protocol/modserver.py management/univention-management-console/src/univention/management/console/protocol/modserver.py index 4b7f984d70..ec2e9dd74f 100644 --- management/univention-management-console/src/univention/management/console/protocol/modserver.py +++ management/univention-management-console/src/univention/management/console/protocol/modserver.py @@ -95,7 +95,7 @@ class ModuleServer(Server): self.__init_etraceback = None self.__handler = None self._load_module() - Server.__init__(self, ssl=False, unix=socket, magic=False, load_ressources=False) + Server.__init__(self, port=None, ssl=False, unix=socket, magic=False, load_ressources=False) MODULE.process('Module socket initialized.') self.signal_connect('session_new', self._client) diff --git management/univention-management-console/src/univention/management/console/protocol/server.py management/univention-management-console/src/univention/management/console/protocol/server.py index d285698a21..3cfa6d58bc 100644 --- management/univention-management-console/src/univention/management/console/protocol/server.py +++ management/univention-management-console/src/univention/management/console/protocol/server.py @@ -266,23 +266,28 @@ class Server(signals.Provider): CORE.info('Initialising server process') self.__port = port self.__unix = unix + self.__realtcpsocket = None + self.__realunixsocket = None self.__ssl = ssl if self.__unix: CORE.info('Using a UNIX socket') - self.__realsocket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - else: + self.__realunixsocket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + if self.__port: CORE.info('Using a TCP socket') try: - self.__realsocket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) + self.__realtcpsocket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) except: CORE.warn('Cannot open socket with AF_INET6 (Python reports socket.has_ipv6 is %s), trying AF_INET' % socket.has_ipv6) - self.__realsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.__realtcpsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.__realsocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.__realsocket.setblocking(0) - fcntl.fcntl(self.__realsocket.fileno(), fcntl.F_SETFD, 1) + for sock in (self.__realtcpsocket, self.__realunixsocket): + if sock is None: + continue + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.setblocking(0) + fcntl.fcntl(sock.fileno(), fcntl.F_SETFD, 1) - if self.__ssl and not self.__unix: + if self.__ssl and self.__port: CORE.info('Setting up SSL configuration') self.crypto_context = SSL.Context(SSL.TLSv1_METHOD) self.crypto_context.set_cipher_list(ucr.get('umc/server/ssl/ciphers', 'DEFAULT')) @@ -300,32 +305,34 @@ class Server(signals.Provider): CRYPT.warn('Communication will not be encrypted!') self.__ssl = False self.crypto_context = None - self.__realsocket.bind(('', self.__port)) + self.__realtcpsocket.bind(('', self.__port)) CRYPT.info('Server listening to unencrypted connections') - self.__realsocket.listen(SERVER_MAX_CONNECTIONS) + self.__realtcpsocket.listen(SERVER_MAX_CONNECTIONS) if self.crypto_context: - self.connection = SSL.Connection(self.crypto_context, self.__realsocket) + self.connection = SSL.Connection(self.crypto_context, self.__realtcpsocket) self.connection.setblocking(0) self.connection.bind(('', self.__port)) self.connection.set_accept_state() CRYPT.info('Server listening to SSL connections') self.connection.listen(SERVER_MAX_CONNECTIONS) - else: + elif not self.__ssl and self.__port: self.crypto_context = None - if self.__unix: - try: - # ensure that the UNIX socket is only accessible by root - old_umask = os.umask(0o077) - self.__realsocket.bind(self.__unix) - # restore old umask - os.umask(old_umask) - except EnvironmentError: - os.unlink(self.__unix) - else: - self.__realsocket.bind(('', self.__port)) + self.__realtcpsocket.bind(('', self.__port)) + CRYPT.info('Server listening to connections') + self.__realtcpsocket.listen(SERVER_MAX_CONNECTIONS) + + if self.__unix: + try: + # ensure that the UNIX socket is only accessible by root + old_umask = os.umask(0o077) + self.__realunixsocket.bind(self.__unix) + # restore old umask + os.umask(old_umask) + except EnvironmentError: + os.unlink(self.__unix) CRYPT.info('Server listening to connections') - self.__realsocket.listen(SERVER_MAX_CONNECTIONS) + self.__realunixsocket.listen(SERVER_MAX_CONNECTIONS) self.__magic = magic self.__magicClass = magicClass @@ -335,10 +342,12 @@ class Server(signals.Provider): else: self.signal_new('session_new') - if self.__ssl and not self.__unix: + if self.__ssl: notifier.socket_add(self.connection, self._connection) - else: - notifier.socket_add(self.__realsocket, self._connection) + if (not self.__ssl and self.__port): + notifier.socket_add(self.__realtcpsocket, self._connection) + if self.__unix: + notifier.socket_add(self.__realunixsocket, self._connection) def __verify_cert_cb(self, conn, cert, errnum, depth, ok): CORE.info('__verify_cert_cb: Got certificate: %s' % cert.get_subject()) @@ -381,14 +390,17 @@ class Server(signals.Provider): if self.__bucket: self.__bucket.exit() - if self.__ssl and not self.__unix: + if self.__ssl and self.__port: notifier.socket_remove(self.connection) self.connection.close() - elif self.__realsocket: - notifier.socket_remove(self.__realsocket) - self.__realsocket.close() - self.__realsocket = None + elif not self.__ssl and self.__port and self.__realtcpsocket: + notifier.socket_remove(self.__realtcpsocket) + self.__realtcpsocket.close() + self.__realtcpsocket = None if self.__unix: + notifier.socket_remove(self.__realunixsocket) + self.__realunixsocket.close() + self.__realunixsocket = None os.unlink(self.__unix) self.__unix = None diff --git management/univention-management-console/univention-management-console-web-server management/univention-management-console/univention-management-console-web-server index 6142305e74..cb1adc4ebb 100755 --- management/univention-management-console/univention-management-console-web-server +++ management/univention-management-console/univention-management-console-web-server @@ -140,7 +140,7 @@ class SessionClient(object): def __init__(self, ip=None): CORE.info('SessionClient(0x%x): creating new session' % (id(self),)) self.authenticated = False - self.client = Client() + self.client = Client(servername=None, port=None, unix='/var/run/univention-management-console/server.socket', ssl=False) self.client.signal_connect('authenticated', self._authenticated) self.client.signal_connect('response', self._response) self.client.signal_connect('closed', self._closed)