554 SMTP synchronization error with exim4 and my code

boatcoder picture boatcoder · Feb 15, 2010 · Viewed 20.1k times · Source

I have run headfirst into this reject error from exim4:

2010-02-15 01:46:05 SMTP protocol synchronization error (input sent without waiting for greeting): rejected connection from H=ender [192.168.20.49] input="HELO 192.168.20.49\r\n"

I have modified my exim4 config to not enforce sync, like so:

 smtp_enforce_sync='false'
 acl_smtp_connect = nosync nosync:
         control = no_enforce_sync
         accept

But that doesn't seem to matter. What makes less sense to me is why I'm getting the 554 in the first place. I send a HELO, I wait for a response, and somehow in the midst of that, I manage to generate the "554 Error"

What am I doing wrong in the code below, that makes this fail 99% of the time (yes, it has worked twice). Yes, the socket is blocking, I hang in recv for ~5 seconds waiting for the rejection. On the 2 times when it has worked, it didn't pause at all.

I've tried sending EHLO instead of HELO, no better luck. I've even had grief getting a telnet session to connect and say HELO. However, i can use python smtp (from another machine) to send emails just fine against this same server!

        hSocket = _connectServerSocket(server, port);    
    if (hSocket != INVALID_SOCKET) {        
        BYTE        sReceiveBuffer[4096];
        int            iLength = 0;
        int            iEnd = 0;
        char        buf[4096];

        strcpy(buf, "HELO ");
        strcat(buf, "192.168.20.49");
        strcat(buf, "\r\n");
        printf("%s", buf);
        if (send(hSocket, (LPSTR)buf, strlen(buf), NO_FLAGS) == SOCKET_ERROR) {
            printf("Socket send error: %d\r\n", WSAGetLastError());    
            return (false);
        }
        iLength = recv(hSocket, 
                       (LPSTR)sReceiveBuffer+iEnd,sizeof(sReceiveBuffer)-iEnd, 
                        NO_FLAGS);
        iEnd += iLength;
        sReceiveBuffer[iEnd] = '\0';

Answer

Anders Lindahl picture Anders Lindahl · Feb 15, 2010

Your code should wait for a 220 line from the smtp server before sending the HELO message. See section 3.1 of RFC 2821. That is probably what the Python library does.

There should be several free libraries available that can help you with this, for example libsmtp. Consider spending time on learning one of these instead of patching your own solution (unless your project is to write your own mail solution).