B
    }d                 @   s   d Z ddlZddlZddlZddlZddlZddlmZ dZdgZ	ye
ZW n ek
rb   dZY nX G dd deZdd	dZd
d ZdS )zUtility module to initialise a kerberos ticket for NDS2 connections

This module provides a lazy-mans python version of the 'kinit'
command-line tool, with internal guesswork using keytabs

See the documentation of the `kinit` function for example usage
    N)OrderedDictz(Duncan Macleod <duncan.macleod@ligo.org>kinitFc               @   s   e Zd ZdZdS )KerberosErrorz%Kerberos (krb5) operation failed
    N)__name__
__module____qualname____doc__ r	   r	   ]/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/gwpy/io/kerberos.pyr   ,   s   r   c             C   s  |dkr.t jdd}|dks*t j|s.d}|ryt|}W n tk
rR   Y n^X | dkrtt|dkrt|d d } | tt	| d krtt	| d 
| }|| d }nd}tj sts| dks|s|dkrtd|dkrd}| dkrd}td| d	} |  d
| }	|s:|dkr:d}tjd|	 dd}|rP|dd||	g}
n||	g}
|rhd|i}nd}tj|
|tjtjd}|s||d |  | }|rt|jd|
|rtd|	  dS )a  Initialise a kerberos ticket using the ``kinit`` command-line tool.

    This allows authenticated connections to, amongst others, NDS2 services.

    Parameters
    ----------
    username : `str`, optional
        name of user, will be prompted for if not given.

    password : `str`, optional
        cleartext password of user for given realm, will be prompted for
        if not given.

    realm : `str`, optional
        name of realm to authenticate against, read from keytab if available,
        defaults to ``'LIGO.ORG'``.

    exe : `str`, optional
        path to kinit executable.

    keytab : `str`, optional
        path to keytab file. If not given this will be read from the
        ``KRB5_KTNAME`` environment variable. See notes for more details.

    krb5ccname : `str`, optional
        path to Kerberos credentials cache.

    verbose : `bool`, optional
        print verbose output (if `True`), or not (`False)`; default is `True`
        if any user-prompting is needed, otherwise `False`.

    Notes
    -----
    If a keytab is given, or is read from the ``KRB5_KTNAME`` environment
    variable, this will be used to guess the username and realm, if it
    contains only a single credential.

    Examples
    --------
    Example 1: standard user input, with password prompt::

    >>> kinit('albert.einstein')
    Password for albert.einstein@LIGO.ORG:
    Kerberos ticket generated for albert.einstein@LIGO.ORG

    Example 2: extract username and realm from keytab, and use that
    in authentication::

    >>> kinit(keytab='~/.kerberos/ligo.org.keytab', verbose=True)
    Kerberos ticket generated for albert.einstein@LIGO.ORG
    NZKRB5_KTNAME   r   z~cannot generate kerberos ticket in a non-interactive session, please manually create a ticket, or consider using a keytab filezLIGO.ORGTz Please provide username for the z kerberos realm: @zPassword for z: )promptz-kz-tZ
KRB5CCNAME)envstdoutstdinzutf-8 zKerberos ticket generated for )osenvirongetpathisfileparse_keytabr   lenlistzipindexsysr   isatty_IPYTHONinputgetpass
subprocessPopenPIPEcommunicateencodewaitpollCalledProcessError
returncodejoinprint)usernamepasswordrealmexekeytabZ
krb5ccnameverbose
principalsidxidentitycmdZkrbenvZkgetretcoder	   r	   r
   r   2   sZ    =



c          	   C   s   yt jdd| gt jd}W n@ tk
r6   tdY n& t jk
rZ   td|  dY nX g }x| D ]t}t|tr|	d}yt
d|d	d
\}}W n tk
r   wjY qjX | sqj|t|dt|f  qjW tt| S )a  Read the contents of a KRB5 keytab file, returning a list of
    credentials listed within

    Parameters
    ----------
    keytab : `str`
        path to keytab file

    Returns
    -------
    creds : `list` of `tuple`
        the (unique) list of `(username, realm, kvno)` as read from the
        keytab file

    Examples
    --------
    >>> from gwpy.io.kerberos import parse_keytab
    >>> print(parse_keytab("creds.keytab"))
    [('albert.einstein', 'LIGO.ORG', 1)]
    Zklistz-k)stderrz*Failed to locate klist, cannot read keytabzCannot read keytab ''zutf-8z\s+r   r   r   )r!   check_outputr#   OSErrorr   r(   
splitlines
isinstancebytesdecoderesplitstrip
ValueErrorisdigitappendtupleintr   r   fromkeyskeys)r0   outr2   lineZkvnoZ	principalr	   r	   r
   r      s&    

"r   )NNNr   NNN)r   r    r   r?   r!   r   collectionsr   
__author____all__Z__IPYTHON__r   	NameErrorRuntimeErrorr   r   r   r	   r	   r	   r
   <module>   s*   
      
{