Browse Source

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

merge-requests/3/head
Kevin Froman 4 years ago
parent
commit
2898dbaafa
No known key found for this signature in database GPG Key ID: D414D0FE405B63B
  1. 4
      LICENSE
  2. 47
      api.py
  3. 7
      core.py
  4. 4
      onionr.py
  5. 4
      readme.md
  6. 6
      tests.py

4
LICENSE

@ -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

@ -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:

7
core.py

@ -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.

4
onionr.py

@ -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):

4
readme.md

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

6
tests.py

@ -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')

Loading…
Cancel
Save