HEX
Server: Apache
System: Linux server2.voipitup.com.au 4.18.0-553.109.1.lve.el8.x86_64 #1 SMP Thu Mar 5 20:23:46 UTC 2026 x86_64
User: posscale (1027)
PHP: 8.2.30
Disabled: exec,passthru,shell_exec,system
Upload Files
File: //opt/saltstack/salt/lib/python3.10/site-packages/salt/__pycache__/crypt.cpython-310.pyc
o

�N�g���@s�dZddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddl
Z
ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlm Z m!Z!m"Z"m#Z#m$Z$m%Z%z"ddl&Z'ddl(m)Z)m*Z*ddl+m,Z,m-Z-ddl.m/Z/m0Z0m1Z1dZ2Wne3y�dZ2Ynwe�4e5�Z6d	Z7d
Z8dZ9dZ:e7�d
e9��Z;e7�d
e:��Z<e8�d
e9��Z=e8�d
e:��Z>e9e:fZ?e8fZ@e7fZAe;e<fZBe=e>fZCdd�ZDdd�ZEd5dd�ZFd6dd�ZGGdd�d�ZHGdd�deH�ZIGdd�deH�ZJejKjLjMdd��ZNdd �ZOd!d"�ZPde=fd#d$�ZQe=fd%d&�ZRd5d'd(�ZSd)d*�ZTd+d,�ZUGd-d.�d.eV�ZWGd/d0�d0�ZXGd1d2�d2eX�ZYGd3d4�d4�ZZdS)7z�
The crypt module manages all of the cryptography functions for minions and
masters, encrypting and decrypting payloads, preparing messages, and
authenticating peers
�N)�AuthenticationError�InvalidKeyError�
MasterExit�SaltClientError�SaltReqTimeoutError�UnsupportedAlgorithm)�hashes�
serialization)�padding�rsa)�Cipher�
algorithms�modesTF�OAEP�PKCS1v15�SHA1�SHA224�-cCstr
ddl}|jjjjjSdS)Nr)�HAS_CRYPTOGRAPHYZ,cryptography.hazmat.backends.openssl.backendZhazmatZbackends�opensslZbackendZ
_fips_enabled)�cryptography�r�>/opt/saltstack/salt/lib/python3.10/site-packages/salt/crypt.py�fips_enabledYs�rcCsd�|�����S)zH
    Clean the key so that it only has unix style line endings (\n)
    �
)�join�strip�
splitlines)�keyrrr�	clean_key`�rcCsNtj�|d�}tjj�d���t�d�tj�	|�r(t�d�	Wd�dStj�	|�r?t�
|tj�s?t�|t
jt
jB�tjj�|d��
}|�d�Wd�n1sWwYt�|t
j�|r�zddl}|�|�j}t�||d	�Wntttfy�YnwWd�dSWd�dSWd�dS1s�wYdS)
zR
    Set an AES dropfile to request the master update the publish session key
    z.dfn�zRotating AES keyz"AES key rotation already requestedN�wb+�r���)�os�pathr�salt�utils�files�	set_umask�log�info�isfile�access�W_OK�chmod�stat�S_IRUSR�S_IWUSR�fopen�write�pwd�getpwnam�pw_uid�chown�KeyError�ImportError�OSError)Zcachedir�userZdfn�fp_r6�uidrrr�dropfilegs6

������"�r@�c
Cs�tj�||�}|�d�}|�d�}t�||�}	tj�|�r|St�|tj�s4td�	tj�
|�t�����t
jj�d��Lt
jj�|d��4}
|rZt�|���}tjj}t�rYtjj}nt��}tjj}|	jtjj||d�}
|
�|
�Wd�n1s{wYWd�n1s�wY|	��}t
jj�|d��}
|jtjjtj j!d�}
|
�|
�Wd�n1s�wYt�"|d	�|r�zd
dl#}|�$|�j%}t�&||d�t�&||d�W|St't(tfy�Y|Sw|S)a
    Generate a RSA public keypair for use with salt

    :param str keydir: The directory to write the keypair to
    :param str keyname: The type of salt server for whom this key should be written. (i.e. 'master' or 'minion')
    :param int keysize: The number of bits in the key
    :param str user: The user on the system who should own this keypair
    :param str passphrase: The passphrase which should be used to encrypt the private key

    :rtype: str
    :return: Path on the filesystem to the RSA private key
    �.pem�.pubz*Write access denied to "{}" for user "{}".r!r"��encoding�format�encryption_algorithmN�rErF�rr$))r%r&rrZgenerate_private_keyr-r.r/r<rF�abspath�getpassZgetuserr'r(r)r*r4r	ZBestAvailableEncryption�encode�
PrivateFormat�TraditionalOpenSSLrZPKCS8�NoEncryption�
private_bytes�Encoding�PEMr5�
public_key�public_bytes�PublicFormat�SubjectPublicKeyInfor0r6r7r8r9r:r;)ZkeydirZkeyname�keysizer=�
passphrase�e�baseZpriv�pub�gen�f�enc�_format�pem�pubkeyr6r?rrr�gen_keys�sh

�����������rbc@s0eZdZedd��Zedd��Zedd��ZdS)�BaseKeycC�F|tvrtd|����|�dd�\}}|tvrtd|����tt|�S)NzInvalid signing algorithm: r��Invalid padding algorithm: )�VALID_SIGNING_ALGORITHMSr�split�VALID_PADDING_FOR_SIGNING�getattrr
��	algorithmZ_pad�_hashrrr�parse_padding_for_signing��
z!BaseKey.parse_padding_for_signingcCrd)N�Invalid encryption algorithm: rrerf)�VALID_ENCRYPTION_ALGORITHMSrrh�VALID_PADDING_FOR_ENCRYPTIONrjr
rkrrr�parse_padding_for_encryption�roz$BaseKey.parse_padding_for_encryptioncCs@d|vrtd|����|�dd�\}}|tvrtd��tt|�S)NrrprezInvalid hashing algorithm)rrh�VALID_HASHES�	Exceptionrjrrkrrr�
parse_hash�s
zBaseKey.parse_hashN)�__name__�
__module__�__qualname__�staticmethodrnrsrvrrrrrc�s

rcc@s6eZdZd
dd�Zdd�Zefdd�Zefdd	�ZdS)�
PrivateKeyNcCst||�|_dS�N)�get_rsa_keyr)�selfr&rXrrr�__init__�szPrivateKey.__init__cCs2|jjtjjtjjt��d�}tj	j
�|��|�S)NrD)
rrPr	rQrRrMrNrOr'r(�rsax931Z
RSAX931Signer�sign)r~�datar`rrr�encrypt�s�zPrivateKey.encryptcCsV|�|�}|�|�}z|j�tjj�|�|�|��WStj	j
y*t
d|����w)N�Unsupported algorithm: )rnrvrr�r'r(�stringutils�to_bytesr�
exceptionsr�r~r�rl�_paddingrmrrrr��s

