2019-03-08 01:08:06 +00:00
|
|
|
'''
|
2019-06-12 20:12:56 +00:00
|
|
|
Onionr - Private P2P Communication
|
2019-03-08 01:08:06 +00:00
|
|
|
|
2019-06-12 20:12:56 +00:00
|
|
|
This module defines user ID-related CLI commands
|
2019-03-08 01:08:06 +00:00
|
|
|
'''
|
|
|
|
'''
|
|
|
|
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/>.
|
|
|
|
'''
|
|
|
|
|
2019-03-15 00:18:35 +00:00
|
|
|
import sys, getpass
|
2019-03-29 17:37:51 +00:00
|
|
|
import logger, onionrexceptions
|
2019-06-18 16:55:14 +00:00
|
|
|
from onionrusers import onionrusers, contactmanager
|
2019-06-19 06:57:13 +00:00
|
|
|
import unpaddedbase32
|
2019-03-08 01:08:06 +00:00
|
|
|
def add_ID(o_inst):
|
|
|
|
try:
|
|
|
|
sys.argv[2]
|
|
|
|
assert sys.argv[2] == 'true'
|
|
|
|
except (IndexError, AssertionError) as e:
|
|
|
|
newID = o_inst.onionrCore._crypto.keyManager.addKey()[0]
|
|
|
|
else:
|
2019-06-20 00:59:05 +00:00
|
|
|
logger.warn('Deterministic keys require random and long passphrases.', terminal=True)
|
|
|
|
logger.warn('If a good passphrase is not used, your key can be easily stolen.', terminal=True)
|
|
|
|
logger.warn('You should use a series of hard to guess words, see this for reference: https://www.xkcd.com/936/', terminal=True)
|
2019-03-08 01:08:06 +00:00
|
|
|
pass1 = getpass.getpass(prompt='Enter at least %s characters: ' % (o_inst.onionrCore._crypto.deterministicRequirement,))
|
|
|
|
pass2 = getpass.getpass(prompt='Confirm entry: ')
|
|
|
|
if o_inst.onionrCore._crypto.safeCompare(pass1, pass2):
|
|
|
|
try:
|
2019-06-20 00:59:05 +00:00
|
|
|
logger.info('Generating deterministic key. This can take a while.', terminal=True)
|
2019-03-08 01:08:06 +00:00
|
|
|
newID, privKey = o_inst.onionrCore._crypto.generateDeterministic(pass1)
|
|
|
|
except onionrexceptions.PasswordStrengthError:
|
2019-06-20 00:59:05 +00:00
|
|
|
logger.error('Passphrase must use at least %s characters.' % (o_inst.onionrCore._crypto.deterministicRequirement,), terminal=True)
|
2019-03-08 01:08:06 +00:00
|
|
|
sys.exit(1)
|
|
|
|
else:
|
2019-06-20 00:59:05 +00:00
|
|
|
logger.error('Passwords do not match.', terminal=True)
|
2019-03-08 01:08:06 +00:00
|
|
|
sys.exit(1)
|
|
|
|
o_inst.onionrCore._crypto.keyManager.addKey(pubKey=newID,
|
|
|
|
privKey=privKey)
|
2019-06-20 00:59:05 +00:00
|
|
|
logger.info('Added ID: %s' % (o_inst.onionrUtils.bytesToStr(newID),), terminal=True)
|
2019-03-08 01:08:06 +00:00
|
|
|
|
|
|
|
def change_ID(o_inst):
|
|
|
|
try:
|
|
|
|
key = sys.argv[2]
|
2019-06-19 06:57:13 +00:00
|
|
|
key = unpaddedbase32.repad(key.encode()).decode()
|
2019-03-08 01:08:06 +00:00
|
|
|
except IndexError:
|
2019-06-20 00:59:05 +00:00
|
|
|
logger.warn('Specify pubkey to use', terminal=True)
|
2019-03-08 01:08:06 +00:00
|
|
|
else:
|
|
|
|
if o_inst.onionrUtils.validatePubKey(key):
|
|
|
|
if key in o_inst.onionrCore._crypto.keyManager.getPubkeyList():
|
|
|
|
o_inst.onionrCore.config.set('general.public_key', key)
|
|
|
|
o_inst.onionrCore.config.save()
|
2019-06-20 00:59:05 +00:00
|
|
|
logger.info('Set active key to: %s' % (key,), terminal=True)
|
|
|
|
logger.info('Restart Onionr if it is running.', terminal=True)
|
2019-03-08 01:08:06 +00:00
|
|
|
else:
|
2019-06-20 00:59:05 +00:00
|
|
|
logger.warn('That key does not exist', terminal=True)
|
2019-03-08 01:08:06 +00:00
|
|
|
else:
|
2019-06-20 00:59:05 +00:00
|
|
|
logger.warn('Invalid key %s' % (key,), terminal=True)
|
2019-03-08 01:08:06 +00:00
|
|
|
|
|
|
|
def friend_command(o_inst):
|
|
|
|
friend = ''
|
|
|
|
try:
|
|
|
|
# Get the friend command
|
|
|
|
action = sys.argv[2]
|
|
|
|
except IndexError:
|
2019-06-20 00:59:05 +00:00
|
|
|
logger.info('Syntax: friend add/remove/list [address]', terminal=True)
|
2019-03-08 01:08:06 +00:00
|
|
|
else:
|
|
|
|
action = action.lower()
|
|
|
|
if action == 'list':
|
|
|
|
# List out peers marked as our friend
|
2019-06-18 16:55:14 +00:00
|
|
|
for friend in contactmanager.ContactManager.list_friends(o_inst.onionrCore):
|
2019-06-20 00:59:05 +00:00
|
|
|
logger.info(friend.publicKey + ' - ' + friend.get_info('name'), terminal=True)
|
2019-03-08 01:08:06 +00:00
|
|
|
elif action in ('add', 'remove'):
|
|
|
|
try:
|
|
|
|
friend = sys.argv[3]
|
|
|
|
if not o_inst.onionrUtils.validatePubKey(friend):
|
|
|
|
raise onionrexceptions.InvalidPubkey('Public key is invalid')
|
|
|
|
if friend not in o_inst.onionrCore.listPeers():
|
|
|
|
raise onionrexceptions.KeyNotKnown
|
|
|
|
friend = onionrusers.OnionrUser(o_inst.onionrCore, friend)
|
|
|
|
except IndexError:
|
2019-06-20 00:59:05 +00:00
|
|
|
logger.warn('Friend ID is required.', terminal=True)
|
2019-06-12 20:12:56 +00:00
|
|
|
action = 'error' # set to 'error' so that the finally block does not process anything
|
2019-03-08 01:08:06 +00:00
|
|
|
except onionrexceptions.KeyNotKnown:
|
|
|
|
o_inst.onionrCore.addPeer(friend)
|
|
|
|
friend = onionrusers.OnionrUser(o_inst.onionrCore, friend)
|
|
|
|
finally:
|
|
|
|
if action == 'add':
|
|
|
|
friend.setTrust(1)
|
2019-06-20 00:59:05 +00:00
|
|
|
logger.info('Added %s as friend.' % (friend.publicKey,), terminal=True)
|
2019-06-12 20:12:56 +00:00
|
|
|
elif action == 'remove':
|
2019-03-08 01:08:06 +00:00
|
|
|
friend.setTrust(0)
|
2019-06-20 00:59:05 +00:00
|
|
|
logger.info('Removed %s as friend.' % (friend.publicKey,), terminal=True)
|
2019-03-08 01:08:06 +00:00
|
|
|
else:
|
2019-06-20 00:59:05 +00:00
|
|
|
logger.info('Syntax: friend add/remove/list [address]', terminal=True)
|