Skip to content

Fix IMAP sync authentication with legacy-encoded passwords#6969

Draft
Copilot wants to merge 3 commits intostagingfrom
copilot/sync-jobs-legacy-passwords
Draft

Fix IMAP sync authentication with legacy-encoded passwords#6969
Copilot wants to merge 3 commits intostagingfrom
copilot/sync-jobs-legacy-passwords

Conversation

Copy link
Contributor

Copilot AI commented Dec 15, 2025

Contribution Guidelines

What does this PR include?

Short Description

IMAP sync jobs fail when passwords contain single-byte characters (e.g., § = 0xA7) because UTF-8 encoding transforms 0xA70xC2 0xA7, breaking authentication with Exchange 2016 and similar servers.

Solution: Retry with Latin-1 encoding on authentication failure, preserving original byte sequences while maintaining UTF-8 compatibility.

Changes:

  • Refactored password file creation into encoding-aware helper function
  • First attempt: UTF-8 encoding (existing behavior)
  • On auth failure: Automatic retry with ISO-8859-1 encoding
  • Added word boundaries to auth failure detection regex

Example flow:

# First attempt (UTF-8)
$stdout = $run_imapsync->('utf8');

# Retry on auth failure (Latin-1)
if ($stdout =~ /\b(LOGIN failed|authentication failed)\b/i) {
  $stdout = $run_imapsync->('latin1');  # Preserves 0xA7 as-is
}

Affected Containers

  • dovecot

Did you run tests?

What did you tested?

  • Encoding byte sequence verification (UTF-8 vs Latin-1)
  • Perl syntax validation
  • Code review and security analysis

What were the final results? (Awaited, got)

  • UTF-8: 0xA70xC2 0xA7 (expected, got)
  • Latin-1: 0xA70xA7 (expected, got)
  • Backward compatibility: UTF-8 passwords continue working
  • No security vulnerabilities introduced
Original prompt

This section details on the original issue you should resolve

<issue_title>Sync-Jobs with legacy-encoded passwords</issue_title>
<issue_description>### Contribution guidelines

Checklist prior issue creation

  • I understand that failure to follow below instructions may cause this issue to be closed.
  • I understand that vague, incomplete or inaccurate information may cause this issue to be closed.
  • I understand that this form is intended solely for reporting software bugs and not for support-related inquiries.
  • I understand that all responses are voluntary and community-driven, and do not constitute commercial support.
  • I confirm that I have reviewed previous issues to ensure this matter has not already been addressed.
  • I confirm that my environment meets all prerequisite requirements as specified in the official documentation.

Description

IMAP sync jobs generated via the mailcow API fail when the remote password contains single-byte (non-UTF-8) characters, such as § (0xA7), which are accepted by Exchange 2016 IMAP.

As example, the user has a password ending with "§" (the character 0xA7) , imapsync_runner.pl will encode that as 0xC2 0xA7 in the password file and pass that to imapsync, failing the Authentication.

The failure is caused by forcing :utf8 binmode on the temporary passfile in the imapsync wrapper, which re-encodes the password to UTF-8, changing the byte sequence and breaking authentication. I understand that this is required for paswords that actually contains UTF-8, so while removing the binmode works for me, it will regress on #5528.

I think there is no easy way to correctly fix this, a workaround could be, if the password is UTF-8 and authentication fails to retry with re-encoding the password to latin1. (This seems also a strategy thunderbird employed, at least some years ago -
https://superuser.com/questions/1696433/outlook-password-encoding-for-email-services-imap-smtp )

Steps to reproduce:

  1. Setup Sync-Job with Exchange 2016, password contains 8-bit character (like §); options like "--showpasswords" and "--debugimap1" are helpful, as they show how the password is sent over the wire.

  2. Sync-Job fails with password error, --showpaswords show that the password is UTF-8 encoded -- see below for extract.

  3. manually calling imapsync with password's "§" sent as 0xA7 only.
    imapsync --showpasswords --debugimap1 --dry --justfolders --host1 <redacted> --user1 <redacted> --password1 $(printf"xxxxxxxxxxxx\xa7") --host2 <redacted> --user2 <redacted> --password2 "<redacted>"

  4. removing the "binmode( $passfile1, ":utf8" );" line from data/Dockerfiles/dovecot/imapsync_runner.pl -- auth now works.

Logs:

step 2 imapsync debug extract with showpasswords:

	Mail::IMAPClient::__ANON__("3 NO LOGIN failed.\x{d}\x{a}") called at /usr/share/perl5/vendor_perl/Mail/IMAPClient.pm line 1424
	Mail::IMAPClient::_imap_command_do(Mail::IMAPClient=HASH(0x7fef355a4550), "LOGIN <redacted> {14}\x{d}\x{a}xxxxxxxxxxxx\x{c2}\x{a7}") called at /usr/share/perl5/vendor_perl/Mail/IMAPClient.pm line 1248



step 3 manual imapsync invocation:

Connected to <exchange-hostname>
Read: 	* OK The Microsoft Exchange IMAP4 service is ready.
Host1 IP address: 192.168.0.211
Host1 banner: * OK The Microsoft Exchange IMAP4 service is ready.
Sending: 1 CAPABILITY
Sent 14 bytes
Read: 	* CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=NTLM AUTH=GSSAPI UIDPLUS MOVE ID CHILDREN IDLE NAMESPACE LITERAL+
  	1 OK CAPABILITY completed.
Host1 capability before authentication: IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=NTLM AUTH=GSSAPI UIDPLUS MOVE ID CHILDREN IDLE NAMESPACE LITERAL+ AUTH
Sending literal: 2 LOGIN <redacted> {13}
  	then: xxxxxxxxxxxx�
Sending: 2 LOGIN <redacted> {13}
Sent 33 bytes
Read: 	+ Ready for additional command text.
Sending: xxxxxxxxxxxx�
Sent 15 bytes
Read: 	2 OK LOGIN completed.

Which branch are you using?

master (stable)

Which architecture are you using?

x86_64

Operating System:

Debian GNU/Linux 13 (trixie)

Server/VM specifications:

16 GiB, 8 cores

Is Apparmor, SELinux or similar active?

no

Virtualization technology:

Proxmox

Docker version:

26.1.5+dfsg1

docker-compose version or docker compose version:

Docker Compose version 2.26.1-4

mailcow version:

2025-12a

Reverse proxy:

n/a

Logs of git diff:

no changes to the code.

Logs of iptables -L -vn:

this is not a network issue

Logs of ip6tables -L -vn:

this is not a network issue

Logs of iptables -L -vn -t nat:

this is not a network issue

Logs of ip6tables...


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits December 15, 2025 08:15
…in-1 retry logic

Co-authored-by: DerLinkman <62480600+DerLinkman@users.noreply.github.com>
Co-authored-by: DerLinkman <62480600+DerLinkman@users.noreply.github.com>
Copilot AI changed the title [WIP] Sync jobs with legacy-encoded passwords Fix IMAP sync authentication with legacy-encoded passwords Dec 15, 2025
Copilot AI requested a review from DerLinkman December 15, 2025 08:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments