# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/backend.py
# class KeyringBackend(object):
#     """The abstract base class of the keyring, every backend must implement
#     this interface.
#     """
# 
#     #@abc.abstractproperty
#     def priority(cls):
#         """
#         Each backend class must supply a priority, a number (float or integer)
#         indicating the priority of the backend relative to all other backends.
#         The priority need not be static -- it may (and should) vary based
#         attributes of the environment in which is runs (platform, available
#         packages, etc.).
# 
#         A higher number indicates a higher priority. The priority should raise
#         a RuntimeError with a message indicating the underlying cause if the
#         backend is not suitable for the current environment.
# 
#         As a rule of thumb, a priority between zero but less than one is
#         suitable, but a priority of one or greater is recommended.
#         """
# 
#     @properties.ClassProperty
#     @classmethod
#     def viable(cls):
#         with errors.ExceptionRaisedContext() as exc:
#             cls.priority
#         return not bool(exc)
# 
#     @abc.abstractmethod
#     def get_password(self, service, username):
#         """Get password of the username for the service
#         """
#         return None
# 
#     @abc.abstractmethod
#     def set_password(self, service, username, password):
#         """Set password for the username of the service
#         """
#         raise errors.PasswordSetError("reason")
# 
#     # for backward-compatibility, don't require a backend to implement
#     #  delete_password
#     #@abc.abstractmethod
#     def delete_password(self, service, username):
#         """Delete the password for the username of the service.
#         """
#         raise errors.PasswordDeleteError("reason")
# 
# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/errors.py
# class PasswordSetError(Exception):
#     """Raised when the password can't be set.
#     """
# 
# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/errors.py
# class PasswordDeleteError(Exception):
#     """Raised when the password can't be deleted.
#     """
# 
# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/util/properties.py
# class ClassProperty(property):
# class NonDataProperty(object):
#     def __get__(self, cls, owner):
#     def __init__(self, fget):
#     def __get__(self, obj, objtype=None):
# 
# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/py27compat.py
# def add_metaclass(metaclass):
#     def wrapper(cls):


import platform
import subprocess
import re
import binascii
import functools
import warnings
import textwrap
from ..backend import KeyringBackend
from ..errors import PasswordSetError
from ..errors import PasswordDeleteError
from ..util import properties
from ..py27compat import unicode_str
            # set up the call to security.
            cmd = [
                'security',
                SecurityCommand('find', self.store),
                '-g',
                '-a', username,
                '-s', service,
            ]
            if self.keychain:
                cmd.append(self.keychain)
            call = subprocess.Popen(
                cmd,
                stderr=subprocess.PIPE,
                stdout=subprocess.PIPE)
            stdoutdata, stderrdata = call.communicate()
            code = call.returncode
            if code != 0:
                raise OSError("Can't fetch password from system")
            output = stderrdata.decode()
            # check for empty password.
            if output == 'password: \n':
                return ''
            # search for special password pattern.
            matches = Keyring.password_regex.search(output)
            if matches:
                group_dict = matches.groupdict()
                hex = group_dict.get('hex')
                pw = group_dict.get('pw')
                if hex:
                    # it's a weird hex password, decode it.

# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/backend.py
# class KeyringBackend(object):
#     """The abstract base class of the keyring, every backend must implement
#     this interface.
#     """
# 
#     #@abc.abstractproperty
#     def priority(cls):
#         """
#         Each backend class must supply a priority, a number (float or integer)
#         indicating the priority of the backend relative to all other backends.
#         The priority need not be static -- it may (and should) vary based
#         attributes of the environment in which is runs (platform, available
#         packages, etc.).
# 
#         A higher number indicates a higher priority. The priority should raise
#         a RuntimeError with a message indicating the underlying cause if the
#         backend is not suitable for the current environment.
# 
#         As a rule of thumb, a priority between zero but less than one is
#         suitable, but a priority of one or greater is recommended.
#         """
# 
#     @properties.ClassProperty
#     @classmethod
#     def viable(cls):
#         with errors.ExceptionRaisedContext() as exc:
#             cls.priority
#         return not bool(exc)
# 
#     @abc.abstractmethod
#     def get_password(self, service, username):
#         """Get password of the username for the service
#         """
#         return None
# 
#     @abc.abstractmethod
#     def set_password(self, service, username, password):
#         """Set password for the username of the service
#         """
#         raise errors.PasswordSetError("reason")
# 
#     # for backward-compatibility, don't require a backend to implement
#     #  delete_password
#     #@abc.abstractmethod
#     def delete_password(self, service, username):
#         """Delete the password for the username of the service.
#         """
#         raise errors.PasswordDeleteError("reason")
# 
# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/errors.py
# class PasswordSetError(Exception):
#     """Raised when the password can't be set.
#     """
# 
# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/errors.py
# class PasswordDeleteError(Exception):
#     """Raised when the password can't be deleted.
#     """
# 
# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/util/properties.py
# class ClassProperty(property):
# class NonDataProperty(object):
#     def __get__(self, cls, owner):
#     def __init__(self, fget):
#     def __get__(self, obj, objtype=None):
# 
# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/py27compat.py
# def add_metaclass(metaclass):
#     def wrapper(cls):


# Path: resources/lib/PhoneBooks/pyicloud/vendorlibs/keyring/backends/OS_X.py
import platform
import subprocess
import re
import binascii
import functools
import warnings
import textwrap
from ..backend import KeyringBackend
from ..errors import PasswordSetError
from ..errors import PasswordDeleteError
from ..util import properties
from ..py27compat import unicode_str

            # set up the call to security.
            cmd = [
                'security',
                SecurityCommand('find', self.store),
                '-g',
                '-a', username,
                '-s', service,
            ]
            if self.keychain:
                cmd.append(self.keychain)
            call = subprocess.Popen(
                cmd,
                stderr=subprocess.PIPE,
                stdout=subprocess.PIPE)
            stdoutdata, stderrdata = call.communicate()
            code = call.returncode
            if code != 0:
                raise OSError("Can't fetch password from system")
            output = stderrdata.decode()
            # check for empty password.
            if output == 'password: \n':
                return ''
            # search for special password pattern.
            matches = Keyring.password_regex.search(output)
            if matches:
                group_dict = matches.groupdict()
                hex = group_dict.get('hex')
                pw = group_dict.get('pw')
                if hex:
                    # it's a weird hex password, decode it.

                    return unicode_str(binascii.unhexlify(hex), 'utf-8')