Skip to content

fix: SSHConfig: check for multiple start/end blocks #510

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
May 23, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
move malformed block check earlier
  • Loading branch information
johnstcn committed May 21, 2025
commit bcebbd4771de09cf742eeaf3c9c645d28a9c0ab2
38 changes: 38 additions & 0 deletions src/sshConfig.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,44 @@ Host coder-vscode.dev.coder.com--*
})
})

it("throws an error if there is a missing end block", async () => {
// The below config is missing an end block.
// This is a malformed config and should throw an error.
const existentSSHConfig = `Host beforeconfig
HostName before.config.tld
User before

# --- START CODER VSCODE dev.coder.com ---
Host coder-vscode.dev.coder.com--*
ConnectTimeout 0
LogLevel ERROR
ProxyCommand some-command-here
StrictHostKeyChecking no
UserKnownHostsFile /dev/null

Host afterconfig
HostName after.config.tld
User after`

const sshConfig = new SSHConfig(sshFilePath, mockFileSystem)
mockFileSystem.readFile.mockResolvedValueOnce(existentSSHConfig)
await sshConfig.load()

// When we try to update the config, it should throw an error.
await expect(
sshConfig.update("dev.coder.com", {
Host: "coder-vscode.dev.coder.com--*",
ProxyCommand: "some-command-here",
ConnectTimeout: "0",
StrictHostKeyChecking: "no",
UserKnownHostsFile: "/dev/null",
LogLevel: "ERROR",
}),
).rejects.toThrow(
`Malformed config: Unterminated START CODER VSCODE dev.coder.com block: Each START block must have an END block.`,
)
})

it("throws an error if there is a mismatched start and end block count", async () => {
// The below config contains two start blocks and one end block.
// This is a malformed config and should throw an error.
Expand Down
17 changes: 9 additions & 8 deletions src/sshConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,27 +126,28 @@ export class SSHConfig {
const raw = this.getRaw()
const startBlock = this.startBlockComment(label)
const endBlock = this.endBlockComment(label)

const startBlockCount = countSubstring(startBlock, raw)
const endBlockCount = countSubstring(endBlock, raw)
const startBlockIndex = raw.indexOf(startBlock)
const endBlockIndex = raw.indexOf(endBlock)
const hasBlock = startBlockIndex > -1 && endBlockIndex > -1

if (!hasBlock) {
return
}

if (startBlockCount !== endBlockCount) {
throw new SSHConfigBadFormat(
`Malformed config: Unterminated START CODER VSCODE ${label ? label + " " : ""}block: Each START block must have an END block.`,
)
}

if (startBlockCount > 1 || endBlockCount > 1) {
throw new SSHConfigBadFormat(
`Malformed config: ssh config has ${startBlockCount} START CODER VSCODE ${label ? label + " " : ""}sections, please remove all but one.`,
)
}

const startBlockIndex = raw.indexOf(startBlock)
const endBlockIndex = raw.indexOf(endBlock)
const hasBlock = startBlockIndex > -1 && endBlockIndex > -1
if (!hasBlock) {
return
}

if (startBlockIndex === -1) {
throw new SSHConfigBadFormat("Start block not found")
}
Expand Down