ó
    ã fiãr  ã                   óì   • S r SSKrSSKrSSKrSSKrSSKrSSKJr  SSKJ	r	  SSK
Jr   \R                  R                  R                  5          \   " S S5      rg! \ a     Nf = f! \ a    \r N!f = f)	zm
shodan.client
~~~~~~~~~~~~~

This module implements the Shodan API.

:copyright: (c) 2014- by John Matherly
é    Né   )ÚAPIError)Úcreate_facet_string)ÚStreamc                   óª  • \ rS rSrSr " S S5      r " S S5      r " S S5      r " S	 S
5      r " S S5      r	 " S S5      r
 " S S5      r " S S5      rS4S jrS5S jrS4S jrS6S jrS rS rS rS7S jrS8S jrS rS rS9S jrS:S  jrS! rS" rS# rS$ rS;S% jrS8S& jrS<S' jr S=S( jr!S) r"S>S* jr#S+ r$S, r%S- r&S. r'S4S/ jr(S0 r)S1 r*S2 r+S3r,g)?ÚShodané)   ao  Wrapper around the Shodan REST and Streaming APIs

:param key: The Shodan API key that can be obtained from your account page (https://account.shodan.io)
:type key: str
:ivar exploits: An instance of `shodan.Shodan.Exploits` that provides access to the Exploits REST API.
:ivar stream: An instance of `shodan.Shodan.Stream` that provides access to the Streaming API.
c                   ó&   • \ rS rSrS rS rS rSrg)ÚShodan.Dataé2   c                 ó   • Xl         g ©N©Úparent©Úselfr   s     ÚR/home/gothic/public_html/Scylla/venv/lib/python3.13/site-packages/shodan/client.pyÚ__init__ÚShodan.Data.__init__4   ó   € Ø �Kó    c                 ó:   • U R                   R                  S0 5      $ )z‰Returns a list of datasets that the user has permission to download.

:returns: A list of objects where every object describes a dataset
z/shodan/data©r   Ú_request©r   s    r   Úlist_datasetsÚShodan.Data.list_datasets7   s   € ð
 —;‘;×'Ñ'¨¸Ó;Ð;r   c                 óX   • U R                   R                  SR                  U5      0 5      $ )zšReturns a list of files that belong to the given dataset.

:returns: A list of objects where each object contains a 'name', 'size', 'timestamp' and 'url'
z/shodan/data/{}©r   r   Úformat)r   Údatasets     r   Ú
list_filesÚShodan.Data.list_files>   s'   € ð
 —;‘;×'Ñ'Ð(9×(@Ñ(@ÀÓ(IÈ2ÓNÐNr   r   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r   r   r"   Ú__static_attributes__© r   r   ÚDatar   2   s   † ò	!ò	<õ	Or   r*   c                   ó$   • \ rS rSrS rSS jrSrg)Ú
Shodan.DnséE   c                 ó   • Xl         g r   r   r   s     r   r   ÚShodan.Dns.__init__G   r   r   Nc                 óŒ   • SU0nU(       a  X%S'   U(       a  X5S'   U R                   R                  SR                  U5      U5      $ )z3Grab the DNS information for a domain.
            ÚpageÚhistoryÚtypez/dns/domain/{}r   )r   Údomainr2   r3   r1   Úargss         r   Údomain_infoÚShodan.Dns.domain_infoJ   sI   € ð ˜ðˆDö Ø")�Y‘ÞØ#�V‘Ø—;‘;×'Ñ'Ð(8×(?Ñ(?ÀÓ(GÈÓNÐNr   r   )FNr   )r$   r%   r&   r'   r   r6   r(   r)   r   r   ÚDnsr,   E   s   † ò	!÷
	Or   r8   c                   óB   • \ rS rSrS rSS jrS rS rS rS r	S	 r
S
rg)ÚShodan.NotifieréV   c                 ó   • Xl         g r   r   r   s     r   r   ÚShodan.Notifier.__init__X   r   r   Nc                 óV   • XS'   U(       a  X2S'   U R                   R                  SUSS9$ )aC  Get the settings for the specified notifier that a user has configured.

:param provider: Provider name
:type provider: str
:param args: Provider arguments
:type args: dict
:param description: Human-friendly description of the notifier
:type description: str
:returns: dict -- fields are 'success' and 'id' of the notifier
ÚproviderÚdescriptionú	/notifierÚpost©Úmethodr   )r   r?   r5   r@   s       r   ÚcreateÚShodan.Notifier.create[   s3   € ð  (�ÑæØ&1�]Ñ#à—;‘;×'Ñ'¨°TÀ&Ð'ÐIÐIr   c                 óV   • U R                   R                  SR                  U5      USS9$ )záGet the settings for the specified notifier that a user has configured.

:param nid: Notifier ID
:type nid: str
:param args: Provider arguments
:type args: dict
:returns: dict -- fields are 'success' and 'id' of the notifier
ú/notifier/{}ÚputrC   r   )r   Únidr5   s      r   ÚeditÚShodan.Notifier.editm   s,   € ð —;‘;×'Ñ'¨×(=Ñ(=¸cÓ(BÀDÐQVÐ'ÐWÐWr   c                 óX   • U R                   R                  SR                  U5      0 5      $ )zªGet the settings for the specified notifier that a user has configured.

:param nid: Notifier ID
:type nid: str
:returns: dict -- object describing the notifier settings
rH   r   ©r   rJ   s     r   ÚgetÚShodan.Notifier.getx   s&   € ð —;‘;×'Ñ'¨×(=Ñ(=¸cÓ(BÀBÓGÐGr   c                 ó:   • U R                   R                  S0 5      $ )zwReturns a list of notifiers that the user has added.

:returns: A list of notifierse that are available on the account
rA   r   r   s    r   Úlist_notifiersÚShodan.Notifier.list_notifiers�   s   € ð
 —;‘;×'Ñ'¨°RÓ8Ð8r   c                 ó:   • U R                   R                  S0 5      $ )zzReturns a list of supported notification providers.

:returns: A list of providers where each object describes a provider
z/notifier/providerr   r   s    r   Úlist_providersÚShodan.Notifier.list_providersˆ   s   € ð
 —;‘;×'Ñ'Ð(<¸bÓAÐAr   c                 óV   • U R                   R                  SR                  U5      0 SS9$ )z‚Delete the provided notifier.

:param nid: Notifier ID
:type nid: str
:returns: dict -- 'success' set to True if action succeeded
rH   ÚdeleterC   r   rN   s     r   ÚremoveÚShodan.Notifier.remove�   s+   € ð —;‘;×'Ñ'¨×(=Ñ(=¸cÓ(BÀBÈxÐ'ÐXÐXr   r   r   )r$   r%   r&   r'   r   rE   rK   rO   rR   rU   rY   r(   r)   r   r   ÚNotifierr:   V   s*   † ò	!ô	Jò$		Xò	Hò	9ò	Bõ	Yr   r[   c                   ó    • \ rS rSrS rS rSrg)ÚShodan.Toolsé˜   c                 ó   • Xl         g r   r   r   s     r   r   ÚShodan.Tools.__init__š   r   r   c                 ó:   • U R                   R                  S0 5      $ )zYGet your current IP address as seen from the Internet.

:returns: str -- your IP address
z/tools/myipr   r   s    r   ÚmyipÚShodan.Tools.myip�   s   € ð
 —;‘;×'Ñ'¨°rÓ:Ð:r   r   N)r$   r%   r&   r'   r   rb   r(   r)   r   r   ÚToolsr]   ˜   s   † ò	!õ	;r   rd   c                   ó.   • \ rS rSrS rSS jrSS jrSrg)	ÚShodan.Exploitsé¤   c                 ó   • Xl         g r   r   r   s     r   r   ÚShodan.Exploits.__init__¦   r   r   Nc                 ól   • UUS.nU(       a  [        U5      US'   U R                  R                  SUSS9$ )a�  Search the entire Shodan Exploits archive using the same query syntax
as the website.

:param query: The exploit search query; same syntax as website.
:type query: str
:param facets: A list of strings or tuples to get summary information on.
:type facets: str
:param page: The page number to access.
:type page: int
:returns: dict -- a dictionary containing the results of the search.
)Úqueryr1   Úfacetsz/api/searchÚexploits©Úservice©r   r   r   )r   rk   r1   rl   Ú
query_argss        r   ÚsearchÚShodan.Exploits.search©   sA   € ð ØñˆJö Ü':¸6Ó'B�
˜8Ñ$à—;‘;×'Ñ'¨°zÈ:Ð'ÐVÐVr   c                 ój   • SU0nU(       a  [        U5      US'   U R                  R                  SUSS9$ )a_  Search the entire Shodan Exploits archive but only return the total # of results,
not the actual exploits.

:param query: The exploit search query; same syntax as website.
:type query: str
:param facets: A list of strings or tuples to get summary information on.
:type facets: str
:returns: dict -- a dictionary containing the results of the search.

rk   rl   z
/api/countrm   rn   rp   ©r   rk   rl   rq   s       r   ÚcountÚShodan.Exploits.count¾   s@   € ð ˜ðˆJö Ü':¸6Ó'B�
˜8Ñ$à—;‘;×'Ñ'¨°jÈ*Ð'ÐUÐUr   r   )r   Nr   )r$   r%   r&   r'   r   rr   rv   r(   r)   r   r   ÚExploitsrf   ¤   s   † ò	!ô	W÷*	Vr   rx   c                   ó    • \ rS rSrS rS rSrg)ÚShodan.LabséÑ   c                 ó   • Xl         g r   r   r   s     r   r   ÚShodan.Labs.__init__Ó   r   r   c                 óX   • U R                   R                  SR                  U5      0 5      $ )z¢Calculate the probability of an IP being an ICS honeypot.

:param ip: IP address of the device
:type ip: str

:returns: int -- honeyscore ranging from 0.0 to 1.0
z/labs/honeyscore/{}r   )r   Úips     r   Ú
honeyscoreÚShodan.Labs.honeyscoreÖ   s'   € ð —;‘;×'Ñ'Ð(=×(DÑ(DÀRÓ(HÈ"ÓMÐMr   r   N)r$   r%   r&   r'   r   r€   r(   r)   r   r   ÚLabsrz   Ñ   s   † ò	!õ	Nr   r‚   c                   ó0   • \ rS rSrS rSS jrS rS rSrg)	ÚShodan.Organizationéà   c                 ó   • Xl         g r   r   r   s     r   r   ÚShodan.Organization.__init__â   r   r   c                 ó`   • U R                   R                  SR                  U5      SU0SS9S   $ )zôAdd the user to the organization.

:param user: username or email address
:type user: str
:param notify: whether or not to send the user an email notification
:type notify: bool

:returns: True if it succeeded and raises an Exception otherwise
ú/org/member/{}ÚnotifyÚPUTrC   Úsuccessr   )r   ÚuserrŠ   s      r   Ú
add_memberÚShodan.Organization.add_memberå   sD   € ð —;‘;×'Ñ'Ð(8×(?Ñ(?ÀÓ(EØ˜&ðHàð (ð à&ñ(ð (r   c                 ó:   • U R                   R                  S0 5      $ )z`Returns general information about the organization the current user is a member of.
            z/orgr   r   s    r   ÚinfoÚShodan.Organization.infoó   s   € ð —;‘;×'Ñ'¨°Ó3Ð3r   c                 ó\   • U R                   R                  SR                  U5      0 SS9S   $ )z¡Remove the user from the organization.

:param user: username or email address
:type user: str

