~mdw
/
catacomb-python
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
catacomb/pwsafe.py: Use `binascii' for Base64 conversion.
[catacomb-python]
/
catacomb
/
pwsafe.py
diff --git
a/catacomb/pwsafe.py
b/catacomb/pwsafe.py
index
31df641
..
97ad354
100644
(file)
--- a/
catacomb/pwsafe.py
+++ b/
catacomb/pwsafe.py
@@
-28,6
+28,7
@@
from __future__ import with_statement
from __future__ import with_statement
+import binascii as _B
import errno as _E
import os as _OS
from cStringIO import StringIO as _StringIO
import errno as _E
import os as _OS
from cStringIO import StringIO as _StringIO
@@
-48,8
+49,15
@@
_NUL = _bin('\0')
_CIPHER = _bin('cipher:')
_MAC = _bin('mac:')
_CIPHER = _bin('cipher:')
_MAC = _bin('mac:')
+def _with_metaclass(meta, *supers):
+ return meta("#<anonymous base %s>" % meta.__name__,
+ supers or (object,), dict())
+
def _excval(): return SYS.exc_info()[1]
def _excval(): return SYS.exc_info()[1]
+_M600 = int("600", 8)
+_M700 = int("700", 8)
+
###--------------------------------------------------------------------------
### Text encoding utilities.
###--------------------------------------------------------------------------
### Text encoding utilities.
@@
-96,10
+104,10
@@
def _dec_metaname(name):
def _b64(s):
"""Encode S as base64, without newlines, and trimming `=' padding."""
def _b64(s):
"""Encode S as base64, without newlines, and trimming `=' padding."""
- return
s.encode('base64'
).replace('\n', '').rstrip('=')
+ return
_text(_B.b2a_base64(s)
).replace('\n', '').rstrip('=')
def _unb64(s):
"""Decode S as base64 with trimmed `=' padding."""
def _unb64(s):
"""Decode S as base64 with trimmed `=' padding."""
- return
(s + '='*((4 - len(s))%4)).decode('base64'
)
+ return
_B.a2b_base64(s + '='*((4 - len(s))%4)
)
def _enc_metaval(val):
"""Encode VAL as a metadata item value, returning the result."""
def _enc_metaval(val):
"""Encode VAL as a metadata item value, returning the result."""
@@
-228,9
+236,11
@@
class StorageBackendClass (type):
Register a new concrete StorageBackend subclass.
"""
super(StorageBackendClass, me).__init__(name, supers, dict)
Register a new concrete StorageBackend subclass.
"""
super(StorageBackendClass, me).__init__(name, supers, dict)
- if me.NAME is not None: StorageBackend.register_concrete_subclass(me)
+ try: name = me.NAME
+ except AttributeError: pass
+ else: StorageBackend.register_concrete_subclass(me)
-class StorageBackend (
object
):
+class StorageBackend (
_with_metaclass(StorageBackendClass)
):
"""
I provide basic protocol for password storage backends.
"""
I provide basic protocol for password storage backends.
@@
-298,8
+308,6
@@
class StorageBackend (object):
priority order when opening an existing database.
"""
priority order when opening an existing database.
"""
- __metaclass__ = StorageBackendClass
- NAME = None
PRIO = 10
## The registry of subclasses.
PRIO = 10
## The registry of subclasses.
@@
-520,7
+528,7
@@
else:
except _G.error: raise StorageBackendRefusal(_excval())
def _create(me, file):
except _G.error: raise StorageBackendRefusal(_excval())
def _create(me, file):
- me._db = _G.open(file, 'n',
0
600)
+ me._db = _G.open(file, 'n',
_M
600)
def _close(me, abruptp):
me._db.close()
def _close(me, abruptp):
me._db.close()
@@
-588,7
+596,7
@@
else:
('unknown database schema version (%d > %d)' % (ver, me.VERSION))
def _create(me, file):
('unknown database schema version (%d > %d)' % (ver, me.VERSION))
def _create(me, file):
- fd = _OS.open(file, _OS.O_WRONLY | _OS.O_CREAT | _OS.O_EXCL,
0
600)
+ fd = _OS.open(file, _OS.O_WRONLY | _OS.O_CREAT | _OS.O_EXCL,
_M
600)
_OS.close(fd)
try:
me._db = _Q.connect(file)
_OS.close(fd)
try:
me._db = _Q.connect(file)
@@
-731,7
+739,7
@@
class PlainTextBackend (StorageBackend):
me._dirtyp = False
super(PlainTextBackend, me).__init__(*args, **kw)
me._dirtyp = False
super(PlainTextBackend, me).__init__(*args, **kw)
- def _create_file(me, file, mode =
0
600, freshp = False):
+ def _create_file(me, file, mode =
_M
600, freshp = False):
"""
Make sure FILE exists, creating it with the given MODE if necessary.
"""
Make sure FILE exists, creating it with the given MODE if necessary.
@@
-783,7
+791,7
@@
class PlainTextBackend (StorageBackend):
if not line or line.startswith('#'): continue
me._parse_line(line)
if not line or line.startswith('#'): continue
me._parse_line(line)
- def _write_file(me, file, writebody, mode =
0
600, magic = None):
+ def _write_file(me, file, writebody, mode =
_M
600, magic = None):
"""
Update FILE atomically.
"""
Update FILE atomically.
@@
-926,9
+934,9
@@
class DirectoryStorageBackend (PlainTextBackend):
me._parse_meta(line)
def _create(me, file):
me._parse_meta(line)
def _create(me, file):
- _OS.mkdir(file,
0
700)
- _OS.mkdir(_OS.path.join(file, 'pw'),
0
700)
- _OS.mkdir(_OS.path.join(file, 'tmp'),
0
700)
+ _OS.mkdir(file,
_M
700)
+ _OS.mkdir(_OS.path.join(file, 'pw'),
_M
700)
+ _OS.mkdir(_OS.path.join(file, 'tmp'),
_M
700)
me._mark_dirty()
me._dir = file
me._mark_dirty()
me._dir = file
@@
-948,7
+956,7
@@
class DirectoryStorageBackend (PlainTextBackend):
with f: return f.read()
def _put_passwd(me, label, payload):
new = me._pwfile(label, 'tmp')
with f: return f.read()
def _put_passwd(me, label, payload):
new = me._pwfile(label, 'tmp')
- fd = _OS.open(new, _OS.O_WRONLY | _OS.O_CREAT | _OS.O_TRUNC,
0
600)
+ fd = _OS.open(new, _OS.O_WRONLY | _OS.O_CREAT | _OS.O_TRUNC,
_M
600)
_OS.close(fd)
with open(new, 'wb') as f: f.write(payload)
_OS.rename(new, me._pwfile(label))
_OS.close(fd)
with open(new, 'wb') as f: f.write(payload)
_OS.rename(new, me._pwfile(label))