You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Dirk vanGulik <Di...@jrc.it> on 1996/07/24 19:56:34 UTC
loggin in anon
This is some logging for mod_auth_anon, forgot who
asked for it; this is not for inclusion in the core,
just to be informative, etc.
Dw.
*** /enrm/httpd/depot/apache_19960606010017/src/mod_auth_anon.c Wed May 29 09:00:22 1996
--- /enrm/httpd/src/mod_auth_anon.c Thu Jun 13 14:58:49 1996
***************
*** 59,65 ****
*
* Adapted to Shambhala by rst.
*
! * Version 0.5 May 1996
*
* Brutally raped by Dirk.vanGulik@jrc.it to
*
--- 59,65 ----
*
* Adapted to Shambhala by rst.
*
! * Version 0.7 Jun 1996
*
* Brutally raped by Dirk.vanGulik@jrc.it to
*
***************
*** 69,81 ****
*
* Just add the following tokes to your <directory> setup:
*
! * Anonymous magic-user-id [magic-user-id]...
*
! * Anonymous_MustGiveEmail [ on | off ] default = off
! * Anonymous_LogEmail [ on | off ] default = on
! * Anonymous_VerifyEmail [ on | off ] default = off
! * Anonymous_NoUserId [ on | off ] default = off
! * Anonymous_Authorative [ on | off ] default = off
*
* The magic user id is something like 'anonymous', it is NOT case sensitive.
*
--- 69,85 ----
*
* Just add the following tokes to your <directory> setup:
*
! * - Anonymous < magic-user-id [magic-user-id]...>
*
! * + Anonymous_MustGiveEmail [ on | off ] default = off
! * + Anonymous_LogEmail [ on | off ] default = on
! * + Anonymous_VerifyEmail [ on | off ] default = off
! * + Anonymous_NoUserId [ on | off ] default = off
! * + Anonymous_Authorative [ on | off ] default = off
! * + Anonymous_LogFile < filename >
! *
! * (Legend -: Can be used in access.conf, + can be used in srm.conf and
! * access.conf for local/server-wide scope)
*
* The magic user id is something like 'anonymous', it is NOT case sensitive.
*
***************
*** 87,92 ****
--- 91,100 ----
* in broken GUIs like W95 is often given by the user. The Default is off.
*
* Dirk.vanGulik@jrc.it; http://ewse.ceo.org; http://me-www.jrc.it/~dirkx
+ *
+ * Changes 0.5 Release
+ * 0.6 added separate logging
+ * 0.7 Made it pass -Wall, removed empty auth function
*
*/
***************
*** 96,101 ****
--- 104,129 ----
#include "http_log.h"
#include "http_protocol.h"
+ /* Because the server-config is not know to the directory config
+ * creation routine, we cannot copy the global defaults along.
+ * This routine allows the global settings to override the local
+ * ones if they are not set.
+ */
+ #define ISSET(local,global,x) (((local->x != UNSET) && (local->x==YES)) || ((local->x == UNSET) && (global->x==YES)))
+ #define NOSET( local,global,x) (((local->x != UNSET) && (local->x==NO)) || ((local->x == UNSET) && (global->x==NO)))
+
+ #define YES (1)
+ #define NO (0)
+ #define UNSET (-1)
+
+ #define NOT_OPEN (-1)
+
+ module anon_auth_module;
+
+ /* This is just a boring linked list containing
+ * all possible anonymous userID's
+ */
+
typedef struct auth_anon {
char *password;
struct auth_anon * next;
***************
*** 104,224 ****
typedef struct {
auth_anon *auth_anon_passwords;
int auth_anon_nouserid;
int auth_anon_logemail;
int auth_anon_verifyemail;
int auth_anon_mustemail;
int auth_anon_authorative;
-
} anon_auth_config_rec;
! void *create_anon_auth_dir_config (pool *p, char *d)
! {
anon_auth_config_rec * sec = (anon_auth_config_rec *)
pcalloc (p, sizeof(anon_auth_config_rec));
! if (!sec) return NULL; /* no memory... */
! /* just to illustrate the defaults really. */
! sec -> auth_anon_passwords =NULL;
sec -> auth_anon_nouserid =0;
sec -> auth_anon_logemail =1;
sec -> auth_anon_verifyemail =0;
sec -> auth_anon_mustemail =1;
sec -> auth_anon_authorative =0;
return sec;
! }
char *anon_set_passwd_flag (cmd_parms *cmd,
anon_auth_config_rec *sec, int arg) {
! sec->auth_anon_mustemail=arg;
return NULL;
}
char *anon_set_userid_flag (cmd_parms *cmd,
anon_auth_config_rec *sec, int arg) {
! sec->auth_anon_nouserid=arg;
return NULL;
}
char *anon_set_logemail_flag (cmd_parms *cmd,
anon_auth_config_rec *sec, int arg) {
! sec->auth_anon_logemail=arg;
return NULL;
}
char *anon_set_verifyemail_flag (cmd_parms *cmd,
anon_auth_config_rec *sec, int arg) {
! sec->auth_anon_verifyemail=arg;
return NULL;
}
char *anon_set_authorative_flag (cmd_parms *cmd,
anon_auth_config_rec *sec, int arg) {
! sec->auth_anon_authorative=arg;
return NULL;
}
char *anon_set_string_slots (cmd_parms *cmd,
anon_auth_config_rec *sec, char *arg) {
auth_anon * first;
if (!(*arg))
! return "Anonymous string cannot be empty, use Anonymous_NoUserId instead";
/* squeeze in a record */
first = sec->auth_anon_passwords;
!
if (
(!(sec->auth_anon_passwords=(auth_anon *) palloc(cmd -> pool, sizeof(auth_anon)))) ||
(!(sec->auth_anon_passwords->password = pstrdup(cmd -> pool, arg)))
) return "Failed to claim memory for an anonymous password...";
- /* and repair the next */
sec->auth_anon_passwords->next = first;
return NULL;
}
command_rec anon_auth_cmds[] = {
{ "Anonymous", anon_set_string_slots,
! NULL,OR_AUTHCFG, ITERATE, NULL },
! { "Anonymous_MustGiveEmail", anon_set_passwd_flag, NULL, OR_AUTHCFG, FLAG,
! "Limited to 'on' or 'off'" },
! { "Anonymous_NoUserId", anon_set_userid_flag, NULL, OR_AUTHCFG, FLAG,
! "Limited to 'on' or 'off'" },
! { "Anonymous_VerifyEmail", anon_set_verifyemail_flag, NULL, OR_AUTHCFG, FLAG,
! "Limited to 'on' or 'off'" },
! { "Anonymous_LogEmail", anon_set_logemail_flag, NULL, OR_AUTHCFG, FLAG,
! "Limited to 'on' or 'off'" },
! { "Anonymous_Authorative", anon_set_authorative_flag, NULL, OR_AUTHCFG, FLAG,
! "Limited to 'on' or 'off'" },
{ NULL }
};
! module anon_auth_module;
int anon_authenticate_basic_user (request_rec *r)
{
anon_auth_config_rec *sec =
(anon_auth_config_rec *)get_module_config (r->per_dir_config,
&anon_auth_module);
conn_rec *c = r->connection;
char *send_pw;
char errstr[MAX_STRING_LEN];
int res=DECLINED;
-
if ((res=get_basic_auth_pw (r,&send_pw)))
! return res;
/* Ignore if we are not configured */
if (!sec->auth_anon_passwords) return DECLINED;
/* Do we allow an empty userID and/or is it the magic one
! */
!
! if ( (!(c->user[0])) && (sec->auth_anon_nouserid) ) {
res=OK;
} else {
auth_anon *p=sec->auth_anon_passwords;
--- 132,431 ----
typedef struct {
auth_anon *auth_anon_passwords;
+
+ char *auth_anon_logfile;
+ int auth_anon_fd;
+
int auth_anon_nouserid;
int auth_anon_logemail;
int auth_anon_verifyemail;
int auth_anon_mustemail;
int auth_anon_authorative;
} anon_auth_config_rec;
!
! void *create_config (pool *p) {
anon_auth_config_rec * sec = (anon_auth_config_rec *)
pcalloc (p, sizeof(anon_auth_config_rec));
! return sec;
! }
! void *create_anon_server_config (pool *p, server_rec *s) {
!
! anon_auth_config_rec * sec = (anon_auth_config_rec *)
! pcalloc (p, sizeof(anon_auth_config_rec));
+ /* just to illustrate the defaults really. */
+ sec -> auth_anon_fd =NOT_OPEN;
sec -> auth_anon_nouserid =0;
sec -> auth_anon_logemail =1;
sec -> auth_anon_verifyemail =0;
sec -> auth_anon_mustemail =1;
sec -> auth_anon_authorative =0;
+
+ sec -> auth_anon_passwords =NULL;
+ sec -> auth_anon_logfile =NULL;
return sec;
! };
!
! void *create_anon_auth_dir_config (pool *p, char *d) {
! anon_auth_config_rec * sec = (anon_auth_config_rec *)
! pcalloc (p, sizeof(anon_auth_config_rec));
!
! /* just to illustrate the defaults really. */
! sec -> auth_anon_fd =NOT_OPEN;
! sec -> auth_anon_nouserid =UNSET;
! sec -> auth_anon_logemail =UNSET;
! sec -> auth_anon_verifyemail =UNSET;
! sec -> auth_anon_mustemail =UNSET;
! sec -> auth_anon_authorative =UNSET;
!
! sec -> auth_anon_passwords =NULL;
! sec -> auth_anon_logfile =NULL;
! return sec;
! };
!
!
! /* These really should be replaced by a generic set_flag_slot()
! * (like a set_string_slot() in the http_config.c
! */
! int valid_flag_value(int x) {
! if (x) return YES;
! return NO;
! };
char *anon_set_passwd_flag (cmd_parms *cmd,
anon_auth_config_rec *sec, int arg) {
! sec->auth_anon_mustemail=valid_flag_value(arg);
return NULL;
}
char *anon_set_userid_flag (cmd_parms *cmd,
anon_auth_config_rec *sec, int arg) {
! sec->auth_anon_nouserid=valid_flag_value(arg);
return NULL;
}
char *anon_set_logemail_flag (cmd_parms *cmd,
anon_auth_config_rec *sec, int arg) {
! sec->auth_anon_logemail=valid_flag_value(arg);
return NULL;
}
char *anon_set_verifyemail_flag (cmd_parms *cmd,
anon_auth_config_rec *sec, int arg) {
! sec->auth_anon_verifyemail=valid_flag_value(arg);
return NULL;
}
char *anon_set_authorative_flag (cmd_parms *cmd,
anon_auth_config_rec *sec, int arg) {
! sec->auth_anon_authorative=valid_flag_value(arg);
! return NULL;
! }
!
! char *anon_set_anon_logfile (cmd_parms *cmd,
! anon_auth_config_rec *sec, char *arg) {
!
! /* Endorsed 'HACK' to find out wether we are talking
! * about the server as a whole (srm.conf) or just about
! * a directory in access.conf.
! */
! if (!(cmd->path))
! sec=(anon_auth_config_rec *) get_module_config(cmd->server->module_config,&anon_auth_module);
!
! sec->auth_anon_logfile=arg;
!
return NULL;
}
+ /* This routine is called ITERating, and the escaping and " removal
+ * is already done for us.
+ */
char *anon_set_string_slots (cmd_parms *cmd,
anon_auth_config_rec *sec, char *arg) {
auth_anon * first;
if (!(*arg))
! return "An Anonymous string cannot be empty, use Anonymous_NoUserId instead";
/* squeeze in a record */
first = sec->auth_anon_passwords;
!
if (
(!(sec->auth_anon_passwords=(auth_anon *) palloc(cmd -> pool, sizeof(auth_anon)))) ||
(!(sec->auth_anon_passwords->password = pstrdup(cmd -> pool, arg)))
) return "Failed to claim memory for an anonymous password...";
sec->auth_anon_passwords->next = first;
return NULL;
}
+
+
command_rec anon_auth_cmds[] = {
{ "Anonymous", anon_set_string_slots,
! NULL,OR_AUTHCFG, ITERATE,
! "Magic 'anonymous' username"
! },
! { "Anonymous_LogFile", anon_set_anon_logfile,
! NULL,OR_ALL, TAKE1,
! "logfile for anonymous 'email/passwords'"
! },
! { "Anonymous_MustGiveEmail", anon_set_passwd_flag, NULL, OR_ALL, FLAG,
! "Limited to 'on' or 'off', enforce that the user must give a password"
! },
! { "Anonymous_NoUserId", anon_set_userid_flag, NULL, OR_ALL, FLAG,
! "Limited to 'on' or 'off', accept an empty userID string"
! },
! { "Anonymous_VerifyEmail", anon_set_verifyemail_flag, NULL, OR_ALL, FLAG,
! "Limited to 'on' or 'off', verify email addresses"
! },
! { "Anonymous_LogEmail", anon_set_logemail_flag, NULL, OR_ALL, FLAG,
! "Limited to 'on' or 'off', logs the email addresses"
! },
! { "Anonymous_Authorative", anon_set_authorative_flag, NULL, OR_ALL, FLAG,
! "Limited to 'on' or 'off', makes this module authorative"
! },
{ NULL }
};
!
! void anonymous_log_child (void *cmd)
! {
! /* Child process code for 'AgentLog "|..."';
! * may want a common framework for this, since I expect it will
! * be common for other foo-loggers to want this sort of thing...
! */
!
! cleanup_for_exec();
! signal (SIGHUP, SIG_IGN);
! execl (SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
! exit (1);
! }
!
! int open_anonymous_log (anon_auth_config_rec *sec, pool *p)
! {
! char *filename;
!
! /* Error handling is a bit peculiar; the routine is called
! * during an init, at which the error is printed on stderr
! * and it should exit(0) the server, and during run time
! * when it is up to the auth funct to do the error reporting.
! */
! if (!(sec->auth_anon_logfile))
! return 1;
!
! filename = server_root_relative (p, sec->auth_anon_logfile);
!
! if (sec->auth_anon_fd != NOT_OPEN) return 1; /* virtual log shared w/main server */
!
! if (*sec->auth_anon_logfile == '|') {
! FILE *pipe;
!
! spawn_child(p, anonymous_log_child, (void *)(sec->auth_anon_logfile+1),
! kill_after_timeout, &pipe, NULL);
!
! if (pipe == NULL) {
! sec->auth_anon_fd=NOT_OPEN;
! fprintf (stderr, "Couldn't fork child for Anonymous Logging process\n");
! return 0;
! }
! sec->auth_anon_fd = fileno (pipe);
! }
!
! else if(*sec->auth_anon_logfile != '\0') {
! if((sec->auth_anon_fd = popenf(p, filename,
! ( O_WRONLY | O_APPEND | O_CREAT ),
! #ifdef __EMX__
! ( S_IREAD | S_IWRITE )
! #else
! ( S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH )
! #endif
! )) < 0) {
! sec->auth_anon_fd=NOT_OPEN;
! fprintf(stderr,"httpd: could not open anonymous log file %s.\n", filename);
! perror("open");
! return 0;
! }
! }
! return 1;
! }
!
! int anonymous_log_transaction(request_rec *r,char *email)
! {
! anon_auth_config_rec *sec =
! (anon_auth_config_rec *)get_module_config (r->per_dir_config,
! &anon_auth_module);
! anon_auth_config_rec *pec =
! (anon_auth_config_rec *)get_module_config (r->server->module_config,
! &anon_auth_module);
! pool *p = r->pool;
! char sign,str[MAX_STRING_LEN];
! long timz;
! struct tm *t;
!
! /* where is the filename/file_fd ? */
! if (!sec->auth_anon_logfile)
! sec=pec;
!
! /* do we really want logging ? */
! if (!(sec->auth_anon_logfile))
! return OK;
!
! /* is there an Email address to log ? */
! if (!(*email))
! return OK;
!
! /* do we need to (re-) open the file ? */
! if (sec->auth_anon_fd==NOT_OPEN) {
! if (!(open_anonymous_log (sec,p))) {
! sprintf(str,"Anonymous: Could not open my logfile '%s': %s",
! sec->auth_anon_logfile,strerror(errno)
! );
! log_error (str, r->server );
! return 0;
! };
! };
!
! t = get_gmtoff(&timz);
! sign = (timz < 0 ? '-' : '+');
! if(timz < 0)
! timz = -timz;
!
! strftime(str,MAX_STRING_LEN,"[%d/%b/%Y:%H:%M:%S ",t);
!
! sprintf(&str[strlen(str)], "%c%02ld%02ld] %s\n", sign, timz/3600,
! timz%3600, email);
!
! return (int) ( strlen(str) == write(sec->auth_anon_fd, str, strlen(str)) );
! }
!
int anon_authenticate_basic_user (request_rec *r)
{
anon_auth_config_rec *sec =
(anon_auth_config_rec *)get_module_config (r->per_dir_config,
&anon_auth_module);
+ anon_auth_config_rec *pec =
+ (anon_auth_config_rec *)get_module_config (r->server->module_config,
+ &anon_auth_module);
conn_rec *c = r->connection;
char *send_pw;
char errstr[MAX_STRING_LEN];
int res=DECLINED;
if ((res=get_basic_auth_pw (r,&send_pw)))
! return DECLINED;
/* Ignore if we are not configured */
if (!sec->auth_anon_passwords) return DECLINED;
+
/* Do we allow an empty userID and/or is it the magic one
! */
! if ( (!(c->user[0])) && (ISSET(sec,pec,auth_anon_nouserid))) {
res=OK;
} else {
auth_anon *p=sec->auth_anon_passwords;
***************
*** 227,296 ****
if (!(strcasecmp(c->user,p->password)))
res=OK;
p=p->next;
! }
! }
if (
! /* username is OK */
! (res == OK) &&
! /* password been filled out ? */
! ( (!sec->auth_anon_mustemail) || strlen(send_pw) ) &&
! /* does the password look like an email address ? */
! ( (!sec->auth_anon_verifyemail) ||
(strpbrk("@",send_pw) != NULL) ||
(strpbrk(".",send_pw) != NULL)
)
) {
! if (sec->auth_anon_logemail) {
! sprintf(errstr,"Anonymous: Passwd <%s> Accepted",
send_pw ? send_pw : "\'none\'");
! log_error (errstr, r->server );
! }
return OK;
! } else {
! if (sec->auth_anon_authorative) {
sprintf(errstr,"Anonymous: Authorative, Passwd <%s> not accepted",
! send_pw ? send_pw : "\'none\'");
log_error(errstr,r->server);
return AUTH_REQUIRED;
! }
! /* Drop out the bottom to return DECLINED */
! }
!
! return DECLINED;
}
! int check_anon_access (request_rec *r) {
!
! #ifdef NOTYET
! conn_rec *c = r->connection;
! anon_auth_config_rec *sec =
! (anon_auth_config_rec *)get_module_config (r->per_dir_config,
! &anon_auth_module);
!
! if (!sec->auth_anon) return DECLINED;
!
! if ( strcasecmp(r->connection->user,sec->auth_anon ))
! return DECLINED;
! return OK;
! #endif
! return DECLINED;
! }
!
module anon_auth_module = {
STANDARD_MODULE_STUFF,
! NULL, /* initializer */
create_anon_auth_dir_config, /* dir config creater */
NULL, /* dir merger ensure strictness */
! NULL, /* server config */
NULL, /* merge server config */
anon_auth_cmds, /* command table */
NULL, /* handlers */
NULL, /* filename translation */
anon_authenticate_basic_user,/* check_user_id */
! check_anon_access, /* check auth */
NULL, /* check access */
NULL, /* type_checker */
NULL, /* fixups */
--- 434,521 ----
if (!(strcasecmp(c->user,p->password)))
res=OK;
p=p->next;
! };
! };
! /* Bail out if it is not our duty... */
! if (res != OK) {
! if (sec->auth_anon_authorative) {
! sprintf(errstr,"Anonymous: Authorative, Username <%s> not accepted as anonymous",
! c->user ? c->user : "\'none-given\'");
! log_error(errstr,r->server);
! return AUTH_REQUIRED;
! };
! return DECLINED;
! };
!
! /* Hairy policy check, for just an email string, or one which
! * actually has at least a '@' and a '.' if so configured.
! */
if (
! ( (NOSET(sec,pec,auth_anon_mustemail)) || strlen(send_pw) ) &&
! ( (NOSET(sec,pec,auth_anon_verifyemail)) ||
(strpbrk("@",send_pw) != NULL) ||
(strpbrk(".",send_pw) != NULL)
)
) {
!
! if (ISSET(sec,pec,auth_anon_logemail)) {
! /* Is there a log file specified, or can we use the
! * normal error log ?
! */
! if ((sec->auth_anon_logfile)||(pec->auth_anon_logfile)) {
! if (!(anonymous_log_transaction(r,send_pw))) {
! sprintf(errstr,"Anonymous: Could not write to my logfile '%s': %s",
! sec->auth_anon_logfile,strerror(errno)
! );
! log_error (errstr, r->server );
! };
! } else {
! /* Or fall back on the normal one ? */
! sprintf(errstr,"Anonymous: Passwd <%s> Accepted",
send_pw ? send_pw : "\'none\'");
! log_error (errstr, r->server );
! };
! };
!
return OK;
! };
!
! if (sec->auth_anon_authorative) {
sprintf(errstr,"Anonymous: Authorative, Passwd <%s> not accepted",
! send_pw ? send_pw : "\'none\'");
log_error(errstr,r->server);
return AUTH_REQUIRED;
! };
! return DECLINED;
}
! /* Just open them right away, so that the user gets the
! * error messages during init, rather then when it is too
! * late do do anything about them.
! */
! void init_anon_log ( server_rec *s, pool *p) {
! for( ; s ; s = s->next ) {
! anon_auth_config_rec * cf= (anon_auth_config_rec *)
! get_module_config(s->module_config,&anon_auth_module);
! if (!(open_anonymous_log ( cf , p )))
! exit(0);
! };
! };
module anon_auth_module = {
STANDARD_MODULE_STUFF,
! init_anon_log, /* initializer */
create_anon_auth_dir_config, /* dir config creater */
NULL, /* dir merger ensure strictness */
! create_anon_server_config, /* server config */
NULL, /* merge server config */
anon_auth_cmds, /* command table */
NULL, /* handlers */
NULL, /* filename translation */
anon_authenticate_basic_user,/* check_user_id */
! NULL, /* check auth */
NULL, /* check access */
NULL, /* type_checker */
NULL, /* fixups */