def get_cpt_no(): # set_dval(q=' Set CPT', dd=smtp['dha']['threads'], key='cpt', val=None) info('info','Note: CPT defines a number of commands sent per single thread where each \n' \ ' thread is a a new SMTP connection which need to be established.\n\n' \ ' * CPT = NOR / NOT\n' \ ' * CPT can not be greater than number of recipients (NOR) \n' \ ' * CPT is recounted when NOT is changed.\n' \ ' * CPT is equal NOR by default ', adj='l' ) print n = raw_input(' [%s]> ' % smtp['dha']['threads'].get('cpt',None)) \ or smtp['dha']['threads'].get('cpt',None) if n == None: return MAX_COMMANDS = 1000 if type(n) is int or n.isdigit(): print if 0 < int(n) < MAX_COMMANDS: # smtp['dha']['threads']['cpt'] = int(n) # fpr.ok('%s'%n) if chDHAThrDep(cpt=int(n)): fpr.ok('%s'%n) else: fpr.fail('Setting CPT as %s' % n)
def get_threads_no(): info('info','Note: NOT defines the number of threads where each thread is a new separate' \ ' and simultaneous connection. \n' \ ' * NOT = NOR / CPT \n' \ ' * NOT is 1 by default \n' \ ' * NOT value should be keep between 1 - %s \n' \ ' * NOT is recounted when CPT is changed' % MAX_THREADS, adj='l' ) print n = raw_input(' [%s]> ' % smtp['dha']['threads'].get('not',None)) \ or smtp['dha']['threads'].get('not',None) if n == None: return if type(n) is int or n.isdigit(): print if 0 < int(n) < MAX_THREADS: # smtp['dha']['threads']['not'] = int(n) # fpr.ok('%s'%n) if chDHAThrDep(t=int(n)): fpr.ok('%s'%n) else: fpr.fail('Setting NoT as %s' % n)
def get_msgs_no(): # from core.data import smtp,fpr,tc,tr # from core.data import MAX_MSG_PER_TH # from core.func import info info('info','Note: MPT defines a number of messages sent per single thread where each \n' \ ' thread is a a new SMTP connection which need to be established.\n\n' \ ' * MPT can not be greater than number of recipients (NOR) when \n' \ ' NOR is greater than one.\n' \ ' * Settinng MPT also does not make sense for single recipient. ', adj='l' ) print n = raw_input(' [%s]> ' % smtp['replay']['threads'].get('mpt',None)) \ or smtp['replay']['threads'].get('mpt',None) if n == None: return if type(n) is int or n.isdigit(): print if 1 <= int(n) <= MAX_MSG_PER_TH: print #ret = chThrDep(mpt=int(n)) #if ret > True: # smtp['replay']['threads']['mpt']=int(ret) if chThrDep(mpt=int(n)): fpr.ok('%s' % n) else: print fpr.fail('%s' % n)
def get_rcpt_no(): # from core.data import smtp,fpr,tc,tr # from core.data import MAX_RCPT_PER_MSG # from core.func import info info('info','Note: RPM defines a number of recipients used with a single message.\n' \ ' It\'s a number of RCPT TO commands send with corresponding addresses.\n\n' \ ' * RPM value can not be greater than number of recipients (NOR) when \n' \ ' NOR is greater than one.\n' \ ' * Settinng RPM does not make sense for single recipient. ', adj='l' ) #fpr('RpM can not be greater than number of recipients when NoR > 1') #fpr('Settinng RpM does not make sense for single recipient') print n = raw_input(' [%s]> ' % smtp['replay']['threads'].get('rpm',None)) \ or smtp['replay']['threads'].get('rpm',None) if n == None: return if type(n) is int or n.isdigit(): print if 0 < int(n) < MAX_RCPT_PER_MSG: print #ret = chThrDep(rpm=int(n)) #if ret > True: # smtp['replay']['threads']['rpm']=int(ret) if chThrDep(rpm=int(n)): fpr.ok('%s' % n) else: print fpr.fail('%s' % n)
def get_timeout(): info('info','Note: Time waiting for server reply', adj='l' ) print n = raw_input(' [%s]> ' % smtp['dha']['threads'].get('timeout',TH_TIMEOUT)) \ or smtp['dha']['threads'].get('timeout',TH_TIMEOUT) if n and (type(n) is int or n.isdigit()): if 0 <= int(n): print smtp['dha']['threads']['timeout']=int(n) fpr.ok('%s'%n) else: print fpr.fail('%s'%n)
def dkim_pktest(privkey): if not (privkey or type(privkey) is str): return False m = re.search("--\n(.*?)\n--", privkey, re.DOTALL) if m is None: return False try: bancls() pkdata = base64.b64decode(m.group(1)) fpr('Private key') info('info', m.group(1), adj='l') return True except TypeError, e: fpr(str(e)) return False
def dumpSession(): info('info','Saved session allows to save current connection and message setting to be \n' \ 'useful with further tests, as a proof of successful test or used as template\n\n'\ 'Note: Session file can store sensitive data like SMTP authentication\n' \ ' credential or private keys and certificate.',adj='l') print if not get_yesno_input( ' Would you like to save your current session: [y/N]> '): return print fpr('Session files are stored under the session subdirectory by default.\n' \ 'Please provide a full path if you would like to store you session somehere else.') sessfile = 'minja-' + datetime.now().strftime('%Y%m%d%H%M%S') + '.session' print sf = raw_input(' [%s]> ' % sessfile) or sessfile print if sf == sessfile or not os.path.dirname(sf): sf = cfgs['sess_path'] + '/' + sf if os.path.exists(sf): fpr('Session file already exist') else: if os.access(os.path.dirname(sf), os.W_OK): #the file does not exists but write privileges are given fpr('Saving under %s\n' % sf) #import json dd = outSMTPdict(smtp) try: #f = codecs.open(sf, 'w', encoding='utf-8') f = open(sf, 'w') json.dump(dd, f, indent=3) fpr.ok('Session saving') except IOError as e: fpr.err('Saving file failed: %s' % e) else: fpr.fail('Missing write permission')
def get_delay(): info('info','Note: Delay is number of miliseconds between starting new threads, \n' \ ' where each new thread is a new SMTP connection.', adj='l' ) print n = raw_input(' [%s]> ' % smtp['dha']['threads'].get('delay',TH_DELAY)) \ or smtp['dha']['threads'].get('delay',TH_DELAY) if n and (type(n) is int or n.isdigit()): if 0 <= int(n): print smtp['dha']['threads']['delay']=int(n) fpr.ok('%s'%n) else: print fpr.fail('%s'%n)
def att_load_eml(mbody, emlfn): #import os #from core.data import smtp,fpr,tc,tr #from core.func import waitin,dbginfo if os.path.isfile(emlfn): print fpr('Loading %s ..' % emlfn) fp = open(emlfn, 'rb') inputs = fp.read() fp.close() if not inputs: dbginfo( 'error', 'Err: File has no content. Please verify file size !\n[ %s ]' % emlfn) #break return False if inputs: info('info', '-- Loaded message: Top dump (view: 500 chars) --', '%s' % inputs[:500] + ' . . .') print #dbglog(inputs) fpr.ok('Message content has been loaded') #smtp['content']['string'] = ''.join(inputs) mbody['string'] = ''.join(inputs) #smtp['content']['string'] = '\r\n'.join(inputs) #smtp['use_mime'] = False waitin() else: fpr('No such file or you don\'t have a permission to access it') print return False
def get_threads_no(): # from core.data import smtp,fpr,tc,tr # from core.data import MAX_THREADS # fpr.info('Threads are treated as seperate connections.') # print # fpr('Try to keep number of Threads between <1-100>') # fpr('NoT can not be greater than number of recipients when NoR > 1') # print info('info','Note: NOT defines the number of threads where each thread is a new seperate' \ ' and simultaneous connection. \n' \ ' * NOT can not be greater then number of recipients (NOR) when \n' \ ' NOR is greater than one.\n' \ ' * NOT value should be kept between 1 - %s \n\n' \ ' ** NOT can be greater than 1 when there is only 1 recipient but\n' \ ' ** this raise a special case when the same message is sent multiple \n' \ ' ** times (NOT times) to single recipient using a seperate connection \n' \ ' ** and bombarding recipient with the same message' % MAX_THREADS, adj='l' ) print n = raw_input(' [%s]> ' % smtp['replay']['threads'].get('not',None)) \ or smtp['replay']['threads'].get('not',None) if n == None: return if type(n) is int or n.isdigit(): print if 0 < int(n) < MAX_THREADS: #smtp['replay']['threads']['not']=int(n) #fpr.ok('%s'%n) #ret = chThrDep(t=int(n)) #if ret > True: # #smtp['replay']['threads']['not']=int(n) # smtp['replay']['threads']['not']=ret if chThrDep(t=int(n)): pass #fpr.ok('%s'%n) else: fpr.fail('Setting NoT as %s' % n)
def get_msgs_delay(): # from core.data import smtp,fpr,tc,tr # from core.data import MAX_MSG_PER_TH # from core.func import info info('info','Note: Delay is number of miliseconds between starting new threads, \n' \ ' where each new thread is a new SMTP connection.', adj='l' ) #fpr('Specify Delay between running new thread/connection') print n = raw_input(' [%s]> ' % smtp['replay']['threads'].get('delay',TH_DELAY)) \ or smtp['replay']['threads'].get('delay',TH_DELAY) if n and (type(n) is int or n.isdigit()): if 0 <= int(n): print smtp['replay']['threads']['delay'] = int(n) fpr.ok('%s' % n) else: print fpr.fail('%s' % n)
def mail_body_parser(body): if not hasattr(body, 'as_string'): fpr.err('Message can not be processed or not loaded !') return b = email.message_from_string(body.as_string()) btype = b.get_content_type() dbginfo('debug', 'btype is %s' % btype) print # parse the body and save split parts in dictionary dparts = dict() body_parser(dparts, b) fpr.cyan('=' * (tc - 4)) # pprint(dparts) if DEBUG: dbginfo('debug', str(dparts.keys())) fpr.cyan('=' * (tc - 4)) ## build a dictionary print if not dparts.keys(): fpr('No MIME parts found') return mimemulti = ['multipart/mixed', 'multipart/alternative'] print mimemulti while True: bancls() fpr('Message MIME structure') print fpr('_' * (tc - 4)) print bstrio = StringIO() _structure(b, bstrio) fpr.warn('%s' % bstrio.getvalue()) #fpr.warn(_structure(bpart)) fpr('_' * (tc - 4)) print fpr('MIME parts ready to review:') print for k in dparts.keys(): #print k #print type(k) if dparts[k]['type'] in mimemulti: fpr.info(' [%s] %s ' % (k, dparts[k]['type'][:69])) else: fpr(' [%s] %s ' % (k, dparts[k]['type'][:69])) print op = raw_input(' []> ') # dparts keys are int not strings if op.isdigit(): k = int(op) if op == '': break while k in dparts.keys(): bancls() fpr('MIME Headers: %s' % k) fpr('_' * (tc - 4)) print for (h, hv) in dparts[k]['mheaders']: fpr('%s: %s' % (h, hv)) fpr('_' * (tc - 4)) print # pprint(dparts) # waitin() if dparts[k].get('type') in mimemulti: fpr.warn('This part is not directly viewable') waitin() break elif dparts[k].get('payload'): fpr('Choose option:') print fpr(' 1) view payload') fpr(' 2) save payload') fpr.off(' 3) attach payload to composer [?future feature?]') print op = raw_input(' []> ') if op == '': waitin() break # --- view payload --- if op in ['1']: bancls() fpr('MIME Payload ') print fpr.warn('%s' % dparts[k].get('type')) print xe = 0 for (h, hv) in dparts[k].get('mheaders'): #fpr('%s: %s' % (h,hv)) if h.lower() == 'content-transfer-encoding': #part['encext'] = '.'+hv.lower() if hv in ['base64']: info( 'info', 'This payload is base64 encoded. You can view it as it is or try to decode it first.' ) print if get_yesno_input( ' Would like to decode the payload first [y/N]:> ' ): dp = decode_attch(dparts[k]['payload']) #pprint(dp) #print len(dp.get('raw')) #print len(str(dp)) if len(dp.get('raw')) > tr: #if True: if get_yesno_input( ' Would like to use system pager to view it [y/N]:> ' ): fpr('_' * (tc - 4)) print pager = Less(num_lines=tr) print dp.get('raw') | pager fpr('_' * (tc - 4)) else: fpr('_' * (tc - 4)) print fpr(dp.get('raw')) print fpr('_' * (tc - 4)) waitin() xe = 1 break # if viewed decoded part do not display encoded one if xe: break print if len(dparts[k].get('payload')) > tr: if get_yesno_input( ' Would like to use system pager to view it [y/N]:> ' ): fpr('_' * (tc - 4)) print pager = Less(num_lines=tr) print dparts[k]['payload'] | pager fpr('_' * (tc - 4)) else: fpr('_' * (tc - 4)) print fpr(dparts[k]['payload']) print fpr('_' * (tc - 4)) else: fpr('_' * (tc - 4)) print if type(dparts[k].get('payload')) is not 'str': fpr.err('An error occured') else: fpr(dparts[k].get('payload')) print fpr('_' * (tc - 4)) waitin() if op in ['2']: bancls() fpr('MIME Payload export') fpr('Choose option:') print fpr(' 1) save payload, as it is (no decoding)') fpr(' 2) save payload - base64 decoded') print op = raw_input(' []> ') print if op == '': waitin() break if op in ['1']: bancls() mpart_saver(dparts[k], 1) waitin() if op in ['2']: bancls() mpart_saver(dparts[k], 2) waitin() break else: fpr.warn( 'Wrr: Empty payloyd. Message malformed or parsing has failed.' ) waitin() break
def att_load_file(mbody, attfn): #import os #from core.data import smtp,fpr,tc,tr #from core.func import waitin,dbginfo if os.path.isfile(attfn): print fpr('Loading %s ..' % attfn) #from mimetypes import guess_type #from email.encoders import encode_base64 mimetype, encoding = guess_type(attfn) # if no extension try to detect mime type wit a libmagic library # from python-magic package if possible if mimetype == None: try: import magic mimetype = magic.from_file(attfn, mime=True) except ImportError: dbginfo( 'warrning', 'Warrning: Missing module: magic. Use: pip install python-magic' ) print mimetype = 'text/plain' #mimetype = mimetype.split('/', 1) fp = open(attfn, 'rb') inputs = fp.read() fp.close() if not inputs: dbginfo( 'error', 'Err: File has no content. Please verify file size !\n[ %s ]' % attfn) #break return False if inputs: info('info','Default Content-* header values are generated based on file extension. If no' \ 'extension and no \'magic\' module is found than text/plain is suggested by \ndefault.',adj='l') print fpr('Please define MIME headers for this attachment') print n = 1 if mbody.keys(): #global n n = max(mbody.keys()) n += 1 #print max(mbody.keys()) fpr('Attachment no: %d' % n, 'c') print mbody.setdefault(n, {})['raw'] = inputs #mbody['0']['b64'] = inputs mbody[n]['h_Content-Type'] = \ raw_input(' Content-Type: [%s]> ' % mimetype) \ or mimetype mbody[n]['h_Content-Disposition'] = \ raw_input(' Content-Disposition: [%s]> ' % \ 'attachments; filename=%s' % os.path.basename(attfn)) \ or 'attachments; filename=%s' % os.path.basename(attfn) mbody[n]['h_Content-transfer-encoding'] = \ raw_input(' Content-transfer-encoding: [%s]> ' % '') \ or '' mbody[n]['h_Content-ID'] = \ raw_input(' Content-ID: [%s]> ' % '') \ or '' mbody[n]['h_Content-Description'] = \ raw_input(' Content-Description: [%s]> ' % '') \ or '' waitin() else: fpr('No such file or you don\'t have a permission to access it') print return False