Skip to content

Commit

Permalink
rework auth - move dovecot sasl log to php
Browse files Browse the repository at this point in the history
  • Loading branch information
FreddleSpl0it authored and DerLinkman committed Feb 8, 2024
1 parent 17b6ac3 commit 7b47159
Show file tree
Hide file tree
Showing 3 changed files with 227 additions and 214 deletions.
57 changes: 6 additions & 51 deletions data/Dockerfiles/dovecot/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -138,18 +138,17 @@ function auth_password_verify(request, password)
ltn12 = require "ltn12"
https = require "ssl.https"
https.TIMEOUT = 5
mysql = require "luasql.mysql"
env = mysql.mysql()
con = env:connect("__DBNAME__","__DBUSER__","__DBPASS__","localhost")
local req = {
username = request.user,
password = password
password = password,
real_rip = request.real_rip,
protocol = {}
}
req.protocol[request.service] = true
local req_json = json.encode(req)
local res = {}
-- check against mailbox passwds
local b, c = https.request {
method = "POST",
url = "https://nginx:9082",
Expand All @@ -162,48 +161,10 @@ function auth_password_verify(request, password)
insecure = true
}
local api_response = json.decode(table.concat(res))
if api_response.role == 'user' then
con:execute(string.format([[REPLACE INTO sasl_log (service, app_password, username, real_rip)
VALUES ("%s", 0, "%s", "%s")]], con:escape(request.service), con:escape(request.user), con:escape(request.real_rip)))
con:close()
return dovecot.auth.PASSDB_RESULT_OK, "password=" .. password
end
-- check against app passwds for imap and smtp
-- app passwords are only available for imap, smtp, sieve and pop3 when using sasl
if request.service == "smtp" or request.service == "imap" or request.service == "sieve" or request.service == "pop3" then
skip_sasl_log = false
req.protocol = {}
if tostring(req.real_rip) ~= "__IPV4_SOGO__" then
skip_sasl_log = true
req.protocol[request.service] = true
end
req_json = json.encode(req)
local b, c = https.request {
method = "POST",
url = "https://nginx:9082",
source = ltn12.source.string(req_json),
headers = {
["content-type"] = "application/json",
["content-length"] = tostring(#req_json)
},
sink = ltn12.sink.table(res),
insecure = true
}
local api_response = json.decode(table.concat(res))
if api_response.role == 'user' then
if skip_sasl_log == false then
con:execute(string.format([[REPLACE INTO sasl_log (service, app_password, username, real_rip)
VALUES ("%s", %d, "%s", "%s")]], con:escape(req.service), row.id, con:escape(req.user), con:escape(req.real_rip)))
end
con:close()
return dovecot.auth.PASSDB_RESULT_OK, "password=" .. password
end
if api_response.success == true then
return dovecot.auth.PASSDB_RESULT_OK, ""
end
con:close()
return dovecot.auth.PASSDB_RESULT_PASSWORD_MISMATCH, "Failed to authenticate"
end
Expand All @@ -212,12 +173,6 @@ function auth_passdb_lookup(req)
end
EOF

# Replace patterns in app-passdb.lua
sed -i "s/__DBUSER__/${DBUSER}/g" /etc/dovecot/auth/passwd-verify.lua
sed -i "s/__DBPASS__/${DBPASS}/g" /etc/dovecot/auth/passwd-verify.lua
sed -i "s/__DBNAME__/${DBNAME}/g" /etc/dovecot/auth/passwd-verify.lua
sed -i "s/__IPV4_SOGO__/${IPV4_NETWORK}.248/g" /etc/dovecot/auth/passwd-verify.lua


# Migrate old sieve_after file
[[ -f /etc/dovecot/sieve_after ]] && mv /etc/dovecot/sieve_after /etc/dovecot/global_sieve_after
Expand Down
35 changes: 27 additions & 8 deletions data/conf/dovecot/auth/mailcowauth.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
<?php
ini_set('error_reporting', 0);
header('Content-Type: application/json');

$post = trim(file_get_contents('php://input'));
if ($post) {
$post = json_decode($post, true);
}

$return = array("success" => false, "role" => false);
if(!isset($post['username']) || !isset($post['password'])){

$return = array("success" => false);
if(!isset($post['username']) || !isset($post['password']) || !isset($post['real_rip'])){
error_log("MAILCOWAUTH: Bad Request");
http_response_code(400); // Bad Request
echo json_encode($return);
exit();
}
Expand All @@ -18,9 +22,7 @@
}
require_once '../../../web/inc/lib/vendor/autoload.php';

ini_set('error_reporting', 0);
// Init database
//$dsn = $database_type . ':host=' . $database_host . ';dbname=' . $database_name;
$dsn = $database_type . ":unix_socket=" . $database_sock . ";dbname=" . $database_name;
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
Expand All @@ -31,7 +33,8 @@
$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
}
catch (PDOException $e) {
$return = array("success" => false, "role" => '');
error_log("MAILCOWAUTH: " . $e . PHP_EOL);
http_response_code(500); // Internal Server Error
echo json_encode($return);
exit;
}
Expand All @@ -44,12 +47,28 @@
// Init provider
$iam_provider = identity_provider('init');

$result = check_login($post['username'], $post['password'], $post['protocol'], true);

$protocol = $post['protocol'];
if ($post['real_rip'] == getenv('IPV4_NETWORK') . '.248') {
$protocol = null;
}
$result = user_login($post['username'], $post['password'], $protocol, array('is_internal' => true));
if ($result === false){
$result = apppass_login($post['username'], $post['password'], $protocol, array(
'is_internal' => true,
'remote_addr' => $post['real_rip']
));
}

if ($result) {
$return = array("success" => true, "role" => $result);
http_response_code(200); // OK
$return['success'] = true;
} else {
$return = array("success" => false, "role" => '');
error_log("MAILCOWAUTH: Login failed for user " . $post['username']);
http_response_code(401); // Unauthorized
}


echo json_encode($return);
session_destroy();
exit;

0 comments on commit 7b47159

Please sign in to comment.