��zPrivateKey.signcCs\|�|�}|�|�}z|j�||tj|�d�|�dd��WStjjy-td|����w�N�rl)ZmgfrlZlabelr�)	rsrvr�decryptr
�MGF1rr�rr�rrrr��s

���zPrivateKey.decryptr|)	rwrxryrr��
PKCS1v15_SHA1r��	OAEP_SHA1r�rrrrr{�s


r{c@s4eZdZdd�Zefdd�Zefdd�Zdd�Zd	S)
�	PublicKeycCsltjj�|d��$}z
t�|���|_Wnty#}zt	d��d}~wwWd�dS1s/wYdS)N�rbzInvalid key)
r'r(r)r4r	�load_pem_public_key�readr�
ValueErrorr)r~r&�fp�excrrrrs���"�zPublicKey.__init__cCsj|�|�}|�|�}tjj�|�}z|j�||tj	|�d�|�dd��WSt
jjy4td|����wr�)
rsrvr'r(r�r�rr�r
r�rr�r)r~r�rlr�rmZbdatarrrr�s

���zPublicKey.encryptcCs^|�|�}|�|�}z|j�tjj�|�tjj�|�|�|��WdStj	j
y.YdSw)NFT)rnrvr�verifyr'r(r�r�rr�ZInvalidSignature)r~r��	signaturerlr�rmrrrr�'s

���zPublicKey.verifycCs0|jjtjjtjjd�}tjj	�
|�}|�|�S)NrH)rrTr	rQrRrUrVr'r(r�ZRSAX931Verifierr�)r~r�r`Zverifierrrrr�5s�
zPublicKey.decryptN)	rwrxryrr�r�r�r�r�rrrrr�s
r�cCsbt�d�|r|��}nd}tjj�|d��}tj|�	�|d�Wd�S1s*wYdS)a�
    Load a private key from disk.  `timestamp` above is intended to be the
    timestamp of the file's last modification. This fn is memoized so if it is
    called with the same path and timestamp (the file's last modified time) the
    second time the result is returned from the memoization.  If the file gets
    modified then the params are different and the key is loaded from disk.
    z3salt.crypt._get_key_with_evict: Loading private keyNr���password)
r+�debugrLr'r(r)r4r	�load_pem_private_keyr�)r&�	timestamprXr�r]rrr�_get_key_with_evict>s
	
�$�r�cCs"t�d�t|ttj�|��|�S)a=
    Read a private key off the disk.  Poor man's simple cache in effect here,
    we memoize the result of calling _get_rsa_with_evict.  This means the first
    time _get_key_with_evict is called with a path and a timestamp the result
    is cached.  If the file (the private key) does not change then its
    timestamp will not change and the next time the result is returned from the
    cache.  If the key DOES change the next time _get_rsa_with_evict is called
    it is called with different parameters and the fn is run fully to retrieve
    the key from disk.
    z+salt.crypt.get_rsa_key: Loading private key)r+r�r��strr%r&�getmtime)r&rXrrrr}Ss
r}cCs�t�d�z#tjj�|d��}t�|���Wd�WS1s!wYWdSt	y3t
d��tjj
y?t
d��w)z)
    Read a public key off the disk.
    z.salt.crypt.get_rsa_pub_key: Loading public keyr�NzEncountered bad RSA public keyzUnsupported key algorithm)r+r�r'r(r)r4r	r�r�r�rrr�r)r&r�rrr�get_rsa_pub_keybs
