Re: [Dovecot] imap-login hanging when firewall blocks ssl handshaking

2012-12-01 Thread Ben Morrow
At 10AM -0800 on 1/12/12 Erik A Johnson wrote:
> 
> On November 29, 2012 at 2:39:51 PM PST, Timo Sirainen  wrote:
> > Yes, that sounds like it would work better:
> > 
> > if (!proxy->client && net_getpeername(proxy->fd_ssl, NULL, NULL)  <
> > 0 && errno == ENOTCONN) {
> 
> Using getpeername or net_getpeername, errno is set to EINVAL = "socket
> has been shut down", so we could instead use 
> 
>if (!proxy->client && net_getpeername(proxy->fd_ssl, NULL, NULL)  <
>0 && errno == EINVAL) {
> 
> So it seems that we have the following options:
> 
> 1.  net_geterror(proxy->fd_ssl) == EBADF
> 2.  read(proxy->fd_ssl, &err, 0) < 0  &&  errno == ENOTCONN
> 3.  net_getpeername(proxy->fd_ssl, NULL, NULL) < 0  &&  errno == EINVAL
> 
> Which is preferable?  

I think the djb page I mentioned before comes down in favour of

if (!proxy->client && net_getpeername(...) < 0 &&
read(proxy->fd_ssl, &err, 1) < 0 && errno == ENOTCONN) {

where the read is of 1 byte rather than 0 since a read of 0 apparently
sometimes succeeds even if the socket isn't connected, and the
getpeername is to protect against actually reading from a connected
socket. However, doing all that every time we try to read seems like a
lot of wasted effort; if possible, it would be better to identify the
circumstances when it might happen (for instance, is it true that if
we've done at least one successful SSL read on this socket that this
error won't occur?).

> Should the "#ifdef __APPLE__" remain? or would any of these tests be
> appropriate for other platforms as well?

I had a go at reproducing this on FreeBSD and failed, but I don't
believe we've seen a packet trace yet so I wasn't entirely sure what
might provoke it. There is definitely a bug in the OS here somewhere,
unless the socket never gets as far as SYN-SYN/ACK-ACK, since ENOTCONN
should only be returned *before* the socket has connected successfully.
An ordinary disconnected socket should simply return EOF from read, and
a socket that got RST should return ECONNRESET.

Are you able to reproduce this and get a tcpdump packet trace (on the
dovecot side of any firewalls)? Also, when this happens, does it happen
straight away or is there a delay until the connection times out?

(I don't suppose you know if the source for the OSX network stack is
online anywhere? I'd be interested to see how different it is from
FreeBSD's.)

Ben



Re: [Dovecot] imap-login hanging when firewall blocks ssl handshaking

2012-12-01 Thread Erik A Johnson
On Nov 29, 2012, at 7:42 AM, Erik A Johnson  wrote:
 No, the test to bug out doesn't work because net_geterror(proxy->fd_ssl) 
 returns 0 in the statement
 
   if (!proxy->client_proxy && net_geterror(proxy->fd_ssl) == ENOTCONN) {

I was wrong here: the FIRST time, net_geterror returns EBADF = "The argument 
socket is not a valid file descriptor" (and then 0 on subsequent calls).

On November 29, 2012 at 12:43:42 PM PST, Timo Sirainen  wrote:
>>> I wonder if something like would work:
>>> 
>>> if (!proxy->client && read(proxy->fd_ssl, &err, 0) < 0 && errno == 
>>> ENOTCONN) {

On November 29, 2012 at 2:12:18 PM PST, Ben Morrow  wrote:
>> How about calling getpeername on fd_ssl? That should reliably tell you
>> if the socket is connected or not. http://cr.yp.to/docs/connect.html
>> suggests that read is not always a reliable test for that.

Thanks, Ben.

On November 29, 2012 at 2:39:51 PM PST, Timo Sirainen  wrote:
> Yes, that sounds like it would work better:
> 
> if (!proxy->client && net_getpeername(proxy->fd_ssl, NULL, NULL)  < 0 && 
> errno == ENOTCONN) {

Using getpeername or net_getpeername, errno is set to EINVAL = "socket has been 
shut down", so we could instead use 

   if (!proxy->client && net_getpeername(proxy->fd_ssl, NULL, NULL)  < 0 && 
errno == EINVAL) {

So it seems that we have the following options:

1.  net_geterror(proxy->fd_ssl) == EBADF
2.  read(proxy->fd_ssl, &err, 0) < 0  &&  errno == ENOTCONN
3.  net_getpeername(proxy->fd_ssl, NULL, NULL) < 0  &&  errno == EINVAL

Which is preferable?  Should the "#ifdef __APPLE__" remain? or would any of 
these tests be appropriate for other platforms as well?

On Nov 28, 2012, at 10:18PM PST, Timo Sirainen  wrote:
> This is either OSX bug or OpenSSL bug.. Apparently what happens is:
> 
> 1. Client sends SYN packet to Dovecot
> 2. Dovecot accept()s the connection (sends SYN-ACK) and goes into OpenSSL 
> code
> 3. Client doesn't send ACK to Dovecot. Does it send RST or nothing or 
> something else? I don't know.
> 4. OSX notices anyway that something is wrong with the socket, and kqueue 
> says that the socket is ready for reading
> 5. OpenSSL read()s, which fails with ENOTCONN. But OpenSSL thinks this is 
> a non-fatal error and simply asks to be notified again when something can 
> be read
> 6. goto 4
> 
> So, whose bug is it? OpenSSL's ENOTCONN handling probably makes sense for 
> client connections where connect() hasn't finished yet. But then again, 
> this is accept()ed connection where it typically should fail like that. 
> Except I guess it might be correct behavior if read() is done after 
> SYN-ACK but before receiving ACK.
> 
> While OSX is receiving ACK from the client, it shouldn't say that the fd 
> is readable. It probably doesn't. But after it receives  it 
> realizes that the socket is disconnected. So read() probably shouldn't be 
> returning ENOTCONN anymore at this point, but instead ECONNRESET or 
> ETIMEDOUT.
> 
> See if the attached patch helps.
> 
> 
> On 29.11.2012, at 7.45, Erik A Johnson wrote:
>> Here's the log:
>> 
>> Nov 28 21:28:11 macbookpro-e17d.home dovecot[54139]: master: Dovecot 
>> v2.1.10 starting up (core dumps disabled)
>> Nov 28 21:30:19 macbookpro-e17d.home dovecot[54141]: imap-login: Debug: 
>> ssl_step()
>> Nov 28 21:30:19 macbookpro-e17d.home dovecot[54141]: imap-login: Debug: 
>> ssl_handshake: SSL_accept()=-1
>> Nov 28 21:30:19 macbookpro-e17d.home dovecot[54141]: imap-login: Debug: 
>> SSL_get_error() = 2
>> Nov 28 21:30:19 macbookpro-e17d.home dovecot[54141]: imap-login: Debug:  
>> - want_read
>> Nov 28 21:30:19 macbookpro-e17d.home dovecot[54141]: imap-login: Debug: 
>> ssl_set_io(0)
>> [last 5 lines are repeated until process is killed]
>> 
>> On Nov 26, 2012, as 11:38PM PST, Timo Sirainen  wrote:
>>> 
>>> Could you try with the attached patch, and with only the problematic
>>> client running? What does it log (the beginning of the session until it
>>> starts repeating the same lines)?
>>> 
>>> On 10.11.2012, at 12.44, Erik A Johnson wrote:
 imap-login processes are hanging (using 100% of CPU) when connected 
 from a client that is partially blocked by a firewall.  It appears 
 that imap-login is stuck in a loop trying to complete an ssl 
 handshake.  imap-login is working fine for other clients not blocked 
 by the firewall (including localhost).
 
 This is dovecot 2.1.10 under Mac OS X 10.8.2 (compiled from sources); 
 the firewall is Little Snitch 3.0.1 blocking port 993, which appears 
 to let the connection initiate but then squashes and disconnects the 
 socket during ssl handshaking.
 
 gdb backtrace and Activity Monitor's "Sample Process" show that 
 imap-login 

[Dovecot] Undeserved permissions error with g+s folder permissions

2012-12-01 Thread tlhackque
I have a (mbox/IMAP) directory under my mail directory with these 
permissions:


drwxrws--- 4 tlhackque mail 4096 Dec  1 10:34 Vendors/

It contains a subdirectory:

-rw-rw 1 thlackque mail 84805345 Dec  1 10:34 Vendors/AVendor

If I try to rename the AVendor folder (client is Thunderbird 17.0), I 
get this error:


Unable to rename across conflicting directory permisssions

If I chmod g-s Vendors, the RENAME command succeeds.

I shouldn't have to do this...

Version and configuration information:

dovecot --version
2.1.10

# OS: Linux 2.6.22.14-72.fc6 i686 Fedora Core release 6 (Zod)
first_valid_gid = 4000
first_valid_uid = 4000
hostname = example.net
login_greeting = Dovecot ready.  Unauthorized access is prohibited.
mail_access_groups = mail
mail_location = mbox:~/mail:INBOX=/var/mail/%n
mail_privileged_group = mail
namespace inbox {
  inbox = yes
  location =
  mailbox Drafts {
special_use = \Drafts
  }
  mailbox Junk {
special_use = \Junk
  }
  mailbox Sent {
special_use = \Sent
  }
  mailbox "Sent Messages" {
special_use = \Sent
  }
  mailbox Trash {
special_use = \Trash
  }
  prefix =
  separator = /
}
passdb {
  driver = pam
}
plugin {
  autocreate = Trash
  autocreate2 = Train As Spam
  autocreate3 = Train As Ham
  autocreate4 = Train As Forgotten
  autosubscribe = Trash
  autosubscribe2 = Train As Spam
  autosubscribe3 = Train As Ham
  autosubscribe4 = Train As Forgotten
}
service imap-login {
  inet_listener imap {
address = imap.v4.example.net imap.v6.example.net
port = 143
  }
  inet_listener imaps {
address = imap.v4.example.net imap.v6.example.net
port = 993
ssl = yes
  }
}
service pop3-login {
  inet_listener pop3 {
address = pop.v4.example.net pop.v6.example.net
port = 110
  }
  inet_listener pop3s {
address = pop.v4.example.net pop.v6.example.net
port = 995
ssl = yes
  }
}
ssl_ca = 

Re: [Dovecot] 回复: 2.1.12 - Pigeonhole 0.3.3 build failed: /usr/bin/ld: cannot find -lssl -lcrypto

2012-12-01 Thread Tobias Hachmer
On Saturday 01 December 2012 08:34:09 Sam DWH wrote:
> Did you installed openssh?

Well, no, I have installed libssl-dev (Ubuntu Precise).
What I have really done is to add the libssl-dev to the dependencies of my 
dovecot-dev package. This dovecot-dev package is a dependency of my pigeonhole 
package.

Regards,
Tobias