ssh-handler 1.0.1__tar.gz → 1.0.3__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 (24) hide show
  1. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/PKG-INFO +46 -2
  2. ssh_handler-1.0.1/ssh_handler.egg-info/PKG-INFO → ssh_handler-1.0.3/README.md +355 -342
  3. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/pyproject.toml +3 -2
  4. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/ssh_handler/__init__.py +4 -2
  5. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/ssh_handler/config.py +9 -0
  6. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/ssh_handler/core.py +143 -6
  7. ssh_handler-1.0.3/ssh_handler/winrm_bootstrap.py +142 -0
  8. ssh_handler-1.0.1/README.md → ssh_handler-1.0.3/ssh_handler.egg-info/PKG-INFO +386 -314
  9. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/ssh_handler.egg-info/SOURCES.txt +1 -0
  10. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/ssh_handler.egg-info/requires.txt +4 -0
  11. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/tests/test_offline.py +11 -0
  12. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/LICENSE +0 -0
  13. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/setup.cfg +0 -0
  14. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/ssh_handler/__main__.py +0 -0
  15. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/ssh_handler/cli.py +0 -0
  16. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/ssh_handler/credentials.py +0 -0
  17. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/ssh_handler/exceptions.py +0 -0
  18. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/ssh_handler/ftp.py +0 -0
  19. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/ssh_handler/pool.py +0 -0
  20. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/ssh_handler/pyqt_worker.py +0 -0
  21. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/ssh_handler/results.py +0 -0
  22. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/ssh_handler.egg-info/dependency_links.txt +0 -0
  23. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/ssh_handler.egg-info/entry_points.txt +0 -0
  24. {ssh_handler-1.0.1 → ssh_handler-1.0.3}/ssh_handler.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ssh-handler
3
- Version: 1.0.1
3
+ Version: 1.0.3
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
@@ -20,10 +20,13 @@ Provides-Extra: scp
20
20
  Requires-Dist: scp>=0.14; extra == "scp"
21
21
  Provides-Extra: gui
22
22
  Requires-Dist: PyQt5>=5.15; extra == "gui"
23
+ Provides-Extra: winrm
24
+ Requires-Dist: pywinrm>=0.4.3; extra == "winrm"
23
25
  Provides-Extra: all
24
26
  Requires-Dist: keyring>=23.0; extra == "all"
25
27
  Requires-Dist: scp>=0.14; extra == "all"
26
28
  Requires-Dist: PyQt5>=5.15; extra == "all"
29
+ Requires-Dist: pywinrm>=0.4.3; extra == "all"
27
30
  Dynamic: license-file
28
31
 
29
32
  # ssh-handler
@@ -185,6 +188,46 @@ CredentialStore("my_test_lab").set("CORP\\myuser", prompt_password())
185
188
  python -m ssh_handler store-credential --user myuser --domain CORP --service my_test_lab
186
189
  ```
187
190
 
191
+ ## RDP-only Windows hosts: auto-enable SSH once (WinRM bootstrap)
192
+
193
+ A freshly imaged corporate Windows box often has **RDP and WinRM open but no SSH
194
+ server** (port 22 closed). You can't start sshd *over* SSH when SSH is down — but
195
+ if WinRM is reachable, the handler can use it as a one-time bootstrap channel.
196
+
197
+ Set one flag and connect normally:
198
+
199
+ ```python
200
+ from ssh_handler import SSHHandler, SSHConfig
201
+
202
+ cfg = SSHConfig(
203
+ host="10.232.9.22", domain="CORP", username="myuser", password="pw",
204
+ auto_bootstrap_via_winrm=True, # if SSH is down but WinRM is up, enable sshd, then retry
205
+ )
206
+ with SSHHandler(cfg) as ssh: # 1st run: enables sshd over WinRM, then connects
207
+ print(ssh.run("whoami").stdout) # every later run: connects straight over SSH
208
+ ```
209
+
210
+ **It's genuinely one-time.** The bootstrap installs the OpenSSH Server capability,
211
+ starts `sshd` with **Automatic** startup, and adds a **persistent** firewall rule —
212
+ so it survives reboots. After the first run, port 22 is already open and the
213
+ handler connects directly over SSH; WinRM is never touched again.
214
+
215
+ Do it explicitly instead of automatically if you prefer:
216
+
217
+ ```python
218
+ ssh = SSHHandler(cfg)
219
+ ssh.bootstrap_sshd_via_winrm() # one-time setup
220
+ ssh.connect()
221
+ ```
222
+
223
+ Requirements: `pip install "ssh-handler[winrm]"` (pulls in `pywinrm`; uses NTLM so
224
+ domain creds work without Kerberos), and the account must be a **local
225
+ administrator** on the target. If SSH already works, this code path never runs.
226
+
227
+ When a connection just fails, the error now self-diagnoses — it probes the SSH and
228
+ RDP ports and tells you *why* (e.g. "Port 22 is closed but RDP (3389) is open … no
229
+ SSH server listening"). Call `ssh.diagnose()` for a pre-flight reachability check.
230
+
188
231
  ## Confidential credentials
189
232
 
190
233
  | Mechanism | What it does |
@@ -310,8 +353,9 @@ with FTPHandler(FTPConfig(host="ftp.example.com", username="u",
310
353
  ssh_handler/
311
354
  config.py SSHConfig, FTPConfig
312
355
  credentials.py Secret, CredentialStore, mask, prompt_password
313
- core.py SSHHandler, ShellSession (SSH + SFTP + SCP)
356
+ core.py SSHHandler, ShellSession (SSH + SFTP + SCP + diagnose)
314
357
  ftp.py FTPHandler (FTP / FTPS)
358
+ winrm_bootstrap.py enable_openssh_via_winrm (one-time sshd enable over WinRM)
315
359
  pool.py SSHPool (parallel multi-host)
316
360
  cli.py argparse entry point (python -m ssh_handler / ssh-handler)
317
361
  pyqt_worker.py SSHWorker (PyQt5, lazy import)