]> code.citadel.org Git - citadel.git/blobdiff - citadel/modules/smtp/serv_smtp.c
Eliminated unnecessary complexity by removing support
[citadel.git] / citadel / modules / smtp / serv_smtp.c
index 960e105d0816164602b6a3182c861439a5179105..dd336ba2bd625193957ebac895f0f1d2e67c90d3 100644 (file)
@@ -7,12 +7,10 @@
  * RFC  821 - Simple Mail Transfer Protocol
  * RFC  876 - Survey of SMTP Implementations
  * RFC 1047 - Duplicate messages and SMTP
- * RFC 1854 - command pipelining
+ * RFC 1652 - 8 bit MIME
  * RFC 1869 - Extended Simple Mail Transfer Protocol
  * RFC 1870 - SMTP Service Extension for Message Size Declaration
- * RFC 1893 - Enhanced Mail System Status Codes
  * RFC 2033 - Local Mail Transfer Protocol
- * RFC 2034 - SMTP Service Extension for Returning Enhanced Error Codes
  * RFC 2197 - SMTP Service Extension for Command Pipelining
  * RFC 2476 - Message Submission
  * RFC 2487 - SMTP Service Extension for Secure SMTP over TLS
@@ -55,6 +53,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <libcitadel.h>
 #include "citadel.h"
 #include "server.h"
 #include "citserver.h"
@@ -66,7 +65,6 @@
 #include "policy.h"
 #include "database.h"
 #include "msgbase.h"
-#include "tools.h"
 #include "internet_addressing.h"
 #include "genstamp.h"
 #include "domain.h"
@@ -105,7 +103,7 @@ enum {                              /* Command states for login authentication */
        smtp_plain
 };
 
-#define SMTP           CC->SMTP
+#define SMTP           ((struct citsmtp *)CC->session_specific_data)
 
 
 int run_queue_now = 0; /* Set to 1 to ignore SMTP send retry times */
@@ -127,7 +125,7 @@ void smtp_greeting(int is_msa)
        strcpy(CC->cs_clientname, "SMTP session");
        CC->internal_pgm = 1;
        CC->cs_flags |= CS_STEALTH;
-       SMTP = malloc(sizeof(struct citsmtp));
+       CC->session_specific_data = malloc(sizeof(struct citsmtp));
        memset(SMTP, 0, sizeof(struct citsmtp));
        SMTP->is_msa = is_msa;
 
@@ -166,7 +164,9 @@ void smtp_greeting(int is_msa)
  */
 void smtps_greeting(void) {
        CtdlModuleStartCryptoMsgs(NULL, NULL, NULL);
+#ifdef HAVE_OPENSSL
        if (!CC->redirect_ssl) CC->kill_me = 1;         /* kill session if no crypto */
+#endif
        smtp_greeting(0);
 }
 
@@ -210,7 +210,7 @@ void lmtp_unfiltered_greeting(void) {
  * Login greeting common to all auth methods
  */
 void smtp_auth_greeting(void) {
-               cprintf("235 2.0.0 Hello, %s\r\n", CC->user.fullname);
+               cprintf("235 Hello, %s\r\n", CC->user.fullname);
                lprintf(CTDL_NOTICE, "SMTP authenticated %s\n", CC->user.fullname);
                CC->internal_pgm = 0;
                CC->cs_flags &= ~CS_STEALTH;
@@ -258,29 +258,21 @@ void smtp_hello(char *argbuf, int which_command) {
                cprintf("250-SIZE %ld\r\n", config.c_maxmsglen);
 
 #ifdef HAVE_OPENSSL
-
-               /* Only offer the PIPELINING command if TLS is inactive,
-                * because of flow control issues.  Also, avoid offering TLS
-                * if TLS is already active.  Finally, we only offer TLS on
+               /*
+                * Offer TLS, but only if TLS is not already active.
+                * Furthermore, only offer TLS when running on
                 * the SMTP-MSA port, not on the SMTP-MTA port, due to
                 * questionable reliability of TLS in certain sending MTA's.
                 */
                if ( (!CC->redirect_ssl) && (SMTP->is_msa) ) {
-                       cprintf("250-PIPELINING\r\n");
                        cprintf("250-STARTTLS\r\n");
                }
-
-#else  /* HAVE_OPENSSL */
-
-               /* Non SSL enabled server, so always offer PIPELINING. */
-               cprintf("250-PIPELINING\r\n");
-
 #endif /* HAVE_OPENSSL */
 
-               cprintf("250-AUTH LOGIN PLAIN\r\n");
-               cprintf("250-AUTH=LOGIN PLAIN\r\n");
-
-               cprintf("250 ENHANCEDSTATUSCODES\r\n");
+               cprintf("250-AUTH LOGIN PLAIN\r\n"
+                       "250-AUTH=LOGIN PLAIN\r\n"
+                       "250 8BITMIME\r\n"
+               );
        }
 }
 
@@ -314,12 +306,12 @@ void smtp_get_user(char *argbuf) {
        CtdlDecodeBase64(username, argbuf, SIZ);
        /* lprintf(CTDL_DEBUG, "Trying <%s>\n", username); */
        if (CtdlLoginExistingUser(NULL, username) == login_ok) {
-               CtdlEncodeBase64(buf, "Password:", 9);
+               CtdlEncodeBase64(buf, "Password:", 9, 0);
                cprintf("334 %s\r\n", buf);
                SMTP->command_state = smtp_password;
        }
        else {
-               cprintf("500 5.7.0 No such user.\r\n");
+               cprintf("500 No such user.\r\n");
                SMTP->command_state = smtp_command;
        }
 }
@@ -337,7 +329,7 @@ void smtp_get_pass(char *argbuf) {
                smtp_auth_greeting();
        }
        else {
-               cprintf("535 5.7.0 Authentication failed.\r\n");
+               cprintf("535 Authentication failed.\r\n");
        }
        SMTP->command_state = smtp_command;
 }
