diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index 3b0acb9dbc34d3acd275dfeadc2bb5a19b8254f5..7badb5405a64f61c19ea0e5ebffc8642d404ae01 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -840,15 +840,26 @@ CREATE TABLE `web_domain` ( `system_group` varchar(255) default NULL, `hd_quota` int(11) NOT NULL default '0', `traffic_quota` int(11) NOT NULL default '0', - `cgi` varchar(255) NOT NULL default 'y', - `ssi` varchar(255) NOT NULL default 'y', - `suexec` varchar(255) NOT NULL default 'y', + `cgi` char(1) NOT NULL default 'y', + `ssi` char(1) NOT NULL default 'y', + `suexec` char(1) NOT NULL default 'y', `php` varchar(255) NOT NULL default 'y', `redirect_type` varchar(255) default NULL, `redirect_path` varchar(255) default NULL, + `ssl` enum('n','y') NOT NULL default 'n', + `ssl_state` varchar(255) NOT NULL, + `ssl_locality` varchar(255) NOT NULL, + `ssl_organisation` varchar(255) NOT NULL, + `ssl_organisation_unit` varchar(255) NOT NULL, + `ssl_country` varchar(255) NOT NULL, + `ssl_request` mediumtext NOT NULL, + `ssl_cert` mediumtext NOT NULL, + `ssl_bundle` mediumtext NOT NULL, + `ssl_action` varchar(10) NOT NULL, `active` varchar(255) NOT NULL default 'y', PRIMARY KEY (`domain_id`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; + -- -- Daten für Tabelle `web_domain` diff --git a/interface/web/sites/form/web_domain.tform.php b/interface/web/sites/form/web_domain.tform.php index 383ac61637fed0ee154cbb18fd149ed025651294..009e6aecaf797870c901c544d0970575ce72da93 100644 --- a/interface/web/sites/form/web_domain.tform.php +++ b/interface/web/sites/form/web_domain.tform.php @@ -159,6 +159,12 @@ $form["tabs"]['domain'] = array ( 'default' => 'y', 'value' => array(0 => 'n',1 => 'y') ), + 'ssl' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n',1 => 'y') + ), 'php' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'SELECT', @@ -177,6 +183,7 @@ $form["tabs"]['domain'] = array ( ) ); + $form["tabs"]['redirect'] = array ( 'title' => "Redirect", 'width' => 100, @@ -188,7 +195,7 @@ $form["tabs"]['redirect'] = array ( 'redirect_type' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'SELECT', - 'default' => 'y', + 'default' => '', 'value' => array('' => 'No redirect', 'R' => 'R', 'L' => 'L') ), 'redirect_path' => array ( @@ -205,6 +212,90 @@ $form["tabs"]['redirect'] = array ( ) ); +$form["tabs"]['ssl'] = array ( + 'title' => "SSL", + 'width' => 100, + 'template' => "templates/web_domain_ssl.htm", + 'fields' => array ( + ################################## + # Begin Datatable fields + ################################## + 'ssl_state' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '', + 'value' => '', + 'width' => '30', + 'maxlength' => '255' + ), + 'ssl_locality' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '', + 'value' => '', + 'width' => '30', + 'maxlength' => '255' + ), + 'ssl_organisation' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '', + 'value' => '', + 'width' => '30', + 'maxlength' => '255' + ), + 'ssl_organisation_unit' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '', + 'value' => '', + 'width' => '30', + 'maxlength' => '255' + ), + 'ssl_country' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '', + 'value' => '', + 'width' => '30', + 'maxlength' => '255' + ), + 'ssl_request' => array ( + 'datatype' => 'TEXT', + 'formtype' => 'TEXTAREA', + 'default' => '', + 'value' => '', + 'cols' => '30', + 'rows' => '10' + ), + 'ssl_cert' => array ( + 'datatype' => 'TEXT', + 'formtype' => 'TEXTAREA', + 'default' => '', + 'value' => '', + 'cols' => '30', + 'rows' => '10' + ), + 'ssl_bundle' => array ( + 'datatype' => 'TEXT', + 'formtype' => 'TEXTAREA', + 'default' => '', + 'value' => '', + 'cols' => '30', + 'rows' => '10' + ), + 'ssl_action' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'default' => '', + 'value' => array('' => 'None', 'save' => 'Save Certificate', 'create' => 'Create Certificate') + ), + ################################## + # ENDE Datatable fields + ################################## + ) +); + if($_SESSION["s"]["user"]["typ"] == 'admin') { $form["tabs"]['advanced'] = array ( diff --git a/interface/web/sites/lib/lang/en_web_domain.lng b/interface/web/sites/lib/lang/en_web_domain.lng index bdb41e26c8b4b7b89bc0687f74b6ecfdf0c7aa2d..ffb180be9c877bc7e5767043e87d1c586f53b6f1 100644 --- a/interface/web/sites/lib/lang/en_web_domain.lng +++ b/interface/web/sites/lib/lang/en_web_domain.lng @@ -1,4 +1,15 @@ <?php +$wb["ssl_state_txt"] = 'State'; +$wb["ssl_locality_txt"] = 'Locality'; +$wb["ssl_organisation_txt"] = 'Organisation'; +$wb["ssl_organisation_unit_txt"] = 'Organisation Unit'; +$wb["ssl_country_txt"] = 'Country'; +$wb["ssl_request_txt"] = 'SSL Request'; +$wb["ssl_cert_txt"] = 'SSL Certificate'; +$wb["ssl_bundle_txt"] = 'SSL Bundle'; +$wb["ssl_action_txt"] = 'SSL Action'; +$wb["btn_save_txt"] = 'Save'; +$wb["btn_cancel_txt"] = 'Cancel'; $wb["server_id_txt"] = 'Server'; $wb["domain_txt"] = 'Domain'; $wb["type_txt"] = 'Type'; @@ -6,8 +17,6 @@ $wb["parent_domain_id_txt"] = 'Parent Website'; $wb["redirect_type_txt"] = 'Redirect Type'; $wb["redirect_path_txt"] = 'Redirect Path'; $wb["active_txt"] = 'Active'; -$wb["btn_save_txt"] = 'Save'; -$wb["btn_cancel_txt"] = 'Cancel'; $wb["document_root_txt"] = 'Documentroot'; $wb["system_user_txt"] = 'Linux User'; $wb["system_group_txt"] = 'Linux Group'; @@ -17,6 +26,7 @@ $wb["hd_quota_txt"] = 'Harddisk Quota'; $wb["traffic_quota_txt"] = 'Traffic Quaota'; $wb["cgi_txt"] = 'CGI'; $wb["ssi_txt"] = 'SSI'; +$wb["ssl_txt"] = 'SSL'; $wb["suexec_txt"] = 'SuEXEC'; $wb["php_txt"] = 'PHP'; $wb["client_txt"] = 'Client'; diff --git a/interface/web/sites/templates/web_domain_edit.htm b/interface/web/sites/templates/web_domain_edit.htm index 6310bd8689919a8817dc8cd86b51a4410fd28f33..36b4fd851fcbc14460f78f3de595cacdaaeb5ea0 100644 --- a/interface/web/sites/templates/web_domain_edit.htm +++ b/interface/web/sites/templates/web_domain_edit.htm @@ -75,6 +75,10 @@ <td class="frmText11">{tmpl_var name='suexec_txt'}:</td> <td class="frmText11">{tmpl_var name='suexec'}</td> </tr> + <tr> + <td class="frmText11">{tmpl_var name='ssl_txt'}:</td> + <td class="frmText11">{tmpl_var name='ssl'}</td> + </tr> <tr> <td class="frmText11">{tmpl_var name='php_txt'}:</td> <td class="frmText11"> diff --git a/interface/web/sites/templates/web_domain_ssl.htm b/interface/web/sites/templates/web_domain_ssl.htm new file mode 100644 index 0000000000000000000000000000000000000000..eb22310f1adcd1c5514758d5e876eb1292f10cf1 --- /dev/null +++ b/interface/web/sites/templates/web_domain_ssl.htm @@ -0,0 +1,52 @@ +<table width="500" border="0" cellspacing="0" cellpadding="2"> + <tr> + <td class="frmText11">{tmpl_var name='ssl_state_txt'}:</td> + <td class="frmText11"><input name="ssl_state" type="text" class="text" value="{tmpl_var name='ssl_state'}" size="30" maxlength="255"></td> + </tr> + <tr> + <td class="frmText11">{tmpl_var name='ssl_locality_txt'}:</td> + <td class="frmText11"><input name="ssl_locality" type="text" class="text" value="{tmpl_var name='ssl_locality'}" size="30" maxlength="255"></td> + </tr> + <tr> + <td class="frmText11">{tmpl_var name='ssl_organisation_txt'}:</td> + <td class="frmText11"><input name="ssl_organisation" type="text" class="text" value="{tmpl_var name='ssl_organisation'}" size="30" maxlength="255"></td> + </tr> + <tr> + <td class="frmText11">{tmpl_var name='ssl_organisation_unit_txt'}:</td> + <td class="frmText11"><input name="ssl_organisation_unit" type="text" class="text" value="{tmpl_var name='ssl_organisation_unit'}" size="30" maxlength="255"></td> + </tr> + <tr> + <td class="frmText11">{tmpl_var name='ssl_country_txt'}:</td> + <td class="frmText11"><input name="ssl_country" type="text" class="text" value="{tmpl_var name='ssl_country'}" size="30" maxlength="255"></td> + </tr> + <tr> + <td class="frmText11">{tmpl_var name='ssl_request_txt'}:</td> + <td class="frmText11"><textarea name='ssl_request' cols='30' rows='10'>{tmpl_var name='ssl_request'}</textarea></td> + </tr> + <tr> + <td class="frmText11">{tmpl_var name='ssl_cert_txt'}:</td> + <td class="frmText11"><textarea name='ssl_cert' cols='30' rows='10'>{tmpl_var name='ssl_cert'}</textarea></td> + </tr> + <tr> + <td class="frmText11">{tmpl_var name='ssl_bundle_txt'}:</td> + <td class="frmText11"><textarea name='ssl_bundle' cols='30' rows='10'>{tmpl_var name='ssl_bundle'}</textarea></td> + </tr> + <tr> + <td class="frmText11">{tmpl_var name='ssl_action_txt'}:</td> + <td class="frmText11"> + <select name="ssl_action" class="text"> + {tmpl_var name='ssl_action'} + </select> + </td> + </tr> <tr> + <td class="frmText11"> </td> + <td class="frmText11"> </td> + </tr> + <tr> + <td> </td> + <td><input name="btn_save" type="button" class="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','sites/web_domain_edit.php');"><div class="buttonEnding"></div> + <input name="btn_cancel" type="button" class="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('sites/web_domain_list.php');"><div class="buttonEnding"></div> + </td> + </tr> +</table> +<input type="hidden" name="id" value="{tmpl_var name='id'}"> \ No newline at end of file diff --git a/server/conf/apache.conf.master b/server/conf/apache.conf.master index 16f3875596eccda6b2f67e9ecb3078477284df41..6f8f7fc7c6d5f55f775eb34a5c10b5811829ba25 100644 --- a/server/conf/apache.conf.master +++ b/server/conf/apache.conf.master @@ -1,2 +1,3 @@ NameVirtualHost *:80 +NameVirtualHost *:443 diff --git a/server/conf/vhost.conf.master b/server/conf/vhost.conf.master index e32edd7a68dec0d7e4c50d78bad26640ecb57679..986d9d6ad43d1005a0ae5c7465b00140e776d444 100644 --- a/server/conf/vhost.conf.master +++ b/server/conf/vhost.conf.master @@ -1,4 +1,3 @@ -# NameVirtualHost *:80 <VirtualHost <tmpl_var name='ip_address'>:80> DocumentRoot <tmpl_var name='web_document_root'> @@ -56,4 +55,71 @@ </tmpl_loop> </tmpl_if> -</VirtualHost> \ No newline at end of file +</VirtualHost> + + + +<tmpl_if name='ssl' op='==' value='y'> +########################################################### +# SSL Vhost +########################################################### + +<VirtualHost <tmpl_var name='ip_address'>:443> + DocumentRoot <tmpl_var name='web_document_root'> + ServerName <tmpl_var name='domain'> + ServerAdmin webmaster@<tmpl_var name='domain'> + ErrorLog <tmpl_var name='document_root'>/log/error.log + + ErrorDocument 400 /error/invalidSyntax.html + ErrorDocument 401 /error/authorizationRequired.html + ErrorDocument 403 /error/forbidden.html + ErrorDocument 404 /error/fileNotFound.html + ErrorDocument 405 /error/methodNotAllowed.html + ErrorDocument 500 /error/internalServerError.html + ErrorDocument 503 /error/overloaded.html + +<tmpl_if name='alias'> + ServerAlias <tmpl_var name='alias'> +</tmpl_if> +<tmpl_if name='cgi'> + # cgi enabled + ScriptAlias /cgi-bin/ <tmpl_var name='document_root'>/cgi-bin/ + AddHandler cgi-script .cgi + AddHandler cgi-script .pl +</tmpl_if> +<tmpl_if name='ssi'> + # ssi enabled + AddType text/html .shtml + AddOutputFilter INCLUDES .shtml +</tmpl_if> +<tmpl_if name='suexec'> + # suexec enabled + SuexecUserGroup <tmpl_var name='system_user'> <tmpl_var name='system_group'> +</tmpl_if> +<tmpl_if name='php' op='==' value='mod'> + # mod_php enabled + AddType application/x-httpd-php .php .php3 .php4 .php5 +</tmpl_if> +<tmpl_if name='php' op='==' value='suphp'> + # suphp enabled + suPHP_Engine on + suPHP_UserGroup <tmpl_var name='system_user'> <tmpl_var name='system_group'> + AddHandler x-httpd-php .php .php3 .php4 .php5 + suPHP_AddHandler x-httpd-php +</tmpl_if> +<tmpl_if name='php' op='==' value='cgi'> + # php as cgi enabled + AddType application/x-httpd-php .php .php3 .php4 .php5 +</tmpl_if> + +<tmpl_if name="rewrite_enabled"> + RewriteEngine on +<tmpl_loop name="redirects"> + RewriteCond %{HTTP_HOST} ^<tmpl_var name='rewrite_domain'> [NC] + RewriteRule ^/(.*)$ <tmpl_var name='rewrite_target'>$1 [<tmpl_var name='rewrite_type'>] +</tmpl_loop> +</tmpl_if> + +</VirtualHost> + +</tmpl_if> \ No newline at end of file diff --git a/server/plugins-enabled/apache2_plugin.inc.php b/server/plugins-enabled/apache2_plugin.inc.php index 520bcb70c4500107070e31190299c6c516fb7321..1d4533e8cd2028f9d5b732dd429cd9476b123a6c 100644 --- a/server/plugins-enabled/apache2_plugin.inc.php +++ b/server/plugins-enabled/apache2_plugin.inc.php @@ -45,6 +45,12 @@ class apache2_plugin { Register for the events */ + + + $app->plugins->registerEvent('web_domain_insert',$this->plugin_name,'ssl'); + $app->plugins->registerEvent('web_domain_update',$this->plugin_name,'ssl'); + $app->plugins->registerEvent('web_domain_delete',$this->plugin_name,'ssl'); + $app->plugins->registerEvent('web_domain_insert',$this->plugin_name,'insert'); $app->plugins->registerEvent('web_domain_update',$this->plugin_name,'update'); $app->plugins->registerEvent('web_domain_delete',$this->plugin_name,'delete'); @@ -55,6 +61,100 @@ class apache2_plugin { } + // Handle the creation of SSL certificates + function ssl($event_name,$data) { + global $app, $conf; + + if(!is_dir($data["new"]["document_root"]."/ssl")) exec("mkdir -p ".$data["new"]["document_root"]."/ssl"); + $ssl_dir = $data["new"]["document_root"]."/ssl"; + $domain = $data["new"]["domain"]; + $key_file = $ssl_dir.'/'.$domain.".key.org"; + $key_file2 = $ssl_dir.'/'.$domain.".key"; + $csr_file = $ssl_dir.'/'.$domain.".csr"; + $crt_file = $ssl_dir.'/'.$domain.".crt"; + + //* Create a SSL Certificate + if($data["new"]["ssl_action"] == 'create') { + $rand_file = $ssl_dir."/random_file"; + $rand_data = md5(uniqid(microtime(),1)); + for($i=0; $i<1000; $i++){ + $rand_data .= md5(uniqid(microtime(),1)); + $rand_data .= md5(uniqid(microtime(),1)); + $rand_data .= md5(uniqid(microtime(),1)); + $rand_data .= md5(uniqid(microtime(),1)); + } + file_put_contents($rand_file, $rand_data); + + $ssl_password = substr(md5(uniqid(microtime(),1)), 0, 15); + + $ssl_cnf = " RANDFILE = $rand_file + + [ req ] + default_bits = 1024 + default_keyfile = keyfile.pem + distinguished_name = req_distinguished_name + attributes = req_attributes + prompt = no + output_password = $ssl_password + + [ req_distinguished_name ] + C = $data[new][ssl_country] + ST = $data[new][ssl_state] + L = $data[new][ssl_locality] + O = $data[new][ssl_organisation] + OU = $data[new][ssl_organisation_unit] + CN = $domain + emailAddress = webmatser@$data[new][domain] + + [ req_attributes ] + challengePassword = A challenge password"; + + $ssl_cnf_file = $ssl_dir."/openssl.conf"; + file_get_contents($ssl_cnf_file,$ssl_cnf); + + $rand_file = escapeshellcmd($rand_file); + $key_file = escapeshellcmd($key_file); + $key_file2 = escapeshellcmd($key_file2); + $ssl_days = 3650; + $csr_file = escapeshellcmd($csr_file); + $config_file = escapeshellcmd($config_file); + $crt_file escapeshellcmd($crt_file); + + if(is_file($ssl_cnf_file)){ + exec("openssl genrsa -des3 -rand $rand_file \ + -passout pass:$ssl_password \ + -out $key_file 1024 \ + && openssl req -new -passin pass:$ssl_password \ + -passout pass:$ssl_password -key $key_file \ + -out $csr_file -days $ssl_days \ + -config $config_file \ + && openssl req -x509 -passin pass:$ssl_password \ + -passout pass:$ssl_password \ + -key $key_file -in $csr_file \ + -out $crt_file -days $ssl_days \ + -config $config_file \ + && openssl rsa -passin pass:$ssl_password \ + -in $key_file \ + -out $key_file2"); + } + + exec("chmod 400 $key_file2"); + exec("rm -f $config_file"); + exec("rm -f $rand_file"); + $ssl_request = file_get_contents($csr_file); + $ssl_cert = file_get_contents($crt_file); + $mod->db->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert' WHERE domain = '".$data["new"]["domain"]."'"); + } + + //* Save a SSL certificate to disk + if($data["new"]["ssl_action"] == 'save') { + + } + + + } + + function insert($event_name,$data) { global $app, $conf; @@ -109,12 +209,17 @@ class apache2_plugin { $client_id = intval($client["client_id"]); unset($client); $tmp_symlinks_array = explode(':',$web_config["website_symlinks"]); - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace("[client_id]",$client_id,$tmp_symlink); - $tmp_symlink = str_replace("[website_domain]",$data["new"]["domain"],$tmp_symlink); - if(!is_link($tmp_symlink)) { - exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); - $app->log("Creating Symlink: ln -s ".$data["new"]["document_root"]."/ ".$tmp_symlink,LOGLEVEL_DEBUG); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace("[client_id]",$client_id,$tmp_symlink); + $tmp_symlink = str_replace("[website_domain]",$data["new"]["domain"],$tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + // create the symlinks, if not exist + if(!is_link($tmp_symlink)) { + exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); + $app->log("Creating Symlink: ln -s ".$data["new"]["document_root"]."/ ".$tmp_symlink,LOGLEVEL_DEBUG); + } } } @@ -239,6 +344,26 @@ class apache2_plugin { if($docroot != '' && !stristr($docroot,'..')) exec("rm -rf $docroot"); $app->log("Removing website: $docroot",LOGLEVEL_DEBUG); + // Delete the symlinks for the sites + $client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".intval($data["old"]["sys_groupid"])); + $client_id = intval($client["client_id"]); + unset($client); + $tmp_symlinks_array = explode(':',$web_config["website_symlinks"]); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace("[client_id]",$client_id,$tmp_symlink); + $tmp_symlink = str_replace("[website_domain]",$data["old"]["domain"],$tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + // create the symlinks, if not exist + if(is_link($tmp_symlink)) { + unlink($tmp_symlink)); + $app->log("Removing symlink: ".$tmp_symlink,LOGLEVEL_DEBUG); + } + } + } + // end removing symlinks + } //* This function is called when a IP on the server is inserted, updated or deleted