:returns: True if it succeeded and raises an Exception otherwise
r‰   ÚDELETErC   rŒ   r   )r   r�   s     r   Úremove_memberÚ!Shodan.Organization.remove_memberø   s3   € ð —;‘;×'Ñ'Ð(8×(?Ñ(?ÀÓ(EÀrÐRZÐ'Ð[Ð\eÑfÐfr   r   N)T)	r$   r%   r&   r'   r   rŽ   r‘   r•   r(   r)   r   r   ÚOrganizationr„   à   s   † ò	!ô	(ò	4õ
	gr   r—   c                   ó,   • \ rS rSrS rS rS rS rSrg)ÚShodan.Trendsi  c                 ó   • Xl         g r   r   r   s     r   r   ÚShodan.Trends.__init__  r   r   c                 óT   • U[        U5      S.nU R                  R                  SUSS9$ )aK  Search the Shodan historical database.

:param query: Search query; identical syntax to the website
:type query: str
:param facets: (optional) A list of properties to get summary information on
:type facets: str

:returns: A dictionary with 3 main items: matches, facets and total. Visit the website for more detailed information.
)rk   rl   z/api/v1/searchÚtrendsrn   rp   )r   rk   rl   r5   s       r   rr   ÚShodan.Trends.search  s5   € ð Ü-¨fÓ5ñˆDð
 —;‘;×'Ñ'Ð(8¸$ÈÐ'ÐQÐQr   c                 ó8   • U R                   R                  S0 SS9$ )z£This method returns a list of facets that can be used to get a breakdown of the top values for a property.

:returns: A list of strings where each is a facet name
z/api/v1/search/facetsr�   rn   r   r   s    r   Úsearch_facetsÚShodan.Trends.search_facets  s!   € ð
 —;‘;×'Ñ'Ð(?ÀÈXÐ'ÐVÐVr   c                 ó8   • U R                   R                  S0 SS9$ )zŒThis method returns a list of search filters that can be used in the search query.

:returns: A list of strings where each is a filter name
z/api/v1/search/filtersr�   rn   r   r   s    r   Úsearch_filtersÚShodan.Trends.search_filters  s!   € ð
 —;‘;×'Ñ'Ð(@À"ÈhÐ'ÐWÐWr   r   N)	r$   r%   r&   r'   r   rr   r    r£   r(   r)   r   r   ÚTrendsr™     s   † ò	!ò	Rò"	Wõ	Xr   r¥   Nc                 ó  • Xl         SU l        SU l        SU l        U R	                  U 5      U l        U R                  U 5      U l        U R                  U 5      U l	        U R                  U 5      U l        U R                  U 5      U l        U R                  U 5      U l        U R!                  U 5      U l        U R%                  U 5      U l        [)        XS9U l        [,        R.                  " 5       U l        SU l        SU l        U(       a6  U R0                  R6                  R9                  U5        SU R0                  l        [<        R>                  RA                  S5      (       a%  [<        R>                  RA                  S5      U l        gg)	z·Initializes the API object.

:param key: The Shodan API key.
:type key: str
:param proxies: A proxies array for the requests library, e.g. {'https': 'your proxy'}
:type proxies: dict
zhttps://api.shodan.iozhttps://exploits.shodan.iozhttps://trends.shodan.io)Úproxiesr   NFÚSHODAN_API_URL)!Úapi_keyÚbase_urlÚbase_exploits_urlÚbase_trends_urlr*   Údatar8   Údnsrx   rm   r¥   r�   r‚   Úlabsr[   Únotifierr—   Úorgrd   Útoolsr   ÚstreamÚrequestsÚSessionÚ_sessionÚapi_rate_limitÚ_api_query_timer§   ÚupdateÚ	trust_envÚosÚenvironrO   )r   Úkeyr§   s      r   r   ÚShodan.__init__&  s   € ð ŒØ/ˆŒØ!=ˆÔØ9ˆÔØ—I‘I˜d“OˆŒ	Ø—8‘8˜D“>ˆŒØŸ™ dÓ+ˆŒØ—k‘k $Ó'ˆŒØ—I‘I˜d“OˆŒ	ØŸ™ dÓ+ˆŒØ×$Ñ$ TÓ*ˆŒØ—Z‘Z Ó%ˆŒ
Ü˜SÑ2ˆŒÜ ×(Ò(Ó*ˆŒØˆÔØ#ˆÔæØ�M‰M×!Ñ!×(Ñ(¨Ô1Ø&+ˆD�M‰MÔ#ä�:‰:�>‰>Ð*×+Ñ+ÜŸJ™JŸN™NÐ+;Ó<ˆD�Mð ,r   c                 óô  • U R                   US'   U R                  U R                  U R                  S.R	                  US5      nU R
                  b›  U R                  S:”  a‹  SU R                  -  U R
                  -   [        R                  " 5       :¼  aX  [        R                  " SU R                  -  5        SU R                  -  U R
                  -   [        R                  " 5       :¼  a  MX   UR                  5       nUS:X  a[  U(       a5  U R                  R                  Xa-   U[        R                  " U5      S	S
0S9nO�U R                  R                  Xa-   U5      nObUS:X  a  U R                  R                  Xa-   US9nO?US:X  a  U R                  R                  Xa-   US9nOU R                  R	                  Xa-   US9n[        R                  " 5       U l        UR$                  S:X  a   UR                  5       S   n[#        U5      eUR$                  S:X  a  [#        S5      eUR$                  S:X  a  [#        S5      e UR                  5       n[/        U5      [0        :X  a  SU;   a  [#        US   5      eU$ ! [          a    [#        S5      ef = f! [          aB  n	UR&                  R)                  S5      (       a  Sn Sn	A	NÅSR+                  U	5      n Sn	A	NÛSn	A	ff = f! [,         a    [#        S5      ef = f)zúGeneral-purpose function to create web requests to SHODAN.

Arguments:
    function  -- name of the function you want to execute
    params    -- dictionary of parameters for the function

Returns
    A dictionary containing the function's results.

r½   )Úshodanrm   r�   rÀ   Nr   g      ð?gš™™™™™¹?rB   zcontent-typezapplication/json)Úparamsr­   ÚheadersrI   ©rÁ   rX   zUnable to connect to Shodani‘  ÚerrorÚ<zInvalid API keyz{}i“  zAccess denied (403 Forbidden)iö  zBad Gateway (502)zUnable to parse JSON response)r©   rª   r«   r¬   rO   r¸   r·   ÚtimeÚsleepÚlowerr¶   rB   ÚjsonÚdumpsrI   rX   Ú	Exceptionr   Ústatus_codeÚtextÚ
startswithr    Ú
ValueErrorr3   Údict)
r   ÚfunctionrÁ   ro   rD   Ú	json_datarª   r­   rÄ   Úes
             r   r   ÚShodan._requestF  s±  € ð Ÿ™ˆˆu‰ð —m‘mØ×.Ñ.Ø×*Ñ*ñ
÷ ‰#ˆg�xÓ
 ð	 	ð ×ÑÑ+°×0CÑ0CÀaÓ0GØ˜×,Ñ,Ñ,°×0DÑ0DÑDÌÏ	Ê	ËÓSÜ—
’
˜3 ×!4Ñ!4Ñ4Ô5ð ˜×,Ñ,Ñ,°×0DÑ0DÑDÌÏ	Ê	ËÕSð	:Ø—\‘\“^ˆFØ˜ÓÞØŸ=™=×-Ñ-¨hÑ.AÈ&Ü15·²¸IÓ1FØ5CÐEWÐ4Xð .ð ‘Dð
  Ÿ=™=×-Ñ-¨hÑ.AÀ6ÓJ‘DØ˜5“Ø—}‘}×(Ñ(¨Ñ)<ÀVÐ(ÐL‘Ø˜8Ó#Ø—}‘}×+Ñ+¨HÑ,?ÈÐ+ÐO‘à—}‘}×(Ñ(¨Ñ)<ÀVÐ(ÐL�Ü#'§9¢9£;ˆDÔ ð
 ×Ñ˜sÓ"ð
,àŸ	™	› GÑ,�ô ˜5“/Ð!Ø×Ñ Ó$ÜÐ:Ó;Ð;Ø×Ñ Ó$ÜÐ.Ó/Ð/ð	<Ø—9‘9“;ˆDô
 �‹:œÓ '¨T£/Ü˜4 ™=Ó)Ð)ð ˆøôE ó 	:ÜÐ8Ó9Ð9ð	:ûô ó ,ð —9‘9×'Ñ'¨×,Ñ,Ø-•Eð "ŸL™L¨›O•Eûð,ûô$ ó 	<ÜÐ:Ó;Ð;ð	<ús7   Ã-C-I9 Ç+J É K! É9JÊ
KÊ"KËKËKË!K7c                 óX   • SU0nU(       a  [        U5      US'   U R                  SU5      $ )aÆ  Returns the total number of search results for the query.

:param query: Search query; identical syntax to the website
:type query: str
:param facets: (optional) A list of properties to get summary information on
:type facets: str

:returns: A dictionary with 1 main property: total. If facets have been provided then another property called "facets" will be available at the top-level of the dictionary. Visit the website for more detailed information.
rk   rl   z/shodan/host/count)r   r   ru   s       r   rv   ÚShodan.count–  s6   € ð �Uð
ˆ
ö Ü#6°vÓ#>ˆJ�xÑ Ø�}‰}Ð1°:Ó>Ð>r   c                 óÂ   • [        U[        5      (       a  U/n0 nU(       a  X$S'   U(       a  X4S'   U R                  SR                  SR	                  U5      5      U5      $ )as  Get all available information on an IP.

:param ip: IP of the computer
:type ip: str
:param history: (optional) True if you want to grab the historical (non-current) banners for the host, False otherwise.
:type history: bool
:param minify: (optional) True to only return the list of ports and the general host information, no banners, False otherwise.
:type minify: bool
r2   Úminifyz/shodan/host/{}Ú,)Ú
isinstanceÚ
basestringr   r    Újoin)r   Úipsr2   rØ   rÁ   s        r   ÚhostÚShodan.host§  sX   € ô �cœ:×&Ñ&Ø�%ˆCàˆÞØ '�9ÑÞØ%�8ÑØ�}‰}Ð.×5Ñ5°c·h±h¸s³mÓDÀfÓMÐMr   c                 ó&   • U R                  S0 5      $ )zŽReturns information about the current API key, such as a list of add-ons
and other features that are enabled for the current user's API plan.
z	/api-info©r   r   s    r   r‘   ÚShodan.info»  s   € ð �}‰}˜[¨"Ó-Ð-r   c                 ó&   • U R                  S0 5      $ )zhGet a list of ports that Shodan crawls

:returns: An array containing the ports that Shodan crawls for.
z/shodan/portsrá   r   s    r   ÚportsÚShodan.portsÁ  s   € ð
 �}‰}˜_¨bÓ1Ð1r   c                 ó&   • U R                  S0 5      $ )z�Get a list of protocols that the Shodan on-demand scanning API supports.

