Esempio n. 1
0
def main():

    args = parse_command_args()
    components_with_no_copyrights = []

    with open(args.token_file, 'r') as tf:
        access_token = tf.readline().strip()

    global bd
    bd = Client(base_url=args.base_url,
                token=access_token,
                verify=args.no_verify,
                timeout=60.0,
                retries=4)
    project_name, project_version = get_project_version_by_name(
        args.project_name, args.version_name)

    for component in bd.get_resource("components", project_version):
        try:
            copyrights = find_copyrights_in_bom_component_origins(component)           \
                      or find_copyrights_in_github_origins(component)                  \
                      or find_copyrights_in_previous_component_versions(component)

            if copyrights:
                print_copyrights(component, copyrights)
            else:
                components_with_no_copyrights.append(component)

        except Exception as e:
            logging.debug(
                f"Component {component['componentName']} failed with {e}")

    if args.report_missing:
        report_components_with_no_copyrights(components_with_no_copyrights)
Esempio n. 2
0
def cb_configserver(button, bdserver, apikey, usecerts):
    global bd

    if button is None:
        raise dash.exceptions.PreventUpdate

    if usecerts == 'INSECURE':
        verify = False
    else:
        verify = True

    bd = Client(
        token=apikey,
        base_url=bdserver,
        timeout=300,
        verify=verify  # TLS certificate verification
    )
    try:
        bd.list_resources()
    except Exception as exc:
        toast = make_connect_toast('Unable to eonnect - {}'.format(str(exc)))
        return True, None, '', '', '', False, toast

    projdf = projs.get_project_data(bd)
    projlabel = "Projects (" + str(len(projdf.index)) + ")"

    return False, projdf.to_dict(
        'records'), projlabel, bdserver, apikey, verify, ''
def main():
    args = parse_command_args()
    with open(args.token_file, 'r') as tf:
        access_token = tf.readline().strip()
    global bd
    bd = Client(base_url=args.base_url,
                token=access_token,
                verify=args.no_verify,
                timeout=60.0,
                retries=4)

    if re.match(".+xlsx?$", args.input_file):
        print(f"Processing EXCEL file {args.input_file}")
        process_excel_file(args.input_file)
    else:
        print("Processing as CSV")
        process_csv_file(args.input_file)
def main():
    upstream_copyright_data_file='copyright_data.txt'

    parser = argparse.ArgumentParser("Enumerate BOM componets without copyrigth statements. retrieve copyright statements form upstream channel and/or version")
    parser.add_argument("-u", "--base-url", required=True, help="Hub server URL e.g. https://your.blackduck.url")
    parser.add_argument("-t", "--token-file", dest='token_file', required=True, help="containing access token")
    parser.add_argument("-nv", "--no-verify", dest='verify', action='store_false', help="disable TLS certificate verification")
    parser.add_argument("-o", "--outputdir", dest='outputdir', default='outdir', help="disable TLS certificate verification")
    args = parser.parse_args()

    with open(args.token_file, 'r') as tf:
        access_token = tf.readline().strip()

    global bd
    bd = Client(base_url=args.base_url, token=access_token, verify=args.verify, timeout = 60.0)
    outdir=None
    if args.outputdir:
        outdir = args.outputdir
    import os
    if not os.path.exists(outdir):
        os.mkdir(outdir)
    projects = bd.get_resource('projects')
    for project in projects:
        versions = bd.get_resource('versions',project)
        for version in versions:
            codelocations = bd.get_resource('codelocations', version)
            for codelocation in codelocations:
                resources = bd.list_resources(codelocation)
                url = resources['scan-data']
                filename = url.split('/')[6]
                response = bd.session.get(url, stream=True, verify=False)
                print (response.status_code)
                print (response.ok)
                print (url)
                if response.ok:
                    pathname = os.path.join(outdir, filename)
                    with open(pathname, "wb") as f:
                        for data in response.iter_content():
                            f.write(data)
                    print(f"{filename}, {pathname}")
                    required=True,
                    help="Project that contains the BOM components")
parser.add_argument("--version",
                    dest='version_name',
                    required=True,
                    help="Version that contains the BOM components")
parser.add_argument("--no-verify",
                    dest='verify',
                    action='store_false',
                    help="disable TLS certificate verification")
