cli adventures

This commit is contained in:
a-Sansara 2012-09-13 20:19:22 +02:00
parent ef8cf429e5
commit 800ce9f013
4 changed files with 310 additions and 103 deletions

View File

@ -30,9 +30,11 @@
# ~~ package cli ~~ # ~~ package cli ~~
from optparse import OptionParser, OptionGroup from optparse import OptionParser, OptionGroup
desc="""version : 0.41 copyright : pluie.org import sys
author : a-Sansara license : GNU GPLv3 import impra.util as util
import impra.core as core
desc="""
ImpraStorage provided a private imap access to store large files. ImpraStorage provided a private imap access to store large files.
Each file stored on the server is split in severals random parts. Each file stored on the server is split in severals random parts.
Each part also contains random noise data (lenght depends on a crypt key) Each part also contains random noise data (lenght depends on a crypt key)
@ -52,7 +54,7 @@ ImpraStorage randomly upload each parts then update the index.
""" """
class _SimplerOptionParser(OptionParser): class _OptionParser(OptionParser):
"""A simplified OptionParser""" """A simplified OptionParser"""
def format_description(self, formatter): def format_description(self, formatter):
@ -61,7 +63,28 @@ class _SimplerOptionParser(OptionParser):
def format_epilog(self, formatter): def format_epilog(self, formatter):
return self.epilog return self.epilog
parser = _SimplerOptionParser(prog='imprastorage', usage='\n\n %prog COMMAND [OPTION]...',epilog="""
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ class Cli ~~
class Cli:
def __init__(self,path):
self.ini = util.IniFile(path+'impra.ini')
parser = _OptionParser(prog='imprastorage', usage='\n\n\
------------------------------------------------------------------------------\n\
-- ImpraStorage --\n\
------------------------------------------------------------------------------\n\
-- version : 0.41 copyright : pluie.org --\n\
-- author : a-Sansara license : GNU GPLv3 --\n\
------------------------------------------------------------------------------\n\
\n\
%prog conf [-D|-L| -K,-H {host},-U {user},-X {password},-P {port},\n\
-B {boxname}] [-A profileName]\n\
%prog data [-l |-a {file, label} |-g {label} |-G {id} |-s {pattern} |\n\
-r {label} |-R {id}] [-c {catg}, -u {owner}, -b {boxname},\n\
-o {outputdir}]',epilog="""
conf command Examples: conf command Examples:
@ -69,8 +92,7 @@ conf command Examples:
imprastorage conf -K -H imap.gmail.com -P 993 -U login -X password imprastorage conf -K -H imap.gmail.com -P 993 -U login -X password
Set config on a new profile with same keys from previous active profile: Set config on a new profile with same keys from previous active profile:
imprastorage conf -A profile1 -H myimapserver.net -P 993 -U login \\ imprastorage conf -H myimapserver.net -P 993 -U login -X password -B boxname -A profile1
-X password -B boxname
Load config from a profile (wich become active) : Load config from a profile (wich become active) :
imprastorage conf -DA profile2 imprastorage conf -DA profile2
@ -108,49 +130,161 @@ data command Examples:
""",description=desc) """,description=desc)
gpData = OptionGroup(parser, '\ndata related Options (command data)\n-----------------------------------') gpData = OptionGroup(parser, '\n------------------------------------\ndata related Options (command data)')
gpConf = OptionGroup(parser, '\nconf related Options (command conf)\n-----------------------------------') gpConf = OptionGroup(parser, '\n------------------------------------\nconf related Options (command conf)')
# metavar='<ARG1> <ARG2>', nargs=2 # metavar='<ARG1> <ARG2>', nargs=2
parser.add_option('-v', '--version' , help='show program\'s version number and exit' , dest='version' , action='store_true' , default=False) parser.add_option('-v', '--version' , help='show program\'s version number and exit' , action='store_true' , default=False)
parser.add_option('-q', '--quiet' , help='don\'t print status messages to stdout' , dest='verbose' , action='store_false', default=True) parser.add_option('-q', '--quiet' , help='don\'t print status messages to stdout' , action='store_false', default=True)
parser.add_option('-f', '--force' , help='dont confirm and force action' , dest='force' , action='store_true' , default=False) parser.add_option('-f', '--force' , help='dont confirm and force action' , action='store_true' , default=False)
parser.add_option('-d', '--debug' , help='set debug mode' , dest='debug' , action='store_true' , default=False) parser.add_option('-d', '--debug' , help='set debug mode' , action='store_true' , default=False)
gpData.add_option('-l', '--list' , help='list index on imap server' , dest='list_index' , action='store_true' , default=False) gpData.add_option('-l', '--list' , help='list index on imap server' , action='store_true' )
gpData.add_option('-b', '--boxname' , help='switch boxname on imap server' , dest='switch_boxname' , action='store', metavar='BOXN') gpData.add_option('-a', '--add' , help='add file FILE with specified LABEL on server' , action='store', metavar='FILE LABEL ', nargs=2)
gpData.add_option('-a', '--add' , help='add file FILE with specified LABEL on server' , dest='add' , action='store', metavar='FILE LABEL', nargs=2) gpData.add_option('-g', '--get' , help='get file with specified LABEL from server' , action='store', metavar='LABEL ')
gpData.add_option('-g', '--get' , help='get file with specified LABEL from server' , dest='get' , action='store', metavar='LABEL') gpData.add_option('-G', '--get-by-id' , help='get file with specified ID from server' , action='store', metavar='ID ')
gpData.add_option('-G', '--get-by-id' , help='get file with specified ID from server' , dest='get_by_id' , action='store', metavar='ID') gpData.add_option('-s', '--search' , help='search file with specified PATTERN' , action='store', metavar='PATTERN ')
gpData.add_option('-s', '--search' , help='search file with specified PATTERN' , dest='search' , action='store', metavar='PATTERN') gpData.add_option('-r', '--remove' , help='remove FILE with specified LABEL from server' , action='store', metavar='LABEL ')
gpData.add_option('-c', '--category' , help='set specified CATEGORY (crit. for opt. -l,-a or -s)' , dest='category' , action='store', metavar='CATG' , default='none') gpData.add_option('-R', '--remove-by-id' , help='remove FILE with specified ID from server' , action='store', metavar='ID ')
gpData.add_option('-u', '--user' , help='set specified USER (crit. for opt. -l,-a or -s)' , dest='owner' , action='store', metavar='OWNER' , default='all') gpData.add_option('-b', '--boxname' , help='switch boxname on imap server' , action='store', metavar='BOXN ')
gpData.add_option('-o', '--output-dir' , help='set specified OUTPUT DIR (for opt. -l,-a,-d or -g)' , dest='output' , action='store', metavar='DIR') gpData.add_option('-c', '--category' , help='set specified CATEGORY (crit. for opt. -l,-a or -s)' , action='store', metavar='CATG ' , default='none')
gpData.add_option('-r', '--remove' , help='remove FILE with specified LABEL from server' , dest='remove' , action='store', metavar='LABEL') gpData.add_option('-u', '--user' , help='set specified USER (crit. for opt. -l,-a or -s)' , action='store', metavar='OWNER ' , default='all')
gpData.add_option('-R', '--remove-by-id' , help='remove FILE with specified ID from server' , dest='remove_by_id' , action='store', metavar='ID') gpData.add_option('-o', '--output-dir' , help='set specified OUTPUT DIR (for opt. -l,-a,-d or -g)' , action='store', metavar='DIR ')
parser.add_option_group(gpData) parser.add_option_group(gpData)
gpConf.add_option('-L', '--list-conf' , help='list configuration' , dest='list_conf' , action='store') gpConf.add_option('-L', '--list-conf' , help='list configuration' , action='store_true', default=False)
gpConf.add_option('-A', '--active-profile', help='set active profile' , dest='profile' , action='store', metavar='PROFILE', default='default') gpConf.add_option('-D', '--load-conf' , help='load configuration' , action='store_true', default=False)
gpConf.add_option('-H', '--set-host' , help='set imap host server' , dest='host' , action='store', metavar='HOST') gpConf.add_option('-H', '--set-host' , help='set imap host server' , action='store', metavar='HOST ')
gpConf.add_option('-U', '--set-user' , help='set imap user login' , dest='user' , action='store', metavar='USER') gpConf.add_option('-U', '--set-user' , help='set imap user login' , action='store', metavar='USER ')
gpConf.add_option('-X', '--set-pass' , help='set imap user password' , dest='password' , action='store', metavar='PASS') gpConf.add_option('-X', '--set-pass' , help='set imap user password' , action='store', metavar='PASS ')
gpConf.add_option('-P', '--set-port' , help='set imap port (default:[%default])' , dest='port' , action='store', metavar='PORT' , default=993) gpConf.add_option('-P', '--set-port' , help='set imap port' , action='store', metavar='PORT ')
gpConf.add_option('-B', '--set-boxname' , help='set boxName on imap server (default:[%default])' , dest='boxname' , action='store', metavar='BOXN' , default='__IMPRA') gpConf.add_option('-N', '--set-name' , help='set user name' , action='store', metavar='NAME ')
gpConf.add_option('-K', '--gen-keys' , help='generate new pub/private keys' , dest='generate_keys' , action='store_true', default=False) gpConf.add_option('-B', '--set-boxn' , help='set boxName on imap server (default:[%default])' , action='store', metavar='BOXNAME ')
gpConf.add_option('-D', '--load-conf' , help='load configuration' , dest='load_conf' , action='store_true', default=False) gpConf.add_option('-K', '--gen-keys' , help='generate new pub/private keys' , action='store_true', default=False)
parser.add_option_group(gpConf) gpConf.add_option('-A', '--active-profile', help='set active profile' , action='store', metavar='PROFILE ')
def show_index(): parser.add_option_group(gpConf)
print('show_index')
(opts, args) = parser.parse_args() (o, a) = parser.parse_args()
#~ if not 'toto' in opts.__dict__ :
#~ print("mandatory option is missing\n")
#~ parser.print_help()
#~ exit(-1)*/ if not a:
#~ print('--------') parser.print_help()
#~ print(opts) print()
#~ print('--------') parser.error(' no commando specified')
#~ print(args) sys.exit(1)
else:
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ conf CMD ~~
if a[0] == 'conf' :
if o.active_profile==None:
if self.ini.has('profile') : o.active_profile = self.ini.get('profile')
else : o.active_profile = 'default'
if o.load_conf : self.load_profile(o)
elif o.list_conf : print(self.ini.toString(o.active_profile))
else :
if not o.set_host and not o.set_user and not o.set_pass and not o.set_port and not o.set_boxn and not o.set_name and not o.gen_keys:
parser.error(' no options specified')
else :
if o.set_port and not util.represents_int(o.set_port):
parser.error(' port must be a number')
sys.exit(1)
if o.set_boxn: ini.set('box' , o.set_boxn,o.active_profile+'.imap')
if o.set_host: ini.set('host', o.set_host,o.active_profile+'.imap')
if o.set_user: ini.set('user', o.set_user,o.active_profile+'.imap')
if o.set_pass: ini.set('pass', o.set_pass,o.active_profile+'.imap')
if o.set_port: ini.set('port', o.set_port,o.active_profile+'.imap')
if o.set_name: ini.set('name', o.set_name,o.active_profile+'.infos')
if o.gen_keys:
rsa = util.Rsa(None,None,path,True)
self.ini.set('prvKey',rsa.prvKey,o.active_profile+'.keys')
self.ini.set('pubKey',rsa.pubKey,o.active_profile+'.keys')
self.ini.set('salt' ,'-¤-ImpraStorage-¤-',o.active_profile+'.keys')
if self.check_profile(o.active_profile):
self.ini.set('profile', o.active_profile)
self.ini.write()
print(self.ini.toString(o.active_profile))
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ data CMD ~~
elif a[0] == 'data' :
o.active_profile = self.ini.get('profile')
if not o.list and not o.add and not o.get and not o.get_by_id and not o.search and not o.remove and not o.remove_by_id :
parser.error(' no options specified')
else :
if self.check_profile(o.active_profile):
conf = core.ImpraConf(self.ini,o.active_profile)
rsa = util.Rsa(conf.get('prvKey','keys'),conf.get('pubKey','keys'))
impst = None
try:
impst = core.ImpraStorage(rsa, conf)
except util.BadKeysException as e :
print('Error : ')
print(e)
print("""
it seems that your current profile %s has bad keys to decrypt index on server.
you can remove index but all presents files on the box %s will be unrecoverable
""" % (o.active_profile, conf.get('box','imap')))
remIndex = input('remove index ? (yes/no)')
if remIndex.lower()=='yes':
impst = core.ImpraStorage(rsa, conf, True)
else :
print('bye')
sys.exit(1)
if o.list :
impst.index.print(True,'-'*120+'\n -- INDEX '+impst.rootBox+'\n'+'-'*120)
elif o.add :
impst.addFile(o.add[0],o.add[1],o.user,o.category)
elif o.get :
print(o.get)
elif o.get_by_id :
print(o.get_by_id)
elif o.search :
print(o.search)
elif o.remove :
print(o.remove)
elif o.remove_by_id :
print(o.remove_by_id)
#~ filePath = '/media/Data/dev/big_toph3.jpg'
#~ lab = 'Meuf\'bonne aussi4'
#~ print('\n -- ADD FILE -- ')
#~ impst.addFile(filePath,lab,conf.get('name','infos'),'images')
#~ else :
#~ self.load_profile(o)
#~ print('data cmd')
#~ print(o)
else : parser.print_help()
def check_profile(self,profile):
""""""
return self.ini.hasSection(profile+'.keys') and self.ini.has('host',profile+'.imap') and self.ini.has('user',profile+'.imap') and self.ini.has('pass',profile+'.imap') and self.ini.has('port',profile+'.imap')
def load_profile(self,o):
""""""
if self.check_profile(o.active_profile):
print('profile '+o.active_profile+' loaded')
self.ini.set('profile', o.active_profile)
self.ini.write()
else :
if not self.ini.hasSection(o.active_profile+'.imap'):
print('profile '+o.active_profile+' don\'t exist !')
else :
print('profile '+o.active_profile+' can\'t be load - incomplete\n (did you remember to generate keys ?)')

