INN commit: trunk (9 files)

INN Commit Russ_Allbery at isc.org
Fri Dec 26 23:03:04 UTC 2008


    Date: Friday, December 26, 2008 @ 15:03:04
  Author: iulius
Revision: 8261

Allow the user to send 403 response codes (with an error string)
with nnrpd Perl and Python filters.
Only 281, 481 and 403 (as the default value) are possible.

Modified:
  trunk/doc/pod/hook-perl.pod
  trunk/doc/pod/hook-python.pod
  trunk/nnrpd/commands.c
  trunk/nnrpd/nnrpd.h
  trunk/nnrpd/perl.c
  trunk/nnrpd/perm.c
  trunk/nnrpd/python.c
  trunk/samples/nnrpd_auth.pl.in
  trunk/samples/nnrpd_auth.py

--------------------------+
 doc/pod/hook-perl.pod    |   13 ++++++-------
 doc/pod/hook-python.pod  |   11 +++++++++++
 nnrpd/commands.c         |   23 +++++++++++++++++++----
 nnrpd/nnrpd.h            |    6 +++---
 nnrpd/perl.c             |    9 +++++----
 nnrpd/perm.c             |   24 ++++++++++++------------
 nnrpd/python.c           |   13 +++++++------
 samples/nnrpd_auth.pl.in |    2 +-
 samples/nnrpd_auth.py    |    3 ++-
 9 files changed, 66 insertions(+), 38 deletions(-)

Modified: doc/pod/hook-perl.pod
===================================================================
--- doc/pod/hook-perl.pod	2008-12-26 19:26:42 UTC (rev 8260)
+++ doc/pod/hook-perl.pod	2008-12-26 23:03:04 UTC (rev 8261)
@@ -450,17 +450,16 @@
 by the client during authentication will be used for matching and
 logging.
 
-The NNTP response code should probably be 281 (authentication
-successful), 481 (authentication unsuccessful), or 400 (server
-failure).  If the code returned is anything other than 281, nnrpd will
-print an authentication error message and drop the connection and
-exit.
+The NNTP response code should be 281 (authentication successful),
+481 (authentication unsuccessful), or 403 (server failure).  If the
+code returned is anything other than than these three values, B<nnrpd>
+will use 403.
 
 If authenticate() dies (either due to a Perl error or due to calling die),
 or if it returns anything other than the two or three element array
 described above, an internal error will be reported to the client, the
-exact error will be logged to syslog, and nnrpd will drop the
-connection and exit.
+exact error will be logged to syslog, and B<nnrpd> will drop the
+connection and exit with a 400 response code.
 
 
 =head1 Dynamic Generation of Access Groups

Modified: doc/pod/hook-python.pod
===================================================================
--- doc/pod/hook-python.pod	2008-12-26 19:26:42 UTC (rev 8260)
+++ doc/pod/hook-python.pod	2008-12-26 23:03:04 UTC (rev 8261)
@@ -523,6 +523,17 @@
 string to be used in place of the client-supplied username (both for
 logging and for matching the connection with an access group).
 
+The NNTP response code should be 281 (authentication successful),
+481 (authentication unsuccessful), or 403 (server failure).  If the
+code returned is anything other than than these three values, B<nnrpd>
+will use 403.
+
+If C<authenticate> dies (either due to a Python error or due to
+calling die), or if it returns anything other than the two or three
+element array described above, an internal error will be reported
+to the client, the exact error will be logged to syslog, and B<nnrpd>
+will drop the connection and exit with a 400 response code.
+
 =item authen_close(I<self>)
 
 This method is invoked on B<nnrpd> termination.  You can use it to save

Modified: nnrpd/commands.c
===================================================================
--- nnrpd/commands.c	2008-12-26 19:26:42 UTC (rev 8260)
+++ nnrpd/commands.c	2008-12-26 23:03:04 UTC (rev 8261)
@@ -246,6 +246,8 @@
     static char	Password[SMBUF];
     char	accesslist[BIG_BUFFER];
     char        errorstr[BIG_BUFFER];
+    char        code[BIG_BUFFER];
+    int         codenum;
 
     if (strcasecmp(av[1], "GENERIC") == 0) {
 	char *logrec = Glom(av);
@@ -356,8 +358,9 @@
         strlcpy(Password, av[2], sizeof(Password));
 
         errorstr[0] = '\0';
-        
-        PERMlogin(User, Password, errorstr);
+        code[0] = '\0';
+
+        PERMlogin(User, Password, code, errorstr);
         PERMgetpermissions();
 
         /* If authentication is successful. */
@@ -375,12 +378,24 @@
             return;
         }
 
+        codenum = atoi(code);
+
+        /* For backwards compatibility, we return 481 instead of 502 (which had
+         * the same meaning as 481 in RFC 2980). */
+        if (codenum == NNTP_ERR_ACCESS) {
+            codenum = NNTP_FAIL_AUTHINFO_BAD;
+        }
+
 	syslog(L_NOTICE, "%s bad_auth", Client.host);
+        /* Return 403 in case the return code is not 481. */
         if (errorstr[0] != '\0') {
             syslog(L_NOTICE, "%s script error str: %s", Client.host, errorstr);
-            Reply("%d %s\r\n", NNTP_FAIL_AUTHINFO_BAD, errorstr);
+            Reply("%d %s\r\n",
+                  codenum != NNTP_FAIL_AUTHINFO_BAD ? NNTP_FAIL_ACTION : codenum,
+                  errorstr);
         } else {
-            Reply("%d Authentication failed\r\n", NNTP_FAIL_AUTHINFO_BAD);
+            Reply("%d Authentication failed\r\n",
+                  codenum != NNTP_FAIL_AUTHINFO_BAD ? NNTP_FAIL_ACTION : codenum);
         }
     }
 }

Modified: nnrpd/nnrpd.h
===================================================================
--- nnrpd/nnrpd.h	2008-12-26 19:26:42 UTC (rev 8260)
+++ nnrpd/nnrpd.h	2008-12-26 23:03:04 UTC (rev 8261)
@@ -227,7 +227,7 @@
 extern bool		PERMartok(void);
 extern void		PERMgetaccess(char *nnrpaccess);
 extern void		PERMgetpermissions(void);
-extern void		PERMlogin(char *uname, char *pass, char *errorstr);
+extern void		PERMlogin(char *uname, char *pass, char* code, char *errorstr);
 extern bool		PERMmatch(char **Pats, char **list);
 extern bool		ParseDistlist(char ***argvp, char *list);
 extern void 		SetDefaultAccess(ACCESSGROUP*);
@@ -276,14 +276,14 @@
 #ifdef  DO_PERL
 extern void loadPerl(void);
 extern void perlAccess(char *user, struct vector *access_vec);
-extern int perlAuthenticate(char *user, char *passwd, char *errorstring, char*newUser);
+extern int perlAuthenticate(char *user, char *passwd, char *code, char *errorstring, char*newUser);
 extern void perlAuthInit(void);
 #endif /* DO_PERL */
 
 #ifdef	DO_PYTHON
 extern bool PY_use_dynamic;
 
-int PY_authenticate(char *path, char *Username, char *Password, char *errorstring, char *newUser);
+int PY_authenticate(char *path, char *Username, char *Password, char *code, char *errorstring, char *newUser);
 void PY_access(char* path, struct vector *access_vec, char *Username);
 void PY_close_python(void);
 int PY_dynamic(char *Username, char *NewsGroup, int PostFlag, char **reply_message);

Modified: nnrpd/perl.c
===================================================================
--- nnrpd/perl.c	2008-12-26 19:26:42 UTC (rev 8260)
+++ nnrpd/perl.c	2008-12-26 23:03:04 UTC (rev 8261)
@@ -327,13 +327,13 @@
 
 
 int
-perlAuthenticate(char *user, char *passwd, char *errorstring, char *newUser)
+perlAuthenticate(char *user, char *passwd, char *code, char *errorstring, char *newUser)
 {
     dSP;
     HV *attribs;
     int rc;
     char *p;
-    int code;
+    int codenum;
     
     if (!PerlFilterActive)
         return NNTP_ERR_ACCESS;
@@ -385,7 +385,8 @@
     p = POPp;
     strlcpy(errorstring, p, BIG_BUFFER);
 
-    code = POPi;
+    codenum = POPi;
+    snprintf(code, sizeof(code), "%d", codenum);
 
     hv_undef(attribs);
 
@@ -393,7 +394,7 @@
     FREETMPS;
     LEAVE;
     
-    return code;
+    return codenum;
 }
 
 

Modified: nnrpd/perm.c
===================================================================
--- nnrpd/perm.c	2008-12-26 19:26:42 UTC (rev 8260)
+++ nnrpd/perm.c	2008-12-26 23:03:04 UTC (rev 8261)
@@ -85,7 +85,7 @@
 static bool MatchHost(char*, char*, char*);
 static int MatchUser(char*, char*);
 static char *ResolveUser(AUTHGROUP*);
-static char *AuthenticateUser(AUTHGROUP*, char*, char*, char*);
+static char *AuthenticateUser(AUTHGROUP*, char*, char*, char*, char*);
 
 static void GrowArray(void*, void*);
 static void PERMvectortoaccess(ACCESSGROUP *acc, const char *name, struct vector *acccess_vec) UNUSED;
@@ -1481,7 +1481,7 @@
 }
 
 void
