OSSP CVS Repository

ossp - Check-in [570]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 570
Date: 2001-Jul-26 17:18:57 (local)
2001-Jul-26 15:18:57 (UTC)
User:thl
Branch:
Comment: lmtp_cb_helo using strict RFC821 <domain> checking in a perl-generated regex
Tickets:
Inspections:
Files:
ossp-pkg/lmtp2nntp/lmtp.c      1.6 -> 1.7     1 inserted, 1 deleted
ossp-pkg/lmtp2nntp/lmtp2nntp.c      1.5 -> 1.6     113 inserted, 26 deleted

ossp-pkg/lmtp2nntp/lmtp.c 1.6 -> 1.7

--- lmtp.c       2001/07/25 19:51:12     1.6
+++ lmtp.c       2001/07/26 15:18:57     1.7
@@ -432,7 +432,7 @@
 
     res.statuscode = "220";
     res.dsncode    = NULL;
-    res.statusmsg  = "LMTP server ready (lmtp2nntp)";
+    res.statusmsg  = "LMTP Service ready.";
     if ((rc = lmtp_response(lmtp, &res)) != LMTP_OK) 
         return rc;
 


ossp-pkg/lmtp2nntp/lmtp2nntp.c 1.5 -> 1.6

--- lmtp2nntp.c  2001/07/25 15:02:57     1.5
+++ lmtp2nntp.c  2001/07/26 15:18:57     1.6
@@ -37,6 +37,7 @@
 #define ERR_DELIVERY -2
 
 #define MESSAGE_MAXLEN 8*1024*1024
+#define STDSTRLEN 128
 
 extern void lmtp_debug_dumplmtp(lmtp_t *lmtp);
 
@@ -52,15 +53,16 @@
 static lmtp_rc_t lmtp_cb_quit   (lmtp_t *lmtp, lmtp_io_t *io, lmtp_req_t *req, void *ctx);
 
 typedef struct {
-    int option_verbose;
-    int option_tracing;
-    int option_mode;
-    char  *azNewsgroups;
-    size_t asNewsgroups;
-    char *rfc822message;
-    int saw_lhlo;
-    char  *azRcpt;
-    size_t asRcpt;
+    int     option_verbose;
+    int     option_tracing;
+    int     option_mode;
+    char   *azNewsgroups;
+    size_t  asNewsgroups;
+    char   *rfc822message;
+    int     lhlo_seen;
+    char   *lhlo_domain;
+    char   *azRcpt;
+    size_t  asRcpt;
 } lmtp2nntp_t;
 
 enum {
@@ -128,7 +130,8 @@
     ctx->azNewsgroups = NULL;
     ctx->asNewsgroups = 0;
     ctx->rfc822message = NULL;
-    ctx->saw_lhlo = FALSE;
+    ctx->lhlo_seen = FALSE;
+    ctx->lhlo_domain = "";
     ctx->azRcpt = NULL;
     ctx->asRcpt = 0;
 
@@ -217,25 +220,109 @@
      *  and the receiver-SMTP are in the initial state, that is, there is no
      *  transaction in progress and all state tables and buffers are cleared.
      * 
+     *  The first command in a session must be the HELO command.  The HELO
+     *  command may be used later in a session as well.  If the HELO command
+     *  argument is not acceptable a 501 failure reply must be returned and
+     *  the receiver-SMTP must stay in the same state.
+     *
+     *  If the transaction beginning command argument is not acceptable a 501
+     *  failure reply must be returned and the receiver-SMTP must stay in the
+     *  same state.  If the commands in a transaction are out of order a 503
+     *  failure reply must be returned and the receiver-SMTP must stay in the
+     *  same state.
+     *
+     *  HELO <SP> <domain> <CRLF>
      */
+    lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx;
     lmtp_rc_t rc = LMTP_OK;
     lmtp_res_t res;
-    lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx;
+    char errorstring[STDSTRLEN];
+    char *cp;
+    int FIXME;
+
+    cp = NULL;
+    if (ctx->lhlo_seen == TRUE) {
+        res.statuscode = "503";
+        res.dsncode    = "5.0.0";
+        res.statusmsg  = "Duplicate LHLO.";
+    } else {
+        if (!str_parse(req->msg, 
+            "^.+ ("
 
-    //FIXME use rset() not lmtp_cb_rset()
-    ctx->saw_lhlo = TRUE;
+            /*
+             ##
+             ##  The mega Perl regular expression below is generated
+             ##  with the following Perl program. This is only possible
+             ##  because the given grammar is Chomsky-3 (right or left
+             ##  linear grammar, but noth both).
+             ##
+
+             # BNF grammar for <domain> according to RFC 821:
+             # <snum>        ::= one, two, or three digits representing a decimal integer value in the range 0 through 255
+             # <a>           ::= any one of the 52 alphabetic characters A through Z in upper case and a through z in lower case
+             # <d>           ::= any one of the ten digits 0 through 9
+             # <let-dig-hyp> ::= <a> | <d> | "-"
+             # <let-dig>     ::= <a> | <d>
+             # <ldh-str>     ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
+             # <dotnum>      ::= <snum> "." <snum> "." <snum> "." <snum>
+             # <number>      ::= <d> | <d> <number>
+             # <name>        ::= <a> <ldh-str> <let-dig>
+             # <element>     ::= <name> | "#" <number> | "[" <dotnum> "]"
+             # <domain>      ::= <element> | <element> "." <domain>
+             
+             # corresponding Perl regular expression ($domain)
+             $snum        = "(?:[0-9]|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])";
+             $d           = "[0-9]";
+             $a           = "[A-Za-z]";
+             $let_dig_hyp = "(?:$a|$d|-)";
+             $let_dig     = "(?:$a|$d)";
+             $ldh_str     = "${let_dig_hyp}+";
+             $dotnum      = "$snum\\.$snum\\.$snum\\.$snum";
+             $number      = "$d+";
+             $name        = "$a$ldh_str$let_dig";
+             $element     = "(?:$name|#$number|\\[$dotnum\\])";
+             $domain      = "(?:$element\.)*$element";
+             
+             # translate into C string block suitable for passing to the Perl
+             # Compatible Regular Expressions (PCRE) based string library Str.
+             my $cregex = $domain;
+             $cregex =~ s|\\|\\\\|sg;
+             $cregex =~ s|(.{70})|"$1"\n|sg;
+             $cregex =~ s|\n([^\n]+)$|\n"$1"|s;
+             print "$cregex\n";
+             */
+
+            "(?:(?:[A-Za-z](?:[A-Za-z]|[0-9]|-)+(?:[A-Za-z]|[0-9])|#[0-9]+|\\[(?:[0"
+            "-9]|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.(?:[0-9]|[0-9]{2}|[0"
+            "-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.(?:[0-9]|[0-9]{2}|[0-1][0-9]{2}|2[0"
+            "-4][0-9]|25[0-5])\\.(?:[0-9]|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5"
+            "])\\]).)*(?:[A-Za-z](?:[A-Za-z]|[0-9]|-)+(?:[A-Za-z]|[0-9])|#[0-9]+|\\"
+            "[(?:[0-9]|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.(?:[0-9]|[0-9]"
+            "{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.(?:[0-9]|[0-9]{2}|[0-1][0-9]{"
+            "2}|2[0-4][0-9]|25[0-5])\\.(?:[0-9]|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|"
+            "25[0-5])\\])"
 
-    res.statuscode = "250";
-    res.dsncode    = NULL; /* DSN not used for greeting */
-    res.statusmsg  = "ENHANCEDSTATUSCODES\nDSN\nPIPELINING\n8BITMIME";
-    res.statusmsg  = "ENHANCEDSTATUSCODES\nDSN\n8BITMIME";
-        /*
-         *  RFC2034 = EHANCEDSTATUSCODES
-         *  RFC1894 = DSN
-         *  RFC1854 = PIPELINING
-         *  RFC1652 = 8BITMIME
-         */
+            ")$", &cp, &ctx->lhlo_domain)) {
+            res.statuscode = "501";
+            res.dsncode    = "5.0.0";
+            res.statusmsg  = "Please identify yourself. See <domain> BNF in RFC821.";
+        } else {
+            ctx->lhlo_seen = TRUE;
+            printf("DEBUG: cp=***%s***, v1=***%s***\n", cp, ctx->lhlo_domain);
+            str_format(errorstring, sizeof(errorstring), "Hello ***%s***", ctx->lhlo_domain);
+            res.statuscode = "250";
+            res.dsncode    = NULL; /* DSN not used for greeting */
+            res.statusmsg  = "ENHANCEDSTATUSCODES\nDSN\nPIPELINING\n8BITMIME";
+                /*
+                 *  RFC2034 = EHANCEDSTATUSCODES
+                 *  RFC1894 = DSN
+                 *  RFC1854 = PIPELINING
+                 *  RFC1652 = 8BITMIME
+                 */
+        }
+    }
     lmtp_response(lmtp, &res);
+    if (cp) free(cp);
     return rc;
 }
 
@@ -245,7 +332,7 @@
     lmtp_rc_t rc = LMTP_OK;
     lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx;
 
-    if (ctx->saw_lhlo == TRUE) {
+    if (ctx->lhlo_seen == TRUE) {
         res.statuscode = "250";
         res.dsncode    = "2.1.0";
         res.statusmsg  = "Sender ok FIXME";
@@ -281,7 +368,7 @@
     lmtp_rc_t rc = LMTP_OK;
     lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx;
     char *buf;
-    char errorstring[128];
+    char errorstring[STDSTRLEN];
     char *rcpt;
 
     res.statuscode = "354";
@@ -349,7 +436,7 @@
     lmtp_rc_t rc = LMTP_EOF;
     res.statuscode = "221";
     res.dsncode    = "2.0.0";
-    res.statusmsg  = "Closing connection.";
+    res.statusmsg  = "LMTP Service closing transmission channel.";
     lmtp_response(lmtp, &res);
     return rc;
 }

CVSTrac 2.0.1