View File

@ -29,7 +29,6 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ package core ~~ # ~~ package core ~~
import inspect
from base64 import urlsafe_b64encode from base64 import urlsafe_b64encode
from email.encoders import encode_base64 from email.encoders import encode_base64
from email.header import Header from email.header import Header
@ -43,8 +42,9 @@ from os import remove, urandom, sep
from os.path import abspath, dirname, join, realpath, basename, getsize, splitext from os.path import abspath, dirname, join, realpath, basename, getsize, splitext
from re import split as regsplit from re import split as regsplit
from impra.imap import ImapHelper, ImapConfig from impra.imap import ImapHelper, ImapConfig
from impra.util import __CALLER__, Rsa, RuTime, Noiser, Randomiz, RuTime, hash_sha256, formatBytes, randomFrom, bstr, quote_escape, stack from impra.util import __CALLER__, Rsa, RuTime, Noiser, Randomiz, RuTime, hash_sha256, formatBytes, randomFrom, bstr, quote_escape, stack, run
DEBUG = True
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ class ConfigKey ~~ # ~~ class ConfigKey ~~
@ -63,7 +63,6 @@ class ConfigKey:
def getHashList(self,name,count,noSorted=False): def getHashList(self,name,count,noSorted=False):
"""""" """"""
rt = RuTime('getHashList')
rt = RuTime(eval(__CALLER__('"%s",%s,%i' % (name,count,noSorted)))) rt = RuTime(eval(__CALLER__('"%s",%s,%i' % (name,count,noSorted))))
self.rdmz.new(count) self.rdmz.new(count)
dic, lst, hroot = {}, [], hash_sha256(self.salt+name) dic, lst, hroot = {}, [], hash_sha256(self.salt+name)
@ -185,21 +184,23 @@ class ImpraConf:
if self.ini.isEmpty(): if self.ini.isEmpty():
save = True save = True
rsa = Rsa() rsa = Rsa()
self.set('host','imap.gmail.com','imap') self.set('host','host','imap')
self.set('port','993','imap') self.set('port','993','imap')
self.set('user','login','imap') self.set('user','login','imap')
self.set('pass','**********','imap') self.set('pass','password','imap')
self.set('box' ,'__SMILF','imap') self.set('box' ,'__IMPRA','imap')
self.set('pubKey',rsa.pubKey,'keys') self.set('pubKey',rsa.pubKey,'keys')
self.set('prvKey',rsa.prvKey,'keys') self.set('prvKey',rsa.prvKey,'keys')
self.set('salt' ,'-¤-ImpraStorage-¤-','keys') self.set('salt' ,'-¤-ImpraStorage-¤-','keys')
if not self.ini.hasSection(self.profile+self.SEP_SECTION+'catg'): if not self.ini.hasSection(self.profile+self.SEP_SECTION+'catg'):
save = True save = True
self.set('users', self.get('name','infos'),'catg') try:
self.set('types', 'music,films,doc,images,archives,games','catg') self.set('users', self.get('name','infos'),'catg')
except Exception : pass
self.set('types', 'music,films,doc,images,archives,games','catg')
if save : if save :
self.ini.write() self.ini.write()
print(self.ini.toString()) #print(self.ini.toString())
def get(self, key, section='main', profile=None): def get(self, key, section='main', profile=None):
"""""" """"""
@ -227,7 +228,7 @@ class ImpraIndex:
SEP_CATEGORY = '¤' SEP_CATEGORY = '¤'
"""Separator used for category section""" """Separator used for category section"""
QUOTE_REPL = '-§' QUOTE_REPL = '§'
"""Char replacement of simple quote String""" """Char replacement of simple quote String"""
SEP_KEY_INTERN = '@' SEP_KEY_INTERN = '@'
@ -246,15 +247,19 @@ class ImpraIndex:
""" """
self.rsa = rsa self.rsa = rsa
self.dic = {} self.dic = {}
self.id = 0
if encdata =='' : data = encdata if encdata =='' : data = encdata
else : data = self.rsa.decrypt(encdata) else : data = self.rsa.decrypt(encdata)
data = data.replace(self.QUOTE_REPL, '\'') data = data.replace(self.QUOTE_REPL, '\'')
ld = regsplit('\n? ?'+self.SEP_CATEGORY+' ?\n?',data) ld = regsplit('\n? ?'+self.SEP_CATEGORY+' ?\n?',data)
l = regsplit(self.SEP_ITEM,ld[0]) l = regsplit(self.SEP_ITEM,ld[0])
for row in l: for row in l:
d = regsplit(self.SEP_TOKEN,row) d = regsplit(self.SEP_TOKEN,row)
# key : count, hash, ext, usr, cat # key : count, hash, ext, usr, cat
if len(d)>4 and d!='': self.dic[d[1]] = d if len(d)>4 and d!='':
d.append(self.id)
self.dic[d[1]] = d
self.id += 1
if len(ld)>1: if len(ld)>1:
l = regsplit(self.SEP_ITEM,ld[1].lstrip('\n')) l = regsplit(self.SEP_ITEM,ld[1].lstrip('\n'))
for row in l: for row in l:
@ -270,7 +275,8 @@ class ImpraIndex:
to decode data, and parts count to decode data, and parts count
""" """
if self.search(label) == None : if self.search(label) == None :
self.dic[label] = (key,label,count,ext,usr,cat) self.dic[label] = (key,label,count,ext,usr,cat, self.id)
self.id +=1
else : else :
print(label+' already exist') print(label+' already exist')
@ -282,7 +288,7 @@ class ImpraIndex:
"""Search the corresponding label in the index""" """Search the corresponding label in the index"""
return self.dic.get(label) return self.dic.get(label)
def toString(self): def toString(self, withoutCatg=False):
"""Make a string representation of the index as it was store on the server""" """Make a string representation of the index as it was store on the server"""
data = cdata = '' data = cdata = ''
for k in sorted(self.dic): for k in sorted(self.dic):
@ -292,26 +298,33 @@ class ImpraIndex:
else : else :
for i in v: data += str(i)+self.SEP_TOKEN for i in v: data += str(i)+self.SEP_TOKEN
data = data.rstrip(self.SEP_TOKEN)+self.SEP_ITEM data = data.rstrip(self.SEP_TOKEN)+self.SEP_ITEM
return data+self.SEP_CATEGORY+'\n'+cdata; if not withoutCatg :
data += self.SEP_CATEGORY+'\n'+cdata
return data;
def encrypt(self): def encrypt(self):
"""""" """"""
return self.rsa.encrypt(self.toString().replace('\'', self.QUOTE_REPL)) return self.rsa.encrypt(self.toString().replace('\'', self.QUOTE_REPL))
def print(self): def print(self,withoutCatg=False, header=''):
"""Print index content as formated bloc""" """Print index content as formated bloc"""
data = self.toString().split(';') data = self.toString(withoutCatg).split(';')
i = 0
print(header)
for row in data: for row in data:
if row.rstrip('\n') != '': print(row) if row.rstrip('\n') != '':
print(str(i).rjust(1+ceil(len(data)/10),' ')+' - '+row)
i += 1
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ class ImpraStorage ~~ # ~~ class ImpraStorage ~~
class ImpraStorage: class ImpraStorage:
"""""" """"""
def __init__(self, rsa, conf, wkdir=None): def __init__(self, rsa, conf, remIndex=False, wkdir=None):
"""""" """"""
if wkdir == None : wkdir = abspath(join(dirname( __file__ ), '..', 'wk')) if wkdir == None : wkdir = abspath(join(dirname( __file__ ), '..', 'wk'))
self.wkdir = wkdir self.wkdir = wkdir
@ -323,6 +336,7 @@ class ImpraStorage:
self.rsa = rsa self.rsa = rsa
self.fsplit = FSplitter(ConfigKey(),self.wkdir) self.fsplit = FSplitter(ConfigKey(),self.wkdir)
self.delids = [] self.delids = []
if remIndex : self.removeIndex()
self.index = self.getIndex() self.index = self.getIndex()
def _getIdIndex(self): def _getIdIndex(self):
@ -345,6 +359,7 @@ class ImpraStorage:
def getIndex(self): def getIndex(self):
"""""" """"""
index = None
self._getIdIndex() self._getIdIndex()
if self.idx : if self.idx :
msgIndex = self.ih.email(self.idx) msgIndex = self.ih.email(self.idx)
@ -355,22 +370,31 @@ class ImpraStorage:
else : else :
encData = '' encData = ''
self.ih.deleteBin() self.ih.deleteBin()
return ImpraIndex(self.rsa,encData, {'catg':self.conf.get('types','catg')}) index = ImpraIndex(self.rsa, encData, {'catg':self.conf.get('types','catg')})
return index
def removeIndex(self):
""""""
self._getIdIndex()
if self.idx :
self.ih.delete(self.idx)
def saveIndex(self): def saveIndex(self):
"""""" """"""
global DEBUG
rt = RuTime(eval(__CALLER__())) rt = RuTime(eval(__CALLER__()))
if self.idx != None : if self.idx != None :
self.ih.delete(self.idx) self.ih.delete(self.idx)
encData = self.index.encrypt() encData = self.index.encrypt()
msgIndex = self.mb.buildIndex(encData) msgIndex = self.mb.buildIndex(encData)
print(msgIndex.as_string()) if DEBUG: print(msgIndex.as_string())
self.ih.send(msgIndex.as_string(), self.rootBox) self.ih.send(msgIndex.as_string(), self.rootBox)
#self.index = self.getIndex() #self.index = self.getIndex()
rt.stop() rt.stop()
def addFile(self, path, label, usr='all', catg=''): def addFile(self, path, label, usr='all', catg=''):
"""""" """"""
global DEBUG
rt = RuTime(eval(__CALLER__('"%s","%s","%s"' % (path[:13]+'...',label,usr)))) rt = RuTime(eval(__CALLER__('"%s","%s","%s"' % (path[:13]+'...',label,usr))))
#~ hlst = self.fsplit.addFile(path,label) #~ hlst = self.fsplit.addFile(path,label)
@ -379,9 +403,10 @@ class ImpraStorage:
try: try:
if self.index.search(label)==None : if self.index.search(label)==None :
hlst = self.fsplit.addFile(path,label) hlst = self.fsplit.addFile(path,label)
print(hlst['head']) if DEBUG :
for v in hlst['data']: print(hlst['head'])
print(v) for v in hlst['data']:
print(v)
nameFrom = self.conf.ini.get('name',self.conf.profile+'.infos') nameFrom = self.conf.ini.get('name',self.conf.profile+'.infos')
for row in hlst['data'] : for row in hlst['data'] :
msg = self.mb.build(nameFrom,usr,hlst['head'][2],self.fsplit.DIR_OUTBOX+row[1]+'.ipr') msg = self.mb.build(nameFrom,usr,hlst['head'][2],self.fsplit.DIR_OUTBOX+row[1]+'.ipr')
@ -397,6 +422,7 @@ class ImpraStorage:
def getFile(self,label): def getFile(self,label):
"""""" """"""
global DEBUG
rt = RuTime(eval(__CALLER__('"%s"' % label))) rt = RuTime(eval(__CALLER__('"%s"' % label)))
key = self.index.search(label) key = self.index.search(label)
if key!=None : if key!=None :
@ -410,9 +436,10 @@ class ImpraStorage:
if to == self.mb.getHashName('all')+'@'+self.mb.DOMAIN_NAME or to == self.mb.getHashName(self.conf.ini.get('name',self.conf.profile+'.infos'))+'@'+self.mb.DOMAIN_NAME : if to == self.mb.getHashName('all')+'@'+self.mb.DOMAIN_NAME or to == self.mb.getHashName(self.conf.ini.get('name',self.conf.profile+'.infos'))+'@'+self.mb.DOMAIN_NAME :
for mid in ids : for mid in ids :
self.ih.downloadAttachment(mid,self.fsplit.DIR_INBOX) self.ih.downloadAttachment(mid,self.fsplit.DIR_INBOX)
print(hlst['head']) if DEBUG :
for v in hlst['data']: print(hlst['head'])
print(v) for v in hlst['data']:
print(v)
self.fsplit.deployFile(hlst, key[3]) self.fsplit.deployFile(hlst, key[3])
else : else :
raise Exception(label+' is private') raise Exception(label+' is private')

