added motd system, reworked handling of bytes in signatures

This commit is contained in:
Kevin Froman 2019-10-07 21:32:33 -05:00
parent 31825bfad7
commit 695f334297
11 changed files with 80 additions and 27 deletions

View File

@ -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)

View File

@ -1 +1 @@
from . import getblocks, staticfiles, endpoints
from . import getblocks, staticfiles, endpoints, motd

View File

@ -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"})

View File

@ -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

View File

@ -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')

View File

@ -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"

View File

@ -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

View File

@ -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
return retData

View File

@ -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">

View File

@ -9,3 +9,7 @@
#refreshStats{
margin: 5px;
}
.motdCard{
margin-top: 1em;
}

View File

@ -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>