Discussion:
lpd with clients using "privacy" addresses
(too old to reply)
Ignatios Souvatzis
2011-03-25 14:35:39 UTC
Permalink
Hi,

I noticed that modern Windows machines couldn't lpr-print via our
lpd anymore after upgrading it to dual-stack.

The reason is that a) Windows (post-XP) has privacy addresses and
interface id randomization enabled per default, and especially the
former somehow don't make it easy (or actually, desirable) to have
matching forward and backward resolved names in DNS.

OTOH, lpd checks for matching reverse and forward resolved names
*before* checking whether it needs to test for an explicit hostname.

The patch below makes this test, but saves the result for later, and
checks for a '+'-Entry in /etc/hosts.lpd or /etc/hosts.equiv if
needed.

This is in production use at my (work) institution.

You still need a reverse DNS entry, but this alone can be easily done
with a catch-all like

* IN PTR unknown-vlan169.department.institution.example.

(The planned big rewriting/replacing of lpd should take this situation
into account btw. - but I need a solution *now* for the existing one.)


I plan to commit next week. Comments?

-is


Index: lpd.8
===================================================================
RCS file: /cvsroot/src/usr.sbin/lpr/lpd/lpd.8,v
retrieving revision 1.33
diff -u -r1.33 lpd.8
--- lpd.8 22 Jan 2006 21:31:17 -0000 1.33
+++ lpd.8 25 Mar 2011 14:25:14 -0000
@@ -177,6 +177,9 @@
.Pa /etc/hosts.equiv
or
.Pa /etc/hosts.lpd .
+A machine using IPv6 privacy addresses (which, by definition, can't have
+name resolution in both directions) will match a '+' host entry, if the
+reverse zone has at least a catch-all name.
Lastly, if the
.Li rs
capability is specified in the
@@ -186,6 +189,7 @@
requests will only be honored for those users with accounts on the
machine with the printer.
Requests must pass all three tests.
+
.Pp
The file
.Em minfree
Index: lpd.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/lpr/lpd/lpd.c,v
retrieving revision 1.55
diff -u -r1.55 lpd.c
--- lpd.c 21 Jul 2008 13:36:58 -0000 1.55
+++ lpd.c 25 Mar 2011 14:25:14 -0000
@@ -133,6 +133,7 @@
static void chkhost(struct sockaddr *, int);
static void usage(void);
static struct pollfd *socksetup(int, int, const char *, int *);
+static void chkplushost(int, FILE *, char*);

uid_t uid, euid;
int child_count;
@@ -362,6 +363,35 @@
}
}

