예제 #1
0
def modules():
    '''
    Return a list of module names available for MultiScanner to use,
    and whether or not they are enabled in the config.
    '''
    files = multiscanner.parseDir(multiscanner.MODULEDIR, True)
    filenames = [os.path.splitext(os.path.basename(f)) for f in files]
    module_names = [m[0] for m in filenames if m[1] == '.py']

    ms_config = configparser.SafeConfigParser()
    ms_config.optionxform = str
    ms_config.read(multiscanner.CONFIG)
    modules = {}
    for module in module_names:
        try:
            modules[module] = ms_config.get(module, 'ENABLED')
        except (configparser.NoSectionError, configparser.NoOptionError):
            pass
    return jsonify({'Modules': modules})
예제 #2
0
def create_task():
    '''
    Create a new task for a submitted file. Save the submitted file to
    UPLOAD_FOLDER, optionally unzipping it. Return task id and 201 status.
    '''
    file_ = request.files['file']
    if request.form.get('upload_type', None) == 'import':
        try:
            task_id = import_task(file_)
        except KeyError:
            return make_response(
                jsonify({'Message': 'Cannot import report missing \'Scan Time\' field!'}),
                HTTP_BAD_REQUEST)
        except InvalidScanTimeFormatError:
            return make_response(
                jsonify({'Message': 'Cannot import report with \'Scan Time\' of invalid format!'}),
                HTTP_BAD_REQUEST)
        except (UnicodeDecodeError, ValueError):
            return make_response(
                jsonify({'Message': 'Cannot import non-JSON files!'}),
                HTTP_BAD_REQUEST)

        return make_response(
            jsonify({'Message': {'task_ids': [task_id]}}),
            HTTP_CREATED
        )

    original_filename = file_.filename

    metadata = {}
    task_id_list = []
    extract_dir = None
    rescan = False
    for key in request.form.keys():
        if key in ['file_id', 'archive-password', 'upload_type'] or request.form[key] == '':
            continue
        elif key == 'duplicate':
            if request.form[key] == 'latest':
                rescan = False
            elif request.form[key] == 'rescan':
                rescan = True
        elif key == 'modules':
            module_names = request.form[key]
            files = multiscanner.parseDir(multiscanner.MODULEDIR, True)
            modules = []
            for f in files:
                split = os.path.splitext(os.path.basename(f))
                if split[0] in module_names and split[1] == '.py':
                    modules.append(f)
        elif key == 'archive-analyze' and request.form[key] == 'true':
            extract_dir = api_config['api']['upload_folder']
            if not os.path.isdir(extract_dir):
                return make_response(
                    jsonify({'Message': "'upload_folder' in API config is not "
                             "a valid folder!"}),
                    HTTP_BAD_REQUEST)

            # Get password if present
            if 'archive-password' in request.form:
                password = request.form['archive-password']
                if PY3:
                    password = bytes(password, 'utf-8')
            else:
                password = ''
        else:
            metadata[key] = request.form[key]

    if extract_dir:
        # Extract a zip
        if zipfile.is_zipfile(file_):
            z = zipfile.ZipFile(file_)
            try:
                # NOTE: zipfile module prior to Py 2.7.4 is insecure!
                # https://docs.python.org/2/library/zipfile.html#zipfile.ZipFile.extract
                z.extractall(path=extract_dir, pwd=password)
                for uzfile in z.namelist():
                    unzipped_file = open(os.path.join(extract_dir, uzfile))
                    f_name, full_path = save_hashed_filename(unzipped_file, True)
                    tid = queue_task(uzfile, f_name, full_path, metadata, rescan=rescan)
                    task_id_list.append(tid)
            except RuntimeError as e:
                msg = "ERROR: Failed to extract " + str(file_) + ' - ' + str(e)
                return make_response(
                    jsonify({'Message': msg}),
                    HTTP_BAD_REQUEST)
        # Extract a rar
        elif rarfile.is_rarfile(file_):
            r = rarfile.RarFile(file_)
            try:
                r.extractall(path=extract_dir, pwd=password)
                for urfile in r.namelist():
                    unrarred_file = open(os.path.join(extract_dir, urfile))
                    f_name, full_path = save_hashed_filename(unrarred_file, True)
                    tid = queue_task(urfile, f_name, full_path, metadata, rescan=rescan)
                    task_id_list.append(tid)
            except RuntimeError as e:
                msg = "ERROR: Failed to extract " + str(file_) + ' - ' + str(e)
                return make_response(
                    jsonify({'Message': msg}),
                    HTTP_BAD_REQUEST)
    else:
        # File was not an archive to extract
        f_name, full_path = save_hashed_filename(file_)
        tid = queue_task(original_filename, f_name, full_path, metadata, rescan=rescan)
        task_id_list = [tid]

    msg = {'task_ids': task_id_list}
    return make_response(
        jsonify({'Message': msg}),
        HTTP_CREATED
    )