Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CVEChecker which guesses the pkg name and version of an archive #8

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/checker.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright (C) 2018 Endless Mobile, Inc.
#
# Authors:
# Andrew Hayzen <[email protected]>
# Joaquim Rocha <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
Expand Down Expand Up @@ -68,6 +69,10 @@ def _get_finish_args_extra_data_from_json(self, json_data):
def _get_module_data_from_json(self, json_data):
external_data = []
for module in json_data.get('modules', []):
# This is a guess at the package name from the name the author
# has given to the module block
pkg_name = module.get('name', None)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes more sense to have the package name as part of the checker data, this way we can enforce it for the CVE Checker.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


for source in module.get('sources', []):
url = source.get('url', None)
if not url:
Expand All @@ -89,8 +94,8 @@ def _get_module_data_from_json(self, json_data):
size = source.get('size', -1)
checker_data = source.get('x-checker-data')

ext_data = ExternalData(data_type, name, url, sha256sum, size,
arches, checker_data)
ext_data = ExternalData(data_type, pkg_name, name, url,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my previous comment, the pkg_name would be part of the checker_data here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

sha256sum, size, arches, checker_data)
external_data.append(ext_data)

return external_data
Expand Down
61 changes: 61 additions & 0 deletions src/checkers/cvechecker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Copyright (C) 2018 Endless Mobile, Inc.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't have to assign the copyright to Endless if you don't want and you're not using most of its code.
Also, please describe what this checker is about (see other checkers for examples).

#
# Authors:
# Andrew Hayzen <[email protected]>
# Joaquim Rocha <[email protected]>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I don't mind but) you don't have to add my name if I didn't touch this code or if most of it wasn't copied from my code.

# Patrick Griffis <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import logging
import re

from lib.externaldata import ExternalData, CheckerRegistry, Checker


class CVEChecker(Checker):

def check(self, external_data):
try:
version = CVEChecker.extract_version_from_url(
external_data.url, external_data.type,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't like the arguments split like this + the single parenthesis.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we are using 100 chars for each line, moved this onto one line.

logging.debug('CVEChecker: Found %s of the version %s' %
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is the old string format, it should be "... Found {} of the versions {}...".format(...).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

(external_data.pkg_name, version))
except ValueError:
external_data.state = ExternalData.State.BROKEN
else:
external_data.state = ExternalData.State.VALID

# TODO: need similar to new_version but for cve_vuln
# this should also output to JSON

@staticmethod
def extract_version_from_url(url, data_type):
if data_type == ExternalData.Type.ARCHIVE:
filename = url.rpartition('/')[2]
match = re.search(r'(\d+\.\d+(?:\.\d+)?)', filename)

if match:
return match.groups()[-1]
else:
logging.debug('CVEChecker: Version not found in {}'.format(url))
raise ValueError
else:
logging.debug('CVEChecker: Unknown type %s' % data_type)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

String format.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

raise ValueError


CheckerRegistry.register_checker(CVEChecker)
8 changes: 6 additions & 2 deletions src/lib/externaldata.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright (C) 2018 Endless Mobile, Inc.
#
# Authors:
# Andrew Hayzen <[email protected]>
# Joaquim Rocha <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
Expand Down Expand Up @@ -40,8 +41,9 @@ class State(Enum):
VALID = 1 << 1 # URL is reachable
BROKEN = 1 << 2 # URL couldn't be reached

def __init__(self, data_type, filename, url, checksum, size=-1, arches=[],
checker_data=None):
def __init__(self, data_type, pkg_name, filename, url, checksum, size=-1,
arches=[], checker_data=None):
self.pkg_name = pkg_name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See other comments regarding the pkg_name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

self.filename = filename
self.url = url
self.checksum = checksum
Expand All @@ -54,13 +56,15 @@ def __init__(self, data_type, filename, url, checksum, size=-1, arches=[],

def __str__(self):
info = '{filename}:\n' \
' PkgName: {pkg_name}\n' \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto for the pkg_name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

' State: {state}\n' \
' Type: {type}\n' \
' URL: {url}\n' \
' SHA256: {checksum}\n' \
' Size: {size}\n' \
' Arches: {arches}\n' \
' Checker: {checker_data}'.format(state=self.state.name,
pkg_name=self.pkg_name,
filename=self.filename,
type=self.type.name,
url=self.url,
Expand Down