Jan reported that the microsoft dhcp server sends the domain name option
as a C string (i.e. NUL terminated) on-wire.
This then ends up in /var/db/dhcpleased/$IF as e.g.
domain-name: example.com\^@
which the installer uses to form /etc/myname which then later on smtpd
complains about.
I'm fresh out of microsoft dhcp servers, but this scapy script
demonstrates the problem:
from scapy.all import DHCP_am
from scapy.base_classes import Net
dhcp_server = DHCP_am(iface='carp0', domain='example.com\0',
pool=Net('192.168.10.0/24'),
network='192.168.10.0/24',
gw='192.168.10.254',
renewal_time=600, lease_time=3600)
dhcp_server()
RFC 2132, 2. BOOTP Extension/DHCP Option Field Format
Options containing NVT ASCII data SHOULD
NOT include a trailing NULL; however, the receiver of such options
MUST be prepared to delete trailing nulls if they exist. The
receiver MUST NOT require that a trailing null be included in the
data.
OK?
p.s. I'm happy to entertain diffs that ensure that the hostname and
domainname follow the rules of RFC 1034, 3.5. Preferred name syntax.
diff --git engine.c engine.c
index fa25fbbf0b9..dad299a0a6e 100644
--- engine.c
+++ engine.c
@@ -727,7 +727,7 @@ parse_dhcp(struct dhcpleased_iface *iface, struct imsg_dhcp
*dhcp)
size_t rem, i;
uint32_t sum, usum, lease_time = 0, renewal_time = 0;
uint32_t rebinding_time = 0;
- uint8_t *p, dho = DHO_PAD, dho_len;
+ uint8_t *p, dho = DHO_PAD, dho_len, slen;
uint8_t dhcp_message_type = 0;
int routes_len = 0, routers = 0, csr = 0;
char from[sizeof("xx:xx:xx:xx:xx:xx")];
@@ -1016,7 +1016,11 @@ parse_dhcp(struct dhcpleased_iface *iface, struct
imsg_dhcp *dhcp)
case DHO_HOST_NAME:
if ( dho_len < 1)
goto wrong_length;
- strvisx(hostname, p, dho_len, VIS_SAFE);
+ /* MUST delete trailing NUL, per RFC 2132 */
+ slen = dho_len;
+ while (p[slen - 1] == '\0')
+ slen--;
+ strvisx(hostname, p, slen, VIS_SAFE);
if (log_getverbose() > 1)
log_debug("DHO_HOST_NAME: %s", hostname);
p += dho_len;
@@ -1025,7 +1029,11 @@ parse_dhcp(struct dhcpleased_iface *iface, struct
imsg_dhcp *dhcp)
case DHO_DOMAIN_NAME:
if ( dho_len < 1)
goto wrong_length;
- strvisx(domainname, p, dho_len, VIS_SAFE);
+ /* MUST delete trailing NUL, per RFC 2132 */
+ slen = dho_len;
+ while (p[slen - 1] == '\0')
+ slen--;
+ strvisx(domainname, p, slen, VIS_SAFE);
if (log_getverbose() > 1)
log_debug("DHO_DOMAIN_NAME: %s", domainname);
p += dho_len;
--
I'm not entirely sure you are real.