Merge I2P Branch (#19)

* work on i2p support

* work on i2p support

* redid socks check

* redid socks check

* redid socks check

* work on i2p and fixed broken block processing

* fixed no newline delim on block list in api

* fixed no newline delim on block list in api

* fixed no newline delim on block list in api

* use extend instead of append for blocklist after newline changes
master
Kevin Froman 2018-05-19 16:32:21 -05:00 committed by Arinerron
parent bbac26fed1
commit 500658808f
8 changed files with 46 additions and 13 deletions

View File

@ -69,6 +69,8 @@ class API:
self.clientToken = config.get('client')['client_hmac'] self.clientToken = config.get('client')['client_hmac']
self.timeBypassToken = base64.b16encode(os.urandom(32)).decode() self.timeBypassToken = base64.b16encode(os.urandom(32)).decode()
self.i2pEnabled = config.get('i2p')['host']
self.mimeType = 'text/plain' self.mimeType = 'text/plain'
with open('data/time-bypass.txt', 'w') as bypass: with open('data/time-bypass.txt', 'w') as bypass:
@ -197,7 +199,7 @@ class API:
elif action == 'getDBHash': elif action == 'getDBHash':
resp = Response(self._utils.getBlockDBHash()) resp = Response(self._utils.getBlockDBHash())
elif action == 'getBlockHashes': elif action == 'getBlockHashes':
resp = Response(self._core.getBlockList()) resp = Response('\n'.join(self._core.getBlockList()))
elif action == 'directMessage': elif action == 'directMessage':
resp = Response(self._core.handle_direct_connection(data)) resp = Response(self._core.handle_direct_connection(data))
elif action == 'announce': elif action == 'announce':
@ -289,6 +291,10 @@ class API:
if not request.host.endswith('onion') and not request.host.endswith('i2p'): if not request.host.endswith('onion') and not request.host.endswith('i2p'):
abort(403) abort(403)
# Validate x-requested-with, to protect against CSRF/metadata leaks # Validate x-requested-with, to protect against CSRF/metadata leaks
if not self.i2pEnabled and request.host.endswith('i2p'):
abort(403)
if not self._developmentMode: if not self._developmentMode:
try: try:
request.headers['X-Requested-With'] request.headers['X-Requested-With']

View File

@ -490,7 +490,7 @@ class OnionrCommunicate:
if lastDB != currentDB: if lastDB != currentDB:
logger.debug('Fetching hash from %s - %s current hash.' % (str(i), currentDB)) logger.debug('Fetching hash from %s - %s current hash.' % (str(i), currentDB))
try: try:
blockList.append(self.performGet('getBlockHashes', i)) blockList.extend(self.performGet('getBlockHashes', i).split('\n'))
except TypeError: except TypeError:
logger.warn('Failed to get data hash from %s' % str(i)) logger.warn('Failed to get data hash from %s' % str(i))
self.peerData[i]['failCount'] -= 1 self.peerData[i]['failCount'] -= 1
@ -616,7 +616,13 @@ class OnionrCommunicate:
return return
def removeBlockFromProcessingList(self, block): def removeBlockFromProcessingList(self, block):
return block in blocksProcessing '''Remove a block from the processing list'''
try:
self.blocksProcessing.remove(block)
except ValueError:
return False
else:
return True
def downloadBlock(self, hash, peerTries=3): def downloadBlock(self, hash, peerTries=3):
''' '''
@ -672,13 +678,13 @@ class OnionrCommunicate:
''' '''
return urllib.parse.quote_plus(data) return urllib.parse.quote_plus(data)
def performGet(self, action, peer, data=None, skipHighFailureAddress=False, peerType='tor', selfCheck=True): def performGet(self, action, peer, data=None, skipHighFailureAddress=False, selfCheck=True):
''' '''
Performs a request to a peer through Tor or i2p (currently only Tor) Performs a request to a peer through Tor or i2p (currently only Tor)
''' '''
if not peer.endswith('.onion') and not peer.endswith('.onion/'): if not peer.endswith('.onion') and not peer.endswith('.onion/') and not peer.endswith('.b32.i2p'):
raise PeerError('Currently only Tor .onion peers are supported. You must manually specify .onion') raise PeerError('Currently only Tor/i2p .onion/.b32.i2p peers are supported. You must manually specify .onion/.b32.i2p')
if len(self._core.hsAdder.strip()) == 0: if len(self._core.hsAdder.strip()) == 0:
raise Exception("Could not perform self address check in performGet due to not knowing our address") raise Exception("Could not perform self address check in performGet due to not knowing our address")
@ -692,9 +698,15 @@ class OnionrCommunicate:
self.peerData[peer] = {'connectCount': 0, 'failCount': 0, 'lastConnectTime': self._utils.getEpoch()} self.peerData[peer] = {'connectCount': 0, 'failCount': 0, 'lastConnectTime': self._utils.getEpoch()}
socksPort = sys.argv[2] socksPort = sys.argv[2]
'''We use socks5h to use tor as DNS''' '''We use socks5h to use tor as DNS'''
proxies = {'http': 'socks5://127.0.0.1:' + str(socksPort), 'https': 'socks5://127.0.0.1:' + str(socksPort)}
if peer.endswith('onion'):
proxies = {'http': 'socks5h://127.0.0.1:' + str(socksPort), 'https': 'socks5h://127.0.0.1:' + str(socksPort)}
elif peer.endswith('b32.i2p'):
proxies = {'http': 'http://127.0.0.1:4444'}
headers = {'user-agent': 'PyOnionr'} headers = {'user-agent': 'PyOnionr'}
url = 'http://' + peer + '/public/?action=' + self.urlencode(action) url = 'http://' + peer + '/public/?action=' + self.urlencode(action)
if data != None: if data != None:
url = url + '&data=' + self.urlencode(data) url = url + '&data=' + self.urlencode(data)
try: try:
@ -704,7 +716,11 @@ class OnionrCommunicate:
else: else:
self.peerStatus[peer] = action self.peerStatus[peer] = action
logger.debug('Contacting %s on port %s' % (peer, str(socksPort))) logger.debug('Contacting %s on port %s' % (peer, str(socksPort)))
r = requests.get(url, headers=headers, proxies=proxies, timeout=(15, 30)) try:
r = requests.get(url, headers=headers, proxies=proxies, allow_redirects=False, timeout=(15, 30))
except ValueError:
proxies = {'http': 'socks5://127.0.0.1:' + str(socksPort), 'https': 'socks5://127.0.0.1:' + str(socksPort)}
r = requests.get(url, headers=headers, proxies=proxies, allow_redirects=False, timeout=(15, 30))
retData = r.text retData = r.text
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
logger.debug("%s failed with peer %s" % (action, peer)) logger.debug("%s failed with peer %s" % (action, peer))

View File

@ -17,7 +17,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
''' '''
import sqlite3, os, sys, time, math, base64, tarfile, getpass, simplecrypt, hashlib, nacl, logger, json, netcontroller, math import sqlite3, os, sys, time, math, base64, tarfile, getpass, simplecrypt, hashlib, nacl, logger, json, netcontroller, math, config
#from Crypto.Cipher import AES #from Crypto.Cipher import AES
#from Crypto import Random #from Crypto import Random
@ -111,6 +111,8 @@ class Core:
''' '''
Add an address to the address database (only tor currently) Add an address to the address database (only tor currently)
''' '''
if address == config.get('i2p')['ownAddr']:
return False
if self._utils.validateID(address): if self._utils.validateID(address):
conn = sqlite3.connect(self.addressDB) conn = sqlite3.connect(self.addressDB)
c = conn.cursor() c = conn.cursor()

View File

@ -575,7 +575,7 @@ class Onionr:
# count stats # count stats
'div2' : True, 'div2' : True,
'Known Peers Count' : str(len(self.onionrCore.listPeers())), 'Known Peers Count' : str(len(self.onionrCore.listPeers()) - 1),
'Enabled Plugins Count' : str(len(config.get('plugins')['enabled'])) + ' / ' + str(len(os.listdir('data/plugins/'))) 'Enabled Plugins Count' : str(len(config.get('plugins')['enabled'])) + ' / ' + str(len(os.listdir('data/plugins/')))
} }

View File

@ -18,7 +18,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
''' '''
import nacl.encoding, nacl.hash, nacl.utils, time, math, threading, binascii, logger, sys import nacl.encoding, nacl.hash, nacl.utils, time, math, threading, binascii, logger, sys, base64
import core import core
class POW: class POW:
@ -45,6 +45,7 @@ class POW:
endTime = math.floor(time.time()) endTime = math.floor(time.time())
if self.reporting: if self.reporting:
logger.info('Found token ' + token, timestamp=True) logger.info('Found token ' + token, timestamp=True)
logger.info('rand value: ' + base64.b64encode(rand).decode())
logger.info('took ' + str(endTime - startTime) + ' seconds', timestamp=True) logger.info('took ' + str(endTime - startTime) + ' seconds', timestamp=True)
self.result = (token, rand) self.result = (token, rand)

View File

@ -109,7 +109,10 @@ class OnionrUtils:
except IndexError: except IndexError:
logger.warn('No pow token') logger.warn('No pow token')
continue continue
powHash = self._core._crypto.blake2bHash(base64.b64decode(key[1]) + self._core._crypto.blake2bHash(key[0].encode())) #powHash = self._core._crypto.blake2bHash(base64.b64decode(key[1]) + self._core._crypto.blake2bHash(key[0].encode()))
value = base64.b64decode(key[1])
hashedKey = self._core._crypto.blake2bHash(key[0])
powHash = self._core._crypto.blake2bHash(value + hashedKey)
try: try:
powHash = powHash.encode() powHash = powHash.encode()
except AttributeError: except AttributeError:

View File

@ -13,6 +13,11 @@
"color": true "color": true
} }
}, },
"i2p":{
"host": false,
"connect": true,
"ownAddr": ""
},
"allocations":{ "allocations":{
"disk": 1000000000, "disk": 1000000000,
"netTotal": 1000000000 "netTotal": 1000000000

View File

@ -1,5 +1,5 @@
<h1>This is an Onionr Node</h1> <h1>This is an Onionr Node</h1>
<p>The content on this server is not necessarily created or intentionally stored by the owner of the software.</p> <p>The content on this server is not necessarily created or intentionally stored by the owner of the server.</p>
<p>To learn more about Onionr, see the website at <a href="https://onionr.voidnet.tech/">https://Onionr.VoidNet.tech/</a></p> <p>To learn more about Onionr, see the website at <a href="https://onionr.voidnet.tech/">https://Onionr.VoidNet.tech/</a></p>