added motd system, reworked handling of bytes in signatures
parent
31825bfad7
commit
695f334297
|
@ -30,6 +30,7 @@ def register_private_blueprints(private_api, app):
|
|||
app.register_blueprint(insertblock.ib)
|
||||
app.register_blueprint(miscclientapi.getblocks.client_get_blocks)
|
||||
app.register_blueprint(miscclientapi.endpoints.PrivateEndpoints(private_api).private_endpoints_bp)
|
||||
app.register_blueprint(miscclientapi.motd.bp)
|
||||
app.register_blueprint(onionrsitesapi.site_api)
|
||||
app.register_blueprint(apiutils.shutdown.shutdown_bp)
|
||||
app.register_blueprint(miscclientapi.staticfiles.static_files_bp)
|
||||
|
|
|
@ -1 +1 @@
|
|||
from . import getblocks, staticfiles, endpoints
|
||||
from . import getblocks, staticfiles, endpoints, motd
|
|
@ -0,0 +1,27 @@
|
|||
from flask import Blueprint
|
||||
from flask import Response
|
||||
import unpaddedbase32
|
||||
|
||||
from coredb import blockmetadb
|
||||
import onionrblocks
|
||||
from etc import onionrvalues
|
||||
import config
|
||||
from onionrutils import bytesconverter
|
||||
|
||||
bp = Blueprint('motd', __name__)
|
||||
|
||||
signer = config.get("motd.motd_key", onionrvalues.MOTD_SIGN_KEY)
|
||||
|
||||
@bp.route('/getmotd')
|
||||
def get_motd()->Response:
|
||||
motds = blockmetadb.get_blocks_by_type("motd")
|
||||
newest_time = 0
|
||||
message = "No MOTD currently present."
|
||||
for x in motds:
|
||||
bl = onionrblocks.onionrblockapi.Block(x)
|
||||
if not bl.verifySig() or bl.signer != bytesconverter.bytes_to_str(unpaddedbase32.repad(bytesconverter.str_to_bytes(signer))): continue
|
||||
if not bl.isSigner(signer): continue
|
||||
if bl.claimedTime > newest_time:
|
||||
newest_time = bl.claimedTime
|
||||
message = bl.bcontent
|
||||
return Response(message, headers={"Content-Type": "text/plain"})
|
|
@ -17,12 +17,14 @@
|
|||
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 unpaddedbase32
|
||||
import binascii
|
||||
import logger, config, onionrexceptions, nacl.exceptions
|
||||
import json, os, sys, datetime, base64, onionrstorage
|
||||
from onionrusers import onionrusers
|
||||
from onionrutils import stringvalidators, epoch
|
||||
from coredb import blockmetadb
|
||||
from onionrutils import bytesconverter
|
||||
from onionrstorage import removeblock
|
||||
import onionrblocks
|
||||
from onionrcrypto import encryption, cryptoutils as cryptoutils, signing
|
||||
|
@ -127,7 +129,9 @@ class Block:
|
|||
'''
|
||||
Verify if a block's signature is signed by its claimed signer
|
||||
'''
|
||||
if self.signer is None or signing.ed_verify(data=self.signedData, key=self.signer, sig=self.signature, encodedData=True):
|
||||
if self.signer is None:
|
||||
return False
|
||||
if signing.ed_verify(data=self.signedData, key=self.signer, sig=self.signature, encodedData=True):
|
||||
self.validSig = True
|
||||
else:
|
||||
self.validSig = False
|
||||
|
@ -175,7 +179,7 @@ class Block:
|
|||
self.signer = self.getHeader('signer', None)
|
||||
self.signature = self.getHeader('sig', None)
|
||||
# signed data is jsonMeta + block content (no linebreak)
|
||||
self.signedData = (None if not self.isSigned() else self.getHeader('meta') + self.getContent())
|
||||
self.signedData = (None if not self.isSigned() else self.getHeader('meta').encode() + self.getContent())
|
||||
self.date = blockmetadb.get_block_date(self.getHash())
|
||||
self.claimedTime = self.getHeader('time', None)
|
||||
|
||||
|
@ -328,7 +332,7 @@ class Block:
|
|||
- (str): the contents of the block
|
||||
'''
|
||||
|
||||
return str(self.bcontent)
|
||||
return self.bcontent
|
||||
|
||||
def getDate(self):
|
||||
'''
|
||||
|
@ -401,7 +405,7 @@ class Block:
|
|||
Outputs:
|
||||
- (bool): whether or not the signer of the block is the signer inputted
|
||||
'''
|
||||
|
||||
signer = unpaddedbase32.repad(bytesconverter.str_to_bytes(signer))
|
||||
try:
|
||||
if (not self.isSigned()) or (not stringvalidators.validate_pub_key(signer)):
|
||||
return False
|
||||
|
|
|
@ -143,7 +143,7 @@ kill_daemon.onionr_help = "Gracefully stops the Onionr API servers"
|
|||
def start(input: bool = False, override: bool = False):
|
||||
"""If no lock file, make one and start onionr, error if there is and its not overridden"""
|
||||
if os.path.exists(filepaths.lock_file) and not override:
|
||||
logger.fatal('Cannot start. Daemon is already running, or it did not exit cleanly.\n(if you are sure that there is not a daemon running, delete filepaths.lock_file & try again).', terminal=True)
|
||||
logger.fatal('Cannot start. Daemon is already running, or it did not exit cleanly.\n(if you are sure that there is not a daemon running, delete onionr.lock & try again).', terminal=True)
|
||||
else:
|
||||
if not onionrvalues.DEVELOPMENT_MODE:
|
||||
lockFile = open(filepaths.lock_file, 'w')
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import onionrblocks
|
||||
|
||||
def motd_creator():
|
||||
"""Create a new MOTD message for the Onionr network"""
|
||||
motd = ''
|
||||
new = ''
|
||||
print('Enter a new MOTD, quit on a new line:')
|
||||
while new != 'quit':
|
||||
new = input()
|
||||
if new != 'quit':
|
||||
motd += new
|
||||
bl = onionrblocks.insert(motd, header='motd', sign=True)
|
||||
print(f"inserted in {bl}")
|
||||
|
||||
motd_creator.onionr_help = "Create a new MOTD message for the onionr network"
|
|
@ -18,6 +18,7 @@
|
|||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
'''
|
||||
from typing import Callable
|
||||
|
||||
from .. import onionrstatistics, version, daemonlaunch, keyadders, openwebinterface
|
||||
from .. import banblocks # Command to blacklist a block by its hash
|
||||
from .. import filecommands # commands to share files with onionr
|
||||
|
@ -28,6 +29,8 @@ from .. import resetplugins # command to reinstall default plugins
|
|||
from .. import softreset # command to delete onionr blocks
|
||||
from .. import restartonionr # command to restart Onionr
|
||||
from .. import runtimetestcmd
|
||||
from .. import motdcreator
|
||||
|
||||
import onionrexceptions
|
||||
from onionrutils import importnewblocks # func to import new blocks
|
||||
from onionrplugins import onionrevents as events
|
||||
|
@ -57,7 +60,8 @@ def get_arguments()->dict:
|
|||
('resetplugins', 'reset-plugins'): resetplugins.reset,
|
||||
('reset-tor-node-transport',): resettor.reset_tor_key_pair,
|
||||
('soft-reset', 'softreset'): softreset.soft_reset,
|
||||
('runtime-test', 'runtimetest'): runtimetestcmd.do_runtime_test
|
||||
('runtime-test', 'runtimetest'): runtimetestcmd.do_runtime_test,
|
||||
('makemotd', 'make-motd'): motdcreator.motd_creator
|
||||
|
||||
}
|
||||
return args
|
||||
|
|
|
@ -27,7 +27,6 @@ def ed_verify(data, key, sig, encodedData=True):
|
|||
try:
|
||||
key = nacl.signing.VerifyKey(key=key, encoder=nacl.encoding.Base32Encoder)
|
||||
except nacl.exceptions.ValueError:
|
||||
#logger.debug('Signature by unknown key (cannot reverse hash)')
|
||||
return False
|
||||
except binascii.Error:
|
||||
logger.warn('Could not load key for verification, invalid padding')
|
||||
|
@ -38,14 +37,8 @@ def ed_verify(data, key, sig, encodedData=True):
|
|||
data = data.encode()
|
||||
except AttributeError:
|
||||
pass
|
||||
if encodedData:
|
||||
try:
|
||||
retData = key.verify(data, sig) # .encode() is not the same as nacl.encoding
|
||||
except nacl.exceptions.BadSignatureError:
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
retData = key.verify(data, sig)
|
||||
except nacl.exceptions.BadSignatureError:
|
||||
pass
|
||||
try:
|
||||
retData = key.verify(data, sig) # .encode() is not the same as nacl.encoding
|
||||
except nacl.exceptions.BadSignatureError:
|
||||
pass
|
||||
return retData
|
|
@ -140,6 +140,17 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card motdCard">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title" title="message of the day">
|
||||
Onionr MOTD
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content motdContent">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
<!--Statistics Card-->
|
||||
|
@ -148,13 +159,6 @@
|
|||
<p class="card-header-title">
|
||||
Statistics
|
||||
</p>
|
||||
<div class="field">
|
||||
<div class="is-pulled-right">
|
||||
<a class="button is-link" id='refreshStats'>
|
||||
Refresh Stats
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
|
|
|
@ -9,3 +9,7 @@
|
|||
#refreshStats{
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.motdCard{
|
||||
margin-top: 1em;
|
||||
}
|
|
@ -13,8 +13,9 @@
|
|||
|
||||
<b>Contributors:</b>
|
||||
<ul>
|
||||
<li><a href="https://invisamage.com/">Travis Kipp</a> (web UI and CSS)</li>
|
||||
<li><a href="https://k7dxs.net/">Duncan Simpson</a> Packaging help</li>
|
||||
<li><a href="https://invisamage.com/">Travis Kipp</a> web UI and CSS</li>
|
||||
<li><a href="https://k7dxs.net/">Duncan Simpson</a> packaging help</li>
|
||||
<li><a href="https://www.siue.edu/~njohnag/">Nicholas Johnson</a> bug fixes</li>
|
||||
</ul>
|
||||
|
||||
<br>
|
||||
|
|
Loading…
Reference in New Issue