work on adding/removing friends, user info

This commit is contained in:
Kevin Froman 2018-08-26 22:44:32 -05:00
parent a33d45f430
commit 7a0cfe34f3
No known key found for this signature in database
GPG Key ID: 0D414D0FE405B63B
13 changed files with 127 additions and 37 deletions

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
''' '''
Onionr - P2P Microblogging Platform & Social network. Onionr - P2P Anonymous Storage Network
This file contains both the OnionrCommunicate class for communcating with peers This file contains both the OnionrCommunicate class for communcating with peers
and code to operate as a daemon, getting commands from the command queue database (see core.Core.daemonQueue) and code to operate as a daemon, getting commands from the command queue database (see core.Core.daemonQueue)

View File

@ -1,5 +1,5 @@
''' '''
Onionr - P2P Microblogging Platform & Social network Onionr - P2P Anonymous Storage Network
Core Onionr library, useful for external programs. Handles peer & data processing Core Onionr library, useful for external programs. Handles peer & data processing
''' '''
@ -102,7 +102,7 @@ class Core:
conn = sqlite3.connect(self.peerDB) conn = sqlite3.connect(self.peerDB)
hashID = self._crypto.pubKeyHashID(peerID) hashID = self._crypto.pubKeyHashID(peerID)
c = conn.cursor() c = conn.cursor()
t = (peerID, name, 'unknown', hashID, powID) t = (peerID, name, 'unknown', hashID, powID, 0)
for i in c.execute("SELECT * FROM PEERS where id = '" + peerID + "';"): for i in c.execute("SELECT * FROM PEERS where id = '" + peerID + "';"):
try: try:
@ -113,7 +113,7 @@ class Core:
pass pass
except IndexError: except IndexError:
pass pass
c.execute('INSERT INTO peers (id, name, dateSeen, pow, hashID) VALUES(?, ?, ?, ?, ?);', t) c.execute('INSERT INTO peers (id, name, dateSeen, pow, hashID, trust) VALUES(?, ?, ?, ?, ?, ?);', t)
conn.commit() conn.commit()
conn.close() conn.close()
@ -403,19 +403,23 @@ class Core:
conn.close() conn.close()
return addressList return addressList
def listPeers(self, randomOrder=True, getPow=False): def listPeers(self, randomOrder=True, getPow=False, trust=0):
''' '''
Return a list of public keys (misleading function name) Return a list of public keys (misleading function name)
randomOrder determines if the list should be in a random order randomOrder determines if the list should be in a random order
trust sets the minimum trust to list
''' '''
conn = sqlite3.connect(self.peerDB) conn = sqlite3.connect(self.peerDB)
c = conn.cursor() c = conn.cursor()
payload = "" payload = ""
if trust not in (0, 1, 2):
logger.error('Tried to select invalid trust.')
return
if randomOrder: if randomOrder:
payload = 'SELECT * FROM peers ORDER BY RANDOM();' payload = 'SELECT * FROM peers where trust >= %s ORDER BY RANDOM();' % (trust,)
else: else:
payload = 'SELECT * FROM peers;' payload = 'SELECT * FROM peers where trust >= %s;' % (trust,)
peerList = [] peerList = []
for i in c.execute(payload): for i in c.execute(payload):
try: try:

View File

