atom feed19 messages in net.sourceforge.lists.courier-usersRe: [courier-users] Debugging courier...
FromSent OnAttachments
Brian A. SekleckiFeb 28, 2006 10:49 am 
Gordon MessmerFeb 28, 2006 11:15 am 
Brian A. SekleckiFeb 28, 2006 11:25 am 
Brian A. SekleckiFeb 28, 2006 11:26 am 
Gordon MessmerFeb 28, 2006 2:01 pm 
Brian A. SekleckiFeb 28, 2006 9:27 pm 
Brian A. SekleckiFeb 28, 2006 9:55 pm.txt
Gordon MessmerFeb 28, 2006 11:18 pm.patch
Brian A. SekleckiMar 1, 2006 1:06 am 
Gordon MessmerMar 1, 2006 1:30 am 
Brian A. SekleckiMar 1, 2006 1:46 am 
Brian A. SekleckiMar 1, 2006 1:46 am 
Gordon MessmerMar 1, 2006 8:15 am 
Brian A. SekleckiMar 1, 2006 10:45 pm 
Gordon MessmerMar 1, 2006 11:17 pm 
Brian A. SekleckiMar 22, 2006 11:17 am 
Lloyd ZusmanMar 23, 2006 4:34 pm 
Gordon MessmerMar 23, 2006 4:51 pm 
Lloyd ZusmanMar 23, 2006 5:04 pm 
Subject:Re: [courier-users] Debugging couriertcpd(8) obfuscation with IDENT to Localhost Addresses on FreeBSD
From:Gordon Messmer (yiny@eburg.com)
Date:Feb 28, 2006 11:18:03 pm
List:net.sourceforge.lists.courier-users
Attachments:

Brian A. Seklecki wrote:

Attached in private mail the last couple thousand lines with ktrace -d -and -i. I appreciate you looking at it.

Not private, but it didn't contain any private data, and it wasn't terribly huge... :)

It looks like it's simply failing to fork.

Actually, it looks like a bug in the s_connect function on FreeBSD. It's not detecting an error when it calls sox_getsockopt(), so tcpd thinks the socket is good, and tries to write data to it. It catches SIGPIPE, which isn't handled, specifically, so the signal causes the process to term.

After reading data from smtpaccess.dat, the next logged call is get_sockname, in tcpd.c's run() function.

13090 couriertcpd CALL getsockname(0x5,0xbfbfe980,0xbfbfe7fc) 13090 couriertcpd RET getsockname 0

... then we go on to the tcpremoteinfo() function.

13090 couriertcpd CALL socket(0x2,0x1,0) 13090 couriertcpd RET socket 6 13090 couriertcpd CALL bind(0x6,0xbfbfe720,0x10) 13090 couriertcpd RET bind 0

Here's the part where tcpremoteinfo() calls s_connect to connect to port 113. s_connect() sets the O_NONBLOCK flag, and then calls connect()

It looks to me like s_connect() needs to check errno when the return value is not 0. I think that the code assumes that errno is set to EINPROGRESS, because the socket was non-blocking. However, that's not the case for you. On your system, errno is set to ECONNREFUSED. s_connect should handle any errno value other than EINPROGRESS as a permanent failure, and should return -1.

I don't think that it's necessary to reset the NONBLOCK option on the socket, so the attached two-line patch should fix it.

13090 couriertcpd CALL gettimeofday(0xbfbfe6b8,0) 13090 couriertcpd RET gettimeofday 0 13090 couriertcpd CALL fcntl(0x6,0x4,0x4) 13090 couriertcpd RET fcntl 0 13090 couriertcpd CALL connect(0x6,0xbfbfe720,0x10) 13090 couriertcpd RET connect -1 errno 61 Connection refused 13090 couriertcpd CALL select(0x7,0,0xbfbfe630,0,0xbfbfe628) 13090 couriertcpd RET select 1 13090 couriertcpd CALL getsockopt(0x6,0xffff,0x1007,0xbfbfe620,0xbfbfe624) 13090 couriertcpd RET getsockopt 0 13090 couriertcpd CALL gettimeofday(0xbfbfe6b8,0) 13090 couriertcpd RET gettimeofday 0 13090 couriertcpd CALL select(0x7,0,0xbfbfe730,0,0xbfbfe708) 13090 couriertcpd RET select 1 13090 couriertcpd CALL write(0x6,0x8053520,0xa) 13090 couriertcpd RET write -1 errno 32 Broken pipe 13090 couriertcpd PSIG SIGPIPE SIG_DFL

--- sconnect.c.orig 2006-02-28 23:10:15.000000000 -0800 +++ sconnect.c 2006-02-28 23:14:31.000000000 -0800 @@ -62,6 +62,8 @@ if (fcntl(sockfd, F_SETFL, 0) < 0) return (-1); return (0); } + else + if (errno != EINPROGRESS) return (-1);

/* Wait for the connection to go through, until the timeout expires */