def dbginfo(itype,msg,log=None): if itype.lower() == 'error': fpr.err( ('-'*(tc-4-len('-- Error --')) + '-- Error --' )) fpr.info(msg) if log: fpr.err('_'*(tc-4)) print fpr(log) fpr.err('_'*(tc-4)) fpr.err('-'*(tc-4)) if itype.lower() == 'warrning': fpr.warn( ('-'*(tc-4-len('-- Warrning --')) + '-- Warrning --' )) fpr.info(msg) if log: fpr.warn('_'*(tc-4)) print fpr(log) fpr.warn('_'*(tc-4)) fpr.warn('-'*(tc-4)) if itype.lower() == 'debug': #from core.data import DEBUG if not DEBUG: return 0 fpr.purple( ('-'*(tc-4-len('-- Debug --')) + '-- Debug --' )) fpr.info(msg) if log: fpr.purple('_'*(tc-4)) print fpr(log) fpr.purple('_'*(tc-4)) fpr.purple('-'*(tc-4))
def dbglog(s,f=0): #from core.data import DEBUG #from pprint import pprint global tc if DEBUG: fpr.purple( ('-'*(tc-4-len('-- DebuG --')) + '-- DebuG --' )) if type(s) is str: fpr(s) else: if f: pprint(s) else: fpr('%r' % s) fpr.purple('-'*(tc-4))
def viewSmtpConv(s): #import re #import sys #from StringIO import StringIO #from core.ui.cless import Less if s: if raw_input( ' Would you like to view SMTP conversation [y/N]:> ') not in [ 'y', 'Y' ]: return True else: print dl = len(s.splitlines()) for line in s.splitlines(): if len(line) > tc: dl += len(line) / tc if dl > tr: fpr('SMTP conversation logs are much bigger than your screen (%s lines)' % dl) if raw_input( ' Would like to use system pager to view it [y/N]:> ') in [ 'y', 'Y' ]: fpr.blue('_' * (tc - 4)) print # use Less if output is much bigger than one screen pager = Less(num_lines=tr) # fetch output from fancy print as Less input must be a string # make copy of original stdout han redirect stdout to string sto = sys.stdout sys.stdout = StringIO() for line in s.splitlines(): if re.search('^send:', line): fpr.cyan(line) elif re.search('^reply:', line): fpr.green(line) elif re.search('^data:', line): fpr.purple(line) else: fpr.info(line) x = sys.stdout.getvalue() sys.stdout.close() sys.stdout = sto print x | pager return True #else: # fpr.blue( '_'*(tc-4)) # print # fpr.blue( '_'*(tc-4)) #else: fpr.blue('_' * (tc - 4)) print for line in s.splitlines(): if re.search('^send:', line): fpr.cyan(line) elif re.search('^reply:', line): fpr.green(line) elif re.search('^data:', line): fpr.purple(line) else: fpr.info(line) fpr.blue('_' * (tc - 4))
def parse_spfHeaders2(h): from email.message import Message import re if not h: return False #print type(h) #print h #h1 = h.replace('\n','') #print h1 # re.DOTALL '.'match everything inludinf newline # re.IGNORECASE is used at the splitHeaders() function first AUTHRE = re.compile('^(Authentication-Results):(.*)', re.DOTALL) RECSPF = re.compile('^(Received-SPF):(.*)', re.DOTALL) m1 = re.match(AUTHRE, h) m2 = re.match(RECSPF, h) if DDDEBUG: fpr.purple(h) dd = {'hn': '', 'hv': ''} #""" Authentication-Results """ if m1: dd['hn'] = m1.group(1) dd['hv'] = m1.group(2) fpr.info('_' * (tc - 4)) print fpr('Header-name : %s' % m1.group(1)) fpr('Header-value : %s' % m1.group(2)) fpr.info('_' * (tc - 4)) print try: import authres # FIXME: fast workaround for authres module # # remove "d=" tag from dmarc auth method as authres # does recognize only below ptype # -> elif ptype.lower() not in ['smtp', 'header', 'body', 'policy'] # and it raise a Syntax error for d= h = h.replace('\n', '') h = h.replace('\r', '') h = h.replace('\t', ' ') DTAG = re.compile('.*dmarc=.* \(.*\)* d=([a-z0-9\.\-]+)', re.IGNORECASE) md = re.match(DTAG, h) if md: fpr.warn('Stripping "d=" tag from dmarc method: d=%s' % md.group(1)) #fpr.green( '%s ---- %s' % (md.group(1), md.group())) h = re.sub('d=%s' % md.group(1), '', h) if DDDEBUG: print h #else: # print 'no d-tag' arh = authres.AuthenticationResultsHeader.parse(h) #if DDDEBUG: # from pprint import pprint # pprint(str(arh)) except Exception, e: fpr.err('Exception: %s' % e) p = {} if str(arh.authserv_id): p['authserv_id'] = str(arh.authserv_id) print len(arh.results) for i in arh.results: if DDDEBUG: pprint(i) fpr('method: %s' % str(i.method)) if str(i.method) == 'spf': p.setdefault('spf', {}) p['spf'].setdefault('mailfrom', {}) p['spf'].setdefault('helo', {}) p['spf'].setdefault('pra', {}) if DDDEBUG: fpr('result : %s' % str(i.result)) if hasattr(i, 'smtp_mailfrom'): fpr('smtp.mailfrom : %s' % str(i.smtp_mailfrom)) if hasattr(i, 'smtp_helo'): fpr('smtp.helo : %s' % str(i.smtp_helo)) if hasattr(i, 'smtp_pra'): fpr('smtp.pra : %s' % str(i.smtp_pra)) for j in i.properties: if j.name == 'mailfrom': p['spf']['mailfrom']['result'] = str(i.result) p['spf']['mailfrom']['type'] = str(j.type) p['spf']['mailfrom']['name'] = str(j.name) p['spf']['mailfrom']['value'] = str(j.value) if j.name == 'helo': p['spf']['helo']['result'] = str(i.result) p['spf']['helo']['type'] = str(j.type) p['spf']['helo']['name'] = str(j.name) p['spf']['helo']['value'] = str(j.value) if j.name == 'pra': p['spf']['pra']['result'] = str(i.result) p['spf']['pra']['type'] = str(j.type) p['spf']['pra']['name'] = str(j.name) p['spf']['pra']['value'] = str(j.value) if DDDEBUG: fpr.green(' type: %s' % str(j.type)) fpr(' name: %s' % str(j.name)) fpr(' value: %s' % str(j.value)) if str(i.method) == 'dkim': p.setdefault('dkim', {}) p['dkim']['result'] = str(i.result) if DDDEBUG: fpr('result : %s' % str(i.result)) fpr('header_i : %s' % str(i.header_i)) for j in i.properties: # dkim header identity p['dkim']['header_i'] = str(j.value) if DDDEBUG: fpr.green(' type: %s' % str(j.type)) fpr(' name: %s' % str(j.name)) fpr(' value: %s' % str(j.value)) if str(i.method) == 'dmarc': p.setdefault('dmarc', {}) p['dmarc']['result'] = str(i.result) if DDDEBUG: fpr('result : %s' % str(i.result)) p['h_value'] = dd['hv'] return p
def chThrDep(t=None, rpm=None, mpt=None): #VERIFY: In Python 2.x : int/int --> int and int/float --> float In Python 3.x : int/int can result in a float from core.data import smtp, fpr, tc, tr from core.func import waitin r = get_rcpts('NoR') #Warunki Konieczne - Essential Conditions # to met WK1, WK2, WK3 if not t: t = smtp['replay']['threads'].get('not', None) elif t and not (1 <= int(t) <= r): if r > 1: t = r if r == 1: #special case pass if t: smtp['replay']['threads']['not'] = int(t) if not rpm: rpm = smtp['replay']['threads'].get('rpm', None) elif rpm and not (1 <= int(rpm) <= r): rpm = int(r) if rpm: fpr.ok('Saving RpM as %s' % rpm) smtp['replay']['threads']['rpm'] = int(rpm) if not mpt: mpt = smtp['replay']['threads'].get('mpt', None) elif mpt and not (1 <= int(mpt) <= r): mpt = int(r) if mpt: fpr.ok('Saving MpT as %s' % mpt) smtp['replay']['threads']['mpt'] = int(mpt) if r: # specific feature: the result depends from number of recipients # -------------------------------------------------------------------- # if t and not rpm and not mpt: fpr.warn('%s : %s : %s - %s' % (t, rpm, mpt, r)) # allow to set t if no rpm or mpt values and number of rcpt > 1 # but t must be <= r, so if t greater then r => it will be equal to r if r > 1: smtp['replay']['threads']['not'] = int(t) fpr.ok('Saving NoT as %s' % t) return t # special case when r == 1 , not related to our Equation # for r = 1 allow to set T > 1 but do not allow than set rpm or mpt # in this special case the sam message is flooding a sepcific rcpt # with this smae message in multiple threads/connection ! if r == 1: #pass smtp['replay']['threads']['not'] = int(t) fpr.ok('Saving NoT as %s' % t) return t # set initial elif rpm and not t and not mpt: fpr.warn('%s : %s : %s - %s' % (t, rpm, mpt, r)) if r > 1: smtp['replay']['threads']['rpm'] = int(rpm) #return rpm #return True if r == 1: fpr.warn('It doesn\'t make sense to define RpM when NoR = 1') return False # elif mpt and not t and not rpm: fpr.warn('%s : %s : %s - %s' % (t, rpm, mpt, r)) if r > 1: smtp['replay']['threads']['mpt'] = int(mpt) #return mpt #return True if r == 1: fpr.warn('It doesn\'t make sense to define MpT when NoR = 1') return False else: fpr.err('Recipients not defined. Build a list of recipients first.') fpr.err('Flush the values if the recipient list has been modified.') return # Some maths :) # # rpm - recipient per message # r - number of recipients (all) # m - number of messages (all) # # rpm = r / m ==> m = r / rpm # mpt - messages per thread # t - number of threads # m - number of messages (all) # # mpt = m / t ==> m = mpt * t # r / rpm = mpt * t # # ==> t = r / (rpm * mpt) # # ==> rpm = r / (mpt * t) # # ==> mpt = r / (rpm * t) fpr.info('_' * (tc - 4)) print fpr.warn('Your limits:') fpr.warn('t = %s : rpm = %s : mpt = %s - r = %s' % (smtp['replay']['threads'].get( 'not', None), smtp['replay']['threads'].get('rpm', None), smtp['replay']['threads'].get('mpt', None), r)) print fpr.err('Maximum possible limits to met Essential Conditions:') fpr.err('t = %s : rpm = %s : mpt = %s - r = %s' % (t, rpm, mpt, r)) fpr.info('_' * (tc - 4)) print def chEque(): print if r: # compare float # https://ubuntuforums.org/showthread.php?t=840665 def float_eq(a, b, epsilon=0.00000001): fpr.cyan('<float_eq> %s' % abs(a - b)) if abs(a - b) < epsilon: return True return False m1 = float(r) / rpm m2 = mpt * float(t) fpr.cyan('r/rpm = %s, mpt * t = %s' % (m1, m2)) if float_eq(m1, m2): fpr.green('Equetion is met') waitin() return True else: fpr.err('Equetion is false') waitin() return False def setReals(t, rpm, mpt): if t and rpm and mpt: smtp['replay']['threads']['reals'].setdefault('not', t) smtp['replay']['threads']['reals'].setdefault('rpm', rpm) smtp['replay']['threads']['reals'].setdefault('mpt', mpt) smtp['replay']['threads']['reals']['not'] = t smtp['replay']['threads']['reals']['rpm'] = rpm smtp['replay']['threads']['reals']['mpt'] = mpt fpr.ok('Reals were set!') if r: # count the mpt - based on rpm and t # -------------------------------------------------------------------- # if t and rpm and not mpt: fpr.green('%s : %s : %s - %s' % (t, rpm, mpt, r)) # m = r / rpm # mpt = m / t # I - validate MPT - MPT <= R mpt = float(r) / (rpm * t) fpr.green('counting mpt = %s' % mpt) chEque() # round up - if there is a remainder if (r % (rpm * t) > 0): mpt = r / (rpm * t) + (r % (rpm * t) > 0) fpr.green('rounding up mpt = %s' % mpt) # find the lowest T for rounded MpT to met RpM t_new = float(r) / (rpm * mpt) #+ (r % (rpm * mpt) > 0) fpr.green('counting new t = %s' % t_new) if (r % (rpm * mpt) > 0): # if remainder t_new = r / (rpm * mpt) + (r % (rpm * mpt) > 0) fpr.green('rounding up new t = %s' % t_new) fpr.err( 'realistic returns would be: *t = %s, rpm = %s, mpt = %s for r = %s' % (int(t_new), rpm, int(mpt), r)) setReals(int(t_new), rpm, int(mpt)) else: fpr.err( 'realistic returns would be: t = %s, rpm = %s, mpt = %s for r = %s' % (t, rpm, int(mpt), r)) setReals(t, rpm, int(mpt)) # count the rpm - for mpt and t # -------------------------------------------------------------------- # elif t and mpt and not rpm: fpr.blue('%s : %s : %s - %s' % (t, rpm, mpt, r)) # m = mpt * t # m = r / rpm # TODO # WK: validate RPM , RPM <= R rpm = float(r) / (mpt * t) fpr.blue('counting: rpm = %s' % rpm) chEque() # if there is a remainder if (r % (mpt * t) > 0): rpm = r / (mpt * t) + (r % (mpt * t) > 0) fpr.blue('rounding up rpm = %s' % rpm) # find the lowest T for rounded MpT to met RpM t_new = float(r) / (rpm * mpt) #+ (r % (rpm * mpt) > 0) fpr.green('counting new t = %s' % t_new) if (r % (rpm * mpt) > 0): # if remainder t_new = r / (rpm * mpt) + (r % (rpm * mpt) > 0) fpr.green('rounding up new t = %s' % t_new) fpr.err( 'realistic returns would be: *t = %s, rpm = %s, mpt = %s for r = %s' % (int(t_new), int(rpm), mpt, r)) setReals(int(t_new), int(rpm), mpt) else: fpr.err( 'realistic returns would be: t = %s, rpm = %s, mpt = %s for r = %s' % (t, int(rpm), mpt, r)) setReals(t, int(rpm), mpt) # count the mpt ( use t = 1 ) # -------------------------------------------------------------------- # elif rpm and not t and not mpt: t = 1 fpr.purple('assuming t eq 1 for equation') fpr.purple('%s : %s : %s - %s' % (t, rpm, mpt, r)) mpt = float(r) / rpm fpr.purple('counting: mpt = %s' % mpt) chEque() #if there is a remainder if (r % rpm > 0): mpt = r / rpm + (r % rpm > 0) fpr.purple('rounding up mpt = %s' % mpt) # find the lowest T for rounded MpT to met RpM t_new = float(r) / (rpm * mpt) #+ (r % (rpm * mpt) > 0) fpr.green('counting new t = %s' % t_new) if (r % (rpm * mpt) > 0): # if remainder t_new = r / (rpm * mpt) + (r % (rpm * mpt) > 0) fpr.green('rounding up new t = %s' % t_new) fpr.err( 'realistic returns would be: *t = %s, rpm = %s, mpt = %s for r = %s' % (int(t_new), rpm, mpt, r)) setReals(int(t_new), rpm, mpt) else: fpr.err( 'realistic returns would be: t = %s, rpm = %s, mpt = %s for r = %s' % (t, rpm, int(mpt), r)) setReals(t, rpm, int(mpt)) # count the rpm ( use t = 1 ) # -------------------------------------------------------------------- # elif mpt and not t and not rpm: t = 1 fpr.purple('assuming t eq 1 for equation') fpr.purple('%s : %s : %s - %s' % (t, rpm, mpt, r)) rpm = float(r) / mpt fpr.purple('counting: rpm = %s' % rpm) t = 1 chEque() #if there is a remainder if (r % mpt > 0): rpm = r / mpt + (r % mpt > 0) fpr.purple('rounding up rpm = %s' % rpm) # find the lowest T for rounded MpT to met RpM t_new = float(r) / (rpm * mpt) #+ (r % (rpm * mpt) > 0) fpr.green('counting new t = %s' % t_new) if (r % (rpm * mpt) > 0): # if remainder t_new = r / (rpm * mpt) + (r % (rpm * mpt) > 0) fpr.green('rounding up new t = %s' % t_new) fpr.err( 'realistic returns would be: *t = %s, rpm = %s, mpt = %s for r = %s' % (int(t_new), int(rpm), mpt, r)) setReals(int(t_new), int(rpm), mpt) else: fpr.err( 'realistic returns would be: t = %s, rpm = %s, mpt = %s for r = %s' % (t, int(rpm), mpt, r)) setReals(t, int(rpm), mpt) # count t - for rpm and mpt # -------------------------------------------------------------------- # elif mpt and rpm and not t: fpr.white('%s : %s : %s - %s' % (t, rpm, mpt, r)) print type(mpt) # add 1 to round up a result # (r % (rpm * mpt) > 0) it will return True which is 1 # if there is a remainder and 0 if not t = float(r) / (rpm * mpt) #+ (r % (rpm * mpt) > 0) fpr.white('counted: t = %s' % t) chEque() # round up if (r % (rpm * mpt) > 0): t = r / (rpm * mpt) + (r % (rpm * mpt) > 0) fpr.white('rounding up t = %s' % t) # validate WK # t = <1,r> # if t < 1 if (float(r) / (rpm * mpt)) < 1: fpr.info('Now to met equetion for t=1 it is not possible for %s (R) recipients '\ 'to send %s (MpT) messeges in one thread with %s (RpM) recipient in message' % (r,mpt,rpm)) print fpr.info('New RpM value can be counted based on existing MpT or new MpT ' \ 'value can be counted based on existing RpM' ) print fpr.info('For simplicity it is assumed that RpM limits is more important so MpT ' \ 'is going to be recounted to met an equation') print mpt_new = float(r) / rpm fpr.white('New MpT to met equetion is %s' % mpt_new) mpt = mpt_new chEque() # now just round up mpt_new = r / rpm + (r % rpm > 0) fpr.white('rounding up new mpt = %s' % mpt_new) fpr.err( 'realistic returns would be: t = %s, rpm = %s, *mpt = %s for r = %s' % (int(t), rpm, int(mpt_new), r)) setReals(int(t), rpm, int(mpt_new)) else: # so if t > 1 and it was counted fpr.err( 'realistic returns would be: t = %s, rpm = %s, mpt = %s for r = %s' % (int(t), rpm, int(mpt), r)) setReals(int(t), rpm, int(mpt)) # only true if r / rpm = mpt * t # -------------------------------------------------------------------- # elif t and rpm and mpt: fpr.cyan('%s : %s : %s - %s' % (t, rpm, mpt, r)) if not chEque(): fpr.info('_' * (tc - 4)) print fpr.warn('It is not recommended trying to set NoT with RpM and MpT. ' \ 'Suggested action would be to flush these values.' ) fpr.info('_' * (tc - 4)) print waitin() return False else: fpr.err( 'realistic returns would be: t = %s, rpm = %s, mpt = %s for r = %s' % (t, rpm, mpt, r)) setReals(t_new, rpm, mpt) # for test waitin()