]> granicus.if.org Git - pdns/commitdiff
API: be more strict when parsing record contents
authorChristian Hofstaedtler <christian@hofstaedtler.name>
Sat, 7 Feb 2015 12:58:08 +0000 (13:58 +0100)
committermind04 <mind04@monshouwer.org>
Thu, 26 Feb 2015 18:48:33 +0000 (19:48 +0100)
Fixes #2113.
(cherry picked from commit 1e5b9ab91512cfc71d1714185cc80bf8ba69fca9)

pdns/ws-auth.cc
regression-tests.api/test_Zones.py

index 66336278cf7bc8937ba7c846b53c3e355b549072..67ad5d25c2d79309c2d915c0c2be1e0f169fab7d 100644 (file)
@@ -407,10 +407,21 @@ static void gatherRecords(const Value& container, vector<DNSResourceRecord>& new
       try {
         shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(rr.qtype.getCode(), 1, rr.content));
         string tmp = drc->serialize(rr.qname);
+        if (rr.qtype.getCode() != QType::AAAA) {
+          tmp = drc->getZoneRepresentation();
+          if (!pdns_iequals(tmp, rr.content)) {
+            throw std::runtime_error("Not in expected format (parsed as '"+tmp+"')");
+          }
+        } else {
+          struct in6_addr tmpbuf;
+          if (inet_pton(AF_INET6, rr.content.c_str(), &tmpbuf) != 1 || rr.content.find('.') != string::npos) {
+            throw std::runtime_error("Invalid IPv6 address");
+          }
+        }
       }
       catch(std::exception& e)
       {
-        throw ApiException("Record "+rr.qname+"/"+rr.qtype.getName()+" "+rr.content+": "+e.what());
+        throw ApiException("Record "+rr.qname+"/"+rr.qtype.getName()+" '"+rr.content+"': "+e.what());
       }
 
       if ((rr.qtype.getCode() == QType::A || rr.qtype.getCode() == QType::AAAA) &&
index f05117efcc33dc2429b63f19c79df1358a8ba752..a9a153dbf4744303da840edec96251e47fa21ca9 100644 (file)
@@ -727,6 +727,30 @@ fred   IN  A      192.168.0.4
         self.assertEquals(r.status_code, 422)
         self.assertIn('unknown type', r.json()['error'])
 
+    def test_create_zone_with_leading_space(self):
+        # Actual regression.
+        payload, zone = self.create_zone()
+        name = payload['name']
+        rrset = {
+            'changetype': 'replace',
+            'name': name,
+            'type': 'A',
+            'records': [
+                {
+                    "name": name,
+                    "type": "A",
+                    "ttl": 3600,
+                    "content": " 4.3.2.1",
+                    "disabled": False
+                }
+            ]
+        }
+        payload = {'rrsets': [rrset]}
+        r = self.session.patch(self.url("/servers/localhost/zones/" + name), data=json.dumps(payload),
+                               headers={'content-type': 'application/json'})
+        self.assertEquals(r.status_code, 422)
+        self.assertIn('Not in expected format', r.json()['error'])
+
     def test_zone_rr_delete_out_of_zone(self):
         payload, zone = self.create_zone()
         name = payload['name']