| 
							
							# SPDX-License-Identifier: AGPL-3.0-or-later
 | 
						
						
						
						
							 | 
							
							"""A plugin to check if the ip address of the request is a Tor exit-node if the
 | 
						
						
						
						
							 | 
							
							user searches for ``tor-check``.  It fetches the tor exit node list from
 | 
						
						
						
						
							 | 
							
							https://check.torproject.org/exit-addresses and parses all the IPs into a list,
 | 
						
						
						
						
							 | 
							
							then checks if the user's IP address is in it.
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							Enable in ``settings.yml``:
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							.. code:: yaml
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							  enabled_plugins:
 | 
						
						
						
						
							 | 
							
							    ..
 | 
						
						
						
						
							 | 
							
							    - 'Tor check plugin'
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							"""
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							import re
 | 
						
						
						
						
							 | 
							
							from flask_babel import gettext
 | 
						
						
						
						
							 | 
							
							from httpx import HTTPError
 | 
						
						
						
						
							 | 
							
							from searx.network import get
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							default_on = False
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							name = gettext("Tor check plugin")
 | 
						
						
						
						
							 | 
							
							'''Translated name of the plugin'''
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							description = gettext(
 | 
						
						
						
						
							 | 
							
							    "This plugin checks if the address of the request is a Tor exit-node, and"
 | 
						
						
						
						
							 | 
							
							    " informs the user if it is; like check.torproject.org, but from SearXNG."
 | 
						
						
						
						
							 | 
							
							)
 | 
						
						
						
						
							 | 
							
							'''Translated description of the plugin.'''
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							preference_section = 'query'
 | 
						
						
						
						
							 | 
							
							'''The preference section where the plugin is shown.'''
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							query_keywords = ['tor-check']
 | 
						
						
						
						
							 | 
							
							'''Query keywords shown in the preferences.'''
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							query_examples = ''
 | 
						
						
						
						
							 | 
							
							'''Query examples shown in the preferences.'''
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							# Regex for exit node addresses in the list.
 | 
						
						
						
						
							 | 
							
							reg = re.compile(r"(?<=ExitAddress )\S+")
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							def post_search(request, search):
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							    if search.search_query.pageno > 1:
 | 
						
						
						
						
							 | 
							
							        return True
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							    if search.search_query.query.lower() == "tor-check":
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							        # Request the list of tor exit nodes.
 | 
						
						
						
						
							 | 
							
							        try:
 | 
						
						
						
						
							 | 
							
							            resp = get("https://check.torproject.org/exit-addresses")
 | 
						
						
						
						
							 | 
							
							            node_list = re.findall(reg, resp.text)
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							        except HTTPError:
 | 
						
						
						
						
							 | 
							
							            # No answer, return error
 | 
						
						
						
						
							 | 
							
							            search.result_container.answers["tor"] = {
 | 
						
						
						
						
							 | 
							
							                "answer": gettext(
 | 
						
						
						
						
							 | 
							
							                    "Could not download the list of Tor exit-nodes from: https://check.torproject.org/exit-addresses"
 | 
						
						
						
						
							 | 
							
							                )
 | 
						
						
						
						
							 | 
							
							            }
 | 
						
						
						
						
							 | 
							
							            return True
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							        x_forwarded_for = request.headers.getlist("X-Forwarded-For")
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							        if x_forwarded_for:
 | 
						
						
						
						
							 | 
							
							            ip_address = x_forwarded_for[0]
 | 
						
						
						
						
							 | 
							
							        else:
 | 
						
						
						
						
							 | 
							
							            ip_address = request.remote_addr
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							        if ip_address in node_list:
 | 
						
						
						
						
							 | 
							
							            search.result_container.answers["tor"] = {
 | 
						
						
						
						
							 | 
							
							                "answer": gettext(
 | 
						
						
						
						
							 | 
							
							                    "You are using Tor and it looks like you have this external IP address: {ip_address}".format(
 | 
						
						
						
						
							 | 
							
							                        ip_address=ip_address
 | 
						
						
						
						
							 | 
							
							                    )
 | 
						
						
						
						
							 | 
							
							                )
 | 
						
						
						
						
							 | 
							
							            }
 | 
						
						
						
						
							 | 
							
							        else:
 | 
						
						
						
						
							 | 
							
							            search.result_container.answers["tor"] = {
 | 
						
						
						
						
							 | 
							
							                "answer": gettext(
 | 
						
						
						
						
							 | 
							
							                    "You are not using Tor and you have this external IP address: {ip_address}".format(
 | 
						
						
						
						
							 | 
							
							                        ip_address=ip_address
 | 
						
						
						
						
							 | 
							
							                    )
 | 
						
						
						
						
							 | 
							
							                )
 | 
						
						
						
						
							 | 
							
							            }
 | 
						
						
						
						
							 | 
							
							
 | 
						
						
						
						
							 | 
							
							    return True
 |