diff --git a/onionr/communicatorutils/deniableinserts.py b/onionr/communicatorutils/deniableinserts.py
index f993e6d0..571a6093 100755
--- a/onionr/communicatorutils/deniableinserts.py
+++ b/onionr/communicatorutils/deniableinserts.py
@@ -27,5 +27,5 @@ def insert_deniable_block(comm_inst):
# 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._core.insertBlock(data, header='pm', encryptType='asym', asymPeer=fakePeer, disableForward=True, meta={'subject': 'foo'})
comm_inst.decrementThreadCount('insert_deniable_block')
\ No newline at end of file
diff --git a/onionr/core.py b/onionr/core.py
index 33b310af..be309309 100755
--- a/onionr/core.py
+++ b/onionr/core.py
@@ -128,7 +128,8 @@ class Core:
'''
Adds a public key to the key database (misleading function name)
'''
- assert peerID not in self.listPeers()
+ if peerID in self.listPeers() or peerID == self._crypto.pubKey:
+ raise ValueError("specified id is already known")
# This function simply adds a peer to the DB
if not self._utils.validatePubKey(peerID):
@@ -776,7 +777,11 @@ class Core:
data = self._crypto.pubKeyEncrypt(data, asymPeer, encodedData=True).decode()
signature = self._crypto.pubKeyEncrypt(signature, asymPeer, encodedData=True).decode()
signer = self._crypto.pubKeyEncrypt(signer, asymPeer, encodedData=True).decode()
- onionrusers.OnionrUser(self, asymPeer, saveUser=True)
+ try:
+ onionrusers.OnionrUser(self, asymPeer, saveUser=True)
+ except ValueError:
+ # if peer is already known
+ pass
else:
raise onionrexceptions.InvalidPubkey(asymPeer + ' is not a valid base32 encoded ed25519 key')
diff --git a/onionr/httpapi/friendsapi/__init__.py b/onionr/httpapi/friendsapi/__init__.py
index 8d6b4122..5b4a883b 100755
--- a/onionr/httpapi/friendsapi/__init__.py
+++ b/onionr/httpapi/friendsapi/__init__.py
@@ -26,7 +26,8 @@ friends = Blueprint('friends', __name__)
@friends.route('/friends/list')
def list_friends():
pubkey_list = {}
- friend_list = contactmanager.ContactManager.list_friends(core.Core())
+ c = core.Core()
+ friend_list = contactmanager.ContactManager.list_friends(c)
for friend in friend_list:
pubkey_list[friend.publicKey] = {'name': friend.get_info('name')}
return json.dumps(pubkey_list)
diff --git a/onionr/onionrcommands/pubkeymanager.py b/onionr/onionrcommands/pubkeymanager.py
index e12fc670..2a6370f9 100755
--- a/onionr/onionrcommands/pubkeymanager.py
+++ b/onionr/onionrcommands/pubkeymanager.py
@@ -21,6 +21,7 @@
import sys, getpass
import logger, onionrexceptions
from onionrusers import onionrusers, contactmanager
+import unpaddedbase32
def add_ID(o_inst):
try:
sys.argv[2]
@@ -50,6 +51,7 @@ def add_ID(o_inst):
def change_ID(o_inst):
try:
key = sys.argv[2]
+ key = unpaddedbase32.repad(key.encode()).decode()
except IndexError:
logger.warn('Specify pubkey to use')
else:
diff --git a/onionr/onionrcrypto.py b/onionr/onionrcrypto.py
index 75fe2138..3c77b3ce 100755
--- a/onionr/onionrcrypto.py
+++ b/onionr/onionrcrypto.py
@@ -19,6 +19,7 @@
'''
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 unpaddedbase32
import logger, onionrproofs
import onionrexceptions, keymanager, core
import config
@@ -93,6 +94,7 @@ class OnionrCrypto:
def pubKeyEncrypt(self, data, pubkey, encodedData=False):
'''Encrypt to a public key (Curve25519, taken from base32 Ed25519 pubkey)'''
+ pubkey = unpaddedbase32.repad(self._core._utils.strToBytes(pubkey))
retVal = ''
box = None
data = self._core._utils.strToBytes(data)
@@ -129,7 +131,7 @@ class OnionrCrypto:
return decrypted
def symmetricEncrypt(self, data, key, encodedKey=False, returnEncoded=True):
- '''Encrypt data to a 32-byte key (Salsa20-Poly1305 MAC)'''
+ '''Encrypt data with a 32-byte key (Salsa20-Poly1305 MAC)'''
if encodedKey:
encoding = nacl.encoding.Base64Encoder
else:
@@ -199,7 +201,7 @@ class OnionrCrypto:
if pubkey == '':
pubkey = self.pubKey
prev = ''
- pubkey = pubkey.encode()
+ pubkey = self._core._utils.strToBytes(pubkey)
for i in range(self.HASH_ID_ROUNDS):
try:
prev = prev.encode()
diff --git a/onionr/onionrusers/contactmanager.py b/onionr/onionrusers/contactmanager.py
index 0524ed64..098cba65 100755
--- a/onionr/onionrusers/contactmanager.py
+++ b/onionr/onionrusers/contactmanager.py
@@ -18,10 +18,12 @@
along with this program. If not, see
Warning: Some values can be dangerous to change. Use caution.
+Warning: Some values can be dangerous to change.
Configuration contains sensitive information.
🔒 Security Level:
🕰️ Uptime:
🖇️ Last Received Request: None since start
⬇️ Total Requests Received: None since start
🔗 Outgoing Connections:
diff --git a/onionr/static-data/www/private/main.css b/onionr/static-data/www/private/main.css index 91a7b588..896cd2f5 100755 --- a/onionr/static-data/www/private/main.css +++ b/onionr/static-data/www/private/main.css @@ -5,4 +5,14 @@ .saveConfig{ margin-top: 1em; +} + + +.idLink{ + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; /* Non-prefixed version, currently + supported by Chrome and Opera */ } \ No newline at end of file diff --git a/onionr/static-data/www/shared/main/stats.js b/onionr/static-data/www/shared/main/stats.js index 86b7f451..9b50185e 100755 --- a/onionr/static-data/www/shared/main/stats.js +++ b/onionr/static-data/www/shared/main/stats.js @@ -18,10 +18,34 @@ */ uptimeDisplay = document.getElementById('uptime') connectedDisplay = document.getElementById('connectedNodes') +connectedDisplay.style.maxHeight = '300px' +connectedDisplay.style.overflowY = 'scroll' storedBlockDisplay = document.getElementById('storedBlocks') queuedBlockDisplay = document.getElementById('blockQueue') lastIncoming = document.getElementById('lastIncoming') totalRec = document.getElementById('totalRec') +securityLevel = document.getElementById('securityLevel') +sec_description_str = 'unknown' + +function showSecStatNotice(){ + var secWarnEls = document.getElementsByClassName('secRequestNotice') + for (el = 0; el < secWarnEls.length; el++){ + secWarnEls[el].style.display = 'block' + } +} + +switch (httpGet('/config/get/general.security_level')){ + case "0": + sec_description_str = 'normal' + break; + case "1": + sec_description_str = 'high' + break; +} + +if (sec_description_str !== 'normal'){ + showSecStatNotice() +} function getStats(){ stats = JSON.parse(httpGet('getstats', webpass)) @@ -29,6 +53,7 @@ function getStats(){ connectedDisplay.innerText = stats['connectedNodes'] storedBlockDisplay.innerText = stats['blockCount'] queuedBlockDisplay.innerText = stats['blockQueueCount'] + securityLevel.innerText = sec_description_str totalRec.innerText = httpGet('/hitcount') var lastConnect = httpGet('/lastconnect') if (lastConnect > 0){ diff --git a/onionr/static-data/www/shared/main/style.css b/onionr/static-data/www/shared/main/style.css index 18388845..8181df8d 100755 --- a/onionr/static-data/www/shared/main/style.css +++ b/onionr/static-data/www/shared/main/style.css @@ -178,8 +178,16 @@ body{ background-color:#396BAC; } +.btn:hover{ + opacity: 0.6; +} + .openSiteBtn{ padding: 5px; border: 1px solid black; border-radius: 5px; } + +.hidden{ + display: none; +} diff --git a/onionr/tests/test_stringvalidations.py b/onionr/tests/test_stringvalidations.py index 0cc45eae..caac34df 100755 --- a/onionr/tests/test_stringvalidations.py +++ b/onionr/tests/test_stringvalidations.py @@ -29,11 +29,13 @@ class OnionrValidations(unittest.TestCase): def test_pubkey_validator(self): # Test ed25519 public key validity - valid = 'JZ5VE72GUS3C7BOHDRIYZX4B5U5EJMCMLKHLYCVBQQF3UKHYIRRQ====' + valids = ['JZ5VE72GUS3C7BOHDRIYZX4B5U5EJMCMLKHLYCVBQQF3UKHYIRRQ====', 'JZ5VE72GUS3C7BOHDRIYZX4B5U5EJMCMLKHLYCVBQQF3UKHYIRRQ'] invalid = [None, '', ' ', 'dfsg', '\n', 'JZ5VE72GUS3C7BOHDRIYZX4B5U5EJMCMLKHLYCVBQQF3UKHYIR$Q===='] c = core.Core() - print('testing', valid) - self.assertTrue(c._utils.validatePubKey(valid)) + + for valid in valids: + print('testing', valid) + self.assertTrue(c._utils.validatePubKey(valid)) for x in invalid: #print('testing', x) diff --git a/requirements.in b/requirements.in index bbb9cdc3..c285834a 100644 --- a/requirements.in +++ b/requirements.in @@ -1,9 +1,10 @@ urllib3==1.24.2 requests==2.21.0 -PyNaCl==1.2.1 +PyNaCl==1.3.0 gevent==1.3.6 Flask==1.0.2 PySocks==1.6.8 stem==1.7.1 deadsimplekv==0.1.1 +unpaddedbase32==0.1.0 jinja2==2.10.1 diff --git a/requirements.txt b/requirements.txt index 06b3303d..261a9996 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ # This file is autogenerated by pip-compile # To update, run: # -# pip-compile --generate-hashes --output-file requirements.txt requirements.in +# pip-compile --generate-hashes --output-file=requirements.txt requirements.in # certifi==2018.11.29 \ --hash=sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7 \ @@ -140,38 +140,26 @@ markupsafe==1.1.1 \ pycparser==2.19 \ --hash=sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3 \ # via cffi -pynacl==1.2.1 \ - --hash=sha256:04e30e5bdeeb2d5b34107f28cd2f5bbfdc6c616f3be88fc6f53582ff1669eeca \ - --hash=sha256:0bfa0d94d2be6874e40f896e0a67e290749151e7de767c5aefbad1121cad7512 \ - --hash=sha256:11aa4e141b2456ce5cecc19c130e970793fa3a2c2e6fbb8ad65b28f35aa9e6b6 \ - --hash=sha256:13bdc1fe084ff9ac7653ae5a924cae03bf4bb07c6667c9eb5b6eb3c570220776 \ - --hash=sha256:14339dc233e7a9dda80a3800e64e7ff89d0878ba23360eea24f1af1b13772cac \ - --hash=sha256:1d33e775fab3f383167afb20b9927aaf4961b953d76eeb271a5703a6d756b65b \ - --hash=sha256:2a42b2399d0428619e58dac7734838102d35f6dcdee149e0088823629bf99fbb \ - --hash=sha256:2dce05ac8b3c37b9e2f65eab56c544885607394753e9613fd159d5e2045c2d98 \ - --hash=sha256:63cfccdc6217edcaa48369191ae4dca0c390af3c74f23c619e954973035948cd \ - --hash=sha256:6453b0dae593163ffc6db6f9c9c1597d35c650598e2c39c0590d1757207a1ac2 \ - --hash=sha256:73a5a96fb5fbf2215beee2353a128d382dbca83f5341f0d3c750877a236569ef \ - --hash=sha256:8abb4ef79161a5f58848b30ab6fb98d8c466da21fdd65558ce1d7afc02c70b5f \ - --hash=sha256:8ac1167195b32a8755de06efd5b2d2fe76fc864517dab66aaf65662cc59e1988 \ - --hash=sha256:8f505f42f659012794414fa57c498404e64db78f1d98dfd40e318c569f3c783b \ - --hash=sha256:9c8a06556918ee8e3ab48c65574f318f5a0a4d31437fc135da7ee9d4f9080415 \ - --hash=sha256:a1e25fc5650cf64f01c9e435033e53a4aca9de30eb9929d099f3bb078e18f8f2 \ - --hash=sha256:be71cd5fce04061e1f3d39597f93619c80cdd3558a6c9ba99a546f144a8d8101 \ - --hash=sha256:c5b1a7a680218dee9da0f1b5e24072c46b3c275d35712bc1d505b85bb03441c0 \ - --hash=sha256:cb785db1a9468841a1265c9215c60fe5d7af2fb1b209e3316a152704607fc582 \ - --hash=sha256:cf6877124ae6a0698404e169b3ba534542cfbc43f939d46b927d956daf0a373a \ - --hash=sha256:d0eb5b2795b7ee2cbcfcadacbe95a13afbda048a262bd369da9904fecb568975 \ - --hash=sha256:d3a934e2b9f20abac009d5b6951067cfb5486889cb913192b4d8288b216842f1 \ - --hash=sha256:d795f506bcc9463efb5ebb0f65ed77921dcc9e0a50499dedd89f208445de9ecb \ - --hash=sha256:d8aaf7e5d6b0e0ef7d6dbf7abeb75085713d0100b4eb1a4e4e857de76d77ac45 \ - --hash=sha256:de2aaca8386cf4d70f1796352f2346f48ddb0bed61dc43a3ce773ba12e064031 \ - --hash=sha256:e0d38fa0a75f65f556fb912f2c6790d1fa29b7dd27a1d9cc5591b281321eaaa9 \ - --hash=sha256:eb2acabbd487a46b38540a819ef67e477a674481f84a82a7ba2234b9ba46f752 \ - --hash=sha256:eeee629828d0eb4f6d98ac41e9a3a6461d114d1d0aa111a8931c049359298da0 \ - --hash=sha256:f5836463a3c0cca300295b229b6c7003c415a9d11f8f9288ddbd728e2746524c \ - --hash=sha256:f5ce9e26d25eb0b2d96f3ef0ad70e1d3ae89b5d60255c462252a3e456a48c053 \ - --hash=sha256:fabf73d5d0286f9e078774f3435601d2735c94ce9e514ac4fb945701edead7e4 +pynacl==1.3.0 \ + --hash=sha256:05c26f93964373fc0abe332676cb6735f0ecad27711035b9472751faa8521255 \ + --hash=sha256:0c6100edd16fefd1557da078c7a31e7b7d7a52ce39fdca2bec29d4f7b6e7600c \ + --hash=sha256:0d0a8171a68edf51add1e73d2159c4bc19fc0718e79dec51166e940856c2f28e \ + --hash=sha256:1c780712b206317a746ace34c209b8c29dbfd841dfbc02aa27f2084dd3db77ae \ + --hash=sha256:2424c8b9f41aa65bbdbd7a64e73a7450ebb4aa9ddedc6a081e7afcc4c97f7621 \ + --hash=sha256:2d23c04e8d709444220557ae48ed01f3f1086439f12dbf11976e849a4926db56 \ + --hash=sha256:30f36a9c70450c7878053fa1344aca0145fd47d845270b43a7ee9192a051bf39 \ + --hash=sha256:37aa336a317209f1bb099ad177fef0da45be36a2aa664507c5d72015f956c310 \ + --hash=sha256:4943decfc5b905748f0756fdd99d4f9498d7064815c4cf3643820c9028b711d1 \ + --hash=sha256:57ef38a65056e7800859e5ba9e6091053cd06e1038983016effaffe0efcd594a \ + --hash=sha256:5bd61e9b44c543016ce1f6aef48606280e45f892a928ca7068fba30021e9b786 \ + --hash=sha256:6482d3017a0c0327a49dddc8bd1074cc730d45db2ccb09c3bac1f8f32d1eb61b \ + --hash=sha256:7d3ce02c0784b7cbcc771a2da6ea51f87e8716004512493a2b69016326301c3b \ + --hash=sha256:a14e499c0f5955dcc3991f785f3f8e2130ed504fa3a7f44009ff458ad6bdd17f \ + --hash=sha256:a39f54ccbcd2757d1d63b0ec00a00980c0b382c62865b61a505163943624ab20 \ + --hash=sha256:aabb0c5232910a20eec8563503c153a8e78bbf5459490c49ab31f6adf3f3a415 \ + --hash=sha256:bd4ecb473a96ad0f90c20acba4f0bf0df91a4e03a1f4dd6a4bdc9ca75aa3a715 \ + --hash=sha256:e2da3c13307eac601f3de04887624939aca8ee3c9488a0bb0eca4fb9401fc6b1 \ + --hash=sha256:f67814c38162f4deb31f68d590771a29d5ae3b1bd64b75cf232308e5c74777e0 pysocks==1.6.8 \ --hash=sha256:3fe52c55890a248676fd69dc9e3c4e811718b777834bcaab7a8125cf9deac672 requests==2.21.0 \ @@ -183,6 +171,8 @@ six==1.12.0 \ # via pynacl stem==1.7.1 \ --hash=sha256:c9eaf3116cb60c15995cbd3dec3a5cbc50e9bb6e062c4d6d42201e566f498ca2 +unpaddedbase32==0.1.0 \ + --hash=sha256:5e4143fcaf77c9c6b4f60d18301c7570f0dac561dcf9b9aed8b5ba6ead7f218c urllib3==1.24.2 \ --hash=sha256:4c291ca23bbb55c76518905869ef34bdd5f0e46af7afe6861e8375643ffee1a0 \ --hash=sha256:9a247273df709c4fedb38c711e44292304f73f39ab01beda9f6b9fc375669ac3