Apache2-SiteControl-1.05/ 0000755 0000764 0000764 00000000000 10470673673 013674 5 ustar tkay tkay Apache2-SiteControl-1.05/docs/ 0000755 0000764 0000764 00000000000 10470673673 014624 5 ustar tkay tkay Apache2-SiteControl-1.05/docs/apache 0000644 0000764 0000764 00000003272 10361323142 015752 0 ustar tkay tkay Apache configuration variables, and their default values/meanings:
AccessControllerDebug: default 0
- Turn on/off debugging of access controller. Set to 1 to enable.
AccessControllerLocks: default /tmp
- The location of the lock files for the session information
AccessControllerManagerFactory: default SiteControl::ManagerFactory
- The name of the module to use as the permission manager factory. This
package includes SiteControl::ManagerFactory, which is an abstract base.
It must be overridden and supplied by the user.
AccessControllerSessions: default /tmp
- The location of the session files
AccessControllerUserFactory: default SiteControl::UserFactory
- The module that will take the user information and create some kind of
user object.
AuthName: default "default"
- The auth name to use with apache for the set of auth parameters. See docs
for apache.
RadiusAccessControllerHost: default localhost
- If using radius, the name of the host that is running the radius server
RadiusAccessControllerSecret: default unknown
- If using radius, the secret key that allows communication
SiteControlMethod: default SiteControl::Radius
- The module that is used to verify credentials. See SiteControl::Radius for
ideas on writing your own.
UserObjectSavePassword: default 0
- Should the user's password be saved in the server side session file. This
is necessary for webapps that must log into other servers as that user
(i.e. imap).
UserObjectPasswordCipher: default CAST5
- The cipher to use for encrypting the user passwords in the session files
UserObjectPasswordKey:
- The key to use with the above cipher when encrypting passwords.
Apache2-SiteControl-1.05/docs/README 0000644 0000764 0000764 00000000173 10361323142 015463 0 ustar tkay tkay Code documentation can be found embedded in the source. This directory contains
a quick reference for apache options only.
Apache2-SiteControl-1.05/lib/ 0000755 0000764 0000764 00000000000 10470673673 014442 5 ustar tkay tkay Apache2-SiteControl-1.05/lib/Apache2/ 0000755 0000764 0000764 00000000000 10470673673 015705 5 ustar tkay tkay Apache2-SiteControl-1.05/lib/Apache2/SiteControl/ 0000755 0000764 0000764 00000000000 10470673673 020152 5 ustar tkay tkay Apache2-SiteControl-1.05/lib/Apache2/SiteControl/Radius.pm 0000644 0000764 0000764 00000005013 10406634363 021726 0 ustar tkay tkay package Apache2::SiteControl::Radius;
use 5.008;
use strict;
use warnings;
use Carp;
use Authen::Radius;
#use Apache2::Connection;
#use Apache2::RequestRec;
#use APR::SockAddr;
sub check_credentials
{
my $r = shift; # Apache request object
my $username = shift;
my $password = shift;
my $host = $r->dir_config("RadiusSiteControlHost") || "localhost";
my $secret = $r->dir_config("RadiusSiteControlSecret") || "unknown";
my $radius;
# Get my IP address to pass as the
# Source IP and NAS IP Address
# TODO: Only works with apache 2...uncommented for now
#my $c = $r->connection;
#my $sockaddr = $c->local_addr if defined($c);
my $nas_ip_address = undef; # $sockaddr->ip_get if defined($sockaddr);
$r->log_error("WARNING: Shared secret is not set. Use RadiusSiteControlSecret in httpd.conf") if $secret eq "unknown";
$radius = new Authen::Radius(Host => $host, Secret => $secret);
if(!$radius) {
$r->log_error("Could not contact radius server!");
return 0;
}
if($radius->check_pwd($username, $password, $nas_ip_address)) {
return 1;
}
$r->log_error("User $username failed authentication:" . $radius->strerror);
return 0;
}
1;
__END__
=head1 NAME
Apache2::SiteControl::Radius - Raduis authentication module for SiteControl
=head1 SYNOPSIS
In Apache/mod_perl's configuration:
=over 4
PerlModule Apache2::SiteControl
...
PerlSetVar SiteControlMethod Apache2::SiteControl::Radius
...
...
PerlSetVar RadiusSiteControlHost "localhost"
PerlSetVar RadiusSiteControlSecret "mysecret"
...
...
PerlSetVar RadiusSiteControlHost "localhost"
PerlSetVar RadiusSiteControlSecret "mysecret"
...
=back
=head1 DESCRIPTION
Apache2::SiteControl::Radius uses Authen::Radius to do the actual authentication
of login attempts for the SiteControl system. See the SiteControl documentation
for a complete apache configuration example. The synopsis above shows the
configuration parameters for the radius module only, which is not a stand-alone
thing.
The proper variables for the apache configuration of this modules are shown in
the synopsis above. You must set the radius host and shared secret in all
sections that will use the SiteControl system for authentication.
=head1 SEE ALSO
Apache2::SiteControl
=head1 AUTHOR
This module was written by Tony Kay, Etkay@uoregon.eduE.
=head1 COPYRIGHT AND LICENSE
=cut
Apache2-SiteControl-1.05/lib/Apache2/SiteControl/UserFactory.pm 0000644 0000764 0000764 00000030465 10470666252 022761 0 ustar tkay tkay package Apache2::SiteControl::UserFactory;
use 5.008;
use strict;
use warnings;
use Carp;
use Data::Dumper;
use Apache2::SiteControl::User;
use Crypt::CBC;
our $engine;
our $encryption_key;
sub init_engine
{
my $cipher = shift;
my $key = shift;
if(!defined($engine)) {
$engine = Crypt::CBC->new({ key => $key, cipher => $cipher });
}
}
# Params: Apache request, username, password, other credentials...
sub makeUser
{
my $this = shift;
my $r = shift;
my $username = shift;
my $password = shift;
my @other_cred = @_;
my $sessiondir = $r->dir_config("SiteControlSessions") || "/tmp";
my $lockdir = $r->dir_config("SiteControlLocks") || "/tmp";
my $mapdir = $r->dir_config("SiteControlUsermap") || "";
my $debug = $r->dir_config("SiteControlDebug") || 0;
my $savePassword = $r->dir_config("UserObjectSavePassword") || 0;
my $cipher = $r->dir_config("UserObjectPasswordCipher") || "CAST5";
my $key = $r->dir_config("UserObjectPasswordKey") || $encryption_key || "A not very secure key because the admin forgot to set it.";
my $saveOther = $r->dir_config("UserObjectSaveOtherCredentials") || 0;
my $factory = $r->dir_config("SiteControlUserFactory") || "Apache2::SiteControl::UserFactory";
my $user = undef;
my %session;
my $usermap;
my $session_removed = 0;
$r->log_error("encryption engine using key: $key") if $debug;
init_engine($cipher, $key) if($savePassword);
# Proper steps:
# 1. Check to see if session already exists for user. If so, delete it.
# 2. Create new session for user and populate it.
# 3. Return the new user object.
$r->log_error("Making user object for $username.") if $debug;
eval {
if($mapdir && -l "$mapdir/$username") {
$r->log_error("$username is logging in, and already had a session. Removing old session.");
$session_removed = 1;
my $sid = readlink "$mapdir/$username";
unlink "$mapdir/$username"; # Remove the link
unlink "$sid"; # Remove the session file
}
tie %session, 'Apache::Session::File', undef,
{
Directory => $sessiondir,
LockDirectory => $lockdir
};
# Remember the username to session mapping.
$r->log_error("Making symlink from $sessiondir/$session{_session_id} to $mapdir/$username") if($mapdir);
symlink "$sessiondir/" . $session{_session_id}, "$mapdir/$username" if($mapdir);
$user = new Apache2::SiteControl::User($username, $session{_session_id}, $factory);
$session{username} = $username;
$session{manager} = $factory;
$session{attr_password} = $engine->encrypt($password) if($savePassword);
$session{attr_session_removed} = $session_removed;
if(@other_cred && $saveOther) {
my $i = 2;
for my $c (@other_cred) {
$r->log_error("Saving extra credential_$i with value $c") if $debug;
$session{"attr_credential_$i"} = $c;
$i++;
}
}
$r->log_error("Created user: " . Dumper($user)) if $debug;
};
if($@) {
$r->log_error("Problem making new user object: $@");
return undef;
}
# Note: this is a half-baked user, but the controller only needs the session
# id. It might be better to return the result of findUser instead.
return $user;
}
# Params: apache request, session_key
sub findUser
{
my $this = shift;
my $r = shift;
my $ses_key = shift;
my $sessiondir = $r->dir_config("SiteControlSessions") || "/tmp";
my $lockdir = $r->dir_config("SiteControlLocks") || "/tmp";
my $debug = $r->dir_config("SiteControlDebug") || 0;
my $savePassword = $r->dir_config("UserObjectSavePassword") || 0;
my $cipher = $r->dir_config("UserObjectPasswordCipher") || "CAST5";
my $key = $r->dir_config("UserObjectPasswordKey") || $encryption_key || "A not very secure key because the admin forgot to set it.";
my %session;
my $user;
$r->log_error("encryption engine using key: $key") if $debug;
init_engine($cipher, $key) if($savePassword);
eval {
tie %session, 'Apache::Session::File', $ses_key, {
Directory => $sessiondir,
LockDirectory => $lockdir
};
# FIXME: Document the possible problems with changing user factories when
# persistent sessions already exist.
$user = new Apache2::SiteControl::User($session{username}, $ses_key, $session{manager});
for my $key (keys %session) {
next if $key !~ /^attr_/;
my $k2 = $key;
$k2 =~ s/^attr_//;
if($k2 eq 'password') {
$user->{attributes}{$k2} = $engine->decrypt($session{$key});
} else {
$user->{attributes}{$k2} = $session{$key};
}
}
$r->log_error("Restored user: " . Dumper($user)) if $debug;
};
if($@) {
# This method should fail for new logins (or login after logout), so
# failing to find the user is not considered a "real" error
$r->log_error("Failed to find a user with cookie $ses_key.") if $debug;
return undef;
}
return $user;
}
# Apache request, user object (not name)
sub invalidate
{
my $this = shift;
my $r = shift;
my $userobj = shift;
my $debug = $r->dir_config("SiteControlDebug") || 0;
my $sessiondir = $r->dir_config("SiteControlSessions") || "/tmp";
my $mapdir = $r->dir_config("SiteControlUsermap") || "";
my $lockdir = $r->dir_config("SiteControlLocks") || "/tmp";
my %session;
if(!$userobj->isa("Apache2::SiteControl::User") || !defined($userobj->{sessionid})) {
$r->log_error("Invalid user object passed to saveAttribute. Cannot remove user.");
return 0;
}
$r->log_error("Logging out user: " . $userobj->getUsername) if $debug;
eval {
unlink "$mapdir/" . $userobj->getUsername; # Remove the MSD link
tie %session, 'Apache::Session::File', $userobj->{sessionid}, {
Directory => $sessiondir,
LockDirectory => $lockdir
};
tied(%session)->delete;
$r->log_error("Done with logout.") if $debug;
};
if($@) {
$r->log_error("Could not delete user (logout): $@");
}
}
# Apache request, user object, attribute name
sub saveAttribute
{
my $this = shift;
my $r = shift;
my $userobj = shift;
my $name = shift;
my $debug = $r->dir_config("SiteControlDebug") || 0;
my $sessiondir = $r->dir_config("SiteControlSessions") || "/tmp";
my $lockdir = $r->dir_config("SiteControlLocks") || "/tmp";
my %session;
if(!$userobj->isa("Apache2::SiteControl::User") || !defined($userobj->{sessionid})) {
$r->log_error("Invalid user object passed to saveAttribute. Attribute not saved.");
return 0;
}
eval {
tie %session, 'Apache::Session::File', $userobj->{sessionid}, {
Directory => $sessiondir,
LockDirectory => $lockdir
};
$r->log_error("Saving attribute $name = " .
$userobj->getAttribute($name) .
"using Apache::Session::File.") if $debug;
$session{"attr_$name"} = $userobj->getAttribute($name);
untie %session;
};
if($@) {
$r->log_error("Failed to save user attribute: $@");
return 0;
}
}
1;
__END__
=head1 NAME
Apache2::SiteControl::UserFactory - User factory/persistence
=head1 DESCRIPTION
This class is responsible for creating user objects (see
Apache2::SiteControl::User) and managing the interfacing of those objects with a
persistent session store. The default implementation uses
Apache::Session::File to store the various attributes of the user to disk.
If you want to do your own user management, then you should leave the User
class alone, and subclass only this factory. The following methods are
required:
=over 3
=item makeUser($$)
This method is called with the Apache Request object, username, password, and
all other credential_# fields from the login form. It must create and return
an instance of Apache2::SiteControl::User (using new...See User), and store that
information (along with the session key stored in cookie format in the request)
in some sort of permanent storage. This method is called in response to a
login, so it should invalidate any existing session for the given user name (so
that a user can be logged in only once). This method must return the key to
use as the browser session key, or undef if it could not create the user.
=item findUser($$)
This method is passed the apache request and the session key (which you defined
in makeUser). This method is called every time a "logged in" user makes a
request. In other words the user objects are not persistent in memory (each
request gets a new "copy" of the state). This method uses the session key
(which was stored in a browser cookie) to figure out what user to restore. The
implementation is required to look up the user by the session key, recreate a
Apache2::SiteControl::User object and return it. It must restore all user
attributes that have been saved via saveAttribute (below).
=item invalidate($$)
This method is passed the apache request object and a previously created user
object. It should delete the user object from permanent store so that future
request to find that user fails unless makeUser has been called to recreate it.
The session ID (which you made up in makeUser) is available from
$user->{sessionid}.
=item saveAttribute($$$)
This method is automatically called whenever a user has a new attribute value.
The incoming arguments are the apache request, the user object, and the name of
the attribute to save (you can read it with $user->getAttribute($name)). This
method must save the attribute in a such a way that later calls to findUser
will be able to restore the attribute to the user object that is created. The
session id you created for this user (in makeUser) is available in
$user->{sessionid}.
=back
=head1 Apache Config Directives
The following is a list of configuration variables that can be set with
apache's PerlSetVar to configure the behavior of this class:
=over 3
=item SiteControlDebug (default 0):
Debug mode
=item SiteControlLocks (default /tmp):
Where the locks are stored
=item SiteControlSessions (default /tmp):
Where the session data is stored
=item SiteControlUsermap (default none):
Where the usernames are mapped to session files. Required if you want multiple
session detection. If unset a single userid can be used to log in multiple
times simultaneously.
=item SiteControlUserFactory (default: Apache2::SiteControl::UserFactory)
An implementation like this module.
=item UserObjectSaveOtherCredentials (default: 0)
Indicates that other form data from the login screen (credential_2,
credential_3, etc.) should be saved in the session data. The keys will be
credential_2, etc. name of the user factory to use when making user objects.
These are useful if your web application has other login choices (i.e. service,
database, etc.) that you need to know about at login.
=item UserObjectSavePassword (default 0)
Indicates that the password should be saved in the local session data, so that
it is available to other parts of the web app (and not just the auth system).
This might be necessary if you are logging the user in and out of services on
the back end (like in webmail and database apps).
=item UserObjectPasswordCipher (default CAST5)
The CBC cipher used for encrypting the user passwords in the session files (See
Crypt::CBC for info on allowed ciphers...this value is passed directly to
Crypt::CBC->new). If you are saving user passwords, they will be encrypted when
stored in the apache session files. This gives a little bit of added security,
and makes the apache config the only sensitive file (since that is where you
configure the key itself) instead of every random session file that is laying
around on disk.
There is a global variable in this package called $encryption_key, which will
be used if this variable is not set. The suggested method is to set the
encryption key during server startup using a random value (i.e. from
/dev/random), so that all server forks will inherit the value.
=item UserObjectPasswordKey
The key to use for encryption of the passwords in the session files. See
UserObjectPasswordCipher above.
=back
=head1 SEE ALSO
Apache2::SiteControl::User, Apache::SiteControl::PermissionManager,
Apache2::SiteControl::Rule, Apache::SiteControl
=head1 AUTHOR
This module was written by Tony Kay, Etkay@uoregon.eduE.
=head1 COPYRIGHT AND LICENSE
Apache2::SiteControl is covered by the GPL.
=cut
Apache2-SiteControl-1.05/lib/Apache2/SiteControl/Rule.pm 0000644 0000764 0000764 00000003670 10406634370 021413 0 ustar tkay tkay package Apache2::SiteControl::Rule;
use 5.008;
use strict;
use warnings;
use Carp;
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $this = { };
bless ($this, $class);
return $this;
}
sub grants($$$$)
{
my $this = shift;
my $user = shift;
my $action = shift;
my $resource = shift;
return 0;
}
sub denies($$$$)
{
my $this = shift;
my $user = shift;
my $action = shift;
my $resource = shift;
return "Abstract rule denies everything. Do not use.";
}
1;
__END__
=head1 NAME
Apache2::SiteControl::Rule - Permission manager access rule.
=head2 DESCRIPTION
Each rule is a custom-written class that implements some aspect of your site's
access logic. Rules can choose to grant or deny a request.
package sample::Test;
use strict;
use warnings;
use Carp;
use Apache2::SiteControl::Rule;
use base qw(Apache2::SiteControl::Rule);
sub grants($$$$)
{
my $this = shift;
my $user = shift;
my $action = shift;
my $resource = shift;
if($action eq "edit" && $resource->isa("sample::Record")) {
return 1 if($user{name} eq "root");
}
return 0;
}
sub denies($$$$)
{
return 0;
}
1;
The PermissionManager will only give permission if I one rule grants
permission, I rule denies it.
It is important that your rules never grant or deny a request they do not
understand, so it is a good idea to use type checking to prevent strangeness.
B if you expect different rules to accept
different resource types or user types, since each rule is used on every access
request.
=head1 EXPORT
None by default.
=head1 SEE ALSO
Apache2::SiteControl::UserFactory, Apache::SiteControl::ManagerFactory,
Apache2::SiteControl::PermissionManager, Apache::SiteControl
=head1 AUTHOR
This module was written by Tony Kay, Etkay@uoregon.eduE.
=head1 COPYRIGHT AND LICENSE
=cut
Apache2-SiteControl-1.05/lib/Apache2/SiteControl/GrantAllRule.pm 0000644 0000764 0000764 00000003475 10406634374 023047 0 ustar tkay tkay package Apache2::SiteControl::GrantAllRule;
use 5.008;
use strict;
use warnings;
use Carp;
use Carp::Assert;
use Apache2::SiteControl::Rule;
use base qw(Apache2::SiteControl::Rule);
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $this = { };
bless ($this, $class);
return $this;
}
sub grants($$$$)
{
my $this = shift;
my $user = shift;
my $action = shift;
my $resource = shift;
return "Default is to allow";
}
sub denies($$$$)
{
my $this = shift;
my $user = shift;
my $action = shift;
my $resource = shift;
return 0;
}
1;
__END__
=head1 NAME
Apache2::SiteControl::GrantAllRule - A rule that grants permission to do everything.
=head1 SYNOPSIS
In your instance of a ManagerFactory:
=over 4
use Apache2::SiteControl::GrantAllRule;
...
sub getPermissionManager
{
...
$manager->addRule(new Apache2::SiteControl::GrantAllRule);
...
return $manager;
}
=back
=head1 DESCRIPTION
Apache2::SiteControl::GrantAllRule is a pre-built rule that grants access for
all permission requests. This rule can be used to help implement a system that
has a default policy of allowing access, and to which you add rules that deny
access for specific cases.
Note that the loose type checking of Perl makes this inherently dangerous,
since a typo is likely to fail to deny access. It is recommended that you
take the opposite approach with your rules, since a typo will err on the
side of denying access. The former is a security hole, the latter is a bug
that people will complain about (so you can fix it).
=head1 SEE ALSO
Apache2::SiteControl::ManagerFactory, Apache::SiteControl::PermissionManager,
Apache2::SiteControl::Rule
=head1 AUTHOR
This module was written by Tony Kay, Etkay@uoregon.eduE.
=head1 COPYRIGHT AND LICENSE
=cut
Apache2-SiteControl-1.05/lib/Apache2/SiteControl/User.pm 0000644 0000764 0000764 00000010627 10406634341 021420 0 ustar tkay tkay package Apache2::SiteControl::User;
use 5.008;
use strict;
use warnings;
use Carp;
# This object represents a transient view of a persistent user. The UserManager
# is responsible for loading/saving these things.
sub new($$$$) {
my $proto = shift;
my $username = shift;
my $sessionid = shift;
my $usermanager = shift;
my $class = ref($proto) || $proto;
my $this = { username => $username,
sessionid => $sessionid,
manager => $usermanager,
attributes => {} };
bless ($this, $class);
return $this;
}
sub getUsername
{
my $this = shift;
return $this->{username};
}
# user, request, name, value
sub setAttribute
{
my $this = shift;
my $r = shift;
my $name = shift;
my $value = shift;
$this->{attributes}{$name} = $value;
eval("$this->{manager}" . '->saveAttribute($r, $this, $name)');
if($@) {
$r->log_error("ERROR! FAILED TO SAVE ATTRIBUTE. SESSION WILL NOT WORK: $@");
}
}
sub getAttribute
{
my $this = shift;
my $name = shift;
return $this->{attributes}{$name} if defined($this->{attributes}{$name});
return undef;
}
# user object, apache request
sub logout
{
my $this = shift;
my $r = shift;
if(!defined($this) || !defined($r)) {
croak "INVALID CALL TO LOGOUT. You forgot to use OO syntax, or you forgot to pass the request object.";
}
eval("$this->{manager}" . '->invalidate($r, $this)');
if($@) {
$r->log_error("Logout failed: $@");
}
}
1;
__END__
=head1 NAME
Apache2::SiteControl::User - User representations
=head2 SYNOPSIS
my $user = Apache2::SiteControl->getCurrentUser($r);
# $r is the apache request object
# Checking out the user's name:
if($user->getUsername eq 'sam') { ... }
...
# Working with attributes (session persistent data)
my $ssn = $user->getAttribute('ssn');
$user->setAttribute($r, 'ssn', '333-555-6666');
# Removing/invalidating session for the user
$user->logout($r);
=head2 DESCRIPTION
The SiteControl system has a base concept of a user which includes the user's
name, persistent attributes (which are persistent via session), and support
for user logout.
It is assumed that you will be working from mod_perl, and some of the methods
require an Apache request object. The request object is used by some methods to
coordinate access to the actual session information in the underlying system
(for storing attributes and implementing logout).
User objects are created by a factory (by default
Apache2::SiteControl::UserFactory), so if you subclass User, you must understand
the complete interaction between the factory (which is responsible for
interfacing with persistence), the SiteControl, etc.
The default implementation of User and UserFactory use AuthCookie to manage the
sessions, and Apache::Session::File to store the various details about a user
to disk.
If you are using Apache2::SiteControl::User and Apache::SiteControl::UserFactory
(the default and recommended), then you should configure the following
parameters in your apache configuration file:
# This is where the session data files will be stored
SiteControlSessions directory_name
# This is where the locks will be stored
SiteControlLocks directory_name
These two directories should be different, and should be readable and writable
by the apache daemon only. They must exist before trying to use SiteControl.
=head1 METHODS
=over 8
=item B Get the name that the current user used to log in.
=item B Get the value of a previously stored attribute. Returns undef is there is no value.
=item B Add an attribute
(scalar data only) to the current session. The current apache request object is
required (in order to figure out the session). Future versions may support more
complex storage in the session. This attribute will stay associated with this
user until they log out.
=item B Log the user out. If you do not pass the current apache request, then this method will log an error to the apache error logs, and the user's session will continue to exist.
=back
=head1 SEE ALSO
Apache2::SiteControl::UserFactory, Apache::SiteControl::ManagerFactory,
Apache2::SiteControl::PermissionManager, Apache::SiteControl
=head1 AUTHOR
This module was written by Tony Kay, Etkay@uoregon.eduE.
=head1 COPYRIGHT AND LICENSE
This modules is covered by the GNU public license.
=cut
Apache2-SiteControl-1.05/lib/Apache2/SiteControl/ManagerFactory.pm 0000644 0000764 0000764 00000002174 10406634343 023404 0 ustar tkay tkay package Apache2::SiteControl::ManagerFactory;
use 5.008;
use strict;
use warnings;
use Carp;
use Carp::Assert;
sub getPermissionManager
{
croak "Attempt to call abstract method getPermissionManager";
}
1;
__END__
=head1 NAME
Apache2::SiteControl::ManagerFactory - An abstract base class to use as a
pattern for custom PermissionManager production.
=head1 DESCRIPTION
This package is a simple abstract base class. Use it as the base for creating
your instances of permission managers. For example,
package MyManagerFactory;
use strict;
use Apache2::SiteControl::ManagerFactory;
use base qw(Apache2::SiteControl::ManagerFactory);
our $manager;
sub getPermissionManager
{
return $manager if(defined($manager) && $manager->isa(Apache2::SiteControl::ManagerFactory));
$manager = new Apache2::SiteControl::PermissionManager;
$manager->addRule(new XYZRule);
$manager->addRule(new SomeOtherRule);
return $manager;
}
1;
=head1 SEE ALSO
Apache2::SiteControl::PermissionManager, Apache::SiteControl::Rule
=head1 AUTHOR
This module was written by Tony Kay, Etkay@uoregon.eduE.
=head1 COPYRIGHT AND LICENSE
=cut
Apache2-SiteControl-1.05/lib/Apache2/SiteControl/PermissionManager.pm 0000644 0000764 0000764 00000012242 10406634346 024125 0 ustar tkay tkay package Apache2::SiteControl::PermissionManager;
use 5.008;
use strict;
use warnings;
use Carp;
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $this = { rules => [] };
bless ($this, $class);
return $this;
}
sub addRule($$)
{
my $this = shift;
my $rule = shift;
push @{$this->{rules}}, $rule;
return 1;
}
sub can($$$$)
{
my $this = shift;
my $user = shift;
my $action = shift;
my $resource = shift;
my $rule;
my ($granted, $denied) = (0,0);
for $rule (@{$this->{rules}})
{
$granted = 1 if($rule->grants($user, $action, $resource));
$denied = 1 if($rule->denies($user, $action, $resource));
}
return ($granted && !$denied);
}
1;
__END__
=head1 NAME
Apache2::SiteControl::PermissionManager - Rule-based permission management
=head1 SYNOPSIS
use Apache2::SiteControl::PermissionManager;
$manager = new Apache2::SiteControl::PermissionManager();
$rule1 = new SomeSubclassOfSiteControl();
$manager->addRule($rule1);
...
$user = new SomeUserTypeYouDefineThatMakesSenseToRules;
if($manager->can($user, $action, $resource)) {
# OK to do action
}
# For example
if($manager->can($user, "read", "/etc/shadow")) {
open DATA, " Decide how you want to represent a user. (i.e. Apache2::SiteControl::User)
=item B<2.> Decide the critical sections of your code that need to be
protected, and decide what to do if the user doesn't pass muster. For example
if a screen should just hide fields, then the application code needs to reflect
that.
=item B<3.> Create a permission manager instance for your application.
Typically use a singleton pattern (there need be only one manager). In the
SiteControl system, this is done by a ManagerFactory that you write.
=item B<4.> Surround sensitive sections of code with something like:
if($manager->can($user, "view salary", $payrollRecord))
{
# show salary fields
} else
# hide salary fields
}
=item B<5.> Create rules that spell out the behavior you want and add them to
your application's permission manager. The basic idea is that a rule can grant
permission, or deny it. If it neither grants or denies, then the manager will
take the safe route and say that the action cannot be taken. Part of the code
for the rule for protecting salaries might look like:
package SalaryViewRule;
use Apache2::SiteControl::Rule;
use Apache2::SiteControl::User;
use base qw(Apache2::SiteControl::Rule);
sub grants
{
$this = shift;
$user = shift;
$action = shift;
$resource = shift;
# Do not grant on requests we don't understand.
return 0 if(!$user->isa("Apache2::SiteControl::User") ||
!$this->isa("Apache2::SiteControl::Rule"));
if($action eq "view salary" && $resource->isa("Payroll::Record")) {
if($user->getUsername() eq $resource->getEmployeeName()) {
return "user can view their own salary";
}
}
return 0;
}
Then in your subclass of ManagerFactory:
use SalaryViewRule;
...
$viewRule = new SalaryViewRule;
$manager->addRule($viewRule);
=back
=head1 METHODS
=over 8
=item B(I, I, I)
This is the primary method of the PermissionManager. It asks if the specified
user can do the specified action on the specified resource. For example,
$manager->can($user, "eat", "cake");
would return true if the user is allowed to eat cake. Note that this gives you
quite a bit of flexibility, but at the expense of strong type safety. It is
suggested that all of your rules do type checking to insure that a rule is
properly applied.
=back
=head1 SEE ALSO
Apache2::SiteControl::Rule, Apache::SiteControl::ManagerFactory,
Apache2::SiteControl::UserFactory, Apache::SiteControl
=head1 AUTHOR
This module was written by Tony Kay, Etkay@uoregon.eduE.
=head1 COPYRIGHT AND LICENSE
=cut
Apache2-SiteControl-1.05/lib/Apache2/SiteControl.pm 0000644 0000764 0000764 00000030752 10470666304 020510 0 ustar tkay tkay package Apache2::SiteControl;
use 5.008;
use strict;
use warnings;
use Carp;
use Apache2::AuthCookie;
use Apache::Session::File;
our $VERSION = "1.05";
use base qw(Apache2::AuthCookie);
our %managers = ();
sub getCurrentUser
{
my $this = shift;
my $r = shift;
my $debug = $r->dir_config("SiteControlDebug") || 0;
my $factory = $r->dir_config("SiteControlUserFactory") || "Apache2::SiteControl::UserFactory";
my $auth_type = $r->auth_type;
my $auth_name = $r->auth_name;
my ($ses_key) = ($r->headers_in->{"Cookie"} || "") =~ /$auth_type\_$auth_name=([^;]+)/;
$r->log_error("Session cookie: " . ($ses_key ? $ses_key:"UNSET")) if $debug;
$r->log_error("Loading module $factory") if $debug;
eval "require $factory" or $r->log_error("Could not load $factory: $@");
$r->log_error("Using user factory $factory") if $debug;
my $username = $r->user();
return undef if(!$username);
$r->log_error("user name is $username") if $debug;
my $user = undef;
$factory = '$user' . " = $factory" . '->findUser($r, $ses_key)';
$r->log_error("Evaluating: $factory") if $debug;
eval($factory) or $r->log_error("Eval failed: $@");
$r->log_error("Got user object: $user") if $debug && defined($user);
return defined($user) ? $user : 0;
}
sub getPermissionManager
{
my $this = shift;
my $r = shift;
my $debug = $r->dir_config("SiteControlDebug") || 0;
my $name = $r->dir_config("AuthName") || "default";
$r->log_error("AuthName is not set! Using 'default'.") if $name eq "default";
return $managers{$name} if(defined($managers{$name}) && $managers{$name});
$r->log_error("Building manager") if $debug;
my $factory = $r->dir_config("SiteControlManagerFactory");
$r->log_error("Manager Factory not set!") if !defined($factory);
return undef if !defined($factory);
$r->log_error("Loading module $factory") if $debug;
eval "require $factory" or $r->log_error("Could not load $factory: $@");
$factory = '$managers{$name}' . " = $factory" . '->getPermissionManager()';
$r->log_error("Building a manager using: $factory") if $debug;
eval($factory) or $r->log_error("Evaluation failed: $@");
return $managers{$name};
}
# This is the method that receives the login form data and decides if the
# user is allowed to log in.
sub authen_cred
{
my $this = shift; # Package name (same as AuthName directive)
my $r = shift; # Apache request object
my @cred = @_; # Credentials from login form
my $debug = $r->dir_config("SiteControlDebug") || 0;
my $checker = $r->dir_config("SiteControlMethod") || "Apache2::SiteControl::Radius";
my $factory = $r->dir_config("SiteControlUserFactory") || "Apache2::SiteControl::UserFactory";
my $user = undef;
my $ok;
# Load the user authentication module
eval "require $checker" or $r->log_error("Could not load $checker: $@");
eval "require $factory" or $r->log_error("Could not load $factory: $@");
eval '$ok = ' . ${checker} . '::check_credentials($r, @cred)' or $r->log_error("authentication error code: $@");
if($ok) {
eval('$user = ' . "$factory" . '->makeUser($r, @cred)');
if($@) {
$r->log_error("Error reported during call to ${factory}->makeUser: $@");
}
}
return $user->{sessionid} if defined($user);
return undef;
}
# This sub is called for every request that is under the control of
# SiteControl. It is responsible for verifying that the user id (session
# key) is valid and that the user is ok.
# It returns a user name if all is well, and undef if not.
sub authen_ses_key
{
my ($this, $r, $session_key) = @_;
my $debug = $r->dir_config("SiteControlDebug") || 0;
my $factory = $r->dir_config("SiteControlUserFactory") || "Apache2::SiteControl::UserFactory";
my $user = undef;
eval "require $factory" or $r->log_error("Could not load $factory: $@");
$r->log_error("Attempting auth using session key $session_key") if $debug;
eval {
eval('$user = ' . "$factory" . '->findUser($r, $session_key)');
if($@) {
$r->log_error("Error reported during call to ${factory}->findUser: $@");
}
};
if($@) {
$r->log_error("User tried access with invalid/nonexistent session: $@");
return undef;
}
return $user->getUsername if defined($user);
return undef;
}
1;
__END__
=head1 NAME
Apache2::SiteControl - Perl web site authentication/authorization system
=head1 SYNOPSIS
See samples/site for complete example. Note, this module is intended for
mod_perl. See Apache2::SiteControl for mod_perl2.
=head1 DESCRIPTION
Apache2::SiteControl is a set of perl object-oriented classes that
implement a fine-grained security control system for a web-based application.
The intent is to provide a clear, easy-to-integrate system that does not
require the policies to be written into your application components. It
attempts to separate the concerns of how to show and manipulate data from the
concerns of who is allowed to view and manipulate data and why.
For example, say your web application is written in HTML::Mason. Your
individual "screens" are composed of Mason modules, and you would like to keep
those as clean as possible, but decisions have to be made about what to allow
as the component is processed. SiteControl attempts to make that as easy as
possible.
=head2 DEVELOPER'S VIEWPOINT - EXAMPLE
In this document we use HTML::Mason to create examples of how to use the
control mechanisms, but any mod_perl based system should be supportable.
A good mason component tries to do most of the perl processing in a separate
block, so that simple substitutions can be made in HTML in the rest of
the page. This makes it much easier for web developers and perl developers to
co-exist on a project.
The SiteControl system tries to make it possible to continue to follow this
model. You obtain a user object and permission manager from the SiteControl
system. These are intended to be opaque data types to the page designer,
and are defined elsewhere (see USERS). The actual web page component
should carry these objects around without implementing anything in the way of
policy.
For example, your mason component might look like this:
...
% if($manager->can($currentUser, "edit", $table)) {
% } else {
x is <% $table->{x} %>
% }
<%init>
my $currentUser = Apache2::SiteControl->getCurrentUser($r);
my $manager = Apache2::SiteControl->getPermissionManager($r);
... application specific stuff...
i.e.
my $table = ...
%init>
Notice that the component does not bother looking at the user object, and there
is no policy code...just a request for permission:
if($manager->can($currentUser, "do something to", $resource))
Of course the developer needs to know I about the underlying system.
For example, the action string "do something to" is rather arbitrary. These can
be anything, and must be specified as rule actions. It is recommended that you
use some form of Perl constants for these instead of strings, but that is up to
you.
The resource is intended to be less opaque. This is likely the object that the
page developer wants to muck with, and so probably knows the internals of that
object a bit better. This is the crossover point from what SiteControl can
figure out on its own to information you have to supply.
The default behavior is for the manager to deny any request. In order for a
request to be approved, someone has to write a rule that joins together the
user, action, and resource and makes a decision about the permissibility of the
action.
If all you want is login and user tracking (but no permission manager), then it
is safe to ignore the permission manager altogether.
=head1 USERS
Users and Rules are the central components of the SiteControl system. The user
object must be Apache2::SiteControl::User (or a subclass). See
Apache2::SiteControl::User for a description of what it supports (session
storage, logout, etc.). The glue to SiteControl is the UserFactory, which you
can define or accept the default of Apache2::SiteControl::UserFactory
(recommended).
Whenever a login attempt succeeds, the factory returns an object that
represents a valid, logged-in user. See Apache2::SiteControl::UserFactory for
more information.
=head2 PERMISSION MANAGER
Each site will have a permission manager. There is usually no need for you
to subclass Apache2::SiteControl::PermissionManager, but you do need to create one
and populate it with your access rules. You do this by creating a
factory class, which looks something like this:
package samples::site::MyPermissionFactory;
use Apache2::SiteControl::PermissionManager;
use Apache2::SiteControl::GrantAllRule;
use samples::site::EditControlRule;
use base qw(Apache2::SiteControl::ManagerFactory);
our $manager;
sub getPermissionManager
{
return $manager if defined($manager);
$manager = new Apache2::SiteControl::PermissionManager;
$manager->addRule(new Apache2::SiteControl::GrantAllRule);
$manager->addRule(new samples::site::EditControlRule);
return $manager;
}
1;
The primary goal of your factory is to produce an instance of a permission
manager that knows the rules for permitting access to your site. This is
an easy process that involves calling the constructor (via new) and then
calling addRule one or more times.
=head2 RULES
The PermissionManager is the object that the site developers ask about
what is allowed and what is not. As you saw in the previous section, you
create a manager, and add some rules.
Each rule is a custom-written class that implements some aspect of your
site's access logic. Rules can choose to grant or deny a request. The following
is a pretty complex example that demonstrates the features of a rule.
Most rules with either specifically grant permission, or deny it. Most will not
deal with both possibilities. In this example we are assuming that the user is
implemented as an object that has attributes which can be retrieved with a
getAttribute method (of course, you would have to have implemented that as
well). The basic action that this rule handles is called "beat up", so the site
makes calls like:
if($referee->can($userA, "beat up", $userB)) { ... }
In terms of English, we would describe the rule "If A is taller than B, then
we say that A can beat up B. If A is less skilled than B, then we say that
A cannot beat up B". The rule looks like this:
package samples::FightRules;
use strict;
use warnings;
use Carp;
use Apache2::SiteControl::Rule;
use base qw(Apache2::SiteControl::Rule);
sub grants($$$$)
{
my $this = shift;
my $user = shift;
my $action = shift;
my $resource = shift;
if($action eq "beat up" && $resource->isa("Apache2::SiteControl::User")) {
my ($h1, $h2);
$h1 = $user->getAttribute("height");
$h2 = $resource->getAttribute("height");
return 1 if(defined($h1) && defined($h2) && $h1 > $h2);
}
return 0;
}
sub denies($$$$)
{
my $this = shift;
my $user = shift;
my $action = shift;
my $resource = shift;
if($action eq "beat up" && $resource->isa("Apache2::SiteControl::User")) {
my ($s1, $s2);
$s1 = $user->getAttribute("skill");
$s2 = $resource->getAttribute("skill");
return 1 if(defined($s1) && defined($s2) && $s1 < $s2);
}
return 0;
}
1;
The PermissionManager will only give permission if I one rule grants
permission, I no rule denies it.
I think it is clearer to separate rules like the previous one into separate
rule classes altogether. A HeightMakesMightRule and a DefenseSkillRule.
Splitting into two rules makes things clearer, and there is no limit to the
number of rules that the PermissionManager can check.
It is important that your rules never grant or deny a request they do not
understand, so it is a good idea to use type checking to prevent strangeness.
B if you expect different rules to accept
different resource types or user types, since each rule is used on every access
request.
=head1 EXPORT
None by default.
=head1 SEE ALSO
Apache2::SiteControl::UserFactory, Apache::SiteControl::ManagerFactory,
Apache2::SiteControl::PermissionManager, Apache::SiteControl::Rule
=head1 AUTHOR
This module was written by Tony Kay, Etkay@uoregon.eduE.
=head1 COPYRIGHT AND LICENSE
This modules is covered by the GNU public license.
=cut
Apache2-SiteControl-1.05/META.yml 0000644 0000764 0000764 00000000760 10470673673 015150 0 ustar tkay tkay # http://module-build.sourceforge.net/META-spec.html
#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX#
name: Apache2-SiteControl
version: 1.05
version_from:
installdirs: site
requires:
Apache2::AuthCookie: 3.08
Apache2::Request: 2.05
Apache::Session::File: 1.54
Crypt::CAST5: 0.04
Crypt::CBC: 2.14
distribution_type: module
generated_by: ExtUtils::MakeMaker version 6.17
Apache2-SiteControl-1.05/README.UPGRADING_TO_1.0 0000644 0000764 0000764 00000001272 10361323143 017034 0 ustar tkay tkay Version 1.0 has a significant change from previous versions. AccessController
is dropped in favor of a module actually called SiteControl. This makes the
whole system work better in the Perl sense, and make version checking and
installation smoother with CPAN.
To upgrade:
1) Edit all of your modules that depend on
Apache2::SiteControl::AccessController, and change them to use
Apache2::SiteControl.
2) Make the same change in all of your pages. i.e.:
$user = Apache2::SiteControl::AccessController->getPermissionManager($r)
becomes:
$user = Apache2::SiteControl->getPermissionManager($r)
i.e.
perl -pi'.bak' 's/SiteControl::AccessController/SiteControl/' *.html
Apache2-SiteControl-1.05/README 0000644 0000764 0000764 00000006611 10361323143 014537 0 ustar tkay tkay Apache Notes
============
This package allows you to create a complex site authorization system where
specific actions on resources are given custom rules. It extends
Apache::AuthCookie to track sessions. It has been tested with Apache 1 and 2,
and seems to work well. There are sample sites in the samples directory. The
differences in the two apache environments require slightly different setups,
so be sure to use the proper sample for your configuration.
Use Apache2::SiteControl for apache 2.x.
Description
===========
There are two levels of control in Apache::SiteControl.
The first is managed by Apache::SiteControl, and determines if a valid user
has logged in. If so, it makes a user object available to the request
processor. This is done using Apache::SiteControl::UserFactory (a good base
implementation is already written). The underlying code associates this user
with a session, and manages the browser interaction.
The second level of control is supplied by an application level
PermissionManager. The user objects are passed to this object, along
with the requested action and an opaque resource (of any type). Rules are
installed in the PM that determine if a specific action is allowed for a given
user and resource.
if($manager->can($currentUser, "change", $dnsrecord)) {
...
}
where the PM applies the various installed rules (user-defined) and returns
true if the action is allowed, false otherwise. In this example, one of the
rules might detect that the resource (dnsrecord) is a row from a DNS tracking
table. It might then check to see if the currentUser is associated with
DNS management and return true if they are, false otherwise. The top level
application could then use this in a pretty abstract way. For example, if there
is a generic section of code that allows users to modify a row from a table,
the same code could be used:
if($manager->can($currentUser, "change", $thisRecord)) {
...
}
The application doesn't have to figure out what thisRecord is...the rules can
sense them. This allows the top-level application to be written in very
generic terms, and rules to be written based on the actual logic involved.
A rule might include code like this:
sub grants
{
$this = shift;
$user = shift;
$action = shift;
$resource = shift;
if($action eq "change") {
if($resource->isa("DNS::Record"))
{
if($resource->getContactEMail() eq $user->getAttribute("email"))
{
return "permission granted by DNSRule";
}
}
}
return 0;
}
which would detect the proper types that it knows how to handle, and do a check
that would indicate if permission is to be granted.
Comments on Rules
How would you make a system that allows everything, unless something is
specifically denied?
Have a GrantAll rule that always grants permission.
Add rules that never grant, but deny on specific cases.
How to make a system that denies everything except things that have been
checked out:
Write rules that grant on your specific cases. The default is to deny
permission if no rules have anything else to say about the request.
A rule can take several approaches:
Relative rule: It grants but never denies. Or it denies, but never grants.
Absolute rule: If it grants, then it does not deny. If it does not grant, then
it denies.
Read the manual pages for more information.
Apache2-SiteControl-1.05/Makefile.PL 0000644 0000764 0000764 00000001422 10470673662 015643 0 ustar tkay tkay use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
NAME => 'Apache2::SiteControl',
VERSION => '1.05',
PREREQ_PM => { Apache2::AuthCookie => 3.08,
Apache::Session::File => 1.54,
Apache2::Request => 2.05,
Crypt::CBC => 2.14,
Crypt::CAST5 => 0.04,
# Authen::Radius => 0.10, optional
}, # e.g., Module::Name => 1.1
ABSTRACT => 'An object-oriented, fine-grained site access control facility',
AUTHOR => 'Tony Kay ',
);
Apache2-SiteControl-1.05/Changes 0000644 0000764 0000764 00000005635 10470666340 015171 0 ustar tkay tkay Aug 16, 2006: Version 1.05
- Added proper code for logout (MSD was not quite complete...)
Aug 14, 2006: Version 1.04
- Major performance improvement in multiple session detection. New variable (SiteControlUsermap) must be set in order to enable multiple session detection now.
Mar 17, 2006: Version 1.03
- Removed Radius from dependency list
July 8, 2005: Version 1.0
- Added code so that session encryption key can be set by external code.
This allows a random, in-memory key to be used instead of a static one
that can be compromised by reading a config file.
- INCOMPATIPLE NAME CHANGE: Changed AccessController to Apache::SiteControl.
This makes more sense in the CPAN sense, and will help with installation
and version checking. See README.UPGRADING_TO_1.0.
- The sample code should work, but it is untested. (Apache2::SiteControl is
not used by the author. It is maintained by request from other users who
do use it.)
June 14, 2005: Version 0.46
- Added encryption when saving passwords to session files. Adds a little
security, but still needs to be better.
May 5, 2005: Version 0.42
- Fixed bug in saving extra user credentials to session
May 1, 2005: Version 0.42
- Changed name to Apache::SiteControl
- Removed radius bugfix from 0.41...needs more debugging
May 1, 2005:
- Fixed bug when passing extended credentials to check_credentials.
Apr 29, 2005: Version 0.41
- Added the ability to pass extra "credentials" from the login page. This
will allow you to choose alternatives (such as imap server for a webmail
client, etc.)
- Patched Radius.pm to include NAS IP
Apr 20, 2005: Version 0.41
- Added ability to store password in user object. This is enabled with an
Apache directive.
Mar 1, 2005: Version 0.3.1
- Changed call to user factory so that all credentials are passed. This
makes it possible to embed the password in the user object for things like
pass-through logins.
- New option to allow caching of passwords in the server side session (off
by default for security reasons...see docs/apache)
June 7, 2004: Version 0.3
- Now works with Apache 2/mod_perl 2 in Apache compat mode
- Wrote sample sites for both apache 1 and 2.
- Updated docs to reflect all the changes
June 2, 2004
- Updated concepts of User, UserFactory
- User now has methods for managing the session. You can add data to the
session simply by calling $user->setAttribute(...), and you can get it
back by calling $user->getAttribute(...)
- Logouts are now done by simply calling $user->logout
- UserFactory is now tightly integrated with Apache::Session::File, and
the factory is now responsible for all persistence management.
- Much less code need be written to start using the package. Mostly done in
httpd.conf now. (You still need to write rules, and a permission factory
of course).
Apache2-SiteControl-1.05/sample/ 0000755 0000764 0000764 00000000000 10470673673 015155 5 ustar tkay tkay Apache2-SiteControl-1.05/sample/samplelogin.pl 0000755 0000764 0000764 00000003021 10361323142 020001 0 ustar tkay tkay #!/usr/bin/perl
use strict;
my $r = Apache2->request;
$r->status(200);
# If they tried going to a protected resource, find out what it was so we can
# forward them there on success.
my $uri = $r->prev->uri if($r->prev);
# if there are args, append that to the uri
my $args = $r->prev->args if($r->prev);
if ($uri && $args) {
$uri .= "?$args";
}
$uri = "/sample/site/index.html" if !$uri;
my $reason = $r->prev->subprocess_env("AuthCookieReason") if($r->prev);
my $form = <Enter Login and Password
HERE
$r->no_cache(1);
my $x = length($form);
$r->content_type("text/html");
$r->header_out("Content-length","$x");
$r->header_out("Pragma", "no-cache");
$r->send_http_header;
$r->print ($form);
Apache2-SiteControl-1.05/sample/index.html 0000644 0000764 0000764 00000000262 10361323142 017130 0 ustar tkay tkay
Sample system
Apache2-SiteControl-1.05/sample/apache_modperlinit.pl 0000755 0000764 0000764 00000000501 10361323142 021316 0 ustar tkay tkay # This is the location of the site_control library. Not needed it you installed
# Apache::SiteControl in your system paths.
use lib qw(/home/tkay/src/site_control2/lib);
# The location of the extra modules used in the sample. Modify to match your
# extract directory
use lib qw(/home/tkay/src/site_control2/sample);
1;
Apache2-SiteControl-1.05/sample/SimpleAuth.pm 0000644 0000764 0000764 00000000501 10361323142 017540 0 ustar tkay tkay package SimpleAuth;
use 5.008;
use strict;
use warnings;
sub check_credentials
{
my $r = shift; # Apache request object
my $username = shift;
my $password = shift;
return 1 if($username eq 'admin' && $password eq 'test');
return 1 if($username eq 'user' && $password eq 'test');
return 0;
}
1;
Apache2-SiteControl-1.05/sample/EditControlRule.pm 0000644 0000764 0000764 00000001557 10361323142 020557 0 ustar tkay tkay package EditControlRule;
use Apache2::SiteControl::Rule;
@ISA = qw(Apache2::SiteControl::Rule);
# This rule is going to be used in a system that automatically grants
# permission for everything (via the GrantAllRule). So this rule will
# only worry about what to deny, and the grants method can return whatever.
# Note that writing a deny-based system is inherently more dangerous and
# buggy because of the lack of type-safety. Typos in the HTML components can
# cause a rule to fail to deny an invalid request, which is typically less
# desirable than failing to grant a request. The former is a security hole that
# might get missed; the latter is a bug that gets quickly reported.
sub grants($$$$)
{
return 0;
}
sub denies($$$$)
{
my ($this, $user, $action, $resource) = @_;
return 1 if($action eq "edit" && $user->getUsername ne "admin");
return 0;
}
1;
Apache2-SiteControl-1.05/sample/site/ 0000755 0000764 0000764 00000000000 10470673673 016121 5 ustar tkay tkay Apache2-SiteControl-1.05/sample/site/logout.html 0000644 0000764 0000764 00000000657 10361323142 020306 0 ustar tkay tkay
LOGOUT
% if($success) {
You have been logged out.
% } else {
Attempt to log out failed. You were not logged in.
% }
<%init>
my $currentUser = Apache2::SiteControl->getCurrentUser($r);
my $manager = Apache2::SiteControl->getPermissionManager($r);
# This would be where you would access your back-end data store to get
# data...we will simulate this will literals:
my $preferences = { favoriteColor => 'Red', age => 20 };
%init>
<%once>
sub colorList($)
{
my $prefs = shift;
my $result = "";
for my $color ("Red", "Green", "Blue", "Purple", "Pink")
{
if($color eq $prefs->{"favoriteColor"}) {
$result .= "