(��r�cCst||��||�S)zS
    Use Crypto.Signature.PKCS1_v1_5 to sign a message. Returns the signature.
    )r{r�)Zprivkey_path�messagerXrlrrr�sign_messagepr r�cCst�d�t|��|||�S)zu
    Use Crypto.Signature.PKCS1_v1_5 to verify the signature on a message.
    Returns True for valid signature.
    z/salt.crypt.verify_signature: Loading public key)r+r�r�r�)�pubkey_pathr�r�rlrrr�verify_signaturews
r�c	Cs�tjj�|��}|��}Wd�n1swYt|||�}t�|�}tj	�
|�r.dSt�dtj	�
|�tj	�
|��tj	�
|�rKt�d|�dStjj�|d��}|�tjj�|��Wd�n1shwYt�d|�dS)zp
    creates a signature for the given public-key with
    the given private key and writes it to sign_path
    NFz$Calculating signature for %s with %szFSignature file %s already exists, please remove it first and try againr"zWrote signature to %sT)r'r(r)r4r�r��binascii�
b2a_base64r%r&r-r+Ztrace�basenamer5r�r�)	Z	priv_path�pub_pathZ	sign_pathrXr>Zmpub_64Zmpub_sigZmpub_sig_64Zsig_frrr�
gen_signature�s.
�


����r�cCs
|�|�S)a
    Generate an M2Crypto-compatible signature

    :param Crypto.PublicKey.RSA._RSAobj key: The RSA key object
    :param str message: The message to sign
    :rtype: str
    :return: The signature, or an empty string if the signature operation failed
    )r�)rr�rrr�private_encrypt�s
	r�cCs0tj|��dd�}|�|t���}tjj�	|�S)Nr�)
r	r�rLr�r
rr'r(r�Z
to_unicode)Zrsa_keyZpwdatarr�rrr�pwdata_decrypt�s�r�cs\eZdZdZ�fdd�Zdd�Zdd�Zdd
d�Zddd
�Zdd�Z	dd�Z
dd�Z�ZS)�
MasterKeysz�
    The Master Keys class is used to manage the RSA public key pair used for
    authentication by the master.

    It also generates a signing key-pair if enabled with master_sign_key_name.
    cs�t���||_tj�|jdd�|_tj�|jdd�|_tj	j
�|jd|j�}|j|d�|_
d|_|dr�|dr�tj�|jd|d�|_tj�|j�r�tj	j�|j��}t|���|_Wd�n1sjwYt�d	tj�|j�|jd�dSt�d
|j�t�d�t�d�dStj	j
�|jd
|j�}tj�|jd|dd�|_tj�|jd|dd�|_|j|dd�|_dSdS)N�pki_dirz
master.pubz
master.pem�key_pass)rXZmaster_sign_pubkeyZmaster_use_pubkey_signatureZmaster_pubkey_signaturezRead %s's signature from %szmSigning the master.pub key with a signature is enabled but no signature file found at the defined location %szgThe signature-file may be either named differently or has to be created with 'salt-key --gen-signature'reZsigning_key_pass�master_sign_key_namerCrB)�name)�superr�optsr%r&rr��rsa_pathr'r(ZsdbZsdb_get�_MasterKeys__get_keysr�
pub_signatureZsig_pathr-r)r4rr�r+r,r��error�sys�exit�
pub_sign_path�
rsa_sign_pathZsign_key)r~r�r�r>��	__class__rrr�sP
���������zMasterKeys.__init__cCs|�|d�dS�Nr�)r)r~�staterrr�__setstate__�szMasterKeys.__setstate__cCs
d|jiSr�)r��r~rrr�__getstate__�s
zMasterKeys.__getstate__�masterNc
CsNtj�|jd|d�}tj�|�s.t�d||jd�t|jd||jd|j�d�|�zt	||�}Wn_t
yM}zd|�d�}WYd}~nUd}~wtyd}zd|�d	�}WYd}~n>d}~wty{}zd|�d
�}WYd}~n'd}~wt
jjy�}zd|�d
�}WYd}~nd}~wwt�d||�|St�|�t|��)z?
        Returns a key object for a key in the pki-dir
        r�rBzGenerating %s keys: %srWr=zUnable to read key: z; file may be corruptNz; passphrase may be incorrectz$; key contains unsupported algorithmzLoaded %s key: %s)r%r&rr��existsr+r,rb�getr{r��	TypeErrorrrr�rr�r�r)r~r�rXr&rrYr�rrrZ
__get_keys�s:
������
zMasterKeys.__get_keyscCs�tj�|jd|d�}tj�|�s=|j��}tjj	�
|d��}|�|jt
jjt
jjd��Wd�n1s8wYtjj	�
|��}t|���Wd�S1sUwYdS)z_
        Return the string representation of a public key
        in the pki-directory
        r�rCr"rHN)r%r&rr�r-rrSr'r(r)r4r5rTr	rQrRrUrVrr�)r~r�r&rar]Zrfhrrr�get_pub_strs
���
$�zMasterKeys.get_pub_strcC�|j|jfSr|)r�r�r�rrr�get_mkey_paths-�zMasterKeys.get_mkey_pathscCr�r|)r�r�r�rrr�get_sign_paths0r�zMasterKeys.get_sign_pathscC�|jS)z�
        returns the base64 encoded signature from the signature file
        or None if the master has its own signing keys
        )r�r�rrr�pubkey_signature3szMasterKeys.pubkey_signature)r�N)r�)
rwrxry�__doc__rr�r�r�r�r�r�r��
__classcell__rrr�rr��s;

r�c@seZdZdZe��ZiZd4dd�Ze	d4dd��Z
d4dd�Zd4d	d
�Zdd�Z
ed
d��Zedd��Zedd��Zdd�Zd4dd�Zejjjjdd��Zejjjjd5dd��Zdd�Zd d!�Zd"d#�Zd$d%�Zd6d&d'�Zd(d)�Z d*d+�Z!d,d-�Z"d6d.d/�Z#d6d0d1�Z$d2d3�Z%dS)7�	AsyncAuthzP
    Set up an Async object to maintain authentication with the salt master
    NcCs�|p	tjjjj��}|tjvrt�	�tj|<tj|}|�
|�}|�|�}|durAt�
d|�t�|�}|j||d�|||<|St�
d|�|S)zC
        Only create one instance of AsyncAuth per __key()
        Nz!Initializing new AsyncAuth for %s��io_loopzRe-using AsyncAuth for %s)r'�ext�tornado�ioloop�IOLoop�currentr��instance_map�weakref�WeakValueDictionary�_AsyncAuth__keyr�r+r��object�__new__�__singleton_init__)�clsr�r�Zloop_instance_mapr�authrrrr�Gs




�zAsyncAuth.__new__cC�|d|d|dfS�Nr��id�
master_urir�r�r�r�rrr�__key_��zAsyncAuth.__keycCsdSr|r�r~r�r�rrrrhszAsyncAuth.__init__cCs�||_tjj�t���|_tj	�
|jdd�|_tj	�
|jdd�|_|jddkr.d|_
nd|_
tj	�|j�s<|��|pEtjjjj��|_|�|j�}|tjvrstj|}||_t|j|d�|_tjjj��|_|j�d	�d
S|��d
S)��
        Init an Auth instance

        :param dict opts: Options for this server
        :return: Auth instance
        :rtype: Auth
        r��
minion.pub�
minion.pem�__roleZsyndic�syndic_master.pub�minion_master.pub�aesTN) r�r'r(r�r��	Crypticle�generate_key_string�tokenr%r&rr�r��mpubr-�get_keysr�r�r�r�r�r�r�r��	creds_map�_creds�
_crypticle�
concurrent�Future�_authenticate_future�
set_result�authenticate)r~r�r�r�credsrrrr�ls$

zAsyncAuth.__singleton_init__cCs\|j}|�|t�|j|��}||t|�<|jD]}|dvrqt||t�|j||��q|S�Nr�)r�r��copy�deepcopyr�r��__dict__�setattr)r~�memor��resultrrrr�__deepcopy__�s
zAsyncAuth.__deepcopy__cCr�r|)r�r�rrrr���zAsyncAuth.credscCr�r|)r�r�rrr�	crypticle�rzAsyncAuth.crypticlecCs"t|d�o|j��o|j��duS)Nr�)�hasattrr��done�	exceptionr�rrr�
authenticated�s

��zAsyncAuth.authenticatedcCs4|jr|`|�|j�}|tjvrtj|=dSdSdSr|)rr�r�r�r�r�)r~rrrr�
invalidate�s
�zAsyncAuth.invalidatecsbt�d�r�j��s�j}ntjjj��}|�_�j�	�j
��dur/��fdd�}|�|�|S)z�
        Ask for this client to reconnect to the origin

        This function will de-dupe all calls here and return a *single* future
        for the sign-in-- whis way callers can all assume there aren't others
        r�Ncs|��}�j��|�dSr|)rr��add_callback)�future�response��callbackr~rr�
handle_future�sz-AsyncAuth.authenticate.<locals>.handle_future)rr�r	r'r�r�r�r�r�r
�
_authenticateZadd_done_callback)r~rrrrrrr��s	��
zAsyncAuth.authenticatec	cs�|jd}|jd}|s|}d}tjjjj|jd|jd���\}d}	z	|j|d�V}Wnty@}z|}WYd}~nfd}~ww|dkr�|j�	d	�durRtd
�}nP|j�	d�rm|j�	dd�rdtd
�}n>t
d
�t�d�|r~t
�d|�tjjj�|�V||kr�||7}t
�d|�q"|dkr�t
�d�n|dkr�t
�d�n	t|t�r�d|vr�|j�	d	�dur�td�}z
tj|�|j�=Wn	ty�Ynw|s�td�}|j�|�n�|�|j�}|tjvr�t
�d|�|tj|<||_t|j|d�|_n!|jd|dk�rt
�d|�|tj|<||_t|j|d�|_|j� d�|j�	d�du�rktj!j"j#|j�	d�|jdd��}|�$||d�tj!j"j%dd d!��Wd�n!1�sVwYWd�dSWd�dSWd�dSWd�dS1�swYdS)"�]
        Authenticate with the master, this method breaks the functional
        paradigm, it will update the master information from a fresh sign
        in, signing in can occur as often as needed to keep up with the
        revolving master AES key.

        :rtype: Crypticle
        :returns: A crypticle used for encryption operations
        �acceptance_wait_time�acceptance_wait_time_maxN�clear��cryptr�T��channel�retry�detect_modezDetect mode is on�caller�
local_masters�PMinion failed to authenticate with the master, has the minion key been accepted?�� Waiting %s seconds before retry.�Authentication wait time is %s�bad enc algozyThis minion is using a encryption algorithm that is not supported by it's Master. Please check your minion configutation.�bad sig algozvThis minion is using a signing algorithm that is not supported by it's Master. Please check your minion configutation.r�z	-|RETRY|-z3Attempt to authenticate with the salt master failed�%s Got new master aes key.�$%s The master's aes key has changed.Zauth_eventsr�F)r��listen)rr�r�r�)�prefix�suffix)&r�r'r�client�AsyncReqChannel�factoryr��sign_inrr��printr�r�r+r,r�r�r\�sleepr�r��
isinstance�dictr�r�r�r:r�Z
set_exceptionr�r�r�r�r(�eventZ	get_eventZ
fire_eventZtagify)	r~rrr�rr�r�rr3rrrr�s��



�����
������


��� ��A�S�T$�zAsyncAuth._authenticate�<Trec

cs4�|j�dd�}|dur|}|j�dd�}|dur|}|j�dd�}|dur(|}d}|s;d}tjjjj|jd|jd�}|��}	zDz|j	|	||d	�V}
Wn0t
y{}z$|rct�d
|�tj
jj�d��|j�d�durstj
jj�d��td
��d}~wwW|r�|��n|r�|��ww|�|	|
�}tj
jj�|��)�
        Send a sign in request to the master, sets the key information and
        returns a dict containing the master publish interface to bind to
        and the decrypted aes key for transport decryption.

        :param int timeout: Number of seconds to wait before timing out the sign-in request
        :param bool safe: If True, do not raise an exception on timeout. Retry instead.
        :param int tries: The number of times to try to authenticate before giving up.

        :raises SaltReqTimeoutError: If the sign-in request has timed out and :param safe: is not set

        :return: Return a string on failure indicating the reason for failure. On success, return a dictionary
        with the publication port and the shared AES key.

        �auth_timeoutN�
auth_safemode�
auth_triesFTrr��tries�timeout�SaltReqTimeoutError: %srr�FAttempt to authenticate with the salt master failed with timeout error)r�r�r'rr+r,r-r��minion_sign_in_payload�sendrr+�warningr�r�r\ZReturnr�close�handle_signin_response)
r~r;�safer:rr6r7r8�
close_channel�sign_in_payload�payloadrY�retrrrr.8sN�

�����
��
�zAsyncAuth.sign_inc	Cs�i}tj�|jd|j�}|jd|d<t|t�rd|vr%t�d|�dSt|dt�rRd|dvrR|dddkrBt�d|�dS|dddkrRt�d|�dS|d}|d	}t	j
�|�}d
|vr�|j|d|vd�|d
<|d
s�t�
dt	jj|�td��tj�|jd|j�}tj�|�r�t||||jdd�s�t�
d�td��|d|dkr�t�
d�td��d|vr�|ds�|jdr�t�d�dSt�
d�t�t�dd��t�t	jjj�n|ddkr�dSt�d|jd�dS|j�d d��r!|j�d!|j�d"d��}|�r t	jjj||jd#d$�|k�r |� ||�n#|j�d"d��rDt	jjj||jd#d$�|jd"k�rD|� |jd"|�|d%|d%<|S)&Nr�r��loadzSign-in attempt failed: %sFrGr$r%�sig�pub_keyr���
master_pubr�a6The Salt Master server's public key did not authenticate!
The master may need to be updated if it is a version of Salt lower than %s, or
If you are confident that you are connecting to a valid Salt Master, then remove the master public key and restart the Salt Minion.
The master public key can be found at:
%szInvalid master key�signing_algorithmr�z'The payload signature did not validate.zInvalid signature�noncez#The payload nonce did not validate.z
Invalid nonceZrejected_retryz�The Salt Master has rejected this minion's public key.
To repair this issue, delete the public key for this minion on the Salt Master.
The Salt Minion will attempt to re-authenicate.rz�The Salt Master has rejected this minion's public key!
To repair this issue, delete the public key for this minion on the Salt Master and restart this minion.
Or restart the Salt Master in open mode to clean out the keys. The Salt Minion will now exit.�
��fullz�The Salt Master has cached the public key for this node, this salt minion will wait for %s seconds before attempting to re-authenticater�
syndic_master�
syndic_fingerZ
master_finger�	hash_type�Zsum_typeZpublish_port)!r%r&rr�r�r1r2r+r�r'rF�loads�
verify_master�critical�version�__version__rr�r��timer0�random�randintr�r��defaultsZ	exitcodes�	EX_NOPERMr�r(r�
pem_finger�_finger_fail)	r~rErFr��m_pub_fnZclear_signed_dataZclear_signatureZmaster_pubkey_pathrSrrrrBos�
���


��
��
���
��z AsyncAuth.handle_signin_responsecCs�|j�dd�}tjj�|jd|�tj�|j	�s3t
�d|jd�t|jdd|jd|j�d��t
|j	d�}t
�d|j	�|S)	z�
        Return keypair object for the minion.

        :rtype: Crypto.PublicKey.RSA._RSAobj
        :return: The RSA keypair
        r=�rootr�zGenerating keys: %sZminionrWNzLoaded minion key: %s)r�r�r'r(r�Zcheck_path_traversalr%r&r�r�r+r,rbr{r�)r~r=rrrrr��s
�zAsyncAuth.get_keyscCst|��|�S)z�
        Encrypt a string with the minion private key to verify identity
        with the master.

        :param str clear_tok: A plaintext token to encrypt
        :return: Encrypted token
        :rtype: str
        )r�r�)r~Z	clear_tokrrr�	gen_token�s	zAsyncAuth.gen_tokenc
CsLi}d|d<|jd|d<t��j|d<|jd|d<|jd|d<d	|jvr@i}|jd	D]
}|jd
�|d�||<q.||d	<ztj�|jd|j�}t	|�}|�
|j|jd�|d
<Wn%tykt
�d�Ynty�}zt
�d|�WYd}~nd}~wwtjj�|j��}t|���|d<Wd�|S1s�wY|S)a
        Generates the payload used to authenticate with the master
        server. This payload consists of the passed in id_ and the ssh
        public key to encrypt the AES key sent back from the master.

        :return: Payload dictionary
        :rtype: dict
        Z_auth�cmdr�rNrGZenc_algorMZsig_algo�autosign_grainsZgrainsNr�r�zMaster public key not foundz#Exception while encrypting token %sr[)r��uuidZuuid4�hexr�r%r&rr�r�r�r��FileNotFoundErrorr+r�rur'r(r)r4r�rr�)r~rFrfZgrainr�r[r�r]rrrr>s:	
���
��z AsyncAuth.minion_sign_in_payloadc
Cs,|j�dd�rt�dd�t����nt�d�|��}|�	|d|jd�}d|vrit
j�|jd	|j�}t
j�
|�rhzt|�}Wn
tyLYd
Swt�|���}tjj�|�}|�	|d�}||krhd
Snd
Stjj�|�}d|vr{|�d�Sd|vr�|�	|d|jd�}	||	fS|s�|dfSd
S)
af
        This function is used to decrypt the AES seed phrase returned from
        the master server. The seed phrase is decrypted with the SSH RSA
        host key.

        Pass in the encrypted AES key.
        Returns the decrypted AES seed key, a string

        :param dict payload: The incoming payload. This is a dictionary which may have the following keys:
            'aes': The shared AES key
            'enc': The format of the message. ('clear', 'pub', etc)
            'sig': The message signature
            'publish_port': The TCP port which published the message
            'token': The encrypted token used to verify the message.
            'pub_key': The public key of the sender.

        :rtype: str
        :return: The decrypted token that was provided, with padding.

        :rtype: str
        :return: The decrypted AES seed key
        Zauth_trbFzAuth Called: %s�z%Decrypting the current master AES keyr�rGrIr�)rjrjz_|-r�)r�r�r+r@r�	traceback�format_stackr�r�r�r%r&r�r�r�ru�hashlib�sha256�	hexdigestr'r(r�r�Zto_strrh)
r~rFrLrZkey_strZm_pathZmkey�digestZm_digestr�rrr�decrypt_aes"s:
��
zAsyncAuth.decrypt_aescCs�|jdrKtj�|jd|jdd�}tj�|�r)t||t�|�|jdd�}nt�	dtj�
|��dS|rDt�d|jdd�d	St�d
�dSt�	d�dS)z�
        Wraps the verify_signature method so we have
        additional checks.

        :rtype: bool
        :return: Success or failure of public key verification
        r�r�rCrMr�zkVerification public key %s does not exist. You need to copy it from the master to the minions pki directoryFzTSuccessfully verified signature of master public key with verification public key %sTz(Failed to verify signature of public keyz�Failed to verify the signature of the message because the verification key-pairs name is not defined. Please make sure that master_sign_key_name is defined.)r�r%r&rr-r�r��
a2b_base64r+r�r�r�)r~r�rIr&�resrrr�verify_pubkey_sig[s8
��
��
�zAsyncAuth.verify_pubkey_sigc
Cs�za|�|d|d�rVt�d|jd�tj�|jd|j�}tj	j
�|j�dd��}tj	j
j|d|d��}|�tj	j�|d��Wd�Wd	S1sNwYWd	St�d
|jd�WdStyv}z	t�d�t|��d}~ww)
NrJ�pub_sigz9Received signed and verified master pubkey from master %sr�r�r=r")r?TzLReceived signed public-key from master %s but signature verification failed!FzCThere was an error while verifying the masters public-key signature)rtr+r,r�r%r&rr�r'r(r=Zget_uidr�r)Zfpopenr5r�r�r�ru)r~rFrbr?ZwfhZsign_excrrr�verify_signing_master�s4�
������zAsyncAuth.verify_signing_mastercCstd|vr|jdrdSd|vr|jdsdSd|vr&|jds&t�d�dSd|vr6|jdr8t�d�dSdSdS)a%
        Checks if both master and minion either sign (master) and
        verify (minion). If one side does not, it should fail.

        :param dict payload: The incoming payload. This is a dictionary which may have the following keys:
            'aes': The shared AES key
            'enc': The format of the message. ('clear', 'pub', 'aes')
            'publish_port': The TCP port which published the message
            'token': The encrypted token used to verify the message.
            'pub_key': The RSA public key of the sender.
        ru�verify_master_pubkey_signTz�The masters sent its public-key signature, but signature verification is not enabled on the minion. Either enable signature verification on the minion or disable signing the public key on the master!Fz�The master did not send its public-key signature, but signature verification is enabled on the minion. Either disable signature verification on the minion or enable signing the public on the master!N)r�r+r�)r~rFrrr�check_auth_deps�s
���zAsyncAuth.check_auth_depscCsh|r*z|�||�\}}||jkrt�d�WdSW|Sty)t�d�YdSw|�||�\}}|S)ag
        Return the AES key received from the master after the minion has been
        successfully authenticated.

        :param dict payload: The incoming payload. This is a dictionary which may have the following keys:
            'aes': The shared AES key
            'enc': The format of the message. ('clear', 'pub', etc)
            'publish_port': The TCP port which published the message
            'token': The encrypted token used to verify the message.
            'pub_key': The RSA public key of the sender.

        :rtype: str
        :return: The shared AES key received from the master.
        z4The master failed to decrypt the random minion tokenrj)rqr�r+r�ru)r~rFrLr�r�rrr�extract_aes�s

��
�zAsyncAuth.extract_aescCs�tj�|jd|j�}tj�|�}|r�|r�|jds�tjj�	|��}t
|���}Wd�n1s2wY|d|kr^|�|�sDdS|jdrW|�
|�rU|j|dd�SdSt�d	�dS|�|�sedS|jd
r�|�
|�rt|�|�St�d|jdd
�dS|�|�S|�|�s�dS|jdr�|�
|�r�|j|dd�SdS|s�tjj�	|d��}|�tjj�|d��Wd�n1s�wY|j|dd�S)a
        Verify that the master is the same one that was previously accepted.

        :param dict payload: The incoming payload. This is a dictionary which may have the following keys:
            'aes': The shared AES key
            'enc': The format of the message. ('clear', 'pub', etc)
            'publish_port': The TCP port which published the message
            'token': The encrypted token used to verify the message.
            'pub_key': The RSA public key of the sender.
        :param bool master_pub: Operate as if minion had no master pubkey when it sent auth request, i.e. don't verify
        the minion signature

        :rtype: str
        :return: An empty string on verification failure. On success, the decrypted AES message in the payload.
        r�Z	open_modeNrJrjrwFrKzfThe master key has changed, the salt master could have been subverted, verify salt master's public keyZalways_verify_signaturezSThe masters public could not be verified. Is the verification pubkey %s up to date?r�rCr")r%r&rr�r�r-r'r(r)r4rr�rxrvryr+r�r5r�r�)r~rFrLrbZm_pub_existsr>Zlocal_master_pubrrrrW�sN�


�



�



�zAsyncAuth.verify_mastercCs0t�d|tjjj||jdd��t�d�dS)Na	The specified fingerprint in the master configuration file:
%s
Does not match the authenticating master's key:
%s
Verify that the configured fingerprint matches the fingerprint of the correct master and that this minion is not subject to a man-in-the-middle attack.rTrU�*)	r+rXr'r(rr`r�r�r�)r~ZfingerZ
master_keyrrrra1s�	zAsyncAuth._finger_failr|�r4TreN)T)&rwrxryr�r��WeakKeyDictionaryr�r�r��classmethodr�rr�r�propertyr�rrrr�r'r�r�r\�	coroutinerr.rBr�rdr>rqrtrvrxryrWrarrrrr�;sB









