Removed more defunct code

This commit is contained in:
Kevin F 2022-08-03 12:18:21 -05:00
parent e1b4b12024
commit cb977a2719
21 changed files with 21 additions and 716 deletions

View File

@ -46,14 +46,6 @@ locale.setlocale(locale.LC_ALL, '') # noqa
ran_as_script = False ran_as_script = False
if __name__ == "__main__": ran_as_script = True if __name__ == "__main__": ran_as_script = True
# Import standard libraries
try:
from onionrutils import dependencycheck # noqa
except ModuleNotFoundError as e:
print('Missing requirement: ' + str(e) + ' installed')
sys.exit(1)
# Import 3rd party libraries # Import 3rd party libraries
from filenuke import nuke # noqa from filenuke import nuke # noqa

View File

@ -1,55 +0,0 @@
"""Onionr - Private P2P Communication.
Desktop notification wrapper
"""
from subprocess import Popen
try:
import simplenotifications as simplenotify
except ImportError:
notifications_enabled = False
else:
notifications_enabled = True
from utils.readstatic import get_static_dir
import config
from onionrplugins.onionrevents import event as plugin_api_event
"""
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
if not config.get('general.show_notifications', True):
notifications_enabled = False
notification_sound_file = get_static_dir() + "sounds/notification1.mp3"
def notify(title: str = "Onionr", message: str = ""):
"""Cross platform method to show a notification."""
if not notifications_enabled:
return
plugin_api_event("notification", data={"title": title, "message": message})
simplenotify.notify(title, message)
def notification_with_sound(sound='', **kwargs):
if not notifications_enabled:
return
if not sound:
sound = notification_sound_file
try:
Popen(["mpv", sound])
except FileNotFoundError:
pass
notify(**kwargs)

View File

@ -1,21 +0,0 @@
from audioop import mul
import multiprocessing
def run_func_in_new_process(func, *args, **kwargs):
queue = multiprocessing.Queue()
def _wrap_func():
if args and kwargs:
queue.put(func(*args, **kwargs))
elif args:
queue.put(func(*args))
elif kwargs:
queue.put(func(**kwargs))
else:
queue.put(func())
proc = multiprocessing.Process(target=_wrap_func, daemon=True)
proc.start()
return queue.get()

View File

@ -10,7 +10,6 @@ import ujson as json
import config import config
import logger import logger
import onionrvalues import onionrvalues
from onionrutils import getopenport
from logger.settings import * from logger.settings import *
from utils import readstatic from utils import readstatic
""" """
@ -77,14 +76,3 @@ def setup_config():
set_level(map[verbosity]) set_level(map[verbosity])
else: else:
logger.warn('Verbosity level %s is not valid, using default verbosity.' % verbosity) logger.warn('Verbosity level %s is not valid, using default verbosity.' % verbosity)
if type(config.get('client.webpassword')) is type(None):
config.set('client.webpassword', base64.b16encode(os.urandom(32)).decode('utf-8'), savefile=True)
if type(config.get('client.client.port')) is type(None):
randomPort = getopenport.get_open_port()
config.set('client.client.port', randomPort, savefile=True)
if type(config.get('client.public.port')) is type(None):
randomPort = getopenport.get_open_port()
config.set('client.public.port', randomPort, savefile=True)
if type(config.get('client.api_version')) is type(None):
config.set('client.api_version', onionrvalues.API_VERSION, savefile=True)

View File

@ -1 +0,0 @@
from urllib3.contrib.socks import SOCKSProxyManager # noqa

View File

@ -1,37 +0,0 @@
'''
Onionr - Private P2P Communication
Return the client api server address and port, which is usually random
'''
'''
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
'''
import filepaths
import config
def get_client_API_server():
config.reload()
retData = ''
getconf = lambda: config.get('client.client.port')
port = getconf()
if port is None:
config.reload()
port = getconf()
try:
with open(filepaths.private_API_host_file, 'r') as host:
hostname = host.read()
except FileNotFoundError:
raise FileNotFoundError
else:
retData += '%s:%s' % (hostname, port)
return retData

View File

@ -1,29 +0,0 @@
'''
Onionr - Private P2P Communication
get an open port
'''
'''
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
'''
import socket
def get_open_port():
# 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/
# changes from source: import moved to top of file, bind specifically to localhost
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("127.0.0.1",0))
s.listen(1)
port = s.getsockname()[1]
s.close()
return port

View File

@ -1,9 +1,13 @@
''' """
Onionr - Private P2P Communication Onionr - Private P2P Communication
validate various string data types validate various string data types
''' """
''' import base64
import string
import unpaddedbase32, nacl.signing, nacl.encoding
from onionrutils import bytesconverter
"""
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
@ -16,34 +20,11 @@
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 base64, string
import unpaddedbase32, nacl.signing, nacl.encoding
from onionrutils import bytesconverter
def validate_hash(data, length=64):
'''
Validate if a string is a valid hash hex digest (does not compare, just checks length and charset)
Length is only invalid if its *more* than the specified
'''
retVal = True
if data == False or data == True:
return False
data = data.strip()
if len(data) > length:
retVal = False
else:
try:
int(data, 16)
except ValueError:
retVal = False
return retVal
def validate_pub_key(key): def validate_pub_key(key):
''' """Validate if a string is a valid base32 encoded Ed25519 key"""
Validate if a string is a valid base32 encoded Ed25519 key
'''
if type(key) is type(None): if type(key) is type(None):
return False return False
# Accept keys that have no = padding # Accept keys that have no = padding
@ -54,18 +35,8 @@ def validate_pub_key(key):
nacl.signing.SigningKey(seed=key, encoder=nacl.encoding.Base32Encoder) nacl.signing.SigningKey(seed=key, encoder=nacl.encoding.Base32Encoder)
except nacl.exceptions.ValueError: except nacl.exceptions.ValueError:
pass pass
except base64.binascii.Error as err: except base64.binascii.Error as _:
pass pass
else: else:
retVal = True retVal = True
return retVal return retVal
def is_integer_string(data):
'''Check if a string is a valid base10 integer (also returns true if already an int)'''
try:
int(data)
except (ValueError, TypeError) as e:
return False
else:
return True

View File

@ -1,7 +0,0 @@
import notifier
def update_event(bl):
"""Show update notification if available, return bool of if update happened"""
if not bl.isSigner(onionrvalues.UPDATE_SIGN_KEY): raise onionrexceptions.InvalidUpdate
onionr.notifier.notify(message="A new Onionr update is available. Stay updated to remain secure.")

View File

@ -1,127 +0,0 @@
"""Onionr - Private P2P Communication.
validate new block's metadata
"""
from json import JSONDecodeError
import ujson as json
import logger, onionrexceptions
import onionrvalues
from . import stringvalidators, epoch, bytesconverter
import config, filepaths, onionrcrypto
"""
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
def validate_metadata(metadata, block_data) -> bool:
"""Validate metadata meets onionr spec (does not validate proof value computation), take in either dictionary or json string"""
ret_data = False
max_clock_difference = onionrvalues.MAX_BLOCK_CLOCK_SKEW
# convert to dict if it is json string
if type(metadata) is str:
try:
metadata = json.loads(metadata)
except JSONDecodeError:
pass
# Validate metadata dict for invalid keys to sizes that are too large
maxAge = onionrvalues.DEFAULT_EXPIRE
if type(metadata) is dict:
for i in metadata:
try:
onionrvalues.BLOCK_METADATA_LENGTHS[i]
except KeyError:
logger.warn('Block has invalid metadata key ' + i)
break
else:
testData = metadata[i]
try:
testData = len(testData)
except (TypeError, AttributeError) as e:
testData = len(str(testData))
if onionrvalues.BLOCK_METADATA_LENGTHS[i] < testData:
logger.warn('Block metadata key ' + i + ' exceeded maximum size')
break
if i == 'time':
if not stringvalidators.is_integer_string(metadata[i]):
logger.warn('Block metadata time stamp is not integer string or int')
break
isFuture = (metadata[i] - epoch.get_epoch())
if isFuture > max_clock_difference:
logger.warn('Block timestamp is skewed to the future over the max %s: %s', (max_clock_difference, isFuture))
break
if (epoch.get_epoch() - metadata[i]) > maxAge:
logger.warn('Block is outdated: %s' % (metadata[i],))
break
elif i == 'expire':
try:
if not int(metadata[i]) > epoch.get_epoch(): raise ValueError
except ValueError:
logger.warn('Block is expired: %s less than %s' % (metadata[i], epoch.get_epoch()))
break
elif i == 'encryptType':
try:
if not metadata[i] in ('asym', 'sym', ''): raise ValueError
except ValueError:
logger.warn('Invalid encryption mode')
break
elif i == 'sig':
try:
metadata['encryptType']
except KeyError:
signer = metadata['signer']
sig = metadata['sig']
encodedMeta = bytesconverter.str_to_bytes(metadata['meta'])
encodedBlock = bytesconverter.str_to_bytes(block_data)
if not onionrcrypto.signing.ed_verify(encodedMeta + encodedBlock[1:], signer, sig):
logger.warn(f'Block was signed by {signer}, but signature failed')
break
else:
# if metadata loop gets no errors, it does not break, therefore metadata is valid
# make sure we do not have another block with the same data content (prevent data duplication and replay attacks)
# Make sure time is set (validity was checked above if it is)
if not config.get('general.store_plaintext_blocks', True):
try:
if not metadata['encryptType']:
raise onionrexceptions.PlaintextNotSupported
except KeyError:
raise onionrexceptions.PlaintextNotSupported
try:
metadata['time']
except KeyError:
logger.warn("Time header not set")
return False
nonce = bytesconverter.bytes_to_str(onionrcrypto.hashers.sha3_hash(block_data))
try:
with open(filepaths.data_nonce_file, 'r') as nonceFile:
if nonce in nonceFile.read():
# we've seen that nonce before, so we can't pass metadata
raise onionrexceptions.DataExists
except FileNotFoundError:
ret_data = True
except onionrexceptions.DataExists:
# do not set ret_data to True, because data has been seen before
logger.warn(f'{nonce} seen before')
raise onionrexceptions.DataExists
else:
ret_data = True
else:
logger.warn('In call to utils.validateMetadata, metadata must be JSON string or a dictionary object')
return ret_data

