From: Christian Hofstaedtler Date: Tue, 29 Dec 2015 13:17:32 +0000 (+0100) Subject: API: clean up cryptokeys resource X-Git-Tag: dnsdist-1.0.0-beta1~21^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=29704f6624be738b2950c92b7e008fc5c1eb06d0;p=pdns API: clean up cryptokeys resource Treat domain not found as a normal not found; treat all keys absent for single resource request as a normal not found; return an object instead of a single-valued list for single resource requests and rename "content" to "privatekey" and don't re-read the key from the backend. Also share UeberBackend with DNSSECKeeper to avoid extra backend connection. --- diff --git a/docs/markdown/httpapi/api_spec.md b/docs/markdown/httpapi/api_spec.md index ebaa41aa1..9e387ddc2 100644 --- a/docs/markdown/httpapi/api_spec.md +++ b/docs/markdown/httpapi/api_spec.md @@ -648,7 +648,7 @@ cryptokey\_resource "active": , "keytype": , "dnskey": , - "content": , + "privatekey": , "ds": [ , , .... ] @@ -659,13 +659,14 @@ cryptokey\_resource `id`: read-only. -`keytype`: `` is one of the following: `ksk` or `zsk`, and they are -both mutually exclusive. +`keytype`: `` is one of the following: `ksk`, `zsk`, `csk`. `dnskey`: the DNSKEY for this key `ds`: an array with all DSes for this key +`privatekey`: private key data (in ISC format). + URL: /api/v1/servers/:server\_id/zones/:zone\_name/cryptokeys ------------------------------------------------------------- @@ -674,7 +675,7 @@ Allowed methods: `GET`, `POST` #### GET -Returns all public data about cryptokeys, but not `content`. +Returns all public data about cryptokeys, but not `privatekey`. #### POST @@ -700,7 +701,7 @@ Allowed methods: `GET`, `PUT`, `DELETE` #### GET -Returns all public data about cryptokeys, including `content`, with all the private data. An array is returned, even though a single key is requested. +Returns all public data about cryptokeys, including `privatekey`. #### PUT diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 2be03a189..b103a6efb 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -527,27 +527,27 @@ static void apiZoneCryptokeys(HttpRequest* req, HttpResponse* resp) { if(req->method != "GET") throw ApiException("Only GET is implemented"); + bool inquireSingleKey = false; + int inquireKeyId; + if (req->parameters.count("key_id")) { + inquireSingleKey = true; + inquireKeyId = std::stoi(req->parameters["key_id"]); + } + DNSName zonename = apiZoneIdToName(req->parameters["id"]); UeberBackend B; + DNSSECKeeper dk(&B); DomainInfo di; - DNSSECKeeper dk; - if(!B.getDomainInfo(zonename, di)) - throw ApiException("Could not find domain '"+zonename.toString()+"'"); + throw HttpNotFoundException(); DNSSECKeeper::keyset_t keyset=dk.getKeys(zonename, false); - if (keyset.empty()) - throw ApiException("No keys for zone '"+zonename.toString()+"'"); - Json::array doc; - for(const DNSSECKeeper::keyset_t::value_type value : keyset) { - if (req->parameters.count("key_id")) { - int keyid = std::stoi(req->parameters["key_id"]); - int curid = value.second.id; - if (keyid != curid) - continue; + for(const auto& value : keyset) { + if (inquireSingleKey && inquireKeyId != value.second.id) { + continue; } string keyType; @@ -566,11 +566,6 @@ static void apiZoneCryptokeys(HttpRequest* req, HttpResponse* resp) { { "dnskey", value.first.getDNSKEY().getZoneRepresentation() } }; - if (req->parameters.count("key_id")) { - DNSSECPrivateKey dpk=dk.getKeyById(zonename, std::stoi(req->parameters["key_id"])); - key["content"] = dpk.getKey()->convertToISC(); - } - if (value.second.keyType == DNSSECKeeper::KSK || value.second.keyType == DNSSECKeeper::CSK) { Json::array dses; for(const int keyid : { 1, 2, 3, 4 }) @@ -579,9 +574,19 @@ static void apiZoneCryptokeys(HttpRequest* req, HttpResponse* resp) { } catch (...) {} key["ds"] = dses; } + + if (inquireSingleKey) { + key["privatekey"] = value.first.getKey()->convertToISC(); + resp->setBody(key); + return; + } doc.push_back(key); } + if (inquireSingleKey) { + // we came here because we couldn't find the requested key. + throw HttpNotFoundException(); + } resp->setBody(doc); }