l6o
"9-
&
Mr�csxeZdZdZe��Zddd�Zeddd��Z	d�fdd�	Z
dd	d
�Zedd��Z
ed
d��Zddd�Zddd�Z�ZS)�SAuthzJ
    Set up an object to maintain authentication with the salt master
    NcCs\|�|�}tj�|�}|dur&t�d|�t�|�}|�|�|tj|<|St�d|�|S)z?
        Only create one instance of SAuth per __key()
        NzInitializing new SAuth for %szRe-using SAuth for %s)	�_SAuth__keyr��	instancesr�r+r�r�r�r�)r�r�r�rr�rrrr�Gs



�z
SAuth.__new__cCr�r�rr�rrrr�Vr�zSAuth.__keycst�j||d�dSr�)r�rr�r�rrr_szSAuth.__init__cCs�||_tjj�t���|_tj	�
|jdd�|_tj	�
|jdd�|_d|_
d|jvr/d|_nd|jvr8d|_nd	|_tj	�|j�sH|��dSdS)
r�r�r�r�NrRr�Zalert_masterzmonitor_master.pubr�)r�r'r(r�r�r�r�r�r%r&rr�r�r�r�r-r�r�rrrr�cs

�zSAuth.__singleton_init__cC�t|d�s	|��|jS)Nr�)rr�r�r�rrrr�y�
zSAuth.credscCr�)Nr�)rr�r�r�rrrrr�zSAuth.crypticlecCsd|jd}|jd}|s|}tjjjj|jdd���}	|j|d�}|dkr\|j�d�r@|j�d	d
�r7td�}n&t	d�t
�d�|rMt�
d
|�t�|�||kr[||7}t�d|�q	|jd
urut�d|�||_t|j|d�|_n+|jd|dkr�t�d|�||_t|j|d�|_Wd
�d
SWd
�d
SWd
�d
S1s�wYd
S)rrrr�rTrrrrNr r!r"r#r&r�r')r�r'rr+�
ReqChannelr-r.r�rr/r�r�r+r,r[r0r�r�r�r�r�)r~�_rrrr�r�rrrr��s\