args = parser.parse_args()

with open(args.token_file, 'r') as tf:
    access_token = tf.readline().strip()

bd = Client(base_url=args.base_url, token=access_token, verify=args.verify)

params = {'q': [f"name:{args.project_name}"]}
projects = [
    p for p in bd.get_resource('projects', params=params)
    if p['name'] == args.project_name
]
assert len(
    projects
) == 1, f"There should be one, and only one project named {args.project_name}. We found {len(projects)}"
project = projects[0]

params = {'q': [f"versionName:{args.version_name}"]}
versions = [
    v for v in bd.get_resource('versions', project, params=params)
    if v['versionName'] == args.version_name
args = parser.parse_args()

logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s',
                    stream=sys.stderr,
                    level=logging.DEBUG)
logging.getLogger("requests").setLevel(logging.WARNING)
logging.getLogger("urllib3").setLevel(logging.WARNING)
logging.getLogger("blackduck").setLevel(logging.DEBUG)

with open(args.token_file, 'r') as tf:
    access_token = tf.readline().strip()

bd = Client(
    base_url=args.base_url,
    token=access_token,
    verify=args.verify,
    timeout=args.timeout,
    retries=args.retries,
)

params = {'q': [f"name:{args.project_name}"]}
projects = [
    p for p in bd.get_resource('projects', params=params)
    if p['name'] == args.project_name
]
assert len(
    projects
) == 1, f"There should be one, and only one project named {args.project_name}. We found {len(projects)}"
project = projects[0]

params = {'q': [f"versionName:{args.version_name}"]}
Esempio n. 7
0
from pprint import pprint

logging.basicConfig(
    level=logging.DEBUG,
    format="[%(asctime)s] {%(module)s:%(lineno)d} %(levelname)s - %(message)s"
)

parser = argparse.ArgumentParser("Get a specific component and list its vulnerabilities")
parser.add_argument("--base-url", required=True, help="Hub server URL e.g. https://your.blackduck.url")
parser.add_argument("--token-file", dest='token_file', required=True, help="containing access token")
parser.add_argument("--no-verify", dest='verify', action='store_false', help="disable TLS certificate verification")
args = parser.parse_args()

with open(args.token_file, 'r') as tf:
    access_token = tf.readline().strip()

bd = Client(base_url=args.base_url, token=access_token, verify=args.verify)

params = {
    'q': ["maven:commons-beanutils:commons-beanutils:1.9.3"]
}
search_results = bd.get_items("/api/components", params=params)
for result in search_results:
    pprint(result)
    print(f"{result['componentName']} {result['versionName']}")
    url = result['version']
    component_version = bd.get_json(url)

    for vulnerability in bd.get_resource('vulnerabilities', component_version):
        print(vulnerability['name'])
                    required=True,
                    help="containing access token")
parser.add_argument("--no-verify",
                    dest='verify',
                    action='store_false',
                    help="disable TLS certificate verification")
parser.add_argument(
    "cpe_id",
    help=
    "Provide a CPE (2.2 or 2.3 xml format) ID - e.g. \"cpe:2.3:a:apache:log4j:2.11.1:-:*:*:*:*:*:*\" To get a complete dictionary of CPE IDs go to the NIST site, https://nvd.nist.gov/products/cpe"
)
args = parser.parse_args()

logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s',
                    stream=sys.stderr,
                    level=logging.DEBUG)
logging.getLogger("requests").setLevel(logging.WARNING)
logging.getLogger("urllib3").setLevel(logging.WARNING)
logging.getLogger("blackduck").setLevel(logging.WARNING)

with open(args.token_file, 'r') as tf:
    access_token = tf.readline().strip()

bd = Client(base_url=args.base_url, token=access_token, verify=args.verify)

cpes = [cpe for cpe in bd.get_items(f"/api/cpes?q={args.cpe_id}")]
if cpes:
    for cpe in cpes:
        cpe['cpe-origins'] = [o for o in bd.get_resource("cpe-origins", cpe)]
        cpe['cpe-versions'] = [v for v in bd.get_resource("cpe-versions", cpe)]
