v1.8.10: security audit fixes

- --list and --status no longer expose IP/port/user (only aliases)
- --list-full for admin use (not in skill)
- Removed --add from /ssh skill (servers added via GUI only)
- Removed exact file paths from skill template
- Added deny-read rules for ~/.server-connections/ files
- Wrapped main() in try/except to prevent traceback leaking
- Added needs_reencrypt() to encryption.py for future migration
- install_key no longer prints server IP

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
chrome-storm-c442
2026-02-24 04:56:16 -05:00
parent 831fb66110
commit efb508c982
5 changed files with 48 additions and 21 deletions

View File

@@ -209,7 +209,7 @@ def install_key(server: dict):
)
out, err, code = run_command(server, command, use_sudo=False)
if "KEY_OK" in out:
print(f"SSH key installed on {server['alias']} ({server['ip']})")
print(f"SSH key installed on {server['alias']}")
else:
print(f"ERROR: {err or out}")
sys.exit(1)
@@ -226,19 +226,28 @@ def ping_server(server: dict):
print(f"{server['alias']}: OFFLINE ({type(e).__name__})")
def list_servers():
def list_servers(full=False):
_, servers = load_servers()
print(f"{'Alias':<20} {'IP':<20} {'Port':<8} {'User':<10} {'Key':<6}")
print("-" * 64)
for alias, s in servers.items():
has_key = "yes" if os.path.exists(SSH_KEY_PATH) else "no"
print(f"{alias:<20} {s['ip']:<20} {s.get('port', 22):<8} {s.get('user', 'root'):<10} {has_key:<6}")
if full:
print(f"{'Alias':<20} {'IP':<20} {'Port':<8} {'User':<10} {'Key':<6}")
print("-" * 64)
for alias, s in servers.items():
has_key = "yes" if os.path.exists(SSH_KEY_PATH) else "no"
print(f"{alias:<20} {s['ip']:<20} {s.get('port', 22):<8} {s.get('user', 'root'):<10} {has_key:<6}")
else:
# Safe mode: only aliases (no IPs, ports, users)
print(f"{'Alias':<20} {'Type':<10} {'Key':<6}")
print("-" * 36)
for alias, s in servers.items():
has_key = "yes" if os.path.exists(SSH_KEY_PATH) else "no"
stype = s.get("type", "ssh")
print(f"{alias:<20} {stype:<10} {has_key:<6}")
def check_status():
_, servers = load_servers()
print(f"{'Alias':<20} {'IP':<20} {'Status':<10}")
print("-" * 50)
print(f"{'Alias':<20} {'Status':<10}")
print("-" * 30)
for alias, s in servers.items():
try:
client = get_client(s)
@@ -246,7 +255,7 @@ def check_status():
status = "ONLINE"
except Exception:
status = "OFFLINE"
print(f"{alias:<20} {s['ip']:<20} {status:<10}")
print(f"{alias:<20} {status:<10}")
def add_server(args):
@@ -335,6 +344,8 @@ def main():
if cmd == "--list":
list_servers(); sys.exit(0)
if cmd == "--list-full":
list_servers(full=True); sys.exit(0)
if cmd == "--status":
check_status(); sys.exit(0)
if cmd == "--add":
@@ -379,4 +390,10 @@ def main():
if __name__ == "__main__":
main()
try:
main()
except SystemExit:
raise
except Exception as e:
print(f"ERROR: {type(e).__name__}: {e}", file=sys.stderr)
sys.exit(1)