View File

@ -29,7 +29,6 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ package imap ~~ # ~~ package imap ~~
import inspect
from email import message_from_bytes from email import message_from_bytes
from email.header import decode_header from email.header import decode_header
from email.message import Message from email.message import Message

View File

@ -29,19 +29,30 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ package util ~~ # ~~ package util ~~
from hashlib import sha256 from hashlib import sha256
from math import log, floor, ceil from math import log, floor, ceil
from random import choice from random import choice
from os import urandom, popen from os import urandom, popen, sep
from os.path import dirname, realpath from os.path import dirname, realpath, abspath
from time import time from time import time
from re import split as regsplit from re import split as regsplit
from base64 import urlsafe_b64encode from base64 import urlsafe_b64encode
from inspect import stack from inspect import stack
from subprocess import PIPE, Popen
from sys import stderr
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ methods ~~ # ~~ methods ~~
def represents_int(s):
""""""
try:
int(s)
return True
except ValueError:
return False
def quote_escape(data): def quote_escape(data):
"""Escape simple quote """Escape simple quote
:Returns: `str` :Returns: `str`
@ -70,6 +81,10 @@ def randomFrom(val, sval=0):
lst = list(range(sval,val)) lst = list(range(sval,val))
return choice(lst) return choice(lst)
def get_file_path(val):
""""""
return abspath(dirname(val))+sep
def formatBytes(b, p=2): def formatBytes(b, p=2):
"""Give a human representation of bytes size `b` """Give a human representation of bytes size `b`
:Returns: `str` :Returns: `str`
@ -89,6 +104,19 @@ def bstr(b,enc='utf-8'):
"""""" """"""
return str(b, encoding=enc) return str(b, encoding=enc)
def run(cmdline):
""""""
try:
p = Popen(cmdline, shell=True,stdout=PIPE, stderr=PIPE)
cmdout, cmderr = p.communicate()
rcode = p.wait()
if rcode < 0:
print((stderr,"Child was terminated by signal",rcode))
else:
return (rcode,cmdout,cmderr)
except OSError as e :
return (e,cmdout,cmderr)
def __CALLER__(args=''): def __CALLER__(args=''):
"""Give basic information of caller method """Give basic information of caller method
usage :: usage ::
@ -174,13 +202,15 @@ class RuTime:
self._start() self._start()
def _start(self): def _start(self):
print(' ==> '+self.label) from impra.core import DEBUG
if DEBUG :print(' ==> '+self.label)
self.sc = time() self.sc = time()
def stop(self): def stop(self):
"""Stop duration and print basics stats duration on console""" """Stop duration and print basics stats duration on console"""
from impra.core import DEBUG
self.ec = time() self.ec = time()
self._stats() if DEBUG:self._stats()
def _stats(self): def _stats(self):
print(' <== '+self.label+(' [%.9f s]' % (self.ec - self.sc))+' <¤¤ ') print(' <== '+self.label+(' [%.9f s]' % (self.ec - self.sc))+' <¤¤ ')
@ -204,7 +234,7 @@ class IniFile:
def has(self, key, section='main'): def has(self, key, section='main'):
"""""" """"""
d = (key in self.dic[section]) d = self.hasSection(section) and (key in self.dic[section])
return d return d
def hasSection(self, section): def hasSection(self, section):
@ -243,19 +273,21 @@ class IniFile:
with open(path, mode='w', encoding='utf-8') as o: with open(path, mode='w', encoding='utf-8') as o:
o.write(content) o.write(content)
def toString(self,path=None): def toString(self,section='*'):
"""""" """"""
if path == None : path = self.path
content = '' content = ''
main = '' main = ''
for s in self.dic: for s in self.dic:
if s!='main': if section=='*' or section+'.'==s[:len(section)+1]:
content += '\n['+s+']\n'
for k in sorted(self.dic[s]):
k = k.rstrip(' ')
if s!='main': if s!='main':
content += k+' = '+self.dic[s][k]+'\n' #~ if section=='*': content += '\n['+s+']\n'
else : main += k+' = '+self.dic[s][k]+'\n' #~ else : content += '\n['+s[len(section)+1:]+']\n'
content += '\n['+s+']\n'
for k in sorted(self.dic[s]):
k = k.rstrip(' ')
if s!='main' :
content += k+' = '+self.dic[s][k]+'\n'
else : main += k+' = '+self.dic[s][k]+'\n'
return main + content return main + content
def read(self): def read(self):
@ -275,33 +307,43 @@ class IniFile:
except IOError : pass except IOError : pass
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ class ImpraStorage ~~
class BadKeysException(BaseException):
pass
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~ class Rsa ~~ # ~~ class Rsa ~~
class Rsa: class Rsa:
"""""" """"""
def __init__(self, prvKey=None, pubKey=None, dpath='./'): def __init__(self, prvKey=None, pubKey=None, dpath='./', forceKeyGen=False):
"""""" """"""
self.cpath = dirname(realpath(__file__))+'/../desurveil/scripts/' self.cpath = dirname(realpath(__file__))+'/../desurveil/scripts/'
self.prvKey = prvKey self.prvKey = prvKey
self.pubKey = pubKey self.pubKey = pubKey
self.dpath = dpath self.dpath = dpath
if prvKey == None or pubKey==None : self.key() if prvKey == None or pubKey==None : self.key(forceKeyGen)
def key(self): def key(self,force=False):
"""""" """"""
cmd = self.cpath+"desurveil key -a "+self.dpath+".impra_id_rsa -l "+self.dpath+".impra_id_rsa.pub" cmd = self.cpath+"desurveil key -a "+self.dpath+".impra_id_rsa -l "+self.dpath+".impra_id_rsa.pub"
#print(cmd) #print(cmd)
try : try :
with open(self.dpath+'.impra_id_rsa','rt') as f: pass with open(self.dpath+'.impra_id_rsa','rt') as f: pass
except IOError as e: if force:d = popen(cmd).read()
except IOError as e:
d = popen(cmd).read() d = popen(cmd).read()
#print(d) #print(d)
self.prvKey = get_file_content(self.dpath+'.impra_id_rsa') self.prvKey = get_file_content(self.dpath+'.impra_id_rsa')
self.pubKey = get_file_content(self.dpath+'.impra_id_rsa.pub') self.pubKey = get_file_content(self.dpath+'.impra_id_rsa.pub')
#print('pubKey : \n'+self.pubKey) #~ print('pubKey : \n'+self.pubKey)
#print('prvKey : \n'+self.prvKey) #~ print('prvKey : \n'+self.prvKey)
def encrypt(self,data): def encrypt(self,data):
"""""" """"""
@ -318,5 +360,10 @@ class Rsa:
if self.prvKey != None : key = " -CI '"+self.prvKey+"'" if self.prvKey != None : key = " -CI '"+self.prvKey+"'"
#if self.prvKey != None : key = " -C '"+self.dpath+".impra_id_rsa'" #if self.prvKey != None : key = " -C '"+self.dpath+".impra_id_rsa'"
cmd = self.cpath+"desurveil decrypt -i '"+data+"'"+key cmd = self.cpath+"desurveil decrypt -i '"+data+"'"+key
#print(cmd)
return popen(cmd).read() rs = run(cmd)
if rs[0]==1:
raise BadKeysException('bad key to decrypt')
else :
encData = str(rs[1],'utf-8')
return encData