nuageinit: add hostname validation (RFC 952/1123) to sethostname()
Validate hostnames before writing them: - Reject empty hostnames - Reject hostnames longer than 253 characters - Reject hostnames with invalid characters - Reject hostnames starting or ending with dot/hyphen - Reject labels longer than 63 characters - Reject labels starting or ending with hyphen Expand the sethostname test to cover all rejection cases. Update nuage.sh sethostname_body to ignore stderr (warnings).
This commit is contained in:
@@ -119,6 +119,33 @@ local function sethostname(hostname)
|
||||
if hostname == nil then
|
||||
return
|
||||
end
|
||||
-- Basic hostname validation (RFC 952/1123)
|
||||
if #hostname == 0 then
|
||||
warnmsg("hostname is empty, ignoring")
|
||||
return
|
||||
end
|
||||
if #hostname > 253 then
|
||||
warnmsg("hostname too long (" .. #hostname .. " > 253), ignoring")
|
||||
return
|
||||
end
|
||||
if hostname:match("[^a-zA-Z0-9%.%-]") then
|
||||
warnmsg("hostname contains invalid characters: " .. hostname)
|
||||
return
|
||||
end
|
||||
if hostname:match("^[%.%-]") or hostname:match("[%.%-]$") then
|
||||
warnmsg("hostname must not start or end with a dot or hyphen: " .. hostname)
|
||||
return
|
||||
end
|
||||
for label in hostname:gmatch("[^.]+") do
|
||||
if #label > 63 then
|
||||
warnmsg("hostname label too long (" .. #label .. " > 63): " .. label)
|
||||
return
|
||||
end
|
||||
if label:match("^-") or label:match("-$") then
|
||||
warnmsg("hostname label starts or ends with hyphen: " .. label)
|
||||
return
|
||||
end
|
||||
end
|
||||
local root = os.getenv("NUAGE_FAKE_ROOTDIR")
|
||||
if not root then
|
||||
root = ""
|
||||
|
||||
@@ -29,7 +29,7 @@ settimezone_body()
|
||||
|
||||
sethostname_body()
|
||||
{
|
||||
atf_check /usr/libexec/flua $(atf_get_srcdir)/sethostname.lua
|
||||
atf_check -e ignore /usr/libexec/flua $(atf_get_srcdir)/sethostname.lua
|
||||
if [ ! -f etc/rc.conf.d/hostname ]; then
|
||||
atf_fail "hostname not written"
|
||||
fi
|
||||
|
||||
@@ -1,5 +1,73 @@
|
||||
#!/usr/libexec/flua
|
||||
---
|
||||
-- SPDX-License-Identifier: BSD-2-Clause
|
||||
--
|
||||
-- Copyright (c) 2026 Baptiste Daroussin <bapt@FreeBSD.org>
|
||||
|
||||
local n = require("nuage")
|
||||
|
||||
local root = os.getenv("NUAGE_FAKE_ROOTDIR")
|
||||
if not root then
|
||||
root = ""
|
||||
end
|
||||
|
||||
local hostnamepath = root .. "/etc/rc.conf.d/hostname"
|
||||
|
||||
local function check_hostname(expected)
|
||||
local f = io.open(hostnamepath, "r")
|
||||
if not f then
|
||||
n.err("hostname file not found, expected: " .. expected)
|
||||
end
|
||||
local content = f:read("*a")
|
||||
f:close()
|
||||
local expected_content = 'hostname="' .. expected:gsub('"', '\\"') .. '"\n'
|
||||
if content ~= expected_content then
|
||||
n.err("hostname mismatch: got '" .. content ..
|
||||
"', expected '" .. expected_content .. "'")
|
||||
end
|
||||
end
|
||||
|
||||
local function check_no_hostname()
|
||||
if io.open(hostnamepath, "r") then
|
||||
n.err("hostname file should not exist")
|
||||
end
|
||||
end
|
||||
|
||||
-- nil hostname: no-op
|
||||
n.sethostname(nil)
|
||||
check_no_hostname()
|
||||
|
||||
-- Empty hostname: invalid
|
||||
n.sethostname("")
|
||||
check_no_hostname()
|
||||
|
||||
-- Hostname too long (>253 chars): invalid
|
||||
n.sethostname(string.rep("a", 254))
|
||||
check_no_hostname()
|
||||
|
||||
-- Invalid characters: invalid
|
||||
n.sethostname("host;name")
|
||||
check_no_hostname()
|
||||
|
||||
-- Starts with dot: invalid
|
||||
n.sethostname(".hostname")
|
||||
check_no_hostname()
|
||||
|
||||
-- Ends with hyphen: invalid
|
||||
n.sethostname("hostname-")
|
||||
check_no_hostname()
|
||||
|
||||
-- Label too long (>63 chars): invalid
|
||||
n.sethostname(string.rep("a", 64) .. ".example.com")
|
||||
check_no_hostname()
|
||||
|
||||
-- Label starts with hyphen: invalid
|
||||
n.sethostname("myhost.-label.com")
|
||||
check_no_hostname()
|
||||
|
||||
-- Valid simple hostname
|
||||
n.sethostname("myhostname")
|
||||
check_hostname("myhostname")
|
||||
|
||||
-- Final: set a valid hostname for the shell test
|
||||
n.sethostname("myhostname")
|
||||
|
||||
Reference in New Issue
Block a user