Commit Graph

63 Commits

Author SHA1 Message Date
Lennart Poettering ae2a15bc14 macro: introduce TAKE_PTR() macro
This macro will read a pointer of any type, return it, and set the
pointer to NULL. This is useful as an explicit concept of passing
ownership of a memory area between pointers.

This takes inspiration from Rust:

https://doc.rust-lang.org/std/option/enum.Option.html#method.take

and was suggested by Alan Jenkins (@sourcejedi).

It drops ~160 lines of code from our codebase, which makes me like it.
Also, I think it clarifies passing of ownership, and thus helps
readability a bit (at least for the initiated who know the new macro)
2018-03-22 20:21:42 +01:00
Lennart Poettering 59f2725cc8 resolved: fix "in-between" logic when boundaries are equal (#7590)
This changes dns_name_between() to deal properly with checking whether B
is between A and C if A and C are equal. Previously we simply returned
-EINVAL in this case, refusing checking. With this change we correct
behaviour: if A and C are equal, then B is "between" both if it is
different from them. That's logical, since we do < and > comparisons, not
<= and >=, and that means that anything "right of A" and "left of C"
lies in between with wrap-around at the ends. And if A and C are equal
that means everything lies between, except for A itself.

This fixes handling of domains using NSEC3 "white lies", for example the
.it TLD.

Fixes: #7421
2017-12-14 14:08:21 +09:00
Dmitry Rozhkov 154ae08781 shared: introduce dnssd_srv_type_is_valid() function 2017-12-08 14:29:27 +02:00
Zbigniew Jędrzejewski-Szmek 53e1b68390 Add SPDX license identifiers to source files under the LGPL
This follows what the kernel is doing, c.f.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5fd54ace4721fc5ce2bb5aef6318fcf17f421460.
2017-11-19 19:08:15 +01:00
Lennart Poettering 4aa1d31c89 Merge pull request #6974 from keszybz/clean-up-defines
Clean up define definitions
2017-10-04 19:25:30 +02:00
Yu Watanabe 4c70109600 tree-wide: use IN_SET macro (#6977) 2017-10-04 16:01:32 +02:00
Zbigniew Jędrzejewski-Szmek 349cc4a507 build-sys: use #if Y instead of #ifdef Y everywhere
The advantage is that is the name is mispellt, cpp will warn us.

$ git grep -Ee "conf.set\('(HAVE|ENABLE)_" -l|xargs sed -r -i "s/conf.set\('(HAVE|ENABLE)_/conf.set10('\1_/"
$ git grep -Ee '#ifn?def (HAVE|ENABLE)' -l|xargs sed -r -i 's/#ifdef (HAVE|ENABLE)/#if \1/; s/#ifndef (HAVE|ENABLE)/#if ! \1/;'
$ git grep -Ee 'if.*defined\(HAVE' -l|xargs sed -i -r 's/defined\((HAVE_[A-Z0-9_]*)\)/\1/g'
$ git grep -Ee 'if.*defined\(ENABLE' -l|xargs sed -i -r 's/defined\((ENABLE_[A-Z0-9_]*)\)/\1/g'
+ manual changes to meson.build

squash! build-sys: use #if Y instead of #ifdef Y everywhere

v2:
- fix incorrect setting of HAVE_LIBIDN2
2017-10-04 12:09:29 +02:00
Zbigniew Jędrzejewski-Szmek 0926f3489d resolved: make sure idn2 conversions are roundtrippable
While working on the gateway→_gateway conversion, I noticed that
libidn2 strips the leading underscore in some names.
https://gitlab.com/libidn/libidn2/issues/30 was resolved in
05d753ea69,
which disabled "STD3 ASCII rules" by default, i.e. disabled stripping
of underscores. So the situation is that with previously released libidn2
versions we would get incorrect behaviour, and once new libidn2 is released,
we should be OK.

Let's implement a simple test which checks that the name survives the
roundtrip, and if it doesn't, skip IDN resolution. Under old libidn2 this will
fail in more cases, and under new libidn2 in fewer, but should be the right
thing to do also under new libidn2.
2017-07-21 08:00:23 -04:00
Zbigniew Jędrzejewski-Szmek ad1f3fe6a8 resolved: allow resolution of names which libidn2 considers invalid (#6315)
https://tools.ietf.org/html/rfc5891#section-4.2.3.1 says that
> The Unicode string MUST NOT contain "--" (two consecutive hyphens) in the third
> and fourth character positions and MUST NOT start or end with a "-" (hyphen).
This means that libidn2 refuses to encode such names.
Let's just resolve them without trying to use IDN.
2017-07-11 10:42:21 +02:00
Zbigniew Jędrzejewski-Szmek 87057e244b resolved: support libidn2 in addition to libidn
libidn2 2.0.0 supports IDNA2008, in contrast to libidn which supports IDNA2003.

https://bugzilla.redhat.com/show_bug.cgi?id=1449145
From that bug report:

Internationalized domain names exist for quite some time (IDNA2003), although
the protocols describing them have evolved in an incompatible way (IDNA2008).
These incompatibilities will prevent applications written for IDNA2003 to
access certain problematic domain names defined with IDNA2008, e.g., faß.de is
translated to domain xn--fa-hia.de with IDNA2008, while in IDNA2003 it is
translated to fass.de domain. That not only causes incompatibility problems,
but may be used as an attack vector to redirect users to different web sites.

v2:
- keep libidn support
- require libidn2 >= 2.0.0
v3:
- keep dns_name_apply_idna caller dumb, and keep the #ifdefs inside of the
  function.
- use both ±IDN and ±IDN2 in the version string
2017-05-11 14:25:01 -04:00
Lennart Poettering 08a4849ec9 shared: add new API to validate a string as hostname or IP address 2016-11-21 22:58:26 +01:00
Zbigniew Jędrzejewski-Szmek 605405c6cc tree-wide: drop NULL sentinel from strjoin
This makes strjoin and strjoina more similar and avoids the useless final
argument.

spatch -I . -I ./src -I ./src/basic -I ./src/basic -I ./src/shared -I ./src/shared -I ./src/network -I ./src/locale -I ./src/login -I ./src/journal -I ./src/journal -I ./src/timedate -I ./src/timesync -I ./src/nspawn -I ./src/resolve -I ./src/resolve -I ./src/systemd -I ./src/core -I ./src/core -I ./src/libudev -I ./src/udev -I ./src/udev/net -I ./src/udev -I ./src/libsystemd/sd-bus -I ./src/libsystemd/sd-event -I ./src/libsystemd/sd-login -I ./src/libsystemd/sd-netlink -I ./src/libsystemd/sd-network -I ./src/libsystemd/sd-hwdb -I ./src/libsystemd/sd-device -I ./src/libsystemd/sd-id128 -I ./src/libsystemd-network --sp-file coccinelle/strjoin.cocci --in-place $(git ls-files src/*.c)

git grep -e '\bstrjoin\b.*NULL' -l|xargs sed -i -r 's/strjoin\((.*), NULL\)/strjoin(\1)/'

This might have missed a few cases (spatch has a really hard time dealing
with _cleanup_ macros), but that's no big issue, they can always be fixed
later.
2016-10-23 11:43:27 -04:00
Martin Pitt f35c467db3 shared: recognize DNS names with more than one trailing dot as invalid (#4111)
One trailing dot is valid, but more than one isn't. This also fixes glibc's
posix/tst-getaddrinfo5 test.

Fixes #3978.
2016-09-09 16:11:54 +01:00
Vito Caputo 313cefa1d9 tree-wide: make ++/-- usage consistent WRT spacing
Throughout the tree there's spurious use of spaces separating ++ and --
operators from their respective operands.  Make ++ and -- operator
consistent with the majority of existing uses; discard the spaces.
2016-02-22 20:32:04 -08:00
Michael Biebl c629ff587b Typo fixes 2016-02-12 00:26:37 +01:00
Daniel Mack b26fa1a2fb tree-wide: remove Emacs lines from all files
This should be handled fine now by .dir-locals.el, so need to carry that
stuff in every file.
2016-02-10 13:41:57 +01:00
Lennart Poettering 3a519900e1 shared: normalize the root domain to "." rather than ""
Let's make sure the root domain is normalized to ".", rather than then empty string, so that there's actually something
to see on screen. Normally, we don't append a trailing dot to normalized domain names, but do so in the one exception
of the root domain, taking inspiration from UNIX file system paths.
2016-01-26 14:42:04 +01:00
Lennart Poettering 23b298bce7 resolved: rework IDNA logic
Move IDNA logic out of the normal domain name processing, and into the bus frontend calls. Previously whenever
comparing two domain names we'd implicitly do IDNA conversion so that "pöttering.de" and "xn--pttering-n4a.de" would be
considered equal. This is problematic not only for DNSSEC, but actually also against he IDNA specs.

Moreover it creates problems when encoding DNS-SD services in classic DNS. There, the specification suggests using
UTF8 encoding for the actual service name, but apply IDNA encoding to the domain suffix.

With this change IDNA conversion is done only:

- When the user passes a non-ASCII hostname when resolving a host name using ResolveHostname()
- When the user passes a non-ASCII domain suffix when resolving a service using ResolveService()

No IDNA encoding is done anymore:

- When the user does raw ResolveRecord() RR resolving
- On the service part of a DNS-SD service name

Previously, IDNA encoding was done when serializing names into packets, at a point where information whether something
is a label that needs IDNA encoding or not was not available, but at a point whether it was known whether to generate a
classic DNS packet (where IDNA applies), or an mDNS/LLMNR packet (where IDNA does not apply, and UTF8 is used instead
for all host names). With this change each DnsQuery object will now maintain two copies of the DnsQuestion to ask: one
encoded in IDNA for use with classic DNS, and one encoded in UTF8 for use with LLMNR and MulticastDNS.
2016-01-18 23:31:16 +01:00
Lennart Poettering 0cf40f5527 resolved add dns_name_apply_idna() to convert a domain name into its IDNA equivalent 2016-01-18 23:31:15 +01:00
Lennart Poettering b9282bc128 resolved: on negative NODATA replies, properly deal with empty non-terminals
empty non-terminals generally lack NSEC RRs, which means we can deduce their existance only from the fact that there
are other RRs that contain them in their suffix. Specifically, the NSEC proof for NODATA on ENTs works by sending the
NSEC whose next name is a suffix of the queried name to the client. Use this information properly.
2016-01-17 20:47:46 +01:00
Lennart Poettering 97c67192ea resolved: when validating an RRset, store information about the synthesizing source and zone in each RR
Having this information available is useful when we need to check whether various RRs are suitable for proofs. This
information is stored in the RRs as number of labels to skip from the beginning of the owner name to reach the
synthesizing source/signer. Simple accessor calls are then added to retrieve the signer/source from the RR using this
information.

This also moves validation of a a number of RRSIG parameters into a new call dnssec_rrsig_prepare() that as side-effect
initializes the two numeric values.
2016-01-17 20:47:45 +01:00
Lennart Poettering 81ec9e0887 shared: reuse dns_label_unescape_undo_idna() in more places
We frequently unescape DNS label follwed by IDNA undoing. We now have a function that does that in one step, hence use
it everywhere.
2016-01-13 20:45:58 +01:00
Lennart Poettering 45c4210ed6 shared: simplify string concatenation with strjoin() 2016-01-13 20:45:20 +01:00
Lennart Poettering 34361485a8 shared: port dns_name_compare_func() to make use of ascii_strcasecmp_nn()
This way we become compatible with DNS names with embedded NUL bytes.
2016-01-13 20:22:32 +01:00
Lennart Poettering f6fbd9c21f shared: simplify dns_name_is_single_label() by using dns_name_parent() to skip first label 2016-01-13 20:22:32 +01:00
Lennart Poettering 3095011d15 shared: replace a few invocations of strcasecmp() for DNS labels with ascii_strcasecmp_n()
This makes our code compatible with embedded NUL bytes, as we don't care about NUL bytes anymore.
2016-01-13 20:22:32 +01:00
Lennart Poettering eb241cdbee shared: add new dns_name_startswith() call
dns_name_startswith() is to dns_name_endswith() as startswith() is to endswith().
2016-01-13 20:21:56 +01:00
Lennart Poettering d51155663a shared: make sure foo.bar and foobar result in different domain name hashes
This also introduces a new macro siphash24_compress_byte() which is useful to add a single byte into the hash stream,
and ports one user over to it.
2016-01-11 19:39:59 +01:00
Lennart Poettering d12315a4c8 shared: simplify dns_name_hash_func() end of name detection 2016-01-11 19:39:59 +01:00
Lennart Poettering 509eddd202 resolved: make sure domain name hash function deals nicely with NUL embedded in labels 2016-01-11 19:39:59 +01:00
Lennart Poettering b577e3d589 basic: introduce generic ascii_strlower_n() call and make use of it everywhere 2016-01-11 19:39:59 +01:00
Lennart Poettering c7feab7647 shared: relax restrictions on valid domain name characters a bit
Previously, we'd not allow control characters to be embedded in domain
names, even when escaped. Since cloudflare uses \000 however to
implement its synthethic minimally covering NSEC RRs, we should allow
them, as long as they are properly escaped.
2015-12-28 14:46:39 +01:00
Lennart Poettering 5651285934 shared: fix handling of suffix "." in dns_name_compare_func()
All our other domain name handling functions make no destinction between
domain names that end in a dot plus a NUL, or those just ending in a
NUL. Make sure dns_name_compare_func() and dns_label_unescape_suffix()
do the same.
2015-12-27 01:41:39 +01:00
Lennart Poettering 735323d9d3 shared: fix error propagation in dns_name_compare_func() 2015-12-26 19:09:11 +01:00
Lennart Poettering db5b0e92b3 resolved: tighten search for NSEC3 RRs a bit
Be stricter when searching suitable NSEC3 RRs for proof: generalize the
check we use to find suitable NSEC3 RRs, in nsec3_is_good(), and add
additional checks, such as checking whether all NSEC3 RRs use the same
parameters, have the same suffix and so on.
2015-12-26 19:09:10 +01:00
Lennart Poettering e7ff0e0b39 resolved: properly implement RRSIG validation of wildcarded RRsets
Note that this is still not complete, one additional step is still
missing: when we verified that a wildcard RRset is properly signed, we
still need to do an NSEC/NSEC3 proof that no more specific RRset exists.
2015-12-26 19:09:10 +01:00
Lennart Poettering f7455baa01 shared: add dns_name_parent() call to determine parent domain of a domain 2015-12-18 14:48:49 +01:00
Thomas Hindoe Paaboel Andersen a8fbdf5424 shared: include what we use
The next step of a general cleanup of our includes. This one mostly
adds missing includes but there are a few removals as well.
2015-12-06 13:49:33 +01:00
Lennart Poettering 3cd03457bd util-lib: update dns_name_to_wire_format() to optionally generate DNSSEC canonical names
We'll need this later when putting together RR serializations to
checksum.
2015-12-02 22:50:11 +01:00
Lennart Poettering 37ade12837 dns-domain: change error codes when dealing with too short buffers to ENOBUFS
Some calls used ENOBUFS to indicate too-short result buffers, others
used ENOSPC. Let's unify this on ENOBUFS.
2015-11-30 19:42:35 +01:00
Lennart Poettering 50dee79bfb dns-domain: check resulting domain name length in dns_name_to_wire_format()
Let's better be safe than sorry.
2015-11-30 19:42:35 +01:00
Lennart Poettering c6cefd13eb dns-domain: make sure dns_name_to_wire_format() may properly encode the root domain
The root domain consists of zero labels, and we should be able to encode
that.
2015-11-30 19:42:35 +01:00
Lennart Poettering 1dfbf0007a dns-domain: don't accept overly long hostnames
Make sure dns_name_normalize(), dns_name_concat(), dns_name_is_valid()
do not accept/generate invalidly long hostnames, i.e. longer than 253
characters.
2015-11-30 19:42:35 +01:00
Lennart Poettering 3b37fa7352 dns-domain: be more strict when encoding/decoding labels
Labels of zero length are not OK, refuse them early on. The concept of a
"zero-length label" doesn't exist, a zero-length full domain name
however does (representing the root domain). See RFC 2181, Section 11.
2015-11-30 19:37:41 +01:00
Thomas Hindoe Paaboel Andersen ae96c4eb2c tree-wide: remove unused variables 2015-11-29 08:59:40 +01:00
Lennart Poettering 422baca0f2 dns-domain: rework dns_label_escape() to not imply memory allocation
The new dns_label_escape() call now operates on a buffer passed in,
similar to dns_label_unescape(). This should make decoding a bit faster,
and nicer.
2015-11-25 22:00:07 +01:00
Lennart Poettering 7e8131e9c6 dns-domain: change dns_srv_type_is_valid() return value to bool
For similar reasons as dns_name_is_root() got changed in the previous
commit.
2015-11-25 22:00:07 +01:00
Lennart Poettering dc477e7385 dns-domain: simplify dns_name_is_root() and dns_name_is_single_label()
Let's change the return value to bool. If we encounter an error while
parsing, return "false" instead of the actual parsing error, after all
the specified hostname does not qualify for what the function is
supposed to test.

Dealing with the additional error codes was always cumbersome, and
easily misused, like for example in the DHCP code.

Let's also rename the functions from dns_name_root() to
dns_name_is_root(), to indicate that this function checks something and
returns a bool. Similar for dns_name_is_signal_label().
2015-11-25 22:00:07 +01:00
Lennart Poettering 58db254ade resolved: implement client-side DNAME resolution
Most servers apparently always implicitly convert DNAME to CNAME, but
some servers don't, hence implement this properly, as this is required
by edns0.
2015-11-24 00:20:39 +01:00
Lennart Poettering 0e8eedbb49 dns-domain: add calls to join/split SRV/DNS-SD service domains
This adds dns_service_join() and dns_service_split() which may be used
to concatenate a DNS-SD service name, am SRV service type string, and a
domain name into a full resolvable DNS domain name string. If the
service name is specified as NULL, only the type and domain are
appended, to implement classic, non-DNS-SD SRV lookups.

The reverse is dns_service_split() which takes the full name, and split
it into the three components again.
2015-11-23 21:31:29 +01:00