Files
sshyp/bin/sshyp
T
2021-11-11 22:33:14 -05:00

573 lines
28 KiB
Python
Executable File

#!/usr/bin/python3
# TODO guarantee numbers in generated passwords
# TODO fix syncing for multi-word entries
# TODO fix folders not being created on server
# TODO combine all print-only functions into one and print based on argument passed to function
# TODO make new, colored list its own callable function
# TODO test /dev/shm security
# external modules
from os import environ, remove, system
from shutil import copy, move, rmtree
from sys import argv
import random
import sshync
import string
# utility functions
def argument_filter(): # filters arguments to usable text TODO move to global process
_argument_list = argv
i, _argument = 0, ''
for _ in _argument_list:
while i < len(_argument_list) - 1:
i += 1
_argument += _argument_list[i] + ' '
return _argument[:-1]
def clear():
print('\n' * 100)
def replace_line(file_name, line_num, text): # replaces text in a given line with different text
_lines = open(file_name, 'r').readlines()
_lines[line_num] = text
open(file_name, 'w').writelines(_lines)
def shm_gen(): # generates random folder in /dev/shm for security and returns random names for the folder and temp file
_shm_folder_gen = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits)
for _ in range(random.randint(10, 30)))
_shm_entry_gen = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits)
for _ in range(random.randint(10, 30)))
system('mkdir -p /dev/shm/' + _shm_folder_gen) # TODO generate with Python
return _shm_folder_gen, _shm_entry_gen
def encrypt(_shm_folder, _shm_entry, _entry_name):
system('gpg -r ' + str(gpg_id) + ' -e ' + "'" + '/dev/shm/' + _shm_folder + '/' + _shm_entry + "'")
move('/dev/shm/' + _shm_folder + '/' + _shm_entry + '.gpg', directory + _entry_name.replace('/', '', 1) + '.gpg')
rmtree('/dev/shm/' + _shm_folder)
def encrypt_folder(_shm_folder, _shm_entry, _folder, _folder_entry_name):
system('gpg -r ' + str(gpg_id) + ' -e ' + "'" + '/dev/shm/' + _shm_folder + '/' + _shm_entry + "'")
move('/dev/shm/' + _shm_folder + '/' + _shm_entry + '.gpg', directory + _folder + '/' + _folder_entry_name + '.gpg')
rmtree('/dev/shm/' + _shm_folder)
def edit_note(_shm_folder, _shm_entry):
lines = open('/dev/shm/' + _shm_folder + '/' + _shm_entry).readlines()
open('/dev/shm/' + _shm_folder + '/' + _shm_entry, 'w').writelines(lines[0:3])
open('/dev/shm/' + _shm_folder + '/' + _shm_entry + '-n', 'w').writelines(lines[4:-2])
system('nano /dev/shm/' + _shm_folder + '/' + _shm_entry + '-n')
edit_notes = open('/dev/shm/' + _shm_folder + '/' + _shm_entry + '-n').read()
open('/dev/shm/' + _shm_folder + '/' + _shm_entry, 'a').write('\n' + edit_notes + '\n\n')
# argument-specific functions
def tweak(): # runs configuration wizard
clear()
# storage directory creation
system('mkdir -p /home/' + environ.get('USER') + '/.password-pasture')
# device type configuration
_device_type = input('\nIs this installation for a client or for a server? (C/s) ')
if _device_type == 'S' or _device_type == 's':
open("/var/lib/sshyp/sshyp-device", 'w').write(_device_type)
copy('/usr/bin/sshync.py', '/home/' + environ.get('USER') + '/')
print('\nMake sure the ssh service is running and properly configured.\n\nConfiguration complete!')
else:
# device type configuration
_device_type = 'c' # ensure device type flag is properly set
open("/var/lib/sshyp/sshyp-device", 'w').write(_device_type)
# gpg configuration
_gpg_id = input('\nsshyp requires the use of a unique gpg key. Do you already have one that you are '
'willing to use? (y/N)')
if _gpg_id != 'y' and _gpg_id != 'Y':
print('\nA unique gpg key has been generated for you.')
system('gpg --full-generate-key')
_gpg_id = str(input('\nPlease input the ID of your gpg key: '))
open("/var/lib/sshyp/sshyp-gpg", 'w').write(_gpg_id + '\n')
# lock file generation
try:
open('/var/lib/sshyp/lock', 'x').write('')
except FileExistsError:
pass
system('gpg -r ' + str(_gpg_id) + ' -e ' + '/var/lib/sshyp/lock')
remove('/var/lib/sshyp/lock')
# ssh key configuration
print('\nMake sure the ssh service on the remote server is running and properly configured.\n')
_ssh_gen = (input('\nMake sure the ssh service on the remote server is running and properly configured.\nrsync '
'support requires a unique ssh key. Would you like to have this automatically generated? '
'(Y/n) '))
if _ssh_gen != 'n' and _ssh_gen != 'N':
system('ssh-keygen -t ed25519 -f ~/.ssh/sshyp')
else:
print('\nEnsure that the key file you are using is located at /home/' + environ.get('USER') + '/.ssh/sshyp')
# ssh ip+port configuration
print('\nExample input: 10.10.10.10:9999\n')
_ip_port = str(input('What is the IP and ssh port of the remote server? '))
_ip, _sep, _port = _ip_port.partition(':')
# ssh user configuration
_username_ssh = str(input('\nWhat is the username of the remote server? '))
print('\nEntry directory: ' + '/home/' + _username_ssh + '/.password-pasture/')
# sshync profile generation
sshync.make_profile('/var/lib/sshyp/sshyp.sshync', '/home/' + environ.get('USER') + '/.password-pasture/',
'/home/' + _username_ssh + '/.password-pasture/', '/home/' + environ.get('USER') +
'/.ssh/sshyp', _ip, _port, _username_ssh)
print('\nConfiguration complete!')
def helper(): # displays help menu TODO update with text art, thematic arguments
clear()
print('\nsshyp Copyright (C) 2021 Randall Winkhart')
print("This is free software, and you are welcome to redistribute it under certain conditions;\nthis program comes "
"with ABSOLUTELY NO WARRANTY;\ntype `sshyp license' for details.")
print('\nUSAGE: sshyp [/<entry name>] [OPTION] [FLAG]\n')
print('Options: ')
print('help/--help/-h bring up this menu')
print('version/-v display sshyp version info')
print('tweak configure sshyp')
print('add add an entry')
print('gen generate a new password')
print('edit edit an existing entry')
print('copy copy details of an entry to your clipboard')
print('shear/-rm delete an existing entry')
print('sync/-s manually sync the entry directory via sshync\n')
print('Flags:')
print('add:')
print(' password/-p add a password entry')
print(' note/-n add a note entry')
print(' folder/-f add a new folder for entries')
print('edit:')
print(' rename/relocate/-r rename or relocate an entry')
print(' username/-u change the username of an entry')
print(' password/-p change the password of an entry')
print(' note/-n change the note attached to an entry')
print(' url/-l change the url attached to an entry')
print('copy:')
print(' username/-u copy the username of an entry to your clipboard')
print(' password/-p copy the password of an entry to your clipboard')
print(' url/-l copy the URL of an entry to your clipboard')
print(' note/-n copy the note of an entry to your clipboard')
print('gen:')
print(' update/-u generate a password for an existing entry\n')
print("Tip: You can quickly read an entry with 'sshyp /<entry name>'!")
print("When specifying entry names, do not include the file extension! '.gpg' is assumed!\n")
def version(): # displays version information TODO update with text art
print('\n////////////////////////////////////////////////////////')
print('/ /')
print('/ sshyp Copyright (C) 2021 Randall Winkhart /')
print('/ /')
print('/ Version 2021.11.12.fr2 /')
print('/ The Rewritten Update /')
print('/ /')
print('////////////////////////////////////////////////////////\n')
def no_arg(): # displays a list of entries and gives an option to select one for viewing TODO new, colored list
print("\nFor a list of usable commands, run 'sshyp help'.\n")
system('cd ' + directory + '; ls -1 *')
_read_entry = str(input('\nEntry to read: '))
clear()
system('gpg -d ' + directory + "'" + _read_entry.replace('/', '', 1) + "'" + '.gpg')
print()
def show_license(): # displays licensing information
print('\nThis program is free software: you can redistribute it and/or modify it under the terms of the GNU General'
'\nPublic License as published by the Free Software Foundation, either version 3 of the License,\nor '
'(at your option) any later version.\n'
'\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\nwithout even '
'the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\nSee the GNU General Public '
'License for more details.\n\nhttps://opensource.org/licenses/GPL-3.0\n')
def read_shortcut(): # shortcut to quickly read an entry TODO may not work w/nested
if argument.replace('/', '', 1).__contains__('/'):
_folder, _sep, _folder_entry = argument.replace('/', '', 1).partition('/')
system('gpg -d ' + directory + _folder + '/' + "'" + _folder_entry + '.gpg' + "'")
else:
system('gpg -d ' + directory + "'" + argument.replace('/', '', 1) + '.gpg' + "'")
def sync(): # calls sshync to sync changes to the user's server
print('\nSyncing entries with the server device...\n')
# set permissions before uploading
system('find ' + directory + ' -type d -exec chmod -R 700 {} +')
system('find ' + directory + ' -type f -exec chmod -R 600 {} +')
sshync.run_profile('/var/lib/sshyp/sshyp.sshync')
def add_info(): # displays 'add' syntax
print('\nUSAGE: sshyp add [FLAG]')
print('Flags:')
print('add:')
print(' password/-p add a password entry')
print(' note/-n add a note entry')
print(' folder/-f add a new folder for entries\n')
def add_entry(): # adds a new entry
_entry_name = str(input('\nName of entry: '))
_shm_folder, _shm_entry = shm_gen()
if argument == 'add note' or argument == 'add -n':
system('nano /dev/shm/' + _shm_folder + '/' + _shm_entry + '-n')
_notes = open('/dev/shm/' + _shm_folder + '/' + _shm_entry + '-n', 'r').read()
open('/dev/shm/' + _shm_folder + '/' + _shm_entry, 'w').writelines('\n\n\n\n' + _notes + '\n\n')
if argument == 'add password' or argument == 'add -p':
_username = str(input('Username: '))
_password = str(input('Password: '))
_url = str(input('URL: '))
_add_note = input('Add a note to this entry? (y/N) ')
if _add_note == 'y' or _add_note == 'Y':
system('nano /dev/shm/' + _shm_folder + '/' + _shm_entry + '-n')
_notes = open('/dev/shm/' + _shm_folder + '/' + _shm_entry + '-n', 'r').read()
else:
_notes = ''
open('/dev/shm/' + _shm_folder + '/' + _shm_entry, 'w').writelines(_username + '\n' + _password + '\n' + _url +
'\n\n' + _notes + '\n\n')
if _entry_name.startswith('/'):
if _entry_name.replace('/', '', 1).__contains__('/'):
_folder, _sep, _folder_entry = _entry_name.replace('/', '', 1).partition('/') # TODO may not work w/nested
encrypt_folder(_shm_folder, _shm_entry, _folder, _folder_entry)
system('gpg -d ' + directory + _folder + '/' + "'" + _folder_entry + '.gpg' + "'")
else:
encrypt(_shm_folder, _shm_entry, _entry_name)
system('gpg -d ' + directory + "'" + _entry_name.replace('/', '', 1) + '.gpg' + "'")
else:
encrypt(_shm_folder, _shm_entry, _entry_name)
system('gpg -d ' + directory + "'" + _entry_name + '.gpg' + "'")
def add_folder(): # creates a new folder TODO create folder on server, as well
_folder_name = str(input('Name of new folder: '))
system('mkdir ' + "'" + directory + _folder_name + "'") # TODO create using Python
def edit_info(): # displays 'edit' syntax
print('\nUSAGE: sshyp edit [FLAG]')
print('Flags:')
print('edit:')
print(' rename/relocate/-r rename or relocate an entry')
print(' username/-u change the username of an entry')
print(' password/-p change the password of an entry')
print(' url/-l change the url attached to an entry')
print(' note/-n change the note attached to an entry\n')
def rename(): # renames an entry or folder TODO delete original from server to prevent re-downloading
print()
system('cd ' + directory + '; ls -1 *') # TODO replace with new list
_entry_name = str(input('\nWhat would you like to rename/relocate? '))
_new_name = str(input('New Name: '))
if _entry_name.startswith('/'):
if _entry_name.replace('/', '', 1).__contains__('/'):
_folder, _sep, _folder_entry = _entry_name.replace('/', '', 1).partition('/')
move(directory + _folder + '/' + _folder_entry + '.gpg', directory + '/' + _new_name + '.gpg')
else:
move(directory + _entry_name.replace('/', '', 1) + '.gpg',
directory + _new_name.replace('/', '', 1) + '.gpg')
else:
move(directory + _entry_name + '.gpg', directory + _new_name + '.gpg')
def edit(): # edits the contents of an entry
print()
system('cd ' + directory + '; ls -1 *')
_entry_name = str(input('\nWhat file would you like to edit? '))
_shm_folder, _shm_entry = shm_gen()
if _entry_name.startswith('/'):
if _entry_name.replace('/', '', 1).__contains__('/'):
_folder, _sep, _folder_entry = _entry_name.replace('/', '', 1).partition('/')
system('gpg -d --output /dev/shm/' + _shm_folder + '/' + _shm_entry + ' ' + directory +
_folder + '/' + _folder_entry + '.gpg')
else:
system('gpg -d --output /dev/shm/' + _shm_folder + '/' + _shm_entry + ' ' + directory +
_entry_name.replace('/', '', 1) + '.gpg')
else:
system('gpg -d --output /dev/shm/' + _shm_folder + '/' + _shm_entry + ' ' + directory + _entry_name + '.gpg')
if argument == 'edit username' or argument == 'edit -u':
_detail = str(input('New Username: '))
replace_line('/dev/shm/' + _shm_folder + '/' + _shm_entry, 0, _detail + '\n')
if argument == 'edit password' or argument == 'edit -p':
_detail = str(input('New Password: '))
replace_line('/dev/shm/' + _shm_folder + '/' + _shm_entry, 1, _detail + '\n')
if argument == 'edit url' or argument == 'edit -l':
_detail = str(input('New URL: '))
replace_line('/dev/shm/' + _shm_folder + '/' + _shm_entry, 2, _detail + '\n')
if argument == 'edit note' or argument == 'edit -n':
edit_note(_shm_folder, _shm_entry)
if _entry_name.startswith('/'):
if _entry_name.replace('/', '', 1).__contains__('/'):
_folder, _sep, _folder_entry = _entry_name.replace('/', '', 1).partition('/')
remove(directory + _folder + '/' + _folder_entry + '.gpg')
encrypt_folder(_shm_folder, _shm_entry, _folder, _folder_entry)
system('gpg -d ' + directory + _folder + '/' + "'" + _folder_entry + '.gpg' + "'")
else:
remove(directory + _entry_name.replace('/', '', 1) + '.gpg')
encrypt(_shm_folder, _shm_entry, _entry_name)
system('gpg -d ' + directory + "'" + _entry_name.replace('/', '', 1) + '.gpg' + "'")
else:
remove(directory + _entry_name + '.gpg')
encrypt(_shm_folder, _shm_entry, _entry_name)
system('gpg -d ' + directory + "'" + _entry_name + '.gpg' + "'")
def gen(): # generates a password for a new or an existing entry
_username, _url, _notes = None, None, None # sets base-line values to avoid errors
_shm_folder, _shm_entry = shm_gen()
if argument == 'gen update' or argument == 'gen -u':
print()
system('cd ' + directory + '; ls -1 *')
_entry_name = str(input('\nName of service: '))
if argument != 'gen update' and argument != 'gen -u':
_username = str(input('Username: '))
_pass_length = int(input('How many characters should be in the password? '))
_pass_type = str(input('Should the password be simple (for compatibility) or complex (for security)? (s/C) '))
if _pass_type != 's':
_pass_type = string.ascii_letters + string.digits + string.punctuation
if _pass_type == 's':
_pass_type = string.ascii_letters + string.digits
_pass_gen = ''.join(random.SystemRandom().choice(_pass_type) for _ in range(_pass_length))
if argument != 'gen update' and argument != 'gen -u':
_url = str(input('URL: '))
_notes = str(input('Additional notes: ')) # TODO update w/new notes system
if argument != 'gen update' and argument != 'gen -u':
open('/dev/shm/' + _shm_folder + '/' + _shm_entry, 'w').writelines(
_username + '\n' + _pass_gen + '\n' + _url + '\n\n' + _notes + '\n\n')
if argument != 'gen update' and argument != 'gen -u':
if _entry_name.startswith('/'):
if _entry_name.replace('/', '', 1).__contains__('/'):
_folder, _sep, _folder_entry = _entry_name.replace('/', '', 1).partition(
'/') # TODO may not work w/nested
encrypt_folder(_shm_folder, _shm_entry, _folder, _folder_entry)
system('gpg -d ' + directory + _folder + '/' + "'" + _folder_entry + '.gpg' + "'")
else:
encrypt(_shm_folder, _shm_entry, _entry_name)
system('gpg -d ' + directory + "'" + _entry_name.replace('/', '', 1) + '.gpg' + "'")
else:
encrypt(_shm_folder, _shm_entry, _entry_name)
system('gpg -d ' + directory + "'" + _entry_name + '.gpg' + "'")
else:
if _entry_name.startswith('/'):
if _entry_name.replace('/', '', 1).__contains__('/'):
_folder, _sep, _folder_entry = _entry_name.replace('/', '', 1).partition(
'/') # TODO may not work w/nested
system('gpg -d --output /dev/shm/' + _shm_folder + '/' + _shm_entry + ' ' + directory +
_folder + '/' + _folder_entry + '.gpg')
replace_line('/dev/shm/' + _shm_folder + '/' + _shm_entry, 1, _pass_gen + '\n')
remove(directory + _folder + '/' + _folder_entry.replace('/', '', 1) + '.gpg')
encrypt_folder(_shm_folder, _shm_entry, _folder, _folder_entry)
system('gpg -d ' + directory + _folder + '/' + "'" + _folder_entry + '.gpg' + "'")
else:
system('gpg -d --output /dev/shm/' + _shm_folder + '/' + _shm_entry + ' ' + directory +
_entry_name.replace('/', '', 1) + '.gpg')
replace_line('/dev/shm/' + _shm_folder + '/' + _shm_entry, 1, _pass_gen + '\n')
remove(directory + _entry_name.replace('/', '', 1) + '.gpg')
encrypt(_shm_folder, _shm_entry, _entry_name)
system('gpg -d ' + directory + "'" + _entry_name.replace('/', '', 1) + '.gpg' + "'")
else:
system(
'gpg -d --output /dev/shm/' + _shm_folder + '/' + _shm_entry + ' ' + directory + _entry_name + '.gpg')
replace_line('/dev/shm/' + _shm_folder + '/' + _shm_entry, 1, _pass_gen + '\n')
remove(directory + _entry_name + '.gpg')
encrypt(_shm_folder, _shm_entry, _entry_name)
system('gpg -d ' + directory + "'" + _entry_name + '.gpg' + "'")
def copy_info(): # displays 'copy' syntax
print('\nUSAGE: sshyp copy [FLAG]')
print('Flags:')
print('copy:')
print(' username/-u copy the username of an entry to your clipboard')
print(' password/-p copy the password of an entry to your clipboard')
print(' url/-l copy the URL of an entry to your clipboard')
print(' note/-n copy the note of an entry to your clipboard\n')
def copy_data(): # copies a specified field of an entry to the clipboard
print()
system('cd ' + directory + '; ls -1 *')
_read_entry = str(input('\nEntry to copy: '))
_shm_folder, _shm_entry = shm_gen()
system('gpg -d --output /dev/shm/' + _shm_folder + '/' + _shm_entry + ' ' + directory + _read_entry + '.gpg')
_copy_line = open('/dev/shm/' + _shm_folder + '/' + _shm_entry, 'r').readlines()
if environ.get('WAYLAND_DISPLAY') == 'wayland-0':
if argument == 'copy username' or argument == 'copy -u':
system('wl-copy ' + "'" + _copy_line[0].replace('\n', '').replace("'", "'\\''") + "'")
elif argument == 'copy password' or argument == 'copy -p':
system('wl-copy ' + "'" + _copy_line[1].replace('\n', '').replace("'", "'\\''") + "'")
elif argument == 'copy url' or argument == 'copy -l':
system('wl-copy ' + "'" + _copy_line[2].replace('\n', '').replace("'", "'\\''") + "'")
elif argument == 'copy note' or argument == 'copy -n':
system('wl-copy ' + "'" + _copy_line[4].replace('\n', '').replace("'", "'\\''") + "'")
else:
if argument == 'copy username' or argument == 'copy -u':
system('echo -n ' + "'" + _copy_line[0].replace('\n', '').replace("'", "'\\''") + "'" + ' | xclip -sel c')
elif argument == 'copy password' or argument == 'copy -p':
system('echo -n ' + "'" + _copy_line[1].replace('\n', '').replace("'", "'\\''") + "'" + ' | xclip -sel c')
elif argument == 'copy url' or argument == 'copy -l':
system('echo -n ' + "'" + _copy_line[2].replace('\n', '').replace("'", "'\\''") + "'" + ' | xclip -sel c')
elif argument == 'copy note' or argument == 'copy -n':
system('echo -n ' + "'" + _copy_line[4].replace('\n', '').replace("'", "'\\''") + "'" + ' | xclip -sel c')
rmtree('/dev/shm/' + _shm_folder)
def remove_data(): # deletes an entry or folder from both the client and the server
print()
system('cd ' + directory + '; ls -1 *')
_entry_name = str(input('\nWhat would you like to delete? '))
try:
system('gpg -d --output /dev/shm/sshyp.lock /var/lib/sshyp/lock.gpg')
_unlock = open('/dev/shm/sshyp.lock', 'r').readlines()
remove('/dev/shm/sshyp.lock')
except FileNotFoundError:
print('\nAccess denied.\n')
exit()
if _entry_name.startswith('/'):
if _entry_name.replace('/', '', 1).__contains__('/'):
if device_type == 'c':
system('ssh -p ' + port + ' ' + username_ssh + '@' + ip + ' "' + ' rm -rf ' + "'" + directory_ssh +
_entry_name.replace('/', '', 1) + '.gpg' + "'" + '"')
remove(directory + _entry_name.replace('/', '', 1) + '.gpg')
else:
if device_type == 'c':
system('ssh -p ' + port + ' ' + username_ssh + '@' + ip + ' "' + ' rm -rf ' + "'" + directory_ssh +
_entry_name.replace('/', '', 1) + "'" + '"')
rmtree(directory + _entry_name.replace('/', '', 1))
else:
if device_type == 'c':
system('ssh -p ' + port + ' ' + username_ssh + '@' + ip + ' "' + ' rm -rf ' + "'" + directory_ssh +
_entry_name + '.gpg' + "'" + '"')
remove(directory + _entry_name + '.gpg')
# program start sequence
# import saved userdata
device_type = ''
try:
device_type = open('/var/lib/sshyp/sshyp-device').read().strip()
if device_type == 'c':
gpg_id = open('/var/lib/sshyp/sshyp-gpg').read().strip()
ssh_info = sshync.get_profile('/var/lib/sshyp/sshyp.sshync')
username_ssh = ssh_info[0].replace('\n', '')
ip = ssh_info[1].replace('\n', '')
port = ssh_info[2].replace('\n', '')
directory = str(ssh_info[3].replace('\n', ''))
directory_ssh = '/home/' + username_ssh + '/.password-pasture/'
except FileNotFoundError:
if device_type != 's' and device_type != 'S':
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print("Not all necessary configuration files are present. Please run 'sshyp tweak'!")
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
exit()
# retrieve typed argument
argument = argument_filter()
# run function based on argument
error = 0 # create an error flag to determine if syncing should occur at end
if argument.startswith('/'):
read_shortcut()
elif argument == '':
try:
no_arg()
except KeyboardInterrupt:
print('\n')
exit()
elif argument == 'tweak':
try:
tweak()
except KeyboardInterrupt:
print('\n')
exit()
elif argument == 'help' or argument == '--help' or argument == '-h':
helper()
elif argument == 'license':
show_license()
elif argument == 'version' or argument == '-v':
version()
elif argument == 'add':
add_info()
elif argument == 'add note' or argument == 'add -n' or argument == 'add password' or argument == 'add -p':
try:
add_entry()
except KeyboardInterrupt:
print('\n')
exit()
elif argument == 'add folder' or argument == 'add -f':
try:
add_folder()
except KeyboardInterrupt:
print('\n')
exit()
elif argument == 'edit':
edit_info()
elif argument == 'edit rename' or argument == 'edit relocate' or argument == 'edit -r':
try:
rename()
except KeyboardInterrupt:
print('\n')
exit()
elif argument == 'edit username' or argument == 'edit -u' or argument == 'edit password' or argument == 'edit -p' or \
argument == 'edit url' or argument == 'edit -l' or argument == 'edit note' or argument == 'edit -n':
try:
edit()
except KeyboardInterrupt:
print('\n')
exit()
elif argument == 'gen' or argument == 'gen update' or argument == 'gen -u':
try:
gen()
except KeyboardInterrupt:
print('\n')
exit()
elif argument == 'copy':
copy_info()
elif argument == 'copy username' or argument == 'copy -u' or argument == 'copy password' or argument == 'copy -p' or \
argument == 'copy url' or argument == 'copy -l' or argument == 'copy note' or argument == 'copy -n':
try:
copy_data()
except KeyboardInterrupt:
print('\n')
exit()
elif argument == 'remove' or argument == '-rm':
try:
remove_data()
except KeyboardInterrupt:
print('\n')
exit()
elif argument == 'sync' or argument == '-s':
sync()
else:
error = 1 # set error flag to 1 to stop syncing
print("\nArgument error! Please run 'sshyp help' for a list of usable commands.\n")
exit()
# sync at end of program if any changes were made
if argument != '' and argument != 'help' and argument != '--help' and argument != '-h' and argument != 'license' and \
argument != 'add' and argument != 'sync' and argument != 'edit' and argument != 'copy username' and argument \
!= 'copy -u' and argument != 'copy password' and argument != 'copy -p' and argument != 'copy url' and argument \
!= 'copy -l' and argument != 'copy note' and argument != 'copy -n' and argument != 'copy' and error == 0 and \
argument.startswith('/') is False:
sync()