* refactored blockmetadata
* be more careful with block type length + work on chatmaster
parent
8c7319048d
commit
7c02f6fff1
|
@ -27,6 +27,8 @@ API_VERSION = '0' # increments of 1; only change when something fundamental abou
|
||||||
MIN_PY_VERSION = 6
|
MIN_PY_VERSION = 6
|
||||||
DEVELOPMENT_MODE = True
|
DEVELOPMENT_MODE = True
|
||||||
|
|
||||||
|
MAX_BLOCK_TYPE_LENGTH = 15
|
||||||
|
|
||||||
platform = platform.system()
|
platform = platform.system()
|
||||||
if platform == 'Windows':
|
if platform == 'Windows':
|
||||||
SCRIPT_NAME = 'run-windows.bat'
|
SCRIPT_NAME = 'run-windows.bat'
|
||||||
|
|
|
@ -54,7 +54,7 @@ class ClientAPISecurity:
|
||||||
def after_req(resp):
|
def after_req(resp):
|
||||||
# Security headers
|
# Security headers
|
||||||
resp = httpheaders.set_default_onionr_http_headers(resp)
|
resp = httpheaders.set_default_onionr_http_headers(resp)
|
||||||
if request.endpoint == 'site':
|
if request.endpoint == 'siteapi.site':
|
||||||
resp.headers['Content-Security-Policy'] = "default-src 'none'; style-src data: 'unsafe-inline'; img-src data:"
|
resp.headers['Content-Security-Policy'] = "default-src 'none'; style-src data: 'unsafe-inline'; img-src data:"
|
||||||
else:
|
else:
|
||||||
resp.headers['Content-Security-Policy'] = "default-src 'none'; script-src 'self'; object-src 'none'; style-src 'self'; img-src 'self'; media-src 'none'; frame-src 'none'; font-src 'none'; connect-src 'self'"
|
resp.headers['Content-Security-Policy'] = "default-src 'none'; script-src 'self'; object-src 'none'; style-src 'self'; img-src 'self'; media-src 'none'; frame-src 'none'; font-src 'none'; connect-src 'self'"
|
||||||
|
|
|
@ -42,11 +42,11 @@ def add_file(singleBlock=False, blockType='bin'):
|
||||||
logger.info('Adding file... this might take a long time.', terminal=True)
|
logger.info('Adding file... this might take a long time.', terminal=True)
|
||||||
try:
|
try:
|
||||||
with open(filename, 'rb') as singleFile:
|
with open(filename, 'rb') as singleFile:
|
||||||
blockhash = insert.insert_block(base64.b64encode(singleFile.read()), header=blockType)
|
blockhash = insert(base64.b64encode(singleFile.read()), header=blockType)
|
||||||
if len(blockhash) > 0:
|
if len(blockhash) > 0:
|
||||||
logger.info('File %s saved in block %s' % (filename, blockhash), terminal=True)
|
logger.info('File %s saved in block %s' % (filename, blockhash), terminal=True)
|
||||||
except:
|
except Exception as e:
|
||||||
logger.error('Failed to save file in block.', timestamp = False, terminal=True)
|
logger.error('Failed to save file in block ' + str(e), timestamp = False, terminal=True)
|
||||||
else:
|
else:
|
||||||
logger.error('%s add-file <filename>' % sys.argv[0], timestamp = False, terminal=True)
|
logger.error('%s add-file <filename>' % sys.argv[0], timestamp = False, terminal=True)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
'''
|
||||||
|
Onionr - Private P2P Communication
|
||||||
|
|
||||||
|
Module to work with block metadata
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
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/>.
|
||||||
|
'''
|
||||||
|
|
||||||
|
from . import hasblock, fromdata, process
|
||||||
|
has_block = hasblock.has_block
|
||||||
|
process_block_metadata = process.process_block_metadata
|
||||||
|
get_block_metadata_from_data = fromdata.get_block_metadata_from_data
|
|
@ -0,0 +1,49 @@
|
||||||
|
'''
|
||||||
|
Onionr - Private P2P Communication
|
||||||
|
|
||||||
|
Return a useful tuple of (metadata (header), meta, and data) by accepting raw block data
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
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 json
|
||||||
|
def get_block_metadata_from_data(block_data):
|
||||||
|
'''
|
||||||
|
accepts block contents as string, returns a tuple of
|
||||||
|
metadata, meta (meta being internal metadata, which will be
|
||||||
|
returned as an encrypted base64 string if it is encrypted, dict if not).
|
||||||
|
'''
|
||||||
|
meta = {}
|
||||||
|
metadata = {}
|
||||||
|
data = block_data
|
||||||
|
try:
|
||||||
|
block_data = block_data.encode()
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
metadata = json.loads(block_data[:block_data.find(b'\n')].decode())
|
||||||
|
except json.decoder.JSONDecodeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
data = block_data[block_data.find(b'\n'):].decode()
|
||||||
|
|
||||||
|
if not metadata['encryptType'] in ('asym', 'sym'):
|
||||||
|
try:
|
||||||
|
meta = json.loads(metadata['meta'])
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
meta = metadata['meta']
|
||||||
|
return (metadata, meta, data)
|
|
@ -0,0 +1,42 @@
|
||||||
|
'''
|
||||||
|
Onionr - Private P2P Communication
|
||||||
|
|
||||||
|
Returns a bool if a block is in the block metadata db or not
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
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 sqlite3
|
||||||
|
from coredb import dbfiles
|
||||||
|
import onionrexceptions
|
||||||
|
from .. import stringvalidators
|
||||||
|
|
||||||
|
def has_block(hash: str) -> bool:
|
||||||
|
'''
|
||||||
|
Check for new block in the block meta db
|
||||||
|
'''
|
||||||
|
conn = sqlite3.connect(dbfiles.block_meta_db)
|
||||||
|
c = conn.cursor()
|
||||||
|
if not stringvalidators.validate_hash(hash):
|
||||||
|
raise onionrexceptions.InvalidHexHash("Invalid hash")
|
||||||
|
for result in c.execute("SELECT COUNT() FROM hashes WHERE hash = ?", (hash,)):
|
||||||
|
if result[0] >= 1:
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return False
|
||||||
|
return False
|
|
@ -1,7 +1,7 @@
|
||||||
'''
|
'''
|
||||||
Onionr - Private P2P Communication
|
Onionr - Private P2P Communication
|
||||||
|
|
||||||
Module to fetch block metadata from raw block data and process it
|
Process block metadata with relevant actions
|
||||||
'''
|
'''
|
||||||
'''
|
'''
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
@ -17,45 +17,19 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
'''
|
'''
|
||||||
import json, sqlite3
|
|
||||||
import logger, onionrevents
|
|
||||||
from onionrusers import onionrusers
|
|
||||||
from etc import onionrvalues
|
from etc import onionrvalues
|
||||||
import onionrblockapi
|
import onionrblockapi
|
||||||
from . import epoch, stringvalidators, bytesconverter
|
from .. import epoch, bytesconverter
|
||||||
from coredb import dbfiles, blockmetadb
|
from coredb import blockmetadb
|
||||||
def get_block_metadata_from_data(blockData):
|
import logger
|
||||||
'''
|
import onionrevents
|
||||||
accepts block contents as string, returns a tuple of
|
|
||||||
metadata, meta (meta being internal metadata, which will be
|
|
||||||
returned as an encrypted base64 string if it is encrypted, dict if not).
|
|
||||||
'''
|
|
||||||
meta = {}
|
|
||||||
metadata = {}
|
|
||||||
data = blockData
|
|
||||||
try:
|
|
||||||
blockData = blockData.encode()
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
def process_block_metadata(blockHash: str):
|
||||||
metadata = json.loads(blockData[:blockData.find(b'\n')].decode())
|
|
||||||
except json.decoder.JSONDecodeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
data = blockData[blockData.find(b'\n'):].decode()
|
|
||||||
|
|
||||||
if not metadata['encryptType'] in ('asym', 'sym'):
|
|
||||||
try:
|
|
||||||
meta = json.loads(metadata['meta'])
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
meta = metadata['meta']
|
|
||||||
return (metadata, meta, data)
|
|
||||||
|
|
||||||
def process_block_metadata(blockHash):
|
|
||||||
'''
|
'''
|
||||||
Read metadata from a block and cache it to the block database
|
Read metadata from a block and cache it to the block database
|
||||||
|
|
||||||
|
blockHash -> sha3_256 hex formatted hash of Onionr block
|
||||||
'''
|
'''
|
||||||
curTime = epoch.get_rounded_epoch(roundS=60)
|
curTime = epoch.get_rounded_epoch(roundS=60)
|
||||||
myBlock = onionrblockapi.Block(blockHash)
|
myBlock = onionrblockapi.Block(blockHash)
|
||||||
|
@ -67,10 +41,13 @@ def process_block_metadata(blockHash):
|
||||||
signer = bytesconverter.bytes_to_str(myBlock.signer)
|
signer = bytesconverter.bytes_to_str(myBlock.signer)
|
||||||
valid = myBlock.verifySig()
|
valid = myBlock.verifySig()
|
||||||
if myBlock.getMetadata('newFSKey') is not None:
|
if myBlock.getMetadata('newFSKey') is not None:
|
||||||
|
try:
|
||||||
onionrusers.OnionrUser(signer).addForwardKey(myBlock.getMetadata('newFSKey'))
|
onionrusers.OnionrUser(signer).addForwardKey(myBlock.getMetadata('newFSKey'))
|
||||||
|
except onionrexceptions.InvalidPubkey:
|
||||||
|
logger.warn('%s has invalid forward secrecy key to add: %s' % (signer, myBlock.getMetadata('newFSKey')))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if len(blockType) <= 10:
|
if len(blockType) <= onionrvalues.MAX_BLOCK_TYPE_LENGTH:
|
||||||
blockmetadb.update_block_info(blockHash, 'dataType', blockType)
|
blockmetadb.update_block_info(blockHash, 'dataType', blockType)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
logger.warn("Missing block information")
|
logger.warn("Missing block information")
|
||||||
|
@ -83,27 +60,4 @@ def process_block_metadata(blockHash):
|
||||||
expireTime = onionrvalues.OnionrValues().default_expire + curTime
|
expireTime = onionrvalues.OnionrValues().default_expire + curTime
|
||||||
finally:
|
finally:
|
||||||
blockmetadb.update_block_info(blockHash, 'expire', expireTime)
|
blockmetadb.update_block_info(blockHash, 'expire', expireTime)
|
||||||
if not blockType is None:
|
|
||||||
blockmetadb.update_block_info(blockHash, 'dataType', blockType)
|
|
||||||
onionrevents.event('processblocks', data = {'block': myBlock, 'type': blockType, 'signer': signer, 'validSig': valid})
|
onionrevents.event('processblocks', data = {'block': myBlock, 'type': blockType, 'signer': signer, 'validSig': valid})
|
||||||
else:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def has_block(hash):
|
|
||||||
'''
|
|
||||||
Check for new block in the list
|
|
||||||
'''
|
|
||||||
conn = sqlite3.connect(dbfiles.block_meta_db)
|
|
||||||
c = conn.cursor()
|
|
||||||
if not stringvalidators.validate_hash(hash):
|
|
||||||
raise Exception("Invalid hash")
|
|
||||||
for result in c.execute("SELECT COUNT() FROM hashes WHERE hash = ?", (hash,)):
|
|
||||||
if result[0] >= 1:
|
|
||||||
conn.commit()
|
|
||||||
conn.close()
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
conn.commit()
|
|
||||||
conn.close()
|
|
||||||
return False
|
|
||||||
return False
|
|
|
@ -68,3 +68,6 @@ def get_messages(peer):
|
||||||
existing = list(existing)
|
existing = list(existing)
|
||||||
key_store.delete('r' + peer)
|
key_store.delete('r' + peer)
|
||||||
return Response(json.dumps(existing))
|
return Response(json.dumps(existing))
|
||||||
|
|
||||||
|
#@flask_blueprint.route('/chatapi/connect/<peer>')
|
||||||
|
#def create_connection(peer)
|
|
@ -36,58 +36,3 @@ def exit_with_error(text=''):
|
||||||
if text != '':
|
if text != '':
|
||||||
logger.error(text)
|
logger.error(text)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
class Chat:
|
|
||||||
def __init__(self, pluginapi):
|
|
||||||
self.peer = None
|
|
||||||
self.transport = None
|
|
||||||
self.shutdown = False
|
|
||||||
self.pluginapi = pluginapi
|
|
||||||
|
|
||||||
def _sender_loop(self):
|
|
||||||
print('Enter a message to send, with ctrl-d or -s on a new line.')
|
|
||||||
print('-c on a new line or ctrl-c stops')
|
|
||||||
message = ''
|
|
||||||
while not self.shutdown:
|
|
||||||
try:
|
|
||||||
message += input()
|
|
||||||
if message == '-s':
|
|
||||||
raise EOFError
|
|
||||||
elif message == '-c':
|
|
||||||
raise KeyboardInterrupt
|
|
||||||
else:
|
|
||||||
message += '\n'
|
|
||||||
except EOFError:
|
|
||||||
message = json.dumps({'m': message, 't': epoch.get_epoch()})
|
|
||||||
print(basicrequests.do_post_request(self.pluginapi.onionr, 'http://%s/chat/sendto' % (self.transport,), port=self.socks, data=message))
|
|
||||||
message = ''
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
self.shutdown = True
|
|
||||||
|
|
||||||
def create(self):
|
|
||||||
try:
|
|
||||||
peer = sys.argv[2]
|
|
||||||
if not stringvalidators.validate_pub_key(peer):
|
|
||||||
exit_with_error('Invalid public key specified')
|
|
||||||
except IndexError:
|
|
||||||
exit_with_error('You must specify a peer public key')
|
|
||||||
self.peer = peer
|
|
||||||
# Ask peer for transport address by creating block for them
|
|
||||||
peer_transport_address = bootstrapservice.bootstrap_client_service(peer)
|
|
||||||
self.transport = peer_transport_address
|
|
||||||
self.socks = config.get('tor.socksport')
|
|
||||||
|
|
||||||
print('connected with', peer, 'on', peer_transport_address)
|
|
||||||
if basicrequests.do_get_request('http://%s/ping' % (peer_transport_address,), ignoreAPI=True, port=self.socks) == 'pong!':
|
|
||||||
print('connected', peer_transport_address)
|
|
||||||
threading.Thread(target=self._sender_loop).start()
|
|
||||||
|
|
||||||
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
|
|
||||||
chat = Chat(pluginapi)
|
|
||||||
return
|
|
||||||
|
|
|
@ -60,9 +60,9 @@ def list_sentbox():
|
||||||
deleted = kv.get('deleted_mail')
|
deleted = kv.get('deleted_mail')
|
||||||
if deleted is None:
|
if deleted is None:
|
||||||
deleted = []
|
deleted = []
|
||||||
for x in list_copy:
|
for sent in list_copy:
|
||||||
if x['hash'] in deleted:
|
if sent['hash'] in deleted:
|
||||||
sentbox_list.remove(x)
|
sentbox_list.remove(sent)
|
||||||
continue
|
continue
|
||||||
x['name'] = contactmanager.ContactManager(x['peer'], saveUser=False).get_info('name')
|
sent['name'] = contactmanager.ContactManager(sent['peer'], saveUser=False).get_info('name')
|
||||||
return json.dumps(sentbox_list)
|
return json.dumps(sentbox_list)
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"name" : "searchengine",
|
||||||
|
"version" : "0.0.0",
|
||||||
|
"author" : "0gitnick"
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
'''
|
||||||
|
Onionr - Private P2P Communication
|
||||||
|
|
||||||
|
Search engine plugin for Onionr, to search for
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
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/>.
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
plugin_name = 'searchengine'
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
<link rel="stylesheet" href="/chat/css/convos.css">
|
<link rel="stylesheet" href="/chat/css/convos.css">
|
||||||
<script defer src='/shared/navbar.js'></script>
|
<script defer src='/shared/navbar.js'></script>
|
||||||
<script defer src='/shared/misc.js'></script>
|
<script defer src='/shared/misc.js'></script>
|
||||||
|
<script defer src='/chat/messages/js'></script>
|
||||||
<script defer src='/chat/js/message-feed.js'></script>
|
<script defer src='/chat/js/message-feed.js'></script>
|
||||||
<script defer src='/chat/js/main.js'></script>
|
<script defer src='/chat/js/main.js'></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
|
@ -17,5 +17,8 @@
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>
|
along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
let MessageCache = class {
|
let MessageCache = class {
|
||||||
|
constructor(user) {
|
||||||
|
this.user = user
|
||||||
|
this.cache = [] // array of Messages
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
Onionr - Private P2P Communication
|
||||||
|
|
||||||
|
Onionr chat message objects
|
||||||
|
|
||||||
|
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/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
let Message = class {
|
||||||
|
constructor(text, to, time){
|
||||||
|
this.text = text // string
|
||||||
|
this.to = to // bool. False = not outgoing
|
||||||
|
this.time = time // epoch int
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue