Merge remote-tracking branch 'origin/tempblocks' into onionrui

This commit is contained in:
Arinerron 2018-11-09 22:13:50 -08:00
commit d5355fdc9e
No known key found for this signature in database
GPG key ID: 99383627861C62F0
35 changed files with 1273 additions and 414 deletions

View file

@ -46,14 +46,15 @@ class OnionrCLIUI:
showMenu = True
isOnline = "No"
firstRun = True
choice = ''
if self.myCore._utils.localCommand('ping') == 'pong':
firstRun = False
while showMenu:
if firstRun:
print("please wait while Onionr starts...")
daemon = subprocess.Popen(["./onionr.py", "start"], stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
logger.info("please wait while Onionr starts...")
daemon = subprocess.Popen(["./onionr.py", "start"], stdin=subprocess.PIPE, stdout=subprocess.DEVNULL)
time.sleep(30)
firstRun = False
@ -91,7 +92,6 @@ Daemon Running: ''' + isOnline + '''
elif choice in ("5", "daemon"):
if isOnline == "Yes":
print("Onionr daemon will shutdown...")
#self.myCore._utils.localCommand("shutdown")
self.myCore.daemonQueueAdd('shutdown')
try:
daemon.kill()

View file

@ -0,0 +1,5 @@
{
"name" : "encrypt",
"version" : "1.0",
"author" : "onionr"
}

View file

@ -0,0 +1,117 @@
'''
Onionr - P2P Microblogging Platform & Social network
This default plugin allows users to encrypt/decrypt messages without using blocks
'''
'''
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/>.
'''
# Imports some useful libraries
import logger, config, threading, time, readline, datetime, sys, json
from onionrblockapi import Block
import onionrexceptions, onionrusers
import locale
locale.setlocale(locale.LC_ALL, '')
class PlainEncryption:
def __init__(self, api):
self.api = api
return
def encrypt(self):
# peer, data
plaintext = ""
encrypted = ""
# detect if signing is enabled
sign = True
try:
if sys.argv[3].lower() == 'false':
sign = False
except IndexError:
pass
try:
if not self.api.get_core()._utils.validatePubKey(sys.argv[2]):
raise onionrexceptions.InvalidPubkey
except (ValueError, IndexError) as e:
logger.error("Peer public key not specified")
except onionrexceptions.InvalidPubkey:
logger.error("Invalid public key")
else:
pubkey = sys.argv[2]
# Encrypt if public key is valid
logger.info("Please enter your message (ctrl-d or -q to stop):")
try:
for line in sys.stdin:
if line == '-q\n':
break
plaintext += line
except KeyboardInterrupt:
sys.exit(1)
# Build Message to encrypt
data = {}
myPub = self.api.get_core()._crypto.pubKey
if sign:
data['sig'] = self.api.get_core()._crypto.edSign(plaintext, key=self.api.get_core()._crypto.privKey, encodeResult=True)
data['sig'] = self.api.get_core()._utils.bytesToStr(data['sig'])
data['signer'] = myPub
data['data'] = plaintext
data = json.dumps(data)
plaintext = data
encrypted = self.api.get_core()._crypto.pubKeyEncrypt(plaintext, pubkey, anonymous=True, encodedData=True)
encrypted = self.api.get_core()._utils.bytesToStr(encrypted)
print('ONIONR ENCRYPTED DATA %s END ENCRYPTED DATA' % (encrypted,))
def decrypt(self):
plaintext = ""
data = ""
logger.info("Please enter your message (ctrl-d or -q to stop):")
try:
for line in sys.stdin:
if line == '-q\n':
break
data += line
except KeyboardInterrupt:
sys.exit(1)
if len(data) <= 1:
return
encrypted = data.replace('ONIONR ENCRYPTED DATA ', '').replace('END ENCRYPTED DATA', '')
myPub = self.api.get_core()._crypto.pubKey
decrypted = self.api.get_core()._crypto.pubKeyDecrypt(encrypted, privkey=self.api.get_core()._crypto.privKey, anonymous=True, encodedData=True)
if decrypted == False:
print("Decryption failed")
else:
data = json.loads(decrypted)
print(data['data'])
try:
logger.info("Signing public key: %s" % (data['signer'],))
assert self.api.get_core()._crypto.edVerify(data['data'], data['signer'], data['sig']) != False
except (AssertionError, KeyError) as e:
logger.warn("WARNING: THIS MESSAGE HAS A MISSING OR INVALID SIGNATURE")
else:
logger.info("Message has good signature.")
return
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
encrypt = PlainEncryption(pluginapi)
api.commands.register(['encrypt'], encrypt.encrypt)
api.commands.register(['decrypt'], encrypt.decrypt)
return

View file

@ -45,9 +45,9 @@ class OnionrFlow:
self.flowRunning = False
if message == "q":
self.flowRunning = False
expireTime = self.myCore._utils.getEpoch() + 43200
if len(message) > 0:
Block(content = message, type = 'txt', core = self.myCore).save()
Block(content = message, type = 'txt', expire=expireTime, core = self.myCore).save()
logger.info("Flow is exiting, goodbye")
return

View file

@ -0,0 +1,5 @@
{
"name" : "metadataprocessor",
"version" : "1.0",
"author" : "onionr"
}

View file

@ -0,0 +1,103 @@
'''
Onionr - P2P Anonymous Storage Network
This processes metadata for Onionr blocks
'''
'''
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/>.
'''
# useful libraries
import logger, config
import os, sys, json, time, random, shutil, base64, getpass, datetime, re
from onionrblockapi import Block
import onionrusers, onionrexceptions
plugin_name = 'metadataprocessor'
# event listeners
def _processUserInfo(api, newBlock):
'''
Set the username for a particular user, from a signed block by them
'''
myBlock = newBlock
peerName = myBlock.getMetadata('name')
try:
if len(peerName) > 20:
raise onionrexceptions.InvalidMetdata('Peer name specified is too large')
except TypeError:
pass
except onionrexceptions.InvalidMetadata:
pass
else:
api.get_core().setPeerInfo(signer, 'name', peerName)
logger.info('%s is now using the name %s.' % (signer, api.get_utils().escapeAnsi(peerName)))
def _processForwardKey(api, myBlock):
'''
Get the forward secrecy key specified by the user for us to use
'''
peer = onionrusers.OnionrUser(api.get_core(), myBlock.signer)
key = myBlock.getMetadata('newFSKey')
# We don't need to validate here probably, but it helps
if api.get_utils().validatePubKey(key):
peer.addForwardKey(key)
else:
raise onionrexceptions.InvalidPubkey("%s is nota valid pubkey key" % (key,))
def on_processblocks(api):
# Generally fired by utils.
myBlock = api.data['block']
blockType = api.data['type']
logger.info('blockType is ' + blockType)
# Process specific block types
# userInfo blocks, such as for setting username
if blockType == 'userInfo':
if api.data['validSig'] == True: # we use == True for type safety
_processUserInfo(api, myBlock)
# forwardKey blocks, add a new forward secrecy key for a peer
elif blockType == 'forwardKey':
if api.data['validSig'] == True:
_processForwardKey(api, myBlock)
# socket blocks
elif blockType == 'socket':
if api.data['validSig'] == True and myBlock.decrypted: # we check if it is decrypted as a way of seeing if it was for us
logger.info('Detected socket advertised to us...')
try:
address = myBlock.getMetadata('address')
except KeyError:
raise onionrexceptions.MissingAddress("Missing address for new socket")
try:
port = myBlock.getMetadata('port')
except KeyError:
raise ValueError("Missing port for new socket")
try:
reason = myBlock.getMetadata('reason')
except KeyError:
raise ValueError("Missing socket reason")
socketInfo = json.dumps({'peer': api.data['signer'], 'address': address, 'port': port, 'create': False, 'reason': reason})
api.get_core().daemonQueueAdd('addSocket', socketInfo)
else:
logger.warn("socket is not for us or is invalid")
def on_init(api, data = None):
pluginapi = api
return

View file

@ -1,5 +1,5 @@
'''
Onionr - P2P Microblogging Platform & Social network
Onionr - P2P Anonymous Storage Network
This default plugin handles private messages in an email like fashion
'''
@ -22,9 +22,13 @@
import logger, config, threading, time, readline, datetime
from onionrblockapi import Block
import onionrexceptions, onionrusers
import locale
import locale, sys, os
locale.setlocale(locale.LC_ALL, '')
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
import sentboxdb # import after path insert
plugin_name = 'pms'
PLUGIN_VERSION = '0.0.1'
@ -44,22 +48,23 @@ class MailStrings:
self.mailInstance = mailInstance
self.programTag = 'OnionrMail v%s' % (PLUGIN_VERSION)
choices = ['view inbox', 'view sentbox', 'send message', 'help', 'quit']
choices = ['view inbox', 'view sentbox', 'send message', 'quit']
self.mainMenuChoices = choices
self.mainMenu = '''\n
-----------------
1. %s
2. %s
3. %s
4. %s
5. %s''' % (choices[0], choices[1], choices[2], choices[3], choices[4])
4. %s''' % (choices[0], choices[1], choices[2], choices[3])
class OnionrMail:
def __init__(self, pluginapi):
self.myCore = pluginapi.get_core()
#self.dataFolder = pluginapi.get_data_folder()
self.strings = MailStrings(self)
self.sentboxTools = sentboxdb.SentBox(self.myCore)
self.sentboxList = []
self.sentMessages = {}
return
def inbox(self):
@ -68,6 +73,7 @@ class OnionrMail:
pmBlocks = {}
logger.info('Decrypting messages...')
choice = ''
displayList = []
# this could use a lot of memory if someone has recieved a lot of messages
for blockHash in self.myCore.getBlocksByType('pm'):
@ -93,8 +99,10 @@ class OnionrMail:
senderDisplay = senderKey
blockDate = pmBlocks[blockHash].getDate().strftime("%m/%d %H:%M")
print('%s. %s - %s: %s' % (blockCount, blockDate, senderDisplay[:12], blockHash))
displayList.append('%s. %s - %s: %s' % (blockCount, blockDate, senderDisplay[:12], blockHash))
#displayList.reverse()
for i in displayList:
print(i)
try:
choice = logger.readline('Enter a block number, -r to refresh, or -q to stop: ').strip().lower()
except (EOFError, KeyboardInterrupt):
@ -121,15 +129,52 @@ class OnionrMail:
else:
cancel = ''
readBlock.verifySig()
print('Message recieved from %s' % (readBlock.signer,))
print('Message recieved from %s' % (self.myCore._utils.bytesToStr(readBlock.signer,)))
print('Valid signature:', readBlock.validSig)
if not readBlock.validSig:
logger.warn('This message has an INVALID signature. ANYONE could have sent this message.')
cancel = logger.readline('Press enter to continue to message, or -q to not open the message (recommended).')
if cancel != '-q':
print(draw_border(self.myCore._utils.escapeAnsi(readBlock.bcontent.decode().strip())))
input("Press enter to continue")
return
def sentbox(self):
'''
Display sent mail messages
'''
entering = True
while entering:
self.getSentList()
print('Enter block number or -q to return')
try:
choice = input('>')
except (EOFError, KeyboardInterrupt) as e:
entering = False
else:
if choice == '-q':
entering = False
else:
try:
self.sentboxList[int(choice) - 1]
except IndexError:
print('Invalid block')
else:
logger.info('Sent to: ' + self.sentMessages[self.sentboxList[int(choice) - 1]][1])
# Print ansi escaped sent message
print(self.myCore._utils.escapeAnsi(self.sentMessages[self.sentboxList[int(choice) - 1]][0]))
input('Press enter to continue...')
return
def getSentList(self):
count = 1
for i in self.sentboxTools.listSent():
self.sentboxList.append(i['hash'])
self.sentMessages[i['hash']] = (i['message'], i['peer'])
print('%s. %s - %s - %s' % (count, i['hash'], i['peer'][:12], i['date']))
count += 1
def draftMessage(self):
message = ''
newLine = ''
@ -166,8 +211,8 @@ class OnionrMail:
print('Inserting encrypted message as Onionr block....')
self.myCore.insertBlock(message, header='pm', encryptType='asym', asymPeer=recip, sign=True)
blockID = self.myCore.insertBlock(message, header='pm', encryptType='asym', asymPeer=recip, sign=True)
self.sentboxTools.addToSent(blockID, recip, message)
def menu(self):
choice = ''
while True:
@ -182,12 +227,10 @@ class OnionrMail:
if choice in (self.strings.mainMenuChoices[0], '1'):
self.inbox()
elif choice in (self.strings.mainMenuChoices[1], '2'):
logger.warn('not implemented yet')
self.sentbox()
elif choice in (self.strings.mainMenuChoices[2], '3'):
self.draftMessage()
elif choice in (self.strings.mainMenuChoices[3], '4'):
logger.warn('not implemented yet')
elif choice in (self.strings.mainMenuChoices[4], '5'):
logger.info('Goodbye.')
break
elif choice == '':

View file

@ -0,0 +1,62 @@
'''
Onionr - P2P Microblogging Platform & Social network
This file handles the sentbox for the mail plugin
'''
'''
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, os
import core
class SentBox:
def __init__(self, mycore):
assert isinstance(mycore, core.Core)
self.dbLocation = mycore.dataDir + 'sentbox.db'
if not os.path.exists(self.dbLocation):
self.createDB()
self.conn = sqlite3.connect(self.dbLocation)
self.cursor = self.conn.cursor()
self.core = mycore
return
def createDB(self):
conn = sqlite3.connect(self.dbLocation)
cursor = conn.cursor()
cursor.execute('''CREATE TABLE sent(
hash id not null,
peer text not null,
message text not null,
date int not null
);
''')
conn.commit()
return
def listSent(self):
retData = []
for entry in self.cursor.execute('SELECT * FROM sent;'):
retData.append({'hash': entry[0], 'peer': entry[1], 'message': entry[2], 'date': entry[3]})
return retData
def addToSent(self, blockID, peer, message):
args = (blockID, peer, message, self.core._utils.getEpoch())
self.cursor.execute('INSERT INTO sent VALUES(?, ?, ?, ?)', args)
self.conn.commit()
return
def removeSent(self, blockID):
args = (blockID,)
self.cursor.execute('DELETE FROM sent where hash=?', args)
self.conn.commit()
return

View file

@ -2,6 +2,8 @@
"general" : {
"dev_mode" : true,
"display_header" : true,
"minimum_block_pow": 5,
"minimum_send_pow": 5,
"direct_connect" : {
"respond" : true,
@ -32,11 +34,10 @@
"client" : {
},
"log" : {
"file" : {
"output" : true,
"path" : "data/output.log"
"log": {
"file": {
"output": false,
"path": "data/output.log"
},
"console" : {

View file

@ -2,6 +2,6 @@
<p>The content on this server is not necessarily created by the server owner, and was not necessarily stored specifically with the owner's knowledge of its contents.</p>
<p>Onionr is a decentralized, distributed data storage system, that anyone can insert data into.</p>
<p>Onionr is a decentralized data storage system that anyone can insert data into.</p>
<p>To learn more about Onionr, see the website at <a href="https://onionr.voidnet.tech/">https://Onionr.VoidNet.tech/</a></p>