3
eE                 @   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
j+e
j,e(e-f  dddZ.G dd dZ/de
j,e
j0e(e(f e
j0d( f d d!d"Z1G d#d$ d$Z2dS ))    N)chain)basename)join   )_log)parse_cookie)gen_salt)Request)Response   )Console)Frame)get_current_traceback)render_console_html)	Traceback)StartResponse)WSGIApplication)WSGIEnvironment<         )pinreturnc             C   s$   t j|  djddj d d S )Nz added saltzutf-8replace   )hashlibsha1encode	hexdigest)r    r   ;/tmp/pip-build-3irwxpxt/Werkzeug/werkzeug/debug/__init__.pyhash_pin$   s    r!   )r   c              C   s4   t d k	rt S tjtjttf  ddd} |  a t S )N)r   c           %   S   s  d} xXdD ]P}y&t |d}|j j }W d Q R X W n tk
rJ   w
Y nX |r
| |7 } P q
W y4t dd }| |j j jdd 7 } W d Q R X W n tk
r   Y nX | r| S yRdd	lm}m} |d
ddddg|dj d }t	j
d|}|d k	r |jdS W n ttfk
r   Y nX tjdkrdd l}yP|j|jdd|j|jB ,}	|j|	d\}
}||jkrv|
jdS |
S Q R X W n tk
r   Y nX d S )N    /etc/machine-id/proc/sys/kernel/random/boot_idrbz/proc/self/cgroup   /r   r   )PopenPIPEZioregz-cZIOPlatformExpertDevicez-d2)stdouts   "serial-number" = <([^>]+)r   win32zSOFTWARE\Microsoft\CryptographyZMachineGuidzutf-8)r#   r$   )openreadlinestripOSError
rpartition
subprocessr'   r(   communicateresearchgroupImportErrorsysplatformwinregOpenKeyHKEY_LOCAL_MACHINEZKEY_READZKEY_WOW64_64KEYQueryValueExREG_SZr   )linuxfilenamefvaluer'   r(   dumpmatchr9   ZrkZguidZ	guid_typer   r   r    	_generate1   sV    
(

z!get_machine_id.<locals>._generate)_machine_idtOptionalUnionstrbytes)rD   r   r   r    get_machine_id+   s
    CrK   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)selfrM   r   r   r    __init__}   s    
z_ConsoleFrame.__init__N)	__name__
__module____qualname____doc__rF   DictrI   AnyrQ   r   r   r   r    rL   x   s   rL   r   )appr   c                s  t jjd}d}d|dkr dS |dk	rJ|jddj rJd|krF|}n|t| dtjt| j	j
}ytj }W n ttfk
r   d}Y nX tjj|}||t| dt| jt|ddg}ttj t g}tj }x8t||D ]*}	|	sqt|	tr |	jd	}	|j|	 qW |jd
 d|j dd  }
dkr\|jd t|j dddd |dkrxLdD ]@ t  dkrldj  fddt!dt D }P qlW }||
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off- rS   rR   __file__zutf-8s
   cookiesaltZ__wzd   s   pinsalt   Z09d	            r   c             3   s&   | ]}||   j  d V  qdS )0N)rjust).0x)
