o
    !`r                     @   sn  d Z ddlZddlmZmZmZ ddlmZmZm	Z	m
Z
mZmZmZ ddlm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Z'ed Z(ed Z)G dd deZ*dedefddZ+dede,de-dee-e,e,e-f fddZ.dede-dee/ee- f fddZ0dedee- de/fddZ1deddfdd Z2dS )!zkThis module provides some utility functions, but these shouldn't
normally be used by external applications.    N)AnyListTuple)DBusAddressDBusErrorResponse	MatchRuleMessageMessageTypenew_method_call
Properties)DBusConnection)
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_backendzorg.freedesktop.secretsServicePromptc                   @   s   e Zd ZdZdedededdfddZd	edefd
dZ	dedededefddZ
dedefddZdedededdfddZdS )DBusAddressWrapperzA wrapper class around :class:`jeepney.wrappers.DBusAddress`
	that adds some additional methods for calling and working with
	properties, and converts error responses to SecretStorage
	exceptions.

	.. versionadded:: 3.0
	path	interface
connectionreturnNc                 C   s   t | |t| || _d S N)r   __init__BUS_NAME_connection)selfr"   r#   r$    r+   4/usr/lib/python3/dist-packages/secretstorage/util.pyr'   '   s   
zDBusAddressWrapper.__init__msgc              
   C   sx   z	| j j|ddW S  ty; } z&|jttfv rtd||jttt	fv r6|j
}t|tr1|d }t|| d }~ww )NT)unwrapzItem does not exist!r   )r)   send_and_get_replyr   namer   r   r   r   r   r   data
isinstancetupler   )r*   r-   respr1   r+   r+   r,   r/   ,   s   


z%DBusAddressWrapper.send_and_get_replymethod	signaturebodyc                 G   s   t | |||}| |S r&   )r
   r/   )r*   r5   r6   r7   r-   r+   r+   r,   call:   s   
zDBusAddressWrapper.callr0   c                 C   s"   t | |}| |\\}}|S r&   )r   getr/   )r*   r0   r-   r6   valuer+   r+   r,   get_property>   s   zDBusAddressWrapper.get_propertyr:   c                 C   s    t | |||}| | d S r&   )r   setr/   )r*   r0   r6   r:   r-   r+   r+   r,   set_propertyC   s   zDBusAddressWrapper.set_property)__name__
__module____qualname____doc__strr   r'   r   r   r/   r8   r;   r=   r+   r+   r+   r,   r!      s    

r!   r$   r%   c           	   
   C   s   t tt| }t }z|ddtdt|jf\}}W n% ty? } z|j	t
kr( |ddtd\}}d|_W Y d}~nd}~ww |\}}|dksJJ t|d}|| ||_|S )z%Returns a new Secret Service session.OpenSessionsvay)s FNbig)r!   r   SERVICE_IFACEr   r8   r   r   my_public_keyr   r0   r   r   	encryptedint
from_bytesset_server_public_keyobject_path)	r$   servicesessionoutputresultr4   r6   r:   keyr+   r+   r,   open_sessionH   s.   

rU   rQ   secretcontent_typec                 C   s   t |tr|d}n	t |tstd| jdusJ | js%| jd||fS | jdus,J dt|d@  }|t|f| 7 }t	
d}t| j}t|t|t  }|||  }| j|||fS )zHFormats `secret` to make possible to pass it to the
	Secret Service API.zutf-8zsecret must be bytesN          )r2   rB   encodebytes	TypeErrorrO   rK   aes_keylenosurandomr   AESr   r   CBCr   	encryptorupdatefinalize)rQ   rV   rW   paddingaes_ivaesrd   encrypted_secretr+   r+   r,   format_secret_   s&   


rk   prompt_pathc                 C   s   t |t| }t|tdtjd}| |}|ddd | |j\}}W d   n1 s.w   Y  |dus9J |dus?J ||fS )zExecutes the prompt in a blocking mode.

	:returns: a tuple; the first element is a boolean value showing
	          whether the operation was dismissed, the second element
	          is a list of unlocked object paths
		Completed)r"   r#   membertyper    rF   rG   N)	r!   PROMPT_IFACEr   r	   signalfilterr8   recv_until_filteredr7   )r$   rl   promptrulesignals	dismissedrS   r+   r+   r,   exec_promptz   s   rx   pathsc                 C   sP   t tt| }|dd|\}}t|dkr&t| |\}\}}|dks$J |S dS )zRequests unlocking objects specified in `paths`.
	Returns a boolean representing whether the operation was dismissed.

	.. versionadded:: 2.1.2Unlockao   F)r!   r   rI   r8   r_   rx   )r$   ry   rP   unlocked_pathsrt   rw   r6   unlockedr+   r+   r,   unlock_objects   s   r   c                 C   s6   t ttd}tdd| d}d|_|dd|  dS )zAdds match rules for the given connection.

	Currently it matches all messages from the Prompt interface, as the
	mock service (unlike GNOME Keyring) does not specify the signal
	destination.

	.. versionadded:: 3.1
	)senderr#   z/org/freedesktop/DBuszorg.freedesktop.DBus)r"   r#   r$   AddMatchrF   N)r   r(   rp   r!   bus_namer8   	serialise)r$   ru   dbusr+   r+   r,   add_match_rules   s   	r   )3rA   r`   typingr   r   r   jeepneyr   r   r   r   r	   r
   r   jeepney.io.blockingr   secretstorage.definesr   r   r   r   r   r   r   r   r   r   secretstorage.dhcryptor   r   secretstorage.exceptionsr   r   &cryptography.hazmat.primitives.ciphersr   r   r   cryptography.hazmat.backendsr   r(   rI   rp   r!   rU   r\   rB   rk   boolrx   r   r   r+   r+   r+   r,   <module>   s6   $0)


