diff --git a/data/Dockerfiles/dovecot/docker-entrypoint.sh b/data/Dockerfiles/dovecot/docker-entrypoint.sh index ac7aeb1d..aa1aa0ae 100755 --- a/data/Dockerfiles/dovecot/docker-entrypoint.sh +++ b/data/Dockerfiles/dovecot/docker-entrypoint.sh @@ -307,12 +307,29 @@ namespace { } EOF +# Get SOGo IPv6 from Dig +SOGO_V6=$(dig +answer sogo AAAA +short) + +if [ $SOGO_V6 ]; then +cat < /etc/dovecot/sogo_trusted_ip.conf +# Autogenerated by mailcow +remote ${IPV4_NETWORK}.248 { + disable_plaintext_auth = no +} + +remote ${SOGO_V6} { + disable_plaintext_auth = no +} +EOF + +else cat < /etc/dovecot/sogo_trusted_ip.conf # Autogenerated by mailcow remote ${IPV4_NETWORK}.248 { disable_plaintext_auth = no } EOF +fi # Create random master Password for SOGo SSO RAND_PASS=$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 32 | head -n 1) diff --git a/data/Dockerfiles/sogo/Dockerfile b/data/Dockerfiles/sogo/Dockerfile index 72f7d816..f08600ac 100644 --- a/data/Dockerfiles/sogo/Dockerfile +++ b/data/Dockerfiles/sogo/Dockerfile @@ -2,7 +2,7 @@ FROM debian:bullseye-slim LABEL maintainer "Andre Peters " ARG DEBIAN_FRONTEND=noninteractive -ARG SOGO_DEBIAN_REPOSITORY=http://packages.inverse.ca/SOGo/nightly/5/debian/ +ARG SOGO_DEBIAN_REPOSITORY=http://packages.sogo.nu/nightly/5/debian/ ENV LC_ALL C ENV GOSU_VERSION 1.14 @@ -30,7 +30,7 @@ RUN echo "Building from repository $SOGO_DEBIAN_REPOSITORY" \ && gosu nobody true \ && mkdir /usr/share/doc/sogo \ && touch /usr/share/doc/sogo/empty.sh \ - && apt-key adv --keyserver keyserver.ubuntu.com --recv-key 0x810273C4 \ + && apt-key adv --keyserver keys.openpgp.org --recv-key 74FFC6D72B925A34B5D356BDF8A27B36A6E2EAE9 \ && echo "deb ${SOGO_DEBIAN_REPOSITORY} bullseye bullseye" > /etc/apt/sources.list.d/sogo.list \ && apt-get update && apt-get install -y --no-install-recommends \ sogo \ @@ -52,4 +52,4 @@ RUN chmod +x /bootstrap-sogo.sh \ ENTRYPOINT ["/docker-entrypoint.sh"] -CMD exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf +CMD exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf \ No newline at end of file diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index 3c767fad..3bab56bb 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -938,13 +938,16 @@ function check_login($user, $pass, $app_passwd_data = false) { $stmt->execute(array(':user' => $user)); $rows = array_merge($rows, $stmt->fetchAll(PDO::FETCH_ASSOC)); } - foreach ($rows as $row) { + foreach ($rows as $row) { // verify password - if ($app_passwd_data['eas'] !== true && $app_passwd_data['dav'] !== true){ - if (verify_hash($row['password'], $pass) !== false) { + if (verify_hash($row['password'], $pass) !== false) { + if (!array_key_exists("app_passwd_id", $row)){ + // password is not a app password // check for tfa authenticators $authenticators = get_tfa($user); - if (isset($authenticators['additional']) && is_array($authenticators['additional']) && count($authenticators['additional']) > 0) { + if (isset($authenticators['additional']) && is_array($authenticators['additional']) && count($authenticators['additional']) > 0 && + $app_passwd_data['eas'] !== true && $app_passwd_data['dav'] !== true) { + // authenticators found, init TFA flow $_SESSION['pending_mailcow_cc_username'] = $user; $_SESSION['pending_mailcow_cc_role'] = "user"; $_SESSION['pending_tfa_methods'] = $authenticators['additional']; @@ -955,7 +958,8 @@ function check_login($user, $pass, $app_passwd_data = false) { 'msg' => array('logged_in_as', $user) ); return "pending"; - } else { + } else if (!isset($authenticators['additional']) || !is_array($authenticators['additional']) || count($authenticators['additional']) == 0) { + // no authenticators found, login successfull // Reactivate TFA if it was set to "deactivate TFA for next login" $stmt = $pdo->prepare("UPDATE `tfa` SET `active`='1' WHERE `username` = :user"); $stmt->execute(array(':user' => $user)); @@ -963,22 +967,19 @@ function check_login($user, $pass, $app_passwd_data = false) { unset($_SESSION['ldelay']); return "user"; } - } - } elseif ($app_passwd_data['eas'] === true || $app_passwd_data['dav'] === true) { - if (array_key_exists("app_passwd_id", $row)){ - if (verify_hash($row['password'], $pass) !== false) { - $service = ($app_passwd_data['eas'] === true) ? 'EAS' : 'DAV'; - $stmt = $pdo->prepare("REPLACE INTO sasl_log (`service`, `app_password`, `username`, `real_rip`) VALUES (:service, :app_id, :username, :remote_addr)"); - $stmt->execute(array( - ':service' => $service, - ':app_id' => $row['app_passwd_id'], - ':username' => $user, - ':remote_addr' => ($_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR']) - )); + } elseif ($app_passwd_data['eas'] === true || $app_passwd_data['dav'] === true) { + // password is a app password + $service = ($app_passwd_data['eas'] === true) ? 'EAS' : 'DAV'; + $stmt = $pdo->prepare("REPLACE INTO sasl_log (`service`, `app_password`, `username`, `real_rip`) VALUES (:service, :app_id, :username, :remote_addr)"); + $stmt->execute(array( + ':service' => $service, + ':app_id' => $row['app_passwd_id'], + ':username' => $user, + ':remote_addr' => ($_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR']) + )); - unset($_SESSION['ldelay']); - return "user"; - } + unset($_SESSION['ldelay']); + return "user"; } } } diff --git a/data/web/inc/vars.inc.php b/data/web/inc/vars.inc.php index 77a821ed..c193db0d 100644 --- a/data/web/inc/vars.inc.php +++ b/data/web/inc/vars.inc.php @@ -100,6 +100,7 @@ $AVAILABLE_LANGUAGES = array( 'ru' => 'Pусский (Russian)', 'sk' => 'Slovenčina (Slovak)', 'sv' => 'Svenska (Swedish)', + 'tr' => 'Türkçe (Turkish)', 'uk' => 'Українська (Ukrainian)', 'zh' => '中文 (Chinese)' ); diff --git a/data/web/lang/lang.cs.json b/data/web/lang/lang.cs.json index 3d213247..6461d332 100644 --- a/data/web/lang/lang.cs.json +++ b/data/web/lang/lang.cs.json @@ -839,7 +839,7 @@ "confirm_delete": "Potvrdit smazání prvku.", "danger": "Nebezpečí", "deliver_inbox": "Doručit do schránky", - "disabled_by_config": "Funkce karanténa je momentálně vypnuta v nastavení systému.", + "disabled_by_config": "Funkce karanténa je momentálně vypnuta v nastavení systému. Nastavte, prosím, prvkům karantény hodnoty \"počet zadržených zpráv\" a \"maximální velikost\".", "download_eml": "Stáhnout (.eml)", "empty": "Žádné výsledky", "high_danger": "Vysoké nebezpečí", diff --git a/data/web/lang/lang.fr.json b/data/web/lang/lang.fr.json index efdf24f1..4af38c63 100644 --- a/data/web/lang/lang.fr.json +++ b/data/web/lang/lang.fr.json @@ -102,7 +102,8 @@ "timeout2": "Délai d'expiration pour la connexion à l'hôte local", "username": "Nom d'utilisateur", "validate": "Valider", - "validation_success": "Validation réussie" + "validation_success": "Validation réussie", + "bcc_dest_format": "La destination Cci doit être une seule adresse e-mail valide.
Si vous avez besoin d'envoyer une copie à plusieurs adresses, créez un alias et utilisez-le ici." }, "admin": { "access": "Accès", @@ -322,7 +323,9 @@ "yes": "✓", "api_read_write": "Accès Lecture-Écriture", "oauth2_add_client": "Ajouter un client OAuth2", - "password_policy": "Politique de mots de passe" + "password_policy": "Politique de mots de passe", + "admins": "Administrateurs", + "api_read_only": "Accès lecture-seule" }, "danger": { "access_denied": "Accès refusé ou données de formulaire non valides", diff --git a/data/web/lang/lang.it.json b/data/web/lang/lang.it.json index cd0e85e5..cd2e0da6 100644 --- a/data/web/lang/lang.it.json +++ b/data/web/lang/lang.it.json @@ -973,7 +973,8 @@ "verified_fido2_login": "Verified FIDO2 login", "verified_totp_login": "Verified TOTP login", "verified_webauthn_login": "Verified WebAuthn login", - "verified_yotp_login": "Verified Yubico OTP login" + "verified_yotp_login": "Verified Yubico OTP login", + "domain_add_dkim_available": "Esisteva già una chiave DKIM" }, "tfa": { "api_register": "%s usa le API Yubico Cloud. Richiedi una chiave API qui", diff --git a/data/web/lang/lang.ro.json b/data/web/lang/lang.ro.json index cc5f17b0..e92defaf 100644 --- a/data/web/lang/lang.ro.json +++ b/data/web/lang/lang.ro.json @@ -979,7 +979,8 @@ "verified_totp_login": "Autentificarea TOTP verificată", "verified_webauthn_login": "Autentificarea WebAuthn verificată", "verified_fido2_login": "Conectare FIDO2 verificată", - "verified_yotp_login": "Autentificarea Yubico OTP verificată" + "verified_yotp_login": "Autentificarea Yubico OTP verificată", + "domain_add_dkim_available": "O cheie DKIM deja a existat" }, "tfa": { "api_register": "%s utilizează API-ul Yubico Cloud. Obțineți o cheie API pentru cheia dvs. de aici", @@ -990,7 +991,7 @@ "enter_qr_code": "Codul tău TOTP dacă dispozitivul tău nu poate scana codurile QR", "error_code": "Cod de eroare", "init_webauthn": "Inițializare, vă rugăm așteptați...", - "key_id": "Un identificator pentru YubiKey", + "key_id": "Un identificator pentru dispozitiv", "key_id_totp": "Un identificator pentru cheia ta", "none": "Dezactivează", "reload_retry": "- (reîncărcați browserul dacă eroarea persistă)", diff --git a/data/web/lang/lang.tr.json b/data/web/lang/lang.tr.json new file mode 100644 index 00000000..697c7483 --- /dev/null +++ b/data/web/lang/lang.tr.json @@ -0,0 +1,85 @@ +{ + "acl": { + "alias_domains": "Takma alan adı ekle", + "app_passwds": "Uygulama şifrelerini yönet", + "delimiter_action": "Sınırlama işlemi", + "domain_relayhost": "Bir alan adı için relayhost sunucusunu değiştir", + "eas_reset": "EAS cihazlarını sıfırla", + "mailbox_relayhost": "Bir posta kutusunun relayhost sunucularını değiştir", + "pushover": "Bildirim", + "quarantine": "Karantina işlemleri", + "quarantine_attachments": "Ekleri karantinaya al", + "quarantine_notification": "Karantina bildirimlerini değiştir", + "smtp_ip_access": "SMTP sunucularının değiştirilmesine izin ver", + "sogo_access": "SOGo erişiminin yönetilmesine izin ver", + "domain_desc": "Alan adı açıklamasını değiştir", + "extend_sender_acl": "Gönderenin acl'sini harici adreslere göre genişletmeye izin ver", + "spam_policy": "Engellenenler / İzin verilenler" + }, + "add": { + "activate_filter_warn": "Aktif edilirse diğer tüm filtreler devre dışı bırakılacak.", + "add_domain_only": "Sadece alan adı ekle", + "alias_address": "Takma ad adres(leri)", + "alias_domain": "Takma alan adı", + "alias_domain_info": "Sadece geçerli alan adları (virgülle ayırın).", + "backup_mx_options": "İletme ayarları", + "delete2": "Kaynakta olmayan hedefteki mesajları sil", + "delete2duplicates": "Hedefteki kopyaları sil", + "disable_login": "Giriş yapmaya izin verme ( Gelen mailler yine de kabul edilir)", + "domain": "Alan adı", + "domain_matches_hostname": "Alan adı %s ana bilgisayar adıyla eşleşiyor", + "add_domain_restart": "Alan adı ekleyin ve SOGo'yu yeniden başlatın", + "alias_address_info": "Bir alan adına ilişkin tüm iletileri yakalamak için tam e-posta adresi veya @example.com olacak şeklinde girin (virgülle ayırın).sadece mailcow alan adları.", + "domain_quota_m": "Toplam alan adı kotası (MiB)", + "generate": "oluştur", + "goto_ham": "Ham olarakişaretle", + "goto_null": "Postaları sessizce çöpe at", + "goto_spam": "Spam olarakişaretle", + "hostname": "Ana sunucu", + "kind": "Tür", + "mailbox_quota_m": "Posta kutusu başına maksimum kota (MiB)", + "max_aliases": "Maksimum olası takma adı", + "max_mailboxes": "Maksimum olası posta kutusu", + "nexthop": "Sonraki atlama", + "port": "Port", + "public_comment": "Genel yorum", + "relay_all": "Tüm alıcılara ilet", + "relay_all_info": "Eğer hiçbir alıcıya iletilmemesini seçerseniz, aktarılması gereken her alıcı için bir (\"kör\") posta kutusu eklemeniz gerekecektir.", + "relay_domain": "Bu alan adını ilet", + "relay_transport_info": "
Bilgi
Bu etki alanı için özel bir hedef için aktarım eşlemeleri tanımlayabilirsiniz. Ayarlanmazsa, bir MX araması yapılacaktır.", + "relay_unknown_only": "Yalnızca mevcut olmayan posta kutularını ilet. Mevcut posta kutuları yerel olarak teslim edilecektir.", + "relayhost_wrapped_tls_info": "Lütfen TLS ile örtülmüş portları kullanmayın (çoğu 465 portunda çalışır).
\nÖrtülmemiş port kullan ve STARTTLS üzerinden yayınla. TLS'yi zorlamak için bir TLS ilkesi \"TLS ilke eşlemeleri\" sayfası içinde oluşturulabilir.", + "skipcrossduplicates": "Klasörler arasında yinelenen mesajları atlayın (ilk mesaj seçilir)", + "target_address": "Adreslere git", + "target_address_info": "Tam e-posta adres(leri) girin ( virgülle ayırın).", + "target_domain": "Hedef alan adı", + "timeout1": "Uzak ana bilgisayara bağlantısı zaman aşımına uğradı", + "timeout2": "Yerel ana bilgisayara bağlantı zaman aşımına uğradı" + }, + "admin": { + "action": "İşlem", + "add_forwarding_host": "Yönlendirme sunucusu ekle", + "add_transport": "İletim ekle", + "admin_details": "Yönetici detaylarını düzenle", + "admin_domains": "Alan adı atamaları", + "add_domain_admin": "Alan adı yöneticisi ekle", + "api_info": "API üzerinde çalışmalar devam etmektedir. Belgeler /apiadresinde bulunabilir", + "apps_name": "\"mailcow Uygulamaları\" adı", + "authed_user": "Yetkili kullanıcı", + "ban_list_info": "Aşağıdaki yasaklı IP'lerin listesine bakın: ağ (kalan yasak süresi) - [işlemler].
Yasağı kaldırılmak üzere sıraya alınan IP'ler birkaç saniye içinde aktif yasak listesinden kaldırılacaktır.
Kırmızı etiketler, kara listeye alınarak aktif kalıcı yasakları gösterir.", + "configuration": "Yapılandırma", + "dkim_from_title": "Verilerin kopyalanacağı kaynak alan adı", + "dkim_to": "Kime", + "dkim_to_title": "Hedef alan ad(ları) üzerinde yazılacak", + "dkim_domains_wo_keys": "Eksik anahtarları olan alan adlarını seçin", + "domain": "Alan adı", + "domain_admin": "Alan adı yöneticisi", + "domain_admins": "Alan adı yöneticileri", + "domain_s": "Alan ad(ları)", + "duplicate": "Çift", + "duplicate_dkim": "Çift DKIM kayıtları", + "f2b_ban_time": "Yasaklama süresi (saniye)", + "f2b_max_attempts": "Maksimum giriş denemesi", + "f2b_retry_window": "Maksimum girişim için deneme pencere(leri)" + } +} diff --git a/docker-compose.yml b/docker-compose.yml index da2b7e0d..308a87c1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -168,7 +168,7 @@ services: - phpfpm sogo-mailcow: - image: mailcow/sogo:1.109 + image: mailcow/sogo:1.110 environment: - DBNAME=${DBNAME} - DBUSER=${DBUSER}