o
    <‘ðik.  ã                   @   sÞ   d dl Z d dlZd dlZd dlZd dlZd dlZe  e¡Ze 	d¡Z
dd„ ZG dd„ dƒZG dd„ deƒZG d	d
„ d
eƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZdS )é    NzW(?<=^)"([^"]+)"(?=:|$)|(?<=:)"([^"]+)"(?=:|$)|(?<=^)([^:]*)(?=:|$)|(?<=:)([^:]*)(?=:|$)c                 C   s   t  | ¡}dd„ |D ƒS )z¹It works like src.split(":") but with the ability to use a colon
    if you wrap the word in quotation marks.

    a:b:c:d -> ['a', 'b', 'c', 'd'
    a:"b:c":c -> ['a', 'b:c', 'd']
    c                 S   s,   g | ]}|d  p|d p|d p|d ‘qS )r   é   é   é   © )Ú.0Úmr   r   úW/root/parts/websockify/install/lib/python3.10/site-packages/websockify/token_plugins.pyÚ
<listcomp>   s   , z%parse_source_args.<locals>.<listcomp>)Ú_SOURCE_SPLIT_REGEXÚfindall)ÚsrcÚmatchesr   r   r   Úparse_source_args   s   
r   c                   @   ó   e Zd Zdd„ Zdd„ ZdS )Ú
BasePluginc                 C   s
   || _ d S ©N)Úsource©Úselfr   r   r   r   Ú__init__   s   
zBasePlugin.__init__c                 C   s   d S r   r   ©r   Útokenr   r   r   Úlookup!   s   zBasePlugin.lookupN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r      s    r   c                       s,   e Zd Z‡ fdd„Zdd„ Zdd„ Z‡  ZS )ÚReadOnlyTokenFilec                    s   t ƒ j|i |¤Ž d | _d S r   )Úsuperr   Ú_targets©r   ÚargsÚkwargs©Ú	__class__r   r   r   )   s   
zReadOnlyTokenFile.__init__c              
      sÎ   t j ˆ j¡r‡ fdd„t  ˆ j¡D ƒ}nˆ jg}i ˆ _d}|D ]D}dd„ t|ƒ ¡ D ƒD ]6}|r_| d¡s_zt	 
d|¡\}}| ¡  dd¡ˆ j|< W n ty^   t dˆ j|f ¡ Y nw |d7 }q-q d S )	Nc                    s   g | ]
}t j ˆ j|¡‘qS r   )ÚosÚpathÚjoinr   )r   Úf©r   r   r   r	   /   s    ÿz3ReadOnlyTokenFile._load_targets.<locals>.<listcomp>r   c                 S   s   g | ]}|  ¡ ‘qS r   )Ústrip)r   Úlr   r   r   r	   7   s    ú#z:\sú:zSyntax error in %s on line %d)r$   r%   Úisdirr   Úlistdirr   ÚopenÚ	readlinesÚ
startswithÚreÚsplitr)   ÚrsplitÚ
ValueErrorÚloggerÚerror)r   Ú	cfg_filesÚindexr'   ÚlineÚtokÚtargetr   r(   r   Ú_load_targets-   s&   

ÿÿ
ùÿzReadOnlyTokenFile._load_targetsc                 C   s*   | j d u r	|  ¡  || j v r| j | S d S r   )r   r=   r   r   r   r   r   @   s
   


zReadOnlyTokenFile.lookup)r   r   r   r   r=   r   Ú__classcell__r   r   r"   r   r   %   s    r   c                       s   e Zd Z‡ fdd„Z‡  ZS )Ú	TokenFilec                    s   |   ¡  tƒ  |¡S r   )r=   r   r   r   r"   r   r   r   Q   s   zTokenFile.lookup)r   r   r   r   r>   r   r   r"   r   r?   M   s    r?   c                       ó$   e Zd Z‡ fdd„Zdd„ Z‡  ZS )ÚTokenFileNamec                    s$   t ƒ  |¡ tj |¡stdƒ‚d S )Nz)TokenFileName plugin requires a directory)r   r   r$   r%   r-   Ú	Exceptionr   r"   r   r   r   Z   s   ÿzTokenFileName.__init__c                 C   sB   t j |¡}t j | j|¡}t j |¡rt|ƒ ¡  ¡  	d¡S d S )Nr,   )
r$   r%   Úbasenamer&   r   Úexistsr/   Úreadr)   r3   )r   r   r%   r   r   r   r   _   s
   zTokenFileName.lookup©r   r   r   r   r   r>   r   r   r"   r   rA   V   s    rA   c                   @   r   )ÚBaseTokenAPIc                 C   s$   |j  d¡\}}| dd¡}||gS )Nr,   ÚasciiÚignore)Útextr3   Úencode)r   ÚrespÚhostÚportr   r   r   Úprocess_resulto   s   zBaseTokenAPI.process_resultc                 C   s,   dd l }| | j| ¡}|jr|  |¡S d S )Nr   )ÚrequestsÚgetr   ÚokrO   )r   r   rP   rL   r   r   r   r   t   s
   
zBaseTokenAPI.lookupN)r   r   r   rO   r   r   r   r   r   rG   h   s    rG   c                   @   ó   e Zd Zdd„ ZdS )ÚJSONTokenApic                 C   s   |  ¡ }|d |d fS )NrM   rN   )Újson)r   rL   Ú	resp_jsonr   r   r   rO   ƒ   s   zJSONTokenApi.process_resultN)r   r   r   rO   r   r   r   r   rT      ó    rT   c                   @   rS   )ÚJWTTokenApic              
   C   sâ  záddl m}m} dd l}| ¡ }zt| jdƒ�}| ¡ }W d   ƒ n1 s'w   Y  W n tyJ } zt	 
dt|ƒ ¡ W Y d }~W d S d }~ww z| |¡ W n   z|j| d¡dd� W n   t	 
d¡ Y Y W d S Y zS|j||d	�}| |j¡}	d
|	v r‹|j||jd	�}| |j¡}
d|
v r¦t ¡ |
d k r¦t	 d¡ W W d S d|
v r»t ¡ |
d kr»t	 d¡ W W d S |
d |
d fW W S  tyá } zt	 
dt|ƒ ¡ W Y d }~W d S d }~ww  tyð   t	 
d¡ Y d S w )Nr   )ÚjwtÚjwkÚrbzError loading key file: %súutf-8Úoct)ÚkÚktyz#Failed to correctly parse key data!)ÚkeyrY   ÚencÚnbfzToken can not be used yet!ÚexpzToken has expired!rM   rN   zFailed to parse token: %szGpackage jwcrypto not found, are you sure you've installed it correctly?)ÚjwcryptorY   rZ   rU   ÚJWKr/   r   rE   rB   r6   r7   ÚstrÚimport_from_pemÚ
import_keyÚdecodeÚJWTÚloadsÚheaderÚclaimsÚtimeÚwarningÚImportError)r   r   rY   rZ   rU   r`   Úkey_fileÚkey_dataÚeÚparsed_headerÚparsedr   r   r   r   Œ   s^   
ÿ€€þ

ý

€þ
þzJWTTokenApi.lookupN)r   r   r   r   r   r   r   r   rX   ˆ   rW   rX   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )Ú
TokenRedisa×  Token plugin based on the Redis in-memory data store.

    The token source is in the format:

        host[:port[:db[:password[:namespace]]]]

    where port, db, password and namespace are optional. If port or db are left empty
    they will take its default value, ie. 6379 and 0 respectively.

    If your redis server is using the default port (6379) then you can use:

        my-redis-host

    In case you need to authenticate with the redis server and you are using
    the default database and port you can use:

        my-redis-host:::verysecretpass

    You can also specify a namespace. In this case, the tokens
    will be stored in the format '{namespace}:{token}'

        my-redis-host::::my-app-namespace

    Or if your namespace is nested, you can wrap it in quotes:

        my-redis-host::::"first-ns:second-ns"

    In the more general case you will use:

        my-redis-host:6380:1:verysecretpass:my-app-namespace

    The TokenRedis plugin expects the format of the target in one of these two
    formats:

    - JSON

        {"host": "target-host:target-port"}

    - Plain text

        target-host:target-port

    Prepare data with:

        redis-cli set my-token '{"host": "127.0.0.1:5000"}'

    Verify with:

        redis-cli --raw get my-token

    Spawn a test "server" using netcat

        nc -l 5000 -v

    Note: This Token Plugin depends on the 'redis' module, so you have
    to install it before using this plugin:

          pip install redis
    c                 C   sÚ  zdd l }W n ty   t d¡ t ¡  Y nw d| _d| _d | _d| _	z²t
|ƒ}t|ƒdkr6|d | _n~t|ƒdkrI|\| _| _| jsHd| _nkt|ƒdkrd|\| _| _| _| js]d| _| jscd| _nPt|ƒdkr‡|\| _| _| _| _| jszd| _| js€d| _| js†d | _n-t|ƒd	kr²|\| _| _| _| _| _	| jsŸd| _| js¥d| _| js«d | _| j	s±d| _	nt‚t| jƒ| _t| jƒ| _| j	rÊ|  j	d
7  _	t d| j| jf ¡ W d S  tyì   t d| ¡ t ¡  Y d S w )Nr   zUnable to load redis moduleië  Ú r   r   r   é   é   r,   z&TokenRedis backend initialized (%s:%s)zpThe provided --token-source='%s' is not in the expected format <host>[:<port>[:<db>[:<password>[:<namespace>]]]])Úredisrp   r6   r7   ÚsysÚexitÚ_portÚ_dbÚ	_passwordÚ
_namespacer   ÚlenÚ_serverr5   ÚintÚinfo)r   r   rz   Úfieldsr   r   r   r   þ   sx   
þ€€€€
ÿþüzTokenRedis.__init__c           	      C   sH  zdd l }W n ty   t d¡ t ¡  Y nw t d| ¡ |j| j| j	| j
| jd�}| | j| ¡}|d u r;d S | d¡ ¡ }t d| ¡ | d¡r€zt |¡}|d  d	¡\}}W n8 tyo   t d
| ¡ Y d S  ty   t d| ¡ Y d S w t d|¡rŽ| d	¡\}}n	t d| ¡ d S t d||f ¡ ||gS )Nr   zFpackage redis not found, are you sure you've installed them correctly?zresolving token '%s')rM   rN   ÚdbÚpasswordr\   zresponse from redis : %sÚ{rM   r,   zUnable to decode JSON token: %sz+Unable to find 'host' key in JSON token: %sz\S+:\S+zUnable to parse token: %szhost: %s, port: %s)rz   rp   r6   r7   r{   r|   r„   ÚRedisr‚   r}   r~   r   rQ   r€   ri   r)   Údebugr1   rU   rk   r3   r5   ÚKeyErrorr2   Úmatch)	r   r   rz   ÚclientÚstuffÚresponseStrÚcomborM   rN   r   r   r   r   8  sH   
þÿ

ÿÿýzTokenRedis.lookupN)r   r   r   Ú__doc__r   r   r   r   r   r   rv   Â   s    ;:rv   c                       r@   )ÚUnixDomainSocketDirectoryc                    s&   t ƒ j|i |¤Ž tj | j¡| _d S r   )r   r   r$   r%   Úabspathr   Ú	_dir_pathr   r"   r   r   r   ^  s   z"UnixDomainSocketDirectory.__init__c              
   C   s´   z=dd l }tj | j¡sW d S tj tj | j|¡¡}| | j¡s$W d S tj |¡s-W d S | 	t  |¡j
¡s9W d S d|gW S  tyY } zt dt|ƒ ¡ W Y d }~d S d }~ww )Nr   Úunix_socketz$Error finding unix domain socket: %s)Ústatr$   r%   r-   r”   r“   r&   r1   rD   ÚS_ISSOCKÚst_moderB   r6   r7   rf   )r   r   r–   Úuds_pathrs   r   r   r   r   b  s"   
€þz UnixDomainSocketDirectory.lookuprF   r   r   r"   r   r’   ]  s    r’   )Úloggingr$   r{   rn   r2   rU   Ú	getLoggerr   r6   Úcompiler
   r   r   r   r?   rA   rG   rT   rX   rv   r’   r   r   r   r   Ú<module>   s*    
ÿ(		: 