���
�
�
�&�%"�zSAuth.authenticater4Trec
Cs4i}|j�dd�}|dur|}|j�dd�}|dur|}|j�dd�}|dur)|}tj�|jd|j�}	|jd|d<d}
|sLd}
tjjj	j
|jd	d
�}|��}z;z
|j|||d�}Wn(t
y�}
z|r{t�d|
�WYd}
~
W|
ry|��d
Sd
Std��d}
~
wwW|
r�|��n|
r�|��ww|�||�S)r5r6Nr7r8r�r�FTrr�r9r<rr=)r�r�r%r&rr�r'rr+r�r-r>r?rr+r@rArrB)r~r;rCr:rr�r6r7r8rbrDrErFrYrrrr.�sN������	��
�z
SAuth.sign_inr|r{)rwrxryr�r�r�r�r�r}r�rr�r~r�rr�r.r�rrr�rr�?s




9r�c@sjeZdZdZdZdZe��jZ	ddd�Z
eddd	��Zed
d��Z
dd
�Zdd�Zddd�Zddd�ZdS)r�zn
    Authenticated encryption class

    Encryption algorithm: AES-CBC
    Signing algorithm: HMAC-SHA256
    spickle::��rcCs&||_|�|j|�|_||_||_dSr|)�
key_string�extract_keys�keys�key_size�serial)r~r�r�r�r�rrrrs
zCrypticle.__init__cCs4t�|d|j�}t�|�}|�d�}|�dd�S)N�zutf-8rrj)r%�urandom�SIG_SIZE�base64�	b64encode�decode�replace)r�r�rZb64keyrrrr�s

