Exemple #1
0
def validate_engine_id(engine_id):
    # Validate engine_id, check octet string can be formed from it
    try:
        OctetString.fromHexString(engine_id)
    except ValueError:
        msg = "engine_id should be a set of octets in " \
              "hexadecimal format."
        raise exception.InvalidInput(msg)
Exemple #2
0
    def validate_connectivity(ctxt, alert_source):
        # Fill optional parameters with default values if not set in input
        if not alert_source.get('port'):
            alert_source['port'] = constants.DEFAULT_SNMP_CONNECT_PORT

        if not alert_source.get('context_name'):
            alert_source['context_name'] = None

        if not alert_source.get('retry_num'):
            alert_source['retry_num'] = constants.DEFAULT_SNMP_RETRY_NUM

        if not alert_source.get('expiration'):
            alert_source['expiration'] = constants.DEFAULT_SNMP_EXPIRATION_TIME

        if CONF.snmp_validation_enabled is False:
            return alert_source

        storage_id = alert_source.get('storage_id')
        access_info = db.access_info_get(ctxt, storage_id)
        access_info = dict(access_info)
        if access_info.get('model') not in constants.SNMP_SUPPORTED_MODELS:
            return alert_source

        cmd_gen = cmdgen.CommandGenerator()

        version = alert_source.get('version')

        # Connect to alert source through snmp get to check the configuration
        try:
            target = cmdgen.UdpTransportTarget(
                (alert_source['host'], alert_source['port']),
                timeout=alert_source['expiration'],
                retries=alert_source['retry_num'])
            target.setLocalAddress((CONF.my_ip, 0))
            if version.lower() == 'snmpv3':
                # Register engine observer to get engineId,
                # Code reference from: http://snmplabs.com/pysnmp/
                observer_context = {}
                cmd_gen.snmpEngine.observer.registerObserver(
                    lambda e, p, v, c: c.update(securityEngineId=v[
                        'securityEngineId']),
                    'rfc3412.prepareDataElements:internal',
                    cbCtx=observer_context)
                auth_key = None
                if alert_source['auth_key']:
                    auth_key = encodeutils.to_utf8(
                        cryptor.decode(alert_source['auth_key']))
                privacy_key = None
                if alert_source['privacy_key']:
                    privacy_key = encodeutils.to_utf8(
                        cryptor.decode(alert_source['privacy_key']))
                auth_protocol = None
                privacy_protocol = None
                if alert_source['auth_protocol']:
                    auth_protocol = constants.AUTH_PROTOCOL_MAP.get(
                        alert_source['auth_protocol'].lower())
                if alert_source['privacy_protocol']:
                    privacy_protocol = constants.PRIVACY_PROTOCOL_MAP.get(
                        alert_source['privacy_protocol'].lower())

                engine_id = alert_source.get('engine_id')
                if engine_id:
                    engine_id = OctetString.fromHexString(engine_id)
                error_indication, __, __, __ = cmd_gen.getCmd(
                    cmdgen.UsmUserData(alert_source['username'],
                                       authKey=auth_key,
                                       privKey=privacy_key,
                                       authProtocol=auth_protocol,
                                       privProtocol=privacy_protocol,
                                       securityEngineId=engine_id),
                    target,
                    constants.SNMP_QUERY_OID,
                )

                if 'securityEngineId' in observer_context:
                    engine_id = observer_context.get('securityEngineId')
                    alert_source['engine_id'] = binascii.hexlify(
                        engine_id.asOctets()).decode()
            else:
                community_string = encodeutils.to_utf8(
                    cryptor.decode(alert_source['community_string']))
                error_indication, __, __, __ = cmd_gen.getCmd(
                    cmdgen.CommunityData(
                        community_string,
                        contextName=alert_source['context_name']),
                    target,
                    constants.SNMP_QUERY_OID,
                )

            cmd_gen.snmpEngine.transportDispatcher.closeDispatcher()

            if not error_indication:
                return alert_source

            # Prepare exception with error_indication
            msg = six.text_type(error_indication)
        except Exception as e:
            msg = six.text_type(e)

        # Since validation occur error, raise exception
        LOG.error("Configuration validation failed with alert source for "
                  "reason: %s." % msg)
        raise exception.SNMPConnectionFailed(msg)
    def _input_check(self, alert_source):
        version = alert_source.get('version')

        if version.lower() == 'snmpv3':
            user_name = alert_source.get('username')
            security_level = alert_source.get('security_level')
            engine_id = alert_source.get('engine_id')

            # Validate engine_id, check octet string can be formed from it
            if engine_id:
                try:
                    OctetString.fromHexString(engine_id)
                except (TypeError, ValueError):
                    msg = "engine_id should be a set of octets in " \
                          "hexadecimal format."
                    raise exception.InvalidInput(msg)

            if not user_name or not security_level:
                msg = "If snmp version is SNMPv3, then username, " \
                      "security_level are required."
                raise exception.InvalidInput(msg)

            if security_level == constants.SecurityLevel.AUTHNOPRIV\
                    or security_level == constants.SecurityLevel.AUTHPRIV:
                auth_protocol = alert_source.get('auth_protocol')
                auth_key = alert_source.get('auth_key')
                if not auth_protocol or not auth_key:
                    msg = "If snmp version is SNMPv3 and security_level is " \
                          "authPriv or authNoPriv, auth_protocol and " \
                          "auth_key are required."
                    raise exception.InvalidInput(msg)
                alert_source['auth_key'] = cryptor.encode(
                    alert_source['auth_key'])

                if security_level == constants.SecurityLevel.AUTHPRIV:
                    privacy_protocol = alert_source.get('privacy_protocol')
                    privacy_key = alert_source.get('privacy_key')
                    if not privacy_protocol or not privacy_key:
                        msg = "If snmp version is SNMPv3 and security_level" \
                              " is authPriv, privacy_protocol and " \
                              "privacy_key are  required."
                        raise exception.InvalidInput(msg)
                    alert_source['privacy_key'] = cryptor.encode(
                        alert_source['privacy_key'])
                else:
                    alert_source['privacy_key'] = None
                    alert_source['privacy_protocol'] = None
            else:
                alert_source['auth_key'] = None
                alert_source['auth_protocol'] = None
                alert_source['privacy_key'] = None
                alert_source['privacy_protocol'] = None

            # Clear keys for other versions.
            alert_source['community_string'] = None
        else:
            community_string = alert_source.get('community_string')
            if not community_string:
                msg = "If snmp version is SNMPv1 or SNMPv2c, " \
                      "community_string is required."
                raise exception.InvalidInput(msg)
            alert_source['community_string'] = cryptor.encode(
                alert_source['community_string'])

            # Clear keys for SNMPv3
            for k in SNMPv3_keys:
                alert_source[k] = None

        return alert_source