basic requests can now use lan, work on lan client
This commit is contained in:
		
							parent
							
								
									b2f630e4f9
								
							
						
					
					
						commit
						0da27a78c7
					
				
					 3 changed files with 107 additions and 13 deletions
				
			
		
							
								
								
									
										66
									
								
								src/httpapi/security/lan.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/httpapi/security/lan.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,66 @@ | |||
| """Onionr - Private P2P Communication. | ||||
| 
 | ||||
| Process incoming requests to the public api server for certain attacks | ||||
| """ | ||||
| from flask import Blueprint, request, abort, g | ||||
| from onionrservices import httpheaders | ||||
| from onionrutils import epoch | ||||
| from lan import getip | ||||
| """ | ||||
|     This program is free software: you can redistribute it and/or modify | ||||
|     it under the terms of the GNU General Public License as published by | ||||
|     the Free Software Foundation, either version 3 of the License, or | ||||
|     (at your option) any later version. | ||||
| 
 | ||||
|     This program is distributed in the hope that it will be useful, | ||||
|     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|     GNU General Public License for more details. | ||||
| 
 | ||||
|     You should have received a copy of the GNU General Public License | ||||
|     along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
| """ | ||||
| 
 | ||||
| 
 | ||||
| class LANAPISecurity: | ||||
|     def __init__(self, lan_client): | ||||
|         lan_api_security_bp = Blueprint('lanapisecurity', __name__) | ||||
|         self.lan_api_security_bp = lan_api_security_bp | ||||
| 
 | ||||
|         @lan_api_security_bp.before_app_request | ||||
|         def validate_request(): | ||||
|             """Validate request has the correct hostname""" | ||||
|             # If high security level, deny requests to public | ||||
|             # (HS should be disabled anyway for Tor, but might not be for I2P) | ||||
|             transports = getip.lan_ips | ||||
|             if lan_client.config.get('general.security_level', default=1) > 0: | ||||
|                 abort(403) | ||||
|             if request.host not in transports: | ||||
|                 # Abort conn if wrong HTTP hostname, to prevent DNS rebinding | ||||
|                 abort(403) | ||||
|             lan_client.hitCount += 1  # raise hit count for valid requests | ||||
|             try: | ||||
|                 if 'onionr' in request.headers['User-Agent'].lower(): | ||||
|                     g.is_onionr_client = True | ||||
|                 else: | ||||
|                     g.is_onionr_client = False | ||||
|             except KeyError: | ||||
|                 g.is_onionr_client = False | ||||
| 
 | ||||
|         @lan_api_security_bp.after_app_request | ||||
|         def send_headers(resp): | ||||
|             """Send api, access control headers""" | ||||
|             resp = httpheaders.set_default_onionr_http_headers(resp) | ||||
|             # Network API version | ||||
|             resp.headers['X-API'] = lan_client.API_VERSION | ||||
|             # Delete some HTTP headers for Onionr user agents | ||||
|             NON_NETWORK_HEADERS = ('Content-Security-Policy', 'X-Frame-Options', | ||||
|                                    'X-Content-Type-Options', 'Feature-Policy', | ||||
|                                    'Clear-Site-Data', 'Referrer-Policy') | ||||
|             try: | ||||
|                 if g.is_onionr_client: | ||||
|                     for header in NON_NETWORK_HEADERS: del resp.headers[header] | ||||
|             except AttributeError: | ||||
|                 abort(403) | ||||
|             lan_client.lastRequest = epoch.get_rounded_epoch(roundS=5) | ||||
|             return resp | ||||
|  | @ -4,7 +4,9 @@ LAN transport client thread | |||
| """ | ||||
| from typing import List | ||||
| 
 | ||||
| from onionrcrypto.cryptoutils.randomshuffle import random_shuffle | ||||
| from utils.bettersleep import better_sleep | ||||
| from onionrutils.basicrequests import do_post_request, do_get_request | ||||
| """ | ||||
|     This program is free software: you can redistribute it and/or modify | ||||
|     it under the terms of the GNU General Public License as published by | ||||
|  | @ -24,9 +26,20 @@ from utils.bettersleep import better_sleep | |||
| class Client: | ||||
|     def __init__(self): | ||||
|         self.peers = [] | ||||
|         return | ||||
|         self.lookup_time = {} | ||||
|         self.poll_delay = 10 | ||||
| 
 | ||||
