Apache-SiteControl

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN


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.

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

docs/apache  view on Meta::CPAN

   - 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.

lib/Apache/SiteControl/Radius.pm  view on Meta::CPAN

#use Apache::Connection;
#use Apache::RequestRec;
#use APR::SockAddr;

our $VERSION = "1.0";

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__

lib/Apache/SiteControl/UserFactory.pm  view on Meta::CPAN

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 $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") || "Apache::SiteControl::UserFactory";
   my $user = undef;

lib/Apache/SiteControl/UserFactory.pm  view on Meta::CPAN

         }
      }
      tie %session, 'Apache::Session::File', undef, 
         {
            Directory => $sessiondir,
            LockDirectory => $lockdir
         };
      $user = new Apache::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;

lib/Apache/SiteControl/UserFactory.pm  view on Meta::CPAN

         Directory => $sessiondir,
         LockDirectory => $lockdir
         };
      # FIXME: Document the possible problems with changing user factories when
      # persistent sessions already exist.
      $user = new Apache::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

lib/Apache/SiteControl/UserFactory.pm  view on Meta::CPAN

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 Apache::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($$) 

lib/Apache/SiteControl/UserFactory.pm  view on Meta::CPAN

=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

Apache::SiteControl::User, Apache::SiteControl::PermissionManager,
Apache::SiteControl::Rule, Apache::SiteControl

=head1 AUTHOR

sample/SimpleAuth.pm  view on Meta::CPAN

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;

sample/samplelogin.pl  view on Meta::CPAN

<HEAD>
<TITLE>Enter Login and Password</TITLE>
</HEAD>
<BODY onLoad="document.forms[0].credential_0.focus();">
<FORM METHOD="POST" ACTION="/sample/SampleLogin">
<TABLE WIDTH=60% ALIGN=CENTER VALIGN=CENTER>
<TR><TD ALIGN=CENTER>
<H1>This is a secure document</H1>
</TD></TR>
<TR><TD ALIGN=LEFT>
<P>Failure reason: '$reason'.  Please enter your login and password to authenticate.</P>
</TD>
<TR><TD>
<INPUT TYPE=hidden NAME=destination VALUE="$uri">

</TD></TR>
<TR><TD>
<TABLE ALIGN=CENTER>
<TR>
<TD ALIGN=RIGHT><B>Login:</B></TD>
<TD><INPUT TYPE="text" NAME="credential_0" SIZE=10 MAXLENGTH=10></TD>
</TR>
<TR>
<TD ALIGN=RIGHT><B>Password:</B></TD>
<TD><INPUT TYPE="password" NAME="credential_1" SIZE=8 MAXLENGTH=8></TD>
</TR>
<TR>
<TD COLSPAN=2 ALIGN=CENTER><INPUT TYPE="submit" VALUE="Continue"></TD>
</TR></TABLE>
</TD></TR></TABLE>
</FORM>
</BODY>
</HTML>
HERE



( run in 1.051 second using v1.01-cache-2.11-cpan-49f99fa48dc )