Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
).stdout
except subprocess.CalledProcessError as ex:
log.error(f"Failed to get default keychain: {ex}")
raise
# The output format looks like this:
# "/Users/dalemy/Library/Keychains/login.keychain-db"
# Remove whitespace
default_keychain_path = default_keychain_path.strip()
# Remove quotes
default_keychain_path = default_keychain_path[1:]
default_keychain_path = default_keychain_path[:-1]
return Keychain(default_keychain_path, password)
try:
subprocess.run(
settings_command,
shell=True,
check=True
)
except subprocess.CalledProcessError as ex:
log.error("Failed to set keychain settings: %s", ex)
raise
class TemporaryKeychain:
"""Context object for working with a temporary keychain."""
keychain: Optional[Keychain]
def __init__(self) -> None:
self.keychain = None
def __enter__(self) -> "Keychain":
"""Enter the context
:returns: A reference to self
"""
self.keychain = Keychain.create_temporary()
return self.keychain
def __exit__(
self,
exc_type: Optional[Type[BaseException]],
exc_val: Optional[Exception],
def create_temporary() -> 'Keychain':
"""Create a new temporary keychain."""
keychain_name = str(uuid.uuid4()) + ".keychain"
keychain_path = os.path.join(tempfile.gettempdir(), keychain_name)
keychain_password = ''.join(secrets.choice(_PASSWORD_ALPHABET) for _ in range(50))
if os.path.exists(keychain_path):
raise Exception("Cannot create temporary keychain. Path already exists: " + keychain_path)
keychain = Keychain(keychain_path, keychain_password, is_temporary=True)
# We have a reference, but now we need to create the keychain with the
# system.
Keychain._create_keychain(keychain_path, keychain_password)
log.info("Created temporary keychain: %s", keychain_path)
return keychain
def add_to_user_search_list(self) -> None:
"""Add the keychain to the user domain keychain search list."""
log.debug("Adding keychain to user search list: %s", self.path)
# There is no "add" operation, only a "set" one, so we need to get the
# existing ones so that we can set those along with our new one.
previous_keychains = Keychain.list_keychains(domain="user")
if self.path in previous_keychains:
return
command = 'security list-keychains -d user -s '
command += shlex.quote(self.path) + ' '
# Our new keychain needs to be at the start of the list so that it is
# searched before the others are (otherwise they'll prompt for
# passwords)
for path in previous_keychains:
command += shlex.quote(path) + ' '
try:
subprocess.run(