You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by so...@apache.org on 2006/02/16 02:07:01 UTC

svn commit: r378134 - in /httpd/mod_smtpd/trunk/src: mod_smtpd.h smtp_core.c smtp_protocol.c smtp_util.c

Author: soc-rian
Date: Wed Feb 15 17:07:00 2006
New Revision: 378134

URL: http://svn.apache.org/viewcvs?rev=378134&view=rev
Log:
Added a mechanism for modules to disallow arbitrary built-in commands.
fixed smtpd_queue array iteration bug.


Modified:
    httpd/mod_smtpd/trunk/src/mod_smtpd.h
    httpd/mod_smtpd/trunk/src/smtp_core.c
    httpd/mod_smtpd/trunk/src/smtp_protocol.c
    httpd/mod_smtpd/trunk/src/smtp_util.c

Modified: httpd/mod_smtpd/trunk/src/mod_smtpd.h
URL: http://svn.apache.org/viewcvs/httpd/mod_smtpd/trunk/src/mod_smtpd.h?rev=378134&r1=378133&r2=378134&view=diff
==============================================================================
--- httpd/mod_smtpd/trunk/src/mod_smtpd.h (original)
+++ httpd/mod_smtpd/trunk/src/mod_smtpd.h Wed Feb 15 17:07:00 2006
@@ -80,6 +80,18 @@
     SMTPD_TRUE
 } smtpd_bool;
 
+typedef enum {
+    SMTPD_COMMAND_MAIL,
+    SMTPD_COMMAND_RCPT,
+    SMTPD_COMMAND_EHLO,
+    SMTPD_COMMAND_HELO,
+    SMTPD_COMMAND_RSET,
+    SMTPD_COMMAND_QUIT,
+    SMTPD_COMMAND_NOOP,
+    SMTPD_COMMAND_DATA,
+    SMTPD_COMMAND_VRFY
+} smtpd_command;
+
 typedef struct smtpd_envelope_rec {
     apr_pool_t *p;
     
@@ -145,6 +157,9 @@
     /* invalid connection? */
     smtpd_bool should_disconnect;
 
+    /* allowed commands bit-vector */
+    unsigned int allowed_commands;
+
     /* greetings */
     apr_array_header_t *connect_greeting;
     apr_array_header_t *queued_greeting;
@@ -152,6 +167,26 @@
 } smtpd_session_rec;
   
 /* public */
+/* allows a mod_smtpd handled SMTP command */
+SMTPD_DECLARE_NONSTD(void) smtpd_allow_command(smtpd_session_rec *scr,
+                                               smtpd_command command);
+
+/* disallows a mod_smtpd handled SMTP command */
+SMTPD_DECLARE_NONSTD(void) smtpd_disallow_command(smtpd_session_rec *scr,
+                                                  smtpd_command command);
+
+/* checks if a command is allowed */
+SMTPD_DECLARE_NONSTD(smtpd_bool) smtpd_check_command(smtpd_session_rec *scr,
+                                                     smtpd_command command);
+
+/* disallows all mod_smtpd handled SMTP commands */
+SMTPD_DECLARE_NONSTD(void) smtpd_disallow_all_commands(smtpd_session_rec
+                                                       *scr);
+
+/* allows all mod_smtpd handled SMTP commands */
+SMTPD_DECLARE_NONSTD(void) smtpd_allow_all_commands(smtpd_session_rec
+                                                    *scr);
+
 SMTPD_DECLARE_NONSTD(void) smtpd_register_extension(smtpd_session_rec *scr,
                                                     const char *line);
        

Modified: httpd/mod_smtpd/trunk/src/smtp_core.c
URL: http://svn.apache.org/viewcvs/httpd/mod_smtpd/trunk/src/smtp_core.c?rev=378134&r1=378133&r2=378134&view=diff
==============================================================================
--- httpd/mod_smtpd/trunk/src/smtp_core.c (original)
+++ httpd/mod_smtpd/trunk/src/smtp_core.c Wed Feb 15 17:07:00 2006
@@ -153,6 +153,9 @@
     scr->queued_greeting = apr_array_make(scr->p, 5, sizeof(char *));
     scr->quit_greeting = apr_array_make(scr->p, 5, sizeof(char *));
 
+    scr->should_disconnect = SMTPD_FALSE;
+    smtpd_allow_all_commands(scr);
+
     /* create envelope rec */
     str = apr_pcalloc(scr->p, sizeof(*str));
     

Modified: httpd/mod_smtpd/trunk/src/smtp_protocol.c
URL: http://svn.apache.org/viewcvs/httpd/mod_smtpd/trunk/src/smtp_protocol.c?rev=378134&r1=378133&r2=378134&view=diff
==============================================================================
--- httpd/mod_smtpd/trunk/src/smtp_protocol.c (original)
+++ httpd/mod_smtpd/trunk/src/smtp_protocol.c Wed Feb 15 17:07:00 2006
@@ -99,6 +99,8 @@
         smtpd_respond(scr, 554, "Connection from you denied",
                       out_data);
         scr->should_disconnect = SMTPD_TRUE;
+        smtpd_disallow_all_commands(scr);
+        smtpd_allow_command(scr, SMTPD_COMMAND_QUIT);
         break;
     default:
         snprintf(buffer, 255, "%s mod_smtpd", scr->s->server_hostname);
@@ -228,9 +230,11 @@
     smtpd_return_data *out_data = NULL;
     smtpd_bool disconnect = SMTPD_FALSE;
 
-    if (scr->should_disconnect == SMTPD_TRUE) {
-        smtpd_respond_oneline(scr, 503, "Please disconnect using the "
-                              " QUIT command");
+    if ((esmtp == SMTPD_TRUE &&
+         smtpd_check_command(scr, SMTPD_COMMAND_EHLO) == FALSE) ||
+        (esmtp == SMTPD_FALSE &&
+         smtpd_check_command(scr, SMTPD_COMMAND_HELO) == FALSE)) {
+        smtpd_respond_oneline(scr, 503, "Command not allowed");
         return disconnect;
     }
 
@@ -328,9 +332,8 @@
     smtpd_return_data *out_data = NULL;
     smtpd_bool disconnect = SMTPD_FALSE;
 
-    if (scr->should_disconnect == SMTPD_TRUE) {
-        smtpd_respond_oneline(scr, 503, "Please disconnect using the "
-                              " QUIT command");
+    if (smtpd_check_command(scr, SMTPD_COMMAND_MAIL) == SMTPD_FALSE) {
+        smtpd_respond_oneline(scr, 503, "Command not allowed");
         return disconnect;
     }
 
@@ -430,9 +433,8 @@
     smtpd_return_data *out_data = NULL;
     smtpd_bool disconnect = SMTPD_FALSE;
         
-    if (scr->should_disconnect == SMTPD_TRUE) {
-        smtpd_respond_oneline(scr, 503, "Please disconnect using the "
-                              " QUIT command");
+    if (smtpd_check_command(scr, SMTPD_COMMAND_RCPT) == SMTPD_FALSE) {
+        smtpd_respond_oneline(scr, 503, "Command not allowed");
         return disconnect;
     }
 
@@ -499,21 +501,26 @@
 static void smtpd_bounce_unqueued(smtpd_session_rec *scr) {
 }
 
+SMTPD_DECLARE_NONSTD(int) smtpd_count_unqueued(void *rec, const char *key,
+                                               const char *val) {
+    int *amount = (int *) rec;
+
+    if (val == NULL) {
+        *amount += 1;
+    }
+    
+    return !0;
+}
+
 static void smtpd_queue(smtpd_session_rec *scr)
 {
     int i, amount_unqueued = 0;
-    const apr_array_header_t *rcpts;
+    const apr_array_header_t *rcpts = apr_table_elts(scr->envelope->rcpt_to);
 
     smtpd_run_on_queue(scr);
 
-    rcpts = apr_table_elts(scr->envelope->rcpt_to);
-
-    for (i = rcpts->nelts-1; i >= 0; i++) {
-        if (apr_table_get(scr->envelope->rcpt_to,
-                          APR_ARRAY_IDX(rcpts, i, char *)) == NULL) {
-            amount_unqueued++;
-        }
-    }
+    apr_table_do(smtpd_count_unqueued, &amount_unqueued,
+                 scr->envelope->rcpt_to, NULL);
 
     if (amount_unqueued > 0) {
         smtpd_bounce_unqueued(scr);
@@ -720,9 +727,8 @@
     smtpd_bool disconnect = SMTPD_FALSE;
     smtpd_return_data *out_data = NULL;
 
-    if (scr->should_disconnect == SMTPD_TRUE) {
-        smtpd_respond_oneline(scr, 503, "Please disconnect using the "
-                              " QUIT command");
+    if (smtpd_check_command(scr, SMTPD_COMMAND_DATA) == SMTPD_FALSE) {
+        smtpd_respond_oneline(scr, 503, "Command not allowed");
         return disconnect;
     }
 
@@ -766,9 +772,8 @@
 
 static smtpd_bool smtpd_handler_rset(smtpd_session_rec *scr, char *buffer)
 {
-    if (scr->should_disconnect == SMTPD_TRUE) {
-        smtpd_respond_oneline(scr, 503, "Please disconnect using the "
-                              " QUIT command");
+    if (smtpd_check_command(scr, SMTPD_COMMAND_RSET) == SMTPD_FALSE) {
+        smtpd_respond_oneline(scr, 503, "Command not allowed");
     }
     else if (buffer != NULL) {
         smtpd_respond_oneline(scr, 501, "Syntax: RSET");
@@ -783,13 +788,13 @@
 
 static smtpd_bool smtpd_handler_noop(smtpd_session_rec *scr, char *buffer)
 {
-   if (scr->should_disconnect == SMTPD_TRUE) {
-       smtpd_respond_oneline(scr, 503, "Please disconnect using the "
-                             " QUIT command");
-   }
-   else {
-       smtpd_respond_oneline(scr, 250, "Ok");
-   }
+
+    if (smtpd_check_command(scr, SMTPD_COMMAND_NOOP) == SMTPD_FALSE) {
+        smtpd_respond_oneline(scr, 503, "Command not allowed");
+    }
+    else {
+        smtpd_respond_oneline(scr, 250, "Ok");
+    }
     
     return SMTPD_FALSE;
 }
@@ -798,8 +803,9 @@
 {
     smtpd_bool disconnect = SMTPD_FALSE;
 
-    if (buffer != NULL) {
-        smtpd_respond_oneline(scr, 501, "Syntax: QUIT");
+    if (smtpd_check_command(scr, SMTPD_COMMAND_QUIT) == SMTPD_FALSE) {
+        smtpd_respond_oneline(scr, 503, "Command not allowed");
+        return disconnect;
     }
     else {
         smtpd_run_on_quit(scr);
@@ -816,12 +822,11 @@
     smtpd_return_data *out_data = NULL;
     smtpd_bool disconnect = SMTPD_FALSE;
 
-    if (scr->should_disconnect == SMTPD_TRUE) {
-        smtpd_respond_oneline(scr, 503, "Please disconnect using the "
-                              " QUIT command");
+    if (smtpd_check_command(scr, SMTPD_COMMAND_VRFY) == SMTPD_FALSE) {
+        smtpd_respond_oneline(scr, 503, "Command not allowed");
         return disconnect;
     }
-    
+
     if (buffer == NULL) {
         goto syntax_error;
     }

Modified: httpd/mod_smtpd/trunk/src/smtp_util.c
URL: http://svn.apache.org/viewcvs/httpd/mod_smtpd/trunk/src/smtp_util.c?rev=378134&r1=378133&r2=378134&view=diff
==============================================================================
--- httpd/mod_smtpd/trunk/src/smtp_util.c (original)
+++ httpd/mod_smtpd/trunk/src/smtp_util.c Wed Feb 15 17:07:00 2006
@@ -21,6 +21,38 @@
 #include "mod_smtpd.h"
 #include "smtp.h"
 
+SMTPD_DECLARE_NONSTD(void) smtpd_allow_command(smtpd_session_rec *scr,
+                                               smtpd_command command)
+{
+    scr->allowed_commands |= 1 << command;
+}
+
+SMTPD_DECLARE_NONSTD(void) smtpd_disallow_command(smtpd_session_rec *scr,
+                                                  smtpd_command command)
+{
+    scr->allowed_commands &= ~(1 << command);
+}
+
+SMTPD_DECLARE_NONSTD(smtpd_bool) smtpd_check_command(smtpd_session_rec *scr,
+                                                     smtpd_command command)
+{
+    return (scr->allowed_commands & (1 << command))
+      ? SMTPD_TRUE 
+      : SMTPD_FALSE;
+}
+
+SMTPD_DECLARE_NONSTD(void) smtpd_disallow_all_commands(smtpd_session_rec
+                                                       *scr)
+{
+    scr->allowed_commands = 0;
+}
+
+SMTPD_DECLARE_NONSTD(void) smtpd_allow_all_commands(smtpd_session_rec
+                                                    *scr)
+{
+    scr->allowed_commands = ~0;
+}
+
 /* should be called at smtpd_hook_connect
  * at least by convention
  */