Example #1
0
def add_non_finding(issue, options):
    """
    Adds a non-finding.
    """
    title = validate_report.capitalize(issue.title.strip())
    print_status('{0} - {1} - {2}'.format(issue.state, issue.labels, title),
                 options)
    non_finding_id = '{0}-{1}'.format(issue.iid, valid_filename(title))
    filename = 'non-findings/{0}.xml'.format(non_finding_id)
    non_finding = collections.OrderedDict()
    non_finding['title'] = title
    non_finding['p'] = unicode.replace(issue.description, '\r\n', '\n')
    for note in [x for x in issue.notes.list() if not x.system]:
        non_finding['p'] += unicode.replace(note.body, '\r\n', '\n')
    non_finding_xml = jxmlease.XMLDictNode(non_finding,
                                           tag='non-finding',
                                           xml_attrs={'id': non_finding_id})
    if options['dry_run']:
        print_line('[+] {0}'.format(filename))
        print(non_finding_xml.emit_xml())
    else:
        if os.path.isfile(filename) and not options['overwrite']:
            print_line(
                'Non-finding {0} already exists (use --overwrite to overwrite)'
                .format(filename))
        else:
            if options['y'] or ask_permission('Create file ' + filename):
                with open(filename, 'w') as xmlfile:
                    xmlfile.write(non_finding_xml.emit_xml().encode('utf-8'))
                print_line('[+] Created {0}'.format(filename))
Example #2
0
def load_merge_xml_config(device, user, pw, config):
    """Load a configuration using "configure private" and "load merge".

    Given a configuration snippet as a jxmlease.XMLDictNode, do:
        configure private,
        load merge of the config snippet,
        commit (and close the configuration),
        and check the results.

    Return True if the config was committed successfully, False otherwise.
    """

    load_config_node = jxmlease.XMLDictNode(config, tag='load-configuration')
    load_config_node.set_xml_attr('action', 'merge')
    load_config_node.set_xml_attr('format', 'xml')

    rpcs = []
    rpcs.append({'open-configuration': {'private': ''}})
    rpcs.append(load_config_node)
    rpcs.append({'commit-configuration': ''})
    rpcs.append({'close-configuration': ''})
    payload_string = jxmlease.XMLListNode(rpcs).emit_xml(full_document=False)

    args = {'stop-on-error': '1'}
    headers = {'Accept': 'application/xml', 'Content-Type': 'application/xml'}
    url = MULTIPLE_RPC_URL_FORMAT % (device)
    http_resp = requests.post(url,
                              auth=(user, pw),
                              params=args,
                              headers=headers,
                              data=payload_string)
    http_resp.raise_for_status()

    responses = parse_multipart_messages(
        type=http_resp.headers['Content-Type'], response=http_resp.text)

    rc = True

    if len(responses) != len(rpcs):
        print "    Error: Fewer responses than expected!"
        rc = False

    for xml_response in responses:
        if xml_response == None:
            print "    Error: Unable to parse an RPC response!"
            rc = False
        else:
            (error_count, warning_count) = check_for_warnings_and_errors(
                parser(xml_response))
            if error_count > 0:
                rc = False

    return rc
Example #3
0
def get_xml_request(module, request, xmlns, content):
    if content is None:
        if xmlns is None:
            return "<%s/>" % request
        else:
            return '<%s xmlns="%s"/>' % (request, xmlns)

    if isinstance(content, str):
        content = content.strip()

        if content.startswith("<") and content.endswith(">"):
            # assumption content contains already XML payload
            if xmlns is None:
                return "<%s>%s</%s>" % (request, content, request)
            else:
                return '<%s xmlns="%s">%s</%s>' % (
                    request,
                    xmlns,
                    content,
                    request,
                )

        try:
            # trying if content contains dict
            content = ast.literal_eval(content)
        except Exception:
            module.fail_json(msg="unsupported content value `%s`" % content)

    if isinstance(content, dict):
        if not HAS_JXMLEASE:
            module.fail_json(
                msg="jxmlease is required to convert RPC content to XML "
                "but does not appear to be installed. "
                "It can be installed using `pip install jxmlease`"
            )

        payload = jxmlease.XMLDictNode(content).emit_xml(
            pretty=False, full_document=False
        )
        if xmlns is None:
            return "<%s>%s</%s>" % (request, payload, request)
        else:
            return '<%s xmlns="%s">%s</%s>' % (
                request,
                xmlns,
                payload,
                request,
            )

    module.fail_json(
        msg="unsupported content data-type `%s`" % type(content).__name__
    )
Example #4
0
def build_config_changes(desc_changes):
    """Generate a configuration snippet with new interface descriptions.

    Given a dictionary of new description values to be configured, build
    a configuration snippet as a jxmlease.XMLDictNode. The configuration
    snippet will configure the new description for each interface.

    Return the configuration snippet as a jxmlease.XMLDictNode.
    """

    interface_list = []
    for local_port in desc_changes:
        interface_list.append({
            'name': local_port,
            'description': desc_changes[local_port]
        })
    config = {'configuration': {'interfaces': {'interface': interface_list}}}
    return jxmlease.XMLDictNode(config)
Example #5
0
def add_finding(issue, options):
    """
    Writes issue as XML finding to file.
    """
    title = validate_report.capitalize(issue.title.strip())
    print_status('{0} - {1} - {2}'.format(issue.state, issue.labels, title),
                 options)
    threat_level = 'Moderate'
    finding_type = 'TODO'
    finding_id = '{0}-{1}'.format(issue.iid, valid_filename(title))
    filename = 'findings/{0}.xml'.format(finding_id)
    finding = collections.OrderedDict()
    finding['title'] = title
    finding['description'] = unicode.replace(issue.description, '\r\n', '\n')
    finding['technicaldescription'] = ''
    for note in [x for x in issue.notes.list() if not x.system]:
        finding['technicaldescription'] += unicode.replace(
            note.body, '\r\n', '\n')
    finding['impact'] = {}
    finding['impact']['p'] = 'TODO'
    finding['recommendation'] = {}
    finding['recommendation']['ul'] = {}
    finding['recommendation']['ul']['li'] = 'TODO'
    finding_xml = jxmlease.XMLDictNode(finding,
                                       tag='finding',
                                       xml_attrs={
                                           'id': finding_id,
                                           'threatLevel': threat_level,
                                           'type': finding_type
                                       })
    if options['dry_run']:
        print_line('[+] {0}'.format(filename))
        print(finding_xml.emit_xml())
    else:
        if os.path.isfile(filename) and not options['overwrite']:
            print_line(
                'Finding {0} already exists (use --overwrite to overwrite)'.
                format(filename))
        else:
            if options['y'] or ask_permission('Create file ' + filename):
                with open(filename, 'w') as xmlfile:
                    xmlfile.write(finding_xml.emit_xml().encode('utf-8'))
                print_line('[+] Created {0}'.format(filename))