cyrus-imapd server, sasl client and "encoded packet size too big (4156 > 4096)"

Ragnar Sundblad ragge at csc.kth.se
Sun Feb 24 17:41:37 EST 2013


Hello all,

We are modernizing our Cyrus IMAP server, and are using
cyrus sasl 2.1.26 and imap server 2.4.17.
We are using Kerberos (GSSAPI) for authenticating the different
parts to each other, such as the proxy to the imapd, imapds to
each other, and such.

We often get "encoded packet size too big (4156 > 4096)" paired
with "decoding error: generic failure; SASL(-1): generic failure:
security flags do not match required, closing connection" on the
receiving end, when one imap server is xfer-ing to another. This
has possibly also occurred for other sasl client/server connections.

We have tried a bunch of different patches while at the same time
learning more of the code.

The GSSAPI adds 60 bytes of overhead on the transfers, but imapd
doesn't always honor that, and sends packets that become to large
and that can't be decoded on the receiving end.

If we forcibly turns down the initial "maxplain" size for the write
stream, with the patch below, it seems to work as intended.
It could possibly be that prot_setsasl() isn't always called on the
write stream correctly, but I am not sure about that.

I guess that if we used SSL/TLS and PLAIN login, we wouldn't have
this problem, since then we wouldn't have an per packet overhead
with SASL.

Has anyone else seen this?

I would be happy for a better fix than the below.

/ragge


This seems to be the best workaround for now:

--- prot.c.DIST        2013-02-21 13:33:22.544751444 +0100
+++ prot.c      2013-02-22 12:22:44.155846743 +0100
@@ -89,13 +89,17 @@ struct protgroup
 struct protstream *prot_new(int fd, int write)
 {
     struct protstream *newstream;
     newstream = (struct protstream *) xzmalloc(sizeof(struct protstream));
     newstream->buf_size = PROT_BUFSIZE;
     newstream->buf = (unsigned char *) 
       xmalloc(sizeof(char) * (newstream->buf_size));
     newstream->ptr = newstream->buf;
     newstream->maxplain = newstream->buf_size;
+    if ( write ) { /* XXX */
+      newstream->maxplain -= 120; /* 60 would probably do */
+    }
     newstream->fd = fd;
     newstream->write = write;
     newstream->logfd = PROT_NO_FD;
     newstream->big_buffer = PROT_NO_FD;



More information about the Info-cyrus mailing list