aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--elivepatch_client/client/checkers.py37
-rw-r--r--elivepatch_client/client/cli.py16
-rw-r--r--elivepatch_client/client/security.py95
3 files changed, 109 insertions, 39 deletions
diff --git a/elivepatch_client/client/checkers.py b/elivepatch_client/client/checkers.py
index 79f45fa..ed8bf97 100644
--- a/elivepatch_client/client/checkers.py
+++ b/elivepatch_client/client/checkers.py
@@ -11,7 +11,6 @@ import tempfile
import os
import os.path
import re
-from git import Repo
from elivepatch_client.client import restful
@@ -81,23 +80,6 @@ class Kernel(object):
self.rest_manager.get_livepatch(self.main_patch_fullpath)
-class CVE(object):
- """
- Check the kernel against a CVE repository
- """
- def __init__(self):
- self.git_url = "https://github.com/nluedtke/linux_kernel_cves"
- self.repo_dir = "/tmp/kernel_cve/"
- pass
-
- def download(self):
- Repo.clone_from(self.git_url, self.repo_dir)
-
- def set_repo(self, git_url, repo_dir):
- self.git_url = git_url
- self.repo_dir = repo_dir
-
-
class FileAction(object):
"""
Work with files
@@ -120,22 +102,3 @@ class FileAction(object):
# Store uncompressed file
temporary.write(uncompressed_output)
return temporary
-
- def config_kernel_version(self, uncompressed_config_file):
- """
- Find the kernel version from where the configuration as been generated
- :param uncompressed_config_file:
- :return: kernel version
- """
- uncompressed_config_file.seek(0)
- with uncompressed_config_file as f:
- i = 0
- while i < 2:
- f.readline()
- if i == 1:
- kernel_line = str(f.readline())
- i += 1
- kernel_version_raw = str(kernel_line.split(' ')[2])
- kernel_version = kernel_version_raw.split(('-'))[0]
- return kernel_version
-
diff --git a/elivepatch_client/client/cli.py b/elivepatch_client/client/cli.py
index 181b1e0..2f45f67 100644
--- a/elivepatch_client/client/cli.py
+++ b/elivepatch_client/client/cli.py
@@ -5,12 +5,13 @@
# Distributed under the terms of the GNU General Public License v2 or later
import sys
+import os
from elivepatch_client.client.checkers import Kernel
from elivepatch_client.client import restful
from elivepatch_client.client.version import VERSION
from elivepatch_client.client import patch
-
+from elivepatch_client.client import security
if sys.hexversion >= 0x30200f0:
ALL_KEYWORD = b'ALL'
@@ -30,7 +31,18 @@ class Main(object):
def dispatch(self, config):
print(str(config))
if config.cve:
- print('Kernel security CVE check is not implemented yet')
+ patch_manager = patch.ManaGer()
+ applied_patches_list = patch_manager.list(config.kernel_version)
+ print(applied_patches_list)
+ cve_repository = security.CVE()
+ if not os.path.isdir("/tmp/kernel_cve"):
+ print("Downloading the CVE repository...")
+ cve_repository.download()
+ else:
+ print("CVE repository already present.")
+ print("updating...")
+ # TODO: update repository
+ cve_repository.cve_git_id()
elif config.patch:
patch_manager = patch.ManaGer()
applied_patches_list = patch_manager.list(config.kernel_version)
diff --git a/elivepatch_client/client/security.py b/elivepatch_client/client/security.py
new file mode 100644
index 0000000..c322b0a
--- /dev/null
+++ b/elivepatch_client/client/security.py
@@ -0,0 +1,95 @@
+from git import Repo
+import os
+import urllib.request as request
+import shutil
+
+
+class CVE(object):
+ """
+ Check the kernel against a CVE repository
+ """
+ def __init__(self):
+ self.git_url = "https://github.com/nluedtke/linux_kernel_cves"
+ self.repo_dir = "/tmp/kernel_cve/"
+ self.cve_patches_dir = "/tmp/patches_cve/"
+ pass
+
+ def download(self):
+ Repo.clone_from(self.git_url, self.repo_dir)
+
+ def set_repo(self, git_url, repo_dir):
+ self.git_url = git_url
+ self.repo_dir = repo_dir
+
+ def cve_git_id(self):
+ major_version, minor_version, revision_version = _current_kernel_version()
+ major_version, minor_version, revision_version = 4,9,25
+ security_file = open("/tmp/kernel_cve/"+str(major_version)+"."+str(minor_version)+
+ "/"+str(major_version)+"."+str(minor_version)+"_security.txt", "r")
+ security_versions = []
+ for line in security_file:
+ if "CVEs fixed in" in line:
+ security_versions_tmp = line.strip().split(' ')[3][:-1]
+ # if there is not revision, set revision as 0
+ if len(security_versions_tmp) == 3:
+ security_versions.append(0)
+ else:
+ security_versions.append(security_versions_tmp.split('.')[2])
+ security_file.close()
+
+ print('[debug] security versions: ' + str(security_versions))
+
+ cve_2d_list = []
+ for version in security_versions:
+ if int(version) > revision_version:
+ cve_2d_list.append(self.cve_id(major_version, minor_version, version))
+
+ patch_index = 0
+ if not os.path.exists(self.cve_patches_dir):
+ os.mkdir(self.cve_patches_dir)
+ for cve_list in cve_2d_list:
+ print(cve_list)
+ print([ii for n,ii in enumerate(cve_list) if ii not in cve_list[:n]])
+ for cve_id in cve_list:
+ self.download_cve_patch(cve_id, str(patch_index))
+ patch_index +=1
+
+ def download_cve_patch(self, cve_id, patch_index):
+ file_name= self.cve_patches_dir + patch_index + '.patch'
+
+ # Download the file from `url` and save it locally under `file_name`:
+ with request.urlopen('https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/patch/?id=' + cve_id) as response, \
+ open(file_name, 'wb') as out_file:
+ shutil.copyfileobj(response, out_file)
+
+ def cve_id(self, major_version, minor_version, revision_version):
+ security_file = open("/tmp/kernel_cve/"+str(major_version)+"."+str(minor_version)+
+ "/"+str(major_version)+"."+str(minor_version)+"_security.txt", "r")
+
+ git_security_id = []
+ # return cve for a kernel version
+ for excluded_line in security_file:
+ if ("CVEs fixed in "+str(major_version)+
+ "."+str(minor_version)+
+ "."+str(revision_version)+
+ ":") in excluded_line:
+ for included_line in security_file:
+ if not "\n" is included_line:
+ git_security_id.append(included_line.strip().split(' ')[1])
+ else:
+ # debug
+ # print('got cve for '+str(major_version)+
+ # "."+str(minor_version)+
+ # "."+str(revision_version))
+ break
+ security_file.close()
+ return git_security_id
+
+
+def _current_kernel_version():
+ kernel_version = os.uname()[2]
+ major_version = int(kernel_version.split('.')[0])
+ minor_version = int(kernel_version.split('.')[1])
+ revision_version = int((kernel_version.split('.')[2]).split('-')[0])
+ return major_version, minor_version, revision_version
+