zCrypticle.generate_key_stringcCsRtjj�t�|��}t|�|d|jksJd��|d|j�||jd�fS)Nr�zinvalid key)r'r(r�r�r��	b64decode�lenr�)r�r�r�rrrrr�s zCrypticle.extract_keysc
Cs�|j\}}|jt|�|j}|tjj�|t|��}t�	|j�}t
t�|�t
�|��}|��}|�|�}||��7}||}t�||tj���}	||	S)zH
        encrypt data with AES-CBC and sign it with HMAC-SHA256
        )r��AES_BLOCK_SIZEr�r'r(r�r��chrr%r�rr
�AESr�CBC�	encryptor�update�finalize�hmac�newrmrnrp)
r~r��aes_key�hmac_key�pad�iv_bytes�cipherr�ZencrrIrrrr�s

zCrypticle.encryptcCs|j\}}||jd�}|d|j�}t|t�s!tjj�|�}t�	||t
j���}t
|�t
|�kr<t�d�td��d}t||�D]
\}}|||AO}qC|dkr[t�d�td��|d|j�}	||jd�}tt�|�t�|	��}
|
��}|�|�|��}|d|d�S)zL
        verify HMAC-SHA256 signature and decrypt data with AES-CBC
        NzFailed to authenticate messagezmessage authentication failedrr$)r�r�r1�bytesr'r(r�r�r�r�rmrnrpr�r+r�r�zipr�rr
r�rr��	decryptorr�r�)r~r�r�r�rIZ	mac_bytesrZzipped_xZzipped_yr�r�r�rrrr�$s*



zCrypticle.decryptNcCs<|r|j|��tj�|�}n	|jtj�|�}|�|�S)z7
        Serialize and encrypt a python object
        )�
PICKLE_PADrLr'rF�dumpsr�)r~�objrNZ	toencryptrrrr�>s
zCrypticle.dumpsFcCs�|�|�}|�|j�s
iS|t|j�d�}|r.|dd���}|dd�}||kr.td��tjj||d�}t	|t
�rVd|vrV|�d�}||jkrSt
�d||j�iS||_|S)z:
        Decrypt and un-serialize a python object
        N� zNonce verification error)�rawr�zvA message with an invalid serial was received.
this serial: %d
last serial: %d
The minion will not honor this request.)r��
startswithr�r�r�rr'rFrVr1r2�popr�r+rX)r~r�r�rNZ	ret_noncerFr�rrrrVHs,



�zCrypticle.loads)r�r)r�r|)FN)rwrxryr�r�r�rmrn�digest_sizer�rr}r�r�r�r�r�rVrrrrr��s




r�r|)NNrA)[r�r�r�r�rKrmr��loggingr%r\r1r�r[rkrgr�Zsalt.channel.clientr'Zsalt.defaults.exitcodesZsalt.ext.tornado.genZsalt.payloadZsalt.utils.cryptZsalt.utils.decoratorsZsalt.utils.eventZsalt.utils.filesZsalt.utils.rsax931Zsalt.utils.sdbZsalt.utils.stringutilsZsalt.utils.userZsalt.utils.verifyZsalt.versionZsalt.exceptionsrrrrrrZcryptography.exceptionsrZcryptography.hazmat.primitivesrr	Z)cryptography.hazmat.primitives.asymmetricr
rZ&cryptography.hazmat.primitives.ciphersrr
rrr;�	getLoggerrwr+rrrrr�ZOAEP_SHA224r�ZPKCS1v15_SHA224rtrirrrqrgrrr@rbrcr{r�r(Z
decoratorsZmemoizer�r}r�r�r�r�r�r�r2r�r�r�r�rrrr�<module>s� 	�
���

H'/

		
6