print(json.dumps(cpes))
Esempio n. 9
0
    args = parser.parse_args()

    verify = False  # TLS certificate verification
    session = HubSession(args.base_url, timeout=15.0, retries=3, verify=verify)

    # De-tangle the possibilities of specifying credentials
    if args.token_file:
        tf = open(args.token_file, 'r')
        access_token = tf.readline().strip()
        auth = BearerAuth(session, access_token)
    elif args.username and args.password:
        auth = CookieAuth(session, args.username, args.password)
    else:
        raise SystemError("Authentication credentials not specified")

    bd = Client(base_url=args.base_url, session=session, auth=auth, verify=verify)

    if args.mode not in ['list', 'delete']:
        print("Error: must specify --mode to be one of: list or delete")
        sys.exit(-1)

    input_file = open(args.csv_file_input, 'r')
    reader = csv.DictReader(input_file)

    logging.info("csv fieldnames:")
    logging.info(reader.fieldnames)

    check_for_columns([
        'projectId',
        'project',
        'versionId',
logging.basicConfig(
    level=logging.DEBUG,
    format="[%(asctime)s] {%(module)s:%(lineno)d} %(levelname)s - %(message)s")

parser = argparse.ArgumentParser("Get a single vulnerability by id")
parser.add_argument("--base-url",
                    required=True,
                    help="Hub server URL e.g. https://your.blackduck.url")
parser.add_argument("--token-file",
                    dest='token_file',
                    required=True,
                    help="containing access token")
parser.add_argument("--no-verify",
                    dest='verify',
                    action='store_false',
                    help="disable TLS certificate verification")
parser.add_argument(
    "--vulnerability",
    help="vulnerability id e.g. CVE-2016-4009 or BDSA-2014-0129")
args = parser.parse_args()

with open(args.token_file, 'r') as tf:
    access_token = tf.readline().strip()

bd = Client(base_url=args.base_url, token=access_token, verify=args.verify)

vulnerability = bd.get_json(f"/api/vulnerabilities/{args.vulnerability}")
print(f"Details about {vulnerability['name']}")
pprint(vulnerability)
Esempio n. 11
0
    level=logging.INFO,
    format="[%(asctime)s] {%(module)s:%(lineno)d} %(levelname)s - %(message)s"
)

parser = argparse.ArgumentParser("Get the BOM components for a given project-version and the license details for each BOM component")
parser.add_argument("--base-url", required=True, help="Hub server URL e.g. https://your.blackduck.url")
parser.add_argument("--token-file", dest='token_file', required=True, help="containing access token")
parser.add_argument("--project", dest='project_name', required=True, help="Project that contains the BOM components")
parser.add_argument("--version", dest='version_name', required=True, help="Version that contains the BOM components")
parser.add_argument("--no-verify", dest='verify', action='store_false', help="disable TLS certificate verification")
args = parser.parse_args()

with open(args.token_file, 'r') as tf:
    access_token = tf.readline().strip()

bd = Client(base_url=args.base_url, token=access_token, verify=args.verify)

params = {
    'q': [f"name:{args.project_name}"]
}
projects = [p for p in bd.get_resource('projects', params=params) if p['name'] == args.project_name]
assert len(projects) == 1, f"There should be one, and only one project named {args.project_name}. We found {len(projects)}"
project = projects[0]

params = {
    'q': [f"versionName:{args.version_name}"]
}
versions = [v for v in bd.get_resource('versions', project, params=params) if v['versionName'] == args.version_name]
assert len(versions) == 1, f"There should be one, and only one version named {args.version_name}. We found {len(versions)}"
version = versions[0]
Esempio n. 12
0
                    required=True,
                    help="Hub server URL e.g. https://your.blackduck.url")
parser.add_argument("--token-file",
                    dest='token_file',
                    required=True,
                    help="containing access token")
parser.add_argument("--no-verify",
                    dest='verify',
                    action='store_false',
                    help="disable TLS certificate verification")
args = parser.parse_args()

with open(args.token_file, 'r') as tf:
    access_token = tf.readline().strip()

bd = Client(base_url=args.base_url, token=access_token, verify=args.verify)


def iterate_sub_resources(parent, breadcrumb=""):
    try:
        resources = bd.list_resources(parent)
    except TypeError:
        return

    for res in resources:
        print(f"{breadcrumb}->{res}", end='')
        if res in [
                'scan-data',  # 200; but .bdio output is not json
                'apiDocumentation',  # 200; but output is just a huge amount of html
                'detectUri',  # 204; no content
        ]:
Esempio n. 13
0
        'q': [f"name:{project_name}"]
    }
    projects = [p for p in bd.get_resource('projects', params=params) if p['name'] == project_name]
    assert len(projects) == 1, f"There should be one, and only one project named {project_name}. We found {len(projects)}"
    project = projects[0]

    params = {
        'q': [f"versionName:{version_name}"]
    }
    versions = [v for v in bd.get_resource('versions', project, params=params) if v['versionName'] == version_name]
    assert len(versions) == 1, f"There should be one, and only one version named {version_name}. We found {len(versions)}"
    version = versions[0]
    return project, version


bd = Client(
    base_url=args.bd_url,
    token=args.user_api_token,
    verify=args.verify
)

project, version = get_project_version_by_name(args.project, args.version)
custom_fields = [cf for cf in bd.get_resource("custom-fields", version)]

cfs = list(filter(lambda cf: cf['label'] == args.field_label, custom_fields))
assert len(cfs) == 1, f"We did not find the field labeled {args.field_label} or we found more than one and that shouldn't happen!"
custom_field = cfs[0]
print(f"Custom field {args.field_label} on project-version {args.project}-{args.version} has value(s) {custom_field['values']}")
print(f"Refer to the BD REST API doc for more details on how to interact with the different custom field types, {bd.base_url}/api-doc/public.html#_reading_a_single_project_version_custom_field")

			print(f"Successfully downloaded zip file to {filename} for report {report_id}")
		else:
			print(f"Failed to retrieve report {report_id}")
			print("Probably not ready yet, waiting 5 seconds then retrying...")
			time.sleep(args.sleep_time)
			retries -= 1
			download_report(location, filename, retries)
	else:
		raise FailedReportDownload(f"Failed to retrieve report {report_id} after multiple retries")

# hub = HubInstance()

with open(args.token_file, 'r') as tf:
	access_token = tf.readline().strip()

bd = Client(base_url=args.bd_url, token=access_token, verify=args.verify)

params = {
    'q': [f"name:{args.project_name}"]
}
projects = [p for p in bd.get_resource('projects', params=params) if p['name'] == args.project_name]
assert len(projects) == 1, f"There should be one, and only one project named {args.project_name}. We found {len(projects)}"
project = projects[0]

params = {
    'q': [f"versionName:{args.version_name}"]
}
versions = [v for v in bd.get_resource('versions', project, params=params) if v['versionName'] == args.version_name]
assert len(versions) == 1, f"There should be one, and only one version named {args.version_name}. We found {len(versions)}"
version = versions[0]
Esempio n. 15
0
from blackduck.Authentication import CookieAuth

import argparse
import logging
from pprint import pprint

logging.basicConfig(
    level=logging.DEBUG,
    format="[%(asctime)s] {%(module)s:%(lineno)d} %(levelname)s - %(message)s")

parser = argparse.ArgumentParser()
parser.add_argument("--base-url",
                    required=True,
                    help="Hub server URL e.g. https://your.blackduck.url")
parser.add_argument("--username", required=True, help="Hub user")
parser.add_argument("--password", required=True, help="Hub user")
parser.add_argument("--no-verify",
                    dest='verify',
                    action='store_false',
                    help="disable TLS certificate verification")
args = parser.parse_args()

verify = args.verify
base_url = args.base_url
session = HubSession(base_url, timeout=15.0, retries=3, verify=verify)
auth = CookieAuth(session, username=args.username, password=args.password)

bd = Client(base_url=base_url, session=session, auth=auth, verify=verify)

pprint(bd.list_resources())
    session = HubSession(base_url,
                         timeout=args.timeout,
                         retries=args.retries,
                         verify=verify)

    # De-tangle the possibilities of specifying credentials
    if args.token_file:
        tf = open(args.token_file, 'r')
        access_token = tf.readline().strip()
        auth = BearerAuth(session, access_token)
    elif args.username and args.password:
        auth = CookieAuth(session, args.username, args.password)
    else:
        raise SystemError("Authentication credentials not specified")

    bd = Client(base_url=base_url, session=session, auth=auth)

    projectDict = {}  # key:projectId: json
    pvDict = {}  # key:projectId: json array

    for project in sageJson['projects']:
        m = re.match(r".*/projects/(.*)", project['url'])
        projectId = m.group(1)
        projectDict[projectId] = project
        pvDict[projectId] = project['versions']

    codelocationsDict = {}  # key:codelocationId: json
    for codelocation in sageJson['scans']:
        m = re.match(r".*/codelocations/(.*)", codelocation['url'])
        codelocationId = m.group(1)
        codelocationsDict[codelocationId] = codelocation
