Fix merge conflicts

master
Arinerron 2018-11-16 23:23:10 -08:00
commit 908ee647a1
No known key found for this signature in database
GPG Key ID: 99383627861C62F0
15 changed files with 152 additions and 44 deletions

View File

@ -94,6 +94,8 @@ class API:
self.mimeType = 'text/plain' self.mimeType = 'text/plain'
self.overrideCSP = False self.overrideCSP = False
self.hideBlocks = [] # Blocks to be denied sharing
with open(self._core.dataDir + 'time-bypass.txt', 'w') as bypass: with open(self._core.dataDir + 'time-bypass.txt', 'w') as bypass:
bypass.write(self.timeBypassToken) bypass.write(self.timeBypassToken)
@ -231,6 +233,15 @@ class API:
self.validateHost('private') self.validateHost('private')
if action == 'hello': if action == 'hello':
resp = Response('Hello, World! ' + request.host) resp = Response('Hello, World! ' + request.host)
elif action == 'waitForShare':
if self._core._utils.validateHash(data):
if data not in self.hideBlocks:
self.hideBlocks.append(data)
else:
self.hideBlocks.remove(data)
resp = "success"
else:
resp = "failed to validate hash"
elif action == 'shutdown': elif action == 'shutdown':
# request.environ.get('werkzeug.server.shutdown')() # request.environ.get('werkzeug.server.shutdown')()
self.http_server.stop() self.http_server.stop()
@ -469,7 +480,11 @@ 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('\n'.join(self._core.getBlockList())) bList = self._core.getBlockList()
for b in self.hideBlocks:
if b in bList:
bList.remove(b)
resp = Response('\n'.join(bList))
# setData should be something the communicator initiates, not this api # setData should be something the communicator initiates, not this api
elif action == 'getData': elif action == 'getData':
resp = '' resp = ''

View File

@ -43,7 +43,7 @@ class OnionrCommunicatorDaemon:
self.nistSaltTimestamp = 0 self.nistSaltTimestamp = 0
self.powSalt = 0 self.powSalt = 0
self.blockToUpload = '' self.blocksToUpload = []
# loop time.sleep delay in seconds # loop time.sleep delay in seconds
self.delay = 1 self.delay = 1
@ -89,16 +89,15 @@ class OnionrCommunicatorDaemon:
# Set timers, function reference, seconds # Set timers, function reference, seconds
# requiresPeer True means the timer function won't fire if we have no connected peers # requiresPeer True means the timer function won't fire if we have no connected peers
OnionrCommunicatorTimers(self, self.runCheck, 1)
OnionrCommunicatorTimers(self, self.daemonCommands, 5)
OnionrCommunicatorTimers(self, self.detectAPICrash, 5)
peerPoolTimer = OnionrCommunicatorTimers(self, self.getOnlinePeers, 60, maxThreads=1) peerPoolTimer = OnionrCommunicatorTimers(self, self.getOnlinePeers, 60, maxThreads=1)
OnionrCommunicatorTimers(self, self.lookupBlocks, self._core.config.get('timers.lookup_blocks'), requiresPeer=True, maxThreads=1) OnionrCommunicatorTimers(self, self.runCheck, 1)
OnionrCommunicatorTimers(self, self.getBlocks, self._core.config.get('timers.get_blocks'), requiresPeer=True) OnionrCommunicatorTimers(self, self.lookupBlocks, self._core.config.get('timers.lookupBlocks'), requiresPeer=True, maxThreads=1)
OnionrCommunicatorTimers(self, self.getBlocks, self._core.config.get('timers.getBlocks'), requiresPeer=True)
OnionrCommunicatorTimers(self, self.clearOfflinePeer, 58) OnionrCommunicatorTimers(self, self.clearOfflinePeer, 58)
OnionrCommunicatorTimers(self, self.daemonTools.cleanOldBlocks, 65) OnionrCommunicatorTimers(self, self.daemonTools.cleanOldBlocks, 65)
OnionrCommunicatorTimers(self, self.lookupAdders, 60, requiresPeer=True) OnionrCommunicatorTimers(self, self.lookupAdders, 60, requiresPeer=True)
OnionrCommunicatorTimers(self, self.daemonTools.cooldownPeer, 30, requiresPeer=True) OnionrCommunicatorTimers(self, self.daemonTools.cooldownPeer, 30, requiresPeer=True)
OnionrCommunicatorTimers(self, self.uploadBlock, 10, requiresPeer=True, maxThreads=1)
netCheckTimer = OnionrCommunicatorTimers(self, self.daemonTools.netCheck, 600) netCheckTimer = OnionrCommunicatorTimers(self, self.daemonTools.netCheck, 600)
announceTimer = OnionrCommunicatorTimers(self, self.daemonTools.announceNode, 305, requiresPeer=True, maxThreads=1) announceTimer = OnionrCommunicatorTimers(self, self.daemonTools.announceNode, 305, requiresPeer=True, maxThreads=1)
cleanupTimer = OnionrCommunicatorTimers(self, self.peerCleanup, 300, requiresPeer=True) cleanupTimer = OnionrCommunicatorTimers(self, self.peerCleanup, 300, requiresPeer=True)
@ -170,7 +169,7 @@ class OnionrCommunicatorDaemon:
else: else:
continue continue
newDBHash = self.peerAction(peer, 'getDBHash') # get their db hash newDBHash = self.peerAction(peer, 'getDBHash') # get their db hash
if newDBHash == False: if newDBHash == False or not self._core._utils.validateHash(newDBHash):
continue # if request failed, restart loop (peer is added to offline peers automatically) continue # if request failed, restart loop (peer is added to offline peers automatically)
triedPeers.append(peer) triedPeers.append(peer)
if newDBHash != self._core.getAddressInfo(peer, 'DBHash'): if newDBHash != self._core.getAddressInfo(peer, 'DBHash'):
@ -409,7 +408,7 @@ class OnionrCommunicatorDaemon:
'''Perform a get request to a peer''' '''Perform a get request to a peer'''
if len(peer) == 0: if len(peer) == 0:
return False return False
logger.info('Performing ' + action + ' with ' + peer + ' on port ' + str(self.proxyPort)) #logger.debug('Performing ' + action + ' with ' + peer + ' on port ' + str(self.proxyPort))
url = 'http://' + peer + '/public/?action=' + action url = 'http://' + peer + '/public/?action=' + action
if len(data) > 0: if len(data) > 0:
url += '&data=' + data url += '&data=' + data
@ -475,8 +474,7 @@ class OnionrCommunicatorDaemon:
if i.timerFunction.__name__ == 'lookupAdders': if i.timerFunction.__name__ == 'lookupAdders':
i.count = (i.frequency - 1) i.count = (i.frequency - 1)
elif cmd[0] == 'uploadBlock': elif cmd[0] == 'uploadBlock':
self.blockToUpload = cmd[1] self.blocksToUpload.append(cmd[1])
threading.Thread(target=self.uploadBlock).start()
elif cmd[0] == 'startSocket': elif cmd[0] == 'startSocket':
# Create our own socket server # Create our own socket server
socketInfo = json.loads(cmd[1]) socketInfo = json.loads(cmd[1])
@ -497,8 +495,12 @@ class OnionrCommunicatorDaemon:
'''Upload our block to a few peers''' '''Upload our block to a few peers'''
# when inserting a block, we try to upload it to a few peers to add some deniability # when inserting a block, we try to upload it to a few peers to add some deniability
triedPeers = [] triedPeers = []
if not self._core._utils.validateHash(self.blockToUpload): finishedUploads = []
if len(self.blocksToUpload) != 0:
for bl in self.blocksToUpload:
if not self._core._utils.validateHash(bl):
logger.warn('Requested to upload invalid block') logger.warn('Requested to upload invalid block')
self.decrementThreadCount('uploadBlock')
return return
for i in range(max(len(self.onlinePeers), 2)): for i in range(max(len(self.onlinePeers), 2)):
peer = self.pickOnlinePeer() peer = self.pickOnlinePeer()
@ -506,14 +508,23 @@ class OnionrCommunicatorDaemon:
continue continue
triedPeers.append(peer) triedPeers.append(peer)
url = 'http://' + peer + '/public/upload/' url = 'http://' + peer + '/public/upload/'
data = {'block': block.Block(self.blockToUpload).getRaw()} data = {'block': block.Block(bl).getRaw()}
proxyType = '' proxyType = ''
if peer.endswith('.onion'): if peer.endswith('.onion'):
proxyType = 'tor' proxyType = 'tor'
elif peer.endswith('.i2p'): elif peer.endswith('.i2p'):
proxyType = 'i2p' proxyType = 'i2p'
logger.info("Uploading block") logger.info("Uploading block to " + peer)
self._core._utils.doPostRequest(url, data=data, proxyType=proxyType) if not self._core._utils.doPostRequest(url, data=data, proxyType=proxyType) == False:
self._core._utils.localCommand('waitForShare', data=bl)
finishedUploads.append(bl)
break
for x in finishedUploads:
try:
self.blocksToUpload.remove(x)
except ValueError:
pass
self.decrementThreadCount('uploadBlock')
def announce(self, peer): def announce(self, peer):
'''Announce to peers our address''' '''Announce to peers our address'''

View File

@ -592,7 +592,6 @@ class Core:
''' '''
conn = sqlite3.connect(self.blockDB, timeout=10) conn = sqlite3.connect(self.blockDB, timeout=10)
c = conn.cursor() c = conn.cursor()
execute = 'SELECT dateReceived FROM hashes WHERE hash=?;' execute = 'SELECT dateReceived FROM hashes WHERE hash=?;'
@ -609,7 +608,6 @@ class Core:
''' '''
conn = sqlite3.connect(self.blockDB, timeout=10) conn = sqlite3.connect(self.blockDB, timeout=10)
c = conn.cursor() c = conn.cursor()
if orderDate: if orderDate:
@ -623,6 +621,7 @@ class Core:
for row in c.execute(execute, args): for row in c.execute(execute, args):
for i in row: for i in row:
rows.append(i) rows.append(i)
return rows return rows
def getExpiredBlocks(self): def getExpiredBlocks(self):
@ -631,10 +630,10 @@ class Core:
c = conn.cursor() c = conn.cursor()
date = int(self._utils.getEpoch()) date = int(self._utils.getEpoch())
execute = 'SELECT hash FROM hashes WHERE expire <= ? ORDER BY dateReceived;' execute = 'SELECT hash FROM hashes WHERE expire <= %s ORDER BY dateReceived;' % (date,)
rows = list() rows = list()
for row in c.execute(execute, (date,)): for row in c.execute(execute):
for i in row: for i in row:
rows.append(i) rows.append(i)
return rows return rows
@ -680,8 +679,7 @@ class Core:
return True return True
def insertBlock(self, data, header='txt', sign=False, encryptType='', symKey='', asymPeer='', meta = None, expire=None):
def insertBlock(self, data, header='txt', sign=False, encryptType='', symKey='', asymPeer='', meta = dict(), expire=None):
''' '''
Inserts a block into the network Inserts a block into the network
encryptType must be specified to encrypt a block encryptType must be specified to encrypt a block
@ -784,6 +782,8 @@ class Core:
payload = proof.waitForResult() payload = proof.waitForResult()
if payload != False: if payload != False:
retData = self.setData(payload) retData = self.setData(payload)
# 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', data=retData)
self.addToBlockDB(retData, selfInsert=True, dataSaved=True) self.addToBlockDB(retData, selfInsert=True, dataSaved=True)
#self.setBlockType(retData, meta['type']) #self.setBlockType(retData, meta['type'])
self._utils.processBlockMetadata(retData) self._utils.processBlockMetadata(retData)

View File

@ -40,7 +40,7 @@ except ImportError:
raise Exception("You need the PySocks module (for use with socks5 proxy to use Tor)") raise Exception("You need the PySocks module (for use with socks5 proxy to use Tor)")
ONIONR_TAGLINE = 'Anonymous P2P Platform - GPLv3 - https://Onionr.VoidNet.Tech' ONIONR_TAGLINE = 'Anonymous P2P Platform - GPLv3 - https://Onionr.VoidNet.Tech'
ONIONR_VERSION = '0.3.0' # for debugging and stuff ONIONR_VERSION = '0.3.2' # for debugging and stuff
ONIONR_VERSION_TUPLE = tuple(ONIONR_VERSION.split('.')) # (MAJOR, MINOR, VERSION) ONIONR_VERSION_TUPLE = tuple(ONIONR_VERSION.split('.')) # (MAJOR, MINOR, VERSION)
API_VERSION = '5' # increments of 1; only change when something fundemental about how the API works changes. This way other nodes know how to communicate without learning too much information about you. API_VERSION = '5' # increments of 1; only change when something fundemental about how the API works changes. This way other nodes know how to communicate without learning too much information about you.
@ -64,7 +64,6 @@ class Onionr:
self.dataDir = 'data/' self.dataDir = 'data/'
# Load global configuration data # Load global configuration data
data_exists = Onionr.setupConfig(self.dataDir, self = self) data_exists = Onionr.setupConfig(self.dataDir, self = self)
self.onionrCore = core.Core() self.onionrCore = core.Core()
@ -169,6 +168,7 @@ class Onionr:
'add-file': self.addFile, 'add-file': self.addFile,
'addfile': self.addFile, 'addfile': self.addFile,
'get-file': self.getFile, 'get-file': self.getFile,
'getfile': self.getFile, 'getfile': self.getFile,
@ -186,6 +186,17 @@ class Onionr:
'gui' : self.openUI, 'gui' : self.openUI,
'chat': self.startChat, 'chat': self.startChat,
'getpassword': self.printWebPassword,
'get-password': self.printWebPassword,
'getpwd': self.printWebPassword,
'get-pwd': self.printWebPassword,
'getpass': self.printWebPassword,
'get-pass': self.printWebPassword,
'getpasswd': self.printWebPassword,
'get-passwd': self.printWebPassword,
'chat': self.startChat,
'friend': self.friendCmd 'friend': self.friendCmd
} }
@ -246,7 +257,6 @@ class Onionr:
for detail in details: for detail in details:
logger.info('%s%s: \n%s%s\n' % (logger.colors.fg.lightgreen, detail, logger.colors.fg.green, details[detail]), sensitive = True) logger.info('%s%s: \n%s%s\n' % (logger.colors.fg.lightgreen, detail, logger.colors.fg.green, details[detail]), sensitive = True)
def startChat(self): def startChat(self):
try: try:
data = json.dumps({'peer': sys.argv[2], 'reason': 'chat'}) data = json.dumps({'peer': sys.argv[2], 'reason': 'chat'})
@ -300,6 +310,48 @@ class Onionr:
logger.info('Syntax: friend add/remove/list [address]') logger.info('Syntax: friend add/remove/list [address]')
def friendCmd(self):
'''List, add, or remove friend(s)
Changes their peer DB entry.
'''
friend = ''
try:
# Get the friend command
action = sys.argv[2]
except IndexError:
logger.info('Syntax: friend add/remove/list [address]')
else:
action = action.lower()
if action == 'list':
# List out peers marked as our friend
for friend in self.onionrCore.listPeers(randomOrder=False, trust=1):
if friend == self.onionrCore._crypto.pubKey: # do not list our key
continue
friendProfile = onionrusers.OnionrUser(self.onionrCore, friend)
logger.info(friend + ' - ' + friendProfile.getName())
elif action in ('add', 'remove'):
try:
friend = sys.argv[3]
if not self.onionrUtils.validatePubKey(friend):
raise onionrexceptions.InvalidPubkey('Public key is invalid')
if friend not in self.onionrCore.listPeers():
raise onionrexceptions.KeyNotKnown
friend = onionrusers.OnionrUser(self.onionrCore, friend)
except IndexError:
logger.error('Friend ID is required.')
except onionrexceptions.KeyNotKnown:
logger.error('That peer is not in our database')
else:
if action == 'add':
friend.setTrust(1)
logger.info('Added %s as friend.' % (friend.publicKey,))
else:
friend.setTrust(0)
logger.info('Removed %s as friend.' % (friend.publicKey,))
else:
logger.info('Syntax: friend add/remove/list [address]')
def banBlock(self): def banBlock(self):
try: try:
ban = sys.argv[2] ban = sys.argv[2]
@ -633,6 +685,7 @@ class Onionr:
logger.debug('Started .onion service: %s' % (logger.colors.underline + net.myID)) logger.debug('Started .onion service: %s' % (logger.colors.underline + net.myID))
logger.debug('Using public key: %s' % (logger.colors.underline + self.onionrCore._crypto.pubKey)) logger.debug('Using public key: %s' % (logger.colors.underline + self.onionrCore._crypto.pubKey))
time.sleep(1) time.sleep(1)
# TODO: make runable on windows # TODO: make runable on windows
communicatorProc = subprocess.Popen([communicatorDaemon, 'run', str(net.socksPort)]) communicatorProc = subprocess.Popen([communicatorDaemon, 'run', str(net.socksPort)])
@ -798,6 +851,7 @@ class Onionr:
logger.error("Syntax %s %s" % (sys.argv[0], '/path/to/filename <blockhash>')) logger.error("Syntax %s %s" % (sys.argv[0], '/path/to/filename <blockhash>'))
else: else:
logger.info(fileName) logger.info(fileName)
contents = None contents = None
if os.path.exists(fileName): if os.path.exists(fileName):
logger.error("File already exists") logger.error("File already exists")
@ -805,6 +859,7 @@ class Onionr:
if not self.onionrUtils.validateHash(bHash): if not self.onionrUtils.validateHash(bHash):
logger.error('Block hash is invalid') logger.error('Block hash is invalid')
return return
Block.mergeChain(bHash, fileName) Block.mergeChain(bHash, fileName)
return return

View File

@ -30,13 +30,16 @@ class OnionrBlackList:
def inBlacklist(self, data): def inBlacklist(self, data):
hashed = self._core._utils.bytesToStr(self._core._crypto.sha3Hash(data)) hashed = self._core._utils.bytesToStr(self._core._crypto.sha3Hash(data))
retData = False retData = False
if not hashed.isalnum(): if not hashed.isalnum():
raise Exception("Hashed data is not alpha numeric") raise Exception("Hashed data is not alpha numeric")
if len(hashed) > 64: if len(hashed) > 64:
raise Exception("Hashed data is too large") raise Exception("Hashed data is too large")
for i in self._dbExecute("SELECT * FROM blacklist WHERE hash = ?", (hashed,)): for i in self._dbExecute("SELECT * FROM blacklist WHERE hash = ?", (hashed,)):
retData = True # this only executes if an entry is present by that hash retData = True # this only executes if an entry is present by that hash
break break
return retData return retData
def _dbExecute(self, toExec, params = ()): def _dbExecute(self, toExec, params = ()):

View File

@ -243,9 +243,9 @@ class Block:
if (not self.getBlockFile() is None) and (recreate is True): if (not self.getBlockFile() is None) and (recreate is True):
with open(self.getBlockFile(), 'wb') as blockFile: with open(self.getBlockFile(), 'wb') as blockFile:
blockFile.write(self.getRaw().encode()) blockFile.write(self.getRaw().encode())
self.update()
else: else:
self.hash = self.getCore().insertBlock(self.getContent(), header = self.getType(), sign = sign, meta = self.getMetadata(), expire = self.getExpire()) self.hash = self.getCore().insertBlock(self.getContent(), header = self.getType(), sign = sign, meta = self.getMetadata(), expire = self.getExpire())
self.update() self.update()
return self.getHash() return self.getHash()

View File

@ -46,4 +46,5 @@ class OnionrChat:
self.communicator.socketClient.sendData(peer, "lol") self.communicator.socketClient.sendData(peer, "lol")
except: except:
pass pass
time.sleep(2) time.sleep(2)

View File

@ -17,6 +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 onionrexceptions, onionrpeers, onionrproofs, logger, onionrusers import onionrexceptions, onionrpeers, onionrproofs, logger, onionrusers
import base64, sqlite3, os import base64, sqlite3, os
from dependencies import secrets from dependencies import secrets
@ -89,6 +90,7 @@ class DaemonTools:
c = conn.cursor() c = conn.cursor()
time = self.daemon._core._utils.getEpoch() time = self.daemon._core._utils.getEpoch()
deleteKeys = [] deleteKeys = []
for entry in c.execute("SELECT * FROM forwardKeys WHERE expire <= ?", (time,)): for entry in c.execute("SELECT * FROM forwardKeys WHERE expire <= ?", (time,)):
logger.info(entry[1]) logger.info(entry[1])
deleteKeys.append(entry[1]) deleteKeys.append(entry[1])
@ -120,6 +122,7 @@ class DaemonTools:
# Cool down a peer, if we have max connections alive for long enough # Cool down a peer, if we have max connections alive for long enough
if onlinePeerAmount >= self.daemon._core.config.get('peers.max_connect', 10): if onlinePeerAmount >= self.daemon._core.config.get('peers.max_connect', 10):
finding = True finding = True
while finding: while finding:
try: try:
toCool = min(tempConnectTimes, key=tempConnectTimes.get) toCool = min(tempConnectTimes, key=tempConnectTimes.get)
@ -132,6 +135,7 @@ class DaemonTools:
else: else:
self.daemon.removeOnlinePeer(toCool) self.daemon.removeOnlinePeer(toCool)
self.daemon.cooldownPeer[toCool] = self.daemon._core._utils.getEpoch() self.daemon.cooldownPeer[toCool] = self.daemon._core._utils.getEpoch()
self.daemon.decrementThreadCount('cooldownPeer') self.daemon.decrementThreadCount('cooldownPeer')
def runCheck(self): def runCheck(self):

View File

@ -87,6 +87,7 @@ class OnionrSocketServer:
def detectShutdown(self): def detectShutdown(self):
while not self._core.killSockets: while not self._core.killSockets:
time.sleep(5) time.sleep(5)
logger.debug('Killing socket server...') logger.debug('Killing socket server...')
self.http_server.stop() self.http_server.stop()

View File

@ -107,12 +107,14 @@ class OnionrUser:
conn.commit() conn.commit()
conn.close() conn.close()
return key return key
def _getForwardKeys(self): def _getForwardKeys(self):
conn = sqlite3.connect(self._core.peerDB, timeout=10) conn = sqlite3.connect(self._core.peerDB, timeout=10)
c = conn.cursor() c = conn.cursor()
keyList = [] keyList = []
for row in c.execute("SELECT forwardKey FROM forwardKeys WHERE peerKey = ? ORDER BY date DESC", (self.publicKey,)): for row in c.execute("SELECT forwardKey FROM forwardKeys WHERE peerKey = ? ORDER BY date DESC", (self.publicKey,)):
key = row[0] key = row[0]
keyList.append(key) keyList.append(key)
@ -150,8 +152,10 @@ class OnionrUser:
pubkey = self._core._utils.bytesToStr(pubkey) pubkey = self._core._utils.bytesToStr(pubkey)
command = (pubkey,) command = (pubkey,)
keyList = [] # list of tuples containing pub, private for peer keyList = [] # list of tuples containing pub, private for peer
for result in c.execute("SELECT * FROM myForwardKeys WHERE peer = ?", command): for result in c.execute("SELECT * FROM myForwardKeys WHERE peer = ?", command):
keyList.append((result[1], result[2])) keyList.append((result[1], result[2]))
if len(keyList) == 0: if len(keyList) == 0:
if genNew: if genNew:
self.generateForwardKey() self.generateForwardKey()

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/>.
''' '''
# Misc functions that do not fit in the main api, but are useful # Misc functions that do not fit in the main api, but are useful
import getpass, sys, requests, os, socket, hashlib, logger, sqlite3, config, binascii, time, base64, json, glob, shutil, math, json, re import getpass, sys, requests, os, socket, hashlib, logger, sqlite3, config, binascii, time, base64, json, glob, shutil, math, json, re, urllib.parse
import nacl.signing, nacl.encoding import nacl.signing, nacl.encoding
from onionrblockapi import Block from onionrblockapi import Block
import onionrexceptions import onionrexceptions
@ -150,7 +150,7 @@ class OnionrUtils:
logger.error('Failed to read my address.', error = error) logger.error('Failed to read my address.', error = error)
return None return None
def localCommand(self, command, silent = True): def localCommand(self, command, data='', silent = True):
''' '''
Send a command to the local http API server, securely. Intended for local clients, DO NOT USE for remote peers. Send a command to the local http API server, securely. Intended for local clients, DO NOT USE for remote peers.
''' '''
@ -164,6 +164,8 @@ class OnionrUtils:
except FileNotFoundError: except FileNotFoundError:
return False return False
payload = 'http://%s:%s/client/?action=%s&token=%s&timingToken=%s' % (hostname, config.get('client.port'), command, config.get('client.hmac'), self.timingToken) payload = 'http://%s:%s/client/?action=%s&token=%s&timingToken=%s' % (hostname, config.get('client.port'), command, config.get('client.hmac'), self.timingToken)
if data != '':
payload += '&data=' + urllib.parse.quote_plus(data)
try: try:
retData = requests.get(payload).text retData = requests.get(payload).text
except Exception as error: except Exception as error:
@ -495,6 +497,12 @@ class OnionrUtils:
except binascii.Error: except binascii.Error:
retVal = False retVal = False
# Validate address is valid base32 (when capitalized and minus extension); v2/v3 onions and .b32.i2p use base32
try:
base64.b32decode(idNoDomain.upper().encode())
except binascii.Error:
retVal = False
return retVal return retVal
except: except:
return False return False

View File

