View Issue Details

IDProjectCategoryView StatusLast Update
0002230SOGoSOPEpublic2013-02-06 22:04
Reporterbofhus Assigned Tojraby 
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionno change required 
Product Version2.0.4b 
Summary0002230: Managesieve dialog troubles
Description

I have found an issue in SOPE, while it talks witch managesieve daemon. In the fact, it is a managesieve daemon issue, but it could be easy workarrounded in SOPE.

SOPE uses two lines construction for autenticate:

AUTHENTICATE "PLAIN" {80+}
[BASE64:<login>\0<login>\0<pass>]

Some managesieve daemons (for example the one shipped with dovecot) expect only one line, and send answer like that:

OK "Logged in."
NO "Error in MANAGESIEVE command [repeated login BASE64 string]: Unknown command."

It's quite well - we are logged, but we got extra line with error.
Unfortunately SOPE expects only one answer and regards second line (with "NO")
as the answer for a next (future) command. It is repeated for all commands in dialog, and it makes trouble later:

SETACTIVE ""
DELETESCRIPT "sogo"

OK "No scripts currently active."
NO (NONEXISTENT) "Script does not exist."

Setactive disables any script, and ends with OK. SOPE takes previous NO, but
it's no problem,

Deletescript doesn't find any script, and returns NO (it should be logged by SOGo), but SOPE takes prevoius "OK" and nothing appears in log.

PUTSCRIPT "sogo" {31+}
redirect "bogdan@xxx.xxx.pl";

OK "PUTSCRIPT completed."

SOPE sends script, and got answer OK. But it takes previous "NO" and return error. This error is logged by SOGo: Could not upload Sieve script: {RawResponse
= "{ok = 0; }"; result = 0; }

SOGo closes interaction, without script activation....

Could you change authenticate command to one line version?
It will be much more compatible with some broken managesieve daemons.

TagsNo tags attached.

Activities

jraby

jraby

2013-02-05 21:48

viewer   ~0005347

what version of dovecot are you using?
I'm testing with 2.0.19 and it seems to work fine as is.

bofhus

bofhus

2013-02-05 21:59

reporter   ~0005348

dovecot 2.1.8
pigeonhole-0.3.1

jraby

jraby

2013-02-05 22:26

viewer   ~0005349

Can you manually reproduce the problem by connecting on the managesieve port and sending the AUTHENTICATE command in both forms?

<pre>
AUTHENTICATE "PLAIN" "base64(user\0user\0passwd)"

and

AUTHENTICATE "PLAIN" {dataLength+}
base64(user\0user\0passwd)
</pre>

If the second form fails, a bug should be reported to the dovecot pigeonhole team as this is a regression.

Also, can you post the capability list of the managesieve server? (initial data sent by the server)

bofhus

bofhus

2013-02-06 05:02

reporter   ~0005350

It was hard to reproduce, but finaly I got success.

Client and server are run on different hosts (not localhost) - it's important.

First I try "telnet imap 4190" and send commands via cut and paste.
With two lines auth I was logged without any error, but with one line version I could not login.

Then I checked SOGo tcpdump session and notice, there are two packets - first with

AUTHENTICATE "PLAIN" {dataLength+}\r\n
base64(user\0user\0passwd)

and second with \r\n only.

So I create test code:
....
write(sockfd,"AUTHENTICATE \"PLAIN\" {80+}\r\nBASE64STRING\r\n",110);
....

It worked right without any error, so I change it:
....
write(sockfd,"AUTHENTICATE \"PLAIN\" {80+}\r\nBASE64STRING\r\n",108);
write(sockfd,"\r\n",2);
....

And managesieve returns:
OK "Logged in."
NO "Error in MANAGESIEVE command BASE64STRING : Unknown command."

Initial data sent by the server:
"IMPLEMENTATION" "Dovecot Pigeonhole"
"SIEVE" "fileinto reject envelope encoded-character vacation subaddress comparator-i
"NOTIFY" "mailto"
"SASL" "PLAIN LOGIN"
"STARTTLS"
"VERSION" "1.0"
OK "Dovecot ready."

bofhus

bofhus

2013-02-06 05:07

reporter   ~0005351

First I try "telnet imap 4190" and send commands via cut and paste.
With two lines auth I was logged without any error, but with
one line version I could not login.

I tried with telnet and one line auth again and it worked too.

jraby

jraby

2013-02-06 15:05

viewer   ~0005357

Last edited: 2013-02-06 15:09

Unfortunately, I think this is a bug in recent versions of pigeonhole (post 0.3).

SOPE sends all its commands in the same way:
<pre>
write(command); / command does NOT end with CRLF /
write("\r\n");
</pre>

From your observations, it looks like pigeon hole processes the commands before having reached the CRLF, which seems wrong to me.

Can you report that to the pigeonhole devs?

Meanwhile I'll attach a patch that you could use to enable single line AUTHENTICATE (by enabling SieveQuotedAuth in your config)
If pigeonhole has a consistent behavior, it might fail in the same way since the command will be sent in 2 writes. (command + CRLF)

2013-02-06 15:08

 

0001-Add-quoted-string-support-in-sieve-authenticate.patch (3,035 bytes)   
From f03a970c35524c6dbd8f1d154b83a25efbf7121b Mon Sep 17 00:00:00 2001
From: Jean Raby <jraby@inverse.ca>
Date: Tue, 5 Feb 2013 18:02:00 -0500
Subject: [PATCH] Add quoted string support in sieve authenticate

By setting 'SieveQuotedAuth' to TRUE, NGSieveClient will send
the auth string on a single line, in a 'quoted string' instead
of the string literal like it does by default.

