Compare commits

...
18 Commits
Author SHA1 Message Date
RandyTheSilly 018d0c511d Updated README.md for release v1.1.2
Former-commit-id: 4eb7a866fa03d5990a300120974def01ab4babec [formerly 0ce5b1c1f6]
Former-commit-id: b0e3e46e63b15184ad7d600ccc5e33e98c185081
2022-08-27 14:27:35 -04:00
RandyTheSilly 55b94fc4cc Removed option for using local source from packaging script, as it is mostly unnecessary and/or broken
Former-commit-id: 86a32b1b3e217708078d5d99f8e30571169697a6 [formerly 35068270af]
Former-commit-id: db7e4d8eedcda2d94a5cec75e4ef9e354eec0687
2022-08-27 14:08:58 -04:00
RandyTheSilly 3f9c4e2c8d Automatically calculate revision number for Alpine packaging
Former-commit-id: 2de24f3dc4b9e5f5e27265da1271ea96be0387f5 [formerly cd5c9150a5]
Former-commit-id: 2c613cdc811dc127968a46758c4f238562bc64f9
2022-08-27 13:53:09 -04:00
RandyTheSilly 166ac50f42 Updated documentation for release v1.1.2
Former-commit-id: e212291e40989a1c50cbccf27060dbc7744da668 [formerly f97c9ad4f9]
Former-commit-id: 150048cc1ab40ee49e83295cedcdc9c3b1c49a8c
2022-08-27 13:12:58 -04:00
RandyTheSilly df1c6482a8 Optimized cross-device entry deletion code
Former-commit-id: 2a1dcda6460c06103846b41fbf2d83bf78c05527 [formerly f1aca39fd1]
Former-commit-id: 268b5564ff2f4cc157ebe039e9c46826a4bdb878
2022-08-27 12:46:54 -04:00
RandyTheSilly 38c6ef3d1b rename() now uses entry_name_fetch()
Former-commit-id: c3a3e7b95eb85225dd0bfbbbb15ac81d78adf7e2 [formerly 1f0b23c25f]
Former-commit-id: d2fe8fce784a01a9f5c127ad1eb3d05550624425
2022-08-27 12:11:59 -04:00
RandyTheSilly 7bea6093b8 Properly handle exception for attempting to copy a field that does not exist
Former-commit-id: 57c07b5ad482413febc9b6ee4e27c3f3a5f4fe11 [formerly 7355092cfe]
Former-commit-id: dc1d96e23a8a558c4b880b997a17e3a8d7cfcadd
2022-08-26 18:04:01 -04:00
RandyTheSilly f9ca6f8e94 Fixed generic package not being compressed
Former-commit-id: 600f05d063f52cfc34b58abef6acb799ce35f651 [formerly 56a99d09ef]
Former-commit-id: 90d9f29f91c3e44cf0e2ef75a8bbbd48ad3aa52c
2022-08-14 19:16:04 -04:00
RandyTheSilly 75d8eb7b7d Added Alpine packaging support, fixed packaging woes regarding a bad shebang
Former-commit-id: 2a440affcd09a28554c4ebe316408889047dc052 [formerly a83297c52b]
Former-commit-id: 41d6aebd702925cfbd4089f974b09250f3f6d8b3
2022-08-14 19:13:50 -04:00
RandyTheSilly 39316d04a2 Updated documentation for release v1.1.1
Former-commit-id: defed7054804d7bf36e93c302282039d335d6561 [formerly 558512ba52]
Former-commit-id: f6cf7d3e5633652439a46c51f9d5cfad007f2236
2022-07-21 22:40:29 -04:00
RandyTheSilly 3e9a4c0403 Fixed gpg auto-generation adding extra spaces to gpg-gen file
Former-commit-id: 0a273095a3a13d2997655c19ff62a674b135f530 [formerly 83a408ca0b]
Former-commit-id: eeee558508a68dcb9e243eea4e049704448c9f3e
2022-07-21 19:34:25 -04:00
RandyTheSilly 3bc07b48ef Fixed encrypt() using global tmp_dir
Former-commit-id: 2e993a03f745ae5b4a4f58acc6695e0660bc278c [formerly b6d3f7c5d1]
Former-commit-id: 9306abe18fe741cdd36280798f4bcffc66a77dd7
2022-07-21 01:37:53 -04:00
RandyTheSilly 5234e8c048 Improved encrypt() usability by extensions
Former-commit-id: 1dad668c15e2e1629c0233c80b88763ed5535c04 [formerly 0c975eab8f]
Former-commit-id: 3bddba6995f6aa92de8ea00500cb64b08d7e17db
2022-07-21 01:29:59 -04:00
RandyTheSilly b7c3535955 Exposed encrypt() function to be used by extensions
Former-commit-id: a055f6359a1bd2b81191ef1ef7b5dfb9432f75b2 [formerly 033bbd59de]
Former-commit-id: 451bafbfaaec27086c8c6cb50cb918ca94cf5497
2022-07-20 16:23:43 -04:00
RandyTheSilly 1f52c45c43 Bump version to v1.1.1
Former-commit-id: b2aad92f56b7931daf7ccab2a44793b29bec61f3 [formerly 5aeaee4c8f]
Former-commit-id: 2c651547721c89147dff385e0ad25d2d44694870
2022-07-17 07:29:56 -04:00
RandyTheSilly 7723baa69e Convert add_entry() and gen() to use optimized_edit()
Former-commit-id: 09f1256a4eed4bc042af7149f15ebb5b1197cbe8 [formerly 2d40db5467]
Former-commit-id: f7aa3b0cd2a761283ed11646b6c8fbb6f8130501
2022-07-17 07:25:12 -04:00
RandyTheSilly b680cc96d6 Significant overhaul to entry format optimization
Former-commit-id: 032103385be1ec017f97192829d591acd7a8c902 [formerly 8f318446bf]
Former-commit-id: 7ae69f3bafa268df1cf114d443d367ff45618f4a
2022-07-17 05:37:54 -04:00
RandyTheSilly f750fe1e4d Fixed compatibility check not adding the correct number of lines under certain circumstances
Former-commit-id: 93a4ff7bd25e38ae0a2b40d147afa51b08d73e04 [formerly a4368d60eb]
Former-commit-id: 58c89fcb9728bcfb430aaaf0df817f696688f1cd
2022-07-16 19:32:57 -04:00
8 changed files with 187 additions and 137 deletions
+2 -2
View File
@@ -40,7 +40,7 @@ What sshyp definitely won't do:
# Installation # Installation
Please see the [installation guide](https://github.com/rwinkhart/sshyp/wiki/Installation) in the sshyp wiki for directions specific to your distribution/OS. Please see the [installation guide](https://github.com/rwinkhart/sshyp/wiki/Installation) in the sshyp wiki for directions specific to your distribution/OS.
Pre-built packages exist for Haiku, FreeBSD, Arch Linux, Debian/Ubuntu Linux, Fedora Linux, and Termux. These can be downloaded from the releases page. Pre-built packages exist for Haiku, FreeBSD, Alpine Linux, Arch Linux, Debian/Ubuntu Linux, Fedora Linux, and Termux. These can be downloaded from the releases page.
Requests for additional distribution/OS support can be filed as issues. Requests for additional distribution/OS support can be filed as issues.
@@ -63,7 +63,7 @@ Haiku and Fedora packaging must be done on their own respective distributions.
The AUR version and the packages attatched to the release tags were already packaged using this script. The AUR version and the packages attatched to the release tags were already packaged using this script.
Currently, the script can create packages for Haiku, FreeBSD, Arch Linux (PKGBUILD), Debian/Ubuntu Linux, Fedora Linux, Termux, and generic. Currently, the script can create packages for Haiku, FreeBSD, Alpine Linux (APKBUILD), Arch Linux (PKGBUILD), Debian/Ubuntu Linux, Fedora Linux, Termux, and generic.
# Usage # Usage
Upon initial installation (on both the server and client devices), be sure to run: Upon initial installation (on both the server and client devices), be sure to run:
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/python3 #!/usr/bin/env python3
# external modules # external modules
+77 -73
View File
@@ -1,4 +1,4 @@
#!/bin/python3 #!/usr/bin/env python3
# external modules # external modules
@@ -82,13 +82,7 @@ def entry_reader(_decrypted_entry): # displays the contents of an entry in a re
print() print()
except IndexError: except IndexError:
if _num == 0: if _num == 0:
print(f"\u001b[38;5;15;48;5;238mpassword:\u001b[0m\n{_entry_lines[0]}") print(f"\u001b[38;5;15;48;5;238mpassword:\u001b[0m\n{_entry_lines[0]}\n")
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 entry_name_fetch(_entry_name_location): # fetches and returns entry name from user input or from provided argument def entry_name_fetch(_entry_name_location): # fetches and returns entry name from user input or from provided argument
@@ -142,10 +136,11 @@ def pass_gen(): # generates and returns a random password based on user-specifi
return _gen return _gen
def encrypt(_shm_folder, _shm_entry, _location): # encrypts an entry and cleans up the temporary files def encrypt(_entry_dir, _shm_folder, _shm_entry, _gpg_com, _gpg_id, _tmp_dir=path.expanduser('~/.config/sshyp/tmp/')):
system(f"{gpg} -qr {str(gpg_id)} -e '{tmp_dir}{_shm_folder}/{_shm_entry}'") # encrypts an entry and cleans up the temporary files
move(f"{tmp_dir}{_shm_folder}/{_shm_entry}.gpg", f"{directory}{_location}.gpg") system(f"{_gpg_com} -qr {str(_gpg_id)} -e '{_tmp_dir}{_shm_folder}/{_shm_entry}'")
rmtree(f"{tmp_dir}{_shm_folder}") move(f"{_tmp_dir}{_shm_folder}/{_shm_entry}.gpg", f"{_entry_dir}.gpg")
rmtree(f"{_tmp_dir}{_shm_folder}")
def decrypt(_entry_dir, _shm_folder, _shm_entry, _gpg_command, _tmp_dir=path.expanduser('~/.config/sshyp/tmp/')): def decrypt(_entry_dir, _shm_folder, _shm_entry, _gpg_command, _tmp_dir=path.expanduser('~/.config/sshyp/tmp/')):
@@ -161,13 +156,34 @@ def decrypt(_entry_dir, _shm_folder, _shm_entry, _gpg_command, _tmp_dir=path.exp
s_exit(1) s_exit(1)
def edit_note(_shm_folder, _shm_entry): # edits the note attached to an entry def optimized_edit(_lines, _edit_data, _edit_line): # ensures an edited entry is optimized for best compatibility
lines = open(f"{tmp_dir}{_shm_folder}/{_shm_entry}").readlines() while len(_lines) < _edit_line + 1:
open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'w').writelines(lines[0:3]) _lines += ['\n']
open(f"{tmp_dir}{_shm_folder}/{_shm_entry}-n", 'w').writelines(lines[3:]) if _edit_data is not None:
_lines[_edit_line] = _edit_data.strip('\n').rstrip() + '\n'
for _num in range(len(_lines)):
if not _lines[_num].endswith('\n'):
_lines[_num] += '\n'
for _num in reversed(range(len(_lines))):
if _lines[_num] == '\n':
_lines = _lines[:-1]
elif _lines[_num].endswith('\n'):
_lines[_num] = _lines[_num].rstrip()
break
else:
break
return _lines
def edit_note(_shm_folder, _shm_entry, _lines): # edits the note attached to an entry
_reg_lines = _lines[0:3]
open(f"{tmp_dir}{_shm_folder}/{_shm_entry}-n", 'w').writelines(_lines[3:])
system(f"{editor} {tmp_dir}{_shm_folder}/{_shm_entry}-n") system(f"{editor} {tmp_dir}{_shm_folder}/{_shm_entry}-n")
edit_notes = open(f"{tmp_dir}{_shm_folder}/{_shm_entry}-n").read() _new_notes = open(f"{tmp_dir}{_shm_folder}/{_shm_entry}-n").readlines()
open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'a').write(edit_notes) while len(_reg_lines) < 3:
_reg_lines += ['\n']
_noted_lines = _reg_lines + _new_notes
return _noted_lines
def copy_name_check(_port, _username_ssh, _ip, _client_device_name): def copy_name_check(_port, _username_ssh, _ip, _client_device_name):
@@ -222,9 +238,9 @@ def tweak(): # runs configuration wizard
else: else:
print('\na unique gpg key is being generated for you...') print('\na unique gpg key is being generated for you...')
if not Path(path.expanduser('~/.config/sshyp/gpg-gen')).is_file(): if not Path(path.expanduser('~/.config/sshyp/gpg-gen')).is_file():
open(path.expanduser('~/.config/sshyp/gpg-gen'), 'w').write('Key-Type: 1\nKey-Length: 4096\nKey-Usage:\ open(path.expanduser('~/.config/sshyp/gpg-gen'), 'w').writelines([
sign encrypt\nName-Real: sshyp\nName-Comment: password manager encryption\nName-Email: \ 'Key-Type: 1\n', 'Key-Length: 4096\n', 'Key-Usage: sign encrypt\n', 'Name-Real: sshyp\n',
https://github.com/rwinkhart/sshyp\nExpire-Date: 0') 'Name-Comment: gpg-sshyp\n', 'Name-Email: https://github.com/rwinkhart/sshyp\n', 'Expire-Date: 0'])
if uname()[0] == 'Haiku': if uname()[0] == 'Haiku':
run(gpg + ' --batch --generate-key --passphrase ' + "'" + run(gpg + ' --batch --generate-key --passphrase ' + "'" +
input('\ngpg passphrase: ') + "'" + " '" + input('\ngpg passphrase: ') + "'" + " '" +
@@ -330,7 +346,7 @@ def print_info(): # prints help text based on argument
'randall winkhart\u001b[38;5;15;48;5;15m \u001b[38;5;7;48;5;8m/\u001b[0m') 'randall winkhart\u001b[38;5;15;48;5;15m \u001b[38;5;7;48;5;8m/\u001b[0m')
print('\u001b[38;5;7;48;5;8m/\u001b[38;5;15;48;5;15m ' print('\u001b[38;5;7;48;5;8m/\u001b[38;5;15;48;5;15m '
'\u001b[38;5;7;48;5;8m/\u001b[0m') '\u001b[38;5;7;48;5;8m/\u001b[0m')
print('\u001b[38;5;7;48;5;8m/\u001b[38;5;15;48;5;15m \u001b[38;5;15;48;5;8mversion 1.1.0' print('\u001b[38;5;7;48;5;8m/\u001b[38;5;15;48;5;15m \u001b[38;5;15;48;5;8mversion 1.1.2'
'\u001b[38;5;15;48;5;15m \u001b[38;5;7;48;5;8m/\u001b[0m') '\u001b[38;5;15;48;5;15m \u001b[38;5;7;48;5;8m/\u001b[0m')
print('\u001b[38;5;7;48;5;8m/\u001b[38;5;15;48;5;15m \u001b[38;5;15;48;5;8mthe sheecrets ' print('\u001b[38;5;7;48;5;8m/\u001b[38;5;15;48;5;15m \u001b[38;5;15;48;5;8mthe sheecrets '
'update\u001b[38;5;15;48;5;15m \u001b[38;5;7;48;5;8m/\u001b[0m') 'update\u001b[38;5;15;48;5;15m \u001b[38;5;7;48;5;8m/\u001b[0m')
@@ -407,22 +423,16 @@ def sync(): # calls sshync to sync changes to the user's server
_deletion_database = None _deletion_database = None
s_exit(1) s_exit(1)
for _file in _deletion_database: for _file in _deletion_database:
if _file[:-1].endswith('/'): try:
try: if silent_sync != 1:
if silent_sync != 1: print(f"\u001b[38;5;208m{_file[:-1]}\u001b[0m has been sheared, removing...")
print(f"\u001b[38;5;208m{_file[:-1]}\u001b[0m has been sheared, removing...") if _file[:-1].endswith('/'):
rmtree(f"{directory}{_file[:-1]}") rmtree(f"{directory}{_file[:-1]}")
except FileNotFoundError: else:
if silent_sync != 1:
print('folder does not exist locally.')
else:
try:
if silent_sync != 1:
print(f"\u001b[38;5;208m{_file[:-1]}\u001b[0m has been sheared, removing...")
remove(f"{directory}{_file[:-1]}.gpg") remove(f"{directory}{_file[:-1]}.gpg")
except (FileNotFoundError, IsADirectoryError): except FileNotFoundError:
if silent_sync != 1: if silent_sync != 1:
print('file does not exist locally.') print('location does not exist locally')
# check for new folders # check for new folders
system(f"ssh -i '{path.expanduser('~/.ssh/sshyp')}' -p {port} {username_ssh}@{ip} \"cd /bin; python -c " system(f"ssh -i '{path.expanduser('~/.ssh/sshyp')}' -p {port} {username_ssh}@{ip} \"cd /bin; python -c "
f"'import sshypRemote; sshypRemote.folder_check()'\"") f"'import sshypRemote; sshypRemote.folder_check()'\"")
@@ -460,7 +470,7 @@ def add_entry(): # adds a new entry
_shm_folder, _shm_entry = shm_gen() _shm_folder, _shm_entry = shm_gen()
system(f"{editor} {tmp_dir}{_shm_folder}/{_shm_entry}-n") system(f"{editor} {tmp_dir}{_shm_folder}/{_shm_entry}-n")
_notes = open(f"{tmp_dir}{_shm_folder}/{_shm_entry}-n", 'r').read() _notes = open(f"{tmp_dir}{_shm_folder}/{_shm_entry}-n", 'r').read()
open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'w').writelines('\n\n\n' + _notes) open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'w').writelines(optimized_edit(['', '', '', _notes], None, -1))
elif argument_list[2] == 'password' or argument_list[2] == '-p': elif argument_list[2] == 'password' or argument_list[2] == '-p':
_username = str(input('username: ')) _username = str(input('username: '))
_password = str(input('password: ')) _password = str(input('password: '))
@@ -472,11 +482,11 @@ def add_entry(): # adds a new entry
_notes = open(f"{tmp_dir}{_shm_folder}/{_shm_entry}-n", 'r').read() _notes = open(f"{tmp_dir}{_shm_folder}/{_shm_entry}-n", 'r').read()
else: else:
_notes = '' _notes = ''
open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'w').writelines(_password + '\n' + _username + '\n' + _url + open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'w')\
'\n' + _notes) .writelines(optimized_edit([_password, _username, _url, _notes], None, -1))
print('\n\u001b[1mentry preview:\u001b[0m') print('\n\u001b[1mentry preview:\u001b[0m')
entry_reader(f"{tmp_dir}{_shm_folder}/{_shm_entry}") entry_reader(f"{tmp_dir}{_shm_folder}/{_shm_entry}")
encrypt(_shm_folder, _shm_entry, _entry_name) encrypt(directory + _entry_name, _shm_folder, _shm_entry, gpg, gpg_id)
def add_folder(): # creates a new folder def add_folder(): # creates a new folder
@@ -497,8 +507,7 @@ def rename(): # renames an entry or folder
if not Path(f"{directory}{_entry_name}.gpg").is_file() and not Path(f"{directory}{_entry_name}").is_dir(): if not Path(f"{directory}{_entry_name}.gpg").is_file() and not Path(f"{directory}{_entry_name}").is_dir():
print(f"\n\u001b[38;5;9merror: entry ({_entry_name}) does not exist\u001b[0m\n") print(f"\n\u001b[38;5;9merror: entry ({_entry_name}) does not exist\u001b[0m\n")
s_exit(1) s_exit(1)
_new_name = str(input('new name: ')) _new_name = entry_name_fetch('new name: ')
print(f"{directory}{_new_name}")
if Path(f"{directory}{_new_name}.gpg").is_file() or Path(f"{directory}{_new_name}").is_dir(): if Path(f"{directory}{_new_name}.gpg").is_file() or Path(f"{directory}{_new_name}").is_dir():
print(f"\n\u001b[38;5;9merror: ({_new_name}) already exists\u001b[0m\n") print(f"\n\u001b[38;5;9merror: ({_new_name}) already exists\u001b[0m\n")
s_exit(1) s_exit(1)
@@ -513,7 +522,7 @@ def rename(): # renames an entry or folder
def edit(): # edits the contents of an entry def edit(): # edits the contents of an entry
_shm_folder, _shm_entry = None, None # sets base-line values to avoid errors _shm_folder, _shm_entry, _detail, _edit_line = None, None, None, None # sets values to avoid PEP8 warnings
if len(argument_list) < 4: if len(argument_list) < 4:
_entry_name = entry_name_fetch('entry to edit: ') _entry_name = entry_name_fetch('entry to edit: ')
else: else:
@@ -523,29 +532,23 @@ def edit(): # edits the contents of an entry
s_exit(1) s_exit(1)
_shm_folder, _shm_entry = shm_gen() _shm_folder, _shm_entry = shm_gen()
decrypt(directory + _entry_name, _shm_folder, _shm_entry, gpg) decrypt(directory + _entry_name, _shm_folder, _shm_entry, gpg)
# compatibility check for GNU pass entries (ensuring they have at least four lines)
_lines = open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'r').readlines()
if len(_lines) < 3:
while len(_lines) < 3:
_lines.append('\n')
open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'w').writelines(_lines)
if argument_list[2] == 'username' or argument_list[2] == '-u': if argument_list[2] == 'username' or argument_list[2] == '-u':
_detail = str(input('new username: ')) _detail, _edit_line = str(input('username: ')), 1
replace_line(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 1, _detail + '\n')
elif argument_list[2] == 'password' or argument_list[2] == '-p': elif argument_list[2] == 'password' or argument_list[2] == '-p':
_detail = str(input('new password: ')) _detail, _edit_line = str(input('password: ')), 0
replace_line(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 0, _detail + '\n')
elif argument_list[2] == 'url' or argument_list[2] == '-l': elif argument_list[2] == 'url' or argument_list[2] == '-l':
_detail = str(input('new url: ')) _detail, _edit_line = str(input('url: ')), 2
replace_line(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 2, _detail + '\n') if argument_list[2] == 'note' or argument_list[2] == '-n':
elif argument_list[2] == 'note' or argument_list[2] == '-n': _edit_line = 2
edit_note(_shm_folder, _shm_entry) _new_lines = optimized_edit(edit_note(_shm_folder, _shm_entry,
open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'r').readlines()), None, -1)
else:
_new_lines = optimized_edit(open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'r').readlines(), _detail, _edit_line)
open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'w').writelines(_new_lines)
remove(f"{directory}{_entry_name}.gpg") remove(f"{directory}{_entry_name}.gpg")
print('\n\u001b[1mentry preview:\u001b[0m') print('\n\u001b[1mentry preview:\u001b[0m')
entry_reader(f"{tmp_dir}{_shm_folder}/{_shm_entry}") entry_reader(f"{tmp_dir}{_shm_folder}/{_shm_entry}")
encrypt(_shm_folder, _shm_entry, _entry_name) encrypt(directory + _entry_name, _shm_folder, _shm_entry, gpg, gpg_id)
def gen(): # generates a password for a new or an existing entry def gen(): # generates a password for a new or an existing entry
@@ -573,20 +576,17 @@ def gen(): # generates a password for a new or an existing entry
_notes = open(f"{tmp_dir}{_shm_folder}/{_shm_entry}-n", 'r').read() _notes = open(f"{tmp_dir}{_shm_folder}/{_shm_entry}-n", 'r').read()
else: else:
_notes = '' _notes = ''
open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'w').writelines(_password + '\n' + _username + '\n' + _url + '\n' open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'w')\
+ _notes) .writelines(optimized_edit([_password, _username, _url, _notes], None, -1))
print('\n\u001b[1mentry preview:\u001b[0m')
entry_reader(f"{tmp_dir}{_shm_folder}/{_shm_entry}")
encrypt(_shm_folder, _shm_entry, _entry_name)
else: else:
_password = pass_gen()
_shm_folder, _shm_entry = shm_gen() _shm_folder, _shm_entry = shm_gen()
decrypt(directory + _entry_name, _shm_folder, _shm_entry, gpg) decrypt(directory + _entry_name, _shm_folder, _shm_entry, gpg)
replace_line(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 0, _password + '\n') _new_lines = optimized_edit(open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'r').readlines(), pass_gen(), 0)
open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'w').writelines(_new_lines)
remove(f"{directory}{_entry_name}.gpg") remove(f"{directory}{_entry_name}.gpg")
print('\n\u001b[1mentry preview:\u001b[0m') print('\n\u001b[1mentry preview:\u001b[0m')
entry_reader(f"{tmp_dir}{_shm_folder}/{_shm_entry}") entry_reader(f"{tmp_dir}{_shm_folder}/{_shm_entry}")
encrypt(_shm_folder, _shm_entry, _entry_name) encrypt(directory + _entry_name, _shm_folder, _shm_entry, gpg, gpg_id)
def copy_data(): # copies a specified field of an entry to the clipboard def copy_data(): # copies a specified field of an entry to the clipboard
@@ -737,7 +737,11 @@ if __name__ == "__main__":
elif argument_list[2] == 'username' or argument_list[2] == '-u' or argument_list[2] == 'password' or \ elif argument_list[2] == 'username' or argument_list[2] == '-u' or argument_list[2] == 'password' or \
argument_list[2] == '-p' or argument_list[2] == 'url' or argument_list[2] == '-l' or \ argument_list[2] == '-p' or argument_list[2] == 'url' or argument_list[2] == '-l' or \
argument_list[2] == 'note' or argument_list[2] == '-n': argument_list[2] == 'note' or argument_list[2] == '-n':
copy_data() try:
copy_data()
except IndexError:
print(f"\n\u001b[38;5;9merror: field does not exist in entry\u001b[0m\n")
s_exit(1)
else: else:
print_info() print_info()
elif argument_list[1] == 'shear' or argument_list[1] == '-rm': elif argument_list[1] == 'shear' or argument_list[1] == '-rm':
+6 -9
View File
@@ -1,4 +1,4 @@
#!/bin/python3 #!/usr/bin/env python3
# external modules # external modules
@@ -10,16 +10,13 @@ from shutil import rmtree
# utility functions # utility functions
def delete(_file_path): # deletes an entry or folder, should be run remotely via ssh def delete(_file_path): # deletes an entry or folder, should be run remotely via ssh
if _file_path.endswith('/'): try:
try: if _file_path.endswith('/'):
rmtree(f"{expanduser('~/.local/share/sshyp/')}{_file_path}") rmtree(f"{expanduser('~/.local/share/sshyp/')}{_file_path}")
except FileNotFoundError: else:
print('folder does not exist remotely')
else:
try:
remove(f"{expanduser('~/.local/share/sshyp/')}{_file_path}.gpg") remove(f"{expanduser('~/.local/share/sshyp/')}{_file_path}.gpg")
except FileNotFoundError: except FileNotFoundError:
print('file does not exist remotely') print('location does not exist remotely')
for _device_name in listdir(expanduser('~/.config/sshyp/devices')): for _device_name in listdir(expanduser('~/.config/sshyp/devices')):
open(f"{expanduser('~/.config/sshyp/deleted/')}{_file_path.replace('/', '@')}^&*{_device_name}", 'w') open(f"{expanduser('~/.config/sshyp/deleted/')}{_file_path.replace('/', '@')}^&*{_device_name}", 'w')
+48
View File
@@ -1,3 +1,51 @@
sshyp v1.1.2
the sheecrets update - patch two
this is a general polish/bugfix release
user-facing features:
- packaging support for Alpine Linux/postmarketOS
- the rename() function is no longer unnecessarily verbose
- handled exception for when the user attempts to copy an entry field that does not exist
fixes/optimizations:
- replaced shebang with "#!/usr/bin/env python3" for improved compatibility with various systems
^ does not affect Haiku packaging
- fixed the generic package not actually being compressed
- reduced lines of code used for cross-device entry deletion
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
sshyp v1.1.1
the sheecrets update - patch one
this is a polish/bug fix release that makes tweaks to the entry format (without breaking compatibility)
compatibility-breaking changes:
- none; the entry format tweaks are backward compatible with sshyp v1.0.0+
^ the new format is slightly more efficient in terms of storage space
^ if you would like to upgrade to it, run this script (after updating to v1.1.1):
https://raw.githubusercontent.com/rwinkhart/sshyp-labs/main/extra/conversion-scripts/sshyp-refresh-1.1.1%2B.py
user-facing features:
- entries (when editing or adding) are now run through the new optimized_edit() function to strip trailing new lines
and ensure the format of the entries is fully compatible with all of sshyp's functions
fixes:
- when adding a note to an entry, there is no longer a chance the first note line will be added as a url
if the entry is using an older format/pass format
- the gpg auto-generation file temporarily created by sshyp no longer includes extra spaces
^ seems to serve no functional purpose - fixed for the sake of polish
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
sshyp v1.1.0 sshyp v1.1.0
the sheecrets update the sheecrets update
+1 -1
View File
@@ -1,4 +1,4 @@
.TH sshyp 1 "14 July 2022" "v1.1.0" "sshyp man page" .TH sshyp 1 "27 August 2022" "v1.1.2" "sshyp man page"
.SH NAME .SH NAME
sshyp \- A very simple self-hosted, synchronized password manager for UNIX(-like) systems. Alternative to (and compatible with) pass/password-store. sshyp \- A very simple self-hosted, synchronized password manager for UNIX(-like) systems. Alternative to (and compatible with) pass/password-store.
.SH SYNOPSIS .SH SYNOPSIS
+41 -25
View File
@@ -3,12 +3,13 @@
# This script packages sshyp (from source) for various UNIX(-like) environments. # This script packages sshyp (from source) for various UNIX(-like) environments.
# Dependencies (Arch Linux): dpkg (packaging for Debian/Termux), freebsd-pkg (packaging for FreeBSD) # Dependencies (Arch Linux): dpkg (packaging for Debian/Termux), freebsd-pkg (packaging for FreeBSD)
# Dependencies (Fedora) (can only package for self): rpmdevtools # Dependencies (Fedora) (can only package for self): rpmdevtools
# Dependencies (Alpine): xz (not part of a basic installation, needed for generic package creation and unpacking for abuild), alpine-sdk (required to build the .apk file from the generated APKBUILD), bash
# NOTE It is recommended to instead use the latest officially packaged and tagged release. # NOTE It is recommended to instead use the latest officially packaged and tagged release.
echo -e '\nOptions (please enter the number only):' echo -e '\nOptions (please enter the number only):'
echo -e '\nPackage Formats:\n\n1. Haiku\n2. Debian&Ubuntu Linux\n3. Fedora Linux\n4. FreeBSD\n5. Termux\n6. Generic (used for PKGBUILD/APKBUILD)' echo -e '\nPackage Formats:\n\n1. Haiku\n2. Debian&Ubuntu Linux\n3. Fedora Linux\n4. FreeBSD\n5. Termux\n6. Generic (used for PKGBUILD/APKBUILD)'
echo -e '\nBuild Scripts:\n\n7. Arch Linux (PKGBUILD)' echo -e '\nBuild Scripts:\n\n7. Arch Linux (PKGBUILD)\n8. Alpine Linux (APKBUILD)'
echo -e '\nOther:\n\n8. All (generates all distribution packages (excluding Haiku and Fedora, as these must be packaged on their respective distributions) and build scripts)\n' echo -e '\nOther:\n\n9. All (generates all distribution packages (excluding Haiku, Fedora, and Alpine, as these must be packaged on their respective distributions) and build scripts)\n'
read -n 1 -r -p "Distribution: " distro read -n 1 -r -p "Distribution: " distro
echo -e '\n\nThe value entered in this field will only affect the version reported to the package manager. The latest source is used regardless.\n' echo -e '\n\nThe value entered in this field will only affect the version reported to the package manager. The latest source is used regardless.\n'
@@ -17,16 +18,8 @@ read -r -p "Version number: " version
echo -e '\nThe value entered in this field will only affect the revision number for build scripts.\n' echo -e '\nThe value entered in this field will only affect the revision number for build scripts.\n'
read -r -p "Revision number: " revision read -r -p "Revision number: " revision
if [ "$distro" == "7" ] || [ "$distro" == "8" ]; then if [ "$distro" == "7" ] || [ "$distro" == "8" ] || [ "$distro" == "9" ]; then
echo -e '\nOptions (please enter the number only):' source='https://github.com/rwinkhart/sshyp/releases/download/v$pkgver/sshyp-$pkgver.tar.xz'
echo -e '\n1. GitHub Release Tag\n2. Local\n'
read -r -p "Source (for build scripts): " source
if [ "$source" == "1" ]; then
source='https://github.com/rwinkhart/sshyp/releases/download/v$pkgver/sshyp-$pkgver.tar.xz'
else
source=local://sshyp-"$version".tar.xz
fi
fi fi
mkdir -p packages mkdir -p packages
@@ -61,6 +54,9 @@ urls {
} }
" > packages/haikutemp/.PackageInfo " > packages/haikutemp/.PackageInfo
cp -r bin packages/haikutemp/ cp -r bin packages/haikutemp/
sed -i '1 s/.*/#!\/bin\/env\ python3/' packages/haikutemp/bin/sshync.py
sed -i '1 s/.*/#!\/bin\/env\ python3/' packages/haikutemp/bin/sshyp.py
sed -i '1 s/.*/#!\/bin\/env\ python3/' packages/haikutemp/bin/sshypRemote.py
ln -s /bin/sshyp.py packages/haikutemp/bin/sshyp ln -s /bin/sshyp.py packages/haikutemp/bin/sshyp
cp -r share/doc/sshyp/ packages/haikutemp/documentation/packages/ cp -r share/doc/sshyp/ packages/haikutemp/documentation/packages/
cp -r share/licenses/sshyp/ packages/haikutemp/documentation/packages/ cp -r share/licenses/sshyp/ packages/haikutemp/documentation/packages/
@@ -75,7 +71,7 @@ urls {
echo -e "\nHaiku packaging complete.\n" echo -e "\nHaiku packaging complete.\n"
fi fi
if [ "$distro" == "2" ] || [ "$distro" == "8" ]; then if [ "$distro" == "2" ] || [ "$distro" == "9" ]; then
echo -e '\nPackaging for Debian...\n' echo -e '\nPackaging for Debian...\n'
mkdir -p packages/debiantemp/sshyp_"$version"-"$revision"_all/{DEBIAN,usr/share/man/man1} mkdir -p packages/debiantemp/sshyp_"$version"-"$revision"_all/{DEBIAN,usr/share/man/man1}
echo "Package: sshyp echo "Package: sshyp
@@ -99,7 +95,7 @@ Installed-Size: 185
echo -e "\nDebian packaging complete.\n" echo -e "\nDebian packaging complete.\n"
fi fi
if [ "$distro" == "5" ] || [ "$distro" == "8" ]; then if [ "$distro" == "5" ] || [ "$distro" == "9" ]; then
echo -e '\nPackaging for Termux...\n' echo -e '\nPackaging for Termux...\n'
mkdir -p packages/termuxtemp/sshyp_"$version"-"$revision"_all_termux/{data/data/com.termux/files/usr/share/man/man1,DEBIAN} mkdir -p packages/termuxtemp/sshyp_"$version"-"$revision"_all_termux/{data/data/com.termux/files/usr/share/man/man1,DEBIAN}
echo "Package: sshyp echo "Package: sshyp
@@ -123,7 +119,7 @@ Installed-Size: 185
echo -e "\nTermux packaging complete.\n" echo -e "\nTermux packaging complete.\n"
fi fi
if [ "$distro" == "3" ] || [ "$distro" == "4" ] || [ "$distro" == "6" ] || [ "$distro" == "7" ] || [ "$distro" == "8" ]; then if [ "$distro" == "3" ] || [ "$distro" == "4" ] || [ "$distro" == "6" ] || [ "$distro" == "7" ] || [ "$distro" == "8" ] || [ "$distro" == "9" ]; then
echo -e '\nPackaging as generic...\n' echo -e '\nPackaging as generic...\n'
mkdir -p packages/generictemp/usr/share/man/man1 mkdir -p packages/generictemp/usr/share/man/man1
cp -r bin packages/generictemp/usr/ cp -r bin packages/generictemp/usr/
@@ -131,7 +127,7 @@ if [ "$distro" == "3" ] || [ "$distro" == "4" ] || [ "$distro" == "6" ] || [ "$d
cp -r share packages/generictemp/usr/ cp -r share packages/generictemp/usr/
cp extra/manpage packages/generictemp/usr/share/man/man1/sshyp.1 cp extra/manpage packages/generictemp/usr/share/man/man1/sshyp.1
gzip packages/generictemp/usr/share/man/man1/sshyp.1 gzip packages/generictemp/usr/share/man/man1/sshyp.1
tar -C packages/generictemp -cvf packages/sshyp-"$version".tar.xz usr/ tar -C packages/generictemp -cvJf packages/sshyp-"$version".tar.xz usr/
rm -rf packages/generictemp rm -rf packages/generictemp
sha512="$(sha512sum packages/sshyp-"$version".tar.xz | awk '{print $1;}')" sha512="$(sha512sum packages/sshyp-"$version".tar.xz | awk '{print $1;}')"
echo -e "\nsha512 sum:\n$sha512" echo -e "\nsha512 sum:\n$sha512"
@@ -177,11 +173,10 @@ rm -rf ~/rpmbuild
echo -e "\nFedora packaging complete.\n" echo -e "\nFedora packaging complete.\n"
fi fi
if [ "$distro" == "4" ] || [ "$distro" == "8" ]; then if [ "$distro" == "4" ] || [ "$distro" == "9" ]; then
echo -e '\nPackaging for FreeBSD...\n' echo -e '\nPackaging for FreeBSD...\n'
mkdir -p packages/FreeBSDtemp/bin mkdir -p packages/FreeBSDtemp/bin
tar xf packages/sshyp-"$version".tar.xz -C packages/FreeBSDtemp tar xf packages/sshyp-"$version".tar.xz -C packages/FreeBSDtemp
ln -s /usr/local/bin/python3 packages/FreeBSDtemp/bin/python3
echo "name: sshyp echo "name: sshyp
version: \""$version"\" version: \""$version"\"
abi = \"FreeBSD:13:*\"; abi = \"FreeBSD:13:*\";
@@ -207,8 +202,7 @@ prefix: /
}, },
}, },
" > packages/FreeBSDtemp/+MANIFEST " > packages/FreeBSDtemp/+MANIFEST
echo "/bin/python3 echo "/usr/bin/sshync.py
/usr/bin/sshync.py
/usr/bin/sshyp /usr/bin/sshyp
/usr/bin/sshyp.py /usr/bin/sshyp.py
/usr/bin/sshypRemote.py /usr/bin/sshypRemote.py
@@ -221,10 +215,9 @@ rm -rf packages/FreeBSDtemp
echo -e "\nFreeBSD packaging complete.\n" echo -e "\nFreeBSD packaging complete.\n"
fi fi
if [ "$distro" == "7" ] || [ "$distro" == "8" ]; then if [ "$distro" == "7" ] || [ "$distro" == "9" ]; then
echo -e '\nGenerating PKGBUILD...' echo -e '\nGenerating PKGBUILD...'
echo "# Maintainer: Randall Winkhart <idgr at tutanota dot com> echo "# Maintainer: Randall Winkhart <idgr at tutanota dot com>
pkgname=sshyp pkgname=sshyp
pkgver="$version" pkgver="$version"
pkgrel="$revision" pkgrel="$revision"
@@ -233,15 +226,38 @@ url='https://github.com/rwinkhart/sshyp'
arch=('any') arch=('any')
license=('GPL3') license=('GPL3')
depends=(python gnupg openssh xclip wl-clipboard) depends=(python gnupg openssh xclip wl-clipboard)
source=(\""$source"\") source=(\""$source"\")
sha512sums=('"$sha512"') sha512sums=('"$sha512"')
package() { package() {
tar xf sshyp-"\"\$pkgver\"".tar.xz -C "\"\${pkgdir}\"" tar xf sshyp-"\"\$pkgver\"".tar.xz -C "\"\${pkgdir}\""
} }
" > packages/PKGBUILD " > packages/PKGBUILD
echo -e "\nPKGBUILD generated.\n" echo -e "\nPKGBUILD generated.\n"
fi fi
if [ "$distro" == "8" ] || [ "$distro" == "9" ]; then
echo -e '\nGenerating APKBUILD...'
echo "# Maintainer: Randall Winkhart <idgr@tutanota.com>
pkgname=sshyp
pkgver="$version"
pkgrel="$((revision-1))"
pkgdesc='A light-weight, self-hosted, synchronized password manager'
options=!check
url='https://github.com/rwinkhart/sshyp'
arch='noarch'
license='GPL-3.0-or-later'
depends='python3 gnupg openssh xclip wl-clipboard'
source=\""$source"\"
package() {
mkdir -p "\"\$pkgdir\""
cp -r "\"\$srcdir/usr/"\" "\"\$pkgdir\""
}
sha512sums=\"
"$sha512' 'sshyp-\"\$pkgver\".tar.xz"
\"
" > packages/APKBUILD
echo -e "\nAPKBUILD generated.\n"
fi
+11 -26
View File
@@ -1,36 +1,21 @@
sshyp v1.1.0 sshyp v1.1.2
the sheecrets update the sheecrets update - patch two
the main focus of this release was adding extension support (particularly for sshyp-mfa) this is a general polish/bugfix release
and cleaning up the configuration experience
compatibility-breaking changes:
- the entry directory has been moved from ~/.password-pasture to ~/.local/share/sshyp
as a means of complying with the XDG base directory spec
^ this requires the user to move their entry directory to the new location manually
^ if this is not done, sshyp will not be able to find entries made prior to v1.1.0
- due to a new configuration option (preferred text editor), 'sshyp tweak' must be run after updating
user-facing features: user-facing features:
- extension support - packaging support for Alpine Linux/postmarketOS
^ some of sshyp's critical functions can now be imported into other programs to extend - the rename() function is no longer unnecessarily verbose
upon sshyp's functionality - handled exception for when the user attempts to copy an entry field that does not exist
^ the first usecase of this is sshyp-mfa, which can be found at https://github.com/rwinkhart/sshyp-labs
- a new configuration experience
^ the 'sshyp tweak' menu has been made much more readable, and now the automatically generated
gpg key has its id automatically input, making the process easier for the user
- customizable text editor
^ the text editor used for editing notes can now be set to any editor preferred by the user
^ this means that nano was dropped as a dependency
fixes: fixes/optimizations:
- to avoid exceptions on server devices, all arguments (apart from 'tweak') have been disabled on servers - replaced shebang with "#!/usr/bin/env python3" for improved compatibility with various systems
- fixed entry readout not printing blank lines between fields under certain conditions ^ does not affect Haiku packaging
- various optimizations - fixed the generic package not actually being compressed
- reduced lines of code used for cross-device entry deletion
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>