Ejemplo n.º 1
0
    def __init__(self, parent, client_iqn, client_settings):
        UINode.__init__(self, client_iqn, parent)
        self.client_iqn = client_iqn
        self.parent.client_map[client_iqn] = self
        self.group_name = ''

        self.ip_address = ''
        self.alias = ''

        for k, v in client_settings.items():
            self.__setattr__(k, v)

        # decode the chap password if necessary
        if 'username' in self.auth and 'password' in self.auth:
            self.chap = CHAP(self.auth['username'], self.auth['password'],
                             self.auth['password_encryption_enabled'])
            self.auth['username'] = self.chap.user
            self.auth['password'] = self.chap.password
        else:
            self.auth['username'] = ''
            self.auth['password'] = ''

        # decode the chap_mutual password if necessary
        if 'mutual_username' in self.auth and 'mutual_password' in self.auth:
            self.chap_mutual = CHAP(
                self.auth['mutual_username'], self.auth['mutual_password'],
                self.auth['mutual_password_encryption_enabled'])
            self.auth['mutual_username'] = self.chap_mutual.user
            self.auth['mutual_password'] = self.chap_mutual.password
        else:
            self.auth['mutual_username'] = ''
            self.auth['mutual_password'] = ''

        self.refresh_luns()
Ejemplo n.º 2
0
    def test_chap_upgrade(self):
        private_key = rsa.generate_private_key(public_exponent=65537,
                                               key_size=2048,
                                               backend=default_backend())
        priv_pem = private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption())
        priv_key_file = tempfile.mkstemp()
        with open(priv_key_file[1], "wb") as kf:
            kf.write(priv_pem)

        pub_pem = private_key.public_key().public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo)
        pub_key_file = tempfile.mkstemp()
        with open(pub_key_file[1], "wb") as kf:
            kf.write(pub_pem)

        settings.config.priv_key = priv_key_file[1]
        settings.config.pub_key = pub_key_file[1]
        settings.config.ceph_config_dir = ""

        key = private_key.public_key()
        encrypted_pw = b64encode(
            key.encrypt(
                "passwordverylonglong".encode('utf-8'),
                padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()),
                             algorithm=hashes.SHA1(),
                             label=None))).decode('utf-8')

        chap2 = CHAP("username/{}".format(encrypted_pw))
        self.assertEqual(chap2._get_chap_str(),
                         "username/passwordverylonglong")
Ejemplo n.º 3
0
    def test_chap_encryption(self):
        private_key = rsa.generate_private_key(public_exponent=65537,
                                               key_size=2048,
                                               backend=default_backend())
        priv_pem = private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption())
        priv_key_file = tempfile.mkstemp()
        with open(priv_key_file[1], "wb") as kf:
            kf.write(priv_pem)

        pub_pem = private_key.public_key().public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo)
        pub_key_file = tempfile.mkstemp()
        with open(pub_key_file[1], "wb") as kf:
            kf.write(pub_pem)

        settings.config.priv_key = priv_key_file[1]
        settings.config.pub_key = pub_key_file[1]
        settings.config.ceph_config_dir = ""

        chap = CHAP("username", "passwordverylonglong", False)

        encrypted_password = chap.encrypted_password(True)
        chap2 = CHAP(chap.user, encrypted_password, True)
        self.assertEqual(chap2.user, "username")
        self.assertEqual(chap2.password, "passwordverylonglong")
        self.assertEqual(chap2.password_str, encrypted_password)
        self.assertNotEqual(encrypted_password, "passwordverylonglong")
Ejemplo n.º 4
0
    def __init__(self, parent, client_iqn, client_settings):
        UINode.__init__(self, client_iqn, parent)
        self.client_iqn = client_iqn
        self.parent.client_map[client_iqn] = self
        self.group_name = ''

        self.ip_address = ''
        self.alias = ''

        for k, v in client_settings.items():
            self.__setattr__(k, v)

        # decode the chap password if necessary
        if 'chap' in self.auth:
            self.chap = CHAP(self.auth['chap'])

            if self.chap.chap_str != '':
                self.auth['chap'] = self.chap.chap_str
            else:
                self.auth['chap'] = "None"
        else:
            self.auth['chap'] = "None"

        # decode the chap_mutual password if necessary
        if 'chap_mutual' in self.auth:
            self.chap_mutual = CHAP(self.auth['chap_mutual'])

            if self.chap_mutual.chap_str != '':
                self.auth['chap_mutual'] = self.chap_mutual.chap_str
            else:
                self.auth['chap_mutual'] = "None"
        else:
            self.auth['chap_mutual'] = "None"

        self.refresh_luns()
