diff --git a/interface/lib/classes/validate_dkim.inc.php b/interface/lib/classes/validate_dkim.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..12c094587574fdab8d59d7dd7de9ec82a6fb0d6c
--- /dev/null
+++ b/interface/lib/classes/validate_dkim.inc.php
@@ -0,0 +1,79 @@
+tform->wordbook[$errmsg])) {
+ return $app->tform->wordbook[$errmsg]." \r\n";
+ } else {
+ return $errmsg." \r\n";
+ }
+ }
+
+ /* Validator function for private DKIM-Key */
+ function check_private_key($field_name, $field_value, $validator) {
+ $dkim_enabled=$_POST['dkim'];
+ if ($dkim_enabled == 'y') {
+ if (empty($field_value)) return $this->get_error($validator['errmsg']);
+ exec('echo '.escapeshellarg($field_value).'|openssl rsa -check',$output,$result);
+ if($result != 0) return $this->get_error($validator['errmsg']);
+ }
+ }
+
+ /* Validator function for DKIM Path */
+ function check_dkim_path($field_name, $field_value, $validator) {
+ if(empty($field_value)) return $this->get_error($validator['errmsg']);
+ if (substr(sprintf('%o', fileperms($field_value)),-3) <= 600)
+ return $this->get_error($validator['errmsg']);
+ }
+
+ /* Check function for DNS-Template */
+ function check_template($field_name, $field_value, $validator) {
+ $dkim=false;
+ foreach($field_value as $field ) { if($field == 'DKIM') $dkim=true; }
+ if ($dkim && $field_value[0]!='DOMAIN') return $this->get_error($validator['errmsg']);
+ }
+
+ /* Validator function for $_POST */
+ function validate_post($key,$value) {
+ switch ($key) {
+ case 'public':
+ if (preg_match("/(^-----BEGIN PUBLIC KEY-----)[a-zA-Z0-9\r\n\/\+=]{1,221}(-----END PUBLIC KEY-----(\n|\r)$)/",$value) === 1) { return true; } else { return false; }
+ break;
+ case 'private':
+ if (preg_match("/(^-----BEGIN RSA PRIVATE KEY-----)[a-zA-Z0-9\r\n\/\+=]{1,850}(-----END RSA PRIVATE KEY-----(\n|\r)$)/",$value) === 1) { return true; } else { return false; }
+ break;
+ }
+ }
+}
+
diff --git a/interface/web/dns/dns_dkim_edit.php b/interface/web/dns/dns_dkim_edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..61b0bd7fb6f290f8c9449b81478ab8fce886422a
--- /dev/null
+++ b/interface/web/dns/dns_dkim_edit.php
@@ -0,0 +1,142 @@
+auth->check_module_permissions('dns');
+
+// Loading classes
+$app->uses('tpl,tform,tform_actions,validate_dns');
+$app->load('tform_actions');
+
+class page_action extends tform_actions {
+
+ function onShowNew() {
+ global $app, $conf;
+ // we will check only users, not admins
+ if($_SESSION["s"]["user"]["typ"] == 'user') {
+
+ // Get the limits of the client
+ $client_group_id = $_SESSION["s"]["user"]["default_group"];
+ $client = $app->db->queryOneRecord("SELECT limit_dns_record FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
+
+ // Check if the user may add another record.
+ if($client["limit_dns_record"] >= 0) {
+ $tmp = $app->db->queryOneRecord("SELECT count(id) as number FROM dns_rr WHERE sys_groupid = $client_group_id");
+ if($tmp["number"] >= $client["limit_dns_record"]) {
+ $app->error($app->tform->wordbook["limit_dns_record_txt"]);
+ }
+ }
+ }
+
+ parent::onShowNew();
+ }
+
+ function onSubmit() {
+ global $app, $conf;
+ // Get the parent soa record of the domain
+ $soa = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = '".$app->functions->intval($_POST["zone"])."' AND ".$app->tform->getAuthSQL('r'));
+ // Check if Domain belongs to user
+ if($soa["id"] != $_POST["zone"]) $app->tform->errorMessage .= $app->tform->wordbook["no_zone_perm"];
+
+ // Check the client limits, if user is not the admin
+ if($_SESSION["s"]["user"]["typ"] != 'admin') { // if user is not admin
+ // Get the limits of the client
+ $client_group_id = $_SESSION["s"]["user"]["default_group"];
+ $client = $app->db->queryOneRecord("SELECT limit_dns_record FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
+ // Check if the user may add another record.
+ if($this->id == 0 && $client["limit_dns_record"] >= 0) {
+ $tmp = $app->db->queryOneRecord("SELECT count(id) as number FROM dns_rr WHERE sys_groupid = $client_group_id");
+ if($tmp["number"] >= $client["limit_dns_record"]) {
+ $app->error($app->tform->wordbook["limit_dns_record_txt"]);
+ }
+ }
+ } // end if user is not admin
+
+ // Set the server ID of the rr record to the same server ID as the parent record.
+ $this->dataRecord["server_id"] = $soa["server_id"];
+
+ // add dkim-settings to the public-key in the txt-record
+ $this->dataRecord['data']='v=DKIM1; t=s; p='.$this->dataRecord['data'];
+ $this->dataRecord['name']='default._domainkey.'.$this->dataRecord['name'];
+
+ // Update the serial number and timestamp of the RR record
+ $soa = $app->db->queryOneRecord("SELECT serial FROM dns_rr WHERE id = ".$this->id);
+ $this->dataRecord["serial"] = $app->validate_dns->increase_serial($soa["serial"]);
+ $this->dataRecord["stamp"] = date('Y-m-d H:i:s');
+
+ // check for duplicate entry
+ $check=$app->db->queryOneRecord("SELECT * FROM dns_rr WHERE zone = ".$this->dataRecord["zone"]." AND type = '".$this->dataRecord["type"]."' AND data ='".$this->dataRecord["data"]."' AND name = '".$this->dataRecord['name']."'");
+ if ($check!='') $app->tform->errorMessage .= $app->tform->wordbook["record_exists_txt"];
+
+ parent::onSubmit();
+ }
+
+ function onAfterInsert() {
+ global $app, $conf;
+
+ //* Set the sys_groupid of the rr record to be the same then the sys_groupid of the soa record
+ $soa = $app->db->queryOneRecord("SELECT sys_groupid,serial FROM dns_soa WHERE id = '".$app->functions->intval($this->dataRecord["zone"])."' AND ".$app->tform->getAuthSQL('r'));
+ $app->db->datalogUpdate('dns_rr', "sys_groupid = ".$soa['sys_groupid'], 'id', $this->id);
+
+ //* Update the serial number of the SOA record
+ $soa_id = $app->functions->intval($_POST["zone"]);
+ $serial = $app->validate_dns->increase_serial($soa["serial"]);
+ $app->db->datalogUpdate('dns_soa', "serial = $serial", 'id', $soa_id);
+ }
+
+ function onAfterUpdate() {
+ global $app, $conf;
+
+ //* Update the serial number of the SOA record
+ $soa = $app->db->queryOneRecord("SELECT serial FROM dns_soa WHERE id = '".$app->functions->intval($this->dataRecord["zone"])."' AND ".$app->tform->getAuthSQL('r'));
+ $soa_id = $app->functions->intval($_POST["zone"]);
+ $serial = $app->validate_dns->increase_serial($soa["serial"]);
+ $app->db->datalogUpdate('dns_soa', "serial = $serial", 'id', $soa_id);
+ }
+}
+
+$page = new page_action;
+$page->onLoad();
+
+?>
diff --git a/interface/web/dns/dns_dkim_get.php b/interface/web/dns/dns_dkim_get.php
new file mode 100644
index 0000000000000000000000000000000000000000..6b8b90b4c2386ee2d3780bd22f34a312693f8a2f
--- /dev/null
+++ b/interface/web/dns/dns_dkim_get.php
@@ -0,0 +1,91 @@
+auth->check_module_permissions('dns');
+
+global $app, $conf;
+
+// Loading classes
+$app->uses('tform,tform_actions');
+
+header('Content-Type: text/xml; charset=utf-8');
+header('Cache-Control: must-revalidate, pre-check=0, no-store, no-cache, max-age=0, post-check=0');
+
+/*
+ This function fix PHP's messing up POST input containing characters space, dot,
+ open square bracket and others to be compatible with with the deprecated register_globals
+*/
+function getRealPOST() {
+ $pairs = explode("&", file_get_contents("php://input"));
+ $vars = array();
+ foreach ($pairs as $pair) {
+ $nv = explode("=", $pair, 2);
+ $name = urldecode($nv[0]);
+ $value = $nv[1];
+ $vars[$name] = $value;
+ }
+ return $vars;
+}
+function pub_key($pubkey) {
+ $public_key='';
+ foreach($pubkey as $values) $public_key=$public_key.$values;
+ return $public_key;
+}
+
+$_POST=getRealPost();
+
+if (ctype_digit($_POST['zone'])) {
+ // Get the parent soa record of the domain
+ $soa = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = '".$app->db->quote($_POST['zone'])."' AND ".$app->tform->getAuthSQL('r'));
+
+ $public_key=$app->db->queryOneRecord("SELECT dkim_public FROM mail_domain WHERE domain = '".substr_replace($soa['origin'],'',-1)."' AND ".$app->tform->getAuthSQL('r'));
+
+ $public_key=pub_key($public_key);
+
+ $public_key=str_replace(array('-----BEGIN PUBLIC KEY-----','-----END PUBLIC KEY-----',"\r","\n"),'',$public_key);
+
+ echo "\n";
+ echo "\n";
+ echo "".$public_key."\n";
+ echo "".$soa['origin']."\n";
+ echo "\n";
+}
+?>
diff --git a/interface/web/dns/form/dns_dkim.tform.php b/interface/web/dns/form/dns_dkim.tform.php
new file mode 100644
index 0000000000000000000000000000000000000000..ffeee58bf6366ecff71941414ca45dccb57e9d95
--- /dev/null
+++ b/interface/web/dns/form/dns_dkim.tform.php
@@ -0,0 +1,154 @@
+ 0 id must match with id of current user
+$form["auth_preset"]["groupid"] = 0; // 0 = default groupid of the user, > 0 id must match with groupid of current user
+$form["auth_preset"]["perm_user"] = 'riud'; //r = read, i = insert, u = update, d = delete
+$form["auth_preset"]["perm_group"] = 'riud'; //r = read, i = insert, u = update, d = delete
+$form["auth_preset"]["perm_other"] = ''; //r = read, i = insert, u = update, d = delete
+
+$form["tabs"]['dns'] = array (
+ 'title' => "DNS DKIM",
+ 'width' => 100,
+ 'template' => "templates/dns_dkim_edit.htm",
+ 'fields' => array (
+ ##################################
+ # Begin Datatable fields
+ ##################################
+ 'server_id' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'SELECT',
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'zone' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'TEXT',
+ 'default' => @$app->functions->intval($_REQUEST["zone"]),
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'name' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'filters' => array( 0 => array( 'event' => 'SAVE',
+ 'type' => 'IDNTOASCII'),
+ 1 => array( 'event' => 'SHOW',
+ 'type' => 'IDNTOUTF8'),
+ 2 => array( 'event' => 'SAVE',
+ 'type' => 'TOLOWER')
+ ),
+ 'validators' => array ( 0 => array ( 'type' => 'REGEX',
+ 'regex' => '/^[\w\.\-]{0,255}$/',
+ 'errmsg'=> 'name_error_regex'),
+ ),
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'type' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'default' => 'TXT',
+ 'value' => '',
+ 'width' => '5',
+ 'maxlength' => '5'
+ ),
+ 'data' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY',
+ 'errmsg'=> 'data_error_empty'),
+ ),
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'ttl' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'TEXT',
+ 'default' => '86400',
+ 'value' => '',
+ 'width' => '10',
+ 'maxlength' => '10'
+ ),
+ 'active' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'CHECKBOX',
+ 'default' => 'Y',
+ 'value' => array(0 => 'N',1 => 'Y')
+ ),
+ 'stamp' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'serial' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'TEXT',
+ 'default' => '',
+ 'value' => '',
+ 'width' => '10',
+ 'maxlength' => '10'
+ ),
+ ##################################
+ # ENDE Datatable fields
+ ##################################
+ )
+);
+
+
+
+?>
diff --git a/interface/web/dns/lib/lang/en_dns_dkim.lng b/interface/web/dns/lib/lang/en_dns_dkim.lng
new file mode 100644
index 0000000000000000000000000000000000000000..526257e909b508c4cb844cc9252acb5fe412bb0a
--- /dev/null
+++ b/interface/web/dns/lib/lang/en_dns_dkim.lng
@@ -0,0 +1,8 @@
+
diff --git a/interface/web/dns/templates/dns_dkim_edit.htm b/interface/web/dns/templates/dns_dkim_edit.htm
new file mode 100644
index 0000000000000000000000000000000000000000..cbf8db941a11a6a534bd5b54c47b40852bef07f3
--- /dev/null
+++ b/interface/web/dns/templates/dns_dkim_edit.htm
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/interface/web/js/dns_dkim.js b/interface/web/js/dns_dkim.js
new file mode 100644
index 0000000000000000000000000000000000000000..1294fd024968dd5e15a08581857b8b30848f22e5
--- /dev/null
+++ b/interface/web/js/dns_dkim.js
@@ -0,0 +1,73 @@
+/*
+Copyright (c) 2007 - 2013, Till Brehm, projektfarm Gmbh
+Copyright (c) 2013, Florian Schaal, info@schaal-24.de
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+This Javascript is invoked by
+ * dns/templates/dns_dkim_edit.htm to get the public key
+*/
+ var request = false;
+
+ function setRequest(zone) {
+ if (window.XMLHttpRequest) {request = new XMLHttpRequest();}
+ else if (window.ActiveXObject) {
+ try {request = new ActiveXObject('Msxml2.XMLHTTP');}
+ catch (e) {
+ try {request = new ActiveXObject('Microsoft.XMLHTTP');}
+ catch (e) {}
+ }
+ }
+ if (!request) {
+ alert("Error creating XMLHTTP-instance");
+ return false;
+ } else {
+ request.open('POST', 'dns/dns_dkim_get.php', true);
+ request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ request.send('&zone='+zone);
+ request.onreadystatechange = interpretRequest;
+ }
+ }
+
+ function interpretRequest() {
+ switch (request.readyState) {
+ case 4:
+ if (request.status != 200) {alert("Request done but NOK\nError:"+request.status);}
+ else {
+ document.getElementsByName('data')[0].value = request.responseXML.getElementsByTagName('data')[0].firstChild.nodeValue;
+ document.getElementsByName('name')[0].value = request.responseXML.getElementsByTagName('name')[0].firstChild.nodeValue;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+var serverType = jQuery('#zone').val();
+setRequest(serverType);
+
+
diff --git a/interface/web/js/mail_domain_dkim.js b/interface/web/js/mail_domain_dkim.js
new file mode 100644
index 0000000000000000000000000000000000000000..b07abc4f3e1e225420f6a9804b3092aa53973691
--- /dev/null
+++ b/interface/web/js/mail_domain_dkim.js
@@ -0,0 +1,72 @@
+/*
+Copyright (c) 2007 - 2013, Till Brehm, projektfarm Gmbh
+Copyright (c) 2013, Florian Schaal, info@schaal-24.de
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+This Javascript is invoked by
+ * mail/templates/mail_domain_edit.htm to show and/or create the key-pair
+*/
+ var request = false;
+
+ function setRequest(action,value,privatekey) {
+ if (window.XMLHttpRequest) {request = new XMLHttpRequest();}
+ else if (window.ActiveXObject) {
+ try {request = new ActiveXObject('Msxml2.XMLHTTP');}
+ catch (e) {
+ try {request = new ActiveXObject('Microsoft.XMLHTTP');}
+ catch (e) {}
+ }
+ }
+ if (!request) {
+ alert("Error creating XMLHTTP-instance");
+ return false;
+ } else {
+ request.open('POST', 'mail/mail_domain_dkim_create.php', true);
+ request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ request.send('domain='+value+'&action='+action+'&pkey='+privatekey);
+ request.onreadystatechange = interpretRequest;
+ }
+ }
+
+ function interpretRequest() {
+ switch (request.readyState) {
+ case 4:
+ if (request.status != 200) {alert("Request done but NOK\nError:"+request.status);}
+ else {
+ document.getElementsByName('dkim_private')[0].value = request.responseXML.getElementsByTagName('privatekey')[0].firstChild.nodeValue;
+ document.getElementsByName('dkim_public')[0].value = request.responseXML.getElementsByTagName('publickey')[0].firstChild.nodeValue;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+var serverType = jQuery('#dkim_private').val();
+setRequest('show','{tmpl_var name="domain"}',serverType);
+
diff --git a/interface/web/mail/mail_domain_dkim_create.php b/interface/web/mail/mail_domain_dkim_create.php
new file mode 100644
index 0000000000000000000000000000000000000000..aab83a6d3395220e1fa97791ba04260a90e0e920
--- /dev/null
+++ b/interface/web/mail/mail_domain_dkim_create.php
@@ -0,0 +1,99 @@
+auth->check_module_permissions('mail');
+
+header('Content-Type: text/xml; charset=utf-8');
+header('Cache-Control: must-revalidate, pre-check=0, no-store, no-cache, max-age=0, post-check=0');
+
+/*
+ This function fix PHP's messing up POST input containing characters space, dot,
+ open square bracket and others to be compatible with with the deprecated register_globals
+*/
+function getRealPOST() {
+ $pairs = explode("&", file_get_contents("php://input"));
+ $vars = array();
+ foreach ($pairs as $pair) {
+ $nv = explode("=", $pair, 2);
+ $name = urldecode($nv[0]);
+ $value = $nv[1];
+ $vars[$name] = $value;
+ }
+ return $vars;
+}
+
+function pub_key($pubkey) {
+ $public_key='';
+ foreach($pubkey as $values) $public_key=$public_key.$values."\n";
+ return $public_key;
+}
+$_POST=getRealPOST();
+
+switch ($_POST['action']) {
+ case 'create': /* create DKIM Private-key */
+ exec('openssl rand -out /usr/local/ispconfig/server/temp/random-data.bin 4096',$output,$result);
+ exec('openssl genrsa -rand /usr/local/ispconfig/server/temp/random-data.bin 1024',$privkey,$result);
+ unlink("/usr/local/ispconfig/server/temp/random-data.bin");
+ $private_key='';
+ foreach($privkey as $values) $private_key=$private_key.$values."\n";
+ if($validate_dkim->validate_post('private',$private_key)) { /* validate the $_POST-value */
+ exec('echo '.escapeshellarg($private_key).'|openssl rsa -pubout -outform PEM',$pubkey,$result);
+ $public_key=pub_key($pubkey);
+ } else { $public_key='invalid key'; }
+ break;
+ case 'show': /* show the DNS-Record onLoad */
+ $private_key=$_POST['pkey'];
+ if($validate_dkim->validate_post('private',$private_key)) { /* validate the $_POST-value */
+ /* get the public-key */
+ exec('echo '.escapeshellarg($private_key).'|openssl rsa -pubout -outform PEM',$pubkey,$result);
+ $public_key=pub_key($pubkey);
+ } else { $public_key='invalid key'; }
+ break;
+}
+echo "\n";
+echo "\n";
+echo "".$private_key."\n";
+echo "".$public_key."\n";
+echo "\n";
+?>