Apache-Authen-Program
view release on metacpan or search on metacpan
123456789101112# Apache::Authen::Program allows you to call an external program
# that performs username/password authentication in Apache.
#
# Copyright (c) 2002-2004 Mark Leighton Fisher, Fisher's Creek Consulting, LLC
#
# This module is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
package
Apache::Authen::Program;
use
strict;
141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394$Apache::Authen::Program::VERSION
=
'0.93'
;
sub
handler {
my
$request
=
shift
;
# Apache request object
my
@args
= ();
# authentication program arguments
my
$cmd
=
""
;
# program command string
my
$i
= 0;
# counter for @args
my
$ofh
=
""
;
# output file handle for password temp file
my
$password
=
""
;
# password from Basic Authentication
my
$passfile
=
""
;
# temporary file containing password
my
$passtype
=
""
;
# "File" if communicating password by temp file
my
$program
=
""
;
# authentication program filename
my
$response
=
""
;
# Apache response object
my
$success
=
""
;
# success string from authentication program
my
$username
=
""
;
# username from Basic Authentication
# get password, decline if not Basic Authentication
(
$response
,
$password
) =
$request
->get_basic_auth_pw;
return
$response
if
$response
;
# get username
$username
=
$request
->connection->user;
if
(
$username
eq
""
) {
$request
->note_basic_auth_failure;
$request
->log_reason(
"Apache::Authen::Program - No Username Given"
,
$request
->uri);
return
AUTH_REQUIRED;
}
# get authentication program, args, and success string
$program
=
$request
->dir_config(
"AuthenProgram"
);
for
(
$i
= 1;
$i
< 10;
$i
++) {
$args
[
$i
] =
$request
->dir_config(
"AuthenProgramArg$i"
);
}
$success
=
$request
->dir_config(
"AuthenProgramSuccess"
);
# write temp. password file on request
$passtype
=
$request
->dir_config(
"AuthenProgramPassword"
);
if
(
$passtype
eq
"File"
) {
(
$ofh
,
$passfile
) = tempfile();
if
(!
defined
(
$ofh
) ||
$ofh
eq
""
) {
$request
->log_reason(
"Apache::Authen::Program can't create password file"
,
$request
->uri);
return
SERVER_ERROR;
}
chmod
(0600,
$passfile
)
||
$request
->log_reason(
"Apache::Authen::Program can't chmod 0600 password file '$passfile' because: $!"
,
$request
->uri);
if
(!
$ofh
$password
,
"\n"
) {
$request
->log_reason(
"Apache::Authen::Program can't write password file '$ofh'"
,
$request
->uri);
return
SERVER_ERROR;
}
if
(!
close
(
$ofh
)) {
$request
->log_reason(
"Apache::Authen::Program can't close password file '$ofh'"
,
$request
->uri);
return
SERVER_ERROR;
}
$password
=
$passfile
;
}
# execute command, then examine output for success or failure
$cmd
=
"$program '$username' '$password' "
;
$cmd
.=
join
(
' '
,
@args
);
my
@output
= `
$cmd
`;
if
(
$passtype
eq
"File"
) {
if
(!
unlink
(
$passfile
)) {
$request
->log_reason(
"Apache::Authen::Program can't delete password file '$ofh'"
,
$request
->uri);
}
}
if
(!
grep
(/
$success
/,
@output
)) {
$request
->note_basic_auth_failure;
$request
->log_reason(
"login failure: "
.
join
(
' '
,
@output
),
$request
->uri);
return
AUTH_REQUIRED;
}
unless
(@{
$request
->get_handlers(
"PerlAuthzHandler"
) || []}) {
162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
</Directory>
These directives can be used in a .htaccess file as well.
directive should follow whatever handler you
use
.
= head1 DESCRIPTION
This mod_perl module provides a reasonably general mechanism
to perform username/password authentication in Apache by
calling an external program. Authentication by an external
program is useful
when
a program can perform an authentication
not supported by any Apache modules (
for
example, cross-domain
authentication is not supported by Apache::NTLM or
Apache::AuthenSmb, but is supported by Samba's smbclient
program).
You must define the program pathname AuthenProgram and the
standard output success string AuthenProgramSuccess.
The first two arguments to the program are the username and
either the password or a temporary file
with
the password,
depending on whether AuthenProgramPassword
has
the value
"File"
.
"File"
forces sending the password to AuthenProgram through a
temporary file to avoid placing passwords on the command line where
they can be seen by ps(1).
Additional program arguments can be passed in the variables
AuthenProgramArg1, AuthenProgramArg2, etc. Up to 9 of these
variables are supported.
The examples/ subdirectory
has
sample programs
for
doing
Samba-based SMB authentication (examples/smblogon),
Oracle authentication (examples/oralogon), and
a simple example (examples/filelogon) that demonstrates communicating
the password through a temporary file.
If you are using this module please let me know, I'm curious how many
people there are that need this type of functionality.
This module was adapted from Apache::AuthenSmb.
=head1 DESIGN NOTES
This module trades off speed for flexibility -- it is not
recommended for use when you need to process lots of
123456789101112Apache::Authen::Program is a mod_perl module that provides a
reasonably general mechanism to perform username/password
authentication in Apache by calling an external program.
Authentication by an external program is useful
when
a
program can perform an authentication not supported by any
Apache modules (
for
example, cross-domain authentication is
not supported by Apache::AuthenNTLM or Apache::AuthenSmb, but
is supported by Samba's smbclient program).
Installing Apache::Authen::Program follows the normal CPAN
convention:
perl Makefile.PL
examples/filelogon view on Meta::CPAN
1234567891011121314151617181920212223242526272829303132333435#!/www/perl-5.6.1/bin/perl -Tw
# Simple authentication with password sent by file.
# ------ pragmas
use
strict;
# ------ define variables
my
$passfile
=
""
;
# password file
my
$password
=
""
;
# password for $username from $passfile
my
$username
=
""
;
# username to authenticate with
# ------ get username and password
if
(
scalar
(
@ARGV
) < 2) {
die
"usage: file-auth username passwordfile\n"
;
}
$ARGV
[0] =~ m
#([^`']+)#;
$username
= $1;
$ARGV
[1] =~ m
#([^`']+)#;
$passfile
= $1;
open
(IFH,
$passfile
)
||
die
"FAILURE: can't open password file '$passfile' because: $!\n"
;
$password
= <IFH>;
chomp
(
$password
);
close
(IFH)
||
die
"FAILURE: can't close password file '$passfile' because: $!\n"
;
if
(!
defined
(
$password
) ||
$password
=~ m/^\s*$/) {
die
"FAILURE: missing or empty password\n"
;
}
# ------ verify username/password
if
(
$username
eq
"fred"
&&
$password
eq
"Scooby-Do!2002"
) {
"OK: File login succeeded.\n"
;
}
else
{
"FAILURE: bad username or password.\n"
;
}
examples/oralogon view on Meta::CPAN
4567891011121314151617181920212223242526272829303132333435363738394041424344# NOTE: Runs in taint mode because it is usually
# invoked by other programs (mainly CGIs).
# ------ pragmas
use
strict;
# ------ define variables
my
$database
=
""
;
# Oracle TNS database name
my
@output
= ();
# output of SQL*Plus command
my
$password
=
""
;
# password for $username
my
$sqlplus
# Oracle SQL*Plus interactive query program
=
"/www/oracle/u01/app/oracle/product/7.3.4/bin/sqlplus"
;
my
$username
=
""
;
# Oracle username to authenticate with
# ------ force secure PATH
$ENV
{
"PATH"
} =
"/bin:/usr/bin"
;
# ------ extract username + password + database
if
(
scalar
(
@ARGV
) < 3) {
die
"usage: oralogon username password TNSname\n"
;
}
$ARGV
[0] =~ m
#([^`']+)#;
$username
= $1;
$ARGV
[1] =~ m
#([^`']+)#;
$password
= $1;
$ARGV
[2] =~ m
#(([a-zA-Z0-9]|-|\+|_|\.)+)#;
$database
= $1;
# ------ run Oracle SQL*Plus, check that authentication succeeded
@output
=<<`endSQLPLUS`;
$sqlplus
$username
/
$password
\
@$database
<<endCMD
$password
quit
endCMD
endSQLPLUS
if
(
grep
(/Connected to:/,
@output
)) {
"OK: Oracle login succeeded.\n"
;
}
else
{
"FAILURE:\n@output\n"
;
}
examples/smblogon view on Meta::CPAN
45678910111213141516171819202122232425262728293031323334353637383940414243444546# NOTE: Runs in taint mode because it is usually
# invoked by other programs (mainly CGIs).
# ------ pragmas
use
strict;
# ------ define variables
my
@output
= ();
# smbclient output lines
my
$password
=
""
;
# $username's password
my
$server
=
""
;
# server NetBIOS name
my
$share
=
""
;
# share on $server (cannot be hidden share)
my
$smbclient
# Samba smbclient pathname
=
"/www/bin/smbclient"
;
my
$username
=
""
;
# user ID for access
# ------ verify and untaint arguments
$ENV
{
"PATH"
} =
"/bin:/usr/bin"
;
if
(
scalar
(
@ARGV
) < 4) {
die
"usage: smblogon username password server share\n"
;
}
$ARGV
[0] =~ m
#([^`']+)#;
$username
= $1;
$ARGV
[1] =~ m
#([^`']+)#;
$password
= $1;
$ARGV
[2] =~ m
#(([a-zA-Z0-9]|-|\+|_|\.)+)#;
$server
= $1;
$ARGV
[3] =~ m
#(([a-zA-Z0-9]|-|\+|_|\.)+)#;
$share
= $1;
# ------ test ability to logon to local domain
@output
= `
$smbclient
//
$server
/
$share
'$password'
-U
'$username'
-c
''
`;
if
(!
grep
(/session setup failed/,
@output
)
&&
grep
(/Domain=.* OS=.* Server=/,
@output
)) {
"OK: SMB login succeeded.\n"
;
exit
0;
}
else
{
"FAILURE:\n@output"
;
exit
1;
}
( run in 0.296 second using v1.01-cache-2.11-cpan-3cd7ad12f66 )