group_sizenumr   r    	<genexpr>   s   z*get_pin_and_cookie_name.<locals>.<genexpr>)NN)r`   ra   rb   )"osenvirongetr   isdigitgetattrrF   castobject	__class__rS   getpassgetuserr6   KeyErrorr7   modulestyperR   rI   uuidgetnoderK   r   r   r   
isinstancer   updater   intlenr   range)rX   r   rvmodnameusernamemodZprobably_public_bitsZprivate_bitshbitZcookie_namer   )rg   rh   r    get_pin_and_cookie_name   sR    







r   c               @   sH  e Zd ZU dZee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.
    Fwerkzeug.request/consoleNTr   )	rX   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jddkr|rtdd | jd krtdd qtdd	| j nd | _d S )
Nr]   r   ZWERKZEUG_RUN_MAINtruewarningz * Debugger is active!z- * Debugger PIN disabled. DEBUGGER UNSECURED!infoz * Debugger PIN: %s)rX   r   frames
tracebacksr   r   r   r   r   secret_failed_pin_authr   rj   rk   rl   r   r   )	rP   rX   r   r   r   r   r   r   r   r   r   r    rQ      s(    


zDebuggedApplication.__init__)r   c             C   s&   t | ds t| j}|\| _| _| jS )N_pin)hasattrr   rX   r   _pin_cookie)rP   
pin_cookier   r   r    r     s    

zDebuggedApplication.pin)rA   r   c             C   s
   || _ d S )N)r   )rP   rA   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   rX   r   r   )rP   r   r   r   r    pin_cookie_name%  s    

z#DebuggedApplication.pin_cookie_namer   r   )rk   start_responser   c             c   s  d}y,| j ||}|E dH  t|dr.|j  W n tk
r    t|drT|j  td| jdd}x|jD ]}|| j|j< qlW || j|j< y|dddg W n" tk
r   |d j	d Y n.X t
| j|}|j| j|| jdjddV  |j|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Content-Typetext/html; charset=utf-8X-XSS-Protectionrc   zwsgi.errorszpDebugging middleware caught exception in streamed response at a point where response headers were already sent.
)r   evalex_trustedr   zutf-8r   )r   r   )r   rc   )rX   r   r   	Exceptionr   r   r   rO   r   writeboolcheck_pin_trustZrender_fullr   r   r   log)rP   rk   r   Zapp_iter	tracebackframe
is_trustedr   r   r    debug_application-  s:    



z%DebuggedApplication.debug_application)requestcommandr   r   c             C   s   t |jj|ddS )zExecute a command in a console.z	text/html)mimetype)r
   rN   eval)rP   r   r   r   r   r   r    execute_command_  s    z#DebuggedApplication.execute_command)r   r   c             C   sh   d| j krB| jdkri }nt| j }|jd| j t|| j d< t| j|j}t	t
| j|dddS )zDisplay a standalone shell.r   NrX   )r   r   z	text/html)r   )r   r   dict
setdefaultrX   rL   r   r   rk   r
   r   r   )rP   r   nsr   r   r   r    display_consolee  s    

z#DebuggedApplication.display_console)r   r?   r   c             C   sj   t dt|}ytjt|}W n tk
r6   d}Y nX |dk	r^tj|d pPd}t||dS tdddS )	z0Return a static resource from the shared folder.ZsharedNr   zapplication/octet-stream)r   z	Not Foundi  )status)	r   r   pkgutilget_data__package__r/   	mimetypes
guess_typer
   )rP   r   r?   datar   r   r   r    get_resourcet  s    
z DebuggedApplication.get_resource)rk   r   c             C   sr   | j dkrdS t|j| j}| s,d|kr0dS |jdd\}}|j sLdS |t| j kr^dS tj 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   rl   r   splitrm   r!   timePIN_TIMEr{   )rP   rk   valtsZpin_hashr   r   r    r     s    
z#DebuggedApplication.check_pin_trustc             C   s*   t j| jdkrdnd |  jd7  _d S )Nr`   g      @g      ?r   )r   sleepr   )rP   r   r   r    _fail_pin_auth  s    z"DebuggedApplication._fail_pin_authc       	      C   s   d}d}| j |j}tjt| j}d}|dkr<| j  d}nT|rFd}nJ| jdkrVd}n:|jd }|j	 j
dd|j
ddkrd| _d}n| j  ttj||d	d
d}|r|j| jttj  dt| dd|jd n|r|j| j |S )zAuthenticates with the pin.FNT
   r   rZ   r[   r   )auth	exhaustedzapplication/json)r   r   ZStrict)httponlyZsamesitesecure)r   rk   rF   ro   rI   r   r   r   argsr.   r   r
   jsondumps
set_cookier   r{   r   r!   Z	is_secureZdelete_cookie)	rP   r   r   r   trustr   
bad_cookieZentered_pinr~   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: %sr[   )r   r   r   r
   )rP   r   r   r    log_pin_request  s
    z#DebuggedApplication.log_pin_requestc       	      C   s  t |}| j}|jjddkr|jjd}|jjd}|jjd}| jj|jjdtd}|dkrt|rt| j||}nr|d	kr|| jkr| j|}nT|d
kr|| jkr| j	 }n8| j
r|dk	r|dk	r| j|kr| j|r| j|||}n,| j
r| jdk	r|j| jkr| j|}|||S )zDispatch the requests.Z__debugger__yescmdr@   sZfrm)rv   resourceZpinauthZprintpinN)r	   r   r   rl   r   r{   r   r   r   r   r   r   r   r   pathr   )	rP   rk   r   r   responser   argr   r   r   r   r    __call__  s0    



zDebuggedApplication.__call__)Fr   r   NFTT)#rR   rS   rT   rU   rI   r   r   r   rF   rG   CallablerV   rW   rQ   propertyr   setterr   IteratorrJ   r   r	   rH   r   rL   r
   r   r   r   r   r   r   r   Iterabler   r   r   r   r    r      s:   
      .13
r   i  iQ i:	 )NN)3rr   r   r   r   rj   r   r3   r7   r   typingrF   rw   	itertoolsr   os.pathr   r   Z	_internalr   httpr   securityr   Zwrappers.requestr	   Zwrappers.responser
   rN   r   Ztbtoolsr   r   r   r   ZTYPE_CHECKINGZ_typeshed.wsgir   r   r   r   rI   r!   rE   rG   rH   rJ   rK   rL   Tupler   r   r   r   r   r    <module>   sH    M(T