@ -52,7 +52,7 @@ class OnionrCLIUI:
while showMenu: while showMenu:
if firstRun: if firstRun:
logger.info('Please wait while Onionr starts...'') logger.info('Please wait while Onionr starts...')
daemon = subprocess.Popen(["./onionr.py", "start"], stdin=subprocess.PIPE, stdout=subprocess.DEVNULL) daemon = subprocess.Popen(["./onionr.py", "start"], stdin=subprocess.PIPE, stdout=subprocess.DEVNULL)
time.sleep(30) time.sleep(30)
firstRun = False firstRun = False
@ -63,7 +63,6 @@ class OnionrCLIUI:
isOnline = "No" isOnline = "No"
logger.info('''Daemon Running: ''' + isOnline + ''' logger.info('''Daemon Running: ''' + isOnline + '''
1. Flow (Anonymous public chat, use at your own risk) 1. Flow (Anonymous public chat, use at your own risk)
2. Mail (Secure email-like service) 2. Mail (Secure email-like service)
3. File Sharing 3. File Sharing
@ -91,6 +90,7 @@ class OnionrCLIUI:
if isOnline == "Yes": if isOnline == "Yes":
logger.info("Onionr daemon will shutdown...") logger.info("Onionr daemon will shutdown...")
self.myCore.daemonQueueAdd('shutdown') self.myCore.daemonQueueAdd('shutdown')
try: try:
daemon.kill() daemon.kill()
except UnboundLocalError: except UnboundLocalError:

View File

@ -72,6 +72,7 @@ class PlainEncryption:
encrypted = self.api.get_core()._crypto.pubKeyEncrypt(plaintext, pubkey, anonymous=True, encodedData=True) encrypted = self.api.get_core()._crypto.pubKeyEncrypt(plaintext, pubkey, anonymous=True, encodedData=True)
encrypted = self.api.get_core()._utils.bytesToStr(encrypted) encrypted = self.api.get_core()._utils.bytesToStr(encrypted)
logger.info('Encrypted Message: \n\nONIONR ENCRYPTED DATA %s END ENCRYPTED DATA' % (encrypted,)) logger.info('Encrypted Message: \n\nONIONR ENCRYPTED DATA %s END ENCRYPTED DATA' % (encrypted,))
def decrypt(self): def decrypt(self):
plaintext = "" plaintext = ""
data = "" data = ""
@ -102,7 +103,6 @@ class PlainEncryption:
logger.info("Message has good signature.") logger.info("Message has good signature.")
return return
def on_init(api, data = None): def on_init(api, data = None):
''' '''
This event is called after Onionr is initialized, but before the command This event is called after Onionr is initialized, but before the command
@ -114,4 +114,5 @@ def on_init(api, data = None):
encrypt = PlainEncryption(pluginapi) encrypt = PlainEncryption(pluginapi)
api.commands.register(['encrypt'], encrypt.encrypt) api.commands.register(['encrypt'], encrypt.encrypt)
api.commands.register(['decrypt'], encrypt.decrypt) api.commands.register(['decrypt'], encrypt.decrypt)
return return

View File

@ -129,8 +129,10 @@ class OnionrMail:
else: else:
cancel = '' cancel = ''
readBlock.verifySig() readBlock.verifySig()
logger.info('Message recieved from %s' % (self.myCore._utils.bytesToStr(readBlock.signer,))) logger.info('Message recieved from %s' % (self.myCore._utils.bytesToStr(readBlock.signer,)))
logger.info('Valid signature: %s' % readBlock.validSig) logger.info('Valid signature: %s' % readBlock.validSig)
if not readBlock.validSig: if not readBlock.validSig:
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).')
@ -172,6 +174,7 @@ class OnionrMail:
for i in self.sentboxTools.listSent(): for i in self.sentboxTools.listSent():
self.sentboxList.append(i['hash']) self.sentboxList.append(i['hash'])
self.sentMessages[i['hash']] = (i['message'], i['peer']) self.sentMessages[i['hash']] = (i['message'], i['peer'])
logger.info('%s. %s - %s - %s' % (count, i['hash'], i['peer'][:12], i['date'])) logger.info('%s. %s - %s - %s' % (count, i['hash'], i['peer'][:12], i['date']))
count += 1 count += 1

View File

@ -2,6 +2,8 @@
"general" : { "general" : {
"dev_mode" : true, "dev_mode" : true,
"display_header" : true, "display_header" : true,
"minimum_block_pow": 5,
"minimum_send_pow": 5,
"minimum_block_pow": 5, "minimum_block_pow": 5,
"minimum_send_pow": 5, "minimum_send_pow": 5,