Compare commits

...

190 Commits

Author SHA1 Message Date
Michael Kaufmann
88ee76e4c9 setting version to 0.10.3 for upcoming release
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-25 14:48:13 +02:00
Michael Kaufmann
90d921ebb5 preserve downward compatibility for 0.10.1 updaters regarding specialsettings for ssl-enabled domains; fixes #739
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-24 18:14:51 +02:00
Michael Kaufmann
7b162c4bd0 added tls-settings per domain for admins with change_serversettings-flag set; fixes #519
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-22 16:45:03 +02:00
Michael Kaufmann
32e2d48aed fallback to /tmp/froxlor.log if file-log is activated but no file given or not writeable; fixes #737
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-22 15:06:41 +02:00
Michael Kaufmann
1fdc524171 correct permissions
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-19 11:08:55 +02:00
Michael Kaufmann
4704798379 setting version to 0.10.2 for upcoming maintenance release
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-18 13:39:23 +02:00
Michael Kaufmann
e5c1e8350d set default_theme value in settings-array to 'Sparkle' as it is in install/froxlor.sql; improve language strings for adding php-configurations and fpm-versions
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-17 18:40:53 +02:00
Michael Kaufmann
f0b36c03ad fix registration and termination date to flip between empty-value and 0000-00-00, thx to dxd
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-17 09:35:33 +02:00
Michael Kaufmann
79056f20ee display API in the list of features the customer is allowed to use; display total diskspace used by customer (web, mail and mysql) on customers dashboard, fixes #733
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-16 12:44:23 +02:00
Michael Kaufmann
5d6aa4d2bb Merge pull request #732 from TimoStramann/patch-1
fixing typo
2019-10-16 06:32:13 +02:00
Timo Stramann
f803276ca2 fixing typo
wrong variable name
2019-10-16 00:11:30 +02:00
Michael Kaufmann
5cf2d32e8a reverse parameter for Domains.add() into so users have to explicitly pass the parameter if they do NOT want the default ssl-ip to be used if left empty, so it behaves like the non-ssl ipandport parameter - if left empty, the system default is being used, thx J-BBB
Signed-off-by: Michael Kaufmann <michael.kaufmann@aixit.com>
2019-10-15 14:35:42 +02:00
Michael Kaufmann
9430f77c2e Setting system.leapiversion exists and just needs to be updated, no added
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-15 07:22:41 +02:00
Michael Kaufmann
302fe994b7 adjust ip/port settings for downward compatibility when adding new ssl-specialsettings related settings
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-14 14:26:13 +02:00
Michael Kaufmann
9b122bc003 order tasks by type descending to create bind and webserver configs at the end of the run; cleanUp configs files after creation of certificates to minimize downtime, thx to SCD for testing
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-14 13:56:55 +02:00
Michael Kaufmann
9410356bc7 fix output of acme command when upgrading
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-14 10:12:26 +02:00
Michael Kaufmann
5d5cc3dda3 fix array to string conversion
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-13 22:49:03 +02:00
Michael Kaufmann
a7ccb7007f add Unit-test for DomainZones.listing()
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-13 14:47:39 +02:00
Michael Kaufmann
5680c88da0 implement DomainZones.listing() to actually return custom stored dns entries for a given domain, fixes #731
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-13 14:40:04 +02:00
Michael Kaufmann
cf01a587c7 fix typo in updater
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-12 14:53:13 +02:00
Michael Kaufmann
b6367e1be1 forgot to add the ssl-default-vhostconf-domain fields in ipsandports
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-12 14:39:58 +02:00
Michael Kaufmann
93aa8bff1e add default-ssl-vhost settings and optionally allow including of non-ssl default-vhost settings, fixes #727
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-12 14:34:18 +02:00
Michael Kaufmann
15fa035dc4 check for minimum required php version in autoupdater
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-12 14:04:43 +02:00
Michael Kaufmann
057f4aaa10 Passing the and parameters in reverse order to implode has been deprecated since PHP 7.4
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-12 10:22:11 +02:00
Michael Kaufmann
f588927bc5 check for existence of certificate files created by acme.sh
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-12 08:17:04 +02:00
Michael Kaufmann
03d2a76dd0 clean up language and code for dropped let's encrypt ACMEv1 support
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-11 20:53:34 +02:00
Michael Kaufmann
0d0e557715 force Let's Encrypt ACMEv2 API, fixed #728
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-11 18:17:05 +02:00
Michael Kaufmann
fb54b887f2 remove unneeded apihelp-page code in admin/customer_index; set explicit version to api-doc URL; check for acme.sh cronjob and uninstall it, as froxlor manages that itself
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-10 16:42:32 +02:00
Michael Kaufmann
9167608794 set version to 0.10.1 for maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-10 14:55:45 +02:00
Michael Kaufmann
050af61082 show success in updater when there are no more old files to delete and exec() is disallowed (showed empty list)
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-09 12:05:04 +02:00
Michael Kaufmann
2c23431daf show on API keys page wether api access is allowed
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-09 11:52:55 +02:00
Michael Kaufmann
4543c73b4f add possibility to enable/disable api access on a per user base
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-09 11:43:22 +02:00
Michael Kaufmann
88d85fc02e fix curly bracket array access (deprecated)
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-09 07:59:38 +02:00
Michael Kaufmann
6102fabcb6 allow setting http2 flag for (sub)domains in customer view, fixes #725
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-09 07:59:11 +02:00
Michael Kaufmann
d7a7412973 Merge pull request #724 from kionez/add-ssl-expirationdate
Add expiration date to SSL certificates loaded via API request, fixes #723
2019-10-08 18:59:27 +02:00
kionez
1b3029b826 Fix typo 2019-10-08 18:50:10 +02:00
Michael Kaufmann
26cb53c8fb correctly validate that a domain has not a certificate in Certificates.add(), refs #722
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 18:44:42 +02:00
Michael Kaufmann
b4999fcc83 Throw exception if domain used to call Certificates.get() does not have a certificate, fixes #722
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 18:01:59 +02:00
kionez
05f602d457 Fix for null expiration date and coding style 2019-10-08 17:44:41 +02:00
Michael Kaufmann
89b95d61d2 return empty array in FroxlorAPI.php example class if last call was unsuccessful, fixes #722
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 17:36:42 +02:00
kionez
9ec03bade7 Add expiration date to SSL certificates loaded via API request 2019-10-08 17:32:03 +02:00
Michael Kaufmann
20699a15a6 update composer dependencies
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 12:54:15 +02:00
Michael Kaufmann
9b8a6e7e67 more php-7.4 compatibility
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 12:38:22 +02:00
Michael Kaufmann
3a8d5a9517 correct Mysql.add phpDoc to produce correct api-doc, fixes #721
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 12:11:00 +02:00
Michael Kaufmann
557b28a69d more php-7.4 compatibility
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 12:08:36 +02:00
Michael Kaufmann
0f1c5506e2 do not create username@domain ftp user if the default-ftp-user is being created in Ftps.add, fixes #720
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 12:04:10 +02:00
Michael Kaufmann
c6a93fa336 fix possible php-7.4 notice 'Trying to access array offset on value of type bool'
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 11:26:05 +02:00
Michael Kaufmann
466ea0fa99 show update steps for version updates (forgot that once or twice); add fallback for file deletion if exec() is not allowed; fix php7.4 warnings
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-08 10:54:08 +02:00
Michael Kaufmann
8f850ee7f3 simplify config-templates for cronjob setup
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-06 22:54:54 +02:00
Michael Kaufmann
55d21e475d set low timeout for version-check and output message if check is not possible (due to connection error, downtime of server, etc.)
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-06 18:53:30 +02:00
Michael Kaufmann
fa3e3da7ac only flush privileges if anything at all happened
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-06 14:47:04 +02:00
Michael Kaufmann
05d66c034e update min-required version of php in composer.json
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-06 09:04:18 +02:00
Michael Kaufmann
98f0839664 Merge branch 'master' of github.com:Froxlor/Froxlor 2019-10-06 09:01:15 +02:00
Michael Kaufmann
4d52c6b6d0 Update README.md 2019-10-04 21:48:10 +02:00
Michael Kaufmann
eb5ea51da1 add explicit tlsv1.3 ciphersuite setting (used for apache-only as of now) 2019-10-04 17:43:11 +02:00
Michael Kaufmann
4b555b4ef2 set version to 0.10.0 for upcoming stable release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-03 12:35:42 +02:00
Michael Kaufmann
1657af8719 updating external libraries prior to release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-03 12:31:27 +02:00
Michael Kaufmann
c9d30654e0 update link to openssl-ciphers manual, thx to lod
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-10-02 09:12:06 +02:00
Michael Kaufmann
47ca350127 increase php requirement to 7.0 as 5.6 is way too old
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-09-27 12:55:14 +02:00
Michael Kaufmann
cc04e44031 add possibility to add customer using a hosting-plan instead of specifying resources
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-09-27 12:54:43 +02:00
Michael Kaufmann
eabad4917b correct try_files in NginxFcgi, fixes #717
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-09-26 09:50:13 +02:00
Michael Kaufmann
6188e5b0e3 Merge pull request #716 from Bobselp/patch-1
fix MysqlHandler user field
2019-09-25 20:18:22 +02:00
Bobselp
13ab7a598b fix MysqlHandler user field
See lib/Froxlor/FroxlorLogger.php:152
2019-09-25 20:03:16 +02:00
Michael Kaufmann
bf2584da65 Merge pull request #714 from Bobselp/patch-1
Get mailbox size with maildirsize file
2019-09-24 19:16:58 +02:00
Bobselp
31cebccd5d fix calc, add check if quota is enabled 2019-09-24 18:16:07 +02:00
Michael Kaufmann
3728e9b22c Merge pull request #715 from z3dm4n/master
lng/english.lng.php: fix typo
2019-09-24 12:55:45 +02:00
Erik Zettel
8a145eca92 lng/english.lng.php: fix typo 2019-09-24 12:44:33 +02:00
Bobselp
14914fce44 Get mailbox size with maildirsize file 2019-09-23 21:08:16 +02:00
Michael Kaufmann
6e3fdc1cf9 Merge pull request #713 from Bobselp/patch-1
fix missing namespaces in PowerDNS cron
2019-09-22 18:05:48 +02:00
Bobselp
6ca68f6a2d fix missing namespaces in PowerDNS cron
Some getDB calls were missing the `\Froxlor\Dns\` prefix
2019-09-22 17:59:21 +02:00
Michael Kaufmann
fd4d3cbcfd specify pop3_logout_format explicitly for dovecot to satisfy maillogparser
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-09-19 13:06:32 +02:00
Michael Kaufmann
75f49e2ee2 added HostingPlans ApiCommand + unit-tests
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-09-16 12:31:02 +02:00
Michael Kaufmann
aca22a9c94 only add lets encrypt certificate if cert is valid; display acme.sh output if --debug is specified
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-09-15 15:40:13 +02:00
Michael Kaufmann
5a8ae0f75f do not log multiple times due to pushing log-handlers multiple times
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-09-15 13:49:40 +02:00
Michael Kaufmann
6ef2be8c1a fixed typo
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-09-15 13:42:32 +02:00
Michael Kaufmann
1b968c885b remove old files from 0.9.x to avoid conflicts and errors; change mod_proxy-usage and ACMEv2 default values to true
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-09-15 10:28:19 +02:00
Michael Kaufmann
dc3f159c90 correctly trigger re-generation of let's encrypt certificates
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-09-15 10:22:25 +02:00
Michael Kaufmann
6ebb8dabc4 re-create certificate if SAN list or domain changes
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-09-12 12:30:47 +02:00
Michael Kaufmann
9e2dcf51d7 also remove let's encrypt certificate for froxlor-hostname when updating to acme.sh; make installation more mysql/mariadb compatible
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-09-09 17:16:41 +02:00
Michael Kaufmann
2d8b0181b3 add gitter notifications for travis-ci
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-08-22 16:20:42 +02:00
Michael Kaufmann
accd6e7416 Update README.md 2019-08-22 16:15:17 +02:00
Michael Kaufmann
f5027695dd Create FUNDING.yml 2019-08-22 15:45:00 +02:00
Michael Kaufmann
34696df700 Merge pull request #711 from TimoStramann/patch-1
Remove unnecessary slash for SSL redirect
2019-08-18 16:15:50 +02:00
Timo Stramann
8e9ddd3d50 Remove unnecessary slash for SSL redirect
Remove slash after hostname since requests directly to the hostname do not require a slash at the end and all other content goes to `$request_uri` which starts with shlash, hence no longer doubleslashes on hostname only queries.
2019-08-18 16:07:59 +02:00
Michael Kaufmann
eca941bdae Merge pull request #710 from TimoStramann/patch-1
Updating another fastcgi_param SCRIPT_FILENAME
2019-08-18 15:19:42 +02:00
Timo Stramann
bd6aba8875 Updating another fastcgi_param SCRIPT_FILENAME
Use $request_filename instead of $document_root$fastcgi_script_name as described in: https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#use-request-filename-for-script-filename
2019-08-17 13:04:18 +02:00
Michael Kaufmann
58f6b558df Merge pull request #709 from TimoStramann/patch-1
Updating fastcgi_param SCRIPT_FILENAME
2019-08-17 07:51:12 +02:00
Michael Kaufmann
7ba72269a4 add dovecot stats service and use correct permissions
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-08-11 11:12:53 +02:00
Michael Kaufmann
76c4486d26 fix subcanemaildomain parameter for Domains.update(); allow exec() in froxlor default vhost php.ini or logfiles-viewer feature
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-08-11 10:31:33 +02:00
Michael Kaufmann
69d7889f02 do not require codecoverage to pass checks
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-08-09 17:55:39 +02:00
Timo Stramann
04898c6114 Updating fastcgi_param
Use $request_filename instead of $document_root$fastcgi_script_name as described in: https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#use-request-filename-for-script-filename
2019-08-09 09:40:55 +02:00
Michael Kaufmann
7364dca53d fix homedir of automatically added ftp-user for new customers, thx Gamerboy59 for finding this
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-08-07 14:01:05 +02:00
Michael Kaufmann
90e7f7af0c correct language-array and minor formatting in serversettings.caa_entry_custom
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-30 10:05:26 +02:00
Michael Kaufmann
878be08563 Merge pull request #706 from makuser/master
Implement CAA DNS records
2019-07-30 09:53:46 +02:00
Michael Kaufmann
a98ae562b2 change mysql-username-test so it generates a loginname that fails depending on the mysql/mariadb version
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-30 08:48:44 +02:00
Michael Kaufmann
2aec6a10ed argh, mixed up the If statement for mysql-version check
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-30 08:31:03 +02:00
Michael Kaufmann
70ac914a86 fix drop database on mysql-5.6 as there is no 'if exists' for 'drop user' prior to mysql-5.7
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-30 07:34:42 +02:00
Michael Kaufmann
169353c429 Merge branch 'makuser-travis-test' 2019-07-30 07:30:56 +02:00
Marc-André Kolly
ede19946c2 Tell ant to fail the build when a php unit test fails 2019-07-29 16:29:39 +02:00
Marc-André Kolly
dd488106af Remove lib/userdata.inc.php.bak 2019-07-29 16:09:11 +02:00
Marc-André Kolly
2489658353 Extrawurst 2.0. 2019-07-29 16:03:27 +02:00
Marc-André Kolly
61b12e3f25 Extrawurst. 2019-07-29 15:47:45 +02:00
Marc-André Kolly
c2ffb6d6bd Update Travis CI to run database tests on MySQL 5.6, 5.7 and 8.0 and on MariaDB 10.3 and 10.4. 2019-07-29 15:12:35 +02:00
Marc-André Kolly
4ef78df27f Update Travis CI 2019-07-29 15:07:18 +02:00
Marc-André Kolly
84d80d695a Add Url and Domain validation for CAA records using native Froxlor function 2019-07-29 15:02:13 +02:00
Marc-André Kolly
3cba61a8d8 Simplify unit tests for CAA entry validation 2019-07-29 14:30:39 +02:00
Marc-André Kolly
16ccc273a9 Don't actually enclose CAA records in brackets 2019-07-29 14:27:44 +02:00
Marc-André Kolly
95d47eb6c9 Add unit tests for CAA entry validation 2019-07-29 11:53:00 +02:00
Marc-André Kolly
bfb3fb0a92 Add Regex to check for invalid CAA entry 2019-07-29 11:36:34 +02:00
Marc-André Kolly
78ef2a4e23 Fix serversettings field 2019-07-29 07:41:09 +02:00
Marc-André Kolly
a377c1e6c5 Split l18n string into title and description 2019-07-29 07:39:21 +02:00
Marc-André Kolly
e67e2a85de Implement test for Domain Zone CAA record 2019-07-28 20:05:55 +02:00
Marc-André Kolly
be0470aec1 Revert per-domain CAA settings 2019-07-28 19:49:56 +02:00
Marc-André Kolly
240178eba7 Implement global CAA settings 2019-07-28 19:49:32 +02:00
Marc-André Kolly
358ca61a26 Implement validators to prevent breaking DNS server when adding newly introduced RR types 2019-07-28 18:47:47 +02:00
Marc-André Kolly
b427212b00 Properly implement migrations for caa field in TABLE_DOMAIN_DNS using showUpdateStep() and lastStepStatus() 2019-07-28 18:12:00 +02:00
Marc-André Kolly
5eef98fdfd Bump DB Version to 201907270 2019-07-28 18:10:01 +02:00
Marc-André Kolly
57ac337ef7 Add a few more commonly used RR types to DNS editor 2019-07-28 16:52:05 +02:00
Marc-André Kolly
64fe300e42 Implement general CAA DNS records for all issuers 2019-07-28 16:28:29 +02:00
Marc-André Kolly
d4e5e32c14 Implement CAA DNS record for letsencrypt.org 2019-07-27 17:36:31 +02:00
Michael Kaufmann
d5e4182878 beautification and minor fixes
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-26 07:49:17 +02:00
Michael Kaufmann
dd87a7374e fix ftp-group not added correctly when new customer is added
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-26 07:45:38 +02:00
Michael Kaufmann
7bc57ed269 set password directly when adding new mysql user
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-26 07:34:32 +02:00
Michael Kaufmann
5658717653 fix wrong parameter for acme.sh --delete when ecc certificates are used
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-19 11:43:14 +02:00
Michael Kaufmann
6c0fb007e4 travis changed the default OS to xenial, set it to the previous trusty which works
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-19 08:43:42 +02:00
Michael Kaufmann
0b898b9936 Merge branch 'master' of github.com:Froxlor/Froxlor 2019-07-19 08:42:31 +02:00
Michael Kaufmann
a261e84830 Merge pull request #705 from MDXDave/patch-2
Disable mail redirections if customer is disabled, fixes #704
2019-07-19 08:28:40 +02:00
Dave
7e9b373a58 Update xenial.xml 2019-07-19 01:43:07 +02:00
Dave
5698f8360e Update rhel_centos.xml 2019-07-19 01:42:49 +02:00
Dave
de7c438315 Update gentoo.xml 2019-07-19 01:42:31 +02:00
Dave
0669450676 Update bionic.xml 2019-07-19 01:42:14 +02:00
Dave
507a62f52d Update trusty.xml 2019-07-19 01:41:54 +02:00
Dave
77a7037072 Update jessie.xml 2019-07-19 01:41:24 +02:00
Dave
577e9d3b70 Update buster.xml 2019-07-19 01:40:55 +02:00
Dave
2526512069 Update stretch.xml 2019-07-19 01:39:01 +02:00
Michael Kaufmann
e91debcbb1 buster dovceot has ssl enabled by default
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-14 09:41:46 +02:00
Michael Kaufmann
065fa0b58b do not store punycode-notation of email-account domain, fixes #703
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-13 09:09:39 +02:00
Michael Kaufmann
db3c95ea10 set last run of letsencrypt cron when called in webserver-cron
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-11 08:39:26 +02:00
Michael Kaufmann
8b417c044c let nginx auto-detect the best ecdh-curve to use, fixes #652
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-11 08:13:00 +02:00
Michael Kaufmann
5e3cfaf847 insert task to regenerate config files after removing old-format lets encrypt certificates
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-10 09:58:12 +02:00
Michael Kaufmann
0f0dd91246 combine Let's Encrypt cron with webserver-vhost-generation but allow manually execution using --debug/--force
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-09 07:50:11 +02:00
Michael Kaufmann
fd912dd161 combine webserver-reload command to parent class to avoid repeating code
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-09 07:13:02 +02:00
Michael Kaufmann
98325a0f40 don't need NSCD when using libnss-extrausers
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-03 18:07:02 +02:00
Michael Kaufmann
c43915c09d show task 12 in admin dashboard overview if active
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-03 12:00:47 +02:00
Michael Kaufmann
01bf814496 remove domain ssl information from acme.sh and filesystem on deletion to avoid trying to renew certificates
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-07-01 20:32:13 +02:00
Michael Kaufmann
2ce517e84a use Fts.add when adding new Customers to reduce duplicate code
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-06-28 15:15:17 +02:00
Michael Kaufmann
e209989f2a use EmailAccounts.delete API call in Emails.delete instead of repeating the code
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-06-28 11:07:29 +02:00
Michael Kaufmann
5dfb74701c improve error message display on missing vendor-folder
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-06-25 11:10:32 +02:00
Michael Kaufmann
bdd583d251 Merge branch 'drexlma-patch-2' 2019-06-25 10:59:06 +02:00
Michael Kaufmann
fd8a1d8dc2 Merge branch 'patch-2' of https://github.com/drexlma/Froxlor into drexlma-patch-2 2019-06-25 10:58:57 +02:00
Michael Kaufmann
d2818f8020 Merge branch 'drexlma-patch-3' 2019-06-25 10:58:20 +02:00
Michael Kaufmann
80a0a34b46 Merge branch 'patch-3' of https://github.com/drexlma/Froxlor into drexlma-patch-3 2019-06-25 10:57:45 +02:00
Michael Kaufmann
6e41c0ad2c add codecov.io to travis build for code-coverage stats - yay
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-06-17 14:11:40 +02:00
Michael Kaufmann
a07a9e6a88 more unit-testing, enhancements in Store-functions
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-06-11 12:10:56 +02:00
Michael Kaufmann
7a94a43053 started \Settings\Store unit tests
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-06-10 13:37:22 +02:00
Michael Kaufmann
028524291e test improvements and preparation for more tests later
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-06-10 11:38:47 +02:00
Michael Kaufmann
1ac304e5ac fix missing domainname parameter when manually adding ssl-certificates for a domain, fixes #700
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-06-10 11:36:05 +02:00
Michael Kaufmann
f266bb05c9 testing \Froxlor\Settings\FroxlorVhostSettings
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-06-06 13:04:43 +02:00
Michael Kaufmann
d8a8f76dc9 update dev-environment to use more recent versions, requries php-7.3 now (dev-only)
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-06-06 10:18:03 +02:00
Michael Kaufmann
0afbe3d13b add validation tests
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-06-05 20:52:37 +02:00
Michael Kaufmann
4917b9c057 added first validation tests
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-06-05 09:07:21 +02:00
Michael Kaufmann
13bfd62ac5 move validateUrl function to correct file
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-06-05 06:50:06 +02:00
Michael Kaufmann
97703e7a0c add a few tests for Settings
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-06-05 06:39:44 +02:00
Michael Kaufmann
13086d91d8 only validate and process ip-list if given at all
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-06-04 15:14:51 +02:00
Michael Kaufmann
b7a10fdeda fix vhost(parts)-merging in nginx cron, fixes #669
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-06-03 11:59:56 +02:00
Michael Kaufmann
6806f896d6 fix proftp path of rhel/centos config template, fixes #636
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-05-31 08:02:03 +02:00
Michael Kaufmann
87a2f86365 do not set default ssl-ips if the frontend values are left empty; if default ssl-ips are specified, preset them in the form when adding a domain, fixes #697
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-05-30 17:44:08 +02:00
Michael Kaufmann
a647d48fbe fix up testing/production switch and challengepath for lets encrypt, fixes #696
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-05-27 17:48:33 +02:00
Daniel Drexlmaier
6ea91f55e5 Update install.php 2019-05-27 15:47:30 +02:00
Daniel Drexlmaier
fb87129e29 Update init.php 2019-05-27 15:46:39 +02:00
Daniel Drexlmaier
79e5113e12 Update init.php 2019-05-27 15:28:08 +02:00
Daniel Drexlmaier
b75c9ddff6 Update install.php 2019-05-27 15:27:28 +02:00
Michael Kaufmann
35e14fde14 set version to 0.10.0-rc2 for second release candidate
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-05-27 11:47:58 +02:00
Michael Kaufmann
68f55f9596 dont allow bootstrap.php file from tests/ to be called via browser
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-05-27 08:33:36 +02:00
Michael Kaufmann
3fec579f85 Merge pull request #683 from discordier/hotfix/pcre-maillog
Fixes #682 - mail log parsing regex character group
2019-05-13 20:03:49 +02:00
Christian Schiffler
e2d69c664a Fixes #682 - mail log parsing regex character group
The mail log parsing regex was incorrectly using a character group of `\A`
2019-05-13 19:53:55 +02:00
Michael Kaufmann
72016a5735 fix integrity-check language-file entries
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-05-07 14:03:37 +02:00
Michael Kaufmann
eba163fc4a Merge pull request #677 from pquerner/#646
allow auth basic in URL, fixes #646
2019-04-30 07:14:48 +02:00
Michael Kaufmann
8df6654ad0 Merge pull request #676 from pquerner/#675
use correct validate-ip function in \Froxlor\Validate\Validate::validateUrl, fixes #675
2019-04-30 07:09:20 +02:00
Pascal
1a5e43b6f7 fixes #646
change regex by using well tested regex from here:
https://mathiasbynens.be/demo/url-regex

by @diegoperini
https://gist.github.com/dperini/729294
2019-04-30 00:08:32 +02:00
Pascal
c4c7f4b636 fixes #675
fix call to static method
2019-04-29 23:39:10 +02:00
Michael Kaufmann
9aa0de16be Merge branch 'foliengriller-annotationsAPI' 2019-04-26 12:24:15 +02:00
Michael Kaufmann
cb636fe2c9 Merge branch 'annotationsAPI' of https://github.com/foliengriller/Froxlor into foliengriller-annotationsAPI 2019-04-26 12:23:58 +02:00
Michael Kaufmann
f93dc5643f fix error that wildcard-domains and lets-encrypt are not possible when using ACMEv2; fixes #674
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-04-25 14:20:02 +02:00
Michael Kaufmann
974b151d02 add Debian 10 (Buster) and Ubuntu 18.04 (Bionic) config-templates for TESTING
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-04-25 14:04:15 +02:00
Michael Kaufmann
8835dd0b65 remove deprecated config-templates for Ubuntu 12.04 (Precise); mark Debian 7 (Jessie) and Ubuntu 14.04 (Trusty) as deprecated
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-04-25 14:03:39 +02:00
Michael Kaufmann
626b791c67 remove recursor options in powerdns config template for gentoo, as recursion has been removed in pdns >=4.1.0; fixes #673
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-04-25 13:56:42 +02:00
Michael Kaufmann
82508587b3 update mysql-table engines to InnoDB; fixes #671
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-04-25 13:31:18 +02:00
Michael Kaufmann
0d7fa5728c fix auto-delete of cetificates when no domain exists anylonger, thx to an error-report
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2019-04-14 08:13:34 +02:00
Michael Rosenberger
98f6ad183e Corrects annotations in API 2018-12-19 16:58:52 +01:00
131 changed files with 14122 additions and 3832 deletions

4
.codecov.yml Normal file
View File

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

3
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,3 @@
# These are supported funding model platforms
custom: ['https://paypal.me/Froxlor']

1
.gitignore vendored
View File

@@ -1,6 +1,7 @@
install/update.log install/update.log
templates/* templates/*
lib/userdata.inc.php lib/userdata.inc.php
lib/userdata.inc.php.bak
logs/* logs/*
!logs/index.html !logs/index.html
.buildpath .buildpath

View File

@@ -1,11 +1,9 @@
language: php language: php
dist: bionic
services:
- docker
php: php:
# - "5.4" - 7.3
# - "5.6"
# - "7.0"
- "7.1"
# - "7.2"
branches: branches:
only: only:
@@ -14,47 +12,56 @@ branches:
matrix: matrix:
include: include:
# - php: 5.6 - php: 7.3
# env: deps=highest env: "DOCKER_MYSQL_TYPE=mysql DOCKER_MYSQL_VERSION=5.6"
# - php: 5.4 - php: 7.3
# env: deps=lowest env: "DOCKER_MYSQL_TYPE=mysql DOCKER_MYSQL_VERSION=5.7"
- php: 7.1 - php: 7.3
env: deps=highest env: "DOCKER_MYSQL_TYPE=mysql DOCKER_MYSQL_VERSION=8.0 STARTCMD='mysqld --default-authentication-plugin=mysql_native_password'"
- php: 7.3
mysql: env: "DOCKER_MYSQL_TYPE=mariadb DOCKER_MYSQL_VERSION=10.3"
database: froxlor010 - php: 7.3
username: root env: "DOCKER_MYSQL_TYPE=mariadb DOCKER_MYSQL_VERSION=10.4"
encoding: utf8
addons: addons:
apt: apt:
update: true update: true
# build.xml includes that before_install:
#install: - export MYSQL_DATABASE=froxlor010
# - composer install - docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=fr0xl0r.TravisCI -e MYSQL_DATABASE=$MYSQL_DATABASE -p 3306:3306 $DOCKER_MYSQL_TYPE:$DOCKER_MYSQL_VERSION $STARTCMD
- sudo apt-get install -y ant
- >
export tries=0;
export max_tries=20;
while [[ true ]]; do
tries=$((tries + 1));
echo "waiting for database server to start up... [$tries]";
sleep 5;
# Now see that today's table is there, which would indicate that the cron job ran.
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -s -e 'SHOW VARIABLES LIKE "%version%";'
look_exit=$?;
if [[ "$look_exit" = "0" ]]; then echo "Database server successfully started"; break; fi;
if [[ "$tries" -ge "$max_tries" ]]; then echo "Database server did not start in time"; exit 1; break; fi;
done;
service: install:
- mysql - mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "CREATE DATABASE IF NOT EXISTS froxlor010;"
- mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "CREATE USER 'froxlor010'@'%' IDENTIFIED BY 'fr0xl0r.TravisCI';"
before_script: - mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "GRANT ALL ON froxlor010.* TO 'froxlor010'@'%';"
- mysql -e 'CREATE DATABASE IF NOT EXISTS froxlor010' - mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI froxlor010 < install/froxlor.sql
- echo "USE mysql;\nUPDATE user SET password=PASSWORD('fr0xl0r.TravisCI') WHERE user='root';\nFLUSH PRIVILEGES;\n" | mysql -u root
- mysql -u root -pfr0xl0r.TravisCI froxlor010 < install/froxlor.sql
- mysql -u root -pfr0xl0r.TravisCI -e "CREATE USER 'froxlor010'@'localhost' IDENTIFIED BY 'fr0xl0r.TravisCI';"
- mysql -u root -pfr0xl0r.TravisCI -e "GRANT ALL ON froxlor010.* TO 'froxlor010'@'localhost';"
script: script:
# sufficient for travis - ant phpunit
- ant phpunit-no-coverage
# - ant full-build-parallel after_success:
# -Dpdepend=$(pwd)/vendor/bin/pdepend - bash <(curl -s https://codecov.io/bash) -f "build/logs/clover.xml"
# -Dphpmd=$(pwd)/vendor/bin/phpmd
# -Dphpcpd=$(pwd)/vendor/bin/phpcpd
# -Dphpcs=$(pwd)/vendor/bin/phpcs
# -Dphploc=$(pwd)/vendor/bin/phploc
# -Dphpdox=$(pwd)/vendor/bin/phpdox
# -Dphpunit=$(pwd)/vendor/bin/phpunit
notifications: notifications:
irc: "irc.freenode.org#froxlor" irc: "irc.freenode.org#froxlor"
webhooks:
urls:
- https://webhooks.gitter.im/e/bdf91d1c3f745e51f796
on_success: always
on_failure: always
on_start: never

View File

@@ -1,4 +1,5 @@
[![Build Status](https://travis-ci.com/Froxlor/Froxlor.svg?branch=master)](https://travis-ci.com/Froxlor/Froxlor) [![Build Status](https://travis-ci.com/Froxlor/Froxlor.svg?branch=master)](https://travis-ci.com/Froxlor/Froxlor)
[![Gitter](https://badges.gitter.im/Froxlor/community.svg)](https://gitter.im/Froxlor/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
# Froxlor # Froxlor
@@ -53,7 +54,7 @@ https://files.froxlor.org/releases/froxlor-latest.tar.gz [MD5](https://files.fro
[HowTo](https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-on-debian) [HowTo](https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-on-debian)
/etc/apt/sources.list.d/froxlor.list /etc/apt/sources.list.d/froxlor.list
> deb http://debian.froxlor.org {wheezy|jessie|stretch} main > deb http://debian.froxlor.org {stretch|buster} main
### Gentoo repository ### Gentoo repository

View File

@@ -45,7 +45,7 @@ return array(
'settinggroup' => 'panel', 'settinggroup' => 'panel',
'varname' => 'default_theme', 'varname' => 'default_theme',
'type' => 'option', 'type' => 'option',
'default' => 'Froxlor', 'default' => 'Sparkle',
'option_mode' => 'one', 'option_mode' => 'one',
'option_options_method' => array( 'option_options_method' => array(
'\\Froxlor\\UI\\Template', '\\Froxlor\\UI\\Template',

View File

@@ -250,6 +250,23 @@ return array(
'default' => '', 'default' => '',
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'
), ),
'system_default_sslvhostconf' => array(
'label' => $lng['serversettings']['default_sslvhostconf'],
'settinggroup' => 'system',
'varname' => 'default_sslvhostconf',
'type' => 'text',
'default' => '',
'save_method' => 'storeSettingField',
'visible' => \Froxlor\Settings::Get('system.use_ssl') == 1
),
'system_include_default_vhostconf' => array(
'label' => $lng['serversettings']['includedefault_sslvhostconf'],
'settinggroup' => 'system',
'varname' => 'include_default_vhostconf',
'type' => 'bool',
'default' => false,
'save_method' => 'storeSettingField'
),
'system_apache_globaldiropt' => array( 'system_apache_globaldiropt' => array(
'label' => $lng['serversettings']['apache_globaldiropt'], 'label' => $lng['serversettings']['apache_globaldiropt'],
'settinggroup' => 'system', 'settinggroup' => 'system',

View File

@@ -54,6 +54,16 @@ return array(
'default' => 'ECDH+AESGCM:ECDH+AES256:!aNULL:!MD5:!DSS:!DH:!AES128', 'default' => 'ECDH+AESGCM:ECDH+AES256:!aNULL:!MD5:!DSS:!DH:!AES128',
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'
), ),
'system_tlsv13_cipher_list' => array(
'label' => $lng['serversettings']['ssl']['tlsv13_cipher_list'],
'settinggroup' => 'system',
'varname' => 'tlsv13_cipher_list',
'type' => 'string',
'string_emptyallowed' => true,
'default' => '',
'visible' => \Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1,
'save_method' => 'storeSettingField',
),
'system_ssl_cert_file' => array( 'system_ssl_cert_file' => array(
'label' => $lng['serversettings']['ssl']['ssl_cert_file'], 'label' => $lng['serversettings']['ssl']['ssl_cert_file'],
'settinggroup' => 'system', 'settinggroup' => 'system',
@@ -128,10 +138,9 @@ return array(
'settinggroup' => 'system', 'settinggroup' => 'system',
'varname' => 'leapiversion', 'varname' => 'leapiversion',
'type' => 'option', 'type' => 'option',
'default' => '1', 'default' => '2',
'option_mode' => 'one', 'option_mode' => 'one',
'option_options' => array( 'option_options' => array(
'1' => 'ACME v1',
'2' => 'ACME v2' '2' => 'ACME v2'
), ),
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'

View File

@@ -99,7 +99,7 @@ return array(
'settinggroup' => 'phpfpm', 'settinggroup' => 'phpfpm',
'varname' => 'use_mod_proxy', 'varname' => 'use_mod_proxy',
'type' => 'bool', 'type' => 'bool',
'default' => false, 'default' => true,
'visible' => \Froxlor\Settings::Get('system.apache24'), 'visible' => \Froxlor\Settings::Get('system.apache24'),
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'
), ),

View File

@@ -107,6 +107,22 @@ return array(
'default' => false, 'default' => false,
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'
), ),
'system_dns_createcaaentry' => array(
'label' => $lng['serversettings']['caa_entry'],
'settinggroup' => 'system',
'varname' => 'dns_createcaaentry',
'type' => 'bool',
'default' => true,
'save_method' => 'storeSettingField'
),
'caa_caa_entry' => array(
'label' => $lng['serversettings']['caa_entry_custom'],
'settinggroup' => 'caa',
'varname' => 'caa_entry',
'type' => 'text',
'default' => '',
'save_method' => 'storeSettingField'
),
'system_defaultttl' => array( 'system_defaultttl' => array(
'label' => $lng['serversettings']['defaultttl'], 'label' => $lng['serversettings']['defaultttl'],
'settinggroup' => 'system', 'settinggroup' => 'system',

View File

@@ -36,6 +36,15 @@ if (! extension_loaded('zip')) {
)); ));
} }
// 0.10.x requires 7.0 at least
if (version_compare("7.0.0", PHP_VERSION, ">=")) {
\Froxlor\UI\Response::redirectTo($filename, array(
's' => $s,
'page' => 'error',
'errno' => 10
));
}
// display initial version check // display initial version check
if ($page == 'overview') { if ($page == 'overview') {
@@ -43,8 +52,11 @@ if ($page == 'overview') {
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "checking auto-update"); $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "checking auto-update");
// check for new version // check for new version
$latestversion = HttpClient::urlGet(UPDATE_URI); try {
$latestversion = HttpClient::urlGet(UPDATE_URI, true, 3);
} catch (\Exception $e) {
\Froxlor\UI\Response::dynamic_error("Version-check currently unavailable, please try again later");
}
$latestversion = explode('|', $latestversion); $latestversion = explode('|', $latestversion);
if (is_array($latestversion) && count($latestversion) >= 1) { if (is_array($latestversion) && count($latestversion) >= 1) {
@@ -175,6 +187,8 @@ elseif ($page == 'extract') {
$zip->close(); $zip->close();
// success - remove unused archive // success - remove unused archive
@unlink($localArchive); @unlink($localArchive);
// wait a bit before we redirect to be sure
sleep(2);
} else { } else {
// error // error
\Froxlor\UI\Response::redirectTo($filename, array( \Froxlor\UI\Response::redirectTo($filename, array(
@@ -216,5 +230,6 @@ elseif ($page == 'error') {
// 7 = local archive does not exist // 7 = local archive does not exist
// 8 = could not extract archive // 8 = could not extract archive
// 9 = checksum mismatch // 9 = checksum mismatch
// 10 = <php-7.0
\Froxlor\UI\Response::standard_error('autoupdate_' . $errno); \Froxlor\UI\Response::standard_error('autoupdate_' . $errno);
} }

View File

@@ -91,10 +91,16 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
'cid' => $row['customerid'] 'cid' => $row['customerid']
)); ));
if ($usages)
{
$row['webspace_used'] = round($usages['webspace'] / 1024, $dec_places); $row['webspace_used'] = round($usages['webspace'] / 1024, $dec_places);
$row['mailspace_used'] = round($usages['mail'] / 1024, $dec_places); $row['mailspace_used'] = round($usages['mail'] / 1024, $dec_places);
$row['dbspace_used'] = round($usages['mysql'] / 1024, $dec_places); $row['dbspace_used'] = round($usages['mysql'] / 1024, $dec_places);
} else {
$row['webspace_used'] = 0;
$row['mailspace_used'] = 0;
$row['dbspace_used'] = 0;
}
$row['traffic_used'] = round($row['traffic_used'] / (1024 * 1024), $dec_places); $row['traffic_used'] = round($row['traffic_used'] / (1024 * 1024), $dec_places);
$row['traffic'] = round($row['traffic'] / (1024 * 1024), $dec_places); $row['traffic'] = round($row['traffic'] / (1024 * 1024), $dec_places);
$row['diskspace_used'] = round($row['diskspace_used'] / 1024, $dec_places); $row['diskspace_used'] = round($row['diskspace_used'] / 1024, $dec_places);

View File

@@ -387,8 +387,6 @@ if ($page == 'overview') {
} }
} elseif ($page == 'apikeys' && Settings::Get('api.enabled') == 1) { } elseif ($page == 'apikeys' && Settings::Get('api.enabled') == 1) {
require_once __DIR__ . '/api_keys.php'; require_once __DIR__ . '/api_keys.php';
} elseif ($page == 'apihelp' && Settings::Get('api.enabled') == 1) {
require_once __DIR__ . '/apihelp.php';
} elseif ($page == '2fa' && Settings::Get('2fa.enabled') == 1) { } elseif ($page == '2fa' && Settings::Get('2fa.enabled') == 1) {
require_once __DIR__ . '/2fa.php'; require_once __DIR__ . '/2fa.php';
} }

View File

@@ -83,7 +83,7 @@ if ($page == 'log' && $userinfo['change_serversettings'] == '1') {
case \Froxlor\FroxlorLogger::LOGIN_ACTION: case \Froxlor\FroxlorLogger::LOGIN_ACTION:
$_action = $lng['logger']['login']; $_action = $lng['logger']['login'];
break; break;
case LOG_ERROR: case \Froxlor\FroxlorLogger::LOG_ERROR:
$_action = $lng['logger']['intern']; $_action = $lng['logger']['intern'];
break; break;
default: default:

View File

@@ -17,6 +17,7 @@
define('AREA', 'admin'); define('AREA', 'admin');
require './lib/init.php'; require './lib/init.php';
use Froxlor\Api\Commands\HostingPlans;
use Froxlor\Database\Database; use Froxlor\Database\Database;
use Froxlor\Settings; use Froxlor\Settings;
@@ -69,22 +70,26 @@ if ($page == '' || $page == 'overview') {
eval("echo \"" . \Froxlor\UI\Template::getTemplate("plans/plans") . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("plans/plans") . "\";");
} elseif ($action == 'delete' && $id != 0) { } elseif ($action == 'delete' && $id != 0) {
$result_stmt = Database::prepare(" try {
SELECT * FROM `" . TABLE_PANEL_PLANS . "` WHERE `id` = :id"); $json_result = HostingPlans::getLocal($userinfo, array(
$result = Database::pexecute_first($result_stmt, array(
'id' => $id 'id' => $id
)); ))->get();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
if ($result['id'] != 0 && $result['id'] == $id && (int) $userinfo['adminid'] == $result['adminid']) { if ($result['id'] != 0 && $result['id'] == $id && (int) $userinfo['adminid'] == $result['adminid']) {
if (isset($_POST['send']) && $_POST['send'] == 'send') { if (isset($_POST['send']) && $_POST['send'] == 'send') {
$del_stmt = Database::prepare(" try {
DELETE FROM `" . TABLE_PANEL_PLANS . "` WHERE `id` = :id"); HostingPlans::getLocal($userinfo, array(
Database::pexecute($del_stmt, array(
'id' => $id 'id' => $id
)); ))->delete();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "Plan '" . $result['name'] . "' has been deleted by '" . $userinfo['loginname'] . "'");
\Froxlor\UI\Response::redirectTo($filename, array( \Froxlor\UI\Response::redirectTo($filename, array(
'page' => $page, 'page' => $page,
's' => $s 's' => $s
@@ -102,113 +107,11 @@ if ($page == '' || $page == 'overview') {
} elseif ($action == 'add') { } elseif ($action == 'add') {
if (isset($_POST['send']) && $_POST['send'] == 'send') { if (isset($_POST['send']) && $_POST['send'] == 'send') {
$name = \Froxlor\Validate\Validate::validate($_POST['name'], 'name'); try {
$description = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $_POST['description']), 'description', '/^[^\0]*$/'); HostingPlans::getLocal($userinfo, $_POST)->add();
} catch (Exception $e) {
$value_arr = array(); \Froxlor\UI\Response::dynamic_error($e->getMessage());
if (empty($name)) {
\Froxlor\UI\Response::standard_error('stringmustntbeempty', 'name');
} }
$value_arr['diskspace'] = (int)($_POST['diskspace']);
if (isset($_POST['diskspace_ul'])) {
$value_arr['diskspace'] = - 1;
}
$value_arr['traffic'] = $_POST['traffic'];
if (isset($_POST['traffic_ul'])) {
$value_arr['traffic'] = - 1;
}
$value_arr['subdomains'] = (int)($_POST['subdomains']);
if (isset($_POST['subdomains_ul'])) {
$value_arr['subdomains'] = - 1;
}
$value_arr['emails'] = (int)($_POST['emails']);
if (isset($_POST['emails_ul'])) {
$value_arr['emails'] = - 1;
}
$value_arr['email_accounts'] = (int)($_POST['email_accounts']);
if (isset($_POST['email_accounts_ul'])) {
$value_arr['email_accounts'] = - 1;
}
$value_arr['email_forwarders'] = (int)($_POST['email_forwarders']);
if (isset($_POST['email_forwarders_ul'])) {
$value_arr['email_forwarders'] = - 1;
}
if (Settings::Get('system.mail_quota_enabled') == '1') {
$value_arr['email_quota'] = \Froxlor\Validate\Validate::validate($_POST['email_quota'], 'email_quota', '/^\d+$/', 'vmailquotawrong', array(
'0',
''
));
if (isset($_POST['email_quota_ul'])) {
$value_arr['email_quota'] = - 1;
}
} else {
$value_arr['email_quota'] = - 1;
}
$value_arr['email_imap'] = 0;
if (isset($_POST['email_imap'])) {
$value_arr['email_imap'] = (int)($_POST['email_imap']);
}
$value_arr['email_pop3'] = 0;
if (isset($_POST['email_pop3'])) {
$value_arr['email_pop3'] = (int)($_POST['email_pop3']);
}
$value_arr['ftps'] = (int)($_POST['ftps']);
if (isset($_POST['ftps_ul'])) {
$value_arr['ftps'] = - 1;
}
$value_arr['mysqls'] = (int)($_POST['mysqls']);
if (isset($_POST['mysqls_ul'])) {
$value_arr['mysqls'] = - 1;
}
$value_arr['phpenabled'] = 0;
if (isset($_POST['phpenabled'])) {
$value_arr['phpenabled'] = intval($_POST['phpenabled']);
}
$value_arr['allowed_phpconfigs'] = array();
if (isset($_POST['allowed_phpconfigs']) && is_array($_POST['allowed_phpconfigs'])) {
foreach ($_POST['allowed_phpconfigs'] as $allowed_phpconfig) {
$allowed_phpconfig = intval($allowed_phpconfig);
$value_arr['allowed_phpconfigs'][] = $allowed_phpconfig;
}
}
$value_arr['perlenabled'] = 0;
if (isset($_POST['perlenabled'])) {
$value_arr['perlenabled'] = intval($_POST['perlenabled']);
}
$value_arr['dnsenabled'] = 0;
if (isset($_POST['dnsenabled'])) {
$value_arr['dnsenabled'] = intval($_POST['dnsenabled']);
}
$ins_stmt = Database::prepare("
INSERT INTO `" . TABLE_PANEL_PLANS . "`
SET `adminid` = :adminid, `name` = :name, `description` = :desc, `value` = :valuearr, `ts` = UNIX_TIMESTAMP();
");
$ins_data = array(
'adminid' => $userinfo['adminid'],
'name' => $name,
'desc' => $description,
'valuearr' => json_encode($value_arr)
);
Database::pexecute($ins_stmt, $ins_data);
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "added plan '" . $name . "'");
\Froxlor\UI\Response::redirectTo($filename, array( \Froxlor\UI\Response::redirectTo($filename, array(
'page' => $page, 'page' => $page,
's' => $s 's' => $s
@@ -266,11 +169,14 @@ if ($page == '' || $page == 'overview') {
eval("echo \"" . \Froxlor\UI\Template::getTemplate("plans/plans_add") . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("plans/plans_add") . "\";");
} }
} elseif ($action == 'edit' && $id != 0) { } elseif ($action == 'edit' && $id != 0) {
$result_stmt = Database::prepare(" try {
SELECT * FROM `" . TABLE_PANEL_PLANS . "` WHERE `id` = :id"); $json_result = HostingPlans::getLocal($userinfo, array(
$result = Database::pexecute_first($result_stmt, array(
'id' => $id 'id' => $id
)); ))->get();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
if ($result['name'] != '') { if ($result['name'] != '') {
@@ -284,110 +190,13 @@ if ($page == '' || $page == 'overview') {
if (isset($_POST['send']) && $_POST['send'] == 'send') { if (isset($_POST['send']) && $_POST['send'] == 'send') {
$name = \Froxlor\Validate\Validate::validate($_POST['name'], 'name'); try {
$description = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $_POST['description']), 'description', '/^[^\0]*$/'); HostingPlans::getLocal($userinfo, array(
$value_arr = array();
$value_arr['diskspace'] = (int)($_POST['diskspace']);
if (isset($_POST['diskspace_ul'])) {
$value_arr['diskspace'] = - 1;
}
$value_arr['traffic'] = $_POST['traffic'];
if (isset($_POST['traffic_ul'])) {
$value_arr['traffic'] = - 1;
}
$value_arr['subdomains'] = (int)($_POST['subdomains']);
if (isset($_POST['subdomains_ul'])) {
$value_arr['subdomains'] = - 1;
}
$value_arr['emails'] = (int)($_POST['emails']);
if (isset($_POST['emails_ul'])) {
$value_arr['emails'] = - 1;
}
$value_arr['email_accounts'] = (int)($_POST['email_accounts']);
if (isset($_POST['email_accounts_ul'])) {
$value_arr['email_accounts'] = - 1;
}
$value_arr['email_forwarders'] = (int)($_POST['email_forwarders']);
if (isset($_POST['email_forwarders_ul'])) {
$value_arr['email_forwarders'] = - 1;
}
if (Settings::Get('system.mail_quota_enabled') == '1') {
$value_arr['email_quota'] = \Froxlor\Validate\Validate::validate($_POST['email_quota'], 'email_quota', '/^\d+$/', 'vmailquotawrong', array(
'0',
''
));
if (isset($_POST['email_quota_ul'])) {
$value_arr['email_quota'] = - 1;
}
} else {
$value_arr['email_quota'] = - 1;
}
$value_arr['email_imap'] = 0;
if (isset($_POST['email_imap'])) {
$value_arr['email_imap'] = (int)($_POST['email_imap']);
}
$value_arr['email_pop3'] = 0;
if (isset($_POST['email_pop3'])) {
$value_arr['email_pop3'] = (int)($_POST['email_pop3']);
}
$value_arr['ftps'] = (int)($_POST['ftps']);
if (isset($_POST['ftps_ul'])) {
$value_arr['ftps'] = - 1;
}
$value_arr['mysqls'] = (int)($_POST['mysqls']);
if (isset($_POST['mysqls_ul'])) {
$value_arr['mysqls'] = - 1;
}
$value_arr['phpenabled'] = 0;
if (isset($_POST['phpenabled'])) {
$value_arr['phpenabled'] = intval($_POST['phpenabled']);
}
$value_arr['allowed_phpconfigs'] = array();
if (isset($_POST['allowed_phpconfigs']) && is_array($_POST['allowed_phpconfigs'])) {
foreach ($_POST['allowed_phpconfigs'] as $allowed_phpconfig) {
$allowed_phpconfig = intval($allowed_phpconfig);
$value_arr['allowed_phpconfigs'][] = $allowed_phpconfig;
}
}
$value_arr['perlenabled'] = 0;
if (isset($_POST['perlenabled'])) {
$value_arr['perlenabled'] = intval($_POST['perlenabled']);
}
$value_arr['dnsenabled'] = 0;
if (isset($_POST['dnsenabled'])) {
$value_arr['dnsenabled'] = intval($_POST['dnsenabled']);
}
$ins_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_PLANS . "`
SET `name` = :name, `description` = :desc, `value` = :valuearr, `ts` = UNIX_TIMESTAMP()
WHERE `id` = :id
");
$ins_data = array(
'name' => $name,
'desc' => $description,
'valuearr' => json_encode($value_arr),
'id' => $id 'id' => $id
); ))->update();
Database::pexecute($ins_stmt, $ins_data); } catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "updated plan '" . $name . "'"); }
\Froxlor\UI\Response::redirectTo($filename, array( \Froxlor\UI\Response::redirectTo($filename, array(
'page' => $page, 'page' => $page,
's' => $s 's' => $s
@@ -502,11 +311,14 @@ if ($page == '' || $page == 'overview') {
} }
} elseif ($action == 'jqGetPlanValues') { } elseif ($action == 'jqGetPlanValues') {
$planid = isset($_POST['planid']) ? (int) $_POST['planid'] : 0; $planid = isset($_POST['planid']) ? (int) $_POST['planid'] : 0;
$result_stmt = Database::prepare(" try {
SELECT * FROM `" . TABLE_PANEL_PLANS . "` WHERE `id` = :id"); $json_result = HostingPlans::getLocal($userinfo, array(
$result = Database::pexecute_first($result_stmt, array(
'id' => $planid 'id' => $planid
)); ))->get();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
echo $result['value']; echo $result['value'];
exit(); exit();
} }

View File

@@ -88,6 +88,7 @@ if ($action == 'delete') {
$valid_until = isset($_POST['valid_until']) ? (int) $_POST['valid_until'] : - 1; $valid_until = isset($_POST['valid_until']) ? (int) $_POST['valid_until'] : - 1;
// validate allowed_from // validate allowed_from
if (! empty($allowed_from)) {
$ip_list = array_map('trim', explode(",", $allowed_from)); $ip_list = array_map('trim', explode(",", $allowed_from));
$_check_list = $ip_list; $_check_list = $ip_list;
foreach ($_check_list as $idx => $ip) { foreach ($_check_list as $idx => $ip) {
@@ -97,6 +98,7 @@ if ($action == 'delete') {
} }
$ip_list = array_map('inet_ntop', array_map('inet_pton', $ip_list)); $ip_list = array_map('inet_ntop', array_map('inet_pton', $ip_list));
$allowed_from = implode(",", array_unique($ip_list)); $allowed_from = implode(",", array_unique($ip_list));
}
if ($valid_until <= 0 || ! is_numeric($valid_until)) { if ($valid_until <= 0 || ! is_numeric($valid_until)) {
$valid_until = - 1; $valid_until = - 1;

View File

@@ -226,14 +226,29 @@
<property name="phpcpd.done" value="true" /> <property name="phpcpd.done" value="true" />
</target> </target>
<target name="phpunit" unless="phpunit.done" depends="composer" <target name="phpunit-prepare" unless="phpunit-prepare.done" depends="composer"
description="prepare xdebug unit tests">
<exec executable="${phpunit}" resultproperty="result.phpunit-prepare"
taskname="phpunit">
<arg value="--configuration" />
<arg path="${basedir}/phpunit.xml" />
<arg value="--dump-xdebug-filter" />
<arg path="${basedir}/tests/xdebug-filter.php" />
</exec>
<property name="phpunit-prepare.done" value="true" />
</target>
<target name="phpunit" unless="phpunit.done" depends="phpunit-prepare"
description="Run unit tests with PHPUnit"> description="Run unit tests with PHPUnit">
<exec executable="${phpunit}" resultproperty="result.phpunit" <exec executable="${phpunit}" failonerror="true" resultproperty="result.phpunit"
taskname="phpunit"> taskname="phpunit">
<arg value="--configuration" /> <arg value="--configuration" />
<arg path="${basedir}/phpunit.xml" /> <arg path="${basedir}/phpunit.xml" />
<arg value="--testsuite" /> <arg value="--testsuite" />
<arg value="froxlor" /> <arg value="froxlor" />
<arg value="--prepend" />
<arg path="${basedir}/tests/xdebug-filter.php" />
</exec> </exec>
<property name="phpunit.done" value="true" /> <property name="phpunit.done" value="true" />

View File

@@ -30,7 +30,7 @@
"docs": "https://github.com/Froxlor/Froxlor/wiki" "docs": "https://github.com/Froxlor/Froxlor/wiki"
}, },
"require": { "require": {
"php": ">=5.6", "php": ">=7.0",
"ext-session": "*", "ext-session": "*",
"ext-ctype": "*", "ext-ctype": "*",
"ext-pdo": "*", "ext-pdo": "*",
@@ -49,17 +49,16 @@
"algo26-matthias/idna-convert": "^2.1" "algo26-matthias/idna-convert": "^2.1"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "6.5.13", "phpunit/phpunit": "^8",
"pdepend/pdepend": "2.5.0", "php": ">=7.3",
"phpmd/phpmd": "2.6.0",
"sebastian/phpcpd": "3.0.1",
"squizlabs/php_codesniffer": "3.3.2",
"phploc/phploc": "3.0.1",
"theseer/phpdox": "0.11.2",
"phpunit/php-invoker": "1.1.4",
"php": ">=7.1",
"ext-pcntl": "*", "ext-pcntl": "*",
"phpcompatibility/php-compatibility": "*" "phpcompatibility/php-compatibility": "*",
"squizlabs/php_codesniffer": "*",
"pdepend/pdepend": "^2.5",
"sebastian/phpcpd": "^4.1",
"theseer/phpdox": "^0.12.0",
"phploc/phploc": "^5.0",
"phpmd/phpmd": "^2.6"
}, },
"suggest": { "suggest": {
"ext-bcmath": "*", "ext-bcmath": "*",

1117
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -369,7 +369,7 @@ if ($page == 'overview') {
$domains .= \Froxlor\UI\HTML::makeoption($idna_convert->decode($row_domain['domain']), $row_domain['id'], $result['aliasdomain']); $domains .= \Froxlor\UI\HTML::makeoption($idna_convert->decode($row_domain['domain']), $row_domain['id'], $result['aliasdomain']);
} }
if (preg_match('/^https?\:\/\//', $result['documentroot']) && \Froxlor\Validate\Form\Data::validateUrl($result['documentroot'])) { if (preg_match('/^https?\:\/\//', $result['documentroot']) && \Froxlor\Validate\Validate::validateUrl($result['documentroot'])) {
if (Settings::Get('panel.pathedit') == 'Dropdown') { if (Settings::Get('panel.pathedit') == 'Dropdown') {
$urlvalue = $result['documentroot']; $urlvalue = $result['documentroot'];
$pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']); $pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']);
@@ -480,6 +480,17 @@ if ($page == 'overview') {
} elseif ($page == 'domainssleditor') { } elseif ($page == 'domainssleditor') {
if ($action == '' || $action == 'view') { if ($action == '' || $action == 'view') {
// get domain
try {
$json_result = SubDomains::getLocal($userinfo, array(
'id' => $id
))->get();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result_domain = json_decode($json_result, true)['data'];
if (isset($_POST['send']) && $_POST['send'] == 'send') { if (isset($_POST['send']) && $_POST['send'] == 'send') {
$do_insert = isset($_POST['do_insert']) ? (($_POST['do_insert'] == 1) ? true : false) : false; $do_insert = isset($_POST['do_insert']) ? (($_POST['do_insert'] == 1) ? true : false) : false;
try { try {

View File

@@ -93,11 +93,19 @@ if ($page == 'overview') {
'cid' => $userinfo['customerid'] 'cid' => $userinfo['customerid']
)); ));
$userinfo['diskspace'] = round($userinfo['diskspace'] / 1024, Settings::Get('panel.decimal_places')); if ($usages)
{
$userinfo['diskspace_used'] = round($usages['webspace'] / 1024, Settings::Get('panel.decimal_places')); $userinfo['diskspace_used'] = round($usages['webspace'] / 1024, Settings::Get('panel.decimal_places'));
$userinfo['mailspace_used'] = round($usages['mail'] / 1024, Settings::Get('panel.decimal_places')); $userinfo['mailspace_used'] = round($usages['mail'] / 1024, Settings::Get('panel.decimal_places'));
$userinfo['dbspace_used'] = round($usages['mysql'] / 1024, Settings::Get('panel.decimal_places')); $userinfo['dbspace_used'] = round($usages['mysql'] / 1024, Settings::Get('panel.decimal_places'));
$userinfo['total_used'] = round(($usages['webspace'] + $usages['mail'] + $usages['mysql']) / 1024, Settings::Get('panel.decimal_places'));
} else {
$userinfo['diskspace_used'] = 0;
$userinfo['mailspace_used'] = 0;
$userinfo['dbspace_used'] = 0;
$userinfo['total_used'] = 0;
}
$userinfo['diskspace'] = round($userinfo['diskspace'] / 1024, Settings::Get('panel.decimal_places'));
$userinfo['traffic'] = round($userinfo['traffic'] / (1024 * 1024), Settings::Get('panel.decimal_places')); $userinfo['traffic'] = round($userinfo['traffic'] / (1024 * 1024), Settings::Get('panel.decimal_places'));
$userinfo['traffic_used'] = round($userinfo['traffic_used'] / (1024 * 1024), Settings::Get('panel.decimal_places')); $userinfo['traffic_used'] = round($userinfo['traffic_used'] / (1024 * 1024), Settings::Get('panel.decimal_places'));
$userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps subdomains'); $userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps subdomains');
@@ -114,6 +122,8 @@ if ($page == 'overview') {
$se[] = "PHP"; $se[] = "PHP";
if ($userinfo['perlenabled'] == '1') if ($userinfo['perlenabled'] == '1')
$se[] = "Perl/CGI"; $se[] = "Perl/CGI";
if ($userinfo['api_allowed'] == '1')
$se[] = '<a href="customer_index.php?s='.$s.'&page=apikeys">API</a>';
$services_enabled = implode(", ", $se); $services_enabled = implode(", ", $se);
eval("echo \"" . \Froxlor\UI\Template::getTemplate('index/index') . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate('index/index') . "\";");
@@ -353,8 +363,6 @@ if ($page == 'overview') {
} }
} elseif ($page == 'apikeys' && Settings::Get('api.enabled') == 1) { } elseif ($page == 'apikeys' && Settings::Get('api.enabled') == 1) {
require_once __DIR__ . '/api_keys.php'; require_once __DIR__ . '/api_keys.php';
} elseif ($page == 'apihelp' && Settings::Get('api.enabled') == 1) {
require_once __DIR__ . '/apihelp.php';
} elseif ($page == '2fa' && Settings::Get('2fa.enabled') == 1) { } elseif ($page == '2fa' && Settings::Get('2fa.enabled') == 1) {
require_once __DIR__ . '/2fa.php'; require_once __DIR__ . '/2fa.php';
} }

View File

@@ -96,7 +96,7 @@ if ($page == 'log') {
case \Froxlor\FroxlorLogger::LOGIN_ACTION: case \Froxlor\FroxlorLogger::LOGIN_ACTION:
$_action = $lng['logger']['login']; $_action = $lng['logger']['login'];
break; break;
case LOG_ERROR: case \Froxlor\FroxlorLogger::LOG_ERROR:
$_action = $lng['logger']['intern']; $_action = $lng['logger']['intern'];
break; break;
default: default:

View File

@@ -108,11 +108,16 @@ if (! empty($dom_entries)) {
$type_select_values = array( $type_select_values = array(
'A', 'A',
'AAAA', 'AAAA',
'NS', 'CAA',
'CNAME',
'DNAME',
'LOC',
'MX', 'MX',
'NS',
'RP',
'SRV', 'SRV',
'SSHFP',
'TXT', 'TXT',
'CNAME'
); );
asort($type_select_values); asort($type_select_values);
foreach ($type_select_values as $_type) { foreach ($type_select_values as $_type) {

View File

@@ -148,6 +148,11 @@ class FroxlorAPI
*/ */
public function getLastResponse(): array public function getLastResponse(): array
{ {
if (!empty($this->getLastError())) {
// nothing is returned when the last call
// was not successful
return [];
}
return $this->last_body; return $this->last_body;
} }

View File

@@ -8,7 +8,7 @@ CREATE TABLE `ftp_groups` (
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `groupname` (`groupname`), UNIQUE KEY `groupname` (`groupname`),
KEY `customerid` (`customerid`) KEY `customerid` (`customerid`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -33,7 +33,7 @@ CREATE TABLE `ftp_users` (
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`), UNIQUE KEY `username` (`username`),
KEY `customerid` (`customerid`) KEY `customerid` (`customerid`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -57,7 +57,7 @@ CREATE TABLE `mail_users` (
`mboxsize` bigint(30) NOT NULL default '0', `mboxsize` bigint(30) NOT NULL default '0',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`) UNIQUE KEY `email` (`email`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -73,7 +73,7 @@ CREATE TABLE `mail_virtual` (
`iscatchall` tinyint(1) unsigned NOT NULL default '0', `iscatchall` tinyint(1) unsigned NOT NULL default '0',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `email` (`email`) KEY `email` (`email`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
DROP TABLE IF EXISTS `panel_activation`; DROP TABLE IF EXISTS `panel_activation`;
@@ -84,7 +84,7 @@ CREATE TABLE `panel_activation` (
`creation` int(11) unsigned NOT NULL default '0', `creation` int(11) unsigned NOT NULL default '0',
`activationcode` varchar(50) default NULL, `activationcode` varchar(50) default NULL,
PRIMARY KEY (id) PRIMARY KEY (id)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
DROP TABLE IF EXISTS `panel_admins`; DROP TABLE IF EXISTS `panel_admins`;
@@ -132,9 +132,10 @@ CREATE TABLE `panel_admins` (
`custom_notes_show` tinyint(1) NOT NULL default '0', `custom_notes_show` tinyint(1) NOT NULL default '0',
`type_2fa` tinyint(1) NOT NULL default '0', `type_2fa` tinyint(1) NOT NULL default '0',
`data_2fa` varchar(500) NOT NULL default '', `data_2fa` varchar(500) NOT NULL default '',
`api_allowed` tinyint(1) NOT NULL default '1',
PRIMARY KEY (`adminid`), PRIMARY KEY (`adminid`),
UNIQUE KEY `loginname` (`loginname`) UNIQUE KEY `loginname` (`loginname`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -199,10 +200,11 @@ CREATE TABLE `panel_customers` (
`allowed_phpconfigs` varchar(500) NOT NULL default '', `allowed_phpconfigs` varchar(500) NOT NULL default '',
`type_2fa` tinyint(1) NOT NULL default '0', `type_2fa` tinyint(1) NOT NULL default '0',
`data_2fa` varchar(500) NOT NULL default '', `data_2fa` varchar(500) NOT NULL default '',
`api_allowed` tinyint(1) NOT NULL default '1',
`logviewenabled` tinyint(1) NOT NULL default '0', `logviewenabled` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`customerid`), PRIMARY KEY (`customerid`),
UNIQUE KEY `loginname` (`loginname`) UNIQUE KEY `loginname` (`loginname`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -215,7 +217,7 @@ CREATE TABLE `panel_databases` (
`dbserver` int(11) unsigned NOT NULL default '0', `dbserver` int(11) unsigned NOT NULL default '0',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `customerid` (`customerid`) KEY `customerid` (`customerid`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -246,6 +248,8 @@ CREATE TABLE `panel_domains` (
`speciallogfile` tinyint(1) NOT NULL default '0', `speciallogfile` tinyint(1) NOT NULL default '0',
`ssl_redirect` tinyint(4) NOT NULL default '0', `ssl_redirect` tinyint(4) NOT NULL default '0',
`specialsettings` text, `specialsettings` text,
`ssl_specialsettings` text,
`include_specialsettings` tinyint(1) NOT NULL default '0',
`deactivated` tinyint(1) NOT NULL default '0', `deactivated` tinyint(1) NOT NULL default '0',
`bindserial` varchar(10) NOT NULL default '2000010100', `bindserial` varchar(10) NOT NULL default '2000010100',
`add_date` int( 11 ) NOT NULL default '0', `add_date` int( 11 ) NOT NULL default '0',
@@ -264,11 +268,15 @@ CREATE TABLE `panel_domains` (
`notryfiles` tinyint(1) DEFAULT '0', `notryfiles` tinyint(1) DEFAULT '0',
`writeaccesslog` tinyint(1) DEFAULT '1', `writeaccesslog` tinyint(1) DEFAULT '1',
`writeerrorlog` tinyint(1) DEFAULT '1', `writeerrorlog` tinyint(1) DEFAULT '1',
`override_tls` tinyint(1) DEFAULT '0',
`ssl_protocols` text,
`ssl_cipher_list` text,
`tlsv13_cipher_list` text,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `customerid` (`customerid`), KEY `customerid` (`customerid`),
KEY `parentdomain` (`parentdomainid`), KEY `parentdomain` (`parentdomainid`),
KEY `domain` (`domain`) KEY `domain` (`domain`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -289,9 +297,13 @@ CREATE TABLE `panel_ipsandports` (
`default_vhostconf_domain` text, `default_vhostconf_domain` text,
`ssl_cert_chainfile` varchar(255) NOT NULL default '', `ssl_cert_chainfile` varchar(255) NOT NULL default '',
`docroot` varchar(255) NOT NULL default '', `docroot` varchar(255) NOT NULL default '',
`ssl_specialsettings` text,
`include_specialsettings` tinyint(1) NOT NULL default '0',
`ssl_default_vhostconf_domain` text,
`include_default_vhostconf_domain` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `ip_port` (`ip`,`port`) UNIQUE KEY `ip_port` (`ip`,`port`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -307,7 +319,7 @@ CREATE TABLE `panel_htaccess` (
`error401path` varchar(255) NOT NULL default '', `error401path` varchar(255) NOT NULL default '',
`options_cgi` tinyint(1) NOT NULL default '0', `options_cgi` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -321,7 +333,7 @@ CREATE TABLE `panel_htpasswds` (
`authname` varchar(255) NOT NULL default 'Restricted Area', `authname` varchar(255) NOT NULL default 'Restricted Area',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `customerid` (`customerid`) KEY `customerid` (`customerid`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -350,7 +362,7 @@ CREATE TABLE `panel_settings` (
`varname` varchar(255) NOT NULL default '', `varname` varchar(255) NOT NULL default '',
`value` text NOT NULL, `value` text NOT NULL,
PRIMARY KEY (`settingid`) PRIMARY KEY (`settingid`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
('catchall', 'catchall_enabled', '1'), ('catchall', 'catchall_enabled', '1'),
@@ -375,6 +387,7 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
('admin', 'show_news_feed', '0'), ('admin', 'show_news_feed', '0'),
('admin', 'show_version_login', '0'), ('admin', 'show_version_login', '0'),
('admin', 'show_version_footer', '0'), ('admin', 'show_version_footer', '0'),
('caa', 'caa_entry', ''),
('spf', 'use_spf', '0'), ('spf', 'use_spf', '0'),
('spf', 'spf_entry', '"v=spf1 a mx -all"'), ('spf', 'spf_entry', '"v=spf1 a mx -all"'),
('dkim', 'dkim_algorithm', 'all'), ('dkim', 'dkim_algorithm', 'all'),
@@ -404,7 +417,7 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
('phpfpm', 'defaultini', '1'), ('phpfpm', 'defaultini', '1'),
('phpfpm', 'vhost_defaultini', '2'), ('phpfpm', 'vhost_defaultini', '2'),
('phpfpm', 'fastcgi_ipcdir', '/var/lib/apache2/fastcgi/'), ('phpfpm', 'fastcgi_ipcdir', '/var/lib/apache2/fastcgi/'),
('phpfpm', 'use_mod_proxy', '0'), ('phpfpm', 'use_mod_proxy', '1'),
('phpfpm', 'ini_flags', 'asp_tags ('phpfpm', 'ini_flags', 'asp_tags
display_errors display_errors
display_startup_errors display_startup_errors
@@ -561,6 +574,7 @@ opcache.interned_strings_buffer'),
('system', 'mod_fcgid_defaultini', '1'), ('system', 'mod_fcgid_defaultini', '1'),
('system', 'ftpserver', 'proftpd'), ('system', 'ftpserver', 'proftpd'),
('system', 'dns_createmailentry', '0'), ('system', 'dns_createmailentry', '0'),
('system', 'dns_createcaaentry', '1'),
('system', 'froxlordirectlyviahostname', '0'), ('system', 'froxlordirectlyviahostname', '0'),
('system', 'report_enable', '1'), ('system', 'report_enable', '1'),
('system', 'report_webmax', '90'), ('system', 'report_webmax', '90'),
@@ -613,7 +627,7 @@ opcache.interned_strings_buffer'),
('system', 'letsencryptkeysize', '4096'), ('system', 'letsencryptkeysize', '4096'),
('system', 'letsencryptreuseold', 0), ('system', 'letsencryptreuseold', 0),
('system', 'leenabled', '0'), ('system', 'leenabled', '0'),
('system', 'leapiversion', '1'), ('system', 'leapiversion', '2'),
('system', 'backupenabled', '0'), ('system', 'backupenabled', '0'),
('system', 'dnsenabled', '0'), ('system', 'dnsenabled', '0'),
('system', 'dns_server', 'Bind'), ('system', 'dns_server', 'Bind'),
@@ -638,6 +652,7 @@ opcache.interned_strings_buffer'),
('system', 'nssextrausers', '0'), ('system', 'nssextrausers', '0'),
('system', 'disable_le_selfcheck', '0'), ('system', 'disable_le_selfcheck', '0'),
('system', 'ssl_protocols', 'TLSv1,TLSv1.2'), ('system', 'ssl_protocols', 'TLSv1,TLSv1.2'),
('system', 'tlsv13_cipher_list', ''),
('system', 'logfiles_format', ''), ('system', 'logfiles_format', ''),
('system', 'logfiles_type', '1'), ('system', 'logfiles_type', '1'),
('system', 'logfiles_piped', '0'), ('system', 'logfiles_piped', '0'),
@@ -680,8 +695,8 @@ opcache.interned_strings_buffer'),
('panel', 'password_special_char', '!?<>§$%+#=@'), ('panel', 'password_special_char', '!?<>§$%+#=@'),
('panel', 'customer_hide_options', ''), ('panel', 'customer_hide_options', ''),
('panel', 'is_configured', '0'), ('panel', 'is_configured', '0'),
('panel', 'version', '0.10.0-rc1'), ('panel', 'version', '0.10.3'),
('panel', 'db_version', '201904100'); ('panel', 'db_version', '201910200');
DROP TABLE IF EXISTS `panel_tasks`; DROP TABLE IF EXISTS `panel_tasks`;
@@ -690,7 +705,7 @@ CREATE TABLE `panel_tasks` (
`type` int(11) NOT NULL default '0', `type` int(11) NOT NULL default '0',
`data` text, `data` text,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
INSERT INTO `panel_tasks` (`type`) VALUES ('99'); INSERT INTO `panel_tasks` (`type`) VALUES ('99');
@@ -705,7 +720,7 @@ CREATE TABLE `panel_templates` (
`value` longtext NOT NULL, `value` longtext NOT NULL,
PRIMARY KEY (id), PRIMARY KEY (id),
KEY adminid (adminid) KEY adminid (adminid)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -723,7 +738,7 @@ CREATE TABLE `panel_traffic` (
`mail` bigint(30) unsigned NOT NULL default '0', `mail` bigint(30) unsigned NOT NULL default '0',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `customerid` (`customerid`) KEY `customerid` (`customerid`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -741,7 +756,7 @@ CREATE TABLE `panel_traffic_admins` (
`mail` bigint(30) unsigned NOT NULL default '0', `mail` bigint(30) unsigned NOT NULL default '0',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `adminid` (`adminid`) KEY `adminid` (`adminid`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -758,7 +773,7 @@ CREATE TABLE `panel_diskspace` (
`mysql` bigint(30) unsigned NOT NULL default '0', `mysql` bigint(30) unsigned NOT NULL default '0',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `customerid` (`customerid`) KEY `customerid` (`customerid`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -775,7 +790,7 @@ CREATE TABLE `panel_diskspace_admins` (
`mysql` bigint(30) unsigned NOT NULL default '0', `mysql` bigint(30) unsigned NOT NULL default '0',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `adminid` (`adminid`) KEY `adminid` (`adminid`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -786,7 +801,7 @@ CREATE TABLE `panel_languages` (
`iso` char(3) NOT NULL DEFAULT 'foo', `iso` char(3) NOT NULL DEFAULT 'foo',
`file` varchar(255) NOT NULL DEFAULT '', `file` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -809,7 +824,7 @@ CREATE TABLE IF NOT EXISTS `panel_syslog` (
`user` varchar(50) NOT NULL, `user` varchar(50) NOT NULL,
`text` text NOT NULL, `text` text NOT NULL,
PRIMARY KEY (`logid`) PRIMARY KEY (`logid`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -830,7 +845,7 @@ CREATE TABLE `panel_fpmdaemons` (
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `reload` (`reload_cmd`), UNIQUE KEY `reload` (`reload_cmd`),
UNIQUE KEY `config` (`config_dir`) UNIQUE KEY `config` (`config_dir`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -865,13 +880,13 @@ CREATE TABLE `panel_phpconfigs` (
`limit_extensions` varchar(255) NOT NULL default '.php', `limit_extensions` varchar(255) NOT NULL default '.php',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `fpmsettingid` (`fpmsettingid`) KEY `fpmsettingid` (`fpmsettingid`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
INSERT INTO `panel_phpconfigs` (`id`, `description`, `binary`, `file_extensions`, `mod_fcgid_starter`, `mod_fcgid_maxrequests`, `phpsettings`) VALUES 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'), (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,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'); (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');
DROP TABLE IF EXISTS `cronjobs_run`; DROP TABLE IF EXISTS `cronjobs_run`;
@@ -885,7 +900,7 @@ CREATE TABLE IF NOT EXISTS `cronjobs_run` (
`isactive` tinyint(1) DEFAULT '1', `isactive` tinyint(1) DEFAULT '1',
`desc_lng_key` varchar(100) NOT NULL DEFAULT 'cron_unknown_desc', `desc_lng_key` varchar(100) NOT NULL DEFAULT 'cron_unknown_desc',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
INSERT INTO `cronjobs_run` (`id`, `module`, `cronfile`, `cronclass`, `interval`, `isactive`, `desc_lng_key`) VALUES INSERT INTO `cronjobs_run` (`id`, `module`, `cronfile`, `cronclass`, `interval`, `isactive`, `desc_lng_key`) VALUES
@@ -910,7 +925,7 @@ CREATE TABLE IF NOT EXISTS `ftp_quotalimits` (
`files_in_avail` int(10) unsigned NOT NULL, `files_in_avail` int(10) unsigned NOT NULL,
`files_out_avail` int(10) unsigned NOT NULL, `files_out_avail` int(10) unsigned NOT NULL,
`files_xfer_avail` int(10) unsigned NOT NULL `files_xfer_avail` int(10) unsigned NOT NULL
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -929,7 +944,7 @@ CREATE TABLE IF NOT EXISTS `ftp_quotatallies` (
`files_in_used` int(10) unsigned NOT NULL, `files_in_used` int(10) unsigned NOT NULL,
`files_out_used` int(10) unsigned NOT NULL, `files_out_used` int(10) unsigned NOT NULL,
`files_xfer_used` int(10) unsigned NOT NULL `files_xfer_used` int(10) unsigned NOT NULL
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -940,7 +955,7 @@ CREATE TABLE IF NOT EXISTS `redirect_codes` (
`desc` varchar(200) NOT NULL, `desc` varchar(200) NOT NULL,
`enabled` tinyint(1) DEFAULT '1', `enabled` tinyint(1) DEFAULT '1',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -958,7 +973,7 @@ CREATE TABLE IF NOT EXISTS `domain_redirect_codes` (
`rid` int(5) NOT NULL, `rid` int(5) NOT NULL,
`did` int(11) unsigned NOT NULL, `did` int(11) unsigned NOT NULL,
UNIQUE KEY `rc` (`rid`, `did`) UNIQUE KEY `rc` (`rid`, `did`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
DROP TABLE IF EXISTS `domain_ssl_settings`; DROP TABLE IF EXISTS `domain_ssl_settings`;
@@ -973,7 +988,7 @@ CREATE TABLE IF NOT EXISTS `domain_ssl_settings` (
`ssl_fullchain_file` mediumtext, `ssl_fullchain_file` mediumtext,
`expirationdate` datetime DEFAULT NULL, `expirationdate` datetime DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
DROP TABLE IF EXISTS `panel_domaintoip`; DROP TABLE IF EXISTS `panel_domaintoip`;
@@ -981,7 +996,7 @@ CREATE TABLE IF NOT EXISTS `panel_domaintoip` (
`id_domain` int(11) unsigned NOT NULL, `id_domain` int(11) unsigned NOT NULL,
`id_ipandports` int(11) unsigned NOT NULL, `id_ipandports` int(11) unsigned NOT NULL,
PRIMARY KEY (`id_domain`,`id_ipandports`) PRIMARY KEY (`id_domain`,`id_ipandports`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
DROP TABLE IF EXISTS `domain_dns_entries`; DROP TABLE IF EXISTS `domain_dns_entries`;
@@ -994,7 +1009,7 @@ CREATE TABLE `domain_dns_entries` (
`ttl` int(11) NOT NULL DEFAULT '18000', `ttl` int(11) NOT NULL DEFAULT '18000',
`prio` int(11) DEFAULT NULL, `prio` int(11) DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
DROP TABLE IF EXISTS `panel_plans`; DROP TABLE IF EXISTS `panel_plans`;
@@ -1007,7 +1022,7 @@ CREATE TABLE `panel_plans` (
`ts` int(15) NOT NULL default '0', `ts` int(15) NOT NULL default '0',
PRIMARY KEY (id), PRIMARY KEY (id),
KEY adminid (adminid) KEY adminid (adminid)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
DROP TABLE IF EXISTS `api_keys`; DROP TABLE IF EXISTS `api_keys`;
@@ -1022,5 +1037,5 @@ CREATE TABLE `api_keys` (
PRIMARY KEY (id), PRIMARY KEY (id),
KEY adminid (adminid), KEY adminid (adminid),
KEY customerid (customerid) KEY customerid (customerid)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;

View File

@@ -15,6 +15,14 @@
* @package Install * @package Install
* *
*/ */
if (! file_exists(dirname(__DIR__) . '/vendor/autoload.php')) {
// get hint-template
$vendor_hint = file_get_contents(dirname(__DIR__) . '/templates/Sparkle/misc/vendormissinghint.tpl');
// replace values
$vendor_hint = str_replace("<FROXLOR_INSTALL_DIR>", dirname(__DIR__), $vendor_hint);
$vendor_hint = str_replace("<CURRENT_YEAR>", date('Y', time()), $vendor_hint);
die($vendor_hint);
}
require dirname(__DIR__) . '/vendor/autoload.php'; require dirname(__DIR__) . '/vendor/autoload.php';
require __DIR__ . '/lib/class.FroxlorInstall.php'; require __DIR__ . '/lib/class.FroxlorInstall.php';

View File

@@ -104,7 +104,7 @@ class FroxlorInstall
// check if we have a valid installation already // check if we have a valid installation already
$this->_checkUserdataFile(); $this->_checkUserdataFile();
// include the MySQL-Table-Definitions // include the MySQL-Table-Definitions
require $this->_basepath . '/lib/tables.inc.php'; require_once $this->_basepath . '/lib/tables.inc.php';
// include language // include language
$this->_includeLanguageFile(); $this->_includeLanguageFile();
// show the action // show the action
@@ -407,6 +407,7 @@ class FroxlorInstall
`name` = 'Froxlor-Administrator', `name` = 'Froxlor-Administrator',
`email` = :email, `email` = :email,
`def_language` = :deflang, `def_language` = :deflang,
`api_allowed` = 1,
`customers` = -1, `customers` = -1,
`customers_see_all` = 1, `customers_see_all` = 1,
`caneditphpsettings` = 1, `caneditphpsettings` = 1,
@@ -643,21 +644,8 @@ class FroxlorInstall
$mysql_access_host_array[] = $this->_data['serverip']; $mysql_access_host_array[] = $this->_data['serverip'];
foreach ($mysql_access_host_array as $mysql_access_host) { foreach ($mysql_access_host_array as $mysql_access_host) {
$_db = str_replace('`', '', $this->_data['mysql_database']); $frox_db = str_replace('`', '', $this->_data['mysql_database']);
$stmt = $db_root->prepare(" $this->_grantDbPrivilegesTo($db_root, $frox_db, $this->_data['mysql_unpriv_user'], $this->_data['mysql_unpriv_pass'], $mysql_access_host);
GRANT ALL PRIVILEGES ON `" . $_db . "`.*
TO :username@:host
IDENTIFIED BY 'password'");
$stmt->execute(array(
"username" => $this->_data['mysql_unpriv_user'],
"host" => $mysql_access_host
));
$stmt = $db_root->prepare("SET PASSWORD FOR :username@:host = PASSWORD(:password)");
$stmt->execute(array(
"username" => $this->_data['mysql_unpriv_user'],
"host" => $mysql_access_host,
"password" => $this->_data['mysql_unpriv_pass']
));
} }
$db_root->query("FLUSH PRIVILEGES;"); $db_root->query("FLUSH PRIVILEGES;");
@@ -667,6 +655,38 @@ class FroxlorInstall
return $content; return $content;
} }
private function _grantDbPrivilegesTo(&$db_root, $database, $username, $password, $access_host)
{
// mysql8 compatibility
if (version_compare($db_root->getAttribute(\PDO::ATTR_SERVER_VERSION), '8.0.11', '>=')) {
// create user
$stmt = $db_root->prepare("
CREATE USER '" . $username . "'@'" . $access_host . "' IDENTIFIED BY :password
");
$stmt->execute(array(
"password" => $password
));
// grant privileges
$stmt = $db_root->prepare("
GRANT ALL ON `" . $database . "`.* TO :username@:host
");
$stmt->execute(array(
"username" => $username,
"host" => $access_host
));
} else {
// grant privileges
$stmt = $db_root->prepare("
GRANT ALL PRIVILEGES ON `" . $database . "`.* TO :username@:host IDENTIFIED BY :password
");
$stmt->execute(array(
"username" => $username,
"host" => $access_host,
"password" => $password
));
}
}
/** /**
* Check if an old database exists and back it up if necessary * Check if an old database exists and back it up if necessary
* *
@@ -944,11 +964,11 @@ class FroxlorInstall
// check for correct php version // check for correct php version
$content .= $this->_status_message('begin', $this->_lng['requirements']['phpversion']); $content .= $this->_status_message('begin', $this->_lng['requirements']['phpversion']);
if (version_compare("5.6.0", PHP_VERSION, ">=")) { if (version_compare("7.0.0", PHP_VERSION, ">=")) {
$content .= $this->_status_message('red', $this->_lng['requirements']['notfound'] . ' (' . PHP_VERSION . ')'); $content .= $this->_status_message('red', $this->_lng['requirements']['notfound'] . ' (' . PHP_VERSION . ')');
$_die = true; $_die = true;
} else { } else {
if (version_compare("7.0.0", PHP_VERSION, ">=")) { if (version_compare("7.1.0", PHP_VERSION, ">=")) {
$content .= $this->_status_message('orange', $this->_lng['requirements']['newerphpprefered'] . ' (' . PHP_VERSION . ')'); $content .= $this->_status_message('orange', $this->_lng['requirements']['newerphpprefered'] . ' (' . PHP_VERSION . ')');
} else { } else {
$content .= $this->_status_message('green', PHP_VERSION); $content .= $this->_status_message('green', PHP_VERSION);
@@ -1060,12 +1080,13 @@ class FroxlorInstall
*/ */
private function _sendHeaders() private function _sendHeaders()
{ {
if (@php_sapi_name() !== 'cli') {
// no caching // no caching
header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: no-store, no-cache, must-revalidate");
header("Pragma: no-cache"); header("Pragma: no-cache");
header('Last-Modified: ' . gmdate('D, d M Y H:i:s \G\M\T', time())); header('Last-Modified: ' . gmdate('D, d M Y H:i:s \G\M\T', time()));
header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time())); header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time()));
}
// ensure that default timezone is set // ensure that default timezone is set
if (function_exists("date_default_timezone_set") && function_exists("date_default_timezone_get")) { if (function_exists("date_default_timezone_set") && function_exists("date_default_timezone_get")) {
@date_default_timezone_set(@date_default_timezone_get()); @date_default_timezone_set(@date_default_timezone_get());
@@ -1082,7 +1103,7 @@ class FroxlorInstall
if (file_exists($userdata)) { if (file_exists($userdata)) {
// includes the usersettings (MySQL-Username/Passwort) // includes the usersettings (MySQL-Username/Passwort)
// to test if Froxlor is already installed // to test if Froxlor is already installed
require $this->_basepath . '/lib/userdata.inc.php'; require_once $this->_basepath . '/lib/userdata.inc.php';
if (isset($sql) && is_array($sql)) { if (isset($sql) && is_array($sql)) {
// use sparkle theme for the notice // use sparkle theme for the notice
@@ -1126,7 +1147,7 @@ class FroxlorInstall
$lngfile = $this->_basepath . '/install/lng/' . $standardlanguage . '.lng.php'; $lngfile = $this->_basepath . '/install/lng/' . $standardlanguage . '.lng.php';
if (file_exists($lngfile)) { if (file_exists($lngfile)) {
// includes file /lng/$language.lng.php if it exists // includes file /lng/$language.lng.php if it exists
require $lngfile; require_once $lngfile;
$this->_lng = $lng; $this->_lng = $lng;
} }
@@ -1135,7 +1156,7 @@ class FroxlorInstall
$lngfile = $this->_basepath . '/install/lng/' . $this->_activelng . '.lng.php'; $lngfile = $this->_basepath . '/install/lng/' . $this->_activelng . '.lng.php';
if (file_exists($lngfile)) { if (file_exists($lngfile)) {
// includes file /lng/$language.lng.php if it exists // includes file /lng/$language.lng.php if it exists
require $lngfile; require_once $lngfile;
$this->_lng = $lng; $this->_lng = $lng;
} }
} }

View File

@@ -22,8 +22,8 @@ $lng['requirements']['not_true'] = 'no';
$lng['requirements']['notfound'] = 'not found'; $lng['requirements']['notfound'] = 'not found';
$lng['requirements']['notinstalled'] = 'not installed'; $lng['requirements']['notinstalled'] = 'not installed';
$lng['requirements']['activated'] = 'enabled'; $lng['requirements']['activated'] = 'enabled';
$lng['requirements']['phpversion'] = 'PHP version >= 5.6'; $lng['requirements']['phpversion'] = 'PHP version >= 7.0';
$lng['requirements']['newerphpprefered'] = 'Good, but php-7.0 is prefered.'; $lng['requirements']['newerphpprefered'] = 'Good, but php-7.1 is prefered.';
$lng['requirements']['phppdo'] = 'PHP PDO extension and PDO-MySQL driver...'; $lng['requirements']['phppdo'] = 'PHP PDO extension and PDO-MySQL driver...';
$lng['requirements']['phpsession'] = 'PHP session-extension...'; $lng['requirements']['phpsession'] = 'PHP session-extension...';
$lng['requirements']['phpctype'] = 'PHP ctype-extension...'; $lng['requirements']['phpctype'] = 'PHP ctype-extension...';

View File

@@ -22,7 +22,7 @@ $lng['requirements']['not_true'] = 'non';
$lng['requirements']['notfound'] = 'introuvable'; $lng['requirements']['notfound'] = 'introuvable';
$lng['requirements']['notinstalled'] = 'non installé'; $lng['requirements']['notinstalled'] = 'non installé';
$lng['requirements']['activated'] = 'activé'; $lng['requirements']['activated'] = 'activé';
$lng['requirements']['phpversion'] = 'PHP version >= 5.6'; $lng['requirements']['phpversion'] = 'PHP version >= 7.0';
$lng['requirements']['phppdo'] = 'extension PHP PDO et pilote PDO-MySQL ...'; $lng['requirements']['phppdo'] = 'extension PHP PDO et pilote PDO-MySQL ...';
$lng['requirements']['phpxml'] = 'extension PHP XML...'; $lng['requirements']['phpxml'] = 'extension PHP XML...';
$lng['requirements']['phpfilter'] = 'extension PHP filter ...'; $lng['requirements']['phpfilter'] = 'extension PHP filter ...';

View File

@@ -22,8 +22,8 @@ $lng['requirements']['not_true'] = 'nein';
$lng['requirements']['notfound'] = 'nicht gefunden'; $lng['requirements']['notfound'] = 'nicht gefunden';
$lng['requirements']['notinstalled'] = 'nicht installiert'; $lng['requirements']['notinstalled'] = 'nicht installiert';
$lng['requirements']['activated'] = 'ist aktiviert.'; $lng['requirements']['activated'] = 'ist aktiviert.';
$lng['requirements']['phpversion'] = 'PHP Version >= 5.6'; $lng['requirements']['phpversion'] = 'PHP Version >= 7.0';
$lng['requirements']['newerphpprefered'] = 'Passt, aber php-7.0 wird bevorzugt.'; $lng['requirements']['newerphpprefered'] = 'Passt, aber php-7.1 wird bevorzugt.';
$lng['requirements']['phppdo'] = 'PHP PDO Erweiterung und PDO-MySQL Treiber...'; $lng['requirements']['phppdo'] = 'PHP PDO Erweiterung und PDO-MySQL Treiber...';
$lng['requirements']['phpsession'] = 'PHP session-Erweiterung...'; $lng['requirements']['phpsession'] = 'PHP session-Erweiterung...';
$lng['requirements']['phpctype'] = 'PHP ctype-Erweiterung...'; $lng['requirements']['phpctype'] = 'PHP ctype-Erweiterung...';

View File

@@ -220,6 +220,14 @@ if (\Froxlor\Froxlor::isDatabaseVersion('201902120')) {
$domain_in = substr($domain_in, 0, - 1); $domain_in = substr($domain_in, 0, - 1);
Database::query("DELETE FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` IN (" . $domain_in . ")"); Database::query("DELETE FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` IN (" . $domain_in . ")");
} }
// check for froxlor domain using let's encrypt
if (Settings::Get('system.le_froxlor_enabled') == 1) {
Database::query("DELETE FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = '0'");
}
lastStepStatus(0);
showUpdateStep("Inserting job to regenerate configfiles");
\Froxlor\System\Cronjob::inserttask('1');
lastStepStatus(0); lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201902170'); \Froxlor\Froxlor::updateToDbVersion('201902170');
@@ -240,3 +248,202 @@ if (\Froxlor\Froxlor::isDatabaseVersion('201902210')) {
\Froxlor\Froxlor::updateToVersion('0.10.0-rc1'); \Froxlor\Froxlor::updateToVersion('0.10.0-rc1');
\Froxlor\Froxlor::updateToDbVersion('201904100'); \Froxlor\Froxlor::updateToDbVersion('201904100');
} }
if (\Froxlor\Froxlor::isDatabaseVersion('201904100')) {
showUpdateStep("Converting all MyISAM tables to InnoDB");
Database::needRoot(true);
Database::needSqlData();
$sql_data = Database::getSqlData();
$result = Database::query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '" . $sql_data['db'] . "' AND ENGINE = 'MyISAM'");
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
Database::query("ALTER TABLE `" . $row['TABLE_NAME'] . "` ENGINE=INNODB");
}
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201904250');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.0-rc1')) {
showUpdateStep("Updating from 0.10.0-rc1 to 0.10.0-rc2", false);
\Froxlor\Froxlor::updateToVersion('0.10.0-rc2');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201904250')) {
showUpdateStep("Adding new settings for CAA");
Settings::AddNew('caa.caa_entry', '', true);
Settings::AddNew('system.dns_createcaaentry', 1, true);
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201907270');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201907270')) {
showUpdateStep("Cleaning up old files");
$to_clean = array(
"actions/admin/settings/000.version.php",
"actions/admin/settings/190.ticket.php",
"admin_tickets.php",
"customer_tickets.php",
"install/scripts/language-check.php",
"install/updates/froxlor/upgrade_syscp.inc.php",
"lib/classes",
"lib/configfiles/precise.xml",
"lib/cron_init.php",
"lib/cron_shutdown.php",
"lib/formfields/admin/tickets",
"lib/formfields/customer/tickets",
"lib/functions.php",
"lib/functions",
"lib/navigation/10.tickets.php",
"scripts/classes",
"scripts/jobs",
"templates/Sparkle/admin/tickets",
"templates/Sparkle/customer/tickets"
);
$disabled = explode(',', ini_get('disable_functions'));
$exec_allowed = ! in_array('exec', $disabled);
$del_list = "";
foreach ($to_clean as $filedir) {
$complete_filedir = \Froxlor\Froxlor::getInstallDir() . $filedir;
if (file_exists($complete_filedir)) {
if ($exec_allowed) {
Froxlor\FileDir::safe_exec("rm -rf " . escapeshellarg($complete_filedir));
} else {
$del_list .= "rm -rf " . escapeshellarg($complete_filedir) . PHP_EOL;
}
}
}
if ($exec_allowed) {
lastStepStatus(0);
} else {
if (empty($del_list)) {
// none of the files existed
lastStepStatus(0);
} else {
lastStepStatus(1, 'manual commands needed');
echo '<span class="update-step update-step-err">Please run the following commands manually:</span><br><pre>' . $del_list . '</pre><br>';
}
}
\Froxlor\Froxlor::updateToDbVersion('201909150');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.0-rc2')) {
showUpdateStep("Updating from 0.10.0-rc2 to 0.10.0 final", false);
\Froxlor\Froxlor::updateToVersion('0.10.0');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201909150')) {
showUpdateStep("Adding TLSv1.3-cipherlist setting");
Settings::AddNew("system.tlsv13_cipher_list", '');
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201910030');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201910030')) {
showUpdateStep("Adding field api_allowed to admins and customers");
Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` ADD `api_allowed` tinyint(1) NOT NULL default '1';");
Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `api_allowed` tinyint(1) NOT NULL default '1';");
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201910090');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.0')) {
showUpdateStep("Updating from 0.10.0 to 0.10.1 final", false);
\Froxlor\Froxlor::updateToVersion('0.10.1');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201910090')) {
showUpdateStep("Adjusting Let's Encrypt API setting");
Settings::Set("system.leapiversion", '2');
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201910110');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201910110')) {
showUpdateStep("Adding new settings for ssl-vhost default content");
Settings::AddNew("system.default_sslvhostconf", '');
Settings::AddNew("system.include_default_vhostconf", '0');
lastStepStatus(0);
showUpdateStep("Adding new fields to ips and ports-table");
Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD `ssl_specialsettings` text AFTER `docroot`;");
Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD `include_specialsettings` tinyint(1) NOT NULL default '0' AFTER `ssl_specialsettings`;");
Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD `ssl_default_vhostconf_domain` text AFTER `include_specialsettings`;");
Database::query("ALTER TABLE `" . TABLE_PANEL_IPSANDPORTS . "` ADD `include_default_vhostconf_domain` tinyint(1) NOT NULL default '0' AFTER `ssl_default_vhostconf_domain`;");
lastStepStatus(0);
showUpdateStep("Adding new fields to domains-table");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_specialsettings` text AFTER `specialsettings`;");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `include_specialsettings` tinyint(1) NOT NULL default '0' AFTER `ssl_specialsettings`;");
lastStepStatus(0);
// select all ips/ports with specialsettings and SSL enabled to include the specialsettings in the ssl-vhost
// because the former implementation included it and users might rely on that, see https://github.com/Froxlor/Froxlor/issues/727
$sel_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `specialsettings` <> '' AND `ssl` = '1'");
Database::pexecute($sel_stmt);
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_IPSANDPORTS . "` SET `include_specialsettings` = '1' WHERE `id` = :id");
if ($sel_stmt->columnCount() > 0) {
showUpdateStep("Adjusting IP/port settings for downward compatibility");
while ($row = $sel_stmt->fetch(PDO::FETCH_ASSOC)) {
Database::pexecute($upd_stmt, [
'id' => $row['id']
]);
}
lastStepStatus(0);
}
// select all domains with an ssl IP connected and specialsettings content to include these in the ssl-vhost
// to maintain former behavior
$sel_stmt = Database::prepare("
SELECT d.id FROM `". TABLE_PANEL_DOMAINS . "` d
LEFT JOIN `". TABLE_DOMAINTOIP . "` d2i ON d2i.id_domain = d.id
LEFT JOIN `". TABLE_PANEL_IPSANDPORTS."` i ON i.id = d2i.id_ipandports
WHERE d.specialsettings <> '' AND i.ssl = '1'
");
Database::pexecute($sel_stmt);
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `include_specialsettings` = '1' WHERE `id` = :id");
if ($sel_stmt->columnCount() > 0) {
showUpdateStep("Adjusting domain settings for downward compatibility");
while ($row = $sel_stmt->fetch(PDO::FETCH_ASSOC)) {
Database::pexecute($upd_stmt, [
'id' => $row['id']
]);
}
lastStepStatus(0);
}
\Froxlor\Froxlor::updateToDbVersion('201910120');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.1')) {
showUpdateStep("Updating from 0.10.1 to 0.10.2", false);
\Froxlor\Froxlor::updateToVersion('0.10.2');
}
if (\Froxlor\Froxlor::isDatabaseVersion('201910120')) {
showUpdateStep("Adding new TLS options to domains-table");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `override_tls` tinyint(1) DEFAULT '0' AFTER `writeerrorlog`;");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_protocols` text AFTER `override_tls`;");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `ssl_cipher_list` text AFTER `ssl_protocols`;");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `tlsv13_cipher_list` text AFTER `ssl_cipher_list`;");
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('201910200');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.2')) {
showUpdateStep("Updating from 0.10.2 to 0.10.3", false);
\Froxlor\Froxlor::updateToVersion('0.10.3');
}

View File

@@ -27,7 +27,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {
@@ -61,7 +61,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function get() public function get()
{ {
@@ -97,6 +97,8 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* optional, default auto-generated * optional, default auto-generated
* @param string $def_language * @param string $def_language
* optional, default is system-default language * optional, default is system-default language
* @param bool $api_allowed
* optional, default is true if system setting api.enabled is true, else false
* @param string $custom_notes * @param string $custom_notes
* optional, default empty * optional, default empty
* @param bool $custom_notes_show * @param bool $custom_notes_show
@@ -158,7 +160,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -171,6 +173,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
// parameters // parameters
$def_language = $this->getParam('def_language', true, Settings::Get('panel.standardlanguage')); $def_language = $this->getParam('def_language', true, Settings::Get('panel.standardlanguage'));
$api_allowed = $this->getBoolParam('api_allowed', true, Settings::Get('api.enabled'));
$custom_notes = $this->getParam('custom_notes', true, ''); $custom_notes = $this->getParam('custom_notes', true, '');
$custom_notes_show = $this->getBoolParam('custom_notes_show', true, 0); $custom_notes_show = $this->getBoolParam('custom_notes_show', true, 0);
$password = $this->getParam('admin_password', true, ''); $password = $this->getParam('admin_password', true, '');
@@ -271,6 +274,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
'name' => $name, 'name' => $name,
'email' => $email, 'email' => $email,
'lang' => $def_language, 'lang' => $def_language,
'api_allowed' => $api_allowed,
'change_serversettings' => $change_serversettings, 'change_serversettings' => $change_serversettings,
'customers' => $customers, 'customers' => $customers,
'customers_see_all' => $customers_see_all, 'customers_see_all' => $customers_see_all,
@@ -299,6 +303,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
`name` = :name, `name` = :name,
`email` = :email, `email` = :email,
`def_language` = :lang, `def_language` = :lang,
`api_allowed` = :api_allowed,
`change_serversettings` = :change_serversettings, `change_serversettings` = :change_serversettings,
`customers` = :customers, `customers` = :customers,
`customers_see_all` = :customers_see_all, `customers_see_all` = :customers_see_all,
@@ -350,6 +355,8 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* optional, default auto-generated * optional, default auto-generated
* @param string $def_language * @param string $def_language
* optional, default is system-default language * optional, default is system-default language
* @param bool $api_allowed
* optional, default is true if system setting api.enabled is true, else false
* @param string $custom_notes * @param string $custom_notes
* optional, default empty * optional, default empty
* @param string $theme * @param string $theme
@@ -415,7 +422,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function update() public function update()
{ {
@@ -444,6 +451,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
// you cannot edit some of the details of yourself // you cannot edit some of the details of yourself
if ($result['adminid'] == $this->getUserDetail('adminid')) { if ($result['adminid'] == $this->getUserDetail('adminid')) {
$api_allowed = $result['api_allowed'];
$deactivated = $result['deactivated']; $deactivated = $result['deactivated'];
$customers = $result['customers']; $customers = $result['customers'];
$domains = $result['domains']; $domains = $result['domains'];
@@ -462,6 +470,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$traffic = $result['traffic']; $traffic = $result['traffic'];
$ipaddress = ($result['ip'] != - 1 ? json_decode($result['ip'], true) : - 1); $ipaddress = ($result['ip'] != - 1 ? json_decode($result['ip'], true) : - 1);
} else { } else {
$api_allowed = $this->getBoolParam('api_allowed', true, $result['api_allowed']);
$deactivated = $this->getBoolParam('deactivated', true, $result['deactivated']); $deactivated = $this->getBoolParam('deactivated', true, $result['deactivated']);
$dec_places = Settings::Get('panel.decimal_places'); $dec_places = Settings::Get('panel.decimal_places');
@@ -578,6 +587,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
'name' => $name, 'name' => $name,
'email' => $email, 'email' => $email,
'lang' => $def_language, 'lang' => $def_language,
'api_allowed' => $api_allowed,
'change_serversettings' => $change_serversettings, 'change_serversettings' => $change_serversettings,
'customers' => $customers, 'customers' => $customers,
'customers_see_all' => $customers_see_all, 'customers_see_all' => $customers_see_all,
@@ -607,6 +617,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
`name` = :name, `name` = :name,
`email` = :email, `email` = :email,
`def_language` = :lang, `def_language` = :lang,
`api_allowed` = :api_allowed,
`change_serversettings` = :change_serversettings, `change_serversettings` = :change_serversettings,
`customers` = :customers, `customers` = :customers,
`customers_see_all` = :customers_see_all, `customers_see_all` = :customers_see_all,
@@ -653,7 +664,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function delete() public function delete()
{ {
@@ -753,7 +764,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function unlock() public function unlock()
{ {
@@ -788,7 +799,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
/** /**
* increase resource-usage * increase resource-usage
* *
* @param int $customerid * @param int $adminid
* @param string $resource * @param string $resource
* @param string $extra * @param string $extra
* optional, default empty * optional, default empty
@@ -803,7 +814,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
/** /**
* decrease resource-usage * decrease resource-usage
* *
* @param int $customerid * @param int $adminid
* @param string $resource * @param string $resource
* @param string $extra * @param string $extra
* optional, default empty * optional, default empty

View File

@@ -38,7 +38,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -63,10 +63,19 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$ssl_cert_chainfile = $this->getParam('ssl_cert_chainfile', true, ''); $ssl_cert_chainfile = $this->getParam('ssl_cert_chainfile', true, '');
// validate whether the domain does not already have an entry // validate whether the domain does not already have an entry
$result = $this->apiCall('Certificates.get', array( $has_cert = true;
try {
$this->apiCall('Certificates.get', array(
'id' => $domainid 'id' => $domainid
)); ));
if (empty($result)) { } catch (\Exception $e) {
if ($e->getCode() == 412) {
$has_cert = false;
} else {
throw $e;
}
}
if (!$has_cert) {
$this->addOrUpdateCertificate($domain['id'], $ssl_cert_file, $ssl_key_file, $ssl_ca_file, $ssl_cert_chainfile, true); $this->addOrUpdateCertificate($domain['id'], $ssl_cert_file, $ssl_key_file, $ssl_ca_file, $ssl_cert_chainfile, true);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] added ssl-certificate for '" . $domain['domain'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] added ssl-certificate for '" . $domain['domain'] . "'");
$result = $this->apiCall('Certificates.get', array( $result = $this->apiCall('Certificates.get', array(
@@ -87,7 +96,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function get() public function get()
{ {
@@ -110,6 +119,9 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$result = Database::pexecute_first($stmt, array( $result = Database::pexecute_first($stmt, array(
"domainid" => $domainid "domainid" => $domainid
)); ));
if (! $result) {
throw new \Exception("Domain '" . $domain['domain'] . "' does not have a certificate.", 412);
}
return $this->response(200, "successfull", $result); return $this->response(200, "successfull", $result);
} }
@@ -129,7 +141,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function update() public function update()
{ {
@@ -164,7 +176,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {
@@ -211,8 +223,8 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
* *
* @param int $id * @param int $id
* *
* @return array
* @throws \Exception * @throws \Exception
* @return string json-encoded array
*/ */
public function delete() public function delete()
{ {
@@ -271,6 +283,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
throw new \Exception("Unable to determine SSL certificate. Maybe no access?", 406); throw new \Exception("Unable to determine SSL certificate. Maybe no access?", 406);
} }
/** /**
* insert or update certificates entry * insert or update certificates entry
* *
@@ -292,6 +305,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
} }
$do_verify = true; $do_verify = true;
$expirationdate = null;
// no cert-file given -> forget everything // no cert-file given -> forget everything
if ($ssl_cert_file == '') { if ($ssl_cert_file == '') {
$ssl_key_file = ''; $ssl_key_file = '';
@@ -332,6 +346,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
} else { } else {
\Froxlor\UI\Response::standard_error('sslcertificateinvalidcert', '', true); \Froxlor\UI\Response::standard_error('sslcertificateinvalidcert', '', true);
} }
$expirationdate = empty($cert_content['validTo_time_t']) ? null : date("Y-m-d H:i:s", $cert_content['validTo_time_t']);
} }
// Add/Update database entry // Add/Update database entry
@@ -345,7 +360,8 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
`ssl_cert_file` = :ssl_cert_file, `ssl_cert_file` = :ssl_cert_file,
`ssl_key_file` = :ssl_key_file, `ssl_key_file` = :ssl_key_file,
`ssl_ca_file` = :ssl_ca_file, `ssl_ca_file` = :ssl_ca_file,
`ssl_cert_chainfile` = :ssl_cert_chainfile `ssl_cert_chainfile` = :ssl_cert_chainfile,
`expirationdate` = :expirationdate
" . $qrywhere . " `domainid`= :domainid " . $qrywhere . " `domainid`= :domainid
"); ");
$params = array( $params = array(
@@ -353,6 +369,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
"ssl_key_file" => $ssl_key_file, "ssl_key_file" => $ssl_key_file,
"ssl_ca_file" => $ssl_ca_file, "ssl_ca_file" => $ssl_ca_file,
"ssl_cert_chainfile" => $ssl_cert_chainfile, "ssl_cert_chainfile" => $ssl_cert_chainfile,
"expirationdate" => $expirationdate,
"domainid" => $domainid "domainid" => $domainid
); );
Database::pexecute($stmt, $params, true, true); Database::pexecute($stmt, $params, true, true);

View File

@@ -37,7 +37,7 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function get() public function get()
{ {
@@ -71,7 +71,7 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function update() public function update()
{ {
@@ -129,7 +129,7 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {

View File

@@ -55,8 +55,8 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
* required when called as admin, not needed when called as customer * required when called as admin, not needed when called as customer
* *
* @access admin, customer * @access admin, customer
* @return array
* @throws \Exception * @throws \Exception
* @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -140,7 +140,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {

View File

@@ -27,7 +27,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {
@@ -69,7 +69,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function get() public function get()
{ {
@@ -136,6 +136,8 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* optional * optional
* @param string $def_language, * @param string $def_language,
* optional, default is system-default language * optional, default is system-default language
* @param bool $api_allowed
* optional, default is true if system setting api.enabled is true, else false
* @param int $gender * @param int $gender
* optional, 0 = no-gender, 1 = male, 2 = female * optional, 0 = no-gender, 1 = male, 2 = female
* @param string $custom_notes * @param string $custom_notes
@@ -197,15 +199,17 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* @param bool $perlenabled * @param bool $perlenabled
* optional, whether to allow usage of Perl/CGI, default 0 (false) * optional, whether to allow usage of Perl/CGI, default 0 (false)
* @param bool $dnsenabled * @param bool $dnsenabled
* optional, ether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false) * optional, wether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
* @param bool $logviewenabled * @param bool $logviewenabled
* optional, ether to allow acccess to webserver access/error-logs, default 0 (false) * optional, wether to allow acccess to webserver access/error-logs, default 0 (false)
* @param bool $store_defaultindex * @param bool $store_defaultindex
* optional, whether to store the default index file to customers homedir * optional, whether to store the default index file to customers homedir
* @param int $hosting_plan_id
* optional, specify a hosting-plan to set certain resource-values from the plan instead of specifying them
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -227,10 +231,43 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$fax = $this->getParam('fax', true, ''); $fax = $this->getParam('fax', true, '');
$customernumber = $this->getParam('customernumber', true, ''); $customernumber = $this->getParam('customernumber', true, '');
$def_language = $this->getParam('def_language', true, Settings::Get('panel.standardlanguage')); $def_language = $this->getParam('def_language', true, Settings::Get('panel.standardlanguage'));
$api_allowed = $this->getBoolParam('api_allowed', true, Settings::Get('api.enabled'));
$gender = (int) $this->getParam('gender', true, 0); $gender = (int) $this->getParam('gender', true, 0);
$custom_notes = $this->getParam('custom_notes', true, ''); $custom_notes = $this->getParam('custom_notes', true, '');
$custom_notes_show = $this->getBoolParam('custom_notes_show', true, 0); $custom_notes_show = $this->getBoolParam('custom_notes_show', true, 0);
$createstdsubdomain = $this->getBoolParam('createstdsubdomain', true, 0);
$password = $this->getParam('new_customer_password', true, '');
$sendpassword = $this->getBoolParam('sendpassword', true, 0);
$store_defaultindex = $this->getBoolParam('store_defaultindex', true, 0);
$loginname = $this->getParam('new_loginname', true, '');
// hosting-plan values
$hosting_plan_id = $this->getParam('hosting_plan_id', true, 0);
if ($hosting_plan_id > 0) {
$hp_result = $this->apiCall('HostingPlans.get', array(
'id' => $hosting_plan_id
));
$hp_result['value'] = json_decode($hp_result['value'], true);
foreach ($hp_result['value'] as $index => $value) {
$hp_result[$index] = $value;
}
$diskspace = $hp_result['diskspace'] ?? 0;
$traffic = $hp_result['traffic'] ?? 0;
$subdomains = $hp_result['subdomains'] ?? 0;
$emails = $hp_result['emails'] ?? 0;
$email_accounts = $hp_result['email_accounts'] ?? 0;
$email_forwarders = $hp_result['email_forwarders'] ?? 0;
$email_quota = $hp_result['email_quota'] ?? Settings::Get('system.mail_quota');
$email_imap = $hp_result['email_imap'] ?? 0;
$email_pop3 = $hp_result['email_pop3'] ?? 0;
$ftps = $hp_result['ftps'] ?? 0;
$mysqls = $hp_result['mysqls'] ?? 0;
$phpenabled = $hp_result['phpenabled'] ?? 0;
$p_allowed_phpconfigs = $hp_result['allowed_phpconfigs'] ?? 0;
$perlenabled = $hp_result['perlenabled'] ?? 0;
$dnsenabled = $hp_result['dnsenabled'] ?? 0;
$logviewenabled = $hp_result['logviewenabled'] ?? 0;
} else {
$diskspace = $this->getUlParam('diskspace', 'diskspace_ul', true, 0); $diskspace = $this->getUlParam('diskspace', 'diskspace_ul', true, 0);
$traffic = $this->getUlParam('traffic', 'traffic_ul', true, 0); $traffic = $this->getUlParam('traffic', 'traffic_ul', true, 0);
$subdomains = $this->getUlParam('subdomains', 'subdomains_ul', true, 0); $subdomains = $this->getUlParam('subdomains', 'subdomains_ul', true, 0);
@@ -242,16 +279,12 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$email_pop3 = $this->getBoolParam('email_pop3', true, 0); $email_pop3 = $this->getBoolParam('email_pop3', true, 0);
$ftps = $this->getUlParam('ftps', 'ftps_ul', true, 0); $ftps = $this->getUlParam('ftps', 'ftps_ul', true, 0);
$mysqls = $this->getUlParam('mysqls', 'mysqls_ul', true, 0); $mysqls = $this->getUlParam('mysqls', 'mysqls_ul', true, 0);
$createstdsubdomain = $this->getBoolParam('createstdsubdomain', true, 0);
$password = $this->getParam('new_customer_password', true, '');
$sendpassword = $this->getBoolParam('sendpassword', true, 0);
$phpenabled = $this->getBoolParam('phpenabled', true, 0); $phpenabled = $this->getBoolParam('phpenabled', true, 0);
$p_allowed_phpconfigs = $this->getParam('allowed_phpconfigs', true, array()); $p_allowed_phpconfigs = $this->getParam('allowed_phpconfigs', true, array());
$perlenabled = $this->getBoolParam('perlenabled', true, 0); $perlenabled = $this->getBoolParam('perlenabled', true, 0);
$dnsenabled = $this->getBoolParam('dnsenabled', true, 0); $dnsenabled = $this->getBoolParam('dnsenabled', true, 0);
$logviewenabled = $this->getBoolParam('logviewenabled', true, 0); $logviewenabled = $this->getBoolParam('logviewenabled', true, 0);
$store_defaultindex = $this->getBoolParam('store_defaultindex', true, 0); }
$loginname = $this->getParam('new_loginname', true, '');
// validation // validation
$name = \Froxlor\Validate\Validate::validate($name, 'name', '', '', array(), true); $name = \Froxlor\Validate\Validate::validate($name, 'name', '', '', array(), true);
@@ -340,11 +373,12 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
'login' => $loginname 'login' => $loginname
), true, true); ), 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 (strtolower($loginname_check['loginname']) == strtolower($loginname) || strtolower($loginname_check_admin['loginname']) == strtolower($loginname)) {
\Froxlor\UI\Response::standard_error('loginnameexists', $loginname, true); \Froxlor\UI\Response::standard_error('loginnameexists', $loginname, true);
} elseif (! \Froxlor\Validate\Validate::validateUsername($loginname, Settings::Get('panel.unix_names'), 14 - strlen(Settings::Get('customer.mysqlprefix')))) { } elseif (! \Froxlor\Validate\Validate::validateUsername($loginname, Settings::Get('panel.unix_names'), $mysql_maxlen)) {
if (strlen($loginname) > 14 - strlen(Settings::Get('customer.mysqlprefix'))) { if (strlen($loginname) > $mysql_maxlen) {
\Froxlor\UI\Response::standard_error('loginnameiswrong2', 14 - strlen(Settings::Get('customer.mysqlprefix')), true); \Froxlor\UI\Response::standard_error('loginnameiswrong2', $mysql_maxlen, true);
} else { } else {
\Froxlor\UI\Response::standard_error('loginnameiswrong', $loginname, true); \Froxlor\UI\Response::standard_error('loginnameiswrong', $loginname, true);
} }
@@ -357,26 +391,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
\Froxlor\UI\Response::standard_error('documentrootexists', $documentroot, true); \Froxlor\UI\Response::standard_error('documentrootexists', $documentroot, true);
} }
if ($createstdsubdomain != '1') {
$createstdsubdomain = '0';
}
if ($phpenabled != '0') {
$phpenabled = '1';
}
if ($perlenabled != '0') {
$perlenabled = '1';
}
if ($dnsenabled != '0') {
$dnsenabled = '1';
}
if ($logviewenabled != '0') {
$logviewenabled = '1';
}
if ($password == '') { if ($password == '') {
$password = \Froxlor\System\Crypt::generatePassword(); $password = \Froxlor\System\Crypt::generatePassword();
} }
@@ -399,6 +413,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
'email' => $email, 'email' => $email,
'customerno' => $customernumber, 'customerno' => $customernumber,
'lang' => $def_language, 'lang' => $def_language,
'api_allowed' => $api_allowed,
'docroot' => $documentroot, 'docroot' => $documentroot,
'guid' => $guid, 'guid' => $guid,
'diskspace' => $diskspace, 'diskspace' => $diskspace,
@@ -439,6 +454,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
`email` = :email, `email` = :email,
`customernumber` = :customerno, `customernumber` = :customerno,
`def_language` = :lang, `def_language` = :lang,
`api_allowed` = :api_allowed,
`documentroot` = :docroot, `documentroot` = :docroot,
`guid` = :guid, `guid` = :guid,
`diskspace` = :diskspace, `diskspace` = :diskspace,
@@ -542,37 +558,14 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
Database::pexecute($ins_stmt, $ins_data, true, true); Database::pexecute($ins_stmt, $ins_data, true, true);
\Froxlor\System\Cronjob::inserttask('1'); \Froxlor\System\Cronjob::inserttask('1');
$cryptPassword = \Froxlor\System\Crypt::makeCryptPassword($password);
// add FTP-User
// @fixme use Ftp-ApiCommand later
$ins_stmt = Database::prepare("
INSERT INTO `" . TABLE_FTP_USERS . "` SET `customerid` = :customerid, `username` = :username, `description` = :desc,
`password` = :passwd, `homedir` = :homedir, `login_enabled` = 'y', `uid` = :guid, `gid` = :guid
");
$ins_data = array(
'customerid' => $customerid,
'username' => $loginname,
'passwd' => $cryptPassword,
'homedir' => $documentroot,
'guid' => $guid,
'desc' => "Default"
);
Database::pexecute($ins_stmt, $ins_data, true, true);
// add FTP-Group
// @fixme use Ftp-ApiCommand later
$ins_stmt = Database::prepare("
INSERT INTO `" . TABLE_FTP_GROUPS . "` SET `customerid` = :customerid, `groupname` = :groupname, `gid` = :guid, `members` = :members
");
$ins_data = array(
'customerid' => $customerid,
'groupname' => $loginname,
'guid' => $guid,
'members' => $loginname . ',' . Settings::Get('system.httpuser')
);
// add default FTP-User
// also, add froxlor-local user to ftp-group (if exists!) to // also, add froxlor-local user to ftp-group (if exists!) to
// allow access to customer-directories from within the panel, which // allow access to customer-directories from within the panel, which
// is necessary when pathedit = Dropdown // is necessary when pathedit = Dropdown
$local_users = array(
Settings::Get('system.httpuser')
);
if ((int) Settings::Get('system.mod_fcgid_ownvhost') == 1 || (int) Settings::Get('phpfpm.enabled_ownvhost') == 1) { if ((int) Settings::Get('system.mod_fcgid_ownvhost') == 1 || (int) Settings::Get('phpfpm.enabled_ownvhost') == 1) {
if ((int) Settings::Get('system.mod_fcgid') == 1) { if ((int) Settings::Get('system.mod_fcgid') == 1) {
$local_user = Settings::Get('system.mod_fcgid_httpuser'); $local_user = Settings::Get('system.mod_fcgid_httpuser');
@@ -581,22 +574,20 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
} }
// check froxlor-local user membership in ftp-group // check froxlor-local user membership in ftp-group
// without this check addition may duplicate user in list if httpuser == local_user // without this check addition may duplicate user in list if httpuser == local_user
if (strpos($ins_data['members'], $local_user) == false) { if (in_array($local_user, $local_users) == false) {
$ins_data['members'] .= ',' . $local_user; $local_users[] = $local_user;
} }
} }
Database::pexecute($ins_stmt, $ins_data, true, true); $this->apiCall('Ftps.add', array(
'customerid' => $customerid,
// FTP-Quotatallies 'path' => '/',
// @fixme use Ftp-ApiCommand later 'ftp_password' => $password,
$ins_stmt = Database::prepare(" 'ftp_description' => "Default",
INSERT INTO `" . TABLE_FTP_QUOTATALLIES . "` SET `name` = :name, `quota_type` = 'user', `bytes_in_used` = '0', 'sendinfomail' => 0,
`bytes_out_used` = '0', `bytes_xfer_used` = '0', `files_in_used` = '0', `files_out_used` = '0', `files_xfer_used` = '0' 'ftp_username' => $loginname,
"); 'additional_members' => $local_users,
Database::pexecute($ins_stmt, array( 'is_defaultuser' => 1
'name' => $loginname ));
), true, true);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] automatically added ftp-account for user '" . $loginname . "'");
$_stdsubdomain = ''; $_stdsubdomain = '';
if ($createstdsubdomain == '1') { if ($createstdsubdomain == '1') {
@@ -749,6 +740,8 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* optional * optional
* @param string $def_language, * @param string $def_language,
* optional, default is system-default language * optional, default is system-default language
* @param bool $api_allowed
* optional, default is true if system setting api.enabled is true, else false
* @param int $gender * @param int $gender
* optional, 0 = no-gender, 1 = male, 2 = female * optional, 0 = no-gender, 1 = male, 2 = female
* @param string $custom_notes * @param string $custom_notes
@@ -820,7 +813,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function update() public function update()
{ {
@@ -851,6 +844,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$fax = $this->getParam('fax', true, $result['fax']); $fax = $this->getParam('fax', true, $result['fax']);
$customernumber = $this->getParam('customernumber', true, $result['customernumber']); $customernumber = $this->getParam('customernumber', true, $result['customernumber']);
$def_language = $this->getParam('def_language', true, $result['def_language']); $def_language = $this->getParam('def_language', true, $result['def_language']);
$api_allowed = $this->getBoolParam('api_allowed', true, $result['api_allowed']);
$gender = (int) $this->getParam('gender', true, $result['gender']); $gender = (int) $this->getParam('gender', true, $result['gender']);
$custom_notes = $this->getParam('custom_notes', true, $result['custom_notes']); $custom_notes = $this->getParam('custom_notes', true, $result['custom_notes']);
$custom_notes_show = $this->getBoolParam('custom_notes_show', true, $result['custom_notes_show']); $custom_notes_show = $this->getBoolParam('custom_notes_show', true, $result['custom_notes_show']);
@@ -993,30 +987,10 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
\Froxlor\System\Cronjob::inserttask('1'); \Froxlor\System\Cronjob::inserttask('1');
} }
if ($deactivated != '1') {
$deactivated = '0';
}
if ($phpenabled != '0') {
$phpenabled = '1';
}
if ($perlenabled != '0') {
$perlenabled = '1';
}
if ($dnsenabled != '0') {
$dnsenabled = '1';
}
if ($phpenabled != $result['phpenabled'] || $perlenabled != $result['perlenabled']) { if ($phpenabled != $result['phpenabled'] || $perlenabled != $result['perlenabled']) {
\Froxlor\System\Cronjob::inserttask('1'); \Froxlor\System\Cronjob::inserttask('1');
} }
if ($logviewenabled != '0') {
$logviewenabled = '1';
}
// activate/deactivate customer services // activate/deactivate customer services
if ($deactivated != $result['deactivated']) { if ($deactivated != $result['deactivated']) {
@@ -1061,6 +1035,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$dbm = new \Froxlor\Database\DbManager($this->logger()); $dbm = new \Froxlor\Database\DbManager($this->logger());
// For each of them // For each of them
$priv_changed = false;
while ($row_database = $databases_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row_database = $databases_stmt->fetch(\PDO::FETCH_ASSOC)) {
if ($last_dbserver != $row_database['dbserver']) { if ($last_dbserver != $row_database['dbserver']) {
@@ -1081,10 +1056,13 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$dbm->getManager()->enableUser($row_database['databasename'], $mysql_access_host); $dbm->getManager()->enableUser($row_database['databasename'], $mysql_access_host);
} }
} }
$priv_changed = true;
} }
// At last flush the new privileges // At last flush the new privileges
if ($priv_changed) {
$dbm->getManager()->flushPrivileges(); $dbm->getManager()->flushPrivileges();
}
Database::needRoot(false); Database::needRoot(false);
// reactivate/deactivate api-keys // reactivate/deactivate api-keys
@@ -1156,7 +1134,8 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
'dnsenabled' => $dnsenabled, 'dnsenabled' => $dnsenabled,
'logviewenabled' => $logviewenabled, 'logviewenabled' => $logviewenabled,
'custom_notes' => $custom_notes, 'custom_notes' => $custom_notes,
'custom_notes_show' => $custom_notes_show 'custom_notes_show' => $custom_notes_show,
'api_allowed' => $api_allowed
); );
$upd_data = $upd_data + $admin_upd_data; $upd_data = $upd_data + $admin_upd_data;
} }
@@ -1197,7 +1176,8 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
`dnsenabled` = :dnsenabled, `dnsenabled` = :dnsenabled,
`logviewenabled` = :logviewenabled, `logviewenabled` = :logviewenabled,
`custom_notes` = :custom_notes, `custom_notes` = :custom_notes,
`custom_notes_show` = :custom_notes_show"; `custom_notes_show` = :custom_notes_show,
`api_allowed` = :api_allowed";
$upd_query .= $admin_upd_query; $upd_query .= $admin_upd_query;
} }
$upd_query .= " WHERE `customerid` = :customerid"; $upd_query .= " WHERE `customerid` = :customerid";
@@ -1337,7 +1317,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function delete() public function delete()
{ {
@@ -1365,6 +1345,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$dbm = new \Froxlor\Database\DbManager($this->logger()); $dbm = new \Froxlor\Database\DbManager($this->logger());
$priv_changed = false;
while ($row_database = $databases_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row_database = $databases_stmt->fetch(\PDO::FETCH_ASSOC)) {
if ($last_dbserver != $row_database['dbserver']) { if ($last_dbserver != $row_database['dbserver']) {
Database::needRoot(true, $row_database['dbserver']); Database::needRoot(true, $row_database['dbserver']);
@@ -1372,8 +1353,11 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$last_dbserver = $row_database['dbserver']; $last_dbserver = $row_database['dbserver'];
} }
$dbm->getManager()->deleteDatabase($row_database['databasename']); $dbm->getManager()->deleteDatabase($row_database['databasename']);
$priv_changed = true;
} }
if ($priv_changed) {
$dbm->getManager()->flushPrivileges(); $dbm->getManager()->flushPrivileges();
}
Database::needRoot(false); Database::needRoot(false);
// delete customer itself // delete customer itself
@@ -1561,7 +1545,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function unlock() public function unlock()
{ {
@@ -1606,7 +1590,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function move() public function move()
{ {

View File

@@ -44,7 +44,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -139,7 +139,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function get() public function get()
{ {
@@ -214,7 +214,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function update() public function update()
{ {
@@ -288,7 +288,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {
@@ -321,7 +321,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function delete() public function delete()
{ {
@@ -394,7 +394,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
{ {
if ($errdoc !== null && $errdoc != '') { if ($errdoc !== null && $errdoc != '') {
// not a URL // not a URL
if ((strtoupper(substr($errdoc, 0, 5)) != 'HTTP:' && strtoupper(substr($errdoc, 0, 6)) != 'HTTPS:') || ! \Froxlor\Validate\Form\Data::validateUrl($errdoc)) { if ((strtoupper(substr($errdoc, 0, 5)) != 'HTTP:' && strtoupper(substr($errdoc, 0, 6)) != 'HTTPS:') || ! \Froxlor\Validate\Validate::validateUrl($errdoc)) {
// a file // a file
if (substr($errdoc, 0, 1) != '"') { if (substr($errdoc, 0, 1) != '"') {
$errdoc = \Froxlor\FileDir::makeCorrectFile($errdoc); $errdoc = \Froxlor\FileDir::makeCorrectFile($errdoc);

View File

@@ -37,7 +37,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -124,7 +124,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function get() public function get()
{ {
@@ -197,7 +197,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function update() public function update()
{ {
@@ -271,7 +271,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {
@@ -306,7 +306,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function delete() public function delete()
{ {

View File

@@ -42,7 +42,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -138,6 +138,43 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$errors[] = $this->lng['error']['dns_arec_noipv4']; $errors[] = $this->lng['error']['dns_arec_noipv4'];
} elseif ($type == 'AAAA' && filter_var($content, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) { } elseif ($type == 'AAAA' && filter_var($content, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
$errors[] = $this->lng['error']['dns_aaaarec_noipv6']; $errors[] = $this->lng['error']['dns_aaaarec_noipv6'];
} elseif ($type == 'CAA' && ! empty($content)) {
$re = '/(?\'critical\'\d)\h*(?\'type\'iodef|issue|issuewild)\h*(?\'value\'(?\'issuevalue\'"(?\'domain\'(?=.{3,128}$)(?>(?>[a-zA-Z0-9]+[a-zA-Z0-9-]*[a-zA-Z0-9]+|[a-zA-Z0-9]+)\.)*(?>[a-zA-Z]{2,}|[a-zA-Z0-9]{2,}\.[a-zA-Z]{2,}))[;\h]*(?\'parameters\'(?>[a-zA-Z0-9]{1,60}=[a-zA-Z0-9]{1,60}\h*)+)?")|(?\'iodefvalue\'"(?\'url\'(mailto:.*|http:\/\/.*|https:\/\/.*))"))/';
preg_match($re, $content, $matches);
if (empty($matches)) {
$errors[] = $this->lng['error']['dns_content_invalid'];
} elseif (($matches['type'] == 'issue' || $matches['type'] == 'issuewild') && ! \Froxlor\Validate\Validate::validateDomain($matches['domain'])) {
$errors[] = $this->lng['error']['dns_content_invalid'];
} elseif ($matches['type'] == 'iodef' && ! \Froxlor\Validate\Validate::validateUrl($matches['url'])) {
$errors[] = $this->lng['error']['dns_content_invalid'];
} else {
$content = $matches[0];
}
} elseif ($type == 'CNAME' || $type == 'DNAME') {
// check for trailing dot
if (substr($content, - 1) == '.') {
// remove it for checks
$content = substr($content, 0, - 1);
} else {
// add domain name
$content .= '.' . $domain;
}
if (! \Froxlor\Validate\Validate::validateDomain($content, true)) {
$errors[] = $this->lng['error']['dns_cname_invaliddom'];
} else {
// check whether there are RR-records for the same resource
foreach ($dom_entries as $existing_entries) {
if (($existing_entries['type'] == 'A' || $existing_entries['type'] == 'AAAA' || $existing_entries['type'] == 'MX' || $existing_entries['type'] == 'NS') && $existing_entries['record'] == $record) {
$errors[] = $this->lng['error']['dns_cname_nomorerr'];
break;
}
}
}
// append trailing dot (again)
$content .= '.';
} elseif ($type == 'LOC' && ! empty($content)) {
$content = $content;
} elseif ($type == 'MX') { } elseif ($type == 'MX') {
if ($prio === null || $prio < 0) { if ($prio === null || $prio < 0) {
$errors[] = $this->lng['error']['dns_mx_prioempty']; $errors[] = $this->lng['error']['dns_mx_prioempty'];
@@ -161,28 +198,6 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
} }
// append trailing dot (again) // append trailing dot (again)
$content .= '.'; $content .= '.';
} elseif ($type == 'CNAME') {
// check for trailing dot
if (substr($content, - 1) == '.') {
// remove it for checks
$content = substr($content, 0, - 1);
} else {
// add domain name
$content .= '.' . $domain;
}
if (! \Froxlor\Validate\Validate::validateDomain($content, true)) {
$errors[] = $this->lng['error']['dns_cname_invaliddom'];
} else {
// check whether there are RR-records for the same resource
foreach ($dom_entries as $existing_entries) {
if (($existing_entries['type'] == 'A' || $existing_entries['type'] == 'AAAA' || $existing_entries['type'] == 'MX' || $existing_entries['type'] == 'NS') && $existing_entries['record'] == $record) {
$errors[] = $this->lng['error']['dns_cname_nomorerr'];
break;
}
}
}
// append trailing dot (again)
$content .= '.';
} elseif ($type == 'NS') { } elseif ($type == 'NS') {
// check for trailing dot // check for trailing dot
if (substr($content, - 1) == '.') { if (substr($content, - 1) == '.') {
@@ -194,9 +209,8 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
} }
// append trailing dot (again) // append trailing dot (again)
$content .= '.'; $content .= '.';
} elseif ($type == 'TXT' && ! empty($content)) { } elseif ($type == 'RP' && ! empty($content)) {
// check that TXT content is enclosed in " " $content = $content;
$content = \Froxlor\Dns\Dns::encloseTXTContent($content);
} elseif ($type == 'SRV') { } elseif ($type == 'SRV') {
if ($prio === null || $prio < 0) { if ($prio === null || $prio < 0) {
$errors[] = $this->lng['error']['dns_srv_prioempty']; $errors[] = $this->lng['error']['dns_srv_prioempty'];
@@ -232,6 +246,11 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
if (substr($content, - 1) != '.') { if (substr($content, - 1) != '.') {
$content .= '.'; $content .= '.';
} }
} elseif ($type == 'SSHFP' && ! empty($content)) {
$content = $content;
} elseif ($type == 'TXT' && ! empty($content)) {
// check that TXT content is enclosed in " "
$content = \Froxlor\Dns\Dns::encloseTXTContent($content);
} }
$new_entry = array( $new_entry = array(
@@ -306,7 +325,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function get() public function get()
{ {
@@ -354,12 +373,50 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
} }
/** /**
* You cannot list dns zones. * List all entry records of a given domain by either id or domainname
* To get all domains use Domains.listing() or SubDomains.listing() *
* @param int $id
* optional, the domain id
* @param string $domainname
* optional, the domain name
*
* @access admin, customer
* @throws \Exception
* @return bool
*/ */
public function listing() public function listing()
{ {
throw new \Exception('You cannot list dns zones. To get all domains use Domains.listing() or SubDomains.listing()', 303); if (Settings::Get('system.dnsenabled') != '1') {
throw new \Exception("DNS service not enabled on this system", 405);
}
if ($this->isAdmin() == false && $this->getUserDetail('dnsenabled') != '1') {
throw new \Exception("You cannot access this resource", 405);
}
$id = $this->getParam('id', true, 0);
$dn_optional = ($id <= 0 ? false : true);
$domainname = $this->getParam('domainname', $dn_optional, '');
// get requested domain
$result = $this->apiCall('SubDomains.get', array(
'id' => $id,
'domainname' => $domainname
));
$id = $result['id'];
$sel_stmt = Database::prepare("SELECT * FROM `" . TABLE_DOMAIN_DNS . "` WHERE `domain_id` = :did");
Database::pexecute($sel_stmt, array(
'did' => $id
), true, true);
$result = [];
while ($row = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successfull", array(
'count' => count($result),
'list' => $result
));
} }
/** /**

View File

@@ -27,7 +27,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {
@@ -70,7 +70,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function get() public function get()
{ {
@@ -119,8 +119,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional, default is the calling admin's ID * optional, default is the calling admin's ID
* @param array $ipandport * @param array $ipandport
* optional list of ip/ports to assign to domain, default is system-default-ips * optional list of ip/ports to assign to domain, default is system-default-ips
* @param bool $subcanemaildomain * @param int $subcanemaildomain
* optional, allow subdomains of this domain as email domains, default 0 (false) * optional, allow subdomains of this domain as email domains, 1 = choosable (default no), 2 = choosable (default yes), 3 = always, default 0 (never)
* @param bool $isemaildomain * @param bool $isemaildomain
* optional, allow email usage with this domain, default 0 (false) * optional, allow email usage with this domain, default 0 (false)
* @param bool $email_only * @param bool $email_only
@@ -147,6 +147,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional, currently not in use, default 0 (false) * optional, currently not in use, default 0 (false)
* @param string $specialsettings * @param string $specialsettings
* optional, custom webserver vhost-content which is added to the generated vhost, default empty * optional, custom webserver vhost-content which is added to the generated vhost, default empty
* @param string $ssl_specialsettings
* optional, custom webserver vhost-content which is added to the generated ssl-vhost, default empty
* @param bool $include_specialsettings
* optional, whether or not to include non-ssl specialsettings in the generated ssl-vhost, default false
* @param bool $notryfiles * @param bool $notryfiles
* optional, [nginx only] do not generate the default try-files directive, default 0 (false) * optional, [nginx only] do not generate the default try-files directive, default 0 (false)
* @param bool $writeaccesslog * @param bool $writeaccesslog
@@ -170,7 +174,9 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* @param bool $letsencrypt * @param bool $letsencrypt
* optional, whether to generate a Let's Encrypt certificate for this domain, default false; requires SSL to be enabled * optional, whether to generate a Let's Encrypt certificate for this domain, default false; requires SSL to be enabled
* @param array $ssl_ipandport * @param array $ssl_ipandport
* optional, list of ssl-enabled ip/port id's to assign to this domain * 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 $http2 * @param bool $http2
* optional, whether to enable http/2 for this domain (requires to be enabled in the settings), default 0 (false) * optional, whether to enable http/2 for this domain (requires to be enabled in the settings), default 0 (false)
* @param int $hsts_maxage * @param int $hsts_maxage
@@ -181,10 +187,18 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional whether or not to preload HSTS header value * optional whether or not to preload HSTS header value
* @param bool $ocsp_stapling * @param bool $ocsp_stapling
* optional whether to enable ocsp-stapling for this domain. default 0 (false), requires SSL * optional whether to enable ocsp-stapling for this domain. default 0 (false), 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
* optional list of allowed/used ssl/tls protocols, see system.ssl_protocols setting, only used/required if $override_tls is true, default empty or system.ssl_protocols setting if $override_tls is true
* @param string $ssl_cipher_list
* optional list of allowed/used ssl/tls ciphers, see system.ssl_cipher_list setting, only used/required if $override_tls is true, default empty or system.ssl_cipher_list setting if $override_tls is true
* @param string $tlsv13_cipher_list
* optional list of allowed/used tls-1.3 specific ciphers, see system.tlsv13_cipher_list setting, only used/required if $override_tls is true, default empty or system.tlsv13_cipher_list setting if $override_tls is true
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -212,6 +226,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$zonefile = $this->getParam('zonefile', true, ''); $zonefile = $this->getParam('zonefile', true, '');
$dkim = $this->getBoolParam('dkim', true, 0); $dkim = $this->getBoolParam('dkim', true, 0);
$specialsettings = $this->getParam('specialsettings', true, ''); $specialsettings = $this->getParam('specialsettings', true, '');
$ssl_specialsettings = $this->getParam('ssl_specialsettings', true, '');
$include_specialsettings = $this->getBoolParam('include_specialsettings', true, 0);
$notryfiles = $this->getBoolParam('notryfiles', true, 0); $notryfiles = $this->getBoolParam('notryfiles', true, 0);
$writeaccesslog = $this->getBoolParam('writeaccesslog', true, 1); $writeaccesslog = $this->getBoolParam('writeaccesslog', true, 1);
$writeerrorlog = $this->getBoolParam('writeerrorlog', true, 1); $writeerrorlog = $this->getBoolParam('writeerrorlog', true, 1);
@@ -223,13 +239,27 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$mod_fcgid_maxrequests = $this->getParam('mod_fcgid_maxrequests', true, - 1); $mod_fcgid_maxrequests = $this->getParam('mod_fcgid_maxrequests', true, - 1);
$ssl_redirect = $this->getBoolParam('ssl_redirect', true, 0); $ssl_redirect = $this->getBoolParam('ssl_redirect', true, 0);
$letsencrypt = $this->getBoolParam('letsencrypt', true, 0); $letsencrypt = $this->getBoolParam('letsencrypt', true, 0);
$p_ssl_ipandports = $this->getParam('ssl_ipandport', true, explode(',', Settings::Get('system.defaultsslip'))); $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')));
$http2 = $this->getBoolParam('http2', true, 0); $http2 = $this->getBoolParam('http2', true, 0);
$hsts_maxage = $this->getParam('hsts_maxage', true, 0); $hsts_maxage = $this->getParam('hsts_maxage', true, 0);
$hsts_sub = $this->getBoolParam('hsts_sub', true, 0); $hsts_sub = $this->getBoolParam('hsts_sub', true, 0);
$hsts_preload = $this->getBoolParam('hsts_preload', true, 0); $hsts_preload = $this->getBoolParam('hsts_preload', true, 0);
$ocsp_stapling = $this->getBoolParam('ocsp_stapling', true, 0); $ocsp_stapling = $this->getBoolParam('ocsp_stapling', true, 0);
$override_tls = $this->getBoolParam('override_tls', true, 0);
$p_ssl_protocols = array();
$ssl_cipher_list = "";
$tlsv13_cipher_list = "";
if ($this->getUserDetail('change_serversettings') == '1') {
if ($override_tls) {
$p_ssl_protocols = $this->getParam('ssl_protocols', true, explode(',', Settings::Get('system.ssl_protocols')));
$ssl_cipher_list = $this->getParam('ssl_cipher_list', true, Settings::Get('system.ssl_cipher_list'));
$tlsv13_cipher_list = $this->getParam('tlsv13_cipher_list', true, Settings::Get('system.tlsv13_cipher_list'));
}
}
// validation // validation
if ($p_domain == Settings::Get('system.hostname')) { if ($p_domain == Settings::Get('system.hostname')) {
\Froxlor\UI\Response::standard_error('admin_domain_emailsystemhostname', '', true); \Froxlor\UI\Response::standard_error('admin_domain_emailsystemhostname', '', true);
@@ -283,7 +313,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
'0', '0',
'' ''
), true); ), true);
if ($registration_date == '0000-00-00') { if ($registration_date == '0000-00-00' || empty($registration_date)) {
$registration_date = null; $registration_date = null;
} }
@@ -292,7 +322,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
'0', '0',
'' ''
), true); ), true);
if ($termination_date == '0000-00-00') { if ($termination_date == '0000-00-00' || empty($termination_date)) {
$termination_date = null; $termination_date = null;
} }
@@ -316,6 +346,34 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
} else { } else {
$documentroot = $_documentroot; $documentroot = $_documentroot;
} }
$ssl_protocols = array();
if (! empty($p_ssl_protocols) && is_numeric($p_ssl_protocols)) {
$p_ssl_protocols = array(
$p_ssl_protocols
);
}
if (! empty($p_ssl_protocols) && ! is_array($p_ssl_protocols)) {
$p_ssl_protocols = json_decode($p_ssl_protocols, true);
}
if (! empty($p_ssl_protocols) && is_array($p_ssl_protocols)) {
$protocols_available = array(
'TLSv1',
'TLSv1.1',
'TLSv1.2',
'TLSv1.3'
);
foreach ($p_ssl_protocols as $ssl_protocol) {
if (! in_array(trim($ssl_protocol), $protocols_available)) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_DEBUG, "[API] unknown SSL protocol '" . trim($ssl_protocol) . "'");
continue;
}
$ssl_protocols[] = $ssl_protocol;
}
}
if (empty($ssl_protocols)) {
$override_tls = '0';
}
} else { } else {
$isbinddomain = '0'; $isbinddomain = '0';
if (Settings::Get('system.bind_enable') == '1') { if (Settings::Get('system.bind_enable') == '1') {
@@ -325,10 +383,14 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$zonefile = ''; $zonefile = '';
$dkim = '0'; $dkim = '0';
$specialsettings = ''; $specialsettings = '';
$ssl_specialsettings = '';
$include_specialsettings = 0;
$notryfiles = '0'; $notryfiles = '0';
$writeaccesslog = '1'; $writeaccesslog = '1';
$writeerrorlog = '1'; $writeerrorlog = '1';
$documentroot = $_documentroot; $documentroot = $_documentroot;
$override_tls = '0';
$ssl_protocols = array();
} }
if ($this->getUserDetail('caneditphpsettings') == '1' || $this->getUserDetail('change_serversettings') == '1') { if ($this->getUserDetail('caneditphpsettings') == '1' || $this->getUserDetail('change_serversettings') == '1') {
@@ -388,6 +450,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$ssl_ipandports = array(); $ssl_ipandports = array();
if (Settings::Get('system.use_ssl') == "1" && ! empty($p_ssl_ipandports)) { if (Settings::Get('system.use_ssl') == "1" && ! empty($p_ssl_ipandports)) {
$ssl_ipandports = $this->validateIpAddresses($p_ssl_ipandports, true); $ssl_ipandports = $this->validateIpAddresses($p_ssl_ipandports, true);
if ($this->getUserDetail('change_serversettings') == '1') {
$ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $ssl_specialsettings), 'ssl_specialsettings', '/^[^\0]*$/', '', array(), true);
}
} }
if (Settings::Get('system.use_ssl') == "0" || empty($ssl_ipandports)) { if (Settings::Get('system.use_ssl') == "0" || empty($ssl_ipandports)) {
$ssl_redirect = 0; $ssl_redirect = 0;
@@ -404,17 +470,16 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
// OCSP stapling // OCSP stapling
$ocsp_stapling = 0; $ocsp_stapling = 0;
// vhost container settings
$ssl_specialsettings = '';
$include_specialsettings = 0;
} }
// We can't enable let's encrypt for wildcard - domains if using acme-v1 // We can't enable let's encrypt for wildcard-domains
if ($serveraliasoption == '0' && $letsencrypt == '1' && Settings::Get('system.leapiversion') == '1') { if ($serveraliasoption == '0' && $letsencrypt == '1') {
\Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt', '', true); \Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt', '', true);
} }
// if using acme-v2 we cannot issue wildcard-certificates
// because they currently only support the dns-01 challenge
if ($serveraliasoption == '0' && $letsencrypt == '1' && Settings::Get('system.leapiversion') == '2') {
\Froxlor\UI\Response::standard_error('nowildcardwithletsencryptv2', '', true);
}
// Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated // Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated
if ($ssl_redirect > 0 && $letsencrypt == 1) { if ($ssl_redirect > 0 && $letsencrypt == 1) {
@@ -542,6 +607,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
'openbasedir' => $openbasedir, 'openbasedir' => $openbasedir,
'speciallogfile' => $speciallogfile, 'speciallogfile' => $speciallogfile,
'specialsettings' => $specialsettings, 'specialsettings' => $specialsettings,
'ssl_specialsettings' => $ssl_specialsettings,
'include_specialsettings' => $include_specialsettings,
'notryfiles' => $notryfiles, 'notryfiles' => $notryfiles,
'writeaccesslog' => $writeaccesslog, 'writeaccesslog' => $writeaccesslog,
'writeerrorlog' => $writeerrorlog, 'writeerrorlog' => $writeerrorlog,
@@ -558,7 +625,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
'hsts' => $hsts_maxage, 'hsts' => $hsts_maxage,
'hsts_sub' => $hsts_sub, 'hsts_sub' => $hsts_sub,
'hsts_preload' => $hsts_preload, 'hsts_preload' => $hsts_preload,
'ocsp_stapling' => $ocsp_stapling 'ocsp_stapling' => $ocsp_stapling,
'override_tls' => $override_tls,
'ssl_protocols' => implode(",", $ssl_protocols),
'ssl_cipher_list' => $ssl_cipher_list,
'tlsv13_cipher_list' => $tlsv13_cipher_list
); );
$ins_stmt = Database::prepare(" $ins_stmt = Database::prepare("
@@ -584,6 +655,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`openbasedir` = :openbasedir, `openbasedir` = :openbasedir,
`speciallogfile` = :speciallogfile, `speciallogfile` = :speciallogfile,
`specialsettings` = :specialsettings, `specialsettings` = :specialsettings,
`ssl_specialsettings` = :ssl_specialsettings,
`include_specialsettings` = :include_specialsettings,
`notryfiles` = :notryfiles, `notryfiles` = :notryfiles,
`writeaccesslog` = :writeaccesslog, `writeaccesslog` = :writeaccesslog,
`writeerrorlog` = :writeerrorlog, `writeerrorlog` = :writeerrorlog,
@@ -600,7 +673,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`hsts` = :hsts, `hsts` = :hsts,
`hsts_sub` = :hsts_sub, `hsts_sub` = :hsts_sub,
`hsts_preload` = :hsts_preload, `hsts_preload` = :hsts_preload,
`ocsp_stapling` = :ocsp_stapling `ocsp_stapling` = :ocsp_stapling,
`override_tls` = :override_tls,
`ssl_protocols` = :ssl_protocols,
`ssl_cipher_list` = :ssl_cipher_list,
`tlsv13_cipher_list` = :tlsv13_cipher_list
"); ");
Database::pexecute($ins_stmt, $ins_data, true, true); Database::pexecute($ins_stmt, $ins_data, true, true);
$domainid = Database::lastInsertId(); $domainid = Database::lastInsertId();
@@ -670,8 +747,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional, default is the calling admin's ID * optional, default is the calling admin's ID
* @param array $ipandport * @param array $ipandport
* optional list of ip/ports to assign to domain, default is system-default-ips * optional list of ip/ports to assign to domain, default is system-default-ips
* @param bool $subcanemaildomain * @param int $subcanemaildomain
* optional, allow subdomains of this domain as email domains, default 0 (false) * optional, allow subdomains of this domain as email domains, 1 = choosable (default no), 2 = choosable (default yes), 3 = always, default 0 (never)
* @param bool $isemaildomain * @param bool $isemaildomain
* optional, allow email usage with this domain, default 0 (false) * optional, allow email usage with this domain, default 0 (false)
* @param bool $email_only * @param bool $email_only
@@ -700,6 +777,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional, currently not in use, default 0 (false) * optional, currently not in use, default 0 (false)
* @param string $specialsettings * @param string $specialsettings
* optional, custom webserver vhost-content which is added to the generated vhost, default empty * optional, custom webserver vhost-content which is added to the generated vhost, default empty
* @param string $ssl_specialsettings
* optional, custom webserver vhost-content which is added to the generated ssl-vhost, default empty
* @param bool $include_specialsettings
* optional, whether or not to include non-ssl specialsettings in the generated ssl-vhost, default false
* @param bool $specialsettingsforsubdomains * @param bool $specialsettingsforsubdomains
* optional, whether to apply specialsettings to all subdomains of this domain, default 0 (false) * optional, whether to apply specialsettings to all subdomains of this domain, default 0 (false)
* @param bool $notryfiles * @param bool $notryfiles
@@ -741,7 +822,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function update() public function update()
{ {
@@ -764,7 +845,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$customerid = intval($this->getParam('customerid', true, $result['customerid'])); $customerid = intval($this->getParam('customerid', true, $result['customerid']));
$adminid = intval($this->getParam('adminid', true, $result['adminid'])); $adminid = intval($this->getParam('adminid', true, $result['adminid']));
$subcanemaildomain = $this->getBoolParam('subcanemaildomain', true, $result['subcanemaildomain']); $subcanemaildomain = $this->getParam('subcanemaildomain', true, $result['subcanemaildomain']);
$isemaildomain = $this->getBoolParam('isemaildomain', true, $result['isemaildomain']); $isemaildomain = $this->getBoolParam('isemaildomain', true, $result['isemaildomain']);
$email_only = $this->getBoolParam('email_only', true, $result['email_only']); $email_only = $this->getBoolParam('email_only', true, $result['email_only']);
$p_serveraliasoption = $this->getParam('selectserveralias', true, - 1); $p_serveraliasoption = $this->getParam('selectserveralias', true, - 1);
@@ -779,6 +860,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$zonefile = $this->getParam('zonefile', true, $result['zonefile']); $zonefile = $this->getParam('zonefile', true, $result['zonefile']);
$dkim = $this->getBoolParam('dkim', true, $result['dkim']); $dkim = $this->getBoolParam('dkim', true, $result['dkim']);
$specialsettings = $this->getParam('specialsettings', true, $result['specialsettings']); $specialsettings = $this->getParam('specialsettings', true, $result['specialsettings']);
$ssl_specialsettings = $this->getParam('ssl_specialsettings', true, $result['ssl_specialsettings']);
$include_specialsettings = $this->getBoolParam('include_specialsettings', true, $result['include_specialsettings']);
$ssfs = $this->getBoolParam('specialsettingsforsubdomains', true, 0); $ssfs = $this->getBoolParam('specialsettingsforsubdomains', true, 0);
$notryfiles = $this->getBoolParam('notryfiles', true, $result['notryfiles']); $notryfiles = $this->getBoolParam('notryfiles', true, $result['notryfiles']);
$writeaccesslog = $this->getBoolParam('writeaccesslog', true, $result['writeaccesslog']); $writeaccesslog = $this->getBoolParam('writeaccesslog', true, $result['writeaccesslog']);
@@ -799,6 +882,24 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$hsts_preload = $this->getBoolParam('hsts_preload', true, $result['hsts_preload']); $hsts_preload = $this->getBoolParam('hsts_preload', true, $result['hsts_preload']);
$ocsp_stapling = $this->getBoolParam('ocsp_stapling', true, $result['ocsp_stapling']); $ocsp_stapling = $this->getBoolParam('ocsp_stapling', true, $result['ocsp_stapling']);
$override_tls = $this->getBoolParam('override_tls', true, $result['override_tls']);
if ($this->getUserDetail('change_serversettings') == '1') {
if ($override_tls) {
$p_ssl_protocols = $this->getParam('ssl_protocols', true, explode(',', $result['ssl_protocols']));
$ssl_cipher_list = $this->getParam('ssl_cipher_list', true, $result['ssl_cipher_list']);
$tlsv13_cipher_list = $this->getParam('tlsv13_cipher_list', true, $result['tlsv13_cipher_list']);
} else {
$p_ssl_protocols = array();
$ssl_cipher_list = "";
$tlsv13_cipher_list = "";
}
} else {
$p_ssl_protocols = explode(',', $result['ssl_protocols']);
$ssl_cipher_list = $result['ssl_cipher_list'];
$tlsv13_cipher_list = $result['tlsv13_cipher_list'];
}
// count subdomain usage of source-domain // count subdomain usage of source-domain
$subdomains_stmt = Database::prepare(" $subdomains_stmt = Database::prepare("
SELECT COUNT(`id`) AS count FROM `" . TABLE_PANEL_DOMAINS . "` WHERE SELECT COUNT(`id`) AS count FROM `" . TABLE_PANEL_DOMAINS . "` WHERE
@@ -905,7 +1006,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
'0', '0',
'' ''
), true); ), true);
if ($registration_date == '0000-00-00') { if ($registration_date == '0000-00-00' || empty($registration_date)) {
$registration_date = null; $registration_date = null;
} }
$termination_date = \Froxlor\Validate\Validate::validate($termination_date, 'termination_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array( $termination_date = \Froxlor\Validate\Validate::validate($termination_date, 'termination_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array(
@@ -913,7 +1014,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
'0', '0',
'' ''
), true); ), true);
if ($termination_date == '0000-00-00') { if ($termination_date == '0000-00-00' || empty($termination_date)) {
$termination_date = null; $termination_date = null;
} }
@@ -968,16 +1069,48 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
if (! preg_match('/^https?\:\/\//', $documentroot) && strstr($documentroot, ":") !== false) { if (! preg_match('/^https?\:\/\//', $documentroot) && strstr($documentroot, ":") !== false) {
\Froxlor\UI\Response::standard_error('pathmaynotcontaincolon', '', true); \Froxlor\UI\Response::standard_error('pathmaynotcontaincolon', '', true);
} }
$ssl_protocols = array();
if (! empty($p_ssl_protocols) && is_numeric($p_ssl_protocols)) {
$p_ssl_protocols = array(
$p_ssl_protocols
);
}
if (! empty($p_ssl_protocols) && ! is_array($p_ssl_protocols)) {
$p_ssl_protocols = json_decode($p_ssl_protocols, true);
}
if (! empty($p_ssl_protocols) && is_array($p_ssl_protocols)) {
$protocols_available = array(
'TLSv1',
'TLSv1.1',
'TLSv1.2',
'TLSv1.3'
);
foreach ($p_ssl_protocols as $ssl_protocol) {
if (! in_array(trim($ssl_protocol), $protocols_available)) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_DEBUG, "[API] unknown SSL protocol '" . trim($ssl_protocol) . "'");
continue;
}
$ssl_protocols[] = $ssl_protocol;
}
}
if (empty($ssl_protocols)) {
$override_tls = '0';
}
} else { } else {
$isbinddomain = $result['isbinddomain']; $isbinddomain = $result['isbinddomain'];
$zonefile = $result['zonefile']; $zonefile = $result['zonefile'];
$dkim = $result['dkim']; $dkim = $result['dkim'];
$specialsettings = $result['specialsettings']; $specialsettings = $result['specialsettings'];
$ssl_specialsettings = $result['ssl_specialsettings'];
$include_specialsettings = $result['include_specialsettings'];
$ssfs = (empty($specialsettings) ? 0 : 1); $ssfs = (empty($specialsettings) ? 0 : 1);
$notryfiles = $result['notryfiles']; $notryfiles = $result['notryfiles'];
$writeaccesslog = $result['writeaccesslog']; $writeaccesslog = $result['writeaccesslog'];
$writeerrorlog = $result['writeerrorlog']; $writeerrorlog = $result['writeerrorlog'];
$documentroot = $result['documentroot']; $documentroot = $result['documentroot'];
$override_tls = $result['override_tls'];
} }
if ($this->getUserDetail('caneditphpsettings') == '1' || $this->getUserDetail('change_serversettings') == '1') { if ($this->getUserDetail('caneditphpsettings') == '1' || $this->getUserDetail('change_serversettings') == '1') {
@@ -1028,6 +1161,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$ssl_ipandports = array(); $ssl_ipandports = array();
if (Settings::Get('system.use_ssl') == "1" && ! empty($p_ssl_ipandports)) { if (Settings::Get('system.use_ssl') == "1" && ! empty($p_ssl_ipandports)) {
$ssl_ipandports = $this->validateIpAddresses($p_ssl_ipandports, true, $result['id']); $ssl_ipandports = $this->validateIpAddresses($p_ssl_ipandports, true, $result['id']);
if ($this->getUserDetail('change_serversettings') == '1') {
$ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $ssl_specialsettings), 'ssl_specialsettings', '/^[^\0]*$/', '', array(), true);
}
} }
if (Settings::Get('system.use_ssl') == "0" || empty($ssl_ipandports)) { if (Settings::Get('system.use_ssl') == "0" || empty($ssl_ipandports)) {
$ssl_redirect = 0; $ssl_redirect = 0;
@@ -1044,17 +1181,16 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
// OCSP stapling // OCSP stapling
$ocsp_stapling = 0; $ocsp_stapling = 0;
// vhost container settings
$ssl_specialsettings = '';
$include_specialsettings = 0;
} }
// We can't enable let's encrypt for wildcard domains when using acme-v1 // We can't enable let's encrypt for wildcard-domains
if ($serveraliasoption == '0' && $letsencrypt == '1' && Settings::Get('system.leapiversion') == '1') { if ($serveraliasoption == '0' && $letsencrypt == '1') {
\Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt', '', true); \Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt', '', true);
} }
// if using acme-v2 we cannot issue wildcard-certificates
// because they currently only support the dns-01 challenge
if ($serveraliasoption == '0' && $letsencrypt == '1' && Settings::Get('system.leapiversion') == '2') {
\Froxlor\UI\Response::standard_error('nowildcardwithletsencryptv2', '', true);
}
// Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated // Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated
if ($ssl_redirect > 0 && $letsencrypt == 1 && $result['letsencrypt'] != $letsencrypt) { if ($ssl_redirect > 0 && $letsencrypt == 1 && $result['letsencrypt'] != $letsencrypt) {
@@ -1252,12 +1388,16 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
if ($ssfs == 1) { if ($ssfs == 1) {
$_update_data['specialsettings'] = $specialsettings; $_update_data['specialsettings'] = $specialsettings;
$upd_specialsettings = ", `specialsettings` = :specialsettings "; $_update_data['ssl_specialsettings'] = $ssl_specialsettings;
$_update_data['include_specialsettings'] = $include_specialsettings;
$upd_specialsettings = ", `specialsettings` = :specialsettings, `ssl_specialsettings` = :ssl_specialsettings, `include_specialsettings` = :include_specialsettings ";
} else { } else {
$upd_specialsettings = ''; $upd_specialsettings = '';
unset($_update_data['specialsettings']); unset($_update_data['specialsettings']);
unset($_update_data['ssl_specialsettings']);
unset($_update_data['include_specialsettings']);
$upd_stmt = Database::prepare(" $upd_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `specialsettings`='' WHERE `parentdomainid` = :id UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `specialsettings`='', `ssl_specialsettings`='', `include_specialsettings`='0' WHERE `parentdomainid` = :id
"); ");
Database::pexecute($upd_stmt, array( Database::pexecute($upd_stmt, array(
'id' => $id 'id' => $id
@@ -1290,6 +1430,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$update_data['mod_fcgid_starter'] = $mod_fcgid_starter; $update_data['mod_fcgid_starter'] = $mod_fcgid_starter;
$update_data['mod_fcgid_maxrequests'] = $mod_fcgid_maxrequests; $update_data['mod_fcgid_maxrequests'] = $mod_fcgid_maxrequests;
$update_data['specialsettings'] = $specialsettings; $update_data['specialsettings'] = $specialsettings;
$update_data['ssl_specialsettings'] = $ssl_specialsettings;
$update_data['include_specialsettings'] = $include_specialsettings;
$update_data['notryfiles'] = $notryfiles; $update_data['notryfiles'] = $notryfiles;
$update_data['writeaccesslog'] = $writeaccesslog; $update_data['writeaccesslog'] = $writeaccesslog;
$update_data['writeerrorlog'] = $writeerrorlog; $update_data['writeerrorlog'] = $writeerrorlog;
@@ -1302,6 +1444,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$update_data['hsts_sub'] = $hsts_sub; $update_data['hsts_sub'] = $hsts_sub;
$update_data['hsts_preload'] = $hsts_preload; $update_data['hsts_preload'] = $hsts_preload;
$update_data['ocsp_stapling'] = $ocsp_stapling; $update_data['ocsp_stapling'] = $ocsp_stapling;
$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['id'] = $id; $update_data['id'] = $id;
$update_stmt = Database::prepare(" $update_stmt = Database::prepare("
@@ -1327,6 +1473,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`mod_fcgid_starter` = :mod_fcgid_starter, `mod_fcgid_starter` = :mod_fcgid_starter,
`mod_fcgid_maxrequests` = :mod_fcgid_maxrequests, `mod_fcgid_maxrequests` = :mod_fcgid_maxrequests,
`specialsettings` = :specialsettings, `specialsettings` = :specialsettings,
`ssl_specialsettings` = :ssl_specialsettings,
`include_specialsettings` = :include_specialsettings,
`notryfiles` = :notryfiles, `notryfiles` = :notryfiles,
`writeaccesslog` = :writeaccesslog, `writeaccesslog` = :writeaccesslog,
`writeerrorlog` = :writeerrorlog, `writeerrorlog` = :writeerrorlog,
@@ -1338,7 +1486,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`hsts` = :hsts, `hsts` = :hsts,
`hsts_sub` = :hsts_sub, `hsts_sub` = :hsts_sub,
`hsts_preload` = :hsts_preload, `hsts_preload` = :hsts_preload,
`ocsp_stapling` = :ocsp_stapling `ocsp_stapling` = :ocsp_stapling,
`override_tls` = :override_tls,
`ssl_protocols` = :ssl_protocols,
`ssl_cipher_list` = :ssl_cipher_list,
`tlsv13_cipher_list` = :tlsv13_cipher_list
WHERE `id` = :id WHERE `id` = :id
"); ");
Database::pexecute($update_stmt, $update_data, true, true); Database::pexecute($update_stmt, $update_data, true, true);
@@ -1349,6 +1501,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$_update_data['openbasedir'] = $openbasedir; $_update_data['openbasedir'] = $openbasedir;
$_update_data['mod_fcgid_starter'] = $mod_fcgid_starter; $_update_data['mod_fcgid_starter'] = $mod_fcgid_starter;
$_update_data['mod_fcgid_maxrequests'] = $mod_fcgid_maxrequests; $_update_data['mod_fcgid_maxrequests'] = $mod_fcgid_maxrequests;
$_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['parentdomainid'] = $id; $_update_data['parentdomainid'] = $id;
// if php config is to be set for all subdomains, check here // if php config is to be set for all subdomains, check here
@@ -1373,7 +1529,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`phpenabled` = :phpenabled, `phpenabled` = :phpenabled,
`openbasedir` = :openbasedir, `openbasedir` = :openbasedir,
`mod_fcgid_starter` = :mod_fcgid_starter, `mod_fcgid_starter` = :mod_fcgid_starter,
`mod_fcgid_maxrequests` = :mod_fcgid_maxrequests `mod_fcgid_maxrequests` = :mod_fcgid_maxrequests,
`override_tls` = :override_tls,
`ssl_protocols` = :ssl_protocols,
`ssl_cipher_list` = :ssl_cipher_list,
`tlsv13_cipher_list` = :tlsv13_cipher_list
" . $update_phpconfig . $upd_specialsettings . $updatechildren . $update_sslredirect . " " . $update_phpconfig . $upd_specialsettings . $updatechildren . $update_sslredirect . "
WHERE `parentdomainid` = :parentdomainid WHERE `parentdomainid` = :parentdomainid
"); ");
@@ -1447,14 +1607,15 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
} }
} }
} }
if ($result['aliasdomain'] != $aliasdomain) { if ($result['aliasdomain'] != $aliasdomain && is_numeric($result['aliasdomain'])) {
// trigger when domain id for alias destination has changed: both for old and new destination // trigger when domain id for alias destination has changed: both for old and new destination
\Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($result['aliasdomain'], $this->logger()); \Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($result['aliasdomain'], $this->logger());
\Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $this->logger()); \Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $this->logger());
} elseif ($result['wwwserveralias'] != $wwwserveralias || $result['letsencrypt'] != $letsencrypt) { }
if ($result['wwwserveralias'] != $wwwserveralias || $result['letsencrypt'] != $letsencrypt) {
// or when wwwserveralias or letsencrypt was changed // or when wwwserveralias or letsencrypt was changed
\Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $this->logger()); \Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $this->logger());
if ($aliasdomain === 0) { if ((int) $aliasdomain === 0) {
// in case the wwwserveralias is set on a main domain, $aliasdomain is 0 // in case the wwwserveralias is set on a main domain, $aliasdomain is 0
// --> the call just above to triggerLetsEncryptCSRForAliasDestinationDomain // --> the call just above to triggerLetsEncryptCSRForAliasDestinationDomain
// is a noop...let's repeat it with the domain id of the main domain // is a noop...let's repeat it with the domain id of the main domain
@@ -1462,7 +1623,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
} }
} }
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] updated domain '" . $result['domain'] . "'"); $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, "successfull", $update_data);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
@@ -1482,7 +1644,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function delete() public function delete()
{ {
@@ -1616,6 +1778,9 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
// remove domains DNS from powerDNS if used, #581 // remove domains DNS from powerDNS if used, #581
\Froxlor\System\Cronjob::inserttask('11', $result['domain']); \Froxlor\System\Cronjob::inserttask('11', $result['domain']);
// remove domain from acme.sh / lets encrypt if used
\Froxlor\System\Cronjob::inserttask('12', $result['domain']);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] deleted domain/subdomains (#" . $result['id'] . ")"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] deleted domain/subdomains (#" . $result['id'] . ")");
\Froxlor\User::updateCounters(); \Froxlor\User::updateCounters();
\Froxlor\System\Cronjob::inserttask('1'); \Froxlor\System\Cronjob::inserttask('1');
@@ -1629,11 +1794,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
/** /**
* validate given ips * validate given ips
* *
* @param int|string|array $p_ipsandports * @param int|string|array $p_ipandports
* @param boolean $edit
* default false
* @param boolean $ssl * @param boolean $ssl
* default false * default false
* @param int $edit_id
* default 0
* *
* @throws \Exception * @throws \Exception
* @return array * @return array

View File

@@ -44,7 +44,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -81,9 +81,9 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
)); ));
$id = $result['id']; $id = $result['id'];
$email_full = $result['email_full'];
$idna_convert = new \Froxlor\Idna\IdnaWrapper(); $idna_convert = new \Froxlor\Idna\IdnaWrapper();
$username = $idna_convert->decode($email_full); $email_full = $result['email_full'];
$username = $email_full;
$password = \Froxlor\Validate\Validate::validate($email_password, 'password', '', '', array(), true); $password = \Froxlor\Validate\Validate::validate($email_password, 'password', '', '', array(), true);
$password = \Froxlor\System\Crypt::validatePassword($password, true); $password = \Froxlor\System\Crypt::validatePassword($password, true);
@@ -300,7 +300,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function update() public function update()
{ {
@@ -412,7 +412,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function delete() public function delete()
{ {

View File

@@ -38,7 +38,7 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
* *
* @access admin,customer * @access admin,customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -150,7 +150,7 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
* *
* @access admin,customer * @access admin,customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function delete() public function delete()
{ {

View File

@@ -38,7 +38,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -152,7 +152,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function get() public function get()
{ {
@@ -195,7 +195,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function update() public function update()
{ {
@@ -268,7 +268,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {
@@ -308,7 +308,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function delete() public function delete()
{ {
@@ -340,26 +340,12 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
} }
// check whether this address is an account // check whether this address is an account
if ($result['popaccountid'] != 0) { if ($result['popaccountid'] != 0) {
// Free the Quota used by the email account // use EmailAccounts.delete
if (Settings::Get('system.mail_quota_enabled') == 1) { $this->apiCall('EmailAccounts.delete', array(
$stmt = Database::prepare("SELECT `quota` FROM `" . TABLE_MAIL_USERS . "` WHERE `customerid`= :customerid AND `id`= :id"); 'id' => $result['id'],
$res_quota = Database::pexecute_first($stmt, array( 'customerid' => $customer['customerid'],
"customerid" => $customer['customerid'], 'delete_userfiles' => $delete_userfiles
"id" => $result['popaccountid'] ));
), true, true);
Customers::decreaseUsage($customer['customerid'], 'email_quota_used', '', $res_quota['quota']);
Admins::decreaseUsage($customer['customerid'], 'email_quota_used', '', $res_quota['quota']);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted quota entries for email address '" . $result['email_full'] . "'");
}
// delete account
$stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_USERS . "` WHERE `customerid`= :customerid AND `id`= :id");
Database::pexecute($stmt, array(
"customerid" => $customer['customerid'],
"id" => $result['popaccountid']
), true, true);
Customers::decreaseUsage($customer['customerid'], 'email_accounts_used');
Admins::decreaseUsage($customer['customerid'], 'email_accounts_used');
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted email account '" . $result['email_full'] . "'");
$number_forwarders --; $number_forwarders --;
} }

View File

@@ -26,7 +26,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {
@@ -80,7 +80,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function get() public function get()
{ {
@@ -126,7 +126,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -237,7 +237,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function update() public function update()
{ {
@@ -332,7 +332,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function delete() public function delete()
{ {

View File

@@ -27,7 +27,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return string * @return string json-encoded array
*/ */
public function checkUpdate() public function checkUpdate()
{ {
@@ -39,7 +39,11 @@ class Froxlor extends \Froxlor\Api\ApiCommand
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] checking for updates"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] checking for updates");
// check for new version // check for new version
$latestversion = \Froxlor\Http\HttpClient::urlGet(UPDATE_URI); 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 = explode('|', $latestversion); $latestversion = explode('|', $latestversion);
if (is_array($latestversion) && count($latestversion) >= 1) { if (is_array($latestversion) && count($latestversion) >= 1) {
@@ -110,7 +114,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return bool * @return string json-encoded bool
*/ */
public function importSettings() public function importSettings()
{ {
@@ -155,7 +159,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listSettings() public function listSettings()
{ {
@@ -236,7 +240,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function listFunctions() public function listFunctions()
{ {

View File

@@ -41,10 +41,14 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
* optional if customer.ftpatdomain is allowed, specify a domain (customer must be owner) * optional if customer.ftpatdomain is allowed, specify a domain (customer must be owner)
* @param int $customerid * @param int $customerid
* required when called as admin, not needed when called as customer * required when called as admin, not needed when called as customer
* @param array $additional_members
* optional whether to add additional usernames to the group
* @param bool $is_defaultuser
* optional whether this is the standard default ftp user which is being added so no usage is decreased
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -66,6 +70,9 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
$ftpusername = $this->getParam('ftp_username', true, ''); $ftpusername = $this->getParam('ftp_username', true, '');
$ftpdomain = $this->getParam('ftp_domain', true, ''); $ftpdomain = $this->getParam('ftp_domain', true, '');
$additional_members = $this->getParam('additional_members', true, array());
$is_defaultuser = $this->getBoolParam('is_defaultuser', true, 0);
// validation // validation
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true); $password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
$password = \Froxlor\System\Crypt::validatePassword($password, true); $password = \Froxlor\System\Crypt::validatePassword($password, true);
@@ -87,13 +94,18 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
$params = array(); $params = array();
// get needed customer info to reduce the ftp-user-counter by one // get needed customer info to reduce the ftp-user-counter by one
if ($is_defaultuser) {
// no resource check for default user
$customer = $this->getCustomerData();
} else {
$customer = $this->getCustomerData('ftps'); $customer = $this->getCustomerData('ftps');
}
if ($sendinfomail != 1) { if ($sendinfomail != 1) {
$sendinfomail = 0; $sendinfomail = 0;
} }
if (Settings::Get('customer.ftpatdomain') == '1') { if (Settings::Get('customer.ftpatdomain') == '1' && !$is_defaultuser) {
if ($ftpusername == '') { if ($ftpusername == '') {
\Froxlor\UI\Response::standard_error(array( \Froxlor\UI\Response::standard_error(array(
'stringisempty', 'stringisempty',
@@ -112,9 +124,13 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
\Froxlor\UI\Response::standard_error('maindomainnonexist', $ftpdomain, true); \Froxlor\UI\Response::standard_error('maindomainnonexist', $ftpdomain, true);
} }
$username = $ftpusername . "@" . $ftpdomain; $username = $ftpusername . "@" . $ftpdomain;
} else {
if ($is_defaultuser) {
$username = $customer['loginname'];
} else { } else {
$username = $customer['loginname'] . Settings::Get('customer.ftpprefix') . (intval($customer['ftp_lastaccountnumber']) + 1); $username = $customer['loginname'] . Settings::Get('customer.ftpprefix') . (intval($customer['ftp_lastaccountnumber']) + 1);
} }
}
$username_check_stmt = Database::prepare(" $username_check_stmt = Database::prepare("
SELECT * FROM `" . TABLE_FTP_USERS . "` WHERE `username` = :username SELECT * FROM `" . TABLE_FTP_USERS . "` WHERE `username` = :username
@@ -163,7 +179,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
), true, true); ), true, true);
} }
$stmt = Database::prepare(" $group_upd_stmt = Database::prepare("
UPDATE `" . TABLE_FTP_GROUPS . "` UPDATE `" . TABLE_FTP_GROUPS . "`
SET `members` = CONCAT_WS(',',`members`, :username) SET `members` = CONCAT_WS(',',`members`, :username)
WHERE `customerid`= :customerid AND `gid`= :guid WHERE `customerid`= :customerid AND `gid`= :guid
@@ -173,12 +189,35 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
"customerid" => $customer['customerid'], "customerid" => $customer['customerid'],
"guid" => $customer['guid'] "guid" => $customer['guid']
); );
Database::pexecute($stmt, $params, true, true);
if ($is_defaultuser) {
// add the new group
$group_ins_stmt = Database::prepare("
INSERT INTO `" . TABLE_FTP_GROUPS . "`
SET `customerid`= :customerid, `gid`= :guid, `groupname` = :username, `members` = :username
");
Database::pexecute($group_ins_stmt, $params, true, true);
} else {
// just update
Database::pexecute($group_upd_stmt, $params, true, true);
}
if (count($additional_members) > 0) {
foreach ($additional_members as $add_member) {
$params = array(
"username" => $add_member,
"customerid" => $customer['customerid'],
"guid" => $customer['guid']
);
Database::pexecute($group_upd_stmt, $params, true, true);
}
}
if (! $is_defaultuser) {
// update customer usage // update customer usage
Customers::increaseUsage($customer['customerid'], 'ftps_used'); Customers::increaseUsage($customer['customerid'], 'ftps_used');
Customers::increaseUsage($customer['customerid'], 'ftp_lastaccountnumber'); Customers::increaseUsage($customer['customerid'], 'ftp_lastaccountnumber');
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] added ftp-account '" . $username . " (" . $path . ")'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] added ftp-account '" . $username . " (" . $path . ")'");
\Froxlor\System\Cronjob::inserttask(5); \Froxlor\System\Cronjob::inserttask(5);
@@ -240,7 +279,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function get() public function get()
{ {
@@ -311,7 +350,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function update() public function update()
{ {
@@ -423,7 +462,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {
@@ -456,7 +495,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function delete() public function delete()
{ {

View File

@@ -1,6 +1,9 @@
<?php <?php
namespace Froxlor\Api\Commands; namespace Froxlor\Api\Commands;
use Froxlor\Settings;
use Froxlor\Database\Database;
/** /**
* This file is part of the Froxlor project. * This file is part of the Froxlor project.
* Copyright (c) 2010 the Froxlor Team (see authors). * Copyright (c) 2010 the Froxlor Team (see authors).
@@ -19,28 +22,380 @@ namespace Froxlor\Api\Commands;
class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntity class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntity
{ {
public function add() /**
{ * list all available hosting plans
throw new \Exception('noop', 303); *
} * @access admin
* @throws \Exception
public function get() * @return string json-encoded array count|list
{ */
throw new \Exception('noop', 303);
}
public function update()
{
throw new \Exception('noop', 303);
}
public function listing() public function listing()
{ {
throw new \Exception('noop', 303); if ($this->isAdmin()) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list hosting-plans");
$result_stmt = Database::prepare("
SELECT p.*, a.loginname as adminname
FROM `" . TABLE_PANEL_PLANS . "` p, `" . TABLE_PANEL_ADMINS . "` a
WHERE `p`.`adminid` = `a`.`adminid`" . ($this->getUserDetail('customers_see_all') ? '' : " AND `p`.`adminid` = :adminid "));
$params = array();
if ($this->getUserDetail('customers_see_all') == '0') {
$params['adminid'] = $this->getUserDetail('adminid');
}
Database::pexecute($result_stmt, $params);
$result = array();
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successfull", array(
'count' => count($result),
'list' => $result
));
}
throw new \Exception("Not allowed to execute given command.", 403);
} }
/**
* return a hosting-plan entry by either id or plan-name
*
* @param int $id
* optional, the hosting-plan-id
* @param string $planname
* optional, the hosting-plan-name
*
* @access admin
* @throws \Exception
* @return string json-encoded array
*/
public function get()
{
if ($this->isAdmin()) {
$id = $this->getParam('id', true, 0);
$dn_optional = ($id <= 0 ? false : true);
$planname = $this->getParam('planname', $dn_optional, '');
$result_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_PLANS . "` WHERE " . ($id > 0 ? "`id` = :iddn" : "`name` = :iddn") . ($this->getUserDetail('customers_see_all') ? '' : " AND `adminid` = :adminid"));
$params = array(
'iddn' => ($id <= 0 ? $planname : $id)
);
if ($this->getUserDetail('customers_see_all') == '0') {
$params['adminid'] = $this->getUserDetail('adminid');
}
$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);
}
$key = ($id > 0 ? "id #" . $id : "planname '" . $planname . "'");
throw new \Exception("Hosting-plan with " . $key . " could not be found", 404);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
/**
* add new hosting-plan
*
* @param string $name
* name of the plan
* @param string $description
* optional, description for hosting-plan
* @param int $diskspace
* optional disk-space available for customer in MB, default 0
* @param bool $diskspace_ul
* optional, whether customer should have unlimited diskspace, default 0 (false)
* @param int $traffic
* optional traffic available for customer in GB, default 0
* @param bool $traffic_ul
* optional, whether customer should have unlimited traffic, default 0 (false)
* @param int $subdomains
* optional amount of subdomains available for customer, default 0
* @param bool $subdomains_ul
* optional, whether customer should have unlimited subdomains, default 0 (false)
* @param int $emails
* optional amount of emails available for customer, default 0
* @param bool $emails_ul
* optional, whether customer should have unlimited emails, default 0 (false)
* @param int $email_accounts
* optional amount of email-accounts available for customer, default 0
* @param bool $email_accounts_ul
* optional, whether customer should have unlimited email-accounts, default 0 (false)
* @param int $email_forwarders
* optional amount of email-forwarders available for customer, default 0
* @param bool $email_forwarders_ul
* optional, whether customer should have unlimited email-forwarders, default 0 (false)
* @param int $email_quota
* optional size of email-quota available for customer in MB, default is system-setting mail_quota
* @param bool $email_quota_ul
* optional, whether customer should have unlimited email-quota, default 0 (false)
* @param bool $email_imap
* optional, whether to allow IMAP access, default 0 (false)
* @param bool $email_pop3
* optional, whether to allow POP3 access, default 0 (false)
* @param int $ftps
* optional amount of ftp-accounts available for customer, default 0
* @param bool $ftps_ul
* optional, whether customer should have unlimited ftp-accounts, default 0 (false)
* @param int $mysqls
* optional amount of mysql-databases available for customer, default 0
* @param bool $mysqls_ul
* optional, whether customer should have unlimited mysql-databases, default 0 (false)
* @param bool $phpenabled
* optional, whether to allow usage of PHP, default 0 (false)
* @param array $allowed_phpconfigs
* optional, array of IDs of php-config that the customer is allowed to use, default empty (none)
* @param bool $perlenabled
* optional, whether to allow usage of Perl/CGI, default 0 (false)
* @param bool $dnsenabled
* optional, ether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
* @param bool $logviewenabled
* optional, ether to allow acccess to webserver access/error-logs, default 0 (false)
*
* @access admin
* @throws \Exception
* @return string json-encoded array
*/
public function add()
{
if ($this->isAdmin()) {
$name = $this->getParam('name');
$description = $this->getParam('description', true, '');
$value_arr = array();
$value_arr['diskspace'] = $this->getUlParam('diskspace', 'diskspace_ul', true, 0);
$value_arr['traffic'] = $this->getUlParam('traffic', 'traffic_ul', true, 0);
$value_arr['subdomains'] = $this->getUlParam('subdomains', 'subdomains_ul', true, 0);
$value_arr['emails'] = $this->getUlParam('emails', 'emails_ul', true, 0);
$value_arr['email_accounts'] = $this->getUlParam('email_accounts', 'email_accounts_ul', true, 0);
$value_arr['email_forwarders'] = $this->getUlParam('email_forwarders', 'email_forwarders_ul', true, 0);
$value_arr['email_quota'] = $this->getUlParam('email_quota', 'email_quota_ul', true, Settings::Get('system.mail_quota'));
$value_arr['email_imap'] = $this->getBoolParam('email_imap', true, 0);
$value_arr['email_pop3'] = $this->getBoolParam('email_pop3', true, 0);
$value_arr['ftps'] = $this->getUlParam('ftps', 'ftps_ul', true, 0);
$value_arr['mysqls'] = $this->getUlParam('mysqls', 'mysqls_ul', true, 0);
$value_arr['phpenabled'] = $this->getBoolParam('phpenabled', true, 0);
$p_allowed_phpconfigs = $this->getParam('allowed_phpconfigs', true, array());
$value_arr['perlenabled'] = $this->getBoolParam('perlenabled', true, 0);
$value_arr['dnsenabled'] = $this->getBoolParam('dnsenabled', true, 0);
$value_arr['logviewenabled'] = $this->getBoolParam('logviewenabled', true, 0);
// validation
$name = \Froxlor\Validate\Validate::validate(trim($name), 'name', '', '', array(), true);
$description = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $description), 'description', '/^[^\0]*$/');
if (Settings::Get('system.mail_quota_enabled') != '1') {
$value_arr['email_quota'] = - 1;
}
$value_arr['allowed_phpconfigs'] = array();
if (! empty($p_allowed_phpconfigs) && is_array($p_allowed_phpconfigs)) {
foreach ($p_allowed_phpconfigs as $allowed_phpconfig) {
$allowed_phpconfig = intval($allowed_phpconfig);
$value_arr['allowed_phpconfigs'][] = $allowed_phpconfig;
}
}
$value_arr['allowed_phpconfigs'] = array_map('intval', $value_arr['allowed_phpconfigs']);
$ins_stmt = Database::prepare("
INSERT INTO `" . TABLE_PANEL_PLANS . "`
SET `adminid` = :adminid, `name` = :name, `description` = :desc, `value` = :valuearr, `ts` = UNIX_TIMESTAMP();
");
$ins_data = array(
'adminid' => $this->getUserDetail('adminid'),
'name' => $name,
'desc' => $description,
'valuearr' => json_encode($value_arr)
);
Database::pexecute($ins_stmt, $ins_data, true, true);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] added hosting-plan '" . $name . "'");
$result = $this->apiCall('HostingPlans.get', array(
'planname' => $name
));
return $this->response(200, "successfull", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
/**
* update hosting-plan by either id or plan-name
*
* @param int $id
* optional the hosting-plan-id
* @param string $planname
* optional the hosting-plan-name
* @param string $name
* optional name of the plan
* @param string $description
* optional description for hosting-plan
* @param int $diskspace
* optional disk-space available for customer in MB, default 0
* @param bool $diskspace_ul
* optional, whether customer should have unlimited diskspace, default 0 (false)
* @param int $traffic
* optional traffic available for customer in GB, default 0
* @param bool $traffic_ul
* optional, whether customer should have unlimited traffic, default 0 (false)
* @param int $subdomains
* optional amount of subdomains available for customer, default 0
* @param bool $subdomains_ul
* optional, whether customer should have unlimited subdomains, default 0 (false)
* @param int $emails
* optional amount of emails available for customer, default 0
* @param bool $emails_ul
* optional, whether customer should have unlimited emails, default 0 (false)
* @param int $email_accounts
* optional amount of email-accounts available for customer, default 0
* @param bool $email_accounts_ul
* optional, whether customer should have unlimited email-accounts, default 0 (false)
* @param int $email_forwarders
* optional amount of email-forwarders available for customer, default 0
* @param bool $email_forwarders_ul
* optional, whether customer should have unlimited email-forwarders, default 0 (false)
* @param int $email_quota
* optional size of email-quota available for customer in MB, default is system-setting mail_quota
* @param bool $email_quota_ul
* optional, whether customer should have unlimited email-quota, default 0 (false)
* @param bool $email_imap
* optional, whether to allow IMAP access, default 0 (false)
* @param bool $email_pop3
* optional, whether to allow POP3 access, default 0 (false)
* @param int $ftps
* optional amount of ftp-accounts available for customer, default 0
* @param bool $ftps_ul
* optional, whether customer should have unlimited ftp-accounts, default 0 (false)
* @param int $mysqls
* optional amount of mysql-databases available for customer, default 0
* @param bool $mysqls_ul
* optional, whether customer should have unlimited mysql-databases, default 0 (false)
* @param bool $phpenabled
* optional, whether to allow usage of PHP, default 0 (false)
* @param array $allowed_phpconfigs
* optional, array of IDs of php-config that the customer is allowed to use, default empty (none)
* @param bool $perlenabled
* optional, whether to allow usage of Perl/CGI, default 0 (false)
* @param bool $dnsenabled
* optional, ether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
* @param bool $logviewenabled
* optional, ether to allow acccess to webserver access/error-logs, default 0 (false)
*
* @access admin
* @throws \Exception
* @return string json-encoded array
*/
public function update()
{
if ($this->isAdmin()) {
// parameters
$id = $this->getParam('id', true, 0);
$dn_optional = ($id <= 0 ? false : true);
$planname = $this->getParam('planname', $dn_optional, '');
// get requested hosting-plan
$result = $this->apiCall('HostingPlans.get', array(
'id' => $id,
'planname' => $planname
));
$id = $result['id'];
$result['value'] = json_decode($result['value'], true);
foreach ($result['value'] as $index => $value) {
$result[$index] = $value;
}
$name = $this->getParam('name', true, $result['name']);
$description = $this->getParam('description', true, $result['description']);
$value_arr = array();
$value_arr['diskspace'] = $this->getUlParam('diskspace', 'diskspace_ul', true, $result['diskspace']);
$value_arr['traffic'] = $this->getUlParam('traffic', 'traffic_ul', true, $result['traffic']);
$value_arr['subdomains'] = $this->getUlParam('subdomains', 'subdomains_ul', true, $result['subdomains']);
$value_arr['emails'] = $this->getUlParam('emails', 'emails_ul', true, $result['emails']);
$value_arr['email_accounts'] = $this->getUlParam('email_accounts', 'email_accounts_ul', true, $result['email_accounts']);
$value_arr['email_forwarders'] = $this->getUlParam('email_forwarders', 'email_forwarders_ul', true, $result['email_forwarders']);
$value_arr['email_quota'] = $this->getUlParam('email_quota', 'email_quota_ul', true, $result['email_quota']);
$value_arr['email_imap'] = $this->getParam('email_imap', true, $result['email_imap']);
$value_arr['email_pop3'] = $this->getParam('email_pop3', true, $result['email_pop3']);
$value_arr['ftps'] = $this->getUlParam('ftps', 'ftps_ul', true, $result['ftps']);
$value_arr['mysqls'] = $this->getUlParam('mysqls', 'mysqls_ul', true, $result['mysqls']);
$value_arr['phpenabled'] = $this->getBoolParam('phpenabled', true, $result['phpenabled']);
$p_allowed_phpconfigs = $this->getParam('allowed_phpconfigs', true, $result['allowed_phpconfigs']);
$value_arr['perlenabled'] = $this->getBoolParam('perlenabled', true, $result['perlenabled']);
$value_arr['dnsenabled'] = $this->getBoolParam('dnsenabled', true, $result['dnsenabled']);
$value_arr['logviewenabled'] = $this->getBoolParam('logviewenabled', true, $result['logviewenabled']);
// validation
$name = \Froxlor\Validate\Validate::validate(trim($name), 'name', '', '', array(), true);
$description = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $description), 'description', '/^[^\0]*$/');
if (Settings::Get('system.mail_quota_enabled') != '1') {
$value_arr['email_quota'] = - 1;
}
if (empty($name)) {
$name = $result['name'];
}
$value_arr['allowed_phpconfigs'] = array();
if (! empty($p_allowed_phpconfigs) && is_array($p_allowed_phpconfigs)) {
foreach ($p_allowed_phpconfigs as $allowed_phpconfig) {
$allowed_phpconfig = intval($allowed_phpconfig);
$value_arr['allowed_phpconfigs'][] = $allowed_phpconfig;
}
}
$value_arr['allowed_phpconfigs'] = array_map('intval', $value_arr['allowed_phpconfigs']);
$upd_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_PLANS . "`
SET `name` = :name, `description` = :desc, `value` = :valuearr, `ts` = UNIX_TIMESTAMP()
WHERE `id` = :id
");
$update_data = array(
'name' => $name,
'desc' => $description,
'valuearr' => json_encode($value_arr),
'id' => $id
);
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);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
/**
* delete hosting-plan by either id or plan-name
*
* @param int $id
* optional the hosting-plan-id
* @param string $planname
* optional the hosting-plan-name
*
* @access admin
* @throws \Exception
* @return string json-encoded array
*/
public function delete() public function delete()
{ {
throw new \Exception('noop', 303); if ($this->isAdmin()) {
$id = $this->getParam('id', true, 0);
$dn_optional = ($id <= 0 ? false : true);
$planname = $this->getParam('planname', $dn_optional, '');
// get requested hosting-plan
$result = $this->apiCall('HostingPlans.get', array(
'id' => $id,
'planname' => $planname
));
$id = $result['id'];
$del_stmt = Database::prepare("
DELETE FROM `" . TABLE_PANEL_PLANS . "` WHERE `id` = :id
");
Database::pexecute($del_stmt, array(
'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);
}
throw new \Exception("Not allowed to execute given command.", 403);
} }
} }

View File

@@ -27,7 +27,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {
@@ -61,7 +61,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function get() public function get()
{ {
@@ -118,10 +118,18 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
* optional, requires $ssl = 1, default empty * optional, requires $ssl = 1, default empty
* @param string $ssl_cert_chainfile * @param string $ssl_cert_chainfile
* optional, requires $ssl = 1, default empty * optional, requires $ssl = 1, default empty
* @param string $ssl_specialsettings
* optional, requires $ssl = 1, default empty
* @param bool $include_specialsettings
* optional, requires $ssl = 1, whether or not to include non-ssl specialsettings, default false
* @param string $ssl_default_vhostconf_domain
* optional, requires $ssl = 1, defatul empty
* @param bool $include_default_vhostconf_domain
* optional, requires $ssl = 1, whether or not to include non-ssl default_vhostconf_domain, default false
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -146,12 +154,20 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$ssl_key_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_key_file', $ssl, ''), 'ssl_key_file', '', '', array(), true); $ssl_key_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_key_file', $ssl, ''), 'ssl_key_file', '', '', array(), true);
$ssl_ca_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_ca_file', true, ''), 'ssl_ca_file', '', '', array(), true); $ssl_ca_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_ca_file', true, ''), 'ssl_ca_file', '', '', array(), true);
$ssl_cert_chainfile = \Froxlor\Validate\Validate::validate($this->getParam('ssl_cert_chainfile', true, ''), 'ssl_cert_chainfile', '', '', array(), true); $ssl_cert_chainfile = \Froxlor\Validate\Validate::validate($this->getParam('ssl_cert_chainfile', true, ''), 'ssl_cert_chainfile', '', '', array(), true);
$ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_specialsettings', true, '')), 'ssl_specialsettings', '/^[^\0]*$/', '', array(), true);
$include_specialsettings = ! empty($this->getBoolParam('include_specialsettings', true, 0)) ? 1 : 0;
$ssl_default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_default_vhostconf_domain', true, '')), 'ssl_default_vhostconf_domain', '/^[^\0]*$/', '', array(), true);
$include_default_vhostconf_domain = ! empty($this->getBoolParam('include_default_vhostconf_domain', true, 0)) ? 1 : 0;
} else { } else {
$ssl = 0; $ssl = 0;
$ssl_cert_file = ''; $ssl_cert_file = '';
$ssl_key_file = ''; $ssl_key_file = '';
$ssl_ca_file = ''; $ssl_ca_file = '';
$ssl_cert_chainfile = ''; $ssl_cert_chainfile = '';
$ssl_specialsettings = '';
$include_specialsettings = 0;
$ssl_default_vhostconf_domain = '';
$include_default_vhostconf_domain = 0;
} }
if ($listen_statement != '1') { if ($listen_statement != '1') {
@@ -217,7 +233,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
`specialsettings` = :ss, `ssl` = :ssl, `specialsettings` = :ss, `ssl` = :ssl,
`ssl_cert_file` = :ssl_cert, `ssl_key_file` = :ssl_key, `ssl_cert_file` = :ssl_cert, `ssl_key_file` = :ssl_key,
`ssl_ca_file` = :ssl_ca, `ssl_cert_chainfile` = :ssl_chain, `ssl_ca_file` = :ssl_ca, `ssl_cert_chainfile` = :ssl_chain,
`default_vhostconf_domain` = :dvhd, `docroot` = :docroot; `default_vhostconf_domain` = :dvhd, `docroot` = :docroot,
`ssl_specialsettings` = :ssl_ss, `include_specialsettings` = :incss,
`ssl_default_vhostconf_domain` = :ssl_dvhd, `include_default_vhostconf_domain` = :incdvhd;
"); ");
$ins_data = array( $ins_data = array(
'ip' => $ip, 'ip' => $ip,
@@ -233,7 +251,11 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'ssl_ca' => $ssl_ca_file, 'ssl_ca' => $ssl_ca_file,
'ssl_chain' => $ssl_cert_chainfile, 'ssl_chain' => $ssl_cert_chainfile,
'dvhd' => $default_vhostconf_domain, 'dvhd' => $default_vhostconf_domain,
'docroot' => $docroot 'docroot' => $docroot,
'ssl_ss' => $ssl_specialsettings,
'incss' => $include_specialsettings,
'ssl_dvhd' => $ssl_default_vhostconf_domain,
'incdvhd' => $include_default_vhostconf_domain
); );
Database::pexecute($ins_stmt, $ins_data); Database::pexecute($ins_stmt, $ins_data);
$ins_data['id'] = Database::lastInsertId(); $ins_data['id'] = Database::lastInsertId();
@@ -287,11 +309,19 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
* optional, requires $ssl = 1, default empty * optional, requires $ssl = 1, default empty
* @param string $ssl_cert_chainfile * @param string $ssl_cert_chainfile
* optional, requires $ssl = 1, default empty * optional, requires $ssl = 1, default empty
* @param string $ssl_specialsettings
* optional, requires $ssl = 1, default empty
* @param bool $include_specialsettings
* optional, requires $ssl = 1, whether or not to include non-ssl specialsettings, default false
* @param string $ssl_default_vhostconf_domain
* optional, requires $ssl = 1, defatul empty
* @param bool $include_default_vhostconf_domain
* optional, requires $ssl = 1, whether or not to include non-ssl default_vhostconf_domain, default false
* *
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function update() public function update()
{ {
@@ -321,12 +351,20 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$ssl_key_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_key_file', $ssl, $result['ssl_key_file']), 'ssl_key_file', '', '', array(), true); $ssl_key_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_key_file', $ssl, $result['ssl_key_file']), 'ssl_key_file', '', '', array(), true);
$ssl_ca_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_ca_file', true, $result['ssl_ca_file']), 'ssl_ca_file', '', '', array(), true); $ssl_ca_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_ca_file', true, $result['ssl_ca_file']), 'ssl_ca_file', '', '', array(), true);
$ssl_cert_chainfile = \Froxlor\Validate\Validate::validate($this->getParam('ssl_cert_chainfile', true, $result['ssl_cert_chainfile']), 'ssl_cert_chainfile', '', '', array(), true); $ssl_cert_chainfile = \Froxlor\Validate\Validate::validate($this->getParam('ssl_cert_chainfile', true, $result['ssl_cert_chainfile']), 'ssl_cert_chainfile', '', '', array(), true);
$ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_specialsettings', true, $result['ssl_specialsettings'])), 'ssl_specialsettings', '/^[^\0]*$/', '', array(), true);
$include_specialsettings = $this->getBoolParam('include_specialsettings', true, $result['include_specialsettings']);
$ssl_default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_default_vhostconf_domain', true, $result['ssl_default_vhostconf_domain'])), 'ssl_default_vhostconf_domain', '/^[^\0]*$/', '', array(), true);
$include_default_vhostconf_domain = $this->getBoolParam('include_default_vhostconf_domain', true, $result['include_default_vhostconf_domain']);
} else { } else {
$ssl = 0; $ssl = 0;
$ssl_cert_file = ''; $ssl_cert_file = '';
$ssl_key_file = ''; $ssl_key_file = '';
$ssl_ca_file = ''; $ssl_ca_file = '';
$ssl_cert_chainfile = ''; $ssl_cert_chainfile = '';
$ssl_specialsettings = '';
$include_specialsettings = 0;
$ssl_default_vhostconf_domain = '';
$include_default_vhostconf_domain = 0;
} }
$result_checkfordouble_stmt = Database::prepare(" $result_checkfordouble_stmt = Database::prepare("
@@ -404,7 +442,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
`specialsettings` = :ss, `ssl` = :ssl, `specialsettings` = :ss, `ssl` = :ssl,
`ssl_cert_file` = :ssl_cert, `ssl_key_file` = :ssl_key, `ssl_cert_file` = :ssl_cert, `ssl_key_file` = :ssl_key,
`ssl_ca_file` = :ssl_ca, `ssl_cert_chainfile` = :ssl_chain, `ssl_ca_file` = :ssl_ca, `ssl_cert_chainfile` = :ssl_chain,
`default_vhostconf_domain` = :dvhd, `docroot` = :docroot `default_vhostconf_domain` = :dvhd, `docroot` = :docroot,
`ssl_specialsettings` = :ssl_ss, `include_specialsettings` = :incss,
`ssl_default_vhostconf_domain` = :ssl_dvhd, `include_default_vhostconf_domain` = :incdvhd
WHERE `id` = :id; WHERE `id` = :id;
"); ");
$upd_data = array( $upd_data = array(
@@ -422,6 +462,10 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'ssl_chain' => $ssl_cert_chainfile, 'ssl_chain' => $ssl_cert_chainfile,
'dvhd' => $default_vhostconf_domain, 'dvhd' => $default_vhostconf_domain,
'docroot' => $docroot, 'docroot' => $docroot,
'ssl_ss' => $ssl_specialsettings,
'incss' => $include_specialsettings,
'ssl_dvhd' => $ssl_default_vhostconf_domain,
'incdvhd' => $include_default_vhostconf_domain,
'id' => $id 'id' => $id
); );
Database::pexecute($upd_stmt, $upd_data); Database::pexecute($upd_stmt, $upd_data);
@@ -449,7 +493,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function delete() public function delete()
{ {

View File

@@ -33,12 +33,12 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* optional, description for database * optional, description for database
* @param bool $sendinfomail * @param bool $sendinfomail
* optional, send created resource-information to customer, default: false * optional, send created resource-information to customer, default: false
* @param int $customer_id * @param int $customerid
* required when called as admin, not needed when called as customer * required when called as admin, not needed when called as customer
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -183,7 +183,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function get() public function get()
{ {
@@ -279,7 +279,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function update() public function update()
{ {
@@ -362,7 +362,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {
@@ -428,7 +428,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function delete() public function delete()
{ {

View File

@@ -30,7 +30,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {
@@ -123,7 +123,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function get() public function get()
{ {
@@ -192,7 +192,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -393,7 +393,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function update() public function update()
{ {
@@ -548,7 +548,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function delete() public function delete()
{ {

View File

@@ -45,6 +45,8 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* optional, whether to generate a https-redirect or not, default false; requires SSL to be enabled * optional, whether to generate a https-redirect or not, default false; requires SSL to be enabled
* @param bool $letsencrypt * @param bool $letsencrypt
* optional, whether to generate a Let's Encrypt certificate for this domain, default false; requires SSL to be enabled * optional, whether to generate a Let's Encrypt certificate for this domain, default false; requires SSL to be enabled
* @param bool $http2
* optional, whether to enable http/2 for this subdomain (requires to be enabled in the settings), default 0 (false)
* @param int $hsts_maxage * @param int $hsts_maxage
* optional max-age value for HSTS header, default 0 * optional max-age value for HSTS header, default 0
* @param bool $hsts_sub * @param bool $hsts_sub
@@ -56,7 +58,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function add() public function add()
{ {
@@ -76,12 +78,14 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
if (Settings::Get('system.use_ssl')) { if (Settings::Get('system.use_ssl')) {
$ssl_redirect = $this->getBoolParam('ssl_redirect', true, 0); $ssl_redirect = $this->getBoolParam('ssl_redirect', true, 0);
$letsencrypt = $this->getBoolParam('letsencrypt', true, 0); $letsencrypt = $this->getBoolParam('letsencrypt', true, 0);
$http2 = $this->getBoolParam('http2', true, 0);
$hsts_maxage = $this->getParam('hsts_maxage', true, 0); $hsts_maxage = $this->getParam('hsts_maxage', true, 0);
$hsts_sub = $this->getBoolParam('hsts_sub', true, 0); $hsts_sub = $this->getBoolParam('hsts_sub', true, 0);
$hsts_preload = $this->getBoolParam('hsts_preload', true, 0); $hsts_preload = $this->getBoolParam('hsts_preload', true, 0);
} else { } else {
$ssl_redirect = 0; $ssl_redirect = 0;
$letsencrypt = 0; $letsencrypt = 0;
$http2 = 0;
$hsts_maxage = 0; $hsts_maxage = 0;
$hsts_sub = 0; $hsts_sub = 0;
$hsts_preload = 0; $hsts_preload = 0;
@@ -241,7 +245,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$phpsid_result['phpsettingid'] = intval($phpsettingid); $phpsid_result['phpsettingid'] = intval($phpsettingid);
} }
// acutall insert domain // actually insert domain
$stmt = Database::prepare(" $stmt = Database::prepare("
INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET
`customerid` = :customerid, `customerid` = :customerid,
@@ -258,12 +262,20 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
`openbasedir_path` = :openbasedir_path, `openbasedir_path` = :openbasedir_path,
`speciallogfile` = :speciallogfile, `speciallogfile` = :speciallogfile,
`specialsettings` = :specialsettings, `specialsettings` = :specialsettings,
`ssl_specialsettings` = :ssl_specialsettings,
`include_specialsettings` = :include_specialsettings,
`ssl_redirect` = :ssl_redirect, `ssl_redirect` = :ssl_redirect,
`phpsettingid` = :phpsettingid, `phpsettingid` = :phpsettingid,
`letsencrypt` = :letsencrypt, `letsencrypt` = :letsencrypt,
`http2` = :http2,
`hsts` = :hsts, `hsts` = :hsts,
`hsts_sub` = :hsts_sub, `hsts_sub` = :hsts_sub,
`hsts_preload` = :hsts_preload `hsts_preload` = :hsts_preload,
`ocsp_stapling` = :ocsp_stapling,
`override_tls` = :override_tls,
`ssl_protocols` = :ssl_protocols,
`ssl_cipher_list` = :ssl_cipher_list,
`tlsv13_cipher_list` = :tlsv13_cipher_list
"); ");
$params = array( $params = array(
"customerid" => $customer['customerid'], "customerid" => $customer['customerid'],
@@ -280,12 +292,20 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
"phpenabled" => $domain_check['phpenabled'], "phpenabled" => $domain_check['phpenabled'],
"speciallogfile" => $domain_check['speciallogfile'], "speciallogfile" => $domain_check['speciallogfile'],
"specialsettings" => $domain_check['specialsettings'], "specialsettings" => $domain_check['specialsettings'],
"ssl_specialsettings" => $domain_check['ssl_specialsettings'],
"include_specialsettings" => $domain_check['include_specialsettings'],
"ssl_redirect" => $ssl_redirect, "ssl_redirect" => $ssl_redirect,
"phpsettingid" => $phpsid_result['phpsettingid'], "phpsettingid" => $phpsid_result['phpsettingid'],
"letsencrypt" => $letsencrypt, "letsencrypt" => $letsencrypt,
"http2" => $http2,
"hsts" => $hsts_maxage, "hsts" => $hsts_maxage,
"hsts_sub" => $hsts_sub, "hsts_sub" => $hsts_sub,
"hsts_preload" => $hsts_preload "hsts_preload" => $hsts_preload,
"ocsp_stapling" => $domain_check['ocsp_stapling'],
"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']
); );
Database::pexecute($stmt, $params, true, true); Database::pexecute($stmt, $params, true, true);
$subdomain_id = Database::lastInsertId(); $subdomain_id = Database::lastInsertId();
@@ -331,7 +351,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function get() public function get()
{ {
@@ -430,6 +450,8 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* optional, whether to generate a https-redirect or not, default false; requires SSL to be enabled * optional, whether to generate a https-redirect or not, default false; requires SSL to be enabled
* @param bool $letsencrypt * @param bool $letsencrypt
* optional, whether to generate a Let's Encrypt certificate for this domain, default false; requires SSL to be enabled * optional, whether to generate a Let's Encrypt certificate for this domain, default false; requires SSL to be enabled
* @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 * @param int $hsts_maxage
* optional max-age value for HSTS header * optional max-age value for HSTS header
* @param bool $hsts_sub * @param bool $hsts_sub
@@ -441,7 +463,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function update() public function update()
{ {
@@ -473,12 +495,14 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
if (Settings::Get('system.use_ssl')) { if (Settings::Get('system.use_ssl')) {
$ssl_redirect = $this->getBoolParam('ssl_redirect', true, $result['ssl_redirect']); $ssl_redirect = $this->getBoolParam('ssl_redirect', true, $result['ssl_redirect']);
$letsencrypt = $this->getBoolParam('letsencrypt', true, $result['letsencrypt']); $letsencrypt = $this->getBoolParam('letsencrypt', true, $result['letsencrypt']);
$http2 = $this->getBoolParam('http2', true, $result['http2']);
$hsts_maxage = $this->getParam('hsts_maxage', true, $result['hsts']); $hsts_maxage = $this->getParam('hsts_maxage', true, $result['hsts']);
$hsts_sub = $this->getBoolParam('hsts_sub', true, $result['hsts_sub']); $hsts_sub = $this->getBoolParam('hsts_sub', true, $result['hsts_sub']);
$hsts_preload = $this->getBoolParam('hsts_preload', true, $result['hsts_preload']); $hsts_preload = $this->getBoolParam('hsts_preload', true, $result['hsts_preload']);
} else { } else {
$ssl_redirect = 0; $ssl_redirect = 0;
$letsencrypt = 0; $letsencrypt = 0;
$http2 = 0;
$hsts_maxage = 0; $hsts_maxage = 0;
$hsts_sub = 0; $hsts_sub = 0;
$hsts_preload = 0; $hsts_preload = 0;
@@ -554,15 +578,10 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
} }
} }
// We can't enable let's encrypt for wildcard - domains when using acme-v1 // We can't enable let's encrypt for wildcard-domains
if ($iswildcarddomain == '1' && $letsencrypt == '1' && Settings::Get('system.leapiversion') == '1') { if ($iswildcarddomain == '1' && $letsencrypt == '1') {
\Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt'); \Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt');
} }
// if using acme-v2 we cannot issue wildcard-certificates
// because they currently only support the dns-01 challenge
if ($iswildcarddomain == '0' && $letsencrypt == '1' && Settings::Get('system.leapiversion') == '2') {
\Froxlor\UI\Response::standard_error('nowildcardwithletsencryptv2');
}
// Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated // Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated
if ($ssl_redirect > 0 && $letsencrypt == 1 && $result['letsencrypt'] != $letsencrypt) { if ($ssl_redirect > 0 && $letsencrypt == 1 && $result['letsencrypt'] != $letsencrypt) {
@@ -599,6 +618,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
`openbasedir_path`= :openbasedir_path, `openbasedir_path`= :openbasedir_path,
`ssl_redirect`= :ssl_redirect, `ssl_redirect`= :ssl_redirect,
`letsencrypt`= :letsencrypt, `letsencrypt`= :letsencrypt,
`http2` = :http2,
`hsts` = :hsts, `hsts` = :hsts,
`hsts_sub` = :hsts_sub, `hsts_sub` = :hsts_sub,
`hsts_preload` = :hsts_preload, `hsts_preload` = :hsts_preload,
@@ -614,6 +634,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
"openbasedir_path" => $openbasedir_path, "openbasedir_path" => $openbasedir_path,
"ssl_redirect" => $ssl_redirect, "ssl_redirect" => $ssl_redirect,
"letsencrypt" => $letsencrypt, "letsencrypt" => $letsencrypt,
"http2" => $http2,
"hsts" => $hsts_maxage, "hsts" => $hsts_maxage,
"hsts_sub" => $hsts_sub, "hsts_sub" => $hsts_sub,
"hsts_preload" => $hsts_preload, "hsts_preload" => $hsts_preload,
@@ -623,13 +644,20 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
); );
Database::pexecute($stmt, $params, true, true); Database::pexecute($stmt, $params, true, true);
if ($result['aliasdomain'] != $aliasdomain) { if ($result['aliasdomain'] != $aliasdomain && is_numeric($result['aliasdomain'])) {
// trigger when domain id for alias destination has changed: both for old and new destination // trigger when domain id for alias destination has changed: both for old and new destination
\Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($result['aliasdomain'], $this->logger()); \Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($result['aliasdomain'], $this->logger());
\Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $this->logger()); \Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $this->logger());
} elseif ($result['wwwserveralias'] != $wwwserveralias || $result['letsencrypt'] != $letsencrypt) { }
if ($result['wwwserveralias'] != $wwwserveralias || $result['letsencrypt'] != $letsencrypt) {
// or when wwwserveralias or letsencrypt was changed // or when wwwserveralias or letsencrypt was changed
\Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $this->logger()); \Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $this->logger());
if ((int) $aliasdomain === 0) {
// in case the wwwserveralias is set on a main domain, $aliasdomain is 0
// --> the call just above to triggerLetsEncryptCSRForAliasDestinationDomain
// is a noop...let's repeat it with the domain id of the main domain
\Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($id, $this->logger());
}
} }
// check whether LE has been disabled, so we remove the certificate // check whether LE has been disabled, so we remove the certificate
@@ -658,7 +686,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {
@@ -735,7 +763,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array * @return string json-encoded array
*/ */
public function delete() public function delete()
{ {
@@ -828,6 +856,8 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
\Froxlor\System\Cronjob::inserttask('4'); \Froxlor\System\Cronjob::inserttask('4');
// remove domains DNS from powerDNS if used, #581 // remove domains DNS from powerDNS if used, #581
\Froxlor\System\Cronjob::inserttask('11', $result['domain']); \Froxlor\System\Cronjob::inserttask('11', $result['domain']);
// remove domain from acme.sh / lets encrypt if used
\Froxlor\System\Cronjob::inserttask('12', $result['domain']);
// reduce subdomain-usage-counter // reduce subdomain-usage-counter
Customers::decreaseUsage($customer['customerid'], 'subdomains_used'); Customers::decreaseUsage($customer['customerid'], 'subdomains_used');
@@ -852,7 +882,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
{ {
// check whether an URL was specified // check whether an URL was specified
$_doredirect = false; $_doredirect = false;
if (! empty($url) && \Froxlor\Validate\Form\Data::validateUrl($url)) { if (! empty($url) && \Froxlor\Validate\Validate::validateUrl($url)) {
$path = $url; $path = $url;
$_doredirect = true; $_doredirect = true;
} else { } else {
@@ -860,7 +890,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
} }
// check whether path is a real path // check whether path is a real path
if (! preg_match('/^https?\:\/\//', $path) || ! \Froxlor\Validate\Form\Data::validateUrl($path)) { if (! preg_match('/^https?\:\/\//', $path) || ! \Froxlor\Validate\Validate::validateUrl($path)) {
if (strstr($path, ":") !== false) { if (strstr($path, ":") !== false) {
\Froxlor\UI\Response::standard_error('pathmaynotcontaincolon', '', true); \Froxlor\UI\Response::standard_error('pathmaynotcontaincolon', '', true);
} }

View File

@@ -69,7 +69,7 @@ class Traffic extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
* @return array count|list * @return string json-encoded array count|list
*/ */
public function listing() public function listing()
{ {

View File

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

View File

@@ -103,7 +103,7 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
echo PHP_EOL; echo PHP_EOL;
while (! in_array($_daemons_config['distro'], $distributions_select_data)) { while (! in_array($_daemons_config['distro'], $distributions_select_data)) {
$_daemons_config['distro'] = ConfigServicesCmd::getInput("choose distribution", "stretch"); $_daemons_config['distro'] = ConfigServicesCmd::getInput("choose distribution", "buster");
} }
// go through all services and let user check whether to include it or not // go through all services and let user check whether to include it or not

0
lib/Froxlor/Cli/ConfigServicesCmd.php Executable file → Normal file
View File

0
lib/Froxlor/Cli/SwitchServerIpCmd.php Executable file → Normal file
View File

View File

@@ -61,6 +61,7 @@ class CronConfig
$month_delay = 7; $month_delay = 7;
while ($row_cronentry = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row_cronentry = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
// create cron.d-entry // create cron.d-entry
$matches = array();
if (preg_match("/(\d+) (MINUTE|HOUR|DAY|WEEK|MONTH)/", $row_cronentry['interval'], $matches)) { if (preg_match("/(\d+) (MINUTE|HOUR|DAY|WEEK|MONTH)/", $row_cronentry['interval'], $matches)) {
if ($matches[1] == 1) { if ($matches[1] == 1) {
$minvalue = "*"; $minvalue = "*";
@@ -101,7 +102,7 @@ class CronConfig
$binpath = "/usr/bin/nice -n 5 /usr/bin/php5 -q"; $binpath = "/usr/bin/nice -n 5 /usr/bin/php5 -q";
} }
$cronfile .= "root " . $binpath . " " . \Froxlor\Froxlor::getInstallDir() . "/scripts/froxlor_master_cronjob.php --" . $row_cronentry['cronfile'] . " 1> /dev/null\n"; $cronfile .= "root " . $binpath . " " . \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . "/scripts/froxlor_master_cronjob.php") . " --" . $row_cronentry['cronfile'] . " 1> /dev/null\n";
} }
} }

View File

@@ -111,7 +111,7 @@ class PowerDNS extends DnsBase
private function insertZone($domainname, $serial = 0) private function insertZone($domainname, $serial = 0)
{ {
$ins_stmt = PowerDNS::getDB()->prepare(" $ins_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("
INSERT INTO domains set `name` = :domainname, `notified_serial` = :serial, `type` = 'NATIVE' INSERT INTO domains set `name` = :domainname, `notified_serial` = :serial, `type` = 'NATIVE'
"); ");
$ins_stmt->execute(array( $ins_stmt->execute(array(
@@ -124,7 +124,7 @@ class PowerDNS extends DnsBase
private function insertRecords($domainid = 0, $records = array(), $origin = "") private function insertRecords($domainid = 0, $records = array(), $origin = "")
{ {
$ins_stmt = PowerDNS::getDB()->prepare(" $ins_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("
INSERT INTO records set INSERT INTO records set
`domain_id` = :did, `domain_id` = :did,
`name` = :rec, `name` = :rec,
@@ -161,7 +161,7 @@ class PowerDNS extends DnsBase
private function insertAllowedTransfers($domainid) private function insertAllowedTransfers($domainid)
{ {
$ins_stmt = PowerDNS::getDB()->prepare(" $ins_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("
INSERT INTO domainmetadata set `domain_id` = :did, `kind` = 'ALLOW-AXFR-FROM', `content` = :value INSERT INTO domainmetadata set `domain_id` = :did, `kind` = 'ALLOW-AXFR-FROM', `content` = :value
"); ");

View File

@@ -3,7 +3,6 @@ namespace Froxlor\Cron\Http;
use Froxlor\Database\Database; use Froxlor\Database\Database;
use Froxlor\Settings; use Froxlor\Settings;
use Froxlor\Cron\Http\Php\Fpm;
use Froxlor\Cron\Http\Php\PhpInterface; use Froxlor\Cron\Http\Php\PhpInterface;
/** /**
@@ -46,30 +45,6 @@ class Apache extends HttpConfigBase
*/ */
private $deactivated = false; private $deactivated = false;
public function reload()
{
if ((int) Settings::Get('phpfpm.enabled') == 1) {
// get all start/stop commands
$startstop_sel = Database::prepare("SELECT reload_cmd, config_dir FROM `" . TABLE_PANEL_FPMDAEMONS . "`");
Database::pexecute($startstop_sel);
$restart_cmds = $startstop_sel->fetchAll(\PDO::FETCH_ASSOC);
// restart all php-fpm instances
foreach ($restart_cmds as $restart_cmd) {
// check whether the config dir is empty (no domains uses this daemon)
// so we need to create a dummy
$_conffiles = glob(\Froxlor\FileDir::makeCorrectFile($restart_cmd['config_dir'] . "/*.conf"));
if ($_conffiles === false || empty($_conffiles)) {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'apache::reload: fpm config directory "' . $restart_cmd['config_dir'] . '" is empty. Creating dummy.');
Fpm::createDummyPool($restart_cmd['config_dir']);
}
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'apache::reload: running ' . $restart_cmd['reload_cmd']);
\Froxlor\FileDir::safe_exec(escapeshellcmd($restart_cmd['reload_cmd']));
}
}
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'apache::reload: reloading apache');
\Froxlor\FileDir::safe_exec(escapeshellcmd(Settings::Get('system.apachereload_command')));
}
/** /**
* define a standard <Directory>-statement, bug #32 * define a standard <Directory>-statement, bug #32
*/ */
@@ -144,7 +119,7 @@ class Apache extends HttpConfigBase
foreach ($statusCodes as $statusCode) { foreach ($statusCodes as $statusCode) {
if (Settings::Get('defaultwebsrverrhandler.err' . $statusCode) != '') { if (Settings::Get('defaultwebsrverrhandler.err' . $statusCode) != '') {
$defhandler = Settings::Get('defaultwebsrverrhandler.err' . $statusCode); $defhandler = Settings::Get('defaultwebsrverrhandler.err' . $statusCode);
if (! \Froxlor\Validate\Form\Data::validateUrl($defhandler)) { if (! \Froxlor\Validate\Validate::validateUrl($defhandler)) {
if (substr($defhandler, 0, 1) != '"' && substr($defhandler, - 1, 1) != '"') { if (substr($defhandler, 0, 1) != '"' && substr($defhandler, - 1, 1) != '"') {
$defhandler = '"' . \Froxlor\FileDir::makeCorrectFile($defhandler) . '"'; $defhandler = '"' . \Froxlor\FileDir::makeCorrectFile($defhandler) . '"';
} }
@@ -428,11 +403,16 @@ class Apache extends HttpConfigBase
* end of dirprotection * end of dirprotection
*/ */
if ($row_ipsandports['specialsettings'] != '') { if ($row_ipsandports['specialsettings'] != '' && ($row_ipsandports['ssl'] == '0' || ($row_ipsandports['ssl'] == '1' && Settings::Get('system.use_ssl') == '1' && $row_ipsandports['include_specialsettings'] == '1'))) {
$this->virtualhosts_data[$vhosts_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['specialsettings'], $domain, $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n"; $this->virtualhosts_data[$vhosts_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['specialsettings'], $domain, $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
} }
if ($row_ipsandports['ssl'] == '1' && Settings::Get('system.use_ssl') == '1') { if ($row_ipsandports['ssl'] == '1' && Settings::Get('system.use_ssl') == '1') {
if ($row_ipsandports['ssl_specialsettings'] != '') {
$this->virtualhosts_data[$vhosts_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['ssl_specialsettings'], $domain, $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
}
if ($row_ipsandports['ssl_cert_file'] == '') { if ($row_ipsandports['ssl_cert_file'] == '') {
$row_ipsandports['ssl_cert_file'] = Settings::Get('system.ssl_cert_file'); $row_ipsandports['ssl_cert_file'] = Settings::Get('system.ssl_cert_file');
if (! file_exists($row_ipsandports['ssl_cert_file'])) { if (! file_exists($row_ipsandports['ssl_cert_file'])) {
@@ -502,6 +482,10 @@ class Apache extends HttpConfigBase
// this makes it more secure, thx to Marcel (08/2013) // this makes it more secure, thx to Marcel (08/2013)
$this->virtualhosts_data[$vhosts_filename] .= ' SSLHonorCipherOrder On' . "\n"; $this->virtualhosts_data[$vhosts_filename] .= ' SSLHonorCipherOrder On' . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n"; $this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n";
$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) {
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCipherSuite TLSv1.3 ' . Settings::Get('system.tlsv13_cipher_list') . "\n";
}
$this->virtualhosts_data[$vhosts_filename] .= ' SSLVerifyDepth 10' . "\n"; $this->virtualhosts_data[$vhosts_filename] .= ' SSLVerifyDepth 10' . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' SSLCertificateFile ' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . "\n"; $this->virtualhosts_data[$vhosts_filename] .= ' SSLCertificateFile ' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . "\n";
@@ -921,9 +905,12 @@ class Apache extends HttpConfigBase
$ipport = $domain['ip'] . ':' . $domain['port'] . ' '; $ipport = $domain['ip'] . ':' . $domain['port'] . ' ';
} }
if ($ipandport['default_vhostconf_domain'] != '') { if ($ipandport['default_vhostconf_domain'] != '' && ($ssl_vhost == false || ($ssl_vhost == true && $ipandport['include_default_vhostconf_domain'] == '1'))) {
$_vhost_content .= $this->processSpecialConfigTemplate($ipandport['default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n"; $_vhost_content .= $this->processSpecialConfigTemplate($ipandport['default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
} }
if ($ipandport['ssl_default_vhostconf_domain'] != '' && $ssl_vhost == true) {
$_vhost_content .= $this->processSpecialConfigTemplate($ipandport['ssl_default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
$ipportlist .= $ipport; $ipportlist .= $ipport;
} }
@@ -949,7 +936,7 @@ class Apache extends HttpConfigBase
'domainid' => $domain['id'] 'domainid' => $domain['id']
)); ));
if ($ssldestport['port'] != '') { if ($ssldestport && $ssldestport['port'] != '') {
$_sslport = ":" . $ssldestport['port']; $_sslport = ":" . $ssldestport['port'];
} }
@@ -980,8 +967,13 @@ class Apache extends HttpConfigBase
} }
if ($domain['ssl_cert_file'] != '') { if ($domain['ssl_cert_file'] != '') {
$ssl_protocols = ($domain['override_tls'] == '1' && ! empty($domain['ssl_protocols'])) ? $domain['ssl_protocols'] : Settings::Get('system.ssl_protocols');
$ssl_cipher_list = ($domain['override_tls'] == '1' && ! empty($domain['ssl_cipher_list'])) ? $domain['ssl_cipher_list'] : Settings::Get('system.ssl_cipher_list');
$tlsv13_cipher_list = ($domain['override_tls'] == '1' && ! empty($domain['tlsv13_cipher_list'])) ? $domain['tlsv13_cipher_list'] : Settings::Get('system.tlsv13_cipher_list');
$vhost_content .= ' SSLEngine On' . "\n"; $vhost_content .= ' SSLEngine On' . "\n";
$vhost_content .= ' SSLProtocol -ALL +' . str_replace(",", " +", Settings::Get('system.ssl_protocols')) . "\n"; $vhost_content .= ' SSLProtocol -ALL +' . str_replace(",", " +", $ssl_protocols) . "\n";
if (Settings::Get('system.apache24') == '1') { if (Settings::Get('system.apache24') == '1') {
if (isset($domain['http2']) && $domain['http2'] == '1' && Settings::Get('system.http2_support') == '1') { if (isset($domain['http2']) && $domain['http2'] == '1' && Settings::Get('system.http2_support') == '1') {
$vhost_content .= ' Protocols h2 http/1.1' . "\n"; $vhost_content .= ' Protocols h2 http/1.1' . "\n";
@@ -997,7 +989,11 @@ class Apache extends HttpConfigBase
} }
// this makes it more secure, thx to Marcel (08/2013) // this makes it more secure, thx to Marcel (08/2013)
$vhost_content .= ' SSLHonorCipherOrder On' . "\n"; $vhost_content .= ' SSLHonorCipherOrder On' . "\n";
$vhost_content .= ' SSLCipherSuite ' . Settings::Get('system.ssl_cipher_list') . "\n"; $vhost_content .= ' SSLCipherSuite ' . $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) {
$vhost_content .= ' SSLCipherSuite TLSv1.3 ' . $tlsv13_cipher_list . "\n";
}
$vhost_content .= ' SSLVerifyDepth 10' . "\n"; $vhost_content .= ' SSLVerifyDepth 10' . "\n";
$vhost_content .= ' SSLCertificateFile ' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . "\n"; $vhost_content .= ' SSLCertificateFile ' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . "\n";
@@ -1074,17 +1070,25 @@ class Apache extends HttpConfigBase
} }
$vhost_content .= $this->getLogfiles($domain); $vhost_content .= $this->getLogfiles($domain);
if ($domain['specialsettings'] != '') { if ($domain['specialsettings'] != '' && ($ssl_vhost == false || ($ssl_vhost == true && $domain['include_specialsettings'] == 1))) {
$vhost_content .= $this->processSpecialConfigTemplate($domain['specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n"; $vhost_content .= $this->processSpecialConfigTemplate($domain['specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
} }
if ($domain['ssl_specialsettings'] != '' && $ssl_vhost == true) {
$vhost_content .= $this->processSpecialConfigTemplate($domain['ssl_specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if ($_vhost_content != '') { if ($_vhost_content != '') {
$vhost_content .= $_vhost_content; $vhost_content .= $_vhost_content;
} }
if (Settings::Get('system.default_vhostconf') != '') { if (Settings::Get('system.default_vhostconf') != '' && ($ssl_vhost == false || ($ssl_vhost == true && Settings::Get('system.include_default_vhostconf') == 1))) {
$vhost_content .= $this->processSpecialConfigTemplate(Settings::Get('system.default_vhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n"; $vhost_content .= $this->processSpecialConfigTemplate(Settings::Get('system.default_vhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
} }
if (Settings::Get('system.default_sslvhostconf') != '' && $ssl_vhost == true) {
$vhost_content .= $this->processSpecialConfigTemplate(Settings::Get('system.default_sslvhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
} }
$vhost_content .= '</VirtualHost>' . "\n"; $vhost_content .= '</VirtualHost>' . "\n";
@@ -1209,7 +1213,7 @@ class Apache extends HttpConfigBase
foreach ($statusCodes as $statusCode) { foreach ($statusCodes as $statusCode) {
if (isset($row_diroptions['error' . $statusCode . 'path']) && $row_diroptions['error' . $statusCode . 'path'] != '') { if (isset($row_diroptions['error' . $statusCode . 'path']) && $row_diroptions['error' . $statusCode . 'path'] != '') {
$defhandler = $row_diroptions['error' . $statusCode . 'path']; $defhandler = $row_diroptions['error' . $statusCode . 'path'];
if (! \Froxlor\Validate\Form\Data::validateUrl($defhandler)) { if (! \Froxlor\Validate\Validate::validateUrl($defhandler)) {
if (substr($defhandler, 0, 1) != '"' && substr($defhandler, - 1, 1) != '"') { if (substr($defhandler, 0, 1) != '"' && substr($defhandler, - 1, 1) != '"') {
$defhandler = '"' . \Froxlor\FileDir::makeCorrectFile($defhandler) . '"'; $defhandler = '"' . \Froxlor\FileDir::makeCorrectFile($defhandler) . '"';
} }

View File

@@ -128,7 +128,7 @@ class ConfigIO
// iterate through all subdirs, // iterate through all subdirs,
// look for vhost/diroption files // look for vhost/diroption files
// and delete them // and delete them
foreach ($its as $fullFileName => $it) { foreach ($its as $it) {
if ($it->isFile() && preg_match($pattern, $it->getFilename())) { if ($it->isFile() && preg_match($pattern, $it->getFilename())) {
// remove file // remove file
\Froxlor\FileDir::safe_exec('rm -f ' . escapeshellarg(\Froxlor\FileDir::makeCorrectFile($its->getPathname()))); \Froxlor\FileDir::safe_exec('rm -f ' . escapeshellarg(\Froxlor\FileDir::makeCorrectFile($its->getPathname())));
@@ -191,7 +191,7 @@ class ConfigIO
/** /**
* don't do anything if the file does not exist * don't do anything if the file does not exist
*/ */
if (@file_exists($awstatsclean['fullentry'])) { if (@file_exists($awstatsclean['fullentry']) && $awstatsclean['entry'] != '.' && $awstatsclean['entry'] != '..') {
$awstatsclean['fh'] = fopen($awstatsclean['fullentry'], 'r'); $awstatsclean['fh'] = fopen($awstatsclean['fullentry'], 'r');
$awstatsclean['headerRead'] = fgets($awstatsclean['fh'], strlen($awstatsclean['header']) + 1); $awstatsclean['headerRead'] = fgets($awstatsclean['fh'], strlen($awstatsclean['header']) + 1);
fclose($awstatsclean['fh']); fclose($awstatsclean['fh']);
@@ -232,7 +232,7 @@ class ConfigIO
// look for php-fcgi-starter files // look for php-fcgi-starter files
// and take immutable-flag away from them // and take immutable-flag away from them
// so we can delete them :) // so we can delete them :)
foreach ($its as $fullFileName => $it) { foreach ($its as $it) {
if ($it->isFile() && $it->getFilename() == 'php-fcgi-starter') { if ($it->isFile() && $it->getFilename() == 'php-fcgi-starter') {
// set chattr -i // set chattr -i
\Froxlor\FileDir::removeImmutable($its->getPathname()); \Froxlor\FileDir::removeImmutable($its->getPathname());

View File

@@ -3,6 +3,7 @@ namespace Froxlor\Cron\Http;
use Froxlor\Database\Database; use Froxlor\Database\Database;
use Froxlor\Settings; use Froxlor\Settings;
use Froxlor\Cron\Http\Php\Fpm;
/** /**
* This file is part of the Froxlor project. * This file is part of the Froxlor project.
@@ -27,6 +28,51 @@ use Froxlor\Settings;
class HttpConfigBase class HttpConfigBase
{ {
public function init()
{
// if Let's Encrypt is activated, run it before regeneration of webserver configfiles
if (Settings::Get('system.leenabled') == 1) {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'Running Let\'s Encrypt cronjob prior to regenerating webserver config files');
\Froxlor\Cron\Http\LetsEncrypt\AcmeSh::$no_inserttask = true;
\Froxlor\Cron\Http\LetsEncrypt\AcmeSh::run(true);
// set last run timestamp of cronjob
\Froxlor\System\Cronjob::updateLastRunOfCron('letsencrypt');
}
}
public function reload()
{
$called_class = get_called_class();
if ((int) Settings::Get('phpfpm.enabled') == 1) {
// get all start/stop commands
$startstop_sel = Database::prepare("SELECT reload_cmd, config_dir FROM `" . TABLE_PANEL_FPMDAEMONS . "`");
Database::pexecute($startstop_sel);
$restart_cmds = $startstop_sel->fetchAll(\PDO::FETCH_ASSOC);
// restart all php-fpm instances
foreach ($restart_cmds as $restart_cmd) {
// check whether the config dir is empty (no domains uses this daemon)
// so we need to create a dummy
$_conffiles = glob(\Froxlor\FileDir::makeCorrectFile($restart_cmd['config_dir'] . "/*.conf"));
if ($_conffiles === false || empty($_conffiles)) {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, $called_class . '::reload: fpm config directory "' . $restart_cmd['config_dir'] . '" is empty. Creating dummy.');
Fpm::createDummyPool($restart_cmd['config_dir']);
}
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, $called_class . '::reload: running ' . $restart_cmd['reload_cmd']);
\Froxlor\FileDir::safe_exec(escapeshellcmd($restart_cmd['reload_cmd']));
}
}
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, $called_class . '::reload: reloading ' . $called_class);
\Froxlor\FileDir::safe_exec(escapeshellcmd(Settings::Get('system.apachereload_command')));
/**
* nginx does not auto-spawn fcgi-processes
*/
if (Settings::Get('system.webserver') == "nginx" && Settings::Get('system.phpreload_command') != '' && (int) Settings::Get('phpfpm.enabled') == 0) {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, $called_class . '::reload: restarting php processes');
\Froxlor\FileDir::safe_exec(Settings::Get('system.phpreload_command'));
}
}
/** /**
* process special config as template, by substituting {VARIABLE} with the * process special config as template, by substituting {VARIABLE} with the
* respective value. * respective value.
@@ -87,7 +133,7 @@ class HttpConfigBase
"); ");
$ssldestport = Database::pexecute_first($ssldestport_stmt); $ssldestport = Database::pexecute_first($ssldestport_stmt);
if ($ssldestport['port'] != '') { if ($ssldestport && $ssldestport['port'] != '') {
$_sslport = ":" . $ssldestport['port']; $_sslport = ":" . $ssldestport['port'];
} }

View File

@@ -43,19 +43,26 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
private static $do_update = true; private static $do_update = true;
public static function run() public static $no_inserttask = false;
public static function run($internal = false)
{ {
if (! defined('CRON_IS_FORCED') && ! defined('CRON_DEBUG_FLAG') && $internal == false) {
// FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Let's Encrypt cronjob is combined with regeneration of webserver configuration files.\nFor debugging purposes you can use the --debug switch and/or the --force switch to run the cron manually.");
return 0;
}
self::checkInstall(); self::checkInstall();
self::$apiserver = 'https://acme-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org/directory'; self::$apiserver = 'https://acme-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org/directory';
FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, "Updating Let's Encrypt certificates"); FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Requesting/renewing Let's Encrypt certificates");
$certificates_stmt = Database::query(" $certificates_stmt = Database::query("
SELECT SELECT
domssl.`id`, domssl.`id`,
domssl.`domainid`, domssl.`domainid`,
domssl.expirationdate, domssl.`expirationdate`,
domssl.`ssl_cert_file`, domssl.`ssl_cert_file`,
domssl.`ssl_key_file`, domssl.`ssl_key_file`,
domssl.`ssl_ca_file`, domssl.`ssl_ca_file`,
@@ -185,10 +192,12 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
// Only renew let's encrypt certificate if no broken ssl_redirect is enabled // Only renew let's encrypt certificate if no broken ssl_redirect is enabled
// - this temp. deactivation of the ssl-redirect is handled by the webserver-cronjob // - this temp. deactivation of the ssl-redirect is handled by the webserver-cronjob
$do_force = false;
if ($cert_mode == 'renew') { if ($cert_mode == 'renew') {
FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, "Creating certificate for " . $certrow['domain']); FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Updating certificate for " . $certrow['domain']);
} else { } else {
FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, "Updating certificate for " . $certrow['domain']); $do_force = true;
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Creating certificate for " . $certrow['domain']);
} }
$cronlog = FroxlorLogger::getInstanceOf(array( $cronlog = FroxlorLogger::getInstanceOf(array(
@@ -196,7 +205,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
'adminsession' => 0 'adminsession' => 0
)); ));
self::runAcmeSh($certrow, $domains, $cert_mode, $cronlog, $changedetected); self::runAcmeSh($certrow, $domains, $cert_mode, $cronlog, $changedetected, $do_force);
} }
} }
@@ -214,20 +223,25 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
// Only renew let's encrypt certificate if no broken ssl_redirect is enabled // Only renew let's encrypt certificate if no broken ssl_redirect is enabled
if ($certrow['ssl_redirect'] != 2) { if ($certrow['ssl_redirect'] != 2) {
if (! empty($certrow['ssl_cert_file'])) { $do_force = false;
if (! empty($certrow['ssl_cert_file']) && ! empty($certrow['expirationdate'])) {
$cert_mode = 'renew'; $cert_mode = 'renew';
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, "Updating certificate for " . $certrow['domain']); $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 { } else {
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, "Creating certificate for " . $certrow['domain']); $cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Creating certificate for " . $certrow['domain']);
} }
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $certrow['domain']); $cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $certrow['domain']);
$domains = array( $domains = array(
$certrow['domain'] $certrow['domain']
); );
// add www.<domain> to SAN list // add www.<domain> to SAN list
if ($certrow['wwwserveralias'] == 1) { if ($certrow['wwwserveralias'] == 1) {
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $certrow['domain']); $cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $certrow['domain']);
$domains[] = 'www.' . $certrow['domain']; $domains[] = 'www.' . $certrow['domain'];
} }
@@ -237,30 +251,33 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
)); ));
$aliasdomains = $aliasdomains_stmt->fetchAll(\PDO::FETCH_ASSOC); $aliasdomains = $aliasdomains_stmt->fetchAll(\PDO::FETCH_ASSOC);
foreach ($aliasdomains as $aliasdomain) { foreach ($aliasdomains as $aliasdomain) {
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $aliasdomain['domain']); $cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: " . $aliasdomain['domain']);
$domains[] = $aliasdomain['domain']; $domains[] = $aliasdomain['domain'];
if ($aliasdomain['wwwserveralias'] == 1) { if ($aliasdomain['wwwserveralias'] == 1) {
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $aliasdomain['domain']); $cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Adding SAN entry: www." . $aliasdomain['domain']);
$domains[] = 'www.' . $aliasdomain['domain']; $domains[] = 'www.' . $aliasdomain['domain'];
} }
} }
self::runAcmeSh($certrow, $domains, $cert_mode, $cronlog, $changedetected); self::runAcmeSh($certrow, $domains, $cert_mode, $cronlog, $changedetected, $do_force);
} else { } else {
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_WARNING, "Skipping Let's Encrypt generation for " . $certrow['domain'] . " due to an enabled ssl_redirect"); $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 // 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 ;) // This is easiest done by just creating a new task ;)
if ($changedetected) { if ($changedetected) {
if (self::$no_inserttask == false) {
\Froxlor\System\Cronjob::inserttask(1); \Froxlor\System\Cronjob::inserttask(1);
} }
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Let's Encrypt certificates have been updated");
FroxlorLogger::getInstanceOf()->logAction(\Froxlor\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");
}
} }
private static function runAcmeSh($certrow = array(), $domains = array(), $cert_mode = 'issue', &$cronlog = null, &$changedetected = 0) private static function runAcmeSh($certrow = array(), $domains = array(), $cert_mode = 'issue', &$cronlog = null, &$changedetected = 0, $force = false)
{ {
if (! empty($domains)) { if (! empty($domains)) {
@@ -272,7 +289,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
$acmesh_cmd = self::$acmesh . " --auto-upgrade 0 --server " . self::$apiserver . " --" . $cert_mode . " -d " . implode(" -d ", $domains); $acmesh_cmd = self::$acmesh . " --auto-upgrade 0 --server " . self::$apiserver . " --" . $cert_mode . " -d " . implode(" -d ", $domains);
if ($cert_mode == 'issue') { if ($cert_mode == 'issue') {
$acmesh_cmd .= " -w " . \Froxlor\Froxlor::getInstallDir(); $acmesh_cmd .= " -w " . Settings::Get('system.letsencryptchallengepath');
} }
if (Settings::Get('system.leecc') > 0) { if (Settings::Get('system.leecc') > 0) {
$acmesh_cmd .= " --keylength ec-" . Settings::Get('system.leecc'); $acmesh_cmd .= " --keylength ec-" . Settings::Get('system.leecc');
@@ -282,8 +299,16 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
if (Settings::Get('system.letsencryptreuseold') != '1') { if (Settings::Get('system.letsencryptreuseold') != '1') {
$acmesh_cmd .= " --always-force-new-domain-key"; $acmesh_cmd .= " --always-force-new-domain-key";
} }
if (Settings::Get('system.letsencryptca') == 'testing') {
$acmesh_cmd .= " --staging";
}
if ($force) {
$acmesh_cmd .= " --force";
}
$acme_result = \Froxlor\FileDir::safe_exec($acmesh_cmd); $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(); $return = array();
self::readCertificateToVar($certrow['domain'], $return); self::readCertificateToVar($certrow['domain'], $return);
@@ -292,6 +317,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
$newcert = openssl_x509_parse($return['crt']); $newcert = openssl_x509_parse($return['crt']);
if ($newcert) {
// Store the new data // Store the new data
Database::pexecute(self::$updcert_stmt, array( Database::pexecute(self::$updcert_stmt, array(
'id' => $certrow['id'], 'id' => $certrow['id'],
@@ -311,10 +337,13 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
)); ));
} }
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, "Updated Let's Encrypt certificate for " . $certrow['domain']); $cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Updated Let's Encrypt certificate for " . $certrow['domain']);
$changedetected = 1; $changedetected = 1;
} else { } else {
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, "Could not get Let's Encrypt certificate for " . $certrow['domain'] . ":\n" . implode("\n", $acme_result)); $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));
} }
} }
} }
@@ -328,18 +357,27 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
$certificate_folder = \Froxlor\FileDir::makeCorrectDir($certificate_folder); $certificate_folder = \Froxlor\FileDir::makeCorrectDir($certificate_folder);
if (is_dir($certificate_folder)) { if (is_dir($certificate_folder)) {
$return['crt'] = file_get_contents(\Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . $domain . '.cer')); foreach ([
$return['key'] = file_get_contents(\Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . $domain . '.key')); 'crt' => $domain . '.cer',
$return['chain'] = file_get_contents(\Froxlor\FileDir::makeCorrectFile($certificate_folder . '/ca.cer')); 'key' => $domain . '.key',
$return['fullchain'] = file_get_contents(\Froxlor\FileDir::makeCorrectFile($certificate_folder . '/fullchain.cer')); 'chain' => 'ca.cer',
$return['csr'] = file_get_contents(\Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . $domain . '.csr')); 'fullchain' => 'fullchain.cer',
'csr' => $domain . '.csr'
] as $index => $sslfile) {
$ssl_file = \Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . $sslfile);
if (file_exists($ssl_file)) {
$return[$index] = file_get_contents($ssl_file);
} else {
$return[$index] = null;
}
}
} }
} }
private static function checkInstall() private static function checkInstall()
{ {
if (! file_exists(self::$acmesh)) { if (! file_exists(self::$acmesh)) {
FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, "Could not find acme.sh - installing it to /root/.acme.sh/"); FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Could not find acme.sh - installing it to /root/.acme.sh/");
$return = false; $return = false;
\Froxlor\FileDir::safe_exec("wget -O - https://get.acme.sh | sh", $return, array( \Froxlor\FileDir::safe_exec("wget -O - https://get.acme.sh | sh", $return, array(
'|' '|'
@@ -350,6 +388,8 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
private static function checkUpgrade() private static function checkUpgrade()
{ {
$acmesh_result = \Froxlor\FileDir::safe_exec(self::$acmesh . " --upgrade"); $acmesh_result = \Froxlor\FileDir::safe_exec(self::$acmesh . " --upgrade");
FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, "Checking for LetsEncrypt client upgrades before renewing certificates:\n" . implode("\n", $acmesh_result)); // check for activated cron (which is installed automatically) but we don't need it
$acmesh_result2 = \Froxlor\FileDir::safe_exec(self::$acmesh . " --uninstall-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

@@ -3,7 +3,6 @@ namespace Froxlor\Cron\Http;
use Froxlor\Database\Database; use Froxlor\Database\Database;
use Froxlor\Settings; use Froxlor\Settings;
use Froxlor\Cron\Http\Php\Fpm;
use Froxlor\Cron\Http\Php\PhpInterface; use Froxlor\Cron\Http\Php\PhpInterface;
/** /**
@@ -45,30 +44,6 @@ class Lighttpd extends HttpConfigBase
*/ */
private $deactivated = false; private $deactivated = false;
public function reload()
{
if ((int) Settings::Get('phpfpm.enabled') == 1) {
// get all start/stop commands
$startstop_sel = Database::prepare("SELECT reload_cmd, config_dir FROM `" . TABLE_PANEL_FPMDAEMONS . "`");
Database::pexecute($startstop_sel);
$restart_cmds = $startstop_sel->fetchAll(\PDO::FETCH_ASSOC);
// restart all php-fpm instances
foreach ($restart_cmds as $restart_cmd) {
// check whether the config dir is empty (no domains uses this daemon)
// so we need to create a dummy
$_conffiles = glob(\Froxlor\FileDir::makeCorrectFile($restart_cmd['config_dir'] . "/*.conf"));
if ($_conffiles === false || empty($_conffiles)) {
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'lighttpd::reload: fpm config directory "' . $restart_cmd['config_dir'] . '" is empty. Creating dummy.');
Fpm::createDummyPool($restart_cmd['config_dir']);
}
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'lighttpd::reload: running ' . $restart_cmd['reload_cmd']);
\Froxlor\FileDir::safe_exec(escapeshellcmd($restart_cmd['reload_cmd']));
}
}
$this->logger->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'lighttpd::reload: reloading lighttpd');
\Froxlor\FileDir::safe_exec(escapeshellcmd(Settings::Get('system.apachereload_command')));
}
public function createIpPort() public function createIpPort()
{ {
$result_ipsandports_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` ORDER BY `ip` ASC, `port` ASC"); $result_ipsandports_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` ORDER BY `ip` ASC, `port` ASC");
@@ -200,7 +175,7 @@ class Lighttpd extends HttpConfigBase
); );
} }
if ($row_ipsandports['specialsettings'] != '') { if ($row_ipsandports['specialsettings'] != '' && ($row_ipsandports['ssl'] == '0' || ($row_ipsandports['ssl'] == '1' && Settings::Get('system.use_ssl') == '1' && $row_ipsandports['include_specialsettings'] == '1'))) {
$this->lighttpd_data[$vhost_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['specialsettings'], $domain, $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n"; $this->lighttpd_data[$vhost_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['specialsettings'], $domain, $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
} }
@@ -208,6 +183,11 @@ class Lighttpd extends HttpConfigBase
} }
if ($row_ipsandports['ssl'] == '1') { if ($row_ipsandports['ssl'] == '1') {
if ($row_ipsandports['ssl_specialsettings'] != '') {
$this->lighttpd_data[$vhost_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['ssl_specialsettings'], $domain, $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
}
if ($row_ipsandports['ssl_cert_file'] == '') { if ($row_ipsandports['ssl_cert_file'] == '') {
$row_ipsandports['ssl_cert_file'] = Settings::Get('system.ssl_cert_file'); $row_ipsandports['ssl_cert_file'] = Settings::Get('system.ssl_cert_file');
if (! file_exists($row_ipsandports['ssl_cert_file'])) { if (! file_exists($row_ipsandports['ssl_cert_file'])) {
@@ -316,7 +296,7 @@ class Lighttpd extends HttpConfigBase
} }
$defhandler = Settings::Get('defaultwebsrverrhandler.err404'); $defhandler = Settings::Get('defaultwebsrverrhandler.err404');
if (! \Froxlor\Validate\Form\Data::validateUrl($defhandler)) { if (! \Froxlor\Validate\Validate::validateUrl($defhandler)) {
$defhandler = \Froxlor\FileDir::makeCorrectFile($defhandler); $defhandler = \Froxlor\FileDir::makeCorrectFile($defhandler);
} }
$this->lighttpd_data[$vhost_filename] = 'server.error-handler-404 = "' . $defhandler . '"'; $this->lighttpd_data[$vhost_filename] = 'server.error-handler-404 = "' . $defhandler . '"';
@@ -396,6 +376,7 @@ class Lighttpd extends HttpConfigBase
protected function createLighttpdHosts($ipid, $ssl, $vhost_filename) protected function createLighttpdHosts($ipid, $ssl, $vhost_filename)
{ {
$domains = WebserverBase::getVhostsToCreate(); $domains = WebserverBase::getVhostsToCreate();
$included_vhosts = array();
foreach ($domains as $domain) { foreach ($domains as $domain) {
if (is_dir(Settings::Get('system.apacheconf_vhost'))) { if (is_dir(Settings::Get('system.apacheconf_vhost'))) {
@@ -475,7 +456,7 @@ class Lighttpd extends HttpConfigBase
'domainid' => $domain['id'] 'domainid' => $domain['id']
)); ));
if ($ssldestport['port'] != '') { if ($ssldestport && $ssldestport['port'] != '') {
$_sslport = ":" . $ssldestport['port']; $_sslport = ":" . $ssldestport['port'];
} }
@@ -536,17 +517,29 @@ class Lighttpd extends HttpConfigBase
$vhost_content .= $this->getSslSettings($domain, $ssl_vhost); $vhost_content .= $this->getSslSettings($domain, $ssl_vhost);
if ($domain['specialsettings'] != "") { if ($domain['specialsettings'] != '' && ($ssl_vhost == false || ($ssl_vhost == true && $domain['include_specialsettings'] == 1))) {
$vhost_content .= $this->processSpecialConfigTemplate($domain['specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n"; $vhost_content .= $this->processSpecialConfigTemplate($domain['specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
} }
if ($ipandport['default_vhostconf_domain'] != '') { if ($domain['ssl_specialsettings'] != '' && $ssl_vhost == true) {
$vhost_content .= $this->processSpecialConfigTemplate($domain['ssl_specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if ($ipandport['default_vhostconf_domain'] != '' && ($ssl_vhost == false || ($ssl_vhost == true && $ipandport['include_default_vhostconf_domain'] == '1'))) {
$vhost_content .= $this->processSpecialConfigTemplate($ipandport['default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n"; $vhost_content .= $this->processSpecialConfigTemplate($ipandport['default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
} }
if (Settings::Get('system.default_vhostconf') != '') { if ($ipandport['ssl_default_vhostconf_domain'] != '' && $ssl_vhost == true) {
$vhost_content .= $this->processSpecialConfigTemplate($ipandport['ssl_default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if (Settings::Get('system.default_vhostconf') != '' && ($ssl_vhost == false || ($ssl_vhost == true && Settings::Get('system.include_default_vhostconf') == 1))) {
$vhost_content .= $this->processSpecialConfigTemplate(Settings::Get('system.default_vhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n"; $vhost_content .= $this->processSpecialConfigTemplate(Settings::Get('system.default_vhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
} }
if (Settings::Get('system.default_sslvhostconf') != '' && $ssl_vhost == true) {
$vhost_content .= $this->processSpecialConfigTemplate(Settings::Get('system.default_sslvhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
} }
$vhost_content .= $this->getLogFiles($domain); $vhost_content .= $this->getLogFiles($domain);
} }
@@ -577,6 +570,8 @@ class Lighttpd extends HttpConfigBase
if ($domain['ssl_cert_file'] != '') { if ($domain['ssl_cert_file'] != '') {
$ssl_cipher_list = ($domain['override_tls'] == '1' && ! empty($domain['ssl_cipher_list'])) ? $domain['ssl_cipher_list'] : Settings::Get('system.ssl_cipher_list');
// ssl.engine only necessary once in the ip/port vhost (SERVER['socket'] condition) // ssl.engine only necessary once in the ip/port vhost (SERVER['socket'] condition)
// $ssl_settings .= 'ssl.engine = "enable"' . "\n"; // $ssl_settings .= 'ssl.engine = "enable"' . "\n";
$ssl_settings .= 'ssl.use-compression = "disable"' . "\n"; $ssl_settings .= 'ssl.use-compression = "disable"' . "\n";
@@ -590,7 +585,7 @@ class Lighttpd extends HttpConfigBase
} }
$ssl_settings .= 'ssl.use-sslv2 = "disable"' . "\n"; $ssl_settings .= 'ssl.use-sslv2 = "disable"' . "\n";
$ssl_settings .= 'ssl.use-sslv3 = "disable"' . "\n"; $ssl_settings .= 'ssl.use-sslv3 = "disable"' . "\n";
$ssl_settings .= 'ssl.cipher-list = "' . Settings::Get('system.ssl_cipher_list') . '"' . "\n"; $ssl_settings .= 'ssl.cipher-list = "' . $ssl_cipher_list . '"' . "\n";
$ssl_settings .= 'ssl.honor-cipher-order = "enable"' . "\n"; $ssl_settings .= 'ssl.honor-cipher-order = "enable"' . "\n";
$ssl_settings .= 'ssl.pemfile = "' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . '"' . "\n"; $ssl_settings .= 'ssl.pemfile = "' . \Froxlor\FileDir::makeCorrectFile($domain['ssl_cert_file']) . '"' . "\n";
@@ -707,7 +702,7 @@ class Lighttpd extends HttpConfigBase
if (! empty($row['error404path'])) { if (! empty($row['error404path'])) {
$defhandler = $row['error404path']; $defhandler = $row['error404path'];
if (! \Froxlor\Validate\Form\Data::validateUrl($defhandler)) { if (! \Froxlor\Validate\Validate::validateUrl($defhandler)) {
$defhandler = \Froxlor\FileDir::makeCorrectFile($domain['documentroot'] . '/' . $defhandler); $defhandler = \Froxlor\FileDir::makeCorrectFile($domain['documentroot'] . '/' . $defhandler);
} }
$error_string .= ' server.error-handler-404 = "' . $defhandler . '"' . "\n\n"; $error_string .= ' server.error-handler-404 = "' . $defhandler . '"' . "\n\n";
@@ -765,23 +760,21 @@ class Lighttpd extends HttpConfigBase
)); ));
while ($row_htpasswds = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row_htpasswds = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
if ($auth_backend_loaded[$domain['ipandport']] != 'yes' && $auth_backend_loaded[$domain['ssl_ipandport']] != 'yes') { if ($this->auth_backend_loaded[$domain['ipandport']] != 'yes' && $this->auth_backend_loaded[$domain['ssl_ipandport']] != 'yes') {
$filename = $domain['customerid'] . '.htpasswd'; $filename = $domain['customerid'] . '.htpasswd';
if ($this->auth_backend_loaded[$domain['ipandport']] != 'yes') { if ($this->auth_backend_loaded[$domain['ipandport']] != 'yes') {
$auth_backend_loaded[$domain['ipandport']] = 'yes'; $this->auth_backend_loaded[$domain['ipandport']] = 'yes';
$diroption_text .= 'auth.backend = "htpasswd"' . "\n"; $diroption_text .= 'auth.backend = "htpasswd"' . "\n";
$diroption_text .= 'auth.backend.htpasswd.userfile = "' . \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.apacheconf_htpasswddir') . '/' . $filename) . '"' . "\n"; $diroption_text .= 'auth.backend.htpasswd.userfile = "' . \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.apacheconf_htpasswddir') . '/' . $filename) . '"' . "\n";
$this->needed_htpasswds[$filename] = $row_htpasswds['username'] . ':' . $row_htpasswds['password'] . "\n"; $this->needed_htpasswds[$filename] = $row_htpasswds['username'] . ':' . $row_htpasswds['password'] . "\n";
$diroption_text .= 'auth.require = ( ' . "\n"; $diroption_text .= 'auth.require = ( ' . "\n";
$previous_domain_id = '1';
} elseif ($this->auth_backend_loaded[$domain['ssl_ipandport']] != 'yes') { } elseif ($this->auth_backend_loaded[$domain['ssl_ipandport']] != 'yes') {
$auth_backend_loaded[$domain['ssl_ipandport']] = 'yes'; $this->auth_backend_loaded[$domain['ssl_ipandport']] = 'yes';
$diroption_text .= 'auth.backend= "htpasswd"' . "\n"; $diroption_text .= 'auth.backend= "htpasswd"' . "\n";
$diroption_text .= 'auth.backend.htpasswd.userfile = "' . \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.apacheconf_htpasswddir') . '/' . $filename) . '"' . "\n"; $diroption_text .= 'auth.backend.htpasswd.userfile = "' . \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.apacheconf_htpasswddir') . '/' . $filename) . '"' . "\n";
$this->needed_htpasswds[$filename] = $row_htpasswds['username'] . ':' . $row_htpasswds['password'] . "\n"; $this->needed_htpasswds[$filename] = $row_htpasswds['username'] . ':' . $row_htpasswds['password'] . "\n";
$diroption_text .= 'auth.require = ( ' . "\n"; $diroption_text .= 'auth.require = ( ' . "\n";
$previous_domain_id = '1';
} }
} }

View File

@@ -3,7 +3,6 @@ namespace Froxlor\Cron\Http;
use Froxlor\Database\Database; use Froxlor\Database\Database;
use Froxlor\Settings; use Froxlor\Settings;
use Froxlor\Cron\Http\Php\Fpm;
use Froxlor\Cron\Http\Php\PhpInterface; use Froxlor\Cron\Http\Php\PhpInterface;
/** /**
@@ -55,39 +54,6 @@ class Nginx extends HttpConfigBase
$this->nginx_server = $nginx_server; $this->nginx_server = $nginx_server;
} }
public function reload()
{
if ((int) Settings::Get('phpfpm.enabled') == 1) {
// get all start/stop commands
$startstop_sel = Database::prepare("SELECT reload_cmd, config_dir FROM `" . TABLE_PANEL_FPMDAEMONS . "`");
Database::pexecute($startstop_sel);
$restart_cmds = $startstop_sel->fetchAll(\PDO::FETCH_ASSOC);
// restart all php-fpm instances
foreach ($restart_cmds as $restart_cmd) {
// check whether the config dir is empty (no domains uses this daemon)
// so we need to create a dummy
$_conffiles = glob(\Froxlor\FileDir::makeCorrectFile($restart_cmd['config_dir'] . "/*.conf"));
if ($_conffiles === false || empty($_conffiles)) {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'nginx::reload: fpm config directory "' . $restart_cmd['config_dir'] . '" is empty. Creating dummy.');
Fpm::createDummyPool($restart_cmd['config_dir']);
}
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'nginx::reload: running ' . $restart_cmd['reload_cmd']);
\Froxlor\FileDir::safe_exec(escapeshellcmd($restart_cmd['reload_cmd']));
}
}
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'nginx::reload: reloading nginx');
\Froxlor\FileDir::safe_exec(Settings::Get('system.apachereload_command'));
/**
* nginx does not auto-spawn fcgi-processes
*/
if (Settings::Get('system.phpreload_command') != '' && (int) Settings::Get('phpfpm.enabled') == 0) {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'nginx::reload: restarting php processes');
\Froxlor\FileDir::safe_exec(Settings::Get('system.phpreload_command'));
}
}
private function createLogformatEntry() private function createLogformatEntry()
{ {
if (Settings::Get('system.logfiles_format') != '') { if (Settings::Get('system.logfiles_format') != '') {
@@ -137,7 +103,7 @@ class Nginx extends HttpConfigBase
foreach ($statusCodes as $statusCode) { foreach ($statusCodes as $statusCode) {
if (Settings::Get('defaultwebsrverrhandler.err' . $statusCode) != '') { if (Settings::Get('defaultwebsrverrhandler.err' . $statusCode) != '') {
$defhandler = Settings::Get('defaultwebsrverrhandler.err' . $statusCode); $defhandler = Settings::Get('defaultwebsrverrhandler.err' . $statusCode);
if (! \Froxlor\Validate\Form\Data::validateUrl($defhandler)) { if (! \Froxlor\Validate\Validate::validateUrl($defhandler)) {
$defhandler = \Froxlor\FileDir::makeCorrectFile($defhandler); $defhandler = \Froxlor\FileDir::makeCorrectFile($defhandler);
} }
$this->nginx_data[$vhosts_filename] .= 'error_page ' . $statusCode . ' ' . $defhandler . ';' . "\n"; $this->nginx_data[$vhosts_filename] .= 'error_page ' . $statusCode . ' ' . $defhandler . ';' . "\n";
@@ -278,7 +244,7 @@ class Nginx extends HttpConfigBase
$is_redirect = false; $is_redirect = false;
} else { } else {
$_sslport = $this->checkAlternativeSslPort(); $_sslport = $this->checkAlternativeSslPort();
$mypath = 'https://' . Settings::Get('system.hostname') . $_sslport . '/'; $mypath = 'https://' . Settings::Get('system.hostname') . $_sslport;
$this->nginx_data[$vhost_filename] .= "\t" . 'location / {' . "\n"; $this->nginx_data[$vhost_filename] .= "\t" . 'location / {' . "\n";
$this->nginx_data[$vhost_filename] .= "\t\t" . 'return 301 ' . $mypath . '$request_uri;' . "\n"; $this->nginx_data[$vhost_filename] .= "\t\t" . 'return 301 ' . $mypath . '$request_uri;' . "\n";
$this->nginx_data[$vhost_filename] .= "\t" . '}' . "\n"; $this->nginx_data[$vhost_filename] .= "\t" . '}' . "\n";
@@ -292,7 +258,7 @@ class Nginx extends HttpConfigBase
$this->nginx_data[$vhost_filename] .= "\t" . '}' . "\n"; $this->nginx_data[$vhost_filename] .= "\t" . '}' . "\n";
} }
if ($row_ipsandports['specialsettings'] != '') { if ($row_ipsandports['specialsettings'] != '' && ($row_ipsandports['ssl'] == '0' || ($row_ipsandports['ssl'] == '1' && Settings::Get('system.use_ssl') == '1' && $row_ipsandports['include_specialsettings'] == '1'))) {
$this->nginx_data[$vhost_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['specialsettings'], array( $this->nginx_data[$vhost_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['specialsettings'], array(
'domain' => Settings::Get('system.hostname'), 'domain' => Settings::Get('system.hostname'),
'loginname' => Settings::Get('phpfpm.vhost_httpuser'), 'loginname' => Settings::Get('phpfpm.vhost_httpuser'),
@@ -307,13 +273,21 @@ class Nginx extends HttpConfigBase
if ($row_ipsandports['ssl'] == '1') { if ($row_ipsandports['ssl'] == '1') {
$row_ipsandports['domain'] = Settings::Get('system.hostname'); $row_ipsandports['domain'] = Settings::Get('system.hostname');
$this->nginx_data[$vhost_filename] .= $this->composeSslSettings($row_ipsandports); $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(
'domain' => Settings::Get('system.hostname'),
'loginname' => Settings::Get('phpfpm.vhost_httpuser'),
'documentroot' => $mypath,
'customerroot' => $mypath
), $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
}
} }
if (! $is_redirect) { if (! $is_redirect) {
$this->nginx_data[$vhost_filename] .= "\tlocation ~ \.php {\n"; $this->nginx_data[$vhost_filename] .= "\tlocation ~ \.php {\n";
$this->nginx_data[$vhost_filename] .= "\t\tfastcgi_split_path_info ^(.+\.php)(/.+)\$;\n"; $this->nginx_data[$vhost_filename] .= "\t\tfastcgi_split_path_info ^(.+\.php)(/.+)\$;\n";
$this->nginx_data[$vhost_filename] .= "\t\tinclude " . Settings::Get('nginx.fastcgiparams') . ";\n"; $this->nginx_data[$vhost_filename] .= "\t\tinclude " . Settings::Get('nginx.fastcgiparams') . ";\n";
$this->nginx_data[$vhost_filename] .= "\t\tfastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;\n"; $this->nginx_data[$vhost_filename] .= "\t\tfastcgi_param SCRIPT_FILENAME \$request_filename;\n";
$this->nginx_data[$vhost_filename] .= "\t\tfastcgi_param PATH_INFO \$fastcgi_path_info;\n"; $this->nginx_data[$vhost_filename] .= "\t\tfastcgi_param PATH_INFO \$fastcgi_path_info;\n";
$this->nginx_data[$vhost_filename] .= "\t\ttry_files \$fastcgi_script_name =404;\n"; $this->nginx_data[$vhost_filename] .= "\t\ttry_files \$fastcgi_script_name =404;\n";
@@ -481,10 +455,12 @@ class Nginx extends HttpConfigBase
$ipport = $domain['ip'] . ':' . $domain['port']; $ipport = $domain['ip'] . ':' . $domain['port'];
} }
if ($ipandport['default_vhostconf_domain'] != '') { if ($ipandport['default_vhostconf_domain'] != '' && ($ssl_vhost == false || ($ssl_vhost == true && $ipandport['include_default_vhostconf_domain'] == '1'))) {
$_vhost_content .= $this->processSpecialConfigTemplate($ipandport['default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n"; $_vhost_content .= $this->processSpecialConfigTemplate($ipandport['default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
} }
if ($ipandport['ssl_default_vhostconf_domain'] != '' && $ssl_vhost == true) {
$_vhost_content .= $this->processSpecialConfigTemplate($ipandport['ssl_default_vhostconf_domain'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
$http2 = $ssl_vhost == true && (isset($domain['http2']) && $domain['http2'] == '1' && Settings::Get('system.http2_support') == '1'); $http2 = $ssl_vhost == true && (isset($domain['http2']) && $domain['http2'] == '1' && Settings::Get('system.http2_support') == '1');
$vhost_content .= "\t" . 'listen ' . $ipport . ($ssl_vhost == true ? ' ssl' : '') . ($http2 == true ? ' http2' : '') . ';' . "\n"; $vhost_content .= "\t" . 'listen ' . $ipport . ($ssl_vhost == true ? ' ssl' : '') . ($http2 == true ? ' http2' : '') . ';' . "\n";
@@ -510,7 +486,7 @@ class Nginx extends HttpConfigBase
'domainid' => $domain['id'] 'domainid' => $domain['id']
)); ));
if ($ssldestport['port'] != '') { if ($ssldestport && $ssldestport['port'] != '') {
$_sslport = ":" . $ssldestport['port']; $_sslport = ":" . $ssldestport['port'];
} }
@@ -556,17 +532,25 @@ class Nginx extends HttpConfigBase
$vhost_content .= isset($this->needed_htpasswds[$domain['id']]) ? $this->needed_htpasswds[$domain['id']] . "\n" : ''; $vhost_content .= isset($this->needed_htpasswds[$domain['id']]) ? $this->needed_htpasswds[$domain['id']] . "\n" : '';
if ($domain['specialsettings'] != "") { if ($domain['specialsettings'] != '' && ($ssl_vhost == false || ($ssl_vhost == true && $domain['include_specialsettings'] == 1))) {
$vhost_content = $this->mergeVhostCustom($vhost_content, $this->processSpecialConfigTemplate($domain['specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost)); $vhost_content = $this->mergeVhostCustom($vhost_content, $this->processSpecialConfigTemplate($domain['specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost));
} }
if ($domain['ssl_specialsettings'] != '' && $ssl_vhost == true) {
$vhost_content .= $this->processSpecialConfigTemplate($domain['ssl_specialsettings'], $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
if ($_vhost_content != '') { if ($_vhost_content != '') {
$vhost_content = $this->mergeVhostCustom($vhost_content, $_vhost_content); $vhost_content = $this->mergeVhostCustom($vhost_content, $_vhost_content);
} }
if (Settings::Get('system.default_vhostconf') != '') { if (Settings::Get('system.default_vhostconf') != '' && ($ssl_vhost == false || ($ssl_vhost == true && Settings::Get('system.include_default_vhostconf') == 1))) {
$vhost_content = $this->mergeVhostCustom($vhost_content, $this->processSpecialConfigTemplate(Settings::Get('system.default_vhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n"); $vhost_content = $this->mergeVhostCustom($vhost_content, $this->processSpecialConfigTemplate(Settings::Get('system.default_vhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n");
} }
if (Settings::Get('system.default_sslvhostconf') != '' && $ssl_vhost == true) {
$vhost_content .= $this->processSpecialConfigTemplate(Settings::Get('system.default_sslvhostconf'), $domain, $domain['ip'], $domain['port'], $ssl_vhost) . "\n";
}
} }
} }
$vhost_content .= "\n}\n\n"; $vhost_content .= "\n}\n\n";
@@ -574,27 +558,39 @@ class Nginx extends HttpConfigBase
return $vhost_content; return $vhost_content;
} }
protected function mergeVhostCustom($vhost_frx, $vhost_usr) private function cleanVhostStruct($vhost = null)
{ {
// Clean froxlor defined settings // Remove windows linebreaks
$vhost_frx = explode("\n", preg_replace('/[ \t]+/', ' ', trim(preg_replace('/\t+/', '', $vhost_frx)))); // Break into array items $vhost = str_replace("\r", "\n", $vhost);
$vhost_frx = array_map("trim", $vhost_frx); // remove unnecessary whitespaces // Break blocks into lines
$vhost = str_replace(array(
// Clean user defined settings
$vhost_usr = str_replace("\r", "\n", $vhost_usr); // Remove windows linebreaks
$vhost_usr = str_replace(array(
"{", "{",
"}" "}"
), array( ), array(
" {\n", " {\n",
"\n}" "\n}"
), $vhost_usr); // Break blocks into lines ), $vhost);
$vhost_usr = explode("\n", preg_replace('/[ \t]+/', ' ', trim(preg_replace('/\t+/', '', $vhost_usr)))); // Break into array items // Break into array items
$vhost = explode("\n", preg_replace('/[ \t]+/', ' ', trim(preg_replace('/\t+/', '', $vhost))));
// Remove empty lines // Remove empty lines
$vhost_usr = array_filter($vhost_usr, function ($a) { $vhost = array_filter($vhost, function ($a) {
return preg_match("#\S#", $a); return preg_match("#\S#", $a);
}); });
// remove unnecessary whitespaces
$vhost = array_map("trim", $vhost);
// re-number array keys
$vhost = array_values($vhost);
return $vhost;
}
protected function mergeVhostCustom($vhost_frx, $vhost_usr)
{
// Clean froxlor defined settings
$vhost_frx = $this->cleanVhostStruct($vhost_frx);
// Clean user defined settings
$vhost_usr = $this->cleanVhostStruct($vhost_usr);
// Cycle through the user defined settings // Cycle through the user defined settings
$currentBlock = array(); $currentBlock = array();
$blockLevel = 0; $blockLevel = 0;
@@ -682,10 +678,14 @@ class Nginx extends HttpConfigBase
if (! file_exists($domain_or_ip['ssl_cert_file'])) { if (! file_exists($domain_or_ip['ssl_cert_file'])) {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, $domain_or_ip['domain'] . ' :: certificate file "' . $domain_or_ip['ssl_cert_file'] . '" does not exist! Cannot create ssl-directives'); \Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_ERR, $domain_or_ip['domain'] . ' :: certificate file "' . $domain_or_ip['ssl_cert_file'] . '" does not exist! Cannot create ssl-directives');
} else { } else {
$ssl_protocols = (isset($domain_or_ip['override_tls']) && $domain_or_ip['override_tls'] == '1' && ! empty($domain_or_ip['ssl_protocols'])) ? $domain_or_ip['ssl_protocols'] : Settings::Get('system.ssl_protocols');
$ssl_cipher_list = (isset($domain_or_ip['override_tls']) && $domain_or_ip['override_tls'] == '1' && ! empty($domain_or_ip['ssl_cipher_list'])) ? $domain_or_ip['ssl_cipher_list'] : Settings::Get('system.ssl_cipher_list');
// obsolete: ssl on now belongs to the listen block as 'ssl' at the end // obsolete: ssl on now belongs to the listen block as 'ssl' at the end
// $sslsettings .= "\t" . 'ssl on;' . "\n"; // $sslsettings .= "\t" . 'ssl on;' . "\n";
$sslsettings .= "\t" . 'ssl_protocols ' . str_replace(",", " ", Settings::Get('system.ssl_protocols')) . ';' . "\n"; $sslsettings .= "\t" . 'ssl_protocols ' . str_replace(",", " ", $ssl_protocols) . ';' . "\n";
$sslsettings .= "\t" . 'ssl_ciphers ' . Settings::Get('system.ssl_cipher_list') . ';' . "\n"; $sslsettings .= "\t" . 'ssl_ciphers ' . $ssl_cipher_list . ';' . "\n";
if (! empty(Settings::Get('system.dhparams_file'))) { if (! empty(Settings::Get('system.dhparams_file'))) {
$dhparams = \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.dhparams_file')); $dhparams = \Froxlor\FileDir::makeCorrectFile(Settings::Get('system.dhparams_file'));
if (! file_exists($dhparams)) { if (! file_exists($dhparams)) {
@@ -693,8 +693,13 @@ class Nginx extends HttpConfigBase
} }
$sslsettings .= 'ssl_dhparam ' . $dhparams . ';' . "\n"; $sslsettings .= 'ssl_dhparam ' . $dhparams . ';' . "\n";
} }
$sslsettings .= "\t" . 'ssl_ecdh_curve secp384r1;' . "\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 on;' . "\n";
$sslsettings .= "\t" . 'ssl_session_cache shared:SSL:10m;' . "\n";
$sslsettings .= "\t" . 'ssl_certificate ' . \Froxlor\FileDir::makeCorrectFile($domain_or_ip['ssl_cert_file']) . ';' . "\n"; $sslsettings .= "\t" . 'ssl_certificate ' . \Froxlor\FileDir::makeCorrectFile($domain_or_ip['ssl_cert_file']) . ';' . "\n";
if ($domain_or_ip['ssl_key_file'] != '') { if ($domain_or_ip['ssl_key_file'] != '') {
@@ -745,7 +750,7 @@ class Nginx extends HttpConfigBase
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
if (! empty($row['error404path'])) { if (! empty($row['error404path'])) {
$defhandler = $row['error404path']; $defhandler = $row['error404path'];
if (! \Froxlor\Validate\Form\Data::validateUrl($defhandler)) { if (! \Froxlor\Validate\Validate::validateUrl($defhandler)) {
$defhandler = \Froxlor\FileDir::makeCorrectFile($defhandler); $defhandler = \Froxlor\FileDir::makeCorrectFile($defhandler);
} }
$path_options .= "\t" . 'error_page 404 ' . $defhandler . ';' . "\n"; $path_options .= "\t" . 'error_page 404 ' . $defhandler . ';' . "\n";
@@ -753,7 +758,7 @@ class Nginx extends HttpConfigBase
if (! empty($row['error403path'])) { if (! empty($row['error403path'])) {
$defhandler = $row['error403path']; $defhandler = $row['error403path'];
if (! \Froxlor\Validate\Form\Data::validateUrl($defhandler)) { if (! \Froxlor\Validate\Validate::validateUrl($defhandler)) {
$defhandler = \Froxlor\FileDir::makeCorrectFile($defhandler); $defhandler = \Froxlor\FileDir::makeCorrectFile($defhandler);
} }
$path_options .= "\t" . 'error_page 403 ' . $defhandler . ';' . "\n"; $path_options .= "\t" . 'error_page 403 ' . $defhandler . ';' . "\n";
@@ -761,7 +766,7 @@ class Nginx extends HttpConfigBase
if (! empty($row['error500path'])) { if (! empty($row['error500path'])) {
$defhandler = $row['error500path']; $defhandler = $row['error500path'];
if (! \Froxlor\Validate\Form\Data::validateUrl($defhandler)) { if (! \Froxlor\Validate\Validate::validateUrl($defhandler)) {
$defhandler = \Froxlor\FileDir::makeCorrectFile($defhandler); $defhandler = \Froxlor\FileDir::makeCorrectFile($defhandler);
} }
$path_options .= "\t" . 'error_page 500 502 503 504 ' . $defhandler . ';' . "\n"; $path_options .= "\t" . 'error_page 500 502 503 504 ' . $defhandler . ';' . "\n";
@@ -911,6 +916,7 @@ class Nginx extends HttpConfigBase
$path = \Froxlor\FileDir::makeCorrectDir(substr($row_htpasswds['path'], strlen($domain['documentroot']) - 1)); $path = \Froxlor\FileDir::makeCorrectDir(substr($row_htpasswds['path'], strlen($domain['documentroot']) - 1));
} else { } else {
// if the website contents is located in a subdirectory of the user // if the website contents is located in a subdirectory of the user
$matches = array();
preg_match('/^([\/[:print:]]*\/)([[:print:]\/]+){1}$/i', $row_htpasswds['path'], $matches); preg_match('/^([\/[:print:]]*\/)([[:print:]\/]+){1}$/i', $row_htpasswds['path'], $matches);
$path = \Froxlor\FileDir::makeCorrectDir(substr($row_htpasswds['path'], strlen($matches[1]) - 1)); $path = \Froxlor\FileDir::makeCorrectDir(substr($row_htpasswds['path'], strlen($matches[1]) - 1));
} }
@@ -951,7 +957,7 @@ class Nginx extends HttpConfigBase
$phpopts .= "\tlocation @php {\n"; $phpopts .= "\tlocation @php {\n";
$phpopts .= "\t\tfastcgi_split_path_info ^(.+\.php)(/.+)\$;\n"; $phpopts .= "\t\tfastcgi_split_path_info ^(.+\.php)(/.+)\$;\n";
$phpopts .= "\t\tinclude " . Settings::Get('nginx.fastcgiparams') . ";\n"; $phpopts .= "\t\tinclude " . Settings::Get('nginx.fastcgiparams') . ";\n";
$phpopts .= "\t\tfastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;\n"; $phpopts .= "\t\tfastcgi_param SCRIPT_FILENAME \$request_filename;\n";
$phpopts .= "\t\tfastcgi_param PATH_INFO \$fastcgi_path_info;\n"; $phpopts .= "\t\tfastcgi_param PATH_INFO \$fastcgi_path_info;\n";
$phpopts .= "\t\ttry_files \$fastcgi_script_name =404;\n"; $phpopts .= "\t\ttry_files \$fastcgi_script_name =404;\n";
$phpopts .= "\t\tfastcgi_pass " . Settings::Get('system.nginx_php_backend') . ";\n"; $phpopts .= "\t\tfastcgi_pass " . Settings::Get('system.nginx_php_backend') . ";\n";

View File

@@ -38,7 +38,7 @@ class NginxFcgi extends Nginx
$php_options_text .= "\t\t" . 'try_files $1 =404;' . "\n\n"; $php_options_text .= "\t\t" . 'try_files $1 =404;' . "\n\n";
$php_options_text .= "\t\t" . 'include ' . Settings::Get('nginx.fastcgiparams') . ";\n"; $php_options_text .= "\t\t" . 'include ' . Settings::Get('nginx.fastcgiparams') . ";\n";
$php_options_text .= "\t\t" . 'fastcgi_split_path_info ^(.+\.php)(/.+)\$;' . "\n"; $php_options_text .= "\t\t" . 'fastcgi_split_path_info ^(.+\.php)(/.+)\$;' . "\n";
$php_options_text .= "\t\t" . 'fastcgi_param SCRIPT_FILENAME $document_root$1;' . "\n"; $php_options_text .= "\t\t" . 'fastcgi_param SCRIPT_FILENAME $request_filename;' . "\n";
$php_options_text .= "\t\t" . 'fastcgi_param PATH_INFO $2;' . "\n"; $php_options_text .= "\t\t" . 'fastcgi_param PATH_INFO $2;' . "\n";
if ($domain['ssl'] == '1' && $ssl_vhost) { if ($domain['ssl'] == '1' && $ssl_vhost) {
$php_options_text .= "\t\t" . 'fastcgi_param HTTPS on;' . "\n"; $php_options_text .= "\t\t" . 'fastcgi_param HTTPS on;' . "\n";

View File

@@ -36,9 +36,7 @@ class WebserverBase
`d`.`phpsettingid`, `c`.`adminid`, `c`.`guid`, `c`.`email`, `d`.`phpsettingid`, `c`.`adminid`, `c`.`guid`, `c`.`email`,
`c`.`documentroot` AS `customerroot`, `c`.`deactivated`, `c`.`documentroot` AS `customerroot`, `c`.`deactivated`,
`c`.`phpenabled` AS `phpenabled_customer`, `c`.`phpenabled` AS `phpenabled_customer`,
`d`.`phpenabled` AS `phpenabled_vhost`, `d`.`phpenabled` AS `phpenabled_vhost`
`d`.`mod_fcgid_starter`,`d`.`mod_fcgid_maxrequests`,
`d`.`ocsp_stapling`
FROM `" . TABLE_PANEL_DOMAINS . "` `d` FROM `" . TABLE_PANEL_DOMAINS . "` `d`
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`) LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` `c` USING(`customerid`)

View File

@@ -44,8 +44,9 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
echo "Below are possible parameters for this file\n\n"; echo "Below are possible parameters for this file\n\n";
echo "--[cronname]\t\tincludes the given cron-file\n"; echo "--[cronname]\t\tincludes the given cron-file\n";
echo "--force\t\t\tforces re-generating of config-files (webserver, nameserver, etc.)\n"; echo "--force\t\t\tforces re-generating of config-files (webserver, nameserver, etc.)\n";
echo "--run-task\t\trun a specific task [1 = re-generate configs, 4 = re-generate dns zones, 10 = re-set quotas, 99 = re-create cron.d-file]\n";
echo "--debug\t\t\toutput debug information about what is going on to STDOUT.\n"; echo "--debug\t\t\toutput debug information about what is going on to STDOUT.\n";
echo "--no-fork\t\t\tdo not fork to backkground (traffic cron only).\n\n"; echo "--no-fork\t\tdo not fork to backkground (traffic cron only).\n\n";
} }
/** /**
@@ -70,10 +71,19 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
// also regenerate cron.d-file // also regenerate cron.d-file
\Froxlor\System\Cronjob::inserttask('99'); \Froxlor\System\Cronjob::inserttask('99');
array_push($jobs_to_run, 'tasks'); array_push($jobs_to_run, 'tasks');
define('CRON_IS_FORCED', 1);
} elseif (strtolower($argv[$x]) == '--debug') { } elseif (strtolower($argv[$x]) == '--debug') {
define('CRON_DEBUG_FLAG', 1); define('CRON_DEBUG_FLAG', 1);
} elseif (strtolower($argv[$x]) == '--no-fork') { } elseif (strtolower($argv[$x]) == '--no-fork') {
define('CRON_NOFORK_FLAG', 1); define('CRON_NOFORK_FLAG', 1);
} elseif (strtolower($argv[$x]) == '--run-task') {
if (isset($argv[$x+1]) && in_array($argv[$x+1], [1,4,10,99])) {
\Froxlor\System\Cronjob::inserttask($argv[$x+1]);
array_push($jobs_to_run, 'tasks');
} else {
echo "Invalid argument for --run-task\n";
exit;
}
} elseif (substr(strtolower($argv[$x]), 0, 2) == '--') { } elseif (substr(strtolower($argv[$x]), 0, 2) == '--') {
// --[cronname] // --[cronname]
if (strlen($argv[$x]) > 3) { if (strlen($argv[$x]) > 3) {
@@ -95,29 +105,13 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
if (count($jobs_to_run) > 0) { if (count($jobs_to_run) > 0) {
// include all jobs we want to execute // include all jobs we want to execute
foreach ($jobs_to_run as $cron) { foreach ($jobs_to_run as $cron) {
self::updateLastRunOfCron($cron); \Froxlor\System\Cronjob::updateLastRunOfCron($cron);
$cronfile = self::getCronModule($cron); $cronfile = self::getCronModule($cron);
if ($cronfile && class_exists($cronfile)) { if ($cronfile && class_exists($cronfile)) {
$cronfile::run(); $cronfile::run();
} }
} }
self::refreshUsers($tasks_cnt['jobcnt']);
if ($tasks_cnt['jobcnt'] > 0) {
if (\Froxlor\Settings::Get('system.nssextrausers') == 1) {
\Froxlor\Cron\System\Extrausers::generateFiles(self::$cronlog);
}
// clear NSCD cache if using fcgid or fpm, #1570
if (\Froxlor\Settings::Get('system.mod_fcgid') == 1 || (int) \Froxlor\Settings::Get('phpfpm.enabled') == 1) {
$false_val = false;
\Froxlor\FileDir::safe_exec('nscd -i passwd 1> /dev/null', $false_val, array(
'>'
));
\Froxlor\FileDir::safe_exec('nscd -i group 1> /dev/null', $false_val, array(
'>'
));
}
}
} }
/** /**
@@ -132,6 +126,26 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
self::shutdown(); self::shutdown();
} }
private static function refreshUsers($jobcount = 0)
{
if ($jobcount > 0) {
if (\Froxlor\Settings::Get('system.nssextrausers') == 1) {
\Froxlor\Cron\System\Extrausers::generateFiles(self::$cronlog);
}
// clear NSCD cache if using fcgid or fpm, #1570 - not needed for nss-extrausers
if ((\Froxlor\Settings::Get('system.mod_fcgid') == 1 || (int) \Froxlor\Settings::Get('phpfpm.enabled') == 1) && \Froxlor\Settings::Get('system.nssextrausers') == 0) {
$false_val = false;
\Froxlor\FileDir::safe_exec('nscd -i passwd 1> /dev/null', $false_val, array(
'>'
));
\Froxlor\FileDir::safe_exec('nscd -i group 1> /dev/null', $false_val, array(
'>'
));
}
}
}
private static function init() private static function init()
{ {
if (@php_sapi_name() != 'cli' && @php_sapi_name() != 'cgi' && @php_sapi_name() != 'cgi-fcgi') { if (@php_sapi_name() != 'cli' && @php_sapi_name() != 'cgi' && @php_sapi_name() != 'cgi-fcgi') {
@@ -335,16 +349,6 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
} }
} }
private static function updateLastRunOfCron($cronname)
{
$upd_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `lastrun` = UNIX_TIMESTAMP() WHERE `cronfile` = :cron;
");
Database::pexecute($upd_stmt, array(
'cron' => $cronname
));
}
private static function getCronModule($cronname) private static function getCronModule($cronname)
{ {
$upd_stmt = Database::prepare(" $upd_stmt = Database::prepare("

View File

@@ -38,6 +38,24 @@ class MailboxsizeCron extends \Froxlor\Cron\FroxlorCron
$_maildir = \Froxlor\FileDir::makeCorrectDir($maildir['maildirpath']); $_maildir = \Froxlor\FileDir::makeCorrectDir($maildir['maildirpath']);
if (file_exists($_maildir) && is_dir($_maildir)) { if (file_exists($_maildir) && is_dir($_maildir)) {
$maildirsize = \Froxlor\FileDir::makeCorrectFile($_maildir . '/maildirsize');
// When quota is enabled and maildirsize file exists, use that to calculate size
if (\Froxlor\Settings::Get('system.mail_quota_enabled') == 1 && file_exists($maildirsize)) {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'found maildirsize file in ' . $_maildir);
$file = file($maildirsize, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// Remove header
array_shift($file);
$emailusage = 0;
// Sum up all the changes (line 2 -> end)
foreach ($file as $line) {
$parts = explode(' ', $line);
if (!empty($parts[0])) {
$emailusage += floatval($parts[0]);
}
}
} else {
// if quota is disabled or maildirsize file does not exist, compute with du
// mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part // mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part
$return = false; $return = false;
$back = \Froxlor\FileDir::safe_exec('du -sk ' . escapeshellarg($_maildir), $return, array( $back = \Froxlor\FileDir::safe_exec('du -sk ' . escapeshellarg($_maildir), $return, array(
@@ -58,6 +76,7 @@ class MailboxsizeCron extends \Froxlor\Cron\FroxlorCron
$emailusage *= 1024; $emailusage *= 1024;
unset($back); unset($back);
}
\Froxlor\Database\Database::pexecute($upd_stmt, array( \Froxlor\Database\Database::pexecute($upd_stmt, array(
'size' => $emailusage, 'size' => $emailusage,
'id' => $maildir['id'] 'id' => $maildir['id']

View File

@@ -30,8 +30,9 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
*/ */
self::$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, "TasksCron: Searching for tasks to do"); self::$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, "TasksCron: Searching for tasks to do");
// no type 99 (regenerate cron.d-file) and no type 20 (customer backup) // no type 99 (regenerate cron.d-file) and no type 20 (customer backup)
// order by type descending to re-create bind and then webserver at the end
$result_tasks_stmt = Database::query(" $result_tasks_stmt = Database::query("
SELECT `id`, `type`, `data` FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` <> '99' AND `type` <> '20' ORDER BY `id` ASC SELECT `id`, `type`, `data` FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` <> '99' AND `type` <> '20' ORDER BY `type` DESC, `id` ASC
"); ");
$num_results = Database::num_rows(); $num_results = Database::num_rows();
$resultIDs = array(); $resultIDs = array();
@@ -92,6 +93,12 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
*/ */
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, "Removing PowerDNS entries for domain " . $row['data']['domain']); \Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, "Removing PowerDNS entries for domain " . $row['data']['domain']);
\Froxlor\Dns\PowerDNS::cleanDomainZone($row['data']['domain']); \Froxlor\Dns\PowerDNS::cleanDomainZone($row['data']['domain']);
} elseif ($row['type'] == '12') {
/**
* TYPE=12 domain has been deleted, remove from acme.sh/let's encrypt directory if used
*/
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, "Removing Let's Encrypt entries for domain " . $row['data']['domain']);
\Froxlor\Domain\Domain::doLetsEncryptCleanUp($row['data']['domain']);
} }
} }
@@ -102,7 +109,7 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
$where[] = "`id` = :id_" . (int) $id; $where[] = "`id` = :id_" . (int) $id;
$where_data['id_' . $id] = $id; $where_data['id_' . $id] = $id;
} }
$where = implode($where, ' OR '); $where = implode(' OR ', $where);
$del_stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_TASKS . "` WHERE " . $where); $del_stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_TASKS . "` WHERE " . $where);
Database::pexecute($del_stmt, $where_data); Database::pexecute($del_stmt, $where_data);
unset($resultIDs); unset($resultIDs);
@@ -114,10 +121,6 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
private static function rebuildWebserverConfigs() private static function rebuildWebserverConfigs()
{ {
// get configuration-I/O object
$configio = new \Froxlor\Cron\Http\ConfigIO();
// clean up old configs
$configio->cleanUp();
if (Settings::Get('system.webserver') == "apache2") { if (Settings::Get('system.webserver') == "apache2") {
$websrv = '\\Froxlor\\Cron\\Http\\Apache'; $websrv = '\\Froxlor\\Cron\\Http\\Apache';
@@ -136,9 +139,15 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
} }
} }
// get configuration-I/O object
$configio = new \Froxlor\Cron\Http\ConfigIO();
// get webserver object
$webserver = new $websrv(); $webserver = new $websrv();
if (isset($webserver)) { if (isset($webserver)) {
$webserver->init();
// clean up old configs
$configio->cleanUp();
$webserver->createIpPort(); $webserver->createIpPort();
$webserver->createVirtualHosts(); $webserver->createVirtualHosts();
$webserver->createFileDirOptions(); $webserver->createFileDirOptions();
@@ -231,8 +240,8 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
Extrausers::generateFiles($extrausers_log); Extrausers::generateFiles($extrausers_log);
} }
// clear NSCD cache if using fcgid or fpm, #1570 // clear NSCD cache if using fcgid or fpm, #1570 - not needed for nss-extrausers
if (Settings::Get('system.mod_fcgid') == 1 || (int) Settings::Get('phpfpm.enabled') == 1) { if ((Settings::Get('system.mod_fcgid') == 1 || (int) Settings::Get('phpfpm.enabled') == 1) && Settings::Get('system.nssextrausers') == 0) {
$false_val = false; $false_val = false;
\Froxlor\FileDir::safe_exec('nscd -i passwd 1> /dev/null', $false_val, array( \Froxlor\FileDir::safe_exec('nscd -i passwd 1> /dev/null', $false_val, array(
'>' '>'

View File

@@ -183,6 +183,21 @@ class Database
return $return; return $return;
} }
/**
* return number of characters that are allowed to use as username
*
* @return int
*/
public static function getSqlUsernameLength()
{
// MySQL user names can be up to 32 characters long (16 characters before MySQL 5.7.8).
$mysql_max = 32;
if (version_compare(Database::getAttribute(\PDO::ATTR_SERVER_VERSION), '5.7.8', '<')) {
$mysql_max = 16;
}
return $mysql_max;
}
/** /**
* let's us interact with the PDO-Object by using static * let's us interact with the PDO-Object by using static
* call like "Database::function()" * call like "Database::function()"

View File

@@ -82,9 +82,11 @@ class DbManagerMySQL
if (version_compare(Database::getAttribute(\PDO::ATTR_SERVER_VERSION), '8.0.11', '>=')) { if (version_compare(Database::getAttribute(\PDO::ATTR_SERVER_VERSION), '8.0.11', '>=')) {
// create user // create user
$stmt = Database::prepare(" $stmt = Database::prepare("
CREATE USER '" . $username . "'@'" . $access_host . "' IDENTIFIED BY 'password' CREATE USER '" . $username . "'@'" . $access_host . "' IDENTIFIED BY :password
"); ");
Database::pexecute($stmt); Database::pexecute($stmt, array(
"password" => $password
));
// grant privileges // grant privileges
$stmt = Database::prepare(" $stmt = Database::prepare("
GRANT ALL ON `" . $username . "`.* TO :username@:host GRANT ALL ON `" . $username . "`.* TO :username@:host
@@ -96,14 +98,15 @@ class DbManagerMySQL
} else { } else {
// grant privileges // grant privileges
$stmt = Database::prepare(" $stmt = Database::prepare("
GRANT ALL PRIVILEGES ON `" . $username . "`.* TO :username@:host IDENTIFIED BY 'password' GRANT ALL PRIVILEGES ON `" . $username . "`.* TO :username@:host IDENTIFIED BY :password
"); ");
Database::pexecute($stmt, array( Database::pexecute($stmt, array(
"username" => $username, "username" => $username,
"host" => $access_host "host" => $access_host,
"password" => $password
)); ));
} }
} } else {
// set passoword // set passoword
if (version_compare(Database::getAttribute(\PDO::ATTR_SERVER_VERSION), '5.7.6', '<')) { if (version_compare(Database::getAttribute(\PDO::ATTR_SERVER_VERSION), '5.7.6', '<')) {
if ($p_encrypted) { if ($p_encrypted) {
@@ -120,6 +123,7 @@ class DbManagerMySQL
"password" => $password "password" => $password
)); ));
} }
}
/** /**
* removes the given database from the dbms and also * removes the given database from the dbms and also
@@ -142,7 +146,11 @@ class DbManagerMySQL
)); ));
// as of MySQL 5.0.2 this also revokes privileges. (requires MySQL 4.1.2+) // as of MySQL 5.0.2 this also revokes privileges. (requires MySQL 4.1.2+)
if (version_compare(Database::getAttribute(\PDO::ATTR_SERVER_VERSION), '5.7.0', '<')) {
$drop_stmt = Database::prepare("DROP USER :dbname@:host");
} else {
$drop_stmt = Database::prepare("DROP USER IF EXISTS :dbname@:host"); $drop_stmt = Database::prepare("DROP USER IF EXISTS :dbname@:host");
}
while ($host = $host_res_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($host = $host_res_stmt->fetch(\PDO::FETCH_ASSOC)) {
Database::pexecute($drop_stmt, array( Database::pexecute($drop_stmt, array(
'dbname' => $dbname, 'dbname' => $dbname,
@@ -150,6 +158,7 @@ class DbManagerMySQL
), false); ), false);
} }
$drop_stmt = Database::prepare("DROP DATABASE IF EXISTS `" . $dbname . "`"); $drop_stmt = Database::prepare("DROP DATABASE IF EXISTS `" . $dbname . "`");
Database::pexecute($drop_stmt); Database::pexecute($drop_stmt);
} }
@@ -168,7 +177,11 @@ class DbManagerMySQL
Database::pexecute($stmt); Database::pexecute($stmt);
} }
// as of MySQL 5.0.2 this also revokes privileges. (requires MySQL 4.1.2+) // as of MySQL 5.0.2 this also revokes privileges. (requires MySQL 4.1.2+)
if (version_compare(Database::getAttribute(\PDO::ATTR_SERVER_VERSION), '5.7.0', '<')) {
$stmt = Database::prepare("DROP USER :username@:host"); $stmt = Database::prepare("DROP USER :username@:host");
} else {
$stmt = Database::prepare("DROP USER IF EXISTS :username@:host");
}
Database::pexecute($stmt, array( Database::pexecute($stmt, array(
"username" => $username, "username" => $username,
"host" => $host "host" => $host

View File

@@ -130,6 +130,12 @@ class Dns
} }
} }
// additional required records for CAA if activated
if (Settings::Get('system.dns_createcaaentry') && Settings::Get('system.use_ssl') == "1" && !empty($domain['p_ssl_ipandports'])) {
// check for CAA content later
self::addRequiredEntry('@CAA@', 'CAA', $required_entries);
}
// additional required records for SPF and DKIM if activated // additional required records for SPF and DKIM if activated
if ($domain['isemaildomain'] == '1') { if ($domain['isemaildomain'] == '1') {
if (Settings::Get('spf.use_spf') == '1') { if (Settings::Get('spf.use_spf') == '1') {
@@ -150,6 +156,10 @@ class Dns
if (array_key_exists($entry['type'], $required_entries) && array_key_exists(md5($entry['record']), $required_entries[$entry['type']])) { if (array_key_exists($entry['type'], $required_entries) && array_key_exists(md5($entry['record']), $required_entries[$entry['type']])) {
unset($required_entries[$entry['type']][md5($entry['record'])]); unset($required_entries[$entry['type']][md5($entry['record'])]);
} }
if (Settings::Get('system.dns_createcaaentry') == '1' && $entry['type'] == 'CAA' && strtolower(substr($entry['content'], 0, 7)) == '"v=caa1') {
// 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') {
// unset special spf required-entry // unset special spf required-entry
unset($required_entries[$entry['type']][md5("@SPF@")]); unset($required_entries[$entry['type']][md5("@SPF@")]);
@@ -278,6 +288,31 @@ class Dns
} }
} }
} }
// CAA
if (array_key_exists("CAA", $required_entries)) {
foreach ($required_entries as $type => $records) {
if ($type == 'CAA') {
foreach ($records as $record) {
if ($record == '@CAA@') {
$caa_entries = explode(PHP_EOL, Settings::Get('caa.caa_entry'));
if ($domain['letsencrypt'] == 1) {
$le_entry = $domain['iswildcarddomain'] == '1' ? '0 issuewild "letsencrypt.org"' : '0 issue "letsencrypt.org"';
array_push($caa_entries, $le_entry);
}
foreach ($caa_entries as $entry) {
$zonerecords[] = new DnsEntry('@', 'CAA', $entry);
// additional required records by subdomain setting
if ($domain['wwwserveralias'] == '1') {
$zonerecords[] = new DnsEntry('www', 'CAA', $entry);
}
}
}
}
}
}
}
} }
if (empty($primary_ns)) { if (empty($primary_ns)) {

View File

@@ -291,6 +291,30 @@ class Domain
} }
} }
public static function doLetsEncryptCleanUp($domainname = null)
{
// @ see \Froxlor\Cron\Http\LetsEncrypt\AcmeSh.php
$acmesh = "/root/.acme.sh/acme.sh";
if (file_exists($acmesh)) {
$certificate_folder = dirname($acmesh) . "/" . $domainname;
if (\Froxlor\Settings::Get('system.leecc') > 0) {
$certificate_folder .= "_ecc";
}
$certificate_folder = \Froxlor\FileDir::makeCorrectDir($certificate_folder);
if (file_exists($certificate_folder)) {
$params = " --remove -d " . $domainname;
if (\Froxlor\Settings::Get('system.leecc') > 0) {
$params .= " --ecc";
}
// run remove command
\Froxlor\FileDir::safe_exec($acmesh . $params);
// remove certificates directory
@unlink($certificate_folder);
}
}
return true;
}
/** /**
* checks give path for security issues * checks give path for security issues
* and returns a string that can be appended * and returns a string that can be appended

View File

@@ -217,7 +217,7 @@ class FileDir
'ADMIN_EMAIL' => $template['admin_email'] 'ADMIN_EMAIL' => $template['admin_email']
); );
// @fixme replaceVariables // replaceVariables
$htmlcontent = PhpHelper::replaceVariables($template['value'], $replace_arr); $htmlcontent = PhpHelper::replaceVariables($template['value'], $replace_arr);
$indexhtmlpath = self::makeCorrectFile($destination . '/index.' . Settings::Get('system.index_file_extension')); $indexhtmlpath = self::makeCorrectFile($destination . '/index.' . Settings::Get('system.index_file_extension'));
$index_html_handler = fopen($indexhtmlpath, 'w'); $index_html_handler = fopen($indexhtmlpath, 'w');

View File

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

View File

@@ -40,6 +40,13 @@ class FroxlorLogger
*/ */
private static $userinfo = array(); private static $userinfo = array();
/**
* whether the logger object has already been initialized
*
* @var bool
*/
private static $is_initialized = false;
const USR_ACTION = '10'; const USR_ACTION = '10';
const RES_ACTION = '20'; const RES_ACTION = '20';
@@ -72,6 +79,7 @@ class FroxlorLogger
} }
} }
if (self::$is_initialized == false) {
foreach (self::$logtypes as $logger) { foreach (self::$logtypes as $logger) {
switch ($logger) { switch ($logger) {
@@ -79,6 +87,9 @@ class FroxlorLogger
self::$ml->pushHandler(new SyslogHandler('froxlor', LOG_USER, Logger::DEBUG)); self::$ml->pushHandler(new SyslogHandler('froxlor', LOG_USER, Logger::DEBUG));
break; break;
case 'file': case 'file':
if (empty(Settings::Get('logger.logfile')) || ! is_writeable(Settings::Get('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(Settings::Get('logger.logfile'), Logger::DEBUG));
break; break;
case 'mysql': case 'mysql':
@@ -86,6 +97,8 @@ class FroxlorLogger
break; break;
} }
} }
self::$is_initialized = true;
}
} }
/** /**

View File

@@ -11,7 +11,7 @@ class HttpClient
* *
* @return array * @return array
*/ */
public static function urlGet($url, $follow_location = true) public static function urlGet($url, $follow_location = true, $timeout = 10)
{ {
$ch = curl_init(); $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_URL, $url);
@@ -19,6 +19,7 @@ class HttpClient
if ($follow_location) { if ($follow_location) {
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
} }
curl_setopt($ch, CURLOPT_TIMEOUT, (int)$timeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch); $output = curl_exec($ch);
if ($output === false) { if ($output === false) {

View File

@@ -101,13 +101,13 @@ class MailLogParser
$timestamp = $this->getLogTimestamp($line); $timestamp = $this->getLogTimestamp($line);
if ($this->startTime < $timestamp) { if ($this->startTime < $timestamp) {
if (preg_match("/postfix\/qmgr.*(?::|\])\s([A-Z\d]+).*from=<?(?:.*\@([a-z\A-Z\d\.\-]+))?>?, size=(\d+),/", $line, $matches)) { if (preg_match("/postfix\/qmgr.*(?::|\])\s([A-Z\d]+).*from=<?(?:.*\@([a-zA-Z\d\.\-]+))?>?, size=(\d+),/", $line, $matches)) {
// Postfix from // Postfix from
$this->mails[$matches[1]] = array( $this->mails[$matches[1]] = array(
"domainFrom" => strtolower($matches[2]), "domainFrom" => strtolower($matches[2]),
"size" => $matches[3] "size" => $matches[3]
); );
} elseif (preg_match("/postfix\/(?:pipe|smtp).*(?::|\])\s([A-Z\d]+).*to=<?(?:.*\@([a-z\A-Z\d\.\-]+))?>?,/", $line, $matches)) { } elseif (preg_match("/postfix\/(?:pipe|smtp).*(?::|\])\s([A-Z\d]+).*to=<?(?:.*\@([a-zA-Z\d\.\-]+))?>?,/", $line, $matches)) {
// Postfix to // Postfix to
if (array_key_exists($matches[1], $this->mails)) { if (array_key_exists($matches[1], $this->mails)) {
$this->mails[$matches[1]]["domainTo"] = strtolower($matches[2]); $this->mails[$matches[1]]["domainTo"] = strtolower($matches[2]);

View File

@@ -263,6 +263,8 @@ class Settings
self::init(); self::init();
// empty update array // empty update array
self::$updatedata = array(); self::$updatedata = array();
// re-read in all settings
return self::readSettings();
} }
public static function loadSettingsInto(&$settings_data) public static function loadSettingsInto(&$settings_data)

View File

@@ -27,44 +27,7 @@ class Store
$returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue); $returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue);
if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'system' && isset($fielddata['varname']) && $fielddata['varname'] == 'defaultip') { if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'system' && isset($fielddata['varname']) && $fielddata['varname'] == 'defaultip') {
self::updateStdSubdomainDefaultIp($newfieldvalue, $defaultips_old);
$customerstddomains_result_stmt = Database::prepare("
SELECT `standardsubdomain` FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `standardsubdomain` <> '0'
");
Database::pexecute($customerstddomains_result_stmt);
$ids = array();
while ($customerstddomains_row = $customerstddomains_result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$ids[] = (int) $customerstddomains_row['standardsubdomain'];
}
if (count($ids) > 0) {
$defaultips_new = explode(',', $newfieldvalue);
// Delete the existing mappings linking to default IPs
$del_stmt = Database::prepare("
DELETE FROM `" . TABLE_DOMAINTOIP . "`
WHERE `id_domain` IN (" . implode(', ', $ids) . ")
AND `id_ipandports` IN (" . $defaultips_old . ", " . $newfieldvalue . ")
");
Database::pexecute($del_stmt);
// Insert the new mappings
$ins_stmt = Database::prepare("
INSERT INTO `" . TABLE_DOMAINTOIP . "`
SET `id_domain` = :domainid, `id_ipandports` = :ipandportid
");
foreach ($ids as $id) {
foreach ($defaultips_new as $defaultip_new) {
Database::pexecute($ins_stmt, array(
'domainid' => $id,
'ipandportid' => $defaultip_new
));
}
}
}
} }
return $returnvalue; return $returnvalue;
@@ -77,14 +40,21 @@ class Store
$returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue); $returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue);
if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'system' && isset($fielddata['varname']) && $fielddata['varname'] == 'defaultsslip') { if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'system' && isset($fielddata['varname']) && $fielddata['varname'] == 'defaultsslip') {
self::updateStdSubdomainDefaultIp($newfieldvalue, $defaultips_old);
}
return $returnvalue;
}
private static function updateStdSubdomainDefaultIp($newfieldvalue, $defaultips_old)
{
// update standard-subdomain of customer if exists
$customerstddomains_result_stmt = Database::prepare(" $customerstddomains_result_stmt = Database::prepare("
SELECT `standardsubdomain` FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `standardsubdomain` <> '0' SELECT `standardsubdomain` FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `standardsubdomain` <> '0'
"); ");
Database::pexecute($customerstddomains_result_stmt); Database::pexecute($customerstddomains_result_stmt);
$ids = array(); $ids = array();
while ($customerstddomains_row = $customerstddomains_result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($customerstddomains_row = $customerstddomains_result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$ids[] = (int) $customerstddomains_row['standardsubdomain']; $ids[] = (int) $customerstddomains_row['standardsubdomain'];
} }
@@ -127,9 +97,6 @@ class Store
} }
} }
return $returnvalue;
}
/** /**
* updates the setting for the default panel-theme * updates the setting for the default panel-theme
* and also the user themes (customers and admins) if * and also the user themes (customers and admins) if
@@ -143,12 +110,11 @@ class Store
*/ */
public static function storeSettingDefaultTheme($fieldname, $fielddata, $newfieldvalue) public static function storeSettingDefaultTheme($fieldname, $fielddata, $newfieldvalue)
{ {
// first save the setting itself // first save the setting itself
$returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue); $returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue);
if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'panel' && isset($fielddata['varname']) && $fielddata['varname'] == 'default_theme') { if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'panel' && isset($fielddata['varname']) && $fielddata['varname'] == 'default_theme') {
// now, if changing themes is disabled we recursivly set // now, if changing themes is disabled we manually set
// the new theme (customers and admin, depending on settings) // the new theme (customers and admin, depending on settings)
if (Settings::Get('panel.allow_theme_change_customer') == '0') { if (Settings::Get('panel.allow_theme_change_customer') == '0') {
$upd_stmt = Database::prepare(" $upd_stmt = Database::prepare("
@@ -204,18 +170,14 @@ class Store
public static function storeSettingFieldInsertBindTask($fieldname, $fielddata, $newfieldvalue) public static function storeSettingFieldInsertBindTask($fieldname, $fielddata, $newfieldvalue)
{ {
if (is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] != '' && isset($fielddata['varname']) && $fielddata['varname'] != '') { // first save the setting itself
if (Settings::Set($fielddata['settinggroup'] . '.' . $fielddata['varname'], $newfieldvalue) !== false) { $returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue);
return array(
$fielddata['settinggroup'] . '.' . $fielddata['varname'] => $newfieldvalue if ($returnvalue !== false) {
); \Froxlor\System\Cronjob::inserttask('4');
} else {
return false;
} }
} else {
return false; return false;
} }
}
public static function storeSettingHostname($fieldname, $fielddata, $newfieldvalue) public static function storeSettingHostname($fieldname, $fielddata, $newfieldvalue)
{ {
@@ -330,25 +292,9 @@ class Store
$returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue); $returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue);
if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'catchall' && isset($fielddata['varname']) && $fielddata['varname'] == 'catchall_enabled' && $newfieldvalue == '0') { if ($returnvalue !== false && is_array($fielddata) && isset($fielddata['settinggroup']) && $fielddata['settinggroup'] == 'catchall' && isset($fielddata['varname']) && $fielddata['varname'] == 'catchall_enabled' && $newfieldvalue == '0') {
Database::query("
$result_stmt = Database::query(" UPDATE `" . TABLE_MAIL_VIRTUAL . "` SET `iscatchall` = '0' WHERE `iscatchall` = '1'
SELECT `id`, `email`, `email_full`, `iscatchall` FROM `" . TABLE_MAIL_VIRTUAL . "`
WHERE `iscatchall` = '1'
"); ");
if (Database::num_rows() > 0) {
$upd_stmt = Database::prepare("
UPDATE `" . TABLE_MAIL_VIRTUAL . "` SET `email` = :email, `iscatchall` = '0' WHERE `id` = :id
");
while ($result_row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
Database::pexecute($upd_stmt, array(
'email' => $result_row['email_full'],
'id' => $result_row['id']
));
}
}
} }
return $returnvalue; return $returnvalue;

View File

@@ -178,6 +178,14 @@ class Cronjob
'type' => '11', 'type' => '11',
'data' => $data 'data' => $data
)); ));
} elseif ($type == '12' && $param1 != '') {
$data = array();
$data['domain'] = $param1;
$data = json_encode($data);
Database::pexecute($ins_stmt, array(
'type' => '12',
'data' => $data
));
} elseif ($type == '20' && is_array($param1)) { } elseif ($type == '20' && is_array($param1)) {
$data = json_encode($param1); $data = json_encode($param1);
Database::pexecute($ins_stmt, array( Database::pexecute($ins_stmt, array(
@@ -277,6 +285,9 @@ class Cronjob
} elseif ($row['type'] == '11') { } elseif ($row['type'] == '11') {
// remove domain from pdns database if used // remove domain from pdns database if used
$task_desc = sprintf($lng['tasks']['remove_pdns_domain'], $row['data']['domain']); $task_desc = sprintf($lng['tasks']['remove_pdns_domain'], $row['data']['domain']);
} elseif ($row['type'] == '12') {
// remove domains ssl files
$task_desc = sprintf($lng['tasks']['remove_ssl_domain'], $row['data']['domain']);
} elseif ($row['type'] == '20') { } elseif ($row['type'] == '20') {
// deleting user-files // deleting user-files
$loginname = ''; $loginname = '';
@@ -350,4 +361,14 @@ class Cronjob
die($message); die($message);
} }
public static function updateLastRunOfCron($cronname)
{
$upd_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `lastrun` = UNIX_TIMESTAMP() WHERE `cronfile` = :cron;
");
Database::pexecute($upd_stmt, array(
'cron' => $cronname
));
}
} }

View File

@@ -57,7 +57,7 @@ class MysqlHandler extends AbstractProcessingHandler
{ {
$this->insert([ $this->insert([
':message' => $record['message'], ':message' => $record['message'],
':contextUser' => (isset($record['context']['loginname']) ? $record['context']['loginname'] : 'unknown'), ':contextUser' => (isset($record['context']['user']) ? $record['context']['user'] : 'unknown'),
':contextAction' => (isset($record['context']['action']) ? $record['context']['action'] : '0'), ':contextAction' => (isset($record['context']['action']) ? $record['context']['action'] : '0'),
':level' => self::$froxlorLevels[$record['level']], ':level' => self::$froxlorLevels[$record['level']],
':datetime' => $record['datetime']->format('U') ':datetime' => $record['datetime']->format('U')

View File

@@ -282,7 +282,7 @@ class Paging
$field .= '`'; $field .= '`';
} }
if ($field{0} != '`') { if ($field[0] != '`') {
$field = '`' . $field; $field = '`' . $field;
} }
@@ -352,7 +352,7 @@ class Paging
$field .= '`'; $field .= '`';
} }
if ($field{0} != '`') { if ($field[0] != '`') {
$field = '`' . $field; $field = '`' . $field;
} }

View File

@@ -192,7 +192,7 @@ class Check
} }
$returnvalue = array(); $returnvalue = array();
if (Validate::validateUsername($newfieldvalue, Settings::Get('panel.unix_names'), 14 - strlen($allnewfieldvalues['customer_mysqlprefix'])) === true) { if (Validate::validateUsername($newfieldvalue, Settings::Get('panel.unix_names'), \Froxlor\Database\Database::getSqlUsernameLength() - strlen($allnewfieldvalues['customer_mysqlprefix'])) === true) {
$returnvalue = array( $returnvalue = array(
self::FORMFIELDS_PLAUSIBILITY_CHECK_OK self::FORMFIELDS_PLAUSIBILITY_CHECK_OK
); );

View File

@@ -33,7 +33,7 @@ class Data
if (isset($fielddata['string_type']) && $fielddata['string_type'] == 'mail') { if (isset($fielddata['string_type']) && $fielddata['string_type'] == 'mail') {
$returnvalue = (filter_var($newfieldvalue, FILTER_VALIDATE_EMAIL) == $newfieldvalue); $returnvalue = (filter_var($newfieldvalue, FILTER_VALIDATE_EMAIL) == $newfieldvalue);
} elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'url') { } elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'url') {
$returnvalue = self::validateUrl($newfieldvalue); $returnvalue = \Froxlor\Validate\Validate::validateUrl($newfieldvalue);
} elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'dir') { } elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'dir') {
// check for empty value (it might be allowed) // check for empty value (it might be allowed)
if (trim($newfieldvalue) == '') { if (trim($newfieldvalue) == '') {
@@ -128,62 +128,6 @@ class Data
} }
} }
/**
* Returns whether a URL is in a correct format or not
*
* @param string $url
* URL to be tested
* @return bool
* @author Christian Hoffmann
* @author Froxlor team <team@froxlor.org> (2010-)
*
*/
public static function validateUrl($url)
{
if (strtolower(substr($url, 0, 7)) != "http://" && strtolower(substr($url, 0, 8)) != "https://") {
$url = 'http://' . $url;
}
// needs converting
try {
$idna_convert = new \Froxlor\Idna\IdnaWrapper();
$url = $idna_convert->encode($url);
} catch (\Exception $e) {
return false;
}
$pattern = "/^https?:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,4}(\:[0-9]+)?\/?(.+)?$/i";
if (preg_match($pattern, $url)) {
return true;
}
// not an fqdn
if (strtolower(substr($url, 0, 7)) == "http://" || strtolower(substr($url, 0, 8)) == "https://") {
if (strtolower(substr($url, 0, 7)) == "http://") {
$ip = strtolower(substr($url, 7));
}
if (strtolower(substr($url, 0, 8)) == "https://") {
$ip = strtolower(substr($url, 8));
}
$ip = substr($ip, 0, strpos($ip, '/'));
// possible : in IP (when a port is given), #1173
// but only if there actually IS ONE
if (strpos($ip, ':') !== false) {
$ip = substr($ip, 0, strpos($ip, ':'));
}
if (validate_ip($ip, true) !== false) {
return true;
} else {
return false;
}
} else {
return false;
}
}
public static function validateFormFieldBool($fieldname, $fielddata, $newfieldvalue) public static function validateFormFieldBool($fieldname, $fielddata, $newfieldvalue)
{ {
if ($newfieldvalue === '1' || $newfieldvalue === 1 || $newfieldvalue === true || strtolower($newfieldvalue) === 'yes' || strtolower($newfieldvalue) === 'ja' || $newfieldvalue === '0' || $newfieldvalue === 0 || $newfieldvalue === false || strtolower($newfieldvalue) === 'no' || strtolower($newfieldvalue) === 'nein' || strtolower($newfieldvalue) === '') { if ($newfieldvalue === '1' || $newfieldvalue === 1 || $newfieldvalue === true || strtolower($newfieldvalue) === 'yes' || strtolower($newfieldvalue) === 'ja' || $newfieldvalue === '0' || $newfieldvalue === 0 || $newfieldvalue === false || strtolower($newfieldvalue) === 'no' || strtolower($newfieldvalue) === 'nein' || strtolower($newfieldvalue) === '') {
@@ -252,7 +196,7 @@ class Data
if (isset($fielddata['string_type']) && $fielddata['string_type'] == 'mail') { if (isset($fielddata['string_type']) && $fielddata['string_type'] == 'mail') {
$returnvalue = (filter_var($newfieldvalue, FILTER_VALIDATE_EMAIL) == $newfieldvalue); $returnvalue = (filter_var($newfieldvalue, FILTER_VALIDATE_EMAIL) == $newfieldvalue);
} elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'url') { } elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'url') {
$returnvalue = \Froxlor\Validate\Form\Data::validateUrl($newfieldvalue); $returnvalue = \Froxlor\Validate\Validate::validateUrl($newfieldvalue);
} elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'dir') { } elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'dir') {
// add trailing slash to validate path if needed // add trailing slash to validate path if needed
// refs #331 // refs #331

View File

@@ -23,8 +23,6 @@ class Validate
*/ */
public static function validate($str, $fieldname, $pattern = '', $lng = '', $emptydefault = array(), $throw_exception = false) public static function validate($str, $fieldname, $pattern = '', $lng = '', $emptydefault = array(), $throw_exception = false)
{ {
global $log;
if (! is_array($emptydefault)) { if (! is_array($emptydefault)) {
$emptydefault_array = array( $emptydefault_array = array(
$emptydefault $emptydefault
@@ -35,8 +33,8 @@ class Validate
} }
// Check if the $str is one of the values which represent the default for an 'empty' value // Check if the $str is one of the values which represent the default for an 'empty' value
if (is_array($emptydefault) && ! empty($emptydefault) && in_array($str, $emptydefault) && isset($emptydefault[0])) { if (is_array($emptydefault) && ! empty($emptydefault) && in_array($str, $emptydefault)) {
return $emptydefault[0]; return $str;
} }
if ($pattern == '') { if ($pattern == '') {
@@ -48,6 +46,7 @@ class Validate
// everything else is removed from the string. // everything else is removed from the string.
$allowed = "/[^a-z0-9\\040\\.\\-\\_\\\\]/i"; $allowed = "/[^a-z0-9\\040\\.\\-\\_\\\\]/i";
$str = preg_replace($allowed, "", $str); $str = preg_replace($allowed, "", $str);
$log = \Froxlor\FroxlorLogger::getInstanceOf();
$log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "cleaned bad formatted string (" . $str . ")"); $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "cleaned bad formatted string (" . $str . ")");
} }
} }
@@ -61,7 +60,6 @@ class Validate
} }
\Froxlor\UI\Response::standard_error($lng, $fieldname, $throw_exception); \Froxlor\UI\Response::standard_error($lng, $fieldname, $throw_exception);
exit();
} }
/** /**
@@ -99,7 +97,6 @@ class Validate
return false; return false;
} else { } else {
\Froxlor\UI\Response::standard_error($lng, $ip, $throw_exception); \Froxlor\UI\Response::standard_error($lng, $ip, $throw_exception);
exit();
} }
} }
@@ -118,10 +115,39 @@ class Validate
return false; return false;
} else { } else {
\Froxlor\UI\Response::standard_error($lng, $ip, $throw_exception); \Froxlor\UI\Response::standard_error($lng, $ip, $throw_exception);
exit();
} }
} }
/**
* Returns whether a URL is in a correct format or not
*
* @param string $url
* URL to be tested
*
* @return bool
*/
public static function validateUrl($url)
{
if (strtolower(substr($url, 0, 7)) != "http://" && strtolower(substr($url, 0, 8)) != "https://") {
$url = 'http://' . $url;
}
// needs converting
try {
$idna_convert = new \Froxlor\Idna\IdnaWrapper();
$url = $idna_convert->encode($url);
} catch (\Exception $e) {
return false;
}
$pattern = '%^(?:(?:https?)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$%iuS';
if (preg_match($pattern, $url)) {
return true;
}
return false;
}
/** /**
* Check if the submitted string is a valid domainname * Check if the submitted string is a valid domainname
* *
@@ -157,7 +183,7 @@ class Validate
*/ */
public static function validateLocalHostname($hostname) public static function validateLocalHostname($hostname)
{ {
$pattern = '/^([a-zA-Z0-9\-])+$/i'; $pattern = '/^[a-z0-9][a-z0-9\-]{0,62}$/i';
if (preg_match($pattern, $hostname)) { if (preg_match($pattern, $hostname)) {
return $hostname; return $hostname;
} }
@@ -180,29 +206,41 @@ class Validate
/** /**
* Returns if an username is in correct format or not. * Returns if an username is in correct format or not.
* *
* @param * @param string $username
* string The username to check * The username to check
* @return bool Correct or not * @param bool $unix_names
* @author Michael Duergner <michael@duergner.com> * optional, default true, checks whether it must be UNIX compatible
* @param int $mysql_max
* optional, number of max mysql username characters, default empty
* *
* @return bool
*/ */
public static function validateUsername($username, $unix_names = 1, $mysql_max = '') public static function validateUsername($username, $unix_names = 1, $mysql_max = '')
{ {
if (empty($mysql_max) || ! is_numeric($mysql_max) || $mysql_max <= 0) {
$mysql_max = \Froxlor\Database\Database::getSqlUsernameLength() - 1;
} else {
$mysql_max --;
}
if ($unix_names == 0) { if ($unix_names == 0) {
if (strpos($username, '--') === false) { if (strpos($username, '--') === false) {
return (preg_match('/^[a-z][a-z0-9\-_]{0,' . (int) ($mysql_max - 1) . '}[a-z0-9]{1}$/Di', $username) != false); return (preg_match('/^[a-z][a-z0-9\-_]{0,' . $mysql_max . '}[a-z0-9]{1}$/Di', $username) != false);
} else { }
return false; return false;
} }
} else {
return (preg_match('/^[a-z][a-z0-9]{0,' . $mysql_max . '}$/Di', $username) != false); return (preg_match('/^[a-z][a-z0-9]{0,' . $mysql_max . '}$/Di', $username) != false);
} }
}
/**
* validate sql interval string
*
* @param string $interval
*
* @return boolean
*/
public static function validateSqlInterval($interval = null) public static function validateSqlInterval($interval = null)
{ {
if (! $interval === null || $interval != '') { if (! empty($interval) && strstr($interval, ' ') !== false) {
if (strstr($interval, ' ') !== false) {
/* /*
* [0] = ([0-9]+) * [0] = ([0-9]+)
* [1] = valid SQL-Interval expression * [1] = valid SQL-Interval expression
@@ -219,15 +257,10 @@ class Validate
$interval_parts = explode(' ', $interval); $interval_parts = explode(' ', $interval);
if (is_array($interval_parts) && isset($interval_parts[0]) && isset($interval_parts[1])) { if (count($interval_parts) == 2 && preg_match('/[0-9]+/', $interval_parts[0]) && in_array(strtoupper($interval_parts[1]), $valid_expr)) {
if (preg_match('/([0-9]+)/i', $interval_parts[0])) {
if (in_array(strtoupper($interval_parts[1]), $valid_expr)) {
return true; return true;
} }
} }
}
}
}
return false; return false;
} }
} }

4675
lib/configfiles/bionic.xml Normal file

File diff suppressed because it is too large Load Diff

4877
lib/configfiles/buster.xml Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -405,11 +405,6 @@ allow-axfr-ips=127.0.0.0/8,::1,<NAMESERVERS_IP>
# #
# allow-dnsupdate-from=127.0.0.0/8,::1 # allow-dnsupdate-from=127.0.0.0/8,::1
#################################
# allow-recursion List of subnets that are allowed to recurse
#
allow-recursion=127.0.0.1
################################# #################################
# also-notify When notifying a domain, also notify these nameservers # also-notify When notifying a domain, also notify these nameservers
# #
@@ -750,16 +745,6 @@ module-dir=/usr/lib/powerdns/pdns/
# #
# receiver-threads=1 # receiver-threads=1
#################################
# recursive-cache-ttl Seconds to store packets for recursive queries in the PacketCache
#
# recursive-cache-ttl=10
#################################
# recursor If recursion is desired, IP address of a recursing nameserver
#
# recursor=no
################################# #################################
# retrieval-threads Number of AXFR-retrieval threads for slave operation # retrieval-threads Number of AXFR-retrieval threads for slave operation
# #
@@ -949,11 +934,6 @@ allow-axfr-ips=127.0.0.0/8,::1,<NAMESERVERS_IP>
# #
# allow-dnsupdate-from=127.0.0.0/8,::1 # allow-dnsupdate-from=127.0.0.0/8,::1
#################################
# allow-recursion List of subnets that are allowed to recurse
#
allow-recursion=127.0.0.1
################################# #################################
# also-notify When notifying a domain, also notify these nameservers # also-notify When notifying a domain, also notify these nameservers
# #
@@ -1294,16 +1274,6 @@ module-dir=/usr/lib/powerdns/pdns/
# #
# receiver-threads=1 # receiver-threads=1
#################################
# recursive-cache-ttl Seconds to store packets for recursive queries in the PacketCache
#
# recursive-cache-ttl=10
#################################
# recursor If recursion is desired, IP address of a recursing nameserver
#
# recursor=no
################################# #################################
# retrieval-threads Number of AXFR-retrieval threads for slave operation # retrieval-threads Number of AXFR-retrieval threads for slave operation
# #
@@ -1504,7 +1474,7 @@ user = <SQL_UNPRIVILEGED_USER>
password = <SQL_UNPRIVILEGED_PASSWORD> password = <SQL_UNPRIVILEGED_PASSWORD>
dbname = <SQL_DB> dbname = <SQL_DB>
hosts = <SQL_HOST> hosts = <SQL_HOST>
query = SELECT destination FROM mail_virtual WHERE email = '%s' AND trim(destination) <> '' query = SELECT destination FROM mail_virtual AS v, panel_customers AS c WHERE c.customerid = v.customerid AND c.deactivated = 0 AND v.email = '%s' AND trim(v.destination) <> ''
]]> ]]>
</content> </content>
</file> </file>
@@ -3687,21 +3657,7 @@ account required pam_mysql.so user=<SQL_UNPRIVILEGED_USER> passwd=<SQL_UN
<!-- Cronjob --> <!-- Cronjob -->
<daemon name="cron" title="Cronjob for froxlor" <daemon name="cron" title="Cronjob for froxlor"
mandatory="true"> mandatory="true">
<file name="/etc/cron.d/froxlor" chown="root:0" chmod="0640"> <command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
<content><![CDATA[
#
# Set PATH, otherwise restart-scripts won't find start-stop-daemon
#
PATH=/sbin:/bin:/usr/sbin:/usr/bin
#
# Regular cron jobs for the froxlor package
#
# Please check that all following paths are correct
#
*/5 * * * * root /usr/bin/nice -n 5 /usr/bin/php -q <BASE_PATH>scripts/froxlor_master_cronjob.php
]]>
</content>
</file>
<command><![CDATA[{{settings.system.crondreload}}]]></command> <command><![CDATA[{{settings.system.crondreload}}]]></command>
</daemon> </daemon>
<!-- AWstats --> <!-- AWstats -->

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<froxlor> <froxlor>
<distribution name="Debian" codename="Jessie" <distribution name="Debian" codename="Jessie"
version="8.x" defaulteditor="/usr/bin/nano"> version="8.x" defaulteditor="/usr/bin/nano" deprecated="true">
<services> <services>
<!-- HTTP --> <!-- HTTP -->
<service type="http" title="{{lng.admin.configfiles.http}}"> <service type="http" title="{{lng.admin.configfiles.http}}">
@@ -1504,7 +1504,7 @@ user = <SQL_UNPRIVILEGED_USER>
password = <SQL_UNPRIVILEGED_PASSWORD> password = <SQL_UNPRIVILEGED_PASSWORD>
dbname = <SQL_DB> dbname = <SQL_DB>
hosts = <SQL_HOST> hosts = <SQL_HOST>
query = SELECT destination FROM mail_virtual WHERE email = '%s' AND trim(destination) <> '' query = SELECT destination FROM mail_virtual AS v, panel_customers AS c WHERE c.customerid = v.customerid AND c.deactivated = 0 AND v.email = '%s' AND trim(v.destination) <> ''
]]> ]]>
</content> </content>
</file> </file>
@@ -3658,7 +3658,7 @@ protocol sieve {
# %m - number of messages (before deletion) # %m - number of messages (before deletion)
# %s - mailbox size in bytes (before deletion) # %s - mailbox size in bytes (before deletion)
# %u - old/new UIDL hash. may help finding out if UIDLs changed unexpectedly # %u - old/new UIDL hash. may help finding out if UIDLs changed unexpectedly
#pop3_logout_format = top=%t/%p, retr=%r/%b, del=%d/%m, size=%s pop3_logout_format = in=%i out=%o top=%t/%p, retr=%r/%b, del=%d/%m, size=%s
# Workarounds for various client bugs: # Workarounds for various client bugs:
# outlook-no-nuls: # outlook-no-nuls:
@@ -4461,21 +4461,7 @@ UPLOADGID=
<!-- Cronjob --> <!-- Cronjob -->
<daemon name="cron" title="Cronjob for froxlor" <daemon name="cron" title="Cronjob for froxlor"
mandatory="true"> mandatory="true">
<file name="/etc/cron.d/froxlor" chown="root:0" chmod="0640"> <command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
<content><![CDATA[
#
# Set PATH, otherwise restart-scripts won't find start-stop-daemon
#
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#
# Regular cron jobs for the froxlor package
#
# Please check that all following paths are correct
#
*/5 * * * * root /usr/bin/nice -n 5 /usr/bin/php -q <BASE_PATH>scripts/froxlor_master_cronjob.php
]]>
</content>
</file>
<command><![CDATA[{{settings.system.crondreload}}]]></command> <command><![CDATA[{{settings.system.crondreload}}]]></command>
</daemon> </daemon>
<!-- AWstats --> <!-- AWstats -->
@@ -4490,7 +4476,7 @@ PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
</daemon> </daemon>
<!-- libnss-mysql --> <!-- libnss-mysql -->
<daemon name="libnss" <daemon name="libnss"
title="libnss-mysql (required for FCGID/php-fpm/mpm-itk)"> title="libnss-mysql (alternative for libnss-extrausers, required for FCGID/php-fpm/mpm-itk)">
<install><![CDATA[apt-get install nscd <install><![CDATA[apt-get install nscd
wget http://debian.froxlor.org/pool/main/libn/libnss-mysql-bg/libnss-mysql-bg_1.5-3+frx1_amd64.deb wget http://debian.froxlor.org/pool/main/libn/libnss-mysql-bg/libnss-mysql-bg_1.5-3+frx1_amd64.deb
dpkg -i libnss-mysql-bg_1.5-3+frx1_amd64.deb dpkg -i libnss-mysql-bg_1.5-3+frx1_amd64.deb
@@ -4663,8 +4649,8 @@ aliases: files
</daemon> </daemon>
<!-- libnss-extrausers --> <!-- libnss-extrausers -->
<daemon name="libnssextrausers" <daemon name="libnssextrausers"
title="libnss-extrausers (alternative to libnss-mysql, required for FCGID/php-fpm/mpm-itk)"> title="libnss-extrausers (required for FCGID/php-fpm/mpm-itk)">
<install><![CDATA[apt-get install nscd libnss-extrausers]]></install> <install><![CDATA[apt-get install libnss-extrausers]]></install>
<commands index="1"> <commands index="1">
<command><![CDATA[mkdir -p /var/lib/extrausers]]></command> <command><![CDATA[mkdir -p /var/lib/extrausers]]></command>
<command><![CDATA[touch /var/lib/extrausers/passwd]]></command> <command><![CDATA[touch /var/lib/extrausers/passwd]]></command>
@@ -4696,9 +4682,6 @@ aliases: files
]]> ]]>
</content> </content>
</file> </file>
<command><![CDATA[/etc/init.d/nscd restart]]></command>
<!-- clear group chache -->
<command><![CDATA[nscd --invalidate=group]]></command>
</daemon> </daemon>
<!-- Logrotate --> <!-- Logrotate -->
<daemon name="logrotate" title="Logrotate"> <daemon name="logrotate" title="Logrotate">

File diff suppressed because it is too large Load Diff

View File

@@ -95,7 +95,7 @@ user = <SQL_UNPRIVILEGED_USER>
password = <SQL_UNPRIVILEGED_PASSWORD> password = <SQL_UNPRIVILEGED_PASSWORD>
dbname = <SQL_DB> dbname = <SQL_DB>
hosts = <SQL_HOST> hosts = <SQL_HOST>
query = SELECT destination FROM mail_virtual WHERE email = '%s' AND trim(destination) <> '' query = SELECT destination FROM mail_virtual AS v, panel_customers AS c WHERE c.customerid = v.customerid AND c.deactivated = 0 AND v.email = '%s' AND trim(v.destination) <> ''
]]> ]]>
</content> </content>
</file> </file>
@@ -1529,7 +1529,7 @@ protocol sieve {
# %m - number of messages (before deletion) # %m - number of messages (before deletion)
# %s - mailbox size in bytes (before deletion) # %s - mailbox size in bytes (before deletion)
# %u - old/new UIDL hash. may help finding out if UIDLs changed unexpectedly # %u - old/new UIDL hash. may help finding out if UIDLs changed unexpectedly
#pop3_logout_format = top=%t/%p, retr=%r/%b, del=%d/%m, size=%s pop3_logout_format = in=%i out=%o top=%t/%p, retr=%r/%b, del=%d/%m, size=%s
# Workarounds for various client bugs: # Workarounds for various client bugs:
# outlook-no-nuls: # outlook-no-nuls:
@@ -1826,7 +1826,7 @@ iterate_query = SELECT username AS user FROM mail_users
<daemon name="proftpd" version="1.3" title="ProFTPd" <daemon name="proftpd" version="1.3" title="ProFTPd"
default="true"> default="true">
<install><![CDATA[yum install proftpd proftpd-mysql]]></install> <install><![CDATA[yum install proftpd proftpd-mysql]]></install>
<file name="/etc/proftpd/proftpd.conf" chown="root:0" <file name="/etc/proftpd.conf" chown="root:0"
chmod="0600" backup="true"> chmod="0600" backup="true">
<content><![CDATA[ <content><![CDATA[
# This is the ProFTPD configuration file # This is the ProFTPD configuration file
@@ -2289,21 +2289,7 @@ ControlsLog /var/log/proftpd/controls.log
<!-- Cronjob --> <!-- Cronjob -->
<daemon name="cron" title="Cronjob for froxlor" <daemon name="cron" title="Cronjob for froxlor"
mandatory="true"> mandatory="true">
<file name="/etc/cron.d/froxlor" chown="root:0" chmod="0640"> <command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
<content><![CDATA[
#
# Set PATH, otherwise restart-scripts won't find start-stop-daemon
#
PATH=/sbin:/bin:/usr/sbin:/usr/bin
#
# Regular cron jobs for the froxlor package
#
# Please check that all following paths are correct
#
*/1 * * * * root /usr/bin/php -q <BASE_PATH>scripts/froxlor_master_cronjob.php
]]>
</content>
</file>
<command><![CDATA[{{settings.system.crondreload}}]]></command> <command><![CDATA[{{settings.system.crondreload}}]]></command>
</daemon> </daemon>
<!-- AWstats --> <!-- AWstats -->

View File

@@ -1493,7 +1493,7 @@ user = <SQL_UNPRIVILEGED_USER>
password = <SQL_UNPRIVILEGED_PASSWORD> password = <SQL_UNPRIVILEGED_PASSWORD>
dbname = <SQL_DB> dbname = <SQL_DB>
hosts = <SQL_HOST> hosts = <SQL_HOST>
query = SELECT destination FROM mail_virtual WHERE email = '%s' AND trim(destination) <> '' query = SELECT destination FROM mail_virtual AS v, panel_customers AS c WHERE c.customerid = v.customerid AND c.deactivated = 0 AND v.email = '%s' AND trim(v.destination) <> ''
]]> ]]>
</content> </content>
</file> </file>
@@ -3735,7 +3735,7 @@ protocol sieve {
# %m - number of messages (before deletion) # %m - number of messages (before deletion)
# %s - mailbox size in bytes (before deletion) # %s - mailbox size in bytes (before deletion)
# %u - old/new UIDL hash. may help finding out if UIDLs changed unexpectedly # %u - old/new UIDL hash. may help finding out if UIDLs changed unexpectedly
#pop3_logout_format = top=%t/%p, retr=%r/%b, del=%d/%m, size=%s pop3_logout_format = in=%i out=%o top=%t/%p, retr=%r/%b, del=%d/%m, size=%s
# Workarounds for various client bugs: # Workarounds for various client bugs:
# outlook-no-nuls: # outlook-no-nuls:
@@ -4528,21 +4528,7 @@ UPLOADGID=
<!-- Cronjob --> <!-- Cronjob -->
<daemon name="cron" title="Cronjob for froxlor" <daemon name="cron" title="Cronjob for froxlor"
mandatory="true"> mandatory="true">
<file name="/etc/cron.d/froxlor" chown="root:0" chmod="0640"> <command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
<content><![CDATA[
#
# Set PATH, otherwise restart-scripts won't find start-stop-daemon
#
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#
# Regular cron jobs for the froxlor package
#
# Please check that all following paths are correct
#
*/5 * * * * root /usr/bin/nice -n 5 /usr/bin/php -q <BASE_PATH>scripts/froxlor_master_cronjob.php
]]>
</content>
</file>
<command><![CDATA[{{settings.system.crondreload}}]]></command> <command><![CDATA[{{settings.system.crondreload}}]]></command>
</daemon> </daemon>
<!-- AWstats --> <!-- AWstats -->
@@ -4557,8 +4543,8 @@ PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
</daemon> </daemon>
<!-- libnss-extrausers --> <!-- libnss-extrausers -->
<daemon name="libnssextrausers" <daemon name="libnssextrausers"
title="libnss-extrausers (alternative to libnss-mysql, required for FCGID/php-fpm/mpm-itk)"> title="libnss-extrausers (required for FCGID/php-fpm/mpm-itk)">
<install><![CDATA[apt-get install nscd libnss-extrausers]]></install> <install><![CDATA[apt-get install libnss-extrausers]]></install>
<commands index="1"> <commands index="1">
<command><![CDATA[mkdir -p /var/lib/extrausers]]></command> <command><![CDATA[mkdir -p /var/lib/extrausers]]></command>
<command><![CDATA[touch /var/lib/extrausers/passwd]]></command> <command><![CDATA[touch /var/lib/extrausers/passwd]]></command>
@@ -4590,9 +4576,6 @@ aliases: files
]]> ]]>
</content> </content>
</file> </file>
<command><![CDATA[/etc/init.d/nscd restart]]></command>
<!-- clear group chache -->
<command><![CDATA[nscd --invalidate=group]]></command>
</daemon> </daemon>
<!-- Logrotate --> <!-- Logrotate -->
<daemon name="logrotate" title="Logrotate"> <daemon name="logrotate" title="Logrotate">

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<froxlor> <froxlor>
<distribution name="Ubuntu" codename="Trusty" <distribution name="Ubuntu" codename="Trusty"
version="14.04" defaulteditor="/usr/bin/nano"> version="14.04" defaulteditor="/usr/bin/nano" deprecated="true">
<services> <services>
<!-- HTTP --> <!-- HTTP -->
<service type="http" title="{{lng.admin.configfiles.http}}"> <service type="http" title="{{lng.admin.configfiles.http}}">
@@ -502,7 +502,7 @@ user = <SQL_UNPRIVILEGED_USER>
password = <SQL_UNPRIVILEGED_PASSWORD> password = <SQL_UNPRIVILEGED_PASSWORD>
dbname = <SQL_DB> dbname = <SQL_DB>
hosts = <SQL_HOST> hosts = <SQL_HOST>
query = SELECT destination FROM mail_virtual WHERE email = '%s' AND trim(destination) <> '' query = SELECT destination FROM mail_virtual AS v, panel_customers AS c WHERE c.customerid = v.customerid AND c.deactivated = 0 AND v.email = '%s' AND trim(v.destination) <> ''
]]> ]]>
</content> </content>
</file> </file>
@@ -1546,21 +1546,7 @@ UPLOADGID=
<!-- Cronjob --> <!-- Cronjob -->
<daemon name="cron" title="Cronjob for froxlor" <daemon name="cron" title="Cronjob for froxlor"
mandatory="true"> mandatory="true">
<file name="/etc/cron.d/froxlor" chown="root:0" chmod="0640"> <command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
<content><![CDATA[
#
# Set PATH, otherwise restart-scripts won't find start-stop-daemon
#
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#
# Regular cron jobs for the froxlor package
#
# Please check that all following paths are correct
#
*/5 * * * * root /usr/bin/nice -n 5 /usr/bin/php -q <BASE_PATH>scripts/froxlor_master_cronjob.php
]]>
</content>
</file>
<command><![CDATA[{{settings.system.crondreload}}]]></command> <command><![CDATA[{{settings.system.crondreload}}]]></command>
</daemon> </daemon>
<!-- AWstats --> <!-- AWstats -->
@@ -1575,7 +1561,7 @@ PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
</daemon> </daemon>
<!-- libnss-mysql --> <!-- libnss-mysql -->
<daemon name="libnss" <daemon name="libnss"
title="libnss-mysql (required for FCGID/php-fpm/mpm-itk)"> title="libnss-mysql (alternative to libnss-extrausers, required for FCGID/php-fpm/mpm-itk)">
<install><![CDATA[apt-get install libnss-mysql-bg nscd]]></install> <install><![CDATA[apt-get install libnss-mysql-bg nscd]]></install>
<file name="/etc/libnss-mysql.cfg" chown="root:root" <file name="/etc/libnss-mysql.cfg" chown="root:root"
chmod="0600" backup="true"> chmod="0600" backup="true">
@@ -1671,8 +1657,8 @@ aliases: files
</daemon> </daemon>
<!-- libnss-extrausers --> <!-- libnss-extrausers -->
<daemon name="libnssextrausers" <daemon name="libnssextrausers"
title="libnss-extrausers (alternative to libnss-mysql, required for FCGID/php-fpm/mpm-itk)"> title="libnss-extrausers (required for FCGID/php-fpm/mpm-itk)">
<install><![CDATA[apt-get install nscd libnss-extrausers]]></install> <install><![CDATA[apt-get install libnss-extrausers]]></install>
<commands index="1"> <commands index="1">
<command><![CDATA[mkdir -p /var/lib/extrausers]]></command> <command><![CDATA[mkdir -p /var/lib/extrausers]]></command>
<command><![CDATA[touch /var/lib/extrausers/passwd]]></command> <command><![CDATA[touch /var/lib/extrausers/passwd]]></command>
@@ -1704,9 +1690,6 @@ aliases: files
]]> ]]>
</content> </content>
</file> </file>
<command><![CDATA[/etc/init.d/nscd restart]]></command>
<!-- clear group chache -->
<command><![CDATA[nscd --invalidate=group]]></command>
</daemon> </daemon>
<!-- Logrotate --> <!-- Logrotate -->
<daemon name="logrotate" title="Logrotate"> <daemon name="logrotate" title="Logrotate">

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<froxlor> <froxlor>
<distribution name="Ubuntu" codename="Xenial" <distribution name="Ubuntu" codename="Xenial"
version="16.04.x" defaulteditor="/bin/nano"> version="16.04" defaulteditor="/bin/nano">
<services> <services>
<!-- HTTP --> <!-- HTTP -->
<service type="http" title="{{lng.admin.configfiles.http}}"> <service type="http" title="{{lng.admin.configfiles.http}}">
@@ -1504,7 +1504,7 @@ user = <SQL_UNPRIVILEGED_USER>
password = <SQL_UNPRIVILEGED_PASSWORD> password = <SQL_UNPRIVILEGED_PASSWORD>
dbname = <SQL_DB> dbname = <SQL_DB>
hosts = <SQL_HOST> hosts = <SQL_HOST>
query = SELECT destination FROM mail_virtual WHERE email = '%s' AND trim(destination) <> '' query = SELECT destination FROM mail_virtual AS v, panel_customers AS c WHERE c.customerid = v.customerid AND c.deactivated = 0 AND v.email = '%s' AND trim(v.destination) <> ''
]]> ]]>
</content> </content>
</file> </file>
@@ -3746,7 +3746,7 @@ protocol sieve {
# %m - number of messages (before deletion) # %m - number of messages (before deletion)
# %s - mailbox size in bytes (before deletion) # %s - mailbox size in bytes (before deletion)
# %u - old/new UIDL hash. may help finding out if UIDLs changed unexpectedly # %u - old/new UIDL hash. may help finding out if UIDLs changed unexpectedly
#pop3_logout_format = top=%t/%p, retr=%r/%b, del=%d/%m, size=%s pop3_logout_format = in=%i out=%o top=%t/%p, retr=%r/%b, del=%d/%m, size=%s
# Workarounds for various client bugs: # Workarounds for various client bugs:
# outlook-no-nuls: # outlook-no-nuls:
@@ -4539,21 +4539,7 @@ UPLOADGID=
<!-- Cronjob --> <!-- Cronjob -->
<daemon name="cron" title="Cronjob for froxlor" <daemon name="cron" title="Cronjob for froxlor"
mandatory="true"> mandatory="true">
<file name="/etc/cron.d/froxlor" chown="root:0" chmod="0640"> <command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
<content><![CDATA[
#
# Set PATH, otherwise restart-scripts won't find start-stop-daemon
#
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#
# Regular cron jobs for the froxlor package
#
# Please check that all following paths are correct
#
*/5 * * * * root /usr/bin/nice -n 5 /usr/bin/php -q <BASE_PATH>scripts/froxlor_master_cronjob.php
]]>
</content>
</file>
<command><![CDATA[{{settings.system.crondreload}}]]></command> <command><![CDATA[{{settings.system.crondreload}}]]></command>
</daemon> </daemon>
<!-- AWstats --> <!-- AWstats -->
@@ -4568,8 +4554,8 @@ PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
</daemon> </daemon>
<!-- libnss-extrausers --> <!-- libnss-extrausers -->
<daemon name="libnssextrausers" <daemon name="libnssextrausers"
title="libnss-extrausers (alternative to libnss-mysql, required for FCGID/php-fpm/mpm-itk)"> title="libnss-extrausers (required for FCGID/php-fpm/mpm-itk)">
<install><![CDATA[apt-get install nscd libnss-extrausers]]></install> <install><![CDATA[apt-get install libnss-extrausers]]></install>
<commands index="1"> <commands index="1">
<command><![CDATA[mkdir -p /var/lib/extrausers]]></command> <command><![CDATA[mkdir -p /var/lib/extrausers]]></command>
<command><![CDATA[touch /var/lib/extrausers/passwd]]></command> <command><![CDATA[touch /var/lib/extrausers/passwd]]></command>
@@ -4601,9 +4587,6 @@ aliases: files
]]> ]]>
</content> </content>
</file> </file>
<command><![CDATA[/etc/init.d/nscd restart]]></command>
<!-- clear group chache -->
<command><![CDATA[nscd --invalidate=group]]></command>
</daemon> </daemon>
<!-- Logrotate --> <!-- Logrotate -->
<daemon name="logrotate" title="Logrotate"> <daemon name="logrotate" title="Logrotate">

View File

@@ -44,6 +44,21 @@ return array(
'label' => $lng['login']['language'], 'label' => $lng['login']['language'],
'type' => 'select', 'type' => 'select',
'select_var' => $language_options 'select_var' => $language_options
),
'api_allowed' => array(
'label' => $lng['usersettings']['api_allowed']['title'],
'desc' => $lng['usersettings']['api_allowed']['description'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
'1'
),
'visible' => (\Froxlor\Settings::Get('api.enabled') == '1' ? true : false)
) )
) )
), ),

View File

@@ -59,6 +59,21 @@ return array(
'type' => 'select', 'type' => 'select',
'select_var' => $language_options, 'select_var' => $language_options,
'visible' => ($result['adminid'] == $userinfo['userid'] ? false : true) 'visible' => ($result['adminid'] == $userinfo['userid'] ? false : true)
),
'api_allowed' => array(
'label' => $lng['usersettings']['api_allowed']['title'],
'desc' => $lng['usersettings']['api_allowed']['description'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
$result['api_allowed']
),
'visible' => (\Froxlor\Settings::Get('api.enabled') == '1' ? true : false)
) )
) )
), ),

View File

@@ -81,6 +81,21 @@ return array(
'label' => $lng['login']['language'], 'label' => $lng['login']['language'],
'type' => 'select', 'type' => 'select',
'select_var' => $language_options 'select_var' => $language_options
),
'api_allowed' => array(
'label' => $lng['usersettings']['api_allowed']['title'],
'desc' => $lng['usersettings']['api_allowed']['description'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
'1'
),
'visible' => (\Froxlor\Settings::Get('api.enabled') == '1' ? true : false)
) )
) )
), ),
@@ -294,9 +309,9 @@ return array(
'values' => $phpconfigs, 'values' => $phpconfigs,
'value' => ((int) \Froxlor\Settings::Get('system.mod_fcgid') == 1 ? array( 'value' => ((int) \Froxlor\Settings::Get('system.mod_fcgid') == 1 ? array(
\Froxlor\Settings::Get('system.mod_fcgid_defaultini') \Froxlor\Settings::Get('system.mod_fcgid_defaultini')
) : (int) \Froxlor\Settings::Get('phpfpm.enabled') == 1 ? array( ) : ((int) \Froxlor\Settings::Get('phpfpm.enabled') == 1 ? array(
\Froxlor\Settings::Get('phpfpm.defaultini') \Froxlor\Settings::Get('phpfpm.defaultini')
) : array()), ) : array())),
'is_array' => 1 'is_array' => 1
), ),
'perlenabled' => array( 'perlenabled' => array(

View File

@@ -74,6 +74,21 @@ return array(
'label' => $lng['login']['language'], 'label' => $lng['login']['language'],
'type' => 'select', 'type' => 'select',
'select_var' => $language_options 'select_var' => $language_options
),
'api_allowed' => array(
'label' => $lng['usersettings']['api_allowed']['title'],
'desc' => $lng['usersettings']['api_allowed']['description'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array(
$result['api_allowed']
),
'visible' => (\Froxlor\Settings::Get('api.enabled') == '1' ? true : false)
) )
) )
), ),

View File

@@ -180,12 +180,18 @@ return array(
'image' => 'icons/domain_add.png', 'image' => 'icons/domain_add.png',
'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? true : false, 'visible' => \Froxlor\Settings::Get('system.use_ssl') == '1' ? true : false,
'fields' => array( 'fields' => array(
'no_ssl_available_info' => array(
'visible' => ($ssl_ipsandports == '' ? true : false),
'label' => 'SSL',
'type' => 'label',
'value' => $lng['panel']['nosslipsavailable']
),
'ssl_ipandport' => array( 'ssl_ipandport' => array(
'label' => $lng['domains']['ipandport_ssl_multi']['title'], 'label' => $lng['domains']['ipandport_ssl_multi']['title'],
'desc' => $lng['domains']['ipandport_ssl_multi']['description'], 'desc' => $lng['domains']['ipandport_ssl_multi']['description'],
'type' => 'checkbox', 'type' => 'checkbox',
'values' => $ssl_ipsandports, 'values' => $ssl_ipsandports,
'value' => '', 'value' => explode(',', \Froxlor\Settings::Get('system.defaultsslip')),
'is_array' => 1 'is_array' => 1
), ),
'ssl_redirect' => array( 'ssl_redirect' => array(
@@ -227,11 +233,81 @@ return array(
), ),
'value' => array() 'value' => array()
), ),
'no_ssl_available_info' => array( 'override_tls' => array(
'visible' => ($ssl_ipsandports == '' ? true : false), 'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
'label' => 'SSL', 'label' => $lng['admin']['domain_override_tls'],
'type' => 'label', 'type' => 'checkbox',
'value' => $lng['panel']['nosslipsavailable'] 'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array()
),
'ssl_protocols' => array(
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' && \Froxlor\Settings::Get('system.webserver') != 'lighttpd' ? true : false),
'label' => $lng['serversettings']['ssl']['ssl_protocols']['title'],
'desc' => $lng['serversettings']['ssl']['ssl_protocols']['description'],
'type' => 'checkbox',
'value' => array(
'TLSv1',
'TLSv1.2'
),
'values' => array(
array(
'value' => 'TLSv1',
'label' => 'TLSv1<br />'
),
array(
'value' => 'TLSv1.1',
'label' => 'TLSv1.1<br />'
),
array(
'value' => 'TLSv1.2',
'label' => 'TLSv1.2<br />'
),
array(
'value' => 'TLSv1.3',
'label' => 'TLSv1.3<br />'
)
),
'is_array' => 1
),
'ssl_cipher_list' => array(
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
'label' => $lng['serversettings']['ssl']['ssl_cipher_list']['title'],
'desc' => $lng['serversettings']['ssl']['ssl_cipher_list']['description'],
'type' => 'text',
'value' => \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' => \Froxlor\Settings::Get('system.tlsv13_cipher_list')
),
'ssl_specialsettings' => array(
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
'style' => 'align-top',
'label' => $lng['admin']['ownsslvhostsettings'],
'desc' => $lng['serversettings']['default_vhostconf']['description'],
'type' => 'textarea',
'cols' => 60,
'rows' => 12
),
'include_specialsettings' => array(
'visible' => (($ssl_ipsandports != '' ? true : false) && $userinfo['change_serversettings'] == '1' ? true : false),
'label' => $lng['admin']['include_ownvhostsettings'],
'type' => 'checkbox',
'values' => array(
array(
'label' => $lng['panel']['yes'],
'value' => '1'
)
),
'value' => array()
), ),
'hsts_maxage' => array( 'hsts_maxage' => array(
'visible' => ($ssl_ipsandports != '' ? true : false), 'visible' => ($ssl_ipsandports != '' ? true : false),

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