SSH-Agent-Socket an ssh durchreichen (wie Terminal), Banner-Tipp, Doku

This commit is contained in:
x3
2026-09-21 23:47:01 +02:00
parent 37a70edbab
commit ed6e96b3c1
4 changed files with 46 additions and 3 deletions
@@ -42,6 +42,30 @@ enum SSHService {
// MARK: - Passwort / Auto-Login
/// SSH-Agent-Socket für GUI-Prozesse auflösen (Finder-Apps erben SSH_AUTH_SOCK
/// nicht, Terminal schon — ohne diesen Unterschied nutzt Terminal evtl. einen
/// Agent-Key, während die App nach dem Passwort fragt und scheitert).
static func agentSocket() -> String? {
let p = Process()
p.executableURL = URL(fileURLWithPath: "/bin/launchctl")
p.arguments = ["getenv", "SSH_AUTH_SOCK"]
let out = Pipe()
let err = Pipe()
p.standardOutput = out
p.standardError = err
do {
try p.run()
p.waitUntilExit()
} catch {
return nil
}
let path = String(data: out.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8)?
.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
guard !path.isEmpty,
FileManager.default.fileExists(atPath: path) else { return nil }
return path
}
/// Gespeichertes Login-Secret: erst Profil-Passwort, dann Key-Passphrase (Keychain, nie JSON).
static func loginSecret(for profile: ConnectionProfile, key: StoredSSHKey?) -> String? {
if let acct = profile.passwordAccount,
+7 -2
View File
@@ -298,12 +298,17 @@ final class TerminalManager: ObservableObject {
baseExe = "/usr/bin/ssh"
baseArgs = SSHService.sshArguments(for: profile, key: key)
}
// Auto-Login nur mit Keychain-Secret + sshpass, sonst interaktiver Prompt im Terminal
// Auto-Login nur mit Keychain-Secret + sshpass, sonst interaktiver Prompt im Terminal.
// SSH-Agent durchreichen (falls vorhanden): gleiche Keys wie in Terminal.app.
let cfg = SSHService.sessionConfig(executable: baseExe, args: baseArgs,
password: SSHService.loginSecret(for: profile, key: key),
sshpassPath: SSHService.findSshpass())
s.configure(executable: cfg.executable, arguments: cfg.arguments)
s.customEnv = cfg.extraEnv
var env = cfg.extraEnv
if let sock = SSHService.agentSocket() {
env["SSH_AUTH_SOCK"] = sock
}
s.customEnv = env
s.setAutoLogin(cfg.autoLogin)
sessions[profile.id] = s
return s
@@ -42,7 +42,7 @@ struct EmbeddedTerminalView: View {
.font(.caption).foregroundStyle(Dracula.foreground)
.lineLimit(3)
if lastMessage.localizedCaseInsensitiveContains("permission denied") {
Text("Tipp: Passwort im Auge-Modus eingeben, auf Tastaturlayout (z. B. Z/Y) achten, Keychain-Eintrag prüfen.")
Text("Tipp: Passwort im Auge-Modus eingeben, Tastaturlayout prüfen. Falls Terminal.app ohne Passwort einloggt (Agent-Key: ssh-add -l), Key in der App hinterlegen oder Agent nutzen.")
.font(.caption).foregroundStyle(Dracula.orange)
}
}
+14
View File
@@ -20,6 +20,7 @@ Stand: 2026-09-21 · Version 0.1.0 · macOS arm64 · Swift 5.9+ · Xcode 15+
| 11 | 2026-09-21 | Passwort-Feature | Wunsch: Passwort + Keys speichern UND nutzen (bisher nur gespeichert, nie benutzt) | Feature | ✅ umgesetzt — Auto-Login via sshpass, sonst interaktiv |
| 12 | 2026-09-21 | „Immer Verbindung falsch" | User-Report ohne Details (Ziel/Credentials unbekannt) | offen | ⬜ Teils: Editor-Validierung + kopierbarer Fehlerbericht; warte auf Bericht |
| 13 | 2026-09-21 | Permission denied trotz richtigem Passwort | Text-Ersetzung im Eingabefeld verfälscht Sonderzeichen | hoch | ✅ behoben — gehärtetes Eingabefeld (alle Ersetzungen aus, 9/9 Tests) |
| 14 | 2026-09-21 | Terminal geht, App nicht (gleiches Passwort) | SSH-Agent-Socket fehlt GUI-Prozessen → evtl. Key-Login in Terminal | hoch | ✅ App reicht Agent jetzt durch; Gegenprobe beim User offen |
---
@@ -184,3 +185,16 @@ Oder mit Token als Passwort: `git push https://<owner>:<token>@git.sysdaemon.xyz
**Fix (`Views/TerminalInputField.swift`):** Eigenes Eingabefeld auf `NSTextView`-Basis mit allen Ersetzungen explizit aus (Quotes, Dashes, Completion, Spelling, Data/Link-Erkennung, Text-Replacement, Plain-Text); Secure-Variante via `NSSecureTextField` (per Design ersetzungsfrei); Enter → Senden, Paste-Normalisierung (keine Umbrüche).
**Verifikation:** Harness 9/9 (alle Flags aus). Hinweis: Restrisiko Tastaturlayout (Z/Y) bleibt — Banner-Tipp ergänzt.
**Status:** ✅ behoben — bitte mit v0.5.1 erneut testen.
## #14 — Terminal.app loggt ein, RemminaMac nicht (gleiches Passwort)
**Stand (User-Antworten):** v0.5.1 installiert, Passwort-Login, Terminal.app funktioniert mit denselben Daten.
**Analyse:** App-seitig ist alles verifiziert (PTY, Fehleranzeige, Passwort-Loop mit Sonderzeichen, Eingabe-Ersetzungen aus). Gleiches Binary + gleiche Config → Unterschied muss aus der Umgebung kommen. Hauptkandidat: **SSH-Agent** — Finder-gestartete GUI-Prozesse erben `SSH_AUTH_SOCK` nicht. Nutzt Terminal unbemerkt einen Agent-Key (statt Passwort), scheitert die App mit Passwort. Verifiziert: `launchctl getenv SSH_AUTH_SOCK` liefert den Socket, Shell-Env wäre ohne Abfrage leer für GUI-Apps.
**Fix:** `SSHService.agentSocket()` (launchctl + Existenzprüfung) → `TerminalManager` injiziert `SSH_AUTH_SOCK` ins ssh-Env (koexistiert mit SSHPASS). Banner-Tipp ergänzt.
**Verifikation:** Harness 4/4 (Auflösung 0.07 s, Pfad existiert, `ssh -G` ok mit echtem + kaputtem Socket).
**Gegenprobe beim User (bitte ausführen):**
```bash
ssh-add -l
ssh -o IdentitiesOnly=yes administrator@sysdaemon.xyz
```
Zweite Zeile erzwingt Passwort-Login ohne Agent — scheitert sie auch im Terminal, war es immer der Agent-Key.
**Status:** ✅ App-Seite umgesetzt — warte auf Gegenprobe.