Compare commits
85 Commits
1584b3c60d
...
main
Author | SHA1 | Date | |
---|---|---|---|
cef2114520 | |||
4f2e601edf | |||
cef6edc9c1
|
|||
bbfbbbc2a8
|
|||
65583296cf | |||
948aef1834 | |||
a3c1f49d97
|
|||
85539ce4f0
|
|||
e089d34114
|
|||
55ccf1323a
|
|||
a63328f7f6
|
|||
9e1a071965 | |||
2aec2c322c | |||
1dfaf11b6a
|
|||
caabe0c525
|
|||
4758464a79 | |||
2735f35883 | |||
fab6459f37
|
|||
2c705975cb | |||
bd40ddb175
|
|||
c35d47c6c6
|
|||
d9d7323a9a
|
|||
d22fa5e577
|
|||
2ff3ea6cea | |||
e9a8effab5 | |||
227fb813ef | |||
3f067b1f92 | |||
8d58282163
|
|||
6085a0156a
|
|||
c262dbbe9d
|
|||
527b9e075f
|
|||
bef733240f
|
|||
f197f10228
|
|||
08da5a0623
|
|||
93ef4d6220
|
|||
7b21a62ac1
|
|||
ce1cefe511
|
|||
df35dc5e05
|
|||
c79682eb0b
|
|||
14d6e21223
|
|||
78db852e82
|
|||
a8c633b1d2
|
|||
ffac3ea1db
|
|||
1a3be77244 | |||
b4dcf77e0a | |||
47083691bb | |||
75e8683238 | |||
2e4e41bf6e | |||
dea136d331 | |||
f5211ff264
|
|||
05c78d17c8
|
|||
236609945c
|
|||
8903832866
|
|||
e8f64f6913
|
|||
46a76764ad
|
|||
d13fef662d
|
|||
adf6f51993
|
|||
acae5dcd7a
|
|||
a97b0173f2
|
|||
549e753353
|
|||
3f6cfe7c14
|
|||
8d54b307ca
|
|||
c9d61e8aaf
|
|||
44e53b14d2 | |||
a35affe08f | |||
da8013db56 | |||
0bb8ac6590
|
|||
a6ab6c52e3 | |||
1392a38c9d
|
|||
c5027b96c6
|
|||
fb3a596289 | |||
ae26e80a25 | |||
dc8575615d | |||
bbfcfb76c3 | |||
c10d40b7fd
|
|||
878379dc73
|
|||
37ebdbb66d
|
|||
8e86cdc73e | |||
f247a7a5bf
|
|||
1238f003d6
|
|||
be717d646d | |||
3b53020bef
|
|||
174978ac3e
|
|||
a0c016887a | |||
28344bda79
|
216
README.md
216
README.md
@ -6,7 +6,221 @@ This is a setup for a Tor based email hosting server. It is provided as is and b
|
||||
Installation Instructions:
|
||||
--------------------------
|
||||
|
||||
TODO
|
||||
### Primary mail server with Tor:
|
||||
|
||||
Uninstall packages that may interfere with this setup:
|
||||
```
|
||||
DEBIAN_FRONTEND=noninteractive apt-get purge -y apache2* dnsmasq* eatmydata exim4* imagemagick-6-common mysql-client* mysql-server* nginx* libnginx-mod* php7* resolvconf && systemctl disable systemd-resolved.service && systemctl stop systemd-resolved.service
|
||||
```
|
||||
|
||||
If you have problems resolving hostnames after this step, temporarily switch to a public nameserver like 1.1.1.1 (from CloudFlare) or 8.8.8.8 (from Google)
|
||||
|
||||
```
|
||||
rm /etc/resolv.conf && echo "nameserver 1.1.1.1" > /etc/resolv.conf
|
||||
```
|
||||
|
||||
Install git and clone this repository
|
||||
|
||||
```
|
||||
apt-get update && apt-get install git -y && git clone https://github.com/DanWin/mail-hosting && cd mail-hosting
|
||||
```
|
||||
|
||||
Install files and programs
|
||||
```
|
||||
./install_binaries.sh
|
||||
```
|
||||
|
||||
Copy (and modify according to your needs) the site files in `etc` to `/etc` after installation has finished. Then restart some services:
|
||||
```
|
||||
systemctl daemon-reload && systemctl restart tor@default.service
|
||||
```
|
||||
|
||||
Replace the default .onion domain with your domain:
|
||||
```
|
||||
sed -i "s/danielas3rtn54uwmofdo3x2bsdifr47huasnmbgqzfrec5ubupvtpid.onion/`cat /var/lib/tor/hidden_service/hostname`/g" /etc/prosody/prosody.cfg.lua /etc/nginx/sites-enabled/mail /var/www/mail/common_config.php /etc/postfix/main.cf
|
||||
```
|
||||
|
||||
Replace the default clearnet domain with your domain:
|
||||
```
|
||||
sed -i "s/danwin1210.de/YOUR_DOMAIN/g" /etc/prosody/prosody.cfg.lua /etc/postfix/main.cf /etc/dovecot/dovecot.conf /etc/nginx/sites-enabled/* /var/www/mail/common_config.php /var/www/mail/www/squirrelmail/config/config.php
|
||||
```
|
||||
|
||||
Create a mysql users and databases:
|
||||
```
|
||||
mysql
|
||||
CREATE DATABASE postfix;
|
||||
CREATE DATABASE prosody;
|
||||
CREATE USER 'postfix'@'%' IDENTIFIED BY 'MY_PASSWORD';
|
||||
CREATE USER 'postfix_readonly'@'%' IDENTIFIED BY 'MY_PASSWORD';
|
||||
CREATE USER 'prosody'@'%' IDENTIFIED BY 'MY_PASSWORD';
|
||||
GRANT ALL PRIVILEGES ON postfix.* TO 'postfix'@'%';
|
||||
GRANT SELECT ON postfix.* TO 'postfix_readonly'@'%';
|
||||
GRANT ALL PRIVILEGES ON prosody.* TO 'prosody'@'%';
|
||||
FLUSH PRIVILEGES;
|
||||
quit
|
||||
```
|
||||
|
||||
Then update the passwords you've set in your configuration files:
|
||||
```
|
||||
nano /etc/dovecot/dovecot-dict-sql.conf.ext /etc/dovecot/dovecot-sql.conf.ext /etc/postfix/sql/mysql_* /etc/prosody/prosody.cfg.lua /var/www/mail/common_config.php
|
||||
```
|
||||
|
||||
Generate a keypair for rspamd with `rspamadm keypair gen` and add it to /etc/rspamd/local.d/worker-fuzzy.inc, add the public encryption key to /etc/rspamd/override.d/fuzzy_check.conf
|
||||
|
||||
Set a password for the web interface with `rspamadm pw` and add the hash for it to /etc/rspamd/override.d/worker-controller.inc
|
||||
|
||||
Generate DKIM signing keys and add them to /etc/rspamd/local.d/arc.conf /etc/rspamd/local.d/dkim_signing.conf, then add the printed DNS records to your domain:
|
||||
```
|
||||
rspamadm dkim_keygen -d YOUR_DOMAIN -s $(date +"%Y%m%d")-rsa -b 4096 -t rsa -k /var/lib/rspamd/dkim/YOUR_DOMAIN-rsa
|
||||
rspamadm dkim_keygen -d YOUR_DOMAIN -s $(date +"%Y%m%d")-ed25519 -t ed25519 -k /var/lib/rspamd/dkim/YOUR_DOMAIN-ed25519
|
||||
```
|
||||
|
||||
Create a password used for your TURN server and replace all `YOUR_SECRET` in `/etc/prosody/prosody.cfg.lua` with it.
|
||||
|
||||
Install [acme.sh](https://github.com/acmesh-official/acme.sh) or [certbot](https://certbot.eff.org/) to obtain a free letsencrypt SSL certificate, then update the path to this new certificate in the following files:
|
||||
```
|
||||
nano /etc/prosody/prosody.cfg.lua /etc/dovecot/dovecot.conf /etc/postfix/main.cf /etc/nginx/nginx.conf /etc/nginx/sites-enabled/mail /etc/nginx/sites-enabled/openpgpkey
|
||||
```
|
||||
|
||||
Add your other servers IP under `unrestricted access to these IPs` in `/etc/rc.local`
|
||||
|
||||
Create database tables, activate firewall and enable cron:
|
||||
```
|
||||
postmap /etc/postfix/header_checks
|
||||
cd /var/www/mail && php setup.php && chmod +x /etc/rc.local && /etc/rc.local && systemctl enable mail-cron.timer
|
||||
```
|
||||
|
||||
Generate a wireguard keypair and add the public key generated here to the primary mail server wireguard config:
|
||||
```
|
||||
export PRIV=$(wg genkey)
|
||||
sed -i "s~YOUR_PRIVATE_KEY~$PRIV~g" /etc/wireguard/wg0.conf
|
||||
echo $PRIV | wg pubkey
|
||||
```
|
||||
|
||||
Replace `YOUR_IP` with the IP of your other server, then enable and start wireguard:
|
||||
```
|
||||
nano /etc/wireguard/wg0.conf
|
||||
systemctl enable wg-quick@wg0 && systemctl start wg-quick@wg0
|
||||
```
|
||||
|
||||
Final step is to reboot the server and check that everything is working.
|
||||
|
||||
### Proxy server:
|
||||
|
||||
To send emails to the regular internet, it is necessary to have a static IP to retain a reputation with an IP+Domain mapping. If you try sending via Tor, your emails will most certainly get blocked by spam filters. For this reason we need to setup a proxy server which will hold no user data itself, but simply act as a gateway to reach the less anonymous part of the internet.
|
||||
|
||||
Uninstall packages that may interfere with this setup:
|
||||
```
|
||||
DEBIAN_FRONTEND=noninteractive apt-get purge -y apache2* dnsmasq* eatmydata exim4* imagemagick-6-common mysql-client* mysql-server* nginx* libnginx-mod* php7* resolvconf && systemctl disable systemd-resolved.service && systemctl stop systemd-resolved.service
|
||||
```
|
||||
|
||||
If you have problems resolving hostnames after this step, temporarily switch to a public nameserver like 1.1.1.1 (from CloudFlare) or 8.8.8.8 (from Google)
|
||||
|
||||
```
|
||||
rm /etc/resolv.conf && echo "nameserver 1.1.1.1" > /etc/resolv.conf
|
||||
```
|
||||
|
||||
Install git and clone this repository
|
||||
```
|
||||
apt-get update && apt-get install git -y && git clone https://github.com/DanWin/mail-hosting && cd mail-hosting
|
||||
```
|
||||
|
||||
Install files and programs
|
||||
```
|
||||
./install_binaries_proxy.sh
|
||||
```
|
||||
|
||||
Copy (and modify according to your needs) the site files in `etc_clearnet_proxy` to `/etc` after installation has finished.
|
||||
|
||||
Add the password for your TURN server you created for prosody in the main server and replace `YOUR_AUTH_SECRET` in `/etc/turnserver.conf` with it.
|
||||
|
||||
Install [acme.sh](https://github.com/acmesh-official/acme.sh) or [certbot](https://certbot.eff.org/) to obtain a free letsencrypt SSL certificate, then update the path to this new certificate in the following files:
|
||||
```
|
||||
nano /etc/postfix/main.cf /etc/nginx/nginx.conf /etc/turnserver.conf
|
||||
```
|
||||
|
||||
Replace `YOUR_PASSWORD` in `/etc/postfix/sql/mysql_tls_policy_out.cf` with the one you've generated previously on the other server.
|
||||
|
||||
Generate a wireguard keypair and add the public key generated here to the primary mail server wireguard config:
|
||||
```
|
||||
export PRIV=$(wg genkey)
|
||||
sed -i "s~YOUR_PRIVATE_KEY~$PRIV~g" /etc/wireguard/wg0.conf
|
||||
echo $PRIV | wg pubkey
|
||||
```
|
||||
|
||||
Replace `YOUR_IP` with the IP of your other server and `ens3` with your network interface name, then enable and start wireguard:
|
||||
```
|
||||
nano /etc/wireguard/wg0.conf
|
||||
systemctl enable wg-quick@wg0 && systemctl start wg-quick@wg0
|
||||
```
|
||||
|
||||
Edit and create your admin user with the following script:
|
||||
```
|
||||
nano /var/www/mail/tools/create_admin.php
|
||||
php /var/www/mail/tools/create_admin.php
|
||||
```
|
||||
|
||||
Copy the file `/etc/postfix/danwin1210-mail.crt` from your main server to the same location on the proxy server.
|
||||
|
||||
Final step is to reboot the server and check that everything is working.
|
||||
|
||||
### General Domain settings
|
||||
|
||||
Add the following DNS records to your domain, with the IPs of your proxy server:
|
||||
```
|
||||
@ IN TXT "v=spf1 ip4:your.ip.v4.address ip6:your:ip:v6:address -all"
|
||||
_dmarc IN TXT "v=DMARC1;p=quarantine;adkim=r;aspf=r;fo=1;rua=mailto:postmaster@yourdomain;ruf=mailto:postmaster@yourdomain;rf=afrf;ri=86400;pct=100"
|
||||
_adsp._domainkey IN TXT "dkim=all;"
|
||||
_domainkey IN TXT "o=-;r=postmaster@yourdomain"
|
||||
*._report._dmarc IN TXT "v=DMARC1"
|
||||
_mta-sts IN TXT "v=STSv1; id=2024060601"
|
||||
_smtp._tls IN TXT "v=TLSRPTv1; rua=mailto:postmaster@yourdomain"
|
||||
_imaps._tcp IN SRV 0 0 993 yourdomain.
|
||||
_submission._tcp IN SRV 0 0 587 yourdomain.
|
||||
@ IN MX 0 yourdomain.
|
||||
@ IN A your.ip.v4.address
|
||||
@ IN AAAA your:ip:v6:address
|
||||
www IN A your.ip.v4.address
|
||||
www IN AAAA your:ip:v6:address
|
||||
mta-sts IN A your.ip.v4.address
|
||||
mta-sts IN AAAA your:ip:v6:address
|
||||
conference IN A your.ip.v4.address
|
||||
conference IN AAAA your:ip:v6:address
|
||||
proxy IN A your.ip.v4.address
|
||||
proxy IN AAAA your:ip:v6:address
|
||||
upload IN A your.ip.v4.address
|
||||
upload IN AAAA your:ip:v6:address
|
||||
_xmpp-server._tcp.conference IN SRV 5 0 5269 yourdomain.
|
||||
_xmpp-server._tcp.conference IN SRV 0 0 5269 your_onion_domain.
|
||||
_xmpp-client._tcp IN SRV 5 0 5222 yourdomain.
|
||||
_xmpp-client._tcp IN SRV 0 0 5222 your_onion_domain.
|
||||
_xmpps-client._tcp IN SRV 5 0 5223 yourdomain.
|
||||
_xmpps-client._tcp IN SRV 0 0 5223 your_onion_domain.
|
||||
_xmpp-server._tcp IN SRV 5 0 5269 yourdomain.
|
||||
_xmpp-server._tcp IN SRV 0 0 5269 your_onion_domain.
|
||||
_stun._udp IN SRV 0 0 3478 yourdomain.
|
||||
_turn._udp IN SRV 0 0 3478 yourdomain.
|
||||
_stun._tcp IN SRV 0 0 3478 yourdomain.
|
||||
_stuns._tcp IN SRV 0 0 3479 yourdomain.
|
||||
_turn._tcp IN SRV 0 0 3478 yourdomain.
|
||||
_turns._tcp IN SRV 0 0 5349 yourdomain.
|
||||
_xmppconnect IN TXT "_xmpp-client-xbosh=https://yourdomain:5281/http-bind"
|
||||
_xmppconnect IN TXT "_xmpp-client-websocket=wss://yourdomain:5281/xmpp-websocket"
|
||||
```
|
||||
|
||||
Set the PTR record of your proxy servers IPs to your domain. This can usually be done from your hosting panels configuration, but may not be available with every hosting provider, where you can then request them to do it via a support ticket.
|
||||
|
||||
Consider registering your domain with [DNSWL](https://www.dnswl.org/), [SNDS](https://sendersupport.olc.protection.outlook.com/snds/), [Google Postmaster Tools](https://postmaster.google.com/) and [YahooCFL](https://senders.yahooinc.com/complaint-feedback-loop/) for valuable insights into your delivery.
|
||||
|
||||
Consider enabling DNSSEC on your domain, when available by your Domain registrar. Some registrars may charge extra for it. Once enabled, you can also enable DANE, which increases security. Use [TLSA Record Genearator](https://ssl-tools.net/tlsa-generator) to help you create an appropriate DNS record.
|
||||
|
||||
Consider adding your domain to [HSTS Preload List](https://hstspreload.org/) which will prevent browsers from even trying to access your domain on the insecure http:// protocol and automatically upgreade to https://
|
||||
|
||||
### Final configuration steps
|
||||
|
||||
Follow [SnappyMail installation instructions](https://github.com/the-djmaze/snappymail/wiki/Installation-instructions#now-access-the-admin-page) to finish setting it up at yourdomain/mail/snappymail/?admin
|
||||
|
||||
|
||||
|
||||
Translating:
|
||||
------------
|
||||
|
@ -11,7 +11,7 @@ const DBPASS = 'YOUR_PASSWORD'; // Database password
|
||||
const DBNAME = 'postfix'; // Database
|
||||
const DBVERSION = 1; // Database schema version
|
||||
const PERSISTENT = true; // persistent database connection
|
||||
const CAPTCHA_DIFFICULTY = 1; // captcha difficulty from 0 to 3
|
||||
const CAPTCHA_DIFFICULTY = 1; // captcha difficulty from 0 to 4
|
||||
const RESERVED_USERNAMES = ['about', 'abuse', 'admin', 'administrator', 'billing', 'contact', 'daemon', 'ftp', 'help', 'hostmaster', 'info', 'legal', 'list', 'list-request', 'lists', 'maildaemon', 'mailerdaemon', 'mailer-daemon', 'marketing', 'media', 'news', 'newsletter', 'nobody', 'noc', 'noreply', 'no-reply', 'notification', 'notifications', 'notify', 'offer', 'offers', 'office', 'official', 'order', 'orders', 'phish', 'phishing', 'postmaster', 'root', 'sale', 'sales', 'security', 'service', 'services', 'shop', 'shopping', 'spam', 'staff', 'support', 'survey', 'system', 'team', 'teams', 'unsbubscribe', 'uucp', 'usenet', 'user', 'username', 'users', 'web', 'webmail', 'webmaster', 'webmasters', 'welcome', 'www']; // list of reserved usernames that can mot be used on public registration
|
||||
const CANONICAL_URL = 'https://danwin1210.de/mail/'; // our preferred URL prefix for search engines
|
||||
const PRIVACY_POLICY_URL = '/privacy.php'; // URL to privacy policy
|
||||
@ -26,6 +26,8 @@ const DBHOST_PROSODY = 'localhost'; // Database host
|
||||
const DBUSER_PROSODY = 'prosody'; // Database user
|
||||
const DBPASS_PROSODY = 'YOUR_PASSWORD'; // Database password
|
||||
const DBNAME_PROSODY = 'prosody'; // Database
|
||||
const REGISTRATION_ENABLED = true; // Whether registration is enabled
|
||||
const DEFAULT_QUOTA = 50 * 1024 * 1024; // Default mailbox quota in bytes
|
||||
|
||||
const LANGUAGES = [
|
||||
'cs' => ['name' => 'čeština', 'locale' => 'cs_CZ', 'flag' => '🇨🇿', 'show_in_menu' => true, 'dir' => 'ltr'],
|
||||
@ -34,6 +36,7 @@ const LANGUAGES = [
|
||||
'pl' => ['name' => 'Polski', 'locale' => 'pl_PL', 'flag' => '🇵🇱', 'show_in_menu' => true, 'dir' => 'ltr'],
|
||||
'ru' => ['name' => 'Русский', 'locale' => 'ru_RU', 'flag' => '🇷🇺', 'show_in_menu' => true, 'dir' => 'ltr'],
|
||||
'tr' => ['name' => 'Türkçe', 'locale' => 'tr_TR', 'flag' => '🇹🇷', 'show_in_menu' => true, 'dir' => 'ltr'],
|
||||
'uk' => ['name' => 'Українська', 'locale' => 'uk_UA', 'flag' => '🇺🇦', 'show_in_menu' => true, 'dir' => 'ltr'],
|
||||
];
|
||||
$language = 'en';
|
||||
$locale = 'en_GB';
|
||||
@ -160,6 +163,45 @@ function send_captcha(): void
|
||||
imagesetpixel( $im, mt_rand( 0, 55 ), mt_rand( 0, 24 ), $dots );
|
||||
}
|
||||
echo '<img alt="" width="55" height="24" src="data:image/gif;base64,';
|
||||
} elseif (CAPTCHA_DIFFICULTY === 3){
|
||||
$im = imagecreatetruecolor(55, 24);
|
||||
$bg = imagecolorallocatealpha($im, 0, 0, 0, 127);
|
||||
$fg = imagecolorallocate($im, 255, 255, 255);
|
||||
$cc = imagecolorallocate($im, 200, 200, 200);
|
||||
$cb = imagecolorallocatealpha($im, 0, 0, 0, 127);
|
||||
imagefill($im, 0, 0, $bg);
|
||||
$line = imagecolorallocate($im, 255, 255, 255);
|
||||
$deg = (mt_rand(0,1)*2-1)*mt_rand(10, 20);
|
||||
|
||||
$background = imagecreatetruecolor(120, 80);
|
||||
imagefill($background, 0, 0, $cb);
|
||||
|
||||
for ($i=0; $i<20; ++$i) {
|
||||
$char = imagecreatetruecolor(12, 16);
|
||||
imagestring($char, 5, 2, 2, $captchachars[mt_rand(0, $length)], $cc);
|
||||
$char = imagerotate($char, (mt_rand(0,1)*2-1)*mt_rand(10, 20), $cb);
|
||||
$char = imagescale($char, 24, 32);
|
||||
imagefilter($char, IMG_FILTER_SMOOTH, 0.6);
|
||||
imagecopy($background, $char, rand(0, 100), rand(0, 60), 0, 0, 24, 32);
|
||||
}
|
||||
|
||||
imagestring($im, 5, 5, 5, $code, $fg);
|
||||
$im = imagescale($im, 110, 48);
|
||||
imagefilter($im, IMG_FILTER_SMOOTH, 0.5);
|
||||
imagefilter($im, IMG_FILTER_GAUSSIAN_BLUR);
|
||||
$im = imagerotate($im, $deg, $bg);
|
||||
$im = imagecrop($im, array('x'=>0, 'y'=>0, 'width'=>120, 'height'=>80));
|
||||
imagecopy($background, $im, 0, 0, 0, 0, 110, 80);
|
||||
imagedestroy($im);
|
||||
$im = $background;
|
||||
|
||||
for($i=0; $i<1000; ++$i){
|
||||
$c = mt_rand(100,230);
|
||||
$dots = imagecolorallocate($im, $c, $c, $c);
|
||||
imagesetpixel($im, mt_rand(0, 120), mt_rand(0, 80), $dots);
|
||||
}
|
||||
imagedestroy($char);
|
||||
echo '<img width="120" height="80" src="data:image/png;base64,';
|
||||
} else {
|
||||
$im = imagecreatetruecolor( 150, 200 );
|
||||
$bg = imagecolorallocate( $im, 0, 0, 0 );
|
||||
@ -256,7 +298,7 @@ function validate_email_list( array $targets, string &$msg = '' ): string
|
||||
if ( $validator->isValid( $email, new NoRFCWarningsValidation() ) ) {
|
||||
$alias_goto .= ",$email";
|
||||
} else {
|
||||
$msg .= '<div class="red" role="alert">'.sprintf(_('Oops, the email "%s" doesn\' look like a valid email address and thus wasn\'t added to the forwarding list.'), htmlspecialchars( $email ) ) . '</div>';
|
||||
$msg .= '<div class="red" role="alert">'.sprintf(htmlspecialchars(_('Oops, the email "%s" doesn\' look like a valid email address and thus wasn\'t added to the forwarding list.')), htmlspecialchars( $email ) ) . '</div>';
|
||||
}
|
||||
}
|
||||
return ltrim( $alias_goto, ',' );
|
||||
@ -282,7 +324,7 @@ function check_domain_access( string &$email, string &$msg = '' ): bool
|
||||
$managed_domains [] = $tmp[ 'domain' ];
|
||||
}
|
||||
if ( ! in_array( $domain, $managed_domains, true ) ) {
|
||||
$msg .= '<div class="red" role="alert">'._('You are not allowed to manage this domain.').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('You are not allowed to manage this domain.')).'</div>';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -293,7 +335,7 @@ function check_email_valid( string $email, string &$msg = '' ): bool
|
||||
{
|
||||
$validator = new EmailValidator();
|
||||
if ( ! $validator->isValid( $email, new NoRFCWarningsValidation() ) ) {
|
||||
$msg .= '<div class="red" role="alert">'._('Invalid email address.').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('Invalid email address.')).'</div>';
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -310,3 +352,13 @@ function alt_links(): void
|
||||
echo '<meta property="og:locale:alternate" content="'.$data['locale'].'">';
|
||||
}
|
||||
}
|
||||
|
||||
function bytes_to_human_readable(int $bytes) : string {
|
||||
$suffix = ['B', 'KiB', 'MiB', 'GiB', 'TiB'];
|
||||
$size_class=(int) log($bytes, 1024);
|
||||
if($size_class!==0){
|
||||
return sprintf('%1.1f', $bytes / pow(1024, $size_class)) . $suffix[$size_class];
|
||||
}else{
|
||||
return $bytes . $suffix[0];
|
||||
}
|
||||
}
|
12
cron.php
12
cron.php
@ -32,9 +32,13 @@ while ( $tmp = $stmt->fetch( PDO::FETCH_ASSOC ) ) {
|
||||
if ( file_exists( $mail_files ) ) {
|
||||
exec( 'rm -r ' . escapeshellarg( $mail_files ) );
|
||||
}
|
||||
$snapmail_files = '/var/local/snappymail/_data_/_default_/storage/' . $domain_basename . '/' . $local_basename;
|
||||
if ( file_exists( $snapmail_files ) ) {
|
||||
exec( 'rm -r ' . escapeshellarg( $snapmail_files ) );
|
||||
}
|
||||
$files = glob( '/var/local/squirrelmail/data/' . $local_basename . '@' . $domain_basename . '.{pref,abook,sig}', GLOB_BRACE );
|
||||
if ( $tmp[ 'domain' ] === 'danwin1210.de' ) {
|
||||
$files = array_merge( $files, glob( '/var/local/squirrelmail/data/' . $local_basename . '{@danielas3rtn54uwmofdo3x2bsdifr47huasnmbgqzfrec5ubupvtpid.onion,}.{pref,abook,sig}', GLOB_BRACE ) );
|
||||
if ( $tmp[ 'domain' ] === CLEARNET_SERVER ) {
|
||||
$files = array_merge( $files, glob( '/var/local/squirrelmail/data/' . $local_basename . '{@'.ONION_SERVER.',}.{pref,abook,sig}', GLOB_BRACE ) );
|
||||
$delete_prosody->execute( [ $tmp[ 'local_part' ], $tmp[ 'domain' ] ] );
|
||||
$delete_prosody_archive->execute( [ $tmp[ 'local_part' ], $tmp[ 'domain' ] ] );
|
||||
}
|
||||
@ -66,6 +70,10 @@ while ( $tmp = $stmt->fetch( PDO::FETCH_ASSOC ) ) {
|
||||
if ( file_exists( $mail_files ) ) {
|
||||
exec( 'rm -r ' . escapeshellarg( $mail_files ) );
|
||||
}
|
||||
$snapmail_files = '/var/local/snappymail/_data_/_default_/storage/' . $domain_basename . '/';
|
||||
if ( file_exists( $snapmail_files ) ) {
|
||||
exec( 'rm -r ' . escapeshellarg( $snapmail_files ) );
|
||||
}
|
||||
if ( is_array( $files ) ) {
|
||||
foreach ( $files as $file ) {
|
||||
@unlink( $file );
|
||||
|
@ -14,9 +14,11 @@ mail_debug = no
|
||||
verbose_ssl = no
|
||||
mail_location = maildir:/var/mail/vmail/%d/%n
|
||||
mail_home = /var/mail/vmail/%d/%n
|
||||
mail_plugins = $mail_plugins mail_crypt zlib
|
||||
mail_plugins = mail_crypt quota zlib
|
||||
mailbox_list_index = yes
|
||||
mail_always_cache_fields = date.save
|
||||
imap_hibernate_timeout = 5s
|
||||
mail_attribute_dict = file:%h/dovecot-attributes
|
||||
|
||||
#plugin setup
|
||||
plugin {
|
||||
@ -34,6 +36,9 @@ plugin {
|
||||
quota_vsizes = yes
|
||||
last_login_dict = proxy::lastlogin
|
||||
last_login_key = last-login/%u
|
||||
sieve = file:~/sieve;active=~/.dovecot.sieve
|
||||
sieve_plugins = sieve_imapsieve
|
||||
imapsieve_url = sieve://danwin1210.de
|
||||
}
|
||||
|
||||
#auth settings
|
||||
@ -47,8 +52,8 @@ auth_mechanisms = plain login
|
||||
|
||||
#TLS parameters
|
||||
ssl = required
|
||||
ssl_cert = </etc/acme.sh/danwin1210.de_ecc/fullchain.cer
|
||||
ssl_key = </etc/acme.sh/danwin1210.de_ecc/danwin1210.de.key
|
||||
ssl_cert = </etc/ssl/certs/ssl-cert-snakeoil.pem
|
||||
ssl_key = </etc/ssl/private/ssl-cert-snakeoil.key
|
||||
ssl_client_ca_dir = /etc/ssl/certs
|
||||
ssl_dh = </etc/dovecot/dh.pem
|
||||
ssl_min_protocol = TLSv1.2
|
||||
@ -57,17 +62,17 @@ ssl_curve_list = X448:X25519:secp521r1:secp384r1
|
||||
ssl_prefer_server_ciphers = yes
|
||||
|
||||
#protocol setup
|
||||
protocols = "imap pop3 lmtp"
|
||||
protocol lmtp {
|
||||
postmaster_address = postmaster@danwin1210.de
|
||||
}
|
||||
protocols = "imap pop3 lmtp sieve"
|
||||
protocol imap {
|
||||
mail_plugins = $mail_plugins quota imap_quota imap_zlib last_login
|
||||
mail_plugins = $mail_plugins imap_quota imap_zlib imap_sieve last_login
|
||||
imap_metadata = yes
|
||||
}
|
||||
protocol pop3 {
|
||||
mail_plugins = $mail_plugins last_login
|
||||
protocol lmtp {
|
||||
mail_plugins = mail_crypt quota zlib sieve last_login
|
||||
}
|
||||
protocol sieve {
|
||||
mail_plugins =
|
||||
}
|
||||
|
||||
#service setup
|
||||
service anvil {
|
||||
unix_listener anvil-auth-penalty {
|
||||
@ -105,6 +110,9 @@ service auth-worker {
|
||||
service imap {
|
||||
service_count = 1000
|
||||
client_limit = 1
|
||||
unix_listener imap-master {
|
||||
user = $default_internal_user
|
||||
}
|
||||
}
|
||||
service imap-login {
|
||||
inet_listener imap {
|
||||
@ -112,7 +120,7 @@ service imap-login {
|
||||
}
|
||||
service_count = 1000
|
||||
vsz_limit = 1G
|
||||
process_min_avail = 4
|
||||
process_min_avail = 1
|
||||
}
|
||||
service lmtp {
|
||||
unix_listener /var/spool/postfix/private/dovecot-lmtp {
|
||||
@ -164,17 +172,20 @@ dict {
|
||||
namespace inbox {
|
||||
inbox = yes
|
||||
mailbox Drafts {
|
||||
auto = subscribe
|
||||
special_use = \Drafts
|
||||
}
|
||||
mailbox Junk {
|
||||
special_use = \Junk
|
||||
}
|
||||
mailbox Trash {
|
||||
auto = subscribe
|
||||
special_use = \Trash
|
||||
autoexpunge = 30d
|
||||
}
|
||||
|
||||
mailbox Sent {
|
||||
auto = subscribe
|
||||
special_use = \Sent
|
||||
}
|
||||
mailbox "Sent Messages" {
|
||||
|
29
etc/nginx/fastcgi.conf
Normal file
29
etc/nginx/fastcgi.conf
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param QUERY_STRING $query_string;
|
||||
fastcgi_param REQUEST_METHOD $request_method;
|
||||
fastcgi_param CONTENT_TYPE $content_type;
|
||||
fastcgi_param CONTENT_LENGTH $content_length;
|
||||
|
||||
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
|
||||
fastcgi_param REQUEST_URI $request_uri;
|
||||
fastcgi_param DOCUMENT_URI $document_uri;
|
||||
fastcgi_param DOCUMENT_ROOT $document_root;
|
||||
fastcgi_param SERVER_PROTOCOL $server_protocol;
|
||||
fastcgi_param REQUEST_SCHEME $scheme;
|
||||
fastcgi_param HTTPS $https if_not_empty;
|
||||
fastcgi_param HTTP_HOST $host;
|
||||
|
||||
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
|
||||
fastcgi_param SERVER_SOFTWARE nginx;
|
||||
|
||||
fastcgi_param REMOTE_ADDR $remote_addr;
|
||||
fastcgi_param REMOTE_PORT $remote_port;
|
||||
fastcgi_param REMOTE_USER $remote_user;
|
||||
fastcgi_param SERVER_ADDR $server_addr;
|
||||
fastcgi_param SERVER_PORT $php_port;
|
||||
fastcgi_param SERVER_NAME $server_name;
|
||||
|
||||
# PHP only, required if PHP was built with --enable-force-cgi-redirect
|
||||
fastcgi_param REDIRECT_STATUS 200;
|
||||
fastcgi_hide_header "X-Powered-By";
|
@ -4,6 +4,7 @@ pid /run/nginx.pid;
|
||||
pcre_jit on;
|
||||
worker_rlimit_nofile 30000;
|
||||
worker_shutdown_timeout 1m;
|
||||
include /etc/nginx/modules-enabled/*.conf;
|
||||
|
||||
events {
|
||||
worker_connections 7680;
|
||||
@ -24,7 +25,7 @@ http {
|
||||
keepalive_timeout 65;
|
||||
types_hash_max_size 2048;
|
||||
server_tokens off;
|
||||
client_max_body_size 50M;
|
||||
client_max_body_size 50M;
|
||||
client_body_timeout 10s;
|
||||
client_header_timeout 10s;
|
||||
client_body_buffer_size 32k;
|
||||
@ -51,8 +52,8 @@ http {
|
||||
ssl_early_data off;
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
ssl_certificate /etc/acme.sh/danwin1210.de_ecc/fullchain.cer;
|
||||
ssl_certificate_key /etc/acme.sh/danwin1210.de_ecc/danwin1210.de.key;
|
||||
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
|
||||
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
|
||||
ssl_dhparam /etc/nginx/dh4096.pem;
|
||||
|
||||
##
|
||||
@ -66,18 +67,10 @@ http {
|
||||
resolver 127.0.0.1 [::1];
|
||||
resolver_timeout 2s;
|
||||
root /var/www/html;
|
||||
proxy_cache_path /var/lib/nginx/cache levels=2 keys_zone=cache:10m inactive=30d max_size=1g;
|
||||
proxy_cache_revalidate on;
|
||||
proxy_cache_use_stale http_503 timeout updating error;
|
||||
proxy_no_cache $http_pragma $http_authorization;
|
||||
proxy_cache_bypass $cookie_nocache $arg_nocache;
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' '';
|
||||
}
|
||||
proxy_cache_lock_timeout 2m;
|
||||
proxy_cache_lock_age 2m;
|
||||
proxy_cache cache;
|
||||
proxy_http_version 1.1;
|
||||
proxy_buffer_size 8k;
|
||||
proxy_buffering off;
|
||||
@ -88,8 +81,6 @@ http {
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_ignore_client_abort on;
|
||||
proxy_cache_key $server_name$request_method$host$request_uri;
|
||||
proxy_read_timeout 3600; #wait up to 60 minutes for e.g. database import
|
||||
|
||||
##
|
||||
# Gzip Settings
|
||||
@ -123,6 +114,12 @@ http {
|
||||
}
|
||||
expires $expires;
|
||||
|
||||
map $server_port $php_port {
|
||||
80 80;
|
||||
443 443;
|
||||
default 80;
|
||||
}
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
include /etc/nginx/sites-enabled/*;
|
||||
}
|
||||
|
@ -28,13 +28,13 @@ server {
|
||||
add_header Cross-Origin-Opener-Policy same-origin always;
|
||||
add_header Cross-Origin-Resource-Policy same-origin always;
|
||||
include snippets/fastcgi-php.conf;
|
||||
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
|
||||
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
|
||||
expires off;
|
||||
}
|
||||
location ~ \.php$ {
|
||||
add_header Referrer-Policy no-referrer always;
|
||||
include snippets/fastcgi-php.conf;
|
||||
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
|
||||
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
|
||||
expires off;
|
||||
}
|
||||
}
|
||||
@ -45,14 +45,13 @@ server {
|
||||
add_header Referrer-Policy no-referrer always;
|
||||
add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), geolocation=(), fullscreen=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), speaker-selection=(), conversion-measurement=(), focus-without-user-activation=(), hid=(), idle-detection=(), sync-script=(), vertical-scroll=(), serial=(), trust-token-redemption=(), interest-cohort=(), otp-credentials=()" always;
|
||||
add_header Onion-Location http://danielas3rtn54uwmofdo3x2bsdifr47huasnmbgqzfrec5ubupvtpid.onion$request_uri always;
|
||||
add_header Expect-CT "max-age=86400, enforce" always;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
add_header Cross-Origin-Embedder-Policy require-corp always;
|
||||
add_header Cross-Origin-Opener-Policy same-origin always;
|
||||
add_header Cross-Origin-Resource-Policy same-origin always;
|
||||
listen [::]:443 ssl proxy_protocol http2;
|
||||
ssl_certificate /etc/acme.sh/danwin1210.de_ecc/fullchain.cer;
|
||||
ssl_certificate_key /etc/acme.sh/danwin1210.de_ecc/danwin1210.de.key;
|
||||
listen [::]:443 ssl http2 fastopen=100 backlog=2048 ipv6only=off default_server;
|
||||
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
|
||||
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
|
||||
root /var/www/html;
|
||||
index index.php;
|
||||
server_name danielas3rtn54uwmofdo3x2bsdifr47huasnmbgqzfrec5ubupvtpid.onion danwin1210.de;
|
||||
@ -70,22 +69,20 @@ server {
|
||||
add_header Referrer-Policy no-referrer always;
|
||||
add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), geolocation=(), fullscreen=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), speaker-selection=(), conversion-measurement=(), focus-without-user-activation=(), hid=(), idle-detection=(), sync-script=(), vertical-scroll=(), serial=(), trust-token-redemption=(), interest-cohort=(), otp-credentials=()" always;
|
||||
add_header Onion-Location http://danielas3rtn54uwmofdo3x2bsdifr47huasnmbgqzfrec5ubupvtpid.onion$request_uri always;
|
||||
add_header Expect-CT "max-age=86400, enforce" always;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
add_header Cross-Origin-Embedder-Policy require-corp always;
|
||||
add_header Cross-Origin-Opener-Policy same-origin always;
|
||||
add_header Cross-Origin-Resource-Policy same-origin always;
|
||||
include snippets/fastcgi-php.conf;
|
||||
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
|
||||
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
|
||||
expires off;
|
||||
}
|
||||
location ~ \.php$ {
|
||||
add_header Referrer-Policy no-referrer always;
|
||||
add_header Onion-Location http://danielas3rtn54uwmofdo3x2bsdifr47huasnmbgqzfrec5ubupvtpid.onion$request_uri always;
|
||||
add_header Expect-CT "max-age=86400, enforce" always;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
include snippets/fastcgi-php.conf;
|
||||
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
|
||||
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
|
||||
expires off;
|
||||
}
|
||||
}
|
||||
|
18
etc/nginx/sites-enabled/mta-sts
Normal file
18
etc/nginx/sites-enabled/mta-sts
Normal file
@ -0,0 +1,18 @@
|
||||
server {
|
||||
listen [::]:443 ssl http2;
|
||||
server_name mta-sts.danwin1210.de;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
|
||||
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
|
||||
location / {
|
||||
return 404;
|
||||
}
|
||||
location = /.well-known/mta-sts.txt {
|
||||
default_type text/plain;
|
||||
return 200 "version: STSv1
|
||||
mode: enforce
|
||||
mx: danwin1210.de
|
||||
max_age: 86400
|
||||
";
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
server {
|
||||
listen [::]:443 ssl proxy_protocol http2;
|
||||
add_header Expect-CT "max-age=86400, enforce" always;
|
||||
listen [::]:443 ssl http2;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
root /var/www/html;
|
||||
location / {
|
||||
@ -13,9 +12,9 @@ server {
|
||||
rewrite /.well-known/openpgpkey/(.*)/hu /mail/openpgpkey_wkd.php?domain=$1 last;
|
||||
location ~ \.php$ {
|
||||
include snippets/fastcgi-php.conf;
|
||||
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
|
||||
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
|
||||
expires off;
|
||||
}
|
||||
ssl_certificate /etc/acme.sh/danwin1210.de_ecc/fullchain.cer;
|
||||
ssl_certificate_key /etc/acme.sh/danwin1210.de_ecc/danwin1210.de.key;
|
||||
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
|
||||
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
|
||||
}
|
||||
|
@ -1,2 +1,2 @@
|
||||
/^To:.*@[^@]*\.de-mail\.de/ REJECT "Sorry, you tried contacting a De-Mail Address. This is a special System by the German government, not compatible with E-Mail. More info here: https://www.cio.bund.de/Web/DE/Innovative-Vorhaben/De-Mail/de_mail_node.html"
|
||||
/^To:.*@[^@]*\.de-mail\.de/ REJECT "Sorry, you tried contacting a De-Mail Address. This is a special System by the German government, not compatible with E-Mail. More info here: https://de-mail.info/"
|
||||
/^(To|From).*@example\.com/ REJECT
|
||||
|
@ -1 +0,0 @@
|
||||
DESKTOPRaihan REJECT
|
@ -24,8 +24,8 @@ compatibility_level = 3.6
|
||||
smtputf8_autodetect_classes = all
|
||||
|
||||
# TLS parameters
|
||||
smtpd_tls_cert_file = /etc/acme.sh/danwin1210.de_ecc/fullchain.cer
|
||||
smtpd_tls_key_file = /etc/acme.sh/danwin1210.de_ecc/danwin1210.de.key
|
||||
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
|
||||
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
|
||||
smtpd_tls_ciphers = HIGH
|
||||
smtpd_tls_mandatory_ciphers = HIGH
|
||||
smtp_tls_ciphers = HIGH
|
||||
@ -33,12 +33,11 @@ smtp_tls_mandatory_ciphers = HIGH
|
||||
tls_eecdh_auto_curves = X448 X25519 secp521r1 secp384r1 prime256v1
|
||||
smtpd_tls_protocols = TLSv1.2 TLSv1.3
|
||||
smtp_tls_protocols = TLSv1.2 TLSv1.3
|
||||
smtpd_tls_exclude_ciphers = aNULL MD5 SHA CAMELLIA
|
||||
smtpd_tls_mandatory_exclude_ciphers = aNULL MD5 SHA CAMELLIA
|
||||
smtpd_tls_exclude_ciphers = aNULL MD5 SHA CAMELLIA RSA AES+SHA256 AES+SHA384
|
||||
smtpd_tls_mandatory_exclude_ciphers = aNULL MD5 SHA CAMELLIA RSA AES+SHA256 AES+SHA384
|
||||
smtp_tls_exclude_ciphers = aNULL MD5 SHA CAMELLIA AES+SHA256 AES+SHA384
|
||||
smtp_tls_mandatory_exclude_ciphers = aNULL MD5 SHA CAMELLIA AES+SHA256 AES+SHA384
|
||||
tls_preempt_cipherlist = yes
|
||||
smtpd_tls_dh1024_param_file = /etc/postfix/dh4096.pem
|
||||
smtpd_tls_security_level = may
|
||||
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
|
||||
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
|
||||
@ -50,10 +49,10 @@ smtp_tls_chain_files = /etc/postfix/danwin1210-mail.chain
|
||||
smtpd_tls_received_header = yes
|
||||
|
||||
#lookup maps for domains and email addresses
|
||||
relay_domains = torbox.danwin1210.me torbox.danwin1210.de
|
||||
canonical_maps = inline:{{@mail2tor.onion=@mail2tor.com}, {@torbox3uiot6wchz.onion=@torbox36ijlcevujx7mjb4oiusvwgvmue7jfn2cvutwa6kl6to3uyqad.onion}, {@torbox.onion=@torbox36ijlcevujx7mjb4oiusvwgvmue7jfn2cvutwa6kl6to3uyqad.onion}, {@torbox.danwin1210.me=@torbox36ijlcevujx7mjb4oiusvwgvmue7jfn2cvutwa6kl6to3uyqad.onion}, {@torbox.danwin1210.de=@torbox36ijlcevujx7mjb4oiusvwgvmue7jfn2cvutwa6kl6to3uyqad.onion}}
|
||||
sender_canonical_maps = inline:{{@localhost=@danwin1210.de}, {@danielas3rtn54uwmofdo3x2bsdifr47huasnmbgqzfrec5ubupvtpid.onion=@danwin1210.de}, {@danwin1210.me=@danwin1210.de}}
|
||||
transport_maps = inline:{{torbox3uiot6wchz.onion=relay:[torbox36ijlcevujx7mjb4oiusvwgvmue7jfn2cvutwa6kl6to3uyqad.onion]:25}, {.onion=smtp}, {mail2tor.com=relay:[xc7tgk2c5onxni2wsy76jslfsitxjbbptejnqhw6gy2ft7khpevhc7ad.onion]:25}, {blackhost.xyz=relay:[blackhost7pws76u6vohksdahnm6adf7riukgcmahrwt43wv2drvyxid.onion]:25}} proxy:mysql:/etc/postfix/sql/mysql_transport_maps.cf inline:{*=relay:[10.9.0.1]:1025}
|
||||
relay_domains =
|
||||
canonical_maps = inline:{{@mail2tor.onion=@mail2tor.com}, {@torbox3uiot6wchz.onion=@torbox36ijlcevujx7mjb4oiusvwgvmue7jfn2cvutwa6kl6to3uyqad.onion}, {@torbox.onion=@torbox36ijlcevujx7mjb4oiusvwgvmue7jfn2cvutwa6kl6to3uyqad.onion}}
|
||||
sender_canonical_maps = inline:{{@localhost=@danwin1210.de}, {@danielas3rtn54uwmofdo3x2bsdifr47huasnmbgqzfrec5ubupvtpid.onion=@danwin1210.de}}
|
||||
transport_maps = inline:{{.onion=smtp}, {mail2tor.com=relay:[xc7tgk2c5onxni2wsy76jslfsitxjbbptejnqhw6gy2ft7khpevhc7ad.onion]:25}, {blackhost.xyz=relay:[blackhost7pws76u6vohksdahnm6adf7riukgcmahrwt43wv2drvyxid.onion]:25}} proxy:mysql:/etc/postfix/sql/mysql_transport_maps.cf inline:{*=relay:[10.9.0.1]:1025}
|
||||
virtual_alias_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf
|
||||
virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
|
||||
virtual_mailbox_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf
|
||||
@ -69,20 +68,20 @@ smtpd_recipient_restrictions = check_policy_service inet:127.0.0.1:12340, permit
|
||||
smtpd_sender_restrictions = reject_sender_login_mismatch, check_sender_access inline:{{<> = REJECT}}, permit_sasl_authenticated
|
||||
smtpd_relay_restrictions = permit_sasl_authenticated, permit_auth_destination, reject_unauth_destination
|
||||
smtpd_sender_login_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_auth_maps.cf
|
||||
smtpd_helo_restrictions = check_helo_access hash:/etc/postfix/helo_checks
|
||||
|
||||
# anti-spam settings
|
||||
smtpd_milters = inet:127.0.0.1:11332
|
||||
non_smtpd_milters = inet:127.0.0.1:11332
|
||||
milter_default_action = accept
|
||||
milter_default_action = tempfail
|
||||
milter_protocol = 6
|
||||
header_checks = regexp:/etc/postfix/header_checks
|
||||
body_checks = regexp:/etc/postfix/body_checks
|
||||
disable_vrfy_command = yes
|
||||
smtpd_discard_ehlo_keywords = silent-discard, dsn
|
||||
smtpd_delay_reject = yes
|
||||
smtpd_helo_required = yes
|
||||
strict_rfc821_envelopes = yes
|
||||
default_destination_concurrency_limit = 2
|
||||
smtpd_recipient_limit = 10
|
||||
smtpd_recipient_limit = 5
|
||||
smtp_pix_workarounds = delay_dotcrlf
|
||||
smtpd_forbid_bare_newline = yes
|
||||
smtpd_forbid_unauth_pipelining = yes
|
||||
|
@ -96,7 +96,6 @@ modules_enabled = {
|
||||
"conversejs";
|
||||
"http_altconnect";
|
||||
"external_services";
|
||||
"conversejs";
|
||||
}
|
||||
|
||||
-- These modules are auto-loaded, but should you want
|
||||
@ -125,8 +124,8 @@ pidfile = "/run/prosody/prosody.pid";
|
||||
-- Force clients to use encrypted connections? This option will
|
||||
-- prevent clients from authenticating unless they are using encryption.
|
||||
ssl = {
|
||||
key = "/etc/acme.sh/danwin1210.de_ecc/danwin1210.de.key";
|
||||
certificate = "/etc/acme.sh/danwin1210.de_ecc/fullchain.cer";
|
||||
key = "/etc/ssl/private/ssl-cert-snakeoil.key";
|
||||
certificate = "/etc/ssl/certs/ssl-cert-snakeoil.pem";
|
||||
dhparam = "/etc/prosody/dh4096.pem";
|
||||
curve = "X448:X25519:secp521r1:secp384r1:secp256k1";
|
||||
ciphers = "HIGH+kEDH:HIGH+kEECDH:HIGH:!RSA:!PSK:!SRP:!3DES:!aNULL:!SHA:!MD5:!CAMELLIA:!ECDHE-RSA-AES256-SHA384:!ECDHE-RSA-AES128-SHA256:!DHE-RSA-AES128-SHA256:!DHE-RSA-AES256-SHA256";
|
||||
@ -239,7 +238,7 @@ aliases = {
|
||||
["danielas3rtn54uwmofdo3x2bsdifr47huasnmbgqzfrec5ubupvtpid.onion"] = "danwin1210.de";
|
||||
}
|
||||
alias_response = "User $alias can be contacted at $target";
|
||||
defautl_storage = "sql"
|
||||
default_storage = "sql"
|
||||
interfaces = { "0.0.0.0", "::" } -- Listen address
|
||||
contact_info = {
|
||||
abuse = { "https://danwin1210.de/contact.php", "mailto:daniel@danwin1210.de" };
|
||||
@ -248,7 +247,7 @@ contact_info = {
|
||||
security = { "https://danwin1210.de/contact.php", "mailto:daniel@danwin1210.de" };
|
||||
support = { "https://danwin1210.de/contact.php", "mailto:daniel@danwin1210.de" };
|
||||
}
|
||||
data_path = "/srv/var/lib/prosody"
|
||||
data_path = "/var/lib/prosody"
|
||||
legacy_ssl_ports = {5223}
|
||||
external_services = {
|
||||
{
|
||||
|
73
etc/rc.local
Executable file
73
etc/rc.local
Executable file
@ -0,0 +1,73 @@
|
||||
#!/bin/sh -e
|
||||
#
|
||||
# rc.local
|
||||
#
|
||||
# This script is executed at the end of each multiuser runlevel.
|
||||
# Make sure that the script will "exit 0" on success or any other
|
||||
# value on error.
|
||||
#
|
||||
# In order to enable or disable this script just change the execution
|
||||
# bits.
|
||||
#
|
||||
# By default this script does nothing.
|
||||
|
||||
#flush iptables
|
||||
iptables -F
|
||||
ip6tables -F
|
||||
iptables -t nat -F
|
||||
ip6tables -t nat -F
|
||||
|
||||
#accept already established connections
|
||||
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
ip6tables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
#allow tor traffic
|
||||
for tor in bind debian-tor; do(
|
||||
iptables -t nat -A OUTPUT -m owner --uid-owner $tor -j RETURN
|
||||
ip6tables -t nat -A OUTPUT -m owner --uid-owner $tor -j RETURN
|
||||
iptables -A OUTPUT -m owner --uid-owner $tor -j ACCEPT
|
||||
ip6tables -A OUTPUT -m owner --uid-owner $tor -j ACCEPT
|
||||
)done
|
||||
|
||||
#allow local communication
|
||||
iptables -A OUTPUT -o lo -j ACCEPT
|
||||
ip6tables -A OUTPUT -o lo -j ACCEPT
|
||||
iptables -A INPUT -i lo -j ACCEPT
|
||||
ip6tables -A INPUT -i lo -j ACCEPT
|
||||
#unrestricted access to these IPs
|
||||
for clearnet in 127.0.0.0/8 10.9.0.0/24; do(
|
||||
iptables -t nat -A OUTPUT -d $clearnet -j RETURN
|
||||
iptables -A OUTPUT -d $clearnet -j ACCEPT
|
||||
) done
|
||||
for clearnet in ::1; do(
|
||||
ip6tables -t nat -A OUTPUT -d $clearnet -j RETURN
|
||||
ip6tables -A OUTPUT -d $clearnet -j ACCEPT
|
||||
) done
|
||||
#accet IPv6 ICMP packages required for SLAAC
|
||||
ip6tables -A INPUT -p ipv6-icmp -j ACCEPT
|
||||
ip6tables -A OUTPUT -p ipv6-icmp -j ACCEPT
|
||||
#allow querriying ntp servers
|
||||
iptables -t nat -A OUTPUT -p udp --dport 123 -j RETURN
|
||||
iptables -A OUTPUT -p udp --dport 123 -j ACCEPT
|
||||
ip6tables -t nat -A OUTPUT -p udp --dport 123 -j RETURN
|
||||
ip6tables -A OUTPUT -p udp --dport 123 -j ACCEPT
|
||||
#redirect all outgoing DNS querries to our dns server
|
||||
iptables -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to-ports 53
|
||||
ip6tables -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to-ports 53
|
||||
#redirect all other TCP traffic through tor
|
||||
iptables -t nat -A OUTPUT -p tcp --syn -j REDIRECT --to-ports 9040
|
||||
ip6tables -t nat -A OUTPUT -p tcp --syn -j REDIRECT --to-ports 9040
|
||||
#reject everything else
|
||||
iptables -A OUTPUT -j REJECT
|
||||
ip6tables -A OUTPUT -j REJECT
|
||||
|
||||
#uncomment to be able to directly connect with your own IP and allow no one else
|
||||
#for clearnet in YOUR_IP_HERE;do(
|
||||
#iptables -A INPUT -s $clearnet -j ACCEPT
|
||||
#)done
|
||||
#drop everything else (uncomment after adding your own IP above)
|
||||
#iptables -A INPUT -j DROP
|
||||
#ip6tables -A INPUT -j DROP
|
||||
|
||||
exit 0
|
2
etc/resolv.conf
Normal file
2
etc/resolv.conf
Normal file
@ -0,0 +1,2 @@
|
||||
nameserver 127.0.0.1
|
||||
options edns0 trust-ad
|
@ -4,11 +4,11 @@ domain {
|
||||
danwin1210.de {
|
||||
selectors [
|
||||
{
|
||||
path: "/usr/local/etc/rspamd/dkim_keys/danwin1210.de-rsa";
|
||||
path: "/var/lib/rspamd/dkim/danwin1210.de-rsa";
|
||||
selector: "20211204-rsa";
|
||||
},
|
||||
{
|
||||
path: "/usr/local/etc/rspamd/dkim_keys/danwin1210.de-ed25519";
|
||||
path: "/var/lib/rspamd/dkim/danwin1210.de-ed25519";
|
||||
selector: "20211204-ed25519";
|
||||
}
|
||||
]
|
@ -8,11 +8,11 @@ domain {
|
||||
danwin1210.de {
|
||||
selectors [
|
||||
{
|
||||
path: "/usr/local/etc/rspamd/dkim_keys/danwin1210.de-rsa";
|
||||
path: "/var/lib/rspamd/dkim/danwin1210.de-rsa";
|
||||
selector: "20211204-rsa";
|
||||
},
|
||||
{
|
||||
path: "/usr/local/etc/rspamd/dkim_keys/danwin1210.de-ed25519";
|
||||
path: "/var/lib/rspamd/dkim/danwin1210.de-ed25519";
|
||||
selector: "20211204-ed25519";
|
||||
}
|
||||
]
|
6
etc/systemd/system/mail-cron.service
Normal file
6
etc/systemd/system/mail-cron.service
Normal file
@ -0,0 +1,6 @@
|
||||
[Unit]
|
||||
Description=Mail cron
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/php /var/www/mail/cron.php
|
12
etc/systemd/system/mail-cron.timer
Normal file
12
etc/systemd/system/mail-cron.timer
Normal file
@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Mail cron
|
||||
|
||||
[Timer]
|
||||
# Time to wait after booting before we run first time
|
||||
OnBootSec=3min
|
||||
# Time between running each consecutive time
|
||||
OnUnitActiveSec=5m
|
||||
Unit=mail-cron.service
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -4,6 +4,7 @@ pid /run/nginx.pid;
|
||||
pcre_jit on;
|
||||
worker_rlimit_nofile 30000;
|
||||
worker_shutdown_timeout 1m;
|
||||
include /etc/nginx/modules-enabled/*.conf;
|
||||
|
||||
events {
|
||||
worker_connections 20000;
|
||||
@ -50,8 +51,8 @@ http {
|
||||
ssl_early_data off;
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
ssl_certificate /etc/acme.sh/danwin1210.de_ecc/fullchain.cer;
|
||||
ssl_certificate_key /etc/acme.sh/danwin1210.de_ecc/danwin1210.de.key;
|
||||
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
|
||||
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
|
||||
ssl_dhparam /etc/nginx/dh4096.pem;
|
||||
|
||||
##
|
||||
@ -65,18 +66,10 @@ http {
|
||||
resolver 127.0.0.1 [::1];
|
||||
resolver_timeout 2s;
|
||||
root /var/www/html;
|
||||
proxy_cache_path /var/lib/nginx/cache levels=2 keys_zone=cache:10m inactive=30d max_size=1g;
|
||||
proxy_cache_revalidate on;
|
||||
proxy_cache_use_stale http_503 timeout updating error;
|
||||
proxy_no_cache $http_pragma $http_authorization;
|
||||
proxy_cache_bypass $cookie_nocache $arg_nocache;
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' '';
|
||||
}
|
||||
proxy_cache_lock_timeout 2m;
|
||||
proxy_cache_lock_age 2m;
|
||||
proxy_cache cache;
|
||||
proxy_http_version 1.1;
|
||||
proxy_buffer_size 8k;
|
||||
proxy_buffering on;
|
||||
@ -87,8 +80,6 @@ http {
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_ignore_client_abort on;
|
||||
proxy_cache_key $server_name$request_method$host$request_uri;
|
||||
proxy_read_timeout 3600; #wait up to 60 minutes for e.g. database import
|
||||
|
||||
##
|
||||
# Gzip Settings
|
||||
@ -119,22 +110,17 @@ stream {
|
||||
ssl_ecdh_curve X448:X25519:secp521r1:secp384r1:secp256k1;
|
||||
ssl_ciphers HIGH:!PSK:!RSA:!aNULL:!MD5:!SHA:!CAMELLIA:!AES+SHA256:!AES+SHA384;
|
||||
ssl_session_cache shared:SSLSTREAM:10m;
|
||||
ssl_certificate /etc/acme.sh/danwin1210.de_ecc/fullchain.cer;
|
||||
ssl_certificate_key /etc/acme.sh/danwin1210.de_ecc/danwin1210.de.key;
|
||||
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
|
||||
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
|
||||
ssl_dhparam /etc/nginx/dh4096.pem;
|
||||
#smtp
|
||||
server {
|
||||
listen [::]:25 fastopen=100 ipv6only=off;
|
||||
proxy_pass smtp_backend_servers;
|
||||
deny 51.254.78.246;
|
||||
}
|
||||
server {
|
||||
listen [::]:587 fastopen=100 ipv6only=off;
|
||||
proxy_pass smtp_auth_backend_servers;
|
||||
deny 49.70.67.204;
|
||||
deny 87.246.7.212;
|
||||
deny 37.49.225.155;
|
||||
deny 103.151.123.103;
|
||||
}
|
||||
server {
|
||||
listen [::]:465 fastopen=100 ipv6only=off;
|
||||
@ -166,93 +152,59 @@ stream {
|
||||
#xmpp
|
||||
server {
|
||||
listen [::]:5269 fastopen=100 ipv6only=off;
|
||||
proxy_pass 10.9.0.3:5269;
|
||||
proxy_pass 10.9.0.2:5269;
|
||||
}
|
||||
server {
|
||||
listen [::]:5000 fastopen=100 ipv6only=off;
|
||||
proxy_pass 10.9.0.3:5000;
|
||||
proxy_pass 10.9.0.2:5000;
|
||||
}
|
||||
server {
|
||||
listen [::]:5222 fastopen=100 ipv6only=off;
|
||||
proxy_pass 10.9.0.3:5222;
|
||||
proxy_pass 10.9.0.2:5222;
|
||||
}
|
||||
server {
|
||||
listen [::]:5223 fastopen=100 ipv6only=off;
|
||||
proxy_pass 10.9.0.3:5223;
|
||||
proxy_pass 10.9.0.2:5223;
|
||||
}
|
||||
server {
|
||||
listen [::]:5280 fastopen=100 ipv6only=off;
|
||||
proxy_pass 10.9.0.3:5280;
|
||||
proxy_pass 10.9.0.2:5280;
|
||||
}
|
||||
server {
|
||||
listen [::]:5281 fastopen=100 ipv6only=off;
|
||||
proxy_pass 10.9.0.3:5281;
|
||||
proxy_pass 10.9.0.2:5281;
|
||||
}
|
||||
#https
|
||||
server {
|
||||
listen [::]:443 fastopen=100 ipv6only=off;
|
||||
# limit_conn addr 2;
|
||||
# proxy_upload_rate 4k;
|
||||
proxy_protocol on;
|
||||
proxy_pass https_backend_servers;
|
||||
}
|
||||
#upstream servers
|
||||
upstream https_backend_servers {
|
||||
server 10.9.0.2:443;
|
||||
server 10.9.0.3:443;
|
||||
server 10.9.0.4:443;
|
||||
server 10.9.0.5:443;
|
||||
}
|
||||
upstream imaps_backend_servers {
|
||||
server 10.9.0.2:993;
|
||||
server 10.9.0.3:993;
|
||||
server 10.9.0.4:993;
|
||||
server 10.9.0.5:993;
|
||||
}
|
||||
upstream imap_backend_servers {
|
||||
server 10.9.0.2:143;
|
||||
server 10.9.0.3:143;
|
||||
server 10.9.0.4:143;
|
||||
server 10.9.0.5:143;
|
||||
}
|
||||
upstream pop3s_backend_servers {
|
||||
server 10.9.0.2:995;
|
||||
server 10.9.0.3:995;
|
||||
server 10.9.0.4:995;
|
||||
server 10.9.0.5:995;
|
||||
}
|
||||
upstream pop3_backend_servers {
|
||||
server 10.9.0.2:110;
|
||||
server 10.9.0.3:110;
|
||||
server 10.9.0.4:110;
|
||||
server 10.9.0.5:110;
|
||||
}
|
||||
upstream dns_backend_server {
|
||||
server [::1]:53;
|
||||
server 127.0.0.1:53;
|
||||
}
|
||||
upstream smtp_backend_servers {
|
||||
server 10.9.0.2:25;
|
||||
server 10.9.0.3:25;
|
||||
server 10.9.0.4:25;
|
||||
server 10.9.0.5:25;
|
||||
}
|
||||
upstream smtp_auth_backend_servers {
|
||||
server 10.9.0.2:587;
|
||||
server 10.9.0.3:587;
|
||||
server 10.9.0.4:587;
|
||||
server 10.9.0.5:587;
|
||||
}
|
||||
upstream smtps_backend_servers {
|
||||
server 10.9.0.2:465;
|
||||
server 10.9.0.3:465;
|
||||
server 10.9.0.4:465;
|
||||
server 10.9.0.5:465;
|
||||
}
|
||||
upstream mysql_backend_servers {
|
||||
server 10.9.0.2:3306;
|
||||
server 10.9.0.3:3306;
|
||||
server 10.9.0.4:3306;
|
||||
server 10.9.0.5:3306;
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ readme_directory = no
|
||||
compatibility_level=3.6
|
||||
|
||||
# TLS parameters
|
||||
smtpd_tls_cert_file=/etc/acme.sh/danwin1210.de_ecc/fullchain.cer
|
||||
smtpd_tls_key_file=/etc/acme.sh/danwin1210.de_ecc/danwin1210.de.key
|
||||
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
|
||||
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
|
||||
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
|
||||
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
|
||||
smtpd_tls_ciphers = HIGH
|
||||
|
2
etc_clearnet_proxy/resolv.conf
Normal file
2
etc_clearnet_proxy/resolv.conf
Normal file
@ -0,0 +1,2 @@
|
||||
nameserver 127.0.0.1
|
||||
options edns0 trust-ad
|
@ -457,7 +457,7 @@ realm=danwin1210.de
|
||||
# Use PEM file format.
|
||||
#
|
||||
#cert=/usr/local/etc/turn_server_cert.pem
|
||||
cert=/etc/acme.sh/danwin1210.de_ecc/fullchain.cer
|
||||
cert=/etc/ssl/certs/ssl-cert-snakeoil.pem
|
||||
|
||||
# Private key file.
|
||||
# Use an absolute path or path relative to the
|
||||
@ -465,7 +465,7 @@ cert=/etc/acme.sh/danwin1210.de_ecc/fullchain.cer
|
||||
# Use PEM file format.
|
||||
#
|
||||
#pkey=/usr/local/etc/turn_server_pkey.pem
|
||||
pkey=/etc/acme.sh/danwin1210.de_ecc/danwin1210.de.key
|
||||
pkey=/etc/ssl/private/ssl-cert-snakeoil.key
|
||||
|
||||
# Private key file password, if it is in encoded format.
|
||||
# This option has no default value.
|
||||
|
@ -8,53 +8,51 @@ workingdir=$(pwd)
|
||||
|
||||
# install all required packages
|
||||
DEBIAN_FRONTEND=noninteractive apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends install -y apt-transport-tor bash-completion bind9 ca-certificates clamav-daemon clamav-freshclam curl dovecot-imapd dovecot-lmtpd dovecot-pop3d git gnupg haveged iptables libsasl2-modules locales locales-all logrotate lsb-release mariadb-server mercurial nano nginx openssl php8.1-cli php8.1-curl php8.1-fpm php8.1-gd php8.1-gmp php8.1-gnupg php8.1-imap php8.1-intl php8.1-mbstring php8.1-mysql php8.1-pspell php8.1-readline postfix postfix-mysql prosody redis tor vim wget unzip wireguard wireguard-tools
|
||||
# build dependencies
|
||||
DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends install -y autoconf automake cmake g++ gcc libcurl4-openssl-dev libglib2.0-dev libicu-dev libluajit-5.1-dev libpcre3-dev libsodium-dev libsqlite3-dev libssl-dev libtool make ragel zlib1g-dev
|
||||
|
||||
# initial repository clones
|
||||
if [ ! -e rspamd ]; then
|
||||
git clone --recurse-submodules https://github.com/rspamd/rspamd.git
|
||||
fi
|
||||
export PROC_LIMIT=`free -g | grep Mem | awk -v nproc=$(nproc) '{print (($2 + 1) < nproc) ? ($2 + 1) : nproc;}'`
|
||||
# start build
|
||||
cd rspamd
|
||||
git fetch --all --recurse-submodules
|
||||
git checkout 3.5 --recurse-submodules
|
||||
cd ..
|
||||
mkdir -p rspamd_build
|
||||
cd rspamd_build
|
||||
cmake ../rspamd -DENABLE_LUAJIT=ON -DCMAKE_BUILD_TYPE=Release
|
||||
make -j $PROC_LIMIT
|
||||
make install
|
||||
cd ..
|
||||
rm -rf rspamd_build
|
||||
ldconfig
|
||||
DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends install -y apt-transport-tor bash-completion bind9 ca-certificates clamav-daemon clamav-freshclam curl dovecot-imapd dovecot-lmtpd dovecot-managesieved dovecot-mysql dovecot-pop3d dovecot-sieve git gnupg haveged iptables libnginx-mod-http-brotli-filter libsasl2-modules locales locales-all logrotate lsb-release lua-dbi-mysql lua-event lua-unbound mariadb-server mercurial nano nginx openssl patch php8.2-cli php8.2-curl php8.2-fpm php8.2-gd php8.2-gmp php8.2-gnupg php8.2-imap php8.2-intl php8.2-mbstring php8.2-mysql php8.2-pspell php8.2-readline php8.2-tidy php8.2-uuid php8.2-xml php8.2-zip postfix postfix-mysql prosody redis rng-tools5 rspamd tor vim wget unzip wireguard wireguard-tools
|
||||
|
||||
# install composer
|
||||
curl -sSL https://github.com/composer/composer/releases/download/2.3.8/composer.phar > /usr/bin/composer
|
||||
curl -sSL https://github.com/composer/composer/releases/download/2.8.3/composer.phar > /usr/bin/composer
|
||||
chmod +x /usr/bin/composer
|
||||
composer self-update
|
||||
|
||||
# rspamd user
|
||||
id -u _rspamd >/dev/null 2>&1 ||useradd -M -r -s /bin/false -d /var/lib/rspamd _rspamd
|
||||
mkdir -p /var/lib/rspamd
|
||||
chown _rspamd: /var/lib/rspamd
|
||||
|
||||
# mysql encryption
|
||||
if [ ! -e /etc/mysql/encryption/keyfile.enc ]; then
|
||||
mkdir -p /etc/mysql/encryption/
|
||||
openssl rand -hex 128 > /etc/mysql/encryption/keyfile.key
|
||||
echo "1;"$(openssl rand -hex 32) | openssl enc -aes-256-cbc -md sha1 -pass file:/etc/mysql/encryption/keyfile.key -out /etc/mysql/encryption/keyfile.enc
|
||||
fi
|
||||
# dovecot encryption
|
||||
if [ ! -e /etc/dovecot/ecprivkey.pem ]; then
|
||||
mkdir -p /etc/dovecot/
|
||||
openssl ecparam -name secp521r1 -genkey | openssl pkey -out /etc/dovecot/ecprivkey.pem
|
||||
openssl pkey -in /etc/dovecot/ecprivkey.pem -pubout -out /etc/dovecot/ecpubkey.pem
|
||||
fi
|
||||
# postifx certificates
|
||||
if [ ! -e /etc/postfix/danwin1210-mail.chain ]; then
|
||||
openssl req -x509 -nodes -days 3650 -newkey ed448 -subj "/" -keyout /etc/postfix/danwin1210-mail.key -out /etc/postfix/danwin1210-mail.crt && cat /etc/postfix/danwin1210-mail.key >> /etc/postfix/danwin1210-mail.chain && cat /etc/postfix/danwin1210-mail.crt >> /etc/postfix/danwin1210-mail.chain
|
||||
fi
|
||||
|
||||
# dhparams
|
||||
for file in /etc/nginx/dh4096.pem /etc/dovecot/dh.pem /etc/prosody/dh4096.pem; do
|
||||
if [ ! -e "$file" ]; then
|
||||
openssl dhparam -out "$file" 4096
|
||||
fi
|
||||
done
|
||||
|
||||
# vmail user
|
||||
id -u vmail > /dev/null 2>&1 || (groupadd -g 5000 -r vmail && useradd -g 5000 -M -r -s /bin/false -u 5000 vmail -d /var/mail/vmail)
|
||||
mkdir -p /var/mail/vmail
|
||||
chown vmail: /var/mail/vmail
|
||||
|
||||
#install scripts
|
||||
mkdir -p /var/www/mail
|
||||
mkdir -p /var/www/html
|
||||
mkdir -p /var/lib/rspamd/dkim
|
||||
chown _rspamd: /var/lib/rspamd/dkim
|
||||
if [ ! -e /var/www/html/mail ]; then
|
||||
ln -s ../mail/www /var/www/html/mail
|
||||
fi
|
||||
cp -r composer.json cron.php setup.php www /var/www/mail/
|
||||
cp -r composer.json cron.php setup.php www tools locale /var/www/mail/
|
||||
cd /var/www/mail/
|
||||
composer install --no-dev
|
||||
|
||||
@ -66,12 +64,58 @@ if [ ! -e /var/www/mail/www/squirrelmail ]; then
|
||||
git clone https://github.com/RealityRipple/squirrelmail .
|
||||
mkdir -p /var/local/squirrelmail/data /var/local/squirrelmail/attach
|
||||
chown www-data:www-data -R /var/local/squirrelmail
|
||||
cd $workingdir
|
||||
cp squirrelmail_config.php /var/www/mail/www/squirrelmail/config/config.php
|
||||
else
|
||||
cd /var/www/mail/www/squirrelmail
|
||||
git fetch --all
|
||||
git pull
|
||||
fi
|
||||
|
||||
if [ ! -e /var/www/mail/www/squirrelmail/plugins/check_quota/ ]; then
|
||||
cd /var/www/mail/www/squirrelmail/plugins/
|
||||
wget https://www.squirrelmail.org/plugins/check_quota-2.2-1.4.0.tar.gz
|
||||
tar -zxf check_quota-2.2-1.4.0.tar.gz
|
||||
rm check_quota-2.2-1.4.0.tar.gz
|
||||
cd $workingdir
|
||||
cp squirrelmail_plugin_hooks.php /var/www/mail/www/squirrelmail/config/plugin_hooks.php
|
||||
patch -p1 -d /var/www/html/mail/squirrelmail/plugins/check_quota/ < squirrelmail_check_quota.patch
|
||||
fi
|
||||
|
||||
# install snappymail
|
||||
mkdir -p /var/www/mail/www/snappymail
|
||||
cd /var/www/mail/www/snappymail
|
||||
VERSION=$(curl -s https://api.github.com/repos/the-djmaze/snappymail/releases/latest | grep tag_name | cut -d '"' -f 4)
|
||||
wget https://github.com/the-djmaze/snappymail/releases/download/${VERSION}/snappymail-${VERSION:1}.zip
|
||||
unzip -o snappymail-${VERSION:1}.zip
|
||||
rm snappymail-${VERSION:1}.zip
|
||||
mkdir -p /var/local/snappymail
|
||||
chown www-data:www-data -R /var/local/snappymail
|
||||
if [ ! -e include.php ]; then
|
||||
cp _include.php include.php
|
||||
echo "define('APP_DATA_FOLDER_PATH', '/var/local/snappymail/');" >> include.php
|
||||
echo "define('SNAPPYMAIL_UPDATE_PLUGINS', 1);" >> include.php
|
||||
fi
|
||||
|
||||
# install converse.js
|
||||
rm -rf /srv/conversejs
|
||||
mkdir -p /srv/conversejs
|
||||
cd /srv/conversejs
|
||||
VERSION=$(curl -s https://api.github.com/repos/conversejs/converse.js/releases/latest | grep tag_name | cut -d '"' -f 4)
|
||||
wget https://github.com/conversejs/converse.js/releases/download/${VERSION}/converse.js-${VERSION:1}.tgz
|
||||
tar xzf converse.js-${VERSION:1}.tgz --strip-components=1
|
||||
rm converse.js-${VERSION:1}.tgz
|
||||
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# install prosody modules
|
||||
if [ ! -e /srv/prosody-modules ]; then
|
||||
hg clone https://hg.prosody.im/prosody-modules/ /srv/prosody-modules
|
||||
else
|
||||
cd /srv/prosody-modules
|
||||
hg pull --update
|
||||
fi
|
||||
|
||||
# copy configuration file
|
||||
cd $workingdir
|
||||
if [ ! -e /var/www/mail/common_config.php ]; then
|
||||
|
@ -5,4 +5,13 @@ export LANG=C.UTF-8
|
||||
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin"
|
||||
# install all required packages
|
||||
DEBIAN_FRONTEND=noninteractive apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends install -y bash-completion bind9 ca-certificates coturn curl git gnupg haveged iptables libsasl2-modules logrotate lsb-release nano nginx openssl postfix postfix-mysql postfix-mta-sts-resolver vim wget wireguard wireguard-tools
|
||||
DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends install -y bash-completion bind9 ca-certificates coturn curl git gnupg haveged iptables libnginx-mod-stream libnginx-mod-http-brotli-filter libsasl2-modules logrotate lsb-release nano nginx openssl postfix postfix-mysql postfix-mta-sts-resolver rng-tools5 vim wget wireguard wireguard-tools
|
||||
|
||||
# dhparams
|
||||
for file in /etc/nginx/dh4096.pem; do
|
||||
if [ ! -e "$file" ]; then
|
||||
openssl dhparam -out "$file" 4096
|
||||
fi
|
||||
done
|
||||
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
locale/uk_UA/LC_MESSAGES/mail-hosting.mo
Normal file
BIN
locale/uk_UA/LC_MESSAGES/mail-hosting.mo
Normal file
Binary file not shown.
1130
locale/uk_UA/LC_MESSAGES/mail-hosting.po
Normal file
1130
locale/uk_UA/LC_MESSAGES/mail-hosting.po
Normal file
File diff suppressed because it is too large
Load Diff
10
setup.php
10
setup.php
@ -60,3 +60,13 @@ try{
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
}
|
||||
}
|
||||
try {
|
||||
$stmt = $db->prepare( 'INSERT IGNORE INTO domain (domain, created, modified) VALUES (?, NOW(), NOW())' );
|
||||
$stmt->execute( [ CLEARNET_SERVER ] );
|
||||
$stmt->execute( [ ONION_SERVER ] );
|
||||
$stmt = $db->prepare( 'INSERT IGNORE INTO alias_domain (alias_domain, target_domain, created, modified) VALUES (?, ?, NOW(), NOW())' );
|
||||
$stmt->execute( [ ONION_SERVER, CLEARNET_SERVER ] );
|
||||
} catch( PDOException $e ) {
|
||||
echo _('Error adding primary domain:') . PHP_EOL;
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
}
|
||||
|
458
squirrelmail_check_quota.patch
Normal file
458
squirrelmail_check_quota.patch
Normal file
@ -0,0 +1,458 @@
|
||||
diff -ruN check_quota_old/config.php check_quota/config.php
|
||||
--- check_quota_old/config.php 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ check_quota/config.php 2023-05-22 08:47:49.000000000 +0200
|
||||
@@ -0,0 +1,409 @@
|
||||
+<?php
|
||||
+
|
||||
+/*
|
||||
+ * This is the configuration file for Check Quota Plugin.
|
||||
+ * You can edit the options here to suit your needs.
|
||||
+ * Please make sure you read the INSTALL file before configuring
|
||||
+ * these options.
|
||||
+*/
|
||||
+
|
||||
+global $settings;
|
||||
+$settings = array();
|
||||
+
|
||||
+
|
||||
+/*******************************
|
||||
+ * Quota Configuration Options *
|
||||
+ *******************************/
|
||||
+
|
||||
+/*
|
||||
+ * Use UNIX (filesystem), IMAP-based or cPanel (experimental) quotas?
|
||||
+ * If you use UNIX (filesystem) quotas, you should set this to 0.
|
||||
+ * If you use IMAP-based quotas, you should set this to 1.
|
||||
+ * If you use cPanel quotas, you should set this to 2.
|
||||
+ *
|
||||
+ * Default: UNIX (filesystem) quotas
|
||||
+ * 0: UNIX / 1: IMAP / 2: cPanel
|
||||
+*/
|
||||
+
|
||||
+$settings['quota_type'] = 1;
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * If you are using UNIX (filesystem) quotas, set the path
|
||||
+ * to the "sudo" binary here. See INSTALL for instructions.
|
||||
+*/
|
||||
+
|
||||
+$settings['sudo_binary'] = '/usr/bin/sudo';
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * If you are using UNIX quotas, set the path to the "quota"
|
||||
+ * binary here. See INSTALL for instructions.
|
||||
+*/
|
||||
+
|
||||
+$settings['quota_binary'] = '/usr/bin/quota';
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * If you are using UNIX quotas and your IMAP server and web server
|
||||
+ * are on different physical machines (i.e. you want to check UNIX
|
||||
+ * quotas remotely) set this to 1. See INSTALL for instructions.
|
||||
+ *
|
||||
+ * This setting is only used for UNIX quotas.
|
||||
+ *
|
||||
+ * Default: Check on local server
|
||||
+ * 0: Check on local server / 1: Check on remote server
|
||||
+*/
|
||||
+
|
||||
+$settings['check_unix_on_remote_server'] = 0;
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * If you are using UNIX quotas and your IMAP server and web server
|
||||
+ * are on different physical machines (i.e. you want to check UNIX
|
||||
+ * quotas remotely) set the path to the "ssh" binary here. See INSTALL
|
||||
+ * for instructions.
|
||||
+ *
|
||||
+ * This setting is only used for remote UNIX quotas.
|
||||
+*/
|
||||
+
|
||||
+$settings['ssh_binary'] = '/usr/bin/ssh';
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * If you are using UNIX quotas and your IMAP server and web server
|
||||
+ * are on different physical machines (i.e. you want to check UNIX
|
||||
+ * quotas remotely) set the username that will check quotas on your
|
||||
+ * IMAP server here. See INSTALL for instructions.
|
||||
+ *
|
||||
+ * This setting is only used for remote UNIX quotas.
|
||||
+*/
|
||||
+
|
||||
+$settings['remote_unix_user'] = 'cquotauser';
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * If you are using UNIX quotas and your IMAP server and web server
|
||||
+ * are on different physical machines (i.e. you want to check UNIX
|
||||
+ * quotas remotely) set the IP address or hostname of your IMAP
|
||||
+ * server here. See INSTALL for instructions.
|
||||
+ *
|
||||
+ * This setting is only used for remote UNIX quotas.
|
||||
+*/
|
||||
+
|
||||
+$settings['remote_unix_server'] = '192.168.1.1';
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * If you are using cPanel quotas, set the path to the "du" binary
|
||||
+ * here. See INSTALL for instructions.
|
||||
+*/
|
||||
+
|
||||
+$settings['du_binary'] = '/usr/bin/du';
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * If you are using cPanel quotas, set the cPanel root path here.
|
||||
+ * See INSTALL for instructions.
|
||||
+*/
|
||||
+
|
||||
+$settings['cpanel_root'] = '/path/to/cpanel/root';
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * If you want to use a separate IMAP connection when checking your
|
||||
+ * quota, set this variable to 1, else, set it to 0
|
||||
+ *
|
||||
+ * This will be a waste of resources if there already is an open
|
||||
+ * IMAP connection to your server. So, most probably you will not need
|
||||
+ * to adjust this variable in most occasions.
|
||||
+ *
|
||||
+ * Default: Do not use separate IMAP connection
|
||||
+ * 0: Do not use separate connection / 1: Use separate connection
|
||||
+*/
|
||||
+
|
||||
+$settings['use_separate_imap_connection'] = 0;
|
||||
+
|
||||
+/***************************
|
||||
+ * General Display Options *
|
||||
+ ***************************/
|
||||
+
|
||||
+/*
|
||||
+ * Which graph type do you prefer?
|
||||
+ *
|
||||
+ * You have three options here. You can use HTML tables, GD images,
|
||||
+ * or Flash graphics.
|
||||
+ *
|
||||
+ * GD images can only be generated if you have GD support built into
|
||||
+ * PHP (--with-gd). For more information on how to install GD support
|
||||
+ * in PHP, see:
|
||||
+ *
|
||||
+ * http://www.php.net/manual/ref.image.php
|
||||
+ *
|
||||
+ * If your server doesn't have GD png, gif or jpg support but you enable GD
|
||||
+ * graphics, the plugin will revert to HTML tables.
|
||||
+ *
|
||||
+ * As SquirrelMail is a pure PHP-driven webmail program, and some people do
|
||||
+ * not have GD support in PHP, default is HTML tables.
|
||||
+ *
|
||||
+ * You will get the most satisfying graph output with GD or Flash graphs.
|
||||
+ *
|
||||
+ * Default: Use HTML
|
||||
+ * 0: Use HTML / 1: Use GD / 2: Use Flash
|
||||
+*/
|
||||
+
|
||||
+$settings['graph_type'] = 0;
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Will the quota information be shown above or below the folders list?
|
||||
+ *
|
||||
+ * Default: Above
|
||||
+ * 0: Below / 1: Above
|
||||
+*/
|
||||
+
|
||||
+$settings['info_above_folders_list'] = 1;
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Font size for quota information displayed on the folder pane.
|
||||
+ * Must be a positive or negative integer value.
|
||||
+ *
|
||||
+ * Default: -2
|
||||
+*/
|
||||
+
|
||||
+$settings['font_size'] = -2;
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Alignment for the graph and text information on the folder pane.
|
||||
+ * This can be "left", "center" or "right".
|
||||
+ *
|
||||
+ * Default: "left"
|
||||
+*/
|
||||
+
|
||||
+$settings['graph_alignment'] = 'left';
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Whether or not to use horizontal rules to seperate quota information
|
||||
+ * from other information on the folder pane.
|
||||
+ *
|
||||
+ * Default: No
|
||||
+ * 0: No / 1: Yes
|
||||
+*/
|
||||
+
|
||||
+$settings['use_hr'] = 0;
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Whether or not to show the introductory "Quota Usage" text for
|
||||
+ * size-based quotas and the "File Usage" text for count-based quotas
|
||||
+ * displayed on the folder pane.
|
||||
+ *
|
||||
+ * Default: On
|
||||
+ * 0: Off / 1: On
|
||||
+*/
|
||||
+
|
||||
+$settings['show_intro_texts'] = 1;
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Show the quota details above or below the quota graph?
|
||||
+ *
|
||||
+ * Default: Below
|
||||
+ * 0: Below / 1: Above
|
||||
+*/
|
||||
+
|
||||
+$settings['details_above_graph'] = 0;
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Whether to show used space (in KB, MB or GB depending on usage) for
|
||||
+ * size-based quotas and file count for count-based quotas instead of
|
||||
+ * percent usage in the information displayed on the folder pane.
|
||||
+ *
|
||||
+ * Default: Show percent
|
||||
+ * 0: Show percent / 1: Show size/count
|
||||
+*/
|
||||
+
|
||||
+$settings['show_quantity_instead_of_percent'] = 0;
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Quota percent thresholds. If the user's usage is more than one
|
||||
+ * of these, the graph will use a different color and you also have
|
||||
+ * the option to show a warning in the SquirrelMail "MOTD" display
|
||||
+ * area when the user logs in.
|
||||
+ *
|
||||
+ * These must be positive integers.
|
||||
+ *
|
||||
+ * Defaults: Yellow: 70% / Red: 90%
|
||||
+*/
|
||||
+
|
||||
+$settings['yellow_alert_limit'] = 70;
|
||||
+$settings['red_alert_limit'] = 90;
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Yellow alert login warning option. When turned on and when the
|
||||
+ * user's usage exceeds the yellow alert threshold (see above), a
|
||||
+ * warning message will be displayed in the SquirrelMail "MOTD" area
|
||||
+ * when he/she logs on.
|
||||
+ *
|
||||
+ * Default: On
|
||||
+ * 0: Off / 1: On
|
||||
+*/
|
||||
+
|
||||
+$settings['show_yellow_alert_motd'] = 1;
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Red alert login warning option. When turned on and when the
|
||||
+ * user's usage exceeds the red alert threshold (see above), a
|
||||
+ * warning message will be displayed in the SquirrelMail "MOTD" area
|
||||
+ * when he/she logs on.
|
||||
+ *
|
||||
+ * Default: On
|
||||
+ * 0: Off / 1: On
|
||||
+*/
|
||||
+
|
||||
+$settings['show_red_alert_motd'] = 1;
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * If your quotas are set based on 1 MB = 1000 KB, you may want to
|
||||
+ * turn this option on. Otherwise, 1 MB = 1024 KB will be used for
|
||||
+ * all quota calculations, which is the generally accepted convention.
|
||||
+ *
|
||||
+ * Default: Off
|
||||
+ * 0: Off (1MB = 1024KB) / 1: On (1MB = 1000KB)
|
||||
+*/
|
||||
+
|
||||
+$settings['use_1000KB_per_MB'] = 0;
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Whether or not to show filesystem names. This setting
|
||||
+ * is only used for UNIX (filesystem) quotas.
|
||||
+ *
|
||||
+ * This is useful when you have more than one filesystem
|
||||
+ * which have quotas for your users.
|
||||
+ *
|
||||
+ * When set to "1" filesystem aliases override filesystem names.
|
||||
+ *
|
||||
+ * Default: Off
|
||||
+ * 0: Off
|
||||
+ * 1: Show filesystem name or alias if an alias is set for that filesystem
|
||||
+*/
|
||||
+
|
||||
+$settings['show_filesystems'] = 0;
|
||||
+
|
||||
+
|
||||
+/********************
|
||||
+ * Override Options *
|
||||
+ ********************/
|
||||
+
|
||||
+/*
|
||||
+ * You can use this list to map different names to your filesystems. For
|
||||
+ * example, you can display "Mail Folder" instead of the filesystem name
|
||||
+ * "/dev/hda4". Leave this empty if you don't want to set up any such
|
||||
+ * aliases. If "show_filesystems" is set to "0" this list will have no
|
||||
+ * meaning.
|
||||
+ *
|
||||
+ * This setting is only used for UNIX quotas.
|
||||
+ *
|
||||
+ * If you use this setting, make sure to replace "/dev/hda8" and "/dev/sda1"
|
||||
+ * below with the filesystems that are appropriate on your system.
|
||||
+*/
|
||||
+
|
||||
+$settings['fs_alias'] = array (
|
||||
+ '/dev/hda8' => 'Mail',
|
||||
+ '/dev/sda6' => 'Data',
|
||||
+ );
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * You can use this list to exclude some filesystems in your quota output.
|
||||
+ * This allows you to only show quota information for the filesystem that
|
||||
+ * your mail accounts reside on, to avoid confusion.
|
||||
+ *
|
||||
+ * You don't need to add filesystems which do not have any
|
||||
+ * quota support here.
|
||||
+ *
|
||||
+ * You will need to write the exact filesystem name and, if you want to
|
||||
+ * hide that filesystem, you will need to set its value to 1. If you want
|
||||
+ * to show that filesystem, you can remove its entry from this list, or
|
||||
+ * you can set its value to 0.
|
||||
+ *
|
||||
+ * This setting is only used for UNIX quotas.
|
||||
+ *
|
||||
+ * If you use this setting, make sure to replace "/dev/hda8" and "/dev/sda1"
|
||||
+ * below with the filesystems that are appropriate on your system.
|
||||
+*/
|
||||
+
|
||||
+$settings['exclude_fs'] = array (
|
||||
+ '/dev/hda8' => 1,
|
||||
+ '/dev/sda6' => 0,
|
||||
+ );
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Some IMAP servers use dynamic quotas, so the users may not be able to
|
||||
+ * see their true quotas. In this situation you can override the max quota
|
||||
+ * information returned by the plugin with these variables. For size-based
|
||||
+ * quotas, change "imap_size_quota", for count-based quotas, change
|
||||
+ * "imap_count_quota".
|
||||
+ *
|
||||
+ * Leave blank for server returned quota information to be displayed.
|
||||
+ *
|
||||
+ * This setting is only used for IMAP quotas.
|
||||
+ *
|
||||
+ * NOTE: Values must be entered in Kilobytes.
|
||||
+*/
|
||||
+
|
||||
+$settings['imap_size_quota'] = '';
|
||||
+$settings['imap_count_quota'] = '';
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * As cPanel quotas work differently from UNIX or IMAP quotas, we have to
|
||||
+ * use "du" to calculate these type of quotas. Using "du" can be very
|
||||
+ * exhaustive for a slow or loaded server. So as a default, we calculate
|
||||
+ * cPanel quotas only once for a logged in user. To refresh the quota
|
||||
+ * information the user has to log out and log in again. This option
|
||||
+ * overrides this behavior and refreshes cPanel quota information on every
|
||||
+ * refresh of the folders list.
|
||||
+ *
|
||||
+ * CAUTION: enabling this may place unnecessarily high load on your server.
|
||||
+ *
|
||||
+ * cPanel quota information is always refreshed on the troubleshooting page,
|
||||
+ * regardless of this option.
|
||||
+ *
|
||||
+ * This setting is only used for cPanel quotas.
|
||||
+ *
|
||||
+ * Default: Off
|
||||
+ * 0: Off; calculate quota once at time of login
|
||||
+ * 1: Always refresh cPanel information
|
||||
+*/
|
||||
+
|
||||
+$settings['always_refresh_cpanel'] = 0;
|
||||
+
|
||||
+
|
||||
+/********************
|
||||
+ * Troubleshooting *
|
||||
+ ********************/
|
||||
+
|
||||
+/*
|
||||
+ * Turn this on to see troubleshooting output from server for help
|
||||
+ * debugging your Check Quota settings. This will add a link to
|
||||
+ * the "Options" page with the name "Check Quota Troubleshooting".
|
||||
+ * You should always turn this off when Check Quota is working as
|
||||
+ * intended.
|
||||
+ *
|
||||
+ * Default: Off
|
||||
+ * 0: Off / 1: On
|
||||
+*/
|
||||
+
|
||||
+$settings['troubleshoot'] = 1;
|
||||
+
|
||||
diff -ruN check_quota_old/functions.php check_quota/functions.php
|
||||
--- check_quota_old/functions.php 2007-08-04 16:58:53.000000000 +0200
|
||||
+++ check_quota/functions.php 2023-05-22 08:14:04.000000000 +0200
|
||||
@@ -143,10 +143,11 @@
|
||||
*/
|
||||
function check_quota_motd($args)
|
||||
{
|
||||
+ global $currentHookName;
|
||||
if ( !sqgetGlobalVar('just_logged_in', $just_logged_in, SQ_SESSION) || empty($just_logged_in) )
|
||||
return FALSE;
|
||||
|
||||
- if ( get_current_hook_name($args) != 'right_main_after_header' || !sqGetGlobalVar('check_quota_motd_displayed', $check_quota_motd_displayed, SQ_SESSION) || empty($check_quota_motd_displayed) )
|
||||
+ if ( $currentHookName !== 'right_main_after_header' || !sqGetGlobalVar('check_quota_motd_displayed', $check_quota_motd_displayed, SQ_SESSION) || empty($check_quota_motd_displayed) )
|
||||
{
|
||||
global $check_quota;
|
||||
|
||||
@@ -214,7 +215,7 @@
|
||||
* settings and checks the user's quota.
|
||||
*
|
||||
*/
|
||||
- function CheckQuota()
|
||||
+ function __construct()
|
||||
{
|
||||
$this->reset_debug();
|
||||
$this->load_settings();
|
||||
@@ -230,7 +231,6 @@
|
||||
global $settings;
|
||||
|
||||
include_once(SM_PATH . 'plugins/check_quota/config.php');
|
||||
-
|
||||
$this->settings = $settings;
|
||||
unset ($settings);
|
||||
}
|
||||
diff -ruN check_quota_old/troubleshoot.php check_quota/troubleshoot.php
|
||||
--- check_quota_old/troubleshoot.php 2007-08-06 11:16:29.000000000 +0200
|
||||
+++ check_quota/troubleshoot.php 2023-05-22 07:55:31.000000000 +0200
|
||||
@@ -42,7 +42,7 @@
|
||||
if ( empty($check_quota->settings['troubleshoot']) )
|
||||
{
|
||||
unset($check_quota);
|
||||
- exit();
|
||||
+// exit();
|
||||
}
|
||||
|
||||
$cq_to = '<tr><td colspan="2" bgcolor="' . $color[4] . '" align="center"><font color="' . $color[8] . '"><b>';
|
200
squirrelmail_config.php
Executable file
200
squirrelmail_config.php
Executable file
@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* SquirrelMail Configuration File
|
||||
* Created using the configure script, conf.pl
|
||||
*/
|
||||
|
||||
$config_version = '1.5.0';
|
||||
$config_use_color = 1;
|
||||
|
||||
$org_name = "SquirrelMail";
|
||||
$org_logo = SM_PATH . 'images/sm_logo.png';
|
||||
$org_logo_width = '308';
|
||||
$org_logo_height = '111';
|
||||
$org_title = "SquirrelMail";
|
||||
$signout_page = '';
|
||||
$frame_top = '_top';
|
||||
|
||||
$provider_uri = '';
|
||||
|
||||
$provider_name = '';
|
||||
|
||||
$motd = "";
|
||||
|
||||
$squirrelmail_default_language = 'en_US';
|
||||
$default_charset = 'utf-8';
|
||||
$show_alternative_names = true;
|
||||
$aggressive_decoding = true;
|
||||
$lossy_encoding = false;
|
||||
|
||||
$domain = 'danwin1210.de';
|
||||
$imapServerAddress = 'danwin1210.de';
|
||||
$imapPort = 993;
|
||||
$useSendmail = false;
|
||||
$smtpServerAddress = 'danwin1210.de';
|
||||
$smtpPort = 465;
|
||||
$sendmail_path = '/usr/sbin/sendmail';
|
||||
$sendmail_args = '-i -t';
|
||||
$pop_before_smtp = false;
|
||||
$pop_before_smtp_host = '';
|
||||
$imap_server_type = 'dovecot';
|
||||
$invert_time = false;
|
||||
$optional_delimiter = 'detect';
|
||||
$encode_header_key = '';
|
||||
|
||||
$default_folder_prefix = '';
|
||||
$trash_folder = 'Trash';
|
||||
$sent_folder = 'Sent';
|
||||
$draft_folder = 'Drafts';
|
||||
$default_move_to_trash = true;
|
||||
$default_move_to_sent = true;
|
||||
$default_save_as_draft = true;
|
||||
$show_prefix_option = false;
|
||||
$list_special_folders_first = true;
|
||||
$use_special_folder_color = true;
|
||||
$auto_expunge = true;
|
||||
$default_sub_of_inbox = false;
|
||||
$show_contain_subfolders_option = false;
|
||||
$default_unseen_notify = 2;
|
||||
$default_unseen_type = 1;
|
||||
$auto_create_special = true;
|
||||
$delete_folder = false;
|
||||
$noselect_fix_enable = false;
|
||||
|
||||
$data_dir = '/var/local/squirrelmail/data/';
|
||||
$attachment_dir = '/var/local/squirrelmail/attach/';
|
||||
$dir_hash_level = 0;
|
||||
$default_left_size = '150';
|
||||
$force_username_lowercase = true;
|
||||
$default_use_priority = false;
|
||||
$hide_sm_attributions = false;
|
||||
$default_use_mdn = false;
|
||||
$edit_identity = false;
|
||||
$edit_name = true;
|
||||
$edit_reply_to = true;
|
||||
$hide_auth_header = true;
|
||||
$disable_thread_sort = false;
|
||||
$disable_server_sort = false;
|
||||
$allow_charset_search = true;
|
||||
$allow_advanced_search = 0;
|
||||
|
||||
$time_zone_type = 0;
|
||||
|
||||
$config_location_base = '';
|
||||
|
||||
$disable_plugins = false;
|
||||
$disable_plugins_user = '';
|
||||
|
||||
$plugins[] = 'check_quota';
|
||||
|
||||
$user_theme_default = 0;
|
||||
$user_themes[0]['PATH'] = 'none';
|
||||
$user_themes[0]['NAME'] = 'Default';
|
||||
$user_themes[1]['PATH'] = SM_PATH . 'css/blue_gradient/';
|
||||
$user_themes[1]['NAME'] = 'Blue Options';
|
||||
$user_themes[2]['PATH'] = SM_PATH . 'css/alien_glow/';
|
||||
$user_themes[2]['NAME'] = 'Alien Glow';
|
||||
$user_themes[3]['PATH'] = SM_PATH . 'css/autumn/';
|
||||
$user_themes[3]['NAME'] = 'Autumn';
|
||||
$user_themes[4]['PATH'] = SM_PATH . 'css/autumn2/';
|
||||
$user_themes[4]['NAME'] = 'Autumn2';
|
||||
$user_themes[5]['PATH'] = SM_PATH . 'css/black_bean_burrito/';
|
||||
$user_themes[5]['NAME'] = 'Black Bean Burrito';
|
||||
$user_themes[6]['PATH'] = SM_PATH . 'css/blue_grey/';
|
||||
$user_themes[6]['NAME'] = 'Blue Grey';
|
||||
$user_themes[7]['PATH'] = SM_PATH . 'css/blue_on_blue/';
|
||||
$user_themes[7]['NAME'] = 'Blue On Blue';
|
||||
$user_themes[8]['PATH'] = SM_PATH . 'css/bluesnews/';
|
||||
$user_themes[8]['NAME'] = 'Bluesnews';
|
||||
$user_themes[9]['PATH'] = SM_PATH . 'css/bluesome/';
|
||||
$user_themes[9]['NAME'] = 'Bluesome';
|
||||
$user_themes[10]['PATH'] = SM_PATH . 'css/bluesteel/';
|
||||
$user_themes[10]['NAME'] = 'Bluesteel';
|
||||
|
||||
$icon_theme_def = 1;
|
||||
$icon_theme_fallback = 3;
|
||||
$icon_themes[0]['PATH'] = 'none';
|
||||
$icon_themes[0]['NAME'] = 'No Icons';
|
||||
$icon_themes[1]['PATH'] = 'template';
|
||||
$icon_themes[1]['NAME'] = 'Template Default Icons';
|
||||
$icon_themes[2]['PATH'] = SM_PATH . 'images/themes/default/';
|
||||
$icon_themes[2]['NAME'] = 'Default Icon Set';
|
||||
$icon_themes[3]['PATH'] = SM_PATH . 'images/themes/xp/';
|
||||
$icon_themes[3]['NAME'] = 'XP Style Icons';
|
||||
|
||||
$templateset_default = 'default';
|
||||
$templateset_fallback = 'default';
|
||||
$rpc_templateset = 'default_rpc';
|
||||
$aTemplateSet[0]['ID'] = 'default';
|
||||
$aTemplateSet[0]['NAME'] = 'Default';
|
||||
$aTemplateSet[1]['ID'] = 'default_advanced';
|
||||
$aTemplateSet[1]['NAME'] = 'Advanced';
|
||||
|
||||
$default_fontsize = '';
|
||||
$default_fontset = '';
|
||||
|
||||
$fontsets = array();
|
||||
$fontsets['verasans'] = 'bitstream vera sans,verdana,sans-serif';
|
||||
$fontsets['sans'] = 'helvetica,arial,sans-serif';
|
||||
$fontsets['comicsans'] = 'comic sans ms,sans-serif';
|
||||
$fontsets['tahoma'] = 'tahoma,sans-serif';
|
||||
$fontsets['serif'] = 'serif';
|
||||
|
||||
$default_use_javascript_addr_book = false;
|
||||
$addrbook_dsn = '';
|
||||
$addrbook_table = 'address';
|
||||
|
||||
$prefs_dsn = '';
|
||||
$prefs_table = 'userprefs';
|
||||
$prefs_user_field = 'user';
|
||||
$prefs_user_size = 128;
|
||||
$prefs_key_field = 'prefkey';
|
||||
$prefs_key_size = 64;
|
||||
$prefs_val_field = 'prefval';
|
||||
$prefs_val_size = 65536;
|
||||
|
||||
$addrbook_global_dsn = '';
|
||||
$addrbook_global_table = 'global_abook';
|
||||
$addrbook_global_writeable = false;
|
||||
$addrbook_global_listing = false;
|
||||
|
||||
$abook_global_file = '';
|
||||
$abook_global_file_writeable = false;
|
||||
|
||||
$abook_global_file_listing = true;
|
||||
|
||||
$abook_file_line_length = 2048;
|
||||
|
||||
$no_list_for_subscribe = false;
|
||||
$smtp_auth_mech = 'plain';
|
||||
$smtp_sitewide_user = '';
|
||||
$smtp_sitewide_pass = '';
|
||||
$imap_auth_mech = 'plain';
|
||||
$use_imap_tls = 1;
|
||||
$use_smtp_tls = 1;
|
||||
$display_imap_login_error = false;
|
||||
$session_name = 'SQMSESSID';
|
||||
$only_secure_cookies = true;
|
||||
$disable_security_tokens = false;
|
||||
$check_referrer = '';
|
||||
$use_transparent_security_image = true;
|
||||
$allow_svg_display = false;
|
||||
$block_svg_download = false;
|
||||
$fix_broken_base64_encoded_messages = false;
|
||||
|
||||
$use_iframe = false;
|
||||
$ask_user_info = false;
|
||||
$use_icons = false;
|
||||
|
||||
$use_php_recode = false;
|
||||
$use_php_iconv = true;
|
||||
|
||||
$buffer_output = false;
|
||||
|
||||
$allow_remote_configtest = false;
|
||||
$secured_config = true;
|
||||
$sq_https_port = 443;
|
||||
$sq_ignore_http_x_forwarded_headers = true;
|
||||
$sm_debug_mode = SM_DEBUG_MODE_OFF;
|
||||
|
25
squirrelmail_plugin_hooks.php
Normal file
25
squirrelmail_plugin_hooks.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* SquirrelMail Plugin Hook Registration File
|
||||
* Auto-generated using the configure script, conf.pl
|
||||
*/
|
||||
|
||||
global $squirrelmail_plugin_hooks;
|
||||
|
||||
$squirrelmail_plugin_hooks['left_main_before']['check_quota']
|
||||
= 'check_quota_graph_before_do';
|
||||
$squirrelmail_plugin_hooks['left_main_after']['check_quota']
|
||||
= 'check_quota_graph_after_do';
|
||||
$squirrelmail_plugin_hooks['right_main_after_header']['check_quota']
|
||||
= 'check_quota_motd_do';
|
||||
$squirrelmail_plugin_hooks['template_construct_left_main.tpl']['check_quota']
|
||||
= 'check_quota_graph_do';
|
||||
$squirrelmail_plugin_hooks['template_construct_motd.tpl']['check_quota']
|
||||
= 'check_quota_motd_do';
|
||||
$squirrelmail_plugin_hooks['optpage_register_block']['check_quota']
|
||||
= 'check_quota_optpage_register_block_do';
|
||||
$squirrelmail_plugin_hooks['configtest']['check_quota']
|
||||
= 'check_quota_check_configuration_do';
|
||||
|
||||
|
9
tools/create_admin.php
Normal file
9
tools/create_admin.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
const ADMIN_USER='admin';
|
||||
const ADMIN_PASS='YOUR_PASSWORD';
|
||||
|
||||
require_once __DIR__ . '/../common_config.php';
|
||||
$db = get_db_instance();
|
||||
$hash = password_hash( ADMIN_PASS, PASSWORD_ARGON2ID );
|
||||
$stmt = $db->prepare( 'INSERT INTO admin (password_hash_type, password, superadmin, username, created, modified) VALUES ("{ARGON2ID}", ?, 1, ?, NOW(), NOW());' );
|
||||
$stmt->execute( [ $hash, ADMIN_USER ] );
|
@ -25,3 +25,36 @@ foreach ( $domains as $domain ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
$domains = array_diff( scandir( '/var/local/snappymail/_data_/_default_/storage/' ), array( '..', '.', '__nobody__' ) );
|
||||
$dirs = [];
|
||||
foreach ( $domains as $domain ) {
|
||||
if ( is_dir( '/var/local/snappymail/_data_/_default_/storage/' . basename( $domain ) ) ) {
|
||||
if ( ! isset( $mailboxes[ $domain ] ) ) {
|
||||
echo sprintf(_('%s does not seem to have any accounts, but has a snappymail directory. Consider deleting it.'), $domain).PHP_EOL;
|
||||
} else {
|
||||
$accounts = array_diff( scandir( '/var/local/snappymail/_data_/_default_/storage/' . basename( $domain ) ), array( '..', '.' ) );
|
||||
foreach ( $accounts as $account ) {
|
||||
if ( ! isset( $mailboxes[ $domain ][ $account ] ) && is_dir( '/var/local/snappymail/_data_/_default_/storage/' . basename( $domain ) . '/' . basename( $account ) ) ) {
|
||||
exec( 'rm -r ' . escapeshellarg('/var/local/snappymail/_data_/_default_/storage/' . basename( $domain ) . '/' . basename( $account )));
|
||||
echo sprintf(_('Deleted: %s'), '/var/local/snappymail/_data_/_default_/storage/' . basename( $domain ) . '/' . basename( $account )) . PHP_EOL;
|
||||
} elseif( is_file('/var/local/snappymail/_data_/_default_/storage/' . basename( $domain ) . '/' . basename( $account ))){
|
||||
echo sprintf(_('File found in mail directory location: "%s". Consider deleting it.'), '/var/local/snappymail/_data_/_default_/storage/'. basename( $domain ) . '/' . basename( $account ) ) . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$accout_files = array_diff( scandir( '/var/local/squirrelmail/data/' ), array( '..', '.' ) );
|
||||
foreach( $accout_files as $file ){
|
||||
if(preg_match( '/^(.+?)(@(.+))?\.(pref|abook|sig)$/', $file, $matches )){
|
||||
$domain = $matches[ 3 ];
|
||||
if(in_array($domain, ['', 'danielas3rtn54uwmofdo3x2bsdifr47huasnmbgqzfrec5ubupvtpid.onion'], true)){
|
||||
$domain = 'danwin1210.de';
|
||||
}
|
||||
$account = $matches[ 1 ];
|
||||
if ( ! isset( $mailboxes[ $domain ][ $account ] )){
|
||||
unlink('/var/local/squirrelmail/data/' . $file);
|
||||
echo sprintf(_('Deleted: %s'), '/var/local/squirrelmail/data/' . $file) . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
394
www/admin.php
394
www/admin.php
File diff suppressed because it is too large
Load Diff
@ -3,41 +3,43 @@ include_once('../common_config.php');
|
||||
global $language, $dir, $locale;
|
||||
?>
|
||||
<!DOCTYPE html><html lang="<?php echo $language; ?>" dir="<?php echo $dir; ?>"><head>
|
||||
<title><?php echo _('E-Mail and XMPP'); ?></title>
|
||||
<title><?php echo htmlspecialchars(_('E-Mail and XMPP')); ?></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="<?php echo _('Get a free and anonymous E-Mail address and an XMPP/Jabber account'); ?>">
|
||||
<meta name="description" content="<?php echo htmlspecialchars(_('Get a free and anonymous E-Mail address and an XMPP/Jabber account')); ?>">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL; ?>">
|
||||
<link rel="alternate" href="<?php echo CANONICAL_URL; ?>" hreflang="x-default">
|
||||
<?php alt_links(); ?>
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="<?php echo _('E-Mail and XMPP'); ?>">
|
||||
<meta property="og:description" content="<?php echo _('Get a free and anonymous E-Mail address and an XMPP/Jabber account'); ?>">
|
||||
<meta property="og:title" content="<?php echo htmlspecialchars(_('E-Mail and XMPP')); ?>">
|
||||
<meta property="og:description" content="<?php echo htmlspecialchars(_('Get a free and anonymous E-Mail address and an XMPP/Jabber account')); ?>">
|
||||
<meta property="og:url" content="<?php echo CANONICAL_URL; ?>">
|
||||
<meta property="og:locale" content="<?php echo $locale; ?>">
|
||||
<script type="application/ld+json">{"@context":"https://schema.org","@type":"Service","name":"<?php echo _('E-Mail and XMPP'); ?>", "description": "<?php echo _('Get a free and anonymous E-Mail address and an XMPP/Jabber account'); ?>", "availableChannel": {"@type": "ServiceChannel", "serviceUrl": "<?php echo CANONICAL_URL; ?>"}}</script>
|
||||
<script type="application/ld+json">{"@context":"https://schema.org","@type":"Service","name":"<?php echo htmlspecialchars(_('E-Mail and XMPP')); ?>", "description": "<?php echo htmlspecialchars(_('Get a free and anonymous E-Mail address and an XMPP/Jabber account')); ?>", "availableChannel": {"@type": "ServiceChannel", "serviceUrl": "<?php echo CANONICAL_URL; ?>"}, "termsOfService": "<?php echo CANONICAL_URL; ?>terms.php"}</script>
|
||||
</head><body>
|
||||
<main>
|
||||
<p><?php echo _('Info'); ?> | <a href="<?php echo ROOT_URL; ?>register.php"><?php echo _('Register'); ?></a> | <a href="<?php echo ROOT_URL; ?>manage_account.php"><?php echo _('Manage account'); ?></a> | <a href="<?php echo ROOT_URL; ?>squirrelmail/src/login.php" target="_blank"><?php echo _('SquirrelMail'); ?></a> | <a href="<?php echo ROOT_URL; ?>snappymail/" target="_blank"><?php echo _('SnappyMail'); ?></a> | <a href="<?php echo WEB_XMPP_URL; ?>" target="_blank" rel="noopener"><?php echo _('Web-XMPP'); ?></a></p>
|
||||
<h2><?php echo _('What you will get'); ?></h2>
|
||||
<p><?php printf(_('You get a free anonymous E-Mail address and an XMPP/Jabber account using the same details. Your Jabber ID is user@%1$s and can be connected to directly from clearnet or via Tor hidden service (%2$s).'), CLEARNET_SERVER, ONION_SERVER); ?></p>
|
||||
<p><?php printf(_('You will have 50MB of disk space available for your mails. If you need more space, just <a href="%1$s">contact me</a>. Your E-Mail address will be %2$s'), CONTACT_URL, CLEARNET_SERVER); ?></p>
|
||||
<p><?php echo _('For privacy, please use PGP mail encryption, if you can. This prevents others from reading your mails to protect your privacy. You can <a href="https://gnupg.org/download/index.html" target="_blank" rel="noopener noreferrer">download GnuPG</a> or similar software for it. Once you have generated your PGP key, you can <a href="manage_account.php">add it to your account</a> to make use of WKD automatic discovery for mail clients.'); ?></p>
|
||||
<p><?php echo _('You can choose between two Web-Mail clients installed on the server. <a href="squirrelmail/src/login.php">SquirrelMail</a> is a very old mail client which works without any JavaScript and is thus the most popular mail client among darknet users. However, it hasn\'t been under development for many years and does not support all features that mail has to offer. You may see strange attachments that should have been inlined in your email, such as PGP/MIME encrypted email messages. A more modern client is <a href="snappymail/">SnappyMail</a>, which also supports PGP encryption within your browser and is more similar to what you may be used to from other mail services. SnappyMail requires JavaScript though, so SquirrelMail is for you if you do not trust executing JavaScript in your browser. Alternatively, you can simply use your favourite desktop mail client and configure it with the settings given below.'); ?></p>
|
||||
<p><?php echo _('The XMPP service provides message archiving and HTTP upload, which can keep your messages and files for up to 1 week. Up to 100MB of file storage is available per user.'); ?></p>
|
||||
<h2><?php echo _('E-Mail Setup'); ?></h2>
|
||||
<p><?php echo htmlspecialchars(_('Info')); ?> | <a href="<?php echo ROOT_URL; ?>register.php"><?php echo htmlspecialchars(_('Register')); ?></a> | <a href="<?php echo ROOT_URL; ?>manage_account.php"><?php echo htmlspecialchars(_('Manage account')); ?></a> | <a href="<?php echo ROOT_URL; ?>squirrelmail/src/login.php" target="_blank"><?php echo htmlspecialchars(_('SquirrelMail')); ?></a> | <a href="<?php echo ROOT_URL; ?>snappymail/" target="_blank"><?php echo htmlspecialchars(_('SnappyMail')); ?></a> | <a href="<?php echo WEB_XMPP_URL; ?>" target="_blank" rel="noopener"><?php echo htmlspecialchars(_('Web-XMPP')); ?></a></p>
|
||||
<h2><?php echo htmlspecialchars(_('What you will get')); ?></h2>
|
||||
<p><?php printf(htmlspecialchars(_('You get a free anonymous E-Mail address and an XMPP/Jabber account using the same details. Your Jabber ID is user@%1$s and can be connected to directly from clearnet or via Tor hidden service (%2$s).')), CLEARNET_SERVER, ONION_SERVER); ?></p>
|
||||
<?php if(DEFAULT_QUOTA > 0) { ?>
|
||||
<p><?php printf(htmlspecialchars(_('You will have %1$s disk space available for your mails. If you need more space, %2$s.')), bytes_to_human_readable(DEFAULT_QUOTA), '<a href="'.CONTACT_URL.'">'.htmlspecialchars(_('contact me')).'</a>'); ?></p>
|
||||
<?php } ?>
|
||||
<p><?php printf(htmlspecialchars(_('Your E-Mail address will be user@%s')), CLEARNET_SERVER); ?></p>
|
||||
<p><?php printf(htmlspecialchars(_('For privacy, please use PGP mail encryption, if you can. This prevents others from reading your mails to protect your privacy. You can %1$s or similar software for it. Once you have generated your PGP key, you can %2$s to make use of WKD automatic discovery for mail clients.')), '<a href="https://gnupg.org/download/index.html" target="_blank" rel="noopener noreferrer">'.htmlspecialchars(_('download GnuPG')).'</a>', '<a href="manage_account.php">'.htmlspecialchars(_('add it to your account')).'</a>'); ?></p>
|
||||
<p><?php printf(htmlspecialchars(_('You can choose between two Web-Mail clients installed on the server. %1$s is a very old mail client which works without any JavaScript and is thus the most popular mail client among darknet users. However, it hasn\'t been under development for many years and does not support all features that mail has to offer. You may see strange attachments that should have been inlined in your email, such as PGP/MIME encrypted email messages. A more modern client is %2$s, which also supports PGP encryption within your browser and is more similar to what you may be used to from other mail services. SnappyMail requires JavaScript though, so SquirrelMail is for you if you do not trust executing JavaScript in your browser. Alternatively, you can simply use your favourite desktop mail client and configure it with the settings given below.')), '<a href="squirrelmail/src/login.php">'.htmlspecialchars(_('SquirrelMail')).'</a>', '<a href="snappymail/">'.htmlspecialchars(_('SnappyMail')).'</a>'); ?></p>
|
||||
<h2><?php echo htmlspecialchars(_('E-Mail Setup')); ?></h2>
|
||||
<p>
|
||||
<?php printf(_('SMTP: %s Port 465 (SSL/TLS) or 587 (StartTLS)'), CLEARNET_SERVER); ?><br>
|
||||
<?php printf(_('IMAP: %s Port 993 (SSL/TLS) or 143 (StartTLS)'), CLEARNET_SERVER); ?><br>
|
||||
<?php printf(_('POP3: %s Port 995 (SSL/TLS) or 110 (StartTLS)'), CLEARNET_SERVER); ?><br>
|
||||
<?php echo _('Authentication: PLAIN, LOGIN'); ?>
|
||||
<?php printf(htmlspecialchars(_('SMTP: %s Port 465 (SSL/TLS) or 587 (StartTLS)')), CLEARNET_SERVER); ?><br>
|
||||
<?php printf(htmlspecialchars(_('IMAP: %s Port 993 (SSL/TLS) or 143 (StartTLS)')), CLEARNET_SERVER); ?><br>
|
||||
<?php printf(htmlspecialchars(_('POP3: %s Port 995 (SSL/TLS) or 110 (StartTLS)')), CLEARNET_SERVER); ?><br>
|
||||
<?php echo htmlspecialchars(_('Authentication: PLAIN, LOGIN')); ?>
|
||||
</p>
|
||||
<p><?php printf(_('You can also connect on the same ports via the Tor onion address %s, but you will have to accept an SSL certificate only valid for the clearnet domain.'), ONION_SERVER); ?></p>
|
||||
<h2><?php echo _('XMPP setup'); ?></h2>
|
||||
<p><?php printf(_('Domain: %s'), CLEARNET_SERVER); ?><br>
|
||||
<?php printf(_('Connect server: %s (optional for torification)'), ONION_SERVER); ?><br>
|
||||
<?php printf(_('File transfer proxy: %s'), XMPP_FILE_PROXY); ?><br>
|
||||
<?php printf(_('BOSH URL: %s (only enable if you have to, as it is slower than directly using xmpp)'), XMPP_BOSH_URL); ?></p>
|
||||
<p><?php printf(htmlspecialchars(_('You can also connect on the same ports via the Tor onion address %s, but you will have to accept an SSL certificate only valid for the clearnet domain.')), ONION_SERVER); ?></p>
|
||||
<h2><?php echo htmlspecialchars(_('XMPP setup')); ?></h2>
|
||||
<p><?php printf(htmlspecialchars(_('Domain: %s')), CLEARNET_SERVER); ?><br>
|
||||
<?php printf(htmlspecialchars(_('Connect server: %s (optional for torification)')), ONION_SERVER); ?><br>
|
||||
<?php printf(htmlspecialchars(_('File transfer proxy: %s')), XMPP_FILE_PROXY); ?><br>
|
||||
<?php printf(htmlspecialchars(_('BOSH URL: %s (only enable if you have to, as it is slower than directly using xmpp)')), XMPP_BOSH_URL); ?></p>
|
||||
</main>
|
||||
</body></html>
|
||||
|
@ -14,7 +14,7 @@ if ( ! empty( $_SESSION[ 'email_user' ] ) ) {
|
||||
$_SESSION = [];
|
||||
session_regenerate_id( true );
|
||||
$_SESSION[ 'csrf_token' ] = sha1( uniqid() );
|
||||
$msg .= '<div class="red" role="alert">'._('It looks like your user no longer exists!').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('It looks like your user no longer exists!')).'</div>';
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ if ( $_SERVER[ 'REQUEST_METHOD' ] === 'POST' ) {
|
||||
unset( $_SESSION[ '2fa_code' ] );
|
||||
unset( $_SESSION[ 'pgp_key' ] );
|
||||
} else {
|
||||
$msg .= '<p style="color:red">'._('Wrong 2FA code').'</p>';
|
||||
$msg .= '<p style="color:red">'.htmlspecialchars(_('Wrong 2FA code')).'</p>';
|
||||
}
|
||||
}
|
||||
if ( ! isset( $_SESSION[ '2fa_code' ] ) && isset( $_POST[ 'action' ] ) ) {
|
||||
@ -35,21 +35,21 @@ if ( $_SERVER[ 'REQUEST_METHOD' ] === 'POST' ) {
|
||||
$_SESSION = [];
|
||||
session_regenerate_id( true );
|
||||
$_SESSION[ 'csrf_token' ] = sha1( uniqid() );
|
||||
$msg .= '<div class="green" role="alert">'._('Successfully logged out').'</div>';
|
||||
$msg .= '<div class="green" role="alert">'.htmlspecialchars(_('Successfully logged out')).'</div>';
|
||||
} elseif ( $_POST[ 'action' ] === 'login' ) {
|
||||
$ok = true;
|
||||
if ( ! check_captcha( $_POST[ 'challenge' ] ?? '', $_POST[ 'captcha' ] ?? '' ) ) {
|
||||
$ok = false;
|
||||
$msg .= '<div class="red" role="alert">'._('Invalid captcha').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('Invalid captcha')).'</div>';
|
||||
}
|
||||
if ( empty( $_POST[ 'user' ] ) || ! preg_match( '/^([^+]+?)(@([^@]+))?$/i', $_POST[ 'user' ], $match ) ) {
|
||||
$ok = false;
|
||||
$msg .= '<div class="red" role="alert">'._('Invalid username').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('Invalid username')).'</div>';
|
||||
}
|
||||
if ( $ok ) {
|
||||
$db = get_db_instance();
|
||||
$user = $match[ 1 ];
|
||||
$domain = $match[ 3 ] ?? 'danwin1210.de';
|
||||
$domain = $match[ 3 ] ?? CLEARNET_SERVER;
|
||||
$stmt = $db->prepare( 'SELECT target_domain FROM alias_domain WHERE alias_domain = ? AND active=1;' );
|
||||
$stmt->execute( [ $domain ] );
|
||||
if ( $tmp = $stmt->fetch( PDO::FETCH_ASSOC ) ) {
|
||||
@ -60,7 +60,7 @@ if ( $_SERVER[ 'REQUEST_METHOD' ] === 'POST' ) {
|
||||
if ( $tmp = $stmt->fetch( PDO::FETCH_ASSOC ) ) {
|
||||
if ( empty( $_POST[ 'pwd' ] ) || ! password_verify( $_POST[ 'pwd' ], $tmp[ 'password' ] ) ) {
|
||||
$ok = false;
|
||||
$msg .= '<div class="red" role="alert">'._('Incorrect username or password').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('Incorrect username or password')).'</div>';
|
||||
} else {
|
||||
$_SESSION[ 'email_user' ] = $tmp[ 'username' ];
|
||||
$stmt = $db->prepare( 'UPDATE mailbox SET last_login = ? WHERE username = ? AND active = 1;' );
|
||||
@ -78,7 +78,7 @@ if ( $_SERVER[ 'REQUEST_METHOD' ] === 'POST' ) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$msg .= '<div class="red" role="alert">'._('Incorrect username or password').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('Incorrect username or password')).'</div>';
|
||||
}
|
||||
}
|
||||
} elseif ( ! empty( $_SESSION[ 'email_user' ] ) && $_POST[ 'action' ] === 'update_settings' ) {
|
||||
@ -97,21 +97,21 @@ if ( $_SERVER[ 'REQUEST_METHOD' ] === 'POST' ) {
|
||||
$stmt->execute( [ ( isset( $_POST[ 'enforce_tls_in' ] ) ? 1 : 0 ), ( isset( $_POST[ 'enforce_tls_out' ] ) ? 1 : 0 ), $_SESSION[ 'email_user' ] ] );
|
||||
} elseif ( ! empty( $_SESSION[ 'email_user' ] ) && $_POST[ 'action' ] === 'update_password' ) {
|
||||
if ( empty( $_POST[ 'pass_update' ] ) || empty( $_POST[ 'pass_update2' ] ) || $_POST[ 'pass_update' ] !== $_POST[ 'pass_update2' ] ) {
|
||||
$msg .= '<div class="red" role="alert">'._('Passwords empty or don\'t match').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('Passwords empty or don\'t match')).'</div>';
|
||||
} else {
|
||||
$hash = password_hash( $_POST[ 'pass_update' ], PASSWORD_ARGON2ID );
|
||||
$stmt = $db->prepare( 'UPDATE mailbox SET password_hash_type = "{ARGON2ID}", password = ? WHERE username = ? AND active = 1;' );
|
||||
$stmt->execute( [ $hash, $_SESSION[ 'email_user' ] ] );
|
||||
$msg .= '<div class="green" role="alert">'._('Successfully updated password').'</div>';
|
||||
$msg .= '<div class="green" role="alert">'.htmlspecialchars(_('Successfully updated password')).'</div>';
|
||||
}
|
||||
} elseif ( ! empty( $_SESSION[ 'email_user' ] ) && $_POST[ 'action' ] === 'delete_account' ) {
|
||||
$msg .= '<div class="red" role="alert">'._('Warning: This will permenently delete your account and all your data. Anyone can immediately register with this user again. It cannot be reversed. Are you absolutely sure?').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('Warning: This will permenently delete your account and all your data. Anyone can immediately register with this user again. It cannot be reversed. Are you absolutely sure?')).'</div>';
|
||||
$msg .= '<form method="post"><input type="hidden" name="csrf_token" value="' . $_SESSION[ 'csrf_token' ] . '">';
|
||||
$msg .= '<button type="submit" name="action" value="delete_account2">'._('Yes, I want to permanently delete my account').'</button></form>';
|
||||
$msg .= '<button type="submit" name="action" value="delete_account2">'.htmlspecialchars(_('Yes, I want to permanently delete my account')).'</button></form>';
|
||||
} elseif ( ! empty( $_SESSION[ 'email_user' ] ) && $_POST[ 'action' ] === 'disable_account' ) {
|
||||
$msg .= '<div class="red" role="alert">'._('Warning: This will disable your account for a year and delete all your data. After a year it is available for registrations again. It cannot be reversed. Are you absolutely sure?').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('Warning: This will disable your account for a year and delete all your data. After a year it is available for registrations again. It cannot be reversed. Are you absolutely sure?')).'</div>';
|
||||
$msg .= '<form method="post"><input type="hidden" name="csrf_token" value="' . $_SESSION[ 'csrf_token' ] . '">';
|
||||
$msg .= '<button type="submit" name="action" value="disable_account2">'._('Yes, I want to disable my account').'</button></form>';
|
||||
$msg .= '<button type="submit" name="action" value="disable_account2">'.htmlspecialchars(_('Yes, I want to disable my account')).'</button></form>';
|
||||
} elseif ( ! empty( $_SESSION[ 'email_user' ] ) && $_POST[ 'action' ] === 'delete_account2' ) {
|
||||
$stmt = $db->prepare( 'DELETE FROM alias WHERE address = ?;' );
|
||||
$stmt->execute( [ $_SESSION[ 'email_user' ] ] );
|
||||
@ -120,7 +120,7 @@ if ( $_SERVER[ 'REQUEST_METHOD' ] === 'POST' ) {
|
||||
$_SESSION = [];
|
||||
session_regenerate_id( true );
|
||||
$_SESSION[ 'csrf_token' ] = sha1( uniqid() );
|
||||
$msg .= '<div class="green" role="alert">'._('Successfully deleted account').'</div>';
|
||||
$msg .= '<div class="green" role="alert">'.htmlspecialchars(_('Successfully deleted account')).'</div>';
|
||||
} elseif ( ! empty( $_SESSION[ 'email_user' ] ) && $_POST[ 'action' ] === 'disable_account2' ) {
|
||||
$stmt = $db->prepare( 'UPDATE alias SET active = 0 WHERE address = ?;' );
|
||||
$stmt->execute( [ $_SESSION[ 'email_user' ] ] );
|
||||
@ -129,11 +129,11 @@ if ( $_SERVER[ 'REQUEST_METHOD' ] === 'POST' ) {
|
||||
$_SESSION = [];
|
||||
session_regenerate_id( true );
|
||||
$_SESSION[ 'csrf_token' ] = sha1( uniqid() );
|
||||
$msg .= '<div class="green" role="alert">'._('Successfully disabled account').'</div>';
|
||||
$msg .= '<div class="green" role="alert">'.htmlspecialchars(_('Successfully disabled account')).'</div>';
|
||||
} elseif ( isset( $_POST[ 'pgp_key' ] ) && ! empty( $_SESSION[ 'email_user' ] ) && $_POST[ 'action' ] === 'update_pgp_key' ) {
|
||||
$pgp_key = trim( $_POST[ 'pgp_key' ] );
|
||||
if ( empty( $pgp_key ) ) {
|
||||
$msg .= '<p class="green">'._('Successfully removed the key').'</p>';
|
||||
$msg .= '<p class="green">'.htmlspecialchars(_('Successfully removed the key')).'</p>';
|
||||
$stmt = $db->prepare( 'UPDATE mailbox SET pgp_key = "", tfa = 0, pgp_verified = 0 WHERE username = ?;' );
|
||||
$stmt->execute( [ $_SESSION[ 'email_user' ] ] );
|
||||
} else {
|
||||
@ -142,7 +142,7 @@ if ( $_SERVER[ 'REQUEST_METHOD' ] === 'POST' ) {
|
||||
gnupg_setarmor( $gpg, 1 );
|
||||
$imported_key = gnupg_import( $gpg, $pgp_key );
|
||||
if ( ! $imported_key ) {
|
||||
$msg .= '<p class="red">'._('There was an error importing the key').'</p>';
|
||||
$msg .= '<p class="red">'.htmlspecialchars(_('There was an error importing the key')).'</p>';
|
||||
} else {
|
||||
$has_this_email = false;
|
||||
$key_info = gnupg_keyinfo( $gpg, $imported_key[ 'fingerprint' ] );
|
||||
@ -155,21 +155,21 @@ if ( $_SERVER[ 'REQUEST_METHOD' ] === 'POST' ) {
|
||||
}
|
||||
}
|
||||
if ( $has_this_email ) {
|
||||
$msg .= '<p class="green">'._('Successfully imported the key').'</p>';
|
||||
$msg .= '<p class="green">'.htmlspecialchars(_('Successfully imported the key')).'</p>';
|
||||
$stmt = $db->prepare( 'UPDATE mailbox SET pgp_key = ?, tfa = 0, pgp_verified = 0 WHERE username = ?;' );
|
||||
$stmt->execute( [ $pgp_key, $_SESSION[ 'email_user' ] ] );
|
||||
} else {
|
||||
$msg .= '<p class="red">' . sprintf( _('Oops, looks like the key is missing this email address as user id. Please add your address "%s" as user ID to your pgp key or create a new key pair.'), htmlspecialchars( $_SESSION[ 'email_user' ] ) ) . '</p>';
|
||||
$msg .= '<p class="red">' . sprintf( htmlspecialchars(_('Oops, looks like the key is missing this email address as user id. Please add your address "%s" as user ID to your pgp key or create a new key pair.')), htmlspecialchars( $_SESSION[ 'email_user' ] ) ) . '</p>';
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ( isset( $_POST[ 'enable_2fa_code' ] ) && ! empty( $_SESSION[ 'email_user' ] ) && $_POST[ 'action' ] === 'enable_2fa' ) {
|
||||
if ( $_POST[ 'enable_2fa_code' ] !== $_SESSION[ 'enable_2fa_code' ] ) {
|
||||
$msg .= '<p class="red">'._('Sorry, the code was incorrect').'</p>';
|
||||
$msg .= '<p class="red">'.htmlspecialchars(_('Sorry, the code was incorrect')).'</p>';
|
||||
} else {
|
||||
$stmt = $db->prepare( 'UPDATE mailbox SET tfa = 1, pgp_verified = 1 WHERE username = ?;' );
|
||||
$stmt->execute( [ $_SESSION[ 'email_user' ] ] );
|
||||
$msg .= '<p class="green">'._('Successfully enabled 2FA').'</p>';
|
||||
$msg .= '<p class="green">'.htmlspecialchars(_('Successfully enabled 2FA')).'</p>';
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -178,21 +178,21 @@ if ( $_SERVER[ 'REQUEST_METHOD' ] === 'POST' ) {
|
||||
<!DOCTYPE html>
|
||||
<html lang="<?php echo $language; ?>" dir="<?php echo $dir; ?>">
|
||||
<head>
|
||||
<title><?php echo _('E-Mail and XMPP - Manage account'); ?></title>
|
||||
<title><?php echo htmlspecialchars(_('E-Mail and XMPP - Manage account')); ?></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description"
|
||||
content="<?php echo _('Manage your free and anonymous E-Mail address and an XMPP/Jabber account. Add forwarding addresses, change your password or disable/delete your account.'); ?>">
|
||||
content="<?php echo htmlspecialchars(_('Manage your free and anonymous E-Mail address and an XMPP/Jabber account. Add forwarding addresses, change your password or disable/delete your account.')); ?>">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL; ?>manage_account.php">
|
||||
<link rel="alternate" href="<?php echo CANONICAL_URL; ?>manage_account.php" hreflang="x-default">
|
||||
<?php alt_links(); ?>
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="<?php echo _('E-Mail and XMPP - Manage account'); ?>">
|
||||
<meta property="og:description" content="<?php echo _('Manage your free and anonymous E-Mail address and an XMPP/Jabber account. Add forwarding addresses, change your password or disable/delete your account.'); ?>">
|
||||
<meta property="og:title" content="<?php echo htmlspecialchars(_('E-Mail and XMPP - Manage account')); ?>">
|
||||
<meta property="og:description" content="<?php echo htmlspecialchars(_('Manage your free and anonymous E-Mail address and an XMPP/Jabber account. Add forwarding addresses, change your password or disable/delete your account.')); ?>">
|
||||
<meta property="og:url" content="<?php echo CANONICAL_URL; ?>manage_account.php">
|
||||
<meta property="og:locale" content="<?php echo $locale; ?>">
|
||||
<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","name":"<?php echo _('E-Mail and XMPP - Manage account'); ?>", "description": "<?php echo _('Manage your free and anonymous E-Mail address and an XMPP/Jabber account. Add forwarding addresses, change your password or disable/delete your account.'); ?>"}</script>
|
||||
<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","name":"<?php echo htmlspecialchars(_('E-Mail and XMPP - Manage account')); ?>", "description": "<?php echo htmlspecialchars(_('Manage your free and anonymous E-Mail address and an XMPP/Jabber account. Add forwarding addresses, change your password or disable/delete your account.')); ?>"}</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
@ -213,15 +213,15 @@ foreach ( $key_info as $key ) {
|
||||
}
|
||||
$encrypted = gnupg_encrypt( $gpg, _('To login, please enter the following code to confirm ownership of your key:')."\n\n" . $_SESSION[ '2fa_code' ] . "\n" );
|
||||
echo $msg;
|
||||
echo '<p>'._('To login, please decrypt the following PGP encrypted message and confirm the code:').'</p>';
|
||||
echo '<p>'.htmlspecialchars(_('To login, please decrypt the following PGP encrypted message and confirm the code:')).'</p>';
|
||||
echo "<pre>$encrypted</pre>";
|
||||
?>
|
||||
<form class="form_limit" action="manage_account.php" method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION[ 'csrf_token' ]; ?>">
|
||||
<div class="row">
|
||||
<div class="col"><input type="text" name="2fa_code" aria-label="<?php echo _('2FA code'); ?>"></div>
|
||||
<div class="col"><input type="text" name="2fa_code" aria-label="<?php echo htmlspecialchars(_('2FA code')); ?>"></div>
|
||||
<div class="col">
|
||||
<button type="submit"><?php echo _('Confirm'); ?></button>
|
||||
<button type="submit"><?php echo htmlspecialchars(_('Confirm')); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@ -234,36 +234,36 @@ exit;
|
||||
if ( ! empty( $_SESSION[ 'email_user' ] ) ){ ?>
|
||||
<form method="post"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION[ 'csrf_token' ]; ?>">
|
||||
<?php } ?>
|
||||
<p><a href="<?php echo ROOT_URL; ?>"><?php echo _('Info'); ?></a> |<?php
|
||||
<p><a href="<?php echo ROOT_URL; ?>"><?php echo htmlspecialchars(_('Info')); ?></a> |<?php
|
||||
if ( ! empty( $_SESSION[ 'email_user' ] ) ) {
|
||||
printf(_('Logged in as %s'), htmlspecialchars( $_SESSION[ 'email_user' ] ) );
|
||||
printf(htmlspecialchars(_('Logged in as %s')), htmlspecialchars( $_SESSION[ 'email_user' ] ) );
|
||||
} else { ?>
|
||||
<a href="<?php echo ROOT_URL; ?>register.php"><?php echo _('Register'); ?></a>
|
||||
<a href="<?php echo ROOT_URL; ?>register.php"><?php echo htmlspecialchars(_('Register')); ?></a>
|
||||
<?php }
|
||||
if ( ! empty( $_SESSION[ 'email_user' ] ) ) { ?>
|
||||
|
|
||||
<button name="action" value="logout" type="submit"><?php echo _('Logout'); ?></button>
|
||||
<button name="action" value="logout" type="submit"><?php echo htmlspecialchars(_('Logout')); ?></button>
|
||||
<?php } else { ?>
|
||||
| <?php echo _('Manage account');
|
||||
} ?> | <a href="<?php echo ROOT_URL; ?>squirrelmail/src/login.php" target="_blank"><?php echo _('SquirrelMail'); ?></a> | <a href="<?php echo ROOT_URL; ?>snappymail/" target="_blank"><?php echo _('SnappyMail'); ?></a> | <a href="<?php echo WEB_XMPP_URL; ?>" target="_blank" rel="noopener"><?php echo _('Web-XMPP'); ?></a></p>
|
||||
| <?php echo htmlspecialchars(_('Manage account'));
|
||||
} ?> | <a href="<?php echo ROOT_URL; ?>squirrelmail/src/login.php" target="_blank"><?php echo htmlspecialchars(_('SquirrelMail')); ?></a> | <a href="<?php echo ROOT_URL; ?>snappymail/" target="_blank"><?php echo htmlspecialchars(_('SnappyMail')); ?></a> | <a href="<?php echo WEB_XMPP_URL; ?>" target="_blank" rel="noopener"><?php echo htmlspecialchars(_('Web-XMPP')); ?></a></p>
|
||||
<?php if ( ! empty( $_SESSION[ 'email_user' ] ) ){ ?></form><?php }
|
||||
echo "<p>$msg</p>";
|
||||
if ( empty( $_SESSION[ 'email_user' ] ) ) { ?>
|
||||
<form class="form_limit" action="manage_account.php" method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION[ 'csrf_token' ]; ?>">
|
||||
<div class="row">
|
||||
<div class="col"><label for="user"><?php echo _('Username'); ?></label></div>
|
||||
<div class="col"><label for="user"><?php echo htmlspecialchars(_('Username')); ?></label></div>
|
||||
<div class="col"><input type="text" name="user" id="user" autocomplete="username" required
|
||||
value="<?php echo htmlspecialchars( $_POST[ 'user' ] ?? '' ); ?>"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"><label for="pwd"><?php echo _('Password'); ?></label></div>
|
||||
<div class="col"><label for="pwd"><?php echo htmlspecialchars(_('Password')); ?></label></div>
|
||||
<div class="col"><input type="password" name="pwd" id="pwd" autocomplete="new-password" required></div>
|
||||
</div>
|
||||
<?php send_captcha(); ?>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button name="action" value="login" type="submit"><?php echo _('Login'); ?></button>
|
||||
<button name="action" value="login" type="submit"><?php echo htmlspecialchars(_('Login')); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@ -280,58 +280,58 @@ if ( empty( $_SESSION[ 'email_user' ] ) ) { ?>
|
||||
$tls_status = $stmt->fetch( PDO::FETCH_ASSOC );
|
||||
?>
|
||||
<form class="form_limit" action="manage_account.php" method="post">
|
||||
<h2><?php echo _('Settings'); ?></h2>
|
||||
<h3><?php echo _('Delivery'); ?></h3>
|
||||
<p><?php echo _('Change how your mail is delivered. You can add forwarding addresses one per line, or comma seperated. When you disable the "keep a local copy" checkbox, your mail will only be sent to your forwarding addresses.'); ?></p>
|
||||
<h2><?php echo htmlspecialchars(_('Settings')); ?></h2>
|
||||
<h3><?php echo htmlspecialchars(_('Delivery')); ?></h3>
|
||||
<p><?php echo htmlspecialchars(_('Change how your mail is delivered. You can add forwarding addresses one per line, or comma seperated. When you disable the "keep a local copy" checkbox, your mail will only be sent to your forwarding addresses.')); ?></p>
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION[ 'csrf_token' ]; ?>">
|
||||
<div class="row">
|
||||
<div class="col"><label for="alias_to"><?php echo _('Forward to'); ?></label></div>
|
||||
<div class="col"><label for="alias_to"><?php echo htmlspecialchars(_('Forward to')); ?></label></div>
|
||||
<div class="col"><textarea name="alias_to"
|
||||
id="alias_to"><?php echo htmlspecialchars( $aliases_to ); ?></textarea></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"><label for="alias_keep_copy"><?php echo _('Keep a local copy'); ?></label></div>
|
||||
<div class="col"><label for="alias_keep_copy"><?php echo htmlspecialchars(_('Keep a local copy')); ?></label></div>
|
||||
<div class="col"><input type="checkbox" name="alias_keep_copy"
|
||||
id="alias_keep_copy"<?php echo in_array( $_SESSION[ 'email_user' ], $aliases, true ) ? ' checked' : ''; ?>>
|
||||
</div>
|
||||
</div>
|
||||
<h3><?php echo _('Encryption'); ?></h3>
|
||||
<p><?php echo _('If you are having issues sending or receiving mails with some other provider, you can try disabling forced encryption here. But be aware, that this makes it possible for 3rd parties on the network to read your emails. Make sure to ask your correspondent to demand encryption support from their provider for a safer internet.'); ?></p>
|
||||
<h3><?php echo htmlspecialchars(_('Encryption')); ?></h3>
|
||||
<p><?php echo htmlspecialchars(_('If you are having issues sending or receiving mails with some other provider, you can try disabling forced encryption here. But be aware, that this makes it possible for 3rd parties on the network to read your emails. Make sure to ask your correspondent to demand encryption support from their provider for a safer internet.')); ?></p>
|
||||
<div class="row">
|
||||
<div class="col"><label for="enforce_tls_in"><?php echo _('Enforce encryption for incoming mail'); ?></label></div>
|
||||
<div class="col"><label for="enforce_tls_in"><?php echo htmlspecialchars(_('Enforce encryption for incoming mail')); ?></label></div>
|
||||
<div class="col"><input type="checkbox" name="enforce_tls_in"
|
||||
id="enforce_tls_in"<?php echo ! empty( $tls_status[ 'enforce_tls_in' ] ) ? ' checked' : ''; ?>>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"><label for="enforce_tls_out"><?php echo _('Enforce encryption for outgoing mail'); ?></label></div>
|
||||
<div class="col"><label for="enforce_tls_out"><?php echo htmlspecialchars(_('Enforce encryption for outgoing mail')); ?></label></div>
|
||||
<div class="col"><input type="checkbox" name="enforce_tls_out"
|
||||
id="enforce_tls_out"<?php echo ! empty( $tls_status[ 'enforce_tls_out' ] ) ? ' checked' : ''; ?>>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button name="action" value="update_settings" type="submit"><?php echo _('Update settings'); ?></button>
|
||||
<button name="action" value="update_settings" type="submit"><?php echo htmlspecialchars(_('Update settings')); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h2><?php echo _('Change password'); ?></h2>
|
||||
<h2><?php echo htmlspecialchars(_('Change password')); ?></h2>
|
||||
<form class="form_limit" action="manage_account.php" method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION[ 'csrf_token' ]; ?>">
|
||||
<div class="row">
|
||||
<div class="col"><label for="pass_update"><?php echo _('Password'); ?></label></div>
|
||||
<div class="col"><label for="pass_update"><?php echo htmlspecialchars(_('Password')); ?></label></div>
|
||||
<div class="col"><input type="password" name="pass_update" id="pass_update" autocomplete="new-password"
|
||||
required></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"><label for="pass_update2"><?php echo _('Password again'); ?></label></div>
|
||||
<div class="col"><label for="pass_update2"><?php echo htmlspecialchars(_('Password again')); ?></label></div>
|
||||
<div class="col"><input type="password" name="pass_update2" id="pass_update2" autocomplete="new-password"
|
||||
required></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button name="action" value="update_password" type="submit"><?php echo _('Change password'); ?></button>
|
||||
<button name="action" value="update_password" type="submit"><?php echo htmlspecialchars(_('Change password')); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@ -342,7 +342,7 @@ if ( empty( $_SESSION[ 'email_user' ] ) ) { ?>
|
||||
$pgp_status = $stmt->fetch( PDO::FETCH_ASSOC );
|
||||
if ( ! empty( $pgp_status[ 'pgp_key' ] ) ) {
|
||||
if ( $pgp_status[ 'tfa' ] === 1 ) {
|
||||
echo '<p class="green">'._('Yay, PGP based 2FA is enabled!').'</p>';
|
||||
echo '<p class="green">'.htmlspecialchars(_('Yay, PGP based 2FA is enabled!')).'</p>';
|
||||
} else {
|
||||
$gpg = gnupg_init();
|
||||
gnupg_seterrormode( $gpg, GNUPG_ERROR_WARNING );
|
||||
@ -352,7 +352,7 @@ if ( empty( $_SESSION[ 'email_user' ] ) ) { ?>
|
||||
$key_info = gnupg_keyinfo( $gpg, $imported_key[ 'fingerprint' ] );
|
||||
foreach ( $key_info as $key ) {
|
||||
if ( ! $key[ 'can_encrypt' ] ) {
|
||||
echo '<p>'._('Sorry, this key can\'t be used to encrypt a message to you. Your key may have expired or has been revoked.').'</p>';
|
||||
echo '<p>'.htmlspecialchars(_('Sorry, this key can\'t be used to encrypt a message to you. Your key may have expired or has been revoked.')).'</p>';
|
||||
} else {
|
||||
foreach ( $key[ 'subkeys' ] as $subkey ) {
|
||||
gnupg_addencryptkey( $gpg, $subkey[ 'fingerprint' ] );
|
||||
@ -361,16 +361,16 @@ if ( empty( $_SESSION[ 'email_user' ] ) ) { ?>
|
||||
}
|
||||
$_SESSION[ 'enable_2fa_code' ] = bin2hex( random_bytes( 3 ) );
|
||||
if ( $encrypted = gnupg_encrypt( $gpg, _('To enable 2FA, please enter the following code to confirm ownership of your key:'). "\n\n$_SESSION[enable_2fa_code]\n" ) ) {
|
||||
echo '<h2>'._( 'Enable 2FA').'</h2>';
|
||||
echo '<p>'._('To enable 2FA using your PGP key, please decrypt the following PGP encrypted message and confirm the code:').'</p>';
|
||||
echo '<h2>'.htmlspecialchars(_( 'Enable 2FA')).'</h2>';
|
||||
echo '<p>'.htmlspecialchars(_('To enable 2FA using your PGP key, please decrypt the following PGP encrypted message and confirm the code:')).'</p>';
|
||||
echo "<pre>$encrypted</pre>";
|
||||
?>
|
||||
<form class="form_limit" action="manage_account.php" method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION[ 'csrf_token' ]; ?>">
|
||||
<div class="row">
|
||||
<div class="col"><input type="text" name="enable_2fa_code" aria-label="<?php echo _('2FA code'); ?>"></div>
|
||||
<div class="col"><input type="text" name="enable_2fa_code" aria-label="<?php echo htmlspecialchars(_('2FA code')); ?>"></div>
|
||||
<div>
|
||||
<button type="submit" name="action" value="enable_2fa"><?php echo _('Confirm'); ?></button>
|
||||
<button type="submit" name="action" value="enable_2fa"><?php echo htmlspecialchars(_('Confirm')); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@ -381,33 +381,33 @@ if ( empty( $_SESSION[ 'email_user' ] ) ) { ?>
|
||||
}
|
||||
?>
|
||||
|
||||
<h2><?php echo _('Add PGP key for 2FA and end-to-end encryption'); ?></h2>
|
||||
<h2><?php echo htmlspecialchars(_('Add PGP key for 2FA and end-to-end encryption')); ?></h2>
|
||||
<form class="form_limit" action="manage_account.php" method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION[ 'csrf_token' ]; ?>">
|
||||
<div class="row">
|
||||
<div class="col"><textarea name="pgp_key" rows="10" cols="50"
|
||||
aria-label="<?php echo _('PGP key'); ?>"><?php echo htmlspecialchars( $pgp_status[ 'pgp_key' ] ?? '' ); ?></textarea>
|
||||
aria-label="<?php echo htmlspecialchars(_('PGP key')); ?>"><?php echo htmlspecialchars( $pgp_status[ 'pgp_key' ] ?? '' ); ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<button type="submit" name="action" value="update_pgp_key"><?php echo _('Update PGP key'); ?></button>
|
||||
<button type="submit" name="action" value="update_pgp_key"><?php echo htmlspecialchars(_('Update PGP key')); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form class="form_limit" action="manage_account.php" method="post">
|
||||
<h2><?php echo _('Disable/Delete account'); ?></h2>
|
||||
<p><?php echo _('Warning, this is permanent and cannot be undone. Disabling an account will delete your email data from the server, but leave the account blocked in the database for a year, so no one else can use it. Deleting your account will completely wipe all records of it and it will be available for new registrations again.'); ?></p>
|
||||
<h2><?php echo htmlspecialchars(_('Disable/Delete account')); ?></h2>
|
||||
<p><?php echo htmlspecialchars(_('Warning, this is permanent and cannot be undone. Disabling an account will delete your email data from the server, but leave the account blocked in the database for a year, so no one else can use it. Deleting your account will completely wipe all records of it and it will be available for new registrations again.')); ?></p>
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION[ 'csrf_token' ]; ?>">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button type="submit" name="action" value="disable_account"><?php echo _('Disable account'); ?></button>
|
||||
<button type="submit" name="action" value="disable_account"><?php echo htmlspecialchars(_('Disable account')); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button type="submit" name="action" value="delete_account"><?php echo _('Delete account'); ?></button>
|
||||
<button type="submit" name="action" value="delete_account"><?php echo htmlspecialchars(_('Delete account')); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
100
www/register.php
100
www/register.php
@ -13,24 +13,28 @@ if ( empty( $_SESSION[ 'csrf_token' ] ) || $_SESSION[ 'UA' ] !== $_SERVER[ 'HTTP
|
||||
$msg = '';
|
||||
if ( isset( $_POST[ 'user' ] ) ) {
|
||||
$ok = true;
|
||||
if( ! REGISTRATION_ENABLED ) {
|
||||
$ok = false;
|
||||
$msg .= '<div class="red" role="alert">'.sprintf(htmlspecialchars(_('Registration is disabled due to too many violations of the %s')), '<a href="'.ROOT_URL.'terms.php" target="_blank">'.htmlspecialchars(_('Terms of Service')).'</a>').'</div>';
|
||||
}
|
||||
if ( $_SESSION[ 'csrf_token' ] !== $_POST[ 'csrf_token' ] ?? '' ) {
|
||||
$ok = false;
|
||||
$msg .= '<div class="red" role="alert">'._('Invalid CSRF token').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('Invalid CSRF token')).'</div>';
|
||||
}
|
||||
if ( ! check_captcha( $_POST[ 'challenge' ] ?? '', $_POST[ 'captcha' ] ?? '' ) ) {
|
||||
$ok = false;
|
||||
$msg .= '<div class="red" role="alert">'._('Invalid captcha').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('Invalid captcha')).'</div>';
|
||||
}
|
||||
$db = get_db_instance();
|
||||
if ( ! preg_match( '/^([^+\/\'"]+?)(@([^@]+))?$/iu', $_POST[ 'user' ], $match ) ) {
|
||||
$ok = false;
|
||||
$msg .= '<div class="red" role="alert">'._('Invalid username. It may not contain a +, \', " or /.').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('Invalid username. It may not contain a +, \', " or /.')).'</div>';
|
||||
}
|
||||
$user = mb_strtolower( $match[ 1 ] ?? '' );
|
||||
$domain = $match[ 3 ] ?? 'danwin1210.de';
|
||||
$domain = $match[ 3 ] ?? CLEARNET_SERVER;
|
||||
if ( $ok && ( empty( $_POST[ 'pwd' ] ) || empty( $_POST[ 'pwd2' ] ) || $_POST[ 'pwd' ] !== $_POST[ 'pwd2' ] ) ) {
|
||||
$ok = false;
|
||||
$msg .= '<div class="red" role="alert">'._('Passwords empty or don\'t match').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('Passwords empty or don\'t match')).'</div>';
|
||||
} elseif ( $ok ) {
|
||||
$stmt = $db->prepare( 'SELECT target_domain FROM alias_domain WHERE alias_domain = ? AND active=1;' );
|
||||
$stmt->execute( [ $domain ] );
|
||||
@ -41,15 +45,15 @@ if ( isset( $_POST[ 'user' ] ) ) {
|
||||
$stmt->execute( [ $domain ] );
|
||||
if ( ! $stmt->fetch() ) {
|
||||
$ok = false;
|
||||
$msg .= '<div class="red" role="alert">'._('The domain you specified is not allowed').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('The domain you specified is not allowed')).'</div>';
|
||||
} else {
|
||||
$validator = new EmailValidator();
|
||||
if ( ! $validator->isValid( "$user@$domain", new NoRFCWarningsValidation() ) ) {
|
||||
$ok = false;
|
||||
$msg .= '<div class="red" role="alert">'._('The email address you specified is not valid').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('The email address you specified is not valid')).'</div>';
|
||||
} elseif(in_array($user, RESERVED_USERNAMES, true)){
|
||||
$ok = false;
|
||||
$msg .= '<div class="red" role="alert">'._('The username you specified is reserved').'</div>';
|
||||
$msg .= '<div class="red" role="alert">'.htmlspecialchars(_('The username you specified is reserved')).'</div>';
|
||||
}
|
||||
|
||||
}
|
||||
@ -65,9 +69,9 @@ if ( isset( $_POST[ 'user' ] ) ) {
|
||||
$hash = password_hash( $_POST[ 'pwd' ], PASSWORD_ARGON2ID );
|
||||
$stmt = $db->prepare( 'INSERT INTO alias (address, goto, domain, created, modified) VALUES (?, ?, ?, NOW(), NOW());' );
|
||||
$stmt->execute( [ "$user@$domain", "$user@$domain", $domain ] );
|
||||
$stmt = $db->prepare( 'INSERT INTO mailbox (username, password, quota, local_part, domain, created, modified, password_hash_type, openpgpkey_wkd) VALUES(?, ?, 51200000, ?, ?, NOW(), NOW(), ?, ?);' );
|
||||
$stmt->execute( [ "$user@$domain", $hash, $user, $domain, '{ARGON2ID}', z_base32_encode( hash( 'sha1', mb_strtolower( $user ), true ) ) ] );
|
||||
$msg .= '<div class="green" role="alert">'._('Successfully created new mailbox!').'</div>';
|
||||
$stmt = $db->prepare( 'INSERT INTO mailbox (username, password, quota, local_part, domain, created, modified, password_hash_type, openpgpkey_wkd) VALUES(?, ?, ?, ?, ?, NOW(), NOW(), ?, ?);' );
|
||||
$stmt->execute( [ "$user@$domain", $hash, DEFAULT_QUOTA, $user, $domain, '{ARGON2ID}', z_base32_encode( hash( 'sha1', mb_strtolower( $user ), true ) ) ] );
|
||||
$msg .= '<div class="green" role="alert">'.htmlspecialchars(_('Successfully created new mailbox!')).'</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -75,53 +79,59 @@ if ( isset( $_POST[ 'user' ] ) ) {
|
||||
<!DOCTYPE html>
|
||||
<html lang="<?php echo $language; ?>" dir="<?php echo $dir; ?>">
|
||||
<head>
|
||||
<title><?php echo _('E-Mail and XMPP - Register'); ?></title>
|
||||
<title><?php echo htmlspecialchars(_('E-Mail and XMPP - Register')); ?></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="<?php echo _('Register for a free and anonymous E-Mail address and an XMPP/Jabber account'); ?>">
|
||||
<meta name="description" content="<?php echo htmlspecialchars(_('Register for a free and anonymous E-Mail address and an XMPP/Jabber account')); ?>">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL; ?>register.php">
|
||||
<link rel="alternate" href="<?php echo CANONICAL_URL; ?>register.php" hreflang="x-default">
|
||||
<?php alt_links(); ?>
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="<?php echo _('E-Mail and XMPP - Register'); ?>">
|
||||
<meta property="og:description" content="<?php echo _('Register for a free and anonymous E-Mail address and an XMPP/Jabber account'); ?>">
|
||||
<meta property="og:title" content="<?php echo htmlspecialchars(_('E-Mail and XMPP - Register')); ?>">
|
||||
<meta property="og:description" content="<?php echo htmlspecialchars(_('Register for a free and anonymous E-Mail address and an XMPP/Jabber account')); ?>">
|
||||
<meta property="og:url" content="<?php echo CANONICAL_URL; ?>register.php">
|
||||
<meta property="og:locale" content="<?php echo $locale; ?>">
|
||||
<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","name":"<?php echo _('E-Mail and XMPP - Register'); ?>", "description": "<?php echo _('Register for a free and anonymous E-Mail address and an XMPP/Jabber account'); ?>"}</script>
|
||||
<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","name":"<?php echo htmlspecialchars(_('E-Mail and XMPP - Register')); ?>", "description": "<?php echo htmlspecialchars(_('Register for a free and anonymous E-Mail address and an XMPP/Jabber account')); ?>"}</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<p><a href="<?php echo ROOT_URL; ?>"><?php echo _('Info'); ?></a> | <?php echo _('Register'); ?> | <a href="<?php echo ROOT_URL; ?>manage_account.php"><?php echo _('Manage account'); ?></a> | <a href="<?php echo ROOT_URL; ?>squirrelmail/src/login.php" target="_blank"><?php echo _('SquirrelMail'); ?></a> | <a href="<?php echo ROOT_URL; ?>snappymail/" target="_blank"><?php echo _('SnappyMail'); ?></a> | <a href="<?php echo WEB_XMPP_URL; ?>" target="_blank" rel="noopener"><?php echo _('Web-XMPP'); ?></a>
|
||||
<p><a href="<?php echo ROOT_URL; ?>"><?php echo htmlspecialchars(_('Info')); ?></a> | <?php echo htmlspecialchars(_('Register')); ?> | <a href="<?php echo ROOT_URL; ?>manage_account.php"><?php echo htmlspecialchars(_('Manage account')); ?></a> | <a href="<?php echo ROOT_URL; ?>squirrelmail/src/login.php" target="_blank"><?php echo htmlspecialchars(_('SquirrelMail')); ?></a> | <a href="<?php echo ROOT_URL; ?>snappymail/" target="_blank"><?php echo htmlspecialchars(_('SnappyMail')); ?></a> | <a href="<?php echo WEB_XMPP_URL; ?>" target="_blank" rel="noopener"><?php echo htmlspecialchars(_('Web-XMPP')); ?></a>
|
||||
</p>
|
||||
<?php echo "<p>$msg</p>"; ?>
|
||||
<form class="form_limit" action="register.php" method="post"><input type="hidden" name="csrf_token"
|
||||
value="<?php echo $_SESSION[ 'csrf_token' ] ?>">
|
||||
<div class="row">
|
||||
<div class="col"><label for="user"><?php echo _('Username'); ?></label></div>
|
||||
<div class="col"><input type="text" name="user" id="user" autocomplete="username" required
|
||||
value="<?php echo htmlspecialchars( $_POST[ 'user' ] ?? '' ); ?>"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"><label for="pwd"><?php echo _('Password'); ?></label></div>
|
||||
<div class="col"><input type="password" name="pwd" id="pwd" autocomplete="new-password" required></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"><label for="pwd2"><?php echo _('Password again'); ?></label></div>
|
||||
<div class="col"><input type="password" name="pwd2" id="pwd2" autocomplete="new-password" required></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"><label for="accept_privacy"><?php printf(_('I have read and agreed to the <a href="%s" target="_blank">Privacy Policy</a>'), PRIVACY_POLICY_URL); ?></label>
|
||||
</div>
|
||||
<div class="col"><input type="checkbox" id="accept_privacy" name="accept_privacy" required></div>
|
||||
</div>
|
||||
<?php send_captcha(); ?>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button type="submit"><?php echo _('Register'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<?php echo "<p>$msg</p>";
|
||||
if( ! REGISTRATION_ENABLED ) {
|
||||
echo '<p>'.sprintf(htmlspecialchars(_('Registration is disabled due to too many violations of the %s')), '<a href="'.ROOT_URL.'terms.php" target="_blank">'.htmlspecialchars(_('Terms of Service')).'</a>').'</p>';
|
||||
} else {
|
||||
?>
|
||||
<form class="form_limit" action="register.php" method="post"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION[ 'csrf_token' ] ?>">
|
||||
<div class="row">
|
||||
<div class="col"><label for="user"><?php echo htmlspecialchars(_('Username')); ?></label></div>
|
||||
<div class="col"><input type="text" name="user" id="user" autocomplete="username" required value="<?php echo htmlspecialchars( $_POST[ 'user' ] ?? '' ); ?>"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"><label for="pwd"><?php echo htmlspecialchars(_('Password')); ?></label></div>
|
||||
<div class="col"><input type="password" name="pwd" id="pwd" autocomplete="new-password" required></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"><label for="pwd2"><?php echo htmlspecialchars(_('Password again')); ?></label></div>
|
||||
<div class="col"><input type="password" name="pwd2" id="pwd2" autocomplete="new-password" required></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"><label for="accept_privacy"><?php printf(htmlspecialchars(_('I have read and agreed to the %s')), '<a href="'.PRIVACY_POLICY_URL.'" target="_blank">'.htmlspecialchars(_('Privacy Policy')).'</a>'); ?></label></div>
|
||||
<div class="col"><input type="checkbox" id="accept_privacy" name="accept_privacy" required></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"><label for="accept_terms"><?php printf(htmlspecialchars(_('I have read and agreed to the %s')), '<a href="'.ROOT_URL.'terms.php" target="_blank">'.htmlspecialchars(_('Terms of Service')).'</a>'); ?></label></div>
|
||||
<div class="col"><input type="checkbox" id="accept_terms" name="accept_terms" required></div>
|
||||
</div>
|
||||
<?php send_captcha(); ?>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button type="submit"><?php echo htmlspecialchars(_('Register')); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<?php } ?>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
41
www/terms.php
Normal file
41
www/terms.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
include_once('../common_config.php');
|
||||
global $language, $dir, $locale;
|
||||
?>
|
||||
<!DOCTYPE html><html lang="<?php echo $language; ?>" dir="<?php echo $dir; ?>"><head>
|
||||
<title><?php echo htmlspecialchars(_('E-Mail and XMPP - Terms of Service')); ?></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="<?php echo htmlspecialchars(_('Terms of Service for E-Mail and XMPP accounts')); ?>">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL; ?>terms.php">
|
||||
<link rel="alternate" href="<?php echo CANONICAL_URL; ?>terms.php" hreflang="x-default">
|
||||
<?php alt_links(); ?>
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="<?php echo htmlspecialchars(_('E-Mail and XMPP - Terms of Service')); ?>">
|
||||
<meta property="og:description" content="<?php echo htmlspecialchars(_('Terms of Service for E-Mail and XMPP accounts')); ?>">
|
||||
<meta property="og:url" content="<?php echo CANONICAL_URL; ?>terms.php">
|
||||
<meta property="og:locale" content="<?php echo $locale; ?>">
|
||||
<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","name":"<?php echo htmlspecialchars(_('E-Mail and XMPP - Terms of Service')); ?>", "description": "<?php echo htmlspecialchars(_('Terms of Service for E-Mail and XMPP accounts')); ?>"}</script>
|
||||
</head><body>
|
||||
<main>
|
||||
<p><a href="<?php echo ROOT_URL; ?>"><?php echo htmlspecialchars(_('Info')); ?></a> | <a href="<?php echo ROOT_URL; ?>register.php"><?php echo htmlspecialchars(_('Register')); ?></a> | <a href="<?php echo ROOT_URL; ?>manage_account.php"><?php echo htmlspecialchars(_('Manage account')); ?></a> | <a href="<?php echo ROOT_URL; ?>squirrelmail/src/login.php" target="_blank"><?php echo htmlspecialchars(_('SquirrelMail')); ?></a> | <a href="<?php echo ROOT_URL; ?>snappymail/" target="_blank"><?php echo htmlspecialchars(_('SnappyMail')); ?></a> | <a href="<?php echo WEB_XMPP_URL; ?>" target="_blank" rel="noopener"><?php echo htmlspecialchars(_('Web-XMPP')); ?></a></p>
|
||||
<ol>
|
||||
<li><?php echo htmlspecialchars(_('I provide this service as is. I do not offer any uptime guarantee.')); ?></li>
|
||||
<li><?php echo htmlspecialchars(_('Inactive accounts get automatically deleted after one year of inactivity.')); ?></li>
|
||||
<li><?php echo htmlspecialchars(_('Spamming is not allowed, and you will be blocked if you do.')); ?></li>
|
||||
<li><?php echo htmlspecialchars(_('Using your account for illegal purposes is not allowed, and you will be blocked if you do.')); ?></li>
|
||||
<li><?php echo htmlspecialchars(_('Mass mailing is not allowed, and you will be blocked if you do.')); ?></li>
|
||||
<li><?php echo htmlspecialchars(_('Please refrain from sending threats of violence or any harmful content. Dealing with law enforcement requests related to such incidents consumes a significant amount of time.')); ?></li>
|
||||
<li><?php echo htmlspecialchars(_('If you lose your password, I will not reset it unless you can prove ownership of the account. You could do so by signing an email with the same PGP key that you use in your account.')); ?></li>
|
||||
<li><?php echo htmlspecialchars(_('You are responsible for the security of your account and password.')); ?></li>
|
||||
<?php if(DEFAULT_QUOTA > 0) { ?>
|
||||
<li><?php printf(htmlspecialchars(_('Your email account has %1$s of disk space by default. If you need more, you can %2$s, and I will increase it for free.')), bytes_to_human_readable(DEFAULT_QUOTA), '<a href="'.CONTACT_URL.'">'.htmlspecialchars(_('contact me')).'</a>'); ?></li>
|
||||
<?php } ?>
|
||||
<li><?php echo htmlspecialchars(_('The XMPP service provides message archiving and HTTP upload, which can keep your messages and files for up to 1 week. Up to 100MB of file storage is available per user.')); ?></li>
|
||||
<li><?php echo htmlspecialchars(_('I reserve the right to block or delete your account without prior notice.')); ?></li>
|
||||
<li><?php echo htmlspecialchars(_('I reserve the right to change these terms without prior notice.')); ?></li>
|
||||
<li><?php echo htmlspecialchars(_('Continued violations may necessitate the closure of registration.')); ?></li>
|
||||
</ol>
|
||||
</main>
|
||||
</body></html>
|
Reference in New Issue
Block a user