
Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­
<!DOCTYPE html>
<html>
3
."ÉdCB  ã               @   s6  d dl 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dlmZ dd„ d<D ƒZ	dZ
d=Zd dhdddhdddhddhdddhdddhdddhdddhdddhdddhd!œ
ZG d"d#„ d#ƒZG d$d%„ d%ejƒZd&d'„ Ze jd(d>ƒZd-d.„ Zd?d0d1„ZG d2d3„ d3eƒZd4d5„ ZG d6d7„ d7ƒZd8d9„ ZG d:d;„ d;ƒZdS )@é    Né   )Ú	alg_lists)Ú
validationc             C   s   i | ]
}d |“qS )r   © )Ú.0Úkr   r   úC./usr/share/crypto-policies/python/cryptopolicies/cryptopolicies.pyú
<dictcomp>   s    r	   Úarbitrary_dh_groupsÚmin_dh_sizeÚmin_dsa_sizeÚmin_rsa_sizeÚsha1_in_certsÚ	ssh_certsÚssh_etmÚ*ÚtlsÚsslÚopensslÚnssÚgnutlsújava-tlsÚsshÚopensshúopenssh-serverúopenssh-clientÚlibsshÚipsecÚikeÚ	libreswanÚkerberosÚkrb5ÚdnssecÚbind)
r#   r   zjava-tlsr!   r   r   r   zopenssh-clientzopenssh-serverr   c               @   s(   e Zd Zefdd„Zdd„ Zdd„ ZdS )ÚScopeSelectorc             C   s”   |j ƒ  | _}|jdƒ | _| jr&|n
|dd… }tjj|| jd� tjj|| jd� |jdƒrr|dd… jdƒn|g| _	tjj
| j	t| jd� dS )a=  
        Initialize a scope selector.
        An example would be `ssh` in `ciphers@ssh = -NULL`.
        When openssh backend will request the configuration,
        it'll offer (`{'ssh', 'openssh'}`) as scopes
        and the rule above will be taken into account.
        Both patterns and scopes are cast to lowercase.
        For more examples, refer to tests/unit/parsing/test_scope_selector.py
        >>> ss = ScopeSelector('!{SSH,IPsec}')
        >>> ss.matches({'ipsec', 'libreswan'})
        False
        >>> ss.matches({'tls', 'openssl'})
        True
        ú!r   N)Zoriginal_patternú{ú,éÿÿÿÿ)ÚlowerÚpatternÚ
startswithÚ	_positiver   ÚscopeZillegal_charactersZcurly_bracketsÚsplitÚ_globsZresulting_globsÚ
ALL_SCOPES)Úselfr*   Úpr   r   r   Ú__init__5   s    $zScopeSelector.__init__c             C   s   dt | jƒ› d�S )Nz<ScopeSelector pattern=ú>)Úreprr*   )r1   r   r   r   Ú__str__P   s    zScopeSelector.__str__c                sR   | j tkrdS dd„ ˆ D ƒ‰ | jr:t‡ fdd„| jD ƒƒS t‡ fdd„| jD ƒƒS )aE  
        Checks whether ScopeSelector matches one of the scopes.
        For more examples, refer to tests/unit/parsing/test_scope_selector.py
        >>> ScopeSelector('{SSH,IPsec}').matches({'ipsec', 'libreswan'})
        True
        >>> ScopeSelector('!{SSH,IPsec}').matches({'ipsec', 'libreswan'})
        False
        Tc             S   s   g | ]}|j ƒ ‘qS r   )r)   )r   Úsr   r   r   ú
<listcomp>^   s    z)ScopeSelector.matches.<locals>.<listcomp>c             3   s   | ]}t jˆ |ƒV  qd S )N)ÚfnmatchÚfilter)r   Úg)Úscopesr   r   ú	<genexpr>a   s    z(ScopeSelector.matches.<locals>.<genexpr>c             3   s   | ]}t jˆ |ƒ V  qd S )N)r9   r:   )r   r;   )r<   r   r   r=   b   s    )r*   Ú	SCOPE_ANYr,   Úanyr/   Úall)r1   r<   r   )r<   r   ÚmatchesS   s    	
zScopeSelector.matchesN)Ú__name__Ú
__module__Ú__qualname__r>   r3   r6   rA   r   r   r   r   r$   4   s   r$   c               @   s$   e Zd ZdZdZdZdZdZdZdS )Ú	OperationzM
    An operation that comes with the right-hand value of the directive.
    r   é   é   é   é   N)	rB   rC   rD   Ú__doc__ÚRESETÚPREPENDÚAPPENDÚOMITÚSET_INTr   r   r   r   rE   g   s   rE   c                s„  dd„ ‰ | j ƒ rLˆtjkr2ˆtkr2tjt| ƒfgS ˆtjkr`tjj	ˆƒ‚q`nˆtkr`tjj
ˆƒ‚| jƒ }t‡ fdd„|D ƒƒs°t‡fdd„|D ƒg ƒ}tjdfgdd„ |D ƒ S t‡ fd	d„|D ƒƒ�rtg }x¢|D ]š}|jd
ƒ�rtj‰tj|dd… ˆƒddd… }nL|jd
ƒ�r:tj‰tj|dd… ˆƒddd… }ntj‰tj|dd… ˆƒ}|j‡fdd„|D ƒƒ qÒW |S tjj| ƒ‚dS )a7  
    Parses right-hand parts of the directives
    into lists of operation/value pairs.
    For more examples, refer to tests/unit/test_parsing.py
    >>> parse_rhs('', 'cipher')
    [(<Operation.RESET: 1>, None)]
    >>> parse_rhs('IDEA-CBC SEED-CBC', 'cipher')
    [(<Operation.RESET: 1>, None),
     (<Operation.APPEND: 3>, 'IDEA-CBC'),
     (<Operation.APPEND: 3>, 'SEED-CBC')]
    >>> # 3DES-CBC gets prepended last for higher prio
    >>> parse_rhs('+*DES-CBC', 'cipher')
    [(<Operation.PREPEND: 2>, 'DES-CBC'),
     (<Operation.PREPEND: 2>, '3DES-CBC')]
    c             S   s   | j dƒp| jdƒp| j dƒS )Nú+ú-)r+   Úendswith)Úvr   r   r   Údifferential‚   s    zparse_rhs.<locals>.differentialc             3   s   | ]}ˆ |ƒV  qd S )Nr   )r   rS   )rT   r   r   r=   ”   s    zparse_rhs.<locals>.<genexpr>c                s   g | ]}t j|ˆ ƒ‘qS r   )r   Úglob)r   rS   )Ú	prop_namer   r   r8   •   s    zparse_rhs.<locals>.<listcomp>Nc             S   s   g | ]}t j|f‘qS r   )rE   rM   )r   rS   r   r   r   r8   —   s    c             3   s   | ]}ˆ |ƒV  qd S )Nr   )r   rS   )rT   r   r   r=   ˜   s    rP   r   c                s   g | ]}ˆ |f‘qS r   r   )r   rS   )Úopr   r   r8   ¥   s    r(   r(   r(   )Úisdigitr   ÚALLÚINT_DEFAULTSrE   rO   Úintr   ÚrulesZNonIntPropertyIntValueErrorZIntPropertyNonIntValueErrorr.   r?   ÚsumrK   r@   r+   rL   rU   rR   rM   rN   ÚextendZ%MixedDifferentialNonDifferentialError)ÚrhsrV   ÚvaluesZ
operationsÚvalueZunglobr   )rT   rW   rV   r   Ú	parse_rhsr   s8    


  rb   Ú	DirectiverV   r-   Ú	operationra   c                s€   | j ƒ sg S tjj| ƒ | jdƒ\}}|j ƒ |j ƒ  }}tjj|| ƒ d|krZ|jddƒn|tf\‰ ‰‡ ‡fdd„t|ˆ ƒD ƒS )ae  
    Parses configuration lines into tuples of directives.
    For more examples, refer to tests/unit/test_parsing.py
    >>> parse_line('cipher@TLS = RC4* NULL')
    [Directive(prop_name='cipher', scope='tls',
               operation=<Operation.RESET: 1>, value=None),
     Directive(prop_name='cipher', scope='tls',
               operation=<Operation.APPEND: 3>, value='RC4-40'),
     Directive(prop_name='cipher', scope='tls',
               operation=<Operation.APPEND: 3>, value='RC4-128'),
     Directive(prop_name='cipher', scope='tls',
               operation=<Operation.APPEND: 3>, value='NULL')]
    ú=ú@r   c                s$   g | ]\}}t ˆ ˆjƒ ||d �‘qS ))rV   r-   rd   ra   )rc   r)   )r   rd   ra   )rV   r-   r   r   r8   Ê   s   zparse_line.<locals>.<listcomp>)Ústripr   r\   Zcount_equals_signsr.   Z	empty_lhsr>   rb   )ÚlineZlhsr_   r   )rV   r-   r   Ú
parse_line²   s     ri   Fc             C   s^   y$t | ƒ}x|D ]}t|jƒ qW W n4 tjk
rX } z|s>‚ tj|ƒ W Y d d }~X nX d S )N)ri   r$   r-   r   ZPolicySyntaxErrorÚwarningsÚwarn)rh   rk   ÚlÚdÚexr   r   r   Úsyntax_check_lineÏ   s    
ro   c                   s   e Zd Z‡ fdd„Z‡  ZS )ÚPolicySyntaxDeprecationWarningc                s@   |j ddƒ}d|› d�}|d|› d�7 }|d7 }tƒ j|ƒ d S )NÚ
z and zoption z is deprecatedz", please rewrite your rules using z; z2be advised that it is not always a 1-1 replacement)ÚreplaceÚsuperr3   )r1   Z
deprecatedZreplacementÚmsg)Ú	__class__r   r   r3   Û   s
    z'PolicySyntaxDeprecationWarning.__init__)rB   rC   rD   r3   Ú__classcell__r   r   )ru   r   rp   Ú   s   rp   c             C   s�  t jdd| ƒ} | jddƒ} djdd„ | jdƒD ƒƒ} | jddƒ} djd	d„ | jdƒD ƒƒ} djd
d„ | jdƒD ƒƒ} t jdd| ƒjƒ } t jd| ƒr¢tjt	ddƒƒ dddddœ}xr|j
ƒ D ]f\}}d| d }t j|| ƒ}|rîtjt	||ƒƒ t j|d| ƒ} x"|D ]}| d|› d|› �7 } �qW qºW t jdd| ƒjƒ } dddœ}xN|j
ƒ D ]B\}}d| d }t j|| ƒ�r|tjt	||ƒƒ t j||| ƒ} �qJW ttjddd%… ƒ}xZ|�rþdjdd„ |dd&… D ƒƒ}	t jd|d'  d |	�rêd |	› �nd| ƒ} |jƒ  �q¦W t jd!d| ƒ} ttjddd(… ƒ}
xZ|
�r|djd"d„ |
dd)… D ƒƒ}	t jd#|
d*  d |	�rhd |	› �nd| ƒ} |
jƒ  �q$W t jd$d| ƒ} | S )+a  
    Preprocesses text before parsing.
    Fixes line breaks, handles backwards compatibility.
    >>> preprocess_text('cipher = c1 \\ \nc2#x')
    'cipher = c1 c2'
    >>> with warnings.catch_warnings():
    ...     warnings.simplefilter("ignore")
    ...     preprocess_text('ike_protocol = IKEv2')
    'protocol@IKE = IKEv2'
    >>> with warnings.catch_warnings():
    ...     warnings.simplefilter("ignore")
    ...     preprocess_text('min_tls_version=TLS1.3')
    'protocol@TLS = -SSL2.0 -SSL3.0 -TLS1.0 -TLS1.1 -TLS1.2'
    z#.*Ú re   z = rq   c             s   s   | ]}|j ƒ V  qd S )N)rg   )r   rl   r   r   r   r=   ô   s    z"preprocess_text.<locals>.<genexpr>z\
c             s   s   | ]}|j ƒ V  qd S )N)rg   )r   rl   r   r   r   r=   ö   s    c             s   s   | ]}t jd d|ƒV  qdS )z\s+ú N)ÚreÚsub)r   rl   r   r   r   r=   ÷   s    z
+z\bprotocol\s*=Úprotocolzprotocol@TLSz
cipher@TLSz
cipher@SSHz	group@SSHzprotocol@IKE)Z
tls_cipherZ
ssh_cipherZ	ssh_groupZike_protocolz\bz\s*=(.*)z

z =z7hash@DNSSec = -SHA1
sign@DNSSec = -RSA-SHA1 -ECDSA-SHA1z7hash@DNSSec = SHA1+
sign@DNSSec = RSA-SHA1+ ECDSA-SHA1+)zsha1_in_dnssec = 0zsha1_in_dnssec = 1Nr   rx   c             s   s   | ]}d | V  qdS )rQ   Nr   )r   rS   r   r   r   r=     s    z\bmin_dtls_version = zprotocol@TLS = z\bmin_dtls_version = 0\bc             s   s   | ]}d | V  qdS )rQ   Nr   )r   rS   r   r   r   r=   $  s    z\bmin_tls_version = z\bmin_tls_version = 0\br(   r(   r(   r(   r(   r(   )ry   rz   rr   Újoinr.   rg   Úfindallrj   rk   rp   ÚitemsÚsearchÚlistr   ZDTLS_PROTOCOLSÚpopZTLS_PROTOCOLS)ÚtextZPOSTFIX_REPLACEMENTSÚfrZtoZregexZmsÚmZPLAIN_REPLACEMENTSZdtls_versionsÚnegZtls_versionsr   r   r   Úpreprocess_textã   sZ    
r†   c               @   sJ   e Zd ZdZddd„Zedd„ ƒZedd„ ƒZed	d
„ ƒZedd„ ƒZ	dS )ÚScopedPolicyaŽ  
    An entity constructing lists of what's `.enabled` and what's `.disabled`
    when the given scopes are active.
    >>> sp = ScopedPolicy(parse_line('cipher@TLS = RC4* NULL'), {'tls'})
    >>> 'AES-256-GCM' in sp.disabled['cipher']
    True
    >>> sp.enabled['cipher']
    ['RC4-40', 'RC4-128', 'NULL']
    >>> ScopedPolicy(parse_line('min_dh_size=2048')).integers['min_dh_size']
    2048
    Nc                s(  |pt ƒ }tjƒ ˆ_dd„ tjD ƒˆ_xæ|D ]Þ‰ tˆ jƒ}|j	|ƒr,ˆ j
tjkr^g ˆjˆ j< q,ˆ j
tjkrŽˆjˆ j }ˆ j|krŒ|jˆ jƒ q,ˆ j
tjkrÌˆjˆ j }ˆ j|kr¼|jˆ jƒ |jdˆ jƒ q,ˆ j
tjkrü‡ fdd„ˆjˆ j D ƒˆjˆ j< q,ˆ jˆjˆ j< q,W ‡fdd„tjD ƒˆ_d S )Nc             S   s   i | ]
}g |“qS r   r   )r   rV   r   r   r   r	   >  s    z)ScopedPolicy.__init__.<locals>.<dictcomp>r   c                s   g | ]}|ˆ j kr|‘qS r   )ra   )r   Úe)Ú	directiver   r   r8   R  s    z)ScopedPolicy.__init__.<locals>.<listcomp>c                s(   i | ] ‰ ‡ ‡fd d„t jˆ  D ƒˆ “qS )c                s   g | ]}|ˆj ˆ  kr|‘qS r   )Úenabled)r   rˆ   )rV   r1   r   r   r8   Z  s    z4ScopedPolicy.__init__.<locals>.<dictcomp>.<listcomp>)r   rY   )r   )r1   )rV   r   r	   Z  s   )ÚsetrZ   ÚcopyÚintegersr   rY   rŠ   r$   r-   rA   rd   rE   rK   rV   rM   ra   ÚappendrL   ÚremoveÚinsertrN   Zdisabled)r1   Ú
directivesZrelevant_scopesZssrŠ   r   )r‰   r1   r   r3   ;  s,    






$
zScopedPolicy.__init__c             C   s   t j| jd ƒS )Nr{   )r   Úmin_tls_versionrŠ   )r1   r   r   r   r’   ^  s    zScopedPolicy.min_tls_versionc             C   s   t j| jd ƒS )Nr{   )r   Úmax_tls_versionrŠ   )r1   r   r   r   r“   b  s    zScopedPolicy.max_tls_versionc             C   s   t j| jd ƒS )Nr{   )r   Úmin_dtls_versionrŠ   )r1   r   r   r   r”   f  s    zScopedPolicy.min_dtls_versionc             C   s   t j| jd ƒS )Nr{   )r   Úmax_dtls_versionrŠ   )r1   r   r   r   r•   j  s    zScopedPolicy.max_dtls_version)N)
rB   rC   rD   rJ   r3   Úpropertyr’   r“   r”   r•   r   r   r   r   r‡   /  s   
#r‡   c             C   s@   x,|D ]$}t jj||ƒ}t j|t jƒr|S qW tj| ||ƒ‚d S )N)ÚosÚpathr|   ÚaccessÚR_OKr   ZPolicyFileNotFoundError)Ú
policynameÚfnameÚpathsrm   r2   r   r   r   Úlookup_fileq  s
    
rž   c               @   sF   e Zd ZdZdZddœdd„Zdd„ Zdd	d
„Zddd„Zdd„ Z	dS )ÚUnscopedCryptoPolicyz/etc/crypto-policiesz/usr/share/crypto-policiesN)Ú	policydirc            G   sR   || _ dj|f| ƒ| _g | _| j|ƒ}x|D ]}|| j|dd�7 }q.W || _d S )Nú:T)Ú	subpolicy)r    r|   r›   ÚlinesÚread_policy_fileÚ_directives)r1   Zpolicy_namer    Zsubpolicy_namesr‘   Zsubpolicy_namer   r   r   r3   €  s    

zUnscopedCryptoPolicy.__init__c             C   s   | j  S )N)r¥   )r1   r   r   r   Úis_empty‹  s    zUnscopedCryptoPolicy.is_emptyc             C   s   t | j|pi ƒS )N)r‡   r¥   )r1   r<   r   r   r   ÚscopedŽ  s    zUnscopedCryptoPolicy.scopedFc       	      C   sÊ   | j pd}|rtjj|dƒ}t|||s*dnd tjj|tjj| j|ƒtjj| j|ƒfƒ}t|ƒ�}|j	ƒ }W d Q R X t
|ƒ}|jdƒ}x|D ]}t|dd� qŒW x|D ]}t|ƒ q¦W tdd	„ |D ƒg ƒS )
NZpoliciesÚmodulesz.polz.pmodrq   T)rk   c             S   s   g | ]}t |ƒ‘qS r   )ri   )r   rl   r   r   r   r8   ¥  s    z9UnscopedCryptoPolicy.read_policy_file.<locals>.<listcomp>)r    r—   r˜   r|   rž   ÚcurdirÚ
CONFIG_DIRÚ	SHARE_DIRÚopenÚreadr†   r.   ro   r]   )	r1   Únamer¢   Zpdirr2   Úfr‚   r£   rl   r   r   r   r¤   ‘  s$    




z%UnscopedCryptoPolicy.read_policy_filec             C   s  dd„ }| j ƒ }d| j› d�}|d7 }|d7 }|d7 }|d7 }|d7 }|j|j–}x"|jƒ D ]\}}||||ƒ7 }q\W d	}xvtjƒ D ]j\}}	| j |	d
�}
|
j|
j–}xH|jƒ D ]<\}}||| kr®|sÒ|d7 }d}|||› d|› �|ƒ7 }q®W q„W |�s |d7 }|S )Nc             S   s2   t |tƒrdj|ƒnt|ƒ}| › d|› �jƒ d S )Nrx   z = rq   )Ú
isinstancer€   r|   ÚstrÚrstrip)Úkeyra   r7   r   r   r   Úfmt¨  s    z)UnscopedCryptoPolicy.__str__.<locals>.fmtz	# Policy z dump
z#
z?# Do not parse the contents of this file with automated tools,
z.# it is provided for review convenience only.
z"# Baseline values for all scopes:
F)r<   z9# Scope-specific properties derived for select backends:
Trf   z&# No scope-specific properties found.
)r§   r›   rŠ   r�   r~   ÚDUMPABLE_SCOPES)r1   r´   Zgeneric_scopedr7   Zgeneric_allrV   ra   Zanything_scope_specificZ
scope_nameZ	scope_setZspecific_scopedZspecific_allr   r   r   r6   §  s2     zUnscopedCryptoPolicy.__str__)N)F)
rB   rC   rD   rª   r«   r3   r¦   r§   r¤   r6   r   r   r   r   rŸ   {  s   

rŸ   )r
   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   )rV   r-   rd   ra   )F)ÚcollectionsÚenumr9   r—   ry   rj   rw   r   r   rZ   r>   r0   rµ   r$   ÚEnumrE   rb   Ú
namedtuplerc   ri   ro   ÚFutureWarningrp   r†   r‡   rž   rŸ   r   r   r   r   Ú<module>   sP          3;
	LB
