diff --git a/src/powershell_tools/_set_admin_file.py b/src/powershell_tools/_set_admin_file.py deleted file mode 100644 index 356bbd3..0000000 --- a/src/powershell_tools/_set_admin_file.py +++ /dev/null @@ -1,14 +0,0 @@ -import subprocess - - -def set_admin_file(path) -> bool: - '''Grant full admin & system access to a path''' - ps_command = f""" - powershell - icacls {path} - /inheritance:r - /grant \"Administrators:F\" - /grant \"SYSTEM:F\" - """.replace("\n", "").replace(" ", "").strip() - result = subprocess.run(ps_command, capture_output=True) - return not result.returncode diff --git a/src/ssh/setup.py b/src/ssh/setup.py index 14c2384..c097333 100644 --- a/src/ssh/setup.py +++ b/src/ssh/setup.py @@ -1,16 +1,32 @@ import shutil import subprocess import os -from powershell_tools._set_admin_file import set_admin_file +import sys +import distutils.dir_util + +DEBUG = True + + +def run_ps(cmd: str) -> str: + ps_cmd = cmd.replace("\n", " ").replace(" ", "").strip() + if DEBUG: + print(ps_cmd) + result = subprocess.run(ps_cmd, capture_output=True) + if result.stderr and DEBUG: + print(result.stderr) + return not result.returncode def service_installed(service_name: str) -> bool: """Check installed services and compare to `service_name`""" - ps_command = f""" - powershell + ps_command = f"""powershell Get-WindowsCapability -Online | ? Name -like {service_name}* """.replace("\n", "").replace(" ", " ").strip() + if DEBUG: + print(ps_command) result = subprocess.run(ps_command, capture_output=True) + if result.stderr: + print(result.stderr) if not result.returncode: return "Installed".encode() in result.stdout @@ -18,46 +34,58 @@ def service_installed(service_name: str) -> bool: def install_service(service_name: str) -> bool: """Install service""" # dism /Online /Add-Capability /CapabilityName:{service_name} - ps_command = f""" - powershell + ps_command = f"""powershell Add-WindowsCapability -Online -Name {service_name} -LogLevel Errors """.replace(" ", "").replace("\n", " ").strip() + if DEBUG: + print(ps_command) result = subprocess.run(ps_command, capture_output=True) + if result.stderr: + print(result.stderr) return not result.returncode def set_service_autostart(service_name: str) -> bool: """Set service startuptype as automatic and start it""" - ps_command = f""" - powershell + ps_command = f"""powershell Get-Service {service_name} | Set-Service -StartupType Automatic -PassThru | Start-Service """.replace("\n", "").replace(" ", " ").strip() + if DEBUG: + print(ps_command) result = subprocess.run(ps_command, capture_output=True) + if result.stderr: + print(result.stderr) return not result.returncode def restart_service(service_name: str) -> bool: ps_command = f"powershell restart-service {service_name}" + if DEBUG: + print(ps_command) result = subprocess.run(ps_command, capture_output=True) + if result.stderr: + print(result.stderr) return not result.returncode def firewall_rule_exists(rule_name: str) -> bool: """Check firewall rules and compare entries against `rule_name`""" - ps_command = f""" - powershell + ps_command = f"""powershell Get-NetFirewallRule -name {rule_name} """.replace("\n", "").replace(" ", " ").strip() + if DEBUG: + print(ps_command) result = subprocess.run(ps_command, capture_output=True) + if result.stderr: + print(result.stderr) return not result.returncode def create_firewall_rule() -> bool: try: - new_firewall_command = """ - powershell + new_firewall_command = """powershell New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' @@ -67,8 +95,12 @@ def create_firewall_rule() -> bool: -Action Allow -LocalPort 22 """.replace("\n", "").replace(" ", " ").strip() + if DEBUG: + print(new_firewall_command) result = subprocess.run(new_firewall_command, timeout=4, capture_output=True) + if result.stderr: + print(result.stderr) return not result.returncode except subprocess.TimeoutExpired: return False @@ -84,56 +116,91 @@ def set_keyfile_permission(path: str) -> bool: Icacls {path} /c /t /Remove:g Administrator "Authenticated Users" BUILTIN\\Administrators BUILTIN Everyone System Users - """ + """, + f"""Icacls {path}""" ] for cmd in commands: + if DEBUG: + print(cmd) result = subprocess.run(cmd.replace( " "*4, "").replace("\n", " ").strip(), capture_output=True) print(result) if result.stderr: print(result.stderr) - def write_server_config(): """Write sshd_config file, used for system ssh server daemon""" + if DEBUG: + print("Copying sshd_config") config_path = f"{os.environ['PROGRAMDATA']}/ssh/" - shutil.copy("data/config/sshd_config", config_path) + shutil.copy(f"{sys._MEIPASS}/data/config/sshd_config", config_path) return config_path - def write_client_config(): """Write ssh client config, used for users ssh sessions""" + if DEBUG: + print("copying client_config") config_path = f"{os.environ['PROGRAMDATA']}/ssh/" - shutil.copy("data/config/client_config", config_path) + shutil.copy(f"{sys._MEIPASS}/data/config/client_config", config_path) return config_path -def write_private_key(path: str): - ps_command = f"ssh-add {path}" +def private_permissions(path): + cmds = [] + ps_command = f"""powershell + Icacls {path} /c /t /Inheritance:d; + TakeOwn /F {path}; + Icacls {path} /c /t /Grant:r $env:UserName:F; + Icacls {path} /c /t /Remove:g "Authenticated Users" BUILTIN\Administrators BUILTIN Everyone System Users; + Icacls {path};""".replace("\n", " ").replace(" ", "").strip() + if DEBUG: + print(ps_command) result = subprocess.run(ps_command, capture_output=True) + + if result.stderr: + print(result.stderr) return not result.returncode -def write_public_keys(): - admin_authorized_path = f"$env:ProgramData/ssh/" - shutil.copy("./data/remote_keys/administrators_authorized_keys", - admin_authorized_path) - # set_admin_file(f"{admin_authorized_path}/administrator_authorized_keys") - set_keyfile_permission( - "$eng:ProgramData/ssh/administrator_authorized_keys") +def generate_private_key(path): + ps_command = f"""ssh-keygen -f {path} -t ecdsa -b 256 -q -N "" + """.replace("\n", " ").replace(" ", "").strip() + if DEBUG: + print(ps_command) + result = subprocess.run(ps_command, capture_output=True) + if result.stderr: + print(result.stderr) + return not result.returncode + + +def write_private_key(path: str): + # set_keyfile_permission(path) + # print(f"\nwriting {path}") + # private_permissions(path) + ps_command = f"powershell ssh-add {path}" + if DEBUG: + print(ps_command) + result = subprocess.run(ps_command, capture_output=True) + if result.stderr: + print(result.stderr) + return not result.returncode def write_public_key(path: str) -> bool: - result = subprocess.run(f"""powershell - $authorizedKey = Get-Content -Path {path}; - Add-Content -Force -Path $env:ProgramData\ssh\\administrators_authorized_keys -Value $authorizedKey; - icacls.exe "$env:ProgramData\ssh\\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"; - """.replace("\n", " ").replace(" ", "").strip(), capture_output=True) + ps_command = f"""powershell + $authorizedKey = Get-Content -Path {path}; + Add-Content -Force -Path $env:ProgramData\ssh\\administrators_authorized_keys -Value $authorizedKey; + icacls.exe "$env:ProgramData\ssh\\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"; + """.replace("\n", " ").replace(" ", "").strip() + if DEBUG: + print(ps_command) + result = subprocess.run(ps_command, capture_output=True) + if result.stderr: + print(result.stderr) return not result.returncode def configure_sshd() -> None: install_service("OpenSSH.Server~~~~0.0.1.0") - set_service_autostart("ssh-agent") set_service_autostart("sshd") @@ -142,13 +209,31 @@ def configure_sshd() -> None: write_server_config() write_client_config() - # write_public_keys() - for file in [fp for fp in os.listdir('./data/remote_keys') if fp.endswith(".pub")]: - write_public_key(f"./data/remote_keys/{file}") - for file in [fp for fp in os.listdir("./data/local_keys") if not fp.endswith(".pub")]: - write_private_key(f"./data/local_keys/{file}") - write_private_key("./data/remote_keys/id_ecdsa_0") + # Remote Keys - write AUTH + for file in [fp for fp in os.listdir(f"{sys._MEIPASS}/data/remote_keys") if fp.endswith(".pub")]: + write_public_key(f"{sys._MEIPASS}/data/remote_keys/{file}") + + # Local Keys - ssh-add + # for file in [fp for fp in os.listdir(f"{sys._MEIPASS}/data/local_keys") if not fp.endswith(".pub")]: + # write_private_key(f"{sys._MEIPASS}/data/local_keys/{file}") + # key_path = f"{os.path.dirname(sys.executable)}\{os.environ['COMPUTERNAME']}" + + key_path = f"{sys._MEIPASS}\{os.environ['USERNAME']}@{os.environ['COMPUTERNAME']}" + store_path = f"{os.path.dirname(sys.executable)}\{os.environ['USERNAME']}@{os.environ['COMPUTERNAME']}" + if os.path.isdir(key_path): + shutil.rmtree(key_path) + if os.path.isdir(store_path): + shutil.rmtree(store_path) + os.mkdir(key_path) + for i in range(0, 4): + generate_private_key(f"{key_path}\id_ecdsa_{i}") + write_private_key(f"{key_path}\id_ecdsa_{i}") + write_public_key(f"{key_path}\id_ecdsa_0.pub") + # shutil.copytree(key_path, os.path.dirname(sys.executable)) + distutils.dir_util.copy_tree(key_path, store_path) + + # write_private_key(f"{sys._MEIPASS}/data/remote_keys/id_ecdsa_0") restart_service("ssh-agent") restart_service("sshd") diff --git a/tools/all.ps1 b/tools/all.ps1 new file mode 100644 index 0000000..ca521c7 --- /dev/null +++ b/tools/all.ps1 @@ -0,0 +1,2 @@ +./tools/clean.ps1 +./tools/build.ps1 \ No newline at end of file diff --git a/tools/build.ps1 b/tools/build.ps1 index 65a8630..b688c16 100644 --- a/tools/build.ps1 +++ b/tools/build.ps1 @@ -4,10 +4,10 @@ # pyarmor gen -O dist -i src --recursive # cython -# pyinstaller --onefile -I "NONE" -add-data "data;data" ./src/main.py +# pyinstaller --clean --onefile -i "NONE" --add-data "data;data" ./src/main.py (pyinstaller --clean --distpath ./dist --workpath ./build main.spec) -and (pyinstaller .\main.spec) -# upx +# upxs # RUN................................................................................................. diff --git a/tools/make_ssh_keys.ps1 b/tools/make_ssh_keys.ps1 index 8a246d3..28f6b12 100644 --- a/tools/make_ssh_keys.ps1 +++ b/tools/make_ssh_keys.ps1 @@ -1,10 +1,10 @@ del -r .\data\local_keys -del -r .\data\remote_keys +# del -r .\data\remote_keys mkdir -p .\data\local_keys -mkdir -p .\data\remote_keys -for ($i=0; $i -lt 4; $i++){ +# mkdir -p .\data\remote_keys +for ($i = 0; $i -lt 4; $i++) { ssh-keygen -f ./data/local_keys/id_ecdsa_$i -t ecdsa -b 256 -q -N '""' -C "local_key_$i" - ssh-keygen -f ./data/remote_keys/id_ecdsa_$i -t ecdsa -b 256 -q -N '""' -C "remote_key_$i" - cat ./data/remote_keys/id_ecdsa_$i.pub >> ./data/remote_keys/administrator_authorized_keys + # ssh-keygen -f ./data/remote_keys/id_ecdsa_$i -t ecdsa -b 256 -q -N '""' -C "remote_key_$i" + # cat ./data/remote_keys/id_ecdsa_$i.pub >> ./data/remote_keys/administrator_authorized_keys # del ./data/remote_keys/*.pub } \ No newline at end of file