:returns: A dictionary containing the protocol name and description.
z/shodan/protocolsrá   r   s    r   Ú	protocolsÚShodan.protocolsÈ  s   € ð
 �}‰}Ð0°"Ó5Ð5r   c                 óØ   • [        U[        5      (       a  U/n[        U[        5      (       a  [        R                  " U5      nOSR                  U5      nUUS.nU R                  SUSS9$ )a†  Scan a network using Shodan

:param ips: A list of IPs or netblocks in CIDR notation or an object structured like:
            {
                "9.9.9.9": [
                    (443, "https"),
                    (8080, "http")
                ],
                "1.1.1.0/24": [
                    (503, "modbus")
                ]
            }
:type ips: str or dict
:param force: Whether or not to force Shodan to re-scan the provided IPs. Only available to enterprise users.
:type force: bool

:returns: A dictionary with a unique ID to check on the scan progress, the number of IPs that will be crawled and how many scan credits are left.
rÙ   )rÝ   Úforcez/shodan/scanrB   rC   )rÚ   rÛ   rÐ   rÉ   rÊ   rÜ   r   )r   rÝ   rê   ÚnetworksrÁ   s        r   ÚscanÚShodan.scanÏ  se   € ô& �cœ:×&Ñ&Ø�%ˆCä�cœ4× Ñ Ü—z’z #“‰Hà—x‘x “}ˆHð Øñ
ˆð
 �}‰}˜^¨V¸Fˆ}ÐCÐCr   c                 ó*   • U R                  SSU05      $ )zqGet a list of scans submitted

:param page: Page through the list of scans 100 results at a time
:type page: int
z/shodan/scansr1   rá   )r   r1   s     r   ÚscansÚShodan.scansñ  s!   € ð �}‰}˜_Ø�Dð/
ó ð 	r   c                 ó.   • UUS.nU R                  SUSS9$ )a  Scan a network using Shodan

:param port: The port that should get scanned.
:type port: int
:param port: The name of the protocol as returned by the protocols() method.
:type port: str

:returns: A dictionary with a unique ID to check on the scan progress.
)ÚportÚprotocolz/shodan/scan/internetrB   rC   rá   )r   rò   ró   rÁ   s       r   Úscan_internetÚShodan.scan_internetû  s)   € ð Ø ñ
ˆð
 �}‰}Ð4°fÀVˆ}ÐLÐLr   c                 óD   • U R                  SR                  U5      0 5      $ )zòGet the status information about a previously submitted scan.

:param id: The unique ID for the scan that was submitted
:type id: str

:returns: A dictionary with general information about the scan, including its status in getting processed.
z/shodan/scan/{}©r   r    )r   Úscan_ids     r   Úscan_statusÚShodan.scan_status  s!   € ð �}‰}Ð.×5Ñ5°gÓ>ÀÓCÐCr   c                 óð   • UUS.nU(       a  X8S'   U(       a  XHS'   OX(S'   U(       a  [        U5      US'   U(       a)  [        U[        5      (       a  SR                  U5      US'   U R	                  SU5      $ )	a�  Search the SHODAN database.

:param query: Search query; identical syntax to the website
:type query: str
:param page: (optional) Page number of the search results
:type page: int
:param limit: (optional) Number of results to return
:type limit: int
:param offset: (optional) Search offset to begin getting results from
:type offset: int
:param facets: (optional) A list of properties to get summary information on
:type facets: str
:param minify: (optional) Whether to minify the banner and only return the important data
:type minify: bool
:param fields: (optional) List of properties that should get returned. This option is mutually exclusive with the "minify" parameter
:type fields: str

:returns: A dictionary with 2 main items: matches and total. If facets have been provided then another property called "facets" will be available at the top-level of the dictionary. Visit the website for more detailed information.
)rk   rØ   ÚlimitÚoffsetr1   rl   rÙ   Úfieldsz/shodan/host/search)r   rÚ   ÚlistrÜ   r   )	r   rk   r1   rü   rý   rl   rØ   rþ   r5   s	            r   rr   ÚShodan.search  ss   € ð* Øñ
ˆö Ø!�‰MÞØ!'�X‘øà�‰LæÜ0°Ó8ˆD�‰Næ”j ¬×.Ñ.Ø ŸX™X fÓ-ˆD�‰Nà�}‰}Ð2°DÓ9Ð9r   c              #   ó  #   • SnSnSnU R                  XXTS9nUS   (       a%  [        [        R                  " US   S-  5      5      nUS    H  n	 U	v •  M
     US-  nXV::  a1   U R                  XXTS9nUS    H  n	 U	v •  M
     US-  nSnXV::  a  M0  gg! [         a       gf = f! [         a       gf = f! [
         a=    Xs:¼  a  [        SR                  U5      5      eUS-  n[        R                  " U5         Nqf = f7f)	a²  Search the SHODAN database.

This method returns an iterator that can directly be in a loop. Use it when you want to loop over
all of the results of a search query. But this method doesn't return a "matches" array or the "total"
information. And it also can't be used with facets, it's only use is to iterate over results more
easily.

:param query: Search query; identical syntax to the website
:type query: str
:param minify: (optional) Whether to minify the banner and only return the important data
:type minify: bool
:param retries: (optional) How often to retry the search in case it times out
:type retries: int

:returns: A search cursor that can be used as an iterator/ generator.
r   r   )rØ   r1   rþ   Útotaléd   ÚmatchesNzRetry limit reached ({:d}))
rr   ÚintÚmathÚceilÚGeneratorExitrË   r   r    rÆ   rÇ   )
r   rk   rØ   Úretriesrþ   r1   Útotal_pagesÚtriesÚresultsÚbanners
             r   Úsearch_cursorÚShodan.search_cursor=  s+  é € ð" ˆØˆØˆð —+‘+˜e¸�+ÐMˆØ�7×ÜœdŸiši¨°Ñ(8¸3Ñ(>Ó?Ó@ˆKà˜iÔ(ˆFðØ”ñ )ð
 	�‰	ˆð Ó!ð"ØŸ+™+ eÀ˜+ÐU�Ø% iÔ0�FðØ$œñ 1ð
 ˜‘	�Ø�ð ×!øô !ó Úðûô )ó Úðûô ó "àÓ#Ü"Ð#?×#FÑ#FÀwÓ#OÓPÐPà˜‘
�Ü—
’
˜5Ö!ð"üs   ‚ADÁBÁDÁ$B7 Á=B&ÂB7 ÂDÂDÂ
B#ÂDÂ"B#Â#DÂ&
B4Â0B7 Â2DÂ3B4Â4B7 Â7AC>Ã;DÃ=C>Ã>Dc                 ó&   • U R                  S0 5      $ )zœReturns a list of search facets that can be used to get aggregate information about a search query.

:returns: A list of strings where each is a facet name
z/shodan/host/search/facetsrá   r   s    r   r    ÚShodan.search_facetsq  s   € ð
 �}‰}Ð9¸2Ó>Ð>r   c                 ó&   • U R                  S0 5      $ )znReturns a list of search filters that are available.

