U
    hWs                     @   s   d Z ddlZddlZddlmZmZmZmZmZm	Z	m
Z
mZmZmZ ddlmZmZ ddlmZmZ ddlmZmZmZ ddlmZ ddlmZ d	Zed
 ZG dd dejZdddZ dd Z!dd Z"dd Z#dd Z$dd Z%dddZ&dd Z'dS )zkThis module provides some utility functions, but these shouldn't
normally be used by external applications.    N)
DBUS_UNKNOWN_METHODDBUS_NO_SUCH_OBJECTDBUS_SERVICE_UNKNOWNDBUS_NO_REPLYDBUS_NOT_SUPPORTEDDBUS_EXEC_FAILEDSS_PATH	SS_PREFIXALGORITHM_DHALGORITHM_PLAIN)Sessionint_to_bytes)ItemNotFoundException"SecretServiceNotAvailableException)Cipher
algorithmsmodes)default_backend)int_from_byteszorg.freedesktop.secretsServicec                   @   s    e Zd ZdZdd Zdd ZdS )InterfaceWrapperzxWraps :cls:`dbus.Interface` class and replaces some D-Bus exceptions
	with :doc:`SecretStorage exceptions <exceptions>`.c                    s    fdd}|S )Nc               
      s   z | |W S  t jjk
r| } zN| tkr6td| tkrNt| | tt	fkrjt
|  W 5 d }~X Y nX d S )NzItem does not exist!)dbus
exceptionsDBusExceptionget_dbus_namer   r   r   get_dbus_messager   r   r   )argskwargsefunction_in 4/usr/lib/python3/dist-packages/secretstorage/util.pyfunction_out   s    z3InterfaceWrapper.catch_errors.<locals>.function_outr!   )selfr    r#   r!   r   r"   catch_errors   s    zInterfaceWrapper.catch_errorsc                 C   s$   t j| |}t|r | |}|S N)r   	Interface__getattr__callabler%   )r$   Z	attributeresultr!   r!   r"   r(   +   s    
zInterfaceWrapper.__getattr__N)__name__
__module____qualname____doc__r%   r(   r!   r!   r!   r"   r      s   r   c              
   C   sf   |pt }z| j||ddW S  tjjk
r` } z$| tttfkrNt	|
  W 5 d}~X Y nX dS )zA wrapper around :meth:`SessionBus.get_object` that raises
	:exc:`~secretstorage.exceptions.SecretServiceNotAvailableException`
	when appropriate.F)Z
introspectN)BUS_NAMEZ
get_objectr   r   r   r   r   r   r   r   r   )busobject_pathZservice_namenamer   r!   r!   r"   bus_get_object1   s    
r3   c              
   C   s   t | t}t|td }t }z$|jttt	|j
dd\}}W nN tjjk
r } z,| tkrh |jtddd\}}d|_W 5 d}~X Y nX tt|d}|| ||_|S )z%Returns a new Secret Service session.r   ZsvZ	signature FNZbig)r3   r   r   r'   r	   r   ZOpenSessionr
   	ByteArrayr   Zmy_public_keyr   r   r   r   r   	encryptedr   	bytearrayZset_server_public_keyr1   )r0   service_objservice_ifacesessionoutputr*   r   r!   r!   r"   open_session>   s,    


r=   c                 C   s   t |ts|d}| js4t| jdt||fS dt|d@  }|tt	|f| 7 }t
d}t| j}t|t|t  }|||  }t| jt|tt	||fS )zHFormats `secret` to make possible to pass it to the
	Secret Service API.zutf-8r5         )
isinstancebytesencoder7   r   ZStructr1   r6   lenr8   osurandomr   ZAESZaes_keyr   r   ZCBCr   	encryptorupdatefinalizeArray)r;   ZsecretZcontent_typeZpaddingZaes_ivZaesrF   Zencrypted_secretr!   r!   r"   format_secretX   s&    


 
rJ   c                    sD   t | |}t|td }|jddd  fdd}|d| dS )	a  Executes the given `prompt`, when complete calls `callback`
	function with two arguments: a boolean representing whether the
	operation was dismissed and a list of unlocked item paths. A main
	loop should be running and registered for this function to work.Promptr5   sr4   c                    s&   t |tjrt|} t| | d S r&   )r@   r   rI   listboolZ	dismissedZunlockedcallbackr!   r"   new_callbackv   s    z!exec_prompt.<locals>.new_callbackZ	CompletedN)r3   r   r'   r	   rK   Zconnect_to_signal)r0   promptrQ   Z
prompt_objZprompt_ifacerR   r!   rP   r"   exec_promptn   s
    
rT   c                    sJ   ddl m} |  g  fdd}t| ||    d d fS )znLike :func:`exec_prompt`, but synchronous (uses loop from GLib
	API). Returns (*dismissed*, *unlocked*) tuple.r   )GLibc                    s     |   |    d S r&   appendquitrO   Zloopr*   r!   r"   rQ      s    

z"exec_prompt_glib.<locals>.callback   )Zgi.repositoryrU   ZMainLooprT   run)r0   rS   rU   rQ   r!   rY   r"   exec_prompt_glib|   s    r\   c                    sJ   ddl m} |g  g  fdd}t| ||    d d fS )zoLike :func:`exec_prompt`, but synchronous (uses loop from PyQt5
	API). Returns (*dismissed*, *unlocked*) tuple.r   )QCoreApplicationc                    s     |   |    d S r&   rV   rO   Zappr*   r!   r"   rQ      s    

z exec_prompt_qt.<locals>.callbackrZ   )ZPyQt5.QtCorer]   rT   Zexec_)r0   rS   r]   rQ   r!   r^   r"   exec_prompt_qt   s    r_   c                 C   sn   t | t}t|t}|j|dd\}}t|}t|dkr\|rLt| || qjt| |d S n|rj|d| dS )a0  Requests unlocking objects specified in `paths`. If `callback`
	is specified, calls it when unlocking is complete (see
	:func:`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.2Zaor4   rZ   r   FN)	r3   r   r   SERVICE_IFACEZUnlockrM   rC   rT   r\   )r0   pathsrQ   r9   r:   Zunlocked_pathsrS   r!   r!   r"   unlock_objects   s    

rb   c                 C   s,   z
t | W S  tk
r&   t|  Y S X dS )z(Converts D-Bus string to unicode string.N)Zunicode	NameErrorstr)stringr!   r!   r"   
to_unicode   s    
rf   )N)N)(r.   r   rD   Zsecretstorage.definesr   r   r   r   r   r   r   r	   r
   r   Zsecretstorage.dhcryptor   r   Zsecretstorage.exceptionsr   r   Z&cryptography.hazmat.primitives.ciphersr   r   r   Zcryptography.hazmat.backendsr   Zcryptography.utilsr   r/   r`   r'   r   r3   r=   rJ   rT   r\   r_   rb   rf   r!   r!   r!   r"   <module>   s&   0

