def get_addresses(maildir): emails = {} for root, _dirs, files in os.walk(maildir): for fname in files: fname = os.path.join(root, fname) msg = HeaderParser().parse(open(fname)) froms = msg.get_all('from', []) tos = msg.get_all('to', []) ccs = msg.get_all('cc', []) resent_tos = msg.get_all('resent-to', []) resent_ccs = msg.get_all('resent-cc', []) all_recipients = getaddresses(froms + tos + ccs + resent_tos + resent_ccs) for (title, addr) in all_recipients: emails.setdefault(addr, set()).add(title) for addr, titles in emails.iteritems(): clean = set() for title in titles: if title.startswith('=?'): title = dheader(title) title = title.strip("'\"<>").replace('\n', ' ') if title and title != addr: clean.add(title) if clean: for title in clean: yield addr, title else: yield addr, ''
def __emailRawSmtp(self, data): msg = HeaderParser().parsestr(data["rawSmtp"]) emailFrom = msg.get('from') emailTo = msg.get_all('to') if not emailTo: emailTo = [] emailCc = msg.get_all('cc') if not emailCc: emailCc = [] emailBcc = msg.get_all('bcc') if not emailBcc: emailBcc = [] msg = data["rawSmtp"].encode("utf8") return self.__sendSmtp(msg, emailFrom, emailTo + emailCc + emailBcc)
def generate_report(header): r = {} n = HeaderParser().parsestr(header.strip()) graph = [] received = n.get_all('Received') if received: received = [i for i in received if ('from' in i or 'by' in i)] else: received = re.findall('Received:\s*(.*?)\n\S+:\s+', mail_data, re.X | re.DOTALL | re.I) pprint.pprint(received) exit(1) c = len(received) for i in range(len(received)): if ';' in received[i]: line = received[i].split(';') else: line = received[i].split('\r\n') line = list(map(str.strip, line)) line = [x.replace('\r\n', ' ') for x in line] try: if ';' in received[i + 1]: next_line = received[i + 1].split(';') else: next_line = received[i + 1].split('\r\n') next_line = list(map(str.strip, next_line)) next_line = [x.replace('\r\n', '') for x in next_line] except IndexError: next_line = None org_time = dateParser(line[-1]) if not next_line: next_time = org_time else: next_time = dateParser(next_line[-1]) if line[0].startswith('from'): data = re.findall( """ from\s+ (.*?)\s+ by(.*?) (?: (?:with|via) (.*?) (?:\sid\s|$) |\sid\s|$ )""", line[0], re.DOTALL | re.X) else: data = re.findall( """ ()by (.*?) (?: (?:with|via) (.*?) (?:\sid\s|$) |\sid\s )""", line[0], re.DOTALL | re.X) delay = (org_time - next_time).seconds if delay < 0: delay = 0 try: ftime = org_time.utctimetuple() ftime = time.strftime('%m/%d/%Y %I:%M:%S %p', ftime) r[c] = { 'Timestmp': org_time, 'Time': ftime, 'Delay': delay, 'Direction': [x.replace('\n', ' ') for x in list(map(str.strip, data[0]))] } c -= 1 except IndexError: pass for i in list(r.values()): if i['Direction'][0]: graph.append(["From: %s" % i['Direction'][0], i['Delay']]) else: graph.append(["By: %s" % i['Direction'][1], i['Delay']]) totalDelay = sum([x['Delay'] for x in list(r.values())]) fTotalDelay = mha_tags.duration(totalDelay) delayed = True if totalDelay else False custom_style = Style( background='transparent', plot_background='transparent', font_family='googlefont:Open Sans', # title_font_size=12, ) line_chart = pygal.HorizontalBar(style=custom_style, height=250, legend_at_bottom=True, tooltip_border_radius=10) line_chart.tooltip_fancy_mode = False line_chart.title = 'Total Delay is: %s' % fTotalDelay line_chart.x_title = 'Delay in seconds.' for i in graph: line_chart.add(i[0], i[1]) chart = line_chart.render(is_unicode=True) summary = { 'From': n.get('From') or getHeaderVal('from', mail_data), 'To': n.get('to') or getHeaderVal('to', mail_data), 'Cc': n.get('cc') or getHeaderVal('cc', mail_data), 'Subject': n.get('Subject') or getHeaderVal('Subject', mail_data), 'MessageID': n.get('Message-ID') or getHeaderVal('Message-ID', mail_data), 'Date': n.get('Date') or getHeaderVal('Date', mail_data), } security_headers = [ 'Received-SPF', 'Authentication-Results', 'DKIM-Signature', 'ARC-Authentication-Results' ] context = { 'data': r, 'delayed': delayed, 'summary': summary, 'n': n, 'chart': chart, 'security_headers': security_headers }
def index(): if request.method == 'POST': with open('freemail') as f: emailFree = [line.rstrip() for line in f] lista_IP = [] mail_data = request.form['headers'].strip() r = {} n = HeaderParser().parsestr(mail_data) graph = [] iP_Analizado = [] received = n.get_all('Received') if received: received = [i for i in received if ('from' in i or 'by' in i)] else: received = re.findall('Received:\s*(.*?)\n\S+:\s+', mail_data, re.X | re.DOTALL | re.I) c = len(received) for i in range(len(received)): if ';' in received[i]: line = received[i].split(';') else: line = received[i].split('\r\n') line = list(map(str.strip, line)) line = [x.replace('\r\n', ' ') for x in line] try: if ';' in received[i + 1]: next_line = received[i + 1].split(';') else: next_line = received[i + 1].split('\r\n') next_line = list(map(str.strip, next_line)) next_line = [x.replace('\r\n', '') for x in next_line] except IndexError: next_line = None org_time = dateParser(line[-1]) if not next_line: next_time = org_time else: next_time = dateParser(next_line[-1]) if line[0].startswith('from'): data = re.findall( """ from\s+ (.*?)\s+ by(.*?) (?: (?:with|via) (.*?) (?:\sid\s|$) |\sid\s|$ )""", line[0], re.DOTALL | re.X) tmp_lista_IP = re.findall( r"\[(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\]", line[0], re.X) for x in range(len(tmp_lista_IP)): lista_IP.append(tmp_lista_IP[x]) else: data = re.findall( """ ()by (.*?) (?: (?:with|via) (.*?) (?:\sid\s|$) |\sid\s )""", line[0], re.DOTALL | re.X) delay = (org_time - next_time).seconds if delay <= 0: delay = 1 try: ftime = org_time.utctimetuple() ftime = time.strftime('%m/%d/%Y %I:%M:%S %p', ftime) r[c] = { 'Timestmp': org_time, 'Time': ftime, 'Delay': delay, 'Direction': [ x.replace('\n', ' ') for x in list(map(str.strip, data[0])) ] } c -= 1 except IndexError: pass for i in list(r.values()): if i['Direction'][0]: graph.append(["From: %s" % i['Direction'][0], i['Delay']]) else: graph.append(["By: %s" % i['Direction'][1], i['Delay']]) totalDelay = sum([x['Delay'] for x in list(r.values())]) fTotalDelay = utility_processor()['duration'](totalDelay) delayed = True if totalDelay else False custom_style = Style( background='transparent', plot_background='transparent', font_family='googlefont:Open Sans', # title_font_size=12, ) line_chart = pygal.HorizontalBar(style=custom_style, height=250, legend_at_bottom=True, tooltip_border_radius=10) line_chart.tooltip_fancy_mode = False line_chart.title = 'Tiempo total: %s' % fTotalDelay line_chart.x_title = 'Tiempo en segundos.' for i in graph: line_chart.add(i[0], i[1]) chart = line_chart.render(is_unicode=True) summary = { 'From': n.get('From') or getHeaderVal('from', mail_data), 'To': n.get('to') or getHeaderVal('to', mail_data), 'Cc': n.get('cc') or getHeaderVal('cc', mail_data), 'Subject': n.get('Subject') or getHeaderVal('Subject', mail_data), 'MessageID': n.get('Message-ID') or getHeaderVal('Message-ID', mail_data), 'Date': n.get('Date') or getHeaderVal('Date', mail_data), 'Return': n.get('Return-Path') or getHeaderVal('Return-Path', mail_data), } security_headers = [ 'Received-SPF', 'Authentication-Results', 'DKIM-Signature', 'ARC-Authentication-Results' ] for x in range(len(lista_IP)): web = 'http://ipinfo.io/' + lista_IP[x] + '/json' with urllib.request.urlopen(web) as url: datos_ip = json.loads(url.read().decode()) if (('hostname' not in datos_ip)): datos_ip['hostname'] = 'Desconocido' if (('city' not in datos_ip)): datos_ip['city'] = 'Desconocida' if (('region' not in datos_ip)): datos_ip['region'] = 'Desconocida' if (('country' not in datos_ip)): datos_ip['country'] = 'Desconocido' if (('loc' not in datos_ip)): datos_ip['loc'] = '0,0' if (('org' not in datos_ip)): datos_ip['org'] = 'Desconocida' if (('postal' not in datos_ip)): datos_ip['postal'] = '0' iP_Analizado.append( Address(lista_IP[x], datos_ip['hostname'], datos_ip['city'], datos_ip['region'], datos_ip['country'], datos_ip['loc'], datos_ip['org'], datos_ip['postal'])) try: email = n.get('From') or getHeaderVal('from', mail_data) d = email.split('@')[1].replace(">", "") if d in emailFree: summary['tipo'] = ' ( CUIDADO CORREO GRATUITO )' else: summary['tipo'] = 'Correo electronico normal' w = whois.query(d, ignore_returncode=1) if w: wd = w.__dict__ for k, v in wd.items(): summary[k] = v # SE RELLENAN LOS DATOS DE WHOIS __DICT__ if k == 'creation_date': fecha = datetime.today() - v meses = round(fecha.days / 60) if meses < 12: summary['diff'] = ' ( PELIGRO ' + str( meses) + ' MESES DE VIDA!!!! )' else: any = round(meses / 12) summary['diff'] = str(any) + ' Años' except Exception as e: print(e) summary['name'] = 'ERROR AL BUSCAR' summary['creation_date'] = 'ERROR AL BUSCAR' summary['last_updated'] = 'ERROR AL BUSCAR' summary['expiration_date'] = 'ERROR AL BUSCAR' summary['name_servers'] = 'ERROR AL BUSCAR' analiza = n.get('Authentication-Results') or getHeaderVal( 'Authentication-Results', mail_data) puntuacion = 0 if analiza.find('spf=pass') >= 0: summary['SPF'] = 'OK.' puntuacion += 1 else: if analiza.find('spf=') >= 0: summary['SPF'] = 'PELIGRO !!!!!! ( MUCHO CUIDADO )' puntuacion -= 2 else: summary[ 'SPF'] = ' SIN SEGURIDAD ( REVISA QUE EL EL ORIGEN Y A DONDE SE RETORNA EL MAIL )' if analiza.find('dkim=pass') >= 0: summary['DKIM'] = 'OK.' puntuacion += 1 else: if analiza.find('dkim=') >= 0: summary['DKIM'] = 'PELIGRO !!!!!! ( MUCHO CUIDADO )' puntuacion -= 2 else: summary[ 'DKIM'] = ' SIN SEGURIDAD ( REVISA QUE EL EL ORIGEN Y A DONDE SE RETORNA EL MAIL )' if analiza.find('dmarc=pass') >= 0: summary['DMARC'] = 'OK.' puntuacion += 1 else: if analiza.find('dmarc=') >= 0: summary['DMARC'] = 'PELIGRO !!!!!! ( MUCHO CUIDADO )' puntuacion -= 2 else: summary[ 'DMARC'] = ' SIN SEGURIDAD ( REVISA QUE EL EL ORIGEN Y A DONDE SE RETORNA EL MAIL )' summary['resultado_seguridad'] = str(round( (puntuacion / 3) * 100, 2)) + '%' return render_template('index.html', data=r, delayed=delayed, summary=summary, n=n, chart=chart, security_headers=security_headers, iP_Analizado=iP_Analizado) else: return render_template('index.html')
# intended to be called from a MUA binding from config import non_VIPs, VIPs, ADDRESS_FILE, VIPS_FILE def confirm(msg): return raw_input("{} [Y/n] ".format(msg)).strip().lower() in ['y', ''] if __name__ == '__main__': # backup json [shutil.copyfile(f, f + ".bak") for f in [ADDRESS_FILE, VIPS_FILE] ] message = HeaderParser().parse(sys.stdin, headersonly=True) ffroms = message.get_all('from', []) #ccs = message.get_all('cc', []) #addrs = getaddresses(ffroms + ccs) addrs = getaddresses(ffroms) # reset STDIN handle sys.stdin = open("/dev/tty") for name, addr in addrs: addr = addr.lower() try: _ = VIPs[addr] print ("key exists: {} -> @vip".format( addr )) continue except KeyError: pass
def index(): if request.method == 'POST': mail_data = request.form['headers'].strip().encode('ascii', 'ignore').decode() r = {} n = HeaderParser().parsestr(mail_data) graph = [] received = n.get_all('Received') if received: received = [i for i in received if ('from' in i or 'by' in i)] else: received = re.findall('Received:\s*(.*?)\n\S+:\s+', mail_data, re.X | re.DOTALL | re.I) c = len(received) for i in range(len(received)): if ';' in received[i]: line = received[i].split(';') else: line = received[i].split('\r\n') line = list(map(str.strip, line)) line = list(map(lambda x: x.replace('\r\n', ' '), line)) try: if ';' in received[i + 1]: next_line = received[i + 1].split(';') else: next_line = received[i + 1].split('\r\n') next_line = list(map(str.strip, next_line)) next_line = list( map(lambda x: x.replace('\r\n', ''), next_line)) except IndexError: next_line = None org_time = dateParser(line[-1]) if not next_line: next_time = org_time else: next_time = dateParser(next_line[-1]) if line[0].startswith('from'): data = re.findall( """ from\s+ (.*?)\s+ by(.*?) (?: (?:with|via) (.*?) (?:\sid\s|$) |\sid\s|$ )""", line[0], re.DOTALL | re.X) else: data = re.findall( """ ()by (.*?) (?: (?:with|via) (.*?) (?:\sid\s|$) |\sid\s )""", line[0], re.DOTALL | re.X) # import ipdb; ipdb.set_trace() delay = (org_time - next_time).seconds if delay < 0: delay = 0 try: ftime = org_time.utctimetuple() ftime = time.strftime('%m/%d/%Y %I:%M:%S %p', ftime) r[c] = { 'Timestmp': org_time, 'Time': ftime, 'Delay': delay, 'Direction': list( map(lambda x: x.replace('\n', ' '), list(map(str.strip, data[0])))) } c -= 1 except IndexError: pass for i in r.values(): if i['Direction'][0]: graph.append(["From: %s" % i['Direction'][0], i['Delay']]) else: graph.append(["By: %s" % i['Direction'][1], i['Delay']]) totalDelay = sum(map(lambda x: x['Delay'], r.values())) fTotalDelay = utility_processor()['duration'](totalDelay) delayed = True if totalDelay else False custom_style = Style( background='transparent', plot_background='transparent', font_family='googlefont:Open Sans', # title_font_size=12, ) line_chart = pygal.HorizontalBar(style=custom_style, height=250, legend_at_bottom=True, tooltip_border_radius=10) line_chart.tooltip_fancy_mode = False line_chart.title = 'Total Delay is: %s' % fTotalDelay line_chart.x_title = 'Delay in seconds.' for i in graph: line_chart.add(i[0], i[1]) chart = line_chart.render(is_unicode=True) summary = { 'From': n.get('From') or getHeaderVal('from', mail_data), 'To': n.get('to') or getHeaderVal('to', mail_data), 'Cc': n.get('cc') or getHeaderVal('cc', mail_data), 'Subject': n.get('Subject') or getHeaderVal('Subject', mail_data), 'MessageID': n.get('Message-ID') or getHeaderVal('Message-ID', mail_data), 'Date': n.get('Date') or getHeaderVal('Date', mail_data), } security_headers = [ 'Received-SPF', 'Authentication-Results', 'DKIM-Signature', 'ARC-Authentication-Results' ] return render_template('index.html', data=r, delayed=delayed, summary=summary, n=n, chart=chart, security_headers=security_headers) else: return render_template('index.html')
def post(self, request, *args, **kwargs): mail_data = request.POST['headers'].strip() r = {} parsed_headers = HeaderParser().parsestr(mail_data) parsed_headers_dict = {} major_header_names = { 'From', 'Message-Id', 'Date', 'Subject', 'To', 'Cc' } major_headers = {} x_headers = {} security_header_names = { 'Received-SPF', 'Authentication-Results', 'DKIM-Signature', 'ARC-Authentication-Results' } security_headers = {} other_headers = {} for header in parsed_headers: parsed_headers_dict[header.replace( '-', '_')] = parsed_headers.get(header) if header in major_header_names: major_headers[header] = parsed_headers.get(header) elif header.startswith('X-'): x_headers[header] = parsed_headers.get(header) elif header in security_header_names: security_headers[header] = parsed_headers.get(header) else: other_headers[header] = parsed_headers.get(header) graph = [] received = parsed_headers.get_all('Received') if received: received = [i for i in received if ('from' in i or 'by' in i)] else: received = re.findall('Received:\s*(.*?)\n\S+:\s+', mail_data, re.X | re.DOTALL | re.I) c = len(received) for i in range(len(received)): if ';' in received[i]: line = received[i].split(';') else: line = received[i].split('\r\n') line = list(map(str.strip, line)) line = [x.replace('\r\n', ' ') for x in line] try: if ';' in received[i + 1]: next_line = received[i + 1].split(';') else: next_line = received[i + 1].split('\r\n') next_line = list(map(str.strip, next_line)) next_line = [x.replace('\r\n', '') for x in next_line] except IndexError: next_line = None org_time = dateParser(line[-1]) if not next_line: next_time = org_time else: next_time = dateParser(next_line[-1]) if line[0].startswith('from'): data = re.findall( """ from\s+ (.*?)\s+ by(.*?) (?: (?:with|via) (.*?) (?:\sid\s|$) |\sid\s|$ )""", line[0], re.DOTALL | re.X) else: data = re.findall( """ ()by (.*?) (?: (?:with|via) (.*?) (?:\sid\s|$) |\sid\s )""", line[0], re.DOTALL | re.X) delay = (org_time - next_time).seconds if delay < 0: delay = 0 try: ftime = org_time.utctimetuple() ftime = time.strftime('%m/%d/%Y %I:%M:%S %p', ftime) r[c] = { 'Timestmp': org_time, 'Time': ftime, 'Delay': delay, 'Direction': [ x.replace('\n', ' ') for x in list(map(str.strip, data[0])) ] } c -= 1 except IndexError: pass for i in list(r.values()): if i['Direction'][0]: graph.append(["From: %s" % i['Direction'][0], i['Delay']]) else: graph.append(["By: %s" % i['Direction'][1], i['Delay']]) totalDelay = sum([x['Delay'] for x in list(r.values())]) fTotalDelay = mha_tags.duration(totalDelay) delayed = True if totalDelay else False custom_style = Style( background='transparent', plot_background='transparent', font_family='googlefont:Open Sans', # title_font_size=12, ) line_chart = pygal.HorizontalBar(style=custom_style, height=250, legend_at_bottom=True, tooltip_border_radius=10) line_chart.tooltip_fancy_mode = False line_chart.title = 'Total Delay is: %s' % fTotalDelay line_chart.x_title = 'Delay in seconds.' for i in graph: line_chart.add(i[0], i[1]) chart = line_chart.render(is_unicode=True) context = { 'hops': sorted(list(r.items()), key=lambda x: x[0]), 'delayed': delayed, 'n': parsed_headers, 'chart': chart, 'headers': parsed_headers_dict, 'major_headers': major_headers, 'x_headers': x_headers, 'security_headers': security_headers, 'other_headers': other_headers } return render(request, self.template_name, context=context)
def index(): if request.method == 'POST': data = request.form['headers'].strip() r = {} n = HeaderParser().parsestr(data) graph = [] received = n.get_all('Received') if received: received = [i for i in received if ('from' in i or 'by' in i)] c = len(received) for i in range(len(received)): if ';' in received[i]: line = received[i].split(';') else: line = received[i].split('\r\n') line = list(map(str.strip, line)) line = [x.replace('\r\n', '') for x in line] try: if ';' in received[i + 1]: next_line = received[i + 1].split(';') else: next_line = received[i + 1].split('\r\n') next_line = list(map(str.strip, next_line)) next_line = [x.replace('\r\n', '') for x in next_line] except IndexError: next_line = None org_time = dateParser(line[1]) if not next_line: next_time = org_time else: next_time = dateParser(next_line[1]) if line[0].startswith('from'): data = re.findall( """ from\s+ (.*?)\s+ by(.*?) (?: (?:with|via) (.*?) (?:id|$) |id|$ )""", line[0], re.DOTALL | re.X) else: data = re.findall( """ ()by (.*?) (?: (?:with|via) (.*?) (?:id|$) |id )""", line[0], re.DOTALL | re.X) delay = org_time.second - next_time.second if delay < 0: delay = 0 try: ftime = org_time.isoformat(' ') r[c] = { 'Timestmp': org_time, 'Time': ftime, 'Delay': delay, 'Direction': [x.replace('\n', ' ') for x in list(map(str.strip, data[0]))] } c -= 1 except IndexError: pass for i in list(r.values()): if i['Direction'][0]: graph.append(["From: %s" % i['Direction'][0], i['Delay']]) else: graph.append(["By: %s" % i['Direction'][1], i['Delay']]) totalDelay = sum([x['Delay'] for x in list(r.values())]) fTotalDelay = utility_processor()['duration'](totalDelay) delayed = True if totalDelay else False custom_style = Style( background='transparent', plot_background='transparent', font_family='googlefont:Open Sans', title_font_size=12, ) line_chart = pygal.HorizontalBar( style=custom_style, height=250, legend_at_bottom=True, tooltip_border_radius=10) line_chart.tooltip_fancy_mode = False line_chart.title = 'Total Delay is: %s' % fTotalDelay line_chart.x_title = 'Delay in seconds.' for i in graph: line_chart.add(i[0], i[1]) chart = line_chart.render(is_unicode=True) summary = { 'From': n.get('from'), 'To': n.get('to'), 'Cc': n.get('cc'), 'Subject': n.get('Subject'), 'MessageID': n.get('Message-ID'), 'Date': n.get('Date'), } return render_template( 'index.html', data=r, delayed=delayed, summary=summary, n=n, chart=chart) else: return render_template('index.html')
# intended to be called from a MUA binding from config import non_VIPs, VIPs, ADDRESS_FILE, VIPS_FILE def confirm(msg): return raw_input("{} [Y/n] ".format(msg)).strip().lower() in ['y', ''] if __name__ == '__main__': # backup json [shutil.copyfile(f, f + ".bak") for f in [ADDRESS_FILE, VIPS_FILE]] message = HeaderParser().parse(sys.stdin, headersonly=True) ffroms = message.get_all('from', []) #ccs = message.get_all('cc', []) #addrs = getaddresses(ffroms + ccs) addrs = getaddresses(ffroms) # reset STDIN handle sys.stdin = open("/dev/tty") for name, addr in addrs: addr = addr.lower() try: _ = VIPs[addr] print("key exists: {} -> @vip".format(addr)) continue except KeyError: pass