def att_plain_sample(mbody, smtype, sm): #from core.data import smpls,fpr,tc,tr #from core.ui.cmenu import Menu #from core.ui.banner import bancls while True: bancls() if smpls[smtype]['astat'] != 0: fpr('It seems you have already attached this type of sample') if not raw_input(' Do you want to append another one [y/N]:') in [ 'y', 'Y' ]: break if True: smpl_menu = Menu(sm) if smpl_menu.op == '': break #if smpl_menu.op == '1': if smpl_menu.op in ['1', '2', '3', '4', '5', '6', '7']: if smpls[smtype][smpl_menu.op].get('sval', '') == '_': mbody.append(smpls[smtype][smpl_menu.op]['val'].replace( smpls[smtype][smpl_menu.op]['sval'], "")) else: mbody.append(smpls[smtype][smpl_menu.op]['val']) smpls[smtype]['astat'] += 1 fpr.ok('Sample attached (x%d)' % smpls[smtype]['astat']) break
def get_filename2(mode='load', title=None): while True: bancls() if title: fpr('%s' % title) print fpr('Please provide a file name:') fn = raw_input(' []> ') print if fn: if mode == 'save': if os.path.isfile(fn): if get_yesno_input (' File already exist. Overwrite it [y/N]: '): return fn #else: # return None else: return fn if mode == 'load': if os.path.exists(fn): return fn else: fpr.fail('File not found') print if get_yesno_input(' Return to menu [y/N]> '): break
def flushDKIMHeaders(): import re from core.data import smtp, fpr if raw_input( ' Flush attached DKIM-Signature headers and Private Key [y/N]:> ' ) in ['y', 'Y']: for k in smtp['headers'].keys(): h = re.match('^(h\d*_DKIM-Signature)$', k) #if re.match('^h\d*_DKIM',k): if h: #print k #h = re.match('^h\d*_DKIM-Signature$',k) #if h: #print (k,h.group(1)) #DEBUG del smtp['headers'][k] fpr(' * %s flushed ' % h.groups()) for k in range(smtp['sign']['dkim']['dstat']): if smtp['sign']['dkim'].get(k): smtp['sign']['dkim'].pop(k, None) fpr(' * Private Key #%s flushed ' % k) # if key in dict if smtp['sign']['dkim']['dstat'] in smtp['sign']['dkim']: # print 'POP' smtp['sign']['dkim'].pop(smtp['sign']['dkim']['dstat'], None) #smtp['sign']['dkim'].pop(smtp['sign']['dkim']['dstat'],None) smtp['sign']['dkim']['dstat'] = 0 fpr.ok('DKIM-Signature headers were flushed !') fpr.ok('DKIM Private Keys were flushed')
def main(): try: signal.signal(signal.SIGINT, sig_handler) iworkspace() ishell() # except Ctrl+C, Ctrl+D # except (KeyboardInterrupt, EOFError): except EOFError: print print fpr.err('Interrupted by user! Session lost!') try: sys.exit(0) except SystemExit: os._exit(0) except Exception, error: print fpr.warn('> Unpredictable Exception has been catched') fpr.err('>>> %s' % str(error)) fpr('> Need help regarding the error, please send me a copy. Thank you.' ) fpr.warn( '> Restarting main() to keep the session.\n> Please save the session and restart me..' ) waitin() main()
def iworkspace(): SECMODE=0700 fpr('Initialiazing workspace ..') # Directory check if os_type() == 'posix': # fpr('+ POSIX system found') # fpr('+ Directory check') for k in cfgs: #print k if re.match('.*_path$',k): #print k,cfgs[k] _dir = cfgs[k] #if not os.path.exists(_dir): if not os.path.isdir(_dir): try: os.makedirs(_dir) fpr.ok('* Creating workspace directory: %s' % _dir ) except OSError as exception: fpr.fail('* Creating workspace directory: %s' % _dir ) if exception.errno != errno.EEXIST: raise if exception.errno != errno.EACCES: raise if os.path.isdir(_dir): if os.path.basename(_dir) in ['keys','logs']: try: os.chmod(_dir,SECMODE) except OSError, e: pass
def runDHAThreads(): viewDHAThreadsSummary() print if smtp['addrlist']['r_reject'].keys() or smtp['addrlist']['r_valid'].keys(): fpr('Flushing currently found results (valid/refused recipients) ..') del smtp['dha']['threads']['ok'][:] del smtp['dha']['threads']['fail'][:] smtp['addrlist']['r_reject'].clear() smtp['addrlist']['r_valid'].clear() from pprint import pprint if smtp['dha'].get('cmd') != 'RCPT TO': #chek if sysem support EXPN/VRFY command before threading print if get_yesno_input(' Would you like to test an SMTP server for %s method before threading [y/N]: ' % smtp['dha'].get('cmd')): sc = enumSMTPcmd(v=False,dhost=smtp['connect']['hosts'][0]) # enumSMTPcmd(v=True,dhost=smtp['connect']['hosts'][0]): #pprint(sc) #if smtp['connect']['hosts'][0]['tls_mode'] == 'TLS': #print smtp['dha'].get('cmd') if smtp['dha'].get('cmd') in sc['method']: fpr.ok('Method %s is supported' % smtp['dha'].get('cmd')) else: fpr.fail('Method %s is unsupported' % smtp['dha'].get('cmd')) print fpr('Consider to change an SMTP method!') print t = srThread() t.daemon = True t.delay = smtp['dha']['threads'].get('delay',1) t.threads = smtp['dha']['threads']['reals'].get( 'not',smtp['dha']['threads'].get('not',1) ) t.cpt = smtp['dha']['threads']['reals'].get( 'cpt',smtp['dha']['threads'].get('cpt',get_rcpts('NoR')) ) t.method = smtp['dha'].get('cmd') t.rcpts = smtp['addrlist']['rcpts'] #print get_rcpts('NoR') if get_rcpts('NoR'): if raw_input(' Confirm threading [y/N]:> ') in ['y','Y']: # enable logging from core.msg.sender import Logger logger = Logger() t.run() logger.close() else: print fpr.err('Threading were Cancaled!') else: print fpr.err('Err. No recipients defined!')
def runThreads(): # ----------------------------------------------------------- # del smtp['replay']['threads']['ok'][:] del smtp['replay']['threads']['fail'][:] if smtp['addrlist']['r_reject'].keys() or smtp['addrlist']['r_valid'].keys( ): fpr('Flushing currently found results (valid/refused recipients) ..') smtp['addrlist']['r_reject'].clear() smtp['addrlist']['r_valid'].clear() viewThreadsSummary() t = srThread() t.daemon = True t.delay = smtp['replay']['threads'].get('delay', 1) #viewThreadsSummary() #print #FIXME: after flushing all values are None t.threads = smtp['replay']['threads']['reals'].get( 'not', smtp['replay']['threads'].get('not', 1)) t.rpm = smtp['replay']['threads']['reals'].get( 'rpm', smtp['replay']['threads'].get('rpm', 1)) t.mpt = smtp['replay']['threads']['reals'].get( 'mpt', smtp['replay']['threads'].get('mpt', 1)) t.rate = smtp['replay']['threads'].get('rate', '1') t.th_interval = smtp['replay']['threads'].get('th_interval', 0) #t.msg = message t.msg = msg_builder() #t.rcpts = [smtp['addrlist']['rcpt_to']]+smtp['addrlist']['rcpts'] t.rcpts = smtp['addrlist']['rcpts'] dbginfo('debug', str(t.rcpts)) #t.msg = msg_builder().as_string(unixfrom=False) # ----------------------------------------------------------- # #print t.msg if t.msg: if raw_input(' Confirm threading [y/N]:> ') in ['y', 'Y']: # enable logging from core.msg.sender import Logger logger = Logger() t.run() logger.close() else: print fpr.err('Threading were Cancaled!') else: print fpr.err('Message can not be processed or not loaded !')
def loadSession(): print if not get_yesno_input(' Would you like to load saved 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 load a session file from different location.') # get the latest file as default: print latest = max(glob.iglob(os.path.join(cfgs['sess_path'], '*.session')), key=os.path.getctime) if latest: fpr('Latest saved session is %s' % os.path.basename(latest)) print sf = raw_input(' [%s]> ' % os.path.basename(latest)) or latest print # if filename does not include path than search file in session dir if not os.path.dirname(sf): sf = cfgs['sess_path'] + '/' + sf if os.path.exists(sf): # import json try: f = open(sf, 'r') # json loads tmp = json.load(f) #from pprint import pprint #pprint(tmp) #TODO: test tmpe dict x = 0 for k in tmp.keys(): if k in [ 'connection', 'signatures', 'replay', 'content', 'headers' ]: x += 1 if x: fpr.ok('Session file seems to be proper') else: fpr.fail('Session file is not proper') return # overwrite main SMTP dict print '=====' #smtp = {k:v for k,v in tmp.items()} for k, v in inSMTPdict(tmp).items(): print k, v smtp[k] = v print '=====' fpr.ok('Session load successful') except IOError as e: fpr.err('Loding session failed: %s' % e) else: fpr.err('Session file does not exist')
def att_raw_sample(mbody, smtype, sm): #from core.data import smpls,fpr,tc,tr #from core.ui.cmenu import Menu #from core.ui.banner import bancls while True: bancls() if smpls[smtype]['astat'] != 0: fpr('It seems you have already attached this type of sample') if not raw_input(' Do you want to append another one [y/N]:') in [ 'y', 'Y' ]: break if True: smpl_menu = Menu(sm) if smpl_menu.op == '': break #if smpl_menu.op == '1': if smpl_menu.op in ['1', '2', '3', '4']: #FIXME this will not work like that for long tmal # fix sampel types in this shity way, the whole code regarding samples need # to be rewritten and reorginize, this is not flexible/scalable if smpls[smtype][smpl_menu.op].get('type') == 'text': #this overwites type under smpls[smtype]['type'] if smpls[smtype][smpl_menu.op].get('sval', '') == '_': # mbody.append(smpls[smtype][smpl_menu.op]['val'].replace("_","")) smtp['content']['text'].append( smpls[smtype][smpl_menu.op]['val'].replace( smpls[smtype][smpl_menu.op]['sval'], "")) else: #print "wtf: %s - %s" % (smtype,smpls[smtype][smpl_menu.op]['val']) #mbody here is smtp['content']['vof'] - this is dict {} - so overwrite #this with fixed path to 'text' or create a seperate att_plain and add #this as mime plain/text ??? #mbody.append(smpls[smtype][smpl_menu.op]['val']) smtp['content']['text'].append( smpls[smtype][smpl_menu.op]['val']) smpls[smtype]['astat'] += 1 fpr.ok('Sample attached (x%d)' % smpls[smtype]['astat']) break else: if smpls[smtype]['type'] == 'b64': #att_b64(mbody,smtype,'1') att_b64(mbody, smtype, smpl_menu.op) elif smpls[smtype]['type'] == 'file': #att_file_sample(mbody,smtype,'1') att_file_sample(mbody, smtype, smpl_menu.op) break
def get_spfHeaders(): fpr('Please provide your input') fpr('Use Ctrl-D with new line to continue.') print fpr.info('_' * (tc - 4)) print inputs = get_inputs(nl=True) fpr.info('_' * (tc - 4)) if inputs: #dbglog(inputs) #inputs = [x.lstrip() for x in inputs] return splitHeaders(inputs, crlf=True)
def get_rrtxt(mfrom): RE_SPF = re.compile(br'^v=spf1$|^v=spf1 ', re.IGNORECASE) fpr('MFROM identity: %s' % mfrom) try: local_part, domain = spf.split_email(s=mfrom, h='') fpr('Domain: %s' % domain) print _dns = spf.DNSLookup(domain, 'TXT', strict=True, timeout=20) if _dns: #dbginfo('debug','DNS: %s ' % dns) # for k, v in DNSLookup(name, qtype, self.strict, timeout): for k, v in _dns: #k = (k[0].lower(), k[1]) if k[1] == 'TXT': m = re.match(RE_SPF, v[0]) if m: fpr('DNS RR: %s' % k[1]) print #for i in v: # fpr.green('%s' % i ) fpr.green('%s' % "".join(v)) #print else: fpr('No TXT RR was found') print except spf.TempError, e: fpr.err('Error: %s' % e) print
def info(itype,msg,log=None,adj='c',frame='warn'): #TODO: add color option for frame # if itype.lower() == 'info': fpr.warn( ('_'*(tc-4-len('__')) + '__' )) print fpr(msg,adj=adj) if log: fpr.info('_'*(tc-4)) print fpr.info(log) fpr.info('_'*(tc-4)) fpr.warn('_'*(tc-4))
def att_dkim_signature(dsig): if smtp['sign']['dkim']['dstat'] != 0: fpr('It seems you have already attached %s DKIM Signature' % smtp['sign']['dkim']['dstat']) if not raw_input(' Do you want to append another one [y/N]:') in [ 'y', 'Y' ]: return smtp['headers']['h' + str(smtp['sign']['dkim']['dstat']) + '_DKIM-Signature'] = dsig smtp['sign']['dkim']['dstat'] += 1 fpr.ok('DKIM Signature attached (x%d)' % smtp['sign']['dkim']['dstat'])
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 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 get_filename(): #import os.path while True: bancls() fpr('Load attachment from file') print fpr('Please provide a full path: ') fn = raw_input(' > ') if fn: #content.att_load_file(smtp['content']['att'],attfn) if os.path.exists(fn): return fn else: fpr.fail('File not found') print if raw_input(' Return to menu [y/N]> ') in ['y','Y']: break
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 viewAcceptedAddresses(): fpr('Accepted Addresses') print for k in smtp['addrlist']['r_valid']: (e, m) = smtp['addrlist']['r_valid'][k] # unpack tuple fpr(" %-30s | %4s | %s " % (k, e, m)) print #fpr('Total number of addresses: %d' % len([smtp['addrlist']['rcpt_to']]+smtp['addrlist']['rcpts'])) fpr('Total number of addresses: %d' % len(smtp['addrlist']['rcpts'])) fpr('Total number of refused addresses: %d' % len(smtp['addrlist']['r_reject'].keys())) fpr.white('Total number of accepted addresses: %d' % len(smtp['addrlist']['r_valid'].keys()))
def att_cont_as_string(content=''): #from core.data import smtp,fpr,tc,tr,DEBUG #from core.func import waitin,get_inputs,dbglog,dbginfo if content: fpr('Body content has been created') smtp['content']['string'] = content dbginfo('debug', smtp['content']['string']) smtp['use_mime'] = False else: while True: #if smpls[smtype]['astat'] != 0: # fpr('It seems you have already attached this type of sample') # if not raw_input(' Do you want to append another one [y/N]:') in ['y','Y']: # break fpr.info('_' * (tc - 4)) print inputs = get_inputs(nl=True) fpr.info('_' * (tc - 4)) if inputs: dbglog(inputs) smtp['content']['string'] = '\r\n'.join(inputs) dbginfo('debug', smtp['content']['string']) # change the way how msg_builder build the message # even if you paste a proparly formatted mime message do not # treat this as MIME because you are not anymore responsible for building # a mime parts, you only need to attach this content as it is smtp['use_mime'] = False # TODO # Since now all other function should be aware when usemime() is FALSE and # than not be able to attach any of predefined sample break else: fpr('Leaving ..') break
def auth_spfplflow(dd, spfid): # info('info','SPF Validation process tests SPF record if it is syntactically correct \n' \ # 'according to RFC 7208 compliant library pyspf. To present the whole path \n' \ # 'this test additionally follow all "include" mechanisms using DNS query to \n' \ # 'retrieve all external SPF policies.' \ # , adj='l') # print fpr('SPF identity type : %s' % spfid) fpr('SPF identity value : %s' % dd['id'].get(spfid)) if spfid == 'mfrom': local_part, domain = spf.split_email(s=dd['id'].get('mfrom'), h=dd['id'].get('helo')) if spfid == 'helo': local_part, domain = spf.split_email(s='', h=dd['id'].get('helo')) fpr('Domain: %s' % domain) print try: q = spf.query(i=dd.get('ip'), s=dd['id'].get('mfrom'), h=dd['id'].get('helo'), timeout=20, verbose=False, querytime=0) except Exception, e: fpr.err('Err: %s' % e) waitin() return
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 rcpt_builder(op): #from core.data import smtp,fpr #from core.func import append_uniq #from core.msg.utils import get_addresses opmap = { '1': 'h_To', '2': 'h_Cc', '3': 'h_Bcc', } print fpr.info('Note: Only unique addresses are going to be included') print ops = [] if op == '4': # all #ops = ['h_To', 'h_Cc', 'h_Bcc'] ops = ['1', '2', '3'] else: ops = [op] for op in ops: if smtp['headers'].get(opmap[op], None): fpr('Processing %s header .. ' % opmap[op]) print r = get_addresses(smtp['headers'][opmap[op]]) if type(r) is list: append_uniq(smtp['addrlist']['rcpts'], r) fpr(' Addresses found with header : %d' % len(r)) fpr(' Total number of recipients : %d' % len(smtp['addrlist']['rcpts'])) print #fpr('%s' % smtp['addrlist']['rcpts'] ) else: fpr.err('Header %s: contains unproper list of recipients!' % opmap[op]) #fpr('Recipients not included!') else: fpr('No %s header' % op)
def banner(): global tc global tr tc, tr = fpr.ts_auto_refresh() fpr('='*(tc-4),ch='|') fpr.DFLT = fpr.GREEN fpr('sMtP mInjA (v=dev080819-2325)', 'c', '|' ) fpr.DFLT = fpr.BLUE fpr('='*(tc-4),ch='|') fpr.DFLT = fpr.RCL print
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_rate(): # from core.data import smtp,fpr,tc,tr # import re rate = smtp['replay']['threads'].get('rate', '') fpr('Allowed values are N, N/Ms, N/Mm, N/Mh') fpr('where:') fpr(' N - number of Recipients/Messages \ \n M - value of s-seconds, m-minutes or h-hours\n') print r = raw_input(' [%s]> ' % (rate or '')) if r: m = re.match(r'^(\d+)(\/)*(\d+[smh])*$', r) if not m: # print fpr.err('Err: Incorrect syntax') return False else: #print type(m.group()) #if m.group(1): # print m.group(1) #if m.group(2): # print m.group(2) #if m.group(3): # print m.group(3) if m.group(1) and not m.group(2): fpr.ok('%s' % m.group()) smtp['replay']['threads']['rate'] = m.group() return m.group() if m.group(3): fpr.ok('%s' % m.group()) smtp['replay']['threads']['rate'] = m.group() return m.group() else: return (rate or '')
def viewRawContent(raw): dl = len(raw.splitlines()) if dl > tr: fpr('Content data is 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 pager = Less(num_lines=tr) print raw | pager else: fpr.blue('_' * (tc - 4)) print fpr('%r' % raw) else: fpr.blue('_' * (tc - 4)) print fpr('%r' % raw) fpr.blue('_' * (tc - 4))
def infos(op): if op == 'help': fpr('Building a help and documentation is always the most time consuming task.' \ 'I have written a tool in such a way it should be a self explanatory in ' \ 'most cases. Although one of the goal of using this tool is to learn how ' \ 'an SMTP protocol and email authentication features works, I would like to ' \ 'include additional help for each of the submenu this tool shares.\n' \ 'Let\'s see how this will work.') print fpr('Feedback! I really appreciate all feedbacks, so please feel free to mail me!' ) if op == 'license': fpr(""" ######################################################################### # Copyright (C) %9s Bartosz Kozak # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation, either version 2 of the License, or # # (at your option) any later version. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program. If not, see <http://www.gnu.org/licenses/>. # ######################################################################### """ % COPYDATE, adj='c') if op == 'about': fpr.white('minja version: %s written by %s %s' % (VERSION, AUTHOR, MAIL))
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 mpart_saver(part, op): if op == 1: #save as it is, no decoding #pprint(part) part['encext'] = None for (h, hv) in part['mheaders']: #fpr('%s: %s' % (h,hv)) if h.lower() == 'content-transfer-encoding': part['encext'] = '.' + hv.lower() print if not get_yesno_input(' Would you like to save this part: [y/N]> '): return print if part['filename']: fn = part['filename'] + part['encext'] else: fn = 'minja-' + part['type'].replace( '/', '_') + '-' + datetime.now().strftime( '%Y%m%d%H%M%S') + part['encext'] print fn = raw_input(' [%s]> ' % fn) or fn print #if sf == sessfile or not os.path.dirname(sf): # sf = cfgs['sess_path']+'/'+sf if not os.path.dirname(fn): fn = cfgs['mparts_path'] + '/' + fn if os.path.exists(fn): fpr('File already exist') else: if os.access(os.path.dirname(fn), os.W_OK): #the file does not exists but write privileges are given fpr('Saving under %s\n' % fn) try: #f = codecs.open(fn, 'w', encoding='utf-8') f = open(fn, 'w') f.write(part['payload']) f.close() fpr.ok('Session saving') except IOError as e: fpr.err('Saving file failed: %s' % e) else: fpr.fail('Missing write permission') if op == 2: #decode base64 first print if not get_yesno_input(' Would you like to save this part: [y/N]> '): return print if part['filename']: fn = part['filename'] else: fn = 'minja-' + part['type'].replace( '/', '_') + '-' + datetime.now().strftime('%Y%m%d%H%M%S') print fn = raw_input(' [%s]> ' % fn) or fn print #if sf == sessfile or not os.path.dirname(sf): # sf = cfgs['sess_path']+'/'+sf if not os.path.dirname(fn): fn = cfgs['mparts_path'] + '/' + fn if os.path.exists(fn): fpr('File already exist') else: if os.access(os.path.dirname(fn), os.W_OK): #the file does not exists but write privileges are given fpr('Saving under %s\n' % fn) try: #f = codecs.open(fn, 'w', encoding='utf-8') f = open(fn, 'wb') d = decode_attch(part['payload']) #pprint(d) f.write(d['raw']) f.close() fpr.ok('Session saving') except IOError as e: fpr.err('Saving file failed: %s' % e) else: fpr.fail('Missing write permission')
def viewDKIMSignTag(_all=0): #TODO: # add Less funct with condition # d = smtp['sign']['dkim'] if not d.get(0): fpr('No DKIM Signature') return for k in range(d['dstat'] + 1): #print d #print k # if not _all then show current only if not _all and k != d['dstat']: k += 1 else: if k in d: dn = d[k] if smtp.get('h' + str(k) + '_DKIM-Signature'): fpr('Signature attached (#%s)' % k, adj='r') else: fpr('Signature not attached (current #%s)' % k, adj='r') fpr.info('_' * (tc - 4)) print fpr('DKIM signature set tags:') print fpr(' version : v=%s' % dn.get('version', '1')) fpr(' alghoritm : a=%s' % dn.get('alghoritm', 'rsa-sha256')) fpr(' canonicalization : c=%s' % dn.get('canonicalize', '')) fpr(' selector : s=%s' % dn.get('selector', '')) fpr(' domain : d=%s' % dn.get('domain', '')) fpr(' header : h=%s' % dn.get('header', "from : to : subject")) fpr(' identity : i=%s' % dn.get('identity', '')) fpr(' length : l=%s' % dn.get('length', '')) print if dn.get('privkey'): fpr('Private Key status : -- Loaded -- ') else: fpr.warn('Private Key status : -- Not loaded -- ') print if dn.get('sig'): fpr('DKIM-Signature: %s' % dn.get('sig', ''), adj='l') else: fpr.warn('DKIM-Signature: -- Not generated --') print if smtp['headers'].get('h' + str(k) + '_DKIM-Signature'): fpr('DKIM-Signature was attached') else: fpr.warn('DKIM-Signature was not attached') print fpr.info('_' * (tc - 4))