diff --git a/onionr/communicator.py b/onionr/communicator.py
index e958d387..e9eeb28f 100755
--- a/onionr/communicator.py
+++ b/onionr/communicator.py
@@ -22,10 +22,12 @@
import sys, os, time
import core, config, logger, onionr
import onionrexceptions, onionrpeers, onionrevents as events, onionrplugins as plugins, onionrblockapi as block
-from communicatorutils import onionrdaemontools, servicecreator, onionrcommunicatortimers
+from communicatorutils import servicecreator, onionrcommunicatortimers
from communicatorutils import downloadblocks, lookupblocks, lookupadders
from communicatorutils import servicecreator, connectnewpeers, uploadblocks
-from communicatorutils import daemonqueuehandler, announcenode
+from communicatorutils import daemonqueuehandler, announcenode, deniableinserts
+from communicatorutils import cooldownpeer, housekeeping, netcheck
+from etc import humanreadabletime
import onionrservices, onionr, onionrproofs
OnionrCommunicatorTimers = onionrcommunicatortimers.OnionrCommunicatorTimers
@@ -88,10 +90,6 @@ class OnionrCommunicatorDaemon:
# Loads in and starts the enabled plugins
plugins.reload()
- # daemon tools are misc daemon functions, e.g. announce to online peers
- # intended only for use by OnionrCommunicatorDaemon
- self.daemonTools = onionrdaemontools.DaemonTools(self)
-
# time app started running for info/statistics purposes
self.startTime = self._core._utils.getEpoch()
@@ -111,13 +109,13 @@ class OnionrCommunicatorDaemon:
OnionrCommunicatorTimers(self, self.clearOfflinePeer, 58)
# Timer to cleanup old blocks
- blockCleanupTimer = OnionrCommunicatorTimers(self, self.daemonTools.cleanOldBlocks, 65)
+ blockCleanupTimer = OnionrCommunicatorTimers(self, housekeeping.clean_old_blocks, 65, myArgs=[self])
# Timer to discover new peers
OnionrCommunicatorTimers(self, self.lookupAdders, 60, requiresPeer=True)
# Timer for adjusting which peers we actively communicate to at any given time, to avoid over-using peers
- OnionrCommunicatorTimers(self, self.daemonTools.cooldownPeer, 30, requiresPeer=True)
+ OnionrCommunicatorTimers(self, cooldownpeer.cooldown_peer, 30, myArgs=[self], requiresPeer=True)
# Timer to read the upload queue and upload the entries to peers
OnionrCommunicatorTimers(self, self.uploadBlock, 10, requiresPeer=True, maxThreads=1)
@@ -133,17 +131,17 @@ class OnionrCommunicatorDaemon:
self.services = onionrservices.OnionrServices(self._core)
self.active_services = []
self.service_greenlets = []
- OnionrCommunicatorTimers(self, servicecreator.service_creator, 5, maxThreads=50, myArgs=(self,))
+ OnionrCommunicatorTimers(self, servicecreator.service_creator, 5, maxThreads=50, myArgs=[self])
else:
self.services = None
# This timer creates deniable blocks, in an attempt to further obfuscate block insertion metadata
if config.get('general.insert_deniable_blocks', True):
- deniableBlockTimer = OnionrCommunicatorTimers(self, self.daemonTools.insertDeniableBlock, 180, requiresPeer=True, maxThreads=1)
+ deniableBlockTimer = OnionrCommunicatorTimers(self, deniableinserts.insert_deniable_block, 180, myArgs=[self], requiresPeer=True, maxThreads=1)
deniableBlockTimer.count = (deniableBlockTimer.frequency - 175)
# Timer to check for connectivity, through Tor to various high-profile onion services
- netCheckTimer = OnionrCommunicatorTimers(self, self.daemonTools.netCheck, 600)
+ netCheckTimer = OnionrCommunicatorTimers(self, netcheck.net_check, 600, myArgs=[self])
# Announce the public API server transport address to other nodes if security level allows
if config.get('general.security_level', 1) == 0:
@@ -157,7 +155,7 @@ class OnionrCommunicatorDaemon:
cleanupTimer = OnionrCommunicatorTimers(self, self.peerCleanup, 300, requiresPeer=True)
# Timer to cleanup dead ephemeral forward secrecy keys
- forwardSecrecyTimer = OnionrCommunicatorTimers(self, self.daemonTools.cleanKeys, 15, maxThreads=1)
+ forwardSecrecyTimer = OnionrCommunicatorTimers(self, housekeeping.clean_keys, 15, myArgs=[self], maxThreads=1)
# Adjust initial timer triggers
peerPoolTimer.count = (peerPoolTimer.frequency - 1)
@@ -255,7 +253,7 @@ class OnionrCommunicatorDaemon:
break
else:
if len(self.onlinePeers) == 0:
- logger.debug('Couldn\'t connect to any peers.' + (' Last node seen %s ago.' % self.daemonTools.humanReadableTime(time.time() - self.lastNodeSeen) if not self.lastNodeSeen is None else ''))
+ logger.debug('Couldn\'t connect to any peers.' + (' Last node seen %s ago.' % humanreadabletime.human_readable_time(time.time() - self.lastNodeSeen) if not self.lastNodeSeen is None else ''))
else:
self.lastNodeSeen = time.time()
self.decrementThreadCount('getOnlinePeers')
@@ -346,7 +344,7 @@ class OnionrCommunicatorDaemon:
def heartbeat(self):
'''Show a heartbeat debug message'''
- logger.debug('Heartbeat. Node running for %s.' % self.daemonTools.humanReadableTime(self.getUptime()))
+ logger.debug('Heartbeat. Node running for %s.' % humanreadabletime.human_readable_time(self.getUptime()))
self.decrementThreadCount('heartbeat')
def daemonCommands(self):
@@ -379,10 +377,17 @@ class OnionrCommunicatorDaemon:
self.decrementThreadCount('detectAPICrash')
def runCheck(self):
- if self.daemonTools.runCheck():
+ if run_file_exists(self):
logger.debug('Status check; looks good.')
self.decrementThreadCount('runCheck')
def startCommunicator(onionrInst, proxyPort):
- OnionrCommunicatorDaemon(onionrInst, proxyPort)
\ No newline at end of file
+ OnionrCommunicatorDaemon(onionrInst, proxyPort)
+
+def run_file_exists(daemon):
+ if os.path.isfile(daemon._core.dataDir + '.runcheck'):
+ os.remove(daemon._core.dataDir + '.runcheck')
+ return True
+
+ return False
\ No newline at end of file
diff --git a/onionr/communicatorutils/README.md b/onionr/communicatorutils/README.md
index 5f37a122..393328c3 100644
--- a/onionr/communicatorutils/README.md
+++ b/onionr/communicatorutils/README.md
@@ -8,15 +8,23 @@ announcenode.py: Uses a communicator instance to announce our transport address
connectnewpeers.py: takes a communicator instance and has it connect to as many peers as needed, and/or to a new specified peer.
+cooldownpeer.py: randomly selects a connected peer in a communicator and disconnects them for the purpose of security and network balancing.
+
daemonqueuehandler.py: checks for new commands in the daemon queue and processes them accordingly.
+deniableinserts.py: insert fake blocks with the communicator for plausible deniability
+
downloadblocks.py: iterates a communicator instance's block download queue and attempts to download the blocks from online peers
+housekeeping.py: cleans old blocks and forward secrecy keys
+
lookupadders.py: ask connected peers to share their list of peer transport addresses
-onionrcommunicataortimers.py: create a timer for a function to be launched on an interval. Control how many possible instances of a timer may be running a function at once and control if the timer should be ran in a thread or not.
+lookupblocks.py: lookup new blocks from connected peers from the communicator
-onionrdaemontools.py: contains the DaemonTools class which has a lot of etc functions useful for the communicator. Deprecated.
+netcheck.py: check if the node is online based on communicator status and onion server ping results
+
+onionrcommunicataortimers.py: create a timer for a function to be launched on an interval. Control how many possible instances of a timer may be running a function at once and control if the timer should be ran in a thread or not.
proxypicker.py: returns a string name for the appropriate proxy to be used with a particular peer transport address.
diff --git a/onionr/communicatorutils/announcenode.py b/onionr/communicatorutils/announcenode.py
index 6ba136ba..e3f7d268 100644
--- a/onionr/communicatorutils/announcenode.py
+++ b/onionr/communicatorutils/announcenode.py
@@ -80,5 +80,5 @@ def announce_node(daemon):
retData = True
daemon._core.setAddressInfo(peer, 'introduced', 1)
daemon._core.setAddressInfo(peer, 'powValue', data['random'])
- daemon.decrementThreadCount('announceNode')
+ daemon.decrementThreadCount('announce_node')
return retData
\ No newline at end of file
diff --git a/onionr/communicatorutils/cooldownpeer.py b/onionr/communicatorutils/cooldownpeer.py
new file mode 100644
index 00000000..26cf2dd9
--- /dev/null
+++ b/onionr/communicatorutils/cooldownpeer.py
@@ -0,0 +1,51 @@
+'''
+ Onionr - Private P2P Communication
+
+ Select a random online peer in a communicator instance and have them "cool down"
+'''
+'''
+ 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 .
+'''
+def cooldown_peer(comm_inst):
+ '''Randomly add an online peer to cooldown, so we can connect a new one'''
+ onlinePeerAmount = len(comm_inst.onlinePeers)
+ minTime = 300
+ cooldownTime = 600
+ toCool = ''
+ tempConnectTimes = dict(comm_inst.connectTimes)
+
+ # Remove peers from cooldown that have been there long enough
+ tempCooldown = dict(comm_inst.cooldownPeer)
+ for peer in tempCooldown:
+ if (comm_inst._core._utils.getEpoch() - tempCooldown[peer]) >= cooldownTime:
+ del comm_inst.cooldownPeer[peer]
+
+ # Cool down a peer, if we have max connections alive for long enough
+ if onlinePeerAmount >= comm_inst._core.config.get('peers.max_connect', 10, save = True):
+ finding = True
+
+ while finding:
+ try:
+ toCool = min(tempConnectTimes, key=tempConnectTimes.get)
+ if (comm_inst._core._utils.getEpoch() - tempConnectTimes[toCool]) < minTime:
+ del tempConnectTimes[toCool]
+ else:
+ finding = False
+ except ValueError:
+ break
+ else:
+ comm_inst.removeOnlinePeer(toCool)
+ comm_inst.cooldownPeer[toCool] = comm_inst._core._utils.getEpoch()
+
+ comm_inst.decrementThreadCount('cooldown_peer')
\ No newline at end of file
diff --git a/onionr/communicatorutils/deniableinserts.py b/onionr/communicatorutils/deniableinserts.py
new file mode 100644
index 00000000..f993e6d0
--- /dev/null
+++ b/onionr/communicatorutils/deniableinserts.py
@@ -0,0 +1,31 @@
+'''
+ Onionr - Private P2P Communication
+
+ Use the communicator to insert fake mail messages
+'''
+'''
+ 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 .
+'''
+import secrets
+from etc import onionrvalues
+def insert_deniable_block(comm_inst):
+ '''Insert a fake block in order to make it more difficult to track real blocks'''
+ fakePeer = ''
+ chance = 10
+ if secrets.randbelow(chance) == (chance - 1):
+ # This assumes on the libsodium primitives to have key-privacy
+ fakePeer = onionrvalues.DENIABLE_PEER_ADDRESS
+ data = secrets.token_hex(secrets.randbelow(1024) + 1)
+ comm_inst._core.insertBlock(data, header='pm', encryptType='asym', asymPeer=fakePeer, meta={'subject': 'foo'})
+ comm_inst.decrementThreadCount('insert_deniable_block')
\ No newline at end of file
diff --git a/onionr/communicatorutils/housekeeping.py b/onionr/communicatorutils/housekeeping.py
new file mode 100644
index 00000000..829564ab
--- /dev/null
+++ b/onionr/communicatorutils/housekeeping.py
@@ -0,0 +1,59 @@
+'''
+ Onionr - Private P2P Communication
+
+ Cleanup old Onionr blocks and forward secrecy keys using the communicator. Ran from a timer usually
+'''
+'''
+ 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 .
+'''
+import sqlite3
+import logger
+from onionrusers import onionrusers
+def clean_old_blocks(comm_inst):
+ '''Delete old blocks if our disk allocation is full/near full, and also expired blocks'''
+
+ # Delete expired blocks
+ for bHash in comm_inst._core.getExpiredBlocks():
+ comm_inst._core._blacklist.addToDB(bHash)
+ comm_inst._core.removeBlock(bHash)
+ logger.info('Deleted block: %s' % (bHash,))
+
+ while comm_inst._core._utils.storageCounter.isFull():
+ oldest = comm_inst._core.getBlockList()[0]
+ comm_inst._core._blacklist.addToDB(oldest)
+ comm_inst._core.removeBlock(oldest)
+ logger.info('Deleted block: %s' % (oldest,))
+
+ comm_inst.decrementThreadCount('clean_old_blocks')
+
+def clean_keys(comm_inst):
+ '''Delete expired forward secrecy keys'''
+ conn = sqlite3.connect(comm_inst._core.peerDB, timeout=10)
+ c = conn.cursor()
+ time = comm_inst._core._utils.getEpoch()
+ deleteKeys = []
+
+ for entry in c.execute("SELECT * FROM forwardKeys WHERE expire <= ?", (time,)):
+ logger.debug('Forward key: %s' % entry[1])
+ deleteKeys.append(entry[1])
+
+ for key in deleteKeys:
+ logger.debug('Deleting forward key %s' % key)
+ c.execute("DELETE from forwardKeys where forwardKey = ?", (key,))
+ conn.commit()
+ conn.close()
+
+ onionrusers.deleteExpiredKeys(comm_inst._core)
+
+ comm_inst.decrementThreadCount('clean_keys')
\ No newline at end of file
diff --git a/onionr/communicatorutils/netcheck.py b/onionr/communicatorutils/netcheck.py
new file mode 100644
index 00000000..36a3a304
--- /dev/null
+++ b/onionr/communicatorutils/netcheck.py
@@ -0,0 +1,32 @@
+'''
+ Onionr - Private P2P Communication
+
+ Determine if our node is able to use Tor based on the status of a communicator instance
+ and the result of pinging onion http servers
+'''
+'''
+ 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 .
+'''
+import logger
+from utils import netutils
+def net_check(comm_inst):
+ '''Check if we are connected to the internet or not when we can't connect to any peers'''
+ if len(comm_inst.onlinePeers) == 0:
+ if not netutils.checkNetwork(comm_inst._core._utils, torPort=comm_inst.proxyPort):
+ if not comm_inst.shutdown:
+ logger.warn('Network check failed, are you connected to the Internet, and is Tor working?')
+ comm_inst.isOnline = False
+ else:
+ comm_inst.isOnline = True
+ comm_inst.decrementThreadCount('net_check')
\ No newline at end of file
diff --git a/onionr/communicatorutils/onionrdaemontools.py b/onionr/communicatorutils/onionrdaemontools.py
deleted file mode 100755
index c0e74df3..00000000
--- a/onionr/communicatorutils/onionrdaemontools.py
+++ /dev/null
@@ -1,158 +0,0 @@
-'''
- Onionr - Private P2P Communication
-
- Contains the DaemonTools class
-'''
-'''
- 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 .
-'''
-
-# MODULE DEPRECATED
-
-import onionrexceptions, onionrpeers, onionrproofs, logger
-import base64, sqlite3, os
-from dependencies import secrets
-from utils import netutils
-from onionrusers import onionrusers
-from etc import onionrvalues
-ov = onionrvalues.OnionrValues()
-
-class DaemonTools:
- '''
- Class intended for use by Onionr Communicator
- '''
- def __init__(self, daemon):
- self.daemon = daemon
- self.announceProgress = {}
- self.announceCache = {}
-
- def netCheck(self):
- '''Check if we are connected to the internet or not when we can't connect to any peers'''
- if len(self.daemon.onlinePeers) == 0:
- if not netutils.checkNetwork(self.daemon._core._utils, torPort=self.daemon.proxyPort):
- if not self.daemon.shutdown:
- logger.warn('Network check failed, are you connected to the Internet, and is Tor working?')
- self.daemon.isOnline = False
- else:
- self.daemon.isOnline = True
- self.daemon.decrementThreadCount('netCheck')
-
- def cleanOldBlocks(self):
- '''Delete old blocks if our disk allocation is full/near full, and also expired blocks'''
-
- # Delete expired blocks
- for bHash in self.daemon._core.getExpiredBlocks():
- self.daemon._core._blacklist.addToDB(bHash)
- self.daemon._core.removeBlock(bHash)
- logger.info('Deleted block: %s' % (bHash,))
-
- while self.daemon._core._utils.storageCounter.isFull():
- oldest = self.daemon._core.getBlockList()[0]
- self.daemon._core._blacklist.addToDB(oldest)
- self.daemon._core.removeBlock(oldest)
- logger.info('Deleted block: %s' % (oldest,))
-
- self.daemon.decrementThreadCount('cleanOldBlocks')
-
- def cleanKeys(self):
- '''Delete expired forward secrecy keys'''
- conn = sqlite3.connect(self.daemon._core.peerDB, timeout=10)
- c = conn.cursor()
- time = self.daemon._core._utils.getEpoch()
- deleteKeys = []
-
- for entry in c.execute("SELECT * FROM forwardKeys WHERE expire <= ?", (time,)):
- logger.debug('Forward key: %s' % entry[1])
- deleteKeys.append(entry[1])
-
- for key in deleteKeys:
- logger.debug('Deleting forward key %s' % key)
- c.execute("DELETE from forwardKeys where forwardKey = ?", (key,))
- conn.commit()
- conn.close()
-
- onionrusers.deleteExpiredKeys(self.daemon._core)
-
- self.daemon.decrementThreadCount('cleanKeys')
-
- def cooldownPeer(self):
- '''Randomly add an online peer to cooldown, so we can connect a new one'''
- onlinePeerAmount = len(self.daemon.onlinePeers)
- minTime = 300
- cooldownTime = 600
- toCool = ''
- tempConnectTimes = dict(self.daemon.connectTimes)
-
- # Remove peers from cooldown that have been there long enough
- tempCooldown = dict(self.daemon.cooldownPeer)
- for peer in tempCooldown:
- if (self.daemon._core._utils.getEpoch() - tempCooldown[peer]) >= cooldownTime:
- del self.daemon.cooldownPeer[peer]
-
- # Cool down a peer, if we have max connections alive for long enough
- if onlinePeerAmount >= self.daemon._core.config.get('peers.max_connect', 10, save = True):
- finding = True
-
- while finding:
- try:
- toCool = min(tempConnectTimes, key=tempConnectTimes.get)
- if (self.daemon._core._utils.getEpoch() - tempConnectTimes[toCool]) < minTime:
- del tempConnectTimes[toCool]
- else:
- finding = False
- except ValueError:
- break
- else:
- self.daemon.removeOnlinePeer(toCool)
- self.daemon.cooldownPeer[toCool] = self.daemon._core._utils.getEpoch()
-
- self.daemon.decrementThreadCount('cooldownPeer')
-
- def runCheck(self):
- if os.path.isfile(self.daemon._core.dataDir + '.runcheck'):
- os.remove(self.daemon._core.dataDir + '.runcheck')
- return True
-
- return False
-
- def humanReadableTime(self, seconds):
- build = ''
-
- units = {
- 'year' : 31557600,
- 'month' : (31557600 / 12),
- 'day' : 86400,
- 'hour' : 3600,
- 'minute' : 60,
- 'second' : 1
- }
-
- for unit in units:
- amnt_unit = int(seconds / units[unit])
- if amnt_unit >= 1:
- seconds -= amnt_unit * units[unit]
- build += '%s %s' % (amnt_unit, unit) + ('s' if amnt_unit != 1 else '') + ' '
-
- return build.strip()
-
- def insertDeniableBlock(self):
- '''Insert a fake block in order to make it more difficult to track real blocks'''
- fakePeer = ''
- chance = 10
- if secrets.randbelow(chance) == (chance - 1):
- # This assumes on the libsodium primitives to have key-privacy
- fakePeer = 'OVPCZLOXD6DC5JHX4EQ3PSOGAZ3T24F75HQLIUZSDSMYPEOXCPFA===='
- data = secrets.token_hex(secrets.randbelow(1024) + 1)
- self.daemon._core.insertBlock(data, header='pm', encryptType='asym', asymPeer=fakePeer, meta={'subject': 'foo'})
- self.daemon.decrementThreadCount('insertDeniableBlock')
\ No newline at end of file
diff --git a/onionr/core.py b/onionr/core.py
index 58c95d9f..53d834f6 100755
--- a/onionr/core.py
+++ b/onionr/core.py
@@ -808,7 +808,7 @@ class Core:
self._utils.processBlockMetadata(retData)
if retData != False:
- if plaintextPeer == 'OVPCZLOXD6DC5JHX4EQ3PSOGAZ3T24F75HQLIUZSDSMYPEOXCPFA====':
+ if plaintextPeer == onionrvalues.DENIABLE_PEER_ADDRESS:
events.event('insertdeniable', {'content': plaintext, 'meta': plaintextMeta, 'hash': retData, 'peer': self._utils.bytesToStr(asymPeer)}, onionr = self.onionrInst, threaded = True)
else:
events.event('insertblock', {'content': plaintext, 'meta': plaintextMeta, 'hash': retData, 'peer': self._utils.bytesToStr(asymPeer)}, onionr = self.onionrInst, threaded = True)
diff --git a/onionr/dependencies/secrets.py b/onionr/dependencies/secrets.py
deleted file mode 100755
index 9b2eb61b..00000000
--- a/onionr/dependencies/secrets.py
+++ /dev/null
@@ -1,331 +0,0 @@
-"""Generate cryptographically strong pseudo-random numbers suitable for
-managing secrets such as account authentication, tokens, and similar.
-
-See PEP 506 for more information.
-https://www.python.org/dev/peps/pep-0506/
-
-
-A. HISTORY OF THE SOFTWARE
-==========================
-
-Python was created in the early 1990s by Guido van Rossum at Stichting
-Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
-as a successor of a language called ABC. Guido remains Python's
-principal author, although it includes many contributions from others.
-
-In 1995, Guido continued his work on Python at the Corporation for
-National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
-in Reston, Virginia where he released several versions of the
-software.
-
-In May 2000, Guido and the Python core development team moved to
-BeOpen.com to form the BeOpen PythonLabs team. In October of the same
-year, the PythonLabs team moved to Digital Creations, which became
-Zope Corporation. In 2001, the Python Software Foundation (PSF, see
-https://www.python.org/psf/) was formed, a non-profit organization
-created specifically to own Python-related Intellectual Property.
-Zope Corporation was a sponsoring member of the PSF.
-
-All Python releases are Open Source (see http://www.opensource.org for
-the Open Source Definition). Historically, most, but not all, Python
-releases have also been GPL-compatible; the table below summarizes
-the various releases.
-
- Release Derived Year Owner GPL-
- from compatible? (1)
-
- 0.9.0 thru 1.2 1991-1995 CWI yes
- 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes
- 1.6 1.5.2 2000 CNRI no
- 2.0 1.6 2000 BeOpen.com no
- 1.6.1 1.6 2001 CNRI yes (2)
- 2.1 2.0+1.6.1 2001 PSF no
- 2.0.1 2.0+1.6.1 2001 PSF yes
- 2.1.1 2.1+2.0.1 2001 PSF yes
- 2.1.2 2.1.1 2002 PSF yes
- 2.1.3 2.1.2 2002 PSF yes
- 2.2 and above 2.1.1 2001-now PSF yes
-
-Footnotes:
-
-(1) GPL-compatible doesn't mean that we're distributing Python under
- the GPL. All Python licenses, unlike the GPL, let you distribute
- a modified version without making your changes open source. The
- GPL-compatible licenses make it possible to combine Python with
- other software that is released under the GPL; the others don't.
-
-(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
- because its license has a choice of law clause. According to
- CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
- is "not incompatible" with the GPL.
-
-Thanks to the many outside volunteers who have worked under Guido's
-direction to make these releases possible.
-
-
-B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
-===============================================================
-
-PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
---------------------------------------------
-
-1. This LICENSE AGREEMENT is between the Python Software Foundation
-("PSF"), and the Individual or Organization ("Licensee") accessing and
-otherwise using this software ("Python") in source or binary form and
-its associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, PSF hereby
-grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
-analyze, test, perform and/or display publicly, prepare derivative works,
-distribute, and otherwise use Python alone or in any derivative version,
-provided, however, that PSF's License Agreement and PSF's notice of copyright,
-i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation; All
-Rights Reserved" are retained in Python alone or in any derivative version
-prepared by Licensee.
-
-3. In the event Licensee prepares a derivative work that is based on
-or incorporates Python or any part thereof, and wants to make
-the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Python.
-
-4. PSF is making Python available to Licensee on an "AS IS"
-basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
-FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
-OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. Nothing in this License Agreement shall be deemed to create any
-relationship of agency, partnership, or joint venture between PSF and
-Licensee. This License Agreement does not grant permission to use PSF
-trademarks or trade name in a trademark sense to endorse or promote
-products or services of Licensee, or any third party.
-
-8. By copying, installing or otherwise using Python, Licensee
-agrees to be bound by the terms and conditions of this License
-Agreement.
-
-
-BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
--------------------------------------------
-
-BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
-
-1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
-office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
-Individual or Organization ("Licensee") accessing and otherwise using
-this software in source or binary form and its associated
-documentation ("the Software").
-
-2. Subject to the terms and conditions of this BeOpen Python License
-Agreement, BeOpen hereby grants Licensee a non-exclusive,
-royalty-free, world-wide license to reproduce, analyze, test, perform
-and/or display publicly, prepare derivative works, distribute, and
-otherwise use the Software alone or in any derivative version,
-provided, however, that the BeOpen Python License is retained in the
-Software, alone or in any derivative version prepared by Licensee.
-
-3. BeOpen is making the Software available to Licensee on an "AS IS"
-basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
-SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
-AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
-DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-5. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-6. This License Agreement shall be governed by and interpreted in all
-respects by the law of the State of California, excluding conflict of
-law provisions. Nothing in this License Agreement shall be deemed to
-create any relationship of agency, partnership, or joint venture
-between BeOpen and Licensee. This License Agreement does not grant
-permission to use BeOpen trademarks or trade names in a trademark
-sense to endorse or promote products or services of Licensee, or any
-third party. As an exception, the "BeOpen Python" logos available at
-http://www.pythonlabs.com/logos.html may be used according to the
-permissions granted on that web page.
-
-7. By copying, installing or otherwise using the software, Licensee
-agrees to be bound by the terms and conditions of this License
-Agreement.
-
-
-CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
----------------------------------------
-
-1. This LICENSE AGREEMENT is between the Corporation for National
-Research Initiatives, having an office at 1895 Preston White Drive,
-Reston, VA 20191 ("CNRI"), and the Individual or Organization
-("Licensee") accessing and otherwise using Python 1.6.1 software in
-source or binary form and its associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, CNRI
-hereby grants Licensee a nonexclusive, royalty-free, world-wide
-license to reproduce, analyze, test, perform and/or display publicly,
-prepare derivative works, distribute, and otherwise use Python 1.6.1
-alone or in any derivative version, provided, however, that CNRI's
-License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
-1995-2001 Corporation for National Research Initiatives; All Rights
-Reserved" are retained in Python 1.6.1 alone or in any derivative
-version prepared by Licensee. Alternately, in lieu of CNRI's License
-Agreement, Licensee may substitute the following text (omitting the
-quotes): "Python 1.6.1 is made available subject to the terms and
-conditions in CNRI's License Agreement. This Agreement together with
-Python 1.6.1 may be located on the Internet using the following
-unique, persistent identifier (known as a handle): 1895.22/1013. This
-Agreement may also be obtained from a proxy server on the Internet
-using the following URL: http://hdl.handle.net/1895.22/1013".
-
-3. In the event Licensee prepares a derivative work that is based on
-or incorporates Python 1.6.1 or any part thereof, and wants to make
-the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Python 1.6.1.
-
-4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
-basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
-1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
-OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. This License Agreement shall be governed by the federal
-intellectual property law of the United States, including without
-limitation the federal copyright law, and, to the extent such
-U.S. federal law does not apply, by the law of the Commonwealth of
-Virginia, excluding Virginia's conflict of law provisions.
-Notwithstanding the foregoing, with regard to derivative works based
-on Python 1.6.1 that incorporate non-separable material that was
-previously distributed under the GNU General Public License (GPL), the
-law of the Commonwealth of Virginia shall govern this License
-Agreement only as to issues arising under or with respect to
-Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this
-License Agreement shall be deemed to create any relationship of
-agency, partnership, or joint venture between CNRI and Licensee. This
-License Agreement does not grant permission to use CNRI trademarks or
-trade name in a trademark sense to endorse or promote products or
-services of Licensee, or any third party.
-
-8. By clicking on the "ACCEPT" button where indicated, or by copying,
-installing or otherwise using Python 1.6.1, Licensee agrees to be
-bound by the terms and conditions of this License Agreement.
-
- ACCEPT
-
-
-CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
---------------------------------------------------
-
-Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
-The Netherlands. All rights reserved.
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Stichting Mathematisch
-Centrum or CWI not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior
-permission.
-
-STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
-THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
-FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-
-"""
-
-__all__ = ['choice', 'randbelow', 'randbits', 'SystemRandom',
- 'token_bytes', 'token_hex', 'token_urlsafe',
- 'compare_digest',
- ]
-
-
-import base64
-import binascii
-import os
-
-from hmac import compare_digest
-from random import SystemRandom
-
-_sysrand = SystemRandom()
-
-randbits = _sysrand.getrandbits
-choice = _sysrand.choice
-
-def randbelow(exclusive_upper_bound):
- """Return a random int in the range [0, n)."""
- if exclusive_upper_bound <= 0:
- raise ValueError("Upper bound must be positive.")
- return _sysrand._randbelow(exclusive_upper_bound)
-
-DEFAULT_ENTROPY = 32 # number of bytes to return by default
-
-def token_bytes(nbytes=None):
- """Return a random byte string containing *nbytes* bytes.
-
- If *nbytes* is ``None`` or not supplied, a reasonable
- default is used.
-
- >>> token_bytes(16) #doctest:+SKIP
- b'\\xebr\\x17D*t\\xae\\xd4\\xe3S\\xb6\\xe2\\xebP1\\x8b'
-
- """
- if nbytes is None:
- nbytes = DEFAULT_ENTROPY
- return os.urandom(nbytes)
-
-def token_hex(nbytes=None):
- """Return a random text string, in hexadecimal.
-
- The string has *nbytes* random bytes, each byte converted to two
- hex digits. If *nbytes* is ``None`` or not supplied, a reasonable
- default is used.
-
- >>> token_hex(16) #doctest:+SKIP
- 'f9bf78b9a18ce6d46a0cd2b0b86df9da'
-
- """
- return binascii.hexlify(token_bytes(nbytes)).decode('ascii')
-
-def token_urlsafe(nbytes=None):
- """Return a random URL-safe text string, in Base64 encoding.
-
- The string has *nbytes* random bytes. If *nbytes* is ``None``
- or not supplied, a reasonable default is used.
-
- >>> token_urlsafe(16) #doctest:+SKIP
- 'Drmhze6EPcv0fN_81Bj-nA'
-
- """
- tok = token_bytes(nbytes)
- return base64.urlsafe_b64encode(tok).rstrip(b'=').decode('ascii')
-
diff --git a/onionr/etc/humanreadabletime.py b/onionr/etc/humanreadabletime.py
new file mode 100644
index 00000000..7e3ff3bc
--- /dev/null
+++ b/onionr/etc/humanreadabletime.py
@@ -0,0 +1,38 @@
+'''
+ Onionr - Private P2P Communication
+
+ human_readable_time takes integer seconds and returns a human readable string
+'''
+'''
+ 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 .
+'''
+def human_readable_time(seconds):
+ build = ''
+
+ units = {
+ 'year' : 31557600,
+ 'month' : (31557600 / 12),
+ 'day' : 86400,
+ 'hour' : 3600,
+ 'minute' : 60,
+ 'second' : 1
+ }
+
+ for unit in units:
+ amnt_unit = int(seconds / units[unit])
+ if amnt_unit >= 1:
+ seconds -= amnt_unit * units[unit]
+ build += '%s %s' % (amnt_unit, unit) + ('s' if amnt_unit != 1 else '') + ' '
+
+ return build.strip()
\ No newline at end of file
diff --git a/onionr/etc/onionrvalues.py b/onionr/etc/onionrvalues.py
index e3e1421d..5df394db 100755
--- a/onionr/etc/onionrvalues.py
+++ b/onionr/etc/onionrvalues.py
@@ -17,7 +17,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
'''
-
+DENIABLE_PEER_ADDRESS = "OVPCZLOXD6DC5JHX4EQ3PSOGAZ3T24F75HQLIUZSDSMYPEOXCPFA===="
class OnionrValues:
def __init__(self):
self.passwordLength = 20
diff --git a/onionr/netcontroller.py b/onionr/netcontroller.py
index fa64c938..6edbd474 100755
--- a/onionr/netcontroller.py
+++ b/onionr/netcontroller.py
@@ -17,11 +17,10 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
'''
-import subprocess, os, random, sys, time, signal, base64, socket
+import subprocess, os, sys, time, signal, base64, socket
from shutil import which
import logger, config
from onionrblockapi import Block
-from dependencies import secrets
def getOpenPort():
# taken from (but modified) https://stackoverflow.com/a/2838309 by https://stackoverflow.com/users/133374/albert ccy-by-sa-3 https://creativecommons.org/licenses/by-sa/3.0/
diff --git a/onionr/onionrcrypto.py b/onionr/onionrcrypto.py
index 2ce90bf6..dab3e8b7 100755
--- a/onionr/onionrcrypto.py
+++ b/onionr/onionrcrypto.py
@@ -17,15 +17,10 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
'''
-import os, binascii, base64, hashlib, time, sys, hmac
+import os, binascii, base64, hashlib, time, sys, hmac, secrets
import nacl.signing, nacl.encoding, nacl.public, nacl.hash, nacl.pwhash, nacl.utils, nacl.secret
import logger, onionrproofs
import onionrexceptions, keymanager, core
-# secrets module was added into standard lib in 3.6+
-if sys.version_info[0] == 3 and sys.version_info[1] < 6:
- from dependencies import secrets
-elif sys.version_info[0] == 3 and sys.version_info[1] >= 6:
- import secrets
import config
class OnionrCrypto: