more work on direct connections

This commit is contained in:
Kevin Froman 2019-03-25 23:25:46 -05:00
parent 7be654401b
commit cd6eb59023
4 changed files with 14 additions and 16 deletions

View File

@ -27,6 +27,7 @@ from onionrblockapi import Block
import onionrutils, onionrexceptions, onionrcrypto, blockimporter, onionrevents as events, logger, config import onionrutils, onionrexceptions, onionrcrypto, blockimporter, onionrevents as events, logger, config
import httpapi import httpapi
from httpapi import friendsapi, simplecache from httpapi import friendsapi, simplecache
from onionrservices import httpheaders
import onionr import onionr
class FDSafeHandler(WSGIHandler): class FDSafeHandler(WSGIHandler):
@ -92,17 +93,9 @@ class PublicAPI:
@app.after_request @app.after_request
def sendHeaders(resp): def sendHeaders(resp):
'''Send api, access control headers''' '''Send api, access control headers'''
resp.headers['Date'] = 'Thu, 1 Jan 1970 00:00:00 GMT' # Clock info is probably useful to attackers. Set to unix epoch, since we can't fully remove the header. resp = httpheaders.set_default_onionr_http_headers(resp)
# CSP to prevent XSS. Mainly for client side attacks (if hostname protection could somehow be bypassed)
resp.headers["Content-Security-Policy"] = "default-src 'none'; script-src 'none'; object-src 'none'; style-src data: 'unsafe-inline'; img-src data:; media-src 'none'; frame-src 'none'; font-src 'none'; connect-src 'none'"
# Prevent click jacking
resp.headers['X-Frame-Options'] = 'deny'
# No sniff is possibly not needed
resp.headers['X-Content-Type-Options'] = "nosniff"
# Network API version # Network API version
resp.headers['X-API'] = onionr.API_VERSION resp.headers['X-API'] = onionr.API_VERSION
# Close connections to limit FD use
resp.headers['Connection'] = "close"
self.lastRequest = clientAPI._core._utils.getRoundedEpoch(roundS=5) self.lastRequest = clientAPI._core._utils.getRoundedEpoch(roundS=5)
return resp return resp
@ -300,15 +293,11 @@ class API:
@app.after_request @app.after_request
def afterReq(resp): def afterReq(resp):
# Security headers # Security headers
resp = httpheaders.set_default_onionr_http_headers(resp)
if request.endpoint == 'site': if request.endpoint == 'site':
resp.headers['Content-Security-Policy'] = "default-src 'none'; style-src data: 'unsafe-inline'; img-src data:" resp.headers['Content-Security-Policy'] = "default-src 'none'; style-src data: 'unsafe-inline'; img-src data:"
else: else:
resp.headers['Content-Security-Policy'] = "default-src 'none'; script-src 'self'; object-src 'none'; style-src 'self'; img-src 'self'; media-src 'none'; frame-src 'none'; font-src 'none'; connect-src 'self'" resp.headers['Content-Security-Policy'] = "default-src 'none'; script-src 'self'; object-src 'none'; style-src 'self'; img-src 'self'; media-src 'none'; frame-src 'none'; font-src 'none'; connect-src 'self'"
resp.headers['X-Frame-Options'] = 'deny'
resp.headers['X-Content-Type-Options'] = "nosniff"
resp.headers['Server'] = ''
resp.headers['Date'] = 'Thu, 1 Jan 1970 00:00:00 GMT' # Clock info is probably useful to attackers. Set to unix epoch.
resp.headers['Connection'] = "close"
return resp return resp
@app.route('/board/', endpoint='board') @app.route('/board/', endpoint='board')

View File

@ -111,6 +111,7 @@ class OnionrCommunicatorDaemon:
if config.get('general.socket_servers', False): if config.get('general.socket_servers', False):
self.services = onionrservices.OnionrServices(self._core) self.services = onionrservices.OnionrServices(self._core)
self.active_services = [] self.active_services = []
self.service_greenlets = []
OnionrCommunicatorTimers(self, servicecreator.service_creator, 5, maxThreads=50, myArgs=(self,)) OnionrCommunicatorTimers(self, servicecreator.service_creator, 5, maxThreads=50, myArgs=(self,))
else: else:
self.services = None self.services = None
@ -148,7 +149,8 @@ class OnionrCommunicatorDaemon:
pass pass
logger.info('Goodbye.') logger.info('Goodbye.')
self._core.killSockets = True for server in self.service_greenlets:
server.stop()
self._core._utils.localCommand('shutdown') # shutdown the api self._core._utils.localCommand('shutdown') # shutdown the api
time.sleep(0.5) time.sleep(0.5)

View File

@ -37,6 +37,12 @@ def bootstrap_client_service(peer, core_inst=None, bootstrap_timeout=300):
bootstrap_port = getOpenPort() bootstrap_port = getOpenPort()
bootstrap_app = Flask(__name__) bootstrap_app = Flask(__name__)
http_server = WSGIServer(('127.0.0.1', bootstrap_port), bootstrap_app, log=None) http_server = WSGIServer(('127.0.0.1', bootstrap_port), bootstrap_app, log=None)
try:
core_inst.onionrInst.communicatorInst
except AttributeError:
pass
else:
core_inst.onionrInst.communicatorInst.service_greenlets.append(http_server)
bootstrap_address = '' bootstrap_address = ''
shutdown = False shutdown = False

View File

@ -40,6 +40,7 @@ class ConnectionServer:
service_port = getOpenPort() service_port = getOpenPort()
service_ip = api.setBindIP() service_ip = api.setBindIP()
http_server = WSGIServer(('127.0.0.1', service_port), service_app, log=None) http_server = WSGIServer(('127.0.0.1', service_port), service_app, log=None)
core_inst.onionrInst.communicatorInst.service_greenlets.append(http_server)
# TODO define basic endpoints useful for direct connections like stats # TODO define basic endpoints useful for direct connections like stats
# TODO load endpoints from plugins # TODO load endpoints from plugins
@ -53,6 +54,6 @@ class ConnectionServer:
# Create the v3 onion service # Create the v3 onion service
response = controller.create_ephemeral_hidden_service({80: service_port}, await_publication = True, key_type='NEW', key_content = 'ED25519-V3') response = controller.create_ephemeral_hidden_service({80: service_port}, await_publication = True, key_type='NEW', key_content = 'ED25519-V3')
self.core_inst._utils.doPostRequest('http://' + address + '/bs/' + response.service_id, port=socks) self.core_inst._utils.doPostRequest('http://' + address + '/bs/' + response.service_id, port=socks)
logger.info('hosting on ' + response.service_id) logger.info('hosting on %s with %s' % (response.service_id, peer))
http_server.serve_forever() http_server.serve_forever()
http_server.stop() http_server.stop()