
À«‘_‰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% Gd d „  d e& ƒ Z' d d „  Z( Gd 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_htmlé<   é   é   c             C   sB   t  |  t ƒ r! |  j d d ƒ }  t j |  d ƒ j ƒ  d  d … S)Nzutf-8Úreplaces
   shittysalté   )Ú
isinstancer   ÚencodeÚhashlibÚmd5Ú	hexdigest)Úpin© r   ú;/tmp/pip-build-5gj8f0j9/Werkzeug/werkzeug/debug/__init__.pyÚhash_pin'   s    r   c              C   s)   t  d  k	 r t  Sd d „  }  |  ƒ  a  t  S)Nc           3   S   s9  d }  xf d D]^ } y/ t  | d ƒ � } | j ƒ  j ƒ  } Wd  QRXWn t k
 rY w Yn X| r |  | 7}  Pq Wy@ t  d d ƒ �* } |  | j ƒ  j ƒ  j d ƒ d 7}  Wd  QRXWn t k
 rÃ Yn X|  rÎ |  Syp d d	 l m } m } | d
 d d d d g d | ƒj ƒ  d } t	 j
 d | ƒ } | d  k	 r=| j d ƒ SWn t t f k
 rXYn Xy d d  l } Wn= t k
 r¨y d d  l } Wn t k
 r£d  } Yn XYn X| d  k	 r5yk | j | j d d | j | j Bƒ �? }	 | j |	 d ƒ \ }
 } | | j k r|
 j d ƒ S|
 SWd  QRXWn t k
 r4Yn Xd  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   zSOFTWARE\Microsoft\CryptographyZMachineGuidzutf-8)r   r    )Ú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   s`    
.!z!get_machine_id.<locals>._generate)Ú_machine_id)r@   r   r   r   Úget_machine_id0   s
    E	rB   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__rH   r   r   r   r   rC      s   rC   c                sK  t  j j d ƒ } d } d ‰ | d k r. d S| d k	 rm | j d d ƒ j ƒ  rm d | k rg | } n | ‰ t |  d |  j j ƒ } y t j	 ƒ  } Wn t
 t f k
 rµ d } Yn Xt j j | ƒ } | | t |  d |  j j ƒ t | d d ƒ g } t t j ƒ  ƒ t ƒ  g } t j ƒ  } xK t | | ƒ D]: }	 |	 s>q/t |	 t ƒ r\|	 j d	 ƒ }	 | j |	 ƒ q/W| j d
 ƒ d | j ƒ  d d … }
 ˆ d k rÐ| j d ƒ d t | j ƒ  d ƒ d d … ‰ | d k rAxb d D]T ‰  t ˆ ƒ ˆ  d k rãd j ‡  ‡ f d d †  t d t ˆ ƒ ˆ  ƒ Dƒ ƒ } PqãWˆ } | |
 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ú-Ú rJ   rI   Ú__file__zutf-8s
   cookiesaltZ__wzdé   s   pinsaltz%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)rT   rU   rV   )ÚosÚenvironÚgetr   ÚisdigitÚgetattrÚ	__class__rJ   ÚgetpassÚgetuserr2   ÚKeyErrorÚsysÚmodulesrI   ÚstrÚuuidÚgetnoderB   r   r   r   r   r   r   Úupdater   ÚintÚlenr   Úrange)Úappr   ÚrvÚmodnameÚusernameÚmodZprobably_public_bitsZprivate_bitsÚhÚbitZcookie_namer   )r[   r\   r   Úget_pin_and_cookie_name‰   sR    $	#rw   c            	   @   sè   e  Z d  Z d Z d d d d d d 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.
    Fzwerkzeug.requestz/consoleNTc	       	      C   sé   | s d  } | |  _  | |  _ i  |  _ i  |  _ | |  _ | |  _ | |  _ | |  _ t d ƒ |  _	 d |  _
 | |  _ | rÜ t j j d ƒ d k rå | rå t d d ƒ |  j d  k rÅ t d d ƒ qå t d d	 |  j ƒ n	 d  |  _ d  S)
NrQ   r   ZWERKZEUG_RUN_MAINÚtrueÚwarningz * Debugger is active!z- * Debugger PIN disabled. DEBUGGER UNSECURED!Úinfoz * Debugger PIN: %s)rp   ÚevalexÚframesÚ
tracebacksÚrequest_keyÚconsole_pathÚconsole_init_funcÚshow_hidden_framesr	   ÚsecretÚ_failed_pin_authÚpin_loggingr^   r_   r`   r   r   )	rF   rp   r|   r   r€   r�   r‚   Zpin_securityr…   r   r   r   rH   ÷   s(    										zDebuggedApplication.__init__c             C   s1   t  |  d ƒ s* t |  j ƒ \ |  _ |  _ |  j S)NÚ_pin)Úhasattrrw   rp   r†   Ú_pin_cookie)rF   r   r   r   r     s    zDebuggedApplication.pinc             C   s   | |  _  d  S)N)r†   )rF   r<   r   r   r   r   !  s    c             C   s1   t  |  d ƒ s* t |  j ƒ \ |  _ |  _ |  j S)zThe name of the pin cookie.rˆ   )r‡   rw   rp   r†   rˆ   )rF   r   r   r   Úpin_cookie_name%  s    z#DebuggedApplication.pin_cookie_namec             c   sa  d } yE |  j  | | ƒ } x | D] } | Vq" Wt | d ƒ rJ | j ƒ  Wnt k
 r\t | d ƒ rt | j ƒ  t d d d |  j d d ƒ } x! | j D] } | |  j | j <qœ W| |  j | j <y | d d d g ƒ Wn# t k
 r| d j	 d ƒ YnE Xt
 |  j | ƒ ƒ } | j d |  j d | d |  j ƒ j d d ƒ V| j | d ƒ Yn Xd S)z6Run the application and conserve the traceback frames.NÚcloseÚskipr   r‚   Zignore_system_exceptionsTz500 INTERNAL SERVER ERRORúContent-Typeútext/html; charset=utf-8úX-XSS-ProtectionrW   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Ž   rW   )rp   r‡   rŠ   Ú	Exceptionr   r‚   r}   rE   r~   ÚwriteÚboolÚcheck_pin_trustZrender_fullr|   rƒ   r   Úlog)rF   r_   Ústart_responseZapp_iterÚitemÚ	tracebackÚframeÚ
is_trustedr   r   r   Údebug_application,  s<    	
		
	z%DebuggedApplication.debug_applicationc             C   s   t  | j j | ƒ d d ƒS)zExecute a command in a console.Úmimetypez	text/html)ÚResponserD   Úeval)rF   ÚrequestÚcommandr˜   r   r   r   Úexecute_command]  s    z#DebuggedApplication.execute_commandc             C   s™   d |  j  k r_ |  j d k r' i  } n t |  j ƒ  ƒ } | j d |  j ƒ t | ƒ |  j  d <t |  j | j ƒ ƒ } t	 t
 d |  j d | ƒ d d ƒS)zDisplay a standalone shell.r   Nrp   rƒ   r�   r›   z	text/html)r}   r�   ÚdictÚ
setdefaultrp   rC   r’   r“   r_   rœ   r   rƒ   )rF   rž   Únsr™   r   r   r   Údisplay_consolea  s    	z#DebuggedApplication.display_consolec             C   s%   | j  ƒ  } t t j | ƒ d d ƒS)z/Paste the traceback and return a JSON response.r›   zapplication/json)Úpasterœ   ÚjsonÚdumps)rF   rž   r—   rq   r   r   r   Úpaste_tracebackp  s    z#DebuggedApplication.paste_tracebackc             C   s‹   t  d t | ƒ ƒ } y t j t | ƒ } Wn t k
 rE d } Yn X| d k	 r{ t j | ƒ d ph d } t | d | ƒSt d d d ƒS)	z0Return a static resource from the shared folder.ZsharedNr   zapplication/octet-streamr›   z	Not FoundÚstatusi”  )	r   r   ÚpkgutilÚget_dataÚ__package__r1   Ú	mimetypesÚ
