]> code.citadel.org Git - citadel.git/blobdiff - citadel/serv_smtp.c
Removed the VRFY and EXPN commands from our SMTP server
[citadel.git] / citadel / serv_smtp.c
index c52fca5864cd33ba9372d036f403e0c08854dff5..a9e46f681b92a7e8a0fe79cb38c19fb58a382116 100644 (file)
@@ -20,6 +20,9 @@
  * RFC 2821 - Simple Mail Transfer Protocol
  * RFC 2822 - Internet Message Format
  * RFC 2920 - SMTP Service Extension for Command Pipelining
+ *  
+ * The VRFY and EXPN commands have been removed from this implementation
+ * because nobody uses these commands anymore, except for spammers.
  *
  */
 
@@ -86,9 +89,6 @@
 struct citsmtp {               /* Information about the current session */
        int command_state;
        char helo_node[SIZ];
-       struct ctdluser vrfy_buffer;
-       int vrfy_count;
-       char vrfy_match[SIZ];
        char from[SIZ];
        char recipients[SIZ];
        int number_of_recipients;
@@ -106,14 +106,7 @@ enum {                             /* Command states for login authentication */
        smtp_plain
 };
 
-enum {                         /* Delivery modes */
-       smtp_deliver_local,
-       smtp_deliver_remote
-};
-
 #define SMTP           CC->SMTP
-#define SMTP_RECPS     CC->SMTP_RECPS
-#define SMTP_ROOMS     CC->SMTP_ROOMS
 
 
 int run_queue_now = 0; /* Set to 1 to ignore SMTP send retry times */
@@ -136,11 +129,7 @@ void smtp_greeting(int is_msa)
        CC->internal_pgm = 1;
        CC->cs_flags |= CS_STEALTH;
        SMTP = malloc(sizeof(struct citsmtp));
-       SMTP_RECPS = malloc(SIZ);
-       SMTP_ROOMS = malloc(SIZ);
        memset(SMTP, 0, sizeof(struct citsmtp));
-       memset(SMTP_RECPS, 0, SIZ);
-       memset(SMTP_ROOMS, 0, SIZ);
        SMTP->is_msa = is_msa;
 
        /* If this config option is set, reject connections from problem
@@ -150,7 +139,7 @@ void smtp_greeting(int is_msa)
                if (rbl_check(message_to_spammer)) {
                        cprintf("550 %s\r\n", message_to_spammer);
                        CC->kill_me = 1;
-                       /* no need to free(valid), it's not allocated yet */
+                       /* no need to free_recipients(valid), it's not allocated yet */
                        return;
                }
        }
@@ -162,10 +151,13 @@ void smtp_greeting(int is_msa)
                        config.c_maxsessions
                );
                CC->kill_me = 1;
-               /* no need to free(valid), it's not allocated yet */
+               /* no need to free_recipients(valid), it's not allocated yet */
                return;
        }
 
+       /* Note: the FQDN *must* appear as the first thing after the 220 code.
+        * Some clients (including citmail.c) depend on it being there.
+        */
        cprintf("220 %s ESMTP Citadel server ready.\r\n", config.c_fqdn);
 }
 
