Compare commits
3 Commits
2eea681e98
...
015a072b0b
Author | SHA1 | Date | |
---|---|---|---|
![]() |
015a072b0b | ||
![]() |
5ae5897703 | ||
![]() |
e9efffff34 |
12
AUTHORS.MD
12
AUTHORS.MD
@ -1,12 +0,0 @@
|
|||||||
# Incomplete List of Contributors
|
|
||||||
|
|
||||||
Onionr is created by a team of hard working volunteers.
|
|
||||||
|
|
||||||
In no order of importance, these people make Onionr happen:
|
|
||||||
|
|
||||||
* [Beardog (Kevin Froman)](https://www.chaoswebs.net/) - Project founder, owner and core developer
|
|
||||||
* [InvisaMage](https://invisamage.com/) - Web UI Bulma design
|
|
||||||
* [Arinerron](https://arinerron.com/) - Logger and config modules, testing and other contributions
|
|
||||||
* [Anhar Ismail](https://github.com/anharismail) - Created Onionr's logo
|
|
||||||
|
|
||||||
+ Other contributors and testers
|
|
@ -64,6 +64,8 @@ def sigusr_stacktrace(signum, frame):
|
|||||||
|
|
||||||
signal.signal(signal.SIGUSR1, sigusr_stacktrace)
|
signal.signal(signal.SIGUSR1, sigusr_stacktrace)
|
||||||
|
|
||||||
|
# Importing initailzes logging
|
||||||
|
from logger import log as logging
|
||||||
|
|
||||||
ran_as_script = False
|
ran_as_script = False
|
||||||
if __name__ == "__main__": ran_as_script = True
|
if __name__ == "__main__": ran_as_script = True
|
||||||
|
@ -2,7 +2,7 @@ from typing import Set
|
|||||||
|
|
||||||
from onionrblocks import Block
|
from onionrblocks import Block
|
||||||
|
|
||||||
import logger
|
from logger import log as logging
|
||||||
|
|
||||||
from .deleteblock import delete_block
|
from .deleteblock import delete_block
|
||||||
from .getblocks import get_blocks_after_timestamp
|
from .getblocks import get_blocks_after_timestamp
|
||||||
@ -18,7 +18,7 @@ def clean_block_database():
|
|||||||
Block(block.id, block.raw, auto_verify=True)
|
Block(block.id, block.raw, auto_verify=True)
|
||||||
except ValueError: # block expired
|
except ValueError: # block expired
|
||||||
remove_set.add(block)
|
remove_set.add(block)
|
||||||
|
|
||||||
if len(remove_set):
|
if len(remove_set):
|
||||||
logger.info(f"Cleaning {len(remove_set)} blocks", terminal=True)
|
logging.info(f"Cleaning {len(remove_set)} blocks")
|
||||||
[i for i in map(delete_block, remove_set)]
|
[i for i in map(delete_block, remove_set)]
|
||||||
|
@ -6,7 +6,7 @@ import os
|
|||||||
from json import JSONDecodeError
|
from json import JSONDecodeError
|
||||||
|
|
||||||
import ujson as json
|
import ujson as json
|
||||||
import logger
|
from logger import log as logging
|
||||||
import filepaths
|
import filepaths
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -106,7 +106,7 @@ def save():
|
|||||||
with open(get_config_file(), 'w', encoding="utf8") as configfile:
|
with open(get_config_file(), 'w', encoding="utf8") as configfile:
|
||||||
json.dump(get_config(), configfile, indent=2)
|
json.dump(get_config(), configfile, indent=2)
|
||||||
except JSONDecodeError:
|
except JSONDecodeError:
|
||||||
logger.warn('Failed to write to configuration file.')
|
logging.warn('Failed to write to configuration file.')
|
||||||
|
|
||||||
|
|
||||||
def reload():
|
def reload():
|
||||||
@ -117,7 +117,7 @@ def reload():
|
|||||||
set_config(json.loads(configfile.read()))
|
set_config(json.loads(configfile.read()))
|
||||||
except (FileNotFoundError, JSONDecodeError) as e:
|
except (FileNotFoundError, JSONDecodeError) as e:
|
||||||
pass
|
pass
|
||||||
#logger.debug('Failed to parse configuration file.')
|
#logging.debug('Failed to parse configuration file.')
|
||||||
|
|
||||||
|
|
||||||
def get_config():
|
def get_config():
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import threading
|
import threading
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from typing import TYPE_CHECKING, Set, Tuple
|
from typing import TYPE_CHECKING, Set, Tuple
|
||||||
|
from logger import log as logging
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ordered_set import OrderedSet
|
from ordered_set import OrderedSet
|
||||||
@ -11,7 +12,6 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
from onionrthreads import add_onionr_thread
|
from onionrthreads import add_onionr_thread
|
||||||
import onionrplugins
|
import onionrplugins
|
||||||
import logger
|
|
||||||
|
|
||||||
from .connectpeer import connect_peer
|
from .connectpeer import connect_peer
|
||||||
from .client import start_gossip_client
|
from .client import start_gossip_client
|
||||||
@ -56,4 +56,4 @@ def start_gossip_threads():
|
|||||||
sleep(60)
|
sleep(60)
|
||||||
if len(gossip_peer_set):
|
if len(gossip_peer_set):
|
||||||
return
|
return
|
||||||
logger.error("Could not connect to any peers :(", terminal=True)
|
logging.error("Could not connect to any peers :(")
|
||||||
|
@ -21,7 +21,7 @@ if TYPE_CHECKING:
|
|||||||
from ..peer import Peer
|
from ..peer import Peer
|
||||||
from ordered_set import OrderedSet
|
from ordered_set import OrderedSet
|
||||||
|
|
||||||
import logger
|
from logger import log as logging
|
||||||
import config
|
import config
|
||||||
import onionrplugins
|
import onionrplugins
|
||||||
from ..commands import GossipCommands
|
from ..commands import GossipCommands
|
||||||
@ -61,20 +61,20 @@ def block_queue_processing():
|
|||||||
while not len(gossip_peer_set):
|
while not len(gossip_peer_set):
|
||||||
sleep(1)
|
sleep(1)
|
||||||
if dandelion_phase.remaining_time() <= 15:
|
if dandelion_phase.remaining_time() <= 15:
|
||||||
#logger.debug("Sleeping", terminal=True)
|
#logging.debug("Sleeping")
|
||||||
sleep(dandelion_phase.remaining_time())
|
sleep(dandelion_phase.remaining_time())
|
||||||
if dandelion_phase.is_stem_phase() and config.get('security.dandelion.enabled', True):
|
if dandelion_phase.is_stem_phase() and config.get('security.dandelion.enabled', True):
|
||||||
logger.debug("Entering stem phase", terminal=True)
|
logging.debug("Entering stem phase")
|
||||||
try:
|
try:
|
||||||
# Stem out blocks for (roughly) remaining epoch time
|
# Stem out blocks for (roughly) remaining epoch time
|
||||||
asyncio.run(stem_out(dandelion_phase))
|
asyncio.run(stem_out(dandelion_phase))
|
||||||
except TimeoutError:
|
except TimeoutError:
|
||||||
pass
|
pass
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.error(traceback.format_exc(), terminal=True)
|
logging.error(traceback.format_exc())
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
#logger.debug("Entering fluff phase", terminal=True)
|
#logging.debug("Entering fluff phase")
|
||||||
# Add block to primary block db, where the diffuser can read it
|
# Add block to primary block db, where the diffuser can read it
|
||||||
sleep(0.1)
|
sleep(0.1)
|
||||||
store_blocks(dandelion_phase)
|
store_blocks(dandelion_phase)
|
||||||
|
@ -5,7 +5,7 @@ from typing import TYPE_CHECKING
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .. import Peer
|
from .. import Peer
|
||||||
|
|
||||||
import logger
|
from logger import log as logging
|
||||||
import onionrplugins
|
import onionrplugins
|
||||||
|
|
||||||
from ..commands import GossipCommands, command_to_byte
|
from ..commands import GossipCommands, command_to_byte
|
||||||
@ -28,7 +28,7 @@ def do_announce():
|
|||||||
sock.sendall(command_to_byte(GossipCommands.ANNOUNCE))
|
sock.sendall(command_to_byte(GossipCommands.ANNOUNCE))
|
||||||
sock.sendall(our_transport_address)
|
sock.sendall(our_transport_address)
|
||||||
if int.from_bytes(sock.recv(1), 'big') != 1:
|
if int.from_bytes(sock.recv(1), 'big') != 1:
|
||||||
logger.warn(
|
logging.warn(
|
||||||
f"Could not announce with {announce_peer.transport_address}")
|
f"Could not announce with {announce_peer.transport_address}")
|
||||||
sock.close()
|
sock.close()
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ from ordered_set import OrderedSet
|
|||||||
import config
|
import config
|
||||||
from onionrthreads import add_delayed_thread
|
from onionrthreads import add_delayed_thread
|
||||||
from blockdb import add_block_to_db
|
from blockdb import add_block_to_db
|
||||||
import logger
|
from logger import log as logging
|
||||||
|
|
||||||
from ...constants import BLACKHOLE_EVADE_TIMER_SECS, OUTBOUND_DANDELION_EDGES
|
from ...constants import BLACKHOLE_EVADE_TIMER_SECS, OUTBOUND_DANDELION_EDGES
|
||||||
from ...commands import GossipCommands, command_to_byte
|
from ...commands import GossipCommands, command_to_byte
|
||||||
@ -45,9 +45,9 @@ async def _setup_edge(
|
|||||||
try:
|
try:
|
||||||
s = peer.get_socket(12)
|
s = peer.get_socket(12)
|
||||||
except TimeoutError:
|
except TimeoutError:
|
||||||
logger.debug(f"{peer.transport_address} timed out when trying stemout")
|
logging.debug(f"{peer.transport_address} timed out when trying stemout")
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.debug(traceback.format_exc())
|
logging.debug(traceback.format_exc())
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -56,18 +56,18 @@ async def _setup_edge(
|
|||||||
if s.recv(1) == dandelion.StemAcceptResult.DENY:
|
if s.recv(1) == dandelion.StemAcceptResult.DENY:
|
||||||
raise StemConnectionDenied
|
raise StemConnectionDenied
|
||||||
except TimeoutError:
|
except TimeoutError:
|
||||||
logger.debug(
|
logging.debug(
|
||||||
"Peer timed out when establishing stem connection", terminal=True)
|
"Peer timed out when establishing stem connection")
|
||||||
logger.debug(traceback.format_exc())
|
logging.debug(traceback.format_exc())
|
||||||
except StemConnectionDenied:
|
except StemConnectionDenied:
|
||||||
logger.debug(
|
logging.debug(
|
||||||
"Stem connection denied (peer has too many) " +
|
"Stem connection denied (peer has too many) " +
|
||||||
f"{peer.transport_address}")
|
f"{peer.transport_address}")
|
||||||
logger.debug(traceback.format_exc())
|
logging.debug(traceback.format_exc())
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.warn(
|
logging.warn(
|
||||||
"Error asking peer to establish stem connection" +
|
"Error asking peer to establish stem connection" +
|
||||||
traceback.format_exc(), terminal=True)
|
traceback.format_exc())
|
||||||
else:
|
else:
|
||||||
# Return peer socket if it is in stem reception mode successfully
|
# Return peer socket if it is in stem reception mode successfully
|
||||||
return s
|
return s
|
||||||
@ -113,10 +113,10 @@ async def stem_out(d_phase: 'DandelionPhase'):
|
|||||||
await _setup_edge(gossip_peer_set, tried_edges))
|
await _setup_edge(gossip_peer_set, tried_edges))
|
||||||
except NotEnoughEdges:
|
except NotEnoughEdges:
|
||||||
# No possible edges at this point (edges < OUTBOUND_DANDELION_EDGE)
|
# No possible edges at this point (edges < OUTBOUND_DANDELION_EDGE)
|
||||||
#logger.debug(
|
#logging.debug(
|
||||||
# "Making too few edges for stemout " +
|
# "Making too few edges for stemout " +
|
||||||
# "this is bad for anonymity if frequent.",
|
# "this is bad for anonymity if frequent.",
|
||||||
# terminal=True)
|
# )
|
||||||
if strict_dandelion:
|
if strict_dandelion:
|
||||||
not_enough_edges = True
|
not_enough_edges = True
|
||||||
else:
|
else:
|
||||||
@ -133,10 +133,10 @@ async def stem_out(d_phase: 'DandelionPhase'):
|
|||||||
else:
|
else:
|
||||||
# Ran out of time for stem phase
|
# Ran out of time for stem phase
|
||||||
if not d_phase.is_stem_phase() or d_phase.remaining_time() < 5:
|
if not d_phase.is_stem_phase() or d_phase.remaining_time() < 5:
|
||||||
logger.error(
|
logging.error(
|
||||||
"Did not stem out any blocks in time, " +
|
"Did not stem out any blocks in time, " +
|
||||||
"if this happens regularly you may be under attack",
|
"if this happens regularly you may be under attack",
|
||||||
terminal=False)
|
)
|
||||||
for s in peer_sockets:
|
for s in peer_sockets:
|
||||||
if s:
|
if s:
|
||||||
s.close()
|
s.close()
|
||||||
@ -155,7 +155,7 @@ async def stem_out(d_phase: 'DandelionPhase'):
|
|||||||
except Empty:
|
except Empty:
|
||||||
pass
|
pass
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.warn(traceback.format_exc())
|
logging.warn(traceback.format_exc())
|
||||||
else:
|
else:
|
||||||
# stream routine exited early
|
# stream routine exited early
|
||||||
pass
|
pass
|
||||||
|
@ -4,7 +4,7 @@ from queue import Empty
|
|||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import logger
|
from logger import log as logging
|
||||||
from ...constants import BLOCK_ID_SIZE, BLOCK_MAX_SIZE, BLOCK_SIZE_LEN
|
from ...constants import BLOCK_ID_SIZE, BLOCK_MAX_SIZE, BLOCK_SIZE_LEN
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@ -22,7 +22,7 @@ async def do_stem_stream(
|
|||||||
remaining_time = d_phase.remaining_time()
|
remaining_time = d_phase.remaining_time()
|
||||||
my_phase_id = d_phase.phase_id
|
my_phase_id = d_phase.phase_id
|
||||||
|
|
||||||
|
|
||||||
while remaining_time > 1 and my_phase_id == d_phase.phase_id:
|
while remaining_time > 1 and my_phase_id == d_phase.phase_id:
|
||||||
# Primary client component that communicate's with gossip.server.acceptstem
|
# Primary client component that communicate's with gossip.server.acceptstem
|
||||||
remaining_time = d_phase.remaining_time()
|
remaining_time = d_phase.remaining_time()
|
||||||
@ -35,7 +35,7 @@ async def do_stem_stream(
|
|||||||
await sleep(1)
|
await sleep(1)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
logger.info("Sending block over dandelion++", terminal=True)
|
logging.info("Sending block over dandelion++")
|
||||||
|
|
||||||
block_size = str(len(bl.raw)).zfill(BLOCK_SIZE_LEN)
|
block_size = str(len(bl.raw)).zfill(BLOCK_SIZE_LEN)
|
||||||
def _send_it():
|
def _send_it():
|
||||||
|
@ -6,7 +6,7 @@ if TYPE_CHECKING:
|
|||||||
from socket import socket
|
from socket import socket
|
||||||
|
|
||||||
from onionrplugins import onionrevents
|
from onionrplugins import onionrevents
|
||||||
import logger
|
from logger import log as logging
|
||||||
|
|
||||||
from socks import GeneralProxyError
|
from socks import GeneralProxyError
|
||||||
|
|
||||||
@ -23,9 +23,9 @@ def _do_ask_peer(peer):
|
|||||||
try:
|
try:
|
||||||
_ask_peer(peer)
|
_ask_peer(peer)
|
||||||
except TimeoutError:
|
except TimeoutError:
|
||||||
logger.debug("Timed out when asking for new peers")
|
logging.debug("Timed out when asking for new peers")
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.error(format_exc(), terminal=True)
|
logging.error(format_exc())
|
||||||
|
|
||||||
def _ask_peer(peer):
|
def _ask_peer(peer):
|
||||||
s: 'socket' = peer.get_socket(12)
|
s: 'socket' = peer.get_socket(12)
|
||||||
@ -46,14 +46,14 @@ def _ask_peer(peer):
|
|||||||
'address': peer,
|
'address': peer,
|
||||||
'callback': connectpeer.connect_peer
|
'callback': connectpeer.connect_peer
|
||||||
}
|
}
|
||||||
#logger.info("Got new peer from exchange " + peer.decode('utf-8'), terminal=True)
|
#logging.info("Got new peer from exchange " + peer.decode('utf-8'))
|
||||||
onionrevents.event('announce_rec', data=connect_data, threaded=True)
|
onionrevents.event('announce_rec', data=connect_data, threaded=True)
|
||||||
s.close()
|
s.close()
|
||||||
|
|
||||||
|
|
||||||
def get_new_peers():
|
def get_new_peers():
|
||||||
if not len(gossip_peer_set):
|
if not len(gossip_peer_set):
|
||||||
logger.debug("Peer set empty, cannot get new peers")
|
logging.debug("Peer set empty, cannot get new peers")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Deep copy the peer list
|
# Deep copy the peer list
|
||||||
|
@ -22,7 +22,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
from ordered_set import OrderedSet
|
from ordered_set import OrderedSet
|
||||||
|
|
||||||
import logger
|
from logger import log as logging
|
||||||
|
|
||||||
import onionrblocks
|
import onionrblocks
|
||||||
from ...peerset import gossip_peer_set
|
from ...peerset import gossip_peer_set
|
||||||
@ -71,7 +71,7 @@ def stream_from_peers():
|
|||||||
need_socket_lock.release()
|
need_socket_lock.release()
|
||||||
return
|
return
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.warn(traceback.format_exc(), terminal=True)
|
logging.warn(traceback.format_exc())
|
||||||
need_socket_lock.release()
|
need_socket_lock.release()
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
@ -83,7 +83,7 @@ def stream_from_peers():
|
|||||||
|
|
||||||
while stream_times >= stream_counter:
|
while stream_times >= stream_counter:
|
||||||
stream_counter += 1
|
stream_counter += 1
|
||||||
#logger.debug("Reading block of id in stream with " + peer.transport_address, terminal=True)
|
#logging.debug("Reading block of id in stream with " + peer.transport_address)
|
||||||
sock.settimeout(5)
|
sock.settimeout(5)
|
||||||
block_id = sock.recv(BLOCK_ID_SIZE)
|
block_id = sock.recv(BLOCK_ID_SIZE)
|
||||||
if blockdb.has_block(block_id):
|
if blockdb.has_block(block_id):
|
||||||
@ -91,12 +91,12 @@ def stream_from_peers():
|
|||||||
continue
|
continue
|
||||||
sock.sendall(int(1).to_bytes(1, 'big'))
|
sock.sendall(int(1).to_bytes(1, 'big'))
|
||||||
|
|
||||||
#logger.debug("Reading block size in stream", terminal=True)
|
#logging.debug("Reading block size in stream")
|
||||||
|
|
||||||
sock.settimeout(5)
|
sock.settimeout(5)
|
||||||
block_size = int(sock.recv(BLOCK_SIZE_LEN))
|
block_size = int(sock.recv(BLOCK_SIZE_LEN))
|
||||||
if block_size > BLOCK_MAX_SIZE or block_size <= 0:
|
if block_size > BLOCK_MAX_SIZE or block_size <= 0:
|
||||||
logger.warn(
|
logging.warn(
|
||||||
f"Peer {peer.transport_address} " +
|
f"Peer {peer.transport_address} " +
|
||||||
"reported block size out of range")
|
"reported block size out of range")
|
||||||
break
|
break
|
||||||
@ -104,9 +104,9 @@ def stream_from_peers():
|
|||||||
sock.settimeout(5)
|
sock.settimeout(5)
|
||||||
block_data = sock.recv(block_size)
|
block_data = sock.recv(block_size)
|
||||||
|
|
||||||
#logger.debug(
|
#logging.debug(
|
||||||
# "We got a block from stream, assuming it is valid",
|
# "We got a block from stream, assuming it is valid",
|
||||||
# terminal=True)
|
# )
|
||||||
try:
|
try:
|
||||||
blockdb.add_block_to_db(
|
blockdb.add_block_to_db(
|
||||||
onionrblocks.Block(
|
onionrblocks.Block(
|
||||||
@ -120,10 +120,10 @@ def stream_from_peers():
|
|||||||
sock.sendall(int(1).to_bytes(1, 'big'))
|
sock.sendall(int(1).to_bytes(1, 'big'))
|
||||||
except (BrokenPipeError, TimeoutError, ConnectionError) as e:
|
except (BrokenPipeError, TimeoutError, ConnectionError) as e:
|
||||||
pass
|
pass
|
||||||
#logger.debug(f"{e} when streaming from peers", terminal=True)
|
#logging.debug(f"{e} when streaming from peers")
|
||||||
#logger.debug(traceback.format_exc())
|
#logging.debug(traceback.format_exc())
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.warn(traceback.format_exc(), terminal=True)
|
logging.warn(traceback.format_exc())
|
||||||
finally:
|
finally:
|
||||||
sock.close()
|
sock.close()
|
||||||
need_socket_lock.release()
|
need_socket_lock.release()
|
||||||
|
@ -2,7 +2,7 @@ import traceback
|
|||||||
from gossip.commands import GossipCommands, command_to_byte
|
from gossip.commands import GossipCommands, command_to_byte
|
||||||
from .peerset import gossip_peer_set
|
from .peerset import gossip_peer_set
|
||||||
|
|
||||||
import logger
|
from logger import log as logging
|
||||||
|
|
||||||
|
|
||||||
def connect_peer(peer):
|
def connect_peer(peer):
|
||||||
@ -11,12 +11,12 @@ def connect_peer(peer):
|
|||||||
try:
|
try:
|
||||||
s = peer.get_socket(120)
|
s = peer.get_socket(120)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.warn(f"Could not connect to {peer.transport_address}")
|
logging.warn(f"Could not connect to {peer.transport_address}")
|
||||||
logger.warn(traceback.format_exc())
|
logging.warn(traceback.format_exc())
|
||||||
else:
|
else:
|
||||||
with s:
|
with s:
|
||||||
s.sendall(command_to_byte(GossipCommands.PING))
|
s.sendall(command_to_byte(GossipCommands.PING))
|
||||||
|
|
||||||
if s.recv(4).decode('utf-8') == 'PONG':
|
if s.recv(4).decode('utf-8') == 'PONG':
|
||||||
gossip_peer_set.add(peer)
|
gossip_peer_set.add(peer)
|
||||||
logger.info(f"connected to {peer.transport_address}", terminal=True)
|
logging.info(f"connected to {peer.transport_address}")
|
||||||
|
@ -12,7 +12,7 @@ from gossip import constants
|
|||||||
from ..connectpeer import connect_peer
|
from ..connectpeer import connect_peer
|
||||||
|
|
||||||
from onionrplugins import onionrevents
|
from onionrplugins import onionrevents
|
||||||
import logger
|
from logger import log as logging
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from onionrblocks import Block
|
from onionrblocks import Block
|
||||||
@ -88,9 +88,9 @@ def gossip_server():
|
|||||||
try:
|
try:
|
||||||
await diffuse_blocks(reader, writer)
|
await diffuse_blocks(reader, writer)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.warn(
|
logging.warn(
|
||||||
f"Err streaming blocks\n{traceback.format_exc()}",
|
f"Err streaming blocks\n{traceback.format_exc()}",
|
||||||
terminal=True)
|
)
|
||||||
case GossipCommands.PUT_BLOCKS:
|
case GossipCommands.PUT_BLOCKS:
|
||||||
# Pick block queue & append stemmed blocks to it
|
# Pick block queue & append stemmed blocks to it
|
||||||
try:
|
try:
|
||||||
@ -99,18 +99,18 @@ def gossip_server():
|
|||||||
inbound_dandelion_edge_count)
|
inbound_dandelion_edge_count)
|
||||||
except asyncio.exceptions.TimeoutError:
|
except asyncio.exceptions.TimeoutError:
|
||||||
pass
|
pass
|
||||||
logger.debug(
|
logging.debug(
|
||||||
"Inbound edge timed out when steming blocks to us",
|
"Inbound edge timed out when steming blocks to us",
|
||||||
terminal=True)
|
)
|
||||||
except asyncio.exceptions.IncompleteReadError:
|
except asyncio.exceptions.IncompleteReadError:
|
||||||
pass
|
pass
|
||||||
logger.debug(
|
logging.debug(
|
||||||
"Inbound edge timed out (Incomplete Read) when steming blocks to us",
|
"Inbound edge timed out (Incomplete Read) when steming blocks to us",
|
||||||
terminal=True)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.warn(
|
logging.warn(
|
||||||
f"Err accepting stem blocks\n{traceback.format_exc()}",
|
f"Err accepting stem blocks\n{traceback.format_exc()}",
|
||||||
terminal=True)
|
)
|
||||||
# Subtract dandelion edge, make sure >=0
|
# Subtract dandelion edge, make sure >=0
|
||||||
inbound_dandelion_edge_count[0] = \
|
inbound_dandelion_edge_count[0] = \
|
||||||
max(inbound_dandelion_edge_count[0] - 1, 0)
|
max(inbound_dandelion_edge_count[0] - 1, 0)
|
||||||
|
@ -5,7 +5,7 @@ from asyncio import wait_for
|
|||||||
|
|
||||||
from onionrblocks import Block
|
from onionrblocks import Block
|
||||||
|
|
||||||
import logger
|
from logger import log as logging
|
||||||
from ..dandelion import StemAcceptResult
|
from ..dandelion import StemAcceptResult
|
||||||
from ..constants import BLOCK_ID_SIZE, BLOCK_SIZE_LEN, BLOCK_MAX_SIZE
|
from ..constants import BLOCK_ID_SIZE, BLOCK_SIZE_LEN, BLOCK_MAX_SIZE
|
||||||
from ..constants import MAX_INBOUND_DANDELION_EDGE, MAX_STEM_BLOCKS_PER_STREAM
|
from ..constants import MAX_INBOUND_DANDELION_EDGE, MAX_STEM_BLOCKS_PER_STREAM
|
||||||
@ -35,13 +35,13 @@ async def accept_stem_blocks(
|
|||||||
|
|
||||||
for _ in range(MAX_STEM_BLOCKS_PER_STREAM):
|
for _ in range(MAX_STEM_BLOCKS_PER_STREAM):
|
||||||
read_routine = reader.readexactly(BLOCK_ID_SIZE)
|
read_routine = reader.readexactly(BLOCK_ID_SIZE)
|
||||||
#logger.debug(f"Reading block id in stem server", terminal=True)
|
#logging.debug(f"Reading block id in stem server")
|
||||||
block_id = await wait_for(read_routine, base_wait_timeout)
|
block_id = await wait_for(read_routine, base_wait_timeout)
|
||||||
block_id = block_id.decode('utf-8')
|
block_id = block_id.decode('utf-8')
|
||||||
if not block_id:
|
if not block_id:
|
||||||
break
|
break
|
||||||
|
|
||||||
#logger.debug(f"Reading block size in stem server", terminal=True)
|
#logging.debug(f"Reading block size in stem server")
|
||||||
block_size = (await wait_for(
|
block_size = (await wait_for(
|
||||||
reader.readexactly(BLOCK_SIZE_LEN),
|
reader.readexactly(BLOCK_SIZE_LEN),
|
||||||
base_wait_timeout)).decode('utf-8')
|
base_wait_timeout)).decode('utf-8')
|
||||||
@ -54,14 +54,14 @@ async def accept_stem_blocks(
|
|||||||
if block_size > BLOCK_MAX_SIZE:
|
if block_size > BLOCK_MAX_SIZE:
|
||||||
raise ValueError("Max block size")
|
raise ValueError("Max block size")
|
||||||
|
|
||||||
#logger.debug(f"Reading block of size {block_size} in stem server", terminal=True)
|
#logging.debug(f"Reading block of size {block_size} in stem server")
|
||||||
|
|
||||||
raw_block: bytes = await wait_for(
|
raw_block: bytes = await wait_for(
|
||||||
reader.readexactly(block_size), base_wait_timeout * 6)
|
reader.readexactly(block_size), base_wait_timeout * 6)
|
||||||
if not raw_block:
|
if not raw_block:
|
||||||
break
|
break
|
||||||
|
|
||||||
logger.debug("Got a stem block, put into queue", terminal=True)
|
logging.debug("Got a stem block, put into queue")
|
||||||
block_queue_to_use.put(
|
block_queue_to_use.put(
|
||||||
Block(block_id, raw_block, auto_verify=True)
|
Block(block_id, raw_block, auto_verify=True)
|
||||||
)
|
)
|
||||||
|
@ -19,7 +19,7 @@ if TYPE_CHECKING:
|
|||||||
from ..constants import BLOCK_MAX_SIZE, BLOCK_SIZE_LEN
|
from ..constants import BLOCK_MAX_SIZE, BLOCK_SIZE_LEN
|
||||||
from ..constants import BLOCK_STREAM_OFFSET_DIGITS
|
from ..constants import BLOCK_STREAM_OFFSET_DIGITS
|
||||||
|
|
||||||
import logger
|
from logger import log as logging
|
||||||
import blockdb
|
import blockdb
|
||||||
from blockdb import get_blocks_after_timestamp, block_storage_observers
|
from blockdb import get_blocks_after_timestamp, block_storage_observers
|
||||||
"""
|
"""
|
||||||
@ -103,5 +103,5 @@ async def diffuse_blocks(reader: 'StreamReader', writer: 'StreamWriter'):
|
|||||||
except ConnectionResetError:
|
except ConnectionResetError:
|
||||||
pass
|
pass
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.warn(traceback.format_exc(), terminal=True)
|
logging.warn(traceback.format_exc())
|
||||||
|
|
||||||
|
@ -1,71 +1,92 @@
|
|||||||
'''
|
"""
|
||||||
Onionr - Private P2P Communication
|
Onionr - Private P2P Communication
|
||||||
|
|
||||||
This file handles all operations involving logging
|
We use built in logging but with a custom formatter for colors and such
|
||||||
'''
|
"""
|
||||||
'''
|
import logging
|
||||||
This program is free software: you can redistribute it and/or modify
|
import sys
|
||||||
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,
|
from filepaths import log_file
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
"""
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
This program is free software: you can redistribute it and/or modify
|
||||||
GNU General Public License for more details.
|
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.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
This program is distributed in the hope that it will be useful,
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
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.
|
||||||
|
|
||||||
import sys, traceback
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
"""
|
||||||
|
|
||||||
from . import colors, readline, log, raw, confirm, colors, settings
|
# credit: https://stackoverflow.com/a/384076
|
||||||
colors = colors.Colors
|
# license: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
readline = readline.readline
|
class ConsoleFormatter(logging.Formatter):
|
||||||
log = log.log
|
|
||||||
raw = raw.raw
|
|
||||||
confirm = confirm.confirm
|
|
||||||
|
|
||||||
# debug: when there is info that could be useful for debugging purposes only
|
grey = "\x1b[38;20m"
|
||||||
def debug(data: str, error = None, timestamp = True, prompt = True, terminal = False, level = settings.LEVEL_DEBUG):
|
green = "\x1b[38;5;82m"
|
||||||
if settings.get_level() <= level:
|
yellow = "\x1b[33;20m"
|
||||||
log('/', data, timestamp = timestamp, prompt = prompt, terminal = terminal)
|
red = "\x1b[31;20m"
|
||||||
if not error is None:
|
bold_red = "\x1b[31;1m"
|
||||||
debug('Error: ' + str(error) + parse_error())
|
reset = "\x1b[0m"
|
||||||
|
format_default = "%(levelname)s - %(message)s (%(filename)s:%(lineno)d)"
|
||||||
|
format_info = "%(message)s - (%(filename)s:%(lineno)d)"
|
||||||
|
|
||||||
# info: when there is something to notify the user of, such as the success of a process
|
FORMATS = {
|
||||||
def info(data: str, timestamp = False, prompt = True, terminal = False, level = settings.LEVEL_INFO):
|
logging.DEBUG: grey + format_default + reset,
|
||||||
if settings.get_level() <= level:
|
logging.INFO: green + format_info + reset,
|
||||||
log('+', data, colors.fg.green, timestamp = timestamp, prompt = prompt, terminal = terminal)
|
logging.WARNING: yellow + format_default + reset,
|
||||||
|
logging.ERROR: red + format_default + reset,
|
||||||
|
logging.CRITICAL: bold_red + format_default + reset
|
||||||
|
}
|
||||||
|
|
||||||
# warn: when there is a potential for something bad to happen
|
def format(self, record):
|
||||||
def warn(data: str, error = None, timestamp = True, prompt = True, terminal = False, level = settings.LEVEL_WARN):
|
log_fmt = self.FORMATS.get(record.levelno)
|
||||||
if not error is None:
|
formatter = logging.Formatter(log_fmt)
|
||||||
debug('Error: ' + str(error) + parse_error())
|
return formatter.format(record)
|
||||||
if settings.get_level() <= level:
|
|
||||||
log('!', data, colors.fg.orange, timestamp = timestamp, prompt = prompt, terminal = terminal)
|
|
||||||
|
|
||||||
# error: when only one function, module, or process of the program encountered a problem and must stop
|
class FileFormatter(logging.Formatter):
|
||||||
def error(data: str, error = None, timestamp = True, prompt = True, terminal = False, level = settings.LEVEL_ERROR):
|
|
||||||
if settings.get_level() <= level:
|
|
||||||
log('-', data, colors.fg.red, timestamp = timestamp, fd = sys.stderr, prompt = prompt, terminal = terminal)
|
|
||||||
if not error is None:
|
|
||||||
debug('Error: ' + str(error) + parse_error())
|
|
||||||
|
|
||||||
# fatal: when the something so bad has happened that the program must stop
|
|
||||||
def fatal(data: str, error = None, timestamp=True, prompt = True, terminal = False, level = settings.LEVEL_FATAL):
|
|
||||||
if not error is None:
|
|
||||||
debug('Error: ' + str(error) + parse_error(), terminal = terminal)
|
|
||||||
if settings.get_level() <= level:
|
|
||||||
log('#', data, colors.bg.red + colors.fg.green + colors.bold, timestamp = timestamp, fd = sys.stderr, prompt = prompt, terminal = terminal)
|
|
||||||
|
|
||||||
# returns a formatted error message
|
format_default = "%(levelname)s - %(message)s (%(filename)s:%(lineno)d)"
|
||||||
def parse_error():
|
format_info = "%(message)s - (%(filename)s:%(lineno)d)"
|
||||||
details = traceback.extract_tb(sys.exc_info()[2])
|
|
||||||
output = ''
|
|
||||||
|
|
||||||
for line in details:
|
FORMATS = {
|
||||||
output += '\n ... module %s in %s:%i' % (line[2], line[0], line[1])
|
logging.DEBUG: format_default,
|
||||||
|
logging.INFO: format_info,
|
||||||
|
logging.WARNING: format_default,
|
||||||
|
logging.ERROR: format_default,
|
||||||
|
logging.CRITICAL: format_default
|
||||||
|
}
|
||||||
|
|
||||||
return output
|
def format(self, record):
|
||||||
|
log_fmt = self.FORMATS.get(record.levelno)
|
||||||
|
formatter = logging.Formatter(log_fmt)
|
||||||
|
return formatter.format(record)
|
||||||
|
|
||||||
|
|
||||||
|
#logging.basicConfig(level=logging.ERROR, format='%(message)s ')
|
||||||
|
log = logging.getLogger('onionr')
|
||||||
|
log.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
ch = logging.StreamHandler(sys.stdout)
|
||||||
|
ch.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
ch.setFormatter(ConsoleFormatter())
|
||||||
|
|
||||||
|
|
||||||
|
def enable_file_logging():
|
||||||
|
fh = logging.FileHandler(log_file)
|
||||||
|
fh.setLevel(logging.INFO)
|
||||||
|
fh.setFormatter(FileFormatter())
|
||||||
|
log.addHandler(fh)
|
||||||
|
|
||||||
|
def disable_console_logging():
|
||||||
|
log.removeHandler(ch)
|
||||||
|
|
||||||
|
def enable_console_logging():
|
||||||
|
log.addHandler(ch)
|
||||||
|
enable_console_logging()
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
'''
|
|
||||||
Onionr - Private P2P Communication
|
|
||||||
|
|
||||||
class to access ANSI control codes
|
|
||||||
'''
|
|
||||||
'''
|
|
||||||
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 re
|
|
||||||
class Colors:
|
|
||||||
'''
|
|
||||||
This class allows you to set the color if ANSI codes are supported
|
|
||||||
'''
|
|
||||||
reset='\033[0m'
|
|
||||||
bold='\033[01m'
|
|
||||||
disable='\033[02m'
|
|
||||||
underline='\033[04m'
|
|
||||||
reverse='\033[07m'
|
|
||||||
strikethrough='\033[09m'
|
|
||||||
invisible='\033[08m'
|
|
||||||
italics='\033[3m'
|
|
||||||
class fg:
|
|
||||||
black='\033[30m'
|
|
||||||
red='\033[31m'
|
|
||||||
green='\033[32m'
|
|
||||||
orange='\033[33m'
|
|
||||||
blue='\033[34m'
|
|
||||||
purple='\033[35m'
|
|
||||||
cyan='\033[36m'
|
|
||||||
lightgrey='\033[37m'
|
|
||||||
darkgrey='\033[90m'
|
|
||||||
lightred='\033[91m'
|
|
||||||
lightgreen='\033[92m'
|
|
||||||
yellow='\033[93m'
|
|
||||||
lightblue='\033[94m'
|
|
||||||
pink='\033[95m'
|
|
||||||
lightcyan='\033[96m'
|
|
||||||
class bg:
|
|
||||||
black='\033[40m'
|
|
||||||
red='\033[41m'
|
|
||||||
green='\033[42m'
|
|
||||||
orange='\033[43m'
|
|
||||||
blue='\033[44m'
|
|
||||||
purple='\033[45m'
|
|
||||||
cyan='\033[46m'
|
|
||||||
lightgrey='\033[47m'
|
|
||||||
@staticmethod
|
|
||||||
def filter(data):
|
|
||||||
return re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]').sub('', str(data))
|
|
@ -1,54 +0,0 @@
|
|||||||
'''
|
|
||||||
Onionr - Private P2P Communication
|
|
||||||
|
|
||||||
confirm y/n cli prompt
|
|
||||||
'''
|
|
||||||
'''
|
|
||||||
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 sys
|
|
||||||
from . import colors, settings
|
|
||||||
colors = colors.Colors
|
|
||||||
def confirm(default = 'y', message = 'Are you sure %s? '):
|
|
||||||
'''
|
|
||||||
Displays an "Are you sure" message, returns True for Y and False for N
|
|
||||||
message: The confirmation message, use %s for (y/n)
|
|
||||||
default: which to prefer-- y or n
|
|
||||||
'''
|
|
||||||
|
|
||||||
color = colors.fg.green + colors.bold
|
|
||||||
|
|
||||||
default = default.lower()
|
|
||||||
confirm = colors.bold
|
|
||||||
if default.startswith('y'):
|
|
||||||
confirm += '(Y/n)'
|
|
||||||
else:
|
|
||||||
confirm += '(y/N)'
|
|
||||||
confirm += colors.reset + color
|
|
||||||
|
|
||||||
output = colors.reset + str(color) + '... ' + colors.reset + str(message) + colors.reset
|
|
||||||
|
|
||||||
if not get_settings() & settings.USE_ANSI:
|
|
||||||
output = colors.filter(output)
|
|
||||||
|
|
||||||
sys.stdout.write(output.replace('%s', confirm))
|
|
||||||
|
|
||||||
inp = input().lower()
|
|
||||||
|
|
||||||
if 'y' in inp:
|
|
||||||
return True
|
|
||||||
if 'n' in inp:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return default == 'y'
|
|
@ -1,38 +0,0 @@
|
|||||||
'''
|
|
||||||
Onionr - Private P2P Communication
|
|
||||||
|
|
||||||
god log function
|
|
||||||
'''
|
|
||||||
'''
|
|
||||||
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 sys, time
|
|
||||||
from . import colors, raw, settings
|
|
||||||
colors = colors.Colors
|
|
||||||
def log(prefix, data, color = '', timestamp=True, fd = sys.stdout, prompt = True, terminal = False):
|
|
||||||
'''
|
|
||||||
Logs the data
|
|
||||||
prefix : The prefix to the output
|
|
||||||
data : The actual data to output
|
|
||||||
color : The color to output before the data
|
|
||||||
'''
|
|
||||||
curTime = ''
|
|
||||||
if timestamp:
|
|
||||||
curTime = time.strftime("%m-%d %H:%M:%S") + ' '
|
|
||||||
|
|
||||||
output = colors.reset + str(color) + ('[' + colors.bold + str(prefix) + colors.reset + str(color) + '] ' if prompt is True else '') + curTime + str(data) + colors.reset
|
|
||||||
if not settings.get_settings() & settings.USE_ANSI:
|
|
||||||
output = colors.filter(output)
|
|
||||||
|
|
||||||
raw.raw(output, fd = fd, terminal = terminal)
|
|
@ -1,54 +0,0 @@
|
|||||||
"""Onionr - Private P2P Communication.
|
|
||||||
|
|
||||||
Output raw data to file or terminal
|
|
||||||
"""
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
from . import settings, colors
|
|
||||||
"""
|
|
||||||
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/>.
|
|
||||||
"""
|
|
||||||
colors = colors.Colors
|
|
||||||
|
|
||||||
|
|
||||||
def raw(data, fd = sys.stdout, terminal = False):
|
|
||||||
"""
|
|
||||||
Outputs raw data to console without formatting
|
|
||||||
"""
|
|
||||||
|
|
||||||
if terminal and (settings.get_settings() & settings.OUTPUT_TO_CONSOLE):
|
|
||||||
try:
|
|
||||||
ts = fd.write('%s\n' % data)
|
|
||||||
except OSError:
|
|
||||||
pass
|
|
||||||
if settings.get_settings() & settings.OUTPUT_TO_FILE:
|
|
||||||
fdata = ''
|
|
||||||
try:
|
|
||||||
for _ in range(5):
|
|
||||||
try:
|
|
||||||
with open(settings._outputfile, 'r') as file:
|
|
||||||
fdata = file.read()
|
|
||||||
except UnicodeDecodeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
except FileNotFoundError:
|
|
||||||
pass
|
|
||||||
fdata = fdata + '\n' + data
|
|
||||||
fdata = fdata.split('\n')
|
|
||||||
if len(fdata) >= settings.MAX_LOG_FILE_LINES:
|
|
||||||
fdata.pop(0)
|
|
||||||
fdata = '\n'.join(fdata)
|
|
||||||
with open(settings._outputfile, 'w') as file:
|
|
||||||
file.write(fdata)
|
|
@ -1,37 +0,0 @@
|
|||||||
'''
|
|
||||||
Onionr - Private P2P Communication
|
|
||||||
|
|
||||||
get a line of input from stdin
|
|
||||||
'''
|
|
||||||
'''
|
|
||||||
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 sys
|
|
||||||
from . import colors, settings
|
|
||||||
colors = colors.Colors
|
|
||||||
def readline(message = ''):
|
|
||||||
'''
|
|
||||||
Takes in input from the console, not stored in logs
|
|
||||||
message: The message to display before taking input
|
|
||||||
'''
|
|
||||||
|
|
||||||
color = colors.fg.green + colors.bold
|
|
||||||
output = colors.reset + str(color) + '... ' + colors.reset + str(message) + colors.reset
|
|
||||||
|
|
||||||
if not settings.get_settings() & settings.USE_ANSI:
|
|
||||||
output = colors.filter(output)
|
|
||||||
|
|
||||||
sys.stdout.write(output)
|
|
||||||
|
|
||||||
return input()
|
|
@ -1,89 +0,0 @@
|
|||||||
'''
|
|
||||||
Onionr - Private P2P Communication
|
|
||||||
|
|
||||||
logger settings
|
|
||||||
'''
|
|
||||||
'''
|
|
||||||
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 os
|
|
||||||
from utils import identifyhome
|
|
||||||
import filepaths
|
|
||||||
|
|
||||||
data_home = os.environ.get('ONIONR_LOG_DIR', identifyhome.identify_home())
|
|
||||||
# Use the bitwise operators to merge these settings
|
|
||||||
USE_ANSI = 0b100
|
|
||||||
if os.name == 'nt':
|
|
||||||
USE_ANSI = 0b000
|
|
||||||
OUTPUT_TO_CONSOLE = 0b010
|
|
||||||
OUTPUT_TO_FILE = 0b001
|
|
||||||
|
|
||||||
LEVEL_DEBUG = 1
|
|
||||||
LEVEL_INFO = 2
|
|
||||||
LEVEL_WARN = 3
|
|
||||||
LEVEL_ERROR = 4
|
|
||||||
LEVEL_FATAL = 5
|
|
||||||
LEVEL_IMPORTANT = 6
|
|
||||||
|
|
||||||
MAX_LOG_FILE_LINES = 10000
|
|
||||||
|
|
||||||
_type = OUTPUT_TO_CONSOLE | USE_ANSI # the default settings for logging
|
|
||||||
_level = LEVEL_DEBUG # the lowest level to log
|
|
||||||
# the file to log to
|
|
||||||
_outputfile = filepaths.log_file
|
|
||||||
|
|
||||||
def set_settings(type):
|
|
||||||
'''
|
|
||||||
Set the settings for the logger using bitwise operators
|
|
||||||
'''
|
|
||||||
|
|
||||||
global _type
|
|
||||||
_type = type
|
|
||||||
|
|
||||||
def get_settings():
|
|
||||||
'''
|
|
||||||
Get settings from the logger
|
|
||||||
'''
|
|
||||||
|
|
||||||
return _type
|
|
||||||
|
|
||||||
def set_level(level):
|
|
||||||
'''
|
|
||||||
Set the lowest log level to output
|
|
||||||
'''
|
|
||||||
|
|
||||||
global _level
|
|
||||||
_level = level
|
|
||||||
|
|
||||||
def get_level()->int:
|
|
||||||
'''
|
|
||||||
Get the lowest log level currently being outputted
|
|
||||||
'''
|
|
||||||
|
|
||||||
return _level
|
|
||||||
|
|
||||||
def set_file(outputfile):
|
|
||||||
'''
|
|
||||||
Set the file to output to, if enabled
|
|
||||||
'''
|
|
||||||
|
|
||||||
global _outputfile
|
|
||||||
_outputfile = outputfile
|
|
||||||
|
|
||||||
def get_file():
|
|
||||||
'''
|
|
||||||
Get the file to output to
|
|
||||||
'''
|
|
||||||
|
|
||||||
return _outputfile
|
|
@ -8,13 +8,14 @@ import sys
|
|||||||
import platform
|
import platform
|
||||||
import signal
|
import signal
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
from logger import log as logging
|
||||||
|
from logger import enable_file_logging
|
||||||
|
|
||||||
import filenuke
|
import filenuke
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
import config
|
import config
|
||||||
|
|
||||||
import logger
|
|
||||||
from onionrplugins import onionrevents as events
|
from onionrplugins import onionrevents as events
|
||||||
|
|
||||||
from utils import identifyhome
|
from utils import identifyhome
|
||||||
@ -59,16 +60,19 @@ def delete_run_files():
|
|||||||
_safe_remove(filepaths.pid_file)
|
_safe_remove(filepaths.pid_file)
|
||||||
|
|
||||||
def _show_info_messages():
|
def _show_info_messages():
|
||||||
version.version(verbosity=5, function=logger.info)
|
version.version(verbosity=5, function=logging.info)
|
||||||
logger.debug('Python version %s' % platform.python_version())
|
logging.debug('Python version %s' % platform.python_version())
|
||||||
|
|
||||||
if onionrvalues.DEVELOPMENT_MODE:
|
if onionrvalues.DEVELOPMENT_MODE:
|
||||||
logger.warn('Development mode enabled', timestamp=False, terminal=True)
|
logging.warn('Development mode enabled')
|
||||||
|
|
||||||
|
|
||||||
def daemon():
|
def daemon():
|
||||||
"""Start Onionr's primary threads for communicator, API server, node, and LAN."""
|
"""Start Onionr's primary threads for communicator, API server, node, and LAN."""
|
||||||
|
|
||||||
|
if config.get('log.file.output', False):
|
||||||
|
enable_file_logging()
|
||||||
|
|
||||||
def _handle_sig_term(signum, frame):
|
def _handle_sig_term(signum, frame):
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
@ -83,8 +87,8 @@ def daemon():
|
|||||||
security_level = config.get('general.security_level', 1)
|
security_level = config.get('general.security_level', 1)
|
||||||
|
|
||||||
_show_info_messages()
|
_show_info_messages()
|
||||||
logger.info(
|
logging.info(
|
||||||
f"Onionr daemon is running under pid {os.getpid()}", terminal=True)
|
f"Onionr daemon is running under pid {os.getpid()}")
|
||||||
events.event('init', threaded=False)
|
events.event('init', threaded=False)
|
||||||
events.event('afterinit', threaded=False)
|
events.event('afterinit', threaded=False)
|
||||||
events.event('daemon_start')
|
events.event('daemon_start')
|
||||||
@ -117,33 +121,25 @@ def start(override: bool = False):
|
|||||||
Error exit if there is and its not overridden
|
Error exit if there is and its not overridden
|
||||||
"""
|
"""
|
||||||
if os.path.exists(filepaths.lock_file) and not override:
|
if os.path.exists(filepaths.lock_file) and not override:
|
||||||
if os.path.exists(filepaths.restarting_indicator):
|
|
||||||
try:
|
|
||||||
os.remove(filepaths.restarting_indicator)
|
|
||||||
except FileNotFoundError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
with open(filepaths.lock_file, 'r') as lock_file:
|
with open(filepaths.lock_file, 'r') as lock_file:
|
||||||
try:
|
try:
|
||||||
proc = psutil.Process(int(lock_file.read())).name()
|
proc = psutil.Process(int(lock_file.read())).name()
|
||||||
except psutil.NoSuchProcess:
|
except psutil.NoSuchProcess:
|
||||||
proc = ""
|
proc = ""
|
||||||
if not proc.startswith("python"):
|
if not proc.startswith("python"):
|
||||||
logger.warn(
|
logging.warn(
|
||||||
f"Detected stale run file, deleting {filepaths.lock_file}",
|
f"Detected stale run file, deleting {filepaths.lock_file}")
|
||||||
terminal=True)
|
|
||||||
try:
|
try:
|
||||||
os.remove(filepaths.lock_file)
|
os.remove(filepaths.lock_file)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
pass
|
pass
|
||||||
start(override=True)
|
start(override=True)
|
||||||
return
|
return
|
||||||
logger.fatal('Cannot start. Daemon is already running,'
|
logging.error('Cannot start. Daemon is already running,'
|
||||||
+ ' or it did not exit cleanly.\n'
|
+ ' or it did not exit cleanly.\n'
|
||||||
+ ' (if you are sure that there is not a daemon running,'
|
+ ' (if you are sure that there is not a daemon running,'
|
||||||
+ f' delete {filepaths.lock_file} & try again).',
|
+ f' delete {filepaths.lock_file} & try again).',
|
||||||
terminal=True)
|
)
|
||||||
else:
|
else:
|
||||||
if not onionrvalues.DEVELOPMENT_MODE:
|
if not onionrvalues.DEVELOPMENT_MODE:
|
||||||
lock_file = open(filepaths.lock_file, 'w')
|
lock_file = open(filepaths.lock_file, 'w')
|
||||||
|
@ -6,7 +6,7 @@ import os
|
|||||||
from signal import SIGTERM
|
from signal import SIGTERM
|
||||||
|
|
||||||
from filepaths import pid_file
|
from filepaths import pid_file
|
||||||
import logger
|
from logger import log as logging
|
||||||
"""
|
"""
|
||||||
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
|
||||||
@ -29,9 +29,9 @@ def kill_daemon():
|
|||||||
with open(pid_file, 'r') as pid:
|
with open(pid_file, 'r') as pid:
|
||||||
os.kill(int(pid.read()), SIGTERM)
|
os.kill(int(pid.read()), SIGTERM)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
logger.error("Daemon not running/pid file missing")
|
logging.error("Daemon not running/pid file missing")
|
||||||
logger.warn('Stopping the running daemon, if one exists...', timestamp=False,
|
logging.warn('Stopping the running daemon, if one exists...', timestamp=False,
|
||||||
terminal=True)
|
)
|
||||||
|
|
||||||
|
|
||||||
kill_daemon.onionr_help = "Gracefully stops the " # type: ignore
|
kill_daemon.onionr_help = "Gracefully stops the " # type: ignore
|
||||||
|
@ -5,11 +5,12 @@ Show nice logo
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
import config
|
import config
|
||||||
import logger
|
|
||||||
|
|
||||||
from .quotes import QUOTE
|
from .quotes import QUOTE
|
||||||
from utils.boxprint import bordered
|
from utils.boxprint import bordered
|
||||||
from utils import logoheader
|
|
||||||
|
from utils import readstatic
|
||||||
|
import onionrvalues
|
||||||
"""
|
"""
|
||||||
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
|
||||||
@ -25,28 +26,34 @@ 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/>.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def header():
|
||||||
|
if onionrvalues.DEVELOPMENT_MODE:
|
||||||
|
return
|
||||||
|
|
||||||
|
pink_ansi = '\033[95m'
|
||||||
|
green_ansi = '\033[92m'
|
||||||
|
reset_ansi = '\x1b[0m'
|
||||||
|
|
||||||
|
logo = readstatic.read_static('header.txt', ret_bin=False)
|
||||||
|
logo = logo.replace('P', pink_ansi).replace('G', green_ansi).replace('W', reset_ansi)
|
||||||
|
print(reset_ansi + logo)
|
||||||
|
|
||||||
def show_logo():
|
def show_logo():
|
||||||
logger.raw('', terminal=True)
|
|
||||||
try:
|
try:
|
||||||
terminal_size = os.get_terminal_size().columns
|
terminal_size = os.get_terminal_size().columns
|
||||||
except OSError: # Generally thrown if not in terminal
|
except OSError: # Generally thrown if not in terminal
|
||||||
terminal_size = 120
|
terminal_size = 120
|
||||||
# print nice header thing :)
|
# print nice header thing :)
|
||||||
if config.get('general.display_header', True):
|
if config.get('general.display_header', True):
|
||||||
logoheader.header("")
|
header()
|
||||||
if terminal_size >= 120:
|
if terminal_size >= 120:
|
||||||
if QUOTE[1]: # If there is an author to show for the quote
|
if QUOTE[1]: # If there is an author to show for the quote
|
||||||
logger.info(
|
print("\u001b[33m\033[F" + bordered(QUOTE[0] + '\n -' + QUOTE[1]))
|
||||||
"\u001b[33m\033[F" + bordered(QUOTE[0] + '\n -' + QUOTE[1]),
|
|
||||||
terminal=True)
|
|
||||||
else:
|
else:
|
||||||
logger.info(
|
print("\u001b[33m\033[F" + bordered(QUOTE[0]))
|
||||||
"\u001b[33m\033[F" + bordered(QUOTE[0]), terminal=True)
|
|
||||||
else:
|
else:
|
||||||
if QUOTE[1]:
|
if QUOTE[1]:
|
||||||
logger.info("\u001b[33m\033[F" + QUOTE[0] + '\n -' + QUOTE[1],
|
print("\u001b[33m\033[F" + QUOTE[0] + '\n -' + QUOTE[1])
|
||||||
terminal=True)
|
|
||||||
else:
|
else:
|
||||||
logger.info("\u001b[33m\033[F" + QUOTE[0], terminal=True)
|
print("\u001b[33m\033[F" + QUOTE[0])
|
||||||
|
|
||||||
|
@ -1,141 +0,0 @@
|
|||||||
"""Onionr - Private P2P Communication.
|
|
||||||
|
|
||||||
This module defines commands to show stats/details about the local node
|
|
||||||
"""
|
|
||||||
import os
|
|
||||||
import logger
|
|
||||||
from utils import sizeutils, getconsolewidth, identifyhome
|
|
||||||
import config
|
|
||||||
import onionrvalues
|
|
||||||
from filepaths import lock_file
|
|
||||||
|
|
||||||
import psutil
|
|
||||||
"""
|
|
||||||
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 _is_running():
|
|
||||||
script = onionrvalues.SCRIPT_NAME
|
|
||||||
if os.path.isfile(lock_file):
|
|
||||||
for process in psutil.process_iter():
|
|
||||||
if process.name() == script:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def show_stats():
|
|
||||||
"""Print/log statistic info about our Onionr install."""
|
|
||||||
try:
|
|
||||||
# define stats messages here
|
|
||||||
home = identifyhome.identify_home()
|
|
||||||
|
|
||||||
|
|
||||||
messages = {
|
|
||||||
# info about local client
|
|
||||||
|
|
||||||
# This line is inaccurate if dev mode is enabled
|
|
||||||
'Onionr Daemon Status':
|
|
||||||
((logger.colors.fg.green + 'Online') \
|
|
||||||
if _is_running() \
|
|
||||||
else logger.colors.fg.red + 'Offline'),
|
|
||||||
|
|
||||||
# file and folder size stats
|
|
||||||
'div1': True, # this creates a solid line across the screen, a div
|
|
||||||
'Total Block Size':
|
|
||||||
sizeutils.human_size(sizeutils.size(home + 'blocks.db')),
|
|
||||||
'Total Plugin Size':
|
|
||||||
sizeutils.human_size(sizeutils.size(home + 'plugins/')),
|
|
||||||
'Log File Size':
|
|
||||||
sizeutils.human_size(sizeutils.size(home + 'output.log')),
|
|
||||||
|
|
||||||
# count stats
|
|
||||||
'div2': True,
|
|
||||||
'Enabled Plugins':
|
|
||||||
str(len(config.get('plugins.enabled', list()))) + ' / ' +
|
|
||||||
str(len(os.listdir(home + 'plugins/')))
|
|
||||||
}
|
|
||||||
|
|
||||||
# color configuration
|
|
||||||
colors = {
|
|
||||||
'title': logger.colors.bold,
|
|
||||||
'key': logger.colors.fg.lightgreen,
|
|
||||||
'val': logger.colors.fg.green,
|
|
||||||
'border': logger.colors.fg.lightblue,
|
|
||||||
|
|
||||||
'reset': logger.colors.reset
|
|
||||||
}
|
|
||||||
|
|
||||||
# pre-processing
|
|
||||||
maxlength = 0
|
|
||||||
width = getconsolewidth.get_console_width()
|
|
||||||
for key, val in messages.items():
|
|
||||||
if not (type(val) is bool and val is True):
|
|
||||||
maxlength = max(len(key), maxlength)
|
|
||||||
prewidth = maxlength + len(' | ')
|
|
||||||
groupsize = width - prewidth - len('[+] ')
|
|
||||||
|
|
||||||
# generate stats table
|
|
||||||
logger.info(colors['title'] + 'Onionr v%s Statistics' %
|
|
||||||
onionrvalues.ONIONR_VERSION + colors['reset'],
|
|
||||||
terminal=True)
|
|
||||||
logger.info(colors['border'] + '-' * (maxlength + 1) +
|
|
||||||
'+' + colors['reset'], terminal=True)
|
|
||||||
for key, val in messages.items():
|
|
||||||
if not (type(val) is bool and val is True):
|
|
||||||
val = [str(val)[i:i + groupsize]
|
|
||||||
for i in range(0, len(str(val)), groupsize)]
|
|
||||||
|
|
||||||
logger.info(colors['key'] + str(key).rjust(maxlength) +
|
|
||||||
colors['reset'] + colors['border'] +
|
|
||||||
' | ' + colors['reset'] + colors['val'] +
|
|
||||||
str(val.pop(0)) + colors['reset'], terminal=True)
|
|
||||||
|
|
||||||
for value in val:
|
|
||||||
logger.info(' ' * maxlength + colors['border'] + ' | ' +
|
|
||||||
colors['reset'] + colors['val'] + str(
|
|
||||||
value) + colors['reset'], terminal=True)
|
|
||||||
else:
|
|
||||||
logger.info(colors['border'] + '-' * (maxlength +
|
|
||||||
1) + '+' +
|
|
||||||
colors['reset'], terminal=True)
|
|
||||||
logger.info(colors['border'] + '-' * (maxlength + 1) +
|
|
||||||
'+' + colors['reset'], terminal=True)
|
|
||||||
except Exception as e: # pylint: disable=W0703
|
|
||||||
logger.error('Failed to generate statistics table. ' +
|
|
||||||
str(e), error=e, timestamp=False, terminal=True)
|
|
||||||
|
|
||||||
|
|
||||||
def show_details():
|
|
||||||
"""Print out details.
|
|
||||||
|
|
||||||
node transport address(es)
|
|
||||||
active user ID
|
|
||||||
active user ID in mnemonic form
|
|
||||||
"""
|
|
||||||
details = {
|
|
||||||
'Data directory': identifyhome.identify_home(),
|
|
||||||
}
|
|
||||||
|
|
||||||
for detail in details:
|
|
||||||
logger.info('%s%s: \n%s%s\n' % (logger.colors.fg.lightgreen,
|
|
||||||
detail, logger.colors.fg.green,
|
|
||||||
details[detail]), terminal=True)
|
|
||||||
|
|
||||||
|
|
||||||
show_details.onionr_help = "Shows relevant information " # type: ignore
|
|
||||||
show_details.onionr_help += "for your Onionr install:"
|
|
||||||
|
|
||||||
show_stats.onionr_help = "Shows statistics for your Onionr " # type: ignore
|
|
||||||
show_stats.onionr_help += "node. Slow if Onionr is not running" # type: ignore
|
|
@ -11,7 +11,7 @@ try:
|
|||||||
except (KeyError, IndexError) as _:
|
except (KeyError, IndexError) as _:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
import logger
|
from logger import log as logging
|
||||||
import onionrexceptions
|
import onionrexceptions
|
||||||
import onionrplugins
|
import onionrplugins
|
||||||
from onionrplugins import onionrpluginapi
|
from onionrplugins import onionrpluginapi
|
||||||
@ -48,10 +48,6 @@ def register_plugin_commands(cmd) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def _show_term(msg: str):
|
|
||||||
logger.info(msg, terminal=True)
|
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
"""Register commands and handles help command processing."""
|
"""Register commands and handles help command processing."""
|
||||||
def get_help_message(cmd: str,
|
def get_help_message(cmd: str,
|
||||||
@ -80,7 +76,7 @@ def register():
|
|||||||
try:
|
try:
|
||||||
cmd = sys.argv[1]
|
cmd = sys.argv[1]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
logger.info('Run with --help to see available commands', terminal=True)
|
logging.info('Run with --help to see available commands')
|
||||||
sys.exit(10)
|
sys.exit(10)
|
||||||
|
|
||||||
is_help_cmd = False
|
is_help_cmd = False
|
||||||
@ -102,29 +98,28 @@ def register():
|
|||||||
sys.argv[2]
|
sys.argv[2]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
for i in arguments.get_arguments():
|
for i in arguments.get_arguments():
|
||||||
_show_term('%s <%s>: %s' % (PROGRAM_NAME, '/'.join(i),
|
logging.info('%s <%s>: %s' % (PROGRAM_NAME, '/'.join(i),
|
||||||
get_help_message(i[0])))
|
get_help_message(i[0])))
|
||||||
for pl in onionrplugins.get_enabled_plugins():
|
for pl in onionrplugins.get_enabled_plugins():
|
||||||
pl = onionrplugins.get_plugin(pl)
|
pl = onionrplugins.get_plugin(pl)
|
||||||
if hasattr(pl, 'ONIONR_COMMANDS'):
|
if hasattr(pl, 'ONIONR_COMMANDS'):
|
||||||
print('')
|
print('')
|
||||||
try:
|
try:
|
||||||
_show_term('%s commands:' % (pl.plugin_name,))
|
logging.info('%s commands:' % (pl.plugin_name,))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
_show_term('%s commands:' % (pl.__name__,))
|
logging.info('%s commands:' % (pl.__name__,))
|
||||||
for plugin_cmd in pl.ONIONR_COMMANDS:
|
for plugin_cmd in pl.ONIONR_COMMANDS:
|
||||||
_show_term('%s %s: %s' %
|
logging.info('%s %s: %s' %
|
||||||
(PROGRAM_NAME,
|
(PROGRAM_NAME,
|
||||||
plugin_cmd,
|
plugin_cmd,
|
||||||
get_help_message(plugin_cmd)),)
|
get_help_message(plugin_cmd)),)
|
||||||
print('')
|
print('')
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
_show_term('%s %s: %s' % (PROGRAM_NAME,
|
logging.info('%s %s: %s' % (PROGRAM_NAME,
|
||||||
sys.argv[2],
|
sys.argv[2],
|
||||||
get_help_message(sys.argv[2])))
|
get_help_message(sys.argv[2])))
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logger.error('%s: command does not exist.' % [sys.argv[2]],
|
logging.error('%s: command does not exist.' % [sys.argv[2]])
|
||||||
terminal=True)
|
|
||||||
sys.exit(3)
|
sys.exit(3)
|
||||||
return
|
return
|
||||||
|
@ -4,7 +4,7 @@ Sets CLI arguments for Onionr
|
|||||||
"""
|
"""
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
|
||||||
from .. import onionrstatistics, version, daemonlaunch
|
from .. import version, daemonlaunch
|
||||||
from .. import resetplugins # command to reinstall default plugins
|
from .. import resetplugins # command to reinstall default plugins
|
||||||
|
|
||||||
|
|
||||||
@ -32,8 +32,6 @@ def get_arguments() -> dict:
|
|||||||
dynamically modify them with plugins
|
dynamically modify them with plugins
|
||||||
"""
|
"""
|
||||||
args = {
|
args = {
|
||||||
('details', 'info'): onionrstatistics.show_details,
|
|
||||||
('stats', 'statistics'): onionrstatistics.show_stats,
|
|
||||||
('version',): version.version,
|
('version',): version.version,
|
||||||
('start', 'daemon'): daemonlaunch.start,
|
('start', 'daemon'): daemonlaunch.start,
|
||||||
('stop', 'kill'): daemonlaunch.kill_daemon,
|
('stop', 'kill'): daemonlaunch.kill_daemon,
|
||||||
|
@ -4,7 +4,7 @@ Try to provide recommendations for invalid Onionr commands
|
|||||||
"""
|
"""
|
||||||
import sys
|
import sys
|
||||||
from difflib import SequenceMatcher
|
from difflib import SequenceMatcher
|
||||||
import logger
|
from logger import log as logging
|
||||||
from . import arguments
|
from . import arguments
|
||||||
"""
|
"""
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@ -30,9 +30,9 @@ def recommend(print_default: bool = True):
|
|||||||
for key in args.keys():
|
for key in args.keys():
|
||||||
for word in key:
|
for word in key:
|
||||||
if SequenceMatcher(None, tried, word).ratio() >= 0.75:
|
if SequenceMatcher(None, tried, word).ratio() >= 0.75:
|
||||||
logger.warn(f'{print_message} "{tried}", '
|
logging.warn(f'{print_message} "{tried}", '
|
||||||
+ f'did you mean "{word}"?',
|
+ f'did you mean "{word}"?',
|
||||||
terminal=True)
|
)
|
||||||
return
|
return
|
||||||
if print_default:
|
if print_default:
|
||||||
logger.error('%s "%s"' % (print_message, tried), terminal=True)
|
logging.error('%s "%s"' % (print_message, tried))
|
||||||
|
@ -6,7 +6,7 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
from utils import identifyhome
|
from utils import identifyhome
|
||||||
import logger
|
from logger import log as logging
|
||||||
"""
|
"""
|
||||||
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
|
||||||
@ -32,7 +32,7 @@ def reset():
|
|||||||
if os.path.exists(plugin_dir):
|
if os.path.exists(plugin_dir):
|
||||||
shutil.rmtree(plugin_dir)
|
shutil.rmtree(plugin_dir)
|
||||||
|
|
||||||
logger.info('Default plugins have been reset.', terminal=True)
|
logging.info('Default plugins have been reset.')
|
||||||
|
|
||||||
|
|
||||||
reset.onionr_help = "reinstalls default Onionr plugins" # type: ignore
|
reset.onionr_help = "reinstalls default Onionr plugins" # type: ignore
|
||||||
|
@ -5,7 +5,7 @@ Command to show version info
|
|||||||
import platform
|
import platform
|
||||||
from utils import identifyhome
|
from utils import identifyhome
|
||||||
import onionrvalues
|
import onionrvalues
|
||||||
import logger
|
from logger import log as logging
|
||||||
"""
|
"""
|
||||||
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
|
||||||
@ -22,23 +22,21 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def version(verbosity=5, function=logger.info):
|
def version(verbosity=5, function=logging.info):
|
||||||
"""Display the Onionr version."""
|
"""Display the Onionr version."""
|
||||||
function('Onionr v%s (%s)' % (onionrvalues.ONIONR_VERSION,
|
function('Onionr v%s (%s)' % (onionrvalues.ONIONR_VERSION,
|
||||||
platform.machine()),
|
platform.machine()))
|
||||||
terminal=True)
|
|
||||||
if verbosity >= 1:
|
if verbosity >= 1:
|
||||||
function(onionrvalues.ONIONR_TAGLINE, terminal=True)
|
function(onionrvalues.ONIONR_TAGLINE)
|
||||||
if verbosity >= 2:
|
if verbosity >= 2:
|
||||||
pf = platform.platform()
|
pf = platform.platform()
|
||||||
release = platform.release()
|
release = platform.release()
|
||||||
python_imp = platform.python_implementation()
|
python_imp = platform.python_implementation()
|
||||||
python_version = platform.python_version()
|
python_version = platform.python_version()
|
||||||
function(
|
function(
|
||||||
f'{python_imp} {python_version} on {pf} {release}',
|
f'{python_imp} {python_version} on {pf} {release}')
|
||||||
terminal=True)
|
|
||||||
function('Onionr data dir: %s' %
|
function('Onionr data dir: %s' %
|
||||||
identifyhome.identify_home(), terminal=True)
|
identifyhome.identify_home())
|
||||||
|
|
||||||
|
|
||||||
version.onionr_help = 'Shows environment details including ' # type: ignore
|
version.onionr_help = 'Shows environment details including ' # type: ignore
|
||||||
|
@ -22,7 +22,7 @@ import traceback
|
|||||||
|
|
||||||
from . import onionrevents as events
|
from . import onionrevents as events
|
||||||
from .pluginapis import plugin_apis
|
from .pluginapis import plugin_apis
|
||||||
import config, logger
|
import config, logging
|
||||||
from utils import identifyhome
|
from utils import identifyhome
|
||||||
|
|
||||||
# set data dir
|
# set data dir
|
||||||
@ -43,9 +43,9 @@ def reload(stop_event = True):
|
|||||||
enabled_plugins = get_enabled_plugins()
|
enabled_plugins = get_enabled_plugins()
|
||||||
|
|
||||||
if stop_event is True:
|
if stop_event is True:
|
||||||
logger.debug('Reloading all plugins...')
|
logging.debug('Reloading all plugins...')
|
||||||
else:
|
else:
|
||||||
logger.debug('Loading all plugins...')
|
logging.debug('Loading all plugins...')
|
||||||
|
|
||||||
if stop_event is True:
|
if stop_event is True:
|
||||||
for plugin in enabled_plugins:
|
for plugin in enabled_plugins:
|
||||||
@ -56,7 +56,7 @@ def reload(stop_event = True):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
except:
|
except:
|
||||||
logger.error('Failed to reload plugins.')
|
logging.error('Failed to reload plugins.')
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -73,8 +73,8 @@ def enable(name, start_event = True):
|
|||||||
except ImportError as e: # Was getting import error on Gitlab CI test "data"
|
except ImportError as e: # Was getting import error on Gitlab CI test "data"
|
||||||
# NOTE: If you are experiencing issues with plugins not being enabled, it might be this resulting from an error in the module
|
# NOTE: If you are experiencing issues with plugins not being enabled, it might be this resulting from an error in the module
|
||||||
# can happen inconsistently (especially between versions)
|
# can happen inconsistently (especially between versions)
|
||||||
logger.error('Failed to enable module:', terminal=True)
|
logging.error('Failed to enable module:')
|
||||||
logger.error(traceback.format_exc(), terminal=True)
|
logging.error(traceback.format_exc())
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
enabled_plugins.append(name)
|
enabled_plugins.append(name)
|
||||||
@ -86,8 +86,8 @@ def enable(name, start_event = True):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
logger.error('Failed to enable plugin \"%s\", disabling plugin.' % name, terminal=True)
|
logging.error('Failed to enable plugin \"%s\", disabling plugin.' % name)
|
||||||
logger.debug('Plugins folder not found: %s' % get_plugins_folder(str(name).lower()), terminal=True)
|
logging.debug('Plugins folder not found: %s' % get_plugins_folder(str(name).lower()))
|
||||||
disable(name)
|
disable(name)
|
||||||
|
|
||||||
return False
|
return False
|
||||||
@ -129,9 +129,9 @@ def start(name):
|
|||||||
|
|
||||||
return plugin
|
return plugin
|
||||||
except:
|
except:
|
||||||
logger.error('Failed to start module \"%s\".' % name)
|
logging.error('Failed to start module \"%s\".' % name)
|
||||||
else:
|
else:
|
||||||
logger.error('Failed to start nonexistant module \"%s\".' % name)
|
logging.error('Failed to start nonexistant module \"%s\".' % name)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -153,9 +153,9 @@ def stop(name):
|
|||||||
|
|
||||||
return plugin
|
return plugin
|
||||||
except:
|
except:
|
||||||
logger.error('Failed to stop module \"%s\".' % name)
|
logging.error('Failed to stop module \"%s\".' % name)
|
||||||
else:
|
else:
|
||||||
logger.error('Failed to stop nonexistant module \"%s\".' % name)
|
logging.error('Failed to stop nonexistant module \"%s\".' % name)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -258,11 +258,11 @@ def check():
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if not config.is_set('plugins'):
|
if not config.is_set('plugins'):
|
||||||
logger.debug('Generating plugin configuration data...')
|
logging.debug('Generating plugin configuration data...')
|
||||||
config.set('plugins', {'enabled': []}, True)
|
config.set('plugins', {'enabled': []}, True)
|
||||||
|
|
||||||
if not os.path.exists(os.path.dirname(get_plugins_folder())):
|
if not os.path.exists(os.path.dirname(get_plugins_folder())):
|
||||||
logger.debug('Generating plugin data folder...')
|
logging.debug('Generating plugin data folder...')
|
||||||
try:
|
try:
|
||||||
os.makedirs(os.path.dirname(get_plugins_folder()))
|
os.makedirs(os.path.dirname(get_plugins_folder()))
|
||||||
except FileExistsError:
|
except FileExistsError:
|
||||||
|
@ -7,7 +7,7 @@ from threading import Thread
|
|||||||
|
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
import config, logger
|
import config, logging
|
||||||
import onionrplugins as plugins
|
import onionrplugins as plugins
|
||||||
from . import onionrpluginapi as pluginapi
|
from . import onionrpluginapi as pluginapi
|
||||||
"""
|
"""
|
||||||
@ -41,11 +41,11 @@ def __event_caller(event_name, data = {}):
|
|||||||
try:
|
try:
|
||||||
call(plugins.get_plugin(plugin), event_name, data, get_pluginapi(data))
|
call(plugins.get_plugin(plugin), event_name, data, get_pluginapi(data))
|
||||||
except ModuleNotFoundError as _:
|
except ModuleNotFoundError as _:
|
||||||
logger.warn('Disabling nonexistant plugin "%s"...' % plugin, terminal=True)
|
logging.warn('Disabling nonexistant plugin "%s"...' % plugin)
|
||||||
plugins.disable(plugin, stop_event = False)
|
plugins.disable(plugin, stop_event = False)
|
||||||
except Exception as _:
|
except Exception as _:
|
||||||
logger.error('Event "%s" failed for plugin "%s".' % (event_name, plugin), terminal=True)
|
logging.error('Event "%s" failed for plugin "%s".' % (event_name, plugin))
|
||||||
logger.error('\n' + traceback.format_exc(), terminal=True)
|
logging.error('\n' + traceback.format_exc())
|
||||||
|
|
||||||
def event(event_name, data = {}, threaded = True):
|
def event(event_name, data = {}, threaded = True):
|
||||||
"""Call an event on all plugins (if defined)"""
|
"""Call an event on all plugins (if defined)"""
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import onionrplugins, logger
|
import onionrplugins, logging
|
||||||
|
|
||||||
|
|
||||||
class PluginAPI:
|
class PluginAPI:
|
||||||
|
@ -20,7 +20,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
import os, shutil
|
import os, shutil
|
||||||
|
|
||||||
import onionrplugins as plugins
|
import onionrplugins as plugins
|
||||||
import logger
|
from logger import log as logging
|
||||||
import filepaths
|
import filepaths
|
||||||
from utils.readstatic import get_static_dir
|
from utils.readstatic import get_static_dir
|
||||||
|
|
||||||
@ -38,9 +38,9 @@ def setup_default_plugins():
|
|||||||
if not name in plugins.get_enabled_plugins():
|
if not name in plugins.get_enabled_plugins():
|
||||||
plugins.enable(name)
|
plugins.enable(name)
|
||||||
else:
|
else:
|
||||||
logger.error(
|
logging.error(
|
||||||
"Plugin source directory does not exist!" +
|
"Plugin source directory does not exist!" +
|
||||||
"Onionr needs plugins to be useful", terminal=True)
|
"Onionr needs plugins to be useful")
|
||||||
|
|
||||||
|
|
||||||
for name in plugins.get_enabled_plugins():
|
for name in plugins.get_enabled_plugins():
|
||||||
@ -50,5 +50,5 @@ def setup_default_plugins():
|
|||||||
except FileExistsError:
|
except FileExistsError:
|
||||||
pass
|
pass
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
#logger.warn('Error enabling plugin: ' + str(e), terminal=True)
|
#logging.warn('Error enabling plugin: ' + str(e))
|
||||||
plugins.disable(name, stop_event = False)
|
plugins.disable(name, stop_event = False)
|
||||||
|
@ -8,9 +8,8 @@ import base64
|
|||||||
import ujson as json
|
import ujson as json
|
||||||
|
|
||||||
import config
|
import config
|
||||||
import logger
|
from logger import log as logging
|
||||||
import onionrvalues
|
import onionrvalues
|
||||||
from logger.settings import *
|
|
||||||
from utils import readstatic
|
from utils import readstatic
|
||||||
"""
|
"""
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@ -37,42 +36,3 @@ def setup_config():
|
|||||||
config.save()
|
config.save()
|
||||||
|
|
||||||
config.reload()
|
config.reload()
|
||||||
|
|
||||||
settings = 0b000
|
|
||||||
if config.get('log.console.color', True):
|
|
||||||
settings = settings | USE_ANSI
|
|
||||||
if config.get('log.console.output', True):
|
|
||||||
settings = settings | OUTPUT_TO_CONSOLE
|
|
||||||
if config.get('log.file.output', True):
|
|
||||||
settings = settings | OUTPUT_TO_FILE
|
|
||||||
set_settings(settings)
|
|
||||||
|
|
||||||
verbosity = str(config.get('log.verbosity', 'default')).lower().strip()
|
|
||||||
if not verbosity in ['default', 'null', 'none', 'nil']:
|
|
||||||
map = {
|
|
||||||
str(LEVEL_DEBUG) : LEVEL_DEBUG,
|
|
||||||
'verbose' : LEVEL_DEBUG,
|
|
||||||
'debug' : LEVEL_DEBUG,
|
|
||||||
str(LEVEL_INFO) : LEVEL_INFO,
|
|
||||||
'info' : LEVEL_INFO,
|
|
||||||
'information' : LEVEL_INFO,
|
|
||||||
str(LEVEL_WARN) : LEVEL_WARN,
|
|
||||||
'warn' : LEVEL_WARN,
|
|
||||||
'warning' : LEVEL_WARN,
|
|
||||||
'warnings' : LEVEL_WARN,
|
|
||||||
str(LEVEL_ERROR) : LEVEL_ERROR,
|
|
||||||
'err' : LEVEL_ERROR,
|
|
||||||
'error' : LEVEL_ERROR,
|
|
||||||
'errors' : LEVEL_ERROR,
|
|
||||||
str(LEVEL_FATAL) : LEVEL_FATAL,
|
|
||||||
'fatal' : LEVEL_FATAL,
|
|
||||||
str(LEVEL_IMPORTANT) : LEVEL_IMPORTANT,
|
|
||||||
'silent' : LEVEL_IMPORTANT,
|
|
||||||
'quiet' : LEVEL_IMPORTANT,
|
|
||||||
'important' : LEVEL_IMPORTANT
|
|
||||||
}
|
|
||||||
|
|
||||||
if verbosity in map:
|
|
||||||
set_level(map[verbosity])
|
|
||||||
else:
|
|
||||||
logger.warn('Verbosity level %s is not valid, using default verbosity.' % verbosity)
|
|
||||||
|
@ -6,7 +6,7 @@ from threading import Thread
|
|||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
import logger
|
from logger import log as logging
|
||||||
|
|
||||||
|
|
||||||
def _onionr_thread(func: Callable,
|
def _onionr_thread(func: Callable,
|
||||||
@ -18,10 +18,10 @@ def _onionr_thread(func: Callable,
|
|||||||
try:
|
try:
|
||||||
func(*args, **kwargs)
|
func(*args, **kwargs)
|
||||||
except Exception as _: # noqa
|
except Exception as _: # noqa
|
||||||
logger.warn(
|
logging.warn(
|
||||||
f"Onionr thread exception in {thread_id} \n" +
|
f"Onionr thread exception in {thread_id} \n" +
|
||||||
traceback.format_exc(),
|
traceback.format_exc(),
|
||||||
terminal=True)
|
)
|
||||||
sleep(sleep_secs)
|
sleep(sleep_secs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
def str_to_bytes(data: str) -> bytes:
|
|
||||||
'''Convert a string to bytes with .encode(), utf8'''
|
|
||||||
try:
|
|
||||||
data = data.encode('UTF-8')
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def bytes_to_str(data: bytes) -> str:
|
|
||||||
"""Convert bytes to strings with .decode(), utf8"""
|
|
||||||
try:
|
|
||||||
data = data.decode('UTF-8')
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
return data
|
|
@ -1,31 +0,0 @@
|
|||||||
"""Onionr - Private P2P Communication.
|
|
||||||
|
|
||||||
Get floored epoch, or rounded epoch
|
|
||||||
"""
|
|
||||||
import time
|
|
||||||
import math
|
|
||||||
"""
|
|
||||||
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 get_rounded_epoch(roundS=60) -> int:
|
|
||||||
"""Return the epoch, rounded down to given seconds (Default 60)."""
|
|
||||||
epoch = get_epoch()
|
|
||||||
return epoch - (epoch % roundS)
|
|
||||||
|
|
||||||
|
|
||||||
def get_epoch() -> int:
|
|
||||||
"""return epoch"""
|
|
||||||
return math.floor(time.time())
|
|
@ -1,15 +0,0 @@
|
|||||||
import sys, os
|
|
||||||
from . import readstatic
|
|
||||||
import logger
|
|
||||||
import onionrvalues
|
|
||||||
def header(message = logger.colors.fg.pink + logger.colors.bold + 'Onionr' + logger.colors.reset + logger.colors.fg.pink + ' has started.'):
|
|
||||||
if onionrvalues.DEVELOPMENT_MODE:
|
|
||||||
return
|
|
||||||
header_path = readstatic.get_static_dir() + 'header.txt'
|
|
||||||
if os.path.exists(header_path) and logger.settings.get_level() <= logger.settings.LEVEL_INFO:
|
|
||||||
with open(header_path, 'rb') as file:
|
|
||||||
# only to stdout, not file or log or anything
|
|
||||||
sys.stderr.write(file.read().decode().replace('P', logger.colors.fg.pink).replace('W', logger.colors.reset + logger.colors.bold).replace('G', logger.colors.fg.green).replace('\n', logger.colors.reset + '\n').replace('B', logger.colors.bold))
|
|
||||||
|
|
||||||
if message:
|
|
||||||
logger.info(logger.colors.fg.lightgreen + '-> ' + str(message) + logger.colors.reset + logger.colors.fg.lightgreen + ' <-\n', terminal=True)
|
|
@ -11,11 +11,10 @@
|
|||||||
"file": {
|
"file": {
|
||||||
"output": true,
|
"output": true,
|
||||||
"remove_on_exit": false
|
"remove_on_exit": false
|
||||||
},
|
}
|
||||||
"verbosity": "default"
|
|
||||||
},
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"disabled": ["unixtransport", "repl", "bigbrother"],
|
"disabled": ["unixtransport", "repl", "bigbrother", "example"],
|
||||||
"enabled": []
|
"enabled": []
|
||||||
},
|
},
|
||||||
"security": {
|
"security": {
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
'''
|
|
||||||
$name plugin template file.
|
|
||||||
Generated on $date by $user.
|
|
||||||
'''
|
|
||||||
|
|
||||||
plugin_name = '$name'
|
|
||||||
|
|
||||||
def on_init(api, data = None):
|
|
||||||
'''
|
|
||||||
This event is called after Onionr is initialized, but before the command
|
|
||||||
inputted is executed. Could be called when daemon is starting or when
|
|
||||||
just the client is running.
|
|
||||||
'''
|
|
||||||
|
|
||||||
pluginapi = api
|
|
||||||
|
|
@ -18,9 +18,9 @@ P ::: :::: ::::::: :::: :::: W:: :: :: ::: :: :: :: :: :::: :::::
|
|||||||
P ::: ::::: :::::: :::: :::: W:: :: :: ::: :: :: :: :: ::: :: :::
|
P ::: ::::: :::::: :::: :::: W:: :: :: ::: :: :: :: :: ::: :: :::
|
||||||
P :::: ::::: ::::: ::: W :::: :: :: :: ::::: :: :: :: ::
|
P :::: ::::: ::::: ::: W :::: :: :: :: ::::: :: :: :: ::
|
||||||
P :::: :::::: :::::: ::::
|
P :::: :::::: :::::: ::::
|
||||||
P :::: :::::::::::: :::: GPB
|
P :::: :::::::::::: ::::
|
||||||
P ::::: :::::::: ::::
|
P ::::: :::::::: ::::
|
||||||
P ::::: :::::
|
P ::::: :::::
|
||||||
P ::::::::::::::::
|
P ::::::::::::::::
|
||||||
P :::::::
|
P :::::::
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import sys
|
|||||||
import os
|
import os
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
|
|
||||||
import logger
|
from logger import log as logging
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@ -49,5 +49,5 @@ def enable_ministries(disable_hooks: Iterable = None):
|
|||||||
|
|
||||||
def on_init(api, data=None):
|
def on_init(api, data=None):
|
||||||
enable_ministries()
|
enable_ministries()
|
||||||
logger.info(
|
logging.info(
|
||||||
"Big brother enabled, blocking unsafe Python code.", terminal=True)
|
"Big brother enabled, blocking unsafe Python code.")
|
||||||
|
@ -4,7 +4,7 @@ Ensure sockets don't get made to non localhost
|
|||||||
"""
|
"""
|
||||||
import ipaddress
|
import ipaddress
|
||||||
|
|
||||||
import logger
|
from logger import log as logging
|
||||||
from onionrexceptions import NetworkLeak
|
from onionrexceptions import NetworkLeak
|
||||||
"""
|
"""
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
@ -37,12 +37,12 @@ def detect_socket_leaks(socket_event):
|
|||||||
try:
|
try:
|
||||||
ip_address = ipaddress.ip_address(ip_address)
|
ip_address = ipaddress.ip_address(ip_address)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
logger.warn(f'Conn made to {ip_address} outside of Tor/similar')
|
logging.warn(f'Conn made to {ip_address} outside of Tor/similar')
|
||||||
raise \
|
raise \
|
||||||
NetworkLeak('Conn to host/non local IP, this is a privacy issue!')
|
NetworkLeak('Conn to host/non local IP, this is a privacy issue!')
|
||||||
|
|
||||||
# Validate that the IP is localhost ipv4
|
# Validate that the IP is localhost ipv4
|
||||||
if not ip_address.is_loopback and not ip_address.is_multicast \
|
if not ip_address.is_loopback and not ip_address.is_multicast \
|
||||||
and not ip_address.is_private:
|
and not ip_address.is_private:
|
||||||
logger.warn(f'Conn made to {ip_address} outside of Tor/similar')
|
logging.warn(f'Conn made to {ip_address} outside of Tor/similar')
|
||||||
raise NetworkLeak('Conn to non local IP, this is a privacy concern!')
|
raise NetworkLeak('Conn to non local IP, this is a privacy concern!')
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
Log (not block) read/write of non-user data files and non-python lib files
|
Log (not block) read/write of non-user data files and non-python lib files
|
||||||
"""
|
"""
|
||||||
from utils.identifyhome import identify_home
|
from utils.identifyhome import identify_home
|
||||||
import logger
|
from logger import log as logging
|
||||||
"""
|
"""
|
||||||
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
|
||||||
@ -33,4 +33,4 @@ def detect_disk_access(info):
|
|||||||
|
|
||||||
if identify_home() not in info[0]:
|
if identify_home() not in info[0]:
|
||||||
if 'proc' not in info[0]: # if it is, it is onionr stats
|
if 'proc' not in info[0]: # if it is, it is onionr stats
|
||||||
logger.warn(f'[DISK MINISTRY] {info}')
|
logging.warn(f'[DISK MINISTRY] {info}')
|
||||||
|
@ -5,7 +5,7 @@ Prevent eval/exec/os.system and log it
|
|||||||
import base64
|
import base64
|
||||||
import platform
|
import platform
|
||||||
|
|
||||||
import logger
|
from logger import log as logging
|
||||||
from utils import identifyhome
|
from utils import identifyhome
|
||||||
from onionrexceptions import ArbitraryCodeExec
|
from onionrexceptions import ArbitraryCodeExec
|
||||||
"""
|
"""
|
||||||
@ -27,8 +27,8 @@ untrusted_exec = True
|
|||||||
|
|
||||||
def block_system(cmd):
|
def block_system(cmd):
|
||||||
"""Prevent os.system except for whitelisted commands+contexts."""
|
"""Prevent os.system except for whitelisted commands+contexts."""
|
||||||
logger.warn('POSSIBLE EXPLOIT DETECTED, SEE LOGS', terminal=True)
|
logging.warn('POSSIBLE EXPLOIT DETECTED, SEE LOGS')
|
||||||
logger.warn(f'POSSIBLE EXPLOIT: shell command not in whitelist: {cmd}')
|
logging.warn(f'POSSIBLE EXPLOIT: shell command not in whitelist: {cmd}')
|
||||||
raise ArbitraryCodeExec('os.system command not in whitelist')
|
raise ArbitraryCodeExec('os.system command not in whitelist')
|
||||||
|
|
||||||
|
|
||||||
@ -57,8 +57,8 @@ def block_exec(event, info):
|
|||||||
if 'plugins/' in info[0].co_filename:
|
if 'plugins/' in info[0].co_filename:
|
||||||
return
|
return
|
||||||
|
|
||||||
logger.warn('POSSIBLE EXPLOIT DETECTED, SEE LOGS', terminal=True)
|
logging.warn('POSSIBLE EXPLOIT DETECTED, SEE LOGS')
|
||||||
logger.warn('POSSIBLE EXPLOIT DETECTED: ' + info[0].co_filename)
|
logging.warn('POSSIBLE EXPLOIT DETECTED: ' + info[0].co_filename)
|
||||||
logger.warn('Prevented exec/eval. Report this with the sample below')
|
logging.warn('Prevented exec/eval. Report this with the sample below')
|
||||||
logger.warn(f'{event} code in base64 format: {code_b64}')
|
logging.warn(f'{event} code in base64 format: {code_b64}')
|
||||||
raise ArbitraryCodeExec("Arbitrary code (eval/exec) detected.")
|
raise ArbitraryCodeExec("Arbitrary code (eval/exec) detected.")
|
||||||
|
@ -6,14 +6,12 @@ import sys
|
|||||||
import os
|
import os
|
||||||
import locale
|
import locale
|
||||||
from time import sleep
|
from time import sleep
|
||||||
import traceback
|
from logger import log as logging
|
||||||
from typing import Set, TYPE_CHECKING
|
from typing import Set, TYPE_CHECKING
|
||||||
from threading import Thread, local
|
|
||||||
import blockdb
|
import blockdb
|
||||||
from gossip.peerset import gossip_peer_set
|
from gossip.peerset import gossip_peer_set
|
||||||
|
|
||||||
import logger
|
|
||||||
|
|
||||||
import onionrblocks
|
import onionrblocks
|
||||||
|
|
||||||
locale.setlocale(locale.LC_ALL, '')
|
locale.setlocale(locale.LC_ALL, '')
|
||||||
@ -58,5 +56,5 @@ def on_printtest_cmd(api, data=None):
|
|||||||
|
|
||||||
|
|
||||||
def on_init(api, data=None):
|
def on_init(api, data=None):
|
||||||
logger.info(
|
logging.info(
|
||||||
f"Example Plugin v{PLUGIN_VERSION} enabled", terminal=True)
|
f"Example Plugin v{PLUGIN_VERSION} enabled")
|
||||||
|
@ -21,6 +21,8 @@ from code import InteractiveConsole
|
|||||||
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
|
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
|
||||||
# import after path insert
|
# import after path insert
|
||||||
|
|
||||||
|
import logger
|
||||||
|
|
||||||
"""
|
"""
|
||||||
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
|
||||||
@ -42,6 +44,7 @@ PLUGIN_VERSION = '0.0.0'
|
|||||||
|
|
||||||
def on_primary_loop(event_name, data):
|
def on_primary_loop(event_name, data):
|
||||||
"""Run a REPL on the primary loop"""
|
"""Run a REPL on the primary loop"""
|
||||||
|
logger.disable_console_logging()
|
||||||
header = """You are now in the Onionr REPL. Type 'exit()' to exit.
|
header = """You are now in the Onionr REPL. Type 'exit()' to exit.
|
||||||
|
|
||||||
Enter repl_locals to see the (default) special locals available to you.
|
Enter repl_locals to see the (default) special locals available to you.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import config
|
import config
|
||||||
import logger
|
from logger import log as logging
|
||||||
from gossip.peerset import gossip_peer_set
|
from gossip.peerset import gossip_peer_set
|
||||||
|
|
||||||
from getsocks import get_socks
|
from getsocks import get_socks
|
||||||
@ -24,6 +24,6 @@ def on_announce_rec(api, data=None):
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
logger.info(f"Peer {announced} announced to us.", terminal=True)
|
logging.info(f"Peer {announced} announced to us.")
|
||||||
|
|
||||||
data['callback'](TorPeer(socks_address, socks_port, announced))
|
data['callback'](TorPeer(socks_address, socks_port, announced))
|
||||||
|
@ -9,7 +9,7 @@ from typing import Callable
|
|||||||
from gossip.peer import Peer
|
from gossip.peer import Peer
|
||||||
from gossip.peerset import gossip_peer_set
|
from gossip.peerset import gossip_peer_set
|
||||||
from utils.identifyhome import identify_home
|
from utils.identifyhome import identify_home
|
||||||
import logger
|
from logger import log as logging
|
||||||
import config
|
import config
|
||||||
from getsocks import get_socks
|
from getsocks import get_socks
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ def on_bootstrap(api, data):
|
|||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
bootstrap_nodes = set()
|
bootstrap_nodes = set()
|
||||||
except Exception as _:
|
except Exception as _:
|
||||||
logger.warn(traceback.format_exc(), terminal=True)
|
logging.warn(traceback.format_exc())
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
@ -60,7 +60,7 @@ def on_bootstrap(api, data):
|
|||||||
try:
|
try:
|
||||||
config.reload()
|
config.reload()
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.error(traceback.format_exc(), terminal=True)
|
logging.error(traceback.format_exc())
|
||||||
|
|
||||||
socks_address, socks_port = get_socks()[0]
|
socks_address, socks_port = get_socks()[0]
|
||||||
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
hc5qc2vfuq2rkz4mjrrobcjgdjnsni6rovhfkbpc7huupbuiztx6wiid
|
|
@ -8,13 +8,12 @@ import locale
|
|||||||
from time import sleep
|
from time import sleep
|
||||||
import traceback
|
import traceback
|
||||||
from typing import Set, TYPE_CHECKING
|
from typing import Set, TYPE_CHECKING
|
||||||
import base64
|
from logger import log as logging
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
import stem
|
import stem
|
||||||
from stem.control import Controller
|
from stem.control import Controller
|
||||||
|
|
||||||
import logger
|
|
||||||
from utils import readstatic
|
from utils import readstatic
|
||||||
import config
|
import config
|
||||||
from filepaths import gossip_server_socket_file
|
from filepaths import gossip_server_socket_file
|
||||||
@ -58,8 +57,8 @@ class OnionrTor:
|
|||||||
|
|
||||||
|
|
||||||
def on_init(api, data=None):
|
def on_init(api, data=None):
|
||||||
logger.info(
|
logging.info(
|
||||||
f"Tor Transport Plugin v{PLUGIN_VERSION} enabled", terminal=True)
|
f"Tor Transport Plugin v{PLUGIN_VERSION} enabled")
|
||||||
|
|
||||||
|
|
||||||
def on_get_our_transport(api, data=None):
|
def on_get_our_transport(api, data=None):
|
||||||
@ -75,10 +74,11 @@ def on_gossip_start(api, data: Set[Peer] = None):
|
|||||||
starttor.start_tor()
|
starttor.start_tor()
|
||||||
|
|
||||||
with Controller.from_socket_file(control_socket) as controller:
|
with Controller.from_socket_file(control_socket) as controller:
|
||||||
|
controller
|
||||||
controller.authenticate()
|
controller.authenticate()
|
||||||
logger.info(
|
logging.info(
|
||||||
"Tor socks is listening on " +
|
"Tor socks is listening on " +
|
||||||
f"{controller.get_listeners('SOCKS')[0]}", terminal=True)
|
f"{controller.get_listeners('SOCKS')[0]}")
|
||||||
key = config.get('tor.key')
|
key = config.get('tor.key')
|
||||||
new_address = ''
|
new_address = ''
|
||||||
if not key:
|
if not key:
|
||||||
@ -98,12 +98,10 @@ def on_gossip_start(api, data: Set[Peer] = None):
|
|||||||
key_content=key, key_type='ED25519-V3',
|
key_content=key, key_type='ED25519-V3',
|
||||||
detached=True, await_publication=True)
|
detached=True, await_publication=True)
|
||||||
except stem.ProtocolError:
|
except stem.ProtocolError:
|
||||||
logger.error(
|
logging.error(
|
||||||
"Could not start Tor transport. Try restarting Onionr",
|
"Could not start Tor transport. Try restarting Onionr",
|
||||||
terminal=True)
|
)
|
||||||
config.set('tor.key', '', savefile=True)
|
config.set('tor.key', '', savefile=True)
|
||||||
return
|
return
|
||||||
logger.info(
|
logging.info(
|
||||||
f'{new_address}Tor transport address {add_onion_resp.service_id}' +
|
f'{new_address}Tor transport address {add_onion_resp.service_id}.onion')
|
||||||
'.onion',
|
|
||||||
terminal=True)
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import socks
|
import socks
|
||||||
|
|
||||||
from gossip.peerset import gossip_peer_set
|
from gossip.peerset import gossip_peer_set
|
||||||
import logger
|
from logger import log as logging
|
||||||
|
|
||||||
|
|
||||||
class HandleRevc:
|
class HandleRevc:
|
||||||
@ -48,9 +48,9 @@ class TorPeer:
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
logger.debug(
|
logging.debug(
|
||||||
f"Could not create socket to peer {self.transport_address}",
|
f"Could not create socket to peer {self.transport_address}",
|
||||||
terminal=True)
|
)
|
||||||
raise TimeoutError
|
raise TimeoutError
|
||||||
mock_recv = HandleRevc(s)
|
mock_recv = HandleRevc(s)
|
||||||
s.recv = mock_recv.recv
|
s.recv = mock_recv.recv
|
||||||
|
@ -6,7 +6,7 @@ import sys
|
|||||||
import os
|
import os
|
||||||
import locale
|
import locale
|
||||||
from time import sleep
|
from time import sleep
|
||||||
import traceback
|
from logger import log as logging
|
||||||
from typing import Set, TYPE_CHECKING
|
from typing import Set, TYPE_CHECKING
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import shelve
|
import shelve
|
||||||
@ -14,7 +14,6 @@ import shelve
|
|||||||
import stem
|
import stem
|
||||||
from stem.control import Controller
|
from stem.control import Controller
|
||||||
|
|
||||||
import logger
|
|
||||||
from utils import readstatic
|
from utils import readstatic
|
||||||
import config
|
import config
|
||||||
from filepaths import gossip_server_socket_file
|
from filepaths import gossip_server_socket_file
|
||||||
@ -59,10 +58,10 @@ def on_shutdown_event(api, data=None):
|
|||||||
db[peer.transport_address] = peer
|
db[peer.transport_address] = peer
|
||||||
|
|
||||||
def on_init(api, data=None):
|
def on_init(api, data=None):
|
||||||
logger.info(
|
logging.info(
|
||||||
f"Unix Transport Plugin v{PLUGIN_VERSION} enabled", terminal=True)
|
f"Unix Transport Plugin v{PLUGIN_VERSION} enabled")
|
||||||
logger.info(
|
logging.info(
|
||||||
f"Peers can connect to {gossip_server_socket_file}", terminal=True)
|
f"Peers can connect to {gossip_server_socket_file}")
|
||||||
|
|
||||||
def on_get_our_transport(api, data=None):
|
def on_get_our_transport(api, data=None):
|
||||||
callback_func = data['callback']
|
callback_func = data['callback']
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import config
|
import config
|
||||||
import logger
|
from logger import log as logging
|
||||||
from gossip.server import gossip_server_socket_file
|
from gossip.server import gossip_server_socket_file
|
||||||
|
|
||||||
from unixpeer import UnixPeer
|
from unixpeer import UnixPeer
|
||||||
@ -19,6 +19,6 @@ def on_announce_rec(api, data=None):
|
|||||||
if announced == gossip_server_socket_file:
|
if announced == gossip_server_socket_file:
|
||||||
return
|
return
|
||||||
|
|
||||||
logger.info(f"Peer {announced} announced to us.", terminal=True)
|
logging.info(f"Peer {announced} announced to us.")
|
||||||
|
|
||||||
data['callback'](UnixPeer(announced))
|
data['callback'](UnixPeer(announced))
|
||||||
|
@ -10,7 +10,7 @@ from gossip.server import gossip_server_socket_file
|
|||||||
from gossip.peer import Peer
|
from gossip.peer import Peer
|
||||||
from gossip.peerset import gossip_peer_set
|
from gossip.peerset import gossip_peer_set
|
||||||
from utils.identifyhome import identify_home
|
from utils.identifyhome import identify_home
|
||||||
import logger
|
from logger import log as logging
|
||||||
import config
|
import config
|
||||||
|
|
||||||
from unixpeer import UnixPeer
|
from unixpeer import UnixPeer
|
||||||
@ -46,7 +46,7 @@ def on_bootstrap(api, data=None):
|
|||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
bootstrap_nodes = set()
|
bootstrap_nodes = set()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warn(traceback.format_exc(), terminal=True)
|
logging.warn(traceback.format_exc())
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
@ -11,7 +11,7 @@ from threading import Thread, local
|
|||||||
from gossip.peerset import gossip_peer_set
|
from gossip.peerset import gossip_peer_set
|
||||||
|
|
||||||
|
|
||||||
import logger
|
from logger import log as logging
|
||||||
|
|
||||||
import onionrplugins
|
import onionrplugins
|
||||||
|
|
||||||
@ -41,8 +41,8 @@ from wot.loadfromblocks import load_identities_from_blocks
|
|||||||
|
|
||||||
|
|
||||||
def on_init(api, data=None):
|
def on_init(api, data=None):
|
||||||
logger.info(
|
logging.info(
|
||||||
f"Web of Trust Plugin v{PLUGIN_VERSION} enabled", terminal=True)
|
f"Web of Trust Plugin v{PLUGIN_VERSION} enabled")
|
||||||
#onionrplugins.plugin_apis['wot'] = wot_test
|
#onionrplugins.plugin_apis['wot'] = wot_test
|
||||||
|
|
||||||
list(map(lambda x: identities.add(x), load_identities_from_blocks()))
|
list(map(lambda x: identities.add(x), load_identities_from_blocks()))
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import logger
|
from logger import log as logging
|
||||||
|
|
||||||
from nacl.signing import VerifyKey
|
from nacl.signing import VerifyKey
|
||||||
|
|
||||||
@ -10,8 +10,8 @@ def process_identity_announce(identity_announce_payload):
|
|||||||
|
|
||||||
# verify that this is a signature for an announce command
|
# verify that this is a signature for an announce command
|
||||||
if identity_announce_payload[0] != WotCommand.ANNOUNCE:
|
if identity_announce_payload[0] != WotCommand.ANNOUNCE:
|
||||||
logger.warn(
|
logging.warn(
|
||||||
f'Invalid command in signature' , terminal=True)
|
f'Invalid command in signature' )
|
||||||
return
|
return
|
||||||
iden = Identity.deserialize(identity_announce_payload[1:])
|
iden = Identity.deserialize(identity_announce_payload[1:])
|
||||||
identities.add(iden)
|
identities.add(iden)
|
@ -1,4 +1,4 @@
|
|||||||
import logger
|
from logger import log as logging
|
||||||
|
|
||||||
from nacl.signing import VerifyKey
|
from nacl.signing import VerifyKey
|
||||||
|
|
||||||
@ -9,13 +9,13 @@ from wot.identity.identityset import identities
|
|||||||
def process_identity_revoke(revoke_payload: bytes):
|
def process_identity_revoke(revoke_payload: bytes):
|
||||||
wot_cmd = revoke_payload[0].to_bytes(1, 'big')
|
wot_cmd = revoke_payload[0].to_bytes(1, 'big')
|
||||||
if revoke_payload[0] != WotCommand.REVOKE:
|
if revoke_payload[0] != WotCommand.REVOKE:
|
||||||
logger.warn(
|
logging.warn(
|
||||||
f'Invalid command in signature', terminal=True)
|
f'Invalid command in signature')
|
||||||
return
|
return
|
||||||
revoked_identity = revoke_payload[1:33]
|
revoked_identity = revoke_payload[1:33]
|
||||||
signature = revoke_payload[33:]
|
signature = revoke_payload[33:]
|
||||||
|
|
||||||
# raises nacl.exceptions.BadSignatureError if bad signature
|
# raises nacl.exceptions.BadSignatureError if bad signature
|
||||||
VerifyKey(revoked_identity).verify(wot_cmd + revoked_identity, signature)
|
VerifyKey(revoked_identity).verify(wot_cmd + revoked_identity, signature)
|
||||||
|
|
||||||
identities.remove(Identity(revoked_identity, "etc"))
|
identities.remove(Identity(revoked_identity, "etc"))
|
||||||
|
@ -2,7 +2,7 @@ import traceback
|
|||||||
|
|
||||||
from nacl.signing import VerifyKey
|
from nacl.signing import VerifyKey
|
||||||
|
|
||||||
import logger
|
from logger import log as logging
|
||||||
|
|
||||||
from wot.getbykey import get_identity_by_key
|
from wot.getbykey import get_identity_by_key
|
||||||
from wot.blockprocessingevent import WotCommand
|
from wot.blockprocessingevent import WotCommand
|
||||||
@ -10,14 +10,14 @@ from wot.blockprocessingevent import WotCommand
|
|||||||
|
|
||||||
def process_revoke_signature(revoke_signature_payload):
|
def process_revoke_signature(revoke_signature_payload):
|
||||||
if len(revoke_signature_payload) != 129:
|
if len(revoke_signature_payload) != 129:
|
||||||
logger.warn(
|
logging.warn(
|
||||||
f'Signature size is invalid for revoking an identity',
|
f'Signature size is invalid for revoking an identity',
|
||||||
terminal=True)
|
)
|
||||||
|
|
||||||
# verify that this is a signature for a trust command
|
# verify that this is a signature for a trust command
|
||||||
if revoke_signature_payload[0] != WotCommand.REVOKE_TRUST:
|
if revoke_signature_payload[0] != WotCommand.REVOKE_TRUST:
|
||||||
logger.warn(
|
logging.warn(
|
||||||
f'Invalid command in signature' , terminal=True)
|
f'Invalid command in signature' )
|
||||||
return
|
return
|
||||||
# signer is first 32 bytes
|
# signer is first 32 bytes
|
||||||
signer = VerifyKey(revoke_signature_payload[1:33])
|
signer = VerifyKey(revoke_signature_payload[1:33])
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import traceback
|
import traceback
|
||||||
import logger
|
from logger import log as logging
|
||||||
|
|
||||||
from nacl.signing import VerifyKey
|
from nacl.signing import VerifyKey
|
||||||
|
|
||||||
@ -9,13 +9,13 @@ from wot.blockprocessingevent import WotCommand
|
|||||||
|
|
||||||
def process_trust_signature(sig_payload: bytes):
|
def process_trust_signature(sig_payload: bytes):
|
||||||
if len(sig_payload) != 129:
|
if len(sig_payload) != 129:
|
||||||
logger.warn(
|
logging.warn(
|
||||||
f'Signature size is invalid for a signed identity')
|
f'Signature size is invalid for a signed identity')
|
||||||
return
|
return
|
||||||
|
|
||||||
# verify that this is a signature for a trust command
|
# verify that this is a signature for a trust command
|
||||||
if sig_payload[0] != WotCommand.TRUST:
|
if sig_payload[0] != WotCommand.TRUST:
|
||||||
logger.warn(
|
logging.warn(
|
||||||
f'Invalid command in signature')
|
f'Invalid command in signature')
|
||||||
return
|
return
|
||||||
# signer is first 32 bytes
|
# signer is first 32 bytes
|
||||||
|
@ -4,7 +4,7 @@ import traceback
|
|||||||
from nacl.signing import VerifyKey
|
from nacl.signing import VerifyKey
|
||||||
import nacl.exceptions
|
import nacl.exceptions
|
||||||
|
|
||||||
import logger
|
from logger import log as logging
|
||||||
import blockdb
|
import blockdb
|
||||||
|
|
||||||
from wot.identity import Identity, identities
|
from wot.identity import Identity, identities
|
||||||
@ -33,5 +33,5 @@ def load_signatures_from_blocks() -> None:
|
|||||||
# noop if already signed
|
# noop if already signed
|
||||||
processtrustsignature.process_trust_signature(block.data)
|
processtrustsignature.process_trust_signature(block.data)
|
||||||
except nacl.exceptions.BadSignatureError:
|
except nacl.exceptions.BadSignatureError:
|
||||||
logger.warn('Bad signature in block:')
|
logging.warn('Bad signature in block:')
|
||||||
logger.warn(traceback.format_exc())
|
logging.warn(traceback.format_exc())
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
import sys
|
|
||||||
import os
|
|
||||||
from subprocess import Popen, PIPE
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/'
|
|
||||||
os.environ["ONIONR_HOME"] = TEST_DIR
|
|
||||||
|
|
||||||
print(f'running integration test for {__file__}')
|
|
||||||
|
|
||||||
with Popen(['./onionr.sh', 'details'], stdout=PIPE) as onionr_proc:
|
|
||||||
output = onionr_proc.stdout.read().decode()
|
|
||||||
if onionr_proc.returncode != 0:
|
|
||||||
raise ValueError('Raised non zero exit ' + str(onionr_proc.returncode))
|
|
@ -3,7 +3,7 @@ import os
|
|||||||
from subprocess import Popen, PIPE
|
from subprocess import Popen, PIPE
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/'
|
TEST_DIR = '../testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/'
|
||||||
os.environ["ONIONR_HOME"] = TEST_DIR
|
os.environ["ONIONR_HOME"] = TEST_DIR
|
||||||
|
|
||||||
print(f'running integration test for {__file__}')
|
print(f'running integration test for {__file__}')
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import sys, os, random
|
import sys, os
|
||||||
sys.path.append(".")
|
sys.path.append(".")
|
||||||
sys.path.append("src/")
|
sys.path.append("src/")
|
||||||
import unittest, uuid
|
import unittest, uuid
|
||||||
@ -12,7 +12,7 @@ from utils import identifyhome, createdirs
|
|||||||
from onionrsetup import setup_config
|
from onionrsetup import setup_config
|
||||||
createdirs.create_dirs()
|
createdirs.create_dirs()
|
||||||
|
|
||||||
from onionrutils.escapeansi import escape_ANSI
|
from utils.escapeansi import escape_ANSI
|
||||||
|
|
||||||
class Colors:
|
class Colors:
|
||||||
""" ANSI color codes """
|
""" ANSI color codes """
|
||||||
@ -41,7 +41,7 @@ class Colors:
|
|||||||
CROSSED = "\033[9m"
|
CROSSED = "\033[9m"
|
||||||
END = "\033[0m"
|
END = "\033[0m"
|
||||||
|
|
||||||
class OnionrForwardSecrecyTests(unittest.TestCase):
|
class OnionrTestEscapeAnsi(unittest.TestCase):
|
||||||
def test_no_replace(self):
|
def test_no_replace(self):
|
||||||
msg = 'test message'
|
msg = 'test message'
|
||||||
self.assertEqual(escape_ANSI(msg), msg)
|
self.assertEqual(escape_ANSI(msg), msg)
|
||||||
|
Loading…
Reference in New Issue
Block a user