View File

@ -1,30 +0,0 @@
"""Onionr - Private P2P Communication.
greenlet safe sleep, ignoring ctrl-c
"""
from gevent import sleep
from onionrutils.epoch import get_epoch
"""
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
def better_sleep(wait: int):
"""Sleep catching ctrl c for wait seconds."""
start = get_epoch()
try:
sleep(wait)
except KeyboardInterrupt:
better_sleep(wait - (get_epoch() - start))

View File

@ -1,17 +0,0 @@
"""Onionr - Private P2P Communication.
read from a file from an offset (efficiently)
"""
from collections import namedtuple
OffsetReadResult = namedtuple('OffsetReadResult', ['data', 'new_offset'])
def read_from_offset(file_path, offset=0):
with open(file_path, 'rb') as f:
if offset:
f.seek(offset)
data = f.read()
offset = f.tell()
return OffsetReadResult(data, offset)

View File

@ -1,51 +0,0 @@
'''
Onionr - Private P2P Communication
z-fill (zero fill) a string to a specific length
intended for reconstructing block hashes
'''
from typing import Union
'''
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
'''
def reconstruct_hash(hex_hash: Union[str, bytes],
length: int = 64) -> Union[str, bytes]:
"""Pad hash hex string with zeros, return result"""
return hex_hash.zfill(length)
def deconstruct_hash(hex_hash: Union[str, bytes]) -> Union[str, bytes]:
"""Remove leading zeros from hex hash, return result"""
new_hash = ''
ret_bytes = False
try:
hex_hash = hex_hash.decode()
ret_bytes = True
except AttributeError:
pass
c = 0
for x in hex_hash:
if x == '0':
c += 1
else:
break
new_hash = hex_hash[c:]
if ret_bytes:
new_hash = new_hash.encode()
return new_hash

View File

@ -1 +0,0 @@
https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/robots.txt,http://2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion/robots.txt,http://rurcblzhmdk22kttfkel2zduhyu3r6to7knyc7wiorzrx5gw4c3lftad.onion/

Binary file not shown.

View File

@ -1,19 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>
Onionr
</title>
<link rel="shortcut icon" type="image/ico" href="/shared/images/favicon.ico">
</head>
<body>
<p>Onionr</p>
</body>
</html>

View File

@ -1,205 +0,0 @@
/**
* Identicon.js 2.3.3
* http://github.com/stewartlord/identicon.js
*
* PNGLib required for PNG output
* http://www.xarg.org/download/pnglib.js
*
* Copyright 2018, Stewart Lord
* Released under the BSD license
* http://www.opensource.org/licenses/bsd-license.php
*/
(function() {
var PNGlib;
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
PNGlib = require('./pnglib');
} else {
PNGlib = window.PNGlib;
}
var Identicon = function(hash, options){
if (typeof(hash) !== 'string' || hash.length < 15) {
throw 'A hash of at least 15 characters is required.';
}
this.defaults = {
background: [240, 240, 240, 255],
margin: 0.08,
size: 64,
saturation: 0.7,
brightness: 0.5,
format: 'png'
};
this.options = typeof(options) === 'object' ? options : this.defaults;
// backward compatibility with old constructor (hash, size, margin)
if (typeof(arguments[1]) === 'number') { this.options.size = arguments[1]; }
if (arguments[2]) { this.options.margin = arguments[2]; }
this.hash = hash
this.background = this.options.background || this.defaults.background;
this.size = this.options.size || this.defaults.size;
this.format = this.options.format || this.defaults.format;
this.margin = this.options.margin !== undefined ? this.options.margin : this.defaults.margin;
// foreground defaults to last 7 chars as hue at 70% saturation, 50% brightness
var hue = parseInt(this.hash.substr(-7), 16) / 0xfffffff;
var saturation = this.options.saturation || this.defaults.saturation;
var brightness = this.options.brightness || this.defaults.brightness;
this.foreground = this.options.foreground || this.hsl2rgb(hue, saturation, brightness);
};
Identicon.prototype = {
background: null,
foreground: null,
hash: null,
margin: null,
size: null,
format: null,
image: function(){
return this.isSvg()
? new Svg(this.size, this.foreground, this.background)
: new PNGlib(this.size, this.size, 256);
},
render: function(){
var image = this.image(),
size = this.size,
baseMargin = Math.floor(size * this.margin),
cell = Math.floor((size - (baseMargin * 2)) / 5),
margin = Math.floor((size - cell * 5) / 2),
bg = image.color.apply(image, this.background),
fg = image.color.apply(image, this.foreground);
// the first 15 characters of the hash control the pixels (even/odd)
// they are drawn down the middle first, then mirrored outwards
var i, color;
for (i = 0; i < 15; i++) {
color = parseInt(this.hash.charAt(i), 16) % 2 ? bg : fg;
if (i < 5) {
this.rectangle(2 * cell + margin, i * cell + margin, cell, cell, color, image);
} else if (i < 10) {
this.rectangle(1 * cell + margin, (i - 5) * cell + margin, cell, cell, color, image);
this.rectangle(3 * cell + margin, (i - 5) * cell + margin, cell, cell, color, image);
} else if (i < 15) {
this.rectangle(0 * cell + margin, (i - 10) * cell + margin, cell, cell, color, image);
this.rectangle(4 * cell + margin, (i - 10) * cell + margin, cell, cell, color, image);
}
}
return image;
},
rectangle: function(x, y, w, h, color, image){
if (this.isSvg()) {
image.rectangles.push({x: x, y: y, w: w, h: h, color: color});
} else {
var i, j;
for (i = x; i < x + w; i++) {
for (j = y; j < y + h; j++) {
image.buffer[image.index(i, j)] = color;
}
}
}
},
// adapted from: https://gist.github.com/aemkei/1325937
hsl2rgb: function(h, s, b){
h *= 6;
s = [
b += s *= b < .5 ? b : 1 - b,
b - h % 1 * s * 2,
b -= s *= 2,
b,
b + h % 1 * s,
b + s
];
return[
s[ ~~h % 6 ] * 255, // red
s[ (h|16) % 6 ] * 255, // green
s[ (h|8) % 6 ] * 255 // blue
];
},
toString: function(raw){
// backward compatibility with old toString, default to base64
if (raw) {
return this.render().getDump();
} else {
return this.render().getBase64();
}
},
isSvg: function(){
return this.format.match(/svg/i)
}
};
var Svg = function(size, foreground, background){
this.size = size;
this.foreground = this.color.apply(this, foreground);
this.background = this.color.apply(this, background);
this.rectangles = [];
};
Svg.prototype = {
size: null,
foreground: null,
background: null,
rectangles: null,
color: function(r, g, b, a){
var values = [r, g, b].map(Math.round);
values.push((a >= 0) && (a <= 255) ? a/255 : 1);
return 'rgba(' + values.join(',') + ')';
},
getDump: function(){
var i,
xml,
rect,
fg = this.foreground,
bg = this.background,
stroke = this.size * 0.005;
xml = "<svg xmlns='http://www.w3.org/2000/svg'"
+ " width='" + this.size + "' height='" + this.size + "'"
+ " style='background-color:" + bg + ";'>"
+ "<g style='fill:" + fg + "; stroke:" + fg + "; stroke-width:" + stroke + ";'>";
for (i = 0; i < this.rectangles.length; i++) {
rect = this.rectangles[i];
if (rect.color == bg) continue;
xml += "<rect "
+ " x='" + rect.x + "'"
+ " y='" + rect.y + "'"
+ " width='" + rect.w + "'"
+ " height='" + rect.h + "'"
+ "/>";
}
xml += "</g></svg>"
return xml;
},
getBase64: function(){
if ('function' === typeof btoa) {
return btoa(this.getDump());
} else if (Buffer) {
return new Buffer(this.getDump(), 'binary').toString('base64');
} else {
throw 'Cannot generate base64 output';
}
}
};
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
module.exports = Identicon;
} else {
window.Identicon = Identicon;
}
})();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

View File

@ -1,46 +0,0 @@
/*
Onionr - Private P2P Communication
Provides userIcon which generates SVG identicons from a Onionr user pubkey
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
function toHexString(byteArray) {
// cc-by-sa-4 https://stackoverflow.com/a/44608819 by https://stackoverflow.com/users/1883624/grantpatterson
var s = '0x'
byteArray.forEach(function(byte) {
s += ('0' + (byte & 0xFF).toString(16)).slice(-2)
})
return s
}
async function sha256(str) {
const buf = await crypto.subtle.digest("SHA-256", new TextEncoder("utf-8").encode(str))
return Array.prototype.map.call(new Uint8Array(buf), x=>(('00'+x.toString(16)).slice(-2))).join('')
}
async function userIcon(pubkey, imgSize=64){
pubkey = await sha256(base32.decode.asBytes(pubkey))
let options = {
//foreground: [0,0,0,1], // rgba black
background: [0, 0, 0, 0], // rgba white
//margin: 0.1,
size: imgSize,
format: 'svg' // use SVG instead of PNG
};
// create a base64 encoded SVG
let data = new Identicon(pubkey, options).toString();
return data
}