Skip to content

Commit 3f9c6a3

Browse files
author
Webslice
committed
Add support for powerdns 4.x, fixes #5223
1 parent 9d417c0 commit 3f9c6a3

File tree

1 file changed

+67
-41
lines changed

1 file changed

+67
-41
lines changed

server/plugins-available/powerdns_plugin.inc.php

Lines changed: 67 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
Redistribution and use in source and binary forms, with or without modification,
88
are permitted provided that the following conditions are met:
99
10-
* Redistributions of source code must retain the above copyright notice,
11-
this list of conditions and the following disclaimer.
12-
* Redistributions in binary form must reproduce the above copyright notice,
13-
this list of conditions and the following disclaimer in the documentation
14-
and/or other materials provided with the distribution.
15-
* Neither the name of ISPConfig nor the names of its contributors
16-
may be used to endorse or promote products derived from this software without
17-
specific prior written permission.
10+
* Redistributions of source code must retain the above copyright notice,
11+
this list of conditions and the following disclaimer.
12+
* Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
* Neither the name of ISPConfig nor the names of its contributors
16+
may be used to endorse or promote products derived from this software without
17+
specific prior written permission.
1818
1919
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2020
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -97,7 +97,7 @@ function onInstall() {
9797

9898

9999
/*
100-
This function is called when the plugin is loaded
100+
This function is called when the plugin is loaded
101101
*/
102102

103103
function onLoad() {
@@ -421,15 +421,23 @@ function find_pdns_control() {
421421
}
422422
}
423423

424-
function find_pdns_pdnssec() {
424+
function find_pdns_pdnssec_or_pdnsutil() {
425425
$output = array();
426426
$retval = '';
427+
428+
// The command is named pdnssec in PowerDNS 3
427429
exec("type -p pdnssec", $output, $retval);
428430
if ($retval == 0 && is_file($output[0])){
429431
return $output[0];
430-
} else {
431-
return false;
432432
}
433+
434+
// But in PowerNDS 4 they renamed it to pdnsutil
435+
exec("type -p pdnsutil", $output, $retval);
436+
if ($retval == 0 && is_file($output[0])){
437+
return $output[0];
438+
}
439+
440+
return false;
433441
}
434442

435443
function zoneRediscover() {
@@ -466,6 +474,14 @@ function get_pdns_version() {
466474
}
467475
}
468476

477+
function is_pdns_version_supported() {
478+
if (preg_match('/^[34]/',$this->get_pdns_version())) {
479+
return true;
480+
}
481+
482+
return false;
483+
}
484+
469485
function handle_dnssec($data) {
470486
// If origin changed, delete keys first
471487
if ($data['old']['origin'] != $data['new']['origin']) {
@@ -475,26 +491,26 @@ function handle_dnssec($data) {
475491
}
476492

477493
// If DNSSEC is disabled, but was enabled before, just disable DNSSEC but leave the keys in dns_info
478-
if ($data['new']['dnssec_wanted'] === 'N' && $data['old']['dnssec_initialized'] === 'Y') {
494+
if ($data['new']['dnssec_wanted'] === 'N' && $data['old']['dnssec_wanted'] === 'Y') {
479495
$this->soa_dnssec_disable($data);
480496

481497
return;
482498
}
483499

484500
// If DNSSEC is wanted, enable it
485-
if ($data['new']['dnssec_wanted'] === 'Y') {
501+
if ($data['new']['dnssec_wanted'] === 'Y' && $data['old']['dnssec_wanted'] === 'N') {
486502
$this->soa_dnssec_create($data);
487503
}
488504
}
489505

490506
function soa_dnssec_create($data) {
491507
global $app;
492508

493-
if (!preg_match('/^3/',$this->get_pdns_version()) ) {
509+
if (false === $this->is_pdns_version_supported()) {
494510
return;
495511
}
496512

497-
$pdns_pdnssec = $this->find_pdns_pdnssec();
513+
$pdns_pdnssec = $this->find_pdns_pdnssec_or_pdnsutil();
498514
if ($pdns_pdnssec === false) {
499515
return;
500516
}
@@ -504,9 +520,13 @@ function soa_dnssec_create($data) {
504520

505521
// We don't log the actual commands here, because having commands in the dnssec_info field will trigger
506522
// the IDS if you try to save the record using the interface afterwards.
507-
$cmd_secure_zone = sprintf('%s secure-zone %s 2>&1', $pdns_pdnssec, $zone);
508-
$log[] = sprintf("\r\n%s %s", date('c'), 'Running secure-zone command...');
509-
exec($cmd_secure_zone, $log);
523+
$cmd_add_zone_key_ksk = sprintf('%s add-zone-key %s ksk active 2048 rsasha256', $pdns_pdnssec, $zone);
524+
$log[] = sprintf("\r\n%s %s", date('c'), 'Running add-zone-key ksk command...');
525+
exec($cmd_add_zone_key_ksk, $log);
526+
527+
$cmd_add_zone_key_zsk = sprintf('%s add-zone-key %s zsk active 1024 rsasha256', $pdns_pdnssec, $zone);
528+
$log[] = sprintf("\r\n%s %s", date('c'), 'Running add-zone-key zsk command...');
529+
exec($cmd_add_zone_key_zsk, $log);
510530

511531
$cmd_set_nsec3 = sprintf('%s set-nsec3 %s "1 0 10 deadbeef" 2>&1', $pdns_pdnssec, $zone);
512532
$log[] = sprintf("\r\n%s %s", date('c'), 'Running set-nsec3 command...');
@@ -539,17 +559,19 @@ function format_dnssec_pubkeys($lines) {
539559
switch ($part = substr($line, 0, 3)) {
540560
case 'ID ':
541561
// Only process active keys
542-
if (!strpos($line, 'Active: 1')) {
543-
continue;
562+
// 'Active: 1' is pdnssec (PowerDNS 3.x) output
563+
// 'Active (' is pdnsutil (PowerDNS 4.x) output
564+
if (!strpos($line, 'Active: 1') && !strpos($line, 'Active ( ')) {
565+
break;
544566
}
545567

546-
// Determine key type (KSK or ZSK)
547-
preg_match('/(KSK|ZSK)/', $line, $matches_key_type);
568+
// Determine key type (KSK, ZSK or CSK)
569+
preg_match('/(KSK|ZSK|CSK)/', $line, $matches_key_type);
548570
$key_type = $matches_key_type[1];
549571

550-
// We only care about the KSK
551-
if ('ZSK' === $key_type) {
552-
continue;
572+
// We only care about the KSK or CSK
573+
if (!in_array($key_type, ['KSK', 'CSK'], true)) {
574+
break;
553575
}
554576

555577
// Determine key tag
@@ -568,6 +590,7 @@ function format_dnssec_pubkeys($lines) {
568590
break;
569591

570592
case 'KSK':
593+
case 'CSK':
571594
// Determine DNSKEY
572595
preg_match('/ IN DNSKEY \d+ \d+ \d+ (.*) ;/', $line, $matches_dnskey);
573596
$formatted[] = sprintf('DNSKEY: %s', $matches_dnskey[1]);
@@ -604,11 +627,11 @@ function format_dnssec_pubkeys($lines) {
604627
function soa_dnssec_disable($data) {
605628
global $app;
606629

607-
if (!preg_match('/^3/',$this->get_pdns_version()) ) {
630+
if (false === $this->is_pdns_version_supported()) {
608631
return;
609632
}
610633

611-
$pdns_pdnssec = $this->find_pdns_pdnssec();
634+
$pdns_pdnssec = $this->find_pdns_pdnssec_or_pdnsutil();
612635
if ($pdns_pdnssec === false) {
613636
return;
614637
}
@@ -631,11 +654,11 @@ function soa_dnssec_disable($data) {
631654
function soa_dnssec_delete($data) {
632655
global $app;
633656

634-
if (!preg_match('/^3/',$this->get_pdns_version()) ) {
657+
if (false === $this->is_pdns_version_supported()) {
635658
return;
636659
}
637660

638-
$pdns_pdnssec = $this->find_pdns_pdnssec();
661+
$pdns_pdnssec = $this->find_pdns_pdnssec_or_pdnsutil();
639662
if ($pdns_pdnssec === false) {
640663
return;
641664
}
@@ -661,17 +684,20 @@ function soa_dnssec_delete($data) {
661684

662685
function rectifyZone($data) {
663686
global $app, $conf;
664-
if ( preg_match('/^3/',$this->get_pdns_version()) ) {
665-
$pdns_pdnssec = $this->find_pdns_pdnssec();
666-
if ( $pdns_pdnssec != false ) {
667-
if (isset($data["new"]["origin"])) {
668-
//* data has origin field only for SOA recordtypes
669-
exec($pdns_pdnssec . ' rectify-zone ' . rtrim($data["new"]["origin"],"."));
670-
} else {
671-
// get origin from DB for all other recordtypes
672-
$zn = $app->db->queryOneRecord("SELECT d.name AS name FROM powerdns.domains d, powerdns.records r WHERE r.ispconfig_id=? AND r.domain_id = d.id", $data["new"]["id"]);
673-
exec($pdns_pdnssec . ' rectify-zone ' . trim($zn["name"]));
674-
}
687+
688+
if (false === $this->is_pdns_version_supported()) {
689+
return;
690+
}
691+
692+
$pdns_pdnssec = $this->find_pdns_pdnssec_or_pdnsutil();
693+
if ( $pdns_pdnssec != false ) {
694+
if (isset($data["new"]["origin"])) {
695+
//* data has origin field only for SOA recordtypes
696+
exec($pdns_pdnssec . ' rectify-zone ' . rtrim($data["new"]["origin"],"."));
697+
} else {
698+
// get origin from DB for all other recordtypes
699+
$zn = $app->db->queryOneRecord("SELECT d.name AS name FROM powerdns.domains d, powerdns.records r WHERE r.ispconfig_id=? AND r.domain_id = d.id", $data["new"]["id"]);
700+
exec($pdns_pdnssec . ' rectify-zone ' . trim($zn["name"]));
675701
}
676702
}
677703
}

0 commit comments

Comments
 (0)