timing attack identity correlation prevention added, python3 test, more fingerprinting prevention, began work on PGP core

master
Kevin Froman 2018-01-05 03:16:21 -06:00
parent fb0309a414
commit 2898dbaafa
No known key found for this signature in database
GPG Key ID: 0D414D0FE405B63B
6 changed files with 60 additions and 12 deletions

View File

@ -1,3 +1,7 @@
Onionr Logo is licensed under Creative Commons Attribution-Share Alike 3.0 Unported
https://creativecommons.org/licenses/by-sa/4.0/
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007

47
api.py
View File

@ -15,7 +15,7 @@
'''
import flask
from flask import request, Response, abort
import configparser, sys, random, threading, hmac, hashlib, base64
import configparser, sys, random, threading, hmac, hashlib, base64, time, math, gnupg
from core import Core
'''
@ -31,6 +31,8 @@ class API:
def __init__(self, config, debug):
self.config = config
self.debug = debug
self._privateDelayTime = 3
self._core = Core()
app = flask.Flask(__name__)
bindPort = int(self.config['CLIENT']['PORT'])
self.bindPort = bindPort
@ -44,12 +46,15 @@ class API:
@app.before_request
def beforeReq():
self.requestFailed = False
return
@app.after_request
def afterReq(resp):
resp.headers['Access-Control-Allow-Origin'] = '*'
resp.headers['server'] = 'Onionr'
if not self.requestFailed:
resp.headers['Access-Control-Allow-Origin'] = '*'
else:
resp.headers['server'] = 'Onionr'
resp.headers['content-type'] = 'text/plain'
resp.headers["Content-Security-Policy"] = "default-src 'none'"
resp.headers['x-frame-options'] = 'deny'
@ -57,29 +62,47 @@ class API:
@app.route('/client/')
def private_handler():
startTime = math.floor(time.time())
# we should keep a hash DB of requests (with hmac) to prevent replays
action = request.args.get('action')
#if not self.debug:
token = request.args.get('token')
if not self.validateToken(token):
abort(403)
self.validateHost()
self.validateHost('private')
if action == 'hello':
resp = Response('Hello, World! ' + request.host)
elif action == 'stats':
resp =Response('something')
resp = Response('something')
elif action == 'init':
# generate PGP key
pass
else:
resp = Response('(O_o) Dude what? (invalid command)')
endTime = math.floor(time.time())
elapsed = endTime - startTime
if elapsed < self._privateDelayTime:
time.sleep(self._privateDelayTime - elapsed)
return resp
@app.route('/public/')
def public_handler():
# Public means it is publicly network accessible
self.validateHost('public')
action = request.args.get('action')
@app.errorhandler(404)
def notfound(err):
resp = Response("\_(0_0)_/ I got nothin")
self.requestFailed = True
resp = Response("")
#resp.headers = getHeaders(resp)
return resp
@app.errorhandler(403)
def authFail(err):
resp = Response("Auth required/security failure")
self.requestFailed = True
resp = Response("403")
return resp
print('Starting client on ' + self.host + ':' + str(bindPort))
@ -87,13 +110,17 @@ class API:
app.run(host=self.host, port=bindPort, debug=True, threaded=True)
def validateHost(self):
def validateHost(self, hostType):
if self.debug:
return
# Validate host header, to protect against DNS rebinding attacks
host = self.host
if not request.host.startswith('127'):
abort(403)
if hostType == 'private':
if not request.host.startswith('127'):
abort(403)
elif hostType == 'public':
if not request.host.endswith('onion') and not request.hosst.endswith('i2p'):
abort(403)
# Validate x-requested-with, to protect against CSRF/metadata leaks
'''
try:

View File

@ -13,13 +13,18 @@
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 sqlite3, os, time, math
import sqlite3, os, time, math, gnupg
class Core:
def __init__(self):
self.queueDB = 'data/queue.db'
#self.daemonQueue() # Call to create the DB if it doesn't exist
return
def generateMainPGP(self):
# Generate main pgp key
gpg = gnupg.GPG(gnupghome='data/pgp/')
return
def daemonQueue(self):
# This function intended to be used by the client
# Queue to exchange data between "client" and server.

View File

@ -43,7 +43,7 @@ class Onionr:
randomPort = 8080
else:
randomPort = random.randint(1024, 65535)
self.config['CLIENT'] = {'CLIENT HMAC': base64.b64encode(os.urandom(32)).decode('utf-8'), 'PORT': randomPort}
self.config['CLIENT'] = {'CLIENT HMAC': base64.b64encode(os.urandom(32)).decode('utf-8'), 'PORT': randomPort, 'API VERSION': '0.0.0'}
with open('data/config.ini', 'w') as configfile:
self.config.write(configfile)
command = ''
@ -67,6 +67,8 @@ class Onionr:
return
return
def daemon(self):
os.system('./communicator.py')
print('Started communicator')
api.API(self.config, self.debug)
return
def killDaemon(self):

View File

@ -3,3 +3,7 @@
P2P microblogging platform and social network, using Tor & I2P.
Major work in progress. *NOT USABLE OR SAFE YET*
# Development

View File

@ -17,6 +17,12 @@
import unittest, sys, os
class OnionrTests(unittest.TestCase):
def testPython3(self):
if sys.version_info.major != 3:
print(sys.version_info.major)
self.assertTrue(False)
else:
self.assertTrue(True)
def testNone(self):
print('--------------------------')
print('Running simple program run test')