Add dkim support (Patch by Florian).
10 files modified
4 files added
New file |
| | |
| | | ALTER TABLE `mail_domain` ADD `dkim_public` MEDIUMTEXT NOT NULL AFTER `domain`; |
| | | ALTER TABLE `mail_domain` ADD `dkim_private` MEDIUMTEXT NOT NULL AFTER `domain`; |
| | | ALTER TABLE `mail_domain` ADD `dkim` ENUM( 'n', 'y' ) NOT NULL AFTER `domain`; |
| | |
| | | `sys_perm_other` varchar(5) NOT NULL default '', |
| | | `server_id` int(11) unsigned NOT NULL default '0', |
| | | `domain` varchar(255) NOT NULL default '', |
| | | `dkim` ENUM( 'n', 'y' ) NOT NULL default 'n', |
| | | `dkim_private` mediumtext NOT NULL default '', |
| | | `dkim_public` mediumtext NOT NULL default '', |
| | | `active` enum('n','y') NOT NULL, |
| | | PRIMARY KEY (`domain_id`), |
| | | KEY `server_id` (`server_id`,`domain`), |
| | |
| | | -- |
| | | -- Dumping data for table `sys_config` |
| | | -- |
| | | |
| | |
|
| | | INSERT INTO sys_config VALUES ('1','db','db_version','3.0.5.2'); |
| | | |
| | | SET FOREIGN_KEY_CHECKS = 1; |
| | |
|
| | | SET FOREIGN_KEY_CHECKS = 1; |
| | |
| | | # Set the log_level to 5 for debugging |
| | | $log_level = 0; # (defaults to 0) |
| | | |
| | | # DKIM |
| | | |
| | | $enable_dkim_verification = 1; |
| | | $enable_dkim_signing = 1; # load DKIM signing code, |
| | | @dkim_signature_options_bysender_maps = ( |
| | | { '.' => { ttl => 21*24*3600, c => 'relaxed/simple' } } ); |
| | | |
| | | #------------ Do not modify anything below this line ------------- |
| | | 1; # insure a defined return |
| | |
| | | $DO_SYSLOG = 1; |
| | | $LOGFILE = "/var/log/amavis.log"; # (defaults to empty, no log) |
| | | |
| | | # DKIM |
| | | |
| | | $enable_dkim_verification = 1; |
| | | $enable_dkim_signing = 1; # load DKIM signing code, |
| | | @dkim_signature_options_bysender_maps = ( |
| | | { '.' => { ttl => 21*24*3600, c => 'relaxed/simple' } } ); |
| | | |
| | | 1; # insure a defined return |
| | |
| | | module=postfix_mysql |
| | | maildir_path=/var/vmail/[domain]/[localpart] |
| | | homedir_path=/var/vmail |
| | | dkim_path=/etc/postfix/dkim |
| | | pop3_imap_daemon=courier |
| | | mail_filter_syntax=maildrop |
| | | mailuser_uid=5000 |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | 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. |
| | | */ |
| | | |
| | | class validate_dkim { |
| | | |
| | | function get_error($errmsg) { |
| | | global $app; |
| | | if(isset($app->tform->wordbook[$errmsg])) { |
| | | return $app->tform->wordbook[$errmsg]."<br>\r\n"; |
| | | } else { |
| | | return $errmsg."<br>\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 "'.$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']); |
| | | } |
| | | |
| | | } |
| | |
| | | 'width' => '40', |
| | | 'maxlength' => '255' |
| | | ), |
| | | 'dkim_path' => array( |
| | | 'datatype' => 'VARCHAR', |
| | | 'formtype' => 'TEXT', |
| | | 'default' => '/var/db/dkim', |
| | | 'validators' => array ( 0 => array ('type' => 'CUSTOM', |
| | | 'class' => 'validate_dkim', |
| | | 'function' => 'check_dkim_path', |
| | | 'errmsg'=> 'dkim_path_error'), |
| | | ), |
| | | 'value' => '', |
| | | 'width' => '40', |
| | | 'maxlength' => '255' |
| | | ), |
| | | 'pop3_imap_daemon' => array( |
| | | 'datatype' => 'VARCHAR', |
| | | 'formtype' => 'SELECT', |
| | |
| | | $wb["module_txt"] = 'Module'; |
| | | $wb["maildir_path_txt"] = 'Maildir Path'; |
| | | $wb["homedir_path_txt"] = 'Homedir Path'; |
| | | $wb["dkim_path_txt"] = 'DKIM Path'; |
| | | $wb["dkim_path_error"] = 'DKIM Path not found or not writeable.'; |
| | | $wb["mailuser_uid_txt"] = 'Mailuser UID'; |
| | | $wb["mailuser_gid_txt"] = 'Mailuser GID'; |
| | | $wb["mailuser_name_txt"] = 'Mailuser Name'; |
| | |
| | | <input name="homedir_path" id="homedir_path" value="{tmpl_var name='homedir_path'}" size="40" maxlength="255" type="text" class="textInput" /> |
| | | </div> |
| | | <div class="ctrlHolder"> |
| | | <label for="dkim_path">{tmpl_var name='dkim_path_txt'}</label> |
| | | <input name="dkim_path" id="dkim_path" value="{tmpl_var name='dkim_path'}" size="40" maxlength="255" type="text" class="textInput" /> |
| | | </div> |
| | | <div class="ctrlHolder"> |
| | | <p class="label">{tmpl_var name='pop3_imap_daemon_txt'}</p> |
| | | <div class="multiField"> |
| | | <select name="pop3_imap_daemon" id="pop3_imap_daemon" class="selectInput"> |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | </div> |
| | | </div> |
| | |
| | | 'maxlength' => '255', |
| | | 'searchable' => 1 |
| | | ), |
| | | 'dkim' => array ( |
| | | 'datatype' => 'VARCHAR', |
| | | 'formtype' => 'CHECKBOX', |
| | | 'default' => 'n', |
| | | 'value' => array(0 => 'n',1 => 'y') |
| | | ), |
| | | 'dkim_private' => array ( |
| | | 'datatype' => 'TEXT', |
| | | 'formtype' => 'TEXTAREA', |
| | | 'default' => '', |
| | | 'value' => '', |
| | | 'cols' => '30', |
| | | 'rows' => '10', |
| | | 'validators' => array ( 0 => array ('type' => 'CUSTOM', |
| | | 'class' => 'validate_dkim', |
| | | 'function' => 'check_private_key', |
| | | 'errmsg'=> 'dkim_private_key_error'), |
| | | ), |
| | | ), |
| | | 'dkim_public' => array ( |
| | | 'datatype' => 'TEXT', |
| | | 'formtype' => 'TEXTAREA', |
| | | 'default' => '', |
| | | 'value' => '', |
| | | 'cols' => '30', |
| | | 'rows' => '10' |
| | | ), |
| | | 'active' => array ( |
| | | 'datatype' => 'VARCHAR', |
| | | 'formtype' => 'CHECKBOX', |
| | |
| | | ); |
| | | |
| | | |
| | | ?> |
| | | ?> |
| | |
| | | $wb["domain_txt"] = 'Domain'; |
| | | $wb["type_txt"] = 'Type'; |
| | | $wb["active_txt"] = 'Active'; |
| | | $wb["dkim_txt"] = 'enable DKIM'; |
| | | $wb["dkim_private_txt"] = 'DKIM Private-key'; |
| | | $wb["dkim_generate_txt"] = 'Generate DKIM Private-key'; |
| | | $wb["dkim_dns_txt"] = 'DNS-Record (TYPE TXT)<br><br>add this record to your DNS'; |
| | | $wb["dkim_private_key_error"] = 'Invalid DKIM-Private key'; |
| | | $wb["domain_error_empty"] = 'Domain is empty.'; |
| | | $wb["domain_error_unique"] = 'Duplicate Domain.'; |
| | | $wb["domain_error_regex"] = 'Invalid domain name.'; |
| | | $wb["dkim_settings_txt"] = 'DomainKeys Identified Mail (DKIM)'; |
| | | $wb["client_txt"] = 'Client'; |
| | | $wb["limit_maildomain_txt"] = 'The max. number of email domains for your account is reached.'; |
| | | $wb["policy_txt"] = 'Spamfilter'; |
| | | $wb["no_policy"] = '- not enabled -'; |
| | | ?> |
| | | ?> |
New file |
| | |
| | | <?php |
| | | /* |
| | | 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 script is invoked by the java-script in interface/web/mail/templates/mail_domain_edit.htm |
| | | when generating the DKIM Private-key. |
| | | |
| | | return DKIM Private-Key and DNS-record |
| | | */ |
| | | |
| | | require_once('../../lib/config.inc.php'); |
| | | |
| | | 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 dns_record() { |
| | | global $private_key; |
| | | $public_key=''; |
| | | exec('echo "'.$private_key.'"|openssl rsa -pubout -outform PEM',$pubkey,$result); |
| | | $pubkey=array_diff($pubkey,array('-----BEGIN PUBLIC KEY-----','-----END PUBLIC KEY-----')); |
| | | foreach($pubkey as $values) $public_key=$public_key.$values."\n"; |
| | | $dns_record="HOSTNAME: default._domainkey.".$_POST['domain'].".\n\nTEXT: v=DKIM1; t=s; p=".$public_key; |
| | | return $dns_record; |
| | | } |
| | | |
| | | $_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"; |
| | | $dns_record=dns_record(); |
| | | break; |
| | | case 'show': /* show the DNS-Record onLoad */ |
| | | $private_key=$_POST['pkey']; |
| | | $dns_record=dns_record(); |
| | | break; |
| | | } |
| | | echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; |
| | | echo "<formatname>\n"; |
| | | echo "<privatekey>".$private_key."</privatekey>\n"; |
| | | echo "<dnsrecord>".$dns_record."</dnsrecord>\n"; |
| | | echo "</formatname>\n"; |
| | | ?> |
| | |
| | | {tmpl_var name='active'} |
| | | </div> |
| | | </div> |
| | | <div class="subsectiontoggle"><span></span>{tmpl_var name='dkim_settings_txt'}<em></em></div> |
| | | <div style="display:none;"> |
| | | <div class="ctrlHolder"> |
| | | <p class="label">{tmpl_var name='dkim_txt'}</p> |
| | | <div class="multiField"> |
| | | {tmpl_var name='dkim'} |
| | | </div> |
| | | </div> |
| | | <div class="ctrlHolder"> |
| | | <label for="dkim_private">{tmpl_var name='dkim_private_txt'}</label> |
| | | <textarea name="dkim_private" id="dkim_private" rows='10' cols='30'>{tmpl_var name='dkim_private'}</textarea> |
| | | <a href="javascript:setRequest('create','{tmpl_var name='domain'}')">{tmpl_var name='dkim_generate_txt'}</a> |
| | | </div> |
| | | <div class="ctrlHolder"> |
| | | <label for="dkim_dns">{tmpl_var name='dkim_dns_txt'}</label> |
| | | <textarea name="dkim_dns" id="dkim_dns" rows='10' cols='30'>{tmpl_var name='dkim_dns'}</textarea> |
| | | </div> |
| | | </div> |
| | | </fieldset> |
| | | |
| | | <input type="hidden" name="id" value="{tmpl_var name='id'}"> |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | </div> |
| | | </div> |
| | | <script language="JavaScript" type="text/javascript"> |
| | | 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_dns')[0].value = request.responseXML.getElementsByTagName('dnsrecord')[0].firstChild.nodeValue; |
| | | } |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | |
| | | var serverType = jQuery('#dkim_private').val(); |
| | | setRequest('show','{tmpl_var name="domain"}',serverType); |
| | | </script> |
| | | |
New file |
| | |
| | | <?php |
| | | |
| | | /* |
| | | todo: |
| | | - DNS interaction |
| | | */ |
| | | /* |
| | | 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. |
| | | */ |
| | | |
| | | class mail_plugin_dkim { |
| | | |
| | | var $plugin_name = 'mail_plugin_dkim'; |
| | | var $class_name = 'mail_plugin_dkim'; |
| | | |
| | | // private variables |
| | | var $action = ''; |
| | | |
| | | /* |
| | | This function is called during ispconfig installation to determine |
| | | if a symlink shall be created for this plugin. |
| | | */ |
| | | function onInstall() { |
| | | global $conf; |
| | | |
| | | if($conf['services']['mail'] == true) { |
| | | return true; |
| | | } else { |
| | | return false; |
| | | } |
| | | |
| | | } |
| | | |
| | | /* |
| | | This function is called when the plugin is loaded |
| | | */ |
| | | function onLoad() { |
| | | global $app,$conf; |
| | | /* |
| | | Register for the events |
| | | */ |
| | | $app->plugins->registerEvent('mail_domain_delete',$this->plugin_name,'domain_dkim_delete'); |
| | | $app->plugins->registerEvent('mail_domain_insert',$this->plugin_name,'domain_dkim_insert'); |
| | | $app->plugins->registerEvent('mail_domain_update',$this->plugin_name,'domain_dkim_update'); |
| | | |
| | | // Register service |
| | | $app->services->registerService('amavisd','mail_module','restartAmavisd'); |
| | | } |
| | | |
| | | /* |
| | | This function gets the amavisd-config file |
| | | */ |
| | | function get_amavis_config() { |
| | | $pos_config=array( |
| | | '/etc/amavisd.conf', |
| | | '/etc/amavisd.conf/50-user' |
| | | ); |
| | | $amavis_configfile=''; |
| | | foreach($pos_config as $conf) { |
| | | if (is_file($conf)) { |
| | | $amavis_configfile=$conf; |
| | | break; |
| | | } |
| | | } |
| | | return $amavis_configfile; |
| | | } |
| | | |
| | | /* |
| | | This function checks the relevant configs and disables dkim for the domain |
| | | if the directory for dkim is not writeable or does not exist |
| | | */ |
| | | function check_system($data) { |
| | | global $app,$mail_config; |
| | | $app->uses('getconf'); |
| | | $check=true; |
| | | /* check for amavis-config */ |
| | | if ( $this->get_amavis_config() == '' || !is_writeable($this->get_amavis_config()) ) { |
| | | $app->log('Amavis-config not found or not writeable.',LOGLEVEL_ERROR); |
| | | $check=false; |
| | | } |
| | | /* dir for dkim-keys writeable? */ |
| | | $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); |
| | | if (isset($mail_config['dkim_path']) && isset($data['new']['dkim_private']) && !empty($data['new']['dkim_private'])) { |
| | | if (!is_writeable($mail_config['dkim_path'])) { |
| | | $app->log('DKIM Path '.$mail_config['dkim_path'].' not found or not writeable.',LOGLEVEL_ERROR); |
| | | $check=false; |
| | | } |
| | | } else { |
| | | $app->log('Unable to write DKIM settings; Check your config!',LOGLEVEL_ERROR); |
| | | $check=false; |
| | | } |
| | | if (!$check) { |
| | | $app->db->query("UPDATE mail_domain SET dkim = 'n' WHERE domain = '".$data['new']['domain']."'"); |
| | | $app->dbmaster->query("UPDATE mail_domain SET dkim = 'n' WHERE domain = '".$data['new']['domain']."'"); |
| | | } |
| | | return $check; |
| | | } |
| | | |
| | | /* |
| | | This function restarts amavis |
| | | */ |
| | | function restart_amavis() { |
| | | global $app,$conf; |
| | | $initfile=$conf['init_scripts'].'/amavis'; |
| | | $app->log('Restarting amavis.',LOGLEVEL_DEBUG); |
| | | exec($conf['init_scripts'].'/amavis restart',$output); |
| | | foreach($output as $logline) $app->log($logline,LOGLEVEL_DEBUG); |
| | | } |
| | | |
| | | /* |
| | | This function writes the keyfiles (public and private) |
| | | The public-key is always created and stored into the db and local key-file |
| | | */ |
| | | function write_dkim_key($key_file,$key_value,$key_domain) { |
| | | global $app,$mailconfig; |
| | | $success=false; |
| | | if (!file_put_contents($key_file.'.private',$key_value) === false) { |
| | | $app->log('Saved DKIM Private-key to '.$key_file.'.private',LOGLEVEL_DEBUG); |
| | | $success=true; |
| | | /* now we get the DKIM Public-key */ |
| | | exec('cat "'.$key_file.'.private'.'"|openssl rsa -pubout',$pubkey,$result); |
| | | $public_key=''; |
| | | foreach($pubkey as $values) $public_key=$public_key.$values."\n"; |
| | | /* save the DKIM Public-key in dkim-dir */ |
| | | if (!file_put_contents($key_file.'.public',$public_key) === false) |
| | | $app->log('Saved DKIM Public to '.$key_domain.'.',LOGLEVEL_DEBUG); |
| | | else $app->log('Unable to save DKIM Public to '.$key_domain.'.',LOGLEVEL_WARNING); |
| | | /* store the private-key to the databse(s) */ |
| | | $app->log('Store the DKIM Public-key in database.',LOGLEVEL_DEBUG); |
| | | $app->db->query("UPDATE mail_domain SET dkim_public = '".$public_key."' WHERE domain = '".$ky_domain."'"); |
| | | $app->dbmaster->query("UPDATE mail_domain SET dkim_public = '".$public_key."' WHERE domain = '".$key_domain."'"); |
| | | } |
| | | return $success; |
| | | } |
| | | |
| | | /* |
| | | This function removes the keyfiles |
| | | */ |
| | | function remove_dkim_key($key_file,$key_domain) { |
| | | global $app; |
| | | if (file_exists($key_file.'.private')) { |
| | | exec('rm -f '.$key_file.'.private'); |
| | | $app->log('Deleted the DKIM Private-key for '.$key_domain.'.',LOGLEVEL_DEBUG); |
| | | } else $app->log('Unable to delete the DKIM Private-key for '.$key_domain.' (not found).',LOGLEVEL_DEBUG); |
| | | if (file_exists($key_file.'.public')) { |
| | | exec('rm -f '.$key_file.'.public'); |
| | | $app->log('Deleted the DKIM Public-key for '.$key_domain.'.',LOGLEVEL_DEBUG); |
| | | } else $app->log('Unable to delete the DKIM Public-key for '.$key_domain.' (not found).',LOGLEVEL_DEBUG); |
| | | } |
| | | |
| | | /* |
| | | This function adds the entry to the amavisd-config |
| | | */ |
| | | function add_to_amavis($key_domain) { |
| | | global $app,$mail_config; |
| | | $amavis_config = file_get_contents($this->get_amavis_config()); |
| | | $key_value="dkim_key('".$key_domain."', 'default', '".$mail_config['dkim_path']."/".$key_domain.".private');\n"; |
| | | if(strpos($amavis_config, $key_value) !== false) $amavis_config = str_replace($key_value, '', $amavis_config); |
| | | if (!file_put_contents($this->get_amavis_config(),$key_value,FILE_APPEND) === false) { |
| | | $app->log('Adding DKIM Private-key to amavis-config.',LOGLEVEL_DEBUG); |
| | | $this->restart_amavis(); |
| | | } |
| | | } |
| | | |
| | | /* |
| | | This function removes the entry from the amavisd-config |
| | | */ |
| | | function remove_from_amavis($key_domain) { |
| | | global $app; |
| | | $amavis_config = file($this->get_amavis_config()); |
| | | $i=0;$found=false; |
| | | foreach($amavis_config as $line) { |
| | | if (preg_match("/^\bdkim_key\b.*\b".$key_domain."\b/",$line)) { |
| | | unset($amavis_config[$i]); |
| | | $found=true; |
| | | } |
| | | $i++; |
| | | } |
| | | if ($found) { |
| | | file_put_contents($this->get_amavis_config(), $amavis_config); |
| | | $app->log('Deleted the DKIM settings from amavis-config for '.$key_domain.'.',LOGLEVEL_DEBUG); |
| | | $this->restart_amavis(); |
| | | } else $app->log('Unable to delete the DKIM settings from amavis-config for '.$key_domain.'.',LOGLEVEL_ERROR); |
| | | } |
| | | |
| | | /* |
| | | This function controlls new key-files and amavisd-entries |
| | | */ |
| | | function add_dkim($data) { |
| | | global $app; |
| | | $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); |
| | | if ( substr($mail_config['dkim_path'],strlen($mail_config['dkim_path'])-1) == '/' ) |
| | | $mail_config['dkim_path'] = substr($mail_config['dkim_path'],0,strlen($mail_config['dkim_path'])-1); |
| | | if ($this->write_dkim_key($mail_config['dkim_path']."/".$data['new']['domain'],$data['new']['dkim_private'],$data['new']['domain'])) { |
| | | $this->add_to_amavis($data['new']['domain']); |
| | | } else { |
| | | $app->log('Error saving the DKIM Private-key for '.$data['new']['domain'].' - DKIM is now disabled for the domain.',LOGLEVEL_ERROR); |
| | | $app->db->query("UPDATE mail_domain SET dkim = 'n' WHERE domain = '".$data['new']['domain']."'"); |
| | | $app->dbmaster->query("UPDATE mail_domain SET dkim = 'n' WHERE domain = '".$data['new']['domain']."'"); |
| | | } |
| | | } |
| | | |
| | | /* |
| | | This function controlls the removement of keyfiles (public and private) |
| | | and the entry in the amavisd-config |
| | | */ |
| | | function remove_dkim($_data) { |
| | | global $app; |
| | | $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); |
| | | if ( substr($mail_config['dkim_path'],strlen($mail_config['dkim_path'])-1) == '/' ) |
| | | $mail_config['dkim_path'] = substr($mail_config['dkim_path'],0,strlen($mail_config['dkim_path'])-1); |
| | | $this->remove_dkim_key($mail_config['dkim_path']."/".$_data['domain'],$_data['domain']); |
| | | $this->remove_from_amavis($_data['domain']); |
| | | } |
| | | |
| | | /* |
| | | Functions called by onLoad |
| | | */ |
| | | function domain_dkim_delete($event_name,$data) { |
| | | if (isset($data['old']['dkim']) && $data['old']['dkim'] == 'y') $this->remove_dkim($data['old']); |
| | | } |
| | | |
| | | function domain_dkim_insert($event_name,$data) { |
| | | if (isset($data['new']['dkim']) && $data['new']['dkim']=='y' && $this->check_system($data)) { |
| | | /* if the domain is already defined, remove from amavis */ |
| | | $this->remove_from_amavis($data['new']['domain']); |
| | | // $this->remove_from_amavis("dkim_key('".$data['new']['domain']."', 'default', '".$mail_config['dkim_path']."/".$data['new']['domain'].".private');\n",$data['new']['domain']); |
| | | $this->add_dkim($data); |
| | | } |
| | | } |
| | | |
| | | function domain_dkim_update($event_name,$data) { |
| | | global $app; |
| | | /* get the config */ |
| | | if (isset($data['new']['dkim']) && $data['new']['dkim']=='y') { /* DKIM enabled */ |
| | | if ($this->check_system($data)) { |
| | | /* new domain-name */ |
| | | if ($data['old']['domain'] != $data['new']['domain']) { |
| | | $this->remove_dkim($data['old']); |
| | | $this->add_dkim($data); |
| | | } |
| | | /* new key */ |
| | | if (($data['old']['dkim_private'] != $data['new']['dkim_private']) || ($data['old']['dkim'] != $data['new']['dkim'])) { |
| | | if ($data['new']['dkim_private'] != $data['old']['dkim_private']) $this->remove_dkim($data['new']); |
| | | $this->add_dkim($data); |
| | | } |
| | | /* change active (on / off) */ |
| | | if ($data['old']['active'] != $data['new']['active']) { |
| | | if ($data['new']['active'] == 'y') { |
| | | $this->add_dkim($data); |
| | | } else { |
| | | $this->remove_dkim($data['new']); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if (isset($data['new']['dkim']) && $data['old']['dkim'] != $data['new']['dkim']) |
| | | if ($this->check_system($data) && $data['new']['dkim'] == 'n') $this->remove_dkim($data['new']); |
| | | } |
| | | } |
| | | ?> |