@ -61,7 +61,6 @@ class DBCreator:
ID text not null, ID text not null,
name text, name text,
adders text, adders text,
blockDBHash text,
forwardKey text, forwardKey text,
dateSeen not null, dateSeen not null,
bytesStored int, bytesStored int,

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
''' '''
Onionr - P2P Microblogging Platform & Social network. Onionr - P2P Anonymous Storage Network
Onionr is the name for both the protocol and the original/reference software. Onionr is the name for both the protocol and the original/reference software.
@ -32,7 +32,7 @@ import onionrutils
from onionrutils import OnionrUtils from onionrutils import OnionrUtils
from netcontroller import NetController from netcontroller import NetController
from onionrblockapi import Block from onionrblockapi import Block
import onionrproofs import onionrproofs, onionrexceptions, onionrusers
try: try:
from urllib3.contrib.socks import SOCKSProxyManager from urllib3.contrib.socks import SOCKSProxyManager
@ -210,7 +210,9 @@ class Onionr:
'getpass': self.printWebPassword, 'getpass': self.printWebPassword,
'get-pass': self.printWebPassword, 'get-pass': self.printWebPassword,
'getpasswd': self.printWebPassword, 'getpasswd': self.printWebPassword,
'get-passwd': self.printWebPassword 'get-passwd': self.printWebPassword,
'friend': self.friendCmd
} }
self.cmdhelp = { self.cmdhelp = {
@ -234,6 +236,7 @@ class Onionr:
'pex': 'exchange addresses with peers (done automatically)', 'pex': 'exchange addresses with peers (done automatically)',
'blacklist-block': 'deletes a block by hash and permanently removes it from your node', 'blacklist-block': 'deletes a block by hash and permanently removes it from your node',
'introduce': 'Introduce your node to the public Onionr network', 'introduce': 'Introduce your node to the public Onionr network',
'friend': '[add|remove] [public key/id]'
} }
# initialize plugins # initialize plugins
@ -260,6 +263,41 @@ class Onionr:
def getCommands(self): def getCommands(self):
return self.cmds return self.cmds
def friendCmd(self):
'''List, add, or remove friend(s)'''
friend = ''
try:
action = sys.argv[2]
except IndexError:
logger.info('Syntax: friend add/remove/list [address]')
else:
action = action.lower()
if action == 'list':
for friend in self.onionrCore.listPeers(randomOrder=False, trust=1):
logger.info(friend)
elif action in ('add', 'remove'):
try:
friend = sys.argv[3]
if not self.onionrUtils.validatePubKey(friend):
raise onionrexceptions.InvalidPubkey('Public key is invalid')
if friend not in self.onionrCore.listPeers():
raise onionrexceptions.KeyNotKnown
friend = onionrusers.OnionrUser(self.onionrCore, friend)
except IndexError:
logger.error('Friend ID is required.')
except onionrexceptions.KeyNotKnown:
logger.error('That peer is not in our database')
else:
if action == 'add':
friend.setTrust(1)
logger.info('Added %s as friend.' % (friend.publicKey,))
else:
friend.setTrust(0)
logger.info('Removed %s as friend.' % (friend.publicKey,))
else:
logger.info('Syntax: friend add/remove/list [address]')
def banBlock(self): def banBlock(self):
try: try:

View File

@ -1,5 +1,5 @@
''' '''
Onionr - P2P Microblogging Platform & Social network. Onionr - P2P Anonymous Storage Network
This file handles maintenence of a blacklist database, for blocks and peers This file handles maintenence of a blacklist database, for blocks and peers
''' '''

View File

@ -1,5 +1,5 @@
''' '''
Onionr - P2P Microblogging Platform & Social network. Onionr - P2P Anonymous Storage Network
This class contains the OnionrBlocks class which is a class for working with Onionr blocks This class contains the OnionrBlocks class which is a class for working with Onionr blocks
''' '''

View File

@ -155,26 +155,6 @@ class OnionrCrypto:
decrypted = anonBox.decrypt(data, encoder=encoding) decrypted = anonBox.decrypt(data, encoder=encoding)
return decrypted return decrypted
def symmetricPeerEncrypt(self, data, peer):
'''Salsa20 encrypt data to peer (with mac)
this function does not accept a key, it is a wrapper for encryption with a peer
'''
key = self._core.getPeerInfo(4)
if type(key) != bytes:
key = self._core.getPeerInfo(2)
encrypted = self.symmetricEncrypt(data, key, encodedKey=True)
return encrypted
def symmetricPeerDecrypt(self, data, peer):
'''Salsa20 decrypt data from peer (with mac)
this function does not accept a key, it is a wrapper for encryption with a peer
'''
key = self._core.getPeerInfo(4)
if type(key) != bytes:
key = self._core.getPeerInfo(2)
decrypted = self.symmetricDecrypt(data, key, encodedKey=True)
return decrypted
def symmetricEncrypt(self, data, key, encodedKey=False, returnEncoded=True): def symmetricEncrypt(self, data, key, encodedKey=False, returnEncoded=True):
'''Encrypt data to a 32-byte key (Salsa20-Poly1305 MAC)''' '''Encrypt data to a 32-byte key (Salsa20-Poly1305 MAC)'''
if encodedKey: if encodedKey:

