def archive_scan(archive, scan_type, f_name, arc_type): """ Scans each file in an archive. This function take advantage of the fact that the tarfile and zipfile Python packages have identical method names. 04/25/2014: Added a SHA-1 checksum generating "scanner" to this method """ arc_scan = False if not f_name: sys.stderr.write("ERROR: Must specify an output file") archive.close() exit(1) else: f = open(f_name, 'w') if arc_type: if arc_type == "t": arc_scan = archive.getnames() elif arc_type == "z": arc_scan = archive.namelist() for name in arc_scan: path = paths.TEMP_ARCHIVE_UNPACK_PATH + "/" + name #Scan types can be n (Ninka) or f (FOSSology) if scan_type is 'n': f.write(str(ninka_scan(path))) elif scan_type is 'f': f.write(str(foss_scan(path))) elif scan_type is 'c': #checksum now included #make sure it's not a directory #(dirs cause the SHA-1 reader to die) if not os.path.isdir(path): checksumstr = str(name) + ";" + str(_hash_file(path)) checksumstr += "\n" else: checksumstr = str(name) + ";" + "ERROR" + "\n" f.write(checksumstr)
def run_scans(target, opts): verbose = False #Checks to see if any options are activated if opts: if opts == "-v": verbose = True """ Runs both FOSSology and Ninka on a given file or package. """ #print("Creating directories needed for the scanners to work") """ Checks to see if the paths we need are there If they are not, it creates them (the archive path is meant for destruction, so it is assumed that it should not be there unless something went wrong) """ if not os.path.isdir(paths.SCANNER_OUTPUT_PATH): subprocess.call(["mkdir", paths.SCANNER_OUTPUT_PATH]) if not os.path.isdir(paths.TEMP_ARCHIVE_UNPACK_PATH): subprocess.call(["mkdir", paths.TEMP_ARCHIVE_UNPACK_PATH]) else: subprocess.call(["rm", paths.TEMP_ARCHIVE_UNPACK_PATH + "/*.*"]) #TODO: Find a way to get the rm dir/*.* function to work... #To ensure the absolute path is not a part of the output file name out_name = get_file_from_absolute_path(target) ninka_out = paths.SCANNER_OUTPUT_PATH + "/" ninka_out += out_name + ".N_out.txt" check_file(ninka_out) foss_out = paths.SCANNER_OUTPUT_PATH + "/" foss_out += out_name + ".F_out.txt" check_file(foss_out) checksum_out = paths.SCANNER_OUTPUT_PATH + "/" checksum_out += out_name + ".SHA-1.txt" if verbose: print("Checking file format") if tarfile.is_tarfile(target): if verbose: print(target + " identified as TAR file") archive = tarfile.open(target) if verbose: print("Extracting data") archive.extractall(paths.TEMP_ARCHIVE_UNPACK_PATH) if verbose: print("Generating SHA-1 checksum(s)") archive_scan(archive, 'c', checksum_out, "t") if verbose: print("Checksum(s) generated") print("Starting Ninka scan") archive_scan(archive, 'n', ninka_out, "t") if verbose: print("Ninka scan finished") print("Starting FOSSology scan") archive_scan(archive, 'f', foss_out, "t") if verbose: print("FOSSology scan finished") archive.close() #This is the same as the tarfile method but with zipfile elif zipfile.is_zipfile(target): if verbose: print(target + " identified as ZIP file") #archive = zipfile.open(target) archive = zipfile.ZipFile(target, "r") if verbose: print("Extracting data") archive.extractall(paths.TEMP_ARCHIVE_UNPACK_PATH) if verbose: print("Generating SHA-1 checksum(s)") archive_scan(archive, 'c', checksum_out, "z") if verbose: print("Checksum(s) generated") print("Starting Ninka scan") archive_scan(archive,'n', ninka_out, "z") if verbose: print("Ninka scan finished") print("Starting FOSSology scan") archive_scan(archive,'f', foss_out, "z") if verbose: print("FOSSology scan finished") archive.close() else: #assumes a single file if verbose: print("File is either not an archive or an unrecognized format;" " scanning as single file") path = paths.TEMP_ARCHIVE_UNPACK_PATH + "/" + out_name subprocess.call(["cp", target, paths.TEMP_ARCHIVE_UNPACK_PATH]) #first we find the SHA-1 checksum c_file = open(checksum_out, 'wb') if verbose: print("Generating SHA-1 checksum(s)") checksumstr = str(out_name) + ";" + str(_hash_file(path)) c_file.write(checksumstr) if verbose: print("Checksum(s) Generated") c_file.close() #next with Ninka n_file = open(ninka_out, 'wb') if verbose: print("Starting Ninka scan") n_file.write(ninka_scan(path)) if verbose: print("Ninka scan fnished") n_file.close() #next with FOSSology f_file = open(foss_out, 'w') if verbose: print("Starting FOSSology scan") f_file.write(foss_scan(path)) if verbose: print("FOSSology scan finished") f_file.close() """