use
vars
qw($VERSION @ISA @EXPORT_OK)
;
$VERSION
=
substr
(
q$Revision: 1.2 $
, 10);
@ISA
=
qw(Exporter)
;
@EXPORT_OK
=
qw(&authen &authz)
;
sub
authen ($$) {
my
$that
=
shift
;
my
$r
=
shift
;
my
(
$ses_key_str
,
$cookie_path
,
$authen_script
);
my
(
$auth_user
,
$auth_name
,
$auth_type
);
my
@ses_key
;
$r
->log_error(
"that "
.
$that
);
return
OK
unless
$r
->is_initial_req;
$auth_type
=
$that
;
$auth_type
=~ s/::.*//;
$r
->log_error(
"auth_type "
.
$auth_type
);
if
(
$r
->auth_type ne
$auth_type
)
{
return
DECLINED;
}
$auth_name
=
$r
->auth_name;
$r
->log_error(
"auth_name "
.
$auth_name
);
if
(!(
$auth_name
))
{
$r
->log_reason(
$auth_type
.
"::Auth:authen need AuthName "
,
$r
->uri);
return
SERVER_ERROR;
}
$cookie_path
=
$r
->dir_config(
$auth_name
.
"Path"
);
if
(!(
$cookie_path
)) {
$r
->log_reason(
$auth_type
.
"::Auth:authen path not set for auth realm "
.
$auth_name
,
$r
->uri);
return
SERVER_ERROR;
}
local
(
$_
) =
$r
->header_in(
"Cookie"
) ||
""
;
$ses_key_str
=
""
;
if
(/${auth_type}_${auth_name}=/) {
s/.*${auth_type}_${auth_name}=//;
s/;.*//;
$ses_key_str
=
$_
;
}
$r
->log_error(
"ses_key_str "
.
$ses_key_str
);
$r
->log_error(
"cookie_path "
.
$cookie_path
);
$r
->log_error(
"filename "
.
$r
->filename);
$r
->log_error(
"uri "
.
$r
->uri);
if
(
$ses_key_str
)
{
@ses_key
=
split
(/:/,
$ses_key_str
);
}
elsif
(
$r
->method_number == M_POST)
{
my
%args
=
$r
->content;
if
(
$args
{
'AuthName'
} ne
$auth_name
||
$args
{
'AuthType'
} ne
$r
->auth_type)
{
$r
->log_reason(
$auth_type
.
"::Auth:authen credentials are not for"
.
"this realm or this is not an authentication responce "
,
$r
->uri);
return
SERVER_ERROR;
}
my
@credentials
;
while
(
$args
{
"credential_"
. (
$#credentials
+ 1)})
{
$r
->log_error(
"credential_"
. (
$#credentials
+ 1) .
" "
.
$args
{
"credential_"
. (
$#credentials
+ 1)});
push
(
@credentials
,
$args
{
"credential_"
. (
$#credentials
+ 1)});
}
@ses_key
=
$that
->authen_cred(
$r
,
@credentials
);
$r
->log_error(
"ses_key "
.
join
(
":"
,
@ses_key
));
$r
->method(
"GET"
);
$r
->method_number(M_GET);
}
elsif
(
$r
->method_number != M_GET)
{
$r
->log_reason(
$auth_type
.
"::Auth:authen auth header is not set and method is not GET "
,
$r
->uri);
return
SERVER_ERROR;
}
$r
->log_error(
"#ses_key "
.
$#ses_key
);
if
(
$#ses_key
>= 0) {
if
(
$auth_user
=
$that
->authen_ses_key(
$r
,
@ses_key
)) {
if
(!(
$ses_key_str
)) {
$r
->header_out(
"Set-Cookie"
=>
$auth_type
.
"_"
.
$auth_name
.
"="
.
join
(
":"
,
@ses_key
) .
"; path="
.
$cookie_path
);
$r
->log_error(
"set_cookie "
.
$r
->header_out(
"Set-Cookie"
));
}
$r
->connection->auth_type(
$auth_type
);
$r
->connection->user(
$auth_user
);
$r
->log_error(
"user authenticated as "
.
$auth_user
);
return
OK;
}
}
if
(
$ses_key_str
) {
$r
->header_out(
"Set-Cookie"
=>
$auth_type
.
"_"
.
$auth_name
.
"=; path="
.
$cookie_path
.
"; expires=Mon, 21-May-1971 00:00:00 GMT"
);
$r
->log_error(
"set_cookie "
.
$r
->header_out(
"Set-Cookie"
));
}
$r
->notes(
"AUTHZ_PASS"
, 1);
$authen_script
=
$r
->dir_config(
$auth_name
.
"AuthenticationScript"
) ||
""
;
if
(!(
$authen_script
)) {
$r
->log_reason(
$auth_type
.
"::Auth:authen authentication script not set for auth realm "
.
$auth_name
,
$r
->uri);
return
SERVER_ERROR;
}
if
(
$authen_script
!~ m|^/|) {
my
$document_root
=
$r
->document_root;
$document_root
.=
"/"
unless
$document_root
=~ m|/$|;
$authen_script
=
$document_root
.
$authen_script
;
}
$r
->filename(
$authen_script
);
$r
->handler(
"perl-script"
);
$r
->push_handlers(
"PerlHandler"
, \
&Apache::Registry::handler
);
$r
->method(
"GET"
);
$r
->method_number(M_GET);
$r
->log_error(
"sending you to the authentication page "
);
$r
->log_error(
"method "
.
$r
->method);
$r
->log_error(
"filename "
.
$r
->filename);
return
OK;
}
sub
authz ($$) {
my
$that
=
shift
;
my
$r
=
shift
;
my
(
$auth_name
,
$auth_type
);
return
OK
unless
$r
->is_initial_req;
$auth_type
=
$that
;
$auth_type
=~ s/::.*//;
if
(
$r
->auth_type ne
$auth_type
) {
return
DECLINED;
}
my
$note
=
$r
->notes(
"AUTHZ_PASS"
) ||
""
;
$r
->log_error(
$auth_type
.
"::Auth:authz note $auth_type "
.
$note
);
return
OK
if
(
$note
);
my
$reqs_arr
=
$r
->requires;
return
OK
unless
$reqs_arr
;
my
$user
=
$r
->connection->user;
if
(!(
$user
)) {
$r
->log_reason(
"No user authenticated"
,
$r
->uri);
return
FORBIDDEN;
}
my
(
$reqs
,
$requirement
,
$args
,
$restricted
);
foreach
$reqs
(
@$reqs_arr
) {
(
$requirement
,
$args
) =
split
/\s+/,
$reqs
->{requirement}, 2;
$r
->log_error(
"requirement := $requirement, $args"
);
if
(
$requirement
eq
"valid-user"
) {
return
OK;
}
elsif
(
$requirement
eq
"user"
) {
return
OK
if
(
$args
=~ m/\b
$user
\b/);
}
else
{
my
$req_method
;
if
(
$req_method
=
$that
->can(
$requirement
)) {
my
$ret_val
=
&$req_method
(
$that
,
$r
,
$args
);
$r
->log_error(
$that
.
" called requirement method "
.
$requirement
.
" which returned "
.
$ret_val
);
return
OK
if
(
$ret_val
== OK);
}
else
{
$r
->log_error(
$that
.
" tried to call undefined requirement method "
.
$requirement
);
}
}
$restricted
++;
}
return
OK
unless
$restricted
;
return
FORBIDDEN;
}
1;