Esempio n. 17
0
    f"Set the base name for the output file (default: {DEFAULT_OUTPUT_BASE}. The format will determine the file extension (e.g. format=JSON means file will end with .json)"
)
# parser.add_argument("-u", "--usage-details", dest="usage_details", action='store_true', help="Use this option to retrieve license usage details which will show what project-versions and components are using the license")
args = parser.parse_args()

logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s',
                    stream=sys.stderr,
                    level=logging.DEBUG)
logging.getLogger("requests").setLevel(logging.WARNING)
logging.getLogger("urllib3").setLevel(logging.WARNING)
logging.getLogger("blackduck").setLevel(logging.WARNING)

with open(args.token_file, 'r') as tf:
    access_token = tf.readline().strip()

bd = Client(base_url=args.base_url, token=access_token, verify=args.verify)

# WARNING:
#   This uses an internal, un-supported API endpoint (see below)
#   and therefore could break in future versions of Black Duck.
#   This script was tested with BD v2021.8.2.
#
# An ER has been filed in Synopsys Jira ticket HUB-26144 to make a
# in-use filter part of a public endpoint for retrieving licenses

inuse_licenses_url = f"{bd.base_url}/api/internal/composite/licenses?filter=inUse:true"

headers = {'Accept': 'application/vnd.blackducksoftware.internal-1+json'}
inuse_licenses_d = {
    l['name']: l
    for l in bd.get_items(inuse_licenses_url, headers=headers)
def main():
    upstream_copyright_data_file = 'copyright_data.txt'

    parser = argparse.ArgumentParser(
        "Enumerate BOM componets without copyrigth statements. retrieve copyright statements form upstream channel and/or version"
    )
    parser.add_argument("-u",
                        "--base-url",
                        required=True,
                        help="Hub server URL e.g. https://your.blackduck.url")
    parser.add_argument("-t",
                        "--token-file",
                        dest='token_file',
                        required=True,
                        help="containing access token")
    parser.add_argument("-p",
                        "--project-name",
                        dest='project_name',
                        required=True,
                        help="Project Name")
    parser.add_argument("-v",
                        "--version-name",
                        dest='version_name',
                        required=True,
                        help="Version Name")
    parser.add_argument("-o",
                        "--output-file",
                        dest='output_file',
                        default=upstream_copyright_data_file,
                        help=f"TEXT-formatted file with data")
    parser.add_argument("-jo",
                        "--json-output-file",
                        dest='json_output_file',
                        default=None,
                        help='JSON formatted file with data')
    parser.add_argument("-ukc",
                        "--use-kb-copyright",
                        dest='use_kb_copyright',
                        default=False,
                        help='Use KB Copyright vs Updated Copyright')
    parser.add_argument("-nv",
                        "--no-verify",
                        dest='verify',
                        action='store_false',
                        help="disable TLS certificate verification")
    args = parser.parse_args()

    with open(args.token_file, 'r') as tf:
        access_token = tf.readline().strip()

    global bd
    bd = Client(base_url=args.base_url,
                token=access_token,
                verify=args.verify,
                timeout=60.0)

    project, version = get_project_version_by_name(args.project_name,
                                                   args.version_name)
    logging.debug(f"Found {project['name']}:{version['versionName']}")

    # retrieve bill of materials and locate entries without copyrights
    bom_components_with_no_copyrights = []
    for component in bd.get_resource("components", version):
        logging.debug(f"Processing component {component['componentName']}")
        #if component['componentName'] != 'musl':
        #    continue
        origins = component['origins']
        if len(origins) == 0:
            bom_components_with_no_copyrights.append(component)
            continue
        copyrights_count = 0
        for origin in origins:
            logging.debug(
                f"Processing origin {origin['externalNamespace']}  {origin['externalId']}"
            )
            origin_copyrights = [
                copyright for copyright in bd.get_resource(
                    'component-origin-copyrights', origin)
            ]
            copyrights_count += len(origin_copyrights)
            if copyrights_count > 0:
                break
        logging.debug(f"Copyright count = {copyrights_count}")
        if copyrights_count == 0:
            bom_components_with_no_copyrights.append(component)

    logging.debug(
        f"Found {len(bom_components_with_no_copyrights)} components with no copyright"
    )
    output_data = list()
    for component in bom_components_with_no_copyrights:
        logging.debug(
            f"Locating copyrights for component {component['componentName']} {component.get('componentVersionName', None)}"
        )
        copyrights = find_copyright_for_component(component)
        logging.debug(f"Found {len(copyrights)} active records")
        output_data.append({'component': component, 'copyrights': copyrights})

    logging.debug(f"Writing results into {args.output_file} file")
    write_text_output(output_data, args.output_file, args.use_kb_copyright)
    if args.json_output_file:
        logging.debug(f"Writing results into {args.json_output_file} file")
        with open(args.json_output_file, 'w') as f:
            json.dump(output_data, f, indent=2)
Esempio n. 19
0
                    required=True,
                    help="Hub server URL e.g. https://your.blackduck.url")