guess_typerœ   )rF   rž   r:   Údatar›   r   r   r   Úget_resourceu  s    z DebuggedApplication.get_resourcec             C   s�   |  j  d k r d St | ƒ j |  j ƒ } | s> d | k rB d S| j d d ƒ \ } } | j ƒ  sj d S| t |  j  ƒ k rƒ d St 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   r`   r‰   Úsplitra   r   ÚtimeÚPIN_TIMErm   )rF   r_   ÚvalÚtsZpin_hashr   r   r   r“   �  s    z#DebuggedApplication.check_pin_trustc             C   s5   t  j |  j d k r d n d ƒ |  j d 7_ d  S)NrT   g      @g      à?r   )r³   Úsleepr„   )rF   r   r   r   Ú_fail_pin_auth“  s    "z"DebuggedApplication._fail_pin_authc             C   sG  d } d } |  j  | j ƒ } d } | d k rC |  j ƒ  d } n‚ | rR d } ns |  j d k rj d } n[ | j j d ƒ } | j ƒ  j d d ƒ |  j j d d ƒ k r» d |  _ d } n
 |  j ƒ  t	 t
 j d	 | d
 | i ƒ d d ƒ} | r-| j |  j d t t j ƒ  ƒ t |  j ƒ f d d ƒn | rC| j |  j ƒ | S)zAuthenticates with the pin.FNTé
   r   rN   rO   r   ÚauthÚ	exhaustedr›   zapplication/jsonz%s|%sÚhttponly)r“   r_   r¸   r„   Úargsr`   r)   r   r   rœ   r¦   r§   Ú
set_cookier‰   rm   r³   r   Zdelete_cookie)rF   rž   r»   rº   ÚtrustÚ
bad_cookieZentered_pinrq   r   r   r   Úpin_auth—  s6    
			-		
	%
zDebuggedApplication.pin_authc             C   sC   |  j  r9 |  j d k	 r9 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: %srO   )r…   r   r   rœ   )rF   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 d t ƒƒ } |  j j | j j d d t ƒƒ }	 | d	 k rÒ | rÒ |  j | | ƒ } qõ| d
 k r| d k	 r| |  j k r|  j	 | | ƒ } qõ| d k r;| |  j k r;|  j
 | ƒ } qõ| d k re| |  j k re|  j ƒ  } qõ|  j rõ| d k	 rõ|	 d k	 rõ|  j | k rõ|  j | ƒ rõ|  j | | |	 ƒ } n9 |  j rõ|  j d k	 rõ| j |  j k rõ|  j | ƒ } | | | ƒ S)zDispatch the requests.Z__debugger__ÚyesÚcmdr;   ÚsÚtbÚtypeZfrmÚresourcer¥   NZpinauthZprintpin)ÚRequestrš   r½   r`   r~   rm   r}   r°   rƒ   r¨   rÁ   rÂ   r|   r“   r    r€   Úpathr¤   )
rF   r_   r•   rž   ÚresponserÄ   Úargrƒ   r—   r˜   r   r   r   Ú__call__Ï  s6    	$$'		zDebuggedApplication.__call__)rI   rJ   rK   rL   rH   Úpropertyr   Úsetterr‰   rš   r    r¤   r¨   r°   r“   r¸   rÁ   rÂ   rÍ   r   r   r   r   rx   Ü   s*   1/	rx   i  i€Q i€:	 )*rL   rd   r   r¦   r­   r^   rª   r.   rg   r³   rj   Ú	itertoolsr   Úos.pathr   r   Ú_compatr   Z	_internalr   Úhttpr   Úsecurityr	   Zwrappersr
   rÉ   r   rœ   rD   r   Ztbtoolsr   r   r´   r   rA   rB   ÚobjectrC   rw   rx   r   r   r   r   Ú<module>
   s:   O
S