work on clandestine

master
Kevin Froman 2019-03-29 12:37:51 -05:00
parent 726bbe61ac
commit 30630e1d8e
10 changed files with 64 additions and 16 deletions

View File

@ -98,7 +98,7 @@ class DaemonTools:
if len(self.daemon.onlinePeers) == 0: if len(self.daemon.onlinePeers) == 0:
if not netutils.checkNetwork(self.daemon._core._utils, torPort=self.daemon.proxyPort): if not netutils.checkNetwork(self.daemon._core._utils, torPort=self.daemon.proxyPort):
if not self.daemon.shutdown: if not self.daemon.shutdown:
logger.warn('Network check failed, are you connected to the internet?') logger.warn('Network check failed, are you connected to the Internet, and is Tor working?')
self.daemon.isOnline = False self.daemon.isOnline = False
else: else:
self.daemon.isOnline = True self.daemon.isOnline = True

View File

@ -12,6 +12,7 @@ def service_creator(daemon):
bs = utils.bytesToStr(bl.bcontent) + '.onion' bs = utils.bytesToStr(bl.bcontent) + '.onion'
if utils.validatePubKey(bl.signer) and utils.validateID(bs): if utils.validatePubKey(bl.signer) and utils.validateID(bs):
daemon.active_services.append(b) daemon.active_services.append(b)
daemon.active_services.append(bl.signer)
daemon.services.create_server(bl.signer, bs) daemon.services.create_server(bl.signer, bs)
daemon.decrementThreadCount('service_creator') daemon.decrementThreadCount('service_creator')

View File

@ -794,11 +794,11 @@ class Core:
retData = False retData = False
else: else:
# Tell the api server through localCommand to wait for the daemon to upload this block to make stastical analysis more difficult # Tell the api server through localCommand to wait for the daemon to upload this block to make stastical analysis more difficult
self._utils.localCommand('/waitforshare/' + retData, post=True) if self._utils.localCommand('/ping', maxWait=10) == 'pong!':
self._utils.localCommand('/waitforshare/' + retData, post=True, maxWait=5)
self.daemonQueueAdd('uploadBlock', retData)
self.addToBlockDB(retData, selfInsert=True, dataSaved=True) self.addToBlockDB(retData, selfInsert=True, dataSaved=True)
#self.setBlockType(retData, meta['type'])
self._utils.processBlockMetadata(retData) self._utils.processBlockMetadata(retData)
self.daemonQueueAdd('uploadBlock', retData)
if retData != False: if retData != False:
if plaintextPeer == 'OVPCZLOXD6DC5JHX4EQ3PSOGAZ3T24F75HQLIUZSDSMYPEOXCPFA====': if plaintextPeer == 'OVPCZLOXD6DC5JHX4EQ3PSOGAZ3T24F75HQLIUZSDSMYPEOXCPFA====':

View File

@ -22,4 +22,4 @@ class OnionrValues:
def __init__(self): def __init__(self):
self.passwordLength = 20 self.passwordLength = 20
self.blockMetadataLengths = {'meta': 1000, 'sig': 200, 'signer': 200, 'time': 10, 'powRandomToken': 1000, 'encryptType': 4, 'expire': 14} #TODO properly refine values to minimum needed self.blockMetadataLengths = {'meta': 1000, 'sig': 200, 'signer': 200, 'time': 10, 'powRandomToken': 1000, 'encryptType': 4, 'expire': 14} #TODO properly refine values to minimum needed
self.default_expire = 2678400 self.default_expire = 2592000

View File

@ -19,11 +19,11 @@
''' '''
import onionrplugins import onionrplugins
def load_plugin_blueprints(flaskapp): def load_plugin_blueprints(flaskapp, blueprint='flask_blueprint'):
'''Iterate enabled plugins and load any http endpoints they have''' '''Iterate enabled plugins and load any http endpoints they have'''
for plugin in onionrplugins.get_enabled_plugins(): for plugin in onionrplugins.get_enabled_plugins():
plugin = onionrplugins.get_plugin(plugin) plugin = onionrplugins.get_plugin(plugin)
try: try:
flaskapp.register_blueprint(getattr(plugin, 'flask_blueprint')) flaskapp.register_blueprint(getattr(plugin, blueprint))
except AttributeError: except AttributeError:
pass pass

View File

@ -19,7 +19,7 @@
''' '''
import sys, getpass import sys, getpass
import logger import logger, onionrexceptions
from onionrusers import onionrusers from onionrusers import onionrusers
def add_ID(o_inst): def add_ID(o_inst):
try: try:
@ -38,7 +38,7 @@ def add_ID(o_inst):
logger.info('Generating deterministic key. This can take a while.') logger.info('Generating deterministic key. This can take a while.')
newID, privKey = o_inst.onionrCore._crypto.generateDeterministic(pass1) newID, privKey = o_inst.onionrCore._crypto.generateDeterministic(pass1)
except onionrexceptions.PasswordStrengthError: except onionrexceptions.PasswordStrengthError:
logger.error('Must use at least 25 characters.') logger.error('Passphrase must use at least %s characters.' % (o_inst.onionrCore._crypto.deterministicRequirement,))
sys.exit(1) sys.exit(1)
else: else:
logger.error('Passwords do not match.') logger.error('Passwords do not match.')

View File

@ -21,7 +21,7 @@ import threading, time
from gevent.pywsgi import WSGIServer, WSGIHandler from gevent.pywsgi import WSGIServer, WSGIHandler
from stem.control import Controller from stem.control import Controller
from flask import Flask from flask import Flask
import core, logger import core, logger, httpapi
from netcontroller import getOpenPort from netcontroller import getOpenPort
import api import api
from . import httpheaders from . import httpheaders
@ -44,7 +44,9 @@ class ConnectionServer:
core_inst.onionrInst.communicatorInst.service_greenlets.append(http_server) 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
httpapi.load_plugin_blueprints(service_app, blueprint='direct_blueprint')
@service_app.route('/ping') @service_app.route('/ping')
def get_ping(): def get_ping():
return "pong!" return "pong!"
@ -60,7 +62,9 @@ class ConnectionServer:
controller.authenticate(core_inst.config.get('tor.controlpassword')) controller.authenticate(core_inst.config.get('tor.controlpassword'))
# 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.keyStore.put('dc-' + response.service_id, self.core_inst._utils.bytesToStr(peer))
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 %s with %s' % (response.service_id, peer)) logger.info('hosting on %s with %s' % (response.service_id, peer))
http_server.serve_forever() http_server.serve_forever()
self.core_inst.keyStore.delete('dc-' + response.service_id)
http_server.stop() http_server.stop()

View File

@ -21,6 +21,6 @@ from flask import Response, request, redirect, Blueprint, abort
flask_blueprint = Blueprint('clandenstine', __name__) flask_blueprint = Blueprint('clandenstine', __name__)
@flask_blueprint.route('/mail/ping') @flask_blueprint.route('/clandenstine/ping')
def ping(): def ping():
return 'pong!' return 'pong!'

View File

@ -23,14 +23,15 @@ import locale, sys, os
locale.setlocale(locale.LC_ALL, '') locale.setlocale(locale.LC_ALL, '')
plugin_name = 'clandenstine' plugin_name = 'clandestine'
PLUGIN_VERSION = '0.0.0' PLUGIN_VERSION = '0.0.0'
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__))) sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
from . import controlapi from . import controlapi, peerserver
flask_blueprint = controlapi.flask_blueprint flask_blueprint = controlapi.flask_blueprint
direct_blueprint = peerserver.direct_blueprint
class Clandenstine: class Clandestine:
def __init__(self, pluginapi): def __init__(self, pluginapi):
self.myCore = pluginapi.get_core() self.myCore = pluginapi.get_core()
@ -42,5 +43,5 @@ def on_init(api, data = None):
''' '''
pluginapi = api pluginapi = api
chat = Clandenstine(pluginapi) chat = Clandestine(pluginapi)
return return

View File

@ -0,0 +1,42 @@
'''
Onionr - P2P Anonymous Storage Network
HTTP endpoints for communicating with peers
'''
'''
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/>.
'''
import core
from flask import Response, request, redirect, Blueprint, abort, g
direct_blueprint = Blueprint('clandestine', __name__)
core_inst = core.Core()
storage_dir = core_inst.dataDir
@direct_blueprint.before_request
def request_setup():
core_inst.keyStore.refresh()
host = request.host
host = host.strip('.b32.i2p')
host = host.strip('.onion')
g.host = host
g.peer = core_inst.keyStore.get('dc-' + g.host)
@direct_blueprint.route('/clandestine/ping')
def pingdirect():
return 'pong!' + g.peer
@direct_blueprint.route('/clandestine/send')
def poll_chat