-PERMlogin(char *uname, char *pass, char *errorstr)
+PERMlogin(char *uname, char *pass, char *code, char *errorstr)
 {
     int i   = 0;
     char *runame;
@@ -1507,7 +1507,7 @@
     runame  = NULL;
 
     while (runame == NULL && i--)
-	runame = AuthenticateUser(auth_realms[i], uname, pass, errorstr);
+	runame = AuthenticateUser(auth_realms[i], uname, pass, code, errorstr);
     if (runame) {
 	strlcpy(PERMuser, runame, sizeof(PERMuser));
         free(runame);
@@ -1959,7 +1959,7 @@
 */
 static char *
 AuthenticateUser(AUTHGROUP *auth, char *username, char *password,
-                 char *errorstr UNUSED)
+                 char *code UNUSED, char *errorstr UNUSED)
 {
     int i, j;
     char *command;
@@ -1983,7 +1983,7 @@
     for (i = 0; auth->auth_methods[i]; i++) {
         if (auth->auth_methods[i]->type == PERMperl_auth) {
 #ifdef DO_PERL
-            int code;
+            int codenum;
             char *script_path, *cp;
             char **args;
             char newUser[BIG_BUFFER];
@@ -2000,8 +2000,8 @@
                 perlAuthInit();
 
                 newUser[0] = '\0';
-                code = perlAuthenticate(username, password, errorstr, newUser);
-                if (code == NNTP_OK_AUTHINFO) {
+                codenum = perlAuthenticate(username, password, code, errorstr, newUser);
+                if (codenum == NNTP_OK_AUTHINFO) {
                     if (newUser[0] != '\0')
                         user = xstrdup(newUser);
                     else
@@ -2021,7 +2021,7 @@
 #endif	/* DO_PERL */
         } else if (auth->auth_methods[i]->type == PERMpython_auth) {
 #ifdef DO_PYTHON
-            int code;
+            int codenum;
             char *script_path, *cp;
             char **args;
             char newUser[BIG_BUFFER];
@@ -2032,10 +2032,10 @@
             script_path = concat(args[0], (char *) 0);
             if ((script_path != NULL) && (strlen(script_path) > 0)) {
                 newUser[0] = '\0';
-                code = PY_authenticate(script_path, username, password,
-                                       errorstr, newUser);
+                codenum = PY_authenticate(script_path, username, password,
+                                       code, errorstr, newUser);
                 free(script_path);
-                if (code == NNTP_OK_AUTHINFO) {
+                if (codenum == NNTP_OK_AUTHINFO) {
                     if (newUser[0] != '\0')
                         user = xstrdup(newUser);
                     else
@@ -2046,7 +2046,7 @@
                         fflush(locallog);
                     }
                     break;
-                } else if (code < 0) {
+                } else if (codenum < 0) {
                     syslog(L_NOTICE, "PY_authenticate(): authentication skipped due to no Python authentication method defined.");
                 } else {
                     syslog(L_NOTICE, "%s bad_auth", Client.host);

Modified: nnrpd/python.c
===================================================================
--- nnrpd/python.c	2008-12-26 19:26:42 UTC (rev 8260)
+++ nnrpd/python.c	2008-12-26 23:03:04 UTC (rev 8261)
@@ -103,12 +103,12 @@
 **  is not defined.
 */
 int
-PY_authenticate(char* file, char *Username, char *Password, char *errorstring,
-                char *newUser)
+PY_authenticate(char* file, char *Username, char *Password, char *code,
+                char *errorstring, char *newUser)
 {
     PyObject    *result, *item, *proc;
     int         authnum;
-    int         code, i;
+    int         codenum, i;
     char        *temp;
 
     PY_load_python();
@@ -187,7 +187,8 @@
     }
 
     /* Store the code. */
-    code = PyInt_AS_LONG(item);
+    codenum = PyInt_AS_LONG(item);
+    snprintf(code, sizeof(code), "%d", codenum);
 
     /* Get the error string. */
     item = PyTuple_GetItem(result, 1);
@@ -232,10 +233,10 @@
     }
 
     /* Log auth result. */
-    syslog(L_NOTICE, "python authenticate method succeeded, return code %d, error string %s", code, errorstring);
+    syslog(L_NOTICE, "python authenticate method succeeded, return code %d, error string %s", codenum, errorstring);
 
     /* Return response code. */
-    return code;
+    return codenum;
 }
 
 

Modified: samples/nnrpd_auth.pl.in
===================================================================
--- samples/nnrpd_auth.pl.in	2008-12-26 19:26:42 UTC (rev 8260)
+++ samples/nnrpd_auth.pl.in	2008-12-26 23:03:04 UTC (rev 8261)
@@ -30,7 +30,7 @@
 use vars qw(%attributes %authcodes %users);
 
 # These codes are a widely implemented de facto standard.
-%authcodes = ('allowed' => 281, 'denied' => 481);
+%authcodes = ('allowed' => 281, 'denied' => 481, 'error' => 403);
 
 # This sub should perform any initialization work that the
 # authentication stuff needs.

Modified: samples/nnrpd_auth.py
===================================================================
--- samples/nnrpd_auth.py	2008-12-26 19:26:42 UTC (rev 8260)
+++ samples/nnrpd_auth.py	2008-12-26 23:03:04 UTC (rev 8261)
@@ -47,7 +47,8 @@
 
         # Create a list of NNTP codes to respond on authentication.
         self.authcodes = {  'ALLOWED': 281,
-                            'DENIED': 481
+                            'DENIED': 481,
+                            'ERROR': 403
         }
 
         syslog('notice', 'nnrpd authentication class instance created')




More information about the inn-committers mailing list