From 801177d38654580a1455f5d8c438275afee0a1d9 Mon Sep 17 00:00:00 2001 From: Cuan Date: Thu, 11 Nov 2021 22:33:14 -0500 Subject: [PATCH] Full re-write of sshyp! --- bin/sshyp | 1134 +++++++++++++++---------------------- extra/changelog-total | 42 ++ share/doc/sshyp/changelog | 25 +- 3 files changed, 498 insertions(+), 703 deletions(-) diff --git a/bin/sshyp b/bin/sshyp index 3ceb445..1d1f610 100755 --- a/bin/sshyp +++ b/bin/sshyp @@ -1,91 +1,154 @@ #!/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 system as term -from os import remove -from os import environ -from shutil import move -from shutil import rmtree -from shutil import copy +from os import environ, remove, system +from shutil import copy, move, rmtree from sys import argv -from re import search -from re import escape import random -import string import sshync +import string -# internal modules +# 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 string_found(string1, string2): - if search(r"\b" + escape(string1) + r"\b", string2): - return True - return False +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 replace_line(file_name, line_num, text): - xlines = open(file_name, 'r').readlines() - xlines[line_num] = text - open(file_name, 'w').writelines(xlines) +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 edit_note(): - lines = open('/dev/shm/' + shmfolder + '/' + shmentry).readlines() - open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines(lines[0:3]) - open('/dev/shm/' + shmfolder + '/' + shmentry + '-n', 'w').writelines(lines[4:-2]) - term('nano /dev/shm/' + shmfolder + '/' + shmentry + '-n') - edit_notes = open('/dev/shm/' + shmfolder + '/' + shmentry + '-n').read() - open('/dev/shm/' + shmfolder + '/' + shmentry, 'a').write('\n' + edit_notes + '\n\n') +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 shmgen(): - shmfoldergen = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits) - for _ in range(random.randint(10, 30))) - shmentrygen = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits) - for _ in range(random.randint(10, 30))) - term('mkdir -p /dev/shm/' + shmfoldergen) - return shmfoldergen, shmentrygen +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 encrypt(): - term('gpg -r ' + str(gpgid) + ' -e ' + "'" + '/dev/shm/' + shmfolder + '/' + shmentry + "'") - move('/dev/shm/' + shmfolder + '/' + shmentry + '.gpg', directory + entryname.replace('/', '', 1) + '.gpg') - rmtree('/dev/shm/' + shmfolder) +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') -def encryptfolder(): - term('gpg -r ' + str(gpgid) + ' -e ' + "'" + '/dev/shm/' + shmfolder + '/' + shmentry + "'") - move('/dev/shm/' + shmfolder + '/' + shmentry + '.gpg', directory + folder + '/' + folderentry + '.gpg') - rmtree('/dev/shm/' + shmfolder) +# argument-specific functions -# argument - filter the argument to usable text +def tweak(): # runs configuration wizard + clear() -argument = str(argv).replace('[', '', 1).replace(']', '', 1).replace(',', '').replace("'", '') \ - .replace(' ', '', 1).replace('/usr/bin/', '', 1).replace('sshyp', '', 1) + # storage directory creation + system('mkdir -p /home/' + environ.get('USER') + '/.password-pasture') -# help + # 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) -if argument == 'help' or argument == '--help' or argument == '-h': + # 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 program comes with ABSOLUTELY NO WARRANTY; for details type `sshyp show w'.\nThis is free software, " - "and you are welcome to redistribute it under certain conditions; type `sshyp show c' for details.") + 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 [/] [OPTION] [FLAG]\n') print('Options: ') print('help/--help/-h bring up this menu') print('version/-v display sshyp version info') - print('config configure sshyp') + 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('remove/-rm delete an existing entry') - print('sync/-s manually sync the entry directory via rsync\n') + 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') @@ -107,148 +170,53 @@ if argument == 'help' or argument == '--help' or argument == '-h': print("Tip: You can quickly read an entry with 'sshyp /'!") print("When specifying entry names, do not include the file extension! '.gpg' is assumed!\n") -# version info -if argument == 'version' or argument == '-v': +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.05.fr1 /') - print('/ The sshync Update /') + print('/ Version 2021.11.12.fr2 /') + print('/ The Rewritten Update /') print('/ /') print('////////////////////////////////////////////////////////\n') -# licensing info -if argument == 'show w': +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() - print('This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;') - print('without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.') - print('See the GNU General Public License for more details.') - print('\nhttps://opensource.org/licenses/GPL-3.0\n') + system('gpg -d ' + directory + "'" + _read_entry.replace('/', '', 1) + "'" + '.gpg') + print() -if argument == 'show c': - clear() - print('This program is free software: you can redistribute it and/or modify it under the terms of the GNU General') - print('Public License as published by the Free Software Foundation, either version 3 of the License,') - print('or (at your option) any later version.\n') -# config +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') -if argument == 'config': - try: - print() - devicetype = str(input('Will this be a client or a server device? (C/s) ')) - if devicetype == 's' or devicetype == 'S': - open("/var/lib/sshyp/sshyp-device", 'w').write(devicetype) - print('\nMake sure the ssh service is running and properly configured.\n') - copy('/usr/bin/sshync.py', '/home/' + environ.get('USER') + '/') - term('mkdir -p /home/' + environ.get('USER') + '/.password-pasture') - print('Configuration complete!\n') - else: - devicetype = 'c' - gpgid = '' - print() - gpgpresent = str(input( - 'sshyp requires the use of a unique gpg key. Do you already have one you are willing to use? (y/N) ')) - if gpgpresent == 'y' or gpgpresent == 'Y': - print() - gpgid = str(input('Please input the ID of your gpg key: ')) - open("/var/lib/sshyp/sshyp-gpg", 'w').write(gpgid + '\n') - else: - print() - gpggen = str( - input('Would you like to generate one now? Note that if you choose not to do this, you will have ' - 'to re-run "sshyp config" to specify a gpg key when you acquire one (Y/n) ')) - if gpggen == 'n' or gpggen == 'N': - exit() - else: - term('gpg --full-generate-key') - print() - gpgid = str(input('Please input the ID of your gpg key: ')) - open("/var/lib/sshyp/sshyp-gpg", 'w').write(gpgid + '\n') - try: - open('/var/lib/sshyp/lock', 'x').write('locked') - except FileExistsError: - pass - term('gpg -r ' + str(gpgid) + ' -e ' + '/var/lib/sshyp/lock') - remove('/var/lib/sshyp/lock') - print('\nMake sure the ssh service on the remote server is running and properly configured.\n') - sshgen = str(input('rsync support requires a unique ssh key. Would you like to have this ' - 'automatically generated? (Y/n) ')) - if sshgen != 'n' and sshgen != 'N': - term('ssh-keygen -t ed25519 -f ~/.ssh/sshyp') - print('\nExample input: 10.10.10.10:9999\n') - ip_port = str(input('What is the IP and ssh port of the remote server? ')) - print() - ip, sep, port = ip_port.partition(':') - usernamessh = str(input('What is the username of the remote server? ')) - print('\nDefault directory: ' + '/home/' + usernamessh + '/.password-pasture/\n') - directoryssh = ('/home/' + usernamessh + '/.password-pasture/') - open("/var/lib/sshyp/sshyp-device", 'w').write(devicetype) - sshync.make_profile('/var/lib/sshyp/sshyp.sshync', '/home/' + environ.get('USER') + '/.password-pasture/', - directoryssh, '/home/' + environ.get('USER') + '/.ssh/sshyp', ip, port, usernamessh) - print('Configuration complete!\n') - except KeyboardInterrupt: - print('\n\nConfiguration cancelled.\n') - exit() -# startup help - -if argument == '': - clear() - print("Use 'help', '--help', or '-h' to see a list of commands.\n") - print('sshyp is currently early software with very little polish\n') - -# import userdata - -devicetype = 'c' -try: - devicetype = open('/var/lib/sshyp/sshyp-device').read().strip() - gpgid = open('/var/lib/sshyp/sshyp-gpg').read().strip() - sshinfo = sshync.get_profile('/var/lib/sshyp/sshyp.sshync') - usernamessh = sshinfo[0].replace('\n', '') - ip = sshinfo[1].replace('\n', '') - port = sshinfo[2].replace('\n', '') - directory = str(sshinfo[3].replace('\n', '')) - directoryssh = sshinfo[4].replace('\n', '') - term('mkdir -p ' + directory) -except FileNotFoundError: - if devicetype != 's' and devicetype != 'S': - print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - print("Not all necessary configuration files are present. Please run 'sshyp config'!") - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n') - devicetype, sshinfo, directory, directoryssh, ip, port, usernamessh = [0, 0, 0, 0, 0, 0, 0] - exit() - -# no argument - -if argument == '': - try: - print() - term('cd ' + directory + '; ls -1 *') - print() - readentry = str(input('Entry to read: ')) - clear() - term('gpg -d ' + directory + "'" + readentry.replace('/', '', 1) + "'" + '.gpg') - print() - except KeyboardInterrupt: - print('\n\nSelection cancelled.\n') - exit() - -# read shortcut - -if argument.startswith('/'): +def read_shortcut(): # shortcut to quickly read an entry TODO may not work w/nested if argument.replace('/', '', 1).__contains__('/'): - folder, sep, folderentry = argument.replace('/', '', 1).partition('/') - term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'") + _folder, _sep, _folder_entry = argument.replace('/', '', 1).partition('/') + system('gpg -d ' + directory + _folder + '/' + "'" + _folder_entry + '.gpg' + "'") else: - term('gpg -d ' + directory + "'" + argument.replace('/', '', 1) + '.gpg' + "'") + system('gpg -d ' + directory + "'" + argument.replace('/', '', 1) + '.gpg' + "'") -# add -if argument == 'add': +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:') @@ -256,89 +224,45 @@ if argument == 'add': print(' note/-n add a note entry') print(' folder/-f add a new folder for entries\n') -if argument == 'add note' or argument == 'add -n': - try: - clear() - entryname = str(input('Name of note: ')) - except KeyboardInterrupt: - entryname, notes = (0, 0) - print('\n\nEntry add cancelled.\n') - exit() - shmfolder, shmentry = shmgen() - term('nano /dev/shm/' + shmfolder + '/' + shmentry + '-n') - notes = open('/dev/shm/' + shmfolder + '/' + shmentry + '-n', 'r').read() - try: - if entryname.startswith('/'): # check if user input contains slashes - if entryname.replace('/', '', 1).__contains__('/'): # create folder and entry if there are two slashes - folder, sep, folderentry = entryname.replace('/', '', 1).partition('/') - open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines('\n\n\n\n' + notes + '\n\n') - encryptfolder() - term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'") - else: # create entry if there is only one slash - open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines('\n\n\n\n' + notes + '\n\n') - encrypt() - term('gpg -d ' + directory + "'" + entryname.replace('/', '', 1) + '.gpg' + "'") - else: # create entry if there are no slashes - open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines('\n\n\n\n' + notes + '\n\n') - encrypt() - term('gpg -d ' + directory + "'" + entryname + '.gpg' + "'") - except FileNotFoundError: - print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - print('The folder you requested to access does not exist!') - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n') - rmtree('/dev/shm/' + shmfolder) - exit() -if argument == 'add password' or argument == 'add -p': - try: - clear() - entryname = str(input('Name of service: ')) - username = str(input('Username: ')) - password = str(input('Password: ')) - url = str(input('URL: ')) - except KeyboardInterrupt: - entryname, username, password, url, notes = (0, 0, 0, 0, 0) - print('\n\nEntry add cancelled.\n') - exit() - shmfolder, shmentry = shmgen() - add_note = input('Add a note to this entry? (y/N) ') - if add_note == 'y' or add_note == 'Y': - term('nano /dev/shm/' + shmfolder + '/' + shmentry + '-n') - notes = open('/dev/shm/' + shmfolder + '/' + shmentry + '-n', 'r').read() - else: - notes = '' - try: - if entryname.startswith('/'): - if entryname.replace('/', '', 1).__contains__('/'): - folder, sep, folderentry = entryname.replace('/', '', 1).partition('/') - open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines(username + '\n' + password + '\n' + url - + '\n\n' + notes + '\n\n') - encryptfolder() - term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'") - else: - open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines(username + '\n' + password + '\n' + url - + '\n\n' + notes + '\n\n') - encrypt() - term('gpg -d ' + directory + "'" + entryname.replace('/', '', 1) + '.gpg' + "'") +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: - open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines(username + '\n' + password + '\n' + url - + '\n\n' + notes + '\n\n') - encrypt() - term('gpg -d ' + directory + "'" + entryname + '.gpg' + "'") - except FileNotFoundError: - print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - print('The folder you requested to access does not exist!') - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n') - rmtree('/dev/shm/' + shmfolder) - exit() + _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' + "'") -if argument == 'add folder' or argument == 'add -f': - newfolder = str(input('Name of new folder: ')) - term('mkdir ' + "'" + directory + newfolder + "'") -# edit +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 -if argument == 'edit': + +def edit_info(): # displays 'edit' syntax print('\nUSAGE: sshyp edit [FLAG]') print('Flags:') print('edit:') @@ -348,201 +272,128 @@ if argument == 'edit': print(' url/-l change the url attached to an entry') print(' note/-n change the note attached to an entry\n') -if argument == 'edit rename' or argument == 'edit relocate' or argument == 'edit -r': - try: - clear() - term('cd ' + directory + '; ls -1 *') - print() - entryname = str(input('What file would you like to edit? ')) - newname = str(input('New Name: ')) - if entryname.startswith('/'): - if entryname.replace('/', '', 1).__contains__('/'): - folder, sep, folderentry = entryname.replace('/', '', 1).partition('/') - move(directory + folder + '/' + folderentry + '.gpg', directory + '/' + newname + '.gpg') - else: - move(directory + entryname.replace('/', '', 1) + '.gpg', - directory + newname.replace('/', '', 1) + '.gpg') + +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 + entryname + '.gpg', directory + newname + '.gpg') - except KeyboardInterrupt: - print('\n\nEdit cancelled.\n') - exit() - except FileNotFoundError: - print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - print('The file you requested to edit does not exist!') - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n') - exit() + move(directory + _entry_name.replace('/', '', 1) + '.gpg', + directory + _new_name.replace('/', '', 1) + '.gpg') + else: + move(directory + _entry_name + '.gpg', directory + _new_name + '.gpg') -if argument == 'edit username' or argument == 'edit -u': - try: - clear() - term('cd ' + directory + '; ls -1 *') - print() - entryname = str(input('What file would you like to edit? ')) - username = str(input('New Username: ')) - except KeyboardInterrupt: - entryname, username = (0, 0) - print('\n\nEdit cancelled.\n') - exit() - shmfolder, shmentry = shmgen() - try: - if entryname.startswith('/'): - if entryname.replace('/', '', 1).__contains__('/'): - folder, sep, folderentry = entryname.replace('/', '', 1).partition('/') - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + - folder + '/' + folderentry + '.gpg') - replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 0, username + '\n') - remove(directory + folder + '/' + folderentry + '.gpg') - encryptfolder() - term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'") - else: - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + - entryname.replace('/', '', 1) + '.gpg') - replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 0, username + '\n') - remove(directory + entryname.replace('/', '', 1) + '.gpg') - encrypt() - term('gpg -d ' + directory + "'" + entryname.replace('/', '', 1) + '.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: - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + entryname + '.gpg') - replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 0, username + '\n') - remove(directory + entryname + '.gpg') - encrypt() - term('gpg -d ' + directory + "'" + entryname + '.gpg' + "'") - except FileNotFoundError: - print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - print('The file you requested to edit does not exist!') - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n') - rmtree('/dev/shm/' + shmfolder) - exit() - -if argument == 'edit password' or argument == 'edit -p': - try: - clear() - term('cd ' + directory + '; ls -1 *') - print() - entryname = str(input('What file would you like to edit? ')) - password = str(input('New Password: ')) - except KeyboardInterrupt: - entryname, password = (0, 0) - print('\n\nEdit cancelled.\n') - exit() - shmfolder, shmentry = shmgen() - try: - if entryname.startswith('/'): - if entryname.replace('/', '', 1).__contains__('/'): - folder, sep, folderentry = entryname.replace('/', '', 1).partition('/') - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + - folder + '/' + folderentry + '.gpg') - replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 1, password + '\n') - remove(directory + folder + '/' + folderentry + '.gpg') - encryptfolder() - term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'") - else: - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + - entryname.replace('/', '', 1) + '.gpg') - replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 1, password + '\n') - remove(directory + entryname.replace('/', '', 1) + '.gpg') - encrypt() - term('gpg -d ' + directory + "'" + entryname.replace('/', '', 1) + '.gpg' + "'") + 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: - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + entryname + '.gpg') - replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 1, password + '\n') - remove(directory + entryname + '.gpg') - encrypt() - term('gpg -d ' + directory + "'" + entryname + '.gpg' + "'") - except FileNotFoundError: - print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - print('The file you requested to edit does not exist!') - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n') - rmtree('/dev/shm/' + shmfolder) - exit() + 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' + "'") -if argument == 'edit url' or argument == 'edit -l': - try: - clear() - term('cd ' + directory + '; ls -1 *') + +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() - entryname = str(input('What file would you like to edit? ')) - url = str(input('New URL: ')) - except KeyboardInterrupt: - entryname, url = (0, 0) - print('\n\nEdit cancelled.\n') - exit() - shmfolder, shmentry = shmgen() - try: - if entryname.startswith('/'): - if entryname.replace('/', '', 1).__contains__('/'): - folder, sep, folderentry = entryname.replace('/', '', 1).partition('/') - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + - folder + '/' + folderentry + '.gpg') - replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 2, url + '\n') - remove(directory + folder + '/' + folderentry + '.gpg') - encryptfolder() - term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'") + 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: - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + - entryname.replace('/', '', 1) + '.gpg') - replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 2, url + '\n') - remove(directory + entryname.replace('/', '', 1) + '.gpg') - encrypt() - term('gpg -d ' + directory + "'" + entryname.replace('/', '', 1) + '.gpg' + "'") + encrypt(_shm_folder, _shm_entry, _entry_name) + system('gpg -d ' + directory + "'" + _entry_name.replace('/', '', 1) + '.gpg' + "'") else: - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + entryname + '.gpg') - replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 2, url + '\n') - remove(directory + entryname + '.gpg') - encrypt() - term('gpg -d ' + directory + "'" + entryname + '.gpg' + "'") - except FileNotFoundError: - print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - print('The file you requested to edit does not exist!') - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n') - rmtree('/dev/shm/' + shmfolder) - exit() - -if argument == 'edit note' or argument == 'edit -n': - try: - clear() - term('cd ' + directory + '; ls -1 *') - print() - entryname = str(input('What file would you like to edit? ')) - except KeyboardInterrupt: - entryname, notes = (0, 0) - print('\n\nEdit cancelled.\n') - exit() - shmfolder, shmentry = shmgen() - try: - if entryname.startswith('/'): - if entryname.replace('/', '', 1).__contains__('/'): - folder, sep, folderentry = entryname.replace('/', '', 1).partition('/') - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + - folder + '/' + folderentry + '.gpg') - edit_note() - remove(directory + folder + '/' + folderentry + '.gpg') - encryptfolder() - term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'") + 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: - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + - entryname.replace('/', '', 1) + '.gpg') - edit_note() - remove(directory + entryname.replace('/', '', 1) + '.gpg') - encrypt() - term('gpg -d ' + directory + "'" + entryname.replace('/', '', 1) + '.gpg' + "'") + 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: - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + entryname + '.gpg') - edit_note() - remove(directory + entryname + '.gpg') - encrypt() - term('gpg -d ' + directory + "'" + entryname + '.gpg' + "'") - except FileNotFoundError: - print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - print('The file you requested to edit does not exist!') - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n') - rmtree('/dev/shm/' + shmfolder) - exit() + 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' + "'") -# copy -if argument == 'copy': +def copy_info(): # displays 'copy' syntax print('\nUSAGE: sshyp copy [FLAG]') print('Flags:') print('copy:') @@ -551,264 +402,171 @@ if argument == 'copy': 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') -if argument == 'copy username' or argument == 'copy -u': - try: - print() - term('cd ' + directory + '; ls -1 *') - print() - readentry = str(input('Entry to copy: ')) - except KeyboardInterrupt: - readentry = 0 - print('\n\nCopy cancelled.\n') - exit() - shmfolder, shmentry = shmgen() - try: - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + readentry + '.gpg') - copyline = open('/dev/shm/' + shmfolder + '/' + shmentry, 'r').readlines() - if environ.get('WAYLAND_DISPLAY') == 'wayland-0': - term('wl-copy ' + "'" + copyline[0].replace('\n', '') + "'") - else: - term('echo -n ' + "'" + copyline[0].replace('\n', '') + "'" + ' | xclip -sel c') - rmtree('/dev/shm/' + shmfolder) - except FileNotFoundError: - print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - print('The file you requested to edit does not exist!') - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n') - rmtree('/dev/shm/' + shmfolder) - exit() -if argument == 'copy password' or argument == 'copy -p': - try: - print() - term('cd ' + directory + '; ls -1 *') - print() - readentry = str(input('Entry to copy: ')) - except KeyboardInterrupt: - readentry = 0 - print('\n\nCopy cancelled.\n') - exit() - shmfolder, shmentry = shmgen() - try: - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + readentry + '.gpg') - copyline = open('/dev/shm/' + shmfolder + '/' + shmentry, 'r').readlines() - if environ.get('WAYLAND_DISPLAY') == 'wayland-0': - term('wl-copy ' + "'" + copyline[1].replace('\n', '').replace("'", "'\\''") + "'") - else: - term('echo -n ' + "'" + copyline[1].replace('\n', '').replace("'", "'\\''") + "'" + ' | xclip -sel c') - rmtree('/dev/shm/' + shmfolder) - except FileNotFoundError: - print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - print('The file you requested to edit does not exist!') - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n') - rmtree('/dev/shm/' + shmfolder) - exit() - -if argument == 'copy url' or argument == 'copy -l': - try: - print() - term('cd ' + directory + '; ls -1 *') - print() - readentry = str(input('Entry to copy: ')) - except KeyboardInterrupt: - readentry = 0 - print('\n\nCopy cancelled.\n') - exit() - shmfolder, shmentry = shmgen() - try: - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + readentry + '.gpg') - copyline = open('/dev/shm/' + shmfolder + '/' + shmentry, 'r').readlines() - if environ.get('WAYLAND_DISPLAY') == 'wayland-0': - term('wl-copy ' + "'" + copyline[2].replace('\n', '') + "'") - else: - term('echo -n ' + "'" + copyline[2].replace('\n', '') + "'" + ' | xclip -sel c') - rmtree('/dev/shm/' + shmfolder) - except FileNotFoundError: - print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - print('The file you requested to edit does not exist!') - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n') - rmtree('/dev/shm/' + shmfolder) - exit() - -if argument == 'copy note' or argument == 'copy -n': - try: - print() - term('cd ' + directory + '; ls -1 *') - print() - readentry = str(input('Entry to copy: ')) - except KeyboardInterrupt: - readentry = 0 - print('\n\nCopy cancelled.\n') - exit() - shmfolder, shmentry = shmgen() - try: - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + readentry + '.gpg') - copyline = open('/dev/shm/' + shmfolder + '/' + shmentry, 'r').readlines() - if environ.get('WAYLAND_DISPLAY') == 'wayland-0': - term('wl-copy ' + "'" + copyline[4].replace('\n', '') + "'") - else: - term('echo -n ' + "'" + copyline[4].replace('\n', '') + "'" + ' | xclip -sel c') - rmtree('/dev/shm/' + shmfolder) - except FileNotFoundError: - print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - print('The file you requested to edit does not exist!') - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n') - rmtree('/dev/shm/' + shmfolder) - exit() - -# gen - -if argument == 'gen': - try: - clear() - entryname = str(input('Name of service: ')) - username = str(input('Username: ')) - passlength = int(input('How many characters should be in the password? ')) - passtype = str(input('Should the password be simple (for compatibility) or complex (for security)? (s/C) ')) - if passtype != 's': - passtype = string.ascii_letters + string.digits + string.punctuation - if passtype == 's': - passtype = string.ascii_letters + string.digits - passgen = ''.join(random.SystemRandom().choice(passtype) for _ in range(passlength)) - url = str(input('URL: ')) - notes = str(input('Additional notes: ')) - except KeyboardInterrupt: - entryname, username, passgen, url, notes = (0, 0, 0, 0, 0) - print('\n\nEntry generation cancelled.\n') - exit() - shmfolder, shmentry = shmgen() - try: - if entryname.startswith('/'): - if entryname.replace('/', '', 1).__contains__('/'): - folder, sep, folderentry = entryname.replace('/', '', 1).partition('/') - open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines(username + '\n' + passgen + '\n' + url - + '\n' + notes + '\n\n') - encryptfolder() - term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'") - else: - open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines(username + '\n' + passgen + '\n' + url - + '\n' + notes + '\n\n') - encrypt() - term('gpg -d ' + directory + "'" + entryname.replace('/', '', 1) + '.gpg' + "'") - else: - open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines(username + '\n' + passgen + '\n' + url - + '\n' + notes + '\n\n') - encrypt() - term('gpg -d ' + directory + "'" + entryname + '.gpg' + "'") - except FileNotFoundError: - print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - print('The folder you requested to access does not exist!') - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n') - rmtree('/dev/shm/' + shmfolder) - exit() - -if argument == 'gen update' or argument == 'gen -u': - try: - clear() - term('cd ' + directory + '; ls -1 *') - print() - entryname = str(input('Which password would you like to re-generate? ')) - passlength = int(input('How many characters should be in the password? ')) - passtype = str(input('Should the password be simple (for compatibility) or complex (for security)? (s/C) ')) - except KeyboardInterrupt: - entryname, passlength, passtype = (0, 0, 0) - print('\n\nEntry generation cancelled.\n') - exit() - shmfolder, shmentry = shmgen() - try: - if passtype != 's': - passtype = string.ascii_letters + string.digits + string.punctuation - if passtype == 's': - passtype = string.ascii_letters + string.digits - passgen = ''.join(random.SystemRandom().choice(passtype) for _ in range(passlength)) - if entryname.startswith('/'): - if entryname.replace('/', '', 1).__contains__('/'): - folder, sep, folderentry = entryname.replace('/', '', 1).partition('/') - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + - folder + '/' + folderentry + '.gpg') - replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 1, passgen + '\n') - remove(directory + folder + '/' + folderentry.replace('/', '', 1) + '.gpg') - encryptfolder() - term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'") - else: - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + - entryname.replace('/', '', 1) + '.gpg') - replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 1, passgen + '\n') - remove(directory + entryname.replace('/', '', 1) + '.gpg') - encrypt() - term('gpg -d ' + directory + "'" + entryname.replace('/', '', 1) + '.gpg' + "'") - else: - term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + entryname + '.gpg') - replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 1, passgen + '\n') - remove(directory + entryname + '.gpg') - encrypt() - term('gpg -d ' + directory + "'" + entryname + '.gpg' + "'") - except FileNotFoundError: - print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - print('The file you requested to edit does not exist!') - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n') - rmtree('/dev/shm/' + shmfolder) - exit() - -# remove - -if argument == 'remove' or argument == '-rm': - clear() - term('cd ' + directory + '; ls -1 *') +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: - entryname = str(input('What would you like to delete? ')) - try: - term('gpg -d --output /dev/shm/sshyp.lock /var/lib/sshyp/lock.gpg') - unlocker = open('/dev/shm/sshyp.lock', 'r').readlines() - remove('/dev/shm/sshyp.lock') - except FileNotFoundError: - print('\nAccess denied.\n') - exit() - if entryname.startswith('/'): - if entryname.replace('/', '', 1).__contains__('/'): - if devicetype == 'c': - term('ssh -p ' + port + ' ' + usernamessh + '@' + ip + ' "' + ' rm -rf ' + "'" + directoryssh + - entryname.replace('/', '', 1) + '.gpg' + "'" + '"') - remove(directory + entryname.replace('/', '', 1) + '.gpg') - else: - if devicetype == 'c': - term('ssh -p ' + port + ' ' + usernamessh + '@' + ip + ' "' + ' rm -rf ' + "'" + directoryssh + - entryname.replace('/', '', 1) + "'" + '"') - rmtree(directory + entryname.replace('/', '', 1)) - else: - if devicetype == 'c': - term('ssh -p ' + port + ' ' + usernamessh + '@' + ip + ' "' + ' rm -rf ' + "'" + directoryssh + - entryname + '.gpg' + "'" + '"') - remove(directory + entryname + '.gpg') - except KeyboardInterrupt: - print('\n\nDeletion cancelled.\n') - exit() + 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('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - print('The file you requested to delete does not exist!') - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n') + 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') -if argument.__contains__('-rm') or string_found('remove', argument) or string_found('add', argument) or \ - string_found('edit', argument) or string_found('gen', argument) or string_found('copy', argument) or \ - string_found('/', argument) or argument == 'sync' or argument == '-s' or argument == '' or argument == 'help' \ - or argument == '--help' or argument == '-h' or argument == 'version' or argument == '-v' or argument == \ - 'config' or argument == 'show w' or argument == 'show c': - pass + +# 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: - print('\n!!!!!!!!!!!!!!!') - print('Argument error!') - print('!!!!!!!!!!!!!!!') - print("\nUse 'help', '--help', or '-h' to see a list of commands.\n") + 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() -# permissions - applied pre-sync to ensure permissions are correct before upload - -term('find ' + directory + ' -type d -exec chmod -R 700 {} +') -term('find ' + directory + ' -type f -exec chmod -R 600 {} +') - -# rsync - ran at end of program to ensure all files are properly synced -if devicetype == 'c': - if argument.__contains__('-rm') or string_found('remove', argument) or string_found('add', argument) or \ - string_found('edit', argument) or string_found('gen', argument) or argument == 'sync' or argument == '-s': - print('Syncing entries with other device(s)...\n') - sshync.run_profile('/var/lib/sshyp/sshyp.sshync') +# 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() diff --git a/extra/changelog-total b/extra/changelog-total index 0a39b91..ff064b5 100755 --- a/extra/changelog-total +++ b/extra/changelog-total @@ -1,5 +1,47 @@ <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> +sshyp 2021.11.12.fr2 + +The Rewritten Update + +This release is a major re-write of old "rpass" code. +sshyp is now more reliable and better documented. + +New features: + +- an almost full re-write of the old "rpass" code used in the last release + ^ includes more reliable argument parsing and various optimizations + +Planned for next update (The Patchwork Update): + +- address all "TODO" comments in sshyp + +Planned for next, next update (The Fluffy Update): + +- new visual features + ^ this includes the new file list and thematic text art. sshyp will be + getting a retro computing theme. +- packages for more environments + ^ "sshyp" will be officially packaged for Arch Linux, Alpine Linux, and Termux (Android). + Debian/Ubuntu and Fedora packaging will come later. + +Planned for next, next, next update (The Sheep w/Shears Update): + +- allow for copying entire notes (not just first line) +- allow for multi-client deletion... somehow +- ability to pass entries as arguments for more functions +- detatch sshync and make it a separate package +- manpage + +Planned, no timeline: + +- create separate gui frontend targetting mobile devices (Android + Linux phones) + ^ the gui will also function on desktop linux +- package for more Linux distributions, such as Debian and Fedora) +- auto-completion on tab (currently unsure of best way to make this work) + +<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> + sshyp 2021.11.05.fr1 First public release of sshyp. diff --git a/share/doc/sshyp/changelog b/share/doc/sshyp/changelog index bce1952..a51d147 100644 --- a/share/doc/sshyp/changelog +++ b/share/doc/sshyp/changelog @@ -1,26 +1,21 @@ -sshyp 2021.11.05.fr1 +sshyp 2021.11.12.fr2 -First public release of sshyp. +The Rewritten Update -This release fixes major bugs from rpass and rebrands the project. +This release is a major re-write of old "rpass" code. +sshyp is now more reliable and better documented. New features: -- an entirely new syncing back-end called sshync (custom Python wrapper around sftp) - ^ in thoery, all syncing-related data loss should now be fixed, however, this new - system has just been created and is still under testing. Maybe wait for a few patches - before trusting this system. +- an almost full re-write of the old "rpass" code used in the last release + ^ includes more reliable argument parsing and various optimizations -Changes: +Planned for next update (The Patchwork Update): -- branding has been updated to reflect new project name and goals -- custom directories, custom ssh keys, and offline only mode are removed (may be temporary) - ^ the configuration wizard is being re-written in the next major update +- address all "TODO" comments in sshyp -Planned for next update (The Fluffy Update): +Planned for next, next update (The Fluffy Update): -- modularized and optimized code - ^ some older, bad code from "rpass" will be re-written. - new visual features ^ this includes the new file list and thematic text art. sshyp will be getting a retro computing theme. @@ -28,7 +23,7 @@ Planned for next update (The Fluffy Update): ^ "sshyp" will be officially packaged for Arch Linux, Alpine Linux, and Termux (Android). Debian/Ubuntu and Fedora packaging will come later. -Planned for next update (The Sheep w/Shears Update): +Planned for next, next, next update (The Sheep w/Shears Update): - allow for copying entire notes (not just first line) - allow for multi-client deletion... somehow