+/*
+ * If there was a forward/backward name resolution mismatch, check
+ * that there's a '+' entry in fhost.
+ */
+
+void
+chkplushost(int good, FILE *fhost, char *hst)
+{
+ int c1, c2, c3;
+
+ if (good) {
+ return;
+ }
+
+ rewind(fhost);
+ while (EOF != (c1 = fgetc(fhost))) {
+ if (c1 == '+') {
+ c2 = fgetc(fhost);
+ if (c2 == ' ' || c2 == '\t' || c2 == '\n') {
+ return;
+ }
+ }
+ do {
+ c3 = fgetc(fhost);
+ } while (c3 != EOF && c3 != '\n');
+ }
+ fatal("address for your hostname (%s) not matched", hst);
+}
+
static void
reapchild(int signo)
{
@@ -606,25 +636,23 @@
fatal("Cannot print address");

/* Check for spoof, ala rlogind */
+ good = 0;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
error = getaddrinfo(fromb, NULL, &hints, &res);
- if (error) {
- fatal("hostname for your address (%s) unknown: %s", hst,
- gai_strerror(error));
+ if (!error) {
+ for (r = res; good == 0 && r; r = r->ai_next) {
+ error = getnameinfo(r->ai_addr, r->ai_addrlen,
+ ip, sizeof(ip), NULL, 0, NI_NUMERICHOST);
+ if (!error && !strcmp(hst, ip))
+ good = 1;
+ }
+ if (res)
+ freeaddrinfo(res);
}
- good = 0;
- for (r = res; good == 0 && r; r = r->ai_next) {
- error = getnameinfo(r->ai_addr, r->ai_addrlen, ip, sizeof(ip),
- NULL, 0, NI_NUMERICHOST);
- if (!error && !strcmp(hst, ip))
- good = 1;
- }
- if (res)
- freeaddrinfo(res);
- if (good == 0)
- fatal("address for your hostname (%s) not matched", hst);
+
+ /* complain about !good later in chkplushost if needed. */

setproctitle("serving %s", from);

@@ -639,6 +667,7 @@
hostf = fopen(_PATH_HOSTSEQUIV, "r");
if (hostf) {
if (__ivaliduser_sa(hostf, f, f->sa_len, DUMMY, DUMMY) == 0) {
+ chkplushost(good, hostf, hst);
(void)fclose(hostf);
return;
}
@@ -647,6 +676,7 @@
hostf = fopen(_PATH_HOSTSLPD, "r");
if (hostf) {
if (__ivaliduser_sa(hostf, f, f->sa_len, DUMMY, DUMMY) == 0) {
+ chkplushost(good, hostf, hst);
(void)fclose(hostf);
return;
}

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
der Mouse
2011-03-25 16:29:27 UTC
Permalink
I noticed that modern Windows machines couldn't lpr-print via our lpd
anymore after upgrading it to dual-stack.
The reason is that a) Windows (post-XP) has privacy addresses and
interface id randomization enabled per default, and especially the
former somehow don't make it easy (or actually, desirable) to have
matching forward and backward resolved names in DNS.
OTOH, lpd checks for matching reverse and forward resolved names
*before* checking whether it needs to test for an explicit hostname.
[...]. Comments?
Comments?

I would say lpd is the canary in the coalmine. The right thing to do
is to fix your rDNS - to fix, work around, or stop using whatever is
breaking it. Patching lpd is basically sticking your fingers in your
ears and going LA LA LA I CAN'T HEAR YOU when lpd is points out the
brokenness.
+A machine using IPv6 privacy addresses (which, by definition, can't have
+name resolution in both directions)
This actually is not true.

Privacy addresses are about tracking - or, more precisely, preventing
tracking - whether the node making a given transaction is the smae as
the node that made some past transaction.

DNS resolution has just about nothing to do with this. If you think it
does, I suspect you are thinking of the DNS name as being tied to the
node rather than to the address; there's no reason a privacy address
couldn't have a forward name pointing to it and a reverse name pointing
back, and this breaks the privacy goal only if the name (or the
address) is somehow tied to the node in question.

But if a node uses ...:ecfe:8270:659b:9f01, which has the name
ecfe-8270-659b-9f01.privacy.example.com with full forward and reverse
DNS, this says nothing about whether it is the same node as the one
that used ...:e017:114f:8dad:edab with name
e017-114f-8dad-edab.privacy.example.com in the past. It wouldn't even
be very hard to set up the DNS. I could probably do it as a BIND
backend in an afternoon (hm, maybe two afternoons; it's been a while
since I mucked about with BIND backends); someone familiar with the
backend interface of other DNS servers could probably do likewise with
them.

Is it worth doing that? Maybe. Depends on the tradeoffs for the
environment in question. Personally, I think that the degree of
paranoia that inheres in wanting to use privacy addresses of this sort
is inconsistent with a desire to communicate with general-purpose
peers.

I don't expect everyone to agree. In fact, given past trends, I would
be surprised if more than a handful of people agreed.

But those are my comments.

/~\ The ASCII Mouse
\ / Ribbon Campaign
X Against HTML ***@rodents-montreal.org
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Ignatios Souvatzis
2011-03-29 05:54:05 UTC
Permalink
Post by der Mouse
I would say lpd is the canary in the coalmine. The right thing to do
is to fix your rDNS - to fix, work around, or stop using whatever is
breaking it. Patching lpd is basically sticking your fingers in your
ears and going LA LA LA I CAN'T HEAR YOU when lpd is points out the
brokenness.
I read your comments, and in general, I agree with the basic requirement,
that one element of rDNS should agree with one element of DNS.

But I don't think this should apply in the case we're talking about:

$(cat /etc/hosts.lpd) -eq '+')

Here

a) we shouldn't check host names at all (and the only conceptionally
ugly part is where I continue to use rDNS; I should check whether using
a string representation of the host name works);

b) if the lpd's administrator really wants to accept print jobs from
anonymous hosts that set up meaningless, but matching forward and
reverse DNS, they can do this (actually for all or a subset of libwrap-using
services (all inetd-called and lpd being some of them)) using a
PARANOID rule with the right polarity in /etc/hosts.allow (or
/etc/hosts.deny).

Regards,
-is

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Loading...