basic requests can now use lan, work on lan client

master
Kevin Froman 2020-03-31 01:48:20 -05:00
parent b2f630e4f9
commit 0da27a78c7
3 changed files with 107 additions and 13 deletions

View 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

View File

@ -4,7 +4,9 @@ LAN transport client thread
""" """
from typing import List from typing import List
from onionrcrypto.cryptoutils.randomshuffle import random_shuffle
from utils.bettersleep import better_sleep 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 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 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: class Client:
def __init__(self): def __init__(self):
self.peers = [] 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): def start(self):
while True: while True:
#print(1, self.peers, type(self.peers)) self.peers = random_shuffle(self.peers)
better_sleep(1)
better_sleep(self.pull_delay)

View File

@ -1,8 +1,14 @@
''' '''Onionr - Private P2P Communication.
Onionr - Private P2P Communication
Do HTTP GET or POST requests through a proxy 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 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 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 You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. 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 = ''): 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 proxyType == 'tor':
if port == 0: if port == 0:
port = localcommand.local_command('/gettorsocks') port = localcommand.local_command('/gettorsocks')
proxies = {'http': 'socks4a://127.0.0.1:' + str(port), 'https': 'socks4a://127.0.0.1:' + str(port)} proxies = {'http': 'socks4a://127.0.0.1:' + str(port), 'https': 'socks4a://127.0.0.1:' + str(port)}
elif proxyType == 'i2p': elif proxyType == 'i2p':
proxies = {'http': 'http://127.0.0.1:4444'} 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: else:
return return
headers = {'User-Agent': 'PyOnionr', 'Connection':'close'} 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 retData = False
return retData return retData
def do_get_request(url, port=0, proxyType='tor', ignoreAPI=False, returnHeaders=False, max_size=5242880): 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 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 retData = False
if proxyType == 'tor': if proxyType == 'tor':
if port == 0: 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)} proxies = {'http': 'socks4a://127.0.0.1:' + str(port), 'https': 'socks4a://127.0.0.1:' + str(port)}
elif proxyType == 'i2p': elif proxyType == 'i2p':
proxies = {'http': 'http://127.0.0.1:4444'} 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: else:
return return
headers = {'User-Agent': 'PyOnionr', 'Connection':'close'} headers = {'User-Agent': 'PyOnionr', 'Connection':'close'}