Onionr/onionr/onionrsockets.py

124 lines
4.2 KiB
Python
Raw Normal View History

'''
Onionr - P2P Anonymous Storage Network
Onionr Socket interface
'''
'''
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/>.
'''
2018-09-15 16:13:03 +00:00
import stem.control
2018-09-23 01:21:39 +00:00
import threading
2018-09-21 04:47:40 +00:00
import socks, config, uuid
2018-09-22 05:01:17 +00:00
import onionrexceptions, time, requests, onionrblockapi
2018-09-15 01:05:25 +00:00
from dependencies import secrets
2018-09-21 04:47:40 +00:00
from flask import request, Response, abort
2018-09-15 01:05:25 +00:00
2018-09-21 04:47:40 +00:00
class OnionrSocketServer:
def __init__(self, coreInst):
self.sockets = {} # pubkey: tor address
self.connPool = {}
2018-09-22 05:01:17 +00:00
2018-09-21 04:47:40 +00:00
self.bindPort = 1337
2018-09-15 01:05:25 +00:00
self._core = coreInst
2018-09-21 04:47:40 +00:00
self.responseData = {}
self.killSocket = False
2018-09-22 05:01:17 +00:00
2018-09-21 04:47:40 +00:00
app = flask.Flask(__name__)
2018-09-15 01:05:25 +00:00
2018-09-21 04:47:40 +00:00
http_server = WSGIServer((socket.service_id, bindPort), app)
2018-09-23 01:21:39 +00:00
threading.Thread(target=http_server.serve_forever).start()
2018-09-15 04:48:48 +00:00
2018-09-21 04:47:40 +00:00
@app.route('/dc/', methods=['POST'])
def acceptConn(self):
data = request.form['data']
data = self._core._utils.bytesTorStr(data)
2018-09-15 04:48:48 +00:00
2018-09-21 04:47:40 +00:00
if request.host in self.connPool:
self.connPool[request.host].append(data)
else:
self.connPool[request.host] = [data]
2018-09-15 16:13:03 +00:00
2018-09-21 04:47:40 +00:00
retData = self.responseData[request.host]
2018-09-20 05:13:26 +00:00
2018-09-21 04:47:40 +00:00
self.responseData[request.host] = ''
return retData
2018-09-15 04:48:48 +00:00
2018-09-21 04:47:40 +00:00
def setResponseData(self, host, data):
self.responseData[host] = data
2018-09-15 16:13:03 +00:00
2018-09-22 05:01:17 +00:00
def addSocket(self, peer, reason=''):
2018-09-21 04:47:40 +00:00
bindPort = 1337
2018-09-20 17:41:34 +00:00
with stem.control.Controller.from_port(port=config.get('tor.controlPort')) as controller:
controller.authenticate(config.get('tor.controlpassword'))
2018-09-15 16:13:03 +00:00
2018-09-21 04:47:40 +00:00
socket = controller.create_ephemeral_hidden_service({80: bindPort}, await_publication = True)
self.sockets[peer] = socket.service_id
2018-09-17 05:02:16 +00:00
2018-09-21 04:47:40 +00:00
self.responseData[socket.service_id] = ''
2018-09-17 05:02:16 +00:00
2018-09-23 01:21:39 +00:00
self._core.insertBlock(uuid.uuid4(), header='socket', sign=True, encryptType='asym', asymPeer=peer, meta={'reason': reason})
2018-09-17 05:02:16 +00:00
2018-09-21 04:47:40 +00:00
while not self.killSocket:
time.sleep(3)
2018-09-17 05:02:16 +00:00
return
2018-09-20 05:13:26 +00:00
2018-09-21 04:47:40 +00:00
class OnionrSocketClient:
def __init__(self, coreInst):
self.sockets = {} # pubkey: tor address
self.connPool = {}
2018-09-22 05:01:17 +00:00
self.sendData = {}
2018-09-21 04:47:40 +00:00
self.bindPort = 1337
self._core = coreInst
self.response = ''
self.request = ''
self.connected = False
2018-09-22 05:01:17 +00:00
self.killSocket = False
2018-09-23 01:21:39 +00:00
def startSocket(self, peer, reason):
2018-09-22 05:01:17 +00:00
address = ''
# Find the newest open socket for a given peer
for block in self._core.getBlocksByType('openSocket'):
block = onionrblockapi.Block(block, core=self._myCore)
if block.decrypt():
if block.verifySig() and block.signer == peer:
address = block.getMetadata('address')
if self._core._utils.validateID(address):
# If we got their address, it is valid, and verified, we can break out
break
else:
address = ''
if address != '':
self.sockets[peer] = address
data = ''
while not self.killSocket:
try:
data = self.sendData[peer]
except KeyError:
pass
else:
self.sendData[peer] = ''
postData = {'data': data}
self.connPool[peer] = self._core._utils.doPostRequest('http://' + address + '/dc/', data=postData)
2018-09-21 04:47:40 +00:00
def getResponse(self, peer):
2018-09-22 05:01:17 +00:00
retData = ''
try:
retData = self.connPool[peer]
except KeyError:
pass
return
def sendData(self, peer, data):
self.sendData[peer] = data