U
    HaF                     @   s  U 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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lmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlm Z  ddlm!Z! e
j"r"d dl#m$Z$ d dl#m%Z% d dl#m&Z& dZ'e(e(dddZ)da*e
j+e
j,e(e-f  e.d< e
j+e
j,e(e-f  dddZ/G dd dZ0de
j,e
j1e(e(f e
j1d f d d!d"Z2G d#d$ d$Z3dS )%    N)chain)basename)join   )_log)parse_cookie)gen_salt)Request)Response   )Console)Frame)get_current_traceback)render_console_html)	Traceback)StartResponse)WSGIApplication)WSGIEnvironmenti:	 )pinreturnc                 C   s$   t |  ddd d d S )Nz added saltutf-8replace   )hashlibsha1encode	hexdigest)r    r   ;/tmp/pip-unpacked-wheel-ub1y1qyw/werkzeug/debug/__init__.pyhash_pin$   s    r   _machine_idr   c                  C   s4   t d k	rt S tjtjttf  ddd} |  a t S )Nr!   c               
   S   s  d} dD ]T}z&t |d}|  }W 5 Q R X W n tk
rJ   Y qY nX |r| |7 }  q^qz4t dd }| |  dd 7 } W 5 Q R X W n tk
r   Y nX | r| S zTddlm}m} |d	d
dddg|d d }t	
d|}|d k	r|dW S W n ttfk
r   Y nX zdd l}W n tk
rB   Y nX zl||jdd|j|jB H}	||	d\}
}||jkr|
dW  5 Q R  W S |
W  5 Q R  W S Q R X W n tk
r   Y nX d S )N    )z/etc/machine-idz/proc/sys/kernel/random/boot_idrbz/proc/self/cgroup   /r   r   )PopenPIPEZioregz-cZIOPlatformExpertDevicez-d2)stdouts   "serial-number" = <([^>]+)r   zSOFTWARE\Microsoft\CryptographyZMachineGuidr   )openreadlinestripOSError
rpartition
subprocessr%   r&   communicateresearchgroupImportErrorwinregOpenKeyHKEY_LOCAL_MACHINEZKEY_READZKEY_WOW64_64KEYQueryValueExREG_SZr   )linuxfilenamefvaluer%   r&   dumpmatchr4   ZrkZguidZ	guid_typer   r   r   	_generate1   sb    
( 

z!get_machine_id.<locals>._generate)r    tOptionalUnionstrbytes)r?   r   r   r   get_machine_id+   s
    ErE   c                   @   s*   e Zd ZdZejeejf dddZdS )_ConsoleFramez]Helper class so that we can reuse the frame console code for the
    standalone console.
    )	namespacec                 C   s   t || _d| _d S )Nr   )r   consoleid)selfrG   r   r   r   __init__   s    
z_ConsoleFrame.__init__N)	__name__
__module____qualname____doc__r@   DictrC   AnyrK   r   r   r   r   rF   z   s   rF   r   NN)appr   c              	      s  t jd}d}d|dkr dS |dk	rJ|dd rJd|krF|}n|t| dtt| j	j
}zt }W n ttfk
r   d}Y nX tj|}||t| dt| jt|d	dg}tt t g}t }t||D ](}	|	sqt|	tr|	d
}	||	 q|d d| dd  }
dkrV|d t| dddd |dkrdD ]D t  dkrdd  fddt!dt D } qqd}||
fS )aQ  Given an application object this returns a semi-stable 9 digit pin
    code and a random key.  The hope is that this is stable between
    restarts to not make debugging particularly frustrating.  If the pin
    was forcefully disabled this returns `None`.

    Second item in the resulting tuple is the cookie name for remembering.
    ZWERKZEUG_DEBUG_PINNoffrR   - rM   rL   __file__r   s
   cookiesaltZ__wzd   s   pinsalt   Z09d	   )         r   c                 3   s&   | ]}||     d V  qdS )0N)rjust).0xZ
group_sizenumr   r   	<genexpr>   s   z*get_pin_and_cookie_name.<locals>.<genexpr>)"osenvirongetr   isdigitgetattrr@   castobject	__class__rM   getpassgetuserr3   KeyErrorsysmodulestyperL   rC   uuidZgetnoderE   r   r   r   
isinstancer   updater   intlenr   range)rS   r   rvmodnameusernamemodZprobably_public_bitsZprivate_bitshbitZcookie_namer   rb   r   get_pin_and_cookie_name   sT    










r   c                   @   sP  e Zd ZU dZeed< eed< d-d	eeeejej	g ej
eejf f  eeedd
	ddZeeje dddZejeddddZeedddZddeje dddZeeejeef edddZeedddZeeedd d!Zdeje d"d#d$Zddd%d&Zeedd'd(Zedd)d*Zddej e dd+d,Z!dS ).DebuggedApplicationa  Enables debugging support for a given application::

        from werkzeug.debug import DebuggedApplication
        from myapp import app
        app = DebuggedApplication(app, evalex=True)

    The `evalex` keyword argument allows evaluating expressions in a
    traceback's frame context.

    :param app: the WSGI application to run debugged.
    :param evalex: enable exception evaluation feature (interactive
                   debugging).  This requires a non-forking server.
    :param request_key: The key that points to the request object in ths
                        environment.  This parameter is ignored in current
                        versions.
    :param console_path: the URL for a general purpose console.
    :param console_init_func: the function that is executed before starting
                              the general purpose console.  The return value
                              is used as initial namespace.
    :param show_hidden_frames: by default hidden traceback frames are skipped.
                               You can show them by setting this parameter
                               to `True`.
    :param pin_security: can be used to disable the pin based security system.
    :param pin_logging: enables the logging of the pin system.
    _pin_pin_cookieFwerkzeug.request/consoleNTr   )	rS   evalexrequest_keyconsole_pathconsole_init_funcshow_hidden_framespin_securitypin_loggingr   c	           	      C   s   |sd }|| _ || _i | _i | _|| _|| _|| _|| _td| _	d| _
|| _|rtjddkr|rtdd | jd krtdd qtdd	| j nd | _d S )
NrX   r   ZWERKZEUG_RUN_MAINtruewarningz * Debugger is active!z- * Debugger PIN disabled. DEBUGGER UNSECURED!infoz * Debugger PIN: %s)rS   r   frames
tracebacksr   r   r   r   r   secret_failed_pin_authr   re   rf   rg   r   r   )	rJ   rS   r   r   r   r   r   r   r   r   r   r   rK      s(    


zDebuggedApplication.__init__r!   c                 C   s&   t | ds t| j}|\| _| _| jS )Nr   hasattrr   rS   r   r   rJ   Z
pin_cookier   r   r   r     s    

zDebuggedApplication.pin)r<   r   c                 C   s
   || _ d S )N)r   )rJ   r<   r   r   r   r   #  s    c                 C   s&   t | ds t| j}|\| _| _| jS )zThe name of the pin cookie.r   r   r   r   r   r   pin_cookie_name'  s    

z#DebuggedApplication.pin_cookie_namer   r   )rf   start_responser   c                 c   s   d}z,|  ||}|E dH  t|dr.|  W n tk
r   t|drR|  td| jdd}|jD ]}|| j|j< qh|| j|j< z|dddg W n" tk
r   |d	 	d
 Y n.X t
| |}|j| j|| jdddV  ||d	  Y nX dS )z6Run the application and conserve the traceback frames.Ncloser   T)skipr   Zignore_system_exceptionsz500 INTERNAL SERVER ERROR)zContent-Typeztext/html; charset=utf-8)zX-XSS-Protectionr^   zwsgi.errorszpDebugging middleware caught exception in streamed response at a point where response headers were already sent.
)r   evalex_trustedr   r   r   )rS   r   r   	Exceptionr   r   r   rI   r   writeboolcheck_pin_trustZrender_fullr   r   r   log)rJ   rf   r   Zapp_iter	tracebackframe
is_trustedr   r   r   debug_application/  sL    



	
   z%DebuggedApplication.debug_application)requestcommandr   r   c                 C   s   t |j|ddS )zExecute a command in a console.	text/htmlmimetype)r
   rH   eval)rJ   r   r   r   r   r   r   execute_commanda  s    z#DebuggedApplication.execute_command)r   r   c                 C   sh   d| j krB| jdkri }nt|  }|d| j t|| j d< t| |j}t	t
