def test_pidfile_exists_true(): set_cwd(tempfile.mkdtemp()) cuckoo_create() p = Pidfile("test4") p.create() assert p.exists() and p.pid == os.getpid()
def test_proc_exists(): assert Pidfile("hello").proc_exists(os.getpid()) # Chances are possible, but slim. assert not Pidfile("hello").proc_exists(13337) assert not Pidfile("hello)").proc_exists(None) assert not Pidfile("hello)").proc_exists("")
def test_active_pids(): set_cwd(tempfile.mkdtemp()) cuckoo_create() Pidfile("test6").create() assert Pidfile.get_active_pids() == { "test6": os.getpid(), }
def test_remove_pidfile(): set_cwd(tempfile.mkdtemp()) cuckoo_create() Pidfile("test2").create() assert os.path.exists(cwd("pidfiles", "test2.pid")) Pidfile("test2").remove() assert not os.path.exists(cwd("pidfiles", "test2.pid"))
def test_pidfile_none(): set_cwd(tempfile.mkdtemp()) cuckoo_create() p = Pidfile("test5") p.create() open(cwd("pidfiles", "test5.pid"), "wb").write("notapid") assert p.read() is None
def process(ctx, instance, report, maxcount): """Process raw task data into reports.""" init_console_logging(level=ctx.parent.level) if instance: pidfile = Pidfile(instance) if pidfile.exists(): log.error(red( "Cuckoo process instance '%s' already exists. PID: %s\n" ), instance, pidfile.pid) sys.exit(1) pidfile.create() init_logfile("process-%s.json" % instance) Database().connect() # Load additional Signatures. load_signatures() try: # Initialize all modules & Yara rules. init_modules() init_yara() except CuckooCriticalError as e: message = red("{0}: {1}".format(e.__class__.__name__, e)) if len(log.handlers): log.critical(message) else: sys.stderr.write("{0}\n".format(message)) sys.exit(1) try: # Regenerate one or more reports. if report: process_task_range(report) elif not instance: print ctx.get_help(), "\n" sys.exit("In automated mode an instance name is required!") else: log.info( "Initialized instance=%s, ready to process some tasks", instance ) process_tasks(instance, maxcount) except KeyboardInterrupt: print(red("Aborting (re-)processing of your analyses..")) if instance: Pidfile(instance).remove()
def cuckoo_main(max_analysis_count=0): """Cuckoo main loop. @param max_analysis_count: kill cuckoo after this number of analyses """ rs, sched = None, None def stop(): if sched: sched.running = False if rs: rs.instance.stop() Pidfile("cuckoo").remove() if sched: sched.stop() def handle_sigterm(sig, f): stop() # Handle a SIGTERM, to reduce the chance of Cuckoo exiting without # cleaning signal.signal(signal.SIGTERM, handle_sigterm) try: rs = ResultServer() sched = Scheduler(max_analysis_count) sched.start() except KeyboardInterrupt: log.info("CTRL+C detected! Stopping.. This can take a few seconds") finally: if Pidfile("cuckoo").exists(): stop()
def stop(): if sched: sched.running = False if rs: rs.instance.stop() Pidfile("cuckoo").remove() if sched: sched.stop()
def cuckoo_main(max_analysis_count=0): """Cuckoo main loop. @param max_analysis_count: kill cuckoo after this number of analyses """ try: ResultServer() sched = Scheduler(max_analysis_count) sched.start() except KeyboardInterrupt: sched.stop() Pidfile("cuckoo").remove()
def cuckoo_status(): # In order to keep track of the diskspace statistics of the temporary # directory we create a temporary file so we can statvfs() on that. temp_file = Files.temp_put("") paths = dict( binaries=cwd("storage", "binaries"), analyses=cwd("storage", "analyses"), temporary=temp_file, ) diskspace = {} for key, path in paths.items(): if hasattr(os, "statvfs") and os.path.isdir(path): stats = os.statvfs(path) diskspace[key] = dict( free=stats.f_bavail * stats.f_frsize, total=stats.f_blocks * stats.f_frsize, used=(stats.f_blocks - stats.f_bavail) * stats.f_frsize, ) # Now we remove the temporary file and its parent directory. os.unlink(temp_file) # Get the CPU load. if hasattr(os, "getloadavg"): cpuload = os.getloadavg() else: cpuload = [] if os.path.isfile("/proc/meminfo"): values = {} for line in open("/proc/meminfo"): key, value = line.split(":", 1) values[key.strip()] = value.replace("kB", "").strip() if "MemAvailable" in values and "MemTotal" in values: memavail = int(values["MemAvailable"]) memtotal = int(values["MemTotal"]) memory = 100 - 100.0 * memavail / memtotal else: memory = memavail = memtotal = None else: memory = memavail = memtotal = None try: cpu_core_count = multiprocessing.cpu_count() except NotImplementedError: cpu_core_count = None response = dict(version=version, hostname=socket.gethostname(), machines=dict(total=len(db.list_machines()), available=db.count_machines_available()), tasks=dict(total=db.count_tasks(), pending=db.count_tasks("pending"), running=db.count_tasks("running"), completed=db.count_tasks("completed"), reported=db.count_tasks("reported")), diskspace=diskspace, cpuload=cpuload, cpu_count=cpu_core_count, memory=memory, memavail=memavail, memtotal=memtotal, processes=Pidfile.get_active_pids()) return jsonify(response)
def cuckoo_status(): # In order to keep track of the diskspace statistics of the temporary # directory we create a temporary file so we can statvfs() on that. temp_file = Files.temp_put("") paths = dict( binaries=cwd("storage", "binaries"), analyses=cwd("storage", "analyses"), temporary=temp_file, ) diskspace = {} for key, path in paths.items(): if hasattr(os, "statvfs") and os.path.isdir(path): stats = os.statvfs(path) diskspace[key] = dict( free=stats.f_bavail * stats.f_frsize, total=stats.f_blocks * stats.f_frsize, used=(stats.f_blocks - stats.f_bavail) * stats.f_frsize, ) # Now we remove the temporary file and its parent directory. os.unlink(temp_file) # Get the CPU load. if hasattr(os, "getloadavg"): cpuload = os.getloadavg() else: cpuload = [] if os.path.isfile("/proc/meminfo"): values = {} for line in open("/proc/meminfo"): key, value = line.split(":", 1) values[key.strip()] = value.replace("kB", "").strip() if "MemAvailable" in values and "MemTotal" in values: memavail = int(values["MemAvailable"]) memtotal = int(values["MemTotal"]) memory = 100 - 100.0 * memavail / memtotal else: memory = memavail = memtotal = None else: memory = memavail = memtotal = None try: cpu_core_count = multiprocessing.cpu_count() except NotImplementedError: cpu_core_count = None response = dict( version=version, hostname=socket.gethostname(), machines=dict( total=len(db.list_machines()), available=db.count_machines_available() ), tasks=dict( total=db.count_tasks(), pending=db.count_tasks("pending"), running=db.count_tasks("running"), completed=db.count_tasks("completed"), reported=db.count_tasks("reported") ), diskspace=diskspace, cpuload=cpuload, cpu_count=cpu_core_count, memory=memory, memavail=memavail, memtotal=memtotal, processes=Pidfile.get_active_pids() ) return jsonify(response)
def cuckoo_init(level, ctx, cfg=None): """Initialize Cuckoo configuration. @param quiet: enable quiet mode. """ logo() # It would appear this is the first time Cuckoo is being run (on this # Cuckoo Working Directory anyway). if not os.path.isdir(cwd()) or not os.listdir(cwd()): cuckoo_create(ctx.user, cfg) sys.exit(0) # Determine if this is a proper CWD. if not os.path.exists(cwd(".cwd")): sys.exit( "No proper Cuckoo Working Directory was identified, did you pass " "along the correct directory? For new installations please use a " "non-existant directory to build up the CWD! You can craft a CWD " "manually, but keep in mind that the CWD layout may change along " "with Cuckoo releases (and don't forget to fill out '$CWD/.cwd')!" ) init_console_logging(level) # Only one Cuckoo process should exist per CWD. Run this check before any # files are possibly modified. Note that we mkdir $CWD/pidfiles/ here as # its CWD migration rules only kick in after the pidfile check. mkdir(cwd("pidfiles")) pidfile = Pidfile("cuckoo") if pidfile.exists(): log.error(red("Cuckoo is already running. PID: %s"), pidfile.pid) sys.exit(1) pidfile.create() check_configs() check_version() ctx.log and init_logging(level) # Determine if any CWD updates are required and if so, do them. current = open(cwd(".cwd"), "rb").read().strip() latest = open(cwd(".cwd", private=True), "rb").read().strip() if current != latest: migrate_cwd() open(cwd(".cwd"), "wb").write(latest) Database().connect() # Load additional Signatures. load_signatures() init_modules() init_tasks() init_yara() init_binaries() init_rooter() init_routing() signatures = 0 for sig in cuckoo.signatures: if not sig.enabled: continue signatures += 1 if not signatures: log.warning( "It appears that you haven't loaded any Cuckoo Signatures. " "Signatures are highly recommended and improve & enrich the " "information extracted during an analysis. They also make up " "for the analysis score that you see in the Web Interface - so, " "pretty important!" ) log.warning( "You'll be able to fetch all the latest Cuckoo Signaturs, Yara " "rules, and more goodies by running the following command:" ) raw = cwd(raw=True) if raw == "." or raw == "~/.cuckoo": command = "cuckoo community" elif " " in raw or "'" in raw: command = 'cuckoo --cwd "%s" community' % raw else: command = "cuckoo --cwd %s community" % raw log.info("$ %s", green(command))
def cuckoo_init(level, ctx, cfg=None): """Initialize Cuckoo configuration. @param quiet: enable quiet mode. """ logo() # It would appear this is the first time Cuckoo is being run (on this # Cuckoo Working Directory anyway). if not os.path.isdir(cwd()) or not os.listdir(cwd()): cuckoo_create(ctx.user, cfg) sys.exit(0) # Determine if this is a proper CWD. if not os.path.exists(cwd(".cwd")): sys.exit( "No proper Cuckoo Working Directory was identified, did you pass " "along the correct directory? For new installations please use a " "non-existant directory to build up the CWD! You can craft a CWD " "manually, but keep in mind that the CWD layout may change along " "with Cuckoo releases (and don't forget to fill out '$CWD/.cwd')!") init_console_logging(level) # Only one Cuckoo process should exist per CWD. Run this check before any # files are possibly modified. Note that we mkdir $CWD/pidfiles/ here as # its CWD migration rules only kick in after the pidfile check. mkdir(cwd("pidfiles")) pidfile = Pidfile("cuckoo") if pidfile.exists(): log.error(red("Cuckoo is already running. PID: %s"), pidfile.pid) sys.exit(1) pidfile.create() check_configs() check_version() ctx.log and init_logging(level) # Determine if any CWD updates are required and if so, do them. current = open(cwd(".cwd"), "rb").read().strip() latest = open(cwd(".cwd", private=True), "rb").read().strip() if current != latest: migrate_cwd() open(cwd(".cwd"), "wb").write(latest) # Ensure the user is able to create and read temporary files. if not ensure_tmpdir(): sys.exit(1) Database().connect() # Load additional Signatures. load_signatures() init_modules() init_tasks() init_yara() init_binaries() init_rooter() init_routing() signatures = 0 for sig in cuckoo.signatures: if not sig.enabled: continue signatures += 1 if not signatures: log.warning( "It appears that you haven't loaded any Cuckoo Signatures. " "Signatures are highly recommended and improve & enrich the " "information extracted during an analysis. They also make up " "for the analysis score that you see in the Web Interface - so, " "pretty important!") log.warning( "You'll be able to fetch all the latest Cuckoo Signaturs, Yara " "rules, and more goodies by running the following command:") log.info("$ %s", green(format_command("community")))
def test_create_pidfile(): set_cwd(tempfile.mkdtemp()) cuckoo_create() Pidfile("test1").create() assert int(open(cwd("pidfiles", "test1.pid"), "rb").read()) == os.getpid()
def test_pidfile_exists_false(): set_cwd(tempfile.mkdtemp()) cuckoo_create() assert not Pidfile("test3").exists()
def test_pid_exists_unsupported_platform(p): p.platform = "DogeOS" assert Pidfile("hello").proc_exists(os.getpid()) is None