Fixed nested folders, replaced bloated folder detection code

This commit is contained in:
2021-11-18 12:27:10 -05:00
parent 29cc47c8d9
commit f15b90d32a
4 changed files with 44 additions and 121 deletions
+1 -1
View File
@@ -90,4 +90,4 @@ Broken Features in Latest Release:
Broken Features in Source: Broken Features in Source:
- nested folders - probably something, but not the things above
+39 -116
View File
@@ -1,10 +1,11 @@
#!/usr/bin/python3 #!/usr/bin/python3.10
# TODO guarantee numbers in generated passwords # TODO guarantee numbers in generated passwords
# TODO fix syncing for multi-word entries # TODO fix syncing for multi-word entries
# TODO combine all print-only functions into one and print based on argument passed to function # 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 make new, colored list its own callable function
# TODO test /dev/shm security # TODO test /dev/shm security
# TODO re-add missing file not found exceptions
# external modules # external modules
@@ -18,21 +19,16 @@ import string
# utility functions # utility functions
def argument_filter(): # filters arguments to usable text TODO move to global process, update incrementer
def argument_filter(): # filters arguments to usable text TODO move to global process
_argument_list = argv _argument_list = argv
i, _argument = 0, '' _i, _argument = 0, ''
for _ in _argument_list: for _ in _argument_list:
while i < len(_argument_list) - 1: while _i < len(_argument_list) - 1:
i += 1 _i += 1
_argument += _argument_list[i] + ' ' _argument += _argument_list[_i] + ' '
return _argument[:-1] 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 def replace_line(file_name, line_num, text): # replaces text in a given line with different text
_lines = open(file_name, 'r').readlines() _lines = open(file_name, 'r').readlines()
_lines[line_num] = text _lines[line_num] = text
@@ -48,15 +44,9 @@ def shm_gen(): # generates random folder in /dev/shm for security and returns r
return _shm_folder_gen, _shm_entry_gen return _shm_folder_gen, _shm_entry_gen
def encrypt(_shm_folder, _shm_entry, _entry_name): def encrypt(_shm_folder, _shm_entry, _location):
system(f"gpg -r {str(gpg_id)} -e '/dev/shm/{_shm_folder}/{_shm_entry}'") system(f"gpg -r {str(gpg_id)} -e '/dev/shm/{_shm_folder}/{_shm_entry}'")
move(f"/dev/shm/{_shm_folder}/{_shm_entry}.gpg", f"{directory}{_entry_name.replace('/', '', 1)}.gpg") move(f"/dev/shm/{_shm_folder}/{_shm_entry}.gpg", f"{directory}{_location}.gpg")
rmtree(f"/dev/shm/{_shm_folder}")
def encrypt_folder(_shm_folder, _shm_entry, _folder, _folder_entry_name):
system(f"gpg -r {str(gpg_id)} -e '/dev/shm/{_shm_folder}/{_shm_entry}'")
move(f"/dev/shm/{_shm_folder}/{_shm_entry}.gpg", f"{directory}{_folder}/{_folder_entry_name}.gpg")
rmtree(f"/dev/shm/{_shm_folder}") rmtree(f"/dev/shm/{_shm_folder}")
@@ -73,8 +63,6 @@ def edit_note(_shm_folder, _shm_entry):
def tweak(): # runs configuration wizard def tweak(): # runs configuration wizard
clear()
# storage directory creation # storage directory creation
system(f"mkdir -p /home/{environ.get('USER')}/.password-pasture") system(f"mkdir -p /home/{environ.get('USER')}/.password-pasture")
@@ -132,7 +120,6 @@ def tweak(): # runs configuration wizard
def helper(): # displays help menu TODO update with text art, thematic arguments def helper(): # displays help menu TODO update with text art, thematic arguments
clear()
print('\nsshyp Copyright (C) 2021 Randall Winkhart') 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 " 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.") "with ABSOLUTELY NO WARRANTY;\ntype `sshyp license' for details.")
@@ -174,7 +161,7 @@ def version(): # displays version information TODO update with text art
print('/ /') print('/ /')
print('/ sshyp Copyright (C) 2021 Randall Winkhart /') print('/ sshyp Copyright (C) 2021 Randall Winkhart /')
print('/ /') print('/ /')
print('/ Version 2021.11.15.fr2 /') print('/ Version 2021.11.20.fr2 /')
print('/ The Rewritten Update /') print('/ The Rewritten Update /')
print('/ /') print('/ /')
print('////////////////////////////////////////////////////////\n') print('////////////////////////////////////////////////////////\n')
@@ -184,7 +171,6 @@ def no_arg(): # displays a list of entries and gives an option to select one fo
print("\nFor a list of usable commands, run 'sshyp help'.\n") print("\nFor a list of usable commands, run 'sshyp help'.\n")
system(f"cd {directory}; ls -1 *") system(f"cd {directory}; ls -1 *")
_read_entry = str(input('\nEntry to read: ')) _read_entry = str(input('\nEntry to read: '))
clear()
system(f"gpg -d '{directory}{_read_entry.replace('/', '', 1)}.gpg'") system(f"gpg -d '{directory}{_read_entry.replace('/', '', 1)}.gpg'")
print() print()
@@ -198,12 +184,8 @@ def show_license(): # displays licensing information
'License for more details.\n\nhttps://opensource.org/licenses/GPL-3.0\n') '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 def read_shortcut(): # shortcut to quickly read an entry
if argument.replace('/', '', 1).__contains__('/'): system(f"gpg -d '{directory}{argument.replace('/', '', 1)}.gpg'")
_folder, _sep, _folder_entry = argument.replace('/', '', 1).partition('/')
system(f"gpg -d '{directory}{_folder}/{_folder_entry}.gpg'") # TODO EXAMPLE of fix for multi-word entry names
else:
system(f"gpg -d '{directory}{argument.replace('/', '', 1)}.gpg'")
def sync(): # calls sshync to sync changes to the user's server def sync(): # calls sshync to sync changes to the user's server
@@ -225,6 +207,8 @@ def add_info(): # displays 'add' syntax
def add_entry(): # adds a new entry def add_entry(): # adds a new entry
_entry_name = str(input('\nName of entry: ')) _entry_name = str(input('\nName of entry: '))
if _entry_name.startswith('/'):
_entry_name = _entry_name.replace('/', '', 1)
_shm_folder, _shm_entry = shm_gen() _shm_folder, _shm_entry = shm_gen()
if argument == 'add note' or argument == 'add -n': if argument == 'add note' or argument == 'add -n':
system(f"nano /dev/shm/{_shm_folder}/{_shm_entry}-n") system(f"nano /dev/shm/{_shm_folder}/{_shm_entry}-n")
@@ -242,20 +226,11 @@ def add_entry(): # adds a new entry
_notes = '' _notes = ''
open(f"/dev/shm/{_shm_folder}/{_shm_entry}", 'w').writelines(_username + '\n' + _password + '\n' + _url + '\n\n' open(f"/dev/shm/{_shm_folder}/{_shm_entry}", 'w').writelines(_username + '\n' + _password + '\n' + _url + '\n\n'
+ _notes + '\n\n') + _notes + '\n\n')
if _entry_name.startswith('/'): encrypt(_shm_folder, _shm_entry, _entry_name)
if _entry_name.replace('/', '', 1).__contains__('/'): system(f"gpg -d '{directory}{_entry_name}.gpg'")
_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(f"gpg -d '{directory}{_folder}/{_folder_entry}.gpg'")
else:
encrypt(_shm_folder, _shm_entry, _entry_name)
system(f"gpg -d '{directory}{_entry_name.replace('/', '', 1)}.gpg'")
else:
encrypt(_shm_folder, _shm_entry, _entry_name)
system(f"gpg -d '{directory}{_entry_name}.gpg'")
def add_folder(): # creates a new folder TODO create folder on server, as well def add_folder(): # creates a new folder
_folder_name = str(input('Name of new folder: ')) _folder_name = str(input('Name of new folder: '))
system(f"mkdir '{directory}{_folder_name}'") # TODO create using Python system(f"mkdir '{directory}{_folder_name}'") # TODO create using Python
system(f"ssh -p {port} {username_ssh}@{ip} \"mkdir -p '{directory_ssh}{_folder_name}'\"") system(f"ssh -p {port} {username_ssh}@{ip} \"mkdir -p '{directory_ssh}{_folder_name}'\"")
@@ -291,16 +266,10 @@ def edit(): # edits the contents of an entry
print() print()
system(f"cd {directory}; ls -1 *") # TODO replace with new list system(f"cd {directory}; ls -1 *") # TODO replace with new list
_entry_name = str(input('\nWhat file would you like to edit? ')) _entry_name = str(input('\nWhat file would you like to edit? '))
_shm_folder, _shm_entry = shm_gen()
if _entry_name.startswith('/'): if _entry_name.startswith('/'):
if _entry_name.replace('/', '', 1).__contains__('/'): _entry_name = _entry_name.replace('/', '', 1)
_folder, _sep, _folder_entry = _entry_name.replace('/', '', 1).partition('/') _shm_folder, _shm_entry = shm_gen()
system(f"gpg -d --output /dev/shm/{_shm_folder}/{_shm_entry} '{directory}{_folder}/{_folder_entry}.gpg'") system(f"gpg -d --output /dev/shm/{_shm_folder}/{_shm_entry} '{directory}{_entry_name}.gpg'")
else:
system(f"gpg -d --output /dev/shm/{_shm_folder}/{_shm_entry} '{directory}{_entry_name.replace('/', '', 1)}"
f".gpg'")
else:
system(f"gpg -d --output /dev/shm/{_shm_folder}/{_shm_entry} '{directory}{_entry_name}.gpg'")
if argument == 'edit username' or argument == 'edit -u': if argument == 'edit username' or argument == 'edit -u':
_detail = str(input('New Username: ')) _detail = str(input('New Username: '))
replace_line(f"/dev/shm/{_shm_folder}/{_shm_entry}", 0, _detail + '\n') replace_line(f"/dev/shm/{_shm_folder}/{_shm_entry}", 0, _detail + '\n')
@@ -312,20 +281,9 @@ def edit(): # edits the contents of an entry
replace_line(f"/dev/shm/{_shm_folder}/{_shm_entry}", 2, _detail + '\n') replace_line(f"/dev/shm/{_shm_folder}/{_shm_entry}", 2, _detail + '\n')
if argument == 'edit note' or argument == 'edit -n': if argument == 'edit note' or argument == 'edit -n':
edit_note(_shm_folder, _shm_entry) edit_note(_shm_folder, _shm_entry)
if _entry_name.startswith('/'): remove(f"{directory}{_entry_name}.gpg")
if _entry_name.replace('/', '', 1).__contains__('/'): encrypt(_shm_folder, _shm_entry, _entry_name)
_folder, _sep, _folder_entry = _entry_name.replace('/', '', 1).partition('/') system(f"gpg -d '{directory}{_entry_name}.gpg'")
remove(f"{directory}{_folder}/{_folder_entry}.gpg")
encrypt_folder(_shm_folder, _shm_entry, _folder, _folder_entry)
system(f"gpg -d '{directory}{_folder}/{_folder_entry}.gpg'")
else:
remove(f"{directory}{_entry_name.replace('/', '', 1)}.gpg")
encrypt(_shm_folder, _shm_entry, _entry_name)
system(f"gpg -d '{directory}{_entry_name.replace('/', '', 1)}.gpg'")
else:
remove(f"{directory}{_entry_name}.gpg")
encrypt(_shm_folder, _shm_entry, _entry_name)
system(f"gpg -d '{directory}{_entry_name}.gpg'")
def gen(): # generates a password for a new or an existing entry def gen(): # generates a password for a new or an existing entry
@@ -335,6 +293,8 @@ def gen(): # generates a password for a new or an existing entry
print() print()
system(f"cd {directory}; ls -1 *") # TODO replace with new list system(f"cd {directory}; ls -1 *") # TODO replace with new list
_entry_name = str(input('\nName of service: ')) _entry_name = str(input('\nName of service: '))
if _entry_name.startswith('/'):
_entry_name = _entry_name.replace('/', '', 1)
if argument != 'gen update' and argument != 'gen -u': if argument != 'gen update' and argument != 'gen -u':
_username = str(input('Username: ')) _username = str(input('Username: '))
_pass_length = int(input('How many characters should be in the password? ')) _pass_length = int(input('How many characters should be in the password? '))
@@ -351,41 +311,14 @@ def gen(): # generates a password for a new or an existing entry
open(f"/dev/shm/{_shm_folder}/{_shm_entry}", 'w').writelines(_username + '\n' + _pass_gen + '\n' + _url + open(f"/dev/shm/{_shm_folder}/{_shm_entry}", 'w').writelines(_username + '\n' + _pass_gen + '\n' + _url +
'\n\n' + _notes + '\n\n') '\n\n' + _notes + '\n\n')
if argument != 'gen update' and argument != 'gen -u': if argument != 'gen update' and argument != 'gen -u':
if _entry_name.startswith('/'): encrypt(_shm_folder, _shm_entry, _entry_name)
if _entry_name.replace('/', '', 1).__contains__('/'): system(f"gpg -d '{directory}{_entry_name}.gpg'")
_folder, _sep, _folder_entry = _entry_name.replace('/', '', 1).partition('/') # TODO nested
encrypt_folder(_shm_folder, _shm_entry, _folder, _folder_entry)
system(f"gpg -d '{directory}{_folder}/{_folder_entry}.gpg'")
else:
encrypt(_shm_folder, _shm_entry, _entry_name)
system(f"gpg -d '{directory}{_entry_name.replace('/', '', 1)}.gpg'")
else:
encrypt(_shm_folder, _shm_entry, _entry_name)
system(f"gpg -d '{directory}{_entry_name}.gpg'")
else: else:
if _entry_name.startswith('/'): system(f"gpg -d --output /dev/shm/{_shm_folder}/{_shm_entry} '{directory}{_entry_name}.gpg'")
if _entry_name.replace('/', '', 1).__contains__('/'): replace_line(f"/dev/shm/{_shm_folder}/{_shm_entry}", 1, _pass_gen + '\n')
_folder, _sep, _folder_entry = _entry_name.replace('/', '', 1).partition( remove(f"{directory}{_entry_name}.gpg")
'/') # TODO may not work w/nested encrypt(_shm_folder, _shm_entry, _entry_name)
system(f"gpg -d --output /dev/shm/{_shm_folder}/{_shm_entry} '{directory}{_folder}/{_folder_entry}" system(f"gpg -d '{directory}{_entry_name}.gpg'")
f".gpg'")
replace_line(f"/dev/shm/{_shm_folder}/{_shm_entry}", 1, _pass_gen + '\n')
remove(f"{directory}{_folder}/{_folder_entry.replace('/', '', 1)}.gpg")
encrypt_folder(_shm_folder, _shm_entry, _folder, _folder_entry)
system(f"gpg -d '{directory}{_folder}/{_folder_entry}.gpg'")
else:
system(f"gpg -d --output /dev/shm/{_shm_folder}/{_shm_entry} '{directory}"
f"{_entry_name.replace('/', '', 1)}.gpg'")
replace_line(f"/dev/shm/{_shm_folder}/'{_shm_entry}", 1, _pass_gen + '\n')
remove(f"{directory}{_entry_name.replace('/', '', 1)}.gpg")
encrypt(_shm_folder, _shm_entry, _entry_name)
system(f"gpg -d '{directory}{_entry_name.replace('/', '', 1)}.gpg'")
else:
system(f"gpg -d --output /dev/shm/{_shm_folder}/{_shm_entry} '{directory}{_entry_name}.gpg'")
replace_line(f"/dev/shm/{_shm_folder}/{_shm_entry}", 1, _pass_gen + '\n')
remove(f"{directory}{_entry_name}.gpg")
encrypt(_shm_folder, _shm_entry, _entry_name)
system(f"gpg -d '{directory}{_entry_name}.gpg'")
def copy_info(): # displays 'copy' syntax def copy_info(): # displays 'copy' syntax
@@ -430,6 +363,8 @@ def remove_data(): # deletes an entry or folder from both the client and the se
print() print()
system(f"cd {directory}; ls -1 *") # TODO replace with new list system(f"cd {directory}; ls -1 *") # TODO replace with new list
_entry_name = str(input('\nWhat would you like to delete? ')) _entry_name = str(input('\nWhat would you like to delete? '))
if _entry_name.startswith('/'):
_entry_name = _entry_name.replace('/', '', 1)
try: try:
system('gpg -d --output /dev/shm/sshyp.lock /var/lib/sshyp/lock.gpg') system('gpg -d --output /dev/shm/sshyp.lock /var/lib/sshyp/lock.gpg')
_unlock = open('/dev/shm/sshyp.lock', 'r').readlines() _unlock = open('/dev/shm/sshyp.lock', 'r').readlines()
@@ -437,21 +372,9 @@ def remove_data(): # deletes an entry or folder from both the client and the se
except FileNotFoundError: except FileNotFoundError:
print('\nAccess denied.\n') print('\nAccess denied.\n')
s_exit() s_exit()
if _entry_name.startswith('/'): if device_type == 'c':
if _entry_name.replace('/', '', 1).__contains__('/'): system(f"ssh -p {port} {username_ssh}@{ip} \"rm -rf '{directory_ssh}{_entry_name}.gpg'\"")
if device_type == 'c': remove(f"{directory}{_entry_name}.gpg")
system(f"ssh -p {port} {username_ssh}@{ip} \"rm -rf '{directory_ssh}{_entry_name.replace('/', '', 1)}"
f".gpg'\"")
remove(f"{directory}{_entry_name.replace('/', '', 1)}.gpg")
else:
if device_type == 'c':
system(f"ssh -p {port} {username_ssh}@{ip} \"rm -rf '{directory_ssh}{_entry_name.replace('/', '', 1)}"
f"'\"")
rmtree(f"{directory}{_entry_name.replace('/', '', 1)}")
else:
if device_type == 'c':
system(f"ssh -p {port} {username_ssh}@{ip} \"rm -rf '{directory_ssh}{_entry_name}.gpg'\"")
remove(f"{directory}{_entry_name}.gpg")
# program start sequence # program start sequence
@@ -561,6 +484,6 @@ else:
if argument != '' and argument != 'help' and argument != '--help' and argument != '-h' and argument != 'license' and \ 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 \ 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 -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 \ != 'copy -l' and argument != 'copy note' and argument != 'copy -n' and argument != 'copy' and argument != \
argument.startswith('/') is False: 'tweak' and error == 0 and argument.startswith('/') is False:
sync() sync()
+2 -2
View File
@@ -12,11 +12,12 @@ New features:
- an almost full re-write of the old "rpass" code used in the last release - an almost full re-write of the old "rpass" code used in the last release
^ includes more reliable argument parsing and various optimizations ^ includes more reliable argument parsing and various optimizations
- new folders are now also created on the server - new folders are now also created on the server
**fix gen command using old notes system ** fix gen command using old notes system
** address TODO comments ** address TODO comments
Changes: Changes:
- nested folders actually work now
** major sshync bugs fixed ** major sshync bugs fixed
^fixed many instances where sshync would refuse to upload/download ^fixed many instances where sshync would refuse to upload/download
^fixed errors that were being thrown despite sshync working as intended ^fixed errors that were being thrown despite sshync working as intended
@@ -32,7 +33,6 @@ Planned for next update (The Fluffier Update):
^ "sshyp" will be officially packaged for Arch Linux, Alpine Linux, and Termux (Android). ^ "sshyp" will be officially packaged for Arch Linux, Alpine Linux, and Termux (Android).
Debian/Ubuntu and Fedora packaging will come later. Debian/Ubuntu and Fedora packaging will come later.
- imporove password generator to guarantee more secure results - imporove password generator to guarantee more secure results
- fix nested folders
Planned for next, next update (The Shears Update Pt. 1): Planned for next, next update (The Shears Update Pt. 1):
+2 -2
View File
@@ -10,11 +10,12 @@ New features:
- an almost full re-write of the old "rpass" code used in the last release - an almost full re-write of the old "rpass" code used in the last release
^ includes more reliable argument parsing and various optimizations ^ includes more reliable argument parsing and various optimizations
- new folders are now also created on the server - new folders are now also created on the server
**fix gen command using old notes system ** fix gen command using old notes system
** address TODO comments ** address TODO comments
Changes: Changes:
- nested folders actually work now
** major sshync bugs fixed ** major sshync bugs fixed
^fixed many instances where sshync would refuse to upload/download ^fixed many instances where sshync would refuse to upload/download
^fixed errors that were being thrown despite sshync working as intended ^fixed errors that were being thrown despite sshync working as intended
@@ -30,7 +31,6 @@ Planned for next update (The Fluffier Update):
^ "sshyp" will be officially packaged for Arch Linux, Alpine Linux, and Termux (Android). ^ "sshyp" will be officially packaged for Arch Linux, Alpine Linux, and Termux (Android).
Debian/Ubuntu and Fedora packaging will come later. Debian/Ubuntu and Fedora packaging will come later.
- imporove password generator to guarantee more secure results - imporove password generator to guarantee more secure results
- fix nested folders
Planned for next, next update (The Shears Update Pt. 1): Planned for next, next update (The Shears Update Pt. 1):