Skip to content

Commit d78933a

Browse files
committed
fix: host verification on custom ssh port
1 parent 340a261 commit d78933a

File tree

1 file changed

+65
-18
lines changed

1 file changed

+65
-18
lines changed

lua/remote-sshfs/connections.lua

Lines changed: 65 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -137,31 +137,62 @@ M.mount_host = function(host, mount_dir, ask_pass)
137137
assert(ssh_known_hosts, "ssh_known_hosts is required")
138138

139139
local hostname = host["HostName"] or host["Name"]
140+
141+
-- Build the hostname string for known_hosts lookup
142+
local lookup_host = hostname
143+
if host["Port"] and host["Port"] ~= "22" then
144+
lookup_host = "[" .. hostname .. "]:" .. host["Port"]
145+
end
140146

141147
-- Check if host is known
142-
local known_info = vim.fn.system { "ssh-keygen", "-F", hostname, "-f", ssh_known_hosts }
148+
local known_info = vim.fn.system { "ssh-keygen", "-F", lookup_host, "-f", ssh_known_hosts }
143149
if known_info:find "found" then
144-
print("Host key for " .. hostname .. " already known.")
145150
callback()
146-
return true
151+
return
147152
end
148153

149-
-- Get fingerprint
150-
local scan = vim.fn.system("ssh-keyscan -t ed25519 " .. hostname .. " 2>/dev/null")
151-
if scan == "" then
152-
vim.notify("Could not get fingerprint for " .. hostname, vim.log.levels.ERROR)
153-
return false
154+
-- Get all available key types from the host
155+
local scan_cmd = { "ssh-keyscan" }
156+
if host["Port"] then
157+
table.insert(scan_cmd, "-p")
158+
table.insert(scan_cmd, host["Port"])
159+
end
160+
table.insert(scan_cmd, hostname)
161+
162+
local scan_result = vim.fn.system(scan_cmd)
163+
if vim.v.shell_error ~= 0 or scan_result == "" then
164+
vim.notify("Could not retrieve host keys for " .. hostname, vim.log.levels.ERROR)
165+
return
166+
end
167+
168+
-- Parse the first key to get its fingerprint
169+
local first_key_line = vim.split(scan_result, "\n")[1]
170+
if not first_key_line or first_key_line == "" then
171+
vim.notify("No valid host keys found for " .. hostname, vim.log.levels.ERROR)
172+
return
154173
end
155174

156-
local fingerprint = vim.fn.system('echo "' .. scan .. '" | ssh-keygen -lf -')
157-
if fingerprint == "" then
175+
-- Create temporary file to get fingerprint
176+
local temp_file = vim.fn.tempname()
177+
local temp_handle = io.open(temp_file, "w")
178+
if not temp_handle then
179+
vim.notify("Could not create temporary file for fingerprint verification", vim.log.levels.ERROR)
180+
return
181+
end
182+
temp_handle:write(first_key_line .. "\n")
183+
temp_handle:close()
184+
185+
local fingerprint = vim.fn.system { "ssh-keygen", "-lf", temp_file }
186+
vim.fn.delete(temp_file)
187+
188+
if vim.v.shell_error ~= 0 or fingerprint == "" then
158189
vim.notify("Could not parse fingerprint for " .. hostname, vim.log.levels.ERROR)
159-
return false
190+
return
160191
end
161192
fingerprint = fingerprint:gsub("\n", "")
162193

163194
local prompt = string.format(
164-
"The authenticity of host '%s' can't be established. %s Add this host key to %s? (y/n)",
195+
"The authenticity of host '%s' can't be established.\n%s\nAdd this host key to %s? (y/n)",
165196
hostname,
166197
fingerprint,
167198
ssh_known_hosts
@@ -170,13 +201,29 @@ M.mount_host = function(host, mount_dir, ask_pass)
170201
ui.prompt_yes_no(prompt, function(item_short)
171202
ui.clear_prompt()
172203
if item_short == "y" then
173-
local scan_cmd = string.format("ssh-keyscan %s >> %s", hostname, ssh_known_hosts)
174-
local result = vim.fn.system(scan_cmd)
175-
if vim.v.shell_error == 0 then
176-
vim.notify("Host key added for " .. hostname, vim.log.levels.INFO)
177-
callback()
204+
local scan_cmd_final = { "ssh-keyscan" }
205+
if host["Port"] then
206+
table.insert(scan_cmd_final, "-p")
207+
table.insert(scan_cmd_final, host["Port"])
208+
end
209+
table.insert(scan_cmd_final, hostname)
210+
211+
local result = vim.fn.system(scan_cmd_final)
212+
if vim.v.shell_error == 0 and result ~= "" then
213+
local file_handle = io.open(ssh_known_hosts, "a")
214+
if file_handle then
215+
file_handle:write(result)
216+
if not result:match("\n$") then
217+
file_handle:write("\n")
218+
end
219+
file_handle:close()
220+
vim.notify("Host key added for " .. hostname, vim.log.levels.INFO)
221+
callback()
222+
else
223+
vim.notify("Failed to write to " .. ssh_known_hosts, vim.log.levels.ERROR)
224+
end
178225
else
179-
vim.notify("Failed to add host key for " .. hostname .. "\n" .. result, vim.log.levels.ERROR)
226+
vim.notify("Failed to retrieve host key for " .. hostname, vim.log.levels.ERROR)
180227
end
181228
else
182229
vim.notify("Aborted adding host key for " .. hostname, vim.log.levels.WARN)

0 commit comments

Comments
 (0)