/usr/lib/python3/dist-packages/secretstorage/item.py is in python3-secretstorage 2.3.1-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | # SecretStorage module for Python
# Access passwords using the SecretService DBus API
# Author: Dmitry Shachnev, 2013
# License: BSD
"""SecretStorage item contains a *secret*, some *attributes* and a
*label* visible to user. Editing all these properties and reading the
secret is possible only when the :doc:`collection <collection>` storing
the item is unlocked. The collection can be unlocked using collection's
:meth:`~secretstorage.collection.Collection.unlock` method."""
import dbus
from secretstorage.defines import SS_PREFIX
from secretstorage.exceptions import LockedException
from secretstorage.util import InterfaceWrapper, bus_get_object, \
open_session, format_secret, to_unicode, unlock_objects
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
ITEM_IFACE = SS_PREFIX + 'Item'
class Item(object):
"""Represents a secret item."""
def __init__(self, bus, item_path, session=None):
self.item_path = item_path
item_obj = bus_get_object(bus, item_path)
self.session = session
self.bus = bus
self.item_iface = InterfaceWrapper(item_obj, ITEM_IFACE)
self.item_props_iface = InterfaceWrapper(item_obj,
dbus.PROPERTIES_IFACE)
self.item_props_iface.Get(ITEM_IFACE, 'Label', signature='ss')
def __eq__(self, other):
return self.item_path == other.item_path
def is_locked(self):
"""Returns :const:`True` if item is locked, otherwise
:const:`False`."""
return bool(self.item_props_iface.Get(ITEM_IFACE, 'Locked',
signature='ss'))
def ensure_not_locked(self):
"""If collection is locked, raises
:exc:`~secretstorage.exceptions.LockedException`."""
if self.is_locked():
raise LockedException('Item is locked!')
def unlock(self, callback=None):
"""Requests unlocking the item. Usually, this will mean that the
whole collection containing this item will be unlocked.
If `callback` is specified, calls it when unlocking is complete
(see :func:`~secretstorage.util.exec_prompt` description for
details). Otherwise, uses the loop from GLib API and returns a
boolean representing whether the operation was dismissed.
.. versionadded:: 2.1.2"""
return unlock_objects(self.bus, [self.item_path], callback)
def get_attributes(self):
"""Returns item attributes (dictionary)."""
attrs = self.item_props_iface.Get(ITEM_IFACE, 'Attributes',
signature='ss')
return {to_unicode(key): to_unicode(value)
for key, value in attrs.items()}
def set_attributes(self, attributes):
"""Sets item attributes to `attributes` (dictionary)."""
self.item_props_iface.Set(ITEM_IFACE, 'Attributes', attributes,
signature='ssv')
def get_label(self):
"""Returns item label (unicode string)."""
label = self.item_props_iface.Get(ITEM_IFACE, 'Label',
signature='ss')
return to_unicode(label)
def set_label(self, label):
"""Sets item label to `label`."""
self.ensure_not_locked()
self.item_props_iface.Set(ITEM_IFACE, 'Label', label,
signature='ssv')
def delete(self):
"""Deletes the item."""
self.ensure_not_locked()
return self.item_iface.Delete(signature='')
def get_secret(self):
"""Returns item secret (bytestring)."""
self.ensure_not_locked()
if not self.session:
self.session = open_session(self.bus)
secret = self.item_iface.GetSecret(self.session.object_path,
signature='o')
if not self.session.encrypted:
return bytes(bytearray(secret[2]))
aes = algorithms.AES(self.session.aes_key)
aes_iv = bytes(bytearray(secret[1]))
decryptor = Cipher(aes, modes.CBC(aes_iv), default_backend()).decryptor()
encrypted_secret = bytes(bytearray(secret[2]))
padded_secret = decryptor.update(encrypted_secret) + decryptor.finalize()
padded_secret = bytearray(padded_secret)
return bytes(padded_secret[:-padded_secret[-1]])
def get_secret_content_type(self):
"""Returns content type of item secret (string)."""
self.ensure_not_locked()
if not self.session:
self.session = open_session(self.bus)
secret = self.item_iface.GetSecret(self.session.object_path,
signature='o')
return str(secret[3])
def set_secret(self, secret, content_type='text/plain'):
"""Sets item secret to `secret`. If `content_type` is given,
also sets the content type of the secret (``text/plain`` by
default)."""
self.ensure_not_locked()
if not self.session:
self.session = open_session(self.bus)
secret = format_secret(self.session, secret, content_type)
self.item_iface.SetSecret(secret, signature='(oayays)')
def get_created(self):
"""Returns UNIX timestamp (integer) representing the time
when the item was created.
.. versionadded:: 1.1"""
return int(self.item_props_iface.Get(ITEM_IFACE, 'Created',
signature='ss'))
def get_modified(self):
"""Returns UNIX timestamp (integer) representing the time
when the item was last modified."""
return int(self.item_props_iface.Get(ITEM_IFACE, 'Modified',
signature='ss'))
def to_tuple(self):
"""Returns (*attributes*, *secret*) tuple representing the
item."""
self.ensure_not_locked()
return self.get_attributes(), self.get_secret()
|