@@ -303,7 +295,6 @@ void smtp_help(void) {
        cprintf("214-Commands accepted:\r\n");
        cprintf("214-    DATA\r\n");
        cprintf("214-    EHLO\r\n");
-       cprintf("214-    EXPN\r\n");
        cprintf("214-    HELO\r\n");
        cprintf("214-    HELP\r\n");
        cprintf("214-    MAIL\r\n");
@@ -311,7 +302,6 @@ void smtp_help(void) {
        cprintf("214-    QUIT\r\n");
        cprintf("214-    RCPT\r\n");
        cprintf("214-    RSET\r\n");
-       cprintf("214-    VRFY\r\n");
        cprintf("214     \r\n");
 }
 
@@ -430,86 +420,6 @@ void smtp_auth(char *argbuf) {
 }
 
 
-/*
- * Back end for smtp_vrfy() command
- */
-void smtp_vrfy_backend(struct ctdluser *us, void *data) {
-
-       if (!fuzzy_match(us, SMTP->vrfy_match)) {
-               ++SMTP->vrfy_count;
-               memcpy(&SMTP->vrfy_buffer, us, sizeof(struct ctdluser));
-       }
-}
-
-
-/* 
- * Implements the VRFY (verify user name) command.
- * Performs fuzzy match on full user names.
- */
-void smtp_vrfy(char *argbuf) {
-       SMTP->vrfy_count = 0;
-       strcpy(SMTP->vrfy_match, argbuf);
-       ForEachUser(smtp_vrfy_backend, NULL);
-
-       if (SMTP->vrfy_count < 1) {
-               cprintf("550 5.1.1 String does not match anything.\r\n");
-       }
-       else if (SMTP->vrfy_count == 1) {
-               cprintf("250 %s <cit%ld@%s>\r\n",
-                       SMTP->vrfy_buffer.fullname,
-                       SMTP->vrfy_buffer.usernum,
-                       config.c_fqdn);
-       }
-       else if (SMTP->vrfy_count > 1) {
-               cprintf("553 5.1.4 Request ambiguous: %d users matched.\r\n",
-                       SMTP->vrfy_count);
-       }
-
-}
-
-
-
-/*
- * Back end for smtp_expn() command
- */
-void smtp_expn_backend(struct ctdluser *us, void *data) {
-
-       if (!fuzzy_match(us, SMTP->vrfy_match)) {
-
-               if (SMTP->vrfy_count >= 1) {
-                       cprintf("250-%s <cit%ld@%s>\r\n",
-                               SMTP->vrfy_buffer.fullname,
-                               SMTP->vrfy_buffer.usernum,
-                               config.c_fqdn);
-               }
-
-               ++SMTP->vrfy_count;
-               memcpy(&SMTP->vrfy_buffer, us, sizeof(struct ctdluser));
-       }
-}
-
-
-/* 
- * Implements the EXPN (expand user name) command.
- * Performs fuzzy match on full user names.
- */
-void smtp_expn(char *argbuf) {
-       SMTP->vrfy_count = 0;
-       strcpy(SMTP->vrfy_match, argbuf);
-       ForEachUser(smtp_expn_backend, NULL);
-
-       if (SMTP->vrfy_count < 1) {
-               cprintf("550 5.1.1 String does not match anything.\r\n");
-       }
-       else if (SMTP->vrfy_count >= 1) {
-               cprintf("250 %s <cit%ld@%s>\r\n",
-                       SMTP->vrfy_buffer.fullname,
-                       SMTP->vrfy_buffer.usernum,
-                       config.c_fqdn);
-       }
-}
-
-
 /*
  * Implements the RSET (reset state) command.
  * Currently this just zeroes out the state buffer.  If pointers to data
@@ -675,7 +585,7 @@ void smtp_rcpt(char *argbuf) {
                if (config.c_rbl_at_greeting == 0) {    /* Don't RBL again if we already did it */
                        if (rbl_check(message_to_spammer)) {
                                cprintf("550 %s\r\n", message_to_spammer);
-                               /* no need to free(valid), it's not allocated yet */
+                               /* no need to free_recipients(valid), it's not allocated yet */
                                return;
                        }
                }
@@ -684,7 +594,7 @@ void smtp_rcpt(char *argbuf) {
        valid = validate_recipients(recp);
        if (valid->num_error != 0) {
                cprintf("599 5.1.1 Error: %s\r\n", valid->errormsg);
-               free(valid);
+               free_recipients(valid);
                return;
        }
 
@@ -692,7 +602,7 @@ void smtp_rcpt(char *argbuf) {
                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);
-                                free(valid);
+                                free_recipients(valid);
                                 return;
                         }
                 }
@@ -702,7 +612,7 @@ void smtp_rcpt(char *argbuf) {
                if ( (SMTP->message_originated_locally == 0)
                   && (SMTP->is_lmtp == 0) ) {
                        cprintf("551 5.7.1 <%s> - relaying denied\r\n", recp);
-                       free(valid);
+                       free_recipients(valid);
                        return;
                }
        }
@@ -714,7 +624,7 @@ void smtp_rcpt(char *argbuf) {
        strcat(SMTP->recipients, recp);
        SMTP->number_of_recipients += 1;
        if (valid != NULL) 
-               free(valid);
+               free_recipients(valid);
 }
 
 
