mirror of
https://github.com/systemd/systemd.git
synced 2024-11-28 04:33:36 +08:00
systemd-resolve: allow easy querying of openpgp keys
$ systemd-resolve --openpgp zbyszek@fedoraproject.org d08ee310438ca124a6149ea5cc21b6313b390dce485576eff96f8722._openpgpkey.fedoraproject.org. IN OPENPGPKEY mQINBFBHPMsBEACeInGYJCb+7TurKfb6wGyTottCDtiSJB310i37/6ZYoeIay/5soJjlM yfMFQ9T2XNT/0LM6gTa0MpC1st9LnzYTMsT6tzRly1D1UbVI6xw0g0vE5y2Cjk3xUwAyn ...
This commit is contained in:
parent
91e023d896
commit
4ac2ca1bdb
@ -5291,7 +5291,9 @@ systemd_resolve_SOURCES = \
|
||||
src/resolve/resolved-dns-question.c \
|
||||
src/resolve/resolved-dns-question.h \
|
||||
src/resolve/dns-type.c \
|
||||
src/resolve/dns-type.h
|
||||
src/resolve/dns-type.h \
|
||||
src/shared/gcrypt-util.c \
|
||||
src/shared/gcrypt-util.h
|
||||
|
||||
nodist_systemd_resolve_SOURCES = \
|
||||
src/resolve/dns_type-from-name.h \
|
||||
|
@ -76,6 +76,13 @@
|
||||
<replaceable>TYPE</replaceable></arg> <replaceable>DOMAIN</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
|
||||
<cmdsynopsis>
|
||||
<command>systemd-resolve</command>
|
||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
<command> --openpgp</command>
|
||||
<arg choice="plain"><replaceable>USER@DOMAIN</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
|
||||
<cmdsynopsis>
|
||||
<command>systemd-resolve</command>
|
||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
@ -114,6 +121,10 @@
|
||||
is assumed to be a domain name, that is already prefixed with an SRV type, and an SRV lookup is done (no
|
||||
TXT).</para>
|
||||
|
||||
<para>The <option>--openpgp</option> switch may be use to query PGP keys stored as the
|
||||
<ulink url="https://tools.ietf.org/html/draft-wouters-dane-openpgp-02">OPENPGPKEY</ulink> resource records.
|
||||
When this option is specified one or more e-mail address must be specified.</para>
|
||||
|
||||
<para>The <option>--statistics</option> switch may be used to show resolver statistics, including information about
|
||||
the number of succesful and failed DNSSEC validations.</para>
|
||||
|
||||
@ -197,6 +208,14 @@
|
||||
<option>--service</option> the TXT service metadata record is resolved as well.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--openpgp</option></term>
|
||||
|
||||
<listitem><para>Enables OPENPGPKEY resource record resolution (see above). Specified e-mail
|
||||
addresses are converted to the corresponding DNS domain name, and any OPENPGPKEY keys are
|
||||
printed.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--cname=</option><replaceable>BOOL</replaceable></term>
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <gcrypt.h>
|
||||
#include <getopt.h>
|
||||
#include <net/if.h>
|
||||
|
||||
@ -30,6 +31,7 @@
|
||||
#include "bus-util.h"
|
||||
#include "escape.h"
|
||||
#include "in-addr-util.h"
|
||||
#include "gcrypt-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "resolved-def.h"
|
||||
#include "resolved-dns-packet.h"
|
||||
@ -48,6 +50,7 @@ static enum {
|
||||
MODE_RESOLVE_HOST,
|
||||
MODE_RESOLVE_RECORD,
|
||||
MODE_RESOLVE_SERVICE,
|
||||
MODE_RESOLVE_OPENPGP,
|
||||
MODE_STATISTICS,
|
||||
MODE_RESET_STATISTICS,
|
||||
} arg_mode = MODE_RESOLVE_HOST;
|
||||
@ -547,15 +550,10 @@ static int resolve_rfc4501(sd_bus *bus, const char *name) {
|
||||
} else
|
||||
n = p;
|
||||
|
||||
if (type == 0)
|
||||
type = arg_type;
|
||||
if (type == 0)
|
||||
type = DNS_TYPE_A;
|
||||
|
||||
if (class == 0)
|
||||
class = arg_class;
|
||||
if (class == 0)
|
||||
class = DNS_CLASS_IN;
|
||||
class = arg_class ?: DNS_CLASS_IN;
|
||||
if (type == 0)
|
||||
type = arg_type ?: DNS_TYPE_A;
|
||||
|
||||
return resolve_record(bus, n, class, type);
|
||||
|
||||
@ -765,6 +763,36 @@ static int resolve_service(sd_bus *bus, const char *name, const char *type, cons
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int resolve_openpgp(sd_bus *bus, const char *address) {
|
||||
const char *domain, *full;
|
||||
int r;
|
||||
_cleanup_free_ char *hashed = NULL;
|
||||
|
||||
assert(bus);
|
||||
assert(address);
|
||||
|
||||
domain = strrchr(address, '@');
|
||||
if (!domain) {
|
||||
log_error("Address does not contain '@': \"%s\"", address);
|
||||
return -EINVAL;
|
||||
} else if (domain == address || domain[1] == '\0') {
|
||||
log_error("Address starts or ends with '@': \"%s\"", address);
|
||||
return -EINVAL;
|
||||
}
|
||||
domain++;
|
||||
|
||||
r = string_hashsum(address, domain - 1 - address, GCRY_MD_SHA224, &hashed);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Hashing failed: %m");
|
||||
|
||||
full = strjoina(hashed, "._openpgpkey.", domain);
|
||||
log_debug("Looking up \"%s\".", full);
|
||||
|
||||
return resolve_record(bus, full,
|
||||
arg_class ?: DNS_CLASS_IN,
|
||||
arg_type ?: DNS_TYPE_OPENPGPKEY);
|
||||
}
|
||||
|
||||
static int show_statistics(sd_bus *bus) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
@ -947,6 +975,7 @@ static void help(void) {
|
||||
" --service Resolve service (SRV)\n"
|
||||
" --service-address=BOOL Do [not] resolve address for services\n"
|
||||
" --service-txt=BOOL Do [not] resolve TXT records for services\n"
|
||||
" --openpgp Query OpenPGP public key\n"
|
||||
" --cname=BOOL Do [not] follow CNAME redirects\n"
|
||||
" --search=BOOL Do [not] use search domains\n"
|
||||
" --legend=BOOL Do [not] print column headers and meta information\n"
|
||||
@ -963,6 +992,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_CNAME,
|
||||
ARG_SERVICE_ADDRESS,
|
||||
ARG_SERVICE_TXT,
|
||||
ARG_OPENPGP,
|
||||
ARG_SEARCH,
|
||||
ARG_STATISTICS,
|
||||
ARG_RESET_STATISTICS,
|
||||
@ -980,6 +1010,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "service", no_argument, NULL, ARG_SERVICE },
|
||||
{ "service-address", required_argument, NULL, ARG_SERVICE_ADDRESS },
|
||||
{ "service-txt", required_argument, NULL, ARG_SERVICE_TXT },
|
||||
{ "openpgp", no_argument, NULL, ARG_OPENPGP },
|
||||
{ "search", required_argument, NULL, ARG_SEARCH },
|
||||
{ "statistics", no_argument, NULL, ARG_STATISTICS, },
|
||||
{ "reset-statistics", no_argument, NULL, ARG_RESET_STATISTICS },
|
||||
@ -1089,6 +1120,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_mode = MODE_RESOLVE_SERVICE;
|
||||
break;
|
||||
|
||||
case ARG_OPENPGP:
|
||||
arg_mode = MODE_RESOLVE_OPENPGP;
|
||||
break;
|
||||
|
||||
case ARG_CNAME:
|
||||
r = parse_boolean(optarg);
|
||||
if (r < 0)
|
||||
@ -1248,6 +1283,24 @@ int main(int argc, char **argv) {
|
||||
|
||||
break;
|
||||
|
||||
case MODE_RESOLVE_OPENPGP:
|
||||
if (argc < optind + 1) {
|
||||
log_error("E-mail address required.");
|
||||
r = -EINVAL;
|
||||
goto finish;
|
||||
|
||||
}
|
||||
|
||||
r = 0;
|
||||
while (optind < argc) {
|
||||
int k;
|
||||
|
||||
k = resolve_openpgp(bus, argv[optind++]);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
}
|
||||
break;
|
||||
|
||||
case MODE_STATISTICS:
|
||||
if (argc > optind) {
|
||||
log_error("Too many arguments.");
|
||||
|
@ -38,3 +38,32 @@ void initialize_libgcrypt(bool secmem) {
|
||||
gcry_control(GCRYCTL_DISABLE_SECMEM);
|
||||
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
}
|
||||
|
||||
int string_hashsum(const char *s, size_t len, int md_algorithm, char **out) {
|
||||
gcry_md_hd_t md = NULL;
|
||||
size_t hash_size;
|
||||
void *hash;
|
||||
char *enc;
|
||||
|
||||
initialize_libgcrypt(false);
|
||||
|
||||
hash_size = gcry_md_get_algo_dlen(md_algorithm);
|
||||
assert(hash_size > 0);
|
||||
|
||||
gcry_md_open(&md, md_algorithm, 0);
|
||||
if (!md)
|
||||
return -EIO;
|
||||
|
||||
gcry_md_write(md, s, len);
|
||||
|
||||
hash = gcry_md_read(md, 0);
|
||||
if (!hash)
|
||||
return -EIO;
|
||||
|
||||
enc = hexmem(hash, hash_size);
|
||||
if (!enc)
|
||||
return -ENOMEM;
|
||||
|
||||
*out = enc;
|
||||
return 0;
|
||||
}
|
||||
|
@ -22,3 +22,4 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
void initialize_libgcrypt(bool secmem);
|
||||
int string_hashsum(const char *s, size_t len, int md_algorithm, char **out);
|
||||
|
Loading…
Reference in New Issue
Block a user