Ejemplo n.º 5
0
    def create_tpg(self, ip):

        try:
            gateway_name = self._get_gateway_name(ip)
            tpg = self.get_tpg_by_gateway_name(gateway_name)
            if not tpg:
                tpg = TPG(self.target)

            # Use initiator name based ACL by default.
            tpg.set_attribute('authentication', '0')

            self.logger.debug("(Gateway.create_tpg) Added tpg for portal "
                              "ip {}".format(ip))
            if ip in self.active_portal_ips:
                target_config = self.config.config['targets'][self.iqn]
                auth_config = target_config['auth']
                config_chap = CHAP(auth_config['username'],
                                   auth_config['password'],
                                   auth_config['password_encryption_enabled'])
                if config_chap.error:
                    self.error = True
                    self.error_msg = config_chap.error_msg
                    return
                config_chap_mutual = CHAP(auth_config['mutual_username'],
                                          auth_config['mutual_password'],
                                          auth_config['mutual_password_encryption_enabled'])
                if config_chap_mutual.error:
                    self.error = True
                    self.error_msg = config_chap_mutual.error_msg
                    return
                self.update_auth(tpg, config_chap.user, config_chap.password,
                                 config_chap_mutual.user, config_chap_mutual.password)
                if self.enable_portal:
                    NetworkPortal(tpg, normalize_ip_literal(ip))
                tpg.enable = True
                self.logger.debug("(Gateway.create_tpg) Added tpg for "
                                  "portal ip {} is enabled".format(ip))
            else:
                NetworkPortal(tpg, normalize_ip_literal(ip))
                # disable the tpg on this host
                tpg.enable = False
                # by disabling tpg_enabled_sendtargets, discovery to just one
                # node will return all portals (default is 1)
                tpg.set_attribute('tpg_enabled_sendtargets', '0')
                self.logger.debug("(Gateway.create_tpg) Added tpg for "
                                  "portal ip {} as disabled".format(ip))

            self.tpg_list.append(tpg)
            self.tpg_tag_by_gateway_name[gateway_name] = tpg.tag

        except RTSLibError as err:
            self.error_msg = err
            self.error = True

        else:

            self.changes_made = True
            self.logger.info("(Gateway.create_tpg) created TPG '{}' "
                             "for target iqn '{}'".format(tpg.tag,
                                                          self.iqn))
Ejemplo n.º 6
0
 def set_discovery_auth_lio(chap_str, chap_mutual_str):
     iscsi_fabric = ISCSIFabricModule()
     if chap_str == '':
         iscsi_fabric.clear_discovery_auth_settings()
     else:
         chap = CHAP(chap_str)
         chap_mutual = CHAP(chap_mutual_str)
         iscsi_fabric.discovery_userid = chap.user
         iscsi_fabric.discovery_password = chap.password
         iscsi_fabric.discovery_mutual_userid = chap_mutual.user
         iscsi_fabric.discovery_mutual_password = chap_mutual.password
         iscsi_fabric.discovery_enable_auth = True
Ejemplo n.º 7
0
 def set_discovery_auth_lio(username, password, password_encryption_enabled,
                            mutual_username, mutual_password,
                            mutual_password_encryption_enabled):
     iscsi_fabric = ISCSIFabricModule()
     if username == '':
         iscsi_fabric.clear_discovery_auth_settings()
     else:
         chap = CHAP(username, password, password_encryption_enabled)
         chap_mutual = CHAP(mutual_username, mutual_password,
                            mutual_password_encryption_enabled)
         iscsi_fabric.discovery_userid = chap.user
         iscsi_fabric.discovery_password = chap.password
         iscsi_fabric.discovery_mutual_userid = chap_mutual.user
         iscsi_fabric.discovery_mutual_password = chap_mutual.password
         iscsi_fabric.discovery_enable_auth = True
Ejemplo n.º 8
0
def define_clients():
    """
    define the clients (nodeACLs) to the gateway definition
    """

    # Client configurations (NodeACL's)
    for client_iqn in config.config['clients']:
        client_metadata = config.config['clients'][client_iqn]
        client_chap = CHAP(client_metadata['auth']['chap'])

        image_list = client_metadata['luns'].keys()

        chap_str = client_chap.chap_str
        if client_chap.error:
            logger.debug("Password decode issue : "
                         "{}".format(client_chap.error_msg))
            halt("Unable to decode password for "
                 "{}".format(client_iqn))

        client = GWClient(logger,
                          client_iqn,
                          image_list,
                          chap_str)

        client.manage('present')  # ensure the client exists