parser.add_argument("--token-file",
                    dest='token_file',
                    required=True,
                    help="containing access token")
parser.add_argument("--no-verify",
                    dest='verify',
                    action='store_false',
                    help="disable TLS certificate verification")
args = parser.parse_args()

with open(args.token_file, 'r') as tf:
    access_token = tf.readline().strip()

bd = Client(base_url=args.base_url, token=access_token, verify=args.verify)

for project in bd.get_resource('projects'):
    print(f"Project: {project['name']}")
    print("Project list_resources():")
    pprint(bd.list_resources(project))
    for version in bd.get_resource('versions', project):
        print(f"Version: {version['versionName']}")
        for bom_component in bd.get_resource('components', version):
            print(
                f"BOM component: {bom_component['componentName']}:{bom_component['componentVersionName']}"
            )
        # print(f"Version list_resources():")
        # pprint(bd.list_resources(version))
        # print("Exiting after printing first project and version")
        # quit(0)
Esempio n. 20
0
            print(f"Failed to retrieve report {report_id}")
            print("Probably not ready yet, waiting 5 seconds then retrying...")
            time.sleep(args.sleep_time)
            retries -= 1
            download_report(location, filename, retries)
    else:
        raise FailedReportDownload(
            f"Failed to retrieve report {report_id} after multiple retries")


# hub = HubInstance()

with open(args.token_file, 'r') as tf:
    access_token = tf.readline().strip()

bd = Client(base_url=args.bd_url, token=access_token, verify=args.verify)

params = {'q': [f"name:{args.project_name}"]}
projects = [
    p for p in bd.get_resource('projects', params=params)
    if p['name'] == args.project_name
]
assert len(
    projects
) == 1, f"There should be one, and only one project named {args.project_name}. We found {len(projects)}"
project = projects[0]

params = {'q': [f"versionName:{args.version_name}"]}
versions = [
    v for v in bd.get_resource('versions', project, params=params)
    if v['versionName'] == args.version_name
Esempio n. 21
0
    format="[%(asctime)s] {%(module)s:%(lineno)d} %(levelname)s - %(message)s"
)

parser = argparse.ArgumentParser("Create, read, update, and delete a project")
parser.add_argument("--base-url", required=True, help="Hub server URL e.g. https://your.blackduck.url")
parser.add_argument("--token-file", dest='token_file', required=True, help="containing access token")
parser.add_argument("--no-verify", dest='verify', action='store_false', help="disable TLS certificate verification")
parser.add_argument("--project", required=True, help="Project name")
args = parser.parse_args()

with open(args.token_file, 'r') as tf:
    access_token = tf.readline().strip()

bd = Client(
    base_url=args.base_url,
    token=access_token,
    verify=args.verify
)

project_name = args.project

# POST
project_data = {
    'name': project_name,
    'description': "some description",
    'projectLevelAdjustments': True,
}

try:
    r = bd.session.post("/api/projects", json=project_data)
    r.raise_for_status()