@@ -373,7 +365,7 @@ void smtp_try_plain(char *encoded_authstring) {
                        return;
                }
        }
-       cprintf("504 5.7.4 Authentication failed.\r\n");
+       cprintf("504 Authentication failed.\r\n");
 }
 
 
@@ -386,7 +378,7 @@ void smtp_auth(char *argbuf) {
        char encoded_authstring[1024];
 
        if (CC->logged_in) {
-               cprintf("504 5.7.4 Already logged in.\r\n");
+               cprintf("504 Already logged in.\r\n");
                return;
        }
 
@@ -397,7 +389,7 @@ void smtp_auth(char *argbuf) {
                        smtp_get_user(&argbuf[6]);
                }
                else {
-                       CtdlEncodeBase64(username_prompt, "Username:", 9);
+                       CtdlEncodeBase64(username_prompt, "Username:", 9, 0);
                        cprintf("334 %s\r\n", username_prompt);
                        SMTP->command_state = smtp_user;
                }
@@ -418,7 +410,7 @@ void smtp_auth(char *argbuf) {
        }
 
        if (strncasecmp(method, "login", 5) ) {
-               cprintf("504 5.7.4 Unknown authentication method.\r\n");
+               cprintf("504 Unknown authentication method.\r\n");
                return;
        }
 
@@ -465,7 +457,7 @@ void smtp_rset(int do_response) {
        SMTP->is_unfiltered = is_unfiltered;
 
        if (do_response) {
-               cprintf("250 2.0.0 Zap!\r\n");
+               cprintf("250 Zap!\r\n");
        }
 }
 
@@ -481,7 +473,13 @@ void smtp_data_clear(void) {
        SMTP->message_originated_locally = 0;
 }
 
+const char *smtp_get_Recipients(void)
+{
+       if (SMTP == NULL)
+               return NULL;
+       else return SMTP->from;
 
+}
 
 /*
  * Implements the "MAIL From:" command
@@ -492,12 +490,12 @@ void smtp_mail(char *argbuf) {
        char name[SIZ];
 
        if (!IsEmptyStr(SMTP->from)) {
-               cprintf("503 5.1.0 Only one sender permitted\r\n");
+               cprintf("503 Only one sender permitted\r\n");
                return;
        }
 
        if (strncasecmp(argbuf, "From:", 5)) {
-               cprintf("501 5.1.7 Syntax error\r\n");
+               cprintf("501 Syntax error\r\n");
                return;
        }
 
@@ -522,7 +520,7 @@ void smtp_mail(char *argbuf) {
         */
        if (CC->logged_in) {
                safestrncpy(SMTP->from, CC->cs_inet_email, sizeof SMTP->from);
-               cprintf("250 2.1.0 Sender ok <%s>\r\n", SMTP->from);
+               cprintf("250 Sender ok <%s>\r\n", SMTP->from);
                SMTP->message_originated_locally = 1;
                return;
        }
@@ -537,15 +535,13 @@ void smtp_mail(char *argbuf) {
        else if (config.c_allow_spoofing == 0) {
                process_rfc822_addr(SMTP->from, user, node, name);
                if (CtdlHostAlias(node) != hostalias_nomatch) {
-                       cprintf("550 5.7.1 "
-                               "You must log in to send mail from %s\r\n",
-                               node);
+                       cprintf("550 You must log in to send mail from %s\r\n", node);
                        strcpy(SMTP->from, "");
                        return;
                }
        }
 
-       cprintf("250 2.0.0 Sender ok\r\n");
+       cprintf("250 Sender ok\r\n");
 }
 
 
@@ -559,18 +555,17 @@ void smtp_rcpt(char *argbuf) {
        struct recptypes *valid = NULL;
 
        if (IsEmptyStr(SMTP->from)) {
-               cprintf("503 5.5.1 Need MAIL before RCPT\r\n");
+               cprintf("503 Need MAIL before RCPT\r\n");
                return;
        }
 
        if (strncasecmp(argbuf, "To:", 3)) {
-               cprintf("501 5.1.7 Syntax error\r\n");
+               cprintf("501 Syntax error\r\n");
                return;
        }
 
        if ( (SMTP->is_msa) && (!CC->logged_in) ) {
-               cprintf("550 5.1.8 "
-                       "You must log in to send mail on this port.\r\n");
+               cprintf("550 You must log in to send mail on this port.\r\n");
                strcpy(SMTP->from, "");
                return;
        }
@@ -580,7 +575,7 @@ void smtp_rcpt(char *argbuf) {
        stripallbut(recp, '<', '>');
 
        if ( (strlen(recp) + strlen(SMTP->recipients) + 1 ) >= SIZ) {
-               cprintf("452 4.5.3 Too many recipients\r\n");
+               cprintf("452 Too many recipients\r\n");
                return;
        }
 
@@ -596,9 +591,11 @@ void smtp_rcpt(char *argbuf) {
                }
        }
 
-       valid = validate_recipients(recp);
+       valid = validate_recipients(recp, 
+                                   smtp_get_Recipients (),
+                                   (CC->logged_in)? POST_LOGGED_IN:POST_EXTERNAL);
        if (valid->num_error != 0) {
-               cprintf("599 5.1.1 Error: %s\r\n", valid->errormsg);
+               cprintf("599 Error: %s\r\n", valid->errormsg);
                free_recipients(valid);
                return;
        }
@@ -606,7 +603,7 @@ void smtp_rcpt(char *argbuf) {
        if (valid->num_internet > 0) {
                if (CC->logged_in) {
                         if (CtdlCheckInternetMailPermission(&CC->user)==0) {
-                               cprintf("551 5.7.1 <%s> - you do not have permission to send Internet mail\r\n", recp);
+                               cprintf("551 <%s> - you do not have permission to send Internet mail\r\n", recp);
                                 free_recipients(valid);
                                 return;
                         }
@@ -616,13 +613,13 @@ void smtp_rcpt(char *argbuf) {
        if (valid->num_internet > 0) {
                if ( (SMTP->message_originated_locally == 0)
                   && (SMTP->is_lmtp == 0) ) {
-                       cprintf("551 5.7.1 <%s> - relaying denied\r\n", recp);
+                       cprintf("551 <%s> - relaying denied\r\n", recp);
                        free_recipients(valid);
                        return;
                }
        }
 
-       cprintf("250 2.1.5 RCPT ok <%s>\r\n", recp);
+       cprintf("250 RCPT ok <%s>\r\n", recp);
        if (!IsEmptyStr(SMTP->recipients)) {
                strcat(SMTP->recipients, ",");
        }
@@ -650,12 +647,12 @@ void smtp_data(void) {
        char result[SIZ];
 
        if (IsEmptyStr(SMTP->from)) {
-               cprintf("503 5.5.1 Need MAIL command first.\r\n");
+               cprintf("503 Need MAIL command first.\r\n");
                return;
        }
 
        if (SMTP->number_of_recipients < 1) {
-               cprintf("503 5.5.1 Need RCPT command first.\r\n");
+               cprintf("503 Need RCPT command first.\r\n");
                return;
        }
 
@@ -673,10 +670,9 @@ void smtp_data(void) {
                        config.c_fqdn,
                        nowstamp);
        
-       body = CtdlReadMessageBody(".", config.c_maxmsglen, body, 1);
+       body = CtdlReadMessageBody(".", config.c_maxmsglen, body, 1, 0);
        if (body == NULL) {
-               cprintf("550 5.6.5 "
-                       "Unable to save message: internal error.\r\n");
+               cprintf("550 Unable to save message: internal error.\r\n");
                return;
        }
 
@@ -719,7 +715,9 @@ void smtp_data(void) {
        msg->cm_fields['V'] = strdup(SMTP->recipients);
 
        /* Submit the message into the Citadel system. */
-       valid = validate_recipients(SMTP->recipients);
+       valid = validate_recipients(SMTP->recipients, 
+                                   smtp_get_Recipients (),
+                                   (CC->logged_in)? POST_LOGGED_IN:POST_EXTERNAL);
 
        /* If there are modules that want to scan this message before final
         * submission (such as virus checkers or spam filters), call them now
@@ -889,7 +887,7 @@ void smtp_command_loop(void) {
        }
 #endif
        else {
-               cprintf("502 5.0.0 I'm afraid I can't do that.\r\n");
+               cprintf("502 I'm afraid I can't do that.\r\n");
        }
 
 
@@ -1109,7 +1107,7 @@ void smtp_try(const char *key, const char *addr, int *status,
        if (!IsEmptyStr(mx_user)) {
                char encoded[1024];
                sprintf(buf, "%s%c%s%c%s", mx_user, '\0', mx_user, '\0', mx_pass);
-               CtdlEncodeBase64(encoded, buf, strlen(mx_user) + strlen(mx_user) + strlen(mx_pass) + 2);
+               CtdlEncodeBase64(encoded, buf, strlen(mx_user) + strlen(mx_user) + strlen(mx_pass) + 2, 0);
                snprintf(buf, sizeof buf, "AUTH PLAIN %s\r\n", encoded);
                lprintf(CTDL_DEBUG, ">%s", buf);
                sock_write(sock, buf, strlen(buf));
@@ -1435,7 +1433,7 @@ void smtp_do_bounce(char *instr) {
                }
 
                /* Can we deliver the bounce to the original sender? */
-               valid = validate_recipients(bounceto);
+               valid = validate_recipients(bounceto, smtp_get_Recipients (), 0);
                if (valid != NULL) {
                        if (valid->num_error == 0) {
                                CtdlSubmitMsg(bmsg, valid, "");
@@ -1812,48 +1810,51 @@ const char *CitadelServiceSMTP_LMTP_UNF="LMTP-UnF";
 
 CTDL_MODULE_INIT(smtp)
 {
-       CtdlRegisterServiceHook(config.c_smtp_port,     /* SMTP MTA */
-                               NULL,
-                               smtp_mta_greeting,
-                               smtp_command_loop,
-                               NULL, 
-                               CitadelServiceSMTP_MTA);
+       if (!threading)
+       {
+               CtdlRegisterServiceHook(config.c_smtp_port,     /* SMTP MTA */
+                                       NULL,
+                                       smtp_mta_greeting,
+                                       smtp_command_loop,
+                                       NULL, 
+                                       CitadelServiceSMTP_MTA);
 
 #ifdef HAVE_OPENSSL
-       CtdlRegisterServiceHook(config.c_smtps_port,
-                               NULL,
-                               smtps_greeting,
-                               smtp_command_loop,
-                               NULL,
-                               CitadelServiceSMTPS_MTA);
+               CtdlRegisterServiceHook(config.c_smtps_port,
+                                       NULL,
+                                       smtps_greeting,
+                                       smtp_command_loop,
+                                       NULL,
+                                       CitadelServiceSMTPS_MTA);
 #endif
 
-       CtdlRegisterServiceHook(config.c_msa_port,      /* SMTP MSA */
-                               NULL,
-                               smtp_msa_greeting,
-                               smtp_command_loop,
-                               NULL,
-                               CitadelServiceSMTP_MSA);
-
-       CtdlRegisterServiceHook(0,                      /* local LMTP */
-                               file_lmtp_socket,
-                               lmtp_greeting,
-                               smtp_command_loop,
-                               NULL,
-                               CitadelServiceSMTP_LMTP);
-
-       CtdlRegisterServiceHook(0,                      /* local LMTP */
-                               file_lmtp_unfiltered_socket,
-                               lmtp_unfiltered_greeting,
-                               smtp_command_loop,
-                               NULL,
-                               CitadelServiceSMTP_LMTP_UNF);
-
-       smtp_init_spoolout();
-       CtdlRegisterSessionHook(smtp_do_queue, EVT_TIMER);
-       CtdlRegisterSessionHook(smtp_cleanup_function, EVT_STOP);
-       CtdlRegisterProtoHook(cmd_smtp, "SMTP", "SMTP utility commands");
-
+               CtdlRegisterServiceHook(config.c_msa_port,      /* SMTP MSA */
+                                       NULL,
+                                       smtp_msa_greeting,
+                                       smtp_command_loop,
+                                       NULL,
+                                       CitadelServiceSMTP_MSA);
+
+               CtdlRegisterServiceHook(0,                      /* local LMTP */
+                                       file_lmtp_socket,
+                                       lmtp_greeting,
+                                       smtp_command_loop,
+                                       NULL,
+                                       CitadelServiceSMTP_LMTP);
+
+               CtdlRegisterServiceHook(0,                      /* local LMTP */
+                                       file_lmtp_unfiltered_socket,
+                                       lmtp_unfiltered_greeting,
+                                       smtp_command_loop,
+                                       NULL,
+                                       CitadelServiceSMTP_LMTP_UNF);
+
+               smtp_init_spoolout();
+               CtdlRegisterSessionHook(smtp_do_queue, EVT_TIMER);
+               CtdlRegisterSessionHook(smtp_cleanup_function, EVT_STOP);
+               CtdlRegisterProtoHook(cmd_smtp, "SMTP", "SMTP utility commands");
+       }
+       
        /* return our Subversion id for the Log */
        return "$Id$";
 }