So far there's only one multi-line abstract. But as pointed out in the
review, it's silly to handle footer but not the abstract.
help_abstract() is not reused because it only works with one-line
abstracts. (It always prints an empty line to separate paragraphs.)
So the formatting is done anew in print_wrapped(). I think this is OK,
since it's all very simple. After everything has been converted to
COMMAND() and its helpers, help_abstract() and the sister functions will
become unused and can be dropped then.
Before this series, many help() functions opened the pager. This got lost
in the translation. Starting the pager requires access to arg_pager_flags.
While we could pipe this through in case when command_print_help() is
called directly, but this hard in the case when verb_help_auto() or
VERB_COMMON_HELP_AUTO/VERB_COMMON_HELP_AUTO_HIDDEN are used. Let's instead
extend the (const static) CommandDescription structure with a pointer to
the arg_pager_flags variable. This restores the pager functionality in a
uniform fashion with a one-line change in the individual binaries.
Previously, the systemd-resolve compat alias was described in the same
CommandDescription structure and resolvectl. But they have different
option sets, so this doesn't really work. The alias is deprecated, so
describe it as such in the abstract, but give it a separate entry.
$ build/resolvectl --introspect-cli
{
"mediaType": "application/vnd.io.systemd.cli-introspection-0",
"commands": [
{
"names": [ "resolvconf" ],
"abstract": [
"Register DNS server and domain configuration with systemd-resolved."
],
...
},
{
"names": [ "resolvectl" ],
"abstract": [
"Send control commands to the network name resolution manager, or\nresolve domain names, IPv4 and IPv6 addresses, DNS records, and services."
],
...
},
{
"names": [ "systemd-resolve" ],
"abstract": [
"Send control commands to the network name resolution manager, or\nresolve domain names, IPv4 and IPv6 addresses, DNS records, and services.\n\nThis command is deprecated. Use resolvectl.1 instead."
],
...
}
]
}
--raw only affects ResolveRecord output. Without --type= or an
RFC4501 dns: URI, query takes the ResolveHostname/ResolveAddress
paths, where --raw was silently ignored.
Reproducer:
build/resolvectl --raw query localhost
Before:
The command exited successfully and printed regular text output,
such as:
localhost: 127.0.0.1
After:
The command fails before issuing a lookup:
--raw may only be combined with --type= or dns: URIs.
Follow-up for: 05ea7e87b6
The service verb documents the one- and two-argument forms as
SRV lookups. They should not request TXT records by default.
Only the three-argument DNS-SD form should request TXT metadata.
Reproducer:
Run resolvectl service _mysvc._tcp signed.test in the
TEST-75-RESOLVED environment, where signed.test contains:
_mysvc._tcp SRV 10 5 1234 myservice
_mysvc._tcp TXT "This is TXT for myservice"
myservice A 10.0.0.20
Before:
resolvectl service _mysvc._tcp signed.test printed TXT data
for the plain SRV form:
_mysvc._tcp/signed.test: myservice.signed.test:1234 [priority=10, weight=5]
10.0.0.20
fd00:dead:beef:cafe::17
This is TXT for myservice
After:
The plain SRV form suppresses TXT data. The DNS-SD form still
shows it:
resolvectl service '' _mysvc._tcp signed.test
Follow-up for: a7a4c60a25
The tlsa command accepts an optional service family before the domain list.
When the only argument was "tcp", "udp", or "sctp", we consumed it as the
family and returned success without issuing any query.
Reproducer:
build/resolvectl tlsa tcp
Before: the command printed nothing and exited with status 0.
Follow-up for: ebbc70e511
When --json is requested, resolution errors returned by resolved still went
through text logging. That made scripts parse stderr even though the
varlink error already carried structured fields such as rcode and EDE.
Add a small JSON error dumper for resolvectl query errors. It outputs the
queried name and varlink error id alongside the original varlink parameters
so DNSError and DNSSECValidationFailed expose rcode, extendedDNSErrorCode,
extendedDNSErrorMessage, queryString, and result without duplicating the
schema in resolvectl.
Keep non-JSON text output and silent warn_missing NXDOMAIN handling
unchanged. Document the JSON resolution error object in resolvectl(1),
including the distinction between resolved errors and local invocation or
connection errors.
Closes#42904
The openpgp and tlsa verbs rejected --json= even though they
already determine the RR type they query. Allow JSON output for
these shortcut commands.
Accept matching explicit --type= values as well, but reject
mismatched types so openpgp only queries OPENPGPKEY records and
tlsa only queries TLSA records.
Refuse unauthenticated key records in JSON format so scripts do
not accidentally consume cryptographic DNS data that would only
produce a warning in human-readable output.
Fixes#43245
Since 4c0d8d9673, most dlopen notes are
set at the beginning of the executables. Let's manage all dlopen notes
there, rather than setting them where dlopen is called.
Note that the only exceptions are the LIBBPF_NOTE for networkd and
nsresource. Since dlopen_bpf() is wrapped in an `#if` guard, the notes
are instead set within the corresponding functionality.
As a result, the DLOPEN_FOO() wrapper macros are no longer needed and
can be dropped completely.
Previously, when a library was dynamically loaded via a helper function
inside libsystemd-shared.so, the resulting dlopen ELF note was not
propagated to the invoking executable's ELF metadata.
This commit explicitly annotates each executable with the relevant
dlopen ELF notes for any optional dependencies it might potentially
load. This ensures that package managers and build systems can properly
discover runtime dependencies that are triggered indirectly.
varlink_call_and_log() does not hand out a new reference for the reply
object, so the caller should not unref it. The _cleanup_(sd_json_variant_unrefp)
on reply was therefore wrong from the start.
The original TAKE_PTR(reply) was working around this incorrect cleanup
by preventing it from firing, but that left reply's refcount one too
high after sd_json_variant_ref(v) incremented the parent's count.
Fix by dropping _cleanup_(sd_json_variant_unrefp) from the reply
variable declaration entirely, as suggested by Lennart Poettering.
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
There are several places where address family is dispatched from JSON,
so take json_dispatch_address_family from networkd and put it in
json-util.c.
Update the all instances in the tree to use this new function, adding
SD_JSON_RELAX to the dispatch flags if AF_UNSPEC should be allowed
in that case.
Use OPTION_NAMESPACE() to keep the resolvectl and systemd-resolve
option sets separate. The resolvconf-compat path (resolvconf
invocation) keeps its own getopt-based parsing.
--help output has the expected changes to formatting. Synopis
for [status] is now shows that the verb is optional.
Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
Until now OpenSSL was linked into every binary and library that needed
cryptography, pulling libcrypto (and, for resolved, libssl) into the
address space of services that never touch them at runtime. This commit
moves all OpenSSL usage behind the same dlopen helper pattern that we
already use for other optional libraries (libpam, libseccomp, libxz, …)
so libcrypto/libssl are only loaded on demand.
The bulk of the work lives in src/shared/crypto-util.{c,h} (libcrypto)
and src/shared/ssl-util.{c,h} (libssl), which replace the previous
src/shared/openssl-util.{c,h}:
- crypto-util.{c,h} declares every libcrypto function we call via
DLSYM_PROTOTYPE() and resolves them inside dlopen_libcrypto().
- ssl-util.{c,h} holds the libssl-specific DLSYM_PROTOTYPEs,
dlopen_libssl(), and the SSL_freep cleanup helper, so translation
units that only need libcrypto do not pull in libssl declarations.
- Callers refer to the symbols through sym_* aliases rather than the
original names.
- Convenience macros that used to be provided by the OpenSSL headers
(OPENSSL_free, BN_num_bytes, the sk_TYPE_* helpers, …) are
reimplemented as sym_* wrappers so no code path needs to fall back
to the linker-resolved symbols.
- All _cleanup_ helpers are redefined in terms of the sym_* variants
(EVP_PKEY_freep, X509_freep, BIO_freep, …) so cleanup attributes
keep working without pulling in libcrypto symbols at link time.
- The public crypto-util.c entry points (openssl_pubkey_from_pem,
openssl_digest_many, openssl_hmac_many, openssl_cipher_many,
kdf_ss_derive, kdf_kb_hmac_derive, rsa_* / ecc_* helpers,
pubkey_fingerprint, digest_and_sign, pkcs7_new, x509_fingerprint,
openssl_extract_public_key, pkey_generate_volume_keys, the load_*
helpers, …) now call dlopen_libcrypto() at entry before touching any
sym_* pointer.
The call sites across the tree have been converted to call
dlopen_libcrypto()/dlopen_libssl() at the appropriate entry point
before their first sym_* use, and to use sym_* variants throughout:
- bootctl, sbsign, measure, pcrlock, pcrextend, tpm2-setup, repart,
cryptsetup, cryptenroll, homectl, homed, homework, keyutil,
sysupdate, creds, import, dissect-image, pe-binary, pkcs11-util,
pkcs7-util, tpm2-util, creds-util. resolved additionally dlopens
libssl for DoT.
The meson build files are updated to depend on libopenssl_cflags (a
new partial dependency that exposes include paths and compile flags
only, not the linker flags) instead of libopenssl for every target that
previously linked against OpenSSL. Nothing links against libcrypto or
libssl directly anymore.
A new src/sbsign/authenticode.c hosts the Authenticode ASN.1 type
definitions that used to live inline in sbsign.c. The OpenSSL
ASN1_SEQUENCE / ASN1_CHOICE / IMPLEMENT_ASN1_FUNCTIONS macros expand to
code that references libcrypto symbols directly, so to keep this
translation unit unlinked from libcrypto we redirect ASN1_item_* to
the sym_* variants via #define and wrap the ASN1_*_it() getters (which
appear as constant function pointers in static initializers) in small
trampoline functions that forward to the sym_* pointers at runtime.
test-dlopen-so gains assertions for dlopen_libcrypto and dlopen_libssl
so the dlopen contract is exercised in CI, and the openssl-specific
test was renamed from test-openssl.c to test-crypto-util.c to match
the new header naming.
We generally want to print an error message if table_print()
fails. Add a helper function for this and use it consistently.
This does one of the three things depending on the call site:
- a no-change reformatting of the code
- change from a custom message to the generic one
- addition of the error message where previously none was printed
In the third case, the actual use impact is very small, since the
table formatting is very unlikely to fail. But if it did, we would
often return an error without any message whatsoever, which we
never want to do.
Almost all callers of table_print() specify stdout or NULL (equivalent
to stdout) as the output stream. Simplify things by not requiring the
the stream to be specified.
In almost all cases, the printing of the table is surrounded by normal
printfs() that don't do explicit flushing and for which we don't check
the output stream status. Let's simplify most callers and skip this
step. The reason is not so much to avoid the extra step itself, but
instead to avoid the _handling_ of the potential failure. We generally
only want to print an error message for ENOMEM and other "internal"
errors, so strictly speaking we should filter out the errors from the
stream. By skipping the flush&check step we implicitly do this.
We often have a pattern where the same verb function is used for
multiple actions. This leads to an antipattern where we figure out what
action needs to be taken from argv[0] multiple times: often once in
parse_argv() to figure out what options are allowed, then once again
implicitly in dispatch_verb(), and then again in the action verb itself.
Let's allow passing a parameter into the verb to simplify this.
This matches a pattern we have in conf-parser.h, where we have both
void *userdata (more global) and void *data (per-config item). Here,
I opted for uintptr_t userdata. It seems that most of the time we'll
want to just pass an enum value. This works OK with no casts. I also
tried a void* and union. In both cases, much more boilerplate is needed:
either a cast or a macro to help avoid compiler warnings. uintptr_t
seems generic enough to cover foreseeable usecases with no fuss.
This is a noop refactoring. See next commit for an example.
Historically, resolvectl status has not included the interface
specification for DNS servers with an IPv6 link-local address, since it
is technically somewhat redundant. But, adding this extra bit of
information makes it easier to copy-and-paste to use elsewhere, etc.
For example, the previous output:
Link 2 (enp34s0)
Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
Protocols: +DefaultRoute LLMNR=resolve -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: fe80::861e:a3ff:feb1:f8e7
DNS Servers: 192.168.1.12 192.168.1.13 fe80::861e:a3ff:feb1:f8e7
DNS Domain: lan
now becomes:
Link 2 (enp34s0)
Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
Protocols: +DefaultRoute LLMNR=resolve -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: fe80::861e:a3ff:feb1:f8e7%2
DNS Servers: 192.168.1.12 192.168.1.13 fe80::861e:a3ff:feb1:f8e7%2
DNS Domain: lan
There is a lot of duplication across the functions for printing global,
link, and delegate output. Since these all use a common DNSConfiguration
type now, the logic can be consolidated.
Adapt printing and format helper functions to accept a DNSConfiguration
parameter to appropriately format output. Then, add print_configuration(),
a single function that prints the appropriate status output based on the
contents of DNSConfiguration.
Now that varlink is always used for status output, consolidate the JSON
and regular status code paths. Add status_full(), which is the single
point that calls DumpDNSConfiguration, filters based on link names and
mode if needed, and prints the output in the appropriate format.
This simplifies status_ifindex(), and removes the need for a separate
status_json().
This is an incremental commit to replacing dbus usage with varlink for
all status output.
Re-implement regular delegate status output using the DumpDNSConfiguration
varlink method. And, remove the DelegateInfo type and associated functions
which were used to map dbus properties.
Since this is the last type of status output to be switched to varlink,
lots of other code becomes dead with these changes, e.g.
read_dns_server_one(), map_dns_servers_internal(), etc., so remove those
too. Finally, status_all() no longer needs sd_bus, so drop that
parameter.
This is an incremental commit to replacing dbus usage with varlink for
all status output.
Re-implement regular link status output using the DumpDNSConfiguration
varlink method. And, remove the LinkInfo type and associated functions
which were used to map dbus properties.
This is an incremental commit to replacing dbus usage with varlink for
all status output.
Re-implement regular global status output using the DumpDNSConfiguration
varlink method. And, remove the GlobalInfo type and associated functions
which were used to map dbus properties.
This introduces /run/systemd/resolve.hook/ as a new directory that local
(privileged) programs can bind a Varlink socket into. If they do they'll
get a method call for each attempted resolved lookup, which they can
then either process themselves (and generate new records for, or return
errors to block stuff) or let pass so that the regular resolution is
done.
Usecase for this is primarily two things:
1. in machined we can add local resolution of machine names to their IP
addresses, similar in fashion to nss-mymachines, but working also if
the non-NSS interfaces to name resolution are used, i.e. the local
DNS responder. In fact, I think we should eventually remove
nss-mymachines from our tree, as soon as this code in resolved is
setlled.
2. in networkd we can add local resolution of names specified in DHCP
leases we hand out.
But beyond that there should be many other uses, for example people
could write "dns firewalls" with this if they like where they
dynamically block certain names from resolution.
Fixes: #8518
We want to reuse these generic DNS concepts in resolved hook
implementations, hence move them to shared code.
(This also enables us to immediately remove som SVCB record handling
duplicate definitions.)
No real code changes, just some moving around of things.