work on adding/removing friends, user info
parent
a33d45f430
commit
7a0cfe34f3
|
@ -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)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -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
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue