From c943b4a88af9c9468013089869a5be6f3804de30 Mon Sep 17 00:00:00 2001
From: Florian Schaal <florian@schaal-24.de>
Date: Mon, 22 Sep 2014 14:55:56 +0200
Subject: [PATCH] FS#2696 - More than 256 chars in DNS record and FS#3679 -
 allow stronger dkim-keys

---
 install/sql/incremental/upd_0078.sql          |  2 ++
 install/sql/ispconfig3.sql                    |  2 +-
 install/tpl/server.ini.master                 | 14 +++++++++++
 interface/lib/classes/validate_dkim.inc.php   |  8 +++++--
 .../web/admin/form/server_config.tform.php    |  6 +++++
 .../web/admin/lib/lang/de_server_config.lng   |  1 +
 .../web/admin/lib/lang/en_server_config.lng   |  1 +
 .../web/admin/lib/lang/es_server_config.lng   |  2 +-
 .../web/admin/lib/lang/es_system_config.lng   |  2 +-
 .../web/admin/lib/lang/fr_server_config.lng   | 24 +++++++++----------
 .../templates/server_config_mail_edit.htm     |  8 +++++++
 interface/web/client/domain_edit.php          |  2 +-
 .../web/mail/mail_domain_dkim_create.php      | 18 +++++++++-----
 13 files changed, 66 insertions(+), 24 deletions(-)
 create mode 100644 install/sql/incremental/upd_0078.sql

diff --git a/install/sql/incremental/upd_0078.sql b/install/sql/incremental/upd_0078.sql
new file mode 100644
index 0000000000..6f25fa331f
--- /dev/null
+++ b/install/sql/incremental/upd_0078.sql
@@ -0,0 +1,2 @@
+ALTER TABLE `dns_rr` CHANGE `data` `data` TEXT NOT NULL DEFAULT ''
+ALTER TABLE `ftp_user` ADD `expires` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `dl_bandwidth` ;
diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql
index 7f81f7cd8e..d195547065 100644
--- a/install/sql/ispconfig3.sql
+++ b/install/sql/ispconfig3.sql
@@ -450,7 +450,7 @@ CREATE TABLE `dns_rr` (
   `zone` int(11) unsigned NOT NULL DEFAULT '0',
   `name` varchar(255) NOT NULL DEFAULT '',
   `type` enum('A','AAAA','ALIAS','CNAME','HINFO','MX','NAPTR','NS','PTR','RP','SRV','TXT') default NULL,
-  `data` varchar(255) NOT NULL DEFAULT '',
+  `data` TEXT NOT NULL DEFAULT '',
   `aux` int(11) unsigned NOT NULL default '0',
   `ttl` int(11) unsigned NOT NULL default '86400',
   `active` enum('N','Y') NOT NULL default 'Y',
diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master
index 427fc8d3b2..4d2a410f28 100644
--- a/install/tpl/server.ini.master
+++ b/install/tpl/server.ini.master
@@ -33,6 +33,7 @@ module=postfix_mysql
 maildir_path=/var/vmail/[domain]/[localpart]
 homedir_path=/var/vmail
 dkim_path=/var/lib/amavis/dkim
+dkim_strength=1024
 pop3_imap_daemon=courier
 mail_filter_syntax=maildrop
 mailuser_uid=5000
@@ -48,6 +49,19 @@ message_size_limit=0
 mailbox_quota_stats=y
 realtime_blackhole_list=
 overquota_notify_admin=y
+q
+q
+q
+q
+q
+q
+q
+q
+q
+q
+q
+q
+q
 overquota_notify_client=y
 overquota_notify_freq=7
 overquota_notify_onok=n
diff --git a/interface/lib/classes/validate_dkim.inc.php b/interface/lib/classes/validate_dkim.inc.php
index 5a9b8c0bec..71b8e85205 100644
--- a/interface/lib/classes/validate_dkim.inc.php
+++ b/interface/lib/classes/validate_dkim.inc.php
@@ -72,13 +72,17 @@ class validate_dkim {
 	 *
 	 * @return boolean - true if $POST contains a real key-file
 	 */
-	function validate_post($key, $value) {
+	function validate_post($key, $value, $dkim_strength) {
+		$value=str_replace("\n", "", $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; }
+			if ( $dkim_strength == 1024 ) $range = "{812,816}";
+			if ( $dkim_strength == 2048 ) $range = "{1588,1592}";
+			if ( $dkim_strength == 4096 ) $range = "{3132,3136}";
+			if (preg_match("/^-----BEGIN RSA PRIVATE KEY-----[a-zA-Z0-9\/\+=]".$range."-----END RSA PRIVATE KEY-----$/", $value) === 1) return true; else return false;
 			break;
 		}
 	}
diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php
index 8c6f89976b..71f2f13e1c 100644
--- a/interface/web/admin/form/server_config.tform.php
+++ b/interface/web/admin/form/server_config.tform.php
@@ -313,6 +313,12 @@ $form["tabs"]['mail'] = array(
 			'width' => '40',
 			'maxlength' => '255'
 		),
+		'dkim_strength' => array(
+			'datatype' => 'INTEGER',
+			'formtype' => 'SELECT',
+			'default' => '1024',
+			'value' => array('1024' => 'normal (1024)', '2048' => 'strong (2048)', '4096' => 'very strong (4096)')
+		),
         'relayhost_password' => array(
             'datatype' => 'VARCHAR',
             'formtype' => 'TEXT',
diff --git a/interface/web/admin/lib/lang/de_server_config.lng b/interface/web/admin/lib/lang/de_server_config.lng
index a6e71ba772..98bcac4dc5 100644
--- a/interface/web/admin/lib/lang/de_server_config.lng
+++ b/interface/web/admin/lib/lang/de_server_config.lng
@@ -198,4 +198,5 @@ $wb["v6_prefix_txt"] = 'IPv6 Prefix';
 $wb["vhost_rewrite_v6_txt"] = 'Rewrite IPv6 on Mirror';
 $wb["v6_prefix_length"] = 'Prefix zu lang fuer angegebene IPv6-Adresse ';
 $wb['monitor_system_updates_txt'] = 'Suche nach Linux updates';
+$wb['dkim_strength_txt'] = 'DKIM Stärke';
 ?>
diff --git a/interface/web/admin/lib/lang/en_server_config.lng b/interface/web/admin/lib/lang/en_server_config.lng
index 9331b50d8f..bf1cff66cf 100644
--- a/interface/web/admin/lib/lang/en_server_config.lng
+++ b/interface/web/admin/lib/lang/en_server_config.lng
@@ -202,4 +202,5 @@ $wb["overquota_db_notify_client_txt"] = 'Send DB quota warnings to client';
 $wb['monitor_system_updates_txt'] = 'Check for Linux updates';
 $wb['php_handler_txt'] = "PHP Handler";
 $wb['disabled_txt'] = 'Disabled';
+$wb['dkim_strength_txt'] = 'DKIM strength';
 ?>
diff --git a/interface/web/admin/lib/lang/es_server_config.lng b/interface/web/admin/lib/lang/es_server_config.lng
index 734d83bdec..7503f7da4a 100644
--- a/interface/web/admin/lib/lang/es_server_config.lng
+++ b/interface/web/admin/lib/lang/es_server_config.lng
@@ -159,7 +159,7 @@ $wb['backup_mode_txt'] = 'Modo de copias de seguridad';
 $wb['backup_mode_userzip'] = 'Copiar archivos del usuario web en un zip';
 $wb['backup_mode_rootgz'] = 'Copiar todos los archivos como usuario root';
 $wb['realtime_blackhole_list_txt'] = 'Real-time Blackhole List';
-$wb['realtime_blackhole_list_note_txt'] = '(Separar RBL's con comas)';
+$wb['realtime_blackhole_list_note_txt'] = "(Separar RBL's con comas)";
 $wb['ssl_settings_txt'] = 'Configuración SSL';
 $wb['permissions_txt'] = 'Permisos';
 $wb['php_settings_txt'] = 'Configuración de PHP';
diff --git a/interface/web/admin/lib/lang/es_system_config.lng b/interface/web/admin/lib/lang/es_system_config.lng
index 503d844b7f..41e61bf0c6 100644
--- a/interface/web/admin/lib/lang/es_system_config.lng
+++ b/interface/web/admin/lib/lang/es_system_config.lng
@@ -45,7 +45,7 @@ $wb['phpmyadmin_url_error_regex'] = 'URL de phpmyadmin no válida';
 $wb['use_combobox_txt'] = 'Usar Combobox de jQuery UI';
 $wb['use_loadindicator_txt'] = 'Usar indicador de carga';
 $wb['f5_to_reload_js_txt'] = 'Si cambias esto, podrías tener que pulsar F5 para que tu navegador recargue las librerías JavaScript o vacíar la caché del navegador.';
-$wb['client_username_web_check_disabled_txt'] = 'Desactivar comprobación de la palabra 'web' en el nombre de cliente.';
+$wb['client_username_web_check_disabled_txt'] = "Desactivar comprobación de la palabra 'web' en el nombre de cliente.";
 $wb['mailbox_show_autoresponder_tab_txt'] = 'Mostrar pestaña autoresponder en los detalles de la cuenta de correo';
 $wb['mailbox_show_mail_filter_tab_txt'] = 'Mostrar pestaña filtro de correo en los detalles de la cuenta de correo';
 $wb['mailbox_show_custom_rules_tab_txt'] = 'Mostrar pestaña filtros personalizados en los detalles de la cuenta de correo';
diff --git a/interface/web/admin/lib/lang/fr_server_config.lng b/interface/web/admin/lib/lang/fr_server_config.lng
index 671bc9b296..6db888febd 100644
--- a/interface/web/admin/lib/lang/fr_server_config.lng
+++ b/interface/web/admin/lib/lang/fr_server_config.lng
@@ -30,7 +30,7 @@ $wb['message_size_limit_txt'] = 'Taille maximale des messages';
 $wb['ip_address_txt'] = 'Adresse IP';
 $wb['netmask_txt'] = 'Masque de réau';
 $wb['gateway_txt'] = 'Passerelle';
-$wb['hostname_txt'] = 'Hô;
+$wb['hostname_txt'] = 'Hô';
 $wb['nameservers_txt'] = 'Serveurs de nom';
 $wb['auto_network_configuration_txt'] = 'Configuration du réau';
 $wb['website_basedir_txt'] = 'Rértoire de base web';
@@ -44,7 +44,7 @@ $wb['config_dir_txt'] = 'Rértoire de configuration';
 $wb['init_script_txt'] = 'Nom du script Cron de lancement';
 $wb['crontab_dir_txt'] = 'Chemin des difféntes tables Cron';
 $wb['wget_txt'] = 'Chemin du programme wget';
-$wb['security_level_txt'] = 'Niveau de sérité
+$wb['security_level_txt'] = 'Niveau de sérité';
 $wb['web_user_txt'] = 'Utilisateur Apache';
 $wb['web_group_txt'] = 'Groupe Apache';
 $wb['loglevel_txt'] = 'Loglevel';
@@ -76,20 +76,20 @@ $wb['php_ini_path_cgi_txt'] = 'Chemin php.ini CGI';
 $wb['php_ini_path_apache_txt'] = 'Chemin php.ini Apache';
 $wb['check_apache_config_txt'] = 'Tester la configuration Apache au redérrage';
 $wb['ufw_enable_txt'] = 'Enable';
-$wb['ufw_manage_builtins_txt'] = 'Gér les Rées Intéé;
+$wb['ufw_manage_builtins_txt'] = 'Gér les Rées Intéé';
 $wb['ufw_ipv6_txt'] = 'Activer l\'IPv6';
 $wb['ufw_default_input_policy_txt'] = 'Politique Entrant (Input) par déult';
 $wb['ufw_default_output_policy_txt'] = 'Politique Sortant (Output) par déult';
 $wb['ufw_default_forward_policy_txt'] = 'Politique de Forward par déult';
 $wb['ufw_default_application_policy_txt'] = 'Politique Application par déult';
 $wb['ufw_log_level_txt'] = 'Niveau de Log';
-$wb['network_config_warning_txt'] = 'L\'option de configuration du réau n'est disponible QUE pour les serveurs Debian et Ubuntu. NE PAS activer cette option si votre carte réau n'est pas en eth0.';
+$wb['network_config_warning_txt'] = "L\'option de configuration du réau n'est disponible QUE pour les serveurs Debian et Ubuntu. NE PAS activer cette option si votre carte réau n'est pas en eth0.";
 $wb['CA_path_txt'] = 'Chemin CA';
 $wb['CA_pass_txt'] = 'Mot de passe CA';
 $wb['fastcgi_config_syntax_txt'] = 'FastCGI config syntax';
 $wb['server_type_txt'] = 'Type de Serveur';
 $wb['nginx_vhost_conf_dir_txt'] = 'Repertoire Nginx Vhost config';
-$wb['nginx_vhost_conf_enabled_dir_txt'] = 'Repertoire Nginx Vhost config activé
+$wb['nginx_vhost_conf_enabled_dir_txt'] = 'Repertoire Nginx Vhost config activé';
 $wb['nginx_user_txt'] = 'Utilisateur Nginx';
 $wb['nginx_group_txt'] = 'Gorupe Nginx';
 $wb['nginx_cgi_socket_txt'] = 'Nginx CGI Socket';
@@ -145,7 +145,7 @@ $wb['php_fpm_socket_dir_error_empty'] = 'Repertoire PHP-FPM socket est vide.';
 $wb['try_rescue_txt'] = 'Activer le service de monitoring et redérrer sur éec';
 $wb['do_not_try_rescue_mysql_txt'] = 'Déctiver le monitoring MySQL';
 $wb['do_not_try_rescue_mail_txt'] = 'Déctiver le monitoring Email';
-$wb['rescue_description_txt'] = '<b>Information:</b> Si vous voulez arreter mysql vous devez selectionner la case Déctiver le monitoring MySQL puis attendre 2 à minutes.<br>Si vous n'attendez pas 2 à minutes, rescue va tenter de redérrer mysql!';
+$wb['rescue_description_txt'] = "<b>Information:</b> Si vous voulez arreter mysql vous devez selectionner la case Déctiver le monitoring MySQL puis attendre 2 à minutes.<br>Si vous n'attendez pas 2 à minutes, rescue va tenter de redérrer mysql!";
 $wb['enable_sni_txt'] = 'Activer SNI';
 $wb['do_not_try_rescue_httpd_txt'] = 'Déctiver le monitoring HTTPD ';
 $wb['set_folder_permissions_on_update_txt'] = 'Regler les permissions des dossiers lors de mise a jour';
@@ -155,7 +155,7 @@ $wb['connect_userid_to_webid_start_txt'] = 'ID de dért pour la liason userid/we
 $wb['website_autoalias_txt'] = 'Auto alias Site web';
 $wb['website_autoalias_note_txt'] = 'Placeholders:';
 $wb['backup_mode_txt'] = 'Mode Sauvegarde';
-$wb['backup_mode_userzip'] = 'Sauvegarder les fichiers web dont l'utilisateur est propriéire en tant que zip';
+$wb['backup_mode_userzip'] = "Sauvegarder les fichiers web dont l'utilisateur est propriéire en tant que zip";
 $wb['backup_mode_rootgz'] = 'Sauvegarder tous les fichiers dans le repertoire web en tant qu\'utilisateur root';
 $wb['realtime_blackhole_list_txt'] = 'Blackhole (trou noir) List en temps ré';
 $wb['realtime_blackhole_list_note_txt'] = '(Separer les RBL avec des virgules)';
@@ -170,7 +170,7 @@ $wb['enable_ip_wildcard_txt'] = 'Autoriser un joker (wildcard) IP (*)';
 $wb['web_folder_protection_txt'] = 'Rendre les dossiers web immuables (attributs éndus)';
 $wb['overtraffic_notify_admin_txt'] = 'Envoyer notification d\'overtraffic à\'admin';
 $wb['overtraffic_notify_client_txt'] = 'Envoyer notification d\'overtraffic au client';
-$wb['rbl_error_regex'] = 'Merci de renseigner des noms d'hô RBL valides.';
+$wb['rbl_error_regex'] = "Merci de renseigner des noms d'hô RBL valides.";
 $wb['overquota_notify_admin_txt'] = 'Envoyer alertes quota à\'admin';
 $wb['overquota_notify_client_txt'] = 'Envoyer alertes quota au client';
 $wb['overquota_notify_onok_txt'] = 'Envoyer message quota ok au client';
@@ -189,13 +189,13 @@ $wb['munin_password_txt'] = 'Mot de passe Munin';
 $wb['munin_url_error_regex'] = 'URL Munin non valide ';
 $wb['munin_url_note_txt'] = 'Placeholder:';
 $wb['backup_dir_is_mount_txt'] = 'Repertoir de Backup/sauvegarde est un mount?';
-$wb['backup_dir_mount_cmd_txt'] = 'Commande Mount, si le repertoire de sauvegarde/backup n'est pas monté
+$wb['backup_dir_mount_cmd_txt'] = "Commande Mount, si le repertoire de sauvegarde/backup n'est pas monté";
 $wb['monitor_system_updates_txt'] = 'Verifier pour des mises àour Linux';
 $wb['dkim_path_txt'] = 'Chemin DKIM';
 $wb["v6_prefix_txt"] = 'Prefix IPv6';
-$wb["vhost_rewrite_v6_txt"] = 'Récrire IPv6 sur miroir';
-$wb["v6_prefix_length"] = 'D\'aprèl'IPv6 déni, le préx est trop long ';
-$wb["overquota_db_notify_admin_txt"] = 'Envoyer avertissement DB quota à\'admin';
+$wb["vhost_rewrite_v6_txt"] = "Récrire IPv6 sur miroir";
+$wb["v6_prefix_length"] = "D\'aprèl'IPv6 déni, le préx est trop long";
+$wb["overquota_db_notify_admin_txt"] = "Envoyer avertissement DB quota à\'admin'";
 $wb["overquota_db_notify_client_txt"] = 'Envoyer avertissement DB quota au client';
 ?>
 
diff --git a/interface/web/admin/templates/server_config_mail_edit.htm b/interface/web/admin/templates/server_config_mail_edit.htm
index 2bf8f9368d..d21df15288 100644
--- a/interface/web/admin/templates/server_config_mail_edit.htm
+++ b/interface/web/admin/templates/server_config_mail_edit.htm
@@ -23,6 +23,14 @@
                 <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='dkim_strength_txt'}</p>
+				<div class="multiField">
+					<select name="dkim_strength" id="dkim_strength" class="selectInput">
+						{tmpl_var name='dkim_strength'}
+					</select>
+				</div>
+			</div>
             <div class="ctrlHolder">
                 <p class="label">{tmpl_var name='pop3_imap_daemon_txt'}</p>
                 <div class="multiField">
diff --git a/interface/web/client/domain_edit.php b/interface/web/client/domain_edit.php
index cda557c6e5..9b78988890 100644
--- a/interface/web/client/domain_edit.php
+++ b/interface/web/client/domain_edit.php
@@ -207,7 +207,7 @@ class page_action extends tform_actions {
 		if($_SESSION["s"]["user"]["typ"] != 'admin' && isset($this->dataRecord["client_group_id"])) {
 			$client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
 			$client = $app->db->queryOneRecord("SELECT client.client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
-			$group = $app->db->queryOneRecord("SELECT sys_group.groupid FROM sys_group, client WHERE sys_group.client_id = client.client_id AND client.parent_client_id = ".$client['client_id']." AND sys_group.groupid = ".$this->dataRecord["client_group_id"]." ORDER BY client.company_name, client.contact_name, sys_group.name";
+			$group = $app->db->queryOneRecord("SELECT sys_group.groupid FROM sys_group, client WHERE sys_group.client_id = client.client_id AND client.parent_client_id = ".$client['client_id']." AND sys_group.groupid = ".$this->dataRecord["client_group_id"]." ORDER BY client.company_name, client.contact_name, sys_group.name");
 			$this->dataRecord["client_group_id"] = $group["groupid"];
                 }
 
diff --git a/interface/web/mail/mail_domain_dkim_create.php b/interface/web/mail/mail_domain_dkim_create.php
index d0ac3e8c86..854bf9f55c 100644
--- a/interface/web/mail/mail_domain_dkim_create.php
+++ b/interface/web/mail/mail_domain_dkim_create.php
@@ -84,9 +84,9 @@ function pub_key($pubkey) {
 	return $public_key;
 }
 
-function get_public_key($private_key) {
+function get_public_key($private_key, $dkim_strength) {
 	$validate_dkim=new validate_dkim ();
-	if($validate_dkim->validate_post('private',$private_key)) { /* validate the $_POST-value */
+	if($validate_dkim->validate_post('private', $private_key, $dkim_strength)) { /* validate the $_POST-value */
 		exec('echo '.escapeshellarg($private_key).'|openssl rsa -pubout -outform PEM 2> /dev/null',$pubkey,$result);
 		$public_key=pub_key($pubkey);
 	} else {
@@ -123,12 +123,18 @@ function new_selector ($old_selector, $domain) {
 	return $selector;
 }
 
+//* get dkim-strength for server_id
+$mail_server_id = $app->functions->intval( $app->db->queryOneRecord("SELECT server_id from mail_domain WHERE domain = ?", $_POST['domain']) );
+$dkim_strength = $app->functions->intval( $app->getconf->get_server_config($mail_server_id, 'mail')['dkim_strength'] );
+if ( empty($dkim_strength) ) $dkim_strength = 1024;
+
 switch ($_POST['action']) {
 	case 'create': /* create DKIM Private-key */
+		$rnd_val = $dkim_strength * 10;
+		exec('openssl rand -out ../../temp/random-data.bin '.$rnd_val.' 2> /dev/null', $output, $result);
+		exec('openssl genrsa -rand ../../temp/random-data.bin '.$dkim_strength.' 2> /dev/null', $privkey, $result);
+		unlink('../../temp/random-data.bin');
 		$_POST=getRealPOST();
-		exec('openssl rand -out /usr/local/ispconfig/server/temp/random-data.bin 4096 2> /dev/null', $output, $result);
-		exec('openssl genrsa -rand /usr/local/ispconfig/server/temp/random-data.bin 1024 2> /dev/null', $privkey, $result);
-		unlink("/usr/local/ispconfig/server/temp/random-data.bin");
 		foreach($privkey as $values) $private_key=$private_key.$values."\n";
 		//* check the selector for updated dkim-settings only
 		if ( isset($_POST['dkim_public']) && !empty($_POST['dkim_public']) ) $selector = new_selector($_POST['dkim_selector'], $_POST['domain']); 
@@ -139,7 +145,7 @@ switch ($_POST['action']) {
 	break;
 }
 
-$public_key=get_public_key($private_key);
+$public_key=get_public_key($private_key, $dkim_strength);
 $dns_record=str_replace(array('-----BEGIN PUBLIC KEY-----','-----END PUBLIC KEY-----',"\r","\n"),'',$public_key);
 
 if ( !isset($selector) ) {
-- 
GitLab