Mask the token used to allow access to consoles

Hide the novncproxy token from the logs.

Conflicts:
    nova/tests/unit/consoleauth/test_consoleauth.py
NOTE: conflict is due to Iffdd4e251bfa2bac1bfd49498e32b738843709de is 
only backported till Queens.

Co-Authored-By:paul-carlton2 <paul.carlton2@hp.com>
Co-Authored-By:Tristan Cacqueray <tdecacqu@redhat.com>

Change-Id: I5b8fa4233d297722c3af08176901d12887bae3de
Closes-Bug: #1492140
(cherry picked from commit 26d4047e17)
(cherry picked from commit d7826bcd76)
(cherry picked from commit d8fbf04f32)
(cherry picked from commit 08f1f914cc)
(cherry picked from commit 366515dcd1)
This commit is contained in:
Balazs Gibizer 2019-08-23 15:51:34 +02:00 committed by Elod Illes
parent abd7eac4e4
commit 2927519cf0
4 changed files with 32 additions and 7 deletions

View File

@ -18,6 +18,7 @@ Websocket proxy that is compatible with OpenStack Nova.
Leverages websockify.py by Joel Martin
'''
import copy
import socket
import sys
@ -133,7 +134,10 @@ class NovaProxyRequestHandlerBase(object):
detail = _("Origin header protocol does not match this host.")
raise exception.ValidationError(detail=detail)
self.msg(_('connect info: %s'), str(connect_info))
sanitized_info = copy.copy(connect_info)
sanitized_info['token'] = '***'
self.msg(_('connect info: %s'), sanitized_info)
host = connect_info['host']
port = int(connect_info['port'])

View File

@ -100,9 +100,8 @@ class ConsoleAuthManager(manager.Manager):
self.mc_instance.set(instance_uuid.encode('UTF-8'),
jsonutils.dumps(tokens))
LOG.info("Received Token: %(token)s, %(token_dict)s",
{'token': token, 'token_dict': token_dict})
token_dict['token'] = '***'
LOG.info("Received Token: %(token_dict)s", {'token_dict': token_dict})
def _validate_token(self, context, token):
instance_uuid = token['instance_uuid']
@ -130,8 +129,8 @@ class ConsoleAuthManager(manager.Manager):
def check_token(self, context, token):
token_str = self.mc.get(token.encode('UTF-8'))
token_valid = (token_str is not None)
LOG.info("Checking Token: %(token)s, %(token_valid)s",
{'token': token, 'token_valid': token_valid})
LOG.info("Checking that token is known: %(token_valid)s",
{'token_valid': token_valid})
if token_valid:
token = jsonutils.loads(token_str)
if self._validate_token(context, token):

View File

@ -108,6 +108,9 @@ class NovaProxyRequestHandlerBaseTestCase(test.NoDBTestCase):
check_token.assert_called_with(mock.ANY, token="123-456-789")
self.wh.socket.assert_called_with('node1', 10000, connect=True)
self.wh.do_proxy.assert_called_with('<socket>')
# ensure that token is masked when logged
connection_info = self.wh.msg.mock_calls[0][1][1]
self.assertEqual('***', connection_info['token'])
@mock.patch('nova.consoleauth.rpcapi.ConsoleAuthAPI.check_token')
def test_new_websocket_client_ipv6_url(self, check_token):

View File

@ -87,6 +87,17 @@ class ConsoleauthTestCase(test.NoDBTestCase):
self.stub_out(self.rpcapi + 'validate_console_port',
fake_validate_console_port)
@mock.patch('nova.consoleauth.manager.LOG.info')
def test_authorize_does_not_log_token_secrete(self, mock_info):
self.manager_api.authorize_console(
self.context, 'secret', 'novnc', '127.0.0.1', '8080', 'host',
self.instance_uuid)
mock_info.assert_called_once_with(
'Received Token: %(token_dict)s', test.MatchType(dict))
self.assertEqual(
'***', mock_info.mock_calls[0][1][1]['token_dict']['token'])
@mock.patch('nova.objects.instance.Instance.get_by_uuid')
def test_multiple_tokens_for_instance(self, mock_get):
mock_get.return_value = None
@ -121,8 +132,9 @@ class ConsoleauthTestCase(test.NoDBTestCase):
self.assertIsNone(
self.manager_api.check_token(self.context, token))
@mock.patch('nova.consoleauth.manager.LOG.info')
@mock.patch('nova.objects.instance.Instance.get_by_uuid')
def test_wrong_token_has_port(self, mock_get):
def test_wrong_token_has_port(self, mock_get, mock_log):
mock_get.return_value = None
token = u'mytok'
@ -133,6 +145,13 @@ class ConsoleauthTestCase(test.NoDBTestCase):
'127.0.0.1', '8080', 'host',
instance_uuid=self.instance_uuid)
self.assertIsNone(self.manager_api.check_token(self.context, token))
mock_log.assert_has_calls([
mock.call(
'Received Token: %(token_dict)s', mock.ANY),
mock.call(
'Checking that token is known: %(token_valid)s',
{'token_valid': True}),
])
def test_delete_expired_tokens(self):
self.useFixture(test.TimeOverride())