| j|dddS )zDisplay a standalone shell.r   NrS   )r   r   r   r   )r   r   dict
setdefaultrS   rF   r   r   rf   r
   r   r   )rJ   r   nsr   r   r   r   display_consoleg  s    

z#DebuggedApplication.display_console)r   r:   r   c                 C   sj   t dt|}ztt|}W n tk
r6   d}Y nX |dk	r^t|d pPd}t||dS tdddS )	z0Return a static resource from the shared folder.ZsharedNr   zapplication/octet-streamr   z	Not Foundi  )status)	r   r   pkgutilget_data__package__r,   	mimetypes
guess_typer
   )rJ   r   r:   datar   r   r   r   get_resourcev  s    
z DebuggedApplication.get_resource)rf   r   c                 C   sp   | j dkrdS t|| j}|r*d|kr.dS |dd\}}| sJdS |t| j kr\dS t t t	|k S )a!  Checks if the request passed the pin test.  This returns `True` if the
        request is trusted on a pin/cookie basis and returns `False` if not.
        Additionally if the cookie's stored pin hash is wrong it will return
        `None` so that appropriate action can be taken.
        NT|Fr   )
r   r   rg   r   splitrh   r   timePIN_TIMErv   )rJ   rf   valtsZpin_hashr   r   r   r     s    
z#DebuggedApplication.check_pin_trustc                 C   s*   t | jdkrdnd |  jd7  _d S )Nr[   g      @g      ?r   )r   sleepr   rJ   r   r   r   _fail_pin_auth  s    z"DebuggedApplication._fail_pin_authc           	      C   s   d}d}|  |j}tt| j}d}|dkr<|   d}nT|rFd}nJ| jdkrVd}n:|jd }|	 
dd|
ddkrd| _d}n|   tt||d	d
d}|r|j| jtt  dt| ddd n|r|| j |S )zAuthenticates with the pin.FNT
   r   rU   rV   r   )auth	exhaustedzapplication/jsonr   r   None)httponlysamesite)r   rf   r@   rj   rC   r   r   r   argsr+   r   r
   jsondumps
set_cookier   rv   r   r   Zdelete_cookie)	rJ   r   r   r   trustr   
bad_cookieZentered_pinry   r   r   r   pin_auth  s>    

zDebuggedApplication.pin_authc                 C   s0   | j r(| jdk	r(tdd tdd| j tdS )zLog the pin if needed.Nr   z= * To enable the debugger you need to enter the security pin:z * Debugger pin code: %srV   )r   r   r   r
   r   r   r   r   log_pin_request  s     z#DebuggedApplication.log_pin_requestc           	      C   s  t |}| j}|jddkr|jd}|jd}|jd}| j|jjdtd}|dkrt|rt| ||}nr|d	kr|| jkr| |}nT|d
kr|| jkr| 	 }n8| j
r|dk	r|dk	r| j|kr| |r| |||}n,| j
r| jdk	r|j| jkr| |}|||S )zDispatch the requests.Z__debugger__yescmdr;   sfrm)rr   resourceZpinauthZprintpinN)r	   r   r   rg   r   rv   r   r   r   r   r   r   r   r   pathr   )	rJ   rf   r   r   responser   argr   r   r   r   r   __call__  s@    


zDebuggedApplication.__call__)Fr   r   NFTT)"rL   rM   rN   rO   rC   __annotations__r   r@   rA   CallablerP   rQ   rK   propertyr   setterr   IteratorrD   r   r	   rB   r   rF   r
   r   r   r   r   r   r   r   Iterabler   r   r   r   r   r      s\   
       $ 3  2
 r   )4rm   r   r   r   re   r   r0   rp   r   typingr@   rs   	itertoolsr   os.pathr   r   	_internalr   httpr   securityr   Zwrappers.requestr	   Zwrappers.responser
   rH   r   Ztbtoolsr   r   r   r   TYPE_CHECKINGZ_typeshed.wsgir   r   r   r   rC   r   r    rA   rB   rD   r   rE   rF   Tupler   r   r   r   r   r   <module>   sJ    OV