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