This should be used as a workaround for broken manage sieve servers.
Fixes #2230
---
 sope-mime/NGImap4/NGSieveClient.m |   28 +++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/sope-mime/NGImap4/NGSieveClient.m b/sope-mime/NGImap4/NGSieveClient.m
index 22c705c..e579ad9 100644
--- a/sope-mime/NGImap4/NGSieveClient.m
+++ b/sope-mime/NGImap4/NGSieveClient.m
@@ -82,6 +82,7 @@ static NSNumber *NoNumber          = nil;
 static BOOL     ProfileImapEnabled = NO;
 static BOOL     LOG_PASSWORD       = NO;
 static BOOL     debugImap4         = NO;
+static BOOL     quotedAuth         = NO;
 
 + (void)initialize {
   static BOOL didInit = NO;
@@ -93,6 +94,7 @@ static BOOL     debugImap4         = NO;
   LOG_PASSWORD       = [ud boolForKey:@"SieveLogPassword"];
   ProfileImapEnabled = [ud boolForKey:@"ProfileImapEnabled"];
   debugImap4         = [ud boolForKey:@"ImapDebugEnabled"];
+  quotedAuth         = [ud boolForKey:@"SieveQuotedAuth"];
   
   YesNumber = [[NSNumber numberWithBool:YES] retain];
   NoNumber  = [[NSNumber numberWithBool:NO] retain];
@@ -391,6 +393,7 @@ static BOOL     debugImap4         = NO;
 - (NSDictionary *)login {
   NGHashMap *map  = nil;
   NSData    *auth;
+  NSString  *s, *logText;
   char      *buf;
   int       bufLen, logLen, authLen;
   
@@ -426,20 +429,27 @@ static BOOL     debugImap4         = NO;
   auth = [NSData dataWithBytesNoCopy:buf length:bufLen];
   auth = [auth dataByEncodingBase64WithLineLength:4096 /* 'unlimited' */];
   
+  if (quotedAuth)
+    {
+      s = [NSString stringWithFormat:@"AUTHENTICATE \"PLAIN\" \"%s\"",
+                                      [auth bytes]];
+      logText = [NSString stringWithString:
+                        @"AUTHENTICATE \"PLAIN\" LOGIN:PASSWORD\r\n"];
+    }
+  else
+    {
+      s = [NSString stringWithFormat:@"AUTHENTICATE \"PLAIN\" {%d+}\r\n%s",
+                                     [auth length], [auth bytes]];
+      logText = [NSString stringWithString:
+                        @"AUTHENTICATE \"PLAIN\" {%d+}\r\nLOGIN:PASSWORD\r\n"];
+    }
+
   if (LOG_PASSWORD) {
-    NSString *s;
-    
-    s = [NSString stringWithFormat:@"AUTHENTICATE \"PLAIN\" {%d+}\r\n%s",
-                  [auth length], [auth bytes]];
     map = [self processCommand:s];
   }
   else {
-    NSString *s;
-    
-    s = [NSString stringWithFormat:@"AUTHENTICATE \"PLAIN\" {%d+}\r\n%s",
-                  [auth length], [auth bytes]];
     map = [self processCommand:s
-                logText:@"AUTHENTICATE \"PLAIN\" {%d+}\r\nLOGIN:PASSWORD\r\n"];
+                logText:logText];
   }
 
   if (map == nil) {
-- 
1.7.9.5

bofhus

bofhus

2013-02-06 15:29

reporter   ~0005359

Single line auth have the same issue. If "\r\n" string is in separate write,
error looks smilar:

OK "Logged in."
NO "Error in MANAGESIEVE command : Unknown command."

I will report it to pigeonhole developers, but I'll upgrade it to the latest version first.

Is it very problematic to send auth string with "/r/n" at the end in single write?

jraby

jraby

2013-02-06 15:43

viewer   ~0005360

To send only the AUTHENTICATE command with the CRLF in a single write would not be pretty since all the sieve commands use the same path to actually 'send' to the server.

It would be easier to do it for all commands, but I'd rather not change that since it works (almost) everywhere...

bofhus

bofhus

2013-02-06 18:54

reporter   ~0005362

Latest version of pigeonhole still got this issue. I'll report it to pigeonhole developers.

bofhus

bofhus

2013-02-06 21:32

reporter   ~0005365

Pigeonhole developer (Stephan) is the fast one :) New patch was created and the issue has gone.

http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/32d178f5e1a2

jraby

jraby

2013-02-06 22:04

viewer   ~0005366

nice!

Thanks for taking the time to debug this.

jraby

jraby

2013-02-06 22:04

viewer   ~0005367

behavior fixed in pigeonhole

Issue History

Date Modified Username Field Change
2013-02-05 19:04 bofhus New Issue
2013-02-05 21:48 jraby Note Added: 0005347
2013-02-05 21:48 jraby Status new => assigned
2013-02-05 21:48 jraby Assigned To => jraby
2013-02-05 21:59 bofhus Note Added: 0005348
2013-02-05 22:26 jraby Note Added: 0005349
2013-02-06 05:02 bofhus Note Added: 0005350
2013-02-06 05:07 bofhus Note Added: 0005351
2013-02-06 15:05 jraby Note Added: 0005357
2013-02-06 15:08 jraby File Added: 0001-Add-quoted-string-support-in-sieve-authenticate.patch
2013-02-06 15:09 jraby Note Edited: 0005357
2013-02-06 15:29 bofhus Note Added: 0005359
2013-02-06 15:43 jraby Note Added: 0005360
2013-02-06 18:54 bofhus Note Added: 0005362
2013-02-06 21:32 bofhus Note Added: 0005365
2013-02-06 22:04 jraby Note Added: 0005366
2013-02-06 22:04 jraby Note Added: 0005367
2013-02-06 22:04 jraby Status assigned => resolved
2013-02-06 22:04 jraby Resolution open => no change required