:returns: A list of strings where each is a filter name
z/shodan/host/search/filtersrá   r   s    r   r£   ÚShodan.search_filtersx  s   € ð
 �}‰}Ð:¸BÓ?Ð?r   c                 ó.   • SU0nU R                  SU5      $ )zìReturns information about the search query itself (filters used etc.)

:param query: Search query; identical syntax to the website
:type query: str

:returns: A dictionary with 4 main properties: filters, errors, attributes and string.
rk   z/shodan/host/search/tokensrá   )r   rk   rq   s      r   Úsearch_tokensÚShodan.search_tokens  s$   € ð �Uð
ˆ
ð �}‰}Ð9¸:ÓFÐFr   c                 ó&   • U R                  S0 5      $ )z¾Get a list of services that Shodan crawls

:returns: A dictionary containing the ports/ services that Shodan crawls for. The key is the port number and the value is the name of the service.
z/shodan/servicesrá   r   s    r   ÚservicesÚShodan.servicesŒ  s   € ð
 �}‰}Ð/°Ó4Ð4r   c                 ó2   • UUUS.nU R                  SU5      $ )a¶  List the search queries that have been shared by other users.

:param page: Page number to iterate over results; each page contains 10 items
:type page: int
:param sort: Sort the list based on a property. Possible values are: votes, timestamp
:type sort: str
:param order: Whether to sort the list in ascending or descending order. Possible values are: asc, desc
:type order: str

:returns: A list of saved search queries (dictionaries).
)r1   ÚsortÚorderz/shodan/queryrá   )r   r1   r  r  r5   s        r   ÚqueriesÚShodan.queries“  s'   € ð ØØñ
ˆð
 �}‰}˜_¨dÓ3Ð3r   c                 ó0   • UUS.nU R                  SU5      $ )a"  Search the directory of saved search queries in Shodan.

:param query: The search string to look for in the search query
:type query: str
:param page: Page number to iterate over results; each page contains 10 items
:type page: int

:returns: A list of saved search queries (dictionaries).
)r1   rk   z/shodan/query/searchrá   )r   rk   r1   r5   s       r   Úqueries_searchÚShodan.queries_search¦  s%   € ð Øñ
ˆð �}‰}Ð3°TÓ:Ð:r   c                 ó.   • SU0nU R                  SU5      $ )zŽSearch the directory of saved search queries in Shodan.

:param size: The number of tags to return
:type size: int

:returns: A list of tags.
Úsizez/shodan/query/tagsrá   )r   r#  r5   s      r   Úqueries_tagsÚShodan.queries_tags¶  s$   € ð �Dð
ˆð �}‰}Ð1°4Ó8Ð8r   c                 ó:   • USU0US.nU R                  S0 USS9nU$ )zâCreate a network alert/ private firehose for the specified IP range(s)

:param name: Name of the alert
:type name: str
:param ip: Network range(s) to monitor
:type ip: str OR list of str

:returns: A dict describing the alert
r   )ÚnameÚfiltersÚexpiresz/shodan/alertrB   ©rÁ   rÒ   rD   rá   )r   r'  r   r)  r­   Úresponses         r   Úcreate_alertÚShodan.create_alertÃ  s;   € ð à�bðð ñ
ˆð —=‘= ¸ÀtÐTZ�=Ð[ˆàˆr   c                 óT   • SSU00nU R                  SR                  U5      0 USS9nU$ )zÅEdit the IPs that should be monitored by the alert.

:param aid: Alert ID
:type name: str
:param ip: Network range(s) to monitor
:type ip: str OR list of str

:returns: A dict describing the alert
r(  r   ú/shodan/alert/{}rB   r*  r÷   )r   Úaidr   r­   r+  s        r   Ú
edit_alertÚShodan.edit_alertÙ  sC   € ð Ø�bðð
ˆð —=‘=Ð!3×!:Ñ!:¸3Ó!?ÈÐVZÐci�=Ðjˆàˆr   c                 ó`   • U(       a  SR                  U5      nOSnU R                  USU0S9nU$ )z4List all of the active alerts that the user created.z/shodan/alert/{}/infoz/shodan/alert/infoÚinclude_expiredrÃ   ©r    r   )r   r0  r4  Úfuncr+  s        r   ÚalertsÚShodan.alertsí  s=   € æØ*×1Ñ1°#Ó6‰Dà'ˆDà—=‘= Ø˜ð/
�=ð ˆð ˆr   c                 óJ   • SR                  U5      nU R                  U0 SS9nU$ )z#Delete the alert with the given ID.r/  rX   )rÁ   rD   r5  )r   r0  r6  r+  s       r   Údelete_alertÚShodan.delete_alertú  s+   € à!×(Ñ(¨Ó-ˆà—=‘= ¨b¸�=ÐBˆàˆr   c                 ó&   • U R                  S0 5      $ )zbReturn a list of available triggers that can be enabled for alerts.

:returns: A list of triggers
z/shodan/alert/triggersrá   r   s    r   Úalert_triggersÚShodan.alert_triggers  s   € ð
 �}‰}Ð5°rÓ:Ð:r   c                 óB   • U R                  SR                  X5      0 SS9$ )z&Enable the given trigger on the alert.ú/shodan/alert/{}/trigger/{}rI   rC   r÷   ©r   r0  Útriggers      r   Úenable_alert_triggerÚShodan.enable_alert_trigger	  s%   € à�}‰}Ð:×AÑAÀ#ÓOÐQSÐ\aˆ}ÐbÐbr   c                 óB   • U R                  SR                  X5      0 SS9$ )z'Disable the given trigger on the alert.r@  rX   rC   r÷   rA  s      r   Údisable_alert_triggerÚShodan.disable_alert_trigger  s%   € à�}‰}Ð:×AÑAÀ#ÓOÐQSÐ\dˆ}ÐeÐer   c                 óê   • US;   aM  U(       aF  [        U[        5      (       a1  U R                  SR                  XX4SR	                  U5      5      0 SS9$ U R                  SR                  XX45      0 SS9$ )z:Ignore trigger notifications for the provided IP and port.)Ú
vulnerableÚvulnerable_unverifiedz+/shodan/alert/{}/trigger/{}/ignore/{}:{}/{}rÙ   rI   rC   ú(/shodan/alert/{}/trigger/{}/ignore/{}:{})rÚ   rÿ   r   r    rÜ   )r   r0  rB  r   rò   Úvulnss         r   Ú!ignore_alert_trigger_notificationÚ(Shodan.ignore_alert_trigger_notification  s‡   € ð
 Ð=Ó=Æ%ÌJÐW\Ô^b×LcÑLcØ—=‘=Ð!N×!UÑ!UÐVYÐdfÐnq×nvÑnvÐw|Ón}Ó!~ð  ACð  LQ�=ð  Rð  Rà�}‰}ÐG×NÑNÈsÐ]_ÓfÐhjÐsxˆ}ÐyÐyr   c                 óD   • U R                  SR                  XX45      0 SS9$ )z<Re-enable trigger notifications for the provided IP and portrK  rX   rC   r÷   )r   r0  rB  r   rò   s        r   Ú#unignore_alert_trigger_notificationÚ*Shodan.unignore_alert_trigger_notification  s(   € à�}‰}ÐG×NÑNÈsÐ]_ÓfÐhjÐs{ˆ}Ð|Ð|r   c                 óB   • U R                  SR                  X5      0 SS9$ )zAEnable the given notifier for an alert that has triggers enabled.ú/shodan/alert/{}/notifier/{}rI   rC   r÷   ©r   r0  rJ   s      r   Úadd_alert_notifierÚShodan.add_alert_notifier  s$   € à�}‰}Ð;×BÑBÀ3ÓLÈbÐY^ˆ}Ð_Ð_r   c                 óB   • U R                  SR                  X5      0 SS9$ )zARemove the given notifier for an alert that has triggers enabled.rS  rX   rC   r÷   rT  s      r   Úremove_alert_notifierÚShodan.remove_alert_notifier#  s$   € à�}‰}Ð;×BÑBÀ3ÓLÈbÐYaˆ}ÐbÐbr   )r¸   r¶   r©   r·   r«   r¬   rª   r­   r®   rm   r¯   r°   r±   r³   r²   r�   r   )rÀ   rO   N)FF)F)r   )r   NNNTN)Té   N)r   Ú	timestampÚdesc)é
   )r   )NT)-r$   r%   r&   r'   Ú__doc__r*   r8   r[   rd   rx   r‚   r—   r¥   r   r   rv   rÞ   r‘   rä   rç   rì   rï   rô   rù   rr   r  r    r£   r  r  r  r   r$  r,  r1  r7  r:  r=  rC  rF  rM  rP  rU  rX  r(   r)   r   r   r   r   )   s  † ñ÷Oñ O÷&Oñ O÷"@Yñ @Y÷D
;ñ 
;÷+Vñ +V÷ZNñ N÷ gñ  g÷D"Xñ "XôH=ô@Nô`?ô"Nò(.ò2ò6ô DôDòMò"Dô%:ôN2"òh?ò@òGò5ô4ô&;ô 9ôò,ô(òò;òcòfôzò}ò`õcr   r   )r^  r  r»   rÆ   r´   rÉ   Ú	exceptionr   Úhelpersr   r³   r   ÚpackagesÚurllib3Údisable_warningsrË   rÛ   Ú	NameErrorÚstrr   r)   r   r   Ú<module>rf     s€   ðñó Û 	Û ã Û å Ý (Ý ð	Ø×Ñ×Ñ×.Ñ.Ô0ð
Ù÷
|cò |cøð ó 	Ùð	ûð ó Ø‚Jðús#   ª$A ÁA( ÁA%Á$A%Á(A3Á2A3