|     def get_lookup_time(self, peer): | ||||
|         try: | ||||
|             return self.lookup_time[peer] | ||||
|         except KeyError: | ||||
|             return 0 | ||||
| 
 | ||||
|     def start(self): | ||||
|         while True: | ||||
|             #print(1, self.peers, type(self.peers)) | ||||
|             better_sleep(1) | ||||
|             self.peers = random_shuffle(self.peers) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|             better_sleep(self.pull_delay) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,8 +1,14 @@ | |||
| ''' | ||||
|     Onionr - Private P2P Communication | ||||
| '''Onionr - Private P2P Communication. | ||||
| 
 | ||||
|     Do HTTP GET or POST requests through a proxy | ||||
| ''' | ||||
| from ipaddress import IPv4Address | ||||
| from urllib.parse import urlparse | ||||
| 
 | ||||
| import requests, streamedrequests | ||||
| import logger, onionrexceptions | ||||
| from etc import onionrvalues | ||||
| from . import localcommand | ||||
| ''' | ||||
|     This program is free software: you can redistribute it and/or modify | ||||
|     it under the terms of the GNU General Public License as published by | ||||
|  | @ -17,20 +23,22 @@ | |||
|     You should have received a copy of the GNU General Public License | ||||
|     along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
| ''' | ||||
| import requests, streamedrequests | ||||
| import logger, onionrexceptions | ||||
| from etc import onionrvalues | ||||
| from . import localcommand | ||||
| 
 | ||||
| 
 | ||||
| def do_post_request(url, data={}, port=0, proxyType='tor', max_size=10000, content_type: str = ''): | ||||
|     ''' | ||||
|     Do a POST request through a local tor or i2p instance | ||||
|     ''' | ||||
|     '''Do a POST request through a local tor or i2p instance.''' | ||||
|     if proxyType == 'tor': | ||||
|         if port == 0: | ||||
|             port = localcommand.local_command('/gettorsocks') | ||||
|         proxies = {'http': 'socks4a://127.0.0.1:' + str(port), 'https': 'socks4a://127.0.0.1:' + str(port)} | ||||
|     elif proxyType == 'i2p': | ||||
|         proxies = {'http': 'http://127.0.0.1:4444'} | ||||
|     elif proxyType == 'lan': | ||||
|         address = urlparse(url).hostname | ||||
|         if IPv4Address(address).is_private and not IPv4Address(address).is_loopback: | ||||
|             proxies = {} | ||||
|         else: | ||||
|             return | ||||
|     else: | ||||
|         return | ||||
|     headers = {'User-Agent': 'PyOnionr', 'Connection':'close'} | ||||
|  | @ -48,6 +56,7 @@ def do_post_request(url, data={}, port=0, proxyType='tor', max_size=10000, conte | |||
|         retData = False | ||||
|     return retData | ||||
| 
 | ||||
| 
 | ||||
| def do_get_request(url, port=0, proxyType='tor', ignoreAPI=False, returnHeaders=False, max_size=5242880): | ||||
|     ''' | ||||
|     Do a get request through a local tor or i2p instance | ||||
|  | @ -56,10 +65,16 @@ def do_get_request(url, port=0, proxyType='tor', ignoreAPI=False, returnHeaders= | |||
|     retData = False | ||||
|     if proxyType == 'tor': | ||||
|         if port == 0: | ||||
|             raise onionrexceptions.MissingPort('Socks port required for Tor HTTP get request') | ||||
|             port = localcommand.local_command('/gettorsocks') | ||||
|         proxies = {'http': 'socks4a://127.0.0.1:' + str(port), 'https': 'socks4a://127.0.0.1:' + str(port)} | ||||
|     elif proxyType == 'i2p': | ||||
|         proxies = {'http': 'http://127.0.0.1:4444'} | ||||
|     elif proxyType == 'lan': | ||||
|         address = urlparse(url).hostname | ||||
|         if IPv4Address(address).is_private and not IPv4Address(address).is_loopback: | ||||
|             proxies = {} | ||||
|         else: | ||||
|             return | ||||
|     else: | ||||
|         return | ||||
|     headers = {'User-Agent': 'PyOnionr', 'Connection':'close'} | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue