Revised patch for merging nnrpperlauth and readers.conf
Erik Klavon
erik at eriq.org
Wed Jan 16 08:03:56 UTC 2002
Greetings
I have been making changes to nnrpd in order to combine the
functionality of the perl authentication hooks and readers.conf. This
has been achived through the addition of two new parameters for auth
groups. The diff of these modifications (revised version) are at the
end of this message.
perl_auth allows the use of perl to authenticate a user. It works in
the same manner as auth:
perl_auth: "/path/to/script/auth1.pl"
It is a special type of auth: the only difference is that it calls the
script given as argument using the perl hook rather then an external
program. Multiple/mixed use of auth: and perl_auth: is permitted
within any auth group. Each method is tried in order as they appear in
the auth group. Initialization of the perl code is delayed so that it
is only loaded when needed (when the nnrpd-perl auth method is reached
or the perl filter is used or perl_access is reached as described
below).
The file given as argument to perl_auth should contain the same
procedures as before. The hash global hash %attributes remains the
same, except for the removal of the "type" entry which is no longer
needed in this modification. The return array now only contains two
elements, the first of which is the NNTP return code. The second is an
error string which is passed to the client if the error code indicates
that the authentication attempt has failed. This allows a specific
error message to be generated by the perl script in place of
"Authentication failed".
To dynamically generate an access group for an auth group using a perl
script, use the parameter:
perl_access: "/path/to/access.pl"
where access.pl contains a function named "access" described below.
If an auth group is successful and contains a perl_access parameter,
then the argument perl script will be used to create an access
group. This group will then be used to determine the access rights of
the client, overriding any access groups in readers.conf. If a
sucessful auth group does not contain the perl_access parameter, then
readers.conf access groups are used to determine the client's rights.
A global hash %attributes exists where `$attributes{hostname}' will
contain the hostname (or the IP address if it doesn't resolve) of the
client machine and `$attributes{ipaddress}' will contain its IP
address (as a string). `$attributes{interface}' will contain the
interface. If a username is available, `$attributes{username}' will
contain the provided username.
access() returns a hash, containing the desiered access parameters and
values. Here is a trival example:
sub access {
%return_hash = (
"read" => "*",
"post" => "local.*",
"virtualhost" => "true",
# ...
);
return %return_hash;
}
This functionality should provide all of the existing capabilities of
the perl hook, in combination with the flexability of readers.conf and
the use of other authentication and resolving programs.
The perl_access concept implemented above is due to Jeffrey
M. Vinocur.
---------------------------------------------
What follows is a diff for all modifications.
---------------------------------------------
diff -r -C3 inn/include/conffile.h inn_patch/include/conffile.h
*** inn/include/conffile.h Fri Nov 19 00:53:12 1999
--- inn_patch/include/conffile.h Tue Jan 15 21:56:15 2002
***************
*** 12,17 ****
--- 12,19 ----
char *buf;
unsigned int sbuf;
int lineno;
+ int array_len;
+ char **array;
char *filename;
} CONFFILE;
diff -r -C3 inn/lib/conffile.c inn_patch/lib/conffile.c
*** inn/lib/conffile.c Wed Oct 4 17:36:51 2000
--- inn_patch/lib/conffile.c Tue Jan 15 22:24:35 2002
***************
*** 9,14 ****
--- 9,36 ----
#include "libinn.h"
#include "macros.h"
+ int getline(CONFFILE *F, char *buffer, int length) {
+ if (F->f) {
+ fgets(buffer, length, F->f);
+ } else if (F->array) {
+ strncpy(buffer, F->array[F->lineno], length);
+ }
+ F->lineno++;
+ if (strlen (F->buf) == F->sbuf) {
+ return 1; /* Line too long */
+ } else {
+ return 0;
+ }
+ }
+
+ int cfeof(CONFFILE *F) {
+ if (F->f) {
+ return feof(F->f);
+ } else if (F->array) {
+ return (F->lineno == F->array_len);
+ }
+ }
+
static char *CONFgetword(CONFFILE *F)
{
register char *p;
***************
*** 19,32 ****
if (!F) return (NULL); /* No conf file */
if (!F->buf || !F->buf[0]) {
! if (feof (F->f)) return (NULL);
if (!F->buf) {
F->sbuf = BIG_BUFFER;
F->buf = NEW(char, F->sbuf);
}
! fgets(F->buf, F->sbuf, F->f);
! F->lineno++;
! if (strlen (F->buf) == F->sbuf)
return (NULL); /* Line too long */
}
do {
--- 41,52 ----
if (!F) return (NULL); /* No conf file */
if (!F->buf || !F->buf[0]) {
! if (cfeof (F)) return (NULL);
if (!F->buf) {
F->sbuf = BIG_BUFFER;
F->buf = NEW(char, F->sbuf);
}
! if (getline(F, F->buf, F->sbuf) != 0)
return (NULL); /* Line too long */
}
do {
***************
*** 39,54 ****
}
for (p = F->buf; *p == ' ' || *p == '\t' ; p++);
flag = TRUE;
! if (*p == '\0' && !feof (F->f)) {
flag = FALSE;
! fgets(F->buf, F->sbuf, F->f);
! F->lineno++;
! if (strlen (F->buf) == F->sbuf)
return (NULL); /* Line too long */
continue;
}
break;
! } while (!feof (F->f) || !flag);
if (*p == '"') { /* double quoted string ? */
p++;
--- 59,72 ----
}
for (p = F->buf; *p == ' ' || *p == '\t' ; p++);
flag = TRUE;
! if (*p == '\0' && !cfeof(F)) {
flag = FALSE;
! if (getline(F, F->buf, F->sbuf))
return (NULL); /* Line too long */
continue;
}
break;
! } while (!cfeof(F) || !flag);
if (*p == '"') { /* double quoted string ? */
p++;
***************
*** 57,65 ****
*t != '\0'; t++);
if (*t == '\0') {
*t++ = '\n';
! fgets(t, F->sbuf - strlen (F->buf), F->f);
! F->lineno++;
! if (strlen (F->buf) == F->sbuf)
return (NULL); /* Line too long */
if ((s = strchr(t, '\n')) != NULL)
*s = '\0';
--- 75,81 ----
*t != '\0'; t++);
if (*t == '\0') {
*t++ = '\n';
! if (getline(F, t, F->sbuf - strlen(F->buf)))
return (NULL); /* Line too long */
if ((s = strchr(t, '\n')) != NULL)
*s = '\0';
***************
*** 66,72 ****
}
else
break;
! } while (!feof (F->f));
*t++ = '\0';
}
else {
--- 82,88 ----
}
else
break;
! } while (!cfeof(F));
*t++ = '\0';
}
else {
***************
*** 74,80 ****
if (*t != '\0')
*t++ = '\0';
}
! if (*p == '\0' && feof (F->f)) return (NULL);
word = COPY (p);
for (p = F->buf; *t != '\0'; t++)
*p++ = *t;
--- 90,96 ----
if (*t != '\0')
*t++ = '\0';
}
! if (*p == '\0' && cfeof(F)) return (NULL);
word = COPY (p);
for (p = F->buf; *t != '\0'; t++)
*p++ = *t;
***************
*** 101,106 ****
--- 117,123 ----
ret->sbuf = 0;
ret->lineno = 0;
ret->f = f;
+ ret->array = NULL;
return(ret);
}
diff -r -C3 inn/nnrpd/commands.c inn_patch/nnrpd/commands.c
*** inn/nnrpd/commands.c Fri Jun 29 14:42:23 2001
--- inn_patch/nnrpd/commands.c Mon Jan 14 15:51:57 2002
***************
*** 223,228 ****
--- 223,229 ----
static char User[30];
static char Password[30];
char accesslist[BIG_BUFFER];
+ char errorstr[BIG_BUFFER];
int code;
if (caseEQ(av[1], "generic")) {
***************
*** 285,316 ****
Password[sizeof Password - 1] = 0;
}
- #ifdef DO_PERL
- if (innconf->nnrpperlauth) {
- code = perlAuthenticate(ClientHost, ClientIp, ServerHost, User, Password, accesslist);
- if (code == NNTP_AUTH_OK_VAL) {
- PERMspecified = NGgetlist(&PERMreadlist, accesslist);
- PERMpostlist = PERMreadlist;
- syslog(L_NOTICE, "%s user %s", ClientHost, User);
- if (LLOGenable) {
- fprintf(locallog, "%s user (%s):%s\n", ClientHost, Username, User);
- fflush(locallog);
- }
- Reply("%d Ok\r\n", NNTP_AUTH_OK_VAL);
- /* save these values in case you need them later */
- strcpy(PERMuser, User);
- strcpy(PERMpass, Password);
- PERMneedauth = FALSE;
- PERMauthorized = TRUE;
- return;
- } else {
- syslog(L_NOTICE, "%s bad_auth", ClientHost);
- Reply("%d Authentication error\r\n", NNTP_ACCESS_VAL);
- ExitWithStats(1, FALSE);
- }
- } else {
- #endif /* DO_PERL */
-
#ifdef DO_PYTHON
if (innconf->nnrppythonauth) {
if ((code = PY_authenticate(ClientHost, ClientIp, ServerHost, User, Password, accesslist)) < 0) {
--- 286,291 ----
***************
*** 351,357 ****
PERMauthorized = TRUE;
return;
}
! PERMlogin(User, Password);
PERMgetpermissions();
if (!PERMneedauth) {
syslog(L_NOTICE, "%s user %s", ClientHost, User);
--- 326,335 ----
PERMauthorized = TRUE;
return;
}
!
! errorstr[0] = '\0';
!
! PERMlogin(User, Password, errorstr);
PERMgetpermissions();
if (!PERMneedauth) {
syslog(L_NOTICE, "%s user %s", ClientHost, User);
***************
*** 367,378 ****
#ifdef DO_PYTHON
}
#endif /* DO_PYTHON */
- #ifdef DO_PERL
- }
- #endif /* DO_PERL */
syslog(L_NOTICE, "%s bad_auth", ClientHost);
! Reply("%d Authentication error\r\n", NNTP_ACCESS_VAL);
ExitWithStats(1, FALSE);
}
--- 345,358 ----
#ifdef DO_PYTHON
}
#endif /* DO_PYTHON */
syslog(L_NOTICE, "%s bad_auth", ClientHost);
! if (errorstr[0] != '\0') {
! syslog(L_NOTICE, "%s perl error str: %s", ClientHost, errorstr);
! Reply("%d %s\r\n", NNTP_ACCESS_VAL, errorstr);
! } else {
! Reply("%d Authentication error\r\n", NNTP_ACCESS_VAL);
! }
ExitWithStats(1, FALSE);
}
diff -r -C3 inn/nnrpd/nnrpd.c inn_patch/nnrpd/nnrpd.c
*** inn/nnrpd/nnrpd.c Tue Sep 25 00:32:15 2001
--- inn_patch/nnrpd/nnrpd.c Sun Jan 13 19:13:17 2002
***************
*** 97,102 ****
--- 97,106 ----
static char *HostErrorStr;
bool GetHostByAddr = TRUE; /* formerly DO_NNRP_GETHOSTBYADDR */
+ #ifdef DO_PERL
+ bool PerlLoaded = FALSE;
+ #endif DO_PERL
+
extern void CMDauthinfo();
extern void CMDdate();
extern void CMDfetch();
***************
*** 504,526 ****
LogName[sizeof(LogName) - 1] = '\0';
syslog(L_NOTICE, "%s connect", ClientHost);
- #ifdef DO_PERL
- if (innconf->nnrpperlauth) {
- if ((code = perlConnect(ClientHost, ClientIp, ServerHost, accesslist)) == 502) {
- syslog(L_NOTICE, "%s no_access", ClientHost);
- Printf("%d You are not in my access file. Goodbye.\r\n",
- NNTP_ACCESS_VAL);
- ExitWithStats(1, TRUE);
- }
- PERMspecified = NGgetlist(&PERMreadlist, accesslist);
- PERMpostlist = PERMreadlist;
- if (!authconf)
- authconf = NEW(ACCESSGROUP, 1);
- PERMaccessconf = authconf;
- SetDefaultAccess(PERMaccessconf);
- } else {
- #endif /* DO_PERL */
-
#ifdef DO_PYTHON
if (innconf->nnrppythonauth) {
if ((code = PY_authenticate(ClientHost, ClientIp, ServerHost, NULL, NULL, accesslist)) < 0) {
--- 508,513 ----
***************
*** 546,554 ****
#ifdef DO_PYTHON
}
#endif /* DO_PYTHON */
- #ifdef DO_PERL
- }
- #endif /* DO_PERL */
}
--- 533,538 ----
***************
*** 658,682 ****
static void SetupDaemon(void) {
bool val;
- char *path;
time_t statinterval;
- #if defined(DO_PERL)
- /* Load the Perl code */
- path = concatpath(innconf->pathfilter, _PATH_PERL_FILTER_NNRPD);
- PERLsetup(NULL, path, "filter_post");
- free(path);
- if (innconf->nnrpperlauth) {
- path = concatpath(innconf->pathfilter, _PATH_PERL_AUTH);
- PERLsetup(NULL, path, "authenticate");
- free(path);
- PerlFilter(TRUE);
- perlAuthInit();
- } else {
- PerlFilter(TRUE);
- }
- #endif /* defined(DO_PERL) */
-
#ifdef DO_PYTHON
/* Load the Python code */
if (innconf->nnrppythonauth) {
--- 642,649 ----
diff -r -C3 inn/nnrpd/nnrpd.h inn_patch/nnrpd/nnrpd.h
*** inn/nnrpd/nnrpd.h Sun Jul 29 07:36:36 2001
--- inn_patch/nnrpd/nnrpd.h Tue Jan 15 21:33:19 2002
***************
*** 210,217 ****
#endif
char *HandleHeaders(char *article);
! int perlConnect(char *ClientHost, char *ClientIP, char *ServerHost, char *accesslist);
! int perlAuthenticate(char *ClientHost, char *ClientIP, char *ServerHost, char *user, char *passwd, char *accesslist);
bool ARTinstorebytoken(TOKEN token);
#ifdef DO_PYTHON
--- 210,217 ----
#endif
char *HandleHeaders(char *article);
! char **perlAccess(char *ClientHost, char *ClientIP, char *ServerHost, char *user);
! int perlAuthenticate(char *ClientHost, char *ClientIP, char *ServerHost, char *user, char *passwd, char *accesslist, char *errorstring);
bool ARTinstorebytoken(TOKEN token);
#ifdef DO_PYTHON
diff -r -C3 inn/nnrpd/perl.c inn_patch/nnrpd/perl.c
*** inn/nnrpd/perl.c Wed Oct 4 17:53:26 2000
--- inn_patch/nnrpd/perl.c Tue Jan 15 21:32:15 2002
***************
*** 41,46 ****
--- 41,49 ----
extern bool HeadersModified;
static int HeaderLen;
+ extern bool PerlLoaded;
+ void loadPerl(void);
+
/* #define DEBUG_MODIFY only if you want to see verbose outout */
#ifdef DEBUG_MODIFY
static FILE *flog;
***************
*** 62,67 ****
--- 65,74 ----
SV *modswitch;
int OtherSize;
+ if(!PerlLoaded) {
+ loadPerl();
+ }
+
if (!PerlFilterActive)
return NULL; /* not really necessary */
***************
*** 186,248 ****
return NULL;
}
! int perlConnect(char *ClientHost, char *ClientIP, char *ServerHost, char *accesslist) {
! dSP;
! HV *attribs;
! int rc;
! SV *sv;
! char *p;
! int code;
!
! if (!PerlFilterActive)
! return NNTP_ACCESS_VAL;
! ENTER;
! SAVETMPS;
! attribs = perl_get_hv("attributes", TRUE);
! hv_store(attribs, "type", 4, newSVpv("connect", 0), 0);
! hv_store(attribs, "hostname", 8, newSVpv(ClientHost, 0), 0);
! hv_store(attribs, "interface", 9, newSVpv(ServerHost, 0), 0);
! hv_store(attribs, "ipaddress", 9, newSVpv(ClientIP, 0), 0);
!
! PUSHMARK(SP);
! rc = perl_call_pv("authenticate", G_EVAL|G_ARRAY);
! SPAGAIN;
! if (rc == 0 ) { /* Error occured, same as checking $@ */
! syslog(L_ERROR, "Perl function authenticate died: %s",
! SvPV(ERRSV, PL_na));
! Reply("%d Internal Error (1). Goodbye\r\n", NNTP_ACCESS_VAL);
! ExitWithStats(1, TRUE);
! }
! if (rc != 5) {
! syslog(L_ERROR, "Perl function authenticate returned wrong number of results: %d", rc);
! Reply("%d Internal Error (2). Goodbye\r\n", NNTP_ACCESS_VAL);
! ExitWithStats(1, TRUE);
! }
! MaxBytesPerSecond = POPi;
! p = POPp;
! strcpy(accesslist, p);
! sv = POPs; PERMcanpost = SvTRUE(sv);
! sv = POPs; PERMcanread = SvTRUE(sv);
! code = POPi;
! if ((code == NNTP_POSTOK_VAL) || (code == NNTP_NOPOSTOK_VAL))
! code = PERMcanpost ? NNTP_POSTOK_VAL : NNTP_NOPOSTOK_VAL;
! if (code == NNTP_AUTH_NEEDED_VAL)
! PERMneedauth = TRUE;
! hv_undef(attribs);
! PUTBACK;
! FREETMPS;
! LEAVE;
!
! return code;
}
int perlAuthInit(void) {
--- 193,289 ----
return NULL;
}
! void loadPerl(void) {
! char *path;
! path = concatpath(innconf->pathfilter, _PATH_PERL_FILTER_NNRPD);
! PERLsetup(NULL, path, "filter_post");
! free(path);
! PerlFilter(TRUE);
! PerlLoaded = TRUE;
! }
! char *itoa(int n) {
! int i = 0;
! char *s = "";
! char *tmp;
! do {
! tmp = calloc(2, sizeof(char));
! tmp[0] = n % 10 + '0';
! tmp[1] = '\0';
! s = strcat(tmp, s);
! } while ((n /= 10) > 0);
! return s;
! }
! char **perlAccess(char *ClientHost, char *ClientIP, char *ServerHost, char *user) {
! dSP;
! HV *attribs;
! SV *sv;
! int rc, code, i;
! char *p, *key, *val, **access_array;
! if (!PerlFilterActive)
! return 0;
! ENTER;
! SAVETMPS;
!
! attribs = perl_get_hv("attributes", TRUE);
! hv_store(attribs, "hostname", 8, newSVpv(ClientHost, 0), 0);
! hv_store(attribs, "ipaddress", 9, newSVpv(ClientIP, 0), 0);
! hv_store(attribs, "interface", 9, newSVpv(ServerHost, 0), 0);
! hv_store(attribs, "username", 8, newSVpv(user, 0), 0);
! PUSHMARK(SP);
! if (perl_get_cv("access", 0) != NULL)
! rc = perl_call_pv("access", G_EVAL|G_ARRAY);
!
! SPAGAIN;
!
! if (rc == 0 ) { /* Error occured, same as checking $@ */
! syslog(L_ERROR, "Perl function access died: %s",
! SvPV(ERRSV, PL_na));
! Reply("%d Internal Error (1). Goodbye\r\n", NNTP_ACCESS_VAL);
! ExitWithStats(1, TRUE);
! }
!
! if ((rc % 2) != 0) {
! syslog(L_ERROR, "Perl function access returned an odd number of arguments: %i", rc);
! Reply("%d Internal Error (2). Goodbye\r\n", NNTP_ACCESS_VAL);
! ExitWithStats(1, TRUE);
! }
!
! i = (rc / 2) + 1;
! access_array = calloc(i, sizeof(char *));
! i--;
! p = itoa(i);
!
! i = 0;
!
! for (i = (rc / 2); i >= 1; i--) {
! sv = POPs;
! val = SvPV_nolen(sv);
! sv = POPs;
! key = SvPV_nolen(sv);
!
! key = strcat(key, ": \"");
! key = strcat(key, val);
! key = strcat(key, "\"\n");
! access_array[i] = COPY(key);
! }
!
! access_array[0] = COPY(p);
! free(p);
!
! PUTBACK;
! FREETMPS;
! LEAVE;
!
! return access_array;
}
int perlAuthInit(void) {
***************
*** 279,285 ****
}
! int perlAuthenticate(char *ClientHost, char *ClientIP, char *ServerHost, char *user, char *passwd, char *accesslist) {
dSP;
HV *attribs;
int rc;
--- 320,326 ----
}
! int perlAuthenticate(char *ClientHost, char *ClientIP, char *ServerHost, char *user, char *passwd, char *accesslist, char *errorstring) {
dSP;
HV *attribs;
int rc;
***************
*** 293,299 ****
ENTER;
SAVETMPS;
attribs = perl_get_hv("attributes", TRUE);
- hv_store(attribs, "type", 4, newSVpv("authenticate", 0), 0);
hv_store(attribs, "hostname", 8, newSVpv(ClientHost, 0), 0);
hv_store(attribs, "ipaddress", 9, newSVpv(ClientIP, 0), 0);
hv_store(attribs, "interface", 9, newSVpv(ServerHost, 0), 0);
--- 334,339 ----
***************
*** 312,328 ****
ExitWithStats(1, FALSE);
}
! if (rc != 5) {
syslog(L_ERROR, "Perl function authenticate returned wrong number of results: %d", rc);
Reply("%d Internal Error (2). Goodbye\r\n", NNTP_ACCESS_VAL);
ExitWithStats(1, FALSE);
}
- MaxBytesPerSecond = POPi;
p = POPp;
! strcpy(accesslist, p);
! sv = POPs; PERMcanpost = SvTRUE(sv);
! sv = POPs; PERMcanread = SvTRUE(sv);
code = POPi;
if ((code == NNTP_POSTOK_VAL) || (code == NNTP_NOPOSTOK_VAL))
--- 352,365 ----
ExitWithStats(1, FALSE);
}
! if (rc != 2) {
syslog(L_ERROR, "Perl function authenticate returned wrong number of results: %d", rc);
Reply("%d Internal Error (2). Goodbye\r\n", NNTP_ACCESS_VAL);
ExitWithStats(1, FALSE);
}
p = POPp;
! strcpy(errorstring, p);
code = POPi;
if ((code == NNTP_POSTOK_VAL) || (code == NNTP_NOPOSTOK_VAL))
diff -r -C3 inn/nnrpd/perm.c inn_patch/nnrpd/perm.c
*** inn/nnrpd/perm.c Thu Oct 18 20:56:53 2001
--- inn_patch/nnrpd/perm.c Tue Jan 15 22:46:30 2002
***************
*** 29,34 ****
--- 29,35 ----
typedef struct _METHOD {
char *name;
char *program;
+ int type; /* for seperating perl_auth from auth */
char *users; /* only used for auth_methods, not for res_methods. */
char **extra_headers;
char **extra_logs;
***************
*** 46,51 ****
--- 47,53 ----
char *default_user;
char *default_domain;
char *localaddress;
+ char *perl_access;
} AUTHGROUP;
typedef struct _GROUP {
***************
*** 58,64 ****
/* function declarations */
static void PERMreadfile(char *filename);
static void authdecl_parse(AUTHGROUP*, CONFFILE*, CONFTOKEN*);
! static void accessdecl_parse(ACCESSGROUP*, CONFFILE*, CONFTOKEN*);
static void method_parse(METHOD*, CONFFILE*, CONFTOKEN*, int);
static void add_authgroup(AUTHGROUP*);
--- 60,66 ----
/* function declarations */
static void PERMreadfile(char *filename);
static void authdecl_parse(AUTHGROUP*, CONFFILE*, CONFTOKEN*);
! static void accessdecl_parse(ACCESSGROUP *curaccess, CONFFILE *f, CONFTOKEN *tok);
static void method_parse(METHOD*, CONFFILE*, CONFTOKEN*, int);
static void add_authgroup(AUTHGROUP*);
***************
*** 76,84 ****
static bool MatchHost(char*, char*, char*);
static int MatchUser(char*, char*);
static char *ResolveUser(AUTHGROUP*);
! static char *AuthenticateUser(AUTHGROUP*, char*, char*);
static void GrowArray(void***, void*);
/* global variables */
static AUTHGROUP **auth_realms;
--- 78,87 ----
static bool MatchHost(char*, char*, char*);
static int MatchUser(char*, char*);
static char *ResolveUser(AUTHGROUP*);
! static char *AuthenticateUser(AUTHGROUP*, char*, char*, char*);
static void GrowArray(void***, void*);
+ static void PERMarraytoaccess(ACCESSGROUP *access, char *name, char **array, int array_len);
/* global variables */
static AUTHGROUP **auth_realms;
***************
*** 88,93 ****
--- 91,99 ----
static char *ConfigBit;
static int ConfigBitsize;
+ extern int LLOGenable;
+ extern bool PerlLoaded;
+
#define PERMlbrace 1
#define PERMrbrace 2
#define PERMgroup 3
***************
*** 143,153 ****
#define PERMlocaladdress 53
#define PERMrejectwith 54
#define PERMmaxbytespersecond 55
#ifdef HAVE_SSL
! #define PERMrequire_ssl 56
! #define PERMMAX 57
#else
! #define PERMMAX 56
#endif
#define TEST_CONFIG(a, b) \
--- 149,161 ----
#define PERMlocaladdress 53
#define PERMrejectwith 54
#define PERMmaxbytespersecond 55
+ #define PERMperl_auth 56
+ #define PERMperl_access 57
#ifdef HAVE_SSL
! #define PERMrequire_ssl 58
! #define PERMMAX 59
#else
! #define PERMMAX 58
#endif
#define TEST_CONFIG(a, b) \
***************
*** 228,233 ****
--- 236,243 ----
{ PERMlocaladdress, "localaddress:" },
{ PERMrejectwith, "reject_with:" },
{ PERMmaxbytespersecond, "max_rate:" },
+ { PERMperl_auth, "perl_auth:" },
+ { PERMperl_access, "perl_access:" },
#ifdef HAVE_SSL
{ PERMrequire_ssl, "require_ssl:" },
#endif
***************
*** 280,285 ****
--- 290,297 ----
(void*) COPY(orig->extra_logs[i]));
}
+ ret->type = orig->type;
+
return(ret);
}
***************
*** 363,368 ****
--- 375,385 ----
else
ret->localaddress = 0;
+ if (orig->perl_access)
+ ret->perl_access = COPY(orig->perl_access);
+ else
+ ret->perl_access = 0;
+
return(ret);
}
***************
*** 496,501 ****
--- 513,520 ----
DISPOSE(del->default_domain);
if (del->localaddress)
DISPOSE(del->localaddress);
+ if (del->perl_access)
+ DISPOSE(del->perl_access);
DISPOSE(del);
}
***************
*** 669,682 ****
}
break;
case PERMauth:
case PERMauthprog:
m = NEW(METHOD, 1);
memset(m, 0, sizeof(METHOD));
memset(ConfigBit, '\0', ConfigBitsize);
GrowArray((void***) &curauth->auth_methods, (void*) m);
! if (oldtype == PERMauthprog)
m->program = COPY(tok->name);
! else {
m->name = COPY(tok->name);
tok = CONFgettoken(PERMtoks, f);
--- 688,710 ----
}
break;
case PERMauth:
+ case PERMperl_auth:
case PERMauthprog:
m = NEW(METHOD, 1);
memset(m, 0, sizeof(METHOD));
memset(ConfigBit, '\0', ConfigBitsize);
GrowArray((void***) &curauth->auth_methods, (void*) m);
! if (oldtype == PERMauthprog) {
! m->type = PERMauthprog;
m->program = COPY(tok->name);
! } else if (oldtype == PERMperl_auth) {
! #ifdef DO_PERL
! m->type = PERMperl_auth;
! m->program = COPY(tok->name);
! #else
! ReportError(f, "perl_auth can not be used in readers.conf: inn not compiled with perl support enabled.");
! #endif
! } else {
m->name = COPY(tok->name);
tok = CONFgettoken(PERMtoks, f);
***************
*** 695,702 ****
ReportError(f, "Unexpected EOF.");
}
}
-
break;
case PERMlocaladdress:
curauth->localaddress = COPY(tok->name);
CompressList(curauth->localaddress);
--- 723,736 ----
ReportError(f, "Unexpected EOF.");
}
}
break;
+ case PERMperl_access:
+ #ifdef DO_PERL
+ curauth->perl_access = COPY(tok->name);
+ #else
+ ReportError(f, "perl_access can not be used in readers.conf: inn not compiled with perl support enabled.");
+ #endif
+ break;
case PERMlocaladdress:
curauth->localaddress = COPY(tok->name);
CompressList(curauth->localaddress);
***************
*** 703,709 ****
SET_CONFIG(PERMlocaladdress);
break;
default:
! ReportError(f, "Unexpected token.");
break;
}
}
--- 737,744 ----
SET_CONFIG(PERMlocaladdress);
break;
default:
! p = strcat("Unexpected token: ", tok->name);
! ReportError(f, p);
break;
}
}
***************
*** 712,718 ****
{
int oldtype, boolval;
bool bit;
! char buff[SMBUF], *oldname;
oldtype = tok->type;
oldname = tok->name;
--- 747,753 ----
{
int oldtype, boolval;
bool bit;
! char buff[SMBUF], *oldname, *p;
oldtype = tok->type;
oldname = tok->name;
***************
*** 945,955 ****
SET_CONFIG(oldtype);
break;
default:
! ReportError(f, "Unexpected token.");
break;
}
}
static void PERMreadfile(char *filename)
{
CONFCHAIN *cf = NULL,
--- 980,1019 ----
SET_CONFIG(oldtype);
break;
default:
! p = strcat("Unexpected token: ", tok->name);
! ReportError(f, p);
break;
}
}
+ static void PERMarraytoaccess(ACCESSGROUP *access, char *name, char **array, int array_len) {
+ CONFTOKEN *tok = NULL;
+ CONFFILE *file;
+ char *str;
+ int i;
+
+ file = NEW(CONFFILE, 1);
+ file->f = NULL;
+ file->array = array;
+ file->array_len = array_len;
+
+ memset(ConfigBit, '\0', ConfigBitsize);
+
+ SetDefaultAccess(access);
+ str = COPY(name);
+ access->name = str;
+
+ for (i = 0; i <= array_len; i++) {
+ tok = CONFgettoken(PERMtoks, file);
+
+ if (tok != NULL) {
+ accessdecl_parse(access, file, tok);
+ }
+ }
+
+ return;
+ }
+
static void PERMreadfile(char *filename)
{
CONFCHAIN *cf = NULL,
***************
*** 963,968 ****
--- 1027,1033 ----
int oldtype;
char *str = NULL;
char *path = NULL;
+ char *p;
if(filename != NULL) {
syslog(L_TRACE, "Reading access from %s",
***************
*** 1188,1194 ****
accessdecl_parse(curgroup->access, cf->f, tok);
break;
default:
! ReportError(cf->f, "Unexpected token.");
break;
}
} else if (inwhat == 1) {
--- 1253,1260 ----
accessdecl_parse(curgroup->access, cf->f, tok);
break;
default:
! p = strcat("Unexpected token: ", tok->name);
! ReportError(cf->f, p);
break;
}
} else if (inwhat == 1) {
***************
*** 1334,1340 ****
}
}
! void PERMlogin(char *uname, char *pass)
{
int i = 0;
char *runame;
--- 1400,1406 ----
}
}
! void PERMlogin(char *uname, char *pass, char *errorstr)
{
int i = 0;
char *runame;
***************
*** 1361,1367 ****
runame = NULL;
while (runame == NULL && i--)
! runame = AuthenticateUser(auth_realms[i], uname, pass);
if (runame) {
strcpy(PERMuser, runame);
uname = strchr(PERMuser, '@');
--- 1427,1433 ----
runame = NULL;
while (runame == NULL && i--)
! runame = AuthenticateUser(auth_realms[i], uname, pass, errorstr);
if (runame) {
strcpy(PERMuser, runame);
uname = strchr(PERMuser, '@');
***************
*** 1403,1408 ****
--- 1469,1479 ----
char *cp, **list;
char *user[2];
static ACCESSGROUP *noaccessconf;
+ char **access_array;
+ char *p, *uname;
+ char *cpp, *perl_path;
+ char **args;
+ int array_len = 0;
if (ConfigBit == NULL) {
if (PERMMAX % 8 == 0)
***************
*** 1420,1453 ****
PERMaccessconf = noaccessconf;
SetDefaultAccess(PERMaccessconf);
return;
! }
! for (i = 0; access_realms[i]; i++)
! ;
! user[0] = PERMuser;
! user[1] = 0;
! while (i--) {
! if ((!success_auth->key && !access_realms[i]->key) ||
! (access_realms[i]->key && success_auth->key &&
! strcmp(access_realms[i]->key, success_auth->key) == 0)) {
! if (!access_realms[i]->users)
! break;
! else if (!*PERMuser)
! continue;
! cp = COPY(access_realms[i]->users);
! list = 0;
! NGgetlist(&list, cp);
! if (PERMmatch(list, user)) {
! syslog(L_TRACE, "%s match_user %s %s", ClientHost,
! PERMuser, access_realms[i]->users);
! DISPOSE(cp);
! DISPOSE(list);
! break;
! } else
! syslog(L_TRACE, "%s no_match_user %s %s", ClientHost,
! PERMuser, access_realms[i]->users);
! DISPOSE(cp);
! DISPOSE(list);
}
}
if (i >= 0) {
/* found the right access group */
--- 1491,1569 ----
PERMaccessconf = noaccessconf;
SetDefaultAccess(PERMaccessconf);
return;
! #ifdef DO_PERL
! } else if (success_auth->perl_access != NULL) {
! i = 0;
! cpp = COPY(success_auth->perl_access);
! args = 0;
! Argify(cpp, &args);
! perl_path = concat(args[0], (char *) 0);
! if ((perl_path != NULL) && (strlen(perl_path) > 0)) {
! if(!PerlLoaded) {
! loadPerl();
! }
! PERLsetup(NULL, perl_path, "access");
! free(perl_path);
!
! uname = COPY(PERMuser);
! p = strchr(uname, '@');
!
! if (p != NULL) {
! *p = '\0';
! }
! DISPOSE(args);
!
! args = perlAccess(ClientHost, ClientIp, ServerHost, uname);
! p = args[0];
! array_len = atoi(p);
! access_array = args;
! access_array++;
!
! DISPOSE(uname);
!
! access_realms[0] = NEW(ACCESSGROUP, 1);
! memset(access_realms[0], 0, sizeof(ACCESSGROUP));
!
! PERMarraytoaccess(access_realms[0], "perl-dyanmic", access_array, array_len);
!
!
! } else {
! syslog(L_ERROR, "No script specified in auth method.\n");
! Reply("%d NNTP server unavailable. Try later.\r\n", NNTP_TEMPERR_VAL);
! ExitWithStats(1, TRUE);
! }
! DISPOSE(cpp);
! DISPOSE(args);
! #endif /* DO_PERL */
! } else {
! for (i = 0; access_realms[i]; i++)
! ;
! user[0] = PERMuser;
! user[1] = 0;
! while (i--) {
! if ((!success_auth->key && !access_realms[i]->key) ||
! (access_realms[i]->key && success_auth->key &&
! strcmp(access_realms[i]->key, success_auth->key) == 0)) {
! if (!access_realms[i]->users)
! break;
! else if (!*PERMuser)
! continue;
! cp = COPY(access_realms[i]->users);
! list = 0;
! NGgetlist(&list, cp);
! if (PERMmatch(list, user)) {
! syslog(L_TRACE, "%s match_user %s %s", ClientHost,
! PERMuser, access_realms[i]->users);
! DISPOSE(cp);
! DISPOSE(list);
! break;
! } else
! syslog(L_TRACE, "%s no_match_user %s %s", ClientHost,
! PERMuser, access_realms[i]->users);
! DISPOSE(cp);
! DISPOSE(list);
}
+ }
}
if (i >= 0) {
/* found the right access group */
***************
*** 1920,1927 ****
--- 2036,2046 ----
char *arg0;
char *resdir;
char *tmp;
+ char *perl_path;
EXECSTUFF *foo;
int done = 0;
+ int code;
+ char accesslist[BIG_BUFFER];
char buf[BIG_BUFFER];
if (!auth->res_methods)
***************
*** 1976,1982 ****
}
/* execute a series of authenticators to get the remote username */
! static char *AuthenticateUser(AUTHGROUP *auth, char *username, char *password)
{
int i, j;
char *cp;
--- 2095,2101 ----
}
/* execute a series of authenticators to get the remote username */
! static char *AuthenticateUser(AUTHGROUP *auth, char *username, char *password, char *errorstr)
{
int i, j;
char *cp;
***************
*** 1984,1991 ****
--- 2103,2113 ----
char *arg0;
char *resdir;
char *tmp;
+ char *perl_path;
EXECSTUFF *foo;
int done = 0;
+ int code;
+ char accesslist[BIG_BUFFER];
char buf[BIG_BUFFER];
if (!auth->auth_methods)
***************
*** 1997,2002 ****
--- 2119,2157 ----
ubuf[0] = '\0';
for (i = 0; auth->auth_methods[i]; i++) {
+ #ifdef DO_PERL
+ if (auth->auth_methods[i]->type == PERMperl_auth) {
+ cp = COPY(auth->auth_methods[i]->program);
+ args = 0;
+ Argify(cp, &args);
+ perl_path = concat(args[0], (char *) 0);
+ if ((perl_path != NULL) && (strlen(perl_path) > 0)) {
+ if(!PerlLoaded) {
+ loadPerl();
+ }
+ PERLsetup(NULL, perl_path, "authenticate");
+ free(perl_path);
+ perlAuthInit();
+
+ code = perlAuthenticate(ClientHost, ClientIp, ServerHost, username, password, accesslist, errorstr);
+ if (code == NNTP_AUTH_OK_VAL) {
+ syslog(L_NOTICE, "%s user %s", ClientHost, username);
+ if (LLOGenable) {
+ fprintf(locallog, "%s user %s\n", ClientHost, username);
+ fflush(locallog);
+ }
+
+ /* save these values in case you need them later */
+ strcpy(ubuf, username);
+ break;
+ } else {
+ syslog(L_NOTICE, "%s bad_auth", ClientHost);
+ }
+ } else {
+ syslog(L_ERROR, "No script specified in auth method.\n");
+ }
+ } else if (auth->auth_methods[i]->type == PERMauthprog) {
+ #endif /* DO_PERL */
if (auth->auth_methods[i]->users &&
!MatchUser(auth->auth_methods[i]->users, username))
continue;
***************
*** 2038,2043 ****
--- 2193,2201 ----
if (done)
/* this authenticator succeeded */
break;
+ #ifdef DO_PERL
+ }
+ #endif /* DO_PERL */
}
DISPOSE(resdir);
if (ubuf[0])
--
erik | "It is idle to think that, by means of words, | Maurice
kl at von | any real communication can ever pass | Maeterlinck
eriq.org | from one [human] to another." | Silence
More information about the inn-patches
mailing list