o
    va1                  
   @   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mZm	Z	m
Z
 ddlmZ ddlmZ ddlmZmZ ddlmZ ddlmZ dd	lmZ zddlZd
ZW n eyn Z zdZede W Y dZ[ndZ[ww G dd deZG dd dejZ dS )zPorts scanner plugin.    N)WINDOWSMACOSBSD)GlancesPortsList)GlancesWebList)TimerCounter)	bool_type)logger)GlancesPluginTFzAMissing Python Lib ({}), Ports plugin is limited to port scanningc                       sh   e Zd ZdZd fdd	Z fddZejejdd Z	d	d
 Z
dddZdddZdddZ  ZS )PluginzGlances ports scanner plugin.Nc                    sT   t t| j||g d || _|| _d| _t||d t||d	  | _
d| _dS )zInit the plugin.)argsconfigZstats_init_valueT)r   r   N)superr   __init__r   r   Zdisplay_curser   Zget_ports_listr   Zget_web_liststats_thread)selfr   r   	__class__ ?/usr/lib/python3/dist-packages/glances/plugins/glances_ports.pyr   0   s   
zPlugin.__init__c                    s&   | j dur
| j   tt|   dS )z+Overwrite the exit method to close threads.N)r   stopr   r   exitr   r   r   r   r   B   s   

zPlugin.exitc                 C   sL   | j dkr"| jdu rd}n| j }|st| j| _| j  | jS 	 | jS )zUpdate the ports list.ZlocalNF)Zinput_methodr   Zis_aliveThreadScannerr   start)r   Zthread_is_runningr   r   r   updateI   s   




zPlugin.updatec                 C   s   dS )zReturn the key of the list.indicer   r   r   r   r   get_keyd   s   zPlugin.get_key Fc                 C   s   d}|d du rd}n"|d dkrd}nt |d ttfr-|d dur-|d |d kr-d}| j|d	}| || | || |||    |S )
z?Return the alert status relative to the port scan return value.OKstatusNCAREFULr   CRITICALrtt_warningWARNINGheader)
isinstancefloatintget_stat_namemanage_thresholdmanage_actionlowerr   )r   portr(   logret	stat_namer   r   r   get_ports_alerth   s&   

zPlugin.get_ports_alertc                 C   s   d}|d du rd}n|d dvrd}n|d dur$|d |d kr$d	}| j |d
}| || | || |||    |S )zBReturn the alert status relative to the web/url scan return value.r!   r"   Nr#   )   i-  i.  r$   r%   elapsedr&   r'   )r,   r-   r.   r/   r   )r   webr(   r1   r2   r3   r   r   r   get_web_alert   s   
zPlugin.get_web_alertc              
   C   s  g }| j r|jr
|S |d }| j D ]}d|v r|d du r d}n+|d du r)d}n"t|d tr9|d du r9d}n|d d	krBd
}n	d|d d }dj|d d	| |d}|| | d|}|| || j||d d d ||   qd|v rdj|d d	| |d}|| | t|d t	j
rd|d }n|d du rd}n|d }d|}|| || j||d d d ||   qz|  W |S  ty   Y |S w )z2Return the dict to display in the curse interface.   hostNNoner"   ZScanningTZOpenr   ZTimeoutz	{0:.0f}msg     @@z
{:{width}}description)widthz{:>9}r   Z_rttr'   urlzCode {})r   Zdisable_portsr)   r	   formatappendZcurse_add_liner4   Zcurse_new_linenumbersNumberr8   pop
IndexError)r   r   Z	max_widthr2   Zname_max_widthpr"   msgr   r   r   	msg_curse   sf   







zPlugin.msg_curse)NN)r    F)__name__
__module____qualname____doc__r   r   r   Z_check_decoratorZ_log_result_decoratorr   r   r4   r8   rG   __classcell__r   r   r   r   r   -   s    

r   c                       s|   e Zd ZdZ fddZdd Zedd Zejdd Zdd
dZ	dd Z
dd Zdd Zdd Zdd Zdd Z  ZS )r   zP
    Specific thread for the port/web scanner.

    stats is a list of dict
    c                    s8   t d| tt|   t | _|| _	d| _
dS )zInit the class.z-ports plugin - Create thread for scan list {}ZportsN)r
   debugr?   r   r   r   	threadingZEvent_stopper_statsplugin_name)r   r   r   r   r   r      s
   

zThreadScanner.__init__c                 C   sR   | j D ]#}|  r dS d|v r| | td qd|v r&tr&| | qdS )z`Grab the stats.

        Infinite loop, should be stopped by calling the stop() method.
        r0      r>   N)rP   stopped
_port_scantimesleeprequests_tag	_web_scan)r   rE   r   r   r   run   s   


zThreadScanner.runc                 C   s   | j S )zStats getter.rP   r   r   r   r   r      s   zThreadScanner.statsc                 C   s
   || _ dS )zStats setter.NrZ   )r   valuer   r   r   r      s   
Nc                 C   s    t d| j | j  dS )zStop the thread.z,ports plugin - Close thread for scan list {}N)r
   rM   r?   rP   rO   set)r   timeoutr   r   r   r     s   zThreadScanner.stopc                 C   s
   | j  S )z%Return True is the thread is stopped.)rO   ZisSetr   r   r   r   rS   
  s   
zThreadScanner.stoppedc              
   C   s   zt j|d d|d |d |d d}W n  ty4 } zt| d|d< d	|d
< W Y d}~|S d}~ww |j|d< |j |d
< |S )z3Scan the  Web/URL (dict) and update the status key.r>   TZ
ssl_verifyproxiesr]   )Zallow_redirectsZverifyr^   r]   Errorr"   r   r6   N)requestshead	Exceptionr
   rM   Zstatus_coder6   Ztotal_seconds)r   r7   Zreqer   r   r   rX     s"   



zThreadScanner._web_scanc                 C   s$   t |d dkr| |S | |S )z9Scan the port structure (dict) and update the status key.r0   r   )r+   _port_scan_icmp_port_scan_tcp)r   r0   r   r   r   rT     s   

zThreadScanner._port_scanc              
   C   sR   |}zt |}W |S  ty( } ztd| j|| W Y d}~|S d}~ww )zConvert hostname to IP address.z({}: Cannot convert {} to IP address ({})N)socketZgethostbynamerb   r
   rM   r?   rQ   )r   Zhostnameiprc   r   r   r   _resolv_name&  s    zThreadScanner._resolv_namec           	   
   C   s   d}t r	d}d}ntstrd}d}nd}d}d|d|t| |d	 | |d
 g}ttjd}z t }t	j
|||dd}|dkrJ| |d< W |S d|d< W |S  t	jy_   d|d< Y |S  ty~ } ztd| j|d
 | W Y d}~|S d}~ww )z@Scan the (ICMP) port structure (dict) and update the status key.Nz-wz-nz-tz-cz-WZping1r]   r:   wT)stdoutstderrZ	close_fdsr   r"   Fz${}: Error while pinging host {} ({}))r   r   r   strrh   openosdevnullr   
subprocessZ
check_callgetZCalledProcessErrorrb   r
   rM   r?   rQ   )	r   r0   r2   Ztimeout_optZ	count_optcmdZfnullcounterrc   r   r   r   rd   /  s>   	

$zThreadScanner._port_scan_icmpc              
   C   s  d}zt |d  t  t jt j}W n ty/ } ztd| j| W Y d}~nd}~ww | 	|d }t
 }zOz||t|d f}W n tye } ztd| j|| W Y d}~nd}~ww |dkrq| |d< nd	|d< W |  |S W |  |S W |  |S |  w )
z?Scan the (TCP) port structure (dict) and update the status key.Nr]   z-{}: Error while creating scanning socket ({})r:   r0   z%{}: Error while scanning port {} ({})r   r"   F)rf   ZsetdefaulttimeoutZAF_INETZSOCK_STREAMrb   r
   rM   r?   rQ   rh   r   Z
connect_exr+   rr   close)r   r0   r2   Z_socketrc   rg   rt   r   r   r   re   W  s8    "

zThreadScanner._port_scan_tcp)N)rH   rI   rJ   rK   r   rY   propertyr   setterr   rS   rX   rT   rh   rd   re   rL   r   r   r   r   r      s    


	(r   )!rK   ro   rq   rN   rf   rU   rA   Zglances.globalsr   r   r   Zglances.ports_listr   Zglances.web_listr   Zglances.timerr   r   Zglances.compatr	   Zglances.loggerr
   Zglances.plugins.glances_pluginr   r`   rW   ImportErrorrc   Zwarningr?   r   ZThreadr   r   r   r   r   <module>   s2    *