diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..885eb8c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/keyutils-1.5.10.tar.bz2 diff --git a/EMPTY b/EMPTY deleted file mode 100644 index 0519ecb..0000000 --- a/EMPTY +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/afs-srv.patch b/afs-srv.patch new file mode 100644 index 0000000..da6027b --- /dev/null +++ b/afs-srv.patch @@ -0,0 +1,150 @@ +commit 0d71523ab58493e1b40e1c80d569ff8ebc5ea27d +Author: David Howells +Date: Wed, 9 May 2018 10:37:03 +0100 + + DNS: Support AFS SRV records and cell db config files + + [dhowells: Cut down to only include generic changes as a prereq for the + next patch] + +Signed-off-by: David Howells +--- + key.dns_resolver.c | 47 +++++++++++++++++++++++++++++++---------------- + 1 file changed, 31 insertions(+), 16 deletions(-) + + +diff --git a/key.dns_resolver.c b/key.dns_resolver.c +index 9c9d458..849c8fe 100644 +--- a/key.dns_resolver.c ++++ b/key.dns_resolver.c +@@ -74,6 +74,7 @@ static int debug_mode; + #define INET_IP6_ONLY 0x2 + #define INET_ALL 0xFF + #define ONE_ADDR_ONLY 0x100 ++unsigned mask = INET_ALL; + + /* + * segmental payload +@@ -164,14 +165,10 @@ static const int ns_errno_map[] = { + [NO_DATA] = ENODATA, + }; + +-static __attribute__((noreturn)) +-void nsError(int err, const char *domain) ++void _nsError(int err, const char *domain) + { +- unsigned timeout = 1 * 60; +- int ret; +- + if (isatty(2)) +- fprintf(stderr, "%s: %s.\n", domain, hstrerror(err)); ++ fprintf(stderr, "NS:%s: %s.\n", domain, hstrerror(err)); + else + syslog(LOG_INFO, "%s: %s", domain, hstrerror(err)); + +@@ -181,11 +178,28 @@ void nsError(int err, const char *domain) + err = ns_errno_map[err]; + + info("Reject the key with error %d", err); ++} ++ ++static __attribute__((noreturn)) ++void nsError(int err, const char *domain) ++{ ++ unsigned timeout; ++ int ret; ++ ++ _nsError(err, domain); + +- if (err == EAGAIN) ++ switch (err) { ++ case TRY_AGAIN: + timeout = 1; +- else if (err == ECONNREFUSED) ++ break; ++ case 0: ++ case NO_RECOVERY: + timeout = 10; ++ break; ++ default: ++ timeout = 1 * 60; ++ break; ++ } + + if (!debug_mode) { + ret = keyctl_reject(key, timeout, err, KEY_REQKEY_DEFL_DEFAULT); +@@ -296,10 +310,10 @@ static void dump_payload(void) + * string to the list of payload segments. + */ + static int +-dns_resolver(const char *server_name, unsigned mask) ++dns_resolver(const char *server_name, const char *port) + { + struct addrinfo hints, *addr, *ai; +- char buf[INET6_ADDRSTRLEN + 1]; ++ char buf[INET6_ADDRSTRLEN + 8 + 1]; + int ret, len; + void *sa; + +@@ -320,8 +334,6 @@ dns_resolver(const char *server_name, unsigned mask) + return -1; + } + +- debug("getaddrinfo = %d", ret); +- + for (ai = addr; ai; ai = ai->ai_next) { + debug("RR: %x,%x,%x,%x,%x,%s", + ai->ai_flags, ai->ai_family, +@@ -350,6 +362,8 @@ dns_resolver(const char *server_name, unsigned mask) + if (!inet_ntop(ai->ai_family, sa, buf, len)) + error("%s: inet_ntop: %m", __func__); + ++ if (port) ++ strcat(buf, port); + append_address_to_payload(buf); + if (mask & ONE_ADDR_ONLY) + break; +@@ -413,7 +427,7 @@ static void afsdb_hosts_to_addrs(ns_msg handle, + goto next_one; + + /* Turn the hostname into IP addresses */ +- ret = dns_resolver(vllist[vlsnum], mask); ++ ret = dns_resolver(vllist[vlsnum], NULL); + if (ret) { + debug("AFSDB RR can't resolve." + "subtype:%d, server name:%s, netmask:%u", +@@ -523,7 +537,6 @@ int dns_query_afsdb(const char *cell, char *options) + static __attribute__((noreturn)) + int dns_query_a_or_aaaa(const char *hostname, char *options) + { +- unsigned mask; + int ret; + + debug("Get A/AAAA RR for hostname:'%s', options:'%s'", +@@ -569,7 +582,7 @@ int dns_query_a_or_aaaa(const char *hostname, char *options) + } + + /* Turn the hostname into IP addresses */ +- ret = dns_resolver(hostname, mask); ++ ret = dns_resolver(hostname, NULL); + if (ret) + nsError(NO_DATA, hostname); + +@@ -630,7 +643,7 @@ int main(int argc, char *argv[]) + + openlog(prog, 0, LOG_DAEMON); + +- while ((ret = getopt_long(argc, argv, "vD", long_options, NULL)) != -1) { ++ while ((ret = getopt_long(argc, argv, "vDV", long_options, NULL)) != -1) { + switch (ret) { + case 'D': + debug_mode = 1; +@@ -713,6 +726,8 @@ int main(int argc, char *argv[]) + qtlen = name - keyend; + name++; + ++ info("Query type: '%*.*s'", qtlen, qtlen, keyend); ++ + if ((qtlen == sizeof(a_query_type) - 1 && + memcmp(keyend, a_query_type, sizeof(a_query_type) - 1) == 0) || + (qtlen == sizeof(aaaa_query_type) - 1 && diff --git a/fix-ci-strcat.patch b/fix-ci-strcat.patch new file mode 100644 index 0000000..e9cd134 --- /dev/null +++ b/fix-ci-strcat.patch @@ -0,0 +1,58 @@ +commit d8106bbb5348591968722e14fe4ee4b81e7902aa +Author: David Howells +Date: Wed Jun 16 15:06:36 2021 +0100 + + Fix issue found by Coverity + + This isn't something that can actually be triggered. The port parameter is + always NULL, so just drop the parameter and the call to strcat(). + + Error: STRING_OVERFLOW (CWE-120): + keyutils-1.5.10/key.dns_resolver.c:388: fixed_size_dest: You might overrun the 55-character fixed-size string "buf" by copying "port" without checking the length. + keyutils-1.5.10/key.dns_resolver.c:388: parameter_as_source: Note: This defect has an elevated risk because the source argument is a parameter of the current function. + +Signed-off-by: David Howells +--- + key.dns_resolver.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/key.dns_resolver.c b/key.dns_resolver.c +index f3052e6..2743119 100644 +--- a/key.dns_resolver.c ++++ b/key.dns_resolver.c +@@ -332,7 +332,7 @@ static void dump_payload(void) + * string to the list of payload segments. + */ + static int +-dns_resolver(const char *server_name, const char *port) ++dns_resolver(const char *server_name) + { + struct addrinfo hints, *addr, *ai; + char buf[INET6_ADDRSTRLEN + 8 + 1]; +@@ -384,8 +384,6 @@ dns_resolver(const char *server_name, const char *port) + if (!inet_ntop(ai->ai_family, sa, buf, len)) + error("%s: inet_ntop: %m", __func__); + +- if (port) +- strcat(buf, port); + append_address_to_payload(buf); + if (mask & ONE_ADDR_ONLY) + break; +@@ -449,7 +447,7 @@ static void afsdb_hosts_to_addrs(ns_msg handle, + goto next_one; + + /* Turn the hostname into IP addresses */ +- ret = dns_resolver(vllist[vlsnum], NULL); ++ ret = dns_resolver(vllist[vlsnum]); + if (ret) { + debug("AFSDB RR can't resolve." + "subtype:%d, server name:%s, netmask:%u", +@@ -604,7 +602,7 @@ int dns_query_a_or_aaaa(const char *hostname, char *options) + } + + /* Turn the hostname into IP addresses */ +- ret = dns_resolver(hostname, NULL); ++ ret = dns_resolver(hostname); + if (ret) + nsError(NO_DATA, hostname); + diff --git a/keyutils.spec b/keyutils.spec new file mode 100644 index 0000000..6c75e50 --- /dev/null +++ b/keyutils.spec @@ -0,0 +1,320 @@ +%define vermajor 1 +%define verminor 5.10 +%define version %{vermajor}.%{verminor} +%define libapivermajor 1 +%define libapiversion %{libapivermajor}.6 + +# % define buildid .local + +Summary: Linux Key Management Utilities +Name: keyutils +Version: %{version} +Release: 9%{?buildid}%{?dist} +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +ExclusiveOS: Linux +Url: http://people.redhat.com/~dhowells/keyutils/ + +Source0: http://people.redhat.com/~dhowells/keyutils/keyutils-%{version}.tar.bz2 +Patch1: test-endianness-check.patch +Patch2: test-rhel8.patch +Patch3: afs-srv.patch +Patch4: ttl.patch +Patch5: fix-ci-strcat.patch + +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +BuildRequires: glibc-kernheaders >= 2.4-9.1.92 +Requires: keyutils-libs == %{version}-%{release} + +%description +Utilities to control the kernel key management facility and to provide +a mechanism by which the kernel call back to user space to get a key +instantiated. + +%package libs +Summary: Key utilities library +Group: System Environment/Base + +%description libs +This package provides a wrapper library for the key management facility system +calls. + +%package libs-devel +Summary: Development package for building Linux key management utilities +Group: System Environment/Base +Requires: keyutils-libs == %{version}-%{release} + +%description libs-devel +This package provides headers and libraries for building key utilities. + +%prep +%setup -q +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 + +%define datadir %{_datarootdir}/keyutils + +%build +make \ + NO_ARLIB=1 \ + ETCDIR=%{_sysconfdir} \ + LIBDIR=%{_libdir} \ + USRLIBDIR=%{_libdir} \ + BINDIR=%{_bindir} \ + SBINDIR=%{_sbindir} \ + MANDIR=%{_mandir} \ + INCLUDEDIR=%{_includedir} \ + SHAREDIR=%{datadir} \ + RELEASE=.%{release} \ + NO_GLIBC_KEYERR=1 \ + CFLAGS="-Wall $RPM_OPT_FLAGS" \ + LDFLAGS="%{?__global_ldflags}" + +%install +make \ + NO_ARLIB=1 \ + DESTDIR=$RPM_BUILD_ROOT \ + ETCDIR=%{_sysconfdir} \ + LIBDIR=%{_libdir} \ + USRLIBDIR=%{_libdir} \ + BINDIR=%{_bindir} \ + SBINDIR=%{_sbindir} \ + MANDIR=%{_mandir} \ + INCLUDEDIR=%{_includedir} \ + SHAREDIR=%{datadir} \ + install + +%ldconfig_scriptlets libs + +%files +%doc README +%license LICENCE.GPL +%{_sbindir}/* +%{_bindir}/* +%{datadir} +%{_mandir}/man1/* +%{_mandir}/man5/* +%{_mandir}/man8/* +%config(noreplace) %{_sysconfdir}/* + +%files libs +%license LICENCE.LGPL +%{_mandir}/man7/* +%{_libdir}/libkeyutils.so.%{libapiversion} +%{_libdir}/libkeyutils.so.%{libapivermajor} + +%files libs-devel +%{_libdir}/libkeyutils.so +%{_includedir}/* +%{_mandir}/man3/* + +%changelog +* Wed Jun 16 2021 David Howells - 1.5.10-9 +- Fix potential strcat overflow found by Coverity in CI test (#1661674). + +* Thu Jun 3 2021 David Howells - 1.5.10-8 +- Fix TTL handling on DNS lookups (#1661674). + +* Thu Apr 18 2019 David Howells - 1.5.10-7 +- Fix testsuite for rhel-8 (#1681963). + +* Fri Feb 09 2018 Igor Gnatenko - 1.5.10-6 +- Escape macros in %%changelog + +* Wed Feb 07 2018 Fedora Release Engineering - 1.5.10-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Sat Feb 03 2018 Igor Gnatenko - 1.5.10-4 +- Switch to %%ldconfig_scriptlets + +* Thu Aug 03 2017 Fedora Release Engineering - 1.5.10-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 1.5.10-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Wed Mar 15 2017 David Howells - 1.5.10-1 +- Include sys/types.h in keyutils.h. +- The dns resolver needs limits.h. +- Overhaul of all manual pages. +- Some manual pages moved to Linux man-pages project. +- Add Diffie-Helman keyctl function. + +* Fri Aug 14 2015 Adam Jackson 1.5.9-7 +- Pass ldflags into the build so hardening works + +* Sat Jul 12 2014 Tom Callaway - 1.5.9-3 +- Fix license handling + +* Fri Feb 21 2014 David Howells - 1.5.9-1 +- Add manpages for get_persistent. +- Fix memory leaks in keyctl_describe/read/get_security_alloc(). +- Use keyctl_describe_alloc in dump_key_tree_aux rather than open coding it. +- Exit rather than returning from act_xxx() functions. +- Fix memory leak in dump_key_tree_aux. +- Only get the groups list if we need it. +- Don't trust sscanf's %%n argument. +- Use the correct path macros in the specfile. +- Avoid use realloc when the memory has no content. +- Fix a bunch of issues in key.dns_resolver. +- Fix command table searching in keyctl utility. +- Fix a typo in the permissions mask constants. +- Improve the keyctl_read manpage. +- Add man7 pages describing various keyrings concepts. + +* Fri Oct 4 2013 David Howells - 1.5.8-1 +- New lib symbols should go in a new library minor version. + +* Wed Oct 2 2013 David Howells - 1.5.7-1 +- Provide a utility function to find a key by type and name. +- Allow keyctl commands to take a type+name arg instead of a key-id arg. +- Add per-UID get_persistent keyring function. + +* Thu Aug 29 2013 David Howells - 1.5.6-1 +- Fix the request-key.conf.5 manpage. +- Fix the max depth of key tree dump (keyctl show). +- The input buffer size for keyctl padd and pinstantiate should be larger. +- Add keyctl_invalidate.3 manpage. + +* Wed Nov 30 2011 David Howells - 1.5.5-1 +- Fix a Makefile error. + +* Wed Nov 30 2011 David Howells - 1.5.4-1 +- Fix the keyctl padd command and similar to handle binary input. +- Make keyctl show able to take a keyring to dump. +- Make keyctl show able to take a flag to request hex key IDs. +- Make keyctl show print the real ID of the root keyring. + +* Tue Nov 15 2011 David Howells +- Allow /sbin/request-key to have multiple config files. + +* Wed Aug 31 2011 David Howells +- Adjust the manual page for 'keyctl unlink' to show keyring is optional. +- Add --version support for the keyutils version and build date. + +* Thu Aug 11 2011 David Howells - 1.5.3-1 +- Make the keyutils rpm depend on the same keyutils-libs rpm version. + +* Tue Jul 26 2011 David Howells - 1.5.2-1 +- Use correct format spec for printing pointer subtraction results. + +* Tue Jul 19 2011 David Howells - 1.5.1-1 +- Fix unread variables. +- Licence file update. + +* Thu Mar 10 2011 David Howells - 1.5-1 +- Disable RPATH setting in Makefile. +- Add -I. to build to get this keyutils.h. +- Make CFLAGS override on make command line work right. +- Make specfile UTF-8. +- Support KEYCTL_REJECT. +- Support KEYCTL_INSTANTIATE_IOV. +- Add AFSDB DNS lookup program from Wang Lei. +- Generalise DNS lookup program. +- Add recursive scan utility function. +- Add bad key reap command to keyctl. +- Add multi-unlink variant to keyctl unlink command. +- Add multi key purge command to keyctl. +- Handle multi-line commands in keyctl command table. +- Move the package to version to 1.5. + +* Tue Mar 1 2011 David Howells - 1.4-4 +- Make build guess at default libdirs and word size. +- Make program build depend on library in Makefile. +- Don't include $(DESTDIR) in MAN* macros. +- Remove NO_GLIBC_KEYSYS as it is obsolete. +- Have Makefile extract version info from specfile and version script. +- Provide RPM build rule in Makefile. +- Provide distclean rule in Makefile. + +* Fri Dec 17 2010 Diego Elio Pettenò - 1.4-3 +- Fix local linking and RPATH. + +* Thu Jun 10 2010 David Howells - 1.4-2 +- Fix prototypes in manual pages (some char* should be void*). +- Rename the keyctl_security.3 manpage to keyctl_get_security.3. + +* Fri Mar 19 2010 David Howells - 1.4-1 +- Fix the library naming wrt the version. +- Move the package to version to 1.4. + +* Fri Mar 19 2010 David Howells - 1.3-3 +- Fix spelling mistakes in manpages. +- Add an index manpage for all the keyctl functions. + +* Thu Mar 11 2010 David Howells - 1.3-2 +- Fix rpmlint warnings. + +* Fri Feb 26 2010 David Howells - 1.3-1 +- Fix compiler warnings in request-key. +- Expose the kernel function to get a key's security context. +- Expose the kernel function to set a processes keyring onto its parent. +- Move libkeyutils library version to 1.3. + +* Tue Aug 22 2006 David Howells - 1.2-1 +- Remove syscall manual pages (section 2) to man-pages package [BZ 203582] +- Don't write to serial port in debugging script + +* Mon Jun 5 2006 David Howells - 1.1-4 +- Call ldconfig during (un)installation. + +* Fri May 5 2006 David Howells - 1.1-3 +- Don't include the release number in the shared library filename +- Don't build static library + +* Fri May 5 2006 David Howells - 1.1-2 +- More bug fixes from Fedora reviewer. + +* Thu May 4 2006 David Howells - 1.1-1 +- Fix rpmlint errors + +* Mon Dec 5 2005 David Howells - 1.0-2 +- Add build dependency on glibc-kernheaders with key management syscall numbers + +* Tue Nov 29 2005 David Howells - 1.0-1 +- Add data pipe-in facility for keyctl request2 + +* Mon Nov 28 2005 David Howells - 1.0-1 +- Rename library and header file "keyutil" -> "keyutils" for consistency +- Fix shared library version naming to same way as glibc. +- Add versioning for shared library symbols +- Create new keyutils-libs package and install library and main symlink there +- Install base library symlink in /usr/lib and place in devel package +- Added a keyutils archive library +- Shorten displayed key permissions list to just those we actually have + +* Thu Nov 24 2005 David Howells - 0.3-4 +- Add data pipe-in facilities for keyctl add, update and instantiate + +* Fri Nov 18 2005 David Howells - 0.3-3 +- Added stdint.h inclusion in keyutils.h +- Made request-key.c use request_key() rather than keyctl_search() +- Added piping facility to request-key + +* Thu Nov 17 2005 David Howells - 0.3-2 +- Added timeout keyctl option +- request_key auth keys must now be assumed +- Fix keyctl argument ordering for debug negate line in request-key.conf + +* Thu Jul 28 2005 David Howells - 0.3-1 +- Must invoke initialisation from perror() override in libkeyutils +- Minor UI changes + +* Wed Jul 20 2005 David Howells - 0.2-2 +- Bump version to permit building in main repositories. + +* Tue Jul 12 2005 David Howells - 0.2-1 +- Don't attempt to define the error codes in the header file. +- Pass the release ID through to the makefile to affect the shared library name. + +* Tue Jul 12 2005 David Howells - 0.1-3 +- Build in the perror() override to get the key error strings displayed. + +* Tue Jul 12 2005 David Howells - 0.1-2 +- Need a defattr directive after each files directive. + +* Tue Jul 12 2005 David Howells - 0.1-1 +- Package creation. diff --git a/sources b/sources new file mode 100644 index 0000000..f4c5b8b --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (keyutils-1.5.10.tar.bz2) = 7f6f956c7e76cdc2aeb52e74fe670b20a5f9a5d9b543fd2ce971d80c48745f37d05235a42f0a8f152b1128a109c7d8bf07e751282a20d2d3f433a99a5308ae8d diff --git a/test-endianness-check.patch b/test-endianness-check.patch new file mode 100644 index 0000000..5fc97fa --- /dev/null +++ b/test-endianness-check.patch @@ -0,0 +1,23 @@ +commit d0fedbf9257a0fed18030527fd094588df5873aa +Author: David Howells +Date: Tue Aug 21 23:24:03 2018 +0100 + + TEST: Add a missing backslash + + Add a missing backslash into a regular expression in the toolbox. + + Signed-off-by: David Howells + +diff --git a/tests/toolbox.inc.sh b/tests/toolbox.inc.sh +index 140be66..0ce6db0 100644 +--- a/tests/toolbox.inc.sh ++++ b/tests/toolbox.inc.sh +@@ -13,7 +13,7 @@ + echo === $OUTPUTFILE === + + endian=`file -L /proc/$$/exe` +-if expr "$endian" : '.* MSB \+\(executable\|shared object).*' >&/dev/null ++if expr "$endian" : '.* MSB \+\(executable\|shared object\).*' >&/dev/null + then + endian=BE + elif expr "$endian" : '.* LSB \+\(executable\|shared object\).*' >&/dev/null diff --git a/test-rhel8.patch b/test-rhel8.patch new file mode 100644 index 0000000..005d8b2 --- /dev/null +++ b/test-rhel8.patch @@ -0,0 +1,27 @@ +commit 0b1654506039e614954e141aad3ceddb7018a2cb +Author: David Howells +Date: Wed Apr 17 15:42:30 2019 +0100 + + TEST: Apply test exclusions for RHEL-8 + + RHEL-8 doesn't enable the DH/KDF code, so disable the tests on all RHEL + distributions for now. + + Signed-off-by: David Howells + +diff --git a/tests/prepare.inc.sh b/tests/prepare.inc.sh +index ab9ae4d..9c4adda 100644 +--- a/tests/prepare.inc.sh ++++ b/tests/prepare.inc.sh +@@ -96,7 +96,10 @@ fi + # Work out whether Diffie-Hellman is supported by the kernel + # + have_dh_compute=0 +-if keyutils_at_or_later_than 1.5.10 && kernel_at_or_later_than 4.7-rc1 ++if [ $OSDIST = RHEL ] ++then ++ : ++elif keyutils_at_or_later_than 1.5.10 && kernel_at_or_later_than 4.7-rc1 + then + have_dh_compute=1 + fi diff --git a/ttl.patch b/ttl.patch new file mode 100644 index 0000000..cc45f4f --- /dev/null +++ b/ttl.patch @@ -0,0 +1,448 @@ +commit 75e7568dc516db698093b33ea273e1b4a30b70be +Author: David Howells +Date: Tue, 14 Apr 2020 16:07:26 +0100 + + dns: Apply a default TTL to records obtained from getaddrinfo() + + Address records obtained from getaddrinfo() don't come with any TTL + information, even if they're obtained from the DNS, with the result that + key.dns_resolver upcall program doesn't set an expiry time on dns_resolver + records unless they include a component obtained directly from the DNS, + such as an SRV or AFSDB record. + + Fix this to apply a default TTL of 10mins in the event that we haven't got + one. This can be configured in /etc/keyutils/key.dns_resolver.conf by + adding the line: + + default_ttl = + + to the file. + + Signed-off-by: David Howells + Reviewed-by: Ben Boeckel + Reviewed-by: Jeff Layton + + [dhowells: Cut down to remove kafs-specific bits] + +Signed-off-by: David Howells +--- + Makefile | 1 + key.dns_resolver.c | 209 +++++++++++++++++++++++++++++++++++++++++--- + man/key.dns_resolver.8 | 25 ++++- + man/key.dns_resolver.conf.5 | 48 ++++++++++ + 4 files changed, 267 insertions(+), 16 deletions(-) + +diff --git a/Makefile b/Makefile +index 824bbbf..c2b2460 100644 +--- a/Makefile ++++ b/Makefile +@@ -175,6 +175,7 @@ endif + $(INSTALL) -D key.dns_resolver $(DESTDIR)$(SBINDIR)/key.dns_resolver + $(INSTALL) -D -m 0644 request-key.conf $(DESTDIR)$(ETCDIR)/request-key.conf + mkdir -p $(DESTDIR)$(ETCDIR)/request-key.d ++ mkdir -p $(DESTDIR)$(ETCDIR)/keyutils + mkdir -p $(DESTDIR)$(MAN1) + $(INSTALL) -m 0644 $(wildcard man/*.1) $(DESTDIR)$(MAN1) + mkdir -p $(DESTDIR)$(MAN3) +diff --git a/key.dns_resolver.c b/key.dns_resolver.c +index 849c8fe..f3052e6 100644 +--- a/key.dns_resolver.c ++++ b/key.dns_resolver.c +@@ -53,10 +53,12 @@ + #include + #include + #include ++#include + #include + #include + #include + #include ++#include + + static const char *DNS_PARSE_VERSION = "1.0"; + static const char prog[] = "key.dns_resolver"; +@@ -64,11 +66,13 @@ static const char key_type[] = "dns_resolver"; + static const char a_query_type[] = "a"; + static const char aaaa_query_type[] = "aaaa"; + static const char afsdb_query_type[] = "afsdb"; ++static const char *config_file = "/etc/keyutils/key.dns_resolver.conf"; + static key_serial_t key; ++static unsigned int key_expiry = 5; ++static bool config_specified = false; + static int verbose; + static int debug_mode; + +- + #define MAX_VLS 15 /* Max Volume Location Servers Per-Cell */ + #define INET_IP4_ONLY 0x1 + #define INET_IP6_ONLY 0x2 +@@ -132,6 +136,23 @@ void _error(const char *fmt, ...) + va_end(va); + } + ++/* ++ * Print a warning to stderr or the syslog ++ */ ++void warning(const char *fmt, ...) ++{ ++ va_list va; ++ ++ va_start(va, fmt); ++ if (isatty(2)) { ++ vfprintf(stderr, fmt, va); ++ fputc('\n', stderr); ++ } else { ++ vsyslog(LOG_WARNING, fmt, va); ++ } ++ va_end(va); ++} ++ + /* + * Print status information + */ +@@ -302,6 +323,7 @@ static void dump_payload(void) + } + + info("The key instantiation data is '%s'", buf); ++ info("The expiry time is %us", key_expiry); + free(buf); + } + +@@ -597,6 +619,9 @@ int dns_query_a_or_aaaa(const char *hostname, char *options) + + /* load the key with data key */ + if (!debug_mode) { ++ ret = keyctl_set_timeout(key, key_expiry); ++ if (ret == -1) ++ error("%s: keyctl_set_timeout: %m", __func__); + ret = keyctl_instantiate_iov(key, payload, payload_index, 0); + if (ret == -1) + error("%s: keyctl_instantiate: %m", __func__); +@@ -605,6 +630,157 @@ int dns_query_a_or_aaaa(const char *hostname, char *options) + exit(0); + } + ++/* ++ * Read the config file. ++ */ ++static void read_config(void) ++{ ++ FILE *f; ++ char buf[4096], *b, *p, *k, *v; ++ unsigned int line = 0, u; ++ int n; ++ ++ info("READ CONFIG %s", config_file); ++ ++ f = fopen(config_file, "r"); ++ if (!f) { ++ if (errno == ENOENT && !config_specified) { ++ debug("%s: %m", config_file); ++ return; ++ } ++ error("%s: %m", config_file); ++ } ++ ++ while (fgets(buf, sizeof(buf) - 1, f)) { ++ line++; ++ ++ /* Trim off leading and trailing spaces and discard whole-line ++ * comments. ++ */ ++ b = buf; ++ while (isspace(*b)) ++ b++; ++ if (!*b || *b == '#') ++ continue; ++ p = strchr(b, '\n'); ++ if (!p) ++ error("%s:%u: line missing newline or too long", config_file, line); ++ while (p > buf && isspace(p[-1])) ++ p--; ++ *p = 0; ++ ++ /* Split into key[=value] pairs and trim spaces. */ ++ k = b; ++ v = NULL; ++ b = strchr(b, '='); ++ if (b) { ++ char quote = 0; ++ bool esc = false; ++ ++ if (b == k) ++ error("%s:%u: Unspecified key", ++ config_file, line); ++ ++ /* NUL-terminate the key. */ ++ for (p = b - 1; isspace(*p); p--) ++ ; ++ p[1] = 0; ++ ++ /* Strip leading spaces */ ++ b++; ++ while (isspace(*b)) ++ b++; ++ if (!*b) ++ goto missing_value; ++ ++ if (*b == '"' || *b == '\'') { ++ quote = *b; ++ b++; ++ } ++ v = p = b; ++ while (*b) { ++ if (esc) { ++ switch (*b) { ++ case ' ': ++ case '\t': ++ case '"': ++ case '\'': ++ case '\\': ++ break; ++ default: ++ goto invalid_escape_char; ++ } ++ esc = false; ++ *p++ = *b++; ++ continue; ++ } ++ if (*b == '\\') { ++ esc = true; ++ b++; ++ continue; ++ } ++ if (*b == quote) { ++ b++; ++ if (*b) ++ goto post_quote_data; ++ quote = 0; ++ break; ++ } ++ if (!quote && *b == '#') ++ break; /* Terminal comment */ ++ *p++ = *b++; ++ } ++ ++ if (esc) ++ error("%s:%u: Incomplete escape", config_file, line); ++ if (quote) ++ error("%s:%u: Unclosed quotes", config_file, line); ++ *p = 0; ++ } ++ ++ if (strcmp(k, "default_ttl") == 0) { ++ if (!v) ++ goto missing_value; ++ if (sscanf(v, "%u%n", &u, &n) != 1) ++ goto bad_value; ++ if (v[n]) ++ goto extra_data; ++ if (u < 1 || u > INT_MAX) ++ goto out_of_range; ++ key_expiry = u; ++ } else { ++ warning("%s:%u: Unknown option '%s'", config_file, line, k); ++ } ++ } ++ ++ if (ferror(f) || fclose(f) == EOF) ++ error("%s: %m", config_file); ++ return; ++ ++missing_value: ++ error("%s:%u: %s: Missing value", config_file, line, k); ++invalid_escape_char: ++ error("%s:%u: %s: Invalid char in escape", config_file, line, k); ++post_quote_data: ++ error("%s:%u: %s: Data after closing quote", config_file, line, k); ++bad_value: ++ error("%s:%u: %s: Bad value", config_file, line, k); ++extra_data: ++ error("%s:%u: %s: Extra data supplied", config_file, line, k); ++out_of_range: ++ error("%s:%u: %s: Value out of range", config_file, line, k); ++} ++ ++/* ++ * Dump the configuration after parsing the config file. ++ */ ++static __attribute__((noreturn)) ++void config_dumper(void) ++{ ++ printf("default_ttl = %u\n", key_expiry); ++ exit(0); ++} ++ + /* + * Print usage details, + */ +@@ -613,22 +789,24 @@ void usage(void) + { + if (isatty(2)) { + fprintf(stderr, +- "Usage: %s [-vv] key_serial\n", ++ "Usage: %s [-vv] [-c config] key_serial\n", + prog); + fprintf(stderr, +- "Usage: %s -D [-vv] \n", ++ "Usage: %s -D [-vv] [-c config] \n", + prog); + } else { +- info("Usage: %s [-vv] key_serial", prog); ++ info("Usage: %s [-vv] [-c config] key_serial", prog); + } + exit(2); + } + +-const struct option long_options[] = { +- { "debug", 0, NULL, 'D' }, +- { "verbose", 0, NULL, 'v' }, +- { "version", 0, NULL, 'V' }, +- { NULL, 0, NULL, 0 } ++static const struct option long_options[] = { ++ { "config", 0, NULL, 'c' }, ++ { "debug", 0, NULL, 'D' }, ++ { "dump-config", 0, NULL, 2 }, ++ { "verbose", 0, NULL, 'v' }, ++ { "version", 0, NULL, 'V' }, ++ { NULL, 0, NULL, 0 } + }; + + /* +@@ -640,11 +818,19 @@ int main(int argc, char *argv[]) + char *keyend, *p; + char *callout_info = NULL; + char *buf = NULL, *name; ++ bool dump_config = false; + + openlog(prog, 0, LOG_DAEMON); + +- while ((ret = getopt_long(argc, argv, "vDV", long_options, NULL)) != -1) { ++ while ((ret = getopt_long(argc, argv, "c:vDV", long_options, NULL)) != -1) { + switch (ret) { ++ case 'c': ++ config_file = optarg; ++ config_specified = true; ++ continue; ++ case 2: ++ dump_config = true; ++ continue; + case 'D': + debug_mode = 1; + continue; +@@ -666,6 +852,9 @@ int main(int argc, char *argv[]) + + argc -= optind; + argv += optind; ++ read_config(); ++ if (dump_config) ++ config_dumper(); + + if (!debug_mode) { + if (argc != 1) +diff --git a/man/key.dns_resolver.8 b/man/key.dns_resolver.8 +index e1882e0..0b17edd 100644 +--- a/man/key.dns_resolver.8 ++++ b/man/key.dns_resolver.8 +@@ -7,28 +7,41 @@ + .\" as published by the Free Software Foundation; either version + .\" 2 of the License, or (at your option) any later version. + .\" +-.TH KEY.DNS_RESOLVER 8 "04 Mar 2011" Linux "Linux Key Management Utilities" ++.TH KEY.DNS_RESOLVER 8 "18 May 2020" Linux "Linux Key Management Utilities" + .SH NAME + key.dns_resolver \- upcall for request\-key to handle dns_resolver keys + .SH SYNOPSIS + \fB/sbin/key.dns_resolver \fR + .br +-\fB/sbin/key.dns_resolver \fR\-D [\-v] [\-v] ++\fB/sbin/key.dns_resolver \fR--dump-config [\-c ] ++.br ++\fB/sbin/key.dns_resolver \fR\-D [\-v] [\-v] [\-c ] ++.br ++ + .SH DESCRIPTION + This program is invoked by request\-key on behalf of the kernel when kernel + services (such as NFS, CIFS and AFS) want to perform a hostname lookup and the + kernel does not have the key cached. It is not ordinarily intended to be + called directly. + .P +-It can be called in debugging mode to test its functionality by passing a +-\fB\-D\fR flag on the command line. For this to work, the key description and +-the callout information must be supplied. Verbosity can be increased by +-supplying one or more \fB\-v\fR flags. ++There program has internal parameters that can be changed with a configuration ++file (see key.dns_resolver.conf(5) for more information). The default ++configuration file is in /etc, but this can be overridden with the \fB-c\fR ++flag. ++.P ++The program can be called in debugging mode to test its functionality by ++passing a \fB\-D\fR or \fB\--debug\fR flag on the command line. For this to ++work, the key description and the callout information must be supplied. ++Verbosity can be increased by supplying one or more \fB\-v\fR flags. ++.P ++The program may also be called with \fB--dump-config\fR to show the values that ++configurable parameters will have after parsing the config file. + .SH ERRORS + All errors will be logged to the syslog. + .SH SEE ALSO + .ad l + .nh ++.BR key.dns_resolver.conf (5), + .BR request\-key.conf (5), + .BR keyrings (7), + .BR request\-key (8) +diff --git a/man/key.dns_resolver.conf.5 b/man/key.dns_resolver.conf.5 +new file mode 100644 +index 0000000..c944ad5 +--- /dev/null ++++ b/man/key.dns_resolver.conf.5 +@@ -0,0 +1,48 @@ ++.\" -*- nroff -*- ++.\" Copyright (C) 2020 Red Hat, Inc. All Rights Reserved. ++.\" Written by David Howells (dhowells@redhat.com) ++.\" ++.\" This program is free software; you can redistribute it and/or ++.\" modify it under the terms of the GNU General Public License ++.\" as published by the Free Software Foundation; either version ++.\" 2 of the License, or (at your option) any later version. ++.\" ++.TH KEY.DNS_RESOLVER.CONF 5 "18 May 2020" Linux "Linux Key Management Utilities" ++.SH NAME ++key.dns_resolver.conf \- Kernel DNS resolver config ++.SH DESCRIPTION ++This file is used by the key.dns_resolver(5) program to set parameters. ++Unless otherwise overridden with the \fB\-c\fR flag, the program reads: ++.IP ++/etc/key.dns_resolver.conf ++.P ++Configuration options are given in \fBkey[=value]\fR form, where \fBvalue\fR is ++optional. If present, the value may be surrounded by a pair of single ('') or ++double quotes ("") which will be stripped off. The special characters in the ++value may be escaped with a backslash to turn them into ordinary characters. ++.P ++Lines beginning with a '#' are considered comments and ignored. A '#' symbol ++anywhere after the '=' makes the rest of the line into a comment unless the '#' ++is inside a quoted section or is escaped. ++.P ++Leading and trailing spaces and spaces around the '=' symbol will be stripped ++off. ++.P ++Available options include: ++.TP ++.B default_ttl= ++The number of seconds to set as the expiration on a cached record. This will ++be overridden if the program manages to retrieve TTL information along with ++the addresses (if, for example, it accesses the DNS directly). The default is ++5 seconds. The value must be in the range 1 to INT_MAX. ++.P ++The file can also include comments beginning with a '#' character unless ++otherwise suppressed by being inside a quoted value or being escaped with a ++backslash. ++ ++.SH FILES ++.ul ++/etc/key.dns_resolver.conf ++.ul 0 ++.SH SEE ALSO ++\fBkey.dns_resolver\fR(8)