Compare commits

..
9 Commits
Author SHA1 Message Date
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
4 changed files with 103 additions and 78 deletions
+62 -55
View File
@@ -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.1'
'\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')
@@ -460,7 +476,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 +488,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
@@ -513,7 +529,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 +539,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 +583,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
+27
View File
@@ -1,3 +1,30 @@
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 "21 July 2022" "v1.1.1" "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
+13 -22
View File
@@ -1,36 +1,27 @@
sshyp v1.1.0 sshyp v1.1.1
the sheecrets update the sheecrets update - patch one
the main focus of this release was adding extension support (particularly for sshyp-mfa) this is a polish/bug fix release that makes tweaks to the entry format (without breaking compatibility)
and cleaning up the configuration experience
compatibility-breaking changes: compatibility-breaking changes:
- the entry directory has been moved from ~/.password-pasture to ~/.local/share/sshyp - none; the entry format tweaks are backward compatible with sshyp v1.0.0+
as a means of complying with the XDG base directory spec ^ the new format is slightly more efficient in terms of storage space
^ this requires the user to move their entry directory to the new location manually ^ if you would like to upgrade to it, run this script (after updating to v1.1.1):
^ if this is not done, sshyp will not be able to find entries made prior to v1.1.0 https://raw.githubusercontent.com/rwinkhart/sshyp-labs/main/extra/conversion-scripts/sshyp-refresh-1.1.1%2B.py
- due to a new configuration option (preferred text editor), 'sshyp tweak' must be run after updating
user-facing features: user-facing features:
- extension support - entries (when editing or adding) are now run through the new optimized_edit() function to strip trailing new lines
^ some of sshyp's critical functions can now be imported into other programs to extend and ensure the format of the entries is fully compatible with all of sshyp's functions
upon sshyp's functionality
^ 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:
- to avoid exceptions on server devices, all arguments (apart from 'tweak') have been disabled on servers - when adding a note to an entry, there is no longer a chance the first note line will be added as a url
- fixed entry readout not printing blank lines between fields under certain conditions if the entry is using an older format/pass format
- various optimizations - 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
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>