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 ~~
from optparse import OptionParser, OptionGroup
desc="""version : 0.41 copyright : pluie.org
author : a-Sansara license : GNU GPLv3
import sys
import impra.util as util
import impra.core as core
desc="""
ImpraStorage provided a private imap access to store large files.
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)
@ -52,7 +54,7 @@ ImpraStorage randomly upload each parts then update the index.
"""
class _SimplerOptionParser(OptionParser):
class _OptionParser(OptionParser):
"""A simplified OptionParser"""
def format_description(self, formatter):
@ -61,7 +63,28 @@ class _SimplerOptionParser(OptionParser):
def format_epilog(self, formatter):
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:
@ -69,8 +92,7 @@ conf command Examples:
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:
imprastorage conf -A profile1 -H myimapserver.net -P 993 -U login \\
-X password -B boxname
imprastorage conf -H myimapserver.net -P 993 -U login -X password -B boxname -A profile1
Load config from a profile (wich become active) :
imprastorage conf -DA profile2
@ -108,49 +130,161 @@ data command Examples:
""",description=desc)
gpData = OptionGroup(parser, '\ndata related Options (command data)\n-----------------------------------')
gpConf = OptionGroup(parser, '\nconf related Options (command conf)\n-----------------------------------')
gpData = OptionGroup(parser, '\n------------------------------------\ndata related Options (command data)')
gpConf = OptionGroup(parser, '\n------------------------------------\nconf related Options (command conf)')
# 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('-q', '--quiet' , help='don\'t print status messages to stdout' , dest='verbose' , 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('-d', '--debug' , help='set debug mode' , dest='debug' , action='store_true' , default=False)
# metavar='<ARG1> <ARG2>', nargs=2
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' , action='store_false', default=True)
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' , 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('-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' , dest='add' , action='store', metavar='FILE LABEL', nargs=2)
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' , dest='get_by_id' , action='store', metavar='ID')
gpData.add_option('-s', '--search' , help='search file with specified PATTERN' , dest='search' , action='store', metavar='PATTERN')
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('-u', '--user' , help='set specified USER (crit. for opt. -l,-a or -s)' , dest='owner' , action='store', metavar='OWNER' , default='all')
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('-r', '--remove' , help='remove FILE with specified LABEL from server' , dest='remove' , action='store', metavar='LABEL')
gpData.add_option('-R', '--remove-by-id' , help='remove FILE with specified ID from server' , dest='remove_by_id' , action='store', metavar='ID')
parser.add_option_group(gpData)
gpData.add_option('-l', '--list' , help='list index on imap server' , action='store_true' )
gpData.add_option('-a', '--add' , help='add file FILE with specified LABEL on server' , 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-by-id' , help='get file with specified ID from server' , action='store', metavar='ID ')
gpData.add_option('-s', '--search' , help='search file with specified PATTERN' , action='store', metavar='PATTERN ')
gpData.add_option('-r', '--remove' , help='remove FILE with specified LABEL from server' , action='store', metavar='LABEL ')
gpData.add_option('-R', '--remove-by-id' , help='remove FILE with specified ID from server' , action='store', metavar='ID ')
gpData.add_option('-b', '--boxname' , help='switch boxname on imap server' , action='store', metavar='BOXN ')
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('-u', '--user' , help='set specified USER (crit. for opt. -l,-a or -s)' , action='store', metavar='OWNER ' , default='all')
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)
gpConf.add_option('-L', '--list-conf' , help='list configuration' , dest='list_conf' , action='store')
gpConf.add_option('-A', '--active-profile', help='set active profile' , dest='profile' , action='store', metavar='PROFILE', default='default')
gpConf.add_option('-H', '--set-host' , help='set imap host server' , dest='host' , action='store', metavar='HOST')
gpConf.add_option('-U', '--set-user' , help='set imap user login' , dest='user' , action='store', metavar='USER')
gpConf.add_option('-X', '--set-pass' , help='set imap user password' , dest='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('-B', '--set-boxname' , help='set boxName on imap server (default:[%default])' , dest='boxname' , action='store', metavar='BOXN' , default='__IMPRA')
gpConf.add_option('-K', '--gen-keys' , help='generate new pub/private keys' , dest='generate_keys' , action='store_true', default=False)
gpConf.add_option('-D', '--load-conf' , help='load configuration' , dest='load_conf' , action='store_true', default=False)
parser.add_option_group(gpConf)
gpConf.add_option('-L', '--list-conf' , help='list configuration' , action='store_true', default=False)
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' , action='store', metavar='HOST ')
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' , action='store', metavar='PASS ')
gpConf.add_option('-P', '--set-port' , help='set imap port' , action='store', metavar='PORT ')
gpConf.add_option('-N', '--set-name' , help='set user name' , action='store', metavar='NAME ')
gpConf.add_option('-B', '--set-boxn' , help='set boxName on imap server (default:[%default])' , action='store', metavar='BOXNAME ')
gpConf.add_option('-K', '--gen-keys' , help='generate new pub/private keys' , action='store_true', default=False)
gpConf.add_option('-A', '--active-profile', help='set active profile' , action='store', metavar='PROFILE ')
def show_index():
print('show_index')
parser.add_option_group(gpConf)
(opts, args) = parser.parse_args()
#~ if not 'toto' in opts.__dict__ :
#~ print("mandatory option is missing\n")
#~ parser.print_help()
#~ exit(-1)*/
#~ print('--------')
#~ print(opts)
#~ print('--------')
#~ print(args)
(o, a) = parser.parse_args()
if not a:
parser.print_help()
print()
parser.error(' no commando specified')
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 ~~
import inspect
from base64 import urlsafe_b64encode
from email.encoders import encode_base64
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 re import split as regsplit
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 ~~
@ -63,7 +63,6 @@ class ConfigKey:
def getHashList(self,name,count,noSorted=False):
""""""
rt = RuTime('getHashList')
rt = RuTime(eval(__CALLER__('"%s",%s,%i' % (name,count,noSorted))))
self.rdmz.new(count)
dic, lst, hroot = {}, [], hash_sha256(self.salt+name)
@ -185,21 +184,23 @@ class ImpraConf:
if self.ini.isEmpty():
save = True
rsa = Rsa()
self.set('host','imap.gmail.com','imap')
self.set('host','host','imap')
self.set('port','993','imap')
self.set('user','login','imap')
self.set('pass','**********','imap')
self.set('box' ,'__SMILF','imap')
self.set('pass','password','imap')
self.set('box' ,'__IMPRA','imap')
self.set('pubKey',rsa.pubKey,'keys')
self.set('prvKey',rsa.prvKey,'keys')
self.set('salt' ,'-¤-ImpraStorage-¤-','keys')
if not self.ini.hasSection(self.profile+self.SEP_SECTION+'catg'):
save = True
self.set('users', self.get('name','infos'),'catg')
try:
self.set('users', self.get('name','infos'),'catg')
except Exception : pass
self.set('types', 'music,films,doc,images,archives,games','catg')
if save :
self.ini.write()
print(self.ini.toString())
#print(self.ini.toString())
def get(self, key, section='main', profile=None):
""""""
@ -227,7 +228,7 @@ class ImpraIndex:
SEP_CATEGORY = '¤'
"""Separator used for category section"""
QUOTE_REPL = '-§'
QUOTE_REPL = '§'
"""Char replacement of simple quote String"""
SEP_KEY_INTERN = '@'
@ -246,6 +247,7 @@ class ImpraIndex:
"""
self.rsa = rsa
self.dic = {}
self.id = 0
if encdata =='' : data = encdata
else : data = self.rsa.decrypt(encdata)
data = data.replace(self.QUOTE_REPL, '\'')
@ -254,7 +256,10 @@ class ImpraIndex:
for row in l:
d = regsplit(self.SEP_TOKEN,row)
# 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:
l = regsplit(self.SEP_ITEM,ld[1].lstrip('\n'))
for row in l:
@ -270,7 +275,8 @@ class ImpraIndex:
to decode data, and parts count
"""
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 :
print(label+' already exist')
@ -282,7 +288,7 @@ class ImpraIndex:
"""Search the corresponding label in the index"""
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"""
data = cdata = ''
for k in sorted(self.dic):
@ -292,17 +298,24 @@ class ImpraIndex:
else :
for i in v: data += str(i)+self.SEP_TOKEN
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):
""""""
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"""
data = self.toString().split(';')
data = self.toString(withoutCatg).split(';')
i = 0
print(header)
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
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -311,7 +324,7 @@ class ImpraIndex:
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'))
self.wkdir = wkdir
@ -323,6 +336,7 @@ class ImpraStorage:
self.rsa = rsa
self.fsplit = FSplitter(ConfigKey(),self.wkdir)
self.delids = []
if remIndex : self.removeIndex()
self.index = self.getIndex()
def _getIdIndex(self):
@ -345,6 +359,7 @@ class ImpraStorage:
def getIndex(self):
""""""
index = None
self._getIdIndex()
if self.idx :
msgIndex = self.ih.email(self.idx)
@ -355,22 +370,31 @@ class ImpraStorage:
else :
encData = ''
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):
""""""
global DEBUG
rt = RuTime(eval(__CALLER__()))
if self.idx != None :
self.ih.delete(self.idx)
encData = self.index.encrypt()
msgIndex = self.mb.buildIndex(encData)
print(msgIndex.as_string())
if DEBUG: print(msgIndex.as_string())
self.ih.send(msgIndex.as_string(), self.rootBox)
#self.index = self.getIndex()
rt.stop()
def addFile(self, path, label, usr='all', catg=''):
""""""
global DEBUG
rt = RuTime(eval(__CALLER__('"%s","%s","%s"' % (path[:13]+'...',label,usr))))
#~ hlst = self.fsplit.addFile(path,label)
@ -379,9 +403,10 @@ class ImpraStorage:
try:
if self.index.search(label)==None :
hlst = self.fsplit.addFile(path,label)
print(hlst['head'])
for v in hlst['data']:
print(v)
if DEBUG :
print(hlst['head'])
for v in hlst['data']:
print(v)
nameFrom = self.conf.ini.get('name',self.conf.profile+'.infos')
for row in hlst['data'] :
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):
""""""
global DEBUG
rt = RuTime(eval(__CALLER__('"%s"' % label)))
key = self.index.search(label)
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 :
for mid in ids :
self.ih.downloadAttachment(mid,self.fsplit.DIR_INBOX)
print(hlst['head'])
for v in hlst['data']:
print(v)
if DEBUG :
print(hlst['head'])
for v in hlst['data']:
print(v)
self.fsplit.deployFile(hlst, key[3])
else :
raise Exception(label+' is private')

View File

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

View File

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