INN commit: trunk (25 files)

INN Commit rra at isc.org
Wed Apr 5 20:01:05 UTC 2017


    Date: Wednesday, April 5, 2017 @ 13:01:05
  Author: iulius
Revision: 10137

Add support for a new syntaxchecks parameter in inn.conf

This parameter permits to control the level of checks performed by
innd and nnrpd.  Up to now, only one check can be enabled/disabled:
when "laxmid" is mentioned in the values of this new parameter, INN
accepts Message-IDs that contain ".." in the left part, as well as
Message-IDs with two "@" (such Message-IDs would otherwise be considered
as syntactically invalid).

Added:
  trunk/tests/lib/messageid-t.c
Modified:
  trunk/MANIFEST
  trunk/doc/pod/inn.conf.pod
  trunk/doc/pod/news.pod
  trunk/include/inn/innconf.h
  trunk/include/inn/libinn.h
  trunk/innd/Makefile
  trunk/innd/art.c
  trunk/innd/innd.c
  trunk/innd/innd.h
  trunk/innd/nc.c
  trunk/lib/Makefile
  trunk/lib/innconf.c
  trunk/lib/messageid.c
  trunk/nnrpd/Makefile
  trunk/nnrpd/article.c
  trunk/nnrpd/commands.c
  trunk/nnrpd/nnrpd.c
  trunk/nnrpd/post.c
  trunk/samples/inn.conf.in
  trunk/support/mkmanifest
  trunk/tests/Makefile
  trunk/tests/TESTS
  trunk/tests/innd/fakeinnd.c
  trunk/tests/lib/	(properties)

-------------------------+
 MANIFEST                |    1 
 doc/pod/inn.conf.pod    |   24 ++++++++
 doc/pod/news.pod        |   19 +++++++
 include/inn/innconf.h   |    7 +-
 include/inn/libinn.h    |    3 -
 innd/Makefile           |   42 +++++++++------
 innd/art.c              |    9 +--
 innd/innd.c             |   22 ++++++++
 innd/innd.h             |    1 
 innd/nc.c               |   12 ++--
 lib/Makefile            |    3 -
 lib/innconf.c           |    1 
 lib/messageid.c         |   38 +++++++++++---
 nnrpd/Makefile          |   58 ++++++++++++---------
 nnrpd/article.c         |    7 +-
 nnrpd/commands.c        |    3 -
 nnrpd/nnrpd.c           |   20 +++++++
 nnrpd/post.c            |    3 -
 samples/inn.conf.in     |    1 
 support/mkmanifest      |    1 
 tests/Makefile          |    5 +
 tests/TESTS             |    1 
 tests/innd/fakeinnd.c   |    1 
 tests/lib               |    1 
 tests/lib/messageid-t.c |  123 ++++++++++++++++++++++++++++++++++++++++++++++
 25 files changed, 339 insertions(+), 67 deletions(-)

Modified: MANIFEST
===================================================================
--- MANIFEST	2017-04-05 19:44:24 UTC (rev 10136)
+++ MANIFEST	2017-04-05 20:01:05 UTC (rev 10137)
@@ -899,6 +899,7 @@
 tests/lib/list-t.c                    Tests for lib/list.c
 tests/lib/md5-t.c                     Tests for lib/md5.c
 tests/lib/memcmp-t.c                  Tests for lib/memcmp.c
+tests/lib/messageid-t.c               Tests for lib/messageid.c
 tests/lib/messages-t.c                Tests for lib/messages.c
 tests/lib/mkstemp-t.c                 Tests for lib/mkstemp.c
 tests/lib/network                     Test suite for network (Directory)

Modified: doc/pod/inn.conf.pod
===================================================================
--- doc/pod/inn.conf.pod	2017-04-05 19:44:24 UTC (rev 10136)
+++ doc/pod/inn.conf.pod	2017-04-05 20:01:05 UTC (rev 10137)
@@ -130,8 +130,32 @@
 environment variable, if it exists, overrides this.  The default value is
 unset.
 
+=item I<syntaxchecks>
+
+A list of values controlling the level of checks performed by B<innd>
+and B<nnrpd>.  For instance:
+
+    syntaxchecks: [ no-laxmid ]
+
+The last occurrence of a given value takes precedence, that is to say
+if C<no-laxmid laxmid> is listed, I<laxmid> takes precedence.
+
+Only one check can currently be enabled/disabled:
+
+=over 4
+
+=item I<laxmid> / I<no-laxmid>
+
+When I<laxmid> is set, Message-IDs containing C<..> in the left part
+are accepted, as well as Message-IDs with two C<@>.  Some non-compliant
+news posters generate such syntactically invalid Message-IDs, especially
+in binary newsgroups.  The default is I<no-laxmid>, that is to say INN
+strictly follows the standard regarding syntax checks.
+
 =back
 
+=back
+
 =head2 Feed Configuration
 
 These parameters govern incoming and outgoing feeds:  what size of

Modified: doc/pod/news.pod
===================================================================
--- doc/pod/news.pod	2017-04-05 19:44:24 UTC (rev 10136)
+++ doc/pod/news.pod	2017-04-05 20:01:05 UTC (rev 10137)
@@ -1,3 +1,22 @@
+=head1 Changes in 2.6.2
+
+=over 2
+
+=item *
+
+A new I<syntaxchecks> parameter has been added in F<inn.conf>.
+It permits to control the level of checks performed by B<innd> and
+B<nnrpd>.  Up to now, only one check can be enabled/disabled:  when
+I<laxmid> is mentioned in the values of this new parameter, INN accepts
+Message-IDs that contain C<..> in the left part, as well as Message-IDs
+with two C<@> (such Message-IDs would otherwise be considered as
+syntactically invalid).  See the inn.conf(5) man page for more details.
+
+The default value (I<no-laxmid>) corresponds to the legacy behaviour
+(the one of S<INN 2.6.1> and earlier).
+
+=back
+
 =head1 Changes in 2.6.1
 
 =over 2

Modified: include/inn/innconf.h
===================================================================
--- include/inn/innconf.h	2017-04-05 19:44:24 UTC (rev 10136)
+++ include/inn/innconf.h	2017-04-05 20:01:05 UTC (rev 10137)
@@ -16,7 +16,7 @@
 **  This structure is organized in the same order as the variables contained
 **  in it are mentioned in the inn.conf documentation, and broken down into
 **  the same sections.  Note that due to the implementation, only three types
-**  of variables are permissible here:  char *, bool, struc vector *, long
+**  of variables are permissible here:  char *, bool, struct vector *, long
 **  and unsigned long.
 */
 struct innconf {
@@ -26,9 +26,10 @@
     char *mailcmd;              /* Command to send report/control type mail */
     char *mta;                  /* MTA for mailing to moderators, innmail */
     char *pathhost;             /* Entry for the Path: line */
-    char *server;               /* Default server to connect to */
     char *runasuser;            /* User to run under */
     char *runasgroup;           /* Group to run under */
+    char *server;               /* Default server to connect to */
+    struct vector *syntaxchecks; /* List of syntax checks to perform or not */
 
     /* Feed Configuration */
     unsigned long artcutoff;    /* Max accepted article age */
@@ -161,8 +162,8 @@
     bool logtrash;              /* Log unwanted newsgroups? */
     bool nnrpdoverstats;        /* Log overview statistics? */
     bool nntplinklog;           /* Put storage token into the log? */
+    char *stathist;             /* Filename for history profiler outputs */
     unsigned long status;       /* Status file update interval */
-    char *stathist;             /* Filename for history profiler outputs */
     unsigned long timer;        /* Performance monitoring interval */
 
     /* System Tuning */

Modified: include/inn/libinn.h
===================================================================
--- include/inn/libinn.h	2017-04-05 19:44:24 UTC (rev 10136)
+++ include/inn/libinn.h	2017-04-05 20:01:05 UTC (rev 10137)
@@ -90,7 +90,8 @@
 /* Headers. */
 extern char *           GenerateMessageID(char *domain);
 extern void             InitializeMessageIDcclass(void);
-extern bool             IsValidMessageID(const char *string, bool stripspaces);
+extern bool             IsValidMessageID(const char *string,
+                                         bool stripspaces, bool laxsyntax);
 extern bool             IsValidHeaderName(const char *string);
 extern bool             IsValidHeaderBody(const char *string);
 extern bool             IsValidHeaderField(const char *string);

Modified: innd/Makefile
===================================================================
--- innd/Makefile	2017-04-05 19:44:24 UTC (rev 10136)
+++ innd/Makefile	2017-04-05 20:01:05 UTC (rev 10137)
@@ -97,7 +97,8 @@
   ../include/inn/messages.h ../include/inn/timer.h ../include/inn/libinn.h \
   ../include/inn/concat.h ../include/inn/xmalloc.h ../include/inn/xwrite.h \
   ../include/inn/nntp.h ../include/inn/paths.h ../include/inn/storage.h \
-  ../include/inn/options.h ../include/inn/inndcomm.h ../include/innperl.h
+  ../include/inn/options.h ../include/inn/vector.h \
+  ../include/inn/inndcomm.h ../include/innperl.h
 chan.o: chan.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -111,7 +112,8 @@
   ../include/inn/history.h ../include/inn/messages.h \
   ../include/inn/timer.h ../include/inn/libinn.h ../include/inn/concat.h \
   ../include/inn/xmalloc.h ../include/inn/xwrite.h ../include/inn/nntp.h \
-  ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h
+  ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h \
+  ../include/inn/vector.h
 icd.o: icd.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -127,7 +129,7 @@
   ../include/inn/timer.h ../include/inn/libinn.h ../include/inn/concat.h \
   ../include/inn/xmalloc.h ../include/inn/xwrite.h ../include/inn/nntp.h \
   ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h \
-  ../include/inn/ov.h ../include/inn/storage.h
+  ../include/inn/vector.h ../include/inn/ov.h ../include/inn/storage.h
 innd.o: innd.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -140,8 +142,8 @@
   ../include/inn/buffer.h ../include/inn/history.h ../include/inn/timer.h \
   ../include/inn/libinn.h ../include/inn/concat.h ../include/inn/xmalloc.h \
   ../include/inn/xwrite.h ../include/inn/nntp.h ../include/inn/paths.h \
-  ../include/inn/storage.h ../include/inn/options.h ../include/inn/ov.h \
-  ../include/inn/storage.h
+  ../include/inn/storage.h ../include/inn/options.h \
+  ../include/inn/vector.h ../include/inn/ov.h ../include/inn/storage.h
 keywords.o: keywords.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -154,7 +156,8 @@
   ../include/portable/getnameinfo.h ../include/inn/buffer.h \
   ../include/inn/history.h ../include/inn/messages.h \
   ../include/inn/timer.h ../include/inn/nntp.h ../include/inn/paths.h \
-  ../include/inn/storage.h ../include/inn/options.h
+  ../include/inn/storage.h ../include/inn/options.h \
+  ../include/inn/vector.h
 lc.o: lc.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -167,7 +170,8 @@
   ../include/inn/messages.h ../include/inn/timer.h ../include/inn/libinn.h \
   ../include/inn/concat.h ../include/inn/xmalloc.h ../include/inn/xwrite.h \
   ../include/inn/nntp.h ../include/inn/paths.h ../include/inn/storage.h \
-  ../include/inn/options.h ../include/portable/socket-unix.h
+  ../include/inn/options.h ../include/inn/vector.h \
+  ../include/portable/socket-unix.h
 nc.o: nc.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -181,7 +185,7 @@
   ../include/inn/messages.h ../include/inn/timer.h ../include/inn/libinn.h \
   ../include/inn/concat.h ../include/inn/xmalloc.h ../include/inn/xwrite.h \
   ../include/inn/nntp.h ../include/inn/paths.h ../include/inn/storage.h \
-  ../include/inn/options.h
+  ../include/inn/options.h ../include/inn/vector.h
 newsfeeds.o: newsfeeds.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -194,7 +198,7 @@
   ../include/inn/messages.h ../include/inn/timer.h ../include/inn/libinn.h \
   ../include/inn/concat.h ../include/inn/xmalloc.h ../include/inn/xwrite.h \
   ../include/inn/nntp.h ../include/inn/paths.h ../include/inn/storage.h \
-  ../include/inn/options.h
+  ../include/inn/options.h ../include/inn/vector.h
 ng.o: ng.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -207,7 +211,8 @@
   ../include/inn/messages.h ../include/inn/timer.h ../include/inn/libinn.h \
   ../include/inn/concat.h ../include/inn/xmalloc.h ../include/inn/xwrite.h \
   ../include/inn/nntp.h ../include/inn/paths.h ../include/inn/storage.h \
-  ../include/inn/options.h ../include/inn/ov.h ../include/inn/storage.h
+  ../include/inn/options.h ../include/inn/vector.h ../include/inn/ov.h \
+  ../include/inn/storage.h
 perl.o: perl.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -220,7 +225,7 @@
   ../include/inn/messages.h ../include/inn/timer.h ../include/inn/libinn.h \
   ../include/inn/concat.h ../include/inn/xmalloc.h ../include/inn/xwrite.h \
   ../include/inn/nntp.h ../include/inn/paths.h ../include/inn/storage.h \
-  ../include/inn/options.h \
+  ../include/inn/options.h ../include/inn/vector.h \
   ../include/ppport.h \
   ../include/innperl.h
 proc.o: proc.c ../include/config.h ../include/inn/defines.h \
@@ -234,7 +239,8 @@
   ../include/inn/history.h ../include/inn/messages.h \
   ../include/inn/timer.h ../include/inn/libinn.h ../include/inn/concat.h \
   ../include/inn/xmalloc.h ../include/inn/xwrite.h ../include/inn/nntp.h \
-  ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h
+  ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h \
+  ../include/inn/vector.h
 python.o: python.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -247,7 +253,8 @@
   ../include/inn/history.h ../include/inn/messages.h \
   ../include/inn/timer.h ../include/inn/libinn.h ../include/inn/concat.h \
   ../include/inn/xmalloc.h ../include/inn/xwrite.h ../include/inn/nntp.h \
-  ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h
+  ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h \
+  ../include/inn/vector.h
 rc.o: rc.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -276,7 +283,7 @@
   ../include/inn/messages.h ../include/inn/timer.h ../include/inn/libinn.h \
   ../include/inn/concat.h ../include/inn/xmalloc.h ../include/inn/xwrite.h \
   ../include/inn/nntp.h ../include/inn/paths.h ../include/inn/storage.h \
-  ../include/inn/options.h
+  ../include/inn/options.h ../include/inn/vector.h
 status.o: status.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -291,7 +298,7 @@
   ../include/inn/timer.h ../include/inn/libinn.h ../include/inn/concat.h \
   ../include/inn/xmalloc.h ../include/inn/xwrite.h ../include/inn/nntp.h \
   ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h \
-  ../include/innperl.h
+  ../include/inn/vector.h ../include/innperl.h
 util.o: util.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -305,7 +312,8 @@
   ../include/portable/socket.h ../include/inn/buffer.h \
   ../include/inn/history.h ../include/inn/messages.h \
   ../include/inn/timer.h ../include/inn/nntp.h ../include/inn/paths.h \
-  ../include/inn/storage.h ../include/inn/options.h
+  ../include/inn/storage.h ../include/inn/options.h \
+  ../include/inn/vector.h
 wip.o: wip.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -318,7 +326,7 @@
   ../include/inn/messages.h ../include/inn/timer.h ../include/inn/libinn.h \
   ../include/inn/concat.h ../include/inn/xmalloc.h ../include/inn/xwrite.h \
   ../include/inn/nntp.h ../include/inn/paths.h ../include/inn/storage.h \
-  ../include/inn/options.h
+  ../include/inn/options.h ../include/inn/vector.h
 tinyleaf.o: tinyleaf.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \

Modified: innd/art.c
===================================================================
--- innd/art.c	2017-04-05 19:44:24 UTC (rev 10136)
+++ innd/art.c	2017-04-05 20:01:05 UTC (rev 10137)
@@ -21,6 +21,7 @@
 #define	ARTIOVCNT	16
 
 extern bool DoCancels;
+extern bool laxmid;
 
 /* Characters used in log messages indicating the disposition of messages. */
 #define ART_ACCEPT              '+'
@@ -1014,7 +1015,7 @@
   }
 
   /* Assumes the Message-ID: header is a required header. */
