Skip to content

Commit 4adc3ad

Browse files
author
Lukas Geiger
committed
fix: reject unknown ssh host keys
1 parent 0249b23 commit 4adc3ad

3 files changed

Lines changed: 33 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Format basiert auf [Keep a Changelog](https://keepachangelog.com/de/1.1.0/).
77

88
### Behoben
99

10+
- `features/remote_editor.py`: SSH/SFTP-Verbindungen laden bekannte Hostkeys und
11+
lehnen unbekannte Hostkeys jetzt ab, statt sie automatisch zu akzeptieren.
1012
- `ui/main_window.py` (B-011): ProjectView blieb beim Öffnen einer Datei aus
1113
einem anderen Ordner auf dem ersten Root hängen. Der Projektbaum folgt jetzt
1214
auch bei späteren Dateiwechseln dem aktuellen Dateiverzeichnis; neuer

features/remote_editor.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,15 @@ def connect(self) -> bool:
5252

5353
try:
5454
self._ssh = paramiko.SSHClient()
55-
self._ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
55+
try:
56+
self._ssh.load_system_host_keys()
57+
except OSError as exc:
58+
logger.debug("System-Hostkeys konnten nicht geladen werden: %s", exc)
59+
60+
user_known_hosts = Path.home() / ".ssh" / "known_hosts"
61+
if user_known_hosts.exists():
62+
self._ssh.load_host_keys(str(user_known_hosts))
63+
self._ssh.set_missing_host_key_policy(paramiko.RejectPolicy())
5664

5765
connect_kwargs = {
5866
"hostname": self.host.hostname,

tests/test_remote_editor.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,25 @@ def fake_get(remote, local):
6363
# Aufräumen
6464
session.disconnect()
6565
session._sftp = None
66+
67+
68+
def test_connect_rejects_unknown_host_keys(monkeypatch):
69+
"""SSH-Verbindungen dürfen unbekannte Hostkeys nicht automatisch akzeptieren."""
70+
from features import remote_editor
71+
72+
fake_paramiko = MagicMock()
73+
ssh_mock = MagicMock()
74+
reject_policy = object()
75+
fake_paramiko.SSHClient.return_value = ssh_mock
76+
fake_paramiko.RejectPolicy.return_value = reject_policy
77+
monkeypatch.setattr(remote_editor, "PARAMIKO_AVAILABLE", True)
78+
monkeypatch.setattr(remote_editor, "paramiko", fake_paramiko, raising=False)
79+
80+
host = remote_editor.RemoteHost(name="test", hostname="localhost", username="user")
81+
session = remote_editor.SFTPSession(host)
82+
83+
assert session.connect() is True
84+
85+
ssh_mock.load_system_host_keys.assert_called_once_with()
86+
ssh_mock.set_missing_host_key_policy.assert_called_once_with(reject_policy)
87+
ssh_mock.connect.assert_called_once_with(hostname="localhost", port=22, username="user")

0 commit comments

Comments
 (0)