changed permisisons
Before Width: | Height: | Size: 189 KiB After Width: | Height: | Size: 189 KiB |
Before Width: | Height: | Size: 191 KiB After Width: | Height: | Size: 191 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
@ -1,75 +0,0 @@
|
||||||
'''
|
|
||||||
Onionr - P2P Anonymous Storage Network
|
|
||||||
|
|
||||||
Handles api data exchange, interfaced by both public and client http api
|
|
||||||
'''
|
|
||||||
'''
|
|
||||||
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 config, apipublic, apiprivate, core, socket, random, threading, time
|
|
||||||
config.reload()
|
|
||||||
|
|
||||||
PRIVATE_API_VERSION = 0
|
|
||||||
PUBLIC_API_VERSION = 1
|
|
||||||
|
|
||||||
DEV_MODE = config.get('general.dev_mode')
|
|
||||||
|
|
||||||
def getOpenPort():
|
|
||||||
'''Get a random open port'''
|
|
||||||
p = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
p.bind(("127.0.0.1",0))
|
|
||||||
p.listen(1)
|
|
||||||
port = p.getsockname()[1]
|
|
||||||
p.close()
|
|
||||||
return port
|
|
||||||
|
|
||||||
def getRandomLocalIP():
|
|
||||||
'''Get a random local ip address'''
|
|
||||||
hostOctets = [str(127), str(random.randint(0x02, 0xFF)), str(random.randint(0x02, 0xFF)), str(random.randint(0x02, 0xFF))]
|
|
||||||
host = '.'.join(hostOctets)
|
|
||||||
return host
|
|
||||||
|
|
||||||
class APIManager:
|
|
||||||
def __init__(self, coreInst):
|
|
||||||
assert isinstance(coreInst, core.Core)
|
|
||||||
self.core = coreInst
|
|
||||||
self.utils = coreInst._utils
|
|
||||||
self.crypto = coreInst._crypto
|
|
||||||
|
|
||||||
# if this gets set to true, both the public and private apis will shutdown
|
|
||||||
self.shutdown = False
|
|
||||||
|
|
||||||
publicIP = '127.0.0.1'
|
|
||||||
privateIP = '127.0.0.1'
|
|
||||||
if DEV_MODE:
|
|
||||||
# set private and local api servers bind IPs to random localhost (127.x.x.x), make sure not the same
|
|
||||||
privateIP = getRandomLocalIP()
|
|
||||||
while True:
|
|
||||||
publicIP = getRandomLocalIP()
|
|
||||||
if publicIP != privateIP:
|
|
||||||
break
|
|
||||||
|
|
||||||
# Make official the IPs and Ports
|
|
||||||
self.publicIP = publicIP
|
|
||||||
self.privateIP = privateIP
|
|
||||||
self.publicPort = config.get('client.port', 59496)
|
|
||||||
self.privatePort = config.get('client.port', 59496)
|
|
||||||
|
|
||||||
# Run the API servers in new threads
|
|
||||||
self.publicAPI = apipublic.APIPublic(self)
|
|
||||||
self.privateAPI = apiprivate.APIPrivate(self)
|
|
||||||
threading.Thread(target=self.publicAPI.run).start()
|
|
||||||
threading.Thread(target=self.privateAPI.run).start()
|
|
||||||
while not self.shutdown:
|
|
||||||
time.sleep(1)
|
|
|
@ -1,32 +0,0 @@
|
||||||
'''
|
|
||||||
Onionr - P2P Anonymous Storage Network
|
|
||||||
|
|
||||||
Handle incoming commands from the client. Intended for localhost use
|
|
||||||
'''
|
|
||||||
'''
|
|
||||||
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 flask, apimanager
|
|
||||||
from flask import request, Response, abort, send_from_directory
|
|
||||||
from gevent.pywsgi import WSGIServer
|
|
||||||
|
|
||||||
class APIPrivate:
|
|
||||||
def __init__(self, managerInst):
|
|
||||||
assert isinstance(managerInst, apimanager.APIManager)
|
|
||||||
self.app = flask.Flask(__name__) # The flask application, which recieves data from the greenlet wsgiserver
|
|
||||||
self.httpServer = WSGIServer((managerInst.privateIP, managerInst.privatePort), self.app, log=None)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.httpServer.serve_forever()
|
|
||||||
return
|
|
|
@ -1,41 +0,0 @@
|
||||||
'''
|
|
||||||
Onionr - P2P Anonymous Storage Network
|
|
||||||
|
|
||||||
Handle incoming commands from other Onionr nodes, over HTTP
|
|
||||||
'''
|
|
||||||
'''
|
|
||||||
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 flask, apimanager
|
|
||||||
from flask import request, Response, abort, send_from_directory
|
|
||||||
from gevent.pywsgi import WSGIServer
|
|
||||||
|
|
||||||
|
|
||||||
class APIPublic:
|
|
||||||
def __init__(self, managerInst):
|
|
||||||
assert isinstance(managerInst, apimanager.APIManager)
|
|
||||||
app = flask.Flask(__name__)
|
|
||||||
@app.route('/')
|
|
||||||
def banner():
|
|
||||||
try:
|
|
||||||
with open('static-data/index.html', 'r') as html:
|
|
||||||
resp = Response(html.read(), mimetype='text/html')
|
|
||||||
except FileNotFoundError:
|
|
||||||
resp = Response("")
|
|
||||||
return resp
|
|
||||||
self.httpServer = WSGIServer((managerInst.publicIP, managerInst.publicPort), app)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.httpServer.serve_forever()
|
|
||||||
return
|
|
|
@ -56,7 +56,7 @@ class Core:
|
||||||
self.privateApiHostFile = self.dataDir + 'private-host.txt'
|
self.privateApiHostFile = self.dataDir + 'private-host.txt'
|
||||||
self.addressDB = self.dataDir + 'address.db'
|
self.addressDB = self.dataDir + 'address.db'
|
||||||
self.hsAddress = ''
|
self.hsAddress = ''
|
||||||
self.i2pAddress = config.get('i2p.ownAddr', None)
|
self.i2pAddress = config.get('i2p.own_addr', None)
|
||||||
self.bootstrapFileLocation = 'static-data/bootstrap-nodes.txt'
|
self.bootstrapFileLocation = 'static-data/bootstrap-nodes.txt'
|
||||||
self.bootstrapList = []
|
self.bootstrapList = []
|
||||||
self.requirements = onionrvalues.OnionrValues()
|
self.requirements = onionrvalues.OnionrValues()
|
||||||
|
|
|
@ -43,37 +43,43 @@ class DaemonTools:
|
||||||
else:
|
else:
|
||||||
peer = self.daemon.pickOnlinePeer()
|
peer = self.daemon.pickOnlinePeer()
|
||||||
|
|
||||||
ourID = self.daemon._core.hsAddress.strip()
|
for x in range(1):
|
||||||
|
if x == 1 and self.daemon._core.config.get('i2p.host'):
|
||||||
url = 'http://' + peer + '/announce'
|
ourID = self.daemon._core.config.get('i2p.own_addr').strip()
|
||||||
data = {'node': ourID}
|
|
||||||
|
|
||||||
combinedNodes = ourID + peer
|
|
||||||
existingRand = self.daemon._core.getAddressInfo(peer, 'powValue')
|
|
||||||
if type(existingRand) is type(None):
|
|
||||||
existingRand = ''
|
|
||||||
|
|
||||||
if peer in self.announceCache:
|
|
||||||
data['random'] = self.announceCache[peer]
|
|
||||||
elif len(existingRand) > 0:
|
|
||||||
data['random'] = existingRand
|
|
||||||
else:
|
|
||||||
proof = onionrproofs.DataPOW(combinedNodes, forceDifficulty=4)
|
|
||||||
try:
|
|
||||||
data['random'] = base64.b64encode(proof.waitForResult()[1])
|
|
||||||
except TypeError:
|
|
||||||
# Happens when we failed to produce a proof
|
|
||||||
logger.error("Failed to produce a pow for announcing to " + peer)
|
|
||||||
announceFail = True
|
|
||||||
else:
|
else:
|
||||||
self.announceCache[peer] = data['random']
|
ourID = self.daemon._core.hsAddress.strip()
|
||||||
if not announceFail:
|
|
||||||
logger.info('Announcing node to ' + url)
|
url = 'http://' + peer + '/announce'
|
||||||
if self.daemon._core._utils.doPostRequest(url, data) == 'Success':
|
data = {'node': ourID}
|
||||||
logger.info('Successfully introduced node to ' + peer)
|
|
||||||
retData = True
|
combinedNodes = ourID + peer
|
||||||
self.daemon._core.setAddressInfo(peer, 'introduced', 1)
|
if ourID != 1:
|
||||||
self.daemon._core.setAddressInfo(peer, 'powValue', data['random'])
|
#TODO: Extend existingRand for i2p
|
||||||
|
existingRand = self.daemon._core.getAddressInfo(peer, 'powValue')
|
||||||
|
if type(existingRand) is type(None):
|
||||||
|
existingRand = ''
|
||||||
|
|
||||||
|
if peer in self.announceCache:
|
||||||
|
data['random'] = self.announceCache[peer]
|
||||||
|
elif len(existingRand) > 0:
|
||||||
|
data['random'] = existingRand
|
||||||
|
else:
|
||||||
|
proof = onionrproofs.DataPOW(combinedNodes, forceDifficulty=4)
|
||||||
|
try:
|
||||||
|
data['random'] = base64.b64encode(proof.waitForResult()[1])
|
||||||
|
except TypeError:
|
||||||
|
# Happens when we failed to produce a proof
|
||||||
|
logger.error("Failed to produce a pow for announcing to " + peer)
|
||||||
|
announceFail = True
|
||||||
|
else:
|
||||||
|
self.announceCache[peer] = data['random']
|
||||||
|
if not announceFail:
|
||||||
|
logger.info('Announcing node to ' + url)
|
||||||
|
if self.daemon._core._utils.doPostRequest(url, data) == 'Success':
|
||||||
|
logger.info('Successfully introduced node to ' + peer)
|
||||||
|
retData = True
|
||||||
|
self.daemon._core.setAddressInfo(peer, 'introduced', 1)
|
||||||
|
self.daemon._core.setAddressInfo(peer, 'powValue', data['random'])
|
||||||
self.daemon.decrementThreadCount('announceNode')
|
self.daemon.decrementThreadCount('announceNode')
|
||||||
return retData
|
return retData
|
||||||
|
|
||||||
|
|
0
onionr/static-data/default-plugins/pluginmanager/.gitignore
vendored
Normal file → Executable file
|
@ -141,7 +141,11 @@ class OnionrMail:
|
||||||
logger.warn('This message has an INVALID signature. ANYONE could have sent this message.')
|
logger.warn('This message has an INVALID signature. ANYONE could have sent this message.')
|
||||||
cancel = logger.readline('Press enter to continue to message, or -q to not open the message (recommended).')
|
cancel = logger.readline('Press enter to continue to message, or -q to not open the message (recommended).')
|
||||||
if cancel != '-q':
|
if cancel != '-q':
|
||||||
print(draw_border(self.myCore._utils.escapeAnsi(readBlock.bcontent.decode().strip())))
|
try:
|
||||||
|
print(draw_border(self.myCore._utils.escapeAnsi(readBlock.bcontent.decode().strip())))
|
||||||
|
except ValueError:
|
||||||
|
logger.warn('Error presenting message. This is usually due to a malformed or blank message.')
|
||||||
|
pass
|
||||||
reply = logger.readline("Press enter to continue, or enter %s to reply" % ("-r",))
|
reply = logger.readline("Press enter to continue, or enter %s to reply" % ("-r",))
|
||||||
if reply == "-r":
|
if reply == "-r":
|
||||||
self.draftMessage(self.myCore._utils.bytesToStr(readBlock.signer,))
|
self.draftMessage(self.myCore._utils.bytesToStr(readBlock.signer,))
|
||||||
|
|
|
@ -21,8 +21,7 @@
|
||||||
"private" : {
|
"private" : {
|
||||||
"run" : true,
|
"run" : true,
|
||||||
"path" : "static-data/www/private/",
|
"path" : "static-data/www/private/",
|
||||||
"guess_mime" : true,
|
"guess_mime" : true
|
||||||
"timing_protection" : true
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"ui" : {
|
"ui" : {
|
||||||
|
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |