ssh-handler 1.0.4__tar.gz → 1.0.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. {ssh_handler-1.0.4/ssh_handler.egg-info → ssh_handler-1.0.6}/PKG-INFO +16 -1
  2. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/README.md +15 -0
  3. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/pyproject.toml +5 -1
  4. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/ssh_handler/__init__.py +1 -1
  5. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/ssh_handler/cli.py +54 -0
  6. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/ssh_handler/results.py +5 -0
  7. ssh_handler-1.0.6/ssh_handler/setup_openssh_server.ps1 +150 -0
  8. {ssh_handler-1.0.4 → ssh_handler-1.0.6/ssh_handler.egg-info}/PKG-INFO +16 -1
  9. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/ssh_handler.egg-info/SOURCES.txt +1 -0
  10. ssh_handler-1.0.6/ssh_handler.egg-info/entry_points.txt +3 -0
  11. ssh_handler-1.0.4/ssh_handler.egg-info/entry_points.txt +0 -2
  12. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/LICENSE +0 -0
  13. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/setup.cfg +0 -0
  14. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/ssh_handler/__main__.py +0 -0
  15. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/ssh_handler/config.py +0 -0
  16. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/ssh_handler/core.py +0 -0
  17. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/ssh_handler/credentials.py +0 -0
  18. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/ssh_handler/exceptions.py +0 -0
  19. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/ssh_handler/ftp.py +0 -0
  20. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/ssh_handler/pool.py +0 -0
  21. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/ssh_handler/pyqt_worker.py +0 -0
  22. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/ssh_handler/winrm_bootstrap.py +0 -0
  23. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/ssh_handler.egg-info/dependency_links.txt +0 -0
  24. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/ssh_handler.egg-info/requires.txt +0 -0
  25. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/ssh_handler.egg-info/top_level.txt +0 -0
  26. {ssh_handler-1.0.4 → ssh_handler-1.0.6}/tests/test_offline.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ssh-handler
3
- Version: 1.0.4
3
+ Version: 1.0.6
4
4
  Summary: Extensive SSH/SFTP/SCP/FTP handler built on Paramiko, for test automation, CLIs and PyQt5 tools.
5
5
  Author: ssh-handler contributors
6
6
  License-Expression: MIT
@@ -224,6 +224,21 @@ Requirements: `pip install "ssh-handler[winrm]"` (pulls in `pywinrm`; uses NTLM
224
224
  domain creds work without Kerberos), and the account must be a **local
225
225
  administrator** on the target. If SSH already works, this code path never runs.
226
226
 
227
+ ### Set up OpenSSH Server on a machine (bundled installer)
228
+
229
+ Installing the package also gives you a one-command setup for the *local* Windows
230
+ machine — it ships inside the wheel, self-elevates to Administrator, installs &
231
+ starts OpenSSH Server, and opens the firewall:
232
+
233
+ ```powershell
234
+ pip install ssh-handler
235
+ ssh-handler-setup # install + start sshd + firewall (self-elevates)
236
+ ssh-handler-setup --install-pip # also (re)install the package as admin
237
+ # equivalent: python -m ssh_handler setup-server
238
+ ```
239
+
240
+ Run it on whichever machine you want to reach over SSH (e.g. the RDP jump box).
241
+
227
242
  When a connection just fails, the error now self-diagnoses — it probes the SSH and
