U
    Aޫ^C                     @   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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Z"dd Z#da$dd Z%G dd de&Z'dd Z(G dd de&Z)dS )z
    werkzeug.debug
    ~~~~~~~~~~~~~~

    WSGI application traceback debugger.

    :copyright: 2007 Pallets
    :license: BSD-3-Clause
    N)chain)basename)join   )	text_type)_log)parse_cookie)gen_salt)BaseRequest)BaseResponse   )Console)get_current_traceback)render_console_htmli:	 c                 C   s0   t | tr| dd} t| d  d d S )Nutf-8replaces
   shittysalt   )
isinstancer   encodehashlibmd5	hexdigest)pin r   ;/tmp/pip-unpacked-wheel-74fb410_/werkzeug/debug/__init__.pyhash_pin'   s    
r   c                  C   s   t d k	rt S dd } |  a t S )Nc                  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
rj   zdd l}W n tk
rd   d }Y nX Y nX |d k	rzl||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IOError
rpartition
subprocessr   r    communicateresearchgroupOSErrorImportErrorwinreg_winregOpenKeyHKEY_LOCAL_MACHINEZKEY_READZKEY_WOW64_64KEYQueryValueExREG_SZr   ZWindowsError)linuxfilenamefvaluer   r    dumpmatchwrZrkZguidZ	guid_typer   r   r   	_generate6   sh    
( 


z!get_machine_id.<locals>._generate)_machine_id)r<   r   r   r   get_machine_id0   s
    Er>   c                   @   s   e Zd ZdZdd ZdS )_ConsoleFramez]Helper class so that we can reuse the frame console code for the
    standalone console.
    c                 C   s   t || _d| _d S )Nr   )r   consoleid)self	namespacer   r   r   __init__   s    
z_ConsoleFrame.__init__N)__name__
__module____qualname____doc__rD   r   r   r   r   r?      s   r?   c              	      s  t jd}d}d|dkr dS |dk	rJ|dd rJd|krF|}n|t| d| jj}zt	 }W n t
tfk
r   d}Y nX tj|}||t| d| jjt|d	dg}tt t g}t }t||D ](}	|	sqt|	tr|	d
}	||	 q|d d| dd  }
dkrJ|d dt| d dd |dkrdD ]D t  dkrXd fddtdt D } qqX}||
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)NN- rF   rE   __file__r   s
   cookiesaltZ__wzd   s   pinsaltz%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getattr	__class__rF   getpassgetuserr.   KeyErrorsysmodulesrE   struuidZgetnoder>   r   r   r   r   r   r   updater   intlenr   range)appr   rvmodnameusernamemodZprobably_public_bitsZprivate_bitshbitZcookie_namer   rW   r   get_pin_and_cookie_name   sT    









rr   c                   @   s   e Zd ZdZd"ddZed	d
 Zejdd
 Zedd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Z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/consoleNTc	           	      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 )
NrM   r   ZWERKZEUG_RUN_MAINtruewarningz * Debugger is active!z- * Debugger PIN disabled. DEBUGGER UNSECURED!infoz * Debugger PIN: %s)rk   evalexframes
tracebacksrequest_keyconsole_pathconsole_init_funcshow_hidden_framesr	   secret_failed_pin_authpin_loggingrZ   r[   r\   r   r   )	rB   rk   ry   r|   r}   r~   r   Zpin_securityr   r   r   r   rD      s(    


zDebuggedApplication.__init__c                 C   s"   t | dst| j\| _| _| jS )N_pinhasattrrr   rk   r   _pin_cookierB   r   r   r   r     s    
zDebuggedApplication.pinc                 C   s
   || _ d S )N)r   )rB   r8   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_namec                 c   s  d}z2|  ||}|D ]
}|V  qt|dr4|  W n tk
r   t|drZ|  td| jdd}|jD ]}|| j|j< qp|| 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-ProtectionrS   zwsgi.errorszpDebugging middleware caught exception in streamed response at a point where response headers were already sent.
)ry   evalex_trustedr   r   r   )rk   r   r   	Exceptionr   r   rz   rA   r{   writeboolcheck_pin_trustZrender_fullry   r   r   log)rB   r[   start_responseZapp_iteritem	tracebackframe
is_trustedr   r   r   debug_application,  sN    


	
   z%DebuggedApplication.debug_applicationc                 C   s   t |j|ddS )zExecute a command in a console.	text/htmlmimetype)Responser@   eval)rB   requestcommandr   r   r   r   execute_command]  s    z#DebuggedApplication.execute_commandc                 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   Nrk   )r   r   r   r   )rz   r~   dict
setdefaultrk   r?   r   r   r[   r   r   r   )rB   r   nsr   r   r   r   display_consolea  s    

z#DebuggedApplication.display_consolec                 C   s   |  }tt|ddS )z/Paste the traceback and return a JSON response.application/jsonr   )paster   jsondumps)rB   r   r   rl   r   r   r   paste_tracebackp  s    z#DebuggedApplication.paste_tracebackc                 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   )rB   r   r6   datar   r   r   r   get_resourceu  s    
z DebuggedApplication.get_resourcec                 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   r\   r   splitr]   r   timePIN_TIMErh   )rB   r[   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 )NrP   g      @g      ?r   )r   sleepr   r   r   r   r   _fail_pin_auth  s    z"DebuggedApplication._fail_pin_authc                 C   s   d}d}|  |j}d}|dkr.|   d}nX|r8d}nN| jdkrHd}n>|jd}| dd| jddkr~d| _d}n|   t	t
||d	d
d}|r|j| jdtt t| jf dd n|r|| j |S )zAuthenticates with the pin.FNT
   r   rJ   rK   r   )auth	exhaustedr   r   z%s|%s)httponly)r   r[   r   r   argsr\   r%   r   r   r   r   r   
set_cookier   rh   r   r   Zdelete_cookie)rB   r   r   r   trust
bad_cookieZentered_pinrl   r   r   r   pin_auth  s:    
zDebuggedApplication.pin_authc                 C   s2   | j r*| jdk	r*tdd tdd| j  tdS )zLog the pin if needed.Nrx   z= * To enable the debugger you need to enter the security pin:z * Debugger pin code: %srK   )r   r   r   r   r   r   r   r   log_pin_request  s     z#DebuggedApplication.log_pin_requestc           
      C   sj  t |}| j}|jddkr4|jd}|jd}|jd}| j|jjdtd}| j|jjdtd}	|d	kr|r| ||}n|d
kr|dk	r|| jkr| 	||}n||dkr|| jkr| 
|}n^|dkr|| jkr|  }nB| 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cmdr7   stb)typefrmresourcer   NZpinauthZprintpin)Requestr   r   r\   r{   rh   rz   r   r   r   r   r   ry   r   r   r}   pathr   )
rB   r[   r   r   responser   argr   r   r   r   r   r   __call__  sF    


zDebuggedApplication.__call__)Frt   ru   NFTT)rE   rF   rG   rH   rD   propertyr   setterr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rs      s2          
$


1/	rs   )*rH   r`   r   r   r   rZ   r   r*   rc   r   rf   	itertoolsr   os.pathr   r   _compatr   	_internalr   httpr   securityr	   wrappersr
   r   r   r   r@   r   Ztbtoolsr   r   r   r   r=   r>   objectr?   rr   rs   r   r   r   r   <module>   s:   	O
S