import datetime import glob import shutil import subprocess from os import chdir, devnull, unlink from os.path import isdir, isfile import celery.log from celery.decorators import task @task(ignore_result=True) def purge_data(asset_path, owner_id): logger = celery.log.LoggingProxy(celery.log.get_default_logger()) logger.write("PURGE For User %s | Path: %s" % (owner_id, asset_path)) if isdir(asset_path): shutil.rmtree(asset_path, False, None) else: for f in glob.glob(asset_path + "*"): try: unlink(f) except: pass @task(ignore_result=True) def run_scan(name_base, workdir, scan_id, owner_id, result_id, cmd): logger = celery.log.LoggingProxy(celery.log.get_default_logger()) chdir(workdir) logger.write("BEGIN Scan %s | User %s\ncmd: %s" % (scan_id, owner_id, cmd)) status_nmap = subprocess.call(["nmap"] + cmd.split(), stdout=open(devnull)) logger.write("END Scan %s | User %s\nstatus: %d" % (scan_id, owner_id, status_nmap)) finished_ok = (status_nmap == 0) # try to save output. even for errors, we might see what happened if isfile(name_base + ".xml"): logger.write("XSLT Scan %s | User %s" % (scan_id, owner_id)) status_xslt = subprocess.call(["xsltproc", name_base + ".xml", "-o", name_base + ".html"]) # html and xml are the most important outputs, so we only track those if status_xslt == 0: output = name_base + ".html" else: output = name_base + ".xml" else: output = None finished_ok = False # well, no output *is* an error process_result.delay(result_id, finished_ok, output) @task(ignore_result=True) def process_result(result_id, finished_ok, output): from django.contrib.sites.models import Site from django.core.urlresolvers import reverse from django.template.loader import render_to_string from core.models import ScanResult result = ScanResult.objects.get(id=result_id) scan = result.for_scan result.finished_ok = finished_ok if output: result.output = output result.finished_on = datetime.datetime.now() result.save() if scan.owner.userprofile.mail_results_all or ( scan.owner.userprofile.mail_results_err and not result.finished_ok): if result.output: link = 'http://%s%s' % (Site.objects.get_current().domain, reverse('core_result_view', args=[result_id])) else: link = None profile_link = 'http://%s%s' % (Site.objects.get_current().domain, reverse('user_profile')) ctx_dict = { 'link': link, 'scan_name': scan.name, 'profile_link': profile_link, } if result.finished_ok and scan.owner.userprofile.mail_results_all: subj = render_to_string('core/email_results_subject_success.txt', ctx_dict) body = render_to_string('core/email_results_success.txt', ctx_dict) else: subj = render_to_string('core/email_results_subject_error.txt', ctx_dict) body = render_to_string('core/email_results_error.txt', ctx_dict) subj = ''.join(subj.splitlines()) result.for_scan.owner.email_user(subj, body, 'scanbot@rainmap.org')