mirror of
https://github.com/rwinkhart/sshyp.git
synced 2026-09-02 23:27:17 -04:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0bcf5fc0d1 | ||
|
|
ec3ee297b8 | ||
|
|
5f5ede7349 | ||
|
|
cc3fa30865 | ||
|
|
3613d3dd0c | ||
|
|
249269a3e3 | ||
|
|
c441802058 |
@@ -1,3 +1,25 @@
|
||||
sshyp v1.5.3
|
||||
01/08/2024
|
||||
|
||||
the fortified flock update - patch three
|
||||
|
||||
this release is a quick hot-fix for some bugs that were noticed after the release of v1.5.2
|
||||
|
||||
fixes/optimizations:
|
||||
|
||||
- fixed a regression with the entry list causing entries not part of a subdirectory to appear
|
||||
in-line with the entry list header
|
||||
- fixed extension group ownership under FreeBSD
|
||||
^ the "wheel" group is now used where previously the non-existent "root" group was used
|
||||
- fixed notes sometimes being appended in the wrong position after editing an incomplete entry
|
||||
- addressed flake8 suggestions (slight optimization)
|
||||
- removed unnecessary empty variable declarations
|
||||
^ these were previously included to silence PyCharm's PEP8 warnings
|
||||
^ the project is now primarily developed in VSCodium with the flake8 linter
|
||||
^ the only change to flake8 defaults in the line length limit (79->120)
|
||||
|
||||
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
|
||||
|
||||
sshyp v1.5.2
|
||||
01/07/2024
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
.TH sshyp 1 "07 January 2024" "v1.5.2" "sshyp man page"
|
||||
.TH sshyp 1 "08 January 2024" "v1.5.3" "sshyp man page"
|
||||
.SH NAME
|
||||
\fBsshyp\fR - Simple, self-hosted, synchronized password management for UNIX(-like) systems. Alternative to (and compatible with) pass/password-store.
|
||||
.SH SYNOPSIS
|
||||
|
||||
+16
-23
@@ -24,6 +24,8 @@ def entry_list_gen(_directory=f"{home}/.local/share/sshyp/"):
|
||||
_color_alternator = 1
|
||||
if _ran:
|
||||
print(f"\n\n\u001b[38;5;7;48;5;8m{_root.replace(f'{home}/.local/share/sshyp', '', 1)}/\u001b[0m")
|
||||
elif _root == f"{home}/.local/share/sshyp/" and len(_files) > 0:
|
||||
print("\n\n\u001b[38;5;7;48;5;8m/\u001b[0m")
|
||||
_char_counter = 0
|
||||
for _filename in sorted(_files):
|
||||
if _color_alternator > 0:
|
||||
@@ -50,7 +52,7 @@ def entry_reader(_decrypted_entry):
|
||||
if pass_show:
|
||||
_entry_password = f'\u001b[38;5;10m{_decrypted_entry[0]}\u001b[0m'
|
||||
else:
|
||||
_entry_password = f'\u001b[38;5;3mend command in "--show" or "-s" to view\u001b[0m'
|
||||
_entry_password = '\u001b[38;5;3mend command in "--show" or "-s" to view\u001b[0m'
|
||||
print()
|
||||
for _num in range(len(_decrypted_entry)):
|
||||
try:
|
||||
@@ -67,7 +69,7 @@ def entry_reader(_decrypted_entry):
|
||||
print('\u001b[38;5;7;48;5;8mnotes:\u001b[0m\n' + _decrypted_entry[_num])
|
||||
if _notes_flag == 1:
|
||||
try:
|
||||
_line_test = _decrypted_entry[_num + 1]
|
||||
_ = _decrypted_entry[_num + 1]
|
||||
except IndexError:
|
||||
print()
|
||||
except IndexError:
|
||||
@@ -136,17 +138,15 @@ def edit_note(_note_lines, _exit_on_match=False):
|
||||
return _new_note
|
||||
|
||||
|
||||
# encrypts an entry and cleans up the temporary files
|
||||
# encrypts an entry
|
||||
def encrypt(_entry_data, _entry_dir, _gpg_id):
|
||||
_bytes_data = '\n'.join(_entry_data).rstrip().encode()
|
||||
_encrypted_data = run(('gpg', '-qr', str(_gpg_id), '-e'), input=_bytes_data, stdout=PIPE).stdout
|
||||
open(_entry_dir + '.gpg', 'wb').write(_encrypted_data)
|
||||
|
||||
|
||||
# decrypts an entry to a temporary directory
|
||||
# decrypts an entry and returns its contents
|
||||
def decrypt(_entry_dir, _quick_verify=None, _quick_pass=None):
|
||||
_contents = None
|
||||
|
||||
# check quick-unlock status, fetch passphrase
|
||||
if _quick_verify:
|
||||
_quick_pass = whitelist_verify(port, username_ssh, ip, client_device_id, identity)
|
||||
@@ -251,13 +251,14 @@ def target_type_check(_target_name, _expected_type=True, _error=False):
|
||||
s_exit(2)
|
||||
|
||||
|
||||
# ensures an edited entry is optimized for best compatibility
|
||||
def line_edit(_lines, _edit_data, _edit_line):
|
||||
# ensures an entry has enough lines to complete an edit and optionally carries out the edit
|
||||
def line_edit(_lines, _edit_line, _edit_data=None):
|
||||
# ensure enough lines are present for edited field
|
||||
while len(_lines) < _edit_line + 1:
|
||||
_lines.append('')
|
||||
# write the edited field
|
||||
_lines[_edit_line] = _edit_data.rstrip()
|
||||
if _edit_data is not None:
|
||||
# write the edited field
|
||||
_lines[_edit_line] = _edit_data.rstrip()
|
||||
return _lines
|
||||
|
||||
|
||||
@@ -296,7 +297,7 @@ def print_info():
|
||||
}}-}}-*]{4 * ' '}`..'..'{9 * ' '}\u001b[0m♥♥♥\u001b[0m{9 * ' '}`..'..'{6 * ' '}|
|
||||
{4 * ' '}◎-◎{4 * ' '}//{3 * ' '}\\\\{10 * ' '}\u001b[38;5;9m♥\u001b[0m{10 * ' '}//{3 * ' '}\\\\{5 * ' '}/|\\""")
|
||||
print(f"{_border}{_blank}\n\u001b[38;5;7;48;5;8m\\\u001b[38;5;15;48;5;15m{18 * ' '}\u001b[38;5;15;48;5;8msshyp "
|
||||
f"version 1.5.2\u001b[38;5;15;48;5;15m{18 * ' '}\u001b[38;5;7;48;5;8m/\u001b[0m")
|
||||
f"version 1.5.3\u001b[38;5;15;48;5;15m{18 * ' '}\u001b[38;5;7;48;5;8m/\u001b[0m")
|
||||
print(f"\u001b[38;5;7;48;5;8m\\\u001b[38;5;15;48;5;15m{14 * ' '}\u001b[38;5;15;48;5;8mthe fortified flock"
|
||||
f" update\u001b[38;5;15;48;5;15m{15 * ' '}\u001b[38;5;7;48;5;8m/\u001b[0m\n{_blank}")
|
||||
print(f"\u001b[38;5;7;48;5;8m\\\u001b[38;5;15;48;5;15m{9 * ' '}\u001b[38;5;15;48;5;8mcopyright 2021-2024 ",
|
||||
@@ -471,9 +472,6 @@ def rename():
|
||||
|
||||
# edits the contents of an entry
|
||||
def edit():
|
||||
# set to avoid PEP8 warnings
|
||||
_detail, _edit_line = None, None
|
||||
|
||||
# ensure the edit target is an entry
|
||||
target_type_check(entry_name, True, True)
|
||||
|
||||
@@ -486,10 +484,10 @@ def edit():
|
||||
_detail, _edit_line = str(input('\nurl: ')), 2
|
||||
if arguments[2] in ('note', '-n'):
|
||||
_old_lines = decrypt(directory + entry_name, _quick_verify=quick_unlock_enabled)
|
||||
_new_lines = _old_lines[0:3] + edit_note(_old_lines[3:], True).split('\n')
|
||||
# pass 2 as _edit_line to simulate a full entry minus notes so that notes are appended correctly
|
||||
_new_lines = line_edit(_old_lines[0:3], 2) + edit_note(_old_lines[3:], True).split('\n')
|
||||
else:
|
||||
_new_lines = line_edit(decrypt(directory + entry_name, _quick_verify=quick_unlock_enabled), _detail,
|
||||
_edit_line)
|
||||
_new_lines = line_edit(decrypt(directory + entry_name, _quick_verify=quick_unlock_enabled), _edit_line, _detail)
|
||||
print('\n\u001b[1mentry preview:\u001b[0m')
|
||||
entry_reader(_new_lines)
|
||||
encrypt(_new_lines, directory + entry_name, gpg_id)
|
||||
@@ -497,13 +495,11 @@ def edit():
|
||||
|
||||
# generates a password for a new or an existing entry
|
||||
def gen():
|
||||
# set to avoid PEP8 warnings
|
||||
_username, _url, _notes = None, None, None
|
||||
# gen update
|
||||
if arg_count == 3 and arguments[2] in ('update', '-u'):
|
||||
# ensure the gen update target is an entry
|
||||
target_type_check(entry_name, True, True)
|
||||
_new_lines = line_edit(decrypt(directory + entry_name, _quick_verify=quick_unlock_enabled), pass_gen(), 0)
|
||||
_new_lines = line_edit(decrypt(directory + entry_name, _quick_verify=quick_unlock_enabled), 0, pass_gen())
|
||||
# gen
|
||||
else:
|
||||
# make sure the gen target does not already exist
|
||||
@@ -614,9 +610,6 @@ if __name__ == "__main__":
|
||||
# set default states
|
||||
ssh_error, success_flag, sync_flag, silent_sync, pass_show = False, False, False, False, False
|
||||
|
||||
# set to avoid PEP8 warnings
|
||||
arg_start, device_type, offline_mode_enabled = None, None, None
|
||||
|
||||
# retrieve typed argument
|
||||
arguments = argv[1:]
|
||||
arg_count = len(arguments)
|
||||
|
||||
+8
-3
@@ -478,8 +478,8 @@ def extension_downloader():
|
||||
if _choice == 1:
|
||||
# download extension files to temporary directory
|
||||
_exe_dir, _ini_dir = f"{gettempdir()}/sshyp_exe", f"{gettempdir()}/sshyp_ini"
|
||||
_ext_exe = urlretrieve(_pointer.get(_selected, 'exe'), _exe_dir)
|
||||
_ext_ini = urlretrieve(_pointer.get(_selected, 'ini'), _ini_dir)
|
||||
urlretrieve(_pointer.get(_selected, 'exe'), _exe_dir)
|
||||
urlretrieve(_pointer.get(_selected, 'ini'), _ini_dir)
|
||||
# set permissions under active user
|
||||
chmod(_exe_dir, 0o755)
|
||||
chmod(_ini_dir, 0o644)
|
||||
@@ -718,7 +718,12 @@ def wrapped_entry(_gm_device_type, _gm_top_message='configuration options:'):
|
||||
# install with privilege escalation (outside of curses)
|
||||
from tempfile import gettempdir
|
||||
_exe_dir, _ini_dir = f"{gettempdir()}/sshyp_exe", f"{gettempdir()}/sshyp_ini"
|
||||
run((_escalator, 'chown', 'root:root', _exe_dir, _ini_dir))
|
||||
# PORT START TWEAK-EXT-CHOWN
|
||||
if uname()[0] == 'FreeBSD':
|
||||
run((_escalator, 'chown', 'root:wheel', _exe_dir, _ini_dir))
|
||||
else:
|
||||
run((_escalator, 'chown', 'root:root', _exe_dir, _ini_dir))
|
||||
# PORT END TWEAK-EXT-CHOWN
|
||||
run((_escalator, 'mv', _exe_dir, f"/usr/lib/sshyp/{_ext_name}"))
|
||||
run((_escalator, 'mv', _ini_dir, f"/usr/lib/sshyp/extensions/{_ext_name}.ini"))
|
||||
else:
|
||||
|
||||
@@ -21,6 +21,7 @@ _create_generic_linux() {
|
||||
cd port-jobs
|
||||
./CLIPTOOL.py LINUX
|
||||
./CLIPBOARD.py LINUX
|
||||
./CHOWN.py
|
||||
./UNAME.py LINUX
|
||||
./COMMENTS.py ALL
|
||||
./BLANKS.py
|
||||
@@ -158,6 +159,7 @@ urls {
|
||||
./RMEXTMAN.py
|
||||
./CLIPTOOL.py
|
||||
./CLIPBOARD.py HAIKU
|
||||
./CHOWN.py
|
||||
./UNAME.py TMP
|
||||
./COMMENTS.py ALL
|
||||
./BLANKS.py
|
||||
@@ -200,6 +202,7 @@ _create_deb() {
|
||||
./CLIPBOARD.py WSL
|
||||
special=WSL-ONLY-DEBIAN
|
||||
fi
|
||||
./CHOWN.py
|
||||
./UNAME.py LINUX
|
||||
./COMMENTS.py ALL
|
||||
./BLANKS.py
|
||||
@@ -253,6 +256,7 @@ _create_termux() {
|
||||
./RMEXTMAN.py
|
||||
./CLIPTOOL.py
|
||||
./CLIPBOARD.py TERMUX
|
||||
./CHOWN.py
|
||||
./UNAME.py TERMUX
|
||||
./COMMENTS.py ALL
|
||||
./BLANKS.py
|
||||
@@ -326,6 +330,7 @@ cp -r %%{_sourcedir}/usr %%{buildroot}
|
||||
cd port-jobs
|
||||
./CLIPTOOL.py LINUX
|
||||
./CLIPBOARD.py LINUX
|
||||
./CHOWN.py
|
||||
./UNAME.py LINUX
|
||||
./COMMENTS.py ALL
|
||||
./BLANKS.py
|
||||
@@ -390,6 +395,7 @@ printf "/usr/bin/sshyp
|
||||
cd port-jobs
|
||||
./CLIPTOOL.py LINUX
|
||||
./CLIPBOARD.py BSD
|
||||
./CHOWN.py BSD
|
||||
./UNAME.py TMP
|
||||
./COMMENTS.py ALL
|
||||
./BLANKS.py
|
||||
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python3
|
||||
import re
|
||||
from sys import argv
|
||||
|
||||
# read arguments
|
||||
arguments = argv[1:]
|
||||
|
||||
# define PORT target
|
||||
string1 = '# PORT START TWEAK-EXT-CHOWN'
|
||||
string2 = '# PORT END TWEAK-EXT-CHOWN'
|
||||
|
||||
# define replacement text depending on arguments
|
||||
if len(arguments) > 0 and arguments[0] == 'BSD':
|
||||
replacement = "run((_escalator, 'chown', 'root:wheel', _exe_dir, _ini_dir))"
|
||||
else:
|
||||
replacement = "run((_escalator, 'chown', 'root:root', _exe_dir, _ini_dir))"
|
||||
|
||||
# read input file
|
||||
text = open('working/stweak.py', 'r').read()
|
||||
|
||||
# compile regex and modify text
|
||||
regex = re.compile(f"{string1}.*?{string2}", re.DOTALL)
|
||||
|
||||
# find and replace the defined PORT target
|
||||
new_text = re.sub(regex, replacement, text)
|
||||
|
||||
# write updated text
|
||||
open('working/stweak.py', 'w').write(new_text)
|
||||
Reference in New Issue
Block a user