Fix Brocade FC SAN lookup MITM vulnerability

Modify the Brocade FC SAN lookup service implementation to use the
same SSH key config properties used elsewhere rather than relying on
arguments which are non-standard and never passed by the base lookup
service.

Change-Id: I0cb5141368bc9a62a4e0374026d66fc2725cfe24
Closes-Bug: 1391311
(cherry picked from commit ab4f572126)
This commit is contained in:
Matthew Edmonds 2014-11-11 16:03:23 -05:00
parent 67c5a66cfc
commit 628196e46e
2 changed files with 20 additions and 17 deletions

View File

@ -42,6 +42,8 @@ _device_map_to_verify = {
'initiator_port_wwn_list': ['10008c7cff523b01'], 'initiator_port_wwn_list': ['10008c7cff523b01'],
'target_port_wwn_list': ['20240002ac000a50']}} 'target_port_wwn_list': ['20240002ac000a50']}}
CONF = cfg.CONF
class TestBrcdFCSanLookupService(brcd_lookup.BrcdFCSanLookupService, class TestBrcdFCSanLookupService(brcd_lookup.BrcdFCSanLookupService,
test.TestCase): test.TestCase):
@ -77,16 +79,14 @@ class TestBrcdFCSanLookupService(brcd_lookup.BrcdFCSanLookupService,
@mock.patch.object(paramiko.hostkeys.HostKeys, 'load') @mock.patch.object(paramiko.hostkeys.HostKeys, 'load')
def test_create_ssh_client(self, load_mock): def test_create_ssh_client(self, load_mock):
mock_args = {} CONF.ssh_hosts_key_file = 'dummy_host_key_file'
mock_args['known_hosts_file'] = 'dummy_host_key_file' CONF.strict_ssh_host_key_policy = True
mock_args['missing_key_policy'] = paramiko.RejectPolicy() ssh_client = self.create_ssh_client()
ssh_client = self.create_ssh_client(**mock_args)
self.assertEqual(ssh_client._host_keys_filename, 'dummy_host_key_file') self.assertEqual(ssh_client._host_keys_filename, 'dummy_host_key_file')
self.assertTrue(isinstance(ssh_client._policy, paramiko.RejectPolicy)) self.assertTrue(isinstance(ssh_client._policy, paramiko.RejectPolicy))
mock_args = {} CONF.strict_ssh_host_key_policy = False
ssh_client = self.create_ssh_client(**mock_args) ssh_client = self.create_ssh_client()
self.assertIsNone(ssh_client._host_keys_filename) self.assertTrue(isinstance(ssh_client._policy, paramiko.AutoAddPolicy))
self.assertTrue(isinstance(ssh_client._policy, paramiko.WarningPolicy))
@mock.patch.object(brcd_lookup.BrcdFCSanLookupService, @mock.patch.object(brcd_lookup.BrcdFCSanLookupService,
'get_nameserver_info') 'get_nameserver_info')

View File

@ -17,6 +17,7 @@
# #
from oslo.config import cfg
import paramiko import paramiko
from cinder import exception from cinder import exception
@ -30,6 +31,8 @@ from cinder.zonemanager.fc_san_lookup_service import FCSanLookupService
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
CONF = cfg.CONF
class BrcdFCSanLookupService(FCSanLookupService): class BrcdFCSanLookupService(FCSanLookupService):
"""The SAN lookup service that talks to Brocade switches. """The SAN lookup service that talks to Brocade switches.
@ -46,7 +49,7 @@ class BrcdFCSanLookupService(FCSanLookupService):
super(BrcdFCSanLookupService, self).__init__(**kwargs) super(BrcdFCSanLookupService, self).__init__(**kwargs)
self.configuration = kwargs.get('configuration', None) self.configuration = kwargs.get('configuration', None)
self.create_configuration() self.create_configuration()
self.client = self.create_ssh_client(**kwargs) self.client = self.create_ssh_client()
def create_configuration(self): def create_configuration(self):
"""Configuration specific to SAN context values.""" """Configuration specific to SAN context values."""
@ -61,16 +64,16 @@ class BrcdFCSanLookupService(FCSanLookupService):
self.fabric_configs = fabric_opts.load_fabric_configurations( self.fabric_configs = fabric_opts.load_fabric_configurations(
fabric_names) fabric_names)
def create_ssh_client(self, **kwargs): def create_ssh_client(self):
ssh_client = paramiko.SSHClient() ssh_client = paramiko.SSHClient()
known_hosts_file = kwargs.get('known_hosts_file', None) known_hosts_file = CONF.ssh_hosts_key_file
if known_hosts_file is None: if not known_hosts_file:
ssh_client.load_system_host_keys() raise exception.ParameterNotFound(param='ssh_hosts_key_file')
ssh_client.load_host_keys(known_hosts_file)
if CONF.strict_ssh_host_key_policy:
missing_key_policy = paramiko.RejectPolicy()
else: else:
ssh_client.load_host_keys(known_hosts_file) missing_key_policy = paramiko.AutoAddPolicy()
missing_key_policy = kwargs.get('missing_key_policy', None)
if missing_key_policy is None:
missing_key_policy = paramiko.WarningPolicy()
ssh_client.set_missing_host_key_policy(missing_key_policy) ssh_client.set_missing_host_key_policy(missing_key_policy)
return ssh_client return ssh_client