228
243
  RDP ports and tells you *why* (e.g. "Port 22 is closed but RDP (3389) is open … no
229
244
  SSH server listening"). Call `ssh.diagnose()` for a pre-flight reachability check.
@@ -193,6 +193,21 @@ Requirements: `pip install "ssh-handler[winrm]"` (pulls in `pywinrm`; uses NTLM
193
193
  domain creds work without Kerberos), and the account must be a **local
194
194
  administrator** on the target. If SSH already works, this code path never runs.
195
195
 
196
+ ### Set up OpenSSH Server on a machine (bundled installer)
197
+
198
+ Installing the package also gives you a one-command setup for the *local* Windows
199
+ machine — it ships inside the wheel, self-elevates to Administrator, installs &
200
+ starts OpenSSH Server, and opens the firewall:
201
+
202
+ ```powershell
203
+ pip install ssh-handler
204
+ ssh-handler-setup # install + start sshd + firewall (self-elevates)
205
+ ssh-handler-setup --install-pip # also (re)install the package as admin
206
+ # equivalent: python -m ssh_handler setup-server
207
+ ```
208
+
209
+ Run it on whichever machine you want to reach over SSH (e.g. the RDP jump box).
210
+
196
211
  When a connection just fails, the error now self-diagnoses — it probes the SSH and
197
212
  RDP ports and tells you *why* (e.g. "Port 22 is closed but RDP (3389) is open … no
198
213
  SSH server listening"). Call `ssh.diagnose()` for a pre-flight reachability check.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ssh-handler"
7
- version = "1.0.4"
7
+ version = "1.0.6"
8
8
  description = "Extensive SSH/SFTP/SCP/FTP handler built on Paramiko, for test automation, CLIs and PyQt5 tools."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -32,6 +32,10 @@ all = ["keyring>=23.0", "scp>=0.14", "PyQt5>=5.15", "pywinrm>=0.4.3"]
32
32
 
33
33
  [project.scripts]
34
34
  ssh-handler = "ssh_handler.cli:main"
35
+ ssh-handler-setup = "ssh_handler.cli:setup_server_main"
35
36
 
36
37
  [tool.setuptools]
37
38
  packages = ["ssh_handler"]
39
+
40
+ [tool.setuptools.package-data]
41
+ ssh_handler = ["*.ps1"]
@@ -22,7 +22,7 @@ dependencies (PyQt5 / scp) don't break the core package.
22
22
 
23
23
  from __future__ import annotations
24
24
 
25
- __version__ = "1.0.4"
25
+ __version__ = "1.0.6"
26
26
 
27
27
  from .config import SSHConfig, FTPConfig
28
28
  from .core import SSHHandler, ShellSession
@@ -15,9 +15,11 @@ Credentials (password never echoed, never stored in plaintext):
15
15
 
16
16
  from __future__ import annotations
17
17
 
18
+ import os
18
19
  import sys
19
20
  import json
20
21
  import argparse
22
+ import subprocess
21
23
 
22
24
  from .config import SSHConfig
23
25
  from .core import SSHHandler
@@ -26,6 +28,35 @@ from .exceptions import SSHError
26
28
  from .results import CommandResult, TransferResult
27
29
 
28
30
 
31
+ def _setup_script_path() -> str:
32
+ """Absolute path to the bundled OpenSSH setup PowerShell script."""
33
+ return os.path.join(os.path.dirname(__file__), "setup_openssh_server.ps1")
34
+
35
+
36
+ def setup_server_main(argv=None) -> int:
37
+ """
38
+ Console entry point (`ssh-handler-setup`): run the bundled PowerShell script
39
+ that installs & starts OpenSSH Server, opens the firewall, and optionally
40
+ pip-installs the package. Self-elevates to Administrator. Windows only.
41
+
42
+ Any extra args are forwarded to the script, e.g.:
43
+ ssh-handler-setup --InstallPip --Port 22
44
+ """
45
+ if os.name != "nt":
46
+ print("ssh-handler-setup only runs on Windows (it sets up OpenSSH Server).",
47
+ file=sys.stderr)
48
+ return 2
49
+ script = _setup_script_path()
50
+ if not os.path.exists(script):
51
+ print(f"Bundled setup script not found: {script}", file=sys.stderr)
52
+ return 1
53
+ extra = list(argv) if argv is not None else sys.argv[1:]
54
+ cmd = ["powershell", "-NoProfile", "-ExecutionPolicy", "Bypass",
55
+ "-File", script] + extra
56
+ print(f"Launching OpenSSH Server setup (will prompt for Administrator)...")
57
+ return subprocess.call(cmd)
58
+
59
+
29
60
  def _add_conn_args(p: argparse.ArgumentParser) -> None:
30
61
  p.add_argument("--host", required=True)
31
62
  p.add_argument("--port", type=int, default=22)
@@ -107,6 +138,29 @@ def main(argv=None) -> int:
107
138
  p_info = sub.add_parser("info", help="connect and report remote OS")
108
139
  _add_conn_args(p_info)
109
140
 
141
+ p_setup = sub.add_parser("setup-server",
142
+ help="install & start OpenSSH Server on THIS Windows "
143
+ "machine (self-elevates to Administrator)")
144
+ p_setup.add_argument("--install-pip", action="store_true",
145
+ help="also pip-install ssh-handler[winrm]")
146
+ p_setup.add_argument("--port", type=int, default=22)
147
+
148
+ # setup-server takes no connection args and runs the bundled PowerShell script
149
+ if argv is None:
150
+ _argv = sys.argv[1:]
151
+ else:
152
+ _argv = list(argv)
153
+ if _argv and _argv[0] == "setup-server":
154
+ forward = []
155
+ rest = _argv[1:]
156
+ if "--install-pip" in rest:
157
+ forward.append("-InstallPip")
158
+ if "--port" in rest:
159
+ i = rest.index("--port")
160
+ if i + 1 < len(rest):
161
+ forward += ["-Port", rest[i + 1]]
162
+ return setup_server_main(forward)
163
+
110
164
  args = parser.parse_args(argv)
111
165
 
112
166
  # store-credential is handled without a connection
@@ -31,6 +31,11 @@ class CommandResult:
31
31
  def ok(self) -> bool:
32
32
  return self.exit_code == 0
33
33
 
34
+ @property
35
+ def text(self) -> str:
36
+ """stdout with surrounding whitespace/newlines stripped - print-ready."""
37
+ return self.stdout.strip()
38
+
34
39
  def __bool__(self) -> bool:
35
40
  return self.ok
36
41
 
@@ -0,0 +1,150 @@
1
+ <#
2
+ .SYNOPSIS
3
+ One-shot setup for an SSH target / RDP jump machine:
4
+ installs & starts OpenSSH Server, opens the firewall, and (optionally)
5
+ pip-installs the ssh-handler package. Self-elevates to Administrator.
6
+
7
+ .DESCRIPTION
8
+ Run this once on a Windows machine that you want to reach over SSH (e.g. the
9
+ RDP box you tunnel through). It:
10
+ 1. Re-launches itself elevated if not already running as Administrator.
11
+ 2. Installs OpenSSH Server (Windows capability -> winget fallback).
12
+ 3. Starts sshd, sets it to start automatically, opens TCP 22.
13
+ 4. Optionally runs `pip install -U "ssh-handler[winrm]"`.
14
+ 5. Verifies sshd is running and listening.
15
+
16
+ .PARAMETER InstallPip
17
+ Also install/upgrade the ssh-handler Python package (needs Python+pip on PATH).
18
+
19
+ .PARAMETER Port
20
+ SSH port to open in the firewall (default 22).
21
+
22
+ .EXAMPLE
23
+ powershell -ExecutionPolicy Bypass -File .\setup_openssh_server.ps1
24
+
25
+ .EXAMPLE
26
+ powershell -ExecutionPolicy Bypass -File .\setup_openssh_server.ps1 -InstallPip
27
+ #>
28
+
29
+ param(
30
+ [switch]$InstallPip,
31
+ [int]$Port = 22
32
+ )
33
+
34
+ $ErrorActionPreference = 'Stop'
35
+ $ProgressPreference = 'SilentlyContinue'
36
+
37
+ # --- 1. Self-elevate to Administrator -------------------------------------- #
38
+ $isAdmin = ([Security.Principal.WindowsPrincipal]`
39
+ [Security.Principal.WindowsIdentity]::GetCurrent()`
40
+ ).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
41
+
42
+ if (-not $isAdmin) {
43
+ Write-Host "Elevating to Administrator..." -ForegroundColor Yellow
44
+ $argList = "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`""
45
+ if ($InstallPip) { $argList += " -InstallPip" }
46
+ $argList += " -Port $Port"
47
+ Start-Process powershell -Verb RunAs -ArgumentList $argList
48
+ exit
49
+ }
50
+
51
+ Write-Host "=== OpenSSH Server setup (running as Administrator) ===" -ForegroundColor Cyan
52
+
53
+ # --- 2. Install OpenSSH Server --------------------------------------------- #
54
+ function Test-SshdPresent {
55
+ return [bool](Get-Service -Name sshd -ErrorAction SilentlyContinue)
56
+ }
57
+
58
+ if (Test-SshdPresent) {
59
+ Write-Host "OpenSSH Server already present." -ForegroundColor Green
60
+ }
61
+ else {
62
+ Write-Host "Installing OpenSSH Server..."
63
+ $installed = $false
64
+
65
+ # 2a. Windows capability (Features-on-Demand). May be slow on corporate nets.
66
+ try {
67
+ $cap = Get-WindowsCapability -Online -Name 'OpenSSH.Server*' |
68
+ Select-Object -First 1
69
+ if ($cap -and $cap.State -ne 'Installed') {
70
+ Write-Host " Trying Add-WindowsCapability (can take a few minutes)..."
71
+ Add-WindowsCapability -Online -Name $cap.Name | Out-Null
72
+ }
73
+ if (Test-SshdPresent) { $installed = $true }
74
+ }
75
+ catch {
76
+ Write-Host " Windows capability install failed: $($_.Exception.Message)" `
77
+ -ForegroundColor DarkYellow
78
+ }
79
+
80
+ # 2b. winget fallback
81
+ if (-not $installed) {
82
+ try {
83
+ Write-Host " Trying winget (Microsoft.OpenSSH.Beta)..."
84
+ winget install --id Microsoft.OpenSSH.Beta -e --silent `
85
+ --accept-source-agreements --accept-package-agreements | Out-Null
86
+ if (Test-SshdPresent) { $installed = $true }
87
+ }
88
+ catch {
89
+ Write-Host " winget not available or failed." -ForegroundColor DarkYellow
90
+ }
91
+ }
92
+
93
+ if (-not $installed -and -not (Test-SshdPresent)) {
94
+ Write-Warning @"
95
+ Could not auto-install OpenSSH Server (Windows Update / winget likely blocked).
96
+ Manual fallback:
97
+ 1. On a machine with internet, download OpenSSH-Win64.zip from
98
+ https://github.com/PowerShell/Win32-OpenSSH/releases/latest
99
+ 2. Copy it here, extract to 'C:\Program Files\OpenSSH'
100
+ 3. Run: powershell -ExecutionPolicy Bypass -File 'C:\Program Files\OpenSSH\install-sshd.ps1'
101
+ Then re-run this script to finish service + firewall setup.
102
+ "@
103
+ exit 1
104
+ }
105
+ Write-Host "OpenSSH Server installed." -ForegroundColor Green
106
+ }
107
+
108
+ # --- 3. Service + firewall -------------------------------------------------- #
109
+ Write-Host "Configuring sshd service and firewall..."
110
+ Set-Service -Name sshd -StartupType Automatic
111
+ Start-Service sshd
112
+
113
+ $ruleName = "OpenSSH-Server-In-TCP"
114
+ if (-not (Get-NetFirewallRule -Name $ruleName -ErrorAction SilentlyContinue)) {
115
+ New-NetFirewallRule -Name $ruleName -DisplayName 'OpenSSH Server (sshd)' `
116
+ -Enabled True -Direction Inbound -Protocol TCP -Action Allow `
117
+ -LocalPort $Port | Out-Null
118
+ Write-Host " Firewall rule added for TCP $Port." -ForegroundColor Green
119
+ }
120
+ else {
121
+ Write-Host " Firewall rule already present." -ForegroundColor Green
122
+ }
123
+
124
+ # --- 4. Optional: pip install the package ---------------------------------- #
125
+ if ($InstallPip) {
126
+ Write-Host "Installing ssh-handler (pip)..."
127
+ try {
128
+ python -m pip install --upgrade pip | Out-Null
129
+ python -m pip install -U "ssh-handler[winrm]"
130
+ Write-Host " ssh-handler installed." -ForegroundColor Green
131
+ }
132
+ catch {
133
+ Write-Warning "pip install failed: $($_.Exception.Message)"
134
+ Write-Host " Ensure Python and pip are on PATH, then run: pip install -U ssh-handler"
135
+ }
136
+ }
137
+
138
+ # --- 5. Verify -------------------------------------------------------------- #
139
+ Write-Host "`n=== Verification ===" -ForegroundColor Cyan
140
+ $svc = Get-Service sshd
141
+ Write-Host ("sshd status : {0}" -f $svc.Status)
142
+ $test = Test-NetConnection localhost -Port $Port -WarningAction SilentlyContinue
143
+ Write-Host ("port {0} open : {1}" -f $Port, $test.TcpTestSucceeded)
144
+
145
+ if ($svc.Status -eq 'Running' -and $test.TcpTestSucceeded) {
146
+ Write-Host "`nDone. This machine now accepts SSH on port $Port." -ForegroundColor Green
147
+ }
148
+ else {
149
+ Write-Warning "Setup finished but sshd is not listening yet - check the messages above."
150
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ssh-handler
3
- Version: 1.0.4
3
+ Version: 1.0.6
4
4
  Summary: Extensive SSH/SFTP/SCP/FTP handler built on Paramiko, for test automation, CLIs and PyQt5 tools.
5
5
  Author: ssh-handler contributors
6
6
  License-Expression: MIT
@@ -224,6 +224,21 @@ Requirements: `pip install "ssh-handler[winrm]"` (pulls in `pywinrm`; uses NTLM
224
224
  domain creds work without Kerberos), and the account must be a **local
225
225
  administrator** on the target. If SSH already works, this code path never runs.
226
226
 
227
+ ### Set up OpenSSH Server on a machine (bundled installer)
228
+
229
+ Installing the package also gives you a one-command setup for the *local* Windows
230
+ machine — it ships inside the wheel, self-elevates to Administrator, installs &
231
+ starts OpenSSH Server, and opens the firewall:
232
+
233
+ ```powershell
234
+ pip install ssh-handler
235
+ ssh-handler-setup # install + start sshd + firewall (self-elevates)
236
+ ssh-handler-setup --install-pip # also (re)install the package as admin
237
+ # equivalent: python -m ssh_handler setup-server
238
+ ```
239
+
240
+ Run it on whichever machine you want to reach over SSH (e.g. the RDP jump box).
241
+
227
242
  When a connection just fails, the error now self-diagnoses — it probes the SSH and
228
243
  RDP ports and tells you *why* (e.g. "Port 22 is closed but RDP (3389) is open … no
229
244
  SSH server listening"). Call `ssh.diagnose()` for a pre-flight reachability check.
@@ -12,6 +12,7 @@ ssh_handler/ftp.py
12
12
  ssh_handler/pool.py
13
13
  ssh_handler/pyqt_worker.py
14
14
  ssh_handler/results.py
15
+ ssh_handler/setup_openssh_server.ps1
15
16
  ssh_handler/winrm_bootstrap.py
16
17
  ssh_handler.egg-info/PKG-INFO
17
18
  ssh_handler.egg-info/SOURCES.txt
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ ssh-handler = ssh_handler.cli:main
3
+ ssh-handler-setup = ssh_handler.cli:setup_server_main
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- ssh-handler = ssh_handler.cli:main
File without changes
File without changes