@@ -868,7 +778,7 @@ void smtp_data(void) {
 
        /* Clean up */
        CtdlFreeMessage(msg);
-       free(valid);
+       free_recipients(valid);
        smtp_data_clear();      /* clear out the buffers now */
 }
 
@@ -932,10 +842,6 @@ void smtp_command_loop(void) {
                smtp_data();
        }
 
-       else if (!strncasecmp(cmdbuf, "EXPN", 4)) {
-               smtp_expn(&cmdbuf[5]);
-       }
-
        else if (!strncasecmp(cmdbuf, "HELO", 4)) {
                smtp_hello(&cmdbuf[5], 0);
        }
@@ -978,10 +884,6 @@ void smtp_command_loop(void) {
                smtp_starttls();
        }
 #endif
-       else if (!strncasecmp(cmdbuf, "VRFY", 4)) {
-               smtp_vrfy(&cmdbuf[5]);
-       }
-
        else {
                cprintf("502 5.0.0 I'm afraid I can't do that.\r\n");
        }
@@ -1201,9 +1103,10 @@ void smtp_try(const char *key, const char *addr, int *status,
 
        /* Do an AUTH command if necessary */
        if (strlen(mx_user) > 0) {
+               char encoded[1024];
                sprintf(buf, "%s%c%s%c%s", mx_user, '\0', mx_user, '\0', mx_pass);
-               CtdlEncodeBase64(mailfrom, buf, strlen(mx_user) + strlen(mx_user) + strlen(mx_pass) + 2);
-               snprintf(buf, sizeof buf, "AUTH PLAIN %s\r\n", mailfrom);
+               CtdlEncodeBase64(encoded, buf, strlen(mx_user) + strlen(mx_user) + strlen(mx_pass) + 2);
+               snprintf(buf, sizeof buf, "AUTH PLAIN %s\r\n", encoded);
                lprintf(CTDL_DEBUG, ">%s", buf);
                sock_write(sock, buf, strlen(buf));
                if (ml_sock_gets(sock, buf) < 0) {
@@ -1460,12 +1363,7 @@ void smtp_do_bounce(char *instr) {
                        omsgid = atol(addr);
                }
 
-               if (
-                  (!strcasecmp(key, "local"))
-                  || (!strcasecmp(key, "remote"))
-                  || (!strcasecmp(key, "ignet"))
-                  || (!strcasecmp(key, "room"))
-               ) {
+               if (!strcasecmp(key, "remote")) {
                        if (status == 5) bounce_this = 1;
                        if (give_up) bounce_this = 1;
                }
@@ -1483,7 +1381,7 @@ void smtp_do_bounce(char *instr) {
                        strcat(bmsg->cm_fields['M'], addr);
                        strcat(bmsg->cm_fields['M'], ": ");
                        strcat(bmsg->cm_fields['M'], dsn);
-                       strcat(bmsg->cm_fields['M'], "\n");
+                       strcat(bmsg->cm_fields['M'], "\r\n");
 
                        remove_token(instr, i, '\n');
                        --i;
@@ -1548,7 +1446,7 @@ void smtp_do_bounce(char *instr) {
 
                /* Free up the memory we used */
                if (valid != NULL) {
-                       free(valid);
+                       free_recipients(valid);
                }
        }
 
@@ -1584,12 +1482,7 @@ int smtp_purge_completed_deliveries(char *instr) {
 
                completed = 0;
 
-               if (
-                  (!strcasecmp(key, "local"))
-                  || (!strcasecmp(key, "remote"))
-                  || (!strcasecmp(key, "ignet"))
-                  || (!strcasecmp(key, "room"))
-               ) {
+               if (!strcasecmp(key, "remote")) {
                        if (status == 2) completed = 1;
                        else ++incomplete;
                }
@@ -1903,8 +1796,6 @@ void smtp_cleanup_function(void) {
 
        lprintf(CTDL_DEBUG, "Performing SMTP cleanup hook\n");
        free(SMTP);
-       free(SMTP_ROOMS);
-       free(SMTP_RECPS);
 }