Merge branch 'master' into patch-1

This commit is contained in:
Michael Kaufmann
2016-12-11 08:55:37 +01:00
committed by GitHub
47 changed files with 1368 additions and 645 deletions

View File

@@ -234,6 +234,7 @@ return array(
'type' => 'option', 'type' => 'option',
'default' => '', 'default' => '',
'option_mode' => 'multiple', 'option_mode' => 'multiple',
'option_emptyallowed' => true,
'option_options' => array( 'option_options' => array(
'email' => $lng['menue']['email']['email'], 'email' => $lng['menue']['email']['email'],
'mysql' => $lng['menue']['mysql']['mysql'], 'mysql' => $lng['menue']['mysql']['mysql'],

View File

@@ -39,7 +39,7 @@ return array(
'varname' => 'le_froxlor_enabled', 'varname' => 'le_froxlor_enabled',
'type' => 'bool', 'type' => 'bool',
'default' => false, 'default' => false,
'save_method' => 'storeSettingField', 'save_method' => 'storeSettingClearCertificates',
'visible' => Settings::Get('system.leenabled') 'visible' => Settings::Get('system.leenabled')
), ),
'system_le_froxlor_redirect' => array( 'system_le_froxlor_redirect' => array(
@@ -49,7 +49,36 @@ return array(
'type' => 'bool', 'type' => 'bool',
'default' => false, 'default' => false,
'save_method' => 'storeSettingField', 'save_method' => 'storeSettingField',
'visible' => Settings::Get('system.leenabled') 'visible' => Settings::Get('system.use_ssl')
),
'system_hsts_maxage' => array(
'label' => $lng['admin']['domain_hsts_maxage'],
'settinggroup' => 'system',
'varname' => 'hsts_maxage',
'type' => 'int',
'int_min' => 0,
'int_max' => 94608000, // 3-years
'default' => 0,
'save_method' => 'storeSettingField',
'visible' => Settings::Get('system.use_ssl')
),
'system_hsts_incsub' => array(
'label' => $lng['admin']['domain_hsts_incsub'],
'settinggroup' => 'system',
'varname' => 'hsts_incsub',
'type' => 'bool',
'default' => false,
'save_method' => 'storeSettingField',
'visible' => Settings::Get('system.use_ssl')
),
'system_hsts_preload' => array(
'label' => $lng['admin']['domain_hsts_preload'],
'settinggroup' => 'system',
'varname' => 'hsts_preload',
'type' => 'bool',
'default' => false,
'save_method' => 'storeSettingField',
'visible' => Settings::Get('system.use_ssl')
), ),
/** /**
* FCGID * FCGID

View File

@@ -179,6 +179,17 @@ return array(
'nginx' 'nginx'
) )
), ),
'system_nginx_http2_support' => array(
'label' => $lng['serversettings']['nginx_http2_support'],
'settinggroup' => 'system',
'varname' => 'nginx_http2_support',
'type' => 'bool',
'default' => false,
'save_method' => 'storeSettingField',
'websrv_avail' => array(
'nginx'
)
),
'system_nginx_php_backend' => array( 'system_nginx_php_backend' => array(
'label' => $lng['serversettings']['nginx_php_backend'], 'label' => $lng['serversettings']['nginx_php_backend'],
'settinggroup' => 'system', 'settinggroup' => 'system',
@@ -260,11 +271,7 @@ return array(
'varname' => 'enabled', 'varname' => 'enabled',
'type' => 'bool', 'type' => 'bool',
'default' => false, 'default' => false,
'save_method' => 'storeSettingField', 'save_method' => 'storeSettingField'
'websrv_avail' => array(
'apache2',
'lighttpd'
)
), ),
'customredirect_default' => array( 'customredirect_default' => array(
'label' => $lng['serversettings']['customredirect_default'], 'label' => $lng['serversettings']['customredirect_default'],
@@ -274,11 +281,7 @@ return array(
'default' => '1', 'default' => '1',
'option_mode' => 'one', 'option_mode' => 'one',
'option_options_method' => 'getRedirectCodes', 'option_options_method' => 'getRedirectCodes',
'save_method' => 'storeSettingField', 'save_method' => 'storeSettingField'
'websrv_avail' => array(
'apache2',
'lighttpd'
)
) )
) )
) )

View File

@@ -210,6 +210,8 @@ if ($page == 'domains' || $page == 'overview') {
'id' => $id 'id' => $id
)); ));
$deleted_domains = $del_stmt->rowCount();
$upd_stmt = Database::prepare(" $upd_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET
`subdomains_used` = `subdomains_used` - :domaincount `subdomains_used` = `subdomains_used` - :domaincount
@@ -393,6 +395,9 @@ if ($page == 'domains' || $page == 'overview') {
'0', '0',
'' ''
)); ));
if ($registration_date == '0000-00-00') {
$registration_date = null;
}
$termination_date = trim($_POST['termination_date']); $termination_date = trim($_POST['termination_date']);
$termination_date = validate($termination_date, 'termination_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array( $termination_date = validate($termination_date, 'termination_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array(
@@ -400,6 +405,9 @@ if ($page == 'domains' || $page == 'overview') {
'0', '0',
'' ''
)); ));
if ($termination_date == '0000-00-00') {
$termination_date = null;
}
if ($userinfo['change_serversettings'] == '1') { if ($userinfo['change_serversettings'] == '1') {
@@ -447,6 +455,7 @@ if ($page == 'domains' || $page == 'overview') {
if ($userinfo['caneditphpsettings'] == '1' || $userinfo['change_serversettings'] == '1') { if ($userinfo['caneditphpsettings'] == '1' || $userinfo['change_serversettings'] == '1') {
$phpenabled = isset($POST_['phpenabled']) ? intval($_POST['phpenabled']) : 0;
$openbasedir = isset($_POST['openbasedir']) ? intval($_POST['openbasedir']) : 0; $openbasedir = isset($_POST['openbasedir']) ? intval($_POST['openbasedir']) : 0;
if ((int) Settings::Get('system.mod_fcgid') == 1 || (int) Settings::Get('phpfpm.enabled') == 1) { if ((int) Settings::Get('system.mod_fcgid') == 1 || (int) Settings::Get('phpfpm.enabled') == 1) {
@@ -487,7 +496,9 @@ if ($page == 'domains' || $page == 'overview') {
} }
} else { } else {
$phpenabled = '1';
$openbasedir = '1'; $openbasedir = '1';
if ((int) Settings::Get('phpfpm.enabled') == 1) { if ((int) Settings::Get('phpfpm.enabled') == 1) {
$phpsettingid = Settings::Get('phpfpm.defaultini'); $phpsettingid = Settings::Get('phpfpm.defaultini');
} else { } else {
@@ -578,12 +589,23 @@ if ($page == 'domains' || $page == 'overview') {
$ssl_ipandports[] = $ssl_ipandport; $ssl_ipandports[] = $ssl_ipandport;
} }
} }
// HSTS
$hsts_maxage = isset($_POST['hsts_maxage']) ? (int)$_POST['hsts_maxage'] : 0;
$hsts_sub = isset($_POST['hsts_sub']) && (int)$_POST['hsts_sub'] == 1 ? 1 : 0;
$hsts_preload = isset($_POST['hsts_preload']) && (int)$_POST['hsts_preload'] == 1 ? 1 : 0;
} else { } else {
$ssl_redirect = 0; $ssl_redirect = 0;
$letsencrypt = 0; $letsencrypt = 0;
// we need this for the serialize // we need this for the serialize
// if ssl is disabled or no ssl-ip/port exists // if ssl is disabled or no ssl-ip/port exists
$ssl_ipandports[] = - 1; $ssl_ipandports[] = - 1;
// HSTS
$hsts_maxage = 0;
$hsts_sub = 0;
$hsts_preload = 0;
} }
} else { } else {
$ssl_redirect = 0; $ssl_redirect = 0;
@@ -591,6 +613,11 @@ if ($page == 'domains' || $page == 'overview') {
// we need this for the serialize // we need this for the serialize
// if ssl is disabled or no ssl-ip/port exists // if ssl is disabled or no ssl-ip/port exists
$ssl_ipandports[] = - 1; $ssl_ipandports[] = - 1;
// HSTS
$hsts_maxage = 0;
$hsts_sub = 0;
$hsts_preload = 0;
} }
// We can't enable let's encrypt for wildcard - domains // We can't enable let's encrypt for wildcard - domains
@@ -667,6 +694,10 @@ if ($page == 'domains' || $page == 'overview') {
standard_error('noipportgiven'); standard_error('noipportgiven');
} }
if($phpenabled != '1') {
$phpenabled = '0';
}
if ($openbasedir != '1') { if ($openbasedir != '1') {
$openbasedir = '0'; $openbasedir = '0';
} }
@@ -746,6 +777,7 @@ if ($page == 'domains' || $page == 'overview') {
'ipandport' => serialize($ipandports), 'ipandport' => serialize($ipandports),
'ssl_redirect' => $ssl_redirect, 'ssl_redirect' => $ssl_redirect,
'ssl_ipandport' => serialize($ssl_ipandports), 'ssl_ipandport' => serialize($ssl_ipandports),
'phpenabled' => $phpenabled,
'openbasedir' => $openbasedir, 'openbasedir' => $openbasedir,
'phpsettingid' => $phpsettingid, 'phpsettingid' => $phpsettingid,
'mod_fcgid_starter' => $mod_fcgid_starter, 'mod_fcgid_starter' => $mod_fcgid_starter,
@@ -754,7 +786,10 @@ if ($page == 'domains' || $page == 'overview') {
'registration_date' => $registration_date, 'registration_date' => $registration_date,
'termination_date' => $termination_date, 'termination_date' => $termination_date,
'issubof' => $issubof, 'issubof' => $issubof,
'letsencrypt' => $letsencrypt 'letsencrypt' => $letsencrypt,
'hsts_maxage' => $hsts_maxage,
'hsts_sub' => $hsts_sub,
'hsts_preload' => $hsts_preload
); );
$security_questions = array( $security_questions = array(
@@ -791,6 +826,7 @@ if ($page == 'domains' || $page == 'overview') {
'email_only' => $email_only, 'email_only' => $email_only,
'subcanemaildomain' => $subcanemaildomain, 'subcanemaildomain' => $subcanemaildomain,
'caneditdomain' => $caneditdomain, 'caneditdomain' => $caneditdomain,
'phpenabled' => $phpenabled,
'openbasedir' => $openbasedir, 'openbasedir' => $openbasedir,
'speciallogfile' => $speciallogfile, 'speciallogfile' => $speciallogfile,
'specialsettings' => $specialsettings, 'specialsettings' => $specialsettings,
@@ -802,7 +838,10 @@ if ($page == 'domains' || $page == 'overview') {
'mod_fcgid_starter' => $mod_fcgid_starter, 'mod_fcgid_starter' => $mod_fcgid_starter,
'mod_fcgid_maxrequests' => $mod_fcgid_maxrequests, 'mod_fcgid_maxrequests' => $mod_fcgid_maxrequests,
'ismainbutsubto' => $issubof, 'ismainbutsubto' => $issubof,
'letsencrypt' => $letsencrypt 'letsencrypt' => $letsencrypt,
'hsts' => $hsts_maxage,
'hsts_sub' => $hsts_sub,
'hsts_preload' => $hsts_preload
); );
$ins_stmt = Database::prepare(" $ins_stmt = Database::prepare("
@@ -824,6 +863,7 @@ if ($page == 'domains' || $page == 'overview') {
`email_only` = :email_only, `email_only` = :email_only,
`subcanemaildomain` = :subcanemaildomain, `subcanemaildomain` = :subcanemaildomain,
`caneditdomain` = :caneditdomain, `caneditdomain` = :caneditdomain,
`phpenabled` = :phpenabled,
`openbasedir` = :openbasedir, `openbasedir` = :openbasedir,
`speciallogfile` = :speciallogfile, `speciallogfile` = :speciallogfile,
`specialsettings` = :specialsettings, `specialsettings` = :specialsettings,
@@ -835,7 +875,10 @@ if ($page == 'domains' || $page == 'overview') {
`mod_fcgid_starter` = :mod_fcgid_starter, `mod_fcgid_starter` = :mod_fcgid_starter,
`mod_fcgid_maxrequests` = :mod_fcgid_maxrequests, `mod_fcgid_maxrequests` = :mod_fcgid_maxrequests,
`ismainbutsubto` = :ismainbutsubto, `ismainbutsubto` = :ismainbutsubto,
`letsencrypt` = :letsencrypt `letsencrypt` = :letsencrypt,
`hsts` = :hsts,
`hsts_sub` = :hsts_sub,
`hsts_preload` = :hsts_preload
"); ");
Database::pexecute($ins_stmt, $ins_data); Database::pexecute($ins_stmt, $ins_data);
$domainid = Database::lastInsertId(); $domainid = Database::lastInsertId();
@@ -1050,8 +1093,12 @@ if ($page == 'domains' || $page == 'overview') {
} elseif ($action == 'edit' && $id != 0) { } elseif ($action == 'edit' && $id != 0) {
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
SELECT `d`.*, `c`.`customerid` FROM `" . TABLE_PANEL_DOMAINS . "` `d` LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`) SELECT `d`.*, `c`.`customerid`
WHERE `d`.`parentdomainid` = '0' AND `d`.`id` = :id" . ($userinfo['customers_see_all'] ? '' : " AND `d`.`adminid` = :adminid")); FROM `" . TABLE_PANEL_DOMAINS . "` `d`
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`)
WHERE `d`.`parentdomainid` = '0'
AND `d`.`id` = :id" . ($userinfo['customers_see_all'] ? '' : " AND `d`.`adminid` = :adminid")
);
$params = array( $params = array(
'id' => $id 'id' => $id
); );
@@ -1196,7 +1243,7 @@ if ($page == 'domains' || $page == 'overview') {
$adminid = $result['adminid']; $adminid = $result['adminid'];
} }
$aliasdomain = intval($_POST['alias']); $aliasdomain = isset($_POST['alias']) ? intval($_POST['alias']) : 0;
$issubof = intval($_POST['issubof']); $issubof = intval($_POST['issubof']);
$subcanemaildomain = intval($_POST['subcanemaildomain']); $subcanemaildomain = intval($_POST['subcanemaildomain']);
$caneditdomain = isset($_POST['caneditdomain']) ? intval($_POST['caneditdomain']) : 0; $caneditdomain = isset($_POST['caneditdomain']) ? intval($_POST['caneditdomain']) : 0;
@@ -1206,12 +1253,18 @@ if ($page == 'domains' || $page == 'overview') {
'0', '0',
'' ''
)); ));
if ($registration_date == '0000-00-00') {
$registration_date = null;
}
$termination_date = trim($_POST['termination_date']); $termination_date = trim($_POST['termination_date']);
$termination_date = validate($termination_date, 'termination_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array( $termination_date = validate($termination_date, 'termination_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array(
'0000-00-00', '0000-00-00',
'0', '0',
'' ''
)); ));
if ($termination_date == '0000-00-00') {
$termination_date = null;
}
$isemaildomain = 0; $isemaildomain = 0;
if (isset($_POST['isemaildomain'])) { if (isset($_POST['isemaildomain'])) {
@@ -1285,6 +1338,7 @@ if ($page == 'domains' || $page == 'overview') {
if ($userinfo['caneditphpsettings'] == '1' || $userinfo['change_serversettings'] == '1') { if ($userinfo['caneditphpsettings'] == '1' || $userinfo['change_serversettings'] == '1') {
$phpenabled = isset($_POST['phpenabled']) ? intval($_POST['phpenabled']) : 0;
$openbasedir = isset($_POST['openbasedir']) ? intval($_POST['openbasedir']) : 0; $openbasedir = isset($_POST['openbasedir']) ? intval($_POST['openbasedir']) : 0;
if ((int) Settings::Get('system.mod_fcgid') == 1 || (int) Settings::Get('phpfpm.enabled') == 1) { if ((int) Settings::Get('system.mod_fcgid') == 1 || (int) Settings::Get('phpfpm.enabled') == 1) {
@@ -1319,6 +1373,7 @@ if ($page == 'domains' || $page == 'overview') {
$mod_fcgid_maxrequests = $result['mod_fcgid_maxrequests']; $mod_fcgid_maxrequests = $result['mod_fcgid_maxrequests'];
} }
} else { } else {
$phpenabled = $result['phpenabled'];
$openbasedir = $result['openbasedir']; $openbasedir = $result['openbasedir'];
$phpsettingid = $result['phpsettingid']; $phpsettingid = $result['phpsettingid'];
$mod_fcgid_starter = $result['mod_fcgid_starter']; $mod_fcgid_starter = $result['mod_fcgid_starter'];
@@ -1361,6 +1416,11 @@ if ($page == 'domains' || $page == 'overview') {
$letsencrypt = (int) $_POST['letsencrypt']; $letsencrypt = (int) $_POST['letsencrypt'];
} }
// HSTS
$hsts_maxage = isset($_POST['hsts_maxage']) ? (int)$_POST['hsts_maxage'] : 0;
$hsts_sub = isset($_POST['hsts_sub']) && (int)$_POST['hsts_sub'] == 1 ? 1 : 0;
$hsts_preload = isset($_POST['hsts_preload']) && (int)$_POST['hsts_preload'] == 1 ? 1 : 0;
$ssl_ipandports = array(); $ssl_ipandports = array();
if (isset($_POST['ssl_ipandport']) && ! is_array($_POST['ssl_ipandport'])) { if (isset($_POST['ssl_ipandport']) && ! is_array($_POST['ssl_ipandport'])) {
$_POST['ssl_ipandport'] = unserialize($_POST['ssl_ipandport']); $_POST['ssl_ipandport'] = unserialize($_POST['ssl_ipandport']);
@@ -1386,12 +1446,18 @@ if ($page == 'domains' || $page == 'overview') {
$ssl_ipandports[] = $ssl_ipandport; $ssl_ipandports[] = $ssl_ipandport;
} }
} }
} else { } else {
$ssl_redirect = 0; $ssl_redirect = 0;
$letsencrypt = 0; $letsencrypt = 0;
// we need this for the serialize // we need this for the serialize
// if ssl is disabled or no ssl-ip/port exists // if ssl is disabled or no ssl-ip/port exists
$ssl_ipandports[] = - 1; $ssl_ipandports[] = - 1;
// HSTS
$hsts_maxage = 0;
$hsts_sub = 0;
$hsts_preload = 0;
} }
} else { } else {
$ssl_redirect = 0; $ssl_redirect = 0;
@@ -1399,6 +1465,11 @@ if ($page == 'domains' || $page == 'overview') {
// we need this for the serialize // we need this for the serialize
// if ssl is disabled or no ssl-ip/port exists // if ssl is disabled or no ssl-ip/port exists
$ssl_ipandports[] = - 1; $ssl_ipandports[] = - 1;
// HSTS
$hsts_maxage = 0;
$hsts_sub = 0;
$hsts_preload = 0;
} }
// We can't enable let's encrypt for wildcard domains // We can't enable let's encrypt for wildcard domains
@@ -1415,6 +1486,10 @@ if ($page == 'domains' || $page == 'overview') {
$documentroot = makeCorrectDir($documentroot); $documentroot = makeCorrectDir($documentroot);
} }
if ($phpenabled != '1') {
$phpenabled = '0';
}
if ($openbasedir != '1') { if ($openbasedir != '1') {
$openbasedir = '0'; $openbasedir = '0';
} }
@@ -1523,6 +1598,7 @@ if ($page == 'domains' || $page == 'overview') {
'dkim' => $dkim, 'dkim' => $dkim,
'selectserveralias' => $serveraliasoption, 'selectserveralias' => $serveraliasoption,
'ssl_redirect' => $ssl_redirect, 'ssl_redirect' => $ssl_redirect,
'phpenabled' => $phpenabled,
'openbasedir' => $openbasedir, 'openbasedir' => $openbasedir,
'phpsettingid' => $phpsettingid, 'phpsettingid' => $phpsettingid,
'mod_fcgid_starter' => $mod_fcgid_starter, 'mod_fcgid_starter' => $mod_fcgid_starter,
@@ -1536,7 +1612,10 @@ if ($page == 'domains' || $page == 'overview') {
'speciallogverified' => $speciallogverified, 'speciallogverified' => $speciallogverified,
'ipandport' => serialize($ipandports), 'ipandport' => serialize($ipandports),
'ssl_ipandport' => serialize($ssl_ipandports), 'ssl_ipandport' => serialize($ssl_ipandports),
'letsencrypt' => $letsencrypt 'letsencrypt' => $letsencrypt,
'hsts_maxage' => $hsts_maxage,
'hsts_sub' => $hsts_sub,
'hsts_preload' => $hsts_preload
); );
$security_questions = array( $security_questions = array(
@@ -1555,7 +1634,7 @@ if ($page == 'domains' || $page == 'overview') {
$wwwserveralias = ($serveraliasoption == '1') ? '1' : '0'; $wwwserveralias = ($serveraliasoption == '1') ? '1' : '0';
$iswildcarddomain = ($serveraliasoption == '0') ? '1' : '0'; $iswildcarddomain = ($serveraliasoption == '0') ? '1' : '0';
if ($documentroot != $result['documentroot'] || $ssl_redirect != $result['ssl_redirect'] || $wwwserveralias != $result['wwwserveralias'] || $iswildcarddomain != $result['iswildcarddomain'] || $openbasedir != $result['openbasedir'] || $phpsettingid != $result['phpsettingid'] || $mod_fcgid_starter != $result['mod_fcgid_starter'] || $mod_fcgid_maxrequests != $result['mod_fcgid_maxrequests'] || $specialsettings != $result['specialsettings'] || $aliasdomain != $result['aliasdomain'] || $issubof != $result['ismainbutsubto'] || $email_only != $result['email_only'] || ($speciallogfile != $result['speciallogfile'] && $speciallogverified == '1') || $letsencrypt != $result['letsencrypt']) { if ($documentroot != $result['documentroot'] || $ssl_redirect != $result['ssl_redirect'] || $wwwserveralias != $result['wwwserveralias'] || $iswildcarddomain != $result['iswildcarddomain'] || $phpenabled != $result['phpenabled'] || $openbasedir != $result['openbasedir'] || $phpsettingid != $result['phpsettingid'] || $mod_fcgid_starter != $result['mod_fcgid_starter'] || $mod_fcgid_maxrequests != $result['mod_fcgid_maxrequests'] || $specialsettings != $result['specialsettings'] || $aliasdomain != $result['aliasdomain'] || $issubof != $result['ismainbutsubto'] || $email_only != $result['email_only'] || ($speciallogfile != $result['speciallogfile'] && $speciallogverified == '1') || $letsencrypt != $result['letsencrypt'] || $hsts_maxage != $result['hsts'] || $hsts_sub != $result['hsts_sub'] || $hsts_preload != $result['hsts_preload']) {
inserttask('1'); inserttask('1');
} }
@@ -1584,6 +1663,16 @@ if ($page == 'domains' || $page == 'overview') {
$log->logAction(ADM_ACTION, LOG_NOTICE, "deleted domain #" . $id . " from mail-tables"); $log->logAction(ADM_ACTION, LOG_NOTICE, "deleted domain #" . $id . " from mail-tables");
} }
// check whether LE has been disabled, so we remove the certificate
if ($letsencrypt == '0' && $result['letsencrypt'] == '1') {
$del_stmt = Database::prepare("
DELETE FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :id
");
Database::pexecute($del_stmt, array(
'id' => $id
));
}
$updatechildren = ''; $updatechildren = '';
if ($subcanemaildomain == '0' && $result['subcanemaildomain'] != '0') { if ($subcanemaildomain == '0' && $result['subcanemaildomain'] != '0') {
@@ -1686,6 +1775,7 @@ if ($page == 'domains' || $page == 'overview') {
$update_data['zonefile'] = $zonefile; $update_data['zonefile'] = $zonefile;
$update_data['wwwserveralias'] = $wwwserveralias; $update_data['wwwserveralias'] = $wwwserveralias;
$update_data['iswildcarddomain'] = $iswildcarddomain; $update_data['iswildcarddomain'] = $iswildcarddomain;
$update_data['phpenabled'] = $phpenabled;
$update_data['openbasedir'] = $openbasedir; $update_data['openbasedir'] = $openbasedir;
$update_data['speciallogfile'] = $speciallogfile; $update_data['speciallogfile'] = $speciallogfile;
$update_data['phpsettingid'] = $phpsettingid; $update_data['phpsettingid'] = $phpsettingid;
@@ -1696,6 +1786,9 @@ if ($page == 'domains' || $page == 'overview') {
$update_data['termination_date'] = $termination_date; $update_data['termination_date'] = $termination_date;
$update_data['ismainbutsubto'] = $issubof; $update_data['ismainbutsubto'] = $issubof;
$update_data['letsencrypt'] = $letsencrypt; $update_data['letsencrypt'] = $letsencrypt;
$update_data['hsts'] = $hsts_maxage;
$update_data['hsts_sub'] = $hsts_sub;
$update_data['hsts_preload'] = $hsts_preload;
$update_data['id'] = $id; $update_data['id'] = $id;
$update_stmt = Database::prepare(" $update_stmt = Database::prepare("
@@ -1714,6 +1807,7 @@ if ($page == 'domains' || $page == 'overview') {
`zonefile` = :zonefile, `zonefile` = :zonefile,
`wwwserveralias` = :wwwserveralias, `wwwserveralias` = :wwwserveralias,
`iswildcarddomain` = :iswildcarddomain, `iswildcarddomain` = :iswildcarddomain,
`phpenabled` = :phpenabled,
`openbasedir` = :openbasedir, `openbasedir` = :openbasedir,
`speciallogfile` = :speciallogfile, `speciallogfile` = :speciallogfile,
`phpsettingid` = :phpsettingid, `phpsettingid` = :phpsettingid,
@@ -1723,13 +1817,17 @@ if ($page == 'domains' || $page == 'overview') {
`registration_date` = :registration_date, `registration_date` = :registration_date,
`termination_date` = :termination_date, `termination_date` = :termination_date,
`ismainbutsubto` = :ismainbutsubto, `ismainbutsubto` = :ismainbutsubto,
`letsencrypt` = :letsencrypt `letsencrypt` = :letsencrypt,
`hsts` = :hsts,
`hsts_sub` = :hsts_sub,
`hsts_preload` = :hsts_preload
WHERE `id` = :id WHERE `id` = :id
"); ");
Database::pexecute($update_stmt, $update_data); Database::pexecute($update_stmt, $update_data);
$_update_data['customerid'] = $customerid; $_update_data['customerid'] = $customerid;
$_update_data['adminid'] = $adminid; $_update_data['adminid'] = $adminid;
$_update_data['phpenabled'] = $phpenabled;
$_update_data['openbasedir'] = $openbasedir; $_update_data['openbasedir'] = $openbasedir;
$_update_data['phpsettingid'] = $phpsettingid; $_update_data['phpsettingid'] = $phpsettingid;
$_update_data['mod_fcgid_starter'] = $mod_fcgid_starter; $_update_data['mod_fcgid_starter'] = $mod_fcgid_starter;
@@ -1748,6 +1846,7 @@ if ($page == 'domains' || $page == 'overview') {
UPDATE `" . TABLE_PANEL_DOMAINS . "` SET UPDATE `" . TABLE_PANEL_DOMAINS . "` SET
`customerid` = :customerid, `customerid` = :customerid,
`adminid` = :adminid, `adminid` = :adminid,
`phpenabled` = :phpenabled,
`openbasedir` = :openbasedir, `openbasedir` = :openbasedir,
`phpsettingid` = :phpsettingid, `phpsettingid` = :phpsettingid,
`mod_fcgid_starter` = :mod_fcgid_starter, `mod_fcgid_starter` = :mod_fcgid_starter,

View File

@@ -369,7 +369,8 @@ if ($page == 'overview') {
$mail_body .= "File: ".$_error['file'].':'.$_error['line']."\n\n"; $mail_body .= "File: ".$_error['file'].':'.$_error['line']."\n\n";
$mail_body .= "Trace:\n".trim($_error['trace'])."\n\n"; $mail_body .= "Trace:\n".trim($_error['trace'])."\n\n";
$mail_body .= "-------------------------------------------------------------\n\n"; $mail_body .= "-------------------------------------------------------------\n\n";
$mail_body .= "Froxlor-version: ".$version."\n\n"; $mail_body .= "Froxlor-version: ".$version."\n";
$mail_body .= "DB-version: ".$dbversion."\n\n";
$mail_body .= "End of report"; $mail_body .= "End of report";
$mail_html = nl2br($mail_body); $mail_html = nl2br($mail_body);

View File

@@ -374,6 +374,11 @@ if ($page == 'overview') {
$ssl_redirect = 2; $ssl_redirect = 2;
} }
// HSTS
$hsts_maxage = isset($_POST['hsts_maxage']) ? (int)$_POST['hsts_maxage'] : 0;
$hsts_sub = isset($_POST['hsts_sub']) && (int)$_POST['hsts_sub'] == 1 ? 1 : 0;
$hsts_preload = isset($_POST['hsts_preload']) && (int)$_POST['hsts_preload'] == 1 ? 1 : 0;
if ($path == '') { if ($path == '') {
standard_error('patherror'); standard_error('patherror');
} elseif ($subdomain == '') { } elseif ($subdomain == '') {
@@ -416,7 +421,10 @@ if ($page == 'overview') {
`specialsettings` = :specialsettings, `specialsettings` = :specialsettings,
`ssl_redirect` = :ssl_redirect, `ssl_redirect` = :ssl_redirect,
`phpsettingid` = :phpsettingid, `phpsettingid` = :phpsettingid,
`letsencrypt` = :letsencrypt" `letsencrypt` = :letsencrypt,
`hsts` = :hsts,
`hsts_sub` = :hsts_sub,
`hsts_preload` = :hsts_preload"
); );
$params = array( $params = array(
"customerid" => $userinfo['customerid'], "customerid" => $userinfo['customerid'],
@@ -433,7 +441,10 @@ if ($page == 'overview') {
"specialsettings" => $domain_check['specialsettings'], "specialsettings" => $domain_check['specialsettings'],
"ssl_redirect" => $ssl_redirect, "ssl_redirect" => $ssl_redirect,
"phpsettingid" => $phpsid_result['phpsettingid'], "phpsettingid" => $phpsid_result['phpsettingid'],
"letsencrypt" => $letsencrypt "letsencrypt" => $letsencrypt,
"hsts" => $hsts_maxage,
"hsts_sub" => $hsts_sub,
"hsts_preload" => $hsts_preload
); );
Database::pexecute($stmt, $params); Database::pexecute($stmt, $params);
@@ -506,7 +517,12 @@ if ($page == 'overview') {
// check if we at least have one ssl-ip/port, #1179 // check if we at least have one ssl-ip/port, #1179
$ssl_ipsandports = ''; $ssl_ipsandports = '';
$ssl_ip_stmt = Database::prepare("SELECT COUNT(*) as countSSL FROM `panel_ipsandports` WHERE `ssl`='1'"); $ssl_ip_stmt = Database::prepare("
SELECT COUNT(*) as countSSL
FROM `".TABLE_PANEL_IPSANDPORTS."` pip
LEFT JOIN `".TABLE_DOMAINTOIP."` dti ON dti.id_ipandports = pip.id
WHERE pip.`ssl`='1'
");
Database::pexecute($ssl_ip_stmt); Database::pexecute($ssl_ip_stmt);
$resultX = $ssl_ip_stmt->fetch(PDO::FETCH_ASSOC); $resultX = $ssl_ip_stmt->fetch(PDO::FETCH_ASSOC);
if (isset($resultX['countSSL']) && (int)$resultX['countSSL'] > 0) { if (isset($resultX['countSSL']) && (int)$resultX['countSSL'] > 0) {
@@ -527,8 +543,7 @@ if ($page == 'overview') {
} }
} elseif ($action == 'edit' && $id != 0) { } elseif ($action == 'edit' && $id != 0) {
$stmt = Database::prepare("SELECT `d`.`id`, `d`.`customerid`, `d`.`domain`, `d`.`documentroot`, `d`.`isemaildomain`, `d`.`isbinddomain`, `d`.`wwwserveralias`, `d`.`iswildcarddomain`, $stmt = Database::prepare("SELECT `d`.*, `pd`.`subcanemaildomain`
`d`.`parentdomainid`, `d`.`ssl_redirect`, `d`.`aliasdomain`, `d`.`openbasedir`, `d`.`openbasedir_path`, `d`.`letsencrypt`, `pd`.`subcanemaildomain`
FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_DOMAINS . "` `pd` FROM `" . TABLE_PANEL_DOMAINS . "` `d`, `" . TABLE_PANEL_DOMAINS . "` `pd`
WHERE `d`.`customerid` = :customerid WHERE `d`.`customerid` = :customerid
AND `d`.`id` = :id AND `d`.`id` = :id
@@ -568,7 +583,7 @@ if ($page == 'overview') {
$_doredirect = true; $_doredirect = true;
} }
$aliasdomain = intval($_POST['alias']); $aliasdomain = isset($_POST['alias']) ? intval($_POST['alias']) : 0;
if (isset($_POST['selectserveralias'])) { if (isset($_POST['selectserveralias'])) {
$iswildcarddomain = ($_POST['selectserveralias'] == '0') ? '1' : '0'; $iswildcarddomain = ($_POST['selectserveralias'] == '0') ? '1' : '0';
@@ -642,6 +657,11 @@ if ($page == 'overview') {
$ssl_redirect = 2; $ssl_redirect = 2;
} }
// HSTS
$hsts_maxage = isset($_POST['hsts_maxage']) ? (int)$_POST['hsts_maxage'] : 0;
$hsts_sub = isset($_POST['hsts_sub']) && (int)$_POST['hsts_sub'] == 1 ? 1 : 0;
$hsts_preload = isset($_POST['hsts_preload']) && (int)$_POST['hsts_preload'] == 1 ? 1 : 0;
if ($path == '') { if ($path == '') {
standard_error('patherror'); standard_error('patherror');
} else { } else {
@@ -666,7 +686,11 @@ if ($page == 'overview') {
|| $aliasdomain != $result['aliasdomain'] || $aliasdomain != $result['aliasdomain']
|| $openbasedir_path != $result['openbasedir_path'] || $openbasedir_path != $result['openbasedir_path']
|| $ssl_redirect != $result['ssl_redirect'] || $ssl_redirect != $result['ssl_redirect']
|| $letsencrypt != $result['letsencrypt']) { || $letsencrypt != $result['letsencrypt']
|| $hsts_maxage != $result['hsts']
|| $hsts_sub != $result['hsts_sub']
|| $hsts_preload != $result['hsts_preload']
) {
$log->logAction(USR_ACTION, LOG_INFO, "edited domain '" . $idna_convert->decode($result['domain']) . "'"); $log->logAction(USR_ACTION, LOG_INFO, "edited domain '" . $idna_convert->decode($result['domain']) . "'");
$stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET
@@ -677,7 +701,10 @@ if ($page == 'overview') {
`aliasdomain`= :aliasdomain, `aliasdomain`= :aliasdomain,
`openbasedir_path`= :openbasedir_path, `openbasedir_path`= :openbasedir_path,
`ssl_redirect`= :ssl_redirect, `ssl_redirect`= :ssl_redirect,
`letsencrypt`= :letsencrypt `letsencrypt`= :letsencrypt,
`hsts` = :hsts,
`hsts_sub` = :hsts_sub,
`hsts_preload` = :hsts_preload
WHERE `customerid`= :customerid WHERE `customerid`= :customerid
AND `id`= :id" AND `id`= :id"
); );
@@ -690,6 +717,9 @@ if ($page == 'overview') {
"openbasedir_path" => $openbasedir_path, "openbasedir_path" => $openbasedir_path,
"ssl_redirect" => $ssl_redirect, "ssl_redirect" => $ssl_redirect,
"letsencrypt" => $letsencrypt, "letsencrypt" => $letsencrypt,
"hsts" => $hsts_maxage,
"hsts_sub" => $hsts_sub,
"hsts_preload" => $hsts_preload,
"customerid" => $userinfo['customerid'], "customerid" => $userinfo['customerid'],
"id" => $id "id" => $id
); );
@@ -699,12 +729,21 @@ if ($page == 'overview') {
// trigger when domain id for alias destination has changed: both for old and new destination // trigger when domain id for alias destination has changed: both for old and new destination
triggerLetsEncryptCSRForAliasDestinationDomain($result['aliasdomain'], $log); triggerLetsEncryptCSRForAliasDestinationDomain($result['aliasdomain'], $log);
triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $log); triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $log);
} else } elseif ($result['wwwserveralias'] != $wwwserveralias || $result['letsencrypt'] != $letsencrypt) {
if ($result['wwwserveralias'] != $wwwserveralias || $result['letsencrypt'] != $letsencrypt) {
// or when wwwserveralias or letsencrypt was changed // or when wwwserveralias or letsencrypt was changed
triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $log); triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $log);
} }
// check whether LE has been disabled, so we remove the certificate
if ($letsencrypt == '0' && $result['letsencrypt'] == '1') {
$del_stmt = Database::prepare("
DELETE FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :id
");
Database::pexecute($del_stmt, array(
'id' => $id
));
}
inserttask('1'); inserttask('1');
// Using nameserver, insert a task which rebuilds the server config // Using nameserver, insert a task which rebuilds the server config
@@ -730,7 +769,7 @@ if ($page == 'overview') {
AND `dip`.`id_ipandports` AND `dip`.`id_ipandports`
IN (SELECT `id_ipandports` FROM `".TABLE_DOMAINTOIP."` IN (SELECT `id_ipandports` FROM `".TABLE_DOMAINTOIP."`
WHERE `id_domain` = :id) WHERE `id_domain` = :id)
GROUP BY `d`.`domain` GROUP BY `d`.`id`, `d`.`domain`
ORDER BY `d`.`domain` ASC" ORDER BY `d`.`domain` ASC"
); );
Database::pexecute($domains_stmt, array("id" => $result['id'], "customerid" => $userinfo['customerid'])); Database::pexecute($domains_stmt, array("id" => $result['id'], "customerid" => $userinfo['customerid']));
@@ -763,8 +802,13 @@ if ($page == 'overview') {
// check if we at least have one ssl-ip/port, #1179 // check if we at least have one ssl-ip/port, #1179
$ssl_ipsandports = ''; $ssl_ipsandports = '';
$ssl_ip_stmt = Database::prepare("SELECT COUNT(*) as countSSL FROM `panel_ipsandports` WHERE `ssl`='1'"); $ssl_ip_stmt = Database::prepare("
Database::pexecute($ssl_ip_stmt); SELECT COUNT(*) as countSSL
FROM `".TABLE_PANEL_IPSANDPORTS."` pip
LEFT JOIN `".TABLE_DOMAINTOIP."` dti ON dti.id_ipandports = pip.id
WHERE `dti`.`id_domain` = :id_domain AND pip.`ssl`='1'
");
Database::pexecute($ssl_ip_stmt, array("id_domain" => $result['id']));
$resultX = $ssl_ip_stmt->fetch(PDO::FETCH_ASSOC); $resultX = $ssl_ip_stmt->fetch(PDO::FETCH_ASSOC);
if (isset($resultX['countSSL']) && (int)$resultX['countSSL'] > 0) { if (isset($resultX['countSSL']) && (int)$resultX['countSSL'] > 0) {
$ssl_ipsandports = 'notempty'; $ssl_ipsandports = 'notempty';

View File

@@ -274,7 +274,8 @@ if ($page == 'overview') {
$mail_body .= "File: ".$_error['file'].':'.$_error['line']."\n\n"; $mail_body .= "File: ".$_error['file'].':'.$_error['line']."\n\n";
$mail_body .= "Trace:\n".trim($_error['trace'])."\n\n"; $mail_body .= "Trace:\n".trim($_error['trace'])."\n\n";
$mail_body .= "-------------------------------------------------------------\n\n"; $mail_body .= "-------------------------------------------------------------\n\n";
$mail_body .= "Froxlor-version: ".$version."\n\n"; $mail_body .= "Froxlor-version: ".$version."\n";
$mail_body .= "DB-version: ".$dbversion."\n\n";
$mail_body .= "End of report"; $mail_body .= "End of report";
$mail_html = str_replace("\n", "<br />", $mail_body); $mail_html = str_replace("\n", "<br />", $mail_body);

View File

@@ -115,8 +115,7 @@ if (!is_null($month) && !is_null($year)) {
$result_stmt = Database::prepare("SELECT `month`, `year`, SUM(`http`) AS http, SUM(`ftp_up`) AS ftp_up, SUM(`ftp_down`) AS ftp_down, SUM(`mail`) AS mail $result_stmt = Database::prepare("SELECT `month`, `year`, SUM(`http`) AS http, SUM(`ftp_up`) AS ftp_up, SUM(`ftp_down`) AS ftp_down, SUM(`mail`) AS mail
FROM `" . TABLE_PANEL_TRAFFIC . "` FROM `" . TABLE_PANEL_TRAFFIC . "`
WHERE `customerid` = :customerid WHERE `customerid` = :customerid
GROUP BY CONCAT(`year`,`month`) GROUP BY `year` DESC, `month` DESC
ORDER BY CONCAT(`year`,`month`) DESC
LIMIT 12" LIMIT 12"
); );
Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid'])); Database::pexecute($result_stmt, array("customerid" => $userinfo['customerid']));

View File

@@ -66,7 +66,7 @@ CREATE TABLE `mail_virtual` (
`id` int(11) NOT NULL auto_increment, `id` int(11) NOT NULL auto_increment,
`email` varchar(255) NOT NULL default '', `email` varchar(255) NOT NULL default '',
`email_full` varchar(255) NOT NULL default '', `email_full` varchar(255) NOT NULL default '',
`destination` text NOT NULL, `destination` text NOT NULL default '',
`domainid` int(11) NOT NULL default '0', `domainid` int(11) NOT NULL default '0',
`customerid` int(11) NOT NULL default '0', `customerid` int(11) NOT NULL default '0',
`popaccountid` int(11) NOT NULL default '0', `popaccountid` int(11) NOT NULL default '0',
@@ -195,8 +195,9 @@ CREATE TABLE `panel_customers` (
`theme` varchar(255) NOT NULL default 'Sparkle', `theme` varchar(255) NOT NULL default 'Sparkle',
`custom_notes` text, `custom_notes` text,
`custom_notes_show` tinyint(1) NOT NULL default '0', `custom_notes_show` tinyint(1) NOT NULL default '0',
`lepublickey` mediumtext DEFAULT NULL, `lepublickey` mediumtext default NULL,
`leprivatekey` mediumtext DEFAULT NULL, `leprivatekey` mediumtext default NULL,
`leregistered` tinyint(1) NOT NULL default '0'
PRIMARY KEY (`customerid`), PRIMARY KEY (`customerid`),
UNIQUE KEY `loginname` (`loginname`) UNIQUE KEY `loginname` (`loginname`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -237,6 +238,7 @@ CREATE TABLE `panel_domains` (
`dkim_pubkey` text, `dkim_pubkey` text,
`wwwserveralias` tinyint(1) NOT NULL default '1', `wwwserveralias` tinyint(1) NOT NULL default '1',
`parentdomainid` int(11) NOT NULL default '0', `parentdomainid` int(11) NOT NULL default '0',
`phpenabled` tinyint(1) NOT NULL default '0',
`openbasedir` tinyint(1) NOT NULL default '0', `openbasedir` tinyint(1) NOT NULL default '0',
`openbasedir_path` tinyint(1) NOT NULL default '0', `openbasedir_path` tinyint(1) NOT NULL default '0',
`speciallogfile` tinyint(1) NOT NULL default '0', `speciallogfile` tinyint(1) NOT NULL default '0',
@@ -245,8 +247,8 @@ CREATE TABLE `panel_domains` (
`deactivated` tinyint(1) NOT NULL default '0', `deactivated` tinyint(1) NOT NULL default '0',
`bindserial` varchar(10) NOT NULL default '2000010100', `bindserial` varchar(10) NOT NULL default '2000010100',
`add_date` int( 11 ) NOT NULL default '0', `add_date` int( 11 ) NOT NULL default '0',
`registration_date` date NOT NULL, `registration_date` date DEFAULT NULL,
`termination_date` date NOT NULL, `termination_date` date DEFAULT NULL,
`phpsettingid` INT( 11 ) UNSIGNED NOT NULL DEFAULT '1', `phpsettingid` INT( 11 ) UNSIGNED NOT NULL DEFAULT '1',
`mod_fcgid_starter` int(4) default '-1', `mod_fcgid_starter` int(4) default '-1',
`mod_fcgid_maxrequests` int(4) default '-1', `mod_fcgid_maxrequests` int(4) default '-1',
@@ -254,7 +256,7 @@ CREATE TABLE `panel_domains` (
`letsencrypt` tinyint(1) NOT NULL default '0', `letsencrypt` tinyint(1) NOT NULL default '0',
`hsts` varchar(10) NOT NULL default '0', `hsts` varchar(10) NOT NULL default '0',
`hsts_sub` tinyint(1) NOT NULL default '0', `hsts_sub` tinyint(1) NOT NULL default '0',
`hsts_preload` tinyint(1) NOT NULL default '1', `hsts_preload` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `customerid` (`customerid`), KEY `customerid` (`customerid`),
KEY `parentdomain` (`parentdomainid`), KEY `parentdomain` (`parentdomainid`),
@@ -497,6 +499,7 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
('system', 'ssl_cert_chainfile', ''), ('system', 'ssl_cert_chainfile', ''),
('system', 'ssl_cipher_list', 'ECDH+AESGCM:ECDH+AES256:!aNULL:!MD5:!DSS:!DH:!AES128'), ('system', 'ssl_cipher_list', 'ECDH+AESGCM:ECDH+AES256:!aNULL:!MD5:!DSS:!DH:!AES128'),
('system', 'nginx_php_backend', '127.0.0.1:8888'), ('system', 'nginx_php_backend', '127.0.0.1:8888'),
('system', 'nginx_http2_support', '0'),
('system', 'perl_server', 'unix:/var/run/nginx/cgiwrap-dispatch.sock'), ('system', 'perl_server', 'unix:/var/run/nginx/cgiwrap-dispatch.sock'),
('system', 'phpreload_command', ''), ('system', 'phpreload_command', ''),
('system', 'apache24', '0'), ('system', 'apache24', '0'),
@@ -543,6 +546,10 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
('system', 'mail_smtp_auth', '1'), ('system', 'mail_smtp_auth', '1'),
('system', 'mail_smtp_user', ''), ('system', 'mail_smtp_user', ''),
('system', 'mail_smtp_passwd', ''), ('system', 'mail_smtp_passwd', ''),
('system', 'hsts_maxage', '0'),
('system', 'hsts_incsub', '0'),
('system', 'hsts_preload', '0'),
('system', 'leregistered', '0'),
('panel', 'decimal_places', '4'), ('panel', 'decimal_places', '4'),
('panel', 'adminmail', 'admin@SERVERNAME'), ('panel', 'adminmail', 'admin@SERVERNAME'),
('panel', 'phpmyadmin_url', ''), ('panel', 'phpmyadmin_url', ''),
@@ -573,8 +580,9 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
('panel', 'password_numeric', '0'), ('panel', 'password_numeric', '0'),
('panel', 'password_special_char_required', '0'), ('panel', 'password_special_char_required', '0'),
('panel', 'password_special_char', '!?<>§$%+#=@'), ('panel', 'password_special_char', '!?<>§$%+#=@'),
('panel', 'version', '0.9.37'), ('panel', 'customer_hide_options', ''),
('panel', 'db_version', '201609200'); ('panel', 'version', '0.9.38.4'),
('panel', 'db_version', '201612110');
DROP TABLE IF EXISTS `panel_tasks`; DROP TABLE IF EXISTS `panel_tasks`;

View File

@@ -3477,8 +3477,99 @@ if (isDatabaseVersion('201609120')) {
} }
if (isDatabaseVersion('201609200')) { if (isDatabaseVersion('201609200')) {
showUpdateStep("Changing tables to be more mysql strict-mode compatible");
Database::query("ALTER TABLE `".TABLE_MAIL_VIRTUAL."` CHANGE `destination` `destination` TEXT NOT NULL DEFAULT '';");
Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` CHANGE `registration_date` `registration_date` DATE NULL DEFAULT NULL;");
Database::query("ALTER TABLE `".TABLE_PANEL_DOMAINS."` CHANGE `termination_date` `termination_date` DATE NULL DEFAULT NULL;");
lastStepStatus(0);
updateToDbVersion('201609240');
}
if (isDatabaseVersion('201609240')) {
showUpdateStep("Add HSTS settings for froxlor-vhost");
Settings::AddNew("system.hsts_maxage", 0);
Settings::AddNew("system.hsts_incsub", 0);
Settings::AddNew("system.hsts_preload", 0);
lastStepStatus(0);
showUpdateStep("Settings HSTS default values for all domains (deactivated)");
Database::query("UPDATE `".TABLE_PANEL_DOMAINS."` SET `hsts_sub` = '0', `hsts_preload` = '0';");
lastStepStatus(0);
updateToDbVersion('201610070');
}
if (isFroxlorVersion('0.9.37')) {
showUpdateStep("Updating from 0.9.37 to 0.9.38-rc1", false);
updateToVersion('0.9.38-rc1');
}
if (isFroxlorVersion('0.9.38-rc1')) {
showUpdateStep("Updating from 0.9.38-rc1 to 0.9.38-rc2", false);
updateToVersion('0.9.38-rc2');
}
if (isFroxlorVersion('0.9.38-rc2')) {
showUpdateStep("Updating from 0.9.38-rc2 to 0.9.38 final", false);
updateToVersion('0.9.38');
}
if (isDatabaseVersion('201610070')) {
showUpdateStep("Add Nginx http2 setting");
Settings::AddNew("system.nginx_http2_support", 0);
lastStepStatus(0);
updateToDbVersion('201611180');
}
if (isFroxlorVersion('0.9.38')) {
showUpdateStep("Updating from 0.9.38 to 0.9.38.1", false);
updateToVersion('0.9.38.1');
}
if (isFroxlorVersion('0.9.38.1')) {
showUpdateStep("Updating from 0.9.38.1 to 0.9.38.2", false);
updateToVersion('0.9.38.2');
}
if (isFroxlorVersion('0.9.38.2')) {
showUpdateStep("Updating from 0.9.38.2 to 0.9.38.3", false);
updateToVersion('0.9.38.3');
}
if (isFroxlorVersion('0.9.38.3')) {
showUpdateStep("Updating from 0.9.38.3 to 0.9.38.4", false);
updateToVersion('0.9.38.4');
}
if (isDatabaseVersion('201611180')) {
showUpdateStep("Updating database table definition for panel_domains");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `phpenabled` tinyint(1) NOT NULL default '1' AFTER `parentdomainid`;");
lastStepStatus(0);
showUpdateStep("Adding field for let's-encrypt registration status");
Database::query("ALTER TABLE `".TABLE_PANEL_CUSTOMERS."` add `leregistered` TINYINT(1) NOT NULL DEFAULT 0;");
lastStepStatus(0);
showUpdateStep("Adding system setting for let's-encrypt registration status");
Settings::AddNew('system.leregistered', '0');
lastStepStatus(0);
showUpdateStep("Adding unique key to ipsandports table"); showUpdateStep("Adding unique key to ipsandports table");
Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD UNIQUE KEY `ip_port` (`ip`,`port`)"); Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD UNIQUE KEY `ip_port` (`ip`,`port`)");
lastStepStatus(0); lastStepStatus(0);
updateToDbVersion('201609270');
updateToDbVersion('201612110');
} }

View File

@@ -122,6 +122,8 @@ class htmlform
return self::_checkbox($fieldname, $data); break; return self::_checkbox($fieldname, $data); break;
case 'file': case 'file':
return self::_file($fieldname, $data); break; return self::_file($fieldname, $data); break;
case 'int':
return self::_int($fieldname, $data); break;
} }
} }
@@ -313,4 +315,29 @@ class htmlform
return $return; return $return;
} }
private static function _int($fieldname = '', $data = array())
{
$return = '';
$extras = '';
if(isset($data['int_min'])) {
$extras .= ' min="'.$data['int_min'].'"';
}
if(isset($data['int_max'])) {
$extras .= ' max="'.$data['int_max'].'"';
}
// add support to save reloaded forms
if (isset($data['value'])) {
$value = $data['value'];
} elseif (isset($_SESSION['requestData'][$fieldname])) {
$value = $_SESSION['requestData'][$fieldname];
} else {
$value = '';
}
$type = 'number';
$ulfield = '';
eval("\$return = \"" . getTemplate("misc/form/input_text", "1") . "\";");
return $return;
}
} }

View File

@@ -135,15 +135,6 @@ class phpinterface_fcgid {
$openbasedir .= appendOpenBasedirPath($this->getTempDir()); $openbasedir .= appendOpenBasedirPath($this->getTempDir());
$openbasedir .= $_phpappendopenbasedir; $openbasedir .= $_phpappendopenbasedir;
$openbasedir = explode(':', $openbasedir);
$clean_openbasedir = array();
foreach ($openbasedir as $number => $path) {
if (trim($path) != '/') {
$clean_openbasedir[] = makeCorrectDir($path);
}
}
$openbasedir = implode(':', $clean_openbasedir);
} else { } else {
$openbasedir = 'none'; $openbasedir = 'none';
$openbasedirc = ';'; $openbasedirc = ';';

View File

@@ -267,15 +267,6 @@ class phpinterface_fpm {
$openbasedir .= appendOpenBasedirPath($this->getTempDir()); $openbasedir .= appendOpenBasedirPath($this->getTempDir());
$openbasedir .= $_phpappendopenbasedir; $openbasedir .= $_phpappendopenbasedir;
$openbasedir = explode(':', $openbasedir);
$clean_openbasedir = array();
foreach ($openbasedir as $number => $path) {
if (trim($path) != '/') {
$clean_openbasedir[] = makeCorrectDir($path);
}
}
$openbasedir = implode(':', $clean_openbasedir);
} }
} }
$fpm_config.= 'php_admin_value[session.save_path] = ' . makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->_domain['loginname'] . '/') . "\n"; $fpm_config.= 'php_admin_value[session.save_path] = ' . makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->_domain['loginname'] . '/') . "\n";

View File

@@ -38,6 +38,12 @@ class lescript
private $accountKey; private $accountKey;
private $customerid;
private $isFroxlorVhost;
private $isLeProduction;
private $version; private $version;
public function __construct($logger, $version = '1') public function __construct($logger, $version = '1')
@@ -57,44 +63,71 @@ class lescript
{ {
// Let's see if we have the private accountkey // Let's see if we have the private accountkey
$this->accountKey = $certrow['leprivatekey']; $this->accountKey = $certrow['leprivatekey'];
if (! $this->accountKey || $this->accountKey == 'unset' || Settings::Get('system.letsencryptca') != 'production') { $this->customerId = $certrow['customerid'];
$this->isFroxlorVhost = $isFroxlorVhost;
$this->isLeProduction = (Settings::Get('system.letsencryptca') == 'production');
$leregistered=$certrow['leregistered'];
if (! $this->accountKey || $this->accountKey == 'unset' || !$this->isLeProduction) {
// generate and save new private key for account // generate and save new private key for account
// --------------------------------------------- // ---------------------------------------------
$this->log('Starting new account registration'); $this->log('Creating new account key');
$keys = $this->generateKey(); $keys = $this->generateKey();
// Only store the accountkey in production, in staging always generate a new key // Only store the accountkey in production, in staging always generate a new key
if (Settings::Get('system.letsencryptca') == 'production') { if ($this->isLeProduction) {
if ($isFroxlorVhost) { if ($isFroxlorVhost) {
Settings::Set('system.lepublickey', $keys['public']); Settings::Set('system.lepublickey', $keys['public']);
Settings::Set('system.leprivatekey', $keys['private']); Settings::Set('system.leprivatekey', $keys['private']);
Settings::Set('system.leregistered', 0); // key is not registered
} else { } else {
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `lepublickey` = :public, `leprivatekey` = :private " . "WHERE `customerid` = :customerid;"); $upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `lepublickey` = :public, `leprivatekey` = :private, `leregistered` = :registered " . "WHERE `customerid` = :customerid;");
Database::pexecute($upd_stmt, array( Database::pexecute($upd_stmt, array(
'public' => $keys['public'], 'public' => $keys['public'],
'private' => $keys['private'], 'private' => $keys['private'],
'customerid' => $certrow['customerid'] 'registered' => 0,
'customerid' => $this->customerId
)); ));
} }
} }
$leregistered=0;
$this->accountKey = $keys['private']; $this->accountKey = $keys['private'];
} else {
$this->log('Using existing account key');
}
if ($leregistered==0) { // Account not registered
$this->log('Starting new account registration');
$response = $this->postNewReg(); $response = $this->postNewReg();
if ($this->client->getLastCode() != 201) { if ($this->client->getLastCode() == 409) {
$this->log('The key was already registered. Using existing account.');
} else if ($this->client->getLastCode() == 201) {
$this->log('New account registered.');
} else {
throw new \RuntimeException("Account not initialized, probably due to rate limiting. Whole response: " . json_encode($response)); throw new \RuntimeException("Account not initialized, probably due to rate limiting. Whole response: " . json_encode($response));
} }
$accountUrl=$this->client->getLastLocation();
$this->log('Accepting lets encrypt Terms of Service');
$this->license = $this->client->getAgreementURL(); $this->license = $this->client->getAgreementURL();
// Terms of Servce are optional according to ACME specs; if no ToS are presented, no need to update registration // Terms of Service are optional according to ACME specs; if no ToS are presented, no need to update registration
if (!empty($this->license)) { if (!empty($this->license)) {
$this->postRegAgreement(parse_url($this->client->getLastLocation(), PHP_URL_PATH)); $response = $this->postRegAgreement(parse_url($accountUrl, PHP_URL_PATH));
if ($this->client->getLastCode() != 202) {
throw new \RuntimeException("Terms of Service not accepted. Whole response: " . json_encode($response));
}
} }
$this->log('New account certificate registered');
} else {
$this->log('Account already registered. Continuing.'); $leregistered=1;
$this->setLeRegisteredState($leregistered); // Account registered
$this->log('Lets encrypt Terms of Service accepted');
} }
} }
/** /**
@@ -136,11 +169,17 @@ class lescript
) )
)); ));
if ($this->client->getLastCode() == 403) {
$this->log("Got status 403 - setting LE status to unregistered.");
$this->setLeRegisteredState(0);
throw new RuntimeException("Got 'unauthorized' response - we need to re-register at next run. Whole response: " . json_encode($response));
}
// if response is not an array but a string, it's most likely a server-error, e.g. // if response is not an array but a string, it's most likely a server-error, e.g.
// <HTML><HEAD><TITLE>Error</TITLE></HEAD><BODY>An error occurred while processing your request. // <HTML><HEAD><TITLE>Error</TITLE></HEAD><BODY>An error occurred while processing your request.
// <p>Reference&#32;&#35;179&#46;d8be1402&#46;1458059103&#46;3613c4db</BODY></HTML> // <p>Reference&#32;&#35;179&#46;d8be1402&#46;1458059103&#46;3613c4db</BODY></HTML>
if (! is_array($response)) { if (! is_array($response)) {
throw new RuntimeException("Invalid response from LE for domain $domain. Whole response: " . $response); throw new RuntimeException("Invalid response from LE for domain $domain. Whole response: " . json_encode($response));
} }
if (! array_key_exists('challenges', $response)) { if (! array_key_exists('challenges', $response)) {
@@ -188,7 +227,7 @@ class lescript
$this->log("Token for $domain saved at $tokenPath and should be available at $uri"); $this->log("Token for $domain saved at $tokenPath and should be available at $uri");
// simple self check // simple self check
$selfcheckContextOptions = array('http' => array('header' => "User Agent: Froxlor/".$this->version)); $selfcheckContextOptions = array('http' => array('header' => "User-Agent: Froxlor/".$this->version));
$selfcheckContext = stream_context_create($selfcheckContextOptions); $selfcheckContext = stream_context_create($selfcheckContextOptions);
if ($payload !== trim(@file_get_contents($uri, false, $selfcheckContext))) { if ($payload !== trim(@file_get_contents($uri, false, $selfcheckContext))) {
$errmsg = json_encode(error_get_last()); $errmsg = json_encode(error_get_last());
@@ -309,6 +348,21 @@ class lescript
); );
} }
private function setLeRegisteredState($state)
{
if ($this->isLeProduction) {
if ($this->isFroxlorVhost) {
Settings::Set('system.leregistered', $state);
} else {
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `leregistered` = :registered " . "WHERE `customerid` = :customerid;");
Database::pexecute($upd_stmt, array(
'registered' => $state,
'customerid' => $this->customerId
));
}
}
}
private function parsePemFromBody($body) private function parsePemFromBody($body)
{ {
$pem = chunk_split(base64_encode($body), 64, "\n"); $pem = chunk_split(base64_encode($body), 64, "\n");
@@ -537,10 +591,46 @@ class Client
return $matches[1]; return $matches[1];
} }
public function getAgreementURLFromLastResponse()
{
if (preg_match_all('~Link: <(.+)>;rel="terms-of-service"~', $this->lastHeader, $matches)) {
return $matches[1][0];
}
return "";
}
public function getAgreementURLFromDirectory()
{
// FIXME: Current license should be found in /directory but LE does not implement this yet
// $this->curl('GET', '/directory');
return "";
}
public function getAgreementURLFromTermsUrl()
{
$this->curl('GET', '/terms');
if (preg_match_all('~Location: (.+)~', $this->lastHeader, $matches)) {
return trim($matches[1][0]);
}
return "";
}
public function getAgreementURL() public function getAgreementURL()
{ {
preg_match_all('~Link: <(.+)>;rel="terms-of-service"~', $this->lastHeader, $matches); // 1. check the header of the last response
return $matches[1][0]; $license=$this->getAgreementURLFromLastResponse();
if (!empty($license)) return $license;
// 2. query directory for license
$license=$this->getAgreementURLFromDirectory();
if (!empty($license)) return $license;
// 3. query /terms endpoint (not ACME standard but implemented by let's enrypt)
$license=$this->getAgreementURLFromTermsUrl();
if (!empty($license)) return $license;
// Fallback: use latest known license. This is only valid for let's encrypt and should be removed as soon as there is an official
// ACME-endpoint to get the current ToS
return "https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf";
// return "";
} }
} }

View File

@@ -31,8 +31,9 @@ class WebserverBase {
$query = "SELECT `d`.*, `pd`.`domain` AS `parentdomain`, `c`.`loginname`, $query = "SELECT `d`.*, `pd`.`domain` AS `parentdomain`, `c`.`loginname`,
`d`.`phpsettingid`, `c`.`adminid`, `c`.`guid`, `c`.`email`, `d`.`phpsettingid`, `c`.`adminid`, `c`.`guid`, `c`.`email`,
`c`.`documentroot` AS `customerroot`, `c`.`deactivated`, `c`.`documentroot` AS `customerroot`, `c`.`deactivated`,
`c`.`phpenabled` AS `phpenabled`, `d`.`mod_fcgid_starter`, `c`.`phpenabled` AS `phpenabled_customer`,
`d`.`mod_fcgid_maxrequests` `d`.`phpenabled` AS `phpenabled_vhost`,
`d`.`mod_fcgid_starter`,`d`.`mod_fcgid_maxrequests`
FROM `".TABLE_PANEL_DOMAINS."` `d` FROM `".TABLE_PANEL_DOMAINS."` `d`
LEFT JOIN `".TABLE_PANEL_CUSTOMERS."` `c` USING(`customerid`) LEFT JOIN `".TABLE_PANEL_CUSTOMERS."` `c` USING(`customerid`)

View File

@@ -101,40 +101,6 @@ return array(
'is_array' => 1, 'is_array' => 1,
'mandatory' => true 'mandatory' => true
), ),
'ssl_ipandport' => array(
'label' => $lng['domains']['ipandport_ssl_multi']['title'],
'desc' => $lng['domains']['ipandport_ssl_multi']['description'],
'type' => 'checkbox',
'values' => $ssl_ipsandports,
'value' => '',
'is_array' => 1
),
'ssl_redirect' => array(
'visible' => (Settings::Get('system.use_ssl') == '1' ? ($ssl_ipsandports != '' ? true : false) : false),
'label' => $lng['domains']['ssl_redirect']['title'],
'desc' => $lng['domains']['ssl_redirect']['description'],
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array()
),
'letsencrypt' => array(
'visible' => (Settings::Get('system.use_ssl') == '1' ? (Settings::Get('system.leenabled') == '1' ? ($ssl_ipsandports != '' ? true : false) : false) : false),
'label' => $lng['admin']['letsencrypt']['title'],
'desc' => $lng['admin']['letsencrypt']['description'],
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array()
),
'no_ssl_available_info' => array(
'visible' => (Settings::Get('system.use_ssl') == '1' ? ($ssl_ipsandports == '' ? true : false) : false),
'label' => 'SSL',
'type' => 'label',
'value' => $lng['panel']['nosslipsavailable']
),
'selectserveralias' => array( 'selectserveralias' => array(
'label' => $lng['admin']['selectserveralias'], 'label' => $lng['admin']['selectserveralias'],
'desc' => $lng['admin']['selectserveralias_desc'], 'desc' => $lng['admin']['selectserveralias_desc'],
@@ -161,11 +127,89 @@ return array(
) )
) )
), ),
'section_bssl' => array(
'title' => $lng['admin']['webserversettings_ssl'],
'image' => 'icons/domain_add.png',
'visible' => Settings::Get('system.use_ssl') == '1' ? true : false,
'fields' => array(
'ssl_ipandport' => array(
'label' => $lng['domains']['ipandport_ssl_multi']['title'],
'desc' => $lng['domains']['ipandport_ssl_multi']['description'],
'type' => 'checkbox',
'values' => $ssl_ipsandports,
'value' => '',
'is_array' => 1
),
'ssl_redirect' => array(
'visible' => ($ssl_ipsandports != '' ? true : false),
'label' => $lng['domains']['ssl_redirect']['title'],
'desc' => $lng['domains']['ssl_redirect']['description'],
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array()
),
'letsencrypt' => array(
'visible' => (Settings::Get('system.leenabled') == '1' ? ($ssl_ipsandports != '' ? true : false) : false),
'label' => $lng['admin']['letsencrypt']['title'],
'desc' => $lng['admin']['letsencrypt']['description'],
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array()
),
'no_ssl_available_info' => array(
'visible' => ($ssl_ipsandports == '' ? true : false),
'label' => 'SSL',
'type' => 'label',
'value' => $lng['panel']['nosslipsavailable']
),
'hsts_maxage' => array(
'visible' => ($ssl_ipsandports != '' ? true : false),
'label' => $lng['admin']['domain_hsts_maxage']['title'],
'desc' => $lng['admin']['domain_hsts_maxage']['description'],
'type' => 'int',
'int_min' => 0,
'int_max' => 94608000, // 3-years
'value' => 0
),
'hsts_sub' => array(
'visible' => ($ssl_ipsandports != '' ? true : false),
'label' => $lng['admin']['domain_hsts_incsub']['title'],
'desc' => $lng['admin']['domain_hsts_incsub']['description'],
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array()
),
'hsts_preload' => array(
'visible' => ($ssl_ipsandports != '' ? true : false),
'label' => $lng['admin']['domain_hsts_preload']['title'],
'desc' => $lng['admin']['domain_hsts_preload']['description'],
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array()
),
),
),
'section_c' => array( 'section_c' => array(
'title' => $lng['admin']['phpserversettings'], 'title' => $lng['admin']['phpserversettings'],
'image' => 'icons/domain_add.png', 'image' => 'icons/domain_add.png',
'visible' => (($userinfo['change_serversettings'] == '1' || $userinfo['caneditphpsettings'] == '1') ? true : false), 'visible' => (($userinfo['change_serversettings'] == '1' || $userinfo['caneditphpsettings'] == '1') ? true : false),
'fields' => array( 'fields' => array(
'phpenabled' => array(
'label' => $lng['admin']['phpenabled'],
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array('1')
),
'openbasedir' => array( 'openbasedir' => array(
'label' => 'OpenBasedir', 'label' => 'OpenBasedir',
'type' => 'checkbox', 'type' => 'checkbox',

View File

@@ -113,40 +113,6 @@ return array(
'is_array' => 1, 'is_array' => 1,
'mandatory' => true 'mandatory' => true
), ),
'ssl_ipandport' => array(
'label' => $lng['domains']['ipandport_ssl_multi']['title'],
'desc' => $lng['domains']['ipandport_ssl_multi']['description'],
'type' => 'checkbox',
'values' => $ssl_ipsandports,
'value' => $usedips,
'is_array' => 1
),
'ssl_redirect' => array(
'visible' => (Settings::Get('system.use_ssl') == '1' ? ($ssl_ipsandports != '' ? true : false) : false),
'label' => $lng['domains']['ssl_redirect']['title'],
'desc' => $lng['domains']['ssl_redirect']['description'] . ($result['temporary_ssl_redirect'] > 1 ? $lng['domains']['ssl_redirect_temporarilydisabled'] : ''),
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array($result['ssl_redirect'])
),
'letsencrypt' => array(
'visible' => (Settings::Get('system.use_ssl') == '1' ? (Settings::Get('system.leenabled') == '1' ? ($ssl_ipsandports != '' ? true : false) : false) : false),
'label' => $lng['admin']['letsencrypt']['title'],
'desc' => $lng['admin']['letsencrypt']['description'],
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array($result['letsencrypt'])
),
'no_ssl_available_info' => array(
'visible' => (Settings::Get('system.use_ssl') == '1' ? ($ssl_ipsandports == '' ? true : false) : false),
'label' => 'SSL',
'type' => 'label',
'value' => $lng['panel']['nosslipsavailable']
),
'selectserveralias' => array( 'selectserveralias' => array(
'label' => $lng['admin']['selectserveralias'], 'label' => $lng['admin']['selectserveralias'],
'desc' => $lng['admin']['selectserveralias_desc'], 'desc' => $lng['admin']['selectserveralias_desc'],
@@ -184,11 +150,89 @@ return array(
) )
) )
), ),
'section_bssl' => array(
'title' => $lng['admin']['webserversettings_ssl'],
'image' => 'icons/domain_edit.png',
'visible' => Settings::Get('system.use_ssl') == '1' ? true : false,
'fields' => array(
'ssl_ipandport' => array(
'label' => $lng['domains']['ipandport_ssl_multi']['title'],
'desc' => $lng['domains']['ipandport_ssl_multi']['description'],
'type' => 'checkbox',
'values' => $ssl_ipsandports,
'value' => $usedips,
'is_array' => 1
),
'ssl_redirect' => array(
'visible' => ($ssl_ipsandports != '' ? true : false),
'label' => $lng['domains']['ssl_redirect']['title'],
'desc' => $lng['domains']['ssl_redirect']['description'] . ($result['temporary_ssl_redirect'] > 1 ? $lng['domains']['ssl_redirect_temporarilydisabled'] : ''),
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array($result['ssl_redirect'])
),
'letsencrypt' => array(
'visible' => (Settings::Get('system.leenabled') == '1' ? ($ssl_ipsandports != '' ? true : false) : false),
'label' => $lng['admin']['letsencrypt']['title'],
'desc' => $lng['admin']['letsencrypt']['description'],
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array($result['letsencrypt'])
),
'no_ssl_available_info' => array(
'visible' => ($ssl_ipsandports == '' ? true : false),
'label' => 'SSL',
'type' => 'label',
'value' => $lng['panel']['nosslipsavailable']
),
'hsts_maxage' => array(
'visible' => ($ssl_ipsandports != '' ? true : false),
'label' => $lng['admin']['domain_hsts_maxage']['title'],
'desc' => $lng['admin']['domain_hsts_maxage']['description'],
'type' => 'int',
'int_min' => 0,
'int_max' => 94608000, // 3-years
'value' => $result['hsts']
),
'hsts_sub' => array(
'visible' => ($ssl_ipsandports != '' ? true : false),
'label' => $lng['admin']['domain_hsts_incsub']['title'],
'desc' => $lng['admin']['domain_hsts_incsub']['description'],
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array($result['hsts_sub'])
),
'hsts_preload' => array(
'visible' => ($ssl_ipsandports != '' ? true : false),
'label' => $lng['admin']['domain_hsts_preload']['title'],
'desc' => $lng['admin']['domain_hsts_preload']['description'],
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array($result['hsts_preload'])
),
)
),
'section_c' => array( 'section_c' => array(
'title' => $lng['admin']['phpserversettings'], 'title' => $lng['admin']['phpserversettings'],
'image' => 'icons/domain_edit.png', 'image' => 'icons/domain_edit.png',
'visible' => (($userinfo['change_serversettings'] == '1' || $userinfo['caneditphpsettings'] == '1') ? true : false), 'visible' => (($userinfo['change_serversettings'] == '1' || $userinfo['caneditphpsettings'] == '1') ? true : false),
'fields' => array( 'fields' => array(
'phpenabled' => array(
'label' => $lng['admin']['phpenabled'],
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array($result['phpenabled'])
),
'openbasedir' => array( 'openbasedir' => array(
'label' => 'OpenBasedir', 'label' => 'OpenBasedir',
'type' => 'checkbox', 'type' => 'checkbox',

View File

@@ -54,7 +54,7 @@ return array(
'type' => 'text' 'type' => 'text'
), ),
'redirectcode' => array( 'redirectcode' => array(
'visible' => ((Settings::Get('system.webserver') == 'apache2' && Settings::Get('customredirect.enabled') == '1') ? true : false), 'visible' => (Settings::Get('customredirect.enabled') == '1' ? true : false),
'label' => $lng['domains']['redirectifpathisurl'], 'label' => $lng['domains']['redirectifpathisurl'],
'desc' => $lng['domains']['redirectifpathisurlinfo'], 'desc' => $lng['domains']['redirectifpathisurlinfo'],
'type' => 'select', 'type' => 'select',
@@ -66,8 +66,19 @@ return array(
'type' => 'label', 'type' => 'label',
'value' => $lng['customer']['selectserveralias_addinfo'] 'value' => $lng['customer']['selectserveralias_addinfo']
), ),
'openbasedir_path' => array(
'label' => $lng['domain']['openbasedirpath'],
'type' => 'select',
'select_var' => $openbasedir
)
)
),
'section_bssl' => array(
'title' => $lng['admin']['webserversettings_ssl'],
'image' => 'icons/domain_add.png',
'visible' => Settings::Get('system.use_ssl') == '1' ? ($ssl_ipsandports != '' ? true : false) : false,
'fields' => array(
'ssl_redirect' => array( 'ssl_redirect' => array(
'visible' => (Settings::Get('system.use_ssl') == '1' ? ($ssl_ipsandports != '' ? true : false) : false),
'label' => $lng['domains']['ssl_redirect']['title'], 'label' => $lng['domains']['ssl_redirect']['title'],
'desc' => $lng['domains']['ssl_redirect']['description'], 'desc' => $lng['domains']['ssl_redirect']['description'],
'type' => 'checkbox', 'type' => 'checkbox',
@@ -77,7 +88,7 @@ return array(
'value' => array() 'value' => array()
), ),
'letsencrypt' => array( 'letsencrypt' => array(
'visible' => (Settings::Get('system.use_ssl') == '1' ? (Settings::Get('system.leenabled') == '1' ? ($ssl_ipsandports != '' ? true : false) : false) : false), 'visible' => (Settings::Get('system.leenabled') == '1' ? true : false),
'label' => $lng['customer']['letsencrypt']['title'], 'label' => $lng['customer']['letsencrypt']['title'],
'desc' => $lng['customer']['letsencrypt']['description'], 'desc' => $lng['customer']['letsencrypt']['description'],
'type' => 'checkbox', 'type' => 'checkbox',
@@ -86,13 +97,34 @@ return array(
), ),
'value' => array() 'value' => array()
), ),
'openbasedir_path' => array( 'hsts_maxage' => array(
'label' => $lng['domain']['openbasedirpath'], 'label' => $lng['admin']['domain_hsts_maxage']['title'],
'type' => 'select', 'desc' => $lng['admin']['domain_hsts_maxage']['description'],
'select_var' => $openbasedir 'type' => 'int',
) 'int_min' => 0,
) 'int_max' => 94608000, // 3-years
) 'value' => 0
),
'hsts_sub' => array(
'label' => $lng['admin']['domain_hsts_incsub']['title'],
'desc' => $lng['admin']['domain_hsts_incsub']['description'],
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array()
),
'hsts_preload' => array(
'label' => $lng['admin']['domain_hsts_preload']['title'],
'desc' => $lng['admin']['domain_hsts_preload']['description'],
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array()
),
),
),
) )
) )
); );

View File

@@ -54,7 +54,7 @@ return array(
'value' => $urlvalue 'value' => $urlvalue
), ),
'redirectcode' => array( 'redirectcode' => array(
'visible' => ((Settings::Get('system.webserver') == 'apache2' && Settings::Get('customredirect.enabled') == '1') ? true : false), 'visible' => (Settings::Get('customredirect.enabled') == '1' ? true : false),
'label' => $lng['domains']['redirectifpathisurl'], 'label' => $lng['domains']['redirectifpathisurl'],
'desc' => $lng['domains']['redirectifpathisurlinfo'], 'desc' => $lng['domains']['redirectifpathisurlinfo'],
'type' => 'select', 'type' => 'select',
@@ -76,8 +76,20 @@ return array(
), ),
'value' => array($result['isemaildomain']) 'value' => array($result['isemaildomain'])
), ),
'openbasedir_path' => array(
'visible' => ($result['openbasedir'] == '1') ? true : false,
'label' => $lng['domain']['openbasedirpath'],
'type' => 'select',
'select_var' => $openbasedir
)
)
),
'section_bssl' => array(
'title' => $lng['admin']['webserversettings_ssl'],
'image' => 'icons/domain_edit.png',
'visible' => Settings::Get('system.use_ssl') == '1' ? ($ssl_ipsandports != '' ? (domainHasSslIpPort($result['id']) ? true : false) : false) : false,
'fields' => array(
'ssl_redirect' => array( 'ssl_redirect' => array(
'visible' => (Settings::Get('system.use_ssl') == '1' ? ($ssl_ipsandports != '' ? (domainHasSslIpPort($result['id']) ? true : false) : false) : false),
'label' => $lng['domains']['ssl_redirect']['title'], 'label' => $lng['domains']['ssl_redirect']['title'],
'desc' => $lng['domains']['ssl_redirect']['description'] . ($result['temporary_ssl_redirect'] > 1 ? $lng['domains']['ssl_redirect_temporarilydisabled'] : ''), 'desc' => $lng['domains']['ssl_redirect']['description'] . ($result['temporary_ssl_redirect'] > 1 ? $lng['domains']['ssl_redirect_temporarilydisabled'] : ''),
'type' => 'checkbox', 'type' => 'checkbox',
@@ -87,7 +99,7 @@ return array(
'value' => array($result['ssl_redirect']) 'value' => array($result['ssl_redirect'])
), ),
'letsencrypt' => array( 'letsencrypt' => array(
'visible' => (Settings::Get('system.use_ssl') == '1' ? (Settings::Get('system.leenabled') == '1' ? ($ssl_ipsandports != '' ? (domainHasSslIpPort($result['id']) ? true : false) : false) : false) : false), 'visible' => Settings::Get('system.leenabled') == '1' ? true : false,
'label' => $lng['customer']['letsencrypt']['title'], 'label' => $lng['customer']['letsencrypt']['title'],
'desc' => $lng['customer']['letsencrypt']['description'], 'desc' => $lng['customer']['letsencrypt']['description'],
'type' => 'checkbox', 'type' => 'checkbox',
@@ -96,14 +108,34 @@ return array(
), ),
'value' => array($result['letsencrypt']) 'value' => array($result['letsencrypt'])
), ),
'openbasedir_path' => array( 'hsts_maxage' => array(
'visible' => ($result['openbasedir'] == '1') ? true : false, 'label' => $lng['admin']['domain_hsts_maxage']['title'],
'label' => $lng['domain']['openbasedirpath'], 'desc' => $lng['admin']['domain_hsts_maxage']['description'],
'type' => 'select', 'type' => 'int',
'select_var' => $openbasedir 'int_min' => 0,
) 'int_max' => 94608000, // 3-years
) 'value' => $result['hsts']
),
'hsts_sub' => array(
'label' => $lng['admin']['domain_hsts_incsub']['title'],
'desc' => $lng['admin']['domain_hsts_incsub']['description'],
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array($result['hsts_sub'])
),
'hsts_preload' => array(
'label' => $lng['admin']['domain_hsts_preload']['title'],
'desc' => $lng['admin']['domain_hsts_preload']['description'],
'type' => 'checkbox',
'values' => array(
array ('label' => $lng['panel']['yes'], 'value' => '1')
),
'value' => array($result['hsts_preload'])
),
) )
),
) )
) )
); );

View File

@@ -275,13 +275,11 @@ function createDomainZone($domain_id, $froxlorhostname = false, $isMainButSubTo
Database::pexecute($upd_stmt, array('serial' => $domain['bindserial'], 'id' => $domain['id'])); Database::pexecute($upd_stmt, array('serial' => $domain['bindserial'], 'id' => $domain['id']));
} }
$soa_content = $primary_ns . " " . escapeSoaAdminMail(Settings::Get('panel.adminmail')) . " (" . PHP_EOL; // PowerDNS does not like multi-line-format
$soa_content .= $domain['bindserial'] . "\t; serial" . PHP_EOL; $soa_content = $primary_ns . " " . escapeSoaAdminMail(Settings::Get('panel.adminmail')) . " ";
$soa_content .= $domain['bindserial'] . " ";
// TODO for now, dummy time-periods // TODO for now, dummy time-periods
$soa_content .= "1800\t; refresh (30 mins)" . PHP_EOL; $soa_content .= "1800 900 604800 1200";
$soa_content .= "900\t; retry (15 mins)" . PHP_EOL;
$soa_content .= "604800\t; expire (7 days)" . PHP_EOL;
$soa_content .= "1200\t)\t; minimum (20 mins)";
$soa_record = new DnsEntry('@', 'SOA', $soa_content); $soa_record = new DnsEntry('@', 'SOA', $soa_content);
array_unshift($zonerecords, $soa_record); array_unshift($zonerecords, $soa_record);

View File

@@ -17,27 +17,57 @@
* *
*/ */
/** /**
* Returns an array of found directories * Returns an array of found directories
* *
* This function checks every found directory if they match either $uid or $gid, if they do * This function checks every found directory if they match either $uid or $gid, if they do
* the found directory is valid. It uses recursive-iterators to find subdirectories. * the found directory is valid. It uses recursive-iterators to find subdirectories.
* *
* @param string $path the path to start searching in * @param string $path
* @param int $uid the uid which must match the found directories * the path to start searching in
* @param int $gid the gid which must match the found direcotries * @param int $uid
* the uid which must match the found directories
* @param int $gid
* the gid which must match the found direcotries
* *
* @return array Array of found valid paths * @return array Array of found valid paths
*/ */
function findDirs($path, $uid, $gid) { function findDirs($path, $uid, $gid)
{
$_fileList = array(); $_fileList = array();
$path = makeCorrectDir($path); $path = makeCorrectDir($path);
// valid directory? // valid directory?
if (is_dir($path)) { if (is_dir($path)) {
// Will exclude everything under these directories
$exclude = array(
'awstats',
'webalizer'
);
/**
*
* @param SplFileInfo $file
* @param mixed $key
* @param RecursiveCallbackFilterIterator $iterator
* @return bool True if you need to recurse or if the item is acceptable
*/
$filter = function ($file, $key, $iterator) use ($exclude) {
if (in_array($file->getFilename(), $exclude)) {
return false;
}
return true;
};
// create RecursiveIteratorIterator // create RecursiveIteratorIterator
$its = new RecursiveIteratorIterator(new IgnorantRecursiveDirectoryIterator($path)); $its = new RecursiveIteratorIterator(
new RecursiveCallbackFilterIterator(
new IgnorantRecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS),
$filter
)
);
// we can limit the recursion-depth, but will it be helpful or // we can limit the recursion-depth, but will it be helpful or
// will people start asking "why do I only see 2 subdirectories, i want to use /a/b/c" // will people start asking "why do I only see 2 subdirectories, i want to use /a/b/c"
// let's keep this in mind and see whether it will be useful // let's keep this in mind and see whether it will be useful
@@ -50,10 +80,10 @@ function findDirs($path, $uid, $gid) {
$_fileList[] = makeCorrectDir(dirname($fullFileName)); $_fileList[] = makeCorrectDir(dirname($fullFileName));
} }
} }
$_fileList[] = $path;
} }
return array_unique($_fileList); return array_unique($_fileList);
} }
/** /**
@@ -61,9 +91,12 @@ function findDirs($path, $uid, $gid) {
* into UnexpectedValueException you may use this little hack to ignore those * into UnexpectedValueException you may use this little hack to ignore those
* directories, such as lost+found on linux. * directories, such as lost+found on linux.
* (User "antennen" @ http://php.net/manual/en/class.recursivedirectoryiterator.php#101654) * (User "antennen" @ http://php.net/manual/en/class.recursivedirectoryiterator.php#101654)
**/ */
class IgnorantRecursiveDirectoryIterator extends RecursiveDirectoryIterator { class IgnorantRecursiveDirectoryIterator extends RecursiveDirectoryIterator
function getChildren() { {
function getChildren()
{
try { try {
return new IgnorantRecursiveDirectoryIterator($this->getPathname()); return new IgnorantRecursiveDirectoryIterator($this->getPathname());
} catch (UnexpectedValueException $e) { } catch (UnexpectedValueException $e) {

View File

@@ -26,7 +26,11 @@
*/ */
function makeCorrectDir($dir) { function makeCorrectDir($dir) {
if (version_compare("5.4.6", PHP_VERSION, ">")) {
assert('is_string($dir) && strlen($dir) > 0 /* $dir does not look like an actual folder name */'); assert('is_string($dir) && strlen($dir) > 0 /* $dir does not look like an actual folder name */');
} else {
assert('is_string($dir) && strlen($dir) > 0', 'Value "' . $dir .'" does not look like an actual folder name');
}
$dir = trim($dir); $dir = trim($dir);

View File

@@ -64,7 +64,12 @@ function makePathfield($path, $uid, $gid, $value = '', $dom = false) {
$_field = ''; $_field = '';
foreach ($dirList as $key => $dir) { foreach ($dirList as $key => $dir) {
if (strpos($dir, $path) === 0) { if (strpos($dir, $path) === 0) {
$dir = makeCorrectDir(substr($dir, strlen($path))); $dir = substr($dir, strlen($path));
// docroot cut off of current directory == empty -> directory is the docroot
if (empty($dir)) {
$dir = '/';
}
$dir = makeCorrectDir($dir);
} }
$_field.= makeoption($dir, $dir, $value); $_field.= makeoption($dir, $dir, $value);
} }

View File

@@ -40,6 +40,9 @@ function validateFormFieldOption($fieldname, $fielddata, $newfieldvalue)
} }
else else
{ {
if (isset($fielddata['option_emptyallowed']) && $fielddata['option_emptyallowed']) {
return true;
}
return 'not in option'; return 'not in option';
} }
} }

View File

@@ -122,7 +122,7 @@ function validateFormFieldString($fieldname, $fielddata, $newfieldvalue)
$newfieldvalue = ''; $newfieldvalue = '';
$returnvalue = 'stringmustntbeempty'; $returnvalue = 'stringmustntbeempty';
} else { } else {
$newfieldvalue = validate_ip2($newfieldvalue, true, true, true); $newfieldvalue = validate_ip2($newfieldvalue, true, 'invalidip', true, true, true);
$returnvalue = ($newfieldvalue !== false ? true : 'invalidip'); $returnvalue = ($newfieldvalue !== false ? true : 'invalidip');
} }
} }

View File

@@ -58,12 +58,13 @@ function getRedirectCodes() {
* domain-id * domain-id
* *
* @param integer $domainid id of the domain * @param integer $domainid id of the domain
* @param string $default
* *
* @return string redirect-code * @return string redirect-code
*/ */
function getDomainRedirectCode($domainid = 0) { function getDomainRedirectCode($domainid = 0, $default = '') {
$code = ''; $code = $default;
if ($domainid > 0) { if ($domainid > 0) {
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("

View File

@@ -0,0 +1,37 @@
<?php
/**
* This file is part of the Froxlor project.
* Copyright (c) 2003-2009 the SysCP Team (see authors).
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Functions
*
*/
function storeSettingClearCertificates($fieldname, $fielddata, $newfieldvalue) {
$returnvalue = storeSettingField($fieldname, $fielddata, $newfieldvalue);
if ($returnvalue !== false
&& is_array($fielddata)
&& isset($fielddata['settinggroup'])
&& $fielddata['settinggroup'] == 'system'
&& isset($fielddata['varname'])
&& $fielddata['varname'] == 'le_froxlor_enabled'
&& $newfieldvalue == '0'
) {
Database::query("
DELETE FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = '0'
");
}
return $returnvalue;
}

View File

@@ -29,15 +29,18 @@
*/ */
function appendOpenBasedirPath($path = '', $first = false) function appendOpenBasedirPath($path = '', $first = false)
{ {
if ($path != '' && $path != '/' if ($path != '' && $path != '/' &&
&& (! preg_match("#^/dev#i", $path) || preg_match("#^/dev/urandom#i", $path)) (! preg_match("#^/dev#i", $path) || preg_match("#^/dev/urandom#i", $path))
&& ! preg_match("#^/proc#i", $path) && ! preg_match("#^/proc#i", $path)
&& ! preg_match("#^/etc#i", $path) && ! preg_match("#^/etc#i", $path)
&& ! preg_match("#^/sys#i", $path) && ! preg_match("#^/sys#i", $path)
&& ! preg_match("#:#", $path) && ! preg_match("#:#", $path)) {
) {
if (preg_match("#^/dev/urandom#i", $path)) {
$path = makeCorrectFile($path);
} else {
$path = makeCorrectDir($path); $path = makeCorrectDir($path);
}
// check for php-version that requires the trailing // check for php-version that requires the trailing
// slash to be removed as it does not allow the usage // slash to be removed as it does not allow the usage

View File

@@ -37,7 +37,11 @@ function validateUrl($url) {
} }
// needs converting // needs converting
try {
$url = $idna_convert->encode($url); $url = $idna_convert->encode($url);
} catch (Exception $e) {
return false;
}
$pattern = "/^https?:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,4}(\:[0-9]+)?\/?(.+)?$/i"; $pattern = "/^https?:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,4}(\:[0-9]+)?\/?(.+)?$/i";
if (preg_match($pattern, $url)) { if (preg_match($pattern, $url)) {

View File

@@ -49,10 +49,30 @@ function validate_ip($ip, $return_bool = false, $lng = 'invalidip') {
* @param string $lng index for error-message (if $return_bool is false) * @param string $lng index for error-message (if $return_bool is false)
* @param bool $allow_localhost whether to allow 127.0.0.1 * @param bool $allow_localhost whether to allow 127.0.0.1
* @param bool $allow_priv whether to allow private network addresses * @param bool $allow_priv whether to allow private network addresses
* @param bool $allow_cidr whether to allow CIDR values e.g. 10.10.10.10/16
* *
* @return string|bool ip address on success, false on failure * @return string|bool ip address on success, false on failure
*/ */
function validate_ip2($ip, $return_bool = false, $lng = 'invalidip', $allow_localhost = false, $allow_priv = false) { function validate_ip2($ip, $return_bool = false, $lng = 'invalidip', $allow_localhost = false, $allow_priv = false, $allow_cidr = false) {
$cidr = "";
if ($allow_cidr) {
$org_ip = $ip;
$ip_cidr = explode("/", $ip);
if (count($ip_cidr) == 2) {
$ip = $ip_cidr[0];
$cidr = "/".$ip_cidr[1];
} else {
$ip = $org_ip;
}
} elseif (strpos($ip, "/") !== false) {
if ($return_bool) {
return false;
} else {
standard_error($lng, $ip);
exit();
}
}
$filter_lan = $allow_priv ? FILTER_FLAG_NO_RES_RANGE : (FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE); $filter_lan = $allow_priv ? FILTER_FLAG_NO_RES_RANGE : (FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE);
@@ -60,12 +80,12 @@ function validate_ip2($ip, $return_bool = false, $lng = 'invalidip', $allow_loca
|| filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) || filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))
&& filter_var($ip, FILTER_VALIDATE_IP, $filter_lan) && filter_var($ip, FILTER_VALIDATE_IP, $filter_lan)
) { ) {
return $ip; return $ip.$cidr;
} }
// special case where localhost ip is allowed (mysql-access-hosts for example) // special case where localhost ip is allowed (mysql-access-hosts for example)
if ($allow_localhost && $ip == '127.0.0.1') { if ($allow_localhost && $ip == '127.0.0.1') {
return $ip; return $ip.$cidr;
} }
if ($return_bool) { if ($return_bool) {

View File

@@ -39,11 +39,6 @@ header("X-XSS-Protection: 1; mode=block");
// Don't allow to load Froxlor in an iframe to prevent i.e. clickjacking // Don't allow to load Froxlor in an iframe to prevent i.e. clickjacking
header("X-Frame-Options: DENY"); header("X-Frame-Options: DENY");
// If Froxlor was called via HTTPS -> enforce it for the next time
if (isset($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS']) != 'off')) {
header("Strict-Transport-Security: max-age=15768000");
}
// Internet Explorer shall not guess the Content-Type, see: // Internet Explorer shall not guess the Content-Type, see:
// http://blogs.msdn.com/ie/archive/2008/07/02/ie8-security-part-v-comprehensive-protection.aspx // http://blogs.msdn.com/ie/archive/2008/07/02/ie8-security-part-v-comprehensive-protection.aspx
header("X-Content-Type-Options: nosniff"); header("X-Content-Type-Options: nosniff");
@@ -127,6 +122,24 @@ require FROXLOR_INSTALL_DIR.'/lib/tables.inc.php';
*/ */
$idna_convert = new idna_convert_wrapper(); $idna_convert = new idna_convert_wrapper();
/**
* If Froxlor was called via HTTPS -> enforce it for the next time by settings HSTS header according to settings
*/
if (isset($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS']) != 'off')) {
$maxage = Settings::Get('system.hsts_maxage');
if (empty($maxage)) {
$maxage = 0;
}
$hsts_header = "Strict-Transport-Security: max-age=".$maxage;
if (Settings::Get('system.hsts_incsub') == '1') {
$hsts_header .= "; includeSubDomains";
}
if (Settings::Get('system.hsts_preload') == '1') {
$hsts_header .= "; preload";
}
header($hsts_header);
}
/** /**
* disable magic_quotes_runtime if enabled * disable magic_quotes_runtime if enabled
*/ */

View File

@@ -16,10 +16,10 @@
*/ */
// Main version variable // Main version variable
$version = '0.9.37'; $version = '0.9.38.4';
// Database version (YYYYMMDDC where C is a daily counter) // Database version (YYYYMMDDC where C is a daily counter)
$dbversion = '201609200'; $dbversion = '201612110';
// Distribution branding-tag (used for Debian etc.) // Distribution branding-tag (used for Debian etc.)
$branding = ''; $branding = '';

View File

@@ -2027,7 +2027,7 @@ $lng['error']['dns_record_toolong'] = 'Records/labels can only be up to 63 chara
$lng['serversettings']['panel_customer_hide_options']['title'] = 'Hide menu items and traffic charts in customer panel'; $lng['serversettings']['panel_customer_hide_options']['title'] = 'Hide menu items and traffic charts in customer panel';
$lng['serversettings']['panel_customer_hide_options']['description'] = 'Select items to hide in customer panel. To select multiple options, hold down CTRL while selecting.'; $lng['serversettings']['panel_customer_hide_options']['description'] = 'Select items to hide in customer panel. To select multiple options, hold down CTRL while selecting.';
// Added in froxlor 0.9.37.1 // Added in froxlor 0.9.38-rc1
$lng['serversettings']['allow_allow_customer_shell']['title'] = 'Allow customers to enable shell access for ftp-users'; $lng['serversettings']['allow_allow_customer_shell']['title'] = 'Allow customers to enable shell access for ftp-users';
$lng['serversettings']['allow_allow_customer_shell']['description'] = '<strong class="red">Please note: Shell access allows the user to execute various binaries on your system. Use with extrem caution. Please only activate this if you REALLY know what you are doing!!!</strong>'; $lng['serversettings']['allow_allow_customer_shell']['description'] = '<strong class="red">Please note: Shell access allows the user to execute various binaries on your system. Use with extrem caution. Please only activate this if you REALLY know what you are doing!!!</strong>';
$lng['serversettings']['available_shells']['title'] = 'List of available shells'; $lng['serversettings']['available_shells']['title'] = 'List of available shells';
@@ -2055,3 +2055,13 @@ $lng['domains']['ssl_certificates'] = 'SSL certificates';
$lng['domains']['ssl_certificate_removed'] = 'The certificate with the id #%s has been removed successfully'; $lng['domains']['ssl_certificate_removed'] = 'The certificate with the id #%s has been removed successfully';
$lng['domains']['ssl_certificate_error'] = "Error reading certificate for domain: %s"; $lng['domains']['ssl_certificate_error'] = "Error reading certificate for domain: %s";
$lng['domains']['no_ssl_certificates'] = "There are no domains with SSL certificate"; $lng['domains']['no_ssl_certificates'] = "There are no domains with SSL certificate";
$lng['admin']['webserversettings_ssl'] = 'Webserver SSL settings';
$lng['admin']['domain_hsts_maxage']['title'] = 'HTTP Strict Transport Security (HSTS)';
$lng['admin']['domain_hsts_maxage']['description'] = 'Specify the max-age value for the Strict-Transport-Security header<br>The value <i>0</i> will disable HSTS for the domain. Most user set a value of <i>31536000</i> (one year).';
$lng['admin']['domain_hsts_incsub']['title'] = 'Include HSTS for any subdomain';
$lng['admin']['domain_hsts_incsub']['description'] = 'The optional "includeSubDomains" directive, if present, signals the UA that the HSTS Policy applies to this HSTS Host as well as any subdomains of the host\'s domain name.';
$lng['admin']['domain_hsts_preload']['title'] = 'Include domain in <a href="https://hstspreload.appspot.com/" target="_blank">HSTS preload list</a>';
$lng['admin']['domain_hsts_preload']['description'] = 'If you would like this domain to be included in the HSTS preload list maintained by Chrome (and used by Firefox and Safari), then use activate this.<br>Sending the preload directive from your site can have PERMANENT CONSEQUENCES and prevent users from accessing your site and any of its subdomains.<br>Please read the details at <a href="hstspreload.appspot.com/#removal" target="_blank">hstspreload.appspot.com/#removal</a> before sending the header with "preload".';
$lng['serversettings']['nginx_http2_support']['title'] = 'Nginx HTTP2 Support';
$lng['serversettings']['nginx_http2_support']['description'] = 'enable http2 support for ssl. ENABLE ONLY IF YOUR Nginx SUPPORT THIS FEATURE. (version 1.9.5+)';

View File

@@ -1679,7 +1679,7 @@ $lng['error']['dns_record_toolong'] = 'Records/Labels können maximal 63 Zeichen
$lng['serversettings']['panel_customer_hide_options']['title'] = 'Menüpunkte und Traffic-Charts im Kundenbereich ausblenden'; $lng['serversettings']['panel_customer_hide_options']['title'] = 'Menüpunkte und Traffic-Charts im Kundenbereich ausblenden';
$lng['serversettings']['panel_customer_hide_options']['description'] = 'Wählen Sie hier die gewünschten Menüpunkte und Traffic-Charts aus, welche im Kundenbereich ausgeblendet werden sollen. Für Mehrfachauswahl, halten Sie während der Auswahl STRG gedrückt.'; $lng['serversettings']['panel_customer_hide_options']['description'] = 'Wählen Sie hier die gewünschten Menüpunkte und Traffic-Charts aus, welche im Kundenbereich ausgeblendet werden sollen. Für Mehrfachauswahl, halten Sie während der Auswahl STRG gedrückt.';
// Added in froxlor 0.9.37.1 // Added in froxlor 0.9.38-rc1
$lng['serversettings']['allow_allow_customer_shell']['title'] = 'Erlaube Kunden für FTP Benutzer eine Shell auszuwählen'; $lng['serversettings']['allow_allow_customer_shell']['title'] = 'Erlaube Kunden für FTP Benutzer eine Shell auszuwählen';
$lng['serversettings']['allow_allow_customer_shell']['description'] = '<strong class="red">Bitte beachten: Shell Zugriff gestattet dem Benutzer verschiedene Programme auf Ihrem System auszuführen. Mit großer Vorsicht verwenden. Bitte aktiviere dies nur wenn WIRKLICH bekannt ist, was das bedeutet!!!</strong>'; $lng['serversettings']['allow_allow_customer_shell']['description'] = '<strong class="red">Bitte beachten: Shell Zugriff gestattet dem Benutzer verschiedene Programme auf Ihrem System auszuführen. Mit großer Vorsicht verwenden. Bitte aktiviere dies nur wenn WIRKLICH bekannt ist, was das bedeutet!!!</strong>';
$lng['serversettings']['available_shells']['title'] = 'Liste der verfügbaren Shells'; $lng['serversettings']['available_shells']['title'] = 'Liste der verfügbaren Shells';
@@ -1706,3 +1706,10 @@ $lng['domains']['ssl_certificates'] = 'SSL Zertifikate';
$lng['domains']['ssl_certificate_removed'] = 'Das Zertifikat mit der ID #%s wurde erfolgreich gelöscht.'; $lng['domains']['ssl_certificate_removed'] = 'Das Zertifikat mit der ID #%s wurde erfolgreich gelöscht.';
$lng['domains']['ssl_certificate_error'] = "Fehler beim Lesen des Zertifikats für die Domain: %s"; $lng['domains']['ssl_certificate_error'] = "Fehler beim Lesen des Zertifikats für die Domain: %s";
$lng['domains']['no_ssl_certificates'] = "Es wurden keine SSL-Zertifikate gefunden"; $lng['domains']['no_ssl_certificates'] = "Es wurden keine SSL-Zertifikate gefunden";
$lng['admin']['webserversettings_ssl'] = 'Webserver SSL-Einstellungen';
$lng['admin']['domain_hsts_maxage']['title'] = 'HTTP Strict Transport Security (HSTS)';
$lng['admin']['domain_hsts_maxage']['description'] = '"max-age" Wert für den Strict-Transport-Security Header<br>Der Wert <i>0</i> deaktiviert HSTS für diese Domain. Meist wird der Wert <i>31536000</i> gerne genutzt (ein Jahr).';
$lng['admin']['domain_hsts_incsub']['title'] = 'Inkludiere HSTS für jede Subdomain';
$lng['admin']['domain_hsts_incsub']['description'] = 'Die optionale "includeSubDomains" Direktive, wenn vorhanden, signalisiert dem UA, dass die HSTS Regel für diese Domain und auch jede Subdomain dieser gilt.';
$lng['admin']['domain_hsts_preload']['title'] = 'Füge Domain in die <a href="https://hstspreload.appspot.com/" target="_blank">HSTS preload Liste</a> hinzu';
$lng['admin']['domain_hsts_preload']['description'] = 'Wenn die Domain in die HSTS preload Liste, verwaltet von Chrome (und genutzt von Firefox und Safari), hinzugefügt werden soll, dann aktiviere diese Einstellung.<br>Die preload-Direktive zu senden kann PERMANTENTE KONSEQUENZEN haben und dazu führen, dass Benutzer auf diese Domain und auch Subdomains nicht zugreifen können.<br>Beachte Details unter <a href="hstspreload.appspot.com/#removal" target="_blank">hstspreload.appspot.com/#removal</a> bevor ein Header mit "preload" gesendet wird.';

View File

@@ -43,6 +43,7 @@ $certificates_stmt = Database::query("
dom.`ssl_redirect`, dom.`ssl_redirect`,
cust.`leprivatekey`, cust.`leprivatekey`,
cust.`lepublickey`, cust.`lepublickey`,
cust.`leregistered`,
cust.`customerid`, cust.`customerid`,
cust.`loginname` cust.`loginname`
FROM FROM
@@ -103,6 +104,7 @@ if (Settings::Get('system.le_froxlor_enabled') == '1') {
'documentroot' => FROXLOR_INSTALL_DIR, 'documentroot' => FROXLOR_INSTALL_DIR,
'leprivatekey' => Settings::Get('system.leprivatekey'), 'leprivatekey' => Settings::Get('system.leprivatekey'),
'lepublickey' => Settings::Get('system.lepublickey'), 'lepublickey' => Settings::Get('system.lepublickey'),
'leregistered' => Settings::Get('system.leregistered'),
'ssl_redirect' => Settings::Get('system.le_froxlor_redirect'), 'ssl_redirect' => Settings::Get('system.le_froxlor_redirect'),
'expirationdate' => null, 'expirationdate' => null,
'ssl_cert_file' => null, 'ssl_cert_file' => null,
@@ -141,8 +143,7 @@ if (Settings::Get('system.le_froxlor_enabled') == '1') {
if ($insert_or_update_required) { if ($insert_or_update_required) {
$domains = array( $domains = array(
$certrow['domain'], $certrow['domain']
'www.' . $certrow['domain']
); );
// Only renew let's encrypt certificate if no broken ssl_redirect is enabled // Only renew let's encrypt certificate if no broken ssl_redirect is enabled

View File

@@ -129,11 +129,9 @@ class bind extends DnsBase
// AXFR server #100 // AXFR server #100
if (count($this->_axfr) > 0) { if (count($this->_axfr) > 0) {
foreach ($this->_axfr as $axfrserver) { foreach ($this->_axfr as $axfrserver) {
if (validate_ip($axfrserver, true) !== false) {
$bindconf_file .= ' ' . $axfrserver . ';' . "\n"; $bindconf_file .= ' ' . $axfrserver . ';' . "\n";
} }
} }
}
// close allow-transfer // close allow-transfer
$bindconf_file .= ' };' . "\n"; $bindconf_file .= ' };' . "\n";
} }

View File

@@ -194,14 +194,12 @@ class pdns extends DnsBase
// AXFR server #100 // AXFR server #100
if (count($this->_axfr) > 0) { if (count($this->_axfr) > 0) {
foreach ($this->_axfr as $axfrserver) { foreach ($this->_axfr as $axfrserver) {
if (validate_ip($axfrserver, true) !== false) {
$ins_data['value'] = $axfrserver; $ins_data['value'] = $axfrserver;
$ins_stmt->execute($ins_data); $ins_stmt->execute($ins_data);
} }
} }
} }
} }
}
private function _connectToPdnsDb() private function _connectToPdnsDb()
{ {

View File

@@ -1,5 +1,4 @@
<?php <?php
if (! defined('MASTER_CRONJOB')) if (! defined('MASTER_CRONJOB'))
die('You cannot access this file directly!'); die('You cannot access this file directly!');
@@ -183,6 +182,10 @@ class apache extends HttpConfigBase
} }
if ($row_ipsandports['vhostcontainer'] == '1') { if ($row_ipsandports['vhostcontainer'] == '1') {
$without_vhost = $this->virtualhosts_data[$vhosts_filename];
$close_vhost = true;
$this->virtualhosts_data[$vhosts_filename] .= '<VirtualHost ' . $ipport . '>' . "\n"; $this->virtualhosts_data[$vhosts_filename] .= '<VirtualHost ' . $ipport . '>' . "\n";
$mypath = $this->getMyPath($row_ipsandports); $mypath = $this->getMyPath($row_ipsandports);
@@ -274,8 +277,9 @@ class apache extends HttpConfigBase
} }
$this->virtualhosts_data[$vhosts_filename] .= ' </Directory>' . "\n"; $this->virtualhosts_data[$vhosts_filename] .= ' </Directory>' . "\n";
} }
} // create php-fpm <Directory>-Part (config is created in apache_fcgid) }
elseif (Settings::Get('phpfpm.enabled') == '1') { elseif (Settings::Get('phpfpm.enabled') == '1') {
// create php-fpm <Directory>-Part (config is created in apache_fcgid)
$domain = array( $domain = array(
'id' => 'none', 'id' => 'none',
'domain' => Settings::Get('system.hostname'), 'domain' => Settings::Get('system.hostname'),
@@ -340,6 +344,15 @@ class apache extends HttpConfigBase
); );
} }
} // end of ssl-redirect check } // end of ssl-redirect check
else
{
// fallback of froxlor domain-data for processSpecialConfigTemplate()
$domain = array(
'domain' => Settings::Get('system.hostname'),
'loginname' => 'froxlor.panel',
'documentroot' => $mypath
);
}
/** /**
* dirprotection, see #72 * dirprotection, see #72
@@ -408,7 +421,7 @@ class apache extends HttpConfigBase
} else { } else {
$this->virtualhosts_data[$vhosts_filename] .= ' SSLEngine On' . "\n"; $this->virtualhosts_data[$vhosts_filename] .= ' SSLEngine On' . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' SSLProtocol ALL -SSLv2 -SSLv3' . "\n"; $this->virtualhosts_data[$vhosts_filename] .= ' SSLProtocol -ALL +TLSv1 +TLSv1.2' . "\n";
// this makes it more secure, thx to Marcel (08/2013) // this makes it more secure, thx to Marcel (08/2013)
$this->virtualhosts_data[$vhosts_filename] .= ' SSLHonorCipherOrder On' . "\n"; $this->virtualhosts_data[$vhosts_filename] .= ' SSLHonorCipherOrder On' . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n"; $this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n";
@@ -443,10 +456,19 @@ class apache extends HttpConfigBase
} }
} }
} }
} else {
// if there is no cert-file specified but we are generating a ssl-vhost,
// we should return an empty string because this vhost would suck dick, ref #1583
$this->logger->logAction(CRON_ACTION, LOG_ERR, $domain['domain'] . ' :: empty certificate file! Cannot create ssl-directives');
$this->virtualhosts_data[$vhosts_filename] = $without_vhost;
$this->virtualhosts_data[$vhosts_filename] .= '# no ssl-certificate was specified for this domain, therefore no explicit vhost-container is being generated';
$close_vhost = false;
} }
} }
if ($close_vhost) {
$this->virtualhosts_data[$vhosts_filename] .= '</VirtualHost>' . "\n"; $this->virtualhosts_data[$vhosts_filename] .= '</VirtualHost>' . "\n";
}
$this->logger->logAction(CRON_ACTION, LOG_DEBUG, $ipport . ' :: inserted vhostcontainer'); $this->logger->logAction(CRON_ACTION, LOG_DEBUG, $ipport . ' :: inserted vhostcontainer');
} }
unset($vhosts_filename); unset($vhosts_filename);
@@ -475,7 +497,7 @@ class apache extends HttpConfigBase
{ {
$php_options_text = ''; $php_options_text = '';
if ($domain['phpenabled'] == '1') { if ($domain['phpenabled_customer'] == 1 && $domain['phpenabled_vhost'] == '1') {
// This vHost has PHP enabled and we are using the regular mod_php // This vHost has PHP enabled and we are using the regular mod_php
if ($domain['openbasedir'] == '1') { if ($domain['openbasedir'] == '1') {
@@ -795,7 +817,7 @@ class apache extends HttpConfigBase
$_sslport = ":" . $ssldestport['port']; $_sslport = ":" . $ssldestport['port'];
} }
$domain['documentroot'] = 'https://' . $domain['domain'] . $_sslport . '/'; $domain['documentroot'] = 'https://%{HTTP_HOST}' . $_sslport . '/';
} }
if ($ssl_vhost === true && $domain['ssl'] == '1' && Settings::Get('system.use_ssl') == '1') { if ($ssl_vhost === true && $domain['ssl'] == '1' && Settings::Get('system.use_ssl') == '1') {
@@ -817,7 +839,7 @@ class apache extends HttpConfigBase
if ($domain['ssl_cert_file'] != '') { if ($domain['ssl_cert_file'] != '') {
$vhost_content .= ' SSLEngine On' . "\n"; $vhost_content .= ' SSLEngine On' . "\n";
$vhost_content .= ' SSLProtocol ALL -SSLv2 -SSLv3' . "\n"; $vhost_content .= ' SSLProtocol -ALL +TLSv1 +TLSv1.2' . "\n";
// this makes it more secure, thx to Marcel (08/2013) // this makes it more secure, thx to Marcel (08/2013)
$vhost_content .= ' SSLHonorCipherOrder On' . "\n"; $vhost_content .= ' SSLHonorCipherOrder On' . "\n";
$vhost_content .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n"; $vhost_content .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n";
@@ -836,7 +858,7 @@ class apache extends HttpConfigBase
$vhost_content .= ' SSLCertificateChainFile ' . makeCorrectFile($domain['ssl_cert_chainfile']) . "\n"; $vhost_content .= ' SSLCertificateChainFile ' . makeCorrectFile($domain['ssl_cert_chainfile']) . "\n";
} }
if ($domain['hsts'] > 0) { if ($domain['hsts'] >= 0) {
$vhost_content .= ' <IfModule mod_headers.c>' . "\n"; $vhost_content .= ' <IfModule mod_headers.c>' . "\n";
$vhost_content .= ' Header always set Strict-Transport-Security "max-age=' . $domain['hsts']; $vhost_content .= ' Header always set Strict-Transport-Security "max-age=' . $domain['hsts'];
if ($domain['hsts_sub'] == 1) { if ($domain['hsts_sub'] == 1) {
@@ -860,10 +882,10 @@ class apache extends HttpConfigBase
$domain['documentroot'] = trim($domain['documentroot']); $domain['documentroot'] = trim($domain['documentroot']);
if (preg_match('/^https?\:\/\//', $domain['documentroot'])) { if (preg_match('/^https?\:\/\//', $domain['documentroot'])) {
$corrected_docroot = $this->idnaConvert->encode_uri($domain['documentroot']); $corrected_docroot = $domain['documentroot'];
// Get domain's redirect code // Get domain's redirect code
$code = getDomainRedirectCode($domain['id']); $code = getDomainRedirectCode($domain['id'], '301');
$modrew_red = ''; $modrew_red = '';
if ($code != '') { if ($code != '') {
$modrew_red = ' [R=' . $code . ';L,NE]'; $modrew_red = ' [R=' . $code . ';L,NE]';

View File

@@ -23,7 +23,7 @@ class apache_fcgid extends apache
{ {
$php_options_text = ''; $php_options_text = '';
if($domain['phpenabled'] == '1') if($domain['phpenabled_customer'] == 1 && $domain['phpenabled_vhost'] == '1')
{ {
$php = new phpinterface($domain); $php = new phpinterface($domain);
$phpconfig = $php->getPhpConfig((int)$domain['phpsettingid']); $phpconfig = $php->getPhpConfig((int)$domain['phpsettingid']);

View File

@@ -162,7 +162,25 @@ class lighttpd extends HttpConfigBase
$this->lighttpd_data[$vhost_filename] .= "\t" . ')' . "\n"; $this->lighttpd_data[$vhost_filename] .= "\t" . ')' . "\n";
$this->lighttpd_data[$vhost_filename] .= "\t" . ')' . "\n"; $this->lighttpd_data[$vhost_filename] .= "\t" . ')' . "\n";
$this->lighttpd_data[$vhost_filename] .= ' )' . "\n"; $this->lighttpd_data[$vhost_filename] .= ' )' . "\n";
} else {
$domain = array(
'id' => 'none',
'domain' => Settings::Get('system.hostname'),
'adminid' => 1, /* first admin-user (superadmin) */
'guid' => Settings::Get('system.httpuser'),
'openbasedir' => 0,
'email' => Settings::Get('panel.adminmail'),
'loginname' => 'froxlor.panel',
'documentroot' => $mypath
);
} }
} else {
// fallback of froxlor domain-data for processSpecialConfigTemplate()
$domain = array(
'domain' => Settings::Get('system.hostname'),
'loginname' => 'froxlor.panel',
'documentroot' => $mypath
);
} }
if ($row_ipsandports['specialsettings'] != '') { if ($row_ipsandports['specialsettings'] != '') {
@@ -210,7 +228,9 @@ class lighttpd extends HttpConfigBase
echo $ip . ':' . $port . ' :: certificate file "' . $domain['ssl_cert_file'] . '" does not exist! Cannot create SSL-directives' . "\n"; echo $ip . ':' . $port . ' :: certificate file "' . $domain['ssl_cert_file'] . '" does not exist! Cannot create SSL-directives' . "\n";
} else { } else {
$this->lighttpd_data[$vhost_filename] .= 'ssl.engine = "enable"' . "\n"; $this->lighttpd_data[$vhost_filename] .= 'ssl.engine = "enable"' . "\n";
$this->lighttpd_data[$vhost_filename] .= 'ssl.use-compression = "disable"' . "\n";
$this->lighttpd_data[$vhost_filename] .= 'ssl.use-sslv2 = "disable"' . "\n"; $this->lighttpd_data[$vhost_filename] .= 'ssl.use-sslv2 = "disable"' . "\n";
$this->lighttpd_data[$vhost_filename] .= 'ssl.use-sslv3 = "disable"' . "\n";
$this->lighttpd_data[$vhost_filename] .= 'ssl.cipher-list = "' . Settings::Get('system.ssl_cipher_list') . '"' . "\n"; $this->lighttpd_data[$vhost_filename] .= 'ssl.cipher-list = "' . Settings::Get('system.ssl_cipher_list') . '"' . "\n";
$this->lighttpd_data[$vhost_filename] .= 'ssl.honor-cipher-order = "enable"' . "\n"; $this->lighttpd_data[$vhost_filename] .= 'ssl.honor-cipher-order = "enable"' . "\n";
$this->lighttpd_data[$vhost_filename] .= 'ssl.pemfile = "' . makeCorrectFile($domain['ssl_cert_file']) . '"' . "\n"; $this->lighttpd_data[$vhost_filename] .= 'ssl.pemfile = "' . makeCorrectFile($domain['ssl_cert_file']) . '"' . "\n";
@@ -422,15 +442,21 @@ class lighttpd extends HttpConfigBase
$_sslport = ":" . $ssldestport['port']; $_sslport = ":" . $ssldestport['port'];
} }
$domain['documentroot'] = 'https://' . $domain['domain'] . $_sslport . '/'; $domain['documentroot'] = 'https://%1' . $_sslport . '/';
} }
// avoid using any whitespaces // avoid using any whitespaces
$domain['documentroot'] = trim($domain['documentroot']); $domain['documentroot'] = trim($domain['documentroot']);
if (preg_match('/^https?\:\/\//', $domain['documentroot'])) { if (preg_match('/^https?\:\/\//', $domain['documentroot'])) {
$uri = $domain['documentroot'];
// Get domain's redirect code
$code = getDomainRedirectCode($domain['id'], '301');
$vhost_content .= ' url.redirect-code = ' . $code. "\n";
$vhost_content .= ' url.redirect = (' . "\n"; $vhost_content .= ' url.redirect = (' . "\n";
$vhost_content .= ' "^/(.*)$" => "' . $this->idnaConvert->encode_uri($domain['documentroot']) . '$1"' . "\n"; $vhost_content .= ' "^/(.*)$" => "' . $uri . '$1"' . "\n";
$vhost_content .= ' )' . "\n"; $vhost_content .= ' )' . "\n";
} else { } else {
@@ -510,7 +536,9 @@ class lighttpd extends HttpConfigBase
if ($domain['ssl_cert_file'] != '') { if ($domain['ssl_cert_file'] != '') {
$ssl_settings .= 'ssl.engine = "enable"' . "\n"; $ssl_settings .= 'ssl.engine = "enable"' . "\n";
$ssl_settings .= 'ssl.use-compression = "disable"' . "\n";
$ssl_settings .= 'ssl.use-sslv2 = "disable"' . "\n"; $ssl_settings .= 'ssl.use-sslv2 = "disable"' . "\n";
$ssl_settings .= 'ssl.use-sslv3 = "disable"' . "\n";
$ssl_settings .= 'ssl.cipher-list = "' . Settings::Get('system.ssl_cipher_list') . '"' . "\n"; $ssl_settings .= 'ssl.cipher-list = "' . Settings::Get('system.ssl_cipher_list') . '"' . "\n";
$ssl_settings .= 'ssl.honor-cipher-order = "enable"' . "\n"; $ssl_settings .= 'ssl.honor-cipher-order = "enable"' . "\n";
$ssl_settings .= 'ssl.pemfile = "' . makeCorrectFile($domain['ssl_cert_file']) . '"' . "\n"; $ssl_settings .= 'ssl.pemfile = "' . makeCorrectFile($domain['ssl_cert_file']) . '"' . "\n";
@@ -519,16 +547,16 @@ class lighttpd extends HttpConfigBase
$ssl_settings .= 'ssl.ca-file = "' . makeCorrectFile($domain['ssl_ca_file']) . '"' . "\n"; $ssl_settings .= 'ssl.ca-file = "' . makeCorrectFile($domain['ssl_ca_file']) . '"' . "\n";
} }
if ($domain['hsts'] > 0) { if ($domain['hsts'] >= 0) {
$vhost_content .= '$HTTP["scheme"] == "https" { setenv.add-response-header = ( "Strict-Transport-Security" => "max-age=' . $domain['hsts']; $ssl_settings .= '$HTTP["scheme"] == "https" { setenv.add-response-header = ( "Strict-Transport-Security" => "max-age=' . $domain['hsts'];
if ($domain['hsts_sub'] == 1) { if ($domain['hsts_sub'] == 1) {
$vhost_content .= '; includeSubDomains'; $ssl_settings .= '; includeSubDomains';
} }
if ($domain['hsts_preload'] == 1) { if ($domain['hsts_preload'] == 1) {
$vhost_content .= '; preload'; $ssl_settings .= '; preload';
} }
$vhost_content .= '") }' . "\n"; $ssl_settings .= '") }' . "\n";
} }
} }
} }

View File

@@ -21,7 +21,7 @@ class lighttpd_fcgid extends lighttpd
{ {
$php_options_text = ''; $php_options_text = '';
if($domain['phpenabled'] == '1') if($domain['phpenabled_customer'] == 1 && $domain['phpenabled_vhost'] == '1')
{ {
$php = new phpinterface($domain); $php = new phpinterface($domain);
$phpconfig = $php->getPhpConfig((int)$domain['phpsettingid']); $phpconfig = $php->getPhpConfig((int)$domain['phpsettingid']);

View File

@@ -1,4 +1,7 @@
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!'); <?php
if (! defined('MASTER_CRONJOB'))
die('You cannot access this file directly!');
/** /**
* This file is part of the Froxlor project. * This file is part of the Froxlor project.
@@ -17,20 +20,32 @@
require_once (dirname(__FILE__) . '/../classes/class.HttpConfigBase.php'); require_once (dirname(__FILE__) . '/../classes/class.HttpConfigBase.php');
class nginx extends HttpConfigBase { class nginx extends HttpConfigBase
{
private $logger = false; private $logger = false;
private $idnaConvert = false; private $idnaConvert = false;
private $nginx_server = array(); private $nginx_server = array();
// protected // protected
protected $nginx_data = array(); protected $nginx_data = array();
protected $needed_htpasswds = array(); protected $needed_htpasswds = array();
protected $auth_backend_loaded = false; protected $auth_backend_loaded = false;
protected $htpasswds_data = array(); protected $htpasswds_data = array();
protected $known_htpasswdsfilenames = array(); protected $known_htpasswdsfilenames = array();
protected $mod_accesslog_loaded = '0'; protected $mod_accesslog_loaded = '0';
protected $vhost_root_autoindex = false; protected $vhost_root_autoindex = false;
protected $known_vhostfilenames = array(); protected $known_vhostfilenames = array();
/** /**
* indicator whether a customer is deactivated or not * indicator whether a customer is deactivated or not
* if yes, only the webroot will be generated * if yes, only the webroot will be generated
@@ -39,23 +54,22 @@ class nginx extends HttpConfigBase {
*/ */
private $_deactivated = false; private $_deactivated = false;
public function __construct($logger, $idnaConvert, $nginx_server=array()) { public function __construct($logger, $idnaConvert, $nginx_server = array())
{
$this->logger = $logger; $this->logger = $logger;
$this->idnaConvert = $idnaConvert; $this->idnaConvert = $idnaConvert;
$this->nginx_server = $nginx_server; $this->nginx_server = $nginx_server;
} }
public function reload()
public function reload() { {
$this->logger->logAction(CRON_ACTION, LOG_INFO, 'nginx::reload: reloading nginx'); $this->logger->logAction(CRON_ACTION, LOG_INFO, 'nginx::reload: reloading nginx');
safe_exec(Settings::Get('system.apachereload_command')); safe_exec(Settings::Get('system.apachereload_command'));
/** /**
* nginx does not auto-spawn fcgi-processes * nginx does not auto-spawn fcgi-processes
*/ */
if (Settings::Get('system.phpreload_command') != '' if (Settings::Get('system.phpreload_command') != '' && (int) Settings::Get('phpfpm.enabled') == 0) {
&& (int)Settings::Get('phpfpm.enabled') == 0
) {
$this->logger->logAction(CRON_ACTION, LOG_INFO, 'nginx::reload: restarting php processes'); $this->logger->logAction(CRON_ACTION, LOG_INFO, 'nginx::reload: restarting php processes');
safe_exec(Settings::Get('system.phpreload_command')); safe_exec(Settings::Get('system.phpreload_command'));
} elseif ((int) Settings::Get('phpfpm.enabled') == 1) { } elseif ((int) Settings::Get('phpfpm.enabled') == 1) {
@@ -64,17 +78,12 @@ class nginx extends HttpConfigBase {
} }
} }
/** /**
* define a default ErrorDocument-statement, bug #unknown-yet * define a default ErrorDocument-statement, bug #unknown-yet
*/ */
private function _createStandardErrorHandler() { private function _createStandardErrorHandler()
if (Settings::Get('defaultwebsrverrhandler.enabled') == '1' {
&& (Settings::Get('defaultwebsrverrhandler.err401') != '' if (Settings::Get('defaultwebsrverrhandler.enabled') == '1' && (Settings::Get('defaultwebsrverrhandler.err401') != '' || Settings::Get('defaultwebsrverrhandler.err403') != '' || Settings::Get('defaultwebsrverrhandler.err404') != '' || Settings::Get('defaultwebsrverrhandler.err500') != '')) {
|| Settings::Get('defaultwebsrverrhandler.err403') != ''
|| Settings::Get('defaultwebsrverrhandler.err404') != ''
|| Settings::Get('defaultwebsrverrhandler.err500') != '')
) {
$vhosts_folder = ''; $vhosts_folder = '';
if (is_dir(Settings::Get('system.apacheconf_vhost'))) { if (is_dir(Settings::Get('system.apacheconf_vhost'))) {
$vhosts_folder = makeCorrectDir(Settings::Get('system.apacheconf_vhost')); $vhosts_folder = makeCorrectDir(Settings::Get('system.apacheconf_vhost'));
@@ -88,7 +97,12 @@ class nginx extends HttpConfigBase {
$this->nginx_data[$vhosts_filename] = ''; $this->nginx_data[$vhosts_filename] = '';
} }
$statusCodes = array('401', '403', '404', '500'); $statusCodes = array(
'401',
'403',
'404',
'500'
);
foreach ($statusCodes as $statusCode) { foreach ($statusCodes as $statusCode) {
if (Settings::Get('defaultwebsrverrhandler.err' . $statusCode) != '') { if (Settings::Get('defaultwebsrverrhandler.err' . $statusCode) != '') {
$defhandler = Settings::Get('defaultwebsrverrhandler.err' . $statusCode); $defhandler = Settings::Get('defaultwebsrverrhandler.err' . $statusCode);
@@ -101,16 +115,14 @@ class nginx extends HttpConfigBase {
} }
} }
public function createVirtualHosts()
{}
public function createVirtualHosts() { public function createFileDirOptions()
} {}
public function createIpPort()
public function createFileDirOptions() { {
}
public function createIpPort() {
$result_ipsandports_stmt = Database::query(" $result_ipsandports_stmt = Database::query("
SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` ORDER BY `ip` ASC, `port` ASC SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` ORDER BY `ip` ASC, `port` ASC
"); ");
@@ -159,7 +171,7 @@ class nginx extends HttpConfigBase {
'adminid' => 1, /* first admin-user (superadmin) */ 'adminid' => 1, /* first admin-user (superadmin) */
'loginname' => 'froxlor.panel', 'loginname' => 'froxlor.panel',
'documentroot' => $mypath, 'documentroot' => $mypath,
'parentdomainid' => 0, 'parentdomainid' => 0
); );
// override corresponding array values // override corresponding array values
@@ -184,15 +196,22 @@ class nginx extends HttpConfigBase {
} }
} }
$http2 = $ssl_vhost == true && Settings::Get('system.nginx_http2_support') == '1';
/** /**
* this HAS to be set for the default host in nginx or else no vhost will work * this HAS to be set for the default host in nginx or else no vhost will work
*/ */
$this->nginx_data[$vhost_filename] .= "\t". 'listen ' . $ip . ':' . $port . ' default_server'. ($ssl_vhost == true ? ' ssl' : '') . ';' . "\n"; $this->nginx_data[$vhost_filename] .= "\t" . 'listen ' . $ip . ':' . $port . ' default_server' . ($ssl_vhost == true ? ' ssl' : '') . ($http2 == true ? ' http2' : '') . ';' . "\n";
$this->nginx_data[$vhost_filename] .= "\t" . '# Froxlor default vhost' . "\n"; $this->nginx_data[$vhost_filename] .= "\t" . '# Froxlor default vhost' . "\n";
$this->nginx_data[$vhost_filename] .= "\t" . 'server_name ' . Settings::Get('system.hostname') . ';' . "\n"; $this->nginx_data[$vhost_filename] .= "\t" . 'server_name ' . Settings::Get('system.hostname') . ';' . "\n";
$this->nginx_data[$vhost_filename] .= "\t" . 'access_log /var/log/nginx/access.log;' . "\n"; $this->nginx_data[$vhost_filename] .= "\t" . 'access_log /var/log/nginx/access.log;' . "\n";
if (Settings::Get('system.use_ssl') == '1' && Settings::Get('system.leenabled') == '1' && Settings::Get('system.le_froxlor_enabled') == '1') {
$acmeConfFilename = Settings::Get('system.letsencryptacmeconf');
$this->nginx_data[$vhost_filename] .= "\t" . 'include ' . $acmeConfFilename . ';' . "\n";
}
$is_redirect = false; $is_redirect = false;
// check for SSL redirect // check for SSL redirect
if ($row_ipsandports['ssl'] == '0' && Settings::Get('system.le_froxlor_redirect') == '1') { if ($row_ipsandports['ssl'] == '0' && Settings::Get('system.le_froxlor_redirect') == '1') {
@@ -205,7 +224,9 @@ class nginx extends HttpConfigBase {
} else { } else {
$_sslport = $this->checkAlternativeSslPort(); $_sslport = $this->checkAlternativeSslPort();
$mypath = 'https://' . Settings::Get('system.hostname') . $_sslport . '/'; $mypath = 'https://' . Settings::Get('system.hostname') . $_sslport . '/';
$this->nginx_data[$vhost_filename] .= "\t".'return 301 '.$mypath.'$request_uri;'."\n"; $this->nginx_data[$vhost_filename] .= "\t" . 'if ($request_uri !~ ^/.well-known/acme-challenge/\w+$) {' . "\n";
$this->nginx_data[$vhost_filename] .= "\t\t" . 'return 301 ' . $mypath . '$request_uri;' . "\n";
$this->nginx_data[$vhost_filename] .= "\t" . '}' . "\n";
} }
} }
@@ -217,14 +238,11 @@ class nginx extends HttpConfigBase {
} }
if ($row_ipsandports['specialsettings'] != '') { if ($row_ipsandports['specialsettings'] != '') {
$this->nginx_data[$vhost_filename].= $this->processSpecialConfigTemplate( $this->nginx_data[$vhost_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['specialsettings'], array(
$row_ipsandports['specialsettings'], 'domain' => Settings::Get('system.hostname'),
array('domain'=> Settings::Get('system.hostname'),
'loginname' => Settings::Get('phpfpm.vhost_httpuser'), 'loginname' => Settings::Get('phpfpm.vhost_httpuser'),
'documentroot'=> $mypath), 'documentroot' => $mypath
$row_ipsandports['ip'], ), $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
$row_ipsandports['port'],
$row_ipsandports['ssl'] == '1'). "\n";
} }
/** /**
@@ -258,7 +276,7 @@ class nginx extends HttpConfigBase {
'openbasedir' => 0, 'openbasedir' => 0,
'email' => Settings::Get('panel.adminmail'), 'email' => Settings::Get('panel.adminmail'),
'loginname' => 'froxlor.panel', 'loginname' => 'froxlor.panel',
'documentroot' => $mypath, 'documentroot' => $mypath
); );
$php = new phpinterface($domain); $php = new phpinterface($domain);
@@ -284,12 +302,11 @@ class nginx extends HttpConfigBase {
$this->_createStandardErrorHandler(); $this->_createStandardErrorHandler();
} }
/** /**
* create vhosts * create vhosts
*/ */
protected function createNginxHosts() { protected function createNginxHosts()
{
$domains = WebserverBase::getVhostsToCreate(); $domains = WebserverBase::getVhostsToCreate();
foreach ($domains as $domain) { foreach ($domains as $domain) {
@@ -303,10 +320,7 @@ class nginx extends HttpConfigBase {
$this->nginx_data[$vhost_filename] = ''; $this->nginx_data[$vhost_filename] = '';
} }
if ((empty($this->nginx_data[$vhost_filename]) if ((empty($this->nginx_data[$vhost_filename]) && ! is_dir(Settings::Get('system.apacheconf_vhost'))) || is_dir(Settings::Get('system.apacheconf_vhost'))) {
&& !is_dir(Settings::Get('system.apacheconf_vhost')))
|| is_dir(Settings::Get('system.apacheconf_vhost'))
) {
$domain['nonexistinguri'] = '/' . md5(uniqid(microtime(), 1)) . '.htm'; $domain['nonexistinguri'] = '/' . md5(uniqid(microtime(), 1)) . '.htm';
// Create non-ssl host // Create non-ssl host
@@ -323,18 +337,11 @@ class nginx extends HttpConfigBase {
} }
} }
protected function getVhostFilename($domain, $ssl_vhost = false)
protected function getVhostFilename($domain, $ssl_vhost = false) { {
if ((int)$domain['parentdomainid'] == 0 if ((int) $domain['parentdomainid'] == 0 && isCustomerStdSubdomain((int) $domain['id']) == false && ((int) $domain['ismainbutsubto'] == 0 || domainMainToSubExists($domain['ismainbutsubto']) == false)) {
&& isCustomerStdSubdomain((int)$domain['id']) == false
&& ((int)$domain['ismainbutsubto'] == 0
|| domainMainToSubExists($domain['ismainbutsubto']) == false)
) {
$vhost_no = '35'; $vhost_no = '35';
} elseif ((int)$domain['parentdomainid'] == 0 } elseif ((int) $domain['parentdomainid'] == 0 && isCustomerStdSubdomain((int) $domain['id']) == false && (int) $domain['ismainbutsubto'] > 0) {
&& isCustomerStdSubdomain((int)$domain['id']) == false
&& (int)$domain['ismainbutsubto'] > 0
) {
$vhost_no = '30'; $vhost_no = '30';
} else { } else {
// number of dots in a domain specifies it's position (and depth of subdomain) starting at 29 going downwards on higher depth // number of dots in a domain specifies it's position (and depth of subdomain) starting at 29 going downwards on higher depth
@@ -350,12 +357,9 @@ class nginx extends HttpConfigBase {
return $vhost_filename; return $vhost_filename;
} }
protected function getVhostContent($domain, $ssl_vhost = false)
protected function getVhostContent($domain, $ssl_vhost = false) { {
if ($ssl_vhost === true if ($ssl_vhost === true && $domain['ssl'] != '1' && $domain['ssl_redirect'] != '1') {
&& $domain['ssl'] != '1'
&& $domain['ssl_redirect'] != '1'
) {
return ''; return '';
} }
@@ -371,9 +375,7 @@ class nginx extends HttpConfigBase {
$query = "SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` `i`, `" . TABLE_DOMAINTOIP . "` `dip` $query = "SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` `i`, `" . TABLE_DOMAINTOIP . "` `dip`
WHERE dip.id_domain = :domainid AND i.id = dip.id_ipandports "; WHERE dip.id_domain = :domainid AND i.id = dip.id_ipandports ";
if ($ssl_vhost === true if ($ssl_vhost === true && ($domain['ssl'] == '1' || $domain['ssl_redirect'] == '1')) {
&& ($domain['ssl'] == '1' || $domain['ssl_redirect'] == '1')
) {
// by ordering by cert-file the row with filled out SSL-Fields will be shown last, // by ordering by cert-file the row with filled out SSL-Fields will be shown last,
// thus it is enough to fill out 1 set of SSL-Fields // thus it is enough to fill out 1 set of SSL-Fields
$query .= "AND i.ssl = 1 ORDER BY i.ssl_cert_file ASC;"; $query .= "AND i.ssl = 1 ORDER BY i.ssl_cert_file ASC;";
@@ -385,7 +387,9 @@ class nginx extends HttpConfigBase {
$vhost_content .= 'server { ' . "\n"; $vhost_content .= 'server { ' . "\n";
$result_stmt = Database::prepare($query); $result_stmt = Database::prepare($query);
Database::pexecute($result_stmt, array('domainid' => $domain['id'])); Database::pexecute($result_stmt, array(
'domainid' => $domain['id']
));
while ($ipandport = $result_stmt->fetch(PDO::FETCH_ASSOC)) { while ($ipandport = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
@@ -411,70 +415,67 @@ class nginx extends HttpConfigBase {
} }
if ($ipandport['default_vhostconf_domain'] != '') { if ($ipandport['default_vhostconf_domain'] != '') {
$_vhost_content .= $this->processSpecialConfigTemplate( $_vhost_content .= $this->processSpecialConfigTemplate($ipandport['default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
$ipandport['default_vhostconf_domain'],
$domain,
$domain['ip'],
$domain['port'],
$ssl_vhost). "\n";
} }
$vhost_content.= "\t" . 'listen ' . $ipport . ($ssl_vhost == true ? ' ssl' : '') . ';' . "\n"; $http2 = $ssl_vhost == true && Settings::Get('system.nginx_http2_support') == '1';
$vhost_content .= "\t" . 'listen ' . $ipport . ($ssl_vhost == true ? ' ssl' : '') . ($http2 == true ? ' http2' : '') . ';' . "\n";
} }
// get all server-names // get all server-names
$vhost_content .= $this->getServerNames($domain); $vhost_content .= $this->getServerNames($domain);
// respect ssl_redirect settings, #542 // respect ssl_redirect settings, #542
if ($ssl_vhost == false if ($ssl_vhost == false && $domain['ssl'] == '1' && $domain['ssl_redirect'] == '1') {
&& $domain['ssl'] == '1'
&& $domain['ssl_redirect'] == '1') {
// We must not check if our port differs from port 443, // We must not check if our port differs from port 443,
// but if there is a destination-port != 443 // but if there is a destination-port != 443
$_sslport = ''; $_sslport = '';
// This returns the first port that is != 443 with ssl enabled, if any // This returns the first port that is != 443 with ssl enabled, if any
// ordered by ssl-certificate (if any) so that the ip/port combo // ordered by ssl-certificate (if any) so that the ip/port combo
// with certificate is used // with certificate is used
$ssldestport_stmt = Database::prepare( $ssldestport_stmt = Database::prepare("SELECT `ip`.`port` FROM " . TABLE_PANEL_IPSANDPORTS . " `ip`
"SELECT `ip`.`port` FROM ".TABLE_PANEL_IPSANDPORTS." `ip`
LEFT JOIN `" . TABLE_DOMAINTOIP . "` `dip` ON (`ip`.`id` = `dip`.`id_ipandports`) LEFT JOIN `" . TABLE_DOMAINTOIP . "` `dip` ON (`ip`.`id` = `dip`.`id_ipandports`)
WHERE `dip`.`id_domain` = :domainid WHERE `dip`.`id_domain` = :domainid
AND `ip`.`ssl` = '1' AND `ip`.`port` != 443 AND `ip`.`ssl` = '1' AND `ip`.`port` != 443
ORDER BY `ip`.`ssl_cert_file` DESC, `ip`.`port` LIMIT 1;" ORDER BY `ip`.`ssl_cert_file` DESC, `ip`.`port` LIMIT 1;");
); $ssldestport = Database::pexecute_first($ssldestport_stmt, array(
$ssldestport = Database::pexecute_first($ssldestport_stmt, array('domainid' => $domain['id'])); 'domainid' => $domain['id']
));
if ($ssldestport['port'] != '') { if ($ssldestport['port'] != '') {
$_sslport = ":" . $ssldestport['port']; $_sslport = ":" . $ssldestport['port'];
} }
$domain['documentroot'] = 'https://' . $domain['domain'] . $_sslport . '/'; $domain['documentroot'] = 'https://$host' . $_sslport . '/';
} }
// avoid using any whitespaces // avoid using any whitespaces
$domain['documentroot'] = trim($domain['documentroot']); $domain['documentroot'] = trim($domain['documentroot']);
// create ssl settings first since they are required for normal and redirect vhosts // create ssl settings first since they are required for normal and redirect vhosts
if ($ssl_vhost === true if ($ssl_vhost === true && $domain['ssl'] == '1' && Settings::Get('system.use_ssl') == '1') {
&& $domain['ssl'] == '1'
&& Settings::Get('system.use_ssl') == '1'
) {
$vhost_content .= "\n" . $this->composeSslSettings($domain) . "\n"; $vhost_content .= "\n" . $this->composeSslSettings($domain) . "\n";
} }
if (Settings::Get('system.use_ssl') == '1' && Settings::Get('system.leenabled') == '1') if (Settings::Get('system.use_ssl') == '1' && Settings::Get('system.leenabled') == '1') {
{
$acmeConfFilename = Settings::Get('system.letsencryptacmeconf'); $acmeConfFilename = Settings::Get('system.letsencryptacmeconf');
$vhost_content .= "\t" . 'include ' . $acmeConfFilename . ';' . "\n"; $vhost_content .= "\t" . 'include ' . $acmeConfFilename . ';' . "\n";
} }
// if the documentroot is an URL we just redirect // if the documentroot is an URL we just redirect
if (preg_match('/^https?\:\/\//', $domain['documentroot'])) { if (preg_match('/^https?\:\/\//', $domain['documentroot'])) {
$uri = $this->idnaConvert->encode_uri($domain['documentroot']); $uri = $domain['documentroot'];
if (substr($uri, - 1) == '/') { if (substr($uri, - 1) == '/') {
$uri = substr($uri, 0, - 1); $uri = substr($uri, 0, - 1);
} }
$vhost_content .= "\t".'return 301 '.$uri.'$request_uri;'."\n";
// Get domain's redirect code
$code = getDomainRedirectCode($domain['id'], '301');
$vhost_content .= "\t" . 'if ($request_uri !~ ^/.well-known/acme-challenge/\w+$) {' . "\n";
$vhost_content .= "\t\t" . 'return ' . $code .' ' . $uri . '$request_uri;' . "\n";
$vhost_content .= "\t" . '}' . "\n";
} else { } else {
mkDirWithCorrectOwnership($domain['customerroot'], $domain['documentroot'], $domain['guid'], $domain['guid'], true); mkDirWithCorrectOwnership($domain['customerroot'], $domain['documentroot'], $domain['guid'], $domain['guid'], true);
@@ -489,13 +490,7 @@ class nginx extends HttpConfigBase {
$vhost_content .= isset($this->needed_htpasswds[$domain['id']]) ? $this->needed_htpasswds[$domain['id']] . "\n" : ''; $vhost_content .= isset($this->needed_htpasswds[$domain['id']]) ? $this->needed_htpasswds[$domain['id']] . "\n" : '';
if ($domain['specialsettings'] != "") { if ($domain['specialsettings'] != "") {
$vhost_content = $this->mergeVhostCustom($vhost_content, $this->processSpecialConfigTemplate( $vhost_content = $this->mergeVhostCustom($vhost_content, $this->processSpecialConfigTemplate($domain['specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost));
$domain['specialsettings'],
$domain,
$domain['ip'],
$domain['port'],
$ssl_vhost
));
} }
if ($_vhost_content != '') { if ($_vhost_content != '') {
@@ -503,13 +498,7 @@ class nginx extends HttpConfigBase {
} }
if (Settings::Get('system.default_vhostconf') != '') { if (Settings::Get('system.default_vhostconf') != '') {
$vhost_content = $this->mergeVhostCustom($vhost_content, $vhost_content = $this->mergeVhostCustom($vhost_content, $this->processSpecialConfigTemplate(Settings::Get('system.default_vhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n");
$this->processSpecialConfigTemplate(
Settings::Get('system.default_vhostconf'),
$domain,
$domain['ip'],
$domain['port'],
$ssl_vhost)."\n");
} }
} }
} }
@@ -518,14 +507,21 @@ class nginx extends HttpConfigBase {
return $vhost_content; return $vhost_content;
} }
protected function mergeVhostCustom($vhost_frx, $vhost_usr) { protected function mergeVhostCustom($vhost_frx, $vhost_usr)
{
// Clean froxlor defined settings // Clean froxlor defined settings
$vhost_frx = explode("\n", preg_replace('/[ \t]+/', ' ', trim(preg_replace('/\t+/', '', $vhost_frx)))); // Break into array items $vhost_frx = explode("\n", preg_replace('/[ \t]+/', ' ', trim(preg_replace('/\t+/', '', $vhost_frx)))); // Break into array items
$vhost_frx = array_map("trim", $vhost_frx); // remove unnecessary whitespaces $vhost_frx = array_map("trim", $vhost_frx); // remove unnecessary whitespaces
// Clean user defined settings // Clean user defined settings
$vhost_usr = str_replace("\r", "\n", $vhost_usr); // Remove windows linebreaks $vhost_usr = str_replace("\r", "\n", $vhost_usr); // Remove windows linebreaks
$vhost_usr = str_replace(array("{ ", " }"), array("{\n", "\n}"), $vhost_usr); // Break blocks into lines $vhost_usr = str_replace(array(
"{ ",
" }"
), array(
"{\n",
"\n}"
), $vhost_usr); // Break blocks into lines
$vhost_usr = explode("\n", preg_replace('/[ \t]+/', ' ', trim(preg_replace('/\t+/', '', $vhost_usr)))); // Break into array items $vhost_usr = explode("\n", preg_replace('/[ \t]+/', ' ', trim(preg_replace('/\t+/', '', $vhost_usr)))); // Break into array items
$vhost_usr = array_filter($vhost_usr, create_function('$a', 'return preg_match("#\S#", $a);')); // Remove empty lines $vhost_usr = array_filter($vhost_usr, create_function('$a', 'return preg_match("#\S#", $a);')); // Remove empty lines
@@ -584,8 +580,8 @@ class nginx extends HttpConfigBase {
return implode("\n", $vhost_frx); return implode("\n", $vhost_frx);
} }
protected function composeSslSettings($domain_or_ip) { protected function composeSslSettings($domain_or_ip)
{
$sslsettings = ''; $sslsettings = '';
if ($domain_or_ip['ssl_cert_file'] == '') { if ($domain_or_ip['ssl_cert_file'] == '') {
@@ -613,7 +609,7 @@ class nginx extends HttpConfigBase {
} else { } else {
// obsolete: ssl on now belongs to the listen block as 'ssl' at the end // obsolete: ssl on now belongs to the listen block as 'ssl' at the end
// $sslsettings .= "\t" . 'ssl on;' . "\n"; // $sslsettings .= "\t" . 'ssl on;' . "\n";
$sslsettings .= "\t" . 'ssl_protocols TLSv1 TLSv1.1 TLSv1.2;' . "\n"; $sslsettings .= "\t" . 'ssl_protocols TLSv1 TLSv1.2;' . "\n";
$sslsettings .= "\t" . 'ssl_ciphers ' . Settings::Get('system.ssl_cipher_list') . ';' . "\n"; $sslsettings .= "\t" . 'ssl_ciphers ' . Settings::Get('system.ssl_cipher_list') . ';' . "\n";
$sslsettings .= "\t" . 'ssl_ecdh_curve secp384r1;' . "\n"; $sslsettings .= "\t" . 'ssl_ecdh_curve secp384r1;' . "\n";
$sslsettings .= "\t" . 'ssl_prefer_server_ciphers on;' . "\n"; $sslsettings .= "\t" . 'ssl_prefer_server_ciphers on;' . "\n";
@@ -628,15 +624,15 @@ class nginx extends HttpConfigBase {
} }
} }
if (isset($domain_or_ip['hsts']) && $domain_or_ip['hsts'] > 0) { if (isset($domain_or_ip['hsts']) && $domain_or_ip['hsts'] >= 0) {
$vhost_content .= 'add_header Strict-Transport-Security "max-age=' . $domain_or_ip['hsts']; $sslsettings .= 'add_header Strict-Transport-Security "max-age=' . $domain_or_ip['hsts'];
if ($domain_or_ip['hsts_sub'] == 1) { if ($domain_or_ip['hsts_sub'] == 1) {
$vhost_content .= '; includeSubDomains'; $sslsettings .= '; includeSubDomains';
} }
if ($domain_or_ip['hsts_preload'] == 1) { if ($domain_or_ip['hsts_preload'] == 1) {
$vhost_content .= '; preload'; $sslsettings .= '; preload';
} }
$vhost_content .= '";' . "\n"; $sslsettings .= '";' . "\n";
} }
} }
} }
@@ -644,15 +640,17 @@ class nginx extends HttpConfigBase {
return $sslsettings; return $sslsettings;
} }
protected function create_pathOptions($domain)
protected function create_pathOptions($domain) { {
$has_location = false; $has_location = false;
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
SELECT * FROM " . TABLE_PANEL_HTACCESS . " SELECT * FROM " . TABLE_PANEL_HTACCESS . "
WHERE `path` LIKE :docroot WHERE `path` LIKE :docroot
"); ");
Database::pexecute($result_stmt, array('docroot' => $domain['documentroot'] . '%')); Database::pexecute($result_stmt, array(
'docroot' => $domain['documentroot'] . '%'
));
$path_options = ''; $path_options = '';
$htpasswds = $this->getHtpasswds($domain); $htpasswds = $this->getHtpasswds($domain);
@@ -739,9 +737,7 @@ class nginx extends HttpConfigBase {
* Perl support * Perl support
* required the fastCGI wrapper to be running to receive the CGI requests. * required the fastCGI wrapper to be running to receive the CGI requests.
*/ */
if (customerHasPerlEnabled($domain['customerid']) if (customerHasPerlEnabled($domain['customerid']) && $row['options_cgi'] != '0') {
&& $row['options_cgi'] != '0'
) {
$path = makeCorrectDir(substr($row['path'], strlen($domain['documentroot']) - 1)); $path = makeCorrectDir(substr($row['path'], strlen($domain['documentroot']) - 1));
mkDirWithCorrectOwnership($domain['documentroot'], $row['path'], $domain['guid'], $domain['guid']); mkDirWithCorrectOwnership($domain['documentroot'], $row['path'], $domain['guid'], $domain['guid']);
@@ -756,7 +752,6 @@ class nginx extends HttpConfigBase {
$path_options .= "\t\t" . 'include ' . Settings::Get('nginx.fastcgiparams') . ';' . "\n"; $path_options .= "\t\t" . 'include ' . Settings::Get('nginx.fastcgiparams') . ';' . "\n";
$path_options .= "\t" . '}' . "\n"; $path_options .= "\t" . '}' . "\n";
} }
} }
// now the rest of the htpasswds // now the rest of the htpasswds
@@ -786,16 +781,18 @@ class nginx extends HttpConfigBase {
return $path_options; return $path_options;
} }
protected function getHtpasswds($domain)
protected function getHtpasswds($domain) { {
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
SELECT * SELECT *
FROM `" . TABLE_PANEL_HTPASSWDS . "` AS a FROM `" . TABLE_PANEL_HTPASSWDS . "` AS a
JOIN `" . TABLE_PANEL_DOMAINS . "` AS b USING (`customerid`) JOIN `" . TABLE_PANEL_DOMAINS . "` AS b USING (`customerid`)
WHERE b.customerid = :customerid AND b.domain = :domain WHERE b.customerid = :customerid AND b.domain = :domain
"); ");
Database::pexecute($result_stmt, array('customerid' => $domain['customerid'], 'domain' => $domain['domain'])); Database::pexecute($result_stmt, array(
'customerid' => $domain['customerid'],
'domain' => $domain['domain']
));
$returnval = array(); $returnval = array();
$x = 0; $x = 0;
@@ -846,10 +843,10 @@ class nginx extends HttpConfigBase {
return $returnval; return $returnval;
} }
protected function composePhpOptions($domain, $ssl_vhost = false)
protected function composePhpOptions($domain, $ssl_vhost = false) { {
$phpopts = ''; $phpopts = '';
if ($domain['phpenabled'] == '1') { if ($domain['phpenabled_customer'] == 1 && $domain['phpenabled_vhost'] == '1') {
$phpopts = "\tlocation ~ \.php {\n"; $phpopts = "\tlocation ~ \.php {\n";
$phpopts .= "\t\t" . 'try_files ' . $domain['nonexistinguri'] . ' @php;' . "\n"; $phpopts .= "\t\t" . 'try_files ' . $domain['nonexistinguri'] . ' @php;' . "\n";
$phpopts .= "\t" . '}' . "\n\n"; $phpopts .= "\t" . '}' . "\n\n";
@@ -866,18 +863,15 @@ class nginx extends HttpConfigBase {
$phpopts .= "\t\tfastcgi_param HTTPS on;\n"; $phpopts .= "\t\tfastcgi_param HTTPS on;\n";
} }
$phpopts .= "\t}\n\n"; $phpopts .= "\t}\n\n";
} }
return $phpopts; return $phpopts;
} }
protected function getWebroot($domain, $ssl)
protected function getWebroot($domain, $ssl) { {
$webroot_text = ''; $webroot_text = '';
if ($domain['deactivated'] == '1' if ($domain['deactivated'] == '1' && Settings::Get('system.deactivateddocroot') != '') {
&& Settings::Get('system.deactivateddocroot') != ''
) {
$webroot_text .= "\t" . '# Using docroot for deactivated users...' . "\n"; $webroot_text .= "\t" . '# Using docroot for deactivated users...' . "\n";
$webroot_text .= "\t" . 'root ' . makeCorrectDir(Settings::Get('system.deactivateddocroot')) . ';' . "\n"; $webroot_text .= "\t" . 'root ' . makeCorrectDir(Settings::Get('system.deactivateddocroot')) . ';' . "\n";
$this->_deactivated = true; $this->_deactivated = true;
@@ -888,13 +882,10 @@ class nginx extends HttpConfigBase {
$webroot_text .= "\n\t" . 'location / {' . "\n"; $webroot_text .= "\n\t" . 'location / {' . "\n";
if ($domain['phpenabled'] == '1') if ($domain['phpenabled_customer'] == 1 && $domain['phpenabled_vhost'] == '1') {
{
$webroot_text .= "\t" . 'index index.php index.html index.htm;' . "\n"; $webroot_text .= "\t" . 'index index.php index.html index.htm;' . "\n";
$webroot_text .= "\t\t" . 'try_files $uri $uri/ @rewrites;' . "\n"; $webroot_text .= "\t\t" . 'try_files $uri $uri/ @rewrites;' . "\n";
} } else {
else
{
$webroot_text .= "\t" . 'index index.html index.htm;' . "\n"; $webroot_text .= "\t" . 'index index.html index.htm;' . "\n";
} }
@@ -904,8 +895,7 @@ class nginx extends HttpConfigBase {
} }
$webroot_text .= "\t" . '}' . "\n\n"; $webroot_text .= "\t" . '}' . "\n\n";
if ($domain['phpenabled'] == '1') if ($domain['phpenabled_customer'] == 1 && $domain['phpenabled_vhost'] == '1') {
{
$webroot_text .= "\tlocation @rewrites {\n"; $webroot_text .= "\tlocation @rewrites {\n";
$webroot_text .= "\t\trewrite ^ /index.php last;\n"; $webroot_text .= "\t\trewrite ^ /index.php last;\n";
$webroot_text .= "\t}\n\n"; $webroot_text .= "\t}\n\n";
@@ -914,8 +904,8 @@ class nginx extends HttpConfigBase {
return $webroot_text; return $webroot_text;
} }
protected function getStats($domain, $single)
protected function getStats($domain, $single) { {
$stats_text = ''; $stats_text = '';
// define basic path to the stats // define basic path to the stats
@@ -955,8 +945,8 @@ class nginx extends HttpConfigBase {
return $stats_text; return $stats_text;
} }
protected function getLogFiles($domain)
protected function getLogFiles($domain) { {
$logfiles_text = ''; $logfiles_text = '';
$speciallogfile = ''; $speciallogfile = '';
@@ -993,7 +983,9 @@ class nginx extends HttpConfigBase {
FROM `" . TABLE_PANEL_DOMAINS . "` FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `aliasdomain` = :domainid OR `parentdomainid` = :domainid WHERE `aliasdomain` = :domainid OR `parentdomainid` = :domainid
"); ");
Database::pexecute($alias_domains_stmt, array('domainid' => $domain['id'])); Database::pexecute($alias_domains_stmt, array(
'domainid' => $domain['id']
));
while (($alias_domain = $alias_domains_stmt->fetch(PDO::FETCH_ASSOC)) !== false) { while (($alias_domain = $alias_domains_stmt->fetch(PDO::FETCH_ASSOC)) !== false) {
$server_alias .= ' ' . $alias_domain['domain'] . ' '; $server_alias .= ' ' . $alias_domain['domain'] . ' ';
@@ -1027,12 +1019,11 @@ class nginx extends HttpConfigBase {
return $logfiles_text; return $logfiles_text;
} }
public function createOwnVhostStarter()
{}
public function createOwnVhostStarter() { protected function getServerNames($domain)
} {
protected function getServerNames($domain) {
$server_alias = ''; $server_alias = '';
if ($domain['iswildcarddomain'] == '1') { if ($domain['iswildcarddomain'] == '1') {
@@ -1046,7 +1037,9 @@ class nginx extends HttpConfigBase {
FROM `" . TABLE_PANEL_DOMAINS . "` FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `aliasdomain` = :domainid WHERE `aliasdomain` = :domainid
"); ");
Database::pexecute($alias_domains_stmt, array('domainid' => $domain['id'])); Database::pexecute($alias_domains_stmt, array(
'domainid' => $domain['id']
));
while (($alias_domain = $alias_domains_stmt->fetch(PDO::FETCH_ASSOC)) !== false) { while (($alias_domain = $alias_domains_stmt->fetch(PDO::FETCH_ASSOC)) !== false) {
$server_alias .= ' ' . $alias_domain['domain']; $server_alias .= ' ' . $alias_domain['domain'];
@@ -1067,8 +1060,8 @@ class nginx extends HttpConfigBase {
return $servernames_text; return $servernames_text;
} }
public function writeConfigs()
public function writeConfigs() { {
$this->logger->logAction(CRON_ACTION, LOG_INFO, "nginx::writeConfigs: rebuilding " . Settings::Get('system.apacheconf_vhost')); $this->logger->logAction(CRON_ACTION, LOG_INFO, "nginx::writeConfigs: rebuilding " . Settings::Get('system.apacheconf_vhost'));
$vhostDir = new frxDirectory(Settings::Get('system.apacheconf_vhost')); $vhostDir = new frxDirectory(Settings::Get('system.apacheconf_vhost'));
@@ -1111,7 +1104,6 @@ class nginx extends HttpConfigBase {
fwrite($vhosts_file_handler, $vhosts_file); fwrite($vhosts_file_handler, $vhosts_file);
fclose($vhosts_file_handler); fclose($vhosts_file_handler);
} }
} }
} }
@@ -1138,6 +1130,4 @@ class nginx extends HttpConfigBase {
} }
} }
} }
} }

View File

@@ -20,7 +20,7 @@ class nginx_phpfpm extends nginx
protected function composePhpOptions($domain, $ssl_vhost = false) { protected function composePhpOptions($domain, $ssl_vhost = false) {
$php_options_text = ''; $php_options_text = '';
if ($domain['phpenabled'] == '1') { if ($domain['phpenabled_customer'] == 1 && $domain['phpenabled_vhost'] == '1') {
$php = new phpinterface($domain); $php = new phpinterface($domain);
$phpconfig = $php->getPhpConfig((int)$domain['phpsettingid']); $phpconfig = $php->getPhpConfig((int)$domain['phpsettingid']);

View File

@@ -86,6 +86,13 @@ if (count($all_certs) == 0) {
foreach ($all_certs as $idx => $cert) { foreach ($all_certs as $idx => $cert) {
if ($paging->checkDisplay($idx)) { if ($paging->checkDisplay($idx)) {
// respect froxlor-hostname
if ($cert['domainid'] == 0) {
$cert['domain'] = Settings::Get('system.hostname');
$cert['letsencrypt'] = Settings::Get('system.le_froxlor_enabled');
$cert['loginname'] = 'froxlor.panel';
}
if (empty($cert['domain']) || empty($cert['ssl_cert_file'])) { if (empty($cert['domain']) || empty($cert['ssl_cert_file'])) {
// no domain found to the entry or empty entry - safely delete it from the DB // no domain found to the entry or empty entry - safely delete it from the DB
Database::pexecute($del_stmt, array( Database::pexecute($del_stmt, array(
@@ -96,10 +103,10 @@ if (count($all_certs) == 0) {
$cert_data = openssl_x509_parse($cert['ssl_cert_file']); $cert_data = openssl_x509_parse($cert['ssl_cert_file']);
$cert['domain'] = $idna_convert->encode($cert['domain']); $cert['domain'] = $idna_convert->decode($cert['domain']);
$adminCustomerLink = ""; $adminCustomerLink = "";
if (AREA == 'admin') { if (AREA == 'admin' && $cert['domainid'] > 0) {
if (! empty($cert['loginname'])) { if (! empty($cert['loginname'])) {
$adminCustomerLink = '&nbsp;(<a href="' . $linker->getLink(array( $adminCustomerLink = '&nbsp;(<a href="' . $linker->getLink(array(
'section' => 'customers', 'section' => 'customers',
@@ -119,6 +126,18 @@ if (count($all_certs) == 0) {
$isValid = false; $isValid = false;
} }
$san_list = "";
if (isset($cert_data['extensions']['subjectAltName']) && !empty($cert_data['extensions']['subjectAltName'])) {
$SANs = explode(",", $cert_data['extensions']['subjectAltName']);
$SANs = array_map('trim', $SANs);
foreach ($SANs as $san) {
$san = str_replace("DNS:", "", $san);
if ($san != $cert_data['subject']['CN'] && strpos($san, "othername:") === false) {
$san_list .= $san."<br>";
}
}
}
$row = htmlentities_array($cert); $row = htmlentities_array($cert);
eval("\$certificates.=\"" . getTemplate("ssl_certificates/certs_cert", true) . "\";"); eval("\$certificates.=\"" . getTemplate("ssl_certificates/certs_cert", true) . "\";");
} else { } else {

View File

@@ -27,7 +27,7 @@ $header
<th>{$lng['admin']['ipsandports']['ip']}&nbsp;{$arrowcode['ip']}</th> <th>{$lng['admin']['ipsandports']['ip']}&nbsp;{$arrowcode['ip']}</th>
<th>{$lng['admin']['ipsandports']['port']}&nbsp;{$arrowcode['port']}</th> <th>{$lng['admin']['ipsandports']['port']}&nbsp;{$arrowcode['port']}</th>
<if !$is_nginx><th>Listen</th></if> <if !$is_nginx><th>Listen</th></if>
<if $is_apache><th>NameVirtualHost</th></if> <if $is_apache && !$is_apache24><th>NameVirtualHost</th></if>
<th>vHost-Container</th> <th>vHost-Container</th>
<th>Specialsettings</th> <th>Specialsettings</th>
<if $is_apache><th>ServerName</th></if> <if $is_apache><th>ServerName</th></if>

View File

@@ -2,7 +2,7 @@
<td>{$row['ip']}</td> <td>{$row['ip']}</td>
<td>{$row['port']}</td> <td>{$row['port']}</td>
<if !$is_nginx><td><if $row['listen_statement']=='1'>{$lng['panel']['yes']}<else>{$lng['panel']['no']}</if></td></if> <if !$is_nginx><td><if $row['listen_statement']=='1'>{$lng['panel']['yes']}<else>{$lng['panel']['no']}</if></td></if>
<if $is_apache><td><if $row['namevirtualhost_statement']=='1'>{$lng['panel']['yes']}<else>{$lng['panel']['no']}</if></td></if> <if $is_apache && !$is_apache24><td><if $row['namevirtualhost_statement']=='1'>{$lng['panel']['yes']}<else>{$lng['panel']['no']}</if></td></if>
<td><if $row['vhostcontainer']=='1'>{$lng['panel']['yes']}<else>{$lng['panel']['no']}</if></td> <td><if $row['vhostcontainer']=='1'>{$lng['panel']['yes']}<else>{$lng['panel']['no']}</if></td>
<td><if $row['specialsettings']!=''>{$lng['panel']['yes']}<else>{$lng['panel']['no']}</if></td> <td><if $row['specialsettings']!=''>{$lng['panel']['yes']}<else>{$lng['panel']['no']}</if></td>
<if $is_apache><td><if $row['vhostcontainer_servername_statement']=='1'>{$lng['panel']['yes']}<else>{$lng['panel']['no']}</if></td></if> <if $is_apache><td><if $row['vhostcontainer_servername_statement']=='1'>{$lng['panel']['yes']}<else>{$lng['panel']['no']}</if></td></if>

View File

@@ -5,6 +5,7 @@
</td> </td>
<td> <td>
{$cert_data['subject']['CN']} {$cert_data['subject']['CN']}
<if !empty($san_list)><br>SAN: {$san_list}</if>
</td> </td>
<td> <td>
{$cert_data['issuer']['O']} {$cert_data['issuer']['O']}