X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fsmtp%2Fserv_smtp.c;h=e0253672cae38e79b42e13c4a9d11ca67041f46c;hb=2b6008f54e8b56b79e24617f47308e469fcaca0e;hp=8f51a8dbe66994986a7036a6c031f1187f1eaf72;hpb=1112d5f6b77a2212b2f54e4d0f3a080e82c94256;p=citadel.git diff --git a/citadel/modules/smtp/serv_smtp.c b/citadel/modules/smtp/serv_smtp.c index 8f51a8dbe..e0253672c 100644 --- a/citadel/modules/smtp/serv_smtp.c +++ b/citadel/modules/smtp/serv_smtp.c @@ -203,7 +203,10 @@ void smtp_msa_greeting(void) { * LMTP is like SMTP but with some extra bonus footage added. */ void lmtp_greeting(void) { + citsmtp *sSMTP; + smtp_greeting(0); + sSMTP = SMTP; SMTP->is_lmtp = 1; } @@ -220,8 +223,10 @@ void smtp_mta_greeting(void) { * We also have an unfiltered LMTP socket that bypasses spam filters. */ void lmtp_unfiltered_greeting(void) { - citsmtp *sSMTP = SMTP; + citsmtp *sSMTP; + smtp_greeting(0); + sSMTP = SMTP; sSMTP->is_lmtp = 1; sSMTP->is_unfiltered = 1; } @@ -662,7 +667,8 @@ void smtp_rcpt(char *argbuf) { * Implements the DATA command */ void smtp_data(void) { - char *body; + StrBuf *body; + char *defbody; //TODO: remove me struct CtdlMessage *msg = NULL; long msgnum = (-1L); char nowstamp[SIZ]; @@ -685,20 +691,20 @@ void smtp_data(void) { cprintf("354 Transmit message now - terminate with '.' by itself\r\n"); datestring(nowstamp, sizeof nowstamp, time(NULL), DATESTRING_RFC822); - body = malloc(4096); + defbody = malloc(4096); - if (body != NULL) { + if (defbody != NULL) { if (sSMTP->is_lmtp && (CC->cs_UDSclientUID != -1)) { - snprintf(body, 4096, - "Received: from %s (Citadel from userid %ld)\n" - " by %s; %s\n", - sSMTP->helo_node, - (long int) CC->cs_UDSclientUID, - config.c_fqdn, - nowstamp); + snprintf(defbody, 4096, + "Received: from %s (Citadel from userid %ld)\n" + " by %s; %s\n", + sSMTP->helo_node, + (long int) CC->cs_UDSclientUID, + config.c_fqdn, + nowstamp); } else { - snprintf(body, 4096, + snprintf(defbody, 4096, "Received: from %s (%s [%s])\n" " by %s; %s\n", sSMTP->helo_node, @@ -708,14 +714,14 @@ void smtp_data(void) { nowstamp); } } - body = CtdlReadMessageBody(".", config.c_maxmsglen, body, 1, 0); + body = CtdlReadMessageBodyBuf(HKEY("."), config.c_maxmsglen, defbody, 1, NULL); if (body == NULL) { cprintf("550 Unable to save message: internal error.\r\n"); return; } CtdlLogPrintf(CTDL_DEBUG, "Converting message...\n"); - msg = convert_internet_message(body); + msg = convert_internet_message_buf(&body); /* If the user is locally authenticated, FORCE the From: header to * show up as the real sender. Yes, this violates the RFC standard, @@ -854,6 +860,10 @@ void smtp_command_loop(void) { char cmdbuf[SIZ]; citsmtp *sSMTP = SMTP; + if (sSMTP == NULL) { + CtdlLogPrintf(CTDL_EMERG, "Session SMTP data is null. WTF? We will crash now.\n"); + } + time(&CC->lastcmd); memset(cmdbuf, 0, sizeof cmdbuf); /* Clear it, just in case */ if (client_getln(cmdbuf, sizeof cmdbuf) < 1) { @@ -965,9 +975,10 @@ void smtp_try(const char *key, const char *addr, int *status, char mx_port[256]; int lp, rp; char *msgtext; - char *ptr; + const char *ptr; size_t msg_size; int scan_done; + CitContext *CCC=CC; /* Parse out the host portion of the recipient address */ @@ -977,15 +988,15 @@ void smtp_try(const char *key, const char *addr, int *status, user, node, name); /* Load the message out of the database */ - CC->redirect_buffer = malloc(SIZ); - CC->redirect_len = 0; - CC->redirect_alloc = SIZ; + CCC->redirect_buffer = malloc(SIZ); + CCC->redirect_len = 0; + CCC->redirect_alloc = SIZ; CtdlOutputMsg(msgnum, MT_RFC822, HEADERS_ALL, 0, 1, NULL, ESC_DOT); msgtext = CC->redirect_buffer; msg_size = CC->redirect_len; - CC->redirect_buffer = NULL; - CC->redirect_len = 0; - CC->redirect_alloc = 0; + CCC->redirect_buffer = NULL; + CCC->redirect_len = 0; + CCC->redirect_alloc = 0; /* If no envelope_from is supplied, extract one from the message */ if ( (envelope_from == NULL) || (IsEmptyStr(envelope_from)) ) { @@ -1092,8 +1103,12 @@ void smtp_try(const char *key, const char *addr, int *status, return; } + CCC->sReadBuf = NewStrBuf(); + CCC->sMigrateBuf = NewStrBuf(); + CCC->sPos = NULL; + /* Process the SMTP greeting from the server */ - if (ml_sock_gets(sock, buf) < 0) { + if (ml_sock_gets(&sock, buf) < 0) { *status = 4; strcpy(dsn, "Connection broken during SMTP conversation"); goto bail; @@ -1117,8 +1132,8 @@ void smtp_try(const char *key, const char *addr, int *status, /* Do a EHLO command. If it fails, try the HELO command. */ snprintf(buf, sizeof buf, "EHLO %s\r\n", config.c_fqdn); CtdlLogPrintf(CTDL_DEBUG, ">%s", buf); - sock_write(sock, buf, strlen(buf)); - if (ml_sock_gets(sock, buf) < 0) { + sock_write(&sock, buf, strlen(buf)); + if (ml_sock_gets(&sock, buf) < 0) { *status = 4; strcpy(dsn, "Connection broken during SMTP HELO"); goto bail; @@ -1127,8 +1142,8 @@ void smtp_try(const char *key, const char *addr, int *status, if (buf[0] != '2') { snprintf(buf, sizeof buf, "HELO %s\r\n", config.c_fqdn); CtdlLogPrintf(CTDL_DEBUG, ">%s", buf); - sock_write(sock, buf, strlen(buf)); - if (ml_sock_gets(sock, buf) < 0) { + sock_write(&sock, buf, strlen(buf)); + if (ml_sock_gets(&sock, buf) < 0) { *status = 4; strcpy(dsn, "Connection broken during SMTP HELO"); goto bail; @@ -1154,8 +1169,8 @@ void smtp_try(const char *key, const char *addr, int *status, CtdlEncodeBase64(encoded, buf, strlen(mx_user) + strlen(mx_user) + strlen(mx_pass) + 2, 0); snprintf(buf, sizeof buf, "AUTH PLAIN %s\r\n", encoded); CtdlLogPrintf(CTDL_DEBUG, ">%s", buf); - sock_write(sock, buf, strlen(buf)); - if (ml_sock_gets(sock, buf) < 0) { + sock_write(&sock, buf, strlen(buf)); + if (ml_sock_gets(&sock, buf) < 0) { *status = 4; strcpy(dsn, "Connection broken during SMTP AUTH"); goto bail; @@ -1178,8 +1193,8 @@ void smtp_try(const char *key, const char *addr, int *status, /* previous command succeeded, now try the MAIL FROM: command */ snprintf(buf, sizeof buf, "MAIL FROM:<%s>\r\n", envelope_from); CtdlLogPrintf(CTDL_DEBUG, ">%s", buf); - sock_write(sock, buf, strlen(buf)); - if (ml_sock_gets(sock, buf) < 0) { + sock_write(&sock, buf, strlen(buf)); + if (ml_sock_gets(&sock, buf) < 0) { *status = 4; strcpy(dsn, "Connection broken during SMTP MAIL"); goto bail; @@ -1201,8 +1216,8 @@ void smtp_try(const char *key, const char *addr, int *status, /* MAIL succeeded, now try the RCPT To: command */ snprintf(buf, sizeof buf, "RCPT TO:<%s@%s>\r\n", user, node); CtdlLogPrintf(CTDL_DEBUG, ">%s", buf); - sock_write(sock, buf, strlen(buf)); - if (ml_sock_gets(sock, buf) < 0) { + sock_write(&sock, buf, strlen(buf)); + if (ml_sock_gets(&sock, buf) < 0) { *status = 4; strcpy(dsn, "Connection broken during SMTP RCPT"); goto bail; @@ -1223,8 +1238,8 @@ void smtp_try(const char *key, const char *addr, int *status, /* RCPT succeeded, now try the DATA command */ CtdlLogPrintf(CTDL_DEBUG, ">DATA\n"); - sock_write(sock, "DATA\r\n", 6); - if (ml_sock_gets(sock, buf) < 0) { + sock_write(&sock, "DATA\r\n", 6); + if (ml_sock_gets(&sock, buf) < 0) { *status = 4; strcpy(dsn, "Connection broken during SMTP DATA"); goto bail; @@ -1244,16 +1259,16 @@ void smtp_try(const char *key, const char *addr, int *status, } /* If we reach this point, the server is expecting data.*/ - sock_write(sock, msgtext, msg_size); + sock_write(&sock, msgtext, msg_size); if (msgtext[msg_size-1] != 10) { CtdlLogPrintf(CTDL_WARNING, "Possible problem: message did not " "correctly terminate. (expecting 0x10, got 0x%02x)\n", buf[msg_size-1]); - sock_write(sock, "\r\n", 2); + sock_write(&sock, "\r\n", 2); } - sock_write(sock, ".\r\n", 3); - if (ml_sock_gets(sock, buf) < 0) { + sock_write(&sock, ".\r\n", 3); + if (ml_sock_gets(&sock, buf) < 0) { *status = 4; strcpy(dsn, "Connection broken during SMTP message transmit"); goto bail; @@ -1277,14 +1292,17 @@ void smtp_try(const char *key, const char *addr, int *status, *status = 2; CtdlLogPrintf(CTDL_DEBUG, ">QUIT\n"); - sock_write(sock, "QUIT\r\n", 6); - ml_sock_gets(sock, buf); + sock_write(&sock, "QUIT\r\n", 6); + ml_sock_gets(&sock, buf); CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf); CtdlLogPrintf(CTDL_INFO, "SMTP client: delivery to <%s> @ <%s> (%s) succeeded\n", user, node, name); bail: free(msgtext); - sock_close(sock); + FreeStrBuf(&CCC->sReadBuf); + FreeStrBuf(&CCC->sMigrateBuf); + if (sock != -1) + sock_close(sock); /* Write something to the syslog (which may or may not be where the * rest of the Citadel logs are going; some sysadmins want LOG_MAIL).