U
    gyh                     @   s  d Z dgZdZdZdZddlZddlmZmZm	Z	m
Z
mZmZmZ ddlmZmZmZmZmZ dd	lmZ dd
lmZ G dd de	ZG dd de	ZG dd de	Ze
eeeeeeeeeZG dd de	ZdZdZdZdZdZeedZ eedZ!e j"Z"ee"_#eege"_$e%e!dr:e!j&Z&ee&_#eege&_$e!j'Z'ee'_#eeeeeege'_$e!j(Z(ee(_#eege(_$e!j)Z)ee)_#eege)_$e!j*Z*ee*_#eege*_$G dd dZ+dd Z,e-dkrddl.Z.ddl/Z/dd Z0e+ Z+e0d e/1 Z2e+,e2e//  e3d!4e+j5e+j6 dS )"z
PAM module for python

Provides an authenticate function that will allow the caller to authenticate
a user against the Pluggable Authentication Modules (PAM) on the system.

Implemented using ctypes, so no compilation is necessary.
pamz1.8.4z David Ford <david@blue-labs.org>z2018 June 15    N)CDLLPOINTER	Structure	CFUNCTYPEcastbyrefsizeof)c_void_pc_size_tc_char_pc_charc_int)memmove)find_libraryc                   @   s"   e Zd ZdZdefgZdd ZdS )	PamHandlez&wrapper class for pam_handle_t pointerhandlec                 C   s   t |  d| _d S )Nr   )r   __init__r   self r   -/usr/local/lib/python3.8/dist-packages/pam.pyr   '   s    
zPamHandle.__init__N)__name__
__module____qualname____doc__r
   _fields_r   r   r   r   r   r   #   s   
r   c                   @   s(   e Zd ZdZdefdefgZdd ZdS )
PamMessagez'wrapper class for pam_message structure	msg_stylemsgc                 C   s   d| j | jf S )Nz<PamMessage %i '%s'>)r   r   r   r   r   r   __repr__/   s    zPamMessage.__repr__N)r   r   r   r   r   r   r   r    r   r   r   r   r   +   s   r   c                   @   s(   e Zd ZdZdefdefgZdd ZdS )PamResponsez(wrapper class for pam_response structurerespresp_retcodec                 C   s   d| j | jf S )Nz<PamResponse %i '%s'>)r#   r"   r   r   r   r   r    6   s    zPamResponse.__repr__N)r   r   r   r   r   r   r   r    r   r   r   r   r!   2   s   r!   c                   @   s    e Zd ZdZdefdefgZdS )PamConvz$wrapper class for pam_conv structureconvZappdata_ptrN)r   r   r   r   	conv_funcr
   r   r   r   r   r   r$   ;   s   r$                  cpam_endc                   @   s&   e Zd ZdZdZdd Zd
dd	ZdS )r   r   Nc                 C   s   d S Nr   r   r   r   r   r   g   s    zpam.__init__loginutf-8Tc                    st  t  fdd}tjdkrZt|tr0||}ttrD|t|tr||}n<t|trn||}ttr|t|tr||}d|ksdksd|krd| _d| _dS t	 t
 }t|d}t||t|t|}	|	dkr|	| _d	| _dS t|d}	|	dk}
|
r.|r.t|t}	|	| _t||	| _tjdkrZ| j|| _ttd
rpt||	 |
S )a  username and password authentication for the given service.

           Returns True for success, or False for failure.

           self.code (integer) and self.reason (string) are always stored and may
           be referenced for the reason why authentication failed. 0/'Success' will
           be stored for success.

           Python3 expects bytes() for ctypes inputs.  This function will make
           necessary conversions using the supplied encoding.

        Inputs:
          username: username to authenticate
          password: password in plain text
          service:  PAM service to authenticate against, defaults to 'login'

        Returns:
          success:  True
          failure:  False
        c                    s   t | tt}t|tt}||d< t| D ]N}|| jjtkr,t t	d tt
}t| t	 ||| _d|| _q,dS )zxSimple conversation function that responds to any
               prompt where the echo is off with the supplied passwordr   r'   )callocr	   r!   r   r   rangecontentsr   PAM_PROMPT_ECHO_OFFlenr   r   r"   r#   )Z
n_messagesmessagesZ
p_responseZapp_dataaddrresponseidstZ	cpasswordpasswordr   r   my_conv   s    
z!pam.authenticate.<locals>.my_convr)       r*   zstrings may not contain NULFr   zpam_start() failedr-   )r&   sysversion_info
isinstancestrencodeunicodecodereasonr   r   r$   	pam_startr   pam_authenticatepam_setcredPAM_REINITIALIZE_CREDpam_strerrordecodehasattrlibpamr-   )r   usernamer<   ZserviceencodingZ
resetcredsr=   r   r%   retvalZauth_successr   r;   r   authenticatej   sL    

 

 

 










zpam.authenticate)r/   r0   T)r   r   r   rF   rG   r   rS   r   r   r   r   r   c   s   c                  O   s   t  j| |S )zB
    Compatibility function for older versions of python-pam.
    )r   rS   )ZvargsZdargsr   r   r   rS      s    rS   __main__c                    s>    fdd}t | tjdkr*t| }nt| }t   |S )Nc                      s   t   t   d S r.   )readlineZinsert_textZ	redisplayr   textr   r   hook   s    
z input_with_prefill.<locals>.hookr>   )rU   Zset_pre_input_hookr@   rA   input	raw_input)promptrW   rX   resultr   rV   r   input_with_prefill   s    


r]   z
Username: z{} {})7r   __all____version__
__author__Z__released__r@   ctypesr   r   r   r   r   r   r	   r
   r   r   r   r   r   ctypes.utilr   r   r   r!   r&   r$   r4   ZPAM_PROMPT_ECHO_ONZPAM_ERROR_MSGZPAM_TEXT_INFOrK   libcrO   r1   restypeZargtypesrN   r-   rH   rJ   rL   rI   r   rS   r   rU   getpassr]   getuserrP   printformatrF   rG   r   r   r   r   <module>   sb   	$ 




_