View File

@ -1,5 +1,5 @@
''' '''
Onionr - P2P Microblogging Platform & Social network. Onionr - P2P Anonymous Storage Network
Contains the CommunicatorUtils class which contains useful functions for the communicator daemon Contains the CommunicatorUtils class which contains useful functions for the communicator daemon
''' '''

View File

@ -1,5 +1,5 @@
''' '''
Onionr - P2P Microblogging Platform & Social network. Onionr - P2P Anonymous Storage Network
This file contains exceptions for onionr This file contains exceptions for onionr
''' '''
@ -34,6 +34,9 @@ class OnlinePeerNeeded(Exception):
class InvalidPubkey(Exception): class InvalidPubkey(Exception):
pass pass
class KeyNotKnown(Exception):
pass
# block exceptions # block exceptions
class InvalidMetadata(Exception): class InvalidMetadata(Exception):
pass pass

View File

@ -1,5 +1,5 @@
''' '''
Onionr - P2P Microblogging Platform & Social network. Onionr - P2P Anonymous Storage Network
This file contains both the PeerProfiles class for network profiling of Onionr nodes This file contains both the PeerProfiles class for network profiling of Onionr nodes
''' '''

51
onionr/onionrusers.py Normal file
View File

@ -0,0 +1,51 @@
'''
Onionr - P2P Anonymous Storage Network
Contains abstractions for interacting with users of Onionr
'''
'''
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/>.
'''
class OnionrUser:
def __init__(self, coreInst, publicKey):
self.trust = 0
self._core = coreInst
self.publicKey = publicKey
self.trust = self._core.getPeerInfo(self.publicKey, 'trust')
return
def setTrust(self, newTrust):
'''Set the peers trust. 0 = not trusted, 1 = friend, 2 = ultimate'''
self._core.setPeerInfo(self.publicKey, 'trust', newTrust)
def isFriend(self):
if self._core.getPeerInfo(self.publicKey, 6) == 1:
return True
return False
def encrypt(self, data):
encrypted = coreInst._crypto.pubKeyEncrypt(data, self.publicKey, encodedData=True)
return encrypted
def decrypt(self, data):
decrypted = coreInst._crypto.pubKeyDecrypt(data, self.publicKey, encodedData=True)
return decrypted
def forwardEncrypt(self, data):
return
def forwardDecrypt(self, encrypted):
return

View File

@ -264,9 +264,24 @@ class OnionrUtils:
if myBlock.isEncrypted: if myBlock.isEncrypted:
myBlock.decrypt() myBlock.decrypt()
blockType = myBlock.getMetadata('type') # we would use myBlock.getType() here, but it is bugged with encrypted blocks blockType = myBlock.getMetadata('type') # we would use myBlock.getType() here, but it is bugged with encrypted blocks
signer = myBlock.getSigner()
try: try:
if len(blockType) <= 10: if len(blockType) <= 10:
self._core.updateBlockInfo(blockHash, 'dataType', blockType) self._core.updateBlockInfo(blockHash, 'dataType', blockType)
if blockType == 'userInfo':
if myBlock.verifySig():
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:
self._core.setPeerInfo(signer, 'name', peerName)
except TypeError: except TypeError:
pass pass

View File

@ -1,6 +1,6 @@
<h1>This is an Onionr Node</h1> <h1>This is an Onionr Node</h1>
<p>The content on this server is not necessarily created by the server owner, and was not necessarily stored with the owner's knowledge.</p> <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, distributed data storage system, that anyone can insert data into.</p>