[Dovecot] Fix app passwds: allow multiple pass hashes by using LUA construct

master
andryyy 2019-12-03 18:50:45 +01:00
parent 851e9c8736
commit afb43c9c5b
No known key found for this signature in database
GPG Key ID: 8EC34FF2794E25EF
3 changed files with 38 additions and 23 deletions

View File

@ -69,6 +69,7 @@ RUN groupadd -g 5000 vmail \
libunicode-string-perl \ libunicode-string-perl \
liburi-perl \ liburi-perl \
libwww-perl \ libwww-perl \
lua-sql-mysql \
mariadb-client \ mariadb-client \
procps \ procps \
python3-pip \ python3-pip \

View File

@ -7,21 +7,6 @@ while ! mysqladmin status --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${D
sleep 2 sleep 2
done done
# Hard-code env vars to scripts due to cron not passing them to the scripts
sed -i "s/__DBUSER__/${DBUSER}/g" /usr/local/bin/imapsync_cron.pl
sed -i "s/__DBPASS__/${DBPASS}/g" /usr/local/bin/imapsync_cron.pl
sed -i "s/__DBNAME__/${DBNAME}/g" /usr/local/bin/imapsync_cron.pl
sed -i "s/__DBUSER__/${DBUSER}/g" /usr/local/bin/quarantine_notify.py
sed -i "s/__DBPASS__/${DBPASS}/g" /usr/local/bin/quarantine_notify.py
sed -i "s/__DBNAME__/${DBNAME}/g" /usr/local/bin/quarantine_notify.py
sed -i "s/__DBUSER__/${DBUSER}/g" /usr/local/bin/clean_q_aged.sh
sed -i "s/__DBPASS__/${DBPASS}/g" /usr/local/bin/clean_q_aged.sh
sed -i "s/__DBNAME__/${DBNAME}/g" /usr/local/bin/clean_q_aged.sh
sed -i "s/__LOG_LINES__/${LOG_LINES}/g" /usr/local/bin/trim_logs.sh
# Create missing directories # Create missing directories
[[ ! -d /etc/dovecot/sql/ ]] && mkdir -p /etc/dovecot/sql/ [[ ! -d /etc/dovecot/sql/ ]] && mkdir -p /etc/dovecot/sql/
[[ ! -d /var/vmail/_garbage ]] && mkdir -p /var/vmail/_garbage [[ ! -d /var/vmail/_garbage ]] && mkdir -p /var/vmail/_garbage
@ -127,12 +112,35 @@ default_pass_scheme = SSHA256
password_query = SELECT password FROM mailbox WHERE active = '1' AND username = '%u' AND domain IN (SELECT domain FROM domain WHERE domain='%d' AND active='1') AND JSON_EXTRACT(attributes, '$.force_pw_update') NOT LIKE '%%1%%' password_query = SELECT password FROM mailbox WHERE active = '1' AND username = '%u' AND domain IN (SELECT domain FROM domain WHERE domain='%d' AND active='1') AND JSON_EXTRACT(attributes, '$.force_pw_update') NOT LIKE '%%1%%'
EOF EOF
cat <<EOF > /etc/dovecot/sql/dovecot-dict-sql-app-passdb.conf cat <<EOF > /var/lib/dovecot/app-passdb.lua
# Autogenerated by mailcow function auth_password_verify(req, pass)
driver = mysql local cur,errorString = con:execute(string.format([[SELECT mailbox, password FROM app_passwd
connect = "host=/var/run/mysqld/mysqld.sock dbname=${DBNAME} user=${DBUSER} password=${DBPASS}" WHERE mailbox = '%s'
default_pass_scheme = SSHA256 AND active = '1'
password_query = SELECT password FROM app_passwd WHERE active = '1' AND mailbox = '%u' AND domain IN (SELECT domain FROM domain WHERE domain='%d' AND active='1') AND domain IN (SELECT domain FROM domain WHERE domain='%s' AND active='1')]], con:escape(req.user), con:escape(req.domain)))
local row = cur:fetch ({}, "a")
while row do
if req.password_verify(req, row.password, pass) == 1 then
req.log_warning(req, string.format("User %s logged in with app password", row.mailbox))
cur:close()
return dovecot.auth.PASSDB_RESULT_OK, "password=" .. pass
end
row = cur:fetch (row, "a")
end
return dovecot.auth.PASSDB_RESULT_USER_UNKNOWN, "no such user"
end
function script_init()
mysql = require "luasql.mysql"
env = mysql.mysql()
con = env:connect("__DBNAME__","__DBUSER__","__DBPASS__","mysql")
return 0
end
function script_deinit()
con:close()
env:close()
end
EOF EOF
# Migrate old sieve_after file # Migrate old sieve_after file
@ -206,6 +214,12 @@ else
rm -f /etc/dovecot/sogo-sso.conf rm -f /etc/dovecot/sogo-sso.conf
fi fi
# Hard-code env vars to scripts due to cron not passing them to the scripts
sed -i "s/__DBUSER__/${DBUSER}/g" /usr/local/bin/imapsync_cron.pl /usr/local/bin/quarantine_notify.py /usr/local/bin/clean_q_aged.sh /var/lib/dovecot/app-passdb.lua
sed -i "s/__DBPASS__/${DBPASS}/g" /usr/local/bin/imapsync_cron.pl /usr/local/bin/quarantine_notify.py /usr/local/bin/clean_q_aged.sh /var/lib/dovecot/app-passdb.lua
sed -i "s/__DBNAME__/${DBNAME}/g" /usr/local/bin/imapsync_cron.pl /usr/local/bin/quarantine_notify.py /usr/local/bin/clean_q_aged.sh /var/lib/dovecot/app-passdb.lua
sed -i "s/__LOG_LINES__/${LOG_LINES}/g" /usr/local/bin/trim_logs.sh
# 401 is user dovecot # 401 is user dovecot
if [[ ! -s /mail_crypt/ecprivkey.pem || ! -s /mail_crypt/ecpubkey.pem ]]; then if [[ ! -s /mail_crypt/ecprivkey.pem || ! -s /mail_crypt/ecpubkey.pem ]]; then
openssl ecparam -name prime256v1 -genkey | openssl pkey -out /mail_crypt/ecprivkey.pem openssl ecparam -name prime256v1 -genkey | openssl pkey -out /mail_crypt/ecprivkey.pem

View File

@ -56,8 +56,8 @@ passdb {
} }
# try an app passwd # try an app passwd
passdb { passdb {
args = /etc/dovecot/sql/dovecot-dict-sql-app-passdb.conf driver = lua
driver = sql args = file=/var/lib/dovecot/app-passdb.lua blocking=yes
pass = yes pass = yes
result_failure = continue result_failure = continue
result_internalfail = continue result_internalfail = continue