Ejemplo n.º 9
0
    def __init__(self, target_iqn, parent):
        UIGroup.__init__(self, target_iqn, parent)
        self.target_iqn = target_iqn

        self.control_values = []
        self.controls = {}

        self.gateway_group = GatewayGroup(self)
        self.client_group = Clients(self)
        self.host_groups = HostGroups(self)
        self.target_disks = TargetDisks(self)

        config = self.parent.parent._get_config()
        if not config:
            self.logger.error("Unable to refresh local config")
            raise GatewayError

        self.auth = config['targets'][target_iqn]['auth']
        # decode the chap password if necessary
        if 'username' in self.auth and 'password' in self.auth:
            self.chap = CHAP(self.auth['username'], self.auth['password'],
                             self.auth['password_encryption_enabled'])
            self.auth['username'] = self.chap.user
            self.auth['password'] = self.chap.password
        else:
            self.auth['username'] = ''
            self.auth['password'] = ''

        # decode the chap_mutual password if necessary
        if 'mutual_username' in self.auth and 'mutual_password' in self.auth:
            self.chap_mutual = CHAP(
                self.auth['mutual_username'], self.auth['mutual_password'],
                self.auth['mutual_password_encryption_enabled'])
            self.auth['mutual_username'] = self.chap_mutual.user
            self.auth['mutual_password'] = self.chap_mutual.password
        else:
            self.auth['mutual_username'] = ''
            self.auth['mutual_password'] = ''
Ejemplo n.º 10
0
    def __init__(self, parent, client_iqn, client_settings):
        UINode.__init__(self, client_iqn, parent)
        self.client_iqn = client_iqn
        self.parent.client_map[client_iqn] = self
        self.group_name = ''

        for k, v in client_settings.iteritems():
            self.__setattr__(k, v)

        # decode the password if necessary
        if 'chap' in self.auth:
            self.chap = CHAP(self.auth['chap'])
            self.auth['chap'] = self.chap.chap_str

        self.refresh_luns()
Ejemplo n.º 11
0
    def __init__(self, parent, client_iqn, client_settings):
        UINode.__init__(self, client_iqn, parent)
        self.client_iqn = client_iqn
        self.logger = self.parent.logger

        for k, v in client_settings.iteritems():
            self.__setattr__(k, v)

        # decode the password if necessary
        if 'chap' in self.auth:
            self.chap = CHAP(self.auth['chap'])
            self.auth['chap'] = self.chap.chap_str

        for rbd_path in self.luns.keys():
            lun_id = self.luns[rbd_path]['lun_id']
            self.parent.update_lun_map('add', rbd_path, self.client_iqn)
            MappedLun(self, rbd_path, lun_id)
Ejemplo n.º 12
0
 def set_discovery_auth_config(username, password, mutual_username,
                               mutual_password, config):
     encryption_enabled = encryption_available()
     discovery_auth_config = {
         'username': '',
         'password': '',
         'password_encryption_enabled': encryption_enabled,
         'mutual_username': '',
         'mutual_password': '',
         'mutual_password_encryption_enabled': encryption_enabled
     }
     if username != '':
         chap = CHAP(username, password, encryption_enabled)
         chap_mutual = CHAP(mutual_username, mutual_password,
                            encryption_enabled)
         discovery_auth_config['username'] = chap.user
         discovery_auth_config['password'] = chap.encrypted_password(
             encryption_enabled)
         discovery_auth_config['mutual_username'] = chap_mutual.user
         discovery_auth_config['mutual_password'] = \
             chap_mutual.encrypted_password(encryption_enabled)
     config.update_item('discovery_auth', '', discovery_auth_config)
