diff --git a/onionr/apiservers/private/register_private_blueprints.py b/onionr/apiservers/private/register_private_blueprints.py
index 0cb463f5..f6d03e37 100644
--- a/onionr/apiservers/private/register_private_blueprints.py
+++ b/onionr/apiservers/private/register_private_blueprints.py
@@ -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)
diff --git a/onionr/httpapi/miscclientapi/__init__.py b/onionr/httpapi/miscclientapi/__init__.py
index 6ea8ea0f..dadcb97c 100644
--- a/onionr/httpapi/miscclientapi/__init__.py
+++ b/onionr/httpapi/miscclientapi/__init__.py
@@ -1 +1 @@
-from . import getblocks, staticfiles, endpoints
\ No newline at end of file
+from . import getblocks, staticfiles, endpoints, motd
\ No newline at end of file
diff --git a/onionr/httpapi/miscclientapi/motd/__init__.py b/onionr/httpapi/miscclientapi/motd/__init__.py
new file mode 100644
index 00000000..ad57b91a
--- /dev/null
+++ b/onionr/httpapi/miscclientapi/motd/__init__.py
@@ -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"})
diff --git a/onionr/onionrblocks/onionrblockapi.py b/onionr/onionrblocks/onionrblockapi.py
index f15347f0..a8c2343b 100755
--- a/onionr/onionrblocks/onionrblockapi.py
+++ b/onionr/onionrblocks/onionrblockapi.py
@@ -17,12 +17,14 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
'''
+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
diff --git a/onionr/onionrcommands/daemonlaunch.py b/onionr/onionrcommands/daemonlaunch.py
index 590fcb33..cfb86ebd 100755
--- a/onionr/onionrcommands/daemonlaunch.py
+++ b/onionr/onionrcommands/daemonlaunch.py
@@ -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')
diff --git a/onionr/onionrcommands/motdcreator.py b/onionr/onionrcommands/motdcreator.py
new file mode 100644
index 00000000..93586f74
--- /dev/null
+++ b/onionr/onionrcommands/motdcreator.py
@@ -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"
diff --git a/onionr/onionrcommands/parser/arguments.py b/onionr/onionrcommands/parser/arguments.py
index 3cd110e8..2011daa1 100644
--- a/onionr/onionrcommands/parser/arguments.py
+++ b/onionr/onionrcommands/parser/arguments.py
@@ -18,6 +18,7 @@
along with this program. If not, see .
'''
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
diff --git a/onionr/onionrcrypto/signing/__init__.py b/onionr/onionrcrypto/signing/__init__.py
index 3562efe0..61a9616e 100644
--- a/onionr/onionrcrypto/signing/__init__.py
+++ b/onionr/onionrcrypto/signing/__init__.py
@@ -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
\ No newline at end of file
diff --git a/static-data/www/private/index.html b/static-data/www/private/index.html
index 88f66ef8..d740961d 100755
--- a/static-data/www/private/index.html
+++ b/static-data/www/private/index.html
@@ -140,6 +140,17 @@
+
@@ -148,13 +159,6 @@
-
diff --git a/static-data/www/private/main.css b/static-data/www/private/main.css
index 7a80bef2..2d7ed83f 100755
--- a/static-data/www/private/main.css
+++ b/static-data/www/private/main.css
@@ -8,4 +8,8 @@
}
#refreshStats{
margin: 5px;
+}
+
+.motdCard{
+ margin-top: 1em;
}
\ No newline at end of file
diff --git a/static-data/www/shared/about.html b/static-data/www/shared/about.html
index bc8fafe8..e4b5f32b 100644
--- a/static-data/www/shared/about.html
+++ b/static-data/www/shared/about.html
@@ -13,8 +13,9 @@
Contributors: