示例#1
0
def diff_file(file_path, source, destination, results):
    if source.is_dir(file_path) and destination.is_dir(file_path):
        diff_directory(file_path, source, destination, results)

    try:
        EVENTS['differ.pre_open'](file_path, source, destination, results,
                                  DIFF_NAME)
    except Exception as e:
        logger.error("File '{}' not found in destination".format(file_path))
        # Store difference in existence

    if EVENTS['differ.with_open']:
        try:
            with source.open(
                    file_path
            ) as fd:  # TODO: When it returns I will stuff it in the right place
                EVENTS['differ.with_open'](
                    file_path,
                    file_type,
                    source,
                    destination,
                    results,
                    DIFF_NAME,
                    fd,
                )

            EVENTS['differ.post_close'](file_path, file_type, source,
                                        destination, results, DIFF_NAME)
        except IOError:
            logger.warn(
                "'open()' System Call not supported on {}".format(file_path))
示例#2
0
def _clone(args, image, context=os):
    entrypoints = []
    for entrypoint in args.entrypoints:
        if context.path.isdir(entrypoint):
            entrypoints.append(entrypoint)
        else:
            logger.error(
                "Entrypoint '{}' is not a Directory".format(entrypoint))
    if not entrypoints:
        logger.critical("No valid Entrypoints Found!")
        logger.critical("Exiting...")
        sys.exit(-1)

    crawler = BaseCrawler(entrypoints, args.excluded_dirs, image=context)

    load_extension_list(args.load_extensions)

    pool = Pool(args.threads)
    pool.starmap(  # image, (filename, filetype), context
        file_worker,
        zip(itertools.repeat(image), crawler(), itertools.repeat(context)))
    pool.close()
    pool.join()

    logger.info("Processed {} files".format(PROCESSED_FILES))
    logger.info("Image Generated!")
    image_serializer = SatoriJsoner()
    # image_serializer = SatoriPickler()
    image_serializer.write(image, args.image_file)
    logger.warn("Stored to file '{}'".format(image_serializer.last_file))
示例#3
0
def diff_directory(file_path, source, destination, results):
    try:
        s_cont = set(source.listdir(file_path))
        d_cont = set(destination.listdir(file_path))
    except PermissionError:
        logger.warn("Permission Denied for listing '{}'. Skipping...".format(
            file_path))
        return
    source_only = s_cont - d_cont
    dest_only = d_cont - s_cont

    for diff_only in (
        (source_only, "src_only"),
        (dest_only, "dst_only"),
    ):
        if diff_only[0]:
            try:
                diff_dict = results.get_attribute(file_path, DIFF_NAME)
            except FileNotFoundError:
                diff_dict = {}
                results.set_attribute(
                    file_path,
                    diff_dict,
                    DIFF_NAME,
                    force_create=True,
                )
            diff_dict[diff_only[1]] = list(diff_only[0])

    # print (s_cont, d_cont)
    common_files = s_cont & d_cont
    # print(common_files)
    for f in common_files:  # Use thread map?
        new_file_path = file_path + '/' + f
        diff_file(new_file_path, source, destination, results)
示例#4
0
def load_extension_list(extension_list):
    """
    extension_list: list of filenames 
    """
    for i, extension in enumerate(extension_list):
        try:
            ext_module = imp.load_source('extension_{}'.format(i), extension)
            logger.warn("Extension '{}' loaded".format(ext_module.__name__))
        except Exception as e:
            logger.error("[{}] - Extension {} could not be loaded".format(
                e, extension))
示例#5
0
def main():
    global ENCODING
    parser = argparse.ArgumentParser()
    parser.add_argument("SatoriFile", help="The SatoriImage file to mount")
    parser.add_argument("--mountpoint",
                        help="The directory to use as mount target")
    parser.add_argument(
        "--encoding",
        help="""The Text Encoding to use for 'open("..","r")' System calls """,
        default=ENCODING,
    )
    parser.add_argument(
        '-l',
        '--load-extensions',
        help='Load the following extensions',
        action='append',
        default=[],
    )

    args = parser.parse_args()
    logging.basicConfig(level=logging.DEBUG)

    ENCODING = args.encoding

    load_extension_list(args.load_extensions)

    mountpoint = args.mountpoint
    use_temp_dir = False
    if mountpoint is None:
        mountpoint = tempfile.mkdtemp(prefix='satori_mnt_')
        use_temp_dir = True

    filename = args.SatoriFile
    image = load_image(filename)
    # print (type(image))
    logger.warn("Mounting Image at: '{}'".format(mountpoint))

    try:
        main_fuse(mountpoint, image)
    finally:
        if use_temp_dir:
            logger.warn("[!] Cleaning up '{}'".format(mountpoint))
            os.rmdir(mountpoint)
示例#6
0
def get_image_context_from_arg(arg, allow_local=True):
    from satoricore.file import load_image

    if arg == '.':
        return dummy_context(os)
    if allow_local:
        try:
            os.stat(arg)
            logger.info("Found to '{}'".format(arg))

            image_path = arg
            source = load_image(image_path)

            if source != None:
                return dummy_context(source)
        except FileNotFoundError:
            logger.error("File '{}' could not be found".format(arg))
            pass

    try:
        import satoriremote
        logger.info("Connecting to '{}'".format(arg))
        conn_context_source, conn_dict = satoriremote.connect(arg)
        logger.warn("Connected to {}".format(conn_dict['host']))
        return conn_context_source
        # with conn_context_source as context:
        #     return context
    except ImportError:
        logger.critical(
            "'satori-remote' package not available, remote paths can't be used"
        )
        sys.exit(-1)
    except ValueError:  # If can't be parsed as regular expression
        logger.critical("'{}' can't be parsed as URI".format(arg))
        sys.exit(-1)
    except ConnectionError:
        logger.critical("Connection failed for path '{}'".format(arg))
        sys.exit(-1)
示例#7
0
def main():

    parser = _setup_argument_parser()
    args = parser.parse_args()

    source_context = get_image_context_from_arg(args.original_image)
    logger.warn("Loaded image '{}'".format(args.original_image))
    destination_context = get_image_context_from_arg(args.tested_image)
    logger.warn("Loaded image '{}'".format(args.tested_image))

    # if not args.output:

    try:
        results = load_image(args.output)

        logger.warn("SatoriImage '{}' loaded to archive results".format(
            args.output))
    except TypeError as te:
        logger.warn("No output image selected")
        logger.info("Using an Empty SatoriImage to store results")
        results = SatoriImage()
    except ValueError:

        logger.error("Output image file '{}' is not a SatoriImage".format(
            args.output))
        logger.warn("Using an Empty SatoriImage to store results".format(
            args.output))
        results = SatoriImage()
    assert (results is not None)

    try:
        logger.info("Adding DIFF section in SatoriImage")
        results.add_section(_DIFFS_SECTION)
    except KeyError:
        logger.warn("DIFF Section in SatoriImage already exists")

    existing_diffs = results.get_classes(_DIFFS_SECTION)
    if existing_diffs:
        logger.info("Existing DIFFs in SatoriImage: {}".format(
            str(existing_diffs)))

    name = get_diff_name(existing_diffs)
    global DIFF_NAME
    DIFF_NAME = name
    logger.warn("New DIFF name is '{}'".format(name))

    with source_context as source:
        with destination_context as destination:
            if not args.entrypoints:
                # s_entrypoints
                try:
                    s_epoints = source.get_entrypoints()
                    logger.info(
                        "Original Image entrypoints: {}".format(s_epoints))
                except:
                    logger.warn("Entrypoints for source cannot be specified.")
                    d_epoints = set('/')

                try:
                    d_epoints = destination.get_entrypoints()
                    logger.info(
                        "Tested Image entrypoints: {}".format(d_epoints))
                except:
                    logger.warn(
                        "Entrypoints for destination cannot be specified.")
                    d_epoints = set('/')

                common_entrypoints = s_epoints & d_epoints
                if not common_entrypoints:
                    logger.critical("No common entrypoints found. Exiting...")
                    sys.exit(-1)
                else:
                    logger.info("Common Entrypoints are {}".format(
                        str(common_entrypoints)))
                    args.entrypoints = common_entrypoints
            logger.warn("Operating for entrypoints: {}".format(
                str(args.entrypoints)))

            EVENTS['differ.on_start'](parser=parser,
                                      args=args,
                                      source=source,
                                      destination=destination,
                                      results=results,
                                      diff_name=DIFF_NAME)
            logger.warn("Diff Process Started...")
            diff_images(source, destination, args.entrypoints, results)

    logger.warn("Diff Process Finished!")

    if not args.output:
        args.output = DIFF_NAME

    image_serializer = SatoriJsoner()
    # image_serializer = SatoriPickler()
    if args.output.endswith(image_serializer.suffix):
        image_serializer.suffix = ''
    image_serializer.write(results, args.output)
    logger.warn("Stored to file '{}'".format(image_serializer.last_file))

    # print(diff_obj)
    # print(results)

    # if args.output:
    # 	pass

    EVENTS['differ.on_end'](results)