Switched to .INI config format, merged config files, finished adding functionality to new config menus

Former-commit-id: b5e877be47a49e967ced792156deb4f61841fb5e
Former-commit-id: c60df212fe964f089e246d39b3dbeaf28c006174
This commit is contained in:
2023-05-13 19:11:38 -04:00
parent 60d3a674c4
commit bdedc98494
3 changed files with 157 additions and 111 deletions
+12 -16
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
from os import listdir, remove, walk
from os.path import expanduser, isdir, getmtime, join
from os.path import expanduser, isdir, isfile, getmtime, join
from subprocess import CalledProcessError, PIPE, run
from sys import exit as s_exit
home = expanduser("~")
@@ -118,25 +118,21 @@ def sort_titles_mods(_list_1, _list_2):
return _title_list_2_sorted, _mod_list_2_sorted
# creates a sshync job profile
def make_profile(_profile_dir, _local_dir, _remote_dir, _identity, _ip, _port, _user):
open(_profile_dir, 'w').write(f"{_user}\n{_ip}\n{_port}\n{_local_dir}\n{_remote_dir}\n{_identity}\n")
# returns a list of data read from a sshync job profile
def get_profile(_profile_dir):
try:
_profile_data = open(_profile_dir).readlines()
except (FileNotFoundError, IndexError):
from configparser import ConfigParser
_profile_data = ConfigParser()
if isfile(_profile_dir):
_profile_data.read(_profile_dir)
else:
print('\n\u001b[38;5;9merror: the profile does not exist or is corrupted\u001b[0m\n')
_profile_data = None
s_exit(2)
_user = _profile_data[0].rstrip()
_ip = _profile_data[1].rstrip()
_port = _profile_data[2].rstrip()
_local_dir = _profile_data[3].rstrip()
_remote_dir = _profile_data[4].rstrip()
_identity = _profile_data[5].rstrip()
_user = _profile_data.get('SSHYNC', 'user')
_ip = _profile_data.get('SSHYNC', 'ip')
_port = _profile_data.get('SSHYNC', 'port')
_local_dir = _profile_data.get('SSHYNC', 'local_dir')
_remote_dir = _profile_data.get('SSHYNC', 'remote_dir')
_identity = _profile_data.get('SSHYNC', 'identity_file')
_client_device_id = listdir(f"{home}/.config/sshyp/devices")[0].rstrip()
return _user, _ip, _port, _local_dir, _remote_dir, _identity, _client_device_id
+35 -28
View File
@@ -1,10 +1,11 @@
#!/usr/bin/env python3
from configparser import ConfigParser, NoSectionError
from os import chmod, environ, listdir, remove, walk
from os.path import exists, expanduser, isdir, isfile, realpath
from pathlib import Path
from random import randint
from shutil import move, rmtree
from sshync import delete as offline_delete, run_profile, get_profile
from sshync import delete as offline_delete, run_profile
from subprocess import CalledProcessError, DEVNULL, PIPE, run
from sys import argv, exit as s_exit
# PORT START UNAME-IMPORT
@@ -162,7 +163,7 @@ def decrypt(_entry_dir, _shm_folder, _shm_entry, _quick_pass,
# call decrypt() based on quick-unlock status
def determine_decrypt(_entry_dir, _shm_folder, _shm_entry):
if quick_unlock_enabled == 'yes':
if quick_unlock_enabled == 'true':
decrypt(_entry_dir, _shm_folder, _shm_entry, whitelist_verify(port, username_ssh, ip, client_device_id))
else:
decrypt(_entry_dir, _shm_folder, _shm_entry, False)
@@ -201,7 +202,10 @@ def edit_note(_shm_folder, _shm_entry, _lines):
# attempts to connect to the user's server via ssh to register the device for syncing
def copy_id_check(_port, _username_ssh, _ip, _client_device_id):
def copy_id_check(_port, _username_ssh, _ip, _client_device_id, _sshyp_data):
from stweak import write_config
if not _sshyp_data.has_section('CLIENT-ONLINE'):
_sshyp_data.add_section('CLIENT-ONLINE')
try:
run(['ssh', '-o', 'ConnectTimeout=3', '-i', f"{home}/.ssh/sshyp", '-p', _port, f"{_username_ssh}@{_ip}",
f'python3 -c \'from pathlib import Path; Path("/home/{_username_ssh}/.config/sshyp/devices/'
@@ -210,9 +214,11 @@ def copy_id_check(_port, _username_ssh, _ip, _client_device_id):
print('\n\u001b[38;5;9mwarning: ssh connection could not be made - ensure the public key (~/.ssh/sshyp.pub) is '
'registered on the remote server and that the entered ip, port, and username are correct\n\nsyncing '
'functionality will be disabled until this is addressed\u001b[0m\n')
open(f"{home}/.config/sshyp/ssh-error", 'w').write('1')
_sshyp_data.set('CLIENT-ONLINE', 'ssh_error', '1')
write_config(_sshyp_data)
return True
open(f"{home}/.config/sshyp/ssh-error", 'w').write('0')
_sshyp_data.set('CLIENT-ONLINE', 'ssh_error', '0')
write_config(_sshyp_data)
return False
@@ -365,7 +371,7 @@ def sync():
chmod(_path, 0o700)
for _file in _files:
chmod(_root + '/' + _file, 0o600)
run_profile(f"{home}/.config/sshyp/sshyp.sshync", silent_sync)
run_profile(f"{home}/.config/sshyp/sshyp.ini", silent_sync)
# PORT START WHITELIST-SERVER
@@ -674,7 +680,6 @@ def remove_data():
# checks extension config files for matches to argument, runs extensions
def extension_runner():
from configparser import ConfigParser
_output_com, _extension_dir = None, realpath(__file__).rsplit('/', 1)[0] + '/extensions/'
if isdir(_extension_dir):
for _extension in listdir(_extension_dir):
@@ -722,31 +727,30 @@ if __name__ == "__main__":
# import saved userdata
tmp_dir = f"{home}/.config/sshyp/tmp/"
try:
sshyp_data = open(f"{home}/.config/sshyp/sshyp-data").readlines()
device_type = sshyp_data[0].rstrip()
sshyp_data = ConfigParser()
sshyp_data.read(f"{home}/.config/sshyp/sshyp.ini")
device_type = sshyp_data.get('GENERAL', 'device_type')
if device_type == 'client':
directory = f"{home}/.local/share/sshyp/"
gpg_id = sshyp_data[1].rstrip()
editor = sshyp_data[2].rstrip()
quick_unlock_enabled = sshyp_data[3].rstrip()
if isfile(f"{home}/.config/sshyp/sshyp.sshync"):
ssh_info = get_profile(f"{home}/.config/sshyp/sshyp.sshync")
username_ssh = ssh_info[0].rstrip()
ip = ssh_info[1].rstrip()
port = ssh_info[2].rstrip()
directory_ssh = str(ssh_info[4].rstrip())
client_device_id = listdir(f"{home}/.config/sshyp/devices")[0].rstrip()
ssh_error = int(open(f"{home}/.config/sshyp/ssh-error").read().rstrip())
if ssh_error == 1:
ssh_error = copy_id_check(port, username_ssh, ip, client_device_id)
else:
ssh_error = False
else:
gpg_id = sshyp_data.get('CLIENT-GENERAL', 'gpg_id')
editor = sshyp_data.get('CLIENT-GENERAL', 'text_editor')
offline_mode_enabled = sshyp_data.get('CLIENT-GENERAL', 'offline_mode_enabled')
if offline_mode_enabled == 'true':
ssh_error = True
except (FileNotFoundError, IndexError):
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
else:
quick_unlock_enabled = sshyp_data.get('CLIENT-ONLINE', 'quick_unlock_enabled')
username_ssh = sshyp_data.get('SSHYNC', 'user')
ip = sshyp_data.get('SSHYNC', 'ip')
port = sshyp_data.get('SSHYNC', 'port')
directory_ssh = sshyp_data.get('SSHYNC', 'remote_dir')
client_device_id = listdir(f"{home}/.config/sshyp/devices")[0]
ssh_error = int(sshyp_data.get('CLIENT-ONLINE', 'ssh_error'))
if ssh_error == 1:
ssh_error = copy_id_check(port, username_ssh, ip, client_device_id, sshyp_data)
except (FileNotFoundError, NoSectionError):
print(f"\n{73*'!'}")
print("not all necessary configurations have been made - please run 'sshyp init'")
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
print(f"{73*'!'}\n")
s_exit(1)
else:
from stweak import initial_setup
@@ -814,6 +818,9 @@ if __name__ == "__main__":
elif arguments[1] == 'setup':
success_flag = True
whitelist_setup()
elif arg_count == 1 and arguments[0] == 'tweak':
from stweak import global_menu
global_menu(False)
elif arg_count > 2 and arguments[1] in ('add', 'del'):
success_flag = True
whitelist_manage(arguments[2])
+110 -67
View File
@@ -1,5 +1,6 @@
#!/usr/bin/env python3
from curses import A_REVERSE, KEY_DOWN, KEY_UP, cbreak, curs_set, endwin, initscr, newwin, noecho, nocbreak
from configparser import ConfigParser
from curses import A_REVERSE, echo, KEY_DOWN, KEY_UP, cbreak, curs_set, endwin, initscr, newwin, noecho, nocbreak
from curses.textpad import rectangle, Textbox
from os import environ, listdir, remove, symlink
from os.path import exists, expanduser, isfile
@@ -7,13 +8,23 @@ from pathlib import Path
from random import randint
from re import sub
from shutil import get_terminal_size, which
from sshync import make_profile
from sshyp import copy_id_check, string_gen
from subprocess import PIPE, run
# PORT START UNAME-IMPORT
from os import uname
# PORT END UNAME-IMPORT
home, stdscr, sshyp_data = expanduser("~"), initscr(), []
home, stdscr, sshyp_data = expanduser("~"), initscr(), ConfigParser()
if isfile(f"{home}/.config/sshyp/sshyp.ini"):
_exists_flag = True
sshyp_data.read(f"{home}/.config/sshyp/sshyp.ini")
else:
_exists_flag = False
# writes data stored in ConfigParser to the correct config file
def write_config(_sshyp_data=sshyp_data):
with open(f"{home}/.config/sshyp/sshyp.ini", 'w') as configfile:
_sshyp_data.write(configfile)
# creates a radio selection between the provided options
@@ -58,15 +69,18 @@ def curses_text(_pretext):
return _box.gather().strip()
# cleanly exit curses
def curses_terminate():
# cleanly exit curses and optionally prints an exit message
def curses_terminate(_term_message):
nocbreak()
echo()
endwin()
if _term_message:
print(_term_message)
# device+sync type selection
def install_type():
_offline_mode = False
_offline_mode = 'false'
# PORT START TWEAK-DEVTYPE
_install_type = curses_radio(('server', 'client (ssh-synchronized)', 'client (offline)'),
'device + sync type configuration')
@@ -74,15 +88,18 @@ def install_type():
_dev_type = 'server'
Path(f"{home}/.config/sshyp/deleted").mkdir(mode=0o700, exist_ok=True)
Path(f"{home}/.config/sshyp/whitelist").mkdir(mode=0o700, exist_ok=True)
curses_terminate()
print(f"\nmake sure the ssh service is running and properly configured")
curses_terminate('\nmake sure the ssh service is running and properly configured')
else:
_dev_type = 'client'
if _install_type == 2:
_offline_mode = True
if isfile(f"{home}/.config/sshyp/sshyp.sshync"):
remove(f"{home}/.config/sshyp/sshyp.sshync")
Path(f"{home}/.local/share/sshyp").mkdir(mode=0o700, parents=True, exist_ok=True)
_offline_mode = 'true'
if not sshyp_data.has_section('CLIENT-GENERAL'):
sshyp_data.add_section('CLIENT-GENERAL')
sshyp_data.set('CLIENT-GENERAL', 'offline_mode_enabled', _offline_mode)
if not sshyp_data.has_section('GENERAL'):
sshyp_data.add_section('GENERAL')
sshyp_data.set('GENERAL', 'device_type', _dev_type)
write_config()
# PORT END TWEAK-DEVTYPE
return _dev_type, _offline_mode
@@ -108,14 +125,35 @@ def gpg_config():
run(['gpg', '--batch', '--generate-key', f"{home}/.config/sshyp/gpg-gen"])
remove(f"{home}/.config/sshyp/gpg-gen")
_gpg_id = run(['gpg', '-k'], stdout=PIPE, text=True).stdout.splitlines()[-3].strip()
return _gpg_id
# lock file generation
if isfile(f"{home}/.config/sshyp/lock.gpg"):
remove(f"{home}/.config/sshyp/lock.gpg")
open(f"{home}/.config/sshyp/lock", 'w')
run(['gpg', '-qr', _gpg_id, '-e', f"{home}/.config/sshyp/lock"])
remove(f"{home}/.config/sshyp/lock")
if not sshyp_data.has_section('CLIENT-GENERAL'):
sshyp_data.add_section('CLIENT-GENERAL')
sshyp_data.set('CLIENT-GENERAL', 'gpg_id', _gpg_id)
write_config()
# text editor configuration
def editor_config():
_editor = curses_text('enter the name of your preferred text editor:\n\n\n\n\n'
'(ctrl+g/enter to confirm)\n\nexample input: vim')
return _editor
def editor_config(_env_mode):
if _env_mode:
# set default text editor to value of EDITOR environment variable, otherwise default to nano
if 'EDITOR' in environ:
_editor = environ['EDITOR']
else:
_editor = 'nano'
else:
_editor = curses_text('enter the name of your preferred text editor:\n\n\n\n\n'
'(ctrl+g/enter to confirm)\n\nexample input: vim')
if not sshyp_data.has_section('CLIENT-GENERAL'):
sshyp_data.add_section('CLIENT-GENERAL')
sshyp_data.set('CLIENT-GENERAL', 'text_editor', _editor)
write_config()
# ssh+sshync configuration
@@ -129,10 +167,15 @@ def ssh_config():
_username_ssh = _uiport_split[0]
_iport = _uiport_split[1].rsplit(':', 1)
# sshync profile generation
make_profile(f"{home}/.config/sshyp/sshyp.sshync",
f"{home}/.local/share/sshyp/", f"/home/{_username_ssh}/.local/share/sshyp/",
f"{home}/.ssh/sshyp", _iport[0], _iport[1], _username_ssh)
if not sshyp_data.has_section('SSHYNC'):
sshyp_data.add_section('SSHYNC')
sshyp_data.set('SSHYNC', 'user', _username_ssh)
sshyp_data.set('SSHYNC', 'ip', _iport[0])
sshyp_data.set('SSHYNC', 'port', _iport[1])
sshyp_data.set('SSHYNC', 'local_dir', f"{home}/.local/share/sshyp/")
sshyp_data.set('SSHYNC', 'remote_dir', f"/home/{_username_ssh}/.local/share/sshyp/")
sshyp_data.set('SSHYNC', 'identity_file', f"{home}/.ssh/sshyp")
write_config()
return _iport[1], _username_ssh, _iport[0]
@@ -148,31 +191,36 @@ def dev_id_config(_ip, _username_ssh, _port):
_device_id = _device_id_prefix + '-' + _device_id_suffix
open(f"{home}/.config/sshyp/devices/{_device_id}", 'w')
# test server connection and attempt to register device id
copy_id_check(_ip, _username_ssh, _port, _device_id)
return _device_id
copy_id_check(_ip, _username_ssh, _port, _device_id, sshyp_data)
# quick-unlock configuration
def quick_unlock_config():
_quick_unlock_sel = curses_radio(('yes', 'no'), 'enable quick-unlock?')
if _quick_unlock_sel == 0:
_enabled = 'yes'
def quick_unlock_config(_default):
if _default:
_enabled = 'false'
else:
_enabled = 'no'
return _enabled
_quick_unlock_sel = curses_radio(('yes', 'no'), 'enable quick-unlock?')
if _quick_unlock_sel == 0:
_enabled = 'true'
else:
_enabled = 'false'
if not sshyp_data.has_section('CLIENT-ONLINE'):
sshyp_data.add_section('CLIENT-ONLINE')
sshyp_data.set('CLIENT-ONLINE', 'quick_unlock_enabled', _enabled)
write_config()
# runs secondary configuration menu - clients only
# runs secondary configuration menu
def global_menu(_post_setup):
# curses initialization
noecho()
cbreak()
stdscr.keypad(True)
_options, _choice = [], 4
_options, _choice, _term_message = [], 4, False
try:
if not _post_setup:
_options.extend(['change device/synchronization types', 'change gpg key', 're-configure ssh',
_options.extend(['change device/synchronization types', 'change gpg key', 're-configure ssh(ync)',
'change device name'])
_message, _choice = 'all configuration options:', 0
_options.extend(['[OPTIONAL, RECOMMENDED] set custom text editor',
@@ -183,28 +231,40 @@ def global_menu(_post_setup):
_choice += curses_radio(_options, _message)
if _choice == 0:
install_type()
_dev_sync_types = install_type()
# if not running in server or offline mode and a sshync config has not been made
if _dev_sync_types[0] != 'server' and _dev_sync_types[1] != 'true' and not sshyp_data.has_section('SSHYNC'):
_ip, _username_ssh, _port = ssh_config()
# if no device id is set
if not listdir(f"{home}/.config/sshyp/devices"):
dev_id_config(_ip, _username_ssh, _port)
elif _choice == 1:
gpg_config()
elif _choice == 2:
ssh_config()
elif _choice == 3:
dev_id_config()
dev_id_config(sshyp_data.get('SSHYNC', 'ip'), sshyp_data.get('SSHYNC', 'user'),
sshyp_data.get('SSHYNC', 'port'))
elif _choice == 4:
editor_config()
editor_config(False)
elif _choice == 5:
quick_unlock_config()
quick_unlock_config(False)
else:
pass
curses_terminate()
curses_terminate(_term_message)
except KeyboardInterrupt:
curses_terminate()
curses_terminate(False)
# runs initial configuration wizard
def initial_setup():
# config directory creation
# required directory creation
Path(f"{home}/.config/sshyp/devices").mkdir(mode=0o700, parents=True, exist_ok=True)
Path(f"{home}/.local/share/sshyp").mkdir(mode=0o700, parents=True, exist_ok=True)
# removal of old config files
if _exists_flag:
sshyp_data.clear()
# temporary file symlink creation
if not exists(f"{home}/.config/sshyp/tmp"):
@@ -218,6 +278,7 @@ def initial_setup():
# PORT END UNAME-TMP
# curses initialization
noecho()
cbreak()
stdscr.keypad(True)
@@ -225,41 +286,33 @@ def initial_setup():
try:
# device+sync type selection
_dev_sync_types = install_type()
sshyp_data.append(_dev_sync_types[0])
if _dev_sync_types[0] == 'client':
# gpg configuration
sshyp_data.append(gpg_config())
gpg_config()
# lock file generation (requires gpg configuration)
if isfile(f"{home}/.config/sshyp/lock.gpg"):
remove(f"{home}/.config/sshyp/lock.gpg")
open(f"{home}/.config/sshyp/lock", 'w')
run(['gpg', '-qr', str(sshyp_data[1]), '-e', f"{home}/.config/sshyp/lock"])
remove(f"{home}/.config/sshyp/lock")
# text editor configuration (automated)
editor_config(True)
# set default text editor to value of EDITOR environment variable, otherwise default to nano
if 'EDITOR' in environ:
sshyp_data.append(environ['EDITOR'])
else:
sshyp_data.append('nano')
# quick-unlock configuration (disabled by default)
quick_unlock_config(True)
# online (synchronized mode) configuration
if not _dev_sync_types[1]:
if _dev_sync_types[1] != 'true':
# ssh+sshync configuration
_ip, _username_ssh, _port = ssh_config()
# device id configuration
_device_id = dev_id_config(_ip, _username_ssh, _port)
dev_id_config(_ip, _username_ssh, _port)
# cleanly exit curses
curses_terminate()
curses_terminate(False)
else:
# cleanly exit curses
curses_terminate()
curses_terminate(False)
# PORT START CLIPTOOL
# check for clipboard tool and display warning if missing
@@ -274,18 +327,8 @@ def initial_setup():
f'"{_clipboard_package}" is installed\u001b[0m')
# PORT END CLIPTOOL
# write main config file (sshyp-data)
with open(f"{home}/.config/sshyp/sshyp-data", 'w') as _config_file:
_lines = 0
for _item in sshyp_data:
_lines += 1
_config_file.write(str(_item) + '\n')
while _lines < 4:
_lines += 1
_config_file.write('n')
global_menu(True)
except KeyboardInterrupt:
# cleanly exit curses
curses_terminate()
curses_terminate(False)