From 6262ab6e7ea59c28b92c64863a783c590acc6755 Mon Sep 17 00:00:00 2001 From: Vantz Stockwell Date: Sat, 14 Mar 2026 01:13:51 -0400 Subject: [PATCH] debug: verify ssh2 key parsing and log derived public key Uses ssh2 utils.parseKey() to check if the key decrypts and parses correctly, logs the key type and public key fingerprint. Co-Authored-By: Claude Opus 4.6 --- backend/src/terminal/ssh-connection.service.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/backend/src/terminal/ssh-connection.service.ts b/backend/src/terminal/ssh-connection.service.ts index 11ca09b..1867772 100644 --- a/backend/src/terminal/ssh-connection.service.ts +++ b/backend/src/terminal/ssh-connection.service.ts @@ -1,5 +1,5 @@ import { Injectable, Logger } from '@nestjs/common'; -import { Client, ClientChannel } from 'ssh2'; +import { Client, ClientChannel, utils } from 'ssh2'; import { createHash } from 'crypto'; import { CredentialsService } from '../vault/credentials.service'; import { HostsService } from '../connections/hosts.service'; @@ -112,6 +112,20 @@ export class SshConnectionService { this.logger.log(`[SSH] Using key auth for ${connectConfig.username}@${connectConfig.host}:${connectConfig.port}`); this.logger.log(`[SSH] Key starts with: ${cred.sshKey.privateKey.substring(0, 40)}...`); this.logger.log(`[SSH] Key length: ${cred.sshKey.privateKey.length}, has passphrase: ${!!cred.sshKey.passphrase}`); + + // Verify ssh2 can parse the key + try { + const parsed = utils.parseKey(cred.sshKey.privateKey, cred.sshKey.passphrase || undefined); + if (parsed instanceof Error) { + this.logger.error(`[SSH] Key parse FAILED: ${parsed.message}`); + } else { + const keyInfo = Array.isArray(parsed) ? parsed[0] : parsed; + this.logger.log(`[SSH] Key parsed OK — type: ${keyInfo.type}, comment: ${keyInfo.comment || 'none'}`); + this.logger.log(`[SSH] Public key fingerprint: ${keyInfo.getPublicSSH?.()?.toString('base64')?.substring(0, 40) || 'N/A'}`); + } + } catch (e: any) { + this.logger.error(`[SSH] Key parse threw: ${e.message}`); + } } else if (cred?.password) { connectConfig.password = cred.password; this.logger.log(`[SSH] Using password auth for ${connectConfig.username}@${connectConfig.host}:${connectConfig.port}`);