Created
January 6, 2016 08:15
-
-
Save mdaniel/059294c298ad6c89397c to your computer and use it in GitHub Desktop.
Driver for https://github.com/Roguelazer/onepasswordpy.git; ```mkdir onepassword/cli; touch onepassword/cli/__init__.py``` then put this `__main__.py` into `onepassword/cli` and invoke it with `python -m onepassword.cli -k path/to/my/keystore --list`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python | |
# -*- coding: utf-8 -*- | |
from __future__ import absolute_import, print_function, unicode_literals | |
import json | |
import sys | |
from getopt import getopt | |
from getpass import getpass | |
# this is a factory method that one can find in "keychain.patch" below | |
from ..keychain import load_keychain | |
def main(argv): | |
opts, args = getopt(argv[1:], 'k:lv', ['keychain=', 'list', 'verbose']) | |
keychain_path = None | |
verbose = False | |
do_list = False | |
for optval, optarg in opts: | |
if optval in ('-k', '--keychain'): | |
keychain_path = optarg | |
elif optval in ('-l', '--list'): | |
do_list = True | |
elif optval in ('-v', '--verbose'): | |
verbose = True | |
if not keychain_path: | |
print('Usage: {0} [-l|--list] -k|--keychain path/to/keychain'.format(argv[0]), | |
file=sys.stderr) | |
return 1 | |
kc = load_keychain(keychain_path) | |
if do_list: | |
p = getpass() | |
kc.unlock(p) | |
out_fh = sys.stdout | |
if verbose: | |
print('Keys:', file=out_fh) | |
for k in kc.keys: | |
print(' "{0}"'.format(k), file=out_fh) | |
def to_dict(i): | |
result = {d: unicode(getattr(i, d)) for d in dir(i) | |
if d != 'keychain' and | |
not d.startswith('__') and | |
not callable(getattr(i, d))} | |
result['__open__'] = i.decrypt() | |
return result | |
#: :type: list[onepassword.item.AItem] | |
the_items = kc.items | |
open_items = [to_dict(i) for i in the_items] | |
json.dump(open_items, out_fh, sort_keys=True, indent=2) | |
out_fh.flush() | |
out_fh.close() | |
return 0 | |
if __name__ == '__main__': | |
sys.exit(main(sys.argv)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/onepassword/keychain.py b/onepassword/keychain.py | |
index be62c69..6c28649 100644 | |
--- a/onepassword/keychain.py | |
+++ b/onepassword/keychain.py | |
@@ -1,3 +1,4 @@ | |
+# -*- coding: utf-8 -*- | |
import base64 | |
import glob | |
import os.path | |
@@ -5,8 +6,8 @@ import os.path | |
import simplejson | |
from . import crypt_util | |
-from . import padding | |
from .item import AItem, CItem | |
+__docformat__ = 'reStructuredText' | |
EXPECTED_VERSION_MIN = 30000 | |
EXPECTED_VERSION_MAX = 40000 | |
@@ -14,6 +15,8 @@ EXPECTED_VERSION_MAX = 40000 | |
class _AbstractKeychain(object): | |
"""Implementation of common keychain logic (MP design, etc).""" | |
+ items = None | |
+ keys = None | |
def __init__(self, path): | |
self._open(path) | |
@@ -63,8 +66,8 @@ class AKeychain(_AbstractKeychain): | |
)) | |
def unlock(self, password): | |
- keys = self._load_keys(password) | |
- self._load_items(keys) | |
+ self._load_keys(password) | |
+ self._load_items() | |
def _load_keys(self, password): | |
self.keys = {} | |
@@ -79,7 +82,7 @@ class AKeychain(_AbstractKeychain): | |
self.keys[identifier] = crypt_util.a_decrypt_key(key, password) | |
self.levels = levels | |
- def _load_items(self, keys): | |
+ def _load_items(self): | |
items = [] | |
for f in glob.glob(os.path.join(self.base_path, 'data', 'default', '*.1password')): | |
items.append(AItem.new_from_file(f, self)) | |
@@ -176,3 +179,19 @@ class CKeychain(_AbstractKeychain): | |
key, | |
hmac | |
) | |
+ | |
+ | |
+def load_keychain(keychain_path): | |
+ """ | |
+ :type keychain_path: str|unicode | |
+ :param keychain_path: the filesystem path to the keychain | |
+ :return: the appropriate kind of keychain for that path | |
+ :rtype: AKeychain|CKeychain | |
+ :raises ValueError: if unable to recognize the provided path | |
+ """ | |
+ if keychain_path.endswith('.agilekeychain'): | |
+ return AKeychain(keychain_path) | |
+ elif keychain_path.endswith('.cloudkeychain'): | |
+ return CKeychain(keychain_path) | |
+ else: | |
+ raise ValueError('Unrecognized keychain path: "{0}"'.format(keychain_path)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment