Compare commits

..

167 Commits

Author SHA1 Message Date
Michael Kaufmann
0398f4cdba set version to 0.10.18 for upcoming release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-06-12 15:17:09 +02:00
Michael Kaufmann
1a0953e77e fix typo in response status message, fixes #858
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-06-08 11:42:44 +02:00
Michael Kaufmann
490704f8e1 Heredoc/nowdoc with an indented closing marker is not supported in PHP 7.2 or earlier.
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-06-06 20:57:24 +02:00
Michael Kaufmann
2748f1b633 also display error when domain does not resolv to any A or AAAA record in lets-encrypt-dns-validation
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-06-06 15:37:06 +02:00
Michael Kaufmann
8e60c6b201 update api documentation for Ftps.update(), fixes #857
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-06-05 16:23:41 +02:00
Michael Kaufmann
d4716b2376 correct documentation for Customers.add(), fixes #856
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-06-05 15:33:49 +02:00
Michael Kaufmann
2c98fc4c2d fix wrong certificate folder for fallback ceck (ecc/non-ecc)
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-06-04 07:42:13 +02:00
Michael Kaufmann
65e1f633ef Merge pull request #855 from daxara/detect_distr
Auto detection in CLI & checks
2020-05-31 20:59:26 +02:00
Ante de Baas
ed4dbba278 also perform checks in Install class 2020-05-31 20:46:27 +02:00
Ante de Baas
1a6082ca91 complete if statement 2020-05-31 20:36:52 +02:00
Ante de Baas
da1d94149a saet defaults and do some checks 2020-05-31 20:34:47 +02:00
Ante de Baas
e7cfceb65d add comment 2020-05-31 20:18:37 +02:00
Ante de Baas
1f48ca4711 autodeterct distribution in CLI 2020-05-31 20:10:07 +02:00
Michael Kaufmann
fe0fb8dd5f fix non-static method called statically in \Froxlor\FileDir
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-05-31 16:38:53 +02:00
Michael Kaufmann
4a5ab7d95d Merge pull request #854 from daxara/detect_distr
fix bugs in dist detection
2020-05-31 16:36:52 +02:00
Ante de Baas
0d44adf265 fix bugs is dist detection 2020-05-31 16:00:50 +02:00
Michael Kaufmann
0b63b4e110 Merge pull request #853 from daxara/centos7
[centos7] proftp requires epel, awstats needs install and awstats cron moved
2020-05-31 15:02:57 +02:00
Michael Kaufmann
ba7e9688c5 Merge pull request #852 from daxara/centos8
Centos8 config updated
2020-05-31 15:02:31 +02:00
Ante de Baas
443ae1df68 proftp requires epel, awstats needs install and awstats cron moved 2020-05-31 14:57:07 +02:00
Ante de Baas
b59aa6f140 undo dnf -y 2020-05-31 14:28:37 +02:00
Ante de Baas
4e9df61fef awstats cron is moved to cron.hourly 2020-05-31 13:15:55 +02:00
Ante de Baas
b350815aa0 install awstats and requirements 2020-05-31 13:11:58 +02:00
Ante de Baas
b672c722b9 no user interaction on package installation 2020-05-31 13:05:52 +02:00
Ante de Baas
db60606cfa proftpd requires epel 2020-05-31 12:52:31 +02:00
Ante de Baas
2524491883 centos8 uses 'dandified yum' 2020-05-31 12:47:28 +02:00
Ante de Baas
de061e7e36 add missing apacheconf_htpasswddir dir 2020-05-31 12:46:33 +02:00
Michael Kaufmann
9ecd182a91 Merge pull request #851 from daxara/master
rename rhel7 to centos7 for consistency
2020-05-31 11:26:12 +02:00
Ante de Baas
a7934bcb7b rename rhel7 to centos7 for consistancy 2020-05-31 11:17:43 +02:00
Michael Kaufmann
9dc2c09da7 Merge pull request #850 from daxara/rhel8
Add CentOS 8 configuration-templates
2020-05-31 09:30:51 +02:00
Michael Kaufmann
b23e4a4d85 Merge pull request #849 from daxara/detect_distr
Detect distribution upon installation and set setting-defaults (if any) for that distribution
2020-05-31 09:29:42 +02:00
Michael Kaufmann
394ec4cd4a fix ecc certificate paths
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-05-31 09:13:22 +02:00
Ante de Baas
6ccfb7efbb remove old code 2020-05-30 10:10:57 +02:00
Ante de Baas
1454d8d40f get defaults from configparser 2020-05-30 10:08:05 +02:00
Ante de Baas
0fde1ce7e9 remove dev comment 2020-05-30 09:15:15 +02:00
Ante de Baas
86155f7a9c use Distribution in german language 2020-05-30 09:11:43 +02:00
Ante de Baas
60578a5d31 rename to CentOS because its most likely to be used 2020-05-29 17:46:38 +02:00
Ante de Baas
7fcacb4637 rename to centos because its most likey to be used 2020-05-29 17:45:37 +02:00
Ante de Baas
fb35fb9a3a read distribution from xml and selection via selectbox 2020-05-29 17:33:48 +02:00
Ante de Baas
6128954231 rename propery to property 2020-05-29 15:54:37 +02:00
Ante de Baas
f4d4490d08 change property tagnames 2020-05-29 15:45:04 +02:00
Ante de Baas
27f0c4eb53 remove distribution names from language files 2020-05-29 15:42:38 +02:00
Ante de Baas
cb1df3a7e0 show failue as nice red message 2020-05-29 15:29:53 +02:00
Ante de Baas
a572ac3914 add rhel8 config file 2020-05-29 15:10:06 +02:00
Ante de Baas
498ff15e98 add redhat defaults 2020-05-29 14:59:48 +02:00
Ante de Baas
022ed1a9a8 add setting defaults per distribution when given 2020-05-29 14:59:40 +02:00
Ante de Baas
814339cc73 Merge branch 'master' into detect_distr 2020-05-29 13:54:36 +02:00
Ante de Baas
0bb48a3cdf fix nginx capitalisation. 2020-05-29 13:45:46 +02:00
Ante de Baas
67d74406bd add os distribution detection 2020-05-29 13:36:31 +02:00
Michael Kaufmann
d73d8da2fd read certificate data folder from acme.sh.env file, fixes #846
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-05-28 20:08:49 +02:00
Michael Kaufmann
3c7bdcb5e0 Merge pull request #847 from Froxlor/dependabot/composer/phpmailer/phpmailer-6.1.6
Bump phpmailer/phpmailer from 6.1.4 to 6.1.6
2020-05-28 10:47:26 +02:00
dependabot[bot]
c6ac73f74f Bump phpmailer/phpmailer from 6.1.4 to 6.1.6
Bumps [phpmailer/phpmailer](https://github.com/PHPMailer/PHPMailer) from 6.1.4 to 6.1.6.
- [Release notes](https://github.com/PHPMailer/PHPMailer/releases)
- [Changelog](https://github.com/PHPMailer/PHPMailer/blob/master/changelog.md)
- [Commits](https://github.com/PHPMailer/PHPMailer/compare/v6.1.4...v6.1.6)

Signed-off-by: dependabot[bot] <support@github.com>
2020-05-27 17:01:04 +00:00
Michael Kaufmann
fdcb294244 Merge pull request #844 from daxara/dns_rhel7
Named DNS for RHEL7
2020-05-25 22:02:40 +02:00
Ante de Baas
8898c7c165 add named dns config 2020-05-25 21:38:58 +02:00
Michael Kaufmann
d4c0acb353 Merge pull request #843 from rubo77/usage
show disk-usage also on unlimited accounts
2020-05-25 09:28:37 +02:00
Ruben Barkow-Kuder
9ea32b69cb show disk-usage also on unlimited accounts
Signed-off-by: Ruben Barkow-Kuder <github@r.z11.de>
2020-05-25 03:14:38 +02:00
Michael Kaufmann
0524c70d2b add config-templates for ubuntu focal (partly tested only for now)
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-05-24 12:16:17 +02:00
Michael Kaufmann
6ca7920147 fix missing language files in config-services cli script; set ubuntu xenial deprecated, remove Ubuntu trusty; fix a2dismod command in buster config-template as php7.3 is default
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-05-24 11:55:20 +02:00
Michael Kaufmann
65b2e4efa7 do not check for mariadb.sys user on mariadb-10.4 when testing with travis
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-05-23 21:17:43 +02:00
Michael Kaufmann
7000fd2c30 Merge pull request #841 from rubo77/patch-1
Don't suggest php5 during update as default
2020-05-23 21:16:39 +02:00
Ruben Barkow-Kuder
3b1ff03b33 Don't suggest php5 during update as default 2020-05-23 20:12:27 +02:00
Michael Kaufmann
ffa9205f95 fix sql query to remove duplicates before setting unique key in updater, fixes #840
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-05-18 20:48:56 +02:00
Michael Kaufmann
bc73ed0c75 adjust tls default value to tlsv1.2; refs #839
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-05-18 20:48:04 +02:00
Michael Kaufmann
17fd350d33 Merge pull request #839 from negrusti/patch-2
TLSv1 is deprecated
2020-05-18 20:07:30 +02:00
Grigory Morozov
c2e57dfd60 TLSv1 is deprecated 2020-05-18 05:18:42 +07:00
Michael Kaufmann
50f2047da3 set version to 0.10.17 for upcoming maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-05-15 20:35:25 +02:00
Michael Kaufmann
ecb9470b65 fix including of language-strings in reports-cron, fixes #836
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-05-15 15:16:24 +02:00
Michael Kaufmann
6d90b5ba80 remove leftover GROUP BY from testing
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-05-15 09:56:24 +02:00
Michael Kaufmann
eb3590dc34 add unique-key domainid to domain_ssl_settings table
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-05-15 09:49:53 +02:00
Michael Kaufmann
bddf9b496c enable internal api-call to bypass customer_hide_options check in certain situations where it is needed, fixes #803
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-05-15 09:35:20 +02:00
Michael Kaufmann
edc702dafa check for required min version of php every time (frontend and cron), fixes #833
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-05-08 10:03:01 +02:00
Michael Kaufmann
85dfc1030a Merge pull request #832 from RipClaw2971/bugfix
Certificate file cannot be read to database
2020-05-04 16:11:42 +02:00
Andreas Grundler
c0dd432916 Certificate file cannot be read to database if the domain contains capital letters. 2020-05-04 12:08:20 +02:00
Michael Kaufmann
b3db4dd887 set version to 0.10.16 for upcoming release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-05-01 16:27:23 +02:00
Michael Kaufmann
14413a3e8d try to fix travis irc notifications again
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-04-30 20:10:52 +02:00
Michael Kaufmann
a02a081c6b try to fix travis irc notifications
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-04-30 20:03:54 +02:00
Michael Kaufmann
43070e4808 remove possible trailing slash of apache DocumentRoot diretives as sugggested by the httpd-docs, thx to jonbert
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-04-30 19:49:20 +02:00
Michael Kaufmann
98c636c282 let send-to-alternative-email be optional if no address is given instead of displaying error that the email address is invalid; fixes #829
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-04-30 13:03:19 +02:00
Michael Kaufmann
8dace6eca5 remove special characters from name when generating extrausers file
add froxlor hostname to 2fa-qrcode; refs #814

Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-04-28 07:59:37 +02:00
Michael Kaufmann
78fc4f84b2 add optional dns validation for let's encrypt activated domains; fixes #817
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-04-14 10:28:33 +02:00
Michael Kaufmann
9018404faa Double check whether installation of acme.sh worked when not installed yet and do not continue if not; fixes #823
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-04-14 08:10:36 +02:00
Michael Kaufmann
8bdd843bd9 fix renew of froxlors own letsencrypt certificate; fix only variables should be passed by reference in BackupCron; fix possible notice or double inclusion of language file in ReportsCron
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-04-08 09:07:48 +02:00
Michael Kaufmann
0d35f5cb29 restructure acmesh implementation and let acme.sh take care of renewing the certificates itself; fixes #792, fixes #816
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-04-04 18:04:39 +02:00
Michael Kaufmann
6815c1c20b Merge pull request #821 from chrschn/master
Fix renewal of ECC/ECDSA certificates.
2020-03-29 23:52:34 +02:00
Christian Schneider
048e6c13ae Fix renewal of ECC/ECDSA certificates.
The ACME v2 implementation uses separate directoies for ECC and on-ECC
certificates. The renew command for a domain checks if an ECC directory
exists (having a "_ecc" suffix) and refuses the command unless the
"--ecc" flag was specified.

Confusingly, this flag is only required to *renew* an ECC certificate,
but not to issue it.

This fixes https://github.com/Froxlor/Froxlor/issues/820.
2020-03-29 22:36:26 +02:00
Michael Kaufmann
aedb829a74 Merge pull request #819 from HBerni/hberni-p0002
fixed parsing due to changes in dovecots default mail_log_prefix
2020-03-21 17:36:00 +01:00
HBerni
4745581720 fixed parsing due to changes in dovecots default mail_log_prefix
regex supports old and new default format now
(see https://wiki2.dovecot.org/Upgrading/2.3)
2020-03-21 16:39:01 +01:00
Michael Kaufmann
489ccbe07a fix removing ip address if ip is set as system-ipaddress but there are other entries of that ip with a different port
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-03-12 07:01:26 +01:00
Michael Kaufmann
a46e7a3bc4 set correct umask to create user config in installation
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-03-10 07:48:35 +01:00
Michael Kaufmann
a4431e25d3 remove ssl-certificates connected to domains that are being deleted when deleting a customer; fixes #818
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-03-10 07:36:22 +01:00
Michael Kaufmann
1fe9f1e9d6 fix language strings for cron cmdline setting and fallback to php binary if no setting is found
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-03-08 10:30:33 +01:00
Michael Kaufmann
13767df562 set version to 0.10.15 for bugfix release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-03-08 07:39:39 +01:00
Michael Kaufmann
02c5f80854 correct chmod value for userdata.inc.php file to be written on installation; fixes #815
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-03-08 07:35:19 +01:00
Michael Kaufmann
d7550ae58a fix deactivated check in api
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-03-06 22:10:01 +01:00
Michael Kaufmann
cf2c7fa31c deny api access to deactivated users with valid api-key
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-03-06 22:03:41 +01:00
Michael Kaufmann
32b6285589 set version to 0.10.14 for upcoming release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-03-06 20:47:20 +01:00
Michael Kaufmann
7e361274c5 forgot one escapeshellarg() and enhanced security on userdata.inc.php creation when installing
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-03-06 20:44:17 +01:00
Michael Kaufmann
62ce21c9ec secure shell-execution of mysqldump on installation if given database-name exists
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-03-04 19:35:57 +01:00
Michael Kaufmann
6b09720ef8 use unpredictable tmpfile-name in installation if lib/userdata.inc.php cannot be written due to permission
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-03-04 19:34:18 +01:00
Michael Kaufmann
8807ae7dad allow private ip ranges in ips-and-ports as some configurations require that; fixes #802
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-03-02 09:51:44 +01:00
Michael Kaufmann
5f3f208534 remove superfluous comma in sql query which causes invalid sql
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-03-01 09:16:47 +01:00
Michael Kaufmann
f11ceacf89 store ace-string of domain besides idn-converted string to have correct sorting in the frontend; fixes #809
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-02-29 09:50:29 +01:00
Michael Kaufmann
26e43077c2 make customer firstname,name,company and customer-no available for all templates; fixes #808
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-02-29 08:16:55 +01:00
Michael Kaufmann
d6c8b92523 add Froxlor.integrityCheck() API call to externally run integrity/consistency check, fixes #801
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-02-15 07:30:56 +01:00
Michael Kaufmann
03450dcfa2 fix listing of customer email addresses if 'domain' section is hidden via settings, fixes #803
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-02-15 07:25:23 +01:00
Michael Kaufmann
f39aab6f32 disable sslsessiontickets-option in domain-add/edit if globally disabled in the settings
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-02-15 07:11:28 +01:00
Michael Kaufmann
7f999302fa do not require enabled vhost-container for froxlor-vhost to change sslsessiontickets-setting
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-02-14 19:26:06 +01:00
Michael Kaufmann
8294985588 require set password complexity for admins too when resetting password; display correct error message if password complexity is not satisfied
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-02-08 10:03:41 +01:00
Michael Kaufmann
a7653551b2 set version to 0.10.13 for upcoming maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-02-07 16:37:06 +01:00
Michael Kaufmann
734c02e33f update php-fpm defaults; update paths for current stable php-7.3; read froxlor default php.ini from file rather then using phpconfig with id=1; fixes #796
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-01-31 13:17:49 +01:00
Michael Kaufmann
ace18cb7c9 use correct default-versions for configuration-step to disable mod_php for debian buster and ubuntu bionic
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-01-31 12:58:04 +01:00
Michael Kaufmann
1270204cd9 fix wrongly initialized resource-usage when re-calculating it; fixes #797
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-01-31 09:49:29 +01:00
Michael Kaufmann
2831923708 Merge pull request #795 from lpedretti/master
Fixed the case that the spf record is not inserted with it's quotes, and so the condition fails and 2 spf records are inserted in the domain
2020-01-24 16:58:10 +01:00
Leonardo Pedretti
6b1ae648b4 Fixed the case that the spf record is not inserted with it's quotes, and so the condition fails and 2 spf records are inserted in the domain 2020-01-23 11:59:28 -03:00
Michael Kaufmann
6c43f1bc56 fix Domains.update() if called as admin/reseller without change_serversettings privileges, thx to rseffner
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-01-22 09:14:07 +01:00
Michael Kaufmann
2e273a41b5 fix IpsAndPorts when checking for system.ipaddress in update() and delete()
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-01-19 10:45:48 +01:00
Michael Kaufmann
2004bbe38d dont access db result arrays directly without checking whether it's false due to an error (php7.4 related)
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-01-19 10:13:28 +01:00
Michael Kaufmann
e44e07784f validate nameserver ip-addresses for binds allow-transfer block; fixes #791
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-01-19 10:08:06 +01:00
Michael Kaufmann
8d6275e1aa set version to 0.10.12 for upcoming maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-01-10 17:41:20 +01:00
Michael Kaufmann
f21d4f8770 when not using awstats, disable awstats-related settings; add minor tweaks to unit-tests
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-01-10 16:44:13 +01:00
Michael Kaufmann
fc97b4d4e9 Merge pull request #786 from patschi/logformat-awstats
Allow configuring awstats LogFormat
2020-01-10 16:32:33 +01:00
Patrik Kernstock
05051309c7 Merge branch 'master' into logformat-awstats 2020-01-09 23:24:26 +00:00
Patrik Kernstock
0f025a6627 Language file update
Signed-off-by: Patrik Kernstock <patrik@kernstock.net>
2020-01-09 23:21:11 +00:00
Michael Kaufmann
f6f5765b54 avoid settig more than one catchall address for one domain in Emails.update(), thx to mrairstone
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-01-09 14:45:51 +01:00
Michael Kaufmann
ac82aa80d2 correct logfiles_format migration; only needed if setting is non-empty
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-01-09 14:14:04 +01:00
Michael Kaufmann
57503d9c6e try to touch logfile from settings in order for is_writable to work correctly, thx to rubberduck
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-01-09 14:10:50 +01:00
Michael Kaufmann
f55ad16d82 Merge pull request #785 from patschi/logformat
Allow using more advanced webserver LogFormat
2020-01-09 09:16:03 +01:00
Patrik Kernstock
ea7834c1d1 Added small notice to lng for awstats LogFormat
Signed-off-by: Patrik Kernstock <patrik@kernstock.net>
2020-01-08 22:08:15 +00:00
Patrik Kernstock
b355711de9 Improvements as suggested by @d00p
Signed-off-by: Patrik Kernstock <patrik@kernstock.net>
2020-01-08 22:08:15 +00:00
Michael Kaufmann
a5287726a4 fix issue in PhpHelper::trimArray() returning an empty array, fixes #751
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-01-03 23:32:21 +01:00
Patrik Kernstock
b393c7d6e6 Merge branch 'master' into logformat 2020-01-03 22:32:45 +01:00
Michael Kaufmann
dd2782771a set version to 0.10.11 for upcoming maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-01-03 13:24:31 +01:00
Michael Kaufmann
25d0bbb766 switch from algo26-matthias/idna-covert to our own fork as we cannot update to >2.1 without having a minimum requirement for php-7.2 but we need a few fixes for php-7.4 support later on
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-01-03 12:48:01 +01:00
Michael Kaufmann
b4dedca3db Update README.md 2020-01-02 13:53:22 +01:00
Patrik Kernstock
09aed61dbf Merge branch 'master' into logformat-awstats 2020-01-02 12:44:35 +01:00
Patrik Kernstock
ca39501530 Fixed awstats_logformat field for new installs
Signed-off-by: Patrik Kernstock <patrik@kernstock.net>
2020-01-02 12:39:25 +01:00
Patrik Kernstock
28fd88e53e Merge branch 'master' into logformat 2020-01-02 12:31:51 +01:00
Michael Kaufmann
e01c2e02fb fix update query for new fpm-custom_config value, refs #783
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-01-02 12:28:48 +01:00
Michael Kaufmann
762bfae61a Merge pull request #783 from patschi/phpfpm-custom-settings
Ability to add custom config to PHPFPM version
2020-01-02 10:19:19 +01:00
Patrik Kernstock
a4d4e16efc Small comment added to escaping double-quote
Signed-off-by: Patrik Kernstock <patrik@kernstock.net>
2019-12-31 22:46:03 +01:00
Patrik Kernstock
7f83ad31f4 Fixed dbversion in SQL/Froxlor.php
Signed-off-by: Patrik Kernstock <patrik@kernstock.net>
2019-12-31 22:30:54 +01:00
Patrik Kernstock
e143ba4577 Allow configuring awstats LogFormat
Signed-off-by: Patrik Kernstock <patrik@kernstock.net>
2019-12-31 22:29:29 +01:00
Patrik Kernstock
6799a56ba1 Allow using more advanced LogFormat
Signed-off-by: Patrik Kernstock <patrik@kernstock.net>
2019-12-31 20:18:52 +01:00
Patrik Kernstock
484fe8acbc Fixed db_DBVERISON in Froxlor.php
Signed-off-by: Patrik Kernstock <patrik@kernstock.net>
2019-12-31 17:22:37 +01:00
Patrik Kernstock
550af5b943 Fixed german lng, fixed db_version in SQL
Signed-off-by: Patrik Kernstock <patrik@kernstock.net>
2019-12-31 17:18:17 +01:00
Patrik Kernstock
7ae59477af New update step, changed order of lang strings
Signed-off-by: Patrik Kernstock <patrik@kernstock.net>
2019-12-31 16:14:26 +01:00
Michael Kaufmann
acefa41806 Merge pull request #781 from patschi/accesslog-logtype
Use logtype for access_log for IPsAndPorts too
2019-12-31 16:01:42 +01:00
Patrik Kernstock
b39c8029cd Merge branch 'master' into phpfpm-custom-settings 2019-12-31 15:51:27 +01:00
Patrik Kernstock
69ff416361 Fixed SQL, minor comments/lng updates
Signed-off-by: Patrik Kernstock <patrik@kernstock.net>
2019-12-31 15:34:46 +01:00
Michael Kaufmann
3eb1718fe0 add option to disable SSL sessiontickets globally for older systems, fixes #784
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-12-31 12:27:35 +01:00
Michael Kaufmann
37c434d4fc testsystem does not listen on socket for mysql
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-12-31 09:29:09 +01:00
Michael Kaufmann
1eb14d7564 update composer-dependencies; add connection-test to Mysqls.update() when changing passwords; validate ssl-certificates to avoid private/public key mismatch and a failed webserver start, fixes #778
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-12-31 09:23:28 +01:00
Michael Kaufmann
1c17df69d2 Merge pull request #782 from patschi/fix-dhparams-indent
Fix dhparam indent
2019-12-31 08:11:40 +01:00
Patrik Kernstock
c61b3b73bd Ability to add custom config to PHPFPM version
Addresses #643

Signed-off-by: Patrik Kernstock <patrik@kernstock.net>
2019-12-31 05:48:36 +01:00
Patrik Kernstock
18c87baec8 Fix dhparam indent 2019-12-31 03:53:12 +01:00
Patrik Kernstock
631b2b59a5 Use logtype for access_log for IPsAndPorts too 2019-12-31 03:51:19 +01:00
Michael Kaufmann
1e0510a43d fix SysLog.delete(), SysLog.listing() and SysLog.listingCount() when called as admin/reseller withouth customers_see_all permission
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-12-21 15:12:51 +01:00
Michael Kaufmann
e62f675c4c apply 'notryfiles', 'writeaccesslog' and 'writeerrorlog' flags to subdomains when editing a domain
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-12-18 08:44:02 +01:00
Michael Kaufmann
fe389ab208 setting version to 0.10.10 for upcoming maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-12-13 16:23:43 +01:00
Michael Kaufmann
63d915804a lowercase domainnames when adding new (sub)domain to avoid issues with certificates on filesystem
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-12-11 20:12:51 +01:00
Michael Kaufmann
466c09137b add new 'ssl-enabled' flag for domains and subdomains so ssl can be deactivated (by a customer too) even if there are ssl-ip/ports assigned; introduce new honorcipherorder and sessiontickets flags for more control over ssl-related settings on a per domain base (admin only); fixes #767 and fixes #769
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-12-10 10:21:35 +01:00
Michael Kaufmann
3a738b7070 fix mysql8 issue with group by and sorting within; fixes #774
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-12-08 10:43:12 +01:00
Michael Kaufmann
5ee9d3064a add new API function Froxlor.generatePassword() to return a random password based on froxlor settings regarding min-length, included characters, etc.; fixes #768
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-12-06 11:51:40 +01:00
Michael Kaufmann
adb5c6734a set version to 0.10.9 for upcoming maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-12-06 10:20:01 +01:00
Michael Kaufmann
7dff46b63e set production Lets Encrypt endpoint as default in settings like the installation does; do nat-sorting only on username-related fields, fixes #765
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-12-05 07:52:11 +01:00
Michael Kaufmann
12883bafd6 check for valid result when reading database usage from information_schema; fixes #766
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-12-04 07:15:28 +01:00
Michael Kaufmann
c2b88200f0 Merge pull request #763 from RipClaw2971/bugfix
SQL error in lib/Froxlor/Api/Commands/Certificates.php
2019-11-29 19:52:13 +01:00
Andreas Grundler
634199780b Bugfix 2019-11-29 19:22:43 +01:00
119 changed files with 9208 additions and 2808 deletions

View File

@@ -1,4 +0,0 @@
codecov:
notify:
require_ci_to_pass: no

View File

@@ -52,13 +52,10 @@ install:
- mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI froxlor010 < install/froxlor.sql
script:
- ant phpunit
after_success:
- bash <(curl -s https://codecov.io/bash) -f "build/logs/clover.xml"
- ant phpunit-no-coverage
notifications:
irc: "irc.freenode.org#froxlor"
irc: "chat.freenode.net#froxlor"
webhooks:
urls:
- https://webhooks.gitter.im/e/bdf91d1c3f745e51f796

View File

@@ -38,7 +38,7 @@ if (AREA == 'admin') {
}
$success_message = "";
$tfa = new \Froxlor\FroxlorTwoFactorAuth('Froxlor');
$tfa = new \Froxlor\FroxlorTwoFactorAuth('Froxlor ' . Settings::Get('system.hostname'));
// do the delete and then just show a success-message
if ($action == 'delete') {

View File

@@ -53,14 +53,21 @@ https://files.froxlor.org/releases/froxlor-latest.tar.gz [MD5](https://files.fro
[HowTo](https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-on-debian)
/etc/apt/sources.list.d/froxlor.list
> deb http://debian.froxlor.org {stretch|buster} main
```
apt-get -y install apt-transport-https lsb-release ca-certificates
wget -O - https://deb.froxlor.org/froxlor.gpg | apt-key add -
echo "deb https://deb.froxlor.org/debian $(lsb_release -sc) main" > /etc/apt/sources.list.d/froxlor.list
```
### Gentoo repository
### Ubuntu repository
[HowTo](https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-on-gentoo)
[HowTo](https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-on-ubuntu)
https://files.froxlor.org/gentoo/repositories.xml
```
apt-get -y install apt-transport-https lsb-release ca-certificates
wget -O - https://deb.froxlor.org/froxlor.gpg | apt-key add -
echo "deb https://deb.froxlor.org/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/froxlor.list
```
## Contributing

View File

@@ -105,6 +105,30 @@ return array(
'hasVhostContainerEnabled'
), true)
),
'system_honorcipherorder' => array(
'label' => $lng['admin']['domain_honorcipherorder'],
'settinggroup' => 'system',
'varname' => 'honorcipherorder',
'type' => 'bool',
'default' => false,
'save_method' => 'storeSettingField',
'visible' => \Froxlor\Settings::Get('system.use_ssl') && call_user_func(array(
'\Froxlor\Settings\FroxlorVhostSettings',
'hasVhostContainerEnabled'
), true)
),
'system_sessiontickets' => array(
'label' => $lng['admin']['domain_sessiontickets'],
'settinggroup' => 'system',
'varname' => 'sessiontickets',
'type' => 'bool',
'default' => true,
'save_method' => 'storeSettingField',
'visible' => \Froxlor\Settings::Get('system.use_ssl') && call_user_func(array(
'\Froxlor\Settings\FroxlorVhostSettings',
'hasVhostContainerEnabled'
), true)
),
/**
* FCGID
*/

View File

@@ -173,7 +173,8 @@ return array(
'websrv_avail' => array(
'apache2',
'nginx'
)
),
'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 1
),
'system_logfiles_type' => array(
'label' => $lng['serversettings']['logfiles_type'],

View File

@@ -35,7 +35,7 @@ return array(
'settinggroup' => 'system',
'varname' => 'ssl_protocols',
'type' => 'option',
'default' => 'TLSv1,TLSv1.2',
'default' => 'TLSv1.2',
'option_mode' => 'multiple',
'option_options' => array(
'TLSv1' => 'TLSv1',
@@ -62,7 +62,7 @@ return array(
'string_emptyallowed' => true,
'default' => '',
'visible' => \Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1,
'save_method' => 'storeSettingField',
'save_method' => 'storeSettingField'
),
'system_ssl_cert_file' => array(
'label' => $lng['serversettings']['ssl']['ssl_cert_file'],
@@ -115,6 +115,15 @@ return array(
'visible' => \Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1,
'save_method' => 'storeSettingField'
),
'system_sessionticketsenabled' => array(
'label' => $lng['admin']['domain_sessionticketsenabled'],
'settinggroup' => 'system',
'varname' => 'sessionticketsenabled',
'type' => 'bool',
'default' => true,
'save_method' => 'storeSettingField',
'visible' => \Froxlor\Settings::Get('system.use_ssl') && (\Froxlor\Settings::Get('system.webserver') == "nginx" || (\Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1))
),
'system_leenabled' => array(
'label' => $lng['serversettings']['leenabled'],
'settinggroup' => 'system',
@@ -150,10 +159,10 @@ return array(
'settinggroup' => 'system',
'varname' => 'letsencryptca',
'type' => 'option',
'default' => 'testing',
'default' => 'production',
'option_mode' => 'one',
'option_options' => array(
'testing' => 'https://acme-staging' . (\Froxlor\Settings::Get('system.leapiversion') == '2' ? '-v02' : '') . '.api.letsencrypt.org (Test)',
'testing' => 'https://acme-staging-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org (Test)',
'production' => 'https://acme-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org (Live)'
),
'save_method' => 'storeSettingField'
@@ -205,11 +214,11 @@ return array(
'save_method' => 'storeSettingField'
),
'system_disable_le_selfcheck' => array(
'label' => $lng['serversettings']['disable_le_selfcheck'],
'label' => $lng['serversettings']['le_domain_dnscheck'],
'settinggroup' => 'system',
'varname' => 'disable_le_selfcheck',
'varname' => 'le_domain_dnscheck',
'type' => 'bool',
'default' => false,
'default' => true,
'save_method' => 'storeSettingField'
)
)

View File

@@ -33,7 +33,8 @@ return array(
1 => $lng['admin']['webalizer']['quiet'],
2 => $lng['admin']['webalizer']['veryquiet']
),
'save_method' => 'storeSettingField'
'save_method' => 'storeSettingField',
'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 0
),
'system_awstats_enabled' => array(
'label' => $lng['serversettings']['awstats_enabled'],
@@ -50,7 +51,8 @@ return array(
'type' => 'string',
'string_type' => 'dir',
'default' => '/usr/bin/',
'save_method' => 'storeSettingField'
'save_method' => 'storeSettingField',
'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 1
),
'system_awstats_awstatspath' => array(
'label' => $lng['serversettings']['awstats_awstatspath'],
@@ -59,7 +61,8 @@ return array(
'type' => 'string',
'string_type' => 'dir',
'default' => '/usr/bin/',
'save_method' => 'storeSettingField'
'save_method' => 'storeSettingField',
'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 1
),
'system_awstats_conf' => array(
'label' => $lng['serversettings']['awstats_conf'],
@@ -68,7 +71,8 @@ return array(
'type' => 'string',
'string_type' => 'dir',
'default' => '/etc/awstats/',
'save_method' => 'storeSettingField'
'save_method' => 'storeSettingField',
'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 1
),
'system_awstats_icons' => array(
'label' => $lng['serversettings']['awstats_icons'],
@@ -77,7 +81,17 @@ return array(
'type' => 'string',
'string_type' => 'dir',
'default' => '/usr/share/awstats/icon/',
'save_method' => 'storeSettingField'
'save_method' => 'storeSettingField',
'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 1
),
'system_awstats_logformat' => array(
'label' => $lng['serversettings']['awstats']['logformat'],
'settinggroup' => 'system',
'varname' => 'awstats_logformat',
'type' => 'string',
'default' => '1',
'save_method' => 'storeSettingField',
'visible' => \Froxlor\Settings::Get('system.awstats_enabled') == 1
)
)
)

View File

@@ -39,7 +39,7 @@ if ($page == 'domains' || $page == 'overview') {
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_domains");
$fields = array(
'd.domain' => $lng['domains']['domainname'],
'd.domain_ace' => $lng['domains']['domainname'],
'c.name' => $lng['customer']['name'],
'c.firstname' => $lng['customer']['firstname'],
'c.company' => $lng['customer']['company'],

View File

@@ -160,5 +160,14 @@ if ($page == 'ipsandports' || $page == 'overview') {
eval("echo \"" . \Froxlor\UI\Template::getTemplate("ipsandports/ipsandports_edit") . "\";");
}
}
} elseif ($action == 'jqCheckIP') {
$ip = $_POST['ip'] ?? "";
if ((filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) || filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) && filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE) == false) {
// returns notice if private network detected so we can display it
echo json_encode($lng['admin']['ipsandports']['ipnote']);
} else {
echo 0;
}
exit();
}
}

View File

@@ -81,8 +81,16 @@ if ($page == 'overview') {
));
} else {
$result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "` WHERE `id` = 1");
$result = $result_stmt->fetch(PDO::FETCH_ASSOC);
if (file_exists(\Froxlor\Froxlor::getInstallDir() . '/templates/misc/php/default.ini.php')) {
require_once \Froxlor\Froxlor::getInstallDir() . '/templates/misc/php/default.ini.php';
$result = [
'phpsettings' => DEFAULT_PHPINI
];
} else {
// use first php-config as fallback
$result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_PHPCONFIGS . "` WHERE `id` = 1");
$result = $result_stmt->fetch(PDO::FETCH_ASSOC);
}
$fpmconfigs = '';
$configs = Database::query("SELECT * FROM `" . TABLE_PANEL_FPMDAEMONS . "` ORDER BY `description` ASC");
@@ -90,9 +98,9 @@ if ($page == 'overview') {
$fpmconfigs .= \Froxlor\UI\HTML::makeoption($row['description'], $row['id'], 1, true, true);
}
$pm_select = \Froxlor\UI\HTML::makeoption('static', 'static', 'static', true, true);
$pm_select .= \Froxlor\UI\HTML::makeoption('dynamic', 'dynamic', 'static', true, true);
$pm_select .= \Froxlor\UI\HTML::makeoption('ondemand', 'ondemand', 'static', true, true);
$pm_select = \Froxlor\UI\HTML::makeoption('static', 'static', 'dynamic', true, true);
$pm_select .= \Froxlor\UI\HTML::makeoption('dynamic', 'dynamic', 'dynamic', true, true);
$pm_select .= \Froxlor\UI\HTML::makeoption('ondemand', 'ondemand', 'dynamic', true, true);
$phpconfig_add_data = include_once dirname(__FILE__) . '/lib/formfields/admin/phpconfig/formfield.phpconfig_add.php';
$phpconfig_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($phpconfig_add_data);
@@ -234,9 +242,9 @@ if ($page == 'overview') {
));
} else {
$pm_select = \Froxlor\UI\HTML::makeoption('static', 'static', 'static', true, true);
$pm_select .= \Froxlor\UI\HTML::makeoption('dynamic', 'dynamic', 'static', true, true);
$pm_select .= \Froxlor\UI\HTML::makeoption('ondemand', 'ondemand', 'static', true, true);
$pm_select = \Froxlor\UI\HTML::makeoption('static', 'static', 'dynamic', true, true);
$pm_select .= \Froxlor\UI\HTML::makeoption('dynamic', 'dynamic', 'dynamic', true, true);
$pm_select .= \Froxlor\UI\HTML::makeoption('ondemand', 'ondemand', 'dynamic', true, true);
$fpmconfig_add_data = include_once dirname(__FILE__) . '/lib/formfields/admin/phpconfig/formfield.fpmconfig_add.php';
$fpmconfig_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($fpmconfig_add_data);

View File

@@ -46,7 +46,7 @@
"phpmailer/phpmailer": "~6.0",
"monolog/monolog": "^1.24",
"robthree/twofactorauth": "^1.6",
"algo26-matthias/idna-convert": "^2.1"
"froxlor/idna-convert-legacy": "^2.1"
},
"require-dev": {
"phpunit/phpunit": "8.4.1",

417
composer.lock generated
View File

@@ -4,20 +4,20 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "5699c65bbdcd2a61a9ced0ac7be84d64",
"content-hash": "a7ba15333ffb4a758ea65039b589545b",
"packages": [
{
"name": "algo26-matthias/idna-convert",
"version": "v2.1.0",
"name": "froxlor/idna-convert-legacy",
"version": "v2.1.2",
"source": {
"type": "git",
"url": "https://github.com/algo26-matthias/idna-convert.git",
"reference": "2717d05713454991936bc581d068c6cea0d84e3b"
"url": "https://github.com/Froxlor/idna-convert-legacy.git",
"reference": "09c1db623ba19e1ed8f2f9dabc15eeda9dc713b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/algo26-matthias/idna-convert/zipball/2717d05713454991936bc581d068c6cea0d84e3b",
"reference": "2717d05713454991936bc581d068c6cea0d84e3b",
"url": "https://api.github.com/repos/Froxlor/idna-convert-legacy/zipball/09c1db623ba19e1ed8f2f9dabc15eeda9dc713b7",
"reference": "09c1db623ba19e1ed8f2f9dabc15eeda9dc713b7",
"shasum": ""
},
"require": {
@@ -43,6 +43,11 @@
"name": "Matthias Sommerfeld",
"email": "matthias.sommerfeld@algo26.de",
"role": "Developer"
},
{
"name": "Michael Kaufmann (d00p)",
"email": "d00p@froxlor.org",
"role": "Developer"
}
],
"description": "A library for encoding and decoding internationalized domain names",
@@ -52,20 +57,20 @@
"idna",
"php"
],
"time": "2019-03-04T17:07:46+00:00"
"time": "2019-12-31T12:16:30+00:00"
},
{
"name": "monolog/monolog",
"version": "1.25.1",
"version": "1.25.3",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "70e65a5470a42cfec1a7da00d30edb6e617e8dcf"
"reference": "fa82921994db851a8becaf3787a9e73c5976b6f1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/70e65a5470a42cfec1a7da00d30edb6e617e8dcf",
"reference": "70e65a5470a42cfec1a7da00d30edb6e617e8dcf",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/fa82921994db851a8becaf3787a9e73c5976b6f1",
"reference": "fa82921994db851a8becaf3787a9e73c5976b6f1",
"shasum": ""
},
"require": {
@@ -130,20 +135,20 @@
"logging",
"psr-3"
],
"time": "2019-09-06T13:49:17+00:00"
"time": "2019-12-20T14:15:16+00:00"
},
{
"name": "phpmailer/phpmailer",
"version": "v6.1.1",
"version": "v6.1.6",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "26bd96350b0b2fcbf0ef4e6f0f9cf3528302a9d8"
"reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/26bd96350b0b2fcbf0ef4e6f0f9cf3528302a9d8",
"reference": "26bd96350b0b2fcbf0ef4e6f0f9cf3528302a9d8",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3",
"reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3",
"shasum": ""
},
"require": {
@@ -152,13 +157,9 @@
"php": ">=5.5.0"
},
"require-dev": {
"doctrine/annotations": "1.2.*",
"doctrine/annotations": "^1.2",
"friendsofphp/php-cs-fixer": "^2.2",
"phpdocumentor/phpdocumentor": "2.*",
"phpunit/phpunit": "^4.8 || ^5.7",
"zendframework/zend-eventmanager": "3.0.*",
"zendframework/zend-i18n": "2.7.3",
"zendframework/zend-serializer": "2.7.*"
"phpunit/phpunit": "^4.8 || ^5.7"
},
"suggest": {
"ext-mbstring": "Needed to send email in multibyte encoding charset",
@@ -196,7 +197,7 @@
}
],
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"time": "2019-09-27T21:33:43+00:00"
"time": "2020-05-27T12:24:03+00:00"
},
{
"name": "psr/log",
@@ -299,17 +300,61 @@
],
"packages-dev": [
{
"name": "doctrine/instantiator",
"version": "1.2.0",
"name": "composer/xdebug-handler",
"version": "1.4.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
"reference": "a2c590166b2133a4633738648b6b064edae0814a"
"url": "https://github.com/composer/xdebug-handler.git",
"reference": "cbe23383749496fe0f373345208b79568e4bc248"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a",
"reference": "a2c590166b2133a4633738648b6b064edae0814a",
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/cbe23383749496fe0f373345208b79568e4bc248",
"reference": "cbe23383749496fe0f373345208b79568e4bc248",
"shasum": ""
},
"require": {
"php": "^5.3.2 || ^7.0 || ^8.0",
"psr/log": "^1.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8"
},
"type": "library",
"autoload": {
"psr-4": {
"Composer\\XdebugHandler\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "John Stevenson",
"email": "john-stevenson@blueyonder.co.uk"
}
],
"description": "Restarts a process without Xdebug.",
"keywords": [
"Xdebug",
"performance"
],
"time": "2019-11-06T16:40:04+00:00"
},
{
"name": "doctrine/instantiator",
"version": "1.3.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
"reference": "ae466f726242e637cebdd526a7d991b9433bacf1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1",
"reference": "ae466f726242e637cebdd526a7d991b9433bacf1",
"shasum": ""
},
"require": {
@@ -352,20 +397,20 @@
"constructor",
"instantiate"
],
"time": "2019-03-17T17:37:11+00:00"
"time": "2019-10-21T16:45:58+00:00"
},
{
"name": "myclabs/deep-copy",
"version": "1.9.3",
"version": "1.9.4",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea"
"reference": "579bb7356d91f9456ccd505f24ca8b667966a0a7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea",
"reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/579bb7356d91f9456ccd505f24ca8b667966a0a7",
"reference": "579bb7356d91f9456ccd505f24ca8b667966a0a7",
"shasum": ""
},
"require": {
@@ -400,20 +445,20 @@
"object",
"object graph"
],
"time": "2019-08-09T12:45:53+00:00"
"time": "2019-12-15T19:12:40+00:00"
},
{
"name": "nikic/php-parser",
"version": "v4.2.5",
"version": "v4.3.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "b76bbc3c51f22c570648de48e8c2d941ed5e2cf2"
"reference": "9a9981c347c5c49d6dfe5cf826bb882b824080dc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/b76bbc3c51f22c570648de48e8c2d941ed5e2cf2",
"reference": "b76bbc3c51f22c570648de48e8c2d941ed5e2cf2",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/9a9981c347c5c49d6dfe5cf826bb882b824080dc",
"reference": "9a9981c347c5c49d6dfe5cf826bb882b824080dc",
"shasum": ""
},
"require": {
@@ -421,7 +466,7 @@
"php": ">=7.0"
},
"require-dev": {
"ircmaxell/php-yacc": "0.0.4",
"ircmaxell/php-yacc": "0.0.5",
"phpunit/phpunit": "^6.5 || ^7.0 || ^8.0"
},
"bin": [
@@ -430,7 +475,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.2-dev"
"dev-master": "4.3-dev"
}
},
"autoload": {
@@ -452,36 +497,43 @@
"parser",
"php"
],
"time": "2019-10-25T18:33:07+00:00"
"time": "2019-11-08T13:50:10+00:00"
},
{
"name": "pdepend/pdepend",
"version": "2.5.2",
"version": "2.6.1",
"source": {
"type": "git",
"url": "https://github.com/pdepend/pdepend.git",
"reference": "9daf26d0368d4a12bed1cacae1a9f3a6f0adf239"
"reference": "395b0f356bc0881ef88864bffb4ba1423ca0d111"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pdepend/pdepend/zipball/9daf26d0368d4a12bed1cacae1a9f3a6f0adf239",
"reference": "9daf26d0368d4a12bed1cacae1a9f3a6f0adf239",
"url": "https://api.github.com/repos/pdepend/pdepend/zipball/395b0f356bc0881ef88864bffb4ba1423ca0d111",
"reference": "395b0f356bc0881ef88864bffb4ba1423ca0d111",
"shasum": ""
},
"require": {
"php": ">=5.3.7",
"symfony/config": "^2.3.0|^3|^4",
"symfony/dependency-injection": "^2.3.0|^3|^4",
"symfony/filesystem": "^2.3.0|^3|^4"
"symfony/config": "^2.3.0|^3|^4|^5",
"symfony/dependency-injection": "^2.3.0|^3|^4|^5",
"symfony/filesystem": "^2.3.0|^3|^4|^5"
},
"require-dev": {
"phpunit/phpunit": "^4.8|^5.7",
"easy-doc/easy-doc": "0.0.0 || ^1.2.3",
"gregwar/rst": "^1.0",
"phpunit/phpunit": "^4.8.35|^5.7",
"squizlabs/php_codesniffer": "^2.0.0"
},
"bin": [
"src/bin/pdepend"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.x-dev"
}
},
"autoload": {
"psr-4": {
"PDepend\\": "src/main/php/PDepend"
@@ -492,7 +544,7 @@
"BSD-3-Clause"
],
"description": "Official version of pdepend to be handled with Composer",
"time": "2017-12-13T13:21:38+00:00"
"time": "2019-12-21T16:33:56+00:00"
},
{
"name": "phar-io/manifest",
@@ -598,16 +650,16 @@
},
{
"name": "phpcompatibility/php-compatibility",
"version": "9.3.2",
"version": "9.3.5",
"source": {
"type": "git",
"url": "https://github.com/PHPCompatibility/PHPCompatibility.git",
"reference": "bfca2be3992f40e92206e5a7ebe5eaee37280b58"
"reference": "9fb324479acf6f39452e0655d2429cc0d3914243"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/bfca2be3992f40e92206e5a7ebe5eaee37280b58",
"reference": "bfca2be3992f40e92206e5a7ebe5eaee37280b58",
"url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243",
"reference": "9fb324479acf6f39452e0655d2429cc0d3914243",
"shasum": ""
},
"require": {
@@ -652,7 +704,7 @@
"phpcs",
"standards"
],
"time": "2019-10-16T21:24:24+00:00"
"time": "2019-12-27T09:44:58+00:00"
},
{
"name": "phpdocumentor/reflection-common",
@@ -708,16 +760,16 @@
},
{
"name": "phpdocumentor/reflection-docblock",
"version": "4.3.2",
"version": "4.3.4",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
"reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e"
"reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e",
"reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/da3fd972d6bafd628114f7e7e036f45944b62e9c",
"reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c",
"shasum": ""
},
"require": {
@@ -729,6 +781,7 @@
"require-dev": {
"doctrine/instantiator": "^1.0.5",
"mockery/mockery": "^1.0",
"phpdocumentor/type-resolver": "0.4.*",
"phpunit/phpunit": "^6.4"
},
"type": "library",
@@ -755,7 +808,7 @@
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"time": "2019-09-12T14:27:41+00:00"
"time": "2019-12-28T18:55:12+00:00"
},
{
"name": "phpdocumentor/type-resolver",
@@ -855,24 +908,26 @@
},
{
"name": "phpmd/phpmd",
"version": "2.7.0",
"version": "2.8.1",
"source": {
"type": "git",
"url": "https://github.com/phpmd/phpmd.git",
"reference": "a05a999c644f4bc9a204846017db7bb7809fbe4c"
"reference": "5664b95d484797582f5af9536238deb9ecde58a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpmd/phpmd/zipball/a05a999c644f4bc9a204846017db7bb7809fbe4c",
"reference": "a05a999c644f4bc9a204846017db7bb7809fbe4c",
"url": "https://api.github.com/repos/phpmd/phpmd/zipball/5664b95d484797582f5af9536238deb9ecde58a1",
"reference": "5664b95d484797582f5af9536238deb9ecde58a1",
"shasum": ""
},
"require": {
"composer/xdebug-handler": "^1.0",
"ext-xml": "*",
"pdepend/pdepend": "^2.5",
"pdepend/pdepend": "^2.6",
"php": ">=5.3.9"
},
"require-dev": {
"easy-doc/easy-doc": "0.0.0 || ^1.3.2",
"gregwar/rst": "^1.0",
"mikey179/vfsstream": "^1.6.4",
"phpunit/phpunit": "^4.8.36 || ^5.7.27",
@@ -919,37 +974,37 @@
"phpmd",
"pmd"
],
"time": "2019-07-30T21:13:32+00:00"
"time": "2019-12-27T11:09:06+00:00"
},
{
"name": "phpspec/prophecy",
"version": "1.9.0",
"version": "1.10.1",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203"
"reference": "cbe1df668b3fe136bcc909126a0f529a78d4cbbc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/f6811d96d97bdf400077a0cc100ae56aa32b9203",
"reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/cbe1df668b3fe136bcc909126a0f529a78d4cbbc",
"reference": "cbe1df668b3fe136bcc909126a0f529a78d4cbbc",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.0.2",
"php": "^5.3|^7.0",
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0",
"sebastian/comparator": "^1.1|^2.0|^3.0",
"sebastian/comparator": "^1.2.3|^2.0|^3.0",
"sebastian/recursion-context": "^1.0|^2.0|^3.0"
},
"require-dev": {
"phpspec/phpspec": "^2.5|^3.2",
"phpspec/phpspec": "^2.5 || ^3.2",
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.8.x-dev"
"dev-master": "1.10.x-dev"
}
},
"autoload": {
@@ -982,20 +1037,20 @@
"spy",
"stub"
],
"time": "2019-10-03T11:07:50+00:00"
"time": "2019-12-22T21:05:45+00:00"
},
{
"name": "phpunit/php-code-coverage",
"version": "7.0.8",
"version": "7.0.10",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "aa0d179a13284c7420fc281fc32750e6cc7c9e2f"
"reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa0d179a13284c7420fc281fc32750e6cc7c9e2f",
"reference": "aa0d179a13284c7420fc281fc32750e6cc7c9e2f",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f1884187926fbb755a9aaf0b3836ad3165b478bf",
"reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf",
"shasum": ""
},
"require": {
@@ -1045,7 +1100,7 @@
"testing",
"xunit"
],
"time": "2019-09-17T06:24:36+00:00"
"time": "2019-11-20T13:55:58+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -1535,16 +1590,16 @@
},
{
"name": "sebastian/environment",
"version": "4.2.2",
"version": "4.2.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/environment.git",
"reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404"
"reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/f2a2c8e1c97c11ace607a7a667d73d47c19fe404",
"reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404",
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368",
"reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368",
"shasum": ""
},
"require": {
@@ -1584,7 +1639,7 @@
"environment",
"hhvm"
],
"time": "2019-05-05T09:05:15+00:00"
"time": "2019-11-20T08:46:58+00:00"
},
{
"name": "sebastian/exporter",
@@ -2075,16 +2130,16 @@
},
{
"name": "squizlabs/php_codesniffer",
"version": "3.5.2",
"version": "3.5.3",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
"reference": "65b12cdeaaa6cd276d4c3033a95b9b88b12701e7"
"reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/65b12cdeaaa6cd276d4c3033a95b9b88b12701e7",
"reference": "65b12cdeaaa6cd276d4c3033a95b9b88b12701e7",
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/557a1fc7ac702c66b0bbfe16ab3d55839ef724cb",
"reference": "557a1fc7ac702c66b0bbfe16ab3d55839ef724cb",
"shasum": ""
},
"require": {
@@ -2122,36 +2177,36 @@
"phpcs",
"standards"
],
"time": "2019-10-28T04:36:32+00:00"
"time": "2019-12-04T04:46:47+00:00"
},
{
"name": "symfony/config",
"version": "v4.3.6",
"version": "v5.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
"reference": "f4ee0ebb91b16ca1ac105aa39f9284f3cac19a15"
"reference": "7f930484966350906185ba0a604728f7898b7ba0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/config/zipball/f4ee0ebb91b16ca1ac105aa39f9284f3cac19a15",
"reference": "f4ee0ebb91b16ca1ac105aa39f9284f3cac19a15",
"url": "https://api.github.com/repos/symfony/config/zipball/7f930484966350906185ba0a604728f7898b7ba0",
"reference": "7f930484966350906185ba0a604728f7898b7ba0",
"shasum": ""
},
"require": {
"php": "^7.1.3",
"symfony/filesystem": "~3.4|~4.0",
"php": "^7.2.5",
"symfony/filesystem": "^4.4|^5.0",
"symfony/polyfill-ctype": "~1.8"
},
"conflict": {
"symfony/finder": "<3.4"
"symfony/finder": "<4.4"
},
"require-dev": {
"symfony/dependency-injection": "~3.4|~4.0",
"symfony/event-dispatcher": "~3.4|~4.0",
"symfony/finder": "~3.4|~4.0",
"symfony/messenger": "~4.1",
"symfony/yaml": "~3.4|~4.0"
"symfony/event-dispatcher": "^4.4|^5.0",
"symfony/finder": "^4.4|^5.0",
"symfony/messenger": "^4.4|^5.0",
"symfony/service-contracts": "^1.1|^2",
"symfony/yaml": "^4.4|^5.0"
},
"suggest": {
"symfony/yaml": "To use the yaml reference dumper"
@@ -2159,7 +2214,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.3-dev"
"dev-master": "5.0-dev"
}
},
"autoload": {
@@ -2186,31 +2241,32 @@
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
"time": "2019-10-30T13:18:51+00:00"
"time": "2019-12-18T13:50:31+00:00"
},
{
"name": "symfony/console",
"version": "v4.3.6",
"version": "v4.4.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "136c4bd62ea871d00843d1bc0316de4c4a84bb78"
"reference": "82437719dab1e6bdd28726af14cb345c2ec816d0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/136c4bd62ea871d00843d1bc0316de4c4a84bb78",
"reference": "136c4bd62ea871d00843d1bc0316de4c4a84bb78",
"url": "https://api.github.com/repos/symfony/console/zipball/82437719dab1e6bdd28726af14cb345c2ec816d0",
"reference": "82437719dab1e6bdd28726af14cb345c2ec816d0",
"shasum": ""
},
"require": {
"php": "^7.1.3",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php73": "^1.8",
"symfony/service-contracts": "^1.1"
"symfony/service-contracts": "^1.1|^2"
},
"conflict": {
"symfony/dependency-injection": "<3.4",
"symfony/event-dispatcher": "<4.3",
"symfony/event-dispatcher": "<4.3|>=5",
"symfony/lock": "<4.4",
"symfony/process": "<3.3"
},
"provide": {
@@ -2218,12 +2274,12 @@
},
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "~3.4|~4.0",
"symfony/dependency-injection": "~3.4|~4.0",
"symfony/config": "^3.4|^4.0|^5.0",
"symfony/dependency-injection": "^3.4|^4.0|^5.0",
"symfony/event-dispatcher": "^4.3",
"symfony/lock": "~3.4|~4.0",
"symfony/process": "~3.4|~4.0",
"symfony/var-dumper": "^4.3"
"symfony/lock": "^4.4|^5.0",
"symfony/process": "^3.4|^4.0|^5.0",
"symfony/var-dumper": "^4.3|^5.0"
},
"suggest": {
"psr/log": "For using the console logger",
@@ -2234,7 +2290,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.3-dev"
"dev-master": "4.4-dev"
}
},
"autoload": {
@@ -2261,41 +2317,41 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2019-10-30T12:58:49+00:00"
"time": "2019-12-17T10:32:23+00:00"
},
{
"name": "symfony/dependency-injection",
"version": "v4.3.6",
"version": "v5.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
"reference": "fc036941dfafa037a7485714b62593c7eaf68edd"
"reference": "f9dbfbf487d08f60b1c83220edcd16559d1e40a2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/fc036941dfafa037a7485714b62593c7eaf68edd",
"reference": "fc036941dfafa037a7485714b62593c7eaf68edd",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f9dbfbf487d08f60b1c83220edcd16559d1e40a2",
"reference": "f9dbfbf487d08f60b1c83220edcd16559d1e40a2",
"shasum": ""
},
"require": {
"php": "^7.1.3",
"php": "^7.2.5",
"psr/container": "^1.0",
"symfony/service-contracts": "^1.1.6"
"symfony/service-contracts": "^1.1.6|^2"
},
"conflict": {
"symfony/config": "<4.3",
"symfony/finder": "<3.4",
"symfony/proxy-manager-bridge": "<3.4",
"symfony/yaml": "<3.4"
"symfony/config": "<5.0",
"symfony/finder": "<4.4",
"symfony/proxy-manager-bridge": "<4.4",
"symfony/yaml": "<4.4"
},
"provide": {
"psr/container-implementation": "1.0",
"symfony/service-implementation": "1.0"
},
"require-dev": {
"symfony/config": "^4.3",
"symfony/expression-language": "~3.4|~4.0",
"symfony/yaml": "~3.4|~4.0"
"symfony/config": "^5.0",
"symfony/expression-language": "^4.4|^5.0",
"symfony/yaml": "^4.4|^5.0"
},
"suggest": {
"symfony/config": "",
@@ -2307,7 +2363,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.3-dev"
"dev-master": "5.0-dev"
}
},
"autoload": {
@@ -2334,30 +2390,30 @@
],
"description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com",
"time": "2019-10-28T17:07:32+00:00"
"time": "2019-12-19T16:01:11+00:00"
},
{
"name": "symfony/filesystem",
"version": "v4.3.6",
"version": "v5.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
"reference": "9abbb7ef96a51f4d7e69627bc6f63307994e4263"
"reference": "1d71f670bc5a07b9ccc97dc44f932177a322d4e6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/9abbb7ef96a51f4d7e69627bc6f63307994e4263",
"reference": "9abbb7ef96a51f4d7e69627bc6f63307994e4263",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/1d71f670bc5a07b9ccc97dc44f932177a322d4e6",
"reference": "1d71f670bc5a07b9ccc97dc44f932177a322d4e6",
"shasum": ""
},
"require": {
"php": "^7.1.3",
"php": "^7.2.5",
"symfony/polyfill-ctype": "~1.8"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.3-dev"
"dev-master": "5.0-dev"
}
},
"autoload": {
@@ -2384,20 +2440,20 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
"time": "2019-08-20T14:07:54+00:00"
"time": "2019-11-26T23:25:11+00:00"
},
{
"name": "symfony/finder",
"version": "v4.3.6",
"version": "v4.4.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "72a068f77e317ae77c0a0495236ad292cfb5ce6f"
"reference": "ce8743441da64c41e2a667b8eb66070444ed911e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/72a068f77e317ae77c0a0495236ad292cfb5ce6f",
"reference": "72a068f77e317ae77c0a0495236ad292cfb5ce6f",
"url": "https://api.github.com/repos/symfony/finder/zipball/ce8743441da64c41e2a667b8eb66070444ed911e",
"reference": "ce8743441da64c41e2a667b8eb66070444ed911e",
"shasum": ""
},
"require": {
@@ -2406,7 +2462,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.3-dev"
"dev-master": "4.4-dev"
}
},
"autoload": {
@@ -2433,20 +2489,20 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"time": "2019-10-30T12:53:54+00:00"
"time": "2019-11-17T21:56:56+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.12.0",
"version": "v1.13.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "550ebaac289296ce228a706d0867afc34687e3f4"
"reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4",
"reference": "550ebaac289296ce228a706d0867afc34687e3f4",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f8f0b461be3385e56d6de3dbb5a0df24c0c275e3",
"reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3",
"shasum": ""
},
"require": {
@@ -2458,7 +2514,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.12-dev"
"dev-master": "1.13-dev"
}
},
"autoload": {
@@ -2491,20 +2547,20 @@
"polyfill",
"portable"
],
"time": "2019-08-06T08:03:45+00:00"
"time": "2019-11-27T13:56:44+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.12.0",
"version": "v1.13.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17"
"reference": "7b4aab9743c30be783b73de055d24a39cf4b954f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17",
"reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7b4aab9743c30be783b73de055d24a39cf4b954f",
"reference": "7b4aab9743c30be783b73de055d24a39cf4b954f",
"shasum": ""
},
"require": {
@@ -2516,7 +2572,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.12-dev"
"dev-master": "1.13-dev"
}
},
"autoload": {
@@ -2550,20 +2606,20 @@
"portable",
"shim"
],
"time": "2019-08-06T08:03:45+00:00"
"time": "2019-11-27T14:18:11+00:00"
},
{
"name": "symfony/polyfill-php73",
"version": "v1.12.0",
"version": "v1.13.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php73.git",
"reference": "2ceb49eaccb9352bff54d22570276bb75ba4a188"
"reference": "4b0e2222c55a25b4541305a053013d5647d3a25f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/2ceb49eaccb9352bff54d22570276bb75ba4a188",
"reference": "2ceb49eaccb9352bff54d22570276bb75ba4a188",
"url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/4b0e2222c55a25b4541305a053013d5647d3a25f",
"reference": "4b0e2222c55a25b4541305a053013d5647d3a25f",
"shasum": ""
},
"require": {
@@ -2572,7 +2628,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.12-dev"
"dev-master": "1.13-dev"
}
},
"autoload": {
@@ -2608,24 +2664,24 @@
"portable",
"shim"
],
"time": "2019-08-06T08:03:45+00:00"
"time": "2019-11-27T16:25:15+00:00"
},
{
"name": "symfony/service-contracts",
"version": "v1.1.7",
"version": "v2.0.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
"reference": "ffcde9615dc5bb4825b9f6aed07716f1f57faae0"
"reference": "144c5e51266b281231e947b51223ba14acf1a749"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/ffcde9615dc5bb4825b9f6aed07716f1f57faae0",
"reference": "ffcde9615dc5bb4825b9f6aed07716f1f57faae0",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/144c5e51266b281231e947b51223ba14acf1a749",
"reference": "144c5e51266b281231e947b51223ba14acf1a749",
"shasum": ""
},
"require": {
"php": "^7.1.3",
"php": "^7.2.5",
"psr/container": "^1.0"
},
"suggest": {
@@ -2634,7 +2690,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
"dev-master": "2.0-dev"
}
},
"autoload": {
@@ -2666,7 +2722,7 @@
"interoperability",
"standards"
],
"time": "2019-09-17T11:12:18+00:00"
"time": "2019-11-18T17:27:11+00:00"
},
{
"name": "theseer/directoryscanner",
@@ -2793,6 +2849,7 @@
}
],
"description": "An XSL wrapper / extension to the PHP 5.x XSLTProcessor with Exception and extended Callback support",
"abandoned": true,
"time": "2014-11-27T20:08:52+00:00"
},
{
@@ -2888,31 +2945,29 @@
},
{
"name": "webmozart/assert",
"version": "1.5.0",
"version": "1.6.0",
"source": {
"type": "git",
"url": "https://github.com/webmozart/assert.git",
"reference": "88e6d84706d09a236046d686bbea96f07b3a34f4"
"reference": "573381c0a64f155a0d9a23f4b0c797194805b925"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4",
"reference": "88e6d84706d09a236046d686bbea96f07b3a34f4",
"url": "https://api.github.com/repos/webmozart/assert/zipball/573381c0a64f155a0d9a23f4b0c797194805b925",
"reference": "573381c0a64f155a0d9a23f4b0c797194805b925",
"shasum": ""
},
"require": {
"php": "^5.3.3 || ^7.0",
"symfony/polyfill-ctype": "^1.8"
},
"conflict": {
"vimeo/psalm": "<3.6.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8.36 || ^7.5.13"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
}
},
"autoload": {
"psr-4": {
"Webmozart\\Assert\\": "src/"
@@ -2934,7 +2989,7 @@
"check",
"validate"
],
"time": "2019-08-24T08:43:50+00:00"
"time": "2019-11-24T13:36:37+00:00"
}
],
"aliases": [],

View File

@@ -42,7 +42,7 @@ if ($page == 'overview') {
if ($action == '') {
$log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_domains::domains");
$fields = array(
'd.domain' => $lng['domains']['domainname'],
'd.domain_ace' => $lng['domains']['domainname'],
'd.aliasdomain' => $lng['domains']['aliasdomain']
);
try {

View File

@@ -19,7 +19,6 @@
define('AREA', 'customer');
require './lib/init.php';
use Froxlor\Api\Commands\SubDomains;
use Froxlor\Database\Database;
use Froxlor\Settings;
use Froxlor\Api\Commands\Emails as Emails;
@@ -44,7 +43,7 @@ if ($page == 'overview') {
if ($action == '') {
$log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_email::emails");
$fields = array(
'd.domain' => $lng['domains']['domainname'],
'd.domain_ace' => $lng['domains']['domainname'],
'm.email_full' => $lng['emails']['emailaddress'],
'm.destination' => $lng['emails']['forwarders']
);
@@ -76,7 +75,7 @@ if ($page == 'overview') {
$emails[$row['domain']][$row['email_full']] = $row;
}
if ($paging->sortfield == 'd.domain' && $paging->sortorder == 'desc') {
if ($paging->sortfield == 'd.domain_ace' && $paging->sortorder == 'desc') {
krsort($emails);
} else {
ksort($emails);
@@ -129,16 +128,15 @@ if ($page == 'overview') {
}
}
$json_result = SubDomains::getLocal($userinfo, [
'sql_search' => [
'd.isemaildomain' => [
'value' => 1,
'op' => '='
]
]
])->listing();
$result = json_decode($json_result, true)['data'];
$emaildomains_count = $result['count'];
$result_stmt = Database::prepare("
SELECT COUNT(`id`) as emaildomains
FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `customerid`= :cid AND `isemaildomain` = '1'
");
$result = Database::pexecute_first($result_stmt, array(
"cid" => $userinfo['customerid']
));
$emaildomains_count = $result['emaildomains'];
eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/emails") . "\";");
} elseif ($action == 'delete' && $id != 0) {
@@ -196,7 +194,7 @@ if ($page == 'overview') {
$result_stmt = Database::prepare("SELECT `id`, `domain`, `customerid` FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `customerid`= :cid
AND `isemaildomain`='1'
ORDER BY `domain` ASC");
ORDER BY `domain_ace` ASC");
Database::pexecute($result_stmt, array(
"cid" => $userinfo['customerid']
));

View File

@@ -112,11 +112,14 @@ if (! is_null($month) && ! is_null($year)) {
eval("echo \"" . \Froxlor\UI\Template::getTemplate('traffic/traffic_details') . "\";");
} else {
$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 . "`
WHERE `customerid` = :customerid
GROUP BY `year` DESC, `month` DESC
LIMIT 12");
GROUP BY `year`, `month`
ORDER BY `year` DESC, `month` DESC
LIMIT 12
");
Database::pexecute($result_stmt, array(
"customerid" => $userinfo['customerid']
));

View File

@@ -393,7 +393,7 @@ if ($action == 'forgotpwd') {
if (isset($_POST['send']) && $_POST['send'] == 'send') {
$loginname = \Froxlor\Validate\Validate::validate($_POST['loginname'], 'loginname');
$email = \Froxlor\Validate\Validate::validateEmail($_POST['loginemail'], 'email');
$result_stmt = Database::prepare("SELECT `adminid`, `customerid`, `firstname`, `name`, `company`, `email`, `loginname`, `def_language`, `deactivated` FROM `" . TABLE_PANEL_CUSTOMERS . "`
$result_stmt = Database::prepare("SELECT `adminid`, `customerid`, `customernumber`, `firstname`, `name`, `company`, `email`, `loginname`, `def_language`, `deactivated` FROM `" . TABLE_PANEL_CUSTOMERS . "`
WHERE `loginname`= :loginname
AND `email`= :email");
Database::pexecute($result_stmt, array(
@@ -481,6 +481,10 @@ if ($action == 'forgotpwd') {
$replace_arr = array(
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($user),
'NAME' => $user['name'],
'FIRSTNAME' => $user['firstname'] ?? "",
'COMPANY' => $user['company'] ?? "",
'CUSTOMER_NO' => $user['customernumber'] ?? 0,
'USERNAME' => $loginname,
'LINK' => $activationlink
);
@@ -598,21 +602,18 @@ if ($action == 'resetpwd') {
));
if ($result !== false) {
if ($result['admin'] == 1) {
$new_password = \Froxlor\Validate\Validate::validate($_POST['new_password'], 'new password');
$new_password_confirm = \Froxlor\Validate\Validate::validate($_POST['new_password_confirm'], 'new password confirm');
} else {
$new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], 'new password');
$new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm');
try {
$new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], true);
$new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], true);
} catch (Exception $e) {
$message = $e->getMessage();
}
if ($new_password == '') {
$message = $new_password;
} elseif ($new_password_confirm == '') {
$message = $new_password_confirm;
} elseif ($new_password != $new_password_confirm) {
$message = $new_password . " != " . $new_password_confirm;
} else {
if (empty($message) && (empty($new_password) || $new_password != $new_password_confirm)) {
$message = $lng['error']['newpasswordconfirmerror'];
}
if (empty($message)) {
// Update user password
if ($result['admin'] == 1) {
$stmt = Database::prepare("UPDATE `" . TABLE_PANEL_ADMINS . "`

View File

@@ -84,7 +84,7 @@ CREATE TABLE `panel_activation` (
`creation` int(11) unsigned NOT NULL default '0',
`activationcode` varchar(50) default NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
DROP TABLE IF EXISTS `panel_admins`;
@@ -224,6 +224,7 @@ DROP TABLE IF EXISTS `panel_domains`;
CREATE TABLE `panel_domains` (
`id` int(11) unsigned NOT NULL auto_increment,
`domain` varchar(255) NOT NULL default '',
`domain_ace` varchar(255) NOT NULL default '',
`adminid` int(11) unsigned NOT NULL default '0',
`customerid` int(11) unsigned NOT NULL default '0',
`aliasdomain` int(11) unsigned NULL,
@@ -271,6 +272,9 @@ CREATE TABLE `panel_domains` (
`ssl_protocols` text,
`ssl_cipher_list` text,
`tlsv13_cipher_list` text,
`ssl_enabled` tinyint(1) DEFAULT '1',
`ssl_honorcipherorder` tinyint(1) DEFAULT '0',
`ssl_sessiontickets` tinyint(1) DEFAULT '1',
PRIMARY KEY (`id`),
KEY `customerid` (`customerid`),
KEY `parentdomain` (`parentdomainid`),
@@ -569,6 +573,7 @@ opcache.interned_strings_buffer'),
('system', 'stdsubdomain', ''),
('system', 'awstats_path', '/usr/bin/'),
('system', 'awstats_conf', '/etc/awstats/'),
('system', 'awstats_logformat', '1'),
('system', 'defaultttl', '604800'),
('system', 'mod_fcgid_defaultini', '1'),
('system', 'ftpserver', 'proftpd'),
@@ -649,9 +654,12 @@ opcache.interned_strings_buffer'),
('system', 'leregistered', '0'),
('system', 'leaccount', ''),
('system', 'nssextrausers', '0'),
('system', 'disable_le_selfcheck', '0'),
('system', 'ssl_protocols', 'TLSv1,TLSv1.2'),
('system', 'le_domain_dnscheck', '1'),
('system', 'ssl_protocols', 'TLSv1.2'),
('system', 'tlsv13_cipher_list', ''),
('system', 'honorcipherorder', '0'),
('system', 'sessiontickets', '1'),
('system', 'sessionticketsenabled', '1'),
('system', 'logfiles_format', ''),
('system', 'logfiles_type', '1'),
('system', 'logfiles_piped', '0'),
@@ -696,8 +704,8 @@ opcache.interned_strings_buffer'),
('panel', 'password_special_char', '!?<>§$%+#=@'),
('panel', 'customer_hide_options', ''),
('panel', 'is_configured', '0'),
('panel', 'version', '0.10.8'),
('panel', 'db_version', '201911220');
('panel', 'version', '0.10.18'),
('panel', 'db_version', '202005150');
DROP TABLE IF EXISTS `panel_tasks`;
@@ -835,14 +843,15 @@ CREATE TABLE `panel_fpmdaemons` (
`description` varchar(50) NOT NULL,
`reload_cmd` varchar(255) NOT NULL,
`config_dir` varchar(255) NOT NULL,
`pm` varchar(15) NOT NULL DEFAULT 'static',
`max_children` int(4) NOT NULL DEFAULT '1',
`start_servers` int(4) NOT NULL DEFAULT '20',
`min_spare_servers` int(4) NOT NULL DEFAULT '5',
`max_spare_servers` int(4) NOT NULL DEFAULT '35',
`pm` varchar(15) NOT NULL DEFAULT 'dynamic',
`max_children` int(4) NOT NULL DEFAULT '5',
`start_servers` int(4) NOT NULL DEFAULT '2',
`min_spare_servers` int(4) NOT NULL DEFAULT '1',
`max_spare_servers` int(4) NOT NULL DEFAULT '3',
`max_requests` int(4) NOT NULL DEFAULT '0',
`idle_timeout` int(4) NOT NULL DEFAULT '30',
`idle_timeout` int(4) NOT NULL DEFAULT '10',
`limit_extensions` varchar(255) NOT NULL default '.php',
`custom_config` text,
PRIMARY KEY (`id`),
UNIQUE KEY `reload` (`reload_cmd`),
UNIQUE KEY `config` (`config_dir`)
@@ -851,7 +860,7 @@ CREATE TABLE `panel_fpmdaemons` (
INSERT INTO `panel_fpmdaemons` (`id`, `description`, `reload_cmd`, `config_dir`) VALUES
(1, 'System default', 'service php7.0-fpm restart', '/etc/php/7.0/fpm/pool.d/');
(1, 'System default', 'service php7.3-fpm restart', '/etc/php/7.3/fpm/pool.d/');
@@ -871,13 +880,13 @@ CREATE TABLE `panel_phpconfigs` (
`fpmsettingid` int(11) NOT NULL DEFAULT '1',
`pass_authorizationheader` tinyint(1) NOT NULL default '0',
`override_fpmconfig` tinyint(1) NOT NULL DEFAULT '0',
`pm` varchar(15) NOT NULL DEFAULT 'static',
`max_children` int(4) NOT NULL DEFAULT '1',
`start_servers` int(4) NOT NULL DEFAULT '20',
`min_spare_servers` int(4) NOT NULL DEFAULT '5',
`max_spare_servers` int(4) NOT NULL DEFAULT '35',
`pm` varchar(15) NOT NULL DEFAULT 'dynamic',
`max_children` int(4) NOT NULL DEFAULT '5',
`start_servers` int(4) NOT NULL DEFAULT '2',
`min_spare_servers` int(4) NOT NULL DEFAULT '1',
`max_spare_servers` int(4) NOT NULL DEFAULT '3',
`max_requests` int(4) NOT NULL DEFAULT '0',
`idle_timeout` int(4) NOT NULL DEFAULT '30',
`idle_timeout` int(4) NOT NULL DEFAULT '10',
`limit_extensions` varchar(255) NOT NULL default '.php',
PRIMARY KEY (`id`),
KEY `fpmsettingid` (`fpmsettingid`)
@@ -886,8 +895,8 @@ CREATE TABLE `panel_phpconfigs` (
INSERT INTO `panel_phpconfigs` (`id`, `description`, `binary`, `file_extensions`, `mod_fcgid_starter`, `mod_fcgid_maxrequests`, `phpsettings`) VALUES
(1, 'Default Config', '/usr/bin/php-cgi', 'php', '-1', '-1', 'allow_call_time_pass_reference = Off\r\nallow_url_fopen = Off\r\nasp_tags = Off\r\ndisable_classes =\r\ndisable_functions = curl_exec,curl_multi_exec,exec,parse_ini_file,passthru,popen,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,show_source,system\r\ndisplay_errors = Off\r\ndisplay_startup_errors = Off\r\nenable_dl = Off\r\nerror_reporting = E_ALL & ~E_NOTICE\r\nexpose_php = Off\r\nfile_uploads = On\r\ncgi.force_redirect = 1\r\ngpc_order = "GPC"\r\nhtml_errors = Off\r\nignore_repeated_errors = Off\r\nignore_repeated_source = Off\r\ninclude_path = ".:{PEAR_DIR}"\r\nlog_errors = On\r\nlog_errors_max_len = 1024\r\nmagic_quotes_gpc = Off\r\nmagic_quotes_runtime = Off\r\nmagic_quotes_sybase = Off\r\nmax_execution_time = 30\r\nmax_input_time = 60\r\nmemory_limit = 128M\r\n{OPEN_BASEDIR_C}open_basedir = "{OPEN_BASEDIR}"\r\noutput_buffering = 4096\r\npost_max_size = 16M\r\nprecision = 14\r\nregister_argc_argv = Off\r\nregister_globals = Off\r\nreport_memleaks = On\r\nsendmail_path = "/usr/sbin/sendmail -t -i -f {CUSTOMER_EMAIL}"\r\nsession.auto_start = 0\r\nsession.bug_compat_42 = 0\r\nsession.bug_compat_warn = 1\r\nsession.cache_expire = 180\r\nsession.cache_limiter = nocache\r\nsession.cookie_domain =\r\nsession.cookie_lifetime = 0\r\nsession.cookie_path = /\r\nsession.entropy_file = /dev/urandom\r\nsession.entropy_length = 16\r\nsession.gc_divisor = 1000\r\nsession.gc_maxlifetime = 1440\r\nsession.gc_probability = 1\r\nsession.name = PHPSESSID\r\nsession.referer_check =\r\nsession.save_handler = files\r\nsession.save_path = "{TMP_DIR}"\r\nsession.serialize_handler = php\r\nsession.use_cookies = 1\r\nsession.use_trans_sid = 0\r\nshort_open_tag = On\r\nsuhosin.mail.protect = 1\r\nsuhosin.simulation = Off\r\ntrack_errors = Off\r\nupload_max_filesize = 32M\r\nupload_tmp_dir = "{TMP_DIR}"\r\nvariables_order = "GPCS"\r\n;mail.add_x_header = On\r\n;mail.log = "/var/log/phpmail.log"\r\nopcache.restrict_api = "{DOCUMENT_ROOT}"\r\n'),
(2, 'Froxlor Vhost Config', '/usr/bin/php-cgi', 'php', '-1', '-1', 'allow_call_time_pass_reference = Off\r\nallow_url_fopen = On\r\nasp_tags = Off\r\ndisable_classes =\r\ndisable_functions = curl_multi_exec,parse_ini_file,passthru,popen,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,show_source,system\r\ndisplay_errors = Off\r\ndisplay_startup_errors = Off\r\nenable_dl = Off\r\nerror_reporting = E_ALL & ~E_NOTICE\r\nexpose_php = Off\r\nfile_uploads = On\r\ncgi.force_redirect = 1\r\ngpc_order = "GPC"\r\nhtml_errors = Off\r\nignore_repeated_errors = Off\r\nignore_repeated_source = Off\r\ninclude_path = ".:{PEAR_DIR}"\r\nlog_errors = On\r\nlog_errors_max_len = 1024\r\nmagic_quotes_gpc = Off\r\nmagic_quotes_runtime = Off\r\nmagic_quotes_sybase = Off\r\nmax_execution_time = 60\r\nmax_input_time = 60\r\nmemory_limit = 128M\r\noutput_buffering = 4096\r\npost_max_size = 16M\r\nprecision = 14\r\nregister_argc_argv = Off\r\nregister_globals = Off\r\nreport_memleaks = On\r\nsendmail_path = "/usr/sbin/sendmail -t -i -f {CUSTOMER_EMAIL}"\r\nsession.auto_start = 0\r\nsession.bug_compat_42 = 0\r\nsession.bug_compat_warn = 1\r\nsession.cache_expire = 180\r\nsession.cache_limiter = nocache\r\nsession.cookie_domain =\r\nsession.cookie_lifetime = 0\r\nsession.cookie_path = /\r\nsession.entropy_file = /dev/urandom\r\nsession.entropy_length = 16\r\nsession.gc_divisor = 1000\r\nsession.gc_maxlifetime = 1440\r\nsession.gc_probability = 1\r\nsession.name = PHPSESSID\r\nsession.referer_check =\r\nsession.save_handler = files\r\nsession.save_path = "{TMP_DIR}"\r\nsession.serialize_handler = php\r\nsession.use_cookies = 1\r\nsession.use_trans_sid = 0\r\nshort_open_tag = On\r\nsuhosin.mail.protect = 1\r\nsuhosin.simulation = Off\r\ntrack_errors = Off\r\nupload_max_filesize = 32M\r\nupload_tmp_dir = "{TMP_DIR}"\r\nvariables_order = "GPCS"\r\n;mail.add_x_header = On\r\n;mail.log = "/var/log/phpmail.log"\r\nopcache.restrict_api = ""\r\n');
(1, 'Default Config', '/usr/bin/php-cgi', 'php', '-1', '-1', 'allow_url_fopen = Off\r\nallow_url_include = Off\r\nauto_append_file =\r\nauto_globals_jit = On\r\nauto_prepend_file =\r\nbcmath.scale = 0\r\ncli_server.color = On\r\ndefault_charset = "UTF-8"\r\ndefault_mimetype = "text/html"\r\ndefault_socket_timeout = 60\r\nasp_tags = Off\r\ndisable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,curl_exec,curl_multi_exec,exec,parse_ini_file,passthru,popen,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,show_source,system\r\ndisplay_errors = Off\r\ndisplay_startup_errors = Off\r\ndoc_root =\r\nenable_dl = Off\r\nerror_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE\r\nexpose_php = Off\r\nfile_uploads = On\r\nhtml_errors = On\r\nignore_repeated_errors = Off\r\nignore_repeated_source = Off\r\ninclude_path = ".:{PEAR_DIR}"\r\nimplicit_flush = Off\r\nldap.max_links = -1\r\nlog_errors = On\r\nlog_errors_max_len = 1024\r\nmail.add_x_header = Off\r\nmax_execution_time = 30\r\nmax_file_uploads = 20\r\nmax_input_time = 60\r\nmemory_limit = 128M\r\n{OPEN_BASEDIR_C}open_basedir = "{OPEN_BASEDIR}"\r\noutput_buffering = 4096\r\npost_max_size = 16M\r\nprecision = 14\r\nregister_argc_argv = Off\r\nreport_memleaks = On\r\nrequest_order = "GP"\r\nsendmail_path = "/usr/sbin/sendmail -t -i -f {CUSTOMER_EMAIL}"\r\nserialize_precision = -1\r\nsession.auto_start = 0\r\nsession.cache_expire = 180\r\nsession.cache_limiter = nocache\r\nsession.cookie_domain =\r\nsession.cookie_httponly =\r\nsession.cookie_lifetime = 0\r\nsession.cookie_path = /\r\nsession.cookie_samesite =\r\nsession.gc_divisor = 1000\r\nsession.gc_maxlifetime = 1440\r\nsession.gc_probability = 0\r\nsession.name = PHPSESSID\r\nsession.referer_check =\r\nsession.save_handler = files\r\nsession.save_path = "{TMP_DIR}"\r\nsession.serialize_handler = php\r\nsession.sid_bits_per_character = 5\r\nsession.sid_length = 26\r\nsession.trans_sid_tags = "a=href,area=href,frame=src,form="\r\nsession.use_cookies = 1\r\nsession.use_only_cookies = 1\r\nsession.use_strict_mode = 0\r\nsession.use_trans_sid = 0\r\nshort_open_tag = On\r\nupload_max_filesize = 32M\r\nupload_tmp_dir = "{TMP_DIR}"\r\nvariables_order = "GPCS"\r\nopcache.restrict_api = "{DOCUMENT_ROOT}"\r\n'),
(2, 'Froxlor Vhost Config', '/usr/bin/php-cgi', 'php', '-1', '-1', 'allow_url_fopen = On\r\nallow_url_include = Off\r\nauto_append_file =\r\nauto_globals_jit = On\r\nauto_prepend_file =\r\nbcmath.scale = 0\r\ncli_server.color = On\r\ndefault_charset = "UTF-8"\r\ndefault_mimetype = "text/html"\r\ndefault_socket_timeout = 60\r\nasp_tags = Off\r\ndisable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,curl_multi_exec,parse_ini_file,passthru,popen,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,show_source,system\r\ndisplay_errors = Off\r\ndisplay_startup_errors = Off\r\ndoc_root =\r\nenable_dl = Off\r\nerror_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE\r\nexpose_php = Off\r\nfile_uploads = On\r\nhtml_errors = On\r\nignore_repeated_errors = Off\r\nignore_repeated_source = Off\r\ninclude_path = ".:{PEAR_DIR}"\r\nimplicit_flush = Off\r\nldap.max_links = -1\r\nlog_errors = On\r\nlog_errors_max_len = 1024\r\nmail.add_x_header = Off\r\nmax_execution_time = 60\r\nmax_file_uploads = 20\r\nmax_input_time = 60\r\nmemory_limit = 128M\r\noutput_buffering = 4096\r\npost_max_size = 16M\r\nprecision = 14\r\nregister_argc_argv = Off\r\nreport_memleaks = On\r\nrequest_order = "GP"\r\nsendmail_path = "/usr/sbin/sendmail -t -i -f {CUSTOMER_EMAIL}"\r\nserialize_precision = -1\r\nsession.auto_start = 0\r\nsession.cache_expire = 180\r\nsession.cache_limiter = nocache\r\nsession.cookie_domain =\r\nsession.cookie_httponly =\r\nsession.cookie_lifetime = 0\r\nsession.cookie_path = /\r\nsession.cookie_samesite =\r\nsession.gc_divisor = 1000\r\nsession.gc_maxlifetime = 1440\r\nsession.gc_probability = 0\r\nsession.name = PHPSESSID\r\nsession.referer_check =\r\nsession.save_handler = files\r\nsession.save_path = "{TMP_DIR}"\r\nsession.serialize_handler = php\r\nsession.sid_bits_per_character = 5\r\nsession.sid_length = 26\r\nsession.trans_sid_tags = "a=href,area=href,frame=src,form="\r\nsession.use_cookies = 1\r\nsession.use_only_cookies = 1\r\nsession.use_strict_mode = 0\r\nsession.use_trans_sid = 0\r\nshort_open_tag = On\r\nupload_max_filesize = 32M\r\nupload_tmp_dir = "{TMP_DIR}"\r\nvariables_order = "GPCS"\r\nopcache.restrict_api = ""\r\n');
DROP TABLE IF EXISTS `cronjobs_run`;
@@ -988,7 +997,8 @@ CREATE TABLE IF NOT EXISTS `domain_ssl_settings` (
`ssl_csr_file` mediumtext,
`ssl_fullchain_file` mediumtext,
`expirationdate` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
PRIMARY KEY (`id`),
UNIQUE KEY (`domainid`)
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;

View File

@@ -159,6 +159,7 @@ class FroxlorInstall
$this->_guessServerName();
$this->_guessServerIP();
$this->_guessWebserver();
$this->_guessDistribution();
$this->_getPostField('mysql_host', '127.0.0.1');
$this->_getPostField('mysql_database', 'froxlor');
@@ -332,22 +333,29 @@ class FroxlorInstall
$userdata .= "?>";
// test if we can store the userdata.inc.php in ../lib
$umask = @umask(077);
$userdata_file = dirname(dirname(dirname(__FILE__))) . '/lib/userdata.inc.php';
if ($fp = @fopen($userdata_file, 'w')) {
$result = @fputs($fp, $userdata, strlen($userdata));
if (@touch($userdata_file) && @is_writable($userdata_file)) {
$fp = @fopen($userdata_file, 'w');
@fputs($fp, $userdata, strlen($userdata));
@fclose($fp);
$content .= $this->_status_message('green', 'OK');
chmod($userdata_file, 0440);
} elseif ($fp = @fopen('/tmp/userdata.inc.php', 'w')) {
$result = @fputs($fp, $userdata, strlen($userdata));
@fclose($fp);
$content .= $this->_status_message('orange', $this->_lng['install']['creating_configfile_temp']);
chmod('/tmp/userdata.inc.php', 0440);
} else {
$content .= $this->_status_message('red', $this->_lng['install']['creating_configfile_failed']);
$escpduserdata = nl2br(htmlspecialchars($userdata));
eval("\$content .= \"" . $this->_getTemplate("textarea") . "\";");
@unlink($userdata_file);
// try creating it in a temporary file
$temp_file = @tempnam(sys_get_temp_dir(), 'fx');
if ($temp_file) {
$fp = @fopen($temp_file, 'w');
@fputs($fp, $userdata, strlen($userdata));
@fclose($fp);
$content .= $this->_status_message('orange', sprintf($this->_lng['install']['creating_configfile_temp'], $temp_file));
} else {
$content .= $this->_status_message('red', $this->_lng['install']['creating_configfile_failed']);
$escpduserdata = nl2br(htmlspecialchars($userdata));
eval("\$content .= \"" . $this->_getTemplate("textarea") . "\";");
}
}
@umask($umask);
return $content;
}
@@ -497,6 +505,17 @@ class FroxlorInstall
$this->_updateSetting($upd_stmt, 'error', 'system', 'errorlog_level');
}
$distros = glob(\Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . '/lib/configfiles/') . '*.xml');
foreach ($distros as $_distribution) {
if($this->_data['distribution'] == str_replace(".xml", "", strtolower(basename($_distribution)))) {
$dist = new \Froxlor\Config\ConfigParser($_distribution);
$defaults = $dist->getDefaults();
foreach ($defaults->property as $property) {
$this->_updateSetting($upd_stmt, $property->value, $property->settinggroup, $property->varname);
}
}
}
$this->_updateSetting($upd_stmt, $this->_data['activate_newsfeed'], 'admin', 'show_news_feed');
$this->_updateSetting($upd_stmt, dirname(dirname(dirname(__FILE__))), 'system', 'letsencryptchallengepath');
@@ -563,7 +582,7 @@ class FroxlorInstall
for ($i = 0; $i < sizeof($sql_query); $i ++) {
if (trim($sql_query[$i]) != '') {
try {
$result = $db->query($sql_query[$i]);
$db->query($sql_query[$i]);
} catch (\PDOException $e) {
$content .= $this->_status_message('red', $e->getMessage());
$fatal_fail = true;
@@ -730,7 +749,7 @@ class FroxlorInstall
}
if ($do_backup) {
$command = $mysql_dump . " " . $this->_data['mysql_database'] . " -u " . $this->_data['mysql_root_user'] . " --password='" . $this->_data['mysql_root_pass'] . "' --result-file=" . $filename;
$command = $mysql_dump . " " . escapeshellarg($this->_data['mysql_database']) . " -u " . escapeshellarg($this->_data['mysql_root_user']) . " --password='" . escapeshellarg($this->_data['mysql_root_pass']) . "' --result-file=" . $filename;
$output = exec($command);
if (stristr($output, "error")) {
$content .= $this->_status_message('red', $this->_lng['install']['backup_failed']);
@@ -833,6 +852,32 @@ class FroxlorInstall
*/
$section = $this->_lng['install']['serversettings'];
eval("\$formdata .= \"" . $this->_getTemplate("datasection") . "\";");
// distribution
if (! empty($_POST['installstep']) && $this->_data['distribution'] == '') {
$diststyle = 'color:red;';
} else {
$diststyle = '';
}
// show list of available distro's
$distros = glob(\Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . '/lib/configfiles/') . '*.xml');
foreach ($distros as $_distribution) {
$dist = new \Froxlor\Config\ConfigParser($_distribution);
$dist_display = $dist->distributionName." ".$dist->distributionCodename." (" . $dist->distributionVersion . ")";
$distributions_select_data[$dist_display] .= str_replace(".xml", "", strtolower(basename($_distribution)));
}
// sort by distribution name
ksort($distributions_select_data);
foreach ($distributions_select_data as $dist_display => $dist_index) {
// create select-box-option
$distributions_select .= \Froxlor\UI\HTML::makeoption($dist_display, $dist_index, $this->_data['distribution']);
//$this->_data['distribution']
}
$formdata .= $this->_getSectionItemSelectbox('distribution', $distributions_select, $diststyle);
// servername
if (! empty($_POST['installstep']) && $this->_data['servername'] == '') {
$style = 'color:red;';
@@ -854,12 +899,12 @@ class FroxlorInstall
$websrvstyle = '';
}
// apache
$formdata .= $this->_getSectionItemCheckbox('apache2', ($this->_data['webserver'] == 'apache2'), $websrvstyle);
$formdata .= $this->_getSectionItemCheckbox('apache24', ($this->_data['webserver'] == 'apache24'), $websrvstyle);
$formdata .= $this->_getSectionItemCheckbox('webserver', 'apache2', ($this->_data['webserver'] == 'apache2'), $websrvstyle);
$formdata .= $this->_getSectionItemCheckbox('webserver', 'apache24', ($this->_data['webserver'] == 'apache24'), $websrvstyle);
// lighttpd
$formdata .= $this->_getSectionItemCheckbox('lighttpd', ($this->_data['webserver'] == 'lighttpd'), $websrvstyle);
$formdata .= $this->_getSectionItemCheckbox('webserver', 'lighttpd', ($this->_data['webserver'] == 'lighttpd'), $websrvstyle);
// nginx
$formdata .= $this->_getSectionItemCheckbox('nginx', ($this->_data['webserver'] == 'nginx'), $websrvstyle);
$formdata .= $this->_getSectionItemCheckbox('webserver', 'nginx', ($this->_data['webserver'] == 'nginx'), $websrvstyle);
// webserver-user
if (! empty($_POST['installstep']) && $this->_data['httpuser'] == '') {
$style = 'color:red;';
@@ -911,7 +956,7 @@ class FroxlorInstall
}
/**
* generate form radio field for webserver-selection
* generate form radio field
*
* @param string $fieldname
* @param boolean $checked
@@ -919,8 +964,9 @@ class FroxlorInstall
*
* @return string
*/
private function _getSectionItemCheckbox($fieldname = null, $checked = false, $style = "")
private function _getSectionItemCheckbox($groupname = null, $fieldname = null, $checked = false, $style = "")
{
$groupname = $this->_lng['install'][$groupname];
$fieldlabel = $this->_lng['install'][$fieldname];
if ($checked) {
$checked = 'checked="checked"';
@@ -930,6 +976,25 @@ class FroxlorInstall
return $sectionitem;
}
/**
* generate form selectbox
*
* @param string $fieldname
* @param boolean $options
* @param string $style
*
* @return string
*/
private function _getSectionItemSelectbox($fieldname = null, $options = null, $style = "")
{
$groupname = $this->_lng['install'][$groupname];
$fieldlabel = $this->_lng['install'][$fieldname];
$sectionitem = "";
eval("\$sectionitem .= \"" . $this->_getTemplate("dataitemselect") . "\";");
return $sectionitem;
}
/**
* generate form checkbox field
*
@@ -1266,6 +1331,39 @@ class FroxlorInstall
}
}
/**
* get/guess linux distribution
*/
private function _guessDistribution()
{
// post
if (! empty($_POST['distribution'])) {
$this->_data['distribution'] = $_POST['distribution'];
} else {
//set default os.
$os_dist = array('ID' => 'buster');
$os_version = array('0' => '10');
//read os-release
if(file_exists('/etc/os-release')) {
$os_dist = parse_ini_file('/etc/os-release', false);
if(is_array($os_dist) && array_key_exists('ID', $os_dist) && array_key_exists('VERSION_ID', $os_dist)) {
$os_version = explode('.',$os_dist['VERSION_ID'])[0];
}
}
$distros = glob(\Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . '/lib/configfiles/') . '*.xml');
foreach ($distros as $_distribution) {
$dist = new \Froxlor\Config\ConfigParser($_distribution);
$ver = explode('.', $dist->distributionVersion)[0];
if (strtolower($os_dist['ID']) == strtolower($dist->distributionName) && $os_version == $ver) {
$this->_data['distribution'] = str_replace(".xml", "", strtolower(basename($_distribution)));
}
}
}
}
/**
* check if POST field is set and get value for the
* internal data array, if not set use either '' or $default if != null

View File

@@ -63,6 +63,7 @@ $lng['install']['admin_pass1'] = 'Administrator Password';
$lng['install']['admin_pass2'] = 'Administrator-Password (confirm)';
$lng['install']['activate_newsfeed'] = 'Enable the official newsfeed<br><small>(https://inside.froxlor.org/news/)</small>';
$lng['install']['serversettings'] = 'Server settings';
$lng['install']['distribution'] = 'Distribution';
$lng['install']['servername'] = 'Server name (FQDN, no ip-address)';
$lng['install']['serverip'] = 'Server IP';
$lng['install']['webserver'] = 'Webserver';
@@ -86,7 +87,7 @@ $lng['install']['changing_data'] = 'Adjusting settings...';
$lng['install']['creating_entries'] = 'Inserting new values...';
$lng['install']['adding_admin_user'] = 'Creating admin-account...';
$lng['install']['creating_configfile'] = 'Creating configfile...';
$lng['install']['creating_configfile_temp'] = 'File was saved in /tmp/userdata.inc.php, please move to ' . dirname(dirname(__DIR__)) . '/lib/.';
$lng['install']['creating_configfile_temp'] = 'File was saved in %s, please move to ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php';
$lng['install']['creating_configfile_failed'] = 'Could not create ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php, please create it manually with the following content:';
$lng['install']['froxlor_succ_installed'] = 'Froxlor was installed successfully.';

View File

@@ -53,6 +53,7 @@ $lng['install']['admin_user'] = 'Nom d\'utilisateur administrateur';
$lng['install']['admin_pass1'] = 'Mot de passe administrateur';
$lng['install']['admin_pass2'] = 'Mot de passe administrateur (confirmez)';
$lng['install']['serversettings'] = 'Réglages serveur';
$lng['install']['distribution'] = 'Distribution';
$lng['install']['servername'] = 'Nom du serveur (FQDN, pas d\'adresse IP)';
$lng['install']['serverip'] = 'Adresse IP du serveur';
$lng['install']['webserver'] = 'Serveur Web';
@@ -76,7 +77,7 @@ $lng['install']['changing_data'] = 'Ajustement des paramètres...';
$lng['install']['creating_entries'] = 'Insertion des nouvelles valeurs...';
$lng['install']['adding_admin_user'] = 'Création du compte administrateur...';
$lng['install']['creating_configfile'] = 'Création du fichier de configuration...';
$lng['install']['creating_configfile_temp'] = 'Le fichier a été enregistré dans /tmp/userdata.inc.php, merci de le déplacer dans ' . dirname(dirname(__DIR__)) . '/lib/.';
$lng['install']['creating_configfile_temp'] = 'Le fichier a été enregistré dans %s, merci de le déplacer dans ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php';
$lng['install']['creating_configfile_failed'] = 'Impossible de créer ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php, merci de le créer manuellement avec le contenu suivant:';
$lng['install']['froxlor_succ_installed'] = 'Froxlor a été installé avec succès.';

View File

@@ -63,6 +63,7 @@ $lng['install']['admin_pass1'] = 'Administrator-Passwort';
$lng['install']['admin_pass2'] = 'Administrator-Passwort (Bestätigung)';
$lng['install']['activate_newsfeed'] = 'Aktiviere das offizielle Newsfeed<br><small>(https://inside.froxlor.org/news/)</small>';
$lng['install']['serversettings'] = 'Servereinstellungen';
$lng['install']['distribution'] = 'Distribution';
$lng['install']['servername'] = 'Servername (FQDN, keine IP-Adresse)';
$lng['install']['serverip'] = 'Server-IP';
$lng['install']['webserver'] = 'Webserver';
@@ -86,7 +87,7 @@ $lng['install']['changing_data'] = 'Einstellungen anpassen...';
$lng['install']['creating_entries'] = 'Trage neue Werte ein...';
$lng['install']['adding_admin_user'] = 'Erstelle Admin-Benutzer...';
$lng['install']['creating_configfile'] = 'Erstelle Konfigurationsdatei...';
$lng['install']['creating_configfile_temp'] = 'Datei wurde in /tmp/userdata.inc.php gespeichert, bitte nach ' . dirname(dirname(__DIR__)) . '/lib/ verschieben.';
$lng['install']['creating_configfile_temp'] = 'Datei wurde in %s gespeichert, bitte nach ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php verschieben.';
$lng['install']['creating_configfile_failed'] = 'Konnte ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php nicht erstellen, bitte manuell mit folgendem Inhalt anlegen:';
$lng['install']['froxlor_succ_installed'] = 'Froxlor wurde erfolgreich installiert.';

View File

@@ -1,4 +1,4 @@
<p>
<label for="{$fieldname}" class="install-block {$style}">{$this->_lng['install']['webserver']} {$fieldlabel}:</label>
<input type="radio" name="webserver" id="{$fieldname}" value="{$fieldname}" {$checked} /><span>{$fieldlabel}</span>
<label for="{$fieldname}" class="install-block {$style}">{$groupname} {$fieldlabel}:</label>
<input type="radio" name="{$groupname}" id="{$fieldname}" value="{$fieldname}" {$checked} /><span>{$fieldlabel}</span>
</p>

View File

@@ -0,0 +1,6 @@
<p>
<label for="{$fieldname}" class="install-block {$style}">{$fieldlabel}:</label>
<select name="{$fieldname}" id="{$fieldname}" class="dropdown">
{$options}
</select>
</p>

View File

@@ -500,3 +500,147 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.10.7')) {
showUpdateStep("Updating from 0.10.7 to 0.10.8", false);
\Froxlor\Froxlor::updateToVersion('0.10.8');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.8')) {
showUpdateStep("Updating from 0.10.8 to 0.10.9", false);
\Froxlor\Froxlor::updateToVersion('0.10.9');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201911220')) {
showUpdateStep("Adding enhanced SSL control over domains");
// customer domains
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_enabled` tinyint(1) DEFAULT '1';");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_honorcipherorder` tinyint(1) DEFAULT '0' AFTER `ssl_enabled`;");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_sessiontickets` tinyint(1) DEFAULT '1' AFTER `ssl_honorcipherorder`;");
// as setting for froxlor vhost
Settings::AddNew("system.honorcipherorder", '0');
Settings::AddNew("system.sessiontickets", '1');
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201912100');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.9')) {
showUpdateStep("Updating from 0.10.9 to 0.10.10", false);
\Froxlor\Froxlor::updateToVersion('0.10.10');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201912100')) {
showUpdateStep("Adding option to disable SSL sessiontickets for older systems");
Settings::AddNew("system.sessionticketsenabled", '1');
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201912310');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201912310')) {
showUpdateStep("Adding custom phpfpm pool configuration field");
Database::query("ALTER TABLE `" . TABLE_PANEL_FPMDAEMONS . "` ADD `custom_config` text AFTER `limit_extensions`;");
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201912311');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.10')) {
showUpdateStep("Updating from 0.10.10 to 0.10.11", false);
\Froxlor\Froxlor::updateToVersion('0.10.11');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201912311')) {
showUpdateStep("Migrate logfiles_format setting");
$current_format = Settings::Set('system.logfiles_format');
if (! empty($current_format)) {
Settings::Set('system.logfiles_format', '"' . Settings::Get('system.logfiles_format') . '"');
lastStepStatus(0);
} else {
lastStepStatus(0, 'not needed');
}
\Froxlor\Froxlor::updateToDbVersion('201912312');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201912312')) {
showUpdateStep("Adding option change awstats LogFormat");
Settings::AddNew("system.awstats_logformat", '1');
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201912313');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.11')) {
showUpdateStep("Updating from 0.10.11 to 0.10.12", false);
\Froxlor\Froxlor::updateToVersion('0.10.12');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.12')) {
showUpdateStep("Updating from 0.10.12 to 0.10.13", false);
\Froxlor\Froxlor::updateToVersion('0.10.13');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201912313')) {
showUpdateStep("Adding new field to domains table");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `domain_ace` varchar(255) NOT NULL default '' AFTER `domain`;");
lastStepStatus(0);
showUpdateStep("Updating domain entries");
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `domain_ace` = :ace WHERE `id` = :domainid");
$sel_stmt = Database::prepare("SELECT id, domain FROM `" . TABLE_PANEL_DOMAINS . "` ORDER BY id ASC");
Database::pexecute($sel_stmt);
$idna_convert = new \Froxlor\Idna\IdnaWrapper();
while ($domain = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
Database::pexecute($upd_stmt, [
'ace' => $idna_convert->decode($domain['domain']),
'domainid' => $domain['id']
]);
}
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202002290');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.13')) {
showUpdateStep("Updating from 0.10.13 to 0.10.14", false);
\Froxlor\Froxlor::updateToVersion('0.10.14');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.14')) {
showUpdateStep("Updating from 0.10.14 to 0.10.15", false);
\Froxlor\Froxlor::updateToVersion('0.10.15');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202002290')) {
showUpdateStep("Adding new setting to validate DNS when using Let's Encrypt");
Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'system' AND `varname` = 'disable_le_selfcheck'");
$le_domain_dnscheck = isset($_POST['system_le_domain_dnscheck']) ? (int) $_POST['system_le_domain_dnscheck'] : '1';
Settings::AddNew("system.le_domain_dnscheck", $le_domain_dnscheck);
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202004140');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.15')) {
showUpdateStep("Updating from 0.10.15 to 0.10.16", false);
\Froxlor\Froxlor::updateToVersion('0.10.16');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202004140')) {
showUpdateStep("Adding unique key on domainid field in domain ssl table");
// check for duplicate entries prior to set a unique key to avoid errors on update
Database::query("
DELETE a.* FROM domain_ssl_settings AS a
LEFT JOIN domain_ssl_settings AS b ON
((b.`domainid`=a.`domainid` AND UNIX_TIMESTAMP(b.`expirationdate`) > UNIX_TIMESTAMP(a.`expirationdate`))
OR (UNIX_TIMESTAMP(b.`expirationdate`) = UNIX_TIMESTAMP(a.`expirationdate`) AND b.`id`>a.`id`))
WHERE b.`id` IS NOT NULL
");
Database::query("ALTER TABLE `domain_ssl_settings` ADD UNIQUE(`domainid`)");
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202005150');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.16')) {
showUpdateStep("Updating from 0.10.16 to 0.10.17", false);
\Froxlor\Froxlor::updateToVersion('0.10.17');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.17')) {
showUpdateStep("Updating from 0.10.17 to 0.10.18", false);
\Froxlor\Froxlor::updateToVersion('0.10.18');
}

View File

@@ -34,6 +34,9 @@ function getPreConfig($current_version, $current_db_version)
include_once \Froxlor\FileDir::makeCorrectFile(dirname(__FILE__) . '/preconfig/0.9/preconfig_0.9.inc.php');
parseAndOutputPreconfig($has_preconfig, $return, $current_version, $current_db_version);
include_once \Froxlor\FileDir::makeCorrectFile(dirname(__FILE__) . '/preconfig/0.10/preconfig_0.10.inc.php');
parseAndOutputPreconfig2($has_preconfig, $return, $current_version, $current_db_version);
$return .= '<br /><br />' . \Froxlor\UI\HTML::makecheckbox('update_changesagreed', '<strong>I have read the update notifications above and I am aware of the changes made to my system.</strong>', '1', true, '0', true);
$return .= '</div>';
$return .= '<input type="hidden" name="update_preconfig" value="1" />';

View File

@@ -0,0 +1,42 @@
<?php
/**
* This file is part of the Froxlor project.
* 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 Updater
*
*/
/**
* checks if the new-version has some updating to do
*
* @param boolean $has_preconfig
* pointer to check if any preconfig has to be output
* @param string $return
* pointer to output string
* @param string $current_version
* current froxlor version
*
* @return null
*/
function parseAndOutputPreconfig2(&$has_preconfig, &$return, $current_version, $current_db_version)
{
global $lng;
if (versionInUpdate($current_db_version, '202004140')) {
$has_preconfig = true;
$description = 'Froxlor can now optionally validate the dns entries of domains that request Lets Encrypt certificates to reduce dns-related problems (e.g. freshly registered domain or updated a-record).<br />';
$question = '<strong>Validate DNS of domains when using Lets Encrypt&nbsp;';
$question .= \Froxlor\UI\HTML::makeyesno('system_le_domain_dnscheck', '1', '0', '1');
eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";");
}
}

View File

@@ -600,8 +600,8 @@ function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $c
if (versionInUpdate($current_version, '0.9.32-rc2')) {
$has_preconfig = true;
$description = 'To customize the command which executes the cronjob (php - basically) change the path below according to your system.<br /><br />';
$question = '<strong>Please specify the command to execute cronscripts</strong> (default: "/usr/bin/nice -n 5 /usr/bin/php5 -q")<br />';
$question .= '<input type="text" class="text" name="croncmdline" value="/usr/bin/nice -n 5 /usr/bin/php5 -q" /><br />';
$question = '<strong>Please specify the command to execute cronscripts</strong> (default: "/usr/bin/nice -n 5 /usr/bin/php -q")<br />';
$question .= '<input type="text" class="text" name="croncmdline" value="/usr/bin/nice -n 5 /usr/bin/php -q" /><br />';
eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";");
}

View File

@@ -54,6 +54,13 @@ abstract class ApiCommand extends ApiParameter
*/
private $mail = null;
/**
* whether the call is an internal one or not
*
* @var boolean
*/
private $internal_call = false;
/**
* language strings array
*
@@ -90,10 +97,12 @@ abstract class ApiCommand extends ApiParameter
* optional, array of parameters (var=>value) for the command
* @param array $userinfo
* optional, passed via WebInterface (instead of $header)
* @param boolean $internal
* optional whether called internally, default false
*
* @throws \Exception
*/
public function __construct($header = null, $params = null, $userinfo = null)
public function __construct($header = null, $params = null, $userinfo = null, $internal = false)
{
parent::__construct($params);
@@ -127,6 +136,9 @@ abstract class ApiCommand extends ApiParameter
if ($this->debug) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::LOG_ERROR, LOG_DEBUG, "[API] " . get_called_class() . ": " . json_encode($params, JSON_UNESCAPED_SLASHES));
}
// set internal call flag
$this->internal_call = $internal;
}
/**
@@ -191,13 +203,15 @@ abstract class ApiCommand extends ApiParameter
* array of user-data
* @param array $params
* array of parameters for the command
* @param boolean $internal
* optional whether called internally, default false
*
* @return ApiCommand
* @throws \Exception
*/
public static function getLocal($userinfo = null, $params = null)
public static function getLocal($userinfo = null, $params = null, $internal = false)
{
return new static(null, $params, $userinfo);
return new static(null, $params, $userinfo, $internal);
}
/**
@@ -210,6 +224,16 @@ abstract class ApiCommand extends ApiParameter
return $this->is_admin;
}
/**
* internal call flag
*
* @return boolean
*/
protected function isInternal()
{
return $this->internal_call;
}
/**
* return field from user-table
*
@@ -241,7 +265,7 @@ abstract class ApiCommand extends ApiParameter
* optional array of placeholders mapped to the actual value which is used in the API commands when executing the statement [internal]
* @param boolean $append
* optional append to WHERE clause rather then create new one, default false [internal]
*
*
* @return string
*/
protected function getSearchWhere(&$query_fields = array(), $append = false)
@@ -304,7 +328,7 @@ abstract class ApiCommand extends ApiParameter
* optional, limit resultset, default 0
* @param int $sql_offset
* optional, offset for limitation, default 0
*
*
* @return string
*/
protected function getLimit()
@@ -333,7 +357,7 @@ abstract class ApiCommand extends ApiParameter
* optional array with index = fieldname and value = ASC|DESC
* @param boolean $append
* optional append to ORDER BY clause rather then create new one, default false [internal]
*
*
* @return string
*/
protected function getOrderBy($append = false)
@@ -346,6 +370,15 @@ abstract class ApiCommand extends ApiParameter
} else {
$order .= " ORDER BY ";
}
$nat_fields = [
'`c`.`loginname`',
'`a`.`loginname`',
'`adminname`',
'`databasename`',
'`username`'
];
foreach ($orderby as $field => $by) {
$sortfield = explode('.', $field);
foreach ($sortfield as $id => $sfield) {
@@ -365,7 +398,7 @@ abstract class ApiCommand extends ApiParameter
])) {
$by = 'ASC';
}
if (\Froxlor\Settings::Get('panel.natsorting') == 1) {
if (\Froxlor\Settings::Get('panel.natsorting') == 1 && in_array($field, $nat_fields)) {
// Acts similar to php's natsort(), found in one comment at http://my.opera.com/cpr/blog/show.dml/160556
$order .= "CONCAT( IF( ASCII( LEFT( " . $field . ", 5 ) ) > 57,
LEFT( " . $field . ", 1 ), 0 ),
@@ -408,15 +441,18 @@ abstract class ApiCommand extends ApiParameter
*
* @param string $command
* @param array|null $params
*
* @param boolean $internal
* optional whether called internally, default false
*
*
* @return array
*/
protected function apiCall($command = null, $params = null)
protected function apiCall($command = null, $params = null, $internal = false)
{
$_command = explode(".", $command);
$module = __NAMESPACE__ . "\Commands\\" . $_command[0];
$function = $_command[1];
$json_result = $module::getLocal($this->getUserData(), $params)->{$function}();
$json_result = $module::getLocal($this->getUserData(), $params, $internal)->{$function}();
return json_decode($json_result, true)['data'];
}
@@ -482,7 +518,7 @@ abstract class ApiCommand extends ApiParameter
$customer_ids[] = $customer['customerid'];
}
} else {
if (! empty($customer_hide_option) && \Froxlor\Settings::IsInList('panel.customer_hide_options', $customer_hide_option)) {
if (!$this->isInternal() && ! empty($customer_hide_option) && \Froxlor\Settings::IsInList('panel.customer_hide_options', $customer_hide_option)) {
throw new \Exception("You cannot access this resource", 405);
}
$customer_ids = array(
@@ -574,8 +610,12 @@ abstract class ApiCommand extends ApiParameter
"group" => $group,
"var" => $varname
), true, true);
$content = $default;
if ($result) {
$content = $result['value'] ?? $default;
}
// @fixme html_entity_decode
$content = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result['value'] != '') ? $result['value'] : $default), $replace_arr));
$content = html_entity_decode(\Froxlor\PhpHelper::replaceVariables($content, $replace_arr));
return $content;
}

View File

@@ -51,7 +51,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -75,7 +75,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_admins']);
return $this->response(200, "successful", $result['num_admins']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -109,7 +109,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get admin '" . $result['loginname'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
$key = ($id > 0 ? "id #" . $id : "loginname '" . $loginname . "'");
throw new \Exception("Admin with " . $key . " could not be found", 404);
@@ -265,7 +265,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
'login' => $loginname
), true, true);
if (strtolower($loginname_check['loginname']) == strtolower($loginname) || strtolower($loginname_check_admin['loginname']) == strtolower($loginname)) {
if (($loginname_check && strtolower($loginname_check['loginname']) == strtolower($loginname)) || ($loginname_check_admin && strtolower($loginname_check_admin['loginname']) == strtolower($loginname))) {
\Froxlor\UI\Response::standard_error('loginnameexists', $loginname, true);
} elseif (preg_match('/^' . preg_quote(Settings::Get('customer.accountprefix'), '/') . '([0-9]+)/', $loginname)) {
// Accounts which match systemaccounts are not allowed, filtering them
@@ -364,7 +364,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Admins.get', array(
'id' => $adminid
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -677,7 +677,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Admins.get', array(
'id' => $result['adminid']
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
}
}
@@ -779,7 +779,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted admin '" . $result['loginname'] . "'");
\Froxlor\User::updateCounters();
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -821,7 +821,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result['loginfail_count'] = 0;
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] unlocked admin '" . $result['loginname'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Froxlor\Api\Commands;
use Froxlor\Database\Database;
use Froxlor\Settings;
/**
* This file is part of the Froxlor project.
* 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 API
* @since 0.10.0
*
*/
class ApiKeys extends \Froxlor\Api\ApiCommand
{
public function listing()
{}
public function listingCount()
{}
}

View File

@@ -81,7 +81,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$result = $this->apiCall('Certificates.get', array(
'id' => $domain['id']
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Domain '" . $domain['domain'] . "' already has a certificate. Did you mean to call update?", 406);
}
@@ -122,7 +122,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
if (! $result) {
throw new \Exception("Domain '" . $domain['domain'] . "' does not have a certificate.", 412);
}
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
/**
@@ -168,7 +168,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$result = $this->apiCall('Certificates.get', array(
'id' => $domain['id']
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
/**
@@ -209,7 +209,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
} else {
$certs_stmt_query .= "1 ";
}
$certs_stmt = Database::prepare($certs_stmt_query . $this->getSearchWhere($query_fields) . $this->getOrderBy() . $this->getLimit());
$certs_stmt = Database::prepare($certs_stmt_query . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
$qry_params = array_merge($qry_params, $query_fields);
Database::pexecute($certs_stmt, $qry_params, true, true);
$result = array();
@@ -222,7 +222,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
}
$result[] = $cert;
}
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -258,7 +258,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$certs_stmt = Database::prepare($certs_stmt_query);
$result = Database::pexecute_first($certs_stmt, $qry_params, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_certs']);
return $this->response(200, "successful", $result['num_certs']);
}
}
@@ -326,7 +326,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
\Froxlor\System\Cronjob::inserttask('12', $chk['domain']);
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] removed ssl-certificate for '" . $chk['domain'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Unable to determine SSL certificate. Maybe no access?", 406);
}

View File

@@ -51,7 +51,7 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
'id' => $id
), true, true);
if ($result) {
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("cronjob with id #" . $id . " could not be found", 404);
}
@@ -119,7 +119,7 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
$result = $this->apiCall('Cronjobs.get', array(
'id' => $id
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -152,7 +152,7 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -175,7 +175,7 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_crons']);
return $this->response(200, "successful", $result['num_crons']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);

View File

@@ -109,7 +109,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
\Froxlor\System\Cronjob::inserttask('20', $task_data);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] added customer-backup job for '" . $customer['loginname'] . "'. Target directory: " . $userpath);
return $this->response(200, "successfull", $task_data);
return $this->response(200, "successful", $task_data);
}
/**
@@ -168,7 +168,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
}
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list customer-backups");
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -202,7 +202,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
$result_count ++;
}
}
return $this->response(200, "successfull", $result_count);
return $this->response(200, "successful", $result_count);
}
/**
@@ -237,7 +237,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
'tid' => $entry
), true, true);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] deleted planned customer-backup #" . $entry);
return $this->response(200, "successfull", true);
return $this->response(200, "successful", true);
}
}
}

View File

@@ -60,7 +60,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -90,7 +90,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
}
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_customers']);
return $this->response(200, "successful", $result['num_customers']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -143,7 +143,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$result['custom_notes'] = "";
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get customer '" . $result['loginname'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
$key = ($id > 0 ? "id #" . $id : "loginname '" . $loginname . "'");
throw new \Exception("Customer with " . $key . " could not be found", 404);
@@ -183,7 +183,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* optional, whether to show the content of custom_notes to the customer, default 0 (false)
* @param string $new_loginname
* optional, if empty generated automatically using customer-prefix and increasing number
* @param string $password
* @param string $new_customer_password
* optional, if empty generated automatically and send to the customer's email if $sendpassword is 1
* @param bool $sendpassword
* optional, whether to send the password to the customer after creation, default 0 (false)
@@ -411,7 +411,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
), true, true);
$mysql_maxlen = \Froxlor\Database\Database::getSqlUsernameLength() - strlen(Settings::Get('customer.mysqlprefix'));
if (strtolower($loginname_check['loginname']) == strtolower($loginname) || strtolower($loginname_check_admin['loginname']) == strtolower($loginname)) {
if (($loginname_check && strtolower($loginname_check['loginname']) == strtolower($loginname)) || ($loginname_check_admin && strtolower($loginname_check_admin['loginname']) == strtolower($loginname))) {
\Froxlor\UI\Response::standard_error('loginnameexists', $loginname, true);
} elseif (! \Froxlor\Validate\Validate::validateUsername($loginname, Settings::Get('panel.unix_names'), $mysql_maxlen)) {
if (strlen($loginname) > $mysql_maxlen) {
@@ -689,6 +689,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
'name' => $name,
'company' => $company
)),
'CUSTOMER_NO' => $customernumber,
'USERNAME' => $loginname,
'PASSWORD' => $password,
'SERVER_HOSTNAME' => $srv_hostname,
@@ -742,7 +743,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$result = $this->apiCall('Customers.get', array(
'loginname' => $loginname
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("No more resources available", 406);
}
@@ -1339,7 +1340,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$result = $this->apiCall('Customers.get', array(
'id' => $result['customerid']
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
/**
@@ -1409,7 +1410,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
'id' => $id
), true, true);
// first gather all domain-id's to clean up panel_domaintoip and dns-entries accordingly
// first gather all domain-id's to clean up panel_domaintoip, dns-entries and certificates accordingly
$did_stmt = Database::prepare("SELECT `id` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id");
Database::pexecute($did_stmt, array(
'id' => $id
@@ -1425,6 +1426,11 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
Database::pexecute($stmt, array(
'did' => $row['id']
), true, true);
// remove domain->certificates entries
$stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :did");
Database::pexecute($stmt, array(
'did' => $row['id']
), true, true);
}
// remove customer domains
$stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id");
@@ -1567,7 +1573,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
\Froxlor\System\Cronjob::inserttask('10');
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted customer '" . $result['loginname'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -1609,7 +1615,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$result['loginfail_count'] = 0;
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] unlocked customer '" . $result['loginname'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -1679,7 +1685,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$result = $this->apiCall('Customers.get', array(
'id' => $c_result['customerid']
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}

View File

@@ -96,7 +96,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
), true, true);
// duplicate check
if ($path_dupe_check['path'] == $path) {
if ($path_dupe_check && $path_dupe_check['path'] == $path) {
\Froxlor\UI\Response::standard_error('errordocpathdupe', $userpath, true);
}
@@ -128,7 +128,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = $this->apiCall('DirOptions.get', array(
'id' => $id
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
/**
@@ -186,7 +186,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get directory options for '" . $result['path'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
$key = "id #" . $id;
throw new \Exception("Directory option with " . $key . " could not be found", 404);
@@ -275,7 +275,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = $this->apiCall('DirOptions.get', array(
'id' => $id
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
/**
@@ -309,14 +309,13 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$query_fields = array();
$result_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_HTACCESS . "`
WHERE `customerid` IN (" . implode(', ', $customer_ids) . ")" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit()
);
WHERE `customerid` IN (" . implode(', ', $customer_ids) . ")" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
Database::pexecute($result_stmt, $query_fields, true, true);
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list directory-options");
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -348,7 +347,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_htaccess']);
return $this->response(200, "successful", $result['num_htaccess']);
}
}
@@ -415,7 +414,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
), true, true);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted directory-option for '" . str_replace($customer_data['documentroot'], '/', $result['path']) . "'");
\Froxlor\System\Cronjob::inserttask('1');
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
/**

View File

@@ -81,7 +81,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
$password_enc = \Froxlor\System\Crypt::makeCryptPassword($password, true);
// duplicate check
if ($username_path_check['username'] == $username && $username_path_check['path'] == $path) {
if ($username_path_check && $username_path_check['username'] == $username && $username_path_check['path'] == $path) {
\Froxlor\UI\Response::standard_error('userpathcombinationdupe', '', true);
} elseif ($password == $username) {
\Froxlor\UI\Response::standard_error('passwordshouldnotbeusername', '', true);
@@ -111,7 +111,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
$result = $this->apiCall('DirProtections.get', array(
'id' => $id
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
/**
@@ -173,7 +173,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get directory protection for '" . $result['path'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
$key = ($id > 0 ? "id #" . $id : "username '" . $username . "'");
throw new \Exception("Directory protection with " . $key . " could not be found", 404);
@@ -258,7 +258,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
$result = $this->apiCall('DirProtections.get', array(
'id' => $result['id']
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
/**
@@ -298,7 +298,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
$result[] = $row;
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list directory-protections");
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -330,7 +330,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_htpasswd']);
return $this->response(200, "successful", $result['num_htpasswd']);
}
}
@@ -386,6 +386,6 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted htpasswd for '" . $result['username'] . " (" . $result['path'] . ")'");
\Froxlor\System\Cronjob::inserttask('1');
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
}

View File

@@ -309,7 +309,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$result = $this->apiCall('DomainZones.get', array(
'id' => $id
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
// return $errors
throw new \Exception(implode("\n", $errors));
@@ -360,7 +360,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$zonefile = (string) $zone;
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get dns-zone for '" . $result['domain'] . "'");
return $this->response(200, "successfull", explode("\n", $zonefile));
return $this->response(200, "successful", explode("\n", $zonefile));
}
/**
@@ -420,7 +420,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
while ($row = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -464,7 +464,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'did' => $id
), true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_dns']);
return $this->response(200, "successful", $result['num_dns']);
}
}
@@ -511,8 +511,8 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
if ($del_stmt->rowCount() > 0) {
// re-generate bind configs
\Froxlor\System\Cronjob::inserttask('4');
return $this->response(200, "successfull", true);
return $this->response(200, "successful", true);
}
return $this->response(304, "successfull", true);
return $this->response(304, "successful", true);
}
}

View File

@@ -68,7 +68,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
}
$result[] = $row;
}
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -100,7 +100,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
}
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_domains']);
return $this->response(200, "successful", $result['num_domains']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -156,7 +156,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$result['ipsandports'] = $this->getIpsForDomain($result['id']);
}
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get domain '" . $result['domain'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
$key = ($id > 0 ? "id #" . $id : "domainname '" . $domainname . "'");
throw new \Exception("Domain with " . $key . " could not be found", 404);
@@ -168,14 +168,15 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* get ips connected to given domain as array
*
* @param number $domain_id
* @param bool $ssl_only
* optional, return only ssl enabled ip's, default false
* @return array
*/
private function getIpsForDomain($domain_id = 0)
private function getIpsForDomain($domain_id = 0, $ssl_only = false)
{
$resultips_stmt = Database::prepare("
SELECT `ips`.* FROM `" . TABLE_DOMAINTOIP . "` AS `dti`, `" . TABLE_PANEL_IPSANDPORTS . "` AS `ips`
WHERE `dti`.`id_ipandports` = `ips`.`id` AND `dti`.`id_domain` = :domainid
");
WHERE `dti`.`id_ipandports` = `ips`.`id` AND `dti`.`id_domain` = :domainid " . ($ssl_only ? " AND `ips`.`ssl` = '1'" : ""));
Database::pexecute($resultips_stmt, array(
'domainid' => $domain_id
@@ -260,6 +261,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional, list of ssl-enabled ip/port id's to assign to this domain, default empty
* @param bool $dont_use_default_ssl_ipandport_if_empty
* optional, do NOT set the systems default ssl ip addresses if none are given via $ssl_ipandport parameter
* @param bool $sslenabled
* optional, whether or not SSL is enabled for this domain, regardless of the assigned ssl-ips, default 1 (true)
* @param bool $http2
* optional, whether to enable http/2 for this domain (requires to be enabled in the settings), default 0 (false)
* @param int $hsts_maxage
@@ -270,6 +273,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional whether or not to preload HSTS header value
* @param bool $ocsp_stapling
* optional whether to enable ocsp-stapling for this domain. default 0 (false), requires SSL
* @param bool $honorcipherorder
* optional whether to honor the (server) cipher order for this domain. default 0 (false), requires SSL
* @param bool $sessiontickets
* optional whether to enable or disable TLS sessiontickets (RFC 5077) for this domain. default 1 (true), requires SSL
* @param bool $override_tls
* optional whether or not to override system-tls settings like protocol, ssl-ciphers and if applicable tls-1.3 ciphers, requires change_serversettings flag for the admin, default false
* @param array $ssl_protocols
@@ -324,11 +331,14 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$letsencrypt = $this->getBoolParam('letsencrypt', true, 0);
$dont_use_default_ssl_ipandport_if_empty = $this->getBoolParam('dont_use_default_ssl_ipandport_if_empty', true, 0);
$p_ssl_ipandports = $this->getParam('ssl_ipandport', true, $dont_use_default_ssl_ipandport_if_empty ? array() : explode(',', Settings::Get('system.defaultsslip')));
$sslenabled = $this->getBoolParam('sslenabled', true, 1);
$http2 = $this->getBoolParam('http2', true, 0);
$hsts_maxage = $this->getParam('hsts_maxage', true, 0);
$hsts_sub = $this->getBoolParam('hsts_sub', true, 0);
$hsts_preload = $this->getBoolParam('hsts_preload', true, 0);
$ocsp_stapling = $this->getBoolParam('ocsp_stapling', true, 0);
$honorcipherorder = $this->getBoolParam('honorcipherorder', true, 0);
$sessiontickets = $this->getBoolParam('sessiontickets', true, 1);
$override_tls = $this->getBoolParam('override_tls', true, 0);
$p_ssl_protocols = array();
@@ -344,7 +354,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
}
// validation
if ($p_domain == Settings::Get('system.hostname')) {
$p_domain = strtolower($p_domain);
if ($p_domain == strtolower(Settings::Get('system.hostname'))) {
\Froxlor\UI\Response::standard_error('admin_domain_emailsystemhostname', '', true);
}
@@ -663,9 +674,9 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
), '', true);
} elseif ($customerid == 0) {
\Froxlor\UI\Response::standard_error('adduserfirst', '', true);
} elseif (strtolower($domain_check['domain']) == strtolower($domain)) {
} elseif ($domain_check && strtolower($domain_check['domain']) == strtolower($domain)) {
\Froxlor\UI\Response::standard_error('domainalreadyexists', $idna_convert->decode($domain), true);
} elseif ($aliasdomain_check['id'] != $aliasdomain) {
} elseif ($aliasdomain_check && $aliasdomain_check['id'] != $aliasdomain) {
\Froxlor\UI\Response::standard_error('domainisaliasorothercustomer', '', true);
} else {
$wwwserveralias = ($serveraliasoption == '1') ? '1' : '0';
@@ -673,6 +684,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$ins_data = array(
'domain' => $domain,
'domain_ace' => $idna_convert->decode($domain),
'customerid' => $customerid,
'adminid' => $adminid,
'documentroot' => $documentroot,
@@ -712,12 +724,16 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
'override_tls' => $override_tls,
'ssl_protocols' => implode(",", $ssl_protocols),
'ssl_cipher_list' => $ssl_cipher_list,
'tlsv13_cipher_list' => $tlsv13_cipher_list
'tlsv13_cipher_list' => $tlsv13_cipher_list,
'sslenabled' => $sslenabled,
'honorcipherorder' => $honorcipherorder,
'sessiontickets' => $sessiontickets
);
$ins_stmt = Database::prepare("
INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET
`domain` = :domain,
`domain_ace` = :domain_ace,
`customerid` = :customerid,
`adminid` = :adminid,
`documentroot` = :documentroot,
@@ -760,7 +776,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`override_tls` = :override_tls,
`ssl_protocols` = :ssl_protocols,
`ssl_cipher_list` = :ssl_cipher_list,
`tlsv13_cipher_list` = :tlsv13_cipher_list
`tlsv13_cipher_list` = :tlsv13_cipher_list,
`ssl_enabled` = :sslenabled,
`ssl_honorcipherorder` = :honorcipherorder,
`ssl_sessiontickets`= :sessiontickets
");
Database::pexecute($ins_stmt, $ins_data, true, true);
$domainid = Database::lastInsertId();
@@ -809,7 +828,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$result = $this->apiCall('Domains.get', array(
'domainname' => $domain
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
}
throw new \Exception("No more resources available", 406);
@@ -894,6 +913,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional, list of ssl-enabled ip/port id's to assign to this domain, if left empty, the current set value is being used, to remove all ssl ips use $remove_ssl_ipandport
* @param bool $remove_ssl_ipandport
* optional, if set to true and no $ssl_ipandport value is given, the ip's get removed, otherwise, the currently set value is used, default false
* @param bool $sslenabled
* optional, whether or not SSL is enabled for this domain, regardless of the assigned ssl-ips, default 1 (true)
* @param bool $http2
* optional, whether to enable http/2 for this domain (requires to be enabled in the settings), default 0 (false)
* @param int $hsts_maxage
@@ -904,6 +925,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional whether or not to preload HSTS header value
* @param bool $ocsp_stapling
* optional whether to enable ocsp-stapling for this domain. default 0 (false), requires SSL
* @param bool $honorcipherorder
* optional whether to honor the (server) cipher order for this domain. default 0 (false), requires SSL
* @param bool $sessiontickets
* optional whether to enable or disable TLS sessiontickets (RFC 5077) for this domain. default 1 (true), requires SSL
*
* @access admin
* @throws \Exception
@@ -964,11 +989,14 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$p_ssl_ipandports = $this->getParam('ssl_ipandport', true, $remove_ssl_ipandport ? array(
- 1
) : null);
$sslenabled = $this->getBoolParam('sslenabled', true, $result['ssl_enabled']);
$http2 = $this->getBoolParam('http2', true, $result['http2']);
$hsts_maxage = $this->getParam('hsts_maxage', true, $result['hsts']);
$hsts_sub = $this->getBoolParam('hsts_sub', true, $result['hsts_sub']);
$hsts_preload = $this->getBoolParam('hsts_preload', true, $result['hsts_preload']);
$ocsp_stapling = $this->getBoolParam('ocsp_stapling', true, $result['ocsp_stapling']);
$honorcipherorder = $this->getBoolParam('honorcipherorder', true, $result['ssl_honorcipherorder']);
$sessiontickets = $this->getBoolParam('sessiontickets', true, $result['ssl_sessiontickets']);
$override_tls = $this->getBoolParam('override_tls', true, $result['override_tls']);
@@ -1197,7 +1225,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$writeaccesslog = $result['writeaccesslog'];
$writeerrorlog = $result['writeerrorlog'];
$documentroot = $result['documentroot'];
$ssl_protocols = $p_ssl_protocols;
$override_tls = $result['override_tls'];
}
@@ -1546,6 +1574,9 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$update_data['ssl_protocols'] = implode(",", $ssl_protocols);
$update_data['ssl_cipher_list'] = $ssl_cipher_list;
$update_data['tlsv13_cipher_list'] = $tlsv13_cipher_list;
$update_data['sslenabled'] = $sslenabled;
$update_data['honorcipherorder'] = $honorcipherorder;
$update_data['sessiontickets'] = $sessiontickets;
$update_data['id'] = $id;
$update_stmt = Database::prepare("
@@ -1588,7 +1619,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`override_tls` = :override_tls,
`ssl_protocols` = :ssl_protocols,
`ssl_cipher_list` = :ssl_cipher_list,
`tlsv13_cipher_list` = :tlsv13_cipher_list
`tlsv13_cipher_list` = :tlsv13_cipher_list,
`ssl_enabled` = :sslenabled,
`ssl_honorcipherorder` = :honorcipherorder,
`ssl_sessiontickets` = :sessiontickets
WHERE `id` = :id
");
Database::pexecute($update_stmt, $update_data, true, true);
@@ -1599,10 +1633,15 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$_update_data['openbasedir'] = $openbasedir;
$_update_data['mod_fcgid_starter'] = $mod_fcgid_starter;
$_update_data['mod_fcgid_maxrequests'] = $mod_fcgid_maxrequests;
$_update_data['notryfiles'] = $notryfiles;
$_update_data['writeaccesslog'] = $writeaccesslog;
$_update_data['writeerrorlog'] = $writeerrorlog;
$_update_data['override_tls'] = $override_tls;
$_update_data['ssl_protocols'] = implode(",", $ssl_protocols);
$_update_data['ssl_cipher_list'] = $ssl_cipher_list;
$_update_data['tlsv13_cipher_list'] = $tlsv13_cipher_list;
$_update_data['honorcipherorder'] = $honorcipherorder;
$_update_data['sessiontickets'] = $sessiontickets;
$_update_data['parentdomainid'] = $id;
// if php config is to be set for all subdomains, check here
@@ -1627,10 +1666,15 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`openbasedir` = :openbasedir,
`mod_fcgid_starter` = :mod_fcgid_starter,
`mod_fcgid_maxrequests` = :mod_fcgid_maxrequests,
`notryfiles` = :notryfiles,
`writeaccesslog` = :writeaccesslog,
`writeerrorlog` = :writeerrorlog,
`override_tls` = :override_tls,
`ssl_protocols` = :ssl_protocols,
`ssl_cipher_list` = :ssl_cipher_list,
`tlsv13_cipher_list` = :tlsv13_cipher_list
`tlsv13_cipher_list` = :tlsv13_cipher_list,
`ssl_honorcipherorder` = :honorcipherorder,
`ssl_sessiontickets` = :sessiontickets
" . $update_phpconfig . $upd_specialsettings . $updatechildren . $update_sslredirect . "
WHERE `parentdomainid` = :parentdomainid
");
@@ -1722,7 +1766,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$idna_convert = new \Froxlor\Idna\IdnaWrapper();
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] updated domain '" . $idna_convert->decode($result['domain']) . "'");
return $this->response(200, "successfull", $update_data);
return $this->response(200, "successful", $update_data);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -1883,7 +1927,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
\Froxlor\System\Cronjob::inserttask('1');
// Using nameserver, insert a task which rebuilds the server config
\Froxlor\System\Cronjob::inserttask('4');
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}

View File

@@ -100,8 +100,8 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
// alternative email address to send info to
if (Settings::Get('panel.sendalternativemail') == 1) {
$alternative_email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($alternative_email, 'alternative_email', '', '', array(), true));
if (! \Froxlor\Validate\Validate::validateEmail($alternative_email)) {
\Froxlor\UI\Response::standard_error('emailiswrong', $alternative_email, true);
if (!empty($alternative_email) && ! \Froxlor\Validate\Validate::validateEmail($alternative_email)) {
\Froxlor\UI\Response::standard_error('alternativeemailiswrong', $alternative_email, true);
}
} else {
$alternative_email = '';
@@ -192,7 +192,12 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
$replace_arr = array(
'EMAIL' => $email_full,
'USERNAME' => $username,
'PASSWORD' => $password
'PASSWORD' => $password,
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($customer),
'NAME' => $customer['name'],
'FIRSTNAME' => $customer['firstname'],
'COMPANY' => $customer['company'],
'CUSTOMER_NO' => $customer['customernumber']
);
// get the customers admin
@@ -231,7 +236,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
$this->mailer()->clearAddresses();
// customer wants to send the e-mail to an alternative email address too
if (Settings::Get('panel.sendalternativemail') == 1) {
if (Settings::Get('panel.sendalternativemail') == 1 && !empty($alternative_email)) {
// get template for mail subject
$mail_subject = $this->getMailTemplate($customer, 'mails', 'pop_success_alternative_subject', $replace_arr, $this->lng['mails']['pop_success_alternative']['subject']);
// get template for mail body
@@ -268,7 +273,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
$result = $this->apiCall('Emails.get', array(
'emailaddr' => $result['email_full']
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("No more resources available", 406);
}
@@ -384,7 +389,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
$result = $this->apiCall('Emails.get', array(
'emailaddr' => $result['email_full']
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
/**
@@ -487,6 +492,6 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
Customers::decreaseUsage($customer['customerid'], 'email_quota_used', '', $quota);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted email account for '" . $result['email_full'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
}

View File

@@ -102,7 +102,7 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
$result = $this->apiCall('Emails.get', array(
'emailaddr' => $result['email_full']
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("No more resources available", 406);
}
@@ -168,7 +168,7 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
];
}
return $this->response(200, "successfull", [
return $this->response(200, "successful", [
'count' => count($destination),
'list' => $destination
]);
@@ -210,7 +210,7 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
$result['destination'] = explode(' ', $result['destination']);
return $this->response(200, "successfull", count($result['destination']));
return $this->response(200, "successful", count($result['destination']));
}
/**
@@ -280,7 +280,7 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
$result = $this->apiCall('Emails.get', array(
'emailaddr' => $result['email_full']
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Unknown forwarder id", 404);
}

View File

@@ -62,9 +62,10 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
}
// check domain and whether it's an email-enabled domain
// use internal call because the customer might have 'domains' in customer_hide_options
$domain_check = $this->apiCall('SubDomains.get', array(
'domainname' => $domain
));
), true);
if ($domain_check['isemaildomain'] == 0) {
\Froxlor\UI\Response::standard_error('maindomainnonexist', $domain, true);
}
@@ -106,10 +107,12 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
);
$email_check = Database::pexecute_first($stmt, $params, true, true);
if (strtolower($email_check['email_full']) == strtolower($email_full)) {
\Froxlor\UI\Response::standard_error('emailexistalready', $email_full, true);
} elseif ($email_check['email'] == $email) {
\Froxlor\UI\Response::standard_error('youhavealreadyacatchallforthisdomain', '', true);
if ($email_check) {
if (strtolower($email_check['email_full']) == strtolower($email_full)) {
\Froxlor\UI\Response::standard_error('emailexistalready', $email_full, true);
} elseif ($email_check['email'] == $email) {
\Froxlor\UI\Response::standard_error('youhavealreadyacatchallforthisdomain', '', true);
}
}
$stmt = Database::prepare("
@@ -137,7 +140,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Emails.get', array(
'emailaddr' => $email_full
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("No more resources available", 406);
}
@@ -173,7 +176,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get email address '" . $result['email_full'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
$key = ($id > 0 ? "id #" . $id : "emailaddr '" . $emailaddr . "'");
throw new \Exception("Email address with " . $key . " could not be found", 404);
@@ -233,6 +236,19 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$iscatchall = '1';
$email_parts = explode('@', $result['email_full']);
$email = '@' . $email_parts[1];
// catchall check
$stmt = Database::prepare("
SELECT `email_full` FROM `" . TABLE_MAIL_VIRTUAL . "`
WHERE `email` = :email AND `customerid` = :cid AND `iscatchall` = '1'
");
$params = array(
"email" => $email,
"cid" => $customer['customerid']
);
$email_check = Database::pexecute_first($stmt, $params, true, true);
if ($email_check) {
\Froxlor\UI\Response::standard_error('youhavealreadyacatchallforthisdomain', '', true);
}
} else {
$iscatchall = '0';
$email = $result['email_full'];
@@ -255,7 +271,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Emails.get', array(
'emailaddr' => $result['email_full']
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
/**
@@ -273,7 +289,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
*
*
* @access admin, customer
* @throws \Exception
* @return string json-encoded array count|list
@@ -294,7 +310,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result[] = $row;
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list email-addresses");
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -324,7 +340,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_emails']);
return $this->response(200, "successful", $result['num_emails']);
}
}
@@ -402,6 +418,6 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
Customers::decreaseUsage($customer['customerid'], 'emails_used');
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted email address '" . $result['email_full'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
}

View File

@@ -32,7 +32,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
*
*
* @access admin
* @throws \Exception
* @return string json-encoded array count|list
@@ -70,7 +70,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$fpmdaemons[] = $row;
}
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($fpmdaemons),
'list' => $fpmdaemons
));
@@ -93,7 +93,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_fpms']);
return $this->response(200, "successful", $result['num_fpms']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -121,7 +121,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
'id' => $id
), true, true);
if ($result) {
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("fpm-daemon with id #" . $id . " could not be found", 404);
}
@@ -135,21 +135,23 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* @param string $reload_cmd
* @param string $config_dir
* @param string $pm
* optional, process-manager, one of 'static', 'dynamic' or 'ondemand', default 'static'
* optional, process-manager, one of 'static', 'dynamic' or 'ondemand', default 'dynamic'
* @param int $max_children
* optional, default 0
* optional, default 5
* @param int $start_servers
* optional, default 0
* optional, default 2
* @param int $min_spare_servers
* optional, default 0
* optional, default 1
* @param int $max_spare_servers
* optional, default 0
* optional, default 3
* @param int $max_requests
* optional, default 0
* @param int $idle_timeout
* optional, default 0
* optional, default 10
* @param string $limit_extensions
* optional, limit execution to the following extensions, default '.php'
* @param string $custom_config
* optional, custom settings appended to phpfpm pool configuration
*
* @access admin
* @throws \Exception
@@ -165,14 +167,15 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$config_dir = $this->getParam('config_dir');
// parameters
$pmanager = $this->getParam('pm', true, 'static');
$max_children = $this->getParam('max_children', true, 0);
$start_servers = $this->getParam('start_servers', true, 0);
$min_spare_servers = $this->getParam('min_spare_servers', true, 0);
$max_spare_servers = $this->getParam('max_spare_servers', true, 0);
$pmanager = $this->getParam('pm', true, 'dynamic');
$max_children = $this->getParam('max_children', true, 5);
$start_servers = $this->getParam('start_servers', true, 2);
$min_spare_servers = $this->getParam('min_spare_servers', true, 1);
$max_spare_servers = $this->getParam('max_spare_servers', true, 3);
$max_requests = $this->getParam('max_requests', true, 0);
$idle_timeout = $this->getParam('idle_timeout', true, 0);
$idle_timeout = $this->getParam('idle_timeout', true, 10);
$limit_extensions = $this->getParam('limit_extensions', true, '.php');
$custom_config = $this->getParam('custom_config', true, '');
// validation
$description = \Froxlor\Validate\Validate::validate($description, 'description', '', '', array(), true);
@@ -206,7 +209,8 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
`max_spare_servers` = :max_spare_servers,
`max_requests` = :max_requests,
`idle_timeout` = :idle_timeout,
`limit_extensions` = :limit_extensions
`limit_extensions` = :limit_extensions,
`custom_config` = :custom_config
");
$ins_data = array(
'desc' => $description,
@@ -219,7 +223,8 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
'max_spare_servers' => $max_spare_servers,
'max_requests' => $max_requests,
'idle_timeout' => $idle_timeout,
'limit_extensions' => $limit_extensions
'limit_extensions' => $limit_extensions,
'custom_config' => $custom_config
);
Database::pexecute($ins_stmt, $ins_data);
$id = Database::lastInsertId();
@@ -229,7 +234,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = $this->apiCall('FpmDaemons.get', array(
'id' => $id
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -246,21 +251,23 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* @param string $config_dir
* optional
* @param string $pm
* optional, process-manager, one of 'static', 'dynamic' or 'ondemand', default 'static'
* optional, process-manager, one of 'static', 'dynamic' or 'ondemand', default 'dynamic'
* @param int $max_children
* optional, default 0
* optional, default 5
* @param int $start_servers
* optional, default 0
* optional, default 2
* @param int $min_spare_servers
* optional, default 0
* optional, default 1
* @param int $max_spare_servers
* optional, default 0
* optional, default 3
* @param int $max_requests
* optional, default 0
* @param int $idle_timeout
* optional, default 0
* optional, default 10
* @param string $limit_extensions
* optional, limit execution to the following extensions, default '.php'
* @param string $custom_config
* optional, custom settings appended to phpfpm pool configuration
*
* @access admin
* @throws \Exception
@@ -289,6 +296,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$max_requests = $this->getParam('max_requests', true, $result['max_requests']);
$idle_timeout = $this->getParam('idle_timeout', true, $result['idle_timeout']);
$limit_extensions = $this->getParam('limit_extensions', true, $result['limit_extensions']);
$custom_config = $this->getParam('custom_config', true, $result['custom_config']);
// validation
$description = \Froxlor\Validate\Validate::validate($description, 'description', '', '', array(), true);
@@ -322,7 +330,8 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
`max_spare_servers` = :max_spare_servers,
`max_requests` = :max_requests,
`idle_timeout` = :idle_timeout,
`limit_extensions` = :limit_extensions
`limit_extensions` = :limit_extensions,
`custom_config` = :custom_config
WHERE `id` = :id
");
$upd_data = array(
@@ -337,6 +346,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
'max_requests' => $max_requests,
'idle_timeout' => $idle_timeout,
'limit_extensions' => $limit_extensions,
'custom_config' => $custom_config,
'id' => $id
);
Database::pexecute($upd_stmt, $upd_data, true, true);
@@ -346,7 +356,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = $this->apiCall('FpmDaemons.get', array(
'id' => $id
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -392,7 +402,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
\Froxlor\System\Cronjob::inserttask('1');
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] fpm-daemon setting '" . $result['description'] . "' has been deleted by '" . $this->getUserDetail('loginname') . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}

View File

@@ -42,7 +42,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
try {
$latestversion = \Froxlor\Http\HttpClient::urlGet(UPDATE_URI, true, 3);
} catch (\Exception $e) {
$latestversion = \Froxlor\Froxlor::getVersion()."|Version-check currently unavailable, please try again later";
$latestversion = \Froxlor\Froxlor::getVersion() . "|Version-check currently unavailable, please try again later";
}
$latestversion = explode('|', $latestversion);
@@ -74,7 +74,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
// zum update schritt #1 -> download
if ($isnewerversion == 1) {
$text = 'There is a newer version available: "' . $_version . '" (Your current version is: ' . $this->version . ')';
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'isnewerversion' => $isnewerversion,
'version' => $_version,
'message' => $text,
@@ -83,7 +83,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
));
} elseif ($isnewerversion == 0) {
// all good
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'isnewerversion' => $isnewerversion,
'version' => $version_label,
'message' => "",
@@ -95,7 +95,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
}
}
}
return $this->response(300, "successfull", array(
return $this->response(300, "successful", array(
'isnewerversion' => 0,
'version' => $this->version . $this->branding,
'message' => 'Version-check not available due to missing php-curl extension',
@@ -129,7 +129,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
\Froxlor\System\Cronjob::inserttask('4');
// cron.d file
\Froxlor\System\Cronjob::inserttask('99');
return $this->response(200, "successfull", true);
return $this->response(200, "successful", true);
} catch (\Exception $e) {
throw new \Exception($e->getMessage(), 406);
}
@@ -149,7 +149,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "User " . $this->getUserDetail('loginname') . " exported settings");
$json_export = \Froxlor\SImExporter::export();
return $this->response(200, "successfull", $json_export);
return $this->response(200, "successful", $json_export);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -175,7 +175,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
'value' => $row['value']
);
}
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -197,7 +197,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
{
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
$setting = $this->getParam('key');
return $this->response(200, "successfull", Settings::Get($setting));
return $this->response(200, "successful", Settings::Get($setting));
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -216,7 +216,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
*/
public function updateSetting()
{
// currently not implemented as it required validation too so no wrong settings are being stored via API
// currently not implemented as it requires validation too so no wrong settings are being stored via API
throw new \Exception("Not available yet.", 501);
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
@@ -227,7 +227,38 @@ class Froxlor extends \Froxlor\Api\ApiCommand
throw new \Exception("Setting '" . $setting . "' could not be found");
}
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] Changing setting '" . $setting . "' from '" . $oldvalue . "' to '" . $value . "'");
return $this->response(200, "successfull", Settings::Set($setting, $value, true));
return $this->response(200, "successful", Settings::Set($setting, $value, true));
}
throw new \Exception("Not allowed to execute given command.", 403);
}
/**
* returns a random password based on froxlor settings for min-length, included characters, etc.
*
* @access admin, customer
* @return string
*/
public function generatePassword()
{
return $this->response(200, "successful", \Froxlor\System\Crypt::generatePassword());
}
/**
* can be used to remotely run the integritiy checks froxlor implements
*
* @access admin
* @throws \Exception
* @return string
*/
public function integrityCheck()
{
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
$integrity = new \Froxlor\Database\IntegrityCheck();
$result = $integrity->checkAll();
if ($result) {
return $this->response(200, "successful", "OK");
}
throw new \Exception("Some checks failed.", 406);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -302,7 +333,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
}
// return the list
return $this->response(200, "successfull", $functions);
return $this->response(200, "successful", $functions);
}
/**

View File

@@ -227,6 +227,10 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
$replace_arr = array(
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($customer),
'CUST_NAME' => \Froxlor\User::getCorrectUserSalutation($customer), // < keep this for compatibility
'NAME' => $customer['name'],
'FIRSTNAME' => $customer['firstname'],
'COMPANY' => $customer['company'],
'CUSTOMER_NO' => $customer['customernumber'],
'USR_NAME' => $username,
'USR_PASS' => $password,
'USR_PATH' => \Froxlor\FileDir::makeCorrectDir(str_replace($customer['documentroot'], "/", $path))
@@ -264,7 +268,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
$result = $this->apiCall('Ftps.get', array(
'username' => $username
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
}
throw new \Exception("No more resources available", 406);
@@ -325,7 +329,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get ftp-user '" . $result['username'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
$key = ($id > 0 ? "id #" . $id : "username '" . $username . "'");
throw new \Exception("FTP user with " . $key . " could not be found", 404);
@@ -335,7 +339,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
* update a given ftp-user by id or username
*
* @param int $id
* optional, the customer-id
* optional, the ftp-user-id
* @param string $username
* optional, the username
* @param string $ftp_password
@@ -450,7 +454,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
'username' => $result['username']
));
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] updated ftp-user '" . $result['username'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
/**
@@ -486,7 +490,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
$result[] = $row;
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list ftp-users");
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -514,7 +518,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_ftps']);
return $this->response(200, "successful", $result['num_ftps']);
}
}
@@ -622,6 +626,6 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
Customers::decreaseUsage($customer_data['customerid'], 'ftps_used', $resetaccnumber);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] deleted ftp-user '" . $result['username'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
}

View File

@@ -57,7 +57,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -85,7 +85,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
}
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_plans']);
return $this->response(200, "successful", $result['num_plans']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -120,7 +120,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get hosting-plan '" . $result['name'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
$key = ($id > 0 ? "id #" . $id : "planname '" . $planname . "'");
throw new \Exception("Hosting-plan with " . $key . " could not be found", 404);
@@ -246,7 +246,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$result = $this->apiCall('HostingPlans.get', array(
'planname' => $name
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -393,7 +393,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
);
Database::pexecute($upd_stmt, $update_data, true, true);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] updated hosting-plan '" . $result['name'] . "'");
return $this->response(200, "successfull", $update_data);
return $this->response(200, "successful", $update_data);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -431,7 +431,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
'id' => $id
), true, true);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted hosting-plan '" . $result['name'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}

View File

@@ -56,7 +56,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -82,7 +82,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
SELECT COUNT(*) as num_ips FROM `" . TABLE_PANEL_IPSANDPORTS . "` " . $ip_where);
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_ips']);
return $this->response(200, "successful", $result['num_ips']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -116,7 +116,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
), true, true);
if ($result) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get ip " . $result['ip'] . " " . $result['port']);
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("IP/port with id #" . $id . " could not be found", 404);
}
@@ -170,7 +170,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
{
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip'), false, 'invalidip', false, false, false, false, true);
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip'), false, 'invalidip', false, true, false, false, true);
$port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, 80), 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array(
'stringisempty',
'myport'
@@ -255,7 +255,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'port' => $port
));
if ($result_checkfordouble['id'] != '') {
if ($result_checkfordouble && $result_checkfordouble['id'] != '') {
\Froxlor\UI\Response::standard_error('myipnotdouble', '', true);
}
@@ -307,7 +307,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$result = $this->apiCall('IpsAndPorts.get', array(
'id' => $ins_data['id']
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -367,7 +367,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'id' => $id
));
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip', true, $result['ip']), false, 'invalidip', false, false, false, false, true);
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip', true, $result['ip']), false, 'invalidip', false, true, false, false, true);
$port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, $result['port']), 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array(
'stringisempty',
'myport'
@@ -462,9 +462,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$docroot = '';
}
if ($result['ip'] != $ip && $result['ip'] == Settings::Get('system.ipaddress') && $result_sameipotherport['id'] == '') {
if ($result['ip'] != $ip && $result['ip'] == Settings::Get('system.ipaddress') && $result_sameipotherport == false) {
\Froxlor\UI\Response::standard_error('cantchangesystemip', '', true);
} elseif ($result_checkfordouble['id'] != '' && $result_checkfordouble['id'] != $id) {
} elseif ($result_checkfordouble && $result_checkfordouble['id'] != '' && $result_checkfordouble['id'] != $id) {
\Froxlor\UI\Response::standard_error('myipnotdouble', '', true);
} else {
@@ -514,7 +514,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$result = $this->apiCall('IpsAndPorts.get', array(
'id' => $result['id']
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -560,7 +560,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'ip' => $result['ip']
));
if (($result['ip'] != Settings::Get('system.ipaddress')) || ($result['ip'] == Settings::Get('system.ipaddress') && $result_sameipotherport['id'] != '')) {
if (($result['ip'] != Settings::Get('system.ipaddress')) || ($result['ip'] == Settings::Get('system.ipaddress') && $result_sameipotherport != false)) {
$del_stmt = Database::prepare("
DELETE FROM `" . TABLE_PANEL_IPSANDPORTS . "`
@@ -583,7 +583,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
\Froxlor\System\Cronjob::inserttask('4');
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted IP/port '" . $result['ip'] . ":" . $result['port'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
} else {
\Froxlor\UI\Response::standard_error('cantdeletesystemip', '', true);
}

View File

@@ -125,6 +125,10 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$replace_arr = array(
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($userinfo),
'CUST_NAME' => \Froxlor\User::getCorrectUserSalutation($userinfo), // < keep this for compatibility
'NAME' => $userinfo['name'],
'FIRSTNAME' => $userinfo['firstname'],
'COMPANY' => $userinfo['company'],
'CUSTOMER_NO' => $userinfo['customernumber'],
'DB_NAME' => $username,
'DB_PASS' => $password,
'DB_DESC' => $databasedescription,
@@ -165,7 +169,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Mysqls.get', array(
'dbname' => $username
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
/**
@@ -252,9 +256,9 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
), true, true);
$mbdata = $mbdata_stmt->fetch(\PDO::FETCH_ASSOC);
Database::needRoot(false);
$result['size'] = $mbdata['MB'];
$result['size'] = $mbdata['MB'] ?? 0;
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get database '" . $result['databasename'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
$key = ($id > 0 ? "id #" . $id : "dbname '" . $dbname . "'");
throw new \Exception("MySQL database with " . $key . " could not be found", 404);
@@ -346,7 +350,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Mysqls.get', array(
'dbname' => $result['databasename']
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
/**
@@ -411,13 +415,13 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
"table_schema" => $row['databasename']
), true, true);
$mbdata = $mbdata_stmt->fetch(\PDO::FETCH_ASSOC);
$row['size'] = $mbdata['MB'];
$row['size'] = $mbdata['MB'] ?? 0;
$result[] = $row;
}
Database::needRoot(false);
}
}
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -444,7 +448,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_dbs']);
return $this->response(200, "successful", $result['num_dbs']);
}
}
@@ -506,6 +510,6 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
Customers::decreaseUsage($customer['customerid'], 'mysqls_used', $resetaccnumber);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] deleted database '" . $result['databasename'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
}

View File

@@ -50,8 +50,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$result_stmt = Database::prepare("
SELECT c.*, fd.description as fpmdesc
FROM `" . TABLE_PANEL_PHPCONFIGS . "` c
LEFT JOIN `" . TABLE_PANEL_FPMDAEMONS . "` fd ON fd.id = c.fpmsettingid" . $this->getSearchWhere($query_fields) . $this->getOrderBy() . $this->getLimit()
);
LEFT JOIN `" . TABLE_PANEL_FPMDAEMONS . "` fd ON fd.id = c.fpmsettingid" . $this->getSearchWhere($query_fields) . $this->getOrderBy() . $this->getLimit());
Database::pexecute($result_stmt, $query_fields, true, true);
$phpconfigs = array();
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
@@ -114,7 +113,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$phpconfigs[] = $row;
}
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($phpconfigs),
'list' => $phpconfigs
));
@@ -138,7 +137,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_phps']);
return $this->response(200, "successful", $result['num_phps']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -166,7 +165,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'id' => $id
), true, true);
if ($result) {
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("php-config with id #" . $id . " could not be found", 404);
}
@@ -368,7 +367,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$result = $this->apiCall('PhpSettings.get', array(
'id' => $ins_data['id']
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -564,7 +563,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$result = $this->apiCall('PhpSettings.get', array(
'id' => $id
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -615,7 +614,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
\Froxlor\System\Cronjob::inserttask('1');
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] php setting '" . $result['description'] . "' has been deleted by '" . $this->getUserDetail('loginname') . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}

View File

@@ -41,6 +41,8 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* optional, php-settings-id, if empty the $domain value is used
* @param int $redirectcode
* optional, redirect-code-id from TABLE_PANEL_REDIRECTCODES
* @param bool $sslenabled
* optional, whether or not SSL is enabled for this domain, regardless of the assigned ssl-ips, default 1 (true)
* @param bool $ssl_redirect
* optional, whether to generate a https-redirect or not, default false; requires SSL to be enabled
* @param bool $letsencrypt
@@ -76,6 +78,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$redirectcode = $this->getParam('redirectcode', true, Settings::Get('customredirect.default'));
$isemaildomain = $this->getParam('isemaildomain', true, 0);
if (Settings::Get('system.use_ssl')) {
$sslenabled = $this->getBoolParam('sslenabled', true, 1);
$ssl_redirect = $this->getBoolParam('ssl_redirect', true, 0);
$letsencrypt = $this->getBoolParam('letsencrypt', true, 0);
$http2 = $this->getBoolParam('http2', true, 0);
@@ -83,6 +86,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$hsts_sub = $this->getBoolParam('hsts_sub', true, 0);
$hsts_preload = $this->getBoolParam('hsts_preload', true, 0);
} else {
$sslenabled = 0;
$ssl_redirect = 0;
$letsencrypt = 0;
$http2 = 0;
@@ -95,6 +99,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$customer = $this->getCustomerData('subdomains');
// validation
$subdomain = strtolower($subdomain);
if (substr($subdomain, 0, 4) == 'xn--') {
\Froxlor\UI\Response::standard_error('domain_nopunycode', '', true);
}
@@ -114,7 +119,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
'mydomain'
), '', true);
}
if ($completedomain == Settings::Get('system.hostname')) {
if ($completedomain == strtolower(Settings::Get('system.hostname'))) {
\Froxlor\UI\Response::standard_error('admin_domain_emailsystemhostname', '', true);
}
@@ -190,7 +195,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
} elseif ($subdomain == 'www' && $domain_check['wwwserveralias'] == '1') {
// you cannot add 'www' as subdomain when the maindomain generates a www-alias
\Froxlor\UI\Response::standard_error('wwwnotallowed', '', true);
} elseif (strtolower($completedomain_check['domain']) == strtolower($completedomain)) {
} elseif ($completedomain_check && strtolower($completedomain_check['domain']) == strtolower($completedomain)) {
// the domain does already exist as main-domain
\Froxlor\UI\Response::standard_error('domainexistalready', $completedomain, true);
}
@@ -251,6 +256,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
`customerid` = :customerid,
`adminid` = :adminid,
`domain` = :domain,
`domain_ace` = :domain_ace,
`documentroot` = :documentroot,
`aliasdomain` = :aliasdomain,
`parentdomainid` = :parentdomainid,
@@ -275,12 +281,14 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
`override_tls` = :override_tls,
`ssl_protocols` = :ssl_protocols,
`ssl_cipher_list` = :ssl_cipher_list,
`tlsv13_cipher_list` = :tlsv13_cipher_list
`tlsv13_cipher_list` = :tlsv13_cipher_list,
`ssl_enabled` = :sslenabled
");
$params = array(
"customerid" => $customer['customerid'],
"adminid" => $customer['adminid'],
"domain" => $completedomain,
"domain_ace" => $idna_convert->decode($completedomain),
"documentroot" => $path,
"aliasdomain" => $aliasdomain != 0 ? $aliasdomain : null,
"parentdomainid" => $domain_check['id'],
@@ -305,7 +313,8 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
"override_tls" => $domain_check['override_tls'],
"ssl_protocols" => $domain_check['ssl_protocols'],
"ssl_cipher_list" => $domain_check['ssl_cipher_list'],
"tlsv13_cipher_list" => $domain_check['tlsv13_cipher_list']
"tlsv13_cipher_list" => $domain_check['tlsv13_cipher_list'],
"sslenabled" => $sslenabled
);
Database::pexecute($stmt, $params, true, true);
$subdomain_id = Database::lastInsertId();
@@ -336,7 +345,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = $this->apiCall('SubDomains.get', array(
'id' => $subdomain_id
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
throw new \Exception("No more resources available", 406);
}
@@ -400,7 +409,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
);
}
} else {
if (Settings::IsInList('panel.customer_hide_options', 'domains')) {
if (! $this->isInternal() && Settings::IsInList('panel.customer_hide_options', 'domains')) {
throw new \Exception("You cannot access this resource", 405);
}
$result_stmt = Database::prepare("
@@ -417,7 +426,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get subdomain '" . $result['domain'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
$key = ($id > 0 ? "id #" . $id : "domainname '" . $domainname . "'");
throw new \Exception("Subdomain with " . $key . " could not be found", 404);
@@ -446,6 +455,8 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* optional, php-settings-id, if empty the $domain value is used
* @param int $redirectcode
* optional, redirect-code-id from TABLE_PANEL_REDIRECTCODES
* @param bool $sslenabled
* optional, whether or not SSL is enabled for this domain, regardless of the assigned ssl-ips, default 1 (true)
* @param bool $ssl_redirect
* optional, whether to generate a https-redirect or not, default false; requires SSL to be enabled
* @param bool $letsencrypt
@@ -493,6 +504,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$phpsettingid = $this->getParam('phpsettingid', true, $result['phpsettingid']);
$redirectcode = $this->getParam('redirectcode', true, \Froxlor\Domain\Domain::getDomainRedirectId($id));
if (Settings::Get('system.use_ssl')) {
$sslenabled = $this->getBoolParam('sslenabled', true, $result['ssl_enabled']);
$ssl_redirect = $this->getBoolParam('ssl_redirect', true, $result['ssl_redirect']);
$letsencrypt = $this->getBoolParam('letsencrypt', true, $result['letsencrypt']);
$http2 = $this->getBoolParam('http2', true, $result['http2']);
@@ -500,6 +512,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$hsts_sub = $this->getBoolParam('hsts_sub', true, $result['hsts_sub']);
$hsts_preload = $this->getBoolParam('hsts_preload', true, $result['hsts_preload']);
} else {
$sslenabled = 0;
$ssl_redirect = 0;
$letsencrypt = 0;
$http2 = 0;
@@ -610,14 +623,15 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
if ($path != $result['documentroot'] || $isemaildomain != $result['isemaildomain'] || $wwwserveralias != $result['wwwserveralias'] || $iswildcarddomain != $result['iswildcarddomain'] || $aliasdomain != $result['aliasdomain'] || $openbasedir_path != $result['openbasedir_path'] || $ssl_redirect != $result['ssl_redirect'] || $letsencrypt != $result['letsencrypt'] || $hsts_maxage != $result['hsts'] || $hsts_sub != $result['hsts_sub'] || $hsts_preload != $result['hsts_preload'] || $phpsettingid != $result['phpsettingid']) {
$stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_DOMAINS . "` SET
`documentroot`= :documentroot,
`isemaildomain`= :isemaildomain,
`wwwserveralias`= :wwwserveralias,
`iswildcarddomain`= :iswildcarddomain,
`aliasdomain`= :aliasdomain,
`openbasedir_path`= :openbasedir_path,
`ssl_redirect`= :ssl_redirect,
`letsencrypt`= :letsencrypt,
`documentroot` = :documentroot,
`isemaildomain` = :isemaildomain,
`wwwserveralias` = :wwwserveralias,
`iswildcarddomain` = :iswildcarddomain,
`aliasdomain` = :aliasdomain,
`openbasedir_path` = :openbasedir_path,
`ssl_enabled` = :sslenabled,
`ssl_redirect` = :ssl_redirect,
`letsencrypt` = :letsencrypt,
`http2` = :http2,
`hsts` = :hsts,
`hsts_sub` = :hsts_sub,
@@ -632,6 +646,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
"iswildcarddomain" => $iswildcarddomain,
"aliasdomain" => ($aliasdomain != 0 && $alias_check == 0) ? $aliasdomain : null,
"openbasedir_path" => $openbasedir_path,
"sslenabled" => $sslenabled,
"ssl_redirect" => $ssl_redirect,
"letsencrypt" => $letsencrypt,
"http2" => $http2,
@@ -678,7 +693,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = $this->apiCall('SubDomains.get', array(
'id' => $id
));
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
/**
@@ -752,6 +767,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
'`d`.`id`',
'`d`.`customerid`',
'`d`.`domain`',
'`d`.`domain_ace`',
'`d`.`documentroot`',
'`d`.`isbinddomain`',
'`d`.`isemaildomain`',
@@ -767,7 +783,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
// prepare select statement
$domains_stmt = Database::prepare("
SELECT " . implode(",", $select_fields) . ", IF(`d`.`parentdomainid` > 0, `pd`.`domain`, `d`.`domain`) AS `parentdomainname`, `ad`.`id` AS `aliasdomainid`, `ad`.`domain` AS `aliasdomain`, `da`.`id` AS `domainaliasid`, `da`.`domain` AS `domainalias`
SELECT " . implode(",", $select_fields) . ", IF(`d`.`parentdomainid` > 0, `pd`.`domain_ace`, `d`.`domain_ace`) AS `parentdomainname`, `ad`.`id` AS `aliasdomainid`, `ad`.`domain` AS `aliasdomain`, `da`.`id` AS `domainaliasid`, `da`.`domain` AS `domainalias`
FROM `" . TABLE_PANEL_DOMAINS . "` `d`
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `ad` ON `d`.`aliasdomain`=`ad`.`id`
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `da` ON `da`.`aliasdomain`=`d`.`id`
@@ -781,7 +797,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
while ($row = $domains_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -846,7 +862,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
");
$result = Database::pexecute_first($domains_stmt, null, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_subdom']);
return $this->response(200, "successful", $result['num_subdom']);
}
}
@@ -960,7 +976,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
Customers::decreaseUsage($customer['customerid'], 'subdomains_used');
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] deleted subdomain '" . $result['domain'] . "'");
return $this->response(200, "successfull", $result);
return $this->response(200, "successful", $result);
}
/**

View File

@@ -55,7 +55,7 @@ class SysLog extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
if (count($customer_names) > 0) {
$result_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_LOG . "`
WHERE `user` = :loginname OR `user` IN (" . implode(', ', $customer_names) . ")" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
WHERE `user` = :loginname OR `user` IN ('" . implode("', '", $customer_names) . "')" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
} else {
$result_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_LOG . "`
@@ -74,7 +74,7 @@ class SysLog extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result[] = $row;
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list log-entries");
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));
@@ -105,7 +105,7 @@ class SysLog extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
if (count($customer_names) > 0) {
$result_stmt = Database::prepare("
SELECT COUNT(*) as num_logs FROM `" . TABLE_PANEL_LOG . "`
WHERE `user` = :loginname OR `user` IN (" . implode(', ', $customer_names) . ")
WHERE `user` = :loginname OR `user` IN ('" . implode("', '", $customer_names) . "')
");
} else {
$result_stmt = Database::prepare("
@@ -129,7 +129,7 @@ class SysLog extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
return $this->response(200, "successfull", $result['num_logs']);
return $this->response(200, "successful", $result['num_logs']);
}
}
@@ -190,13 +190,12 @@ class SysLog extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
}
if (count($customer_names) > 0) {
$result_stmt = Database::prepare("
DELETE FROM `" . TABLE_PANEL_LOG . "` WHERE `date` < :trunc AND `user` = :loginname OR `user` IN (" . implode(', ', $customer_names) . ")
");
DELETE FROM `" . TABLE_PANEL_LOG . "` WHERE `date` < :trunc AND `user` = :loginname OR `user` IN ('" . implode("', '", $customer_names) . "')
");
} else {
$result_stmt = Database::prepare("
SELECT COUNT(*) as num_logs FROM `" . TABLE_PANEL_LOG . "`
DELETE FROM `" . TABLE_PANEL_LOG . "` WHERE `date` < :trunc AND `user` = :loginname
");
DELETE FROM `" . TABLE_PANEL_LOG . "` WHERE `date` < :trunc AND `user` = :loginname
");
}
$params = [
'loginname' => $this->getUserDetail('loginname')
@@ -205,7 +204,7 @@ class SysLog extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$params['trunc'] = $truncatedate;
Database::pexecute($result_stmt, $params, true, true);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] truncated the froxlor syslog");
return $this->response(200, "successfull", true);
return $this->response(200, "successful", true);
}
throw new \Exception("Not allowed to execute given command.", 403);
}

View File

@@ -110,7 +110,7 @@ class Traffic extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$result[] = $row;
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list traffic");
return $this->response(200, "successfull", array(
return $this->response(200, "successful", array(
'count' => count($result),
'list' => $result
));

View File

@@ -56,7 +56,7 @@ class FroxlorRPC
private static function validateAuth($key, $secret)
{
$sel_stmt = \Froxlor\Database\Database::prepare("
SELECT ak.*, a.api_allowed as admin_api_allowed, c.api_allowed as cust_api_allowed
SELECT ak.*, a.api_allowed as admin_api_allowed, c.api_allowed as cust_api_allowed, c.deactivated
FROM `api_keys` ak
LEFT JOIN `panel_admins` a ON a.adminid = ak.adminid
LEFT JOIN `panel_customers` c ON c.customerid = ak.customerid
@@ -67,7 +67,7 @@ class FroxlorRPC
'as' => $secret
), true, true);
if ($result) {
if ($result['apikey'] == $key && $result['secret'] == $secret && ($result['valid_until'] == - 1 || $result['valid_until'] >= time()) && (($result['customerid'] == 0 && $result['admin_api_allowed'] == 1) || ($result['customerid'] > 0 && $result['cust_api_allowed'] == 1))) {
if ($result['apikey'] == $key && $result['secret'] == $secret && ($result['valid_until'] == - 1 || $result['valid_until'] >= time()) && (($result['customerid'] == 0 && $result['admin_api_allowed'] == 1) || ($result['customerid'] > 0 && $result['cust_api_allowed'] == 1 && $result['deactivated'] == 0))) {
// get user to check whether api call is allowed
if (! empty($result['allowed_from'])) {
// @todo allow specification and validating of whole subnets later

View File

@@ -26,11 +26,16 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
*/
private function validate()
{
global $lng;
$this->checkConfigParam(true);
$this->parseConfig();
require FROXLOR_INSTALL_DIR . '/lib/tables.inc.php';
include_once FROXLOR_INSTALL_DIR . '/lng/english.lng.php';
include_once FROXLOR_INSTALL_DIR . '/lng/lng_references.php';
if (array_key_exists("import-settings", $this->_args)) {
$this->importSettings();
}
@@ -78,6 +83,20 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
$distros = glob($config_dir . '*.xml');
// tmp array
$distributions_select_data = array();
//set default os.
$os_dist = array('ID' => 'buster');
$os_version = array('0' => '10');
$os_default = $os_dist['ID'];
//read os-release
if(file_exists('/etc/os-release')) {
$os_dist = parse_ini_file('/etc/os-release', false);
if(is_array($os_dist) && array_key_exists('ID', $os_dist) && array_key_exists('VERSION_ID', $os_dist)) {
$os_version = explode('.',$os_dist['VERSION_ID'])[0];
}
}
// read in all the distros
foreach ($distros as $_distribution) {
// get configparser object
@@ -86,6 +105,12 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
$dist_display = $this->getCompleteDistroName($dist);
// store in tmp array
$distributions_select_data[$dist_display] = str_replace(".xml", "", strtolower(basename($_distribution)));
//guess if this is the current distro.
$ver = explode('.', $dist->distributionVersion)[0];
if (strtolower($os_dist['ID']) == strtolower($dist->distributionName) && $os_version == $ver) {
$os_default = str_replace(".xml", "", strtolower(basename($_distribution)));
}
}
// sort by distribution name
@@ -103,7 +128,7 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
echo PHP_EOL;
while (! in_array($_daemons_config['distro'], $distributions_select_data)) {
$_daemons_config['distro'] = ConfigServicesCmd::getInput("choose distribution", "buster");
$_daemons_config['distro'] = ConfigServicesCmd::getInput("choose distribution", $os_default);
}
// go through all services and let user check whether to include it or not

View File

@@ -39,6 +39,13 @@ class ConfigParser
*/
private $services = array();
/**
* Holding the available defaults in the XML
*
* @var array
*/
private $defaults = array();
/**
* Store the parsed SimpleXMLElement for usage
*
@@ -147,7 +154,7 @@ class ConfigParser
*
* @return bool
*/
private function parse()
private function parseServices()
{
// We only want to parse the stuff one time
if ($this->isparsed == true) {
@@ -174,6 +181,29 @@ class ConfigParser
return true;
}
/**
* Parse the XML and populate $this->services
*
* @return bool
*/
private function parseDefaults()
{
// We only want to parse the stuff one time
if ($this->isparsed == true) {
return true;
}
// Get all defaults
$defaults = $this->xml->xpath('//defaults');
foreach ($defaults as $default) {
$this->defaults = $default;
}
// Switch flag to indicate we parsed our data
$this->isparsed = true;
return true;
}
/**
* Return all services defined by the XML
*
@@ -184,9 +214,25 @@ class ConfigParser
public function getServices()
{
// Let's parse this shit(!)
$this->parse();
$this->parseServices();
// Return our carefully searched for services
return $this->services;
}
/**
* Return all defaults defined by the XML
*
* The array will hold ConfigDefaults - Objects for further handling
*
* @return array
*/
public function getDefaults()
{
// Let's parse this shit(!)
$this->parseDefaults();
// Return our carefully searched for defaults
return $this->defaults;
}
}

View File

@@ -99,7 +99,7 @@ class CronConfig
$binpath = Settings::Get("system.croncmdline");
// fallback as it is important
if ($binpath === null) {
$binpath = "/usr/bin/nice -n 5 /usr/bin/php5 -q";
$binpath = "/usr/bin/nice -n 5 /usr/bin/php -q";
}
$cronfile .= "root " . $binpath . " " . \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . "/scripts/froxlor_master_cronjob.php") . " --" . $row_cronentry['cronfile'] . " 1> /dev/null\n";

View File

@@ -112,7 +112,10 @@ class Bind extends DnsBase
if (count($this->ns) > 0) {
foreach ($this->ns as $ns) {
foreach ($ns["ips"] as $ip) {
$bindconf_file .= ' ' . $ip . ";\n";
$ip = \Froxlor\Validate\Validate::validate_ip2($ip, true, 'invalidip', true, true, true);
if ($ip) {
$bindconf_file .= ' ' . $ip . ";\n";
}
}
}
}

View File

@@ -172,7 +172,7 @@ class Apache extends HttpConfigBase
$mypath = $this->getMyPath($row_ipsandports);
$this->virtualhosts_data[$vhosts_filename] .= 'DocumentRoot "' . $mypath . '"' . "\n";
$this->virtualhosts_data[$vhosts_filename] .= 'DocumentRoot "' . rtrim($mypath, "/") . '"' . "\n";
if ($row_ipsandports['vhostcontainer_servername_statement'] == '1') {
$this->virtualhosts_data[$vhosts_filename] .= ' ServerName ' . Settings::Get('system.hostname') . "\n";
@@ -442,7 +442,9 @@ class Apache extends HttpConfigBase
'loginname' => 'froxlor.panel',
'documentroot' => $mypath,
'customerroot' => $mypath,
'parentdomainid' => 0
'parentdomainid' => 0,
'ssl_honorcipherorder' => Settings::Get('system.honorcipherorder'),
'ssl_sessiontickets' => Settings::Get('system.sessiontickets')
);
// override corresponding array values
@@ -478,9 +480,12 @@ class Apache extends HttpConfigBase
$this->virtualhosts_data[$vhosts_filename] .= ' SSLOpenSSLConfCmd DHParameters "' . $dhparams . '"' . "\n";
}
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCompression Off' . "\n";
if (Settings::Get('system.sessionticketsenabled') == '1') {
$this->virtualhosts_data[$vhosts_filename] .= ' SSLSessionTickets ' . ($domain['ssl_sessiontickets'] == '1' ? 'on' : 'off') . "\n";
}
}
// this makes it more secure, thx to Marcel (08/2013)
$this->virtualhosts_data[$vhosts_filename] .= ' SSLHonorCipherOrder On' . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' SSLHonorCipherOrder ' . ($domain['ssl_honorcipherorder'] == '1' ? 'on' : 'off') . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n";
$protocols = array_map('trim', explode(",", Settings::Get('system.ssl_protocols')));
if (in_array("TLSv1.3", $protocols) && ! empty(Settings::Get('system.tlsv13_cipher_list')) && Settings::Get('system.apache24') == 1) {
@@ -656,7 +661,7 @@ class Apache extends HttpConfigBase
if ($domain['deactivated'] == '1' && Settings::Get('system.deactivateddocroot') != '') {
$webroot_text .= ' # Using docroot for deactivated users...' . "\n";
$webroot_text .= ' DocumentRoot "' . \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.deactivateddocroot')) . "\"\n";
$webroot_text .= ' DocumentRoot "' . rtrim(\Froxlor\FileDir::makeCorrectDir(Settings::Get('system.deactivateddocroot')), "/") . "\"\n";
$webroot_text .= ' <Directory "' . \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.deactivateddocroot')) . '">' . "\n";
// >=apache-2.4 enabled?
if (Settings::Get('system.apache24') == '1') {
@@ -669,7 +674,7 @@ class Apache extends HttpConfigBase
$webroot_text .= ' </Directory>' . "\n";
$this->deactivated = true;
} else {
$webroot_text .= ' DocumentRoot "' . $domain['documentroot'] . "\"\n";
$webroot_text .= ' DocumentRoot "' . rtrim($domain['documentroot'], "/") . "\"\n";
$this->deactivated = false;
}
@@ -755,7 +760,7 @@ class Apache extends HttpConfigBase
$logtype = 'combined';
if (Settings::Get('system.logfiles_format') != '') {
$logtype = 'frx_custom';
$logfiles_text .= ' LogFormat "' . Settings::Get('system.logfiles_format') . '" ' . $logtype . "\n";
$logfiles_text .= ' LogFormat ' . Settings::Get('system.logfiles_format') . ' ' . $logtype . "\n";
}
if (Settings::Get('system.logfiles_type') == '2' && Settings::Get('system.logfiles_format') == '') {
$logtype = 'vhost_combined';
@@ -986,9 +991,11 @@ class Apache extends HttpConfigBase
$vhost_content .= ' SSLOpenSSLConfCmd DHParameters "' . $dhparams . '"' . "\n";
}
$vhost_content .= ' SSLCompression Off' . "\n";
if (Settings::Get('system.sessionticketsenabled') == '1') {
$vhost_content .= ' SSLSessionTickets ' . ($domain['ssl_sessiontickets'] == '1' ? 'on' : 'off') . "\n";
}
}
// this makes it more secure, thx to Marcel (08/2013)
$vhost_content .= ' SSLHonorCipherOrder On' . "\n";
$vhost_content .= ' SSLHonorCipherOrder ' . ($domain['ssl_honorcipherorder'] == '1' ? 'on' : 'off') . "\n";
$vhost_content .= ' SSLCipherSuite ' . $ssl_cipher_list . "\n";
$protocols = array_map('trim', explode(",", $ssl_protocols));
if (in_array("TLSv1.3", $protocols) && ! empty($tlsv13_cipher_list) && Settings::Get('system.apache24') == 1) {
@@ -1114,7 +1121,7 @@ class Apache extends HttpConfigBase
// Create vhost without ssl
$this->virtualhosts_data[$vhosts_filename] .= $this->getVhostContent($domain, false);
if ($domain['ssl'] == '1' || $domain['ssl_redirect'] == '1') {
if ($domain['ssl_enabled'] == '1' && ($domain['ssl'] == '1' || $domain['ssl_redirect'] == '1')) {
// Adding ssl stuff if enabled
$vhosts_filename_ssl = $this->getVhostFilename($domain, true);
$this->virtualhosts_data[$vhosts_filename_ssl] = '# Domain ID: ' . $domain['id'] . ' (SSL) - CustomerID: ' . $domain['customerid'] . ' - CustomerLogin: ' . $domain['loginname'] . "\n";

View File

@@ -68,6 +68,11 @@ class DomainSSL
'ssl_key_file' => \Froxlor\FileDir::makeCorrectFile($sslcertpath . '/' . $domain['domain'] . '.key')
);
if (! $this->validateCertificate($dom_certs)) {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, 'Given SSL private key for ' . $domain['domain'] . ' does not seem to match the certificate. Cannot create ssl-directives');
return;
}
if (Settings::Get('system.webserver') == 'lighttpd') {
// put my.crt and my.key together for lighty.
$dom_certs['ssl_cert_file'] = trim($dom_certs['ssl_cert_file']) . "\n" . trim($dom_certs['ssl_key_file']) . "\n";
@@ -112,4 +117,9 @@ class DomainSSL
return;
}
private function validateCertificate($dom_certs = array())
{
return openssl_x509_check_private_key($dom_certs['ssl_cert_file'], $dom_certs['ssl_key_file']);
}
}

View File

@@ -4,6 +4,9 @@ namespace Froxlor\Cron\Http\LetsEncrypt;
use Froxlor\FroxlorLogger;
use Froxlor\Settings;
use Froxlor\Database\Database;
use Froxlor\PhpHelper;
use Froxlor\Domain\Domain;
use Froxlor\FileDir;
/**
* This file is part of the Froxlor project.
@@ -18,9 +21,9 @@ use Froxlor\Database\Database;
* @author Froxlor team <team@froxlor.org> (2016-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Cron
*
*
* @since 0.9.35
*
*
*/
class AcmeSh extends \Froxlor\Cron\FroxlorCron
{
@@ -45,7 +48,406 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
public static $no_inserttask = false;
private static function needRenew()
/**
* run the task
*
* @param boolean $internal
* @return number
*/
public static function run($internal = false)
{
// usually, this is action is called from within the tasks-jobs
if (! defined('CRON_IS_FORCED') && ! defined('CRON_DEBUG_FLAG') && $internal == false) {
// Let's Encrypt cronjob is combined with regeneration of webserver configuration files.
// For debugging purposes you can use the --debug switch and the --force switch to run the cron manually.
// check whether we MIGHT need to run although there is no task to regenerate config-files
$needRenew = self::issueDomains();
if ($needRenew || self::issueFroxlorVhost()) {
// insert task to generate certificates and vhost-configs
\Froxlor\System\Cronjob::inserttask(1);
}
return 0;
}
// set server according to settings
self::$apiserver = 'https://acme-' . (Settings::Get('system.letsencryptca') == 'testing' ? 'staging-' : '') . 'v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org/directory';
// validate acme.sh installation
if (! self::checkInstall()) {
return - 1;
}
// flag for re-generation of vhost files
$changedetected = 0;
// prepare update sql
self::$updcert_stmt = Database::prepare("
REPLACE INTO
`" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
SET
`id` = :id,
`domainid` = :domainid,
`ssl_cert_file` = :crt,
`ssl_key_file` = :key,
`ssl_ca_file` = :ca,
`ssl_cert_chainfile` = :chain,
`ssl_csr_file` = :csr,
`ssl_fullchain_file` = :fullchain,
`expirationdate` = :expirationdate
");
// prepare domain update sql
self::$upddom_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `ssl_redirect` = '1' WHERE `id` = :domainid");
// check whether there are certificates to issue
$issue_froxlor = self::issueFroxlorVhost();
$issue_domains = self::issueDomains();
// first - generate LE for system-vhost if enabled
if ($issue_froxlor) {
// build row
$certrow = array(
'loginname' => 'froxlor.panel',
'domain' => Settings::Get('system.hostname'),
'domainid' => 0,
'documentroot' => \Froxlor\Froxlor::getInstallDir(),
'leprivatekey' => Settings::Get('system.leprivatekey'),
'lepublickey' => Settings::Get('system.lepublickey'),
'leregistered' => Settings::Get('system.leregistered'),
'ssl_redirect' => Settings::Get('system.le_froxlor_redirect'),
'expirationdate' => null,
'ssl_cert_file' => null,
'ssl_key_file' => null,
'ssl_ca_file' => null,
'ssl_csr_file' => null,
'id' => null
);
// add to queue
$issue_domains[] = $certrow;
}
if (count($issue_domains)) {
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Requesting " . count($issue_domains) . " new Let's Encrypt certificates");
self::runIssueFor($issue_domains);
$changedetected = 1;
}
// compare file-system certificates with the ones in our database
// and update if needed
$renew_froxlor = self::renewFroxlorVhost();
$renew_domains = self::renewDomains();
if ($renew_froxlor) {
// build row
$certrow = array(
'loginname' => 'froxlor.panel',
'domain' => Settings::Get('system.hostname'),
'domainid' => 0,
'documentroot' => \Froxlor\Froxlor::getInstallDir(),
'leprivatekey' => Settings::Get('system.leprivatekey'),
'lepublickey' => Settings::Get('system.lepublickey'),
'leregistered' => Settings::Get('system.leregistered'),
'ssl_redirect' => Settings::Get('system.le_froxlor_redirect'),
'expirationdate' => is_array($renew_froxlor) ? $renew_froxlor['expirationdate'] : date('Y-m-d H:i:s', 0),
'ssl_cert_file' => is_array($renew_froxlor) ? $renew_froxlor['ssl_cert_file'] : null,
'ssl_key_file' => is_array($renew_froxlor) ? $renew_froxlor['ssl_key_file'] : null,
'ssl_ca_file' => is_array($renew_froxlor) ? $renew_froxlor['ssl_ca_file'] : null,
'ssl_csr_file' => is_array($renew_froxlor) ? $renew_froxlor['ssl_csr_file'] : null,
'id' => is_array($renew_froxlor) ? $renew_froxlor['id'] : null
);
$renew_domains[] = $certrow;
}
foreach ($renew_domains as $domain) {
$cronlog = FroxlorLogger::getInstanceOf(array(
'loginname' => $domain['loginname'],
'adminsession' => 0
));
if (defined('CRON_IS_FORCED') || self::checkFsFilesAreNewer($domain['domain'], $domain['expirationdate'])) {
self::certToDb($domain, $cronlog, array());
$changedetected = 1;
}
}
// If we have a change in a certificate, we need to update the webserver - configs
// This is easiest done by just creating a new task ;)
if ($changedetected) {
if (self::$no_inserttask == false) {
\Froxlor\System\Cronjob::inserttask(1);
}
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Let's Encrypt certificates have been updated");
} else {
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "No new certificates or certificate updates found");
}
}
/**
* issue certificates for a list of domains
*/
private static function runIssueFor($certrows = array())
{
// prepare aliasdomain-check
$aliasdomains_stmt = Database::prepare("
SELECT
dom.`id` as domainid,
dom.`domain`,
dom.`wwwserveralias`
FROM `" . TABLE_PANEL_DOMAINS . "` AS dom
WHERE
dom.`aliasdomain` = :id
AND dom.`letsencrypt` = 1
AND dom.`iswildcarddomain` = 0
");
// iterate through all domains
foreach ($certrows as $certrow) {
// set logger to corresponding loginname for the log to appear in the users system-log
$cronlog = FroxlorLogger::getInstanceOf(array(
'loginname' => $certrow['loginname'],
'adminsession' => 0
));
// Only issue let's encrypt certificate if no broken ssl_redirect is enabled
if ($certrow['ssl_redirect'] != 2) {
$do_force = false;
if (! empty($certrow['ssl_cert_file']) && empty($certrow['expirationdate'])) {
// domain changed (SAN or similar)
$do_force = true;
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Re-creating certificate for " . $certrow['domain']);
} else {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Creating certificate for " . $certrow['domain']);
}
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding common-name: " . $certrow['domain']);
$domains = array(
strtolower($certrow['domain'])
);
// add www.<domain> to SAN list
if ($certrow['wwwserveralias'] == 1) {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $certrow['domain']);
$domains[] = strtolower('www.' . $certrow['domain']);
}
if ($certrow['domainid'] == 0) {
$froxlor_aliases = Settings::Get('system.froxloraliases');
if (! empty($froxlor_aliases)) {
$froxlor_aliases = explode(",", $froxlor_aliases);
foreach ($froxlor_aliases as $falias) {
if (\Froxlor\Validate\Validate::validateDomain(trim($falias))) {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: " . strtolower(trim($falias)));
$domains[] = strtolower(trim($falias));
}
}
}
} else {
// add alias domains (and possibly www.<aliasdomain>) to SAN list
Database::pexecute($aliasdomains_stmt, array(
'id' => $certrow['domainid']
));
$aliasdomains = $aliasdomains_stmt->fetchAll(\PDO::FETCH_ASSOC);
foreach ($aliasdomains as $aliasdomain) {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $aliasdomain['domain']);
$domains[] = strtolower($aliasdomain['domain']);
if ($aliasdomain['wwwserveralias'] == 1) {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $aliasdomain['domain']);
$domains[] = strtolower('www.' . $aliasdomain['domain']);
}
}
}
self::validateDns($domains, $certrow['domainid'], $cronlog);
self::runAcmeSh($certrow, $domains, $cronlog, $do_force);
} else {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Skipping Let's Encrypt generation for " . $certrow['domain'] . " due to an enabled ssl_redirect");
}
}
}
/**
* validate dns (A / AAAA record) of domain against known system ips
*
* @param array $domains
* @param int $domain_id
* @param FroxlorLogger $cronlog
*/
private static function validateDns(&$domains = array(), $domain_id, &$cronlog)
{
if (Settings::Get('system.le_domain_dnscheck') == '1' && ! empty($domains)) {
$loop_domains = $domains;
// ips according to our system
$our_ips = Domain::getIpsOfDomain($domain_id);
foreach ($loop_domains as $idx => $domain) {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Validating DNS of " . $domain);
// ips accordint to NS
$domain_ips = PhpHelper::gethostbynamel6($domain);
if ($domain_ips == false || count(array_intersect($our_ips, $domain_ips)) <= 0) {
// no common ips...
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Skipping Let's Encrypt generation for " . $domain . " due to no system known IP address via DNS check");
unset($domains[$idx]);
}
}
}
}
private static function runAcmeSh($certrow = array(), $domains = array(), &$cronlog = null, $force = false)
{
if (! empty($domains)) {
if (self::$do_update) {
self::checkUpgrade();
self::$do_update = false;
}
$acmesh_cmd = self::$acmesh . " --auto-upgrade 0 --server " . self::$apiserver . " --issue -d " . implode(" -d ", $domains);
// challenge path
$acmesh_cmd .= " -w " . Settings::Get('system.letsencryptchallengepath');
if (Settings::Get('system.leecc') > 0) {
// ecc certificate
$acmesh_cmd .= " --keylength ec-" . Settings::Get('system.leecc');
} else {
$acmesh_cmd .= " --keylength " . Settings::Get('system.letsencryptkeysize');
}
if (Settings::Get('system.letsencryptreuseold') != '1') {
$acmesh_cmd .= " --always-force-new-domain-key";
}
if (Settings::Get('system.letsencryptca') == 'testing') {
$acmesh_cmd .= " --staging";
}
if ($force) {
$acmesh_cmd .= " --force";
}
if (defined('CRON_DEBUG_FLAG')) {
$acmesh_cmd .= " --debug";
}
$acme_result = \Froxlor\FileDir::safe_exec($acmesh_cmd);
// debug output of acme.sh run
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, implode("\n", $acme_result));
self::certToDb($certrow, $cronlog, $acme_result);
}
}
private static function certToDb($certrow, &$cronlog, $acme_result)
{
$return = array();
self::readCertificateToVar(strtolower($certrow['domain']), $return, $cronlog);
if (! empty($return['crt'])) {
$newcert = openssl_x509_parse($return['crt']);
if ($newcert) {
// Store the new data
Database::pexecute(self::$updcert_stmt, array(
'id' => $certrow['id'],
'domainid' => $certrow['domainid'],
'crt' => $return['crt'],
'key' => $return['key'],
'ca' => $return['chain'],
'chain' => $return['chain'],
'csr' => $return['csr'],
'fullchain' => $return['fullchain'],
'expirationdate' => date('Y-m-d H:i:s', $newcert['validTo_time_t'])
));
if ($certrow['ssl_redirect'] == 3) {
Database::pexecute(self::$upddom_stmt, array(
'domainid' => $certrow['domainid']
));
}
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Updated Let's Encrypt certificate for " . $certrow['domain']);
} else {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Got non-successful Let's Encrypt response for " . $certrow['domain'] . ":\n" . implode("\n", $acme_result));
}
} else {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Could not get Let's Encrypt certificate for " . $certrow['domain'] . ":\n" . implode("\n", $acme_result));
}
}
/**
* check whether we need to issue a new certificate for froxlor itself
*
* @return boolean
*/
private static function issueFroxlorVhost()
{
if (Settings::Get('system.le_froxlor_enabled') == '1') {
// let's encrypt is enabled, now check whether we have a certificate
$froxlor_ssl_settings_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
WHERE `domainid` = '0'
");
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
// also check for possible existing certificate
if (! $froxlor_ssl && ! self::checkFsFilesAreNewer(Settings::Get('system.hostname'), date('Y-m-d H:i:s'))) {
return true;
}
}
return false;
}
/**
* check whether we need to renew-check the certificate for froxlor itself
*
* @return boolean
*/
private static function renewFroxlorVhost()
{
if (Settings::Get('system.le_froxlor_enabled') == '1') {
// let's encrypt is enabled, now check whether we have a certificate
$froxlor_ssl_settings_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
WHERE `domainid` = '0'
");
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
// also check for possible existing certificate
if ($froxlor_ssl || (! $froxlor_ssl && ! self::checkFsFilesAreNewer(Settings::Get('system.hostname'), date('Y-m-d H:i:s', 0)))) {
return ($froxlor_ssl ? $froxlor_ssl : true);
}
}
return false;
}
/**
* get a list of domains that have a lets encrypt certificate (possible renew)
*/
private static function renewDomains()
{
$certificates_stmt = Database::query("
SELECT
domssl.`id`,
domssl.`domainid`,
domssl.`expirationdate`,
domssl.`ssl_cert_file`,
domssl.`ssl_key_file`,
dom.`domain`,
dom.`id` AS 'domainid',
dom.`ssl_redirect`,
cust.`loginname`
FROM
`" . TABLE_PANEL_CUSTOMERS . "` AS cust,
`" . TABLE_PANEL_DOMAINS . "` AS dom
LEFT JOIN
`" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` AS domssl ON
dom.`id` = domssl.`domainid`
WHERE
dom.`customerid` = cust.`customerid`
AND cust.deactivated = 0
AND dom.`letsencrypt` = 1
AND dom.`aliasdomain` IS NULL
AND dom.`iswildcarddomain` = 0
");
$renew_certs = $certificates_stmt->fetchAll(\PDO::FETCH_ASSOC);
if ($renew_certs) {
return $renew_certs;
}
return array();
}
/**
* get a list of domains that require a new certificate (issue)
*/
private static function issueDomains()
{
$certificates_stmt = Database::query("
SELECT
@@ -78,322 +480,70 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
AND dom.`letsencrypt` = 1
AND dom.`aliasdomain` IS NULL
AND dom.`iswildcarddomain` = 0
AND (
domssl.`expirationdate` < DATE_ADD(NOW(), INTERVAL 30 DAY)
OR domssl.`expirationdate` IS NULL
)
AND domssl.`expirationdate` IS NULL
");
$customer_ssl = $certificates_stmt->fetchAll(\PDO::FETCH_ASSOC);
if (! $customer_ssl) {
$customer_ssl = array();
if ($customer_ssl) {
return $customer_ssl;
}
return array();
}
$froxlor_ssl = array();
if (Settings::Get('system.le_froxlor_enabled') == '1') {
$froxlor_ssl_settings_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
WHERE `domainid` = '0' AND
(`expirationdate` < DATE_ADD(NOW(), INTERVAL 30 DAY) OR `expirationdate` IS NULL)
");
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
if (! $froxlor_ssl) {
$froxlor_ssl = array();
private static function checkFsFilesAreNewer($domain, $cert_date = 0)
{
$certificate_folder = self::getWorkingDirFromEnv($domain);
$ssl_file = \Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . $domain . '.cer');
if (is_dir($certificate_folder) && file_exists($ssl_file) && is_readable($ssl_file)) {
$cert_data = openssl_x509_parse(file_get_contents($ssl_file));
if (strtotime($cert_data['validTo_time_t']) > strtotime($cert_date)) {
return true;
}
}
if (count($customer_ssl) > 0 || count($froxlor_ssl) > 0) {
return array(
'customer_ssl' => $customer_ssl,
'froxlor_ssl' => $froxlor_ssl
);
}
return false;
}
public static function run($internal = false)
public static function getWorkingDirFromEnv($domain = "", $forced_noecc = false)
{
if (! defined('CRON_IS_FORCED') && ! defined('CRON_DEBUG_FLAG') && $internal == false) {
// Let's Encrypt cronjob is combined with regeneration of webserver configuration files.
// For debugging purposes you can use the --debug switch and the --force switch to run the cron manually.
// check whether we MIGHT need to run although there is no task to regenerate config-files
$needRenew = self::needRenew();
if ($needRenew) {
// insert task to generate certificates and vhost-configs
\Froxlor\System\Cronjob::inserttask(1);
}
return 0;
if (Settings::Get('system.leecc') > 0 && ! $forced_noecc) {
$domain .= "_ecc";
}
self::checkInstall();
self::$apiserver = 'https://acme-'.(Settings::Get('system.letsencryptca') == 'testing' ? 'staging-' : '').'v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org/directory';
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Requesting/renewing Let's Encrypt certificates");
$aliasdomains_stmt = Database::prepare("
SELECT
dom.`id` as domainid,
dom.`domain`,
dom.`wwwserveralias`
FROM `" . TABLE_PANEL_DOMAINS . "` AS dom
WHERE
dom.`aliasdomain` = :id
AND dom.`letsencrypt` = 1
AND dom.`iswildcarddomain` = 0
");
self::$updcert_stmt = Database::prepare("
REPLACE INTO
`" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
SET
`id` = :id,
`domainid` = :domainid,
`ssl_cert_file` = :crt,
`ssl_key_file` = :key,
`ssl_ca_file` = :ca,
`ssl_cert_chainfile` = :chain,
`ssl_csr_file` = :csr,
`ssl_fullchain_file` = :fullchain,
`expirationdate` = :expirationdate
");
self::$upddom_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `ssl_redirect` = '1' WHERE `id` = :domainid");
// flag for re-generation of vhost files
$changedetected = 0;
$needRenew = self::needRenew();
// first - generate LE for system-vhost if enabled
if (Settings::Get('system.le_froxlor_enabled') == '1') {
$certrow = array(
'loginname' => 'froxlor.panel',
'domain' => Settings::Get('system.hostname'),
'domainid' => 0,
'documentroot' => \Froxlor\Froxlor::getInstallDir(),
'leprivatekey' => Settings::Get('system.leprivatekey'),
'lepublickey' => Settings::Get('system.lepublickey'),
'leregistered' => Settings::Get('system.leregistered'),
'ssl_redirect' => Settings::Get('system.le_froxlor_redirect'),
'expirationdate' => null,
'ssl_cert_file' => null,
'ssl_key_file' => null,
'ssl_ca_file' => null,
'ssl_csr_file' => null,
'id' => null
);
$froxlor_ssl = $needRenew ? $needRenew['froxlor_ssl'] : array();
$cert_mode = 'issue';
if (count($froxlor_ssl) > 0) {
$cert_mode = 'renew';
$certrow['id'] = $froxlor_ssl['id'];
$certrow['expirationdate'] = $froxlor_ssl['expirationdate'];
$certrow['ssl_cert_file'] = $froxlor_ssl['ssl_cert_file'];
$certrow['ssl_key_file'] = $froxlor_ssl['ssl_key_file'];
$certrow['ssl_ca_file'] = $froxlor_ssl['ssl_ca_file'];
$certrow['ssl_csr_file'] = $froxlor_ssl['ssl_csr_file'];
} else {
// check whether we have an entry with valid certificates which just does not need
// updating yet, so we need to skip this here
$froxlor_ssl_settings_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = '0'
");
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
if ($froxlor_ssl && ! empty($froxlor_ssl['ssl_cert_file'])) {
$cert_mode = false;
}
}
if ($cert_mode) {
$domains = array(
strtolower($certrow['domain'])
);
$froxlor_aliases = Settings::Get('system.froxloraliases');
if (! empty($froxlor_aliases)) {
$froxlor_aliases = explode(",", $froxlor_aliases);
foreach ($froxlor_aliases as $falias) {
if (\Froxlor\Validate\Validate::validateDomain(trim($falias))) {
$domains[] = strtolower(trim($falias));
}
}
}
// Only renew let's encrypt certificate if no broken ssl_redirect is enabled
// - this temp. deactivation of the ssl-redirect is handled by the webserver-cronjob
$do_force = false;
if ($cert_mode == 'renew') {
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Updating certificate for " . $certrow['domain']);
} else {
$do_force = true;
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Creating certificate for " . $certrow['domain']);
}
$cronlog = FroxlorLogger::getInstanceOf(array(
'loginname' => $certrow['loginname'],
'adminsession' => 0
));
self::runAcmeSh($certrow, $domains, $cert_mode, $cronlog, $changedetected, $do_force);
$env_file = FileDir::makeCorrectFile(dirname(self::$acmesh) . '/acme.sh.env');
if (file_exists($env_file)) {
$output = [];
$cut = <<<EOC
cut -d'"' -f2
EOC;
exec('grep "LE_WORKING_DIR" ' . escapeshellarg($env_file) . ' | ' . $cut, $output);
if (is_array($output) && ! empty($output) && isset($output[0]) && ! empty($output[0])) {
return FileDir::makeCorrectDir($output[0] . "/" . $domain);
}
}
// customer domains
$certrows = $needRenew ? $needRenew['customer_ssl'] : array();
foreach ($certrows as $certrow) {
// initialize mode to 'issue'
$cert_mode = 'issue';
// set logger to corresponding loginname for the log to appear in the users system-log
$cronlog = FroxlorLogger::getInstanceOf(array(
'loginname' => $certrow['loginname'],
'adminsession' => 0
));
// Only renew let's encrypt certificate if no broken ssl_redirect is enabled
if ($certrow['ssl_redirect'] != 2) {
$do_force = false;
if (! empty($certrow['ssl_cert_file']) && ! empty($certrow['expirationdate'])) {
$cert_mode = 'renew';
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Updating certificate for " . $certrow['domain']);
} else if (! empty($certrow['ssl_cert_file']) && empty($certrow['expirationdate'])) {
// domain changed (SAN or similar)
$do_force = true;
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Re-creating certificate for " . $certrow['domain']);
} else {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Creating certificate for " . $certrow['domain']);
}
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $certrow['domain']);
$domains = array(
strtolower($certrow['domain'])
);
// add www.<domain> to SAN list
if ($certrow['wwwserveralias'] == 1) {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $certrow['domain']);
$domains[] = strtolower('www.' . $certrow['domain']);
}
// add alias domains (and possibly www.<aliasdomain>) to SAN list
Database::pexecute($aliasdomains_stmt, array(
'id' => $certrow['domainid']
));
$aliasdomains = $aliasdomains_stmt->fetchAll(\PDO::FETCH_ASSOC);
foreach ($aliasdomains as $aliasdomain) {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $aliasdomain['domain']);
$domains[] = strtolower($aliasdomain['domain']);
if ($aliasdomain['wwwserveralias'] == 1) {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $aliasdomain['domain']);
$domains[] = strtolower('www.' . $aliasdomain['domain']);
}
}
self::runAcmeSh($certrow, $domains, $cert_mode, $cronlog, $changedetected, $do_force);
} else {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Skipping Let's Encrypt generation for " . $certrow['domain'] . " due to an enabled ssl_redirect");
}
}
// If we have a change in a certificate, we need to update the webserver - configs
// This is easiest done by just creating a new task ;)
if ($changedetected) {
if (self::$no_inserttask == false) {
\Froxlor\System\Cronjob::inserttask(1);
}
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Let's Encrypt certificates have been updated");
} else {
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "No new certificates or certificates due for renewal found");
}
return FileDir::makeCorrectDir(dirname(self::$acmesh) . "/" . $domain);
}
private static function runAcmeSh($certrow = array(), $domains = array(), $cert_mode = 'issue', &$cronlog = null, &$changedetected = 0, $force = false)
public static function getAcmeSh()
{
if (! empty($domains)) {
if (self::$do_update) {
self::checkUpgrade();
self::$do_update = false;
}
$acmesh_cmd = self::$acmesh . " --auto-upgrade 0 --server " . self::$apiserver . " --" . $cert_mode . " -d " . implode(" -d ", $domains);
if ($cert_mode == 'issue') {
$acmesh_cmd .= " -w " . Settings::Get('system.letsencryptchallengepath');
}
if (Settings::Get('system.leecc') > 0) {
$acmesh_cmd .= " --keylength ec-" . Settings::Get('system.leecc');
} else {
$acmesh_cmd .= " --keylength " . Settings::Get('system.letsencryptkeysize');
}
if (Settings::Get('system.letsencryptreuseold') != '1') {
$acmesh_cmd .= " --always-force-new-domain-key";
}
if (Settings::Get('system.letsencryptca') == 'testing') {
$acmesh_cmd .= " --staging";
}
if ($force) {
$acmesh_cmd .= " --force";
}
if (defined('CRON_DEBUG_FLAG')) {
$acmesh_cmd .= " --debug";
}
$acme_result = \Froxlor\FileDir::safe_exec($acmesh_cmd);
// debug output of acme.sh run
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, implode("\n", $acme_result));
$return = array();
self::readCertificateToVar($certrow['domain'], $return);
if (! empty($return['crt'])) {
$newcert = openssl_x509_parse($return['crt']);
if ($newcert) {
// Store the new data
Database::pexecute(self::$updcert_stmt, array(
'id' => $certrow['id'],
'domainid' => $certrow['domainid'],
'crt' => $return['crt'],
'key' => $return['key'],
'ca' => $return['chain'],
'chain' => $return['chain'],
'csr' => $return['csr'],
'fullchain' => $return['fullchain'],
'expirationdate' => date('Y-m-d H:i:s', $newcert['validTo_time_t'])
));
if ($certrow['ssl_redirect'] == 3) {
Database::pexecute(self::$upddom_stmt, array(
'domainid' => $certrow['domainid']
));
}
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Updated Let's Encrypt certificate for " . $certrow['domain']);
$changedetected = 1;
} else {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Got non-successful Let's Encrypt response for " . $certrow['domain'] . ":\n" . implode("\n", $acme_result));
}
} else {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Could not get Let's Encrypt certificate for " . $certrow['domain'] . ":\n" . implode("\n", $acme_result));
}
}
return self::$acmesh;
}
private static function readCertificateToVar($domain, &$return)
/**
* get certificate files from filesystem and store in $return array
*
* @param string $domain
* @param array $return
* @param object $cronlog
*/
private static function readCertificateToVar($domain, &$return, &$cronlog)
{
$certificate_folder = dirname(self::$acmesh) . "/" . $domain;
$certificate_folder = self::getWorkingDirFromEnv($domain);
$certificate_folder_noecc = null;
if (Settings::Get('system.leecc') > 0) {
$certificate_folder .= "_ecc";
$certificate_folder_noecc = self::getWorkingDirFromEnv($domain, true);
}
$certificate_folder = \Froxlor\FileDir::makeCorrectDir($certificate_folder);
if (is_dir($certificate_folder)) {
if (is_dir($certificate_folder) || is_dir($certificate_folder_noecc)) {
foreach ([
'crt' => $domain . '.cer',
'key' => $domain . '.key',
@@ -405,28 +555,52 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
if (file_exists($ssl_file)) {
$return[$index] = file_get_contents($ssl_file);
} else {
if (! empty($certificate_folder_noecc)) {
$ssl_file_fb = \Froxlor\FileDir::makeCorrectFile($certificate_folder_noecc . '/' . $sslfile);
if (file_exists($ssl_file_fb)) {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "ECC certificates activated but found only non-ecc file");
$return[$index] = file_get_contents($ssl_file_fb);
continue;
}
}
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Could not find file '" . $sslfile . "' in '" . $certificate_folder . "'");
$return[$index] = null;
}
}
} else {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Could not find certificate-folder '" . $certificate_folder . "'");
}
}
private static function checkInstall()
/**
* install acme.sh if not found yet
*/
private static function checkInstall($tries = 0)
{
if (! file_exists(self::$acmesh)) {
if (! file_exists(self::$acmesh) && $tries > 0) {
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Download/installation of acme.sh seems to have failed. Re-run cronjob to try again or install manually to '" . self::$acmesh . "'");
echo PHP_EOL . "Download/installation of acme.sh seems to have failed. Re-run cronjob to try again or install manually to '" . self::$acmesh . "'" . PHP_EOL;
return false;
} else if (! file_exists(self::$acmesh)) {
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Could not find acme.sh - installing it to /root/.acme.sh/");
$return = false;
\Froxlor\FileDir::safe_exec("wget -O - https://get.acme.sh | sh", $return, array(
'|'
));
// check whether the installation worked
return self::checkInstall(++ $tries);
}
return true;
}
/**
* run upgrade
*/
private static function checkUpgrade()
{
$acmesh_result = \Froxlor\FileDir::safe_exec(self::$acmesh . " --upgrade");
// check for activated cron (which is installed automatically) but we don't need it
$acmesh_result2 = \Froxlor\FileDir::safe_exec(self::$acmesh . " --uninstall-cronjob");
// check for activated cron
$acmesh_result2 = \Froxlor\FileDir::safe_exec(self::$acmesh . " --install-cronjob");
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Checking for LetsEncrypt client upgrades before renewing certificates:\n" . implode("\n", $acmesh_result) . "\n" . implode("\n", $acmesh_result2));
}
}

View File

@@ -432,7 +432,7 @@ class Lighttpd extends HttpConfigBase
protected function getVhostContent($domain, $ssl_vhost = false, $ipid = 0)
{
if ($ssl_vhost === true && $domain['ssl'] != '1' && $domain['ssl_redirect'] != '1') {
if ($ssl_vhost === true && $domain['ssl'] != '1' && $domain['ssl_enabled'] != '1' && $domain['ssl_redirect'] != '1') {
return '';
}
@@ -586,7 +586,7 @@ class Lighttpd extends HttpConfigBase
$ssl_settings .= 'ssl.use-sslv2 = "disable"' . "\n";
$ssl_settings .= 'ssl.use-sslv3 = "disable"' . "\n";
$ssl_settings .= 'ssl.cipher-list = "' . $ssl_cipher_list . '"' . "\n";
$ssl_settings .= 'ssl.honor-cipher-order = "enable"' . "\n";
$ssl_settings .= 'ssl.honor-cipher-order = ' . ($domain['ssl_honorcipherorder'] == '1' ? '"enable"' : '"disable"') . "\n";
$ssl_settings .= 'ssl.pemfile = "' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . '"' . "\n";
if ($domain['ssl_ca_file'] != '') {

View File

@@ -71,7 +71,7 @@ class Nginx extends HttpConfigBase
}
$logtype = 'frx_custom';
$this->nginx_data[$vhosts_filename] = 'log_format ' . $logtype . ' "' . Settings::Get('system.logfiles_format') . '";' . "\n";
$this->nginx_data[$vhosts_filename] = 'log_format ' . $logtype . ' ' . Settings::Get('system.logfiles_format') . ';' . "\n";
}
}
@@ -226,7 +226,12 @@ class Nginx extends HttpConfigBase
$aliases = " " . trim($aliases);
}
$this->nginx_data[$vhost_filename] .= "\t" . 'server_name ' . Settings::Get('system.hostname') . $aliases . ';' . "\n";
$this->nginx_data[$vhost_filename] .= "\t" . 'access_log /var/log/nginx/access.log;' . "\n";
$logtype = 'combined';
if (Settings::Get('system.logfiles_format') != '') {
$logtype = 'frx_custom';
}
$this->nginx_data[$vhost_filename] .= "\t" . 'access_log /var/log/nginx/access.log ' . $logtype . ';' . "\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');
@@ -272,6 +277,8 @@ class Nginx extends HttpConfigBase
*/
if ($row_ipsandports['ssl'] == '1') {
$row_ipsandports['domain'] = Settings::Get('system.hostname');
$row_ipsandports['ssl_honorcipherorder'] = Settings::Get('system.honorcipherorder');
$row_ipsandports['ssl_sessiontickets'] = Settings::Get('system.sessiontickets');
$this->nginx_data[$vhost_filename] .= $this->composeSslSettings($row_ipsandports);
if ($row_ipsandports['ssl_specialsettings'] != '') {
$this->nginx_data[$vhost_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['ssl_specialsettings'], array(
@@ -693,14 +700,17 @@ class Nginx extends HttpConfigBase
if (! file_exists($dhparams)) {
\Froxlor\FileDir::safe_exec('openssl dhparam -out ' . escapeshellarg($dhparams) . ' 4096');
}
$sslsettings .= 'ssl_dhparam ' . $dhparams . ';' . "\n";
$sslsettings .= "\t" . 'ssl_dhparam ' . $dhparams . ';' . "\n";
}
// When <1.11.0: Defaults to prime256v1, similar to first curve recommendation by Mozilla.
// (When specifyng just one, there's no fallback when specific curve is not supported by client.)
// When >1.11.0: Defaults to auto, using recommended curves provided by OpenSSL.
// see https://github.com/Froxlor/Froxlor/issues/652
// $sslsettings .= "\t" . 'ssl_ecdh_curve secp384r1;' . "\n";
$sslsettings .= "\t" . 'ssl_prefer_server_ciphers on;' . "\n";
$sslsettings .= "\t" . 'ssl_prefer_server_ciphers ' . (isset($domain_or_ip['ssl_honorcipherorder']) && $domain_or_ip['ssl_honorcipherorder'] == '1' ? 'on' : 'off') . ';' . "\n";
if (Settings::Get('system.sessionticketsenabled') == '1') {
$sslsettings .= "\t" . 'ssl_session_tickets ' . (isset($domain_or_ip['ssl_sessiontickets']) && $domain_or_ip['ssl_sessiontickets'] == '1' ? 'on' : 'off') . ';' . "\n";
}
$sslsettings .= "\t" . 'ssl_session_cache shared:SSL:10m;' . "\n";
$sslsettings .= "\t" . 'ssl_certificate ' . \Froxlor\FileDir::makeCorrectFile($domain_or_ip['ssl_cert_file']) . ';' . "\n";

View File

@@ -115,6 +115,7 @@ class Fpm
$fpm_requests = (int) $this->fpm_cfg['max_requests'];
$fpm_process_idle_timeout = (int) $this->fpm_cfg['idle_timeout'];
$fpm_limit_extensions = $this->fpm_cfg['limit_extensions'];
$fpm_custom_config = $this->fpm_cfg['custom_config'];
if ($fpm_children == 0) {
$fpm_children = 1;
@@ -260,6 +261,12 @@ class Fpm
$fpm_config .= 'php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f ' . $this->domain['email'] . "\n";
}
// append custom phpfpm configuration
if (! empty($fpm_custom_config)) {
$fpm_config .= "\n; Custom Configuration\n";
$fpm_config .= \Froxlor\PhpHelper::replaceVariables($fpm_custom_config, $php_ini_variables);
}
fwrite($fh, $fpm_config, strlen($fpm_config));
fclose($fh);
}

View File

@@ -77,6 +77,7 @@ class BackupCron extends \Froxlor\Cron\FroxlorCron
$del_stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_TASKS . "` WHERE `id` = :id");
$cronlog = FroxlorLogger::getInstanceOf();
$all_jobs = $result_tasks_stmt->fetchAll();
foreach ($all_jobs as $row) {
@@ -96,7 +97,7 @@ class BackupCron extends \Froxlor\Cron\FroxlorCron
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg($row['data']['destdir']));
}
self::createCustomerBackup($row['data'], $customerdocroot, FroxlorLogger::getInstanceOf());
self::createCustomerBackup($row['data'], $customerdocroot, $cronlog);
}
}

View File

@@ -67,7 +67,7 @@ class Extrausers
'name' => \Froxlor\Customer\Customer::getCustomerDetail($u['customerid'], 'name'),
'company' => \Froxlor\Customer\Customer::getCustomerDetail($u['customerid'], 'company')
);
$u['comment'] = \Froxlor\User::getCorrectUserSalutation($salutation_array);
$u['comment'] = self::cleanString(\Froxlor\User::getCorrectUserSalutation($salutation_array));
if ($u['login_enabled'] != 'Y') {
$u['password'] = '*';
$u['shell'] = '/bin/false';
@@ -90,4 +90,10 @@ class Extrausers
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Error when writing ' . $type . ' file entries');
}
}
private static function cleanString($string = null)
{
$allowed = "/[^a-z0-9\\.\\-\\_\\ ]/i";
return preg_replace($allowed, "", $string);
}
}

View File

@@ -36,7 +36,7 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
if ((int) Settings::Get('system.report_trafficmax') > 0) {
// Warn the customers at xx% traffic-usage
$result_stmt = Database::prepare("
SELECT `c`.`customerid`, `c`.`adminid`, `c`.`name`, `c`.`firstname`,
SELECT `c`.`customerid`, `c`.`customernumber`, `c`.`adminid`, `c`.`name`, `c`.`firstname`,
`c`.`company`, `c`.`traffic`, `c`.`email`, `c`.`def_language`,
`a`.`name` AS `adminname`, `a`.`email` AS `adminmail`,
(SELECT SUM(`t`.`http` + `t`.`ftp_up` + `t`.`ftp_down` + `t`.`mail`)
@@ -55,16 +55,19 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
Database::pexecute($result_stmt, $result_data);
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
if (isset($row['traffic']) && $row['traffic'] > 0 && $row['traffic_used'] != null && (($row['traffic_used'] * 100) / $row['traffic']) >= (int) Settings::Get('system.report_trafficmax')) {
$rep_userinfo = array(
'name' => $row['name'],
'firstname' => $row['firstname'],
'company' => $row['company']
'company' => $row['company'],
'customernumber' => $row['customernumber']
);
$replace_arr = array(
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($rep_userinfo),
'NAME' => $row['name'], // < keep this for compatibility
'NAME' => $rep_userinfo['name'],
'FIRSTNAME' => $rep_userinfo['firstname'],
'COMPANY' => $rep_userinfo['company'],
'CUSTOMER_NO' => $rep_userinfo['customernumber'],
'TRAFFIC' => round(($row['traffic'] / 1024), 2), /* traffic is stored in KB, template uses MB */
'TRAFFICUSED' => round(($row['traffic_used'] / 1024), 2), /* traffic is stored in KB, template uses MB */
'USAGE_PERCENT' => round(($row['traffic_used'] * 100) / $row['traffic'], 2),
@@ -89,9 +92,11 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
}
// include english language file (fallback)
include_once \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
include \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
// include admin/customer language file
include_once \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/' . $langfile);
if ($lngfile != 'lng/english.lng.php') {
include \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/' . $langfile);
}
// Get mail templates from database; the ones from 'admin' are fetched for fallback
$result2_stmt = Database::prepare("
@@ -142,6 +147,8 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
Database::pexecute($upd_stmt, array(
'customerid' => $row['customerid']
));
unset($lng);
}
}
@@ -168,8 +175,8 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
$replace_arr = array(
'NAME' => $row['name'],
'TRAFFIC' => round(($row['traffic'] / 1024), 2), /* traffic is stored in KB, template uses MB */
'TRAFFICUSED' => round(($row['traffic_used_total'] / 1024), 2), /* traffic is stored in KB, template uses MB */
'USAGE_PERCENT' => round(($row['traffic_used_total'] * 100) / $row['traffic'], 2),
'TRAFFICUSED' => round(($row['traffic_used_total'] / 1024), 2), /* traffic is stored in KB, template uses MB */
'USAGE_PERCENT' => round(($row['traffic_used_total'] * 100) / $row['traffic'], 2),
'MAX_PERCENT' => Settings::Get('system.report_trafficmax')
);
@@ -191,9 +198,11 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
}
// include english language file (fallback)
include_once \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
include \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
// include admin/customer language file
include_once \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/' . $langfile);
if ($lngfile != 'lng/english.lng.php') {
include \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/' . $langfile);
}
// Get mail templates from database; the ones from 'admin' are fetched for fallback
$result2_stmt = Database::prepare("
@@ -322,6 +331,8 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
}
$mail->ClearAddresses();
unset($lng);
}
}
} // trafficmax > 0
@@ -343,7 +354,7 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
* report about diskusage for customers
*/
$result_stmt = Database::query("
SELECT `c`.`customerid`, `c`.`adminid`, `c`.`name`, `c`.`firstname`,
SELECT `c`.`customerid`, `c`.`customernumber`, `c`.`adminid`, `c`.`name`, `c`.`firstname`,
`c`.`company`, `c`.`diskspace`, `c`.`diskspace_used`, `c`.`email`, `c`.`def_language`,
`a`.`name` AS `adminname`, `a`.`email` AS `adminmail`
FROM `" . TABLE_PANEL_CUSTOMERS . "` AS `c`
@@ -361,11 +372,15 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
$rep_userinfo = array(
'name' => $row['name'],
'firstname' => $row['firstname'],
'company' => $row['company']
'company' => $row['company'],
'customernumber' => $row['customernumber']
);
$replace_arr = array(
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($rep_userinfo),
'NAME' => $row['name'], // < keep this for compatibility
'NAME' => $rep_userinfo['name'],
'FIRSTNAME' => $rep_userinfo['firstname'],
'COMPANY' => $rep_userinfo['company'],
'CUSTOMER_NO' => $rep_userinfo['customernumber'],
'DISKAVAILABLE' => round(($row['diskspace'] / 1024), 2), /* traffic is stored in KB, template uses MB */
'DISKUSED' => round($row['diskspace_used'] / 1024, 2), /* traffic is stored in KB, template uses MB */
'USAGE_PERCENT' => round(($row['diskspace_used'] * 100) / $row['diskspace'], 2),
@@ -386,13 +401,15 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
$lngfile = Database::pexecute_first($lngfile_stmt, array(
'deflang' => Settings::Get('panel.standardlanguage')
));
$langfile = $lngfile['file'];
$langfile = $lngfile['file'] ?? 'lng/english.lng.php';
}
// include english language file (fallback)
include_once \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
include \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
// include admin/customer language file
include_once \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/' . $langfile);
if ($lngfile != 'lng/english.lng.php') {
include \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/' . $langfile);
}
// Get mail templates from database; the ones from 'admin' are fetched for fallback
$result2_stmt = Database::prepare("
@@ -443,6 +460,8 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
Database::pexecute($upd_stmt, array(
'customerid' => $row['customerid']
));
unset($lng);
}
}
@@ -483,9 +502,11 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
}
// include english language file (fallback)
include_once \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
include \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/lng/english.lng.php');
// include admin/customer language file
include_once \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/' . $langfile);
if ($lngfile != 'lng/english.lng.php') {
include \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . '/' . $langfile);
}
// Get mail templates from database; the ones from 'admin' are fetched for fallback
$result2_stmt = Database::prepare("
@@ -536,6 +557,8 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
Database::pexecute($upd_stmt, array(
'adminid' => $row['adminid']
));
unset($lng);
}
}
} // webmax > 0

View File

@@ -137,7 +137,11 @@ class TrafficCron extends \Froxlor\Cron\FroxlorCron
$mysqlusage_all[$row_database['customerid']] = 0;
}
// sum up result
$mysqlusage_all[$row_database['customerid']] += floatval($mysql_usage_row['customerusage']);
if ($mysql_usage_row) {
$mysqlusage_all[$row_database['customerid']] += floatval($mysql_usage_row['customerusage']);
} else {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_WARNING, "Cannot get usage for database " . $row_database['databasename'] . ".");
}
} else {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_WARNING, "Seems like the database " . $row_database['databasename'] . " had been removed manually.");
}

View File

@@ -30,7 +30,7 @@ class Customer
*
* @return string customers loginname
*/
public function getLoginNameByUid($uid = null)
public static function getLoginNameByUid($uid = null)
{
$result_stmt = Database::prepare("
SELECT `loginname` FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `guid` = :guid

View File

@@ -160,7 +160,7 @@ class Dns
// unset special CAA required-entry
unset($required_entries[$entry['type']][md5("@CAA@")]);
}
if (Settings::Get('spf.use_spf') == '1' && $entry['type'] == 'TXT' && $entry['record'] == '@' && strtolower(substr($entry['content'], 0, 7)) == '"v=spf1') {
if (Settings::Get('spf.use_spf') == '1' && $entry['type'] == 'TXT' && $entry['record'] == '@' && (strtolower(substr($entry['content'], 0, 7)) == '"v=spf1' || strtolower(substr($entry['content'], 0, 6)) == 'v=spf1') ) {
// unset special spf required-entry
unset($required_entries[$entry['type']][md5("@SPF@")]);
}

View File

@@ -6,6 +6,41 @@ use Froxlor\Database\Database;
class Domain
{
/**
* return all ip addresses associated with given domain,
* returns all ips if domain-id = 0 (froxlor.vhost)
*
* @param int $domain_id
* @return array
*/
public static function getIpsOfDomain($domain_id)
{
if ($domain_id > 0) {
$sel_stmt = Database::prepare("
SELECT i.ip FROM `" . TABLE_PANEL_IPSANDPORTS . "` `i`
LEFT JOIN `" . TABLE_DOMAINTOIP . "` `dip` ON dip.id_ipandports = i.id
AND dip.id_domain = :domainid
GROUP BY i.ip
");
$sel_param = array(
'domainid' => $domain_id
);
} else {
// assuming froxlor.vhost (id = 0)
$sel_stmt = Database::prepare("
SELECT ip FROM `" . TABLE_PANEL_IPSANDPORTS . "`
GROUP BY ip
");
$sel_param = array();
}
Database::pexecute($sel_stmt, $sel_param);
$result = array();
while ($ip = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $ip['ip'];
}
return $result;
}
/**
* return an array of all enabled redirect-codes
*
@@ -294,9 +329,9 @@ class Domain
public static function doLetsEncryptCleanUp($domainname = null)
{
// @ see \Froxlor\Cron\Http\LetsEncrypt\AcmeSh.php
$acmesh = "/root/.acme.sh/acme.sh";
$acmesh = \Froxlor\Cron\Http\LetsEncrypt\AcmeSh::getAcmeSh();
if (file_exists($acmesh)) {
$certificate_folder = dirname($acmesh) . "/" . $domainname;
$certificate_folder = \Froxlor\Cron\Http\LetsEncrypt\AcmeSh::getWorkingDirFromEnv($domainname);
if (\Froxlor\Settings::Get('system.leecc') > 0) {
$certificate_folder .= "_ecc";
}

View File

@@ -7,10 +7,10 @@ final class Froxlor
{
// Main version variable
const VERSION = '0.10.8';
const VERSION = '0.10.18';
// Database version (YYYYMMDDC where C is a daily counter)
const DBVERSION = '201911220';
const DBVERSION = '202005150';
// Distribution branding-tag (used for Debian etc.)
const BRANDING = '';

View File

@@ -87,10 +87,13 @@ class FroxlorLogger
self::$ml->pushHandler(new SyslogHandler('froxlor', LOG_USER, Logger::DEBUG));
break;
case 'file':
if (empty(Settings::Get('logger.logfile')) || ! is_writeable(Settings::Get('logger.logfile'))) {
$logger_logfile = Settings::Get('logger.logfile');
// is_writable needs an existing file to check if it's actually writable
@touch($logger_logfile);
if (empty($logger_logfile) || ! is_writable($logger_logfile)) {
Settings::Set('logger.logfile', '/tmp/froxlor.log');
}
self::$ml->pushHandler(new StreamHandler(Settings::Get('logger.logfile'), Logger::DEBUG));
self::$ml->pushHandler(new StreamHandler($logger_logfile, Logger::DEBUG));
break;
case 'mysql':
self::$ml->pushHandler(new MysqlHandler(Logger::DEBUG));

View File

@@ -37,20 +37,31 @@ class Statistics
\Froxlor\FileDir::safe_exec('mkdir -p ' . escapeshellarg(Settings::Get('system.awstats_conf')));
}
$logformat = Settings::Get('system.awstats_logformat');
if (! is_numeric($logformat)) {
// if LogFormat is NOT numeric (e.g. 1,2,3,4), we quote it.
// 1-4 are pre-defined formats by awstats which must not be quoted to work properly. So if
// it is not a integer, it is something customized and we simply quote it.
// Only escaping double-quote should be fine, as we only put the whole string under double-quote.
$logformat = '"' . str_replace('"', '\"', Settings::Get('system.awstats_logformat')) . '"';
}
// These are the variables we will replace
$regex = array(
'/\{LOG_FILE\}/',
'/\{SITE_DOMAIN\}/',
'/\{HOST_ALIASES\}/',
'/\{CUSTOMER_DOCROOT\}/',
'/\{AWSTATS_CONF\}/'
'/\{AWSTATS_CONF\}/',
'/\{AWSTATS_LOGFORMAT\}/'
);
$replace = array(
\Froxlor\FileDir::makeCorrectFile($logFile),
$siteDomain,
$hostAliases,
$awstats_dir,
\Froxlor\FileDir::makeCorrectDir(Settings::Get('system.awstats_conf'))
\Froxlor\FileDir::makeCorrectDir(Settings::Get('system.awstats_conf')),
$logformat
);
// File names

View File

@@ -209,12 +209,12 @@ class MailLogParser
$timestamp = $this->getLogTimestamp($line);
if ($this->startTime < $timestamp) {
if (preg_match("/dovecot.*(?::|\]) imap\(.*@([a-z0-9\.\-]+)\):.*(?:in=(\d+) out=(\d+)|bytes=(\d+)\/(\d+))/i", $line, $matches)) {
if (preg_match("/dovecot.*(?::|\]) imap\(.*@([a-z0-9\.\-]+)\)(<\d+><[a-z0-9+\/=]+>)?:.*(?:in=(\d+) out=(\d+)|bytes=(\d+)\/(\d+))/i", $line, $matches)) {
// Dovecot IMAP
$this->addDomainTraffic($matches[1], (int) $matches[2] + (int) $matches[3], $timestamp);
} elseif (preg_match("/dovecot.*(?::|\]) pop3\(.*@([a-z0-9\.\-]+)\):.*in=(\d+).*out=(\d+)/i", $line, $matches)) {
$this->addDomainTraffic($matches[1], (int) $matches[3] + (int) $matches[4], $timestamp);
} elseif (preg_match("/dovecot.*(?::|\]) pop3\(.*@([a-z0-9\.\-]+)\)(<\d+><[a-z0-9+\/=]+>)?:.*in=(\d+).*out=(\d+)/i", $line, $matches)) {
// Dovecot POP3
$this->addDomainTraffic($matches[1], (int) $matches[2] + (int) $matches[3], $timestamp);
$this->addDomainTraffic($matches[1], (int) $matches[3] + (int) $matches[4], $timestamp);
}
}
}

View File

@@ -374,7 +374,7 @@ class PhpHelper
$returnval = array();
if (is_array($source)) {
$source = array_map('trim', $source);
$source = array_filter($source, function ($value) {
$returnval = array_filter($source, function ($value) {
return $value !== '';
});
} else {

View File

@@ -12,5 +12,4 @@ class FroxlorVhostSettings
$result = Database::pexecute_first($sel_stmt);
return $result['vcentries'] > 0 ? true : false;
}
}

View File

@@ -242,8 +242,8 @@ class Store
$mysql_access_host_array = array_map('trim', explode(',', Settings::Get('system.mysql_access_host')));
$mysql_access_host_array[] = $newfieldvalue;
$mysql_access_host_array = array_unique(\Froxlor\PhpHelper::arrayTrim($mysql_access_host_array));
$mysql_access_host = implode(',', $mysql_access_host_array);
\Froxlor\Database\DbManager::correctMysqlUsers($mysql_access_host_array);
$mysql_access_host = implode(',', $mysql_access_host_array);
Settings::Set('system.mysql_access_host', $mysql_access_host);
}
@@ -293,9 +293,11 @@ class Store
'cleanMySQLAccessHost'
), $mysql_access_host_array);
$mysql_access_host_array = array_unique($mysql_access_host_array);
$mysql_access_host_array = array_unique(\Froxlor\PhpHelper::arrayTrim($mysql_access_host_array));
$newfieldvalue = implode(',', $mysql_access_host_array);
\Froxlor\Database\DbManager::correctMysqlUsers($mysql_access_host_array);
$mysql_access_host = implode(',', $mysql_access_host_array);
Settings::Set('system.mysql_access_host', $mysql_access_host);
}
return $returnvalue;

View File

@@ -79,8 +79,8 @@ class User
/**
* Function which updates all counters of used ressources in panel_admins and panel_customers
*
* @param
* bool Set to true to get an array with debug information
* @param bool $returndebuginfo
* Set to true to get an array with debug information
* @return array Contains debug information if parameter 'returndebuginfo' is set to true
*
* @author Florian Lippert <flo@syscp.org> (2003-2009)
@@ -100,17 +100,17 @@ class User
// Customers
$customers_stmt = Database::prepare('SELECT * FROM `' . TABLE_PANEL_CUSTOMERS . '` ORDER BY `customerid`');
Database::pexecute($customers_stmt);
// array to store currently used resources per admin
$admin_resources = array();
while ($customer = $customers_stmt->fetch(\PDO::FETCH_ASSOC)) {
// set current admin
$cur_adm = $customer['adminid'];
// initialize admin-resources array for admin $customer['adminid']
if (! isset($admin_resources[$cur_adm])) {
$admin_resources[$cur_adm] = array();
}
// fill admin resource usage array with customer data
self::addResourceCountEx($admin_resources[$cur_adm], $customer, 'diskspace_used', 'diskspace');
self::addResourceCountEx($admin_resources[$cur_adm], $customer, 'traffic_used', 'traffic_used'); // !!! yes, USED and USED
@@ -126,6 +126,7 @@ class User
self::addResourceCount($admin_resources[$cur_adm], $customer, $field . '_used', $field);
}
// calculate real usage
$customer_mysqls_stmt = Database::prepare('SELECT COUNT(*) AS `number_mysqls` FROM `' . TABLE_PANEL_DATABASES . '`
WHERE `customerid` = :cid');
$customer_mysqls = Database::pexecute_first($customer_mysqls_stmt, array(
@@ -181,6 +182,7 @@ class User
));
$customer['email_quota_used_new'] = (int) $customer_email_quota['email_quota'];
// update database accordingly
$stmt = Database::prepare('UPDATE `' . TABLE_PANEL_CUSTOMERS . '`
SET `mysqls_used` = :mysqls_used,
`emails_used` = :emails_used,
@@ -211,63 +213,56 @@ class User
$admins_stmt = Database::prepare('SELECT * FROM `' . TABLE_PANEL_ADMINS . '` ORDER BY `adminid`');
Database::pexecute($admins_stmt, array());
$resource_fields = array(
'diskspace_used',
'traffic_used',
'mysqls_used',
'ftps_used',
'emails_used',
'email_accounts_used',
'email_forwarders_used',
'email_quota_used',
'subdomains_used'
);
$admin_customers_stmt = Database::prepare('SELECT * FROM `' . TABLE_PANEL_CUSTOMERS . '` WHERE `adminid` = :aid');
while ($admin = $admins_stmt->fetch(\PDO::FETCH_ASSOC)) {
$admin_customers_stmt = Database::prepare('SELECT * FROM `' . TABLE_PANEL_CUSTOMERS . '` WHERE `adminid` = :aid');
Database::pexecute($admin_customers_stmt, array(
"aid" => $admin['adminid']
));
$admin_customers = $admin_customers_stmt->fetchAll(\PDO::FETCH_ASSOC);
$admin['customers_used_new'] = count($admin_customers);
$admin_domains_stmt = Database::prepare('SELECT COUNT(*) AS `number_domains` FROM `' . TABLE_PANEL_DOMAINS . '` WHERE `adminid` = :aid');
$admin_domains_stmt = Database::prepare('SELECT COUNT(*) AS `number_domains` FROM `' . TABLE_PANEL_DOMAINS . '` WHERE `adminid` = :aid AND `parentdomainid` = "0"');
$admin_domains = Database::pexecute_first($admin_domains_stmt, array(
"aid" => $admin['adminid']
));
// substract the amount of domains that are std-subdomains later when we iterated through all customers and now for sure
// substract the amount of domains that are std-subdomains later when we iterated through all customers and know for sure
$admin['domains_used_new'] = $admin_domains['number_domains'];
// set current admin
$cur_adm = $admin['adminid'];
// if there's an admin without any customers it might be possible that the id is not yet known in $admin_resources
if (! isset($admin_resources[$cur_adm])) {
$admin_resources[$cur_adm] = array();
}
foreach (array(
'diskspace_used',
'traffic_used',
'mysqls_used',
'ftps_used',
'emails_used',
'email_accounts_used',
'email_forwarders_used',
'email_quota_used',
'subdomains_used'
) as $field) {
// be sure that all fields are set in the array
foreach ($resource_fields as $field) {
self::initArrField($field, $admin_resources[$cur_adm], 0);
$admin[$field . '_new'] = $admin_resources[$cur_adm][$field];
// initialize new values
$admin[$field . '_new'] = 0;
}
// now get the customer resource usage which we have re-calculated previously
foreach ($admin_customers as $acustomer) {
foreach (array(
'diskspace_used',
'traffic_used',
'mysqls_used',
'ftps_used',
'emails_used',
'email_accounts_used',
'email_forwarders_used',
'email_quota_used',
'subdomains_used'
) as $field) {
foreach ($resource_fields as $field) {
$admin[$field . '_new'] += $acustomer[$field];
}
// check for std-subdomain
if ($acustomer['standardsubdomain'] > 0) {
// std-subdomain does not count to assign resource
$admin['domains_used_new']--;
// std-subdomain does not count as assigned resource
$admin['domains_used_new'] --;
}
}
// update database entry accordingly
$stmt = Database::prepare('UPDATE `' . TABLE_PANEL_ADMINS . '`
SET `customers_used` = :customers_used,
`domains_used` = :domains_used,

View File

@@ -4625,7 +4625,7 @@ aliases: files
<command><![CDATA[useradd -s /bin/false -g {{settings.system.mod_fcgid_httpgroup}} {{settings.system.mod_fcgid_httpuser}}]]></command>
<command><![CDATA[mkdir -p {{settings.system.mod_fcgid_configdir}}]]></command>
<command><![CDATA[mkdir -p {{settings.system.mod_fcgid_tmpdir}}]]></command>
<command><![CDATA[a2dismod php7.0]]></command>
<command><![CDATA[a2dismod php7.2]]></command>
</commands>
<!-- instead of just restarting apache, we let the cronjob do all the
dirty work -->

View File

@@ -4827,7 +4827,7 @@ aliases: files
<command><![CDATA[useradd -s /bin/false -g {{settings.system.mod_fcgid_httpgroup}} {{settings.system.mod_fcgid_httpuser}}]]></command>
<command><![CDATA[mkdir -p {{settings.system.mod_fcgid_configdir}}]]></command>
<command><![CDATA[mkdir -p {{settings.system.mod_fcgid_tmpdir}}]]></command>
<command><![CDATA[a2dismod php7.0]]></command>
<command><![CDATA[a2dismod php7.3]]></command>
</commands>
<!-- instead of just restarting apache, we let the cronjob do all the
dirty work -->
@@ -4860,7 +4860,7 @@ aliases: files
</visibility>
<visibility mode="true">{{settings.phpfpm.enabled_ownvhost}}
</visibility>
<command><![CDATA[a2dismod php7.0]]></command>
<command><![CDATA[a2dismod php7.3]]></command>
</commands>
<commands index="5">
<visibility mode="equals" value="apache2">{{settings.system.webserver}}

View File

@@ -1,7 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<froxlor>
<distribution name="RHEL / CentOS" version="7"
<distribution name="CentOS" version="7"
defaulteditor="/usr/bin/nano">
<defaults>
<property>
<varname>apacheconf_vhost</varname>
<settinggroup>system</settinggroup>
<value>/etc/httpd/conf.d/</value>
</property>
<property>
<varname>apacheconf_diroptions</varname>
<settinggroup>system</settinggroup>
<value>/etc/httpd/conf.d/</value>
</property>
<property>
<varname>apacheconf_htpasswddir</varname>
<settinggroup>system</settinggroup>
<value>/etc/httpd/froxlor-htpasswd/</value>
</property>
<property>
<varname>apachereload_command</varname>
<settinggroup>system</settinggroup>
<value>systemctl reload-or-restart httpd.service</value>
</property>
<property>
<varname>bindreload_command</varname>
<settinggroup>system</settinggroup>
<value>systemctl reload-or-restart named.service</value>
</property>
<property>
<varname>crondreload</varname>
<settinggroup>system</settinggroup>
<value>systemctl reload-or-restart crond.service</value>
</property>
</defaults>
<services>
<!-- HTTP -->
<service type="http" title="{{lng.admin.configfiles.http}}">
@@ -61,6 +93,20 @@ Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}
<command><![CDATA[systemctl reload-or-restart httpd.service]]></command>
</daemon>
</service>
<!--DNS -->
<service type="dns" title="{{lng.admin.configfiles.dns}}">
<!--Bind9 -->
<daemon name="bind" title="Bind9 nameserver" default="true">
<install><![CDATA[yum install bind]]></install>
<command><![CDATA[ln -sv /etc/named /etc/bind]]></command>
<command><![CDATA[echo "include \"/etc/named.conf.local\";" >> /etc/named.conf]]></command>
<command><![CDATA[echo "include \"{{settings.system.bindconf_directory}}froxlor_bind.conf\";" >> /etc/named.conf.local]]></command>
<command><![CDATA[touch {{settings.system.bindconf_directory}}froxlor_bind.conf]]></command>
<command><![CDATA[chown named:0 {{settings.system.bindconf_directory}}froxlor_bind.conf]]></command>
<command><![CDATA[chmod 0644 {{settings.system.bindconf_directory}}froxlor_bind.conf]]></command>
<command><![CDATA[systemctl restart named]]></command>
</daemon>
</service>
<!-- SMTP services -->
<service type="smtp" title="{{lng.admin.configfiles.smtp}}">
<!-- general SMTP commands -->
@@ -1825,6 +1871,7 @@ iterate_query = SELECT username AS user FROM mail_users
<!-- Proftpd -->
<daemon name="proftpd" version="1.3" title="ProFTPd"
default="true">
<install><![CDATA[yum --enablerepo=extras install epel-release]]></install>
<install><![CDATA[yum install proftpd proftpd-mysql]]></install>
<file name="/etc/proftpd.conf" chown="root:0"
chmod="0600" backup="true">
@@ -2295,9 +2342,10 @@ ControlsLog /var/log/proftpd/controls.log
<!-- AWstats -->
<daemon name="awstats"
title="Awstats (webalizer alternative)">
<install><![CDATA[yum install awstats]]></install>
<command><![CDATA[sed -i.bak 's/^DirData/# DirData/' {{settings.system.awstats_conf}}/awstats.model.conf]]></command>
<command><![CDATA[sed -i.bak 's|^\\(DirIcons=\\).*$|\\1\\"/awstats-icon\\"|' {{settings.system.awstats_conf}}/awstats.model.conf]]></command>
<command><![CDATA[rm /etc/cron.d/awstats]]></command>
<command><![CDATA[rm /etc/cron.hourly/awstats]]></command>
</daemon>
<!-- libnss-mysql -->
<daemon name="libnss"

2484
lib/configfiles/centos8.xml Normal file

File diff suppressed because it is too large Load Diff

4100
lib/configfiles/focal.xml Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<froxlor>
<distribution name="Ubuntu" codename="Xenial"
version="16.04" defaulteditor="/bin/nano">
version="16.04" defaulteditor="/bin/nano" deprecated="true">
<services>
<!-- HTTP -->
<service type="http" title="{{lng.admin.configfiles.http}}">

View File

@@ -180,6 +180,20 @@ return array(
'image' => 'icons/domain_add.png',
'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? true : false,
'fields' => array(
'sslenabled' => array(
'visible' => ($ssl_ipsandports != '' ? true : false),
'label' => $lng['admin']['domain_sslenabled'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
'1'
)
),
'no_ssl_available_info' => array(
'visible' => ($ssl_ipsandports == '' ? true : false),
'label' => 'SSL',
@@ -251,7 +265,6 @@ return array(
'desc' => $lng['serversettings']['ssl']['ssl_protocols']['description'],
'type' => 'checkbox',
'value' => array(
'TLSv1',
'TLSv1.2'
),
'values' => array(
@@ -356,6 +369,32 @@ return array(
)
),
'value' => array()
),
'honorcipherorder' => array(
'visible' => ($ssl_ipsandports != '' ? true : false),
'label' => $lng['admin']['domain_honorcipherorder'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array()
),
'sessiontickets' => array(
'visible' => ($ssl_ipsandports != '' ? true : false) && \Froxlor\Settings::Get('system.webserver') != 'lighttpd' && \Froxlor\Settings::Get('system.sessionticketsenabled' != '1'),
'label' => $lng['admin']['domain_sessiontickets'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
'1'
)
)
)
),

View File

@@ -212,6 +212,20 @@ return array(
'image' => 'icons/domain_edit.png',
'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? true : false,
'fields' => array(
'sslenabled' => array(
'visible' => ($ssl_ipsandports != '' ? true : false),
'label' => $lng['admin']['domain_sslenabled'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
$result['ssl_enabled']
)
),
'no_ssl_available_info' => array(
'visible' => ($ssl_ipsandports == '' ? true : false),
'label' => 'SSL',
@@ -290,7 +304,7 @@ return array(
'label' => $lng['serversettings']['ssl']['ssl_protocols']['title'],
'desc' => $lng['serversettings']['ssl']['ssl_protocols']['description'],
'type' => 'checkbox',
'value' => !empty($result['ssl_protocols']) ? explode(",", $result['ssl_protocols']) : explode(",", \Froxlor\Settings::Get('system.ssl_protocols')),
'value' => ! empty($result['ssl_protocols']) ? explode(",", $result['ssl_protocols']) : explode(",", \Froxlor\Settings::Get('system.ssl_protocols')),
'values' => array(
array(
'value' => 'TLSv1',
@@ -316,14 +330,14 @@ return array(
'label' => $lng['serversettings']['ssl']['ssl_cipher_list']['title'],
'desc' => $lng['serversettings']['ssl']['ssl_cipher_list']['description'],
'type' => 'text',
'value' => !empty($result['ssl_cipher_list']) ? $result['ssl_cipher_list'] : \Froxlor\Settings::Get('system.ssl_cipher_list')
'value' => ! empty($result['ssl_cipher_list']) ? $result['ssl_cipher_list'] : \Froxlor\Settings::Get('system.ssl_cipher_list')
),
'tlsv13_cipher_list' => array(
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' && \Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1 ? true : false),
'label' => $lng['serversettings']['ssl']['tlsv13_cipher_list']['title'],
'desc' => $lng['serversettings']['ssl']['tlsv13_cipher_list']['description'],
'type' => 'text',
'value' => !empty($result['tlsv13_cipher_list']) ? $result['tlsv13_cipher_list'] : \Froxlor\Settings::Get('system.tlsv13_cipher_list')
'value' => ! empty($result['tlsv13_cipher_list']) ? $result['tlsv13_cipher_list'] : \Froxlor\Settings::Get('system.tlsv13_cipher_list')
),
'ssl_specialsettings' => array(
'visible' => ($userinfo['change_serversettings'] == '1' ? true : false),
@@ -401,6 +415,34 @@ return array(
'value' => array(
$result['ocsp_stapling']
)
),
'honorcipherorder' => array(
'visible' => ($ssl_ipsandports != '' ? true : false),
'label' => $lng['admin']['domain_honorcipherorder'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
$result['ssl_honorcipherorder']
)
),
'sessiontickets' => array(
'visible' => ($ssl_ipsandports != '' ? true : false) && \Froxlor\Settings::Get('system.webserver') != 'lighttpd' && \Froxlor\Settings::Get('system.sessionticketsenabled' != '1'),
'label' => $lng['admin']['domain_sessiontickets'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
$result['ssl_sessiontickets']
)
)
)
),

View File

@@ -32,13 +32,13 @@ return array(
'label' => $lng['serversettings']['phpfpm_settings']['reload'],
'type' => 'text',
'maxlength' => 255,
'value' => 'service php7.0-fpm restart'
'value' => 'service php7.3-fpm restart'
),
'config_dir' => array(
'label' => $lng['serversettings']['phpfpm_settings']['configdir'],
'type' => 'text',
'maxlength' => 255,
'value' => '/etc/php/7.0/fpm/pool.d/'
'value' => '/etc/php/7.3/fpm/pool.d/'
),
'pm' => array(
'label' => $lng['serversettings']['phpfpm_settings']['pm'],
@@ -49,25 +49,25 @@ return array(
'label' => $lng['serversettings']['phpfpm_settings']['max_children']['title'],
'desc' => $lng['serversettings']['phpfpm_settings']['max_children']['description'],
'type' => 'int',
'value' => 1
'value' => 5
),
'start_servers' => array(
'label' => $lng['serversettings']['phpfpm_settings']['start_servers']['title'],
'desc' => $lng['serversettings']['phpfpm_settings']['start_servers']['description'],
'type' => 'int',
'value' => 20
'value' => 2
),
'min_spare_servers' => array(
'label' => $lng['serversettings']['phpfpm_settings']['min_spare_servers']['title'],
'desc' => $lng['serversettings']['phpfpm_settings']['min_spare_servers']['description'],
'type' => 'int',
'value' => 5
'value' => 1
),
'max_spare_servers' => array(
'label' => $lng['serversettings']['phpfpm_settings']['max_spare_servers']['title'],
'desc' => $lng['serversettings']['phpfpm_settings']['max_spare_servers']['description'],
'type' => 'int',
'value' => 35
'value' => 3
),
'max_requests' => array(
'label' => $lng['serversettings']['phpfpm_settings']['max_requests']['title'],
@@ -79,13 +79,20 @@ return array(
'label' => $lng['serversettings']['phpfpm_settings']['idle_timeout']['title'],
'desc' => $lng['serversettings']['phpfpm_settings']['idle_timeout']['description'],
'type' => 'int',
'value' => 30
'value' => 10
),
'limit_extensions' => array(
'label' => $lng['serversettings']['phpfpm_settings']['limit_extensions']['title'],
'desc' => $lng['serversettings']['phpfpm_settings']['limit_extensions']['description'],
'type' => 'text',
'value' => '.php'
),
'custom_config' => array(
'label' => $lng['serversettings']['phpfpm_settings']['custom_config']['title'],
'desc' => $lng['serversettings']['phpfpm_settings']['custom_config']['description'],
'type' => 'textarea',
'cols' => 50,
'rows' => 7
)
)
)

View File

@@ -87,6 +87,14 @@ return array(
'desc' => $lng['serversettings']['phpfpm_settings']['limit_extensions']['description'],
'type' => 'text',
'value' => $result['limit_extensions']
),
'custom_config' => array(
'label' => $lng['serversettings']['phpfpm_settings']['custom_config']['title'],
'desc' => $lng['serversettings']['phpfpm_settings']['custom_config']['description'],
'type' => 'textarea',
'cols' => 50,
'rows' => 7,
'value' => $result['custom_config']
)
)
)

View File

@@ -163,7 +163,7 @@ return array(
'label' => $lng['serversettings']['phpfpm_settings']['idle_timeout']['title'],
'desc' => $lng['serversettings']['phpfpm_settings']['idle_timeout']['description'] . $lng['serversettings']['phpfpm_settings']['override_fpmconfig_addinfo'],
'type' => 'int',
'value' => 30
'value' => 10
),
'limit_extensions' => array(
'visible' => (\Froxlor\Settings::Get('phpfpm.enabled') == 1 ? true : false),

View File

@@ -83,6 +83,19 @@ return array(
'image' => 'icons/domain_add.png',
'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? ($ssl_ipsandports != '' ? true : false) : false,
'fields' => array(
'sslenabled' => array(
'label' => $lng['admin']['domain_sslenabled'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
'1'
)
),
'ssl_redirect' => array(
'label' => $lng['domains']['ssl_redirect']['title'],
'desc' => $lng['domains']['ssl_redirect']['description'],

View File

@@ -99,6 +99,19 @@ return array(
'image' => 'icons/domain_edit.png',
'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? ($ssl_ipsandports != '' ? (\Froxlor\Domain\Domain::domainHasSslIpPort($result['id']) ? true : false) : false) : false,
'fields' => array(
'sslenabled' => array(
'label' => $lng['admin']['domain_sslenabled'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
$result['ssl_enabled']
)
),
'ssl_redirect' => array(
'label' => $lng['domains']['ssl_redirect']['title'],
'desc' => $lng['domains']['ssl_redirect']['description'] . ($result['temporary_ssl_redirect'] > 1 ? $lng['domains']['ssl_redirect_temporarilydisabled'] : ''),

View File

@@ -20,6 +20,17 @@
// define default theme for configurehint, etc.
$_deftheme = 'Sparkle';
// validate correct php version
if (version_compare("7.0.0", PHP_VERSION, ">=")) {
// get hint-template
$vendor_hint = file_get_contents(dirname(__DIR__) . '/templates/' . $_deftheme . '/misc/phprequirementfailed.tpl');
// replace values
$vendor_hint = str_replace("<FROXLOR_PHPMIN>", "7.0.0", $vendor_hint);
$vendor_hint = str_replace("<CURRENT_VERSION>", PHP_VERSION, $vendor_hint);
$vendor_hint = str_replace("<CURRENT_YEAR>", date('Y', time()), $vendor_hint);
die($vendor_hint);
}
if (! file_exists(dirname(__DIR__) . '/vendor/autoload.php')) {
// get hint-template
$vendor_hint = file_get_contents(dirname(__DIR__) . '/templates/' . $_deftheme . '/misc/vendormissinghint.tpl');

View File

@@ -204,6 +204,7 @@ $lng['error']['mydomain'] = '\'Domain\'';
$lng['error']['mydocumentroot'] = '\'Documentroot\'';
$lng['error']['loginnameexists'] = 'Loginname %s already exists';
$lng['error']['emailiswrong'] = 'Email-address %s contains invalid characters or is incomplete';
$lng['error']['alternativeemailiswrong'] = 'The given alternative email address %s to send the credentials to seems to be invalid';
$lng['error']['loginnameiswrong'] = 'Loginname "%s" contains illegal characters.';
$lng['error']['loginnameiswrong2'] = 'Loginname contains too many characters. Only %s characters are allowed.';
$lng['error']['userpathcombinationdupe'] = 'Combination of username and path already exists';
@@ -317,6 +318,7 @@ $lng['admin']['templates']['COMPANY'] = 'Replaces with the customer\'s company n
$lng['admin']['templates']['USERNAME'] = 'Replaced with the customer\'s account username.';
$lng['admin']['templates']['PASSWORD'] = 'Replaced with the customer\'s account password.';
$lng['admin']['templates']['EMAIL'] = 'Replaced with the address of the POP3/IMAP account.';
$lng['admin']['templates']['CUSTOMER_NO'] = 'Replaces with the customer number';
$lng['admin']['webserver'] = 'Webserver';
$lng['admin']['bindzonewarning'] = $lng['panel']['emptyfordefault'] . '<br /><strong class="red">ATTENTION:</strong> If you use a zonefile you will have to manage all required records for all sub-zones manually as well.';
@@ -339,7 +341,7 @@ $lng['serversettings']['logfiles_directory']['description'] = 'Where should all
$lng['serversettings']['logfiles_script']['title'] = 'Custom script to pipe log-files to';
$lng['serversettings']['logfiles_script']['description'] = 'You can specify a script here and use the placeholders <strong>{LOGFILE}, {DOMAIN} and {CUSTOMER}</strong> if needed. In case you want to use it you will need to activate the <strong>Pipe webserver logfiles</strong> option too. No prefixed pipe-character is needed.';
$lng['serversettings']['logfiles_format']['title'] = 'Access-log format';
$lng['serversettings']['logfiles_format']['description'] = 'Enter a custom log-format here according to your webservers specifications, leave empty for default';
$lng['serversettings']['logfiles_format']['description'] = 'Enter a custom log-format here according to your webservers specifications, leave empty for default. Depending on your format the string must be quoted.<br/>If used with nginx, it will look like <i>log_format frx_custom {CONFIGURED_VALUE}</i>.<br/>If used with Apache, it will look like <i>LogFormat {CONFIGURED_VALUE} frx_custom</i>.<br/><strong>Attention</strong>: The code won\'t be checked for any errors. If it contains errors, webserver might not start again!';
$lng['serversettings']['logfiles_type']['title'] = 'Access-log type';
$lng['serversettings']['logfiles_type']['description'] = 'Choose between <strong>combined</strong> or <strong>vhost_combined</strong> here.';
$lng['serversettings']['logfiles_piped']['title'] = 'Pipe webserver logfiles to specified script (see above)';
@@ -408,6 +410,7 @@ $lng['admin']['ipsandports']['add'] = 'Add IP/Port';
$lng['admin']['ipsandports']['edit'] = 'Edit IP/Port';
$lng['admin']['ipsandports']['ipandport'] = 'IP/Port';
$lng['admin']['ipsandports']['ip'] = 'IP';
$lng['admin']['ipsandports']['ipnote'] = '<div id="ipnote" class="red">Note: Although private ip addresses are allowed, some features like DNS might not behave correctly.<br>Only use private ip addresses if you are sure.</div>';
$lng['admin']['ipsandports']['port'] = 'Port';
// ADDED IN 1.2.13-rc3
@@ -1695,7 +1698,7 @@ $lng['admin']['integrityresult'] = 'Result';
$lng['admin']['integrityfix'] = 'Fix problems automatically';
$lng['question']['admin_integritycheck_reallyfix'] = 'Do you really want to try fixing all database integrity problems automatically?';
$lng['serversettings']['system_croncmdline']['title'] = 'Cron execution command (php-binary)';
$lng['serversettings']['system_croncmdline']['description'] = 'Command to execute our cronjobs. Change this only if you know what you are doing (default: "/usr/bin/nice -n 5 /usr/bin/php5 -q")!';
$lng['serversettings']['system_croncmdline']['description'] = 'Command to execute our cronjobs. Change this only if you know what you are doing (default: "/usr/bin/nice -n 5 /usr/bin/php -q")!';
$lng['error']['cannotdeletehostnamephpconfig'] = 'This PHP-configuration is used by the Froxlor-vhost and cannot be deleted.';
$lng['error']['cannotdeletedefaultphpconfig'] = 'This PHP-configuration is set as default and cannot be deleted.';
$lng['serversettings']['system_cron_allowautoupdate']['title'] = 'Allow automatic database updates';
@@ -1980,8 +1983,8 @@ $lng['admin']['domain_http2']['title'] = 'HTTP2 support';
$lng['admin']['domain_http2']['description'] = 'See <a target="_blank" href="https://en.wikipedia.org/wiki/HTTP/2">Wikipedia</a> for a detailed explanation of HTTP2';
$lng['admin']['testmail'] = 'SMTP test';
$lng['success']['testmailsent'] = 'Test mail sent successfully';
$lng['serversettings']['disable_le_selfcheck']['title'] = "Disable Let's Encrypt local self-check";
$lng['serversettings']['disable_le_selfcheck']['description'] = "If activated, froxlor will <strong>not</strong> perform its self-check for token accessibility. Needed for NATed IP's or similar.";
$lng['serversettings']['le_domain_dnscheck']['title'] = "Validate DNS of domains when using Let's Encrypt";
$lng['serversettings']['le_domain_dnscheck']['description'] = "If activated, froxlor will validate whether the domain which requests a Let's Encrypt certificate resolves to at least one of the system ip addresses.";
$lng['menue']['phpsettings']['fpmdaemons'] = 'PHP-FPM versions';
$lng['admin']['phpsettings']['activephpconfigs'] = 'In use for php-config(s)';
$lng['admin']['phpsettingsforsubdomains'] = 'Apply php-config to all subdomains:';
@@ -1990,7 +1993,7 @@ $lng['serversettings']['leapiversion']['title'] = "Choose Let's Encrypt ACME imp
$lng['serversettings']['leapiversion']['description'] = "Currently only ACME v2 implementation for Let's Encrypt is supported.";
$lng['admin']['phpsettings']['pass_authorizationheader'] = 'Add "-pass-header Authorization" / "CGIPassAuth On" to vhosts';
$lng['serversettings']['ssl']['ssl_protocols']['title'] = 'Configure the TLS protocol version';
$lng['serversettings']['ssl']['ssl_protocols']['description'] = 'This is a list of ssl protocols that you want (or don\'t want) to use when using SSL. <b>Notice:</b> Some older browsers may not support the newest protcol versions.<br /><br /><b>Default value is:</b><pre>TLSv1, TLSv1.2</pre>';
$lng['serversettings']['ssl']['ssl_protocols']['description'] = 'This is a list of ssl protocols that you want (or don\'t want) to use when using SSL. <b>Notice:</b> Some older browsers may not support the newest protcol versions.<br /><br /><b>Default value is:</b><pre>TLSv1.2</pre>';
$lng['serversettings']['phpfpm_settings']['limit_extensions']['title'] = 'Allowed extensions';
$lng['serversettings']['phpfpm_settings']['limit_extensions']['description'] = 'Limits the extensions of the main script FPM will allow to parse. This can prevent configuration mistakes on the web server side. You should only limit FPM to .php extensions to prevent malicious users to use other extensions to execute php code. Default value: .php';
$lng['phpfpm']['ini_flags'] = 'Enter possible <strong>php_flag</strong>s for php.ini. One entry per line';
@@ -2082,3 +2085,16 @@ $lng['admin']['domain_override_tls'] = 'Override system TLS settings';
$lng['domains']['isaliasdomainof'] = 'Is aliasdomain for %s';
$lng['serversettings']['apply_specialsettings_default']['title'] = 'Default value for "' . $lng['admin']['specialsettingsforsubdomains'] . "' setting when editing a domain";
$lng['serversettings']['apply_phpconfigs_default']['title'] = 'Default value for "' . $lng['admin']['phpsettingsforsubdomains'] . "' setting when editing a domain";
$lng['admin']['domain_sslenabled'] = 'Enable usage of SSL';
$lng['admin']['domain_honorcipherorder'] = 'Honor the (server) cipher order, default <strong>no</strong>';
$lng['admin']['domain_sessiontickets'] = 'Enable TLS sessiontickets (RFC 5077), default <strong>yes</strong>';
$lng['admin']['domain_sessionticketsenabled']['title'] = 'Enable usage of TLS sessiontickets globally';
$lng['admin']['domain_sessionticketsenabled']['description'] = 'Default <strong>yes</strong><br>Requires apache-2.4.11+ or nginx-1.5.9+';
$lng['serversettings']['phpfpm_settings']['restart_note'] = 'Attention: The config won\'t be checked for any errors. If it contains errors, PHP-FPM might not start again!';
$lng['serversettings']['phpfpm_settings']['custom_config']['title'] = 'Custom configuration';
$lng['serversettings']['phpfpm_settings']['custom_config']['description'] = 'Add custom configuration to each PHP-FPM version instance, for example <i>pm.status_path = /status</i> for monitoring. Variables below can be used here. ' . ' <strong>' . $lng['serversettings']['phpfpm_settings']['restart_note'] . '</strong>';
$lng['serversettings']['awstats']['logformat']['title'] = 'LogFormat setting';
$lng['serversettings']['awstats']['logformat']['description'] = 'If you use customized logformat for your webserver, you need change the awstats LogFormat too.<br/>Default is 1. For more information check documentation <a target="_blank" href="https://awstats.sourceforge.io/docs/awstats_config.html#LogFormat">here</a>.';

View File

@@ -202,6 +202,7 @@ $lng['error']['mydomain'] = '\'Domain\'';
$lng['error']['mydocumentroot'] = '\'Documentroot\'';
$lng['error']['loginnameexists'] = 'Der Login-Name "%s" existiert bereits.';
$lng['error']['emailiswrong'] = 'Die E-Mail-Adresse "%s" enthält ungültige Zeichen oder ist nicht vollständig.';
$lng['error']['alternativeemailiswrong'] = 'Die angegebene alternative E-Mail Adresse "%s", an welche die Zugangsdaten geschickt werden soll, scheint ungültig zu sein.';
$lng['error']['loginnameiswrong'] = 'Der Login-Name "%s" enthält ungültige Zeichen.';
$lng['error']['loginnameiswrong2'] = 'Der Login-Name enthält zu viele Zeichen, es sind maximal %s Zeichen erlaubt.';
$lng['error']['userpathcombinationdupe'] = 'Die Kombination aus Benutzername und Pfad existiert bereits.';
@@ -314,6 +315,7 @@ $lng['admin']['templates']['COMPANY'] = 'Wird mit dem Firmennamen des Kunden ers
$lng['admin']['templates']['USERNAME'] = 'Wird mit dem Benutzernamen des neuen Kundenkontos ersetzt.';
$lng['admin']['templates']['PASSWORD'] = 'Wird mit dem Passwort des neuen Kundenkontos ersetzt.';
$lng['admin']['templates']['EMAIL'] = 'Wird mit der Adresse des neuen E-Mail-Kontos ersetzt.';
$lng['admin']['templates']['CUSTOMER_NO'] = 'Wir mit der Kunden-Nummer ersetzt';
$lng['admin']['bindzonewarning'] = $lng['panel']['emptyfordefault'] . '<br /><strong class="red">WARNUNG:</strong> Bei der Verwendung einer Zonendatei müssen alle benötigten Records aller Subdomains ebenfalls manuell verwaltet werden.';
/**
@@ -335,7 +337,7 @@ $lng['serversettings']['logfiles_directory']['description'] = 'Wo sollen die Log
$lng['serversettings']['logfiles_script']['title'] = 'Eigenes Script zu dem Log-Files übergeben werden';
$lng['serversettings']['logfiles_script']['description'] = 'Hier kann ein Script an das die Loginhalte übergeben werden hinterlegt und die Platzhalter <strong>{LOGFILE}, {DOMAIN} und {CUSTOMER}</strong> genutzt werden, sofern nötig. Falls ein Script angegeben wird, muss die Option <strong>Webserver Logdateien umleiten</strong> gesetzt werden';
$lng['serversettings']['logfiles_format']['title'] = 'Access-Log Format';
$lng['serversettings']['logfiles_format']['description'] = 'Hier kann ein angepasstes Log-format entsprechend der Webserver-Dokumentation angegeben werden, leer lassen für Standard';
$lng['serversettings']['logfiles_format']['description'] = 'Hier kann ein angepasstes Log-format entsprechend der Webserver-Dokumentation angegeben werden, leer lassen für Standard. Abhängig vom LogFormat muss die Angabe unter Anführungszeichen stehen.<br/>Wenn verwendet mit nginx, so kann es wie folgt aussehen: <i>log_format frx_custom {EINGESTELLTES_FORMAT}</i>.<br/>Wenn verwendet mit Apache, so kann es wie folgt aussehen: <i>LogFormat {EINGESTELLTES_FORMAT} frx_custom</i>.<br /><strong>ACHTUNG:</strong> Der Code wird nicht auf Fehler geprüft. Etwaige Fehler werden auch übernommen und der Webserver könnte nicht mehr starten!';
$lng['serversettings']['logfiles_type']['title'] = 'Access-Log Typ';
$lng['serversettings']['logfiles_type']['description'] = 'Wähle zwischen <strong>combined</strong> oder <strong>vhost_combined</strong>.';
$lng['serversettings']['logfiles_piped']['title'] = 'Webserver Logdateien zu eigenem Script umleiten (siehe oben)';
@@ -403,6 +405,7 @@ $lng['admin']['ipsandports']['add'] = 'IP-Adresse/Port hinzufügen';
$lng['admin']['ipsandports']['edit'] = 'IP-Adresse/Port bearbeiten';
$lng['admin']['ipsandports']['ipandport'] = 'IP-Adresse/Port';
$lng['admin']['ipsandports']['ip'] = 'IP-Adresse';
$lng['admin']['ipsandports']['ipnote'] = '<div id="ipnote" class="red">Hinweis: Obwohl private IP Adressen erlaubt sind, kann es bei manchen Features wie DNS zu ungewolltem Verhalten kommen.<br>Verwende private Adressen nur wenn du sicher bist.</div>';
$lng['admin']['ipsandports']['port'] = 'Port';
// ADDED IN 1.2.13-rc3
@@ -1419,7 +1422,7 @@ $lng['admin']['integrityresult'] = 'Ergebnis';
$lng['admin']['integrityfix'] = 'Probleme automatisch beheben';
$lng['question']['admin_integritycheck_reallyfix'] = 'M&ouml;chten Sie wirklich versuchen s&auml;mtliche Datenbank-Integrit&auml;tsprobleme automatisch zu beheben?';
$lng['serversettings']['system_croncmdline']['title'] = 'Cron Startbefehl (php Programm)';
$lng['serversettings']['system_croncmdline']['description'] = 'Befehl zum Ausführen des Cronjobs. Ändern dieser Einstellung nur wenn nötig (Standard: "/usr/bin/nice -n 5 /usr/bin/php5 -q")!';
$lng['serversettings']['system_croncmdline']['description'] = 'Befehl zum Ausführen des Cronjobs. Ändern dieser Einstellung nur wenn nötig (Standard: "/usr/bin/nice -n 5 /usr/bin/php -q")!';
$lng['error']['cannotdeletehostnamephpconfig'] = 'Diese PHP-Konfiguration ist dem Froxlor-Vhost zugewiesen und kann daher nicht gelöscht werden.';
$lng['error']['cannotdeletedefaultphpconfig'] = 'Diese PHP-Konfiguration ist als Standard hinterlegt und kann daher nicht gelöscht werden.';
$lng['serversettings']['system_cron_allowautoupdate']['title'] = 'Erlaube automatische Datenbank-Aktualisierungen';
@@ -1630,8 +1633,8 @@ $lng['admin']['domain_http2']['title'] = 'HTTP2 Unterstützung';
$lng['admin']['domain_http2']['description'] = 'Siehe <a target="_blank" href="https://de.wikipedia.org/wiki/Hypertext_Transfer_Protocol#HTTP.2F2">Wikipedia</a> für eine ausführliche Beschreibung von HTTP2';
$lng['admin']['testmail'] = 'SMTP Test';
$lng['success']['testmailsent'] = 'Test E-Mail erfolgreich gesendet';
$lng['serversettings']['disable_le_selfcheck']['title'] = "Deaktiviere Let's Encrypt lokale Selbstprüfung";
$lng['serversettings']['disable_le_selfcheck']['description'] = "Wenn aktiviert wird Froxlor <strong>keine</strong> Erreichbarkeitsprüfung des Tokens vornehmen. Nötig bei ge-NAT-eten IP-Adressen oder Ähnlichem";
$lng['serversettings']['le_domain_dnscheck']['title'] = "Validiere DNS der Domains wenn Let's Encrypt genutzt wird";
$lng['serversettings']['le_domain_dnscheck']['description'] = "Wenn aktiviert wird froxlor überprüfen ob die DNS Einträge der Domains, welche ein Let's Encrypt Zertifikat beantragt, mindestens auf eine der System IP Adressen auflöst.";
$lng['menue']['phpsettings']['fpmdaemons'] = 'PHP-FPM Versionen';
$lng['admin']['phpsettings']['activephpconfigs'] = 'In Verwendung für PHP-Konfiguration(en)';
$lng['admin']['phpsettingsforsubdomains'] = 'PHP-Config für alle Subdomains übernehmen:';
@@ -1640,7 +1643,7 @@ $lng['serversettings']['leapiversion']['title'] = "Wählen Sie die Let's Encrypt
$lng['serversettings']['leapiversion']['description'] = "Aktuell unterstützt froxlor lediglich die ACME v2 Implementierung von Let's Encrypt.";
$lng['admin']['phpsettings']['pass_authorizationheader'] = 'Füge "-pass-header Authorization" / "CGIPassAuth On" in Vhosts ein';
$lng['serversettings']['ssl']['ssl_protocols']['title'] = 'SSL Protokollversion festlegen';
$lng['serversettings']['ssl']['ssl_protocols']['description'] = 'Dies ist eine Liste von SSL/TLS Protokollversionen die genutzt werden sollen (oder auch nicht genutzt werden sollen), wenn SSL verwendet wird. <b>Hinweis:</b> Ältere Browser sind möglicherweise nicht vollständig zum neusten Protokoll kompatibel.<br /><br /><b>Standard-Wert ist:</b><pre>TLSv1, TLSv1.2</pre>';
$lng['serversettings']['ssl']['ssl_protocols']['description'] = 'Dies ist eine Liste von SSL/TLS Protokollversionen die genutzt werden sollen (oder auch nicht genutzt werden sollen), wenn SSL verwendet wird. <b>Hinweis:</b> Ältere Browser sind möglicherweise nicht vollständig zum neusten Protokoll kompatibel.<br /><br /><b>Standard-Wert ist:</b><pre>TLSv1.2</pre>';
$lng['serversettings']['phpfpm_settings']['limit_extensions']['title'] = 'Erlaubte Dateiendungen';
$lng['serversettings']['phpfpm_settings']['limit_extensions']['description'] = 'Beschränkt die Dateierweiterungen des Haupt-Skripts, das FPM zu parsen erlaubt. Dies kann Konfigurationsfehler auf der Webserverseite verhindern. Sie sollten FPM nur auf .php Erweiterungen beschränken, um zu verhindern, dass bösartige Nutzter andere Erweiterungen verwenden, um PHP Code auszuführen. Standardwert: .php';
$lng['phpfpm']['ini_flags'] = 'Mögliche <strong>php_flag</strong>s für die php.ini. Pro Zeile eine Direktive';
@@ -1729,3 +1732,16 @@ $lng['admin']['domain_override_tls'] = 'Überschreibe System TLS Einstellungen';
$lng['domains']['isaliasdomainof'] = 'Ist Aliasdomain für %s';
$lng['serversettings']['apply_specialsettings_default']['title'] = 'Standardwert für "' . $lng['admin']['specialsettingsforsubdomains'] . "' Einstellung beim Bearbeiten einer Domain";
$lng['serversettings']['apply_phpconfigs_default']['title'] = 'Standardwert für "' . $lng['admin']['phpsettingsforsubdomains'] . "' Einstellung beim Bearbeiten einer Domain";
$lng['admin']['domain_sslenabled'] = 'Aktiviere Nutzung von SSL';
$lng['admin']['domain_honorcipherorder'] = 'Bevorzuge die serverseitige Cipher Reihenfolge, Standardwert <strong>nein</strong>';
$lng['admin']['domain_sessiontickets'] = 'Aktiviere TLS Sessiontickets (RFC 5077), Standardwert <strong>ja</strong>';
$lng['admin']['domain_sessionticketsenabled']['title'] = 'Aktiviere Nutzung von TLS Sessiontickets systemweit';
$lng['admin']['domain_sessionticketsenabled']['description'] = 'Standardwert <strong>yes</strong><br>Erfordert apache-2.4.11+ oder nginx-1.5.9+';
$lng['serversettings']['phpfpm_settings']['restart_note'] = 'Achtung: Der Code wird nicht auf Fehler geprüft. Bei etwaigen Fehlern könnte der PHP-FPM-Prozess nicht mehr starten!';
$lng['serversettings']['phpfpm_settings']['custom_config']['title'] = 'Benutzerdefinierte Konfiguration';
$lng['serversettings']['phpfpm_settings']['custom_config']['description'] = 'Füge eine benutzerdefinierte Einstellungen zur PHP-FPM Instanz hinzu, beispielsweise <i>pm.status_path = /status</i> für Monitoring. Unten ersichtliche Variablen können verwendet werden.' . ' <strong>' . $lng['serversettings']['phpfpm_settings']['restart_note'] . '</strong>';
$lng['serversettings']['awstats']['logformat']['title'] = 'LogFormat Einstellung';
$lng['serversettings']['awstats']['logformat']['description'] = 'Wenn ein benutzerdefiniertes LogFormat beim Webserver verwendet wird, muss LogFormat von awstats ebenso angepasst werden.<br/>Standard ist 1. Für weitere Informationen siehe Dokumentation unter <a target="_blank" href="https://awstats.sourceforge.io/docs/awstats_config.html#LogFormat">hier</a>.';

View File

@@ -1635,7 +1635,7 @@ $lng['admin']['integrityresult'] = 'Risultato';
$lng['admin']['integrityfix'] = 'Risolvi problemi automaticamente';
$lng['question']['admin_integritycheck_reallyfix'] = 'Vuoi veramente provare a risolvere i problemi di integrità del database automaticamente?';
$lng['serversettings']['system_croncmdline']['title'] = 'Commando di esecuzione Cron (binario php)';
$lng['serversettings']['system_croncmdline']['description'] = 'Commando per eseguire i nostri cronjob. Modificalo soltanto se sai cosa stai facendo (predefinito: "/usr/bin/nice -n 5 /usr/bin/php5 -q")!';
$lng['serversettings']['system_croncmdline']['description'] = 'Commando per eseguire i nostri cronjob. Modificalo soltanto se sai cosa stai facendo (predefinito: "/usr/bin/nice -n 5 /usr/bin/php -q")!';
$lng['error']['cannotdeletehostnamephpconfig'] = 'Questa configurazione PHP è utilizzata dal vhost Froxlor e non può essere eliminata.';
$lng['error']['cannotdeletedefaultphpconfig'] = 'Questa configurazione PHP è impostata come predefinita e non può essere eliminata.';
$lng['serversettings']['system_cron_allowautoupdate']['title'] = 'Permetti aggiornamenti automatici del database';

View File

@@ -14,6 +14,12 @@
* @package Cron
*
*/
// validate correct php version
if (version_compare("7.0.0", PHP_VERSION, ">=")) {
die('Froxlor requires at least php-7.0. Please validate that your php-cli version and the cron execution command are correct.');
}
require dirname(__DIR__) . '/vendor/autoload.php';
\Froxlor\Cron\MasterCron::setArguments($argv);

View File

@@ -34,7 +34,7 @@
</if>
</if>
<else>
<div class="progress">∞
<div class="progress tipper" title="{$row['diskspace_used']} MiB {$lng['panel']['used']}">∞
<div class="bar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</if>
@@ -58,7 +58,7 @@
</if>
</if>
<else>
<div class="progress">∞
<div class="progress tipper" title="{$row['traffic_used']} GiB {$lng['panel']['used']}">∞
<div class="bar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</if>

View File

@@ -41,7 +41,7 @@
</if>
</if>
<else>
<div class="progress">∞
<div class="progress tipper" title="{$lng['panel']['used']}:<br>web: {$row['webspace_used']} {$lng['customer']['mib']}<br>mail: {$row['mailspace_used']} {$lng['customer']['mib']}<br>mysql: {$row['dbspace_used']} MiB">∞
<div class="bar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</if>
@@ -65,7 +65,7 @@
</if>
</if>
<else>
<div class="progress">∞
<div class="progress tipper" title="{$row['traffic_used']} GiB {$lng['panel']['used']}">∞
<div class="bar" aria-valuenow="{$traffic_percent}" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</if>

View File

@@ -30,7 +30,7 @@
<table class="full hl">
<thead>
<tr>
<th>{$lng['domains']['domainname']}&nbsp;{$arrowcode['d.domain']}</th>
<th>{$lng['domains']['domainname']}&nbsp;{$arrowcode['d.domain_ace']}</th>
<th>{$lng['admin']['ipsandports']['ip']}</th>
<th>{$lng['admin']['customer']}&nbsp;{$arrowcode['c.loginname']}</th>
<th>{$lng['panel']['options']}</th>

Some files were not shown because too many files have changed in this diff Show More