Ejemplo n.º 13
0
    def activate(self):
        disk = self.config.config['disks'].get(self.config_key, None)
        if not disk:
            raise CephiSCSIError("Image {} not found.".format(self.image))

        wwn = disk.get('wwn', None)
        if not wwn:
            raise CephiSCSIError("LUN {} missing wwn".format(self.image))

        # re-add backend storage object
        so = self.lio_stg_object()
        if not so:
            self.add_dev_to_lio(wwn)
            if self.error:
                raise CephiSCSIError("LUN activate failure - {}".format(
                    self.error_msg))

        # re-add LUN to target
        local_gw = this_host()
        targets_items = [
            item for item in self.config.config['targets'].items()
            if self.config_key in item[1]['disks']
            and local_gw in item[1]['portals']
        ]
        for target_iqn, target in targets_items:
            ip_list = target['ip_list']

            # Add the mapping for the lun to ensure the block device is
            # present on all TPG's
            gateway = GWTarget(self.logger, target_iqn, ip_list)

            gateway.manage('map')
            if gateway.error:
                raise CephiSCSIError("LUN mapping failed - {}".format(
                    gateway.error_msg))

            # re-map LUN to hosts
            client_err = ''
            for client_iqn in target['clients']:
                client_metadata = target['clients'][client_iqn]
                if client_metadata.get('group_name', ''):
                    continue

                image_list = list(client_metadata['luns'].keys())
                if self.config_key not in image_list:
                    continue

                client_chap = CHAP(client_metadata['auth']['chap'])
                chap_str = client_chap.chap_str
                if client_chap.error:
                    raise CephiSCSIError("Password decode issue : "
                                         "{}".format(client_chap.error_msg))

                client_chap_mutual = CHAP(
                    client_metadata['auth']['chap_mutual'])
                chap_mutual_str = client_chap_mutual.chap_str
                if client_chap_mutual.error:
                    raise CephiSCSIError("Password decode issue : "
                                         "{}".format(
                                             client_chap_mutual.error_msg))

                client = GWClient(self.logger, client_iqn, image_list,
                                  chap_str, chap_mutual_str, target_iqn)
                client.manage('present')
                if client.error:
                    client_err = "LUN mapping failed {} - {}".format(
                        client_iqn, client.error_msg)

            # re-map LUN to host groups
            for group_name in target['groups']:
                host_group = target['groups'][group_name]
                members = host_group.get('members')
                disks = host_group.get('disks').keys()
                if self.config_key not in disks:
                    continue

                group = Group(self.logger, target_iqn, group_name, members,
                              disks)
                group.apply()
                if group.error:
                    client_err = "LUN mapping failed {} - {}".format(
                        group_name, group.error_msg)

            if client_err:
                raise CephiSCSIError(client_err)
Ejemplo n.º 14
0
 def test_chap_no_encryption(self):
     chap = CHAP("")
     chap._set_chap_str("username/password")
     self.assertEqual(chap._get_chap_str(), "username/password")
Ejemplo n.º 15
0
 def test_chap_no_encryption(self):
     chap = CHAP("username", "password", False)
     self.assertEqual(chap.user, "username")
     self.assertEqual(chap.password, "password")
     self.assertEqual(chap.password_str, "password")
Ejemplo n.º 16
0
def all_client_luns(client_iqn):
    """
    Coordinate the addition(PUT) and removal(DELETE) of a disk from a client
    :param client_iqn: (str) IQN of the client
    :param disk: (str) rbd image name of the format pool.image
    **RESTRICTED**
    """

    http_mode = 'https' if settings.config.api_secure else 'http'

    local_gw = this_host()
    logger.debug("this host is {}".format(local_gw))
    gateways = [
        key for key in config.config['gateways']
        if isinstance(config.config['gateways'][key], dict)
    ]
    logger.debug("other gateways - {}".format(gateways))
    gateways.remove(local_gw)

    disk = request.form.get('disk')

    lun_list = config.config['clients'][client_iqn]['luns'].keys()

    if request.method == 'PUT':
        lun_list.append(disk)
    else:
        # this is a delete request
        if disk in lun_list:
            lun_list.remove(disk)
        else:
            return jsonify(message="disk not mapped to client"), 400

    chap_obj = CHAP(config.config['clients'][client_iqn]['auth']['chap'])
    chap = "{}/{}".format(chap_obj.user, chap_obj.password)
    image_list = ','.join(lun_list)

    client_usable = valid_client(mode='disk',
                                 client_iqn=client_iqn,
                                 image_list=image_list)
    if client_usable != 'ok':
        logger.error("Bad disk request for client {} : "
                     "{}".format(client_iqn, client_usable))
        return jsonify(message=client_usable), 400

    # committing host is the local LIO node
    api_vars = {
        "committing_host": local_gw,
        "image_list": image_list,
        "chap": chap
    }

    clientlun_api = '{}://127.0.0.1:{}/api/clientlun/{}'.format(
        http_mode, settings.config.api_port, client_iqn)

    api = APIRequest(clientlun_api, data=api_vars)
    api.put()

    if api.response.status_code == 200:

        logger.info("disk mapping update for {} successful".format(client_iqn))

        for gw in gateways:
            clientlun_api = '{}://{}:{}/api/clientlun/{}'.format(
                http_mode, gw, settings.config.api_port, client_iqn)

            logger.debug("Updating disk map for {} on GW {}".format(
                client_iqn, gw))
            api = APIRequest(clientlun_api, data=api_vars)
            api.put()

            if api.response.status_code == 200:
                logger.debug("gateway '{}' updated".format(gw))
                continue
            else:
                logger.error("disk mapping update on {} failed".format(gw))
                return jsonify(message="disk map updated failed on "
                                       "{}".format(gw)), \
                       api.response.status_code

        return jsonify(message="ok"), 200

    else:
        # disk map update failed at the first hurdle!
        logger.error("disk map update failed on the local LIO instance")
        return jsonify(message="failed to update local LIO instance"), \
               api.response.status_code