X-Git-Url: http://dspam.git.sourceforge.net/git/gitweb.cgi?p=dspam%2Fdspam;a=blobdiff_plain;f=src%2Fclient.c;h=1b5dcf4849110999fc384a024db1db1234134cfe;hp=3e2d1f4ca634e8ae4c287598846970090d0ceab8;hb=4cc68027e730a372002448c5e798d627d6d836e8;hpb=5f0e08c0286047c1b1aeb21211ad8c0c0e5cbd89 diff --git a/src/client.c b/src/client.c index 3e2d1f4..1b5dcf4 100644 --- a/src/client.c +++ b/src/client.c @@ -1,4 +1,4 @@ -/* $Id: client.c,v 1.685 2010/05/13 22:38:45 sbajic Exp $ */ +/* $Id: client.c,v 1.689 2011/03/02 21:16:28 sbajic Exp $ */ /* DSPAM @@ -140,15 +140,56 @@ int client_process(AGENT_CTX *ATX, buffer *message) { i = 0; msglen = strlen(message->data); while(idata+i, msglen - i, 0); - if (r <= 0) { - STATUS(ERR_CLIENT_SEND_FAILED); - goto BAIL; + int r; + int t; + int buflen; + + /* + * fill buf with partial msg, replacing \n with \r\n + * and do dot stuffing, if needed. + */ + buflen = 0; + while ((size_t)buflen < (sizeof(buf) - 4) && i < msglen) { + if (i > 0) { + if (message->data[i] == '\n') { + /* only replace \n and not \r\n */ + if (message->data[i - 1] != '\r') { + buf[buflen] = '\r'; + buflen++; + } + /* take care of dot stuffing \n */ + if (message->data[i + 1] && message->data[i + 1] == '.') { + buf[buflen] = '\n'; + buflen++; + buf[buflen] = '.'; + buflen++; + buf[buflen] = '.'; + buflen++; + i += 2; + continue; + } + } + } + + buf[buflen] = message->data[i]; + buflen++; + i++; + } + + /* send buf */ + t = 0; + while (t < buflen) { + r = send(TTX.sockfd, buf+t, buflen - t, 0); + if (r <= 0) { + LOG(LOG_ERR, ERR_CLIENT_SEND_FAILED); + STATUS(ERR_CLIENT_SEND_FAILED); + goto BAIL; + } + t += r; } - i += r; } - if (message->data[strlen(message->data)-1]!= '\n') { + if (message->data[msglen-1]!= '\n') { if (send_socket(&TTX, "")<=0) { STATUS(ERR_CLIENT_SEND_FAILED); goto BAIL; @@ -685,6 +726,7 @@ int deliver_socket(AGENT_CTX *ATX, const char *msg, int proto) { int buflen; char *inp; int i; + int size_extension = 0; err[0] = 0; @@ -720,9 +762,50 @@ int deliver_socket(AGENT_CTX *ATX, const char *msg, int proto) { goto BAIL; } - /* MAIL FROM */ + /* Check for SIZE extension */ - inp = client_expect(&TTX, LMTP_OK, err, sizeof(err)); + if (proto == DDP_LMTP) { + char *dup, *ptr, *ptrptr; + inp = client_getline(&TTX, 300); + while(inp != NULL) { + code = 0; + dup = strdup(inp); + if (!dup) { + free(inp); + LOG(LOG_CRIT, ERR_MEM_ALLOC); + LOG(LOG_ERR, ERR_CLIENT_INVALID_RESPONSE, "LHLO", ERR_MEM_ALLOC); + STATUS("LHLO: %s", ERR_MEM_ALLOC); + goto QUIT; + } + if (!strcmp(dup, "250-SIZE") || (!strncmp(dup, "250-SIZE", 8) && strlen(dup)>=8 && isspace(dup[8]))) { + free(inp); + free(dup); + size_extension = 1; + inp = client_expect(&TTX, LMTP_OK, err, sizeof(err)); + break; + } else if (strncmp(dup, "250-", 4)) { + ptr = strtok_r(dup, " ", &ptrptr); + if (ptr) + code = atoi(ptr); + if (code == LMTP_OK) { + ptr = strtok_r(NULL, " ", &ptrptr); + if (ptr && !strcmp(ptr, "SIZE")) + size_extension = 1; + } + free(dup); + if (code == LMTP_OK) { + err[0] = 0; + break; + } + LOG(LOG_WARNING, ERR_CLIENT_RESPONSE_CODE, code, inp); + } + strlcpy(err, inp, sizeof(err)); + free(inp); + inp = client_getline(&TTX, 300); + } + } else { + inp = client_expect(&TTX, LMTP_OK, err, sizeof(err)); + } if (inp == NULL) { LOG(LOG_ERR, ERR_CLIENT_INVALID_RESPONSE, (proto == DDP_LMTP) ? "LHLO" : "HELO", err); @@ -731,8 +814,10 @@ int deliver_socket(AGENT_CTX *ATX, const char *msg, int proto) { } free(inp); - if (proto == DDP_LMTP) { - snprintf(buf, sizeof(buf), "MAIL FROM:<%s> SIZE=%ld", + /* MAIL FROM */ + + if (proto == DDP_LMTP && size_extension == 1) { + snprintf(buf, sizeof(buf), "MAIL FROM:<%s> SIZE=%ld", ATX->mailfrom, (long) strlen(msg)); } else { snprintf(buf, sizeof(buf), "MAIL FROM:<%s>", ATX->mailfrom);