From 0a466dfd65c07d4bf8c61c0e98c536c0f0b65ec1 Mon Sep 17 00:00:00 2001
From: tbrehm <t.brehm@ispconfig.org>
Date: Tue, 23 Oct 2007 11:07:59 -0400
Subject: [PATCH] Added SSL website support.
---
server/conf/vhost.conf.master | 70 +++++++++
interface/web/sites/templates/web_domain_ssl.htm | 52 +++++++
install/sql/ispconfig3.sql | 19 ++
server/plugins-enabled/apache2_plugin.inc.php | 137 ++++++++++++++++++
server/conf/apache.conf.master | 1
interface/web/sites/lib/lang/en_web_domain.lng | 14 +
interface/web/sites/form/web_domain.tform.php | 93 +++++++++++++
interface/web/sites/templates/web_domain_edit.htm | 4
8 files changed, 375 insertions(+), 15 deletions(-)
diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql
index 3b0acb9..7badb54 100644
--- a/install/sql/ispconfig3.sql
+++ b/install/sql/ispconfig3.sql
@@ -840,15 +840,26 @@
`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 383ac61..009e6ae 100644
--- a/interface/web/sites/form/web_domain.tform.php
+++ b/interface/web/sites/form/web_domain.tform.php
@@ -159,6 +159,12 @@
'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"]['redirect'] = array (
'title' => "Redirect",
'width' => 100,
@@ -188,7 +195,7 @@
'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"]['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 bdb41e2..ffb180b 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["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["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 6310bd8..36b4fd8 100644
--- a/interface/web/sites/templates/web_domain_edit.htm
+++ b/interface/web/sites/templates/web_domain_edit.htm
@@ -76,6 +76,10 @@
<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">
<select name="php" class="text">
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 0000000..eb22310
--- /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 16f3875..6f8f7fc 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 e32edd7..986d9d6 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 520bcb7..1d4533e 100644
--- a/server/plugins-enabled/apache2_plugin.inc.php
+++ b/server/plugins-enabled/apache2_plugin.inc.php
@@ -45,6 +45,12 @@
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');
@@ -54,6 +60,100 @@
$app->plugins->registerEvent('server_ip_delete',$this->plugin_name,'server_ip');
}
+
+ // 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 @@
$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 @@
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
--
Gitblit v1.9.1