def gen_fs_hash(self): '''Get the filesystem hash if the image class was created with a tar_file''' if self.__tar_file: fs_dir = rootfs.get_untar_dir(self.__tar_file) tar_file = rootfs.get_layer_tar_path(self.__tar_file) rootfs.extract_tarfile(tar_file, fs_dir) self.__fs_hash = rootfs.calc_fs_hash(fs_dir)
def gen_fs_hash(self): '''Get the filesystem hash if the image class was created with a tar_file''' if self.tar_file: fs_dir = self.get_untar_dir() # make directory structure if it doesn't exist if not os.path.exists(fs_dir): os.makedirs(fs_dir) tar_file = os.path.join(rootfs.get_working_dir(), self.tar_file) rootfs.extract_tarfile(tar_file, fs_dir) self.__fs_hash = rootfs.calc_fs_hash(fs_dir)
def extract_image(args): """The image can either be downloaded from a container registry or provided as an image tarball. Extract the image into a working directory accordingly Return an image name and tag and an image digest if it exists""" if args.docker_image: # extract the docker image image_attrs = docker_api.dump_docker_image(args.docker_image) if image_attrs: # repo name and digest is preferred, but if that doesn't exist # the repo name and tag will do. If neither exist use repo Id. if image_attrs['Id']: image_string = image_attrs['Id'] if image_attrs['RepoTags']: image_string = image_attrs['RepoTags'][0] if image_attrs['RepoDigests']: image_string = image_attrs['RepoDigests'][0] return image_string logger.critical("Cannot extract Docker image") if args.raw_image: # for now we assume that the raw image tarball is always # the product of "docker save", hence it will be in # the docker style layout if rootfs.extract_tarfile(args.raw_image, rootfs.get_working_dir()): return args.raw_image logger.critical("Cannot extract raw image") return None
def extract_image_metadata(image_tag_string): '''Run docker save and extract the files in a temporary directory''' temp_path = os.path.abspath(temp_folder) try: image = client.images.get(image_tag_string) result = image.save(chunk_size=2097152, named=True) # write all of the tar byte stream into temporary tar file with open(temp_tarfile, 'wb') as f: for chunk in result: f.write(chunk) # extract tarfile into folder rootfs.extract_tarfile(temp_tarfile, temp_path) # remove temporary tar file os.remove(temp_tarfile) if not os.listdir(temp_path): raise IOError('Unable to untar Docker image') except docker.errors.APIError: # pylint: disable=try-except-raise raise
def extract_image_metadata(image_tag_string): '''Run docker save and extract the files in a temporary directory''' temp_path = rootfs.get_working_dir() placeholder = os.path.join(general.get_top_dir(), temp_tarfile) try: if general.check_tar(image_tag_string) is True: # image_tag_string is the path to the tar file for raw images rootfs.extract_tarfile(image_tag_string, temp_path) else: image = client.images.get(image_tag_string) result = image.save(chunk_size=2097152, named=True) # write all of the tar byte stream into temporary tar file with open(placeholder, 'wb') as f: for chunk in result: f.write(chunk) # extract tarfile into folder rootfs.extract_tarfile(placeholder, temp_path) # remove temporary tar file os.remove(placeholder) if not os.listdir(temp_path): raise IOError('Unable to untar Docker image') except docker.errors.APIError: # pylint: disable=try-except-raise raise
def extract_image(image_obj): """Run docker save and extract the resulting tarball into the working directory.""" temp_path = rootfs.get_working_dir() placeholder = os.path.join(general.get_top_dir(), constants.temp_tarfile) # try to save the image try: result = image_obj.save(chunk_size=2097152, named=True) # write all of the tar byte stream into temporary tar file with open(placeholder, 'wb') as f: for chunk in result: f.write(chunk) # extract temporary tar file into the working directory rootfs.extract_tarfile(placeholder, temp_path) # remove the tar file os.remove(placeholder) # If these operations didn't work, return False if not os.listdir(temp_path): logger.critical('Unable to extract Docker image') return False return True except docker.errors.APIError as e: logger.critical('Something happened with the Docker client: %s', e) return False
def extract_image(args): """The image can either be downloaded from a container registry or provided as an image tarball. Extract the image into a working directory accordingly Return an image name and tag and an image digest if it exists""" if args.image: # download the image result = skopeo.pull_image(args.image, args.no_tls) if result: return 'oci', args.image logger.critical("Cannot download Container image: \"%s\"", args.image) if args.raw_image: # for now we assume that the raw image tarball is always # the product of "docker save", hence it will be in # the docker style layout if rootfs.extract_tarfile(args.raw_image, rootfs.get_working_dir()): return 'docker', args.raw_image logger.critical("Cannot extract raw Docker image") return None, None
def execute_docker_image(args): # pylint: disable=too-many-branches '''Execution path if given a Docker image''' logger.debug('Starting analysis...') image_string = '' image_digest = '' if args.docker_image: # extract the docker image image_attrs = docker_api.dump_docker_image(args.docker_image) if image_attrs: if image_attrs['RepoTags']: image_string = image_attrs['RepoTags'][0] if image_attrs['RepoDigests']: image_digest = image_attrs['RepoDigests'][0] else: logger.critical("Cannot extract Docker image") elif args.raw_image: # for now we assume that the raw image tarball is always # the product of "docker save", hence it will be in # the docker style layout if rootfs.extract_tarfile(args.raw_image, rootfs.get_working_dir()): image_string = args.raw_image else: logger.critical("Cannot extract raw image") # If the image has been extracted, load the metadata if image_string: full_image = report.load_full_image(image_string, image_digest) # check if the image was loaded successfully if full_image.origins.is_empty(): # Add an image origin here full_image.origins.add_notice_origin( formats.docker_image.format(imagetag=image_string)) # analyze image analyze(full_image, args) # report out report.report_out(args, full_image) else: # we cannot load the full image logger.error('Cannot retrieve full image metadata') # cleanup if not args.keep_wd: prep.clean_image_tars(full_image)