-  if (!IsValidMessageID(HDR(HDR__MESSAGE_ID), true)) {
+  if (!IsValidMessageID(HDR(HDR__MESSAGE_ID), true, laxmid)) {
     HDR_LEN(HDR__MESSAGE_ID) = 0;
     sprintf(buff, "%d Bad \"Message-ID\" header",
             ihave ? NNTP_FAIL_IHAVE_REJECT : NNTP_FAIL_TAKETHIS_REJECT);
@@ -1239,7 +1240,7 @@
     return;
   }
 
-  if (!IsValidMessageID(MessageID, true)) {
+  if (!IsValidMessageID(MessageID, true, laxmid)) {
     syslog(L_NOTICE, "%s bad cancel Message-ID %s", data->Feedsite,
            MaxLength(MessageID, MessageID));
     TMRstop(TMR_ARTCNCL);
@@ -1298,7 +1299,7 @@
   if ((c == 'c' || c == 'C') && strncasecmp(Control, "cancel", 6) == 0) {
     for (p = &Control[6]; ISWHITE(*p); p++)
       continue;
-    if (*p && IsValidMessageID(p, true))
+    if (*p && IsValidMessageID(p, true, laxmid))
       ARTcancel(data, p, false);
     return;
   }
@@ -2627,7 +2628,7 @@
       ARTcontrol(data, HDR(HDR__CONTROL), cp);
     }
     if (DoCancels && HDR_FOUND(HDR__SUPERSEDES)) {
-      if (IsValidMessageID(HDR(HDR__SUPERSEDES), true))
+      if (IsValidMessageID(HDR(HDR__SUPERSEDES), true, laxmid))
 	ARTcancel(data, HDR(HDR__SUPERSEDES), false);
     }
   }

Modified: innd/innd.c
===================================================================
--- innd/innd.c	2017-04-05 19:44:24 UTC (rev 10136)
+++ innd/innd.c	2017-04-05 20:01:05 UTC (rev 10137)
@@ -31,6 +31,9 @@
 
 static char	*PID = NULL;
 
+/* Default values for the syntaxchecks parameter in inn.conf. */
+bool laxmid = false;
+
 /* Signal handling.  If we receive a signal that should kill the server,
    killer_signal is set to the signal number that we received.  This isn't
    what indicates that we should terminate; that's the separate global
@@ -351,6 +354,7 @@
     bool flag;
     static char		WHEN[] = "PID file";
     int			i;
+    size_t              j;
     char		buff[SMBUF];
     FILE		*F;
     bool		ShouldFork;
@@ -528,6 +532,24 @@
 	exit(1);
     }
 
+    /* Initialize the checks to perform or not on article syntax. */
+    if ((innconf->syntaxchecks != NULL) && (innconf->syntaxchecks->count > 0)) {
+        for (j = 0; j < innconf->syntaxchecks->count; j++) {
+            if (innconf->syntaxchecks->strings[j] != NULL) {
+                if (strcmp(innconf->syntaxchecks->strings[j], "laxmid") == 0) {
+                    laxmid = true;
+                } else if (strcmp(innconf->syntaxchecks->strings[j],
+                                  "no-laxmid") == 0) {
+                    laxmid = false;
+                } else {
+                    syslog(L_NOTICE, "Unknown \"%s\" value in syntaxchecks "
+                           "parameter in inn.conf",
+                           innconf->syntaxchecks->strings[j]);
+                }
+            }
+        }
+    }
+
     /* Get the Path entry. */
     if (innconf->pathhost == NULL) {
 	syslog(L_FATAL, "%s No pathhost set", LogName);

Modified: innd/innd.h
===================================================================
--- innd/innd.h	2017-04-05 19:44:24 UTC (rev 10136)
+++ innd/innd.h	2017-04-05 20:01:05 UTC (rev 10137)
@@ -50,6 +50,7 @@
 #include "inn/nntp.h"
 #include "inn/paths.h"
 #include "inn/storage.h"
+#include "inn/vector.h"
 
 BEGIN_DECLS
 

Modified: innd/nc.c
===================================================================
--- innd/nc.c	2017-04-05 19:44:24 UTC (rev 10136)
+++ innd/nc.c	2017-04-05 20:01:05 UTC (rev 10137)
@@ -15,6 +15,8 @@
 #define BAD_COMMAND_COUNT	10
 
 
+extern bool laxmid;
+
 /*
 **  An entry in the dispatch table.  The name, and implementing function,
 **  of every command we support.
@@ -358,7 +360,7 @@
         return;
     }
 
-    if (!IsValidMessageID(cp->av[1], true)) {
+    if (!IsValidMessageID(cp->av[1], true, laxmid)) {
         xasprintf(&buff, "%d Syntax error in message-ID", NNTP_ERR_SYNTAX);
         NCwritereply(cp, buff);
         free(buff);
@@ -424,7 +426,7 @@
         return;
     }
 
-    if (!IsValidMessageID(cp->av[1], true)) {
+    if (!IsValidMessageID(cp->av[1], true, laxmid)) {
         xasprintf(&buff, "%d Syntax error in message-ID", NNTP_ERR_SYNTAX);
         NCwritereply(cp, buff);
         free(buff);
@@ -647,7 +649,7 @@
     cp->Ihave++;
     cp->Start = cp->Next;
 
-    if (!IsValidMessageID(cp->av[1], false)) {
+    if (!IsValidMessageID(cp->av[1], false, laxmid)) {
         /* Return 435 here instead of 501 for compatibility reasons. */
         xasprintf(&buff, "%d Syntax error in message-ID", NNTP_FAIL_IHAVE_REFUSE);
         NCwritereply(cp, buff);
@@ -1816,7 +1818,7 @@
             cp->Sendid.size = MED_BUFFER;
         cp->Sendid.data = xmalloc(cp->Sendid.size);
     }
-    if (!IsValidMessageID(cp->av[1], false)) {
+    if (!IsValidMessageID(cp->av[1], false, laxmid)) {
 	snprintf(cp->Sendid.data, cp->Sendid.size, "%d %s",
                  NNTP_FAIL_CHECK_REFUSE, cp->av[1]);
 	NCwritereply(cp, cp->Sendid.data);
@@ -1930,7 +1932,7 @@
     idlen = strlen(mid);
     msglen = idlen + 5; /* 3 digits + space + id + null. */
 
-    if (!IsValidMessageID(mid, false)) {
+    if (!IsValidMessageID(mid, false, laxmid)) {
         syslog(L_NOTICE, "%s bad_messageid %s", CHANname(cp),
                MaxLength(mid, mid));
         returncode = NNTP_FAIL_TAKETHIS_REJECT;

Modified: lib/Makefile
===================================================================
--- lib/Makefile	2017-04-05 19:44:24 UTC (rev 10136)
+++ lib/Makefile	2017-04-05 20:01:05 UTC (rev 10137)
@@ -685,4 +685,5 @@
   ../include/config.h ../include/inn/macros.h \
   ../include/portable/stdbool.h ../include/inn/libinn.h \
   ../include/inn/concat.h ../include/inn/xmalloc.h ../include/inn/xwrite.h \
-  ../include/ppport.h ../include/innperl.h
+  ../include/ppport.h \
+  ../include/innperl.h

Modified: lib/innconf.c
===================================================================
--- lib/innconf.c	2017-04-05 19:44:24 UTC (rev 10136)
+++ lib/innconf.c	2017-04-05 20:01:05 UTC (rev 10137)
@@ -126,6 +126,7 @@
     { K(server),                  STRING  (NULL) },
     { K(sourceaddress),           STRING  (NULL) },
     { K(sourceaddress6),          STRING  (NULL) },
+    { K(syntaxchecks),            LIST    (NULL) },
     { K(timer),                   UNUMBER  (600) },
 
     { K(runasuser),               STRING  (RUNASUSER) },

Modified: lib/messageid.c
===================================================================
--- lib/messageid.c	2017-04-05 19:44:24 UTC (rev 10136)
+++ lib/messageid.c	2017-04-05 20:01:05 UTC (rev 10137)
@@ -52,6 +52,8 @@
 
 /*
 **  Initialize the character class tables.
+**  See Section 3.2.3 of RFC 5322 (atext) and Section 3.1.3 of RFC 5536
+**  (mdtext).
 */
 void
 InitializeMessageIDcclass(void)
@@ -62,12 +64,12 @@
     /* Set up the character class tables.  These are written a
      * little strangely to work around a GCC2.0 bug. */
     memset(midcclass, 0, sizeof(midcclass));
-        
+
     p = (const unsigned char*) "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
     while ((i = *p++) != 0) {
         midcclass[i] = CC_MSGID_ATOM | CC_MSGID_NORM;
     }
-      
+
     p = (const unsigned char*) "!#$%&'*+-/=?^_`{|}~";
     while ((i = *p++) != 0) {
         midcclass[i] = CC_MSGID_ATOM | CC_MSGID_NORM;
@@ -98,11 +100,18 @@
 **  in <#*tyo2'~n at twinsun.com>, with additional e-mail discussion.
 **  Thanks, Paul, for the original implementation based upon RFC 1036.
 **  Updated to RFC 5536 by Julien Elie.
+**
+**  When stripspaces is true, whitespace at the beginning and at the end
+**  of MessageID are discarded.
+**
+**  When laxsyntax is true, '@' can occur twice in MessageID, and '..' is
+**  also accepted in the left part of MessageID.
 */
 bool
-IsValidMessageID(const char *MessageID, bool stripspaces)
+IsValidMessageID(const char *MessageID, bool stripspaces, bool laxsyntax)
 {
     int c;
+    bool atfound = false;
     const unsigned char *p;
 
     /* Check the length of the message-ID. */
@@ -125,10 +134,27 @@
         } else {
             return false;
         }
-        if (*p != '.')
-            break;
+        if (*p != '.') {
+            if (laxsyntax && *p == '@') {
+                /* The domain part begins at the second '@', if it exists. */
+                if (atfound || (p[1] == '[')
+                    || (strchr((char *) p+1, '@') == NULL)) {
+                    break;
+                }
+                atfound = true;
+                continue;
+            } else {
+                break;
+            }
+        }
+        /* Dot found. */
+        if (laxsyntax) {
+            if (*p != '\0' && p[1] == '.') {
+                p++;
+            }
+        }
     }
-    
+
     /* Scan domain part:  "@ dot-atom-text|no-fold-literal > \0" */
     if (*p++ != '@')
         return false;

Modified: nnrpd/Makefile
===================================================================
--- nnrpd/Makefile	2017-04-05 19:44:24 UTC (rev 10136)
+++ nnrpd/Makefile	2017-04-05 20:01:05 UTC (rev 10137)
@@ -82,8 +82,9 @@
   ../include/inn/qio.h ../include/inn/libinn.h ../include/inn/concat.h \
   ../include/inn/xmalloc.h ../include/inn/xwrite.h ../include/inn/nntp.h \
   ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h \
-  ../include/inn/vector.h ../include/inn/timer.h ../include/inn/ov.h \
-  ../include/inn/history.h ../include/inn/storage.h tls.h cache.h
+  ../include/inn/vector.h ../include/inn/timer.h \
+  ../include/inn/ov.h ../include/inn/history.h ../include/inn/storage.h \
+  tls.h cache.h
 auth-ext.o: auth-ext.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -117,9 +118,9 @@
   ../include/inn/libinn.h ../include/inn/concat.h ../include/inn/xmalloc.h \
   ../include/inn/xwrite.h ../include/inn/nntp.h ../include/inn/paths.h \
   ../include/inn/storage.h ../include/inn/options.h \
-  ../include/inn/vector.h ../include/inn/timer.h ../include/inn/fdflag.h \
-  ../include/inn/portable-socket.h ../include/inn/ov.h \
-  ../include/inn/history.h ../include/inn/storage.h \
+  ../include/inn/vector.h ../include/inn/timer.h \
+  ../include/inn/fdflag.h ../include/inn/portable-socket.h \
+  ../include/inn/ov.h ../include/inn/history.h ../include/inn/storage.h \
   ../include/inn/innconf.h ../include/inn/messages.h \
   ../include/inn/version.h tls.h
 group.o: group.c ../include/config.h ../include/inn/defines.h \
@@ -133,8 +134,8 @@
   ../include/inn/qio.h ../include/inn/libinn.h ../include/inn/concat.h \
   ../include/inn/xmalloc.h ../include/inn/xwrite.h ../include/inn/nntp.h \
   ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h \
-  ../include/inn/vector.h ../include/inn/timer.h ../include/inn/ov.h \
-  ../include/inn/history.h ../include/inn/storage.h
+  ../include/inn/vector.h ../include/inn/timer.h \
+  ../include/inn/ov.h ../include/inn/history.h ../include/inn/storage.h
 line.o: line.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -146,7 +147,8 @@
   ../include/inn/qio.h ../include/inn/libinn.h ../include/inn/concat.h \
   ../include/inn/xmalloc.h ../include/inn/xwrite.h ../include/inn/nntp.h \
   ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h \
-  ../include/inn/vector.h ../include/inn/timer.h tls.h
+  ../include/inn/vector.h ../include/inn/timer.h \
+  tls.h
 list.o: list.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -158,8 +160,8 @@
   ../include/inn/libinn.h ../include/inn/concat.h ../include/inn/xmalloc.h \
   ../include/inn/xwrite.h ../include/inn/nntp.h ../include/inn/paths.h \
   ../include/inn/storage.h ../include/inn/options.h \
-  ../include/inn/vector.h ../include/inn/timer.h ../include/inn/ov.h \
-  ../include/inn/history.h ../include/inn/storage.h \
+  ../include/inn/vector.h ../include/inn/timer.h \
+  ../include/inn/ov.h ../include/inn/history.h ../include/inn/storage.h \
   ../include/inn/innconf.h ../include/inn/messages.h
 misc.o: misc.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
@@ -172,8 +174,9 @@
   ../include/inn/qio.h ../include/inn/libinn.h ../include/inn/concat.h \
   ../include/inn/xmalloc.h ../include/inn/xwrite.h ../include/inn/nntp.h \
   ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h \
-  ../include/inn/vector.h ../include/inn/timer.h tls.h ../include/inn/ov.h \
-  ../include/inn/history.h ../include/inn/storage.h
+  ../include/inn/vector.h ../include/inn/timer.h \
+  tls.h \
+  ../include/inn/ov.h ../include/inn/history.h ../include/inn/storage.h
 newnews.o: newnews.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -186,8 +189,9 @@
   ../include/inn/qio.h ../include/inn/libinn.h ../include/inn/concat.h \
   ../include/inn/xmalloc.h ../include/inn/xwrite.h ../include/inn/nntp.h \
   ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h \
-  ../include/inn/vector.h ../include/inn/timer.h ../include/inn/ov.h \
-  ../include/inn/history.h ../include/inn/storage.h cache.h
+  ../include/inn/vector.h ../include/inn/timer.h \
+  ../include/inn/ov.h ../include/inn/history.h ../include/inn/storage.h \
+  cache.h
 nnrpd.o: nnrpd.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -217,8 +221,10 @@
   ../include/inn/qio.h ../include/inn/libinn.h ../include/inn/concat.h \
   ../include/inn/xmalloc.h ../include/inn/xwrite.h ../include/inn/nntp.h \
   ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h \
-  ../include/inn/vector.h ../include/inn/timer.h post.h \
-  ../include/ppport.h ../include/innperl.h
+  ../include/inn/vector.h ../include/inn/timer.h \
+  post.h \
+  ../include/ppport.h \
+  ../include/innperl.h
 perm.o: perm.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -233,7 +239,8 @@
   ../include/inn/libinn.h ../include/inn/concat.h ../include/inn/xmalloc.h \
   ../include/inn/xwrite.h ../include/inn/nntp.h ../include/inn/paths.h \
   ../include/inn/storage.h ../include/inn/options.h \
-  ../include/inn/vector.h ../include/inn/timer.h tls.h
+  ../include/inn/vector.h ../include/inn/timer.h \
+  tls.h
 post.o: post.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -245,8 +252,9 @@
   ../include/inn/qio.h ../include/inn/libinn.h ../include/inn/concat.h \
   ../include/inn/xmalloc.h ../include/inn/xwrite.h ../include/inn/nntp.h \
   ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h \
-  ../include/inn/vector.h ../include/inn/timer.h ../include/inn/ov.h \
-  ../include/inn/history.h ../include/inn/storage.h post.h
+  ../include/inn/vector.h ../include/inn/timer.h \
+  ../include/inn/ov.h ../include/inn/history.h ../include/inn/storage.h \
+  post.h
 python.o: python.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -258,7 +266,8 @@
   ../include/inn/qio.h ../include/inn/libinn.h ../include/inn/concat.h \
   ../include/inn/xmalloc.h ../include/inn/xwrite.h ../include/inn/nntp.h \
   ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h \
-  ../include/inn/vector.h ../include/inn/timer.h ../include/inn/hashtab.h
+  ../include/inn/vector.h ../include/inn/timer.h \
+  ../include/inn/hashtab.h
 sasl.o: sasl.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -270,8 +279,9 @@
   ../include/inn/qio.h ../include/inn/libinn.h ../include/inn/concat.h \
   ../include/inn/xmalloc.h ../include/inn/xwrite.h ../include/inn/nntp.h \
   ../include/inn/paths.h ../include/inn/storage.h ../include/inn/options.h \
-  ../include/inn/vector.h ../include/inn/timer.h ../include/inn/ov.h \
-  ../include/inn/history.h ../include/inn/storage.h tls.h
+  ../include/inn/vector.h ../include/inn/timer.h \
+  ../include/inn/ov.h ../include/inn/history.h ../include/inn/storage.h \
+  tls.h
 tls.o: tls.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
@@ -283,8 +293,8 @@
   ../include/inn/libinn.h ../include/inn/concat.h ../include/inn/xmalloc.h \
   ../include/inn/xwrite.h ../include/inn/nntp.h ../include/inn/paths.h \
   ../include/inn/storage.h ../include/inn/options.h \
-  ../include/inn/vector.h ../include/inn/timer.h ../include/inn/innconf.h \
-  tls.h
+  ../include/inn/vector.h ../include/inn/timer.h \
+  ../include/inn/innconf.h tls.h
 track.o: track.c ../include/config.h ../include/inn/defines.h \
   ../include/inn/system.h ../include/inn/macros.h \
   ../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \

Modified: nnrpd/article.c
===================================================================
--- nnrpd/article.c	2017-04-05 19:44:24 UTC (rev 10136)
+++ nnrpd/article.c	2017-04-05 20:01:05 UTC (rev 10137)
@@ -20,6 +20,7 @@
 #include "tls.h"
 #include "cache.h"
 
+extern bool laxmid;
 #ifdef HAVE_OPENSSL
 extern SSL *tls_conn;
 #endif 
@@ -636,7 +637,7 @@
     ARTNUM		tart;
     bool                final = false;
 
-    mid = (ac > 1 && IsValidMessageID(av[1], true));
+    mid = (ac > 1 && IsValidMessageID(av[1], true, laxmid));
 
     /* Check the syntax of the arguments first. */
     if (ac > 1 && !IsValidArticleNumber(av[1])) {
@@ -931,7 +932,7 @@
     bool                xover, mid;
 
     xover = (strcasecmp(av[0], "XOVER") == 0);
-    mid = (ac > 1 && IsValidMessageID(av[1], true));
+    mid = (ac > 1 && IsValidMessageID(av[1], true, laxmid));
 
     if (mid && !xover) {
         /* FIXME:  We still do not support OVER MSGID, sorry! */
@@ -1151,7 +1152,7 @@
     bool                hdr, mid;
 
     hdr = (strcasecmp(av[0], "HDR") == 0);
-    mid = (ac > 2 && IsValidMessageID(av[2], true));
+    mid = (ac > 2 && IsValidMessageID(av[2], true, laxmid));
 
     /* Check the syntax of the arguments first. */
     if (ac > 2 && !IsValidRange(av[2])) {

Modified: nnrpd/commands.c
===================================================================
--- nnrpd/commands.c	2017-04-05 19:44:24 UTC (rev 10136)
+++ nnrpd/commands.c	2017-04-05 20:01:05 UTC (rev 10137)
@@ -14,6 +14,7 @@
 #include "inn/version.h"
 #include "tls.h"
 
+extern bool laxmid;
 #if defined(HAVE_OPENSSL)
 extern bool encryption_layer_on;
 #endif /* HAVE_OPENSSL */
@@ -625,7 +626,7 @@
     ihave = (strcasecmp(av[0], "IHAVE") == 0);
 
     /* Check whether the message-ID is valid for IHAVE. */
-    if (ihave && ac == 2 && !IsValidMessageID(av[1], true)) {
+    if (ihave && ac == 2 && !IsValidMessageID(av[1], true, laxmid)) {
         Reply("%d Syntax error in message-ID\r\n", NNTP_ERR_SYNTAX);
         return;
     }

Modified: nnrpd/nnrpd.c
===================================================================
--- nnrpd/nnrpd.c	2017-04-05 19:44:24 UTC (rev 10136)
+++ nnrpd/nnrpd.c	2017-04-05 20:01:05 UTC (rev 10137)
@@ -101,6 +101,9 @@
 bool GetHostByAddr = true;      /* Formerly DO_NNRP_GETHOSTBYADDR. */
 const char *NNRPinstance = "";
 
+/* Default values for the syntaxchecks parameter in inn.conf. */
+bool laxmid = false;
+
 #ifdef DO_PERL
 bool   PerlLoaded = false;
 #endif
@@ -1100,6 +1103,23 @@
     else
         NNRPACCESS = concatpath(innconf->pathetc,INN_PATH_NNRPACCESS);
 
+    /* Initialize the checks to perform or not on article syntax. */
+    if ((innconf->syntaxchecks != NULL) && (innconf->syntaxchecks->count > 0)) {
+        for (j = 0; j < innconf->syntaxchecks->count; j++) {
+            if (innconf->syntaxchecks->strings[j] != NULL) {
+                if (strcmp(innconf->syntaxchecks->strings[j], "laxmid") == 0) {
+                    laxmid = true;
+                } else if (strcmp(innconf->syntaxchecks->strings[j], 
+                                  "no-laxmid") == 0) {
+                    laxmid = false;
+                } else {
+                    syslog(L_NOTICE, "Unknown \"%s\" value in syntaxchecks "
+                           "parameter in inn.conf",
+                           innconf->syntaxchecks->strings[j]);
+                }
+            }
+        }
+    }
 
     if (DaemonMode) {
         /* Allocate an lfds array to hold the file descriptors

Modified: nnrpd/post.c
===================================================================
--- nnrpd/post.c	2017-04-05 19:44:24 UTC (rev 10136)
+++ nnrpd/post.c	2017-04-05 20:01:05 UTC (rev 10137)
@@ -23,6 +23,7 @@
 static const char * const BadDistribs[] = {
     BAD_DISTRIBS
 };
+extern bool laxmid;
 
 /*
 **  Do not modify the table without also looking at post.h for potential
@@ -459,7 +460,7 @@
     if (HDR(HDR__MESSAGEID) == NULL) {
 	HDR_SET(HDR__MESSAGEID, idbuff);
     }
-    if (!IsValidMessageID(HDR(HDR__MESSAGEID), true)) {
+    if (!IsValidMessageID(HDR(HDR__MESSAGEID), true, laxmid)) {
         return "Can't parse Message-ID: header";
     }
 

Modified: samples/inn.conf.in
===================================================================
--- samples/inn.conf.in	2017-04-05 19:44:24 UTC (rev 10136)
+++ samples/inn.conf.in	2017-04-05 20:01:05 UTC (rev 10137)
@@ -33,6 +33,7 @@
 #innflags:
 mailcmd:                     @bindir@/innmail
 #server:
+#syntaxchecks:               [ no-laxmid ]
 
 # Feed Configuration
 

Modified: support/mkmanifest
===================================================================
--- support/mkmanifest	2017-04-05 19:44:24 UTC (rev 10136)
+++ support/mkmanifest	2017-04-05 20:01:05 UTC (rev 10137)
@@ -290,6 +290,7 @@
 tests/lib/list.t
 tests/lib/md5.t
 tests/lib/memcmp.t
+tests/lib/messageid.t
 tests/lib/messages.t
 tests/lib/mkstemp.t
 tests/lib/network/addr-ipv4.t

Modified: tests/Makefile
===================================================================
--- tests/Makefile	2017-04-05 19:44:24 UTC (rev 10136)
+++ tests/Makefile	2017-04-05 20:01:05 UTC (rev 10137)
@@ -21,7 +21,7 @@
 	lib/getaddrinfo.t lib/getnameinfo.t lib/hash.t \
 	lib/hashtab.t lib/headers.t lib/hex.t lib/inet_aton.t \
 	lib/inet_ntoa.t lib/inet_ntop.t lib/innconf.t lib/list.t lib/md5.t \
-	lib/memcmp.t lib/messages.t lib/mkstemp.t \
+	lib/memcmp.t lib/messageid.t lib/messages.t lib/mkstemp.t \
 	lib/network/addr-ipv4.t lib/network/addr-ipv6.t \
 	lib/network/client.t lib/network/server.t \
 	lib/pread.t lib/pwrite.t lib/qio.t lib/reallocarray.t \
@@ -173,6 +173,9 @@
 lib/memcmp.t: lib/memcmp.o lib/memcmp-t.o tap/basic.o $(LIBINN)
 	$(LINK) lib/memcmp.o lib/memcmp-t.o tap/basic.o $(LIBINN)
 
+lib/messageid.t: lib/messageid-t.o tap/basic.o $(LIBINN)
+	$(LINK) lib/messageid-t.o tap/basic.o $(LIBINN)
+
 lib/messages.t: lib/messages-t.o tap/basic.o tap/process.o tap/string.o $(LIBINN)
 	$(LINK) lib/messages-t.o tap/basic.o tap/process.o tap/string.o \
 	    $(LIBINN)

Modified: tests/TESTS
===================================================================
--- tests/TESTS	2017-04-05 19:44:24 UTC (rev 10136)
+++ tests/TESTS	2017-04-05 20:01:05 UTC (rev 10137)
@@ -26,6 +26,7 @@
 lib/list
 lib/md5
 lib/memcmp
+lib/messageid
 lib/messages
 lib/mkstemp
 lib/network/addr-ipv4

Modified: tests/innd/fakeinnd.c
===================================================================
--- tests/innd/fakeinnd.c	2017-04-05 19:44:24 UTC (rev 10136)
+++ tests/innd/fakeinnd.c	2017-04-05 20:01:05 UTC (rev 10137)
@@ -26,6 +26,7 @@
 bool BufferedLogs = true;
 FILE *Log = NULL;
 FILE *Errlog = NULL;
+bool laxmid = false;
 
 /* We have to copy this here.  Bleh.  We only need to care about headers up to
    message ID and Path, but they have to be in the same order as in innd.c and

Index: trunk/tests/lib
===================================================================
--- tests/lib	2017-04-05 19:44:24 UTC (rev 10136)
+++ tests/lib	2017-04-05 20:01:05 UTC (rev 10137)

Property changes on: trunk/tests/lib
___________________________________________________________________
Modified: svn:ignore
## -22,6 +22,7 ##
 list.t
 md5.t
 memcmp.t
+messageid.t
 messages.t
 mkstemp.t
 pread.t
Added: tests/lib/messageid-t.c
===================================================================
--- tests/lib/messageid-t.c	                        (rev 0)
+++ tests/lib/messageid-t.c	2017-04-05 20:01:05 UTC (rev 10137)
@@ -0,0 +1,123 @@
+/*
+** messageid test suite.
+**
+** $Id$
+*/
+
+#define LIBTEST_NEW_FORMAT 1
+
+#include "inn/libinn.h"
+#include "tap/basic.h"
+
+void testMessageIDs(bool stripspaces, bool laxsyntax);
+
+/*
+ * Test a bunch of message-IDs that are always either bad or good, no matter
+ * how lax we are.
+ */
+void
+testMessageIDs(bool strip, bool lax)
+{
+    is_bool(false, IsValidMessageID(NULL, strip, lax),
+            "bad ID 1");
+    is_bool(false, IsValidMessageID("", strip, lax),
+            "bad ID 2");
+    is_bool(false, IsValidMessageID("<invalid at test", strip, lax),
+            "bad ID 3");
+    is_bool(false, IsValidMessageID("invalid at test>", strip, lax),
+            "bad ID 4");
+    is_bool(false, IsValidMessageID("<inva\177lid at test>", strip, lax),
+            "bad ID 5");
+    is_bool(false, IsValidMessageID("<inva lid at test>", strip, lax),
+            "bad ID 6");
+    is_bool(false, IsValidMessageID("<invalid at te\tst>", strip, lax),
+            "bad ID 7");
+    is_bool(false, IsValidMessageID("<invalid>", strip, lax),
+            "bad ID 8");
+    is_bool(false, IsValidMessageID("<inva\r\nlid at test>", strip, lax),
+            "bad ID 9");
+    is_bool(false, IsValidMessageID("<inva(lid at test>", strip, lax),
+            "bad ID 10");
+    is_bool(false, IsValidMessageID("<inva;lid at test>", strip, lax),
+            "bad ID 11");
+    is_bool(false, IsValidMessageID("<inva\"lid at test>", strip, lax),
+            "bad ID 12");
+    is_bool(false, IsValidMessageID("<inva>lid at test>", strip, lax),
+            "bad ID 13");
+    is_bool(false, IsValidMessageID("<inva<lid at test>", strip, lax),
+            "bad ID 14");
+    is_bool(false, IsValidMessageID("<>", strip, lax),
+            "bad ID 15");
+    is_bool(false, IsValidMessageID("<a@>", strip, lax),
+            "bad ID 16");
+    is_bool(false, IsValidMessageID("<123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 at 1234567890>", strip, lax),
+            "bad ID 17");
+    is_bool(false, IsValidMessageID("<inva...lid at test>", strip, lax),
+            "bad ID 18");
+    is_bool(false, IsValidMessageID("<invalid at yEnc@twice at test>", strip, lax),
+            "bad ID 19");
+    is_bool(false, IsValidMessageID("<invalid. at test>", strip, lax),
+            "bad ID 20");
+    is_bool(false, IsValidMessageID("<invalid@>", strip, lax),
+            "bad ID 21");
+    is_bool(false, IsValidMessageID("<@invalid>", strip, lax),
+            "bad ID 22");
+    is_bool(false, IsValidMessageID("<invalid at test.>", strip, lax),
+            "bad ID 23");
+    is_bool(false, IsValidMessageID("<inva[lid at test>", strip, lax),
+            "bad ID 24");
+    is_bool(false, IsValidMessageID("<invalid at t[es]t>", strip, lax),
+            "bad ID 25");
+    is_bool(false,  IsValidMessageID("<valid@[t@].[e<s].t>", strip, lax),
+            "bad ID 26");
+
+    is_bool(true,  IsValidMessageID("<valid at test>", strip, lax),
+            "good ID 1");
+    is_bool(true,  IsValidMessageID("<v4l.#%-{T`?*!.id at te|st>", strip, lax),
+            "good ID 2");
+    is_bool(true,  IsValidMessageID("<a at b>", strip, lax),
+            "good ID 3");
+    is_bool(true,  IsValidMessageID("<a.valid.id at testing.fr>", strip, lax),
+            "good ID 4");
+    is_bool(true,  IsValidMessageID("<valid@[te.st]>", strip, lax),
+            "good ID 5");
+    is_bool(true,  IsValidMessageID("<valid@[te;s@<t]>", strip, lax),
+            "good ID 6");
+}
+
+
+
+int
+main(void)
+{
+    plan(4*(25+7)+2+5);
+
+    InitializeMessageIDcclass();
+
+    /* Test several message-IDs with and without stripping spaces and lax
+     * syntax. */
+    testMessageIDs(true,  true);
+    testMessageIDs(true,  false);
+    testMessageIDs(false, true);
+    testMessageIDs(false, false);
+
+    /* Test whether stripping spaces works. */
+    is_bool(true,  IsValidMessageID(" \t\t <valid at test>\t  ", true, false),
+            "good ID stripspaces 1");
+    is_bool(false, IsValidMessageID(" \t\t <invalid at test>\t  ", false, false),
+            "bad ID stripspaces 1");
+
+    /* Test whether lax syntax works. */
+    is_bool(true,  IsValidMessageID("<valid at yEnc@test>", false, true),
+            "good ID laxsyntax 1");
+    is_bool(false, IsValidMessageID("<invalid at yEnc@test>", false, false),
+            "bad ID laxsyntax 1");
+    is_bool(true,  IsValidMessageID("<va..lid at test>", false, true),
+            "good ID laxsyntax 2");
+    is_bool(false, IsValidMessageID("<inva..lid at test>", false, false),
+            "bad ID laxsyntax 2");
+    is_bool(false, IsValidMessageID("<invalid at te..st>", false, true),
+            "bad ID laxsyntax 3");
+
+    return 0;
+}


Property changes on: trunk/tests/lib/messageid-t.c
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property


More information about the inn-committers mailing list