#!/usr/bin/perl
#
# webcalng - a web based calendar program.
# Copyright 2003 - webcalng software solutions
#
# Specify the install directory, and chdir to it. This is needed to support mod_perl2.
chdir '/home/httpd/vhosts/iplac.org/httpdocs/cgi/calendar';
use lib '/home/httpd/vhosts/iplac.org/httpdocs/cgi/calendar';
$::db_dir = "/home/httpd/vhosts/iplac.org/httpdocs/CalImages";
# Test for the existance and compilation of perl modules. Print error
# and exit if anything is not working right already.
BEGIN {
eval q{
use CGI;
use Time::Local;
use HTML::Template;
use webcalng_subs;
use webcalng_io;
use webcalng_auth;
use webcalng_auth_io;
};
if ($@) {
print "Content-Type: text/html\n\n";
print "Error: webcalng could not load a necessary Perl module:
$@\n";
exit;
}
}
# Load standard Perl modules that we need.
use strict;
use CGI;
# Load webcalng custom Perl modules.
use webcalng_subs;
use webcalng_io;
use webcalng_auth;
use webcalng_auth_io;
#
# Set PATH for Taint mode.
#
$ENV{'PATH'} = "/bin:/usr/bin";
#
# Initialize global variables in case we are running under mod_perl.
#
# The $::output variable holds all the HTML to be sent back to the
# browser until the end of the script, just in case we encounter
# an error and want to abort at any point.
#
$::output = "";
$::calendar = "";
$::cgi_calendar = "";
$::username = "";
$::q = "";
$::cleanq = "";
$::op = "";
$::next_url = "";
%::webcalng_conf = ();
%::preferences = ();
%::language = ();
$::language_filter = "";
$::nocache = 0;
$::permissions_ref = "";
$::template_path = "";
$::HTTP = "";
$::dbh = "";
$::wap = 0;
$::sessionkey = "";
# The $::calendar variable is used in lots of places, so get it and untaint it now.
$::q = new CGI;
$::calendar = $::q->param('calendar');
if ($::calendar) {
if ($::calendar =~ /^([\w,\-,\s,\.]{1,40})$/) {
$::calendar = $1;
$::calendar =~ s/\+/ /g;
$::cgi_calendar = $::calendar;
$::cgi_calendar =~ s/\s+/+/g;
} else {
webcalng_subs::hard_error("Could not untaint \$::calendar");
}
}
#
# Read in the configuration file.
#
webcalng_subs::read_webcalng_conf();
#
# Connect to the database, unless we are using flat files.
#
if ($::webcalng_conf{'DB'}) {
require webcalng_rdbms;
webcalng_rdbms::dbh_setup();
}
#
# We need to read in the preferences before we can properly clean the input parameters
# and setup the language information.
#
webcalng_subs::read_preferences();
$::cleanq = webcalng_subs::clean_params();
$::op = $::cleanq->{'op'} || "";
$::next_url = $::cleanq->{'next_url'} || "";
$::wap = $::cleanq->{'wap'} || 0;
$::sessionkey = $::cleanq->{'sessionkey'} || "";
#
# Detect if they are using a WAP device.
#
if (($ENV{'HTTP_ACCEPT'}) && ($ENV{'HTTP_ACCEPT'} =~ /wml/)) {
$::wap = 1 unless ($::preferences{'force_wap'}{'value'});
}
#
# Load the Time::HiRes module and start timing if we need to.
#
if ($::webcalng_conf{'TIMEIT'}) {
eval q{
require Time::HiRes;
};
webcalng_subs::hard_error($@) if ($@);
$::start_time = [ Time::HiRes::gettimeofday() ];
}
#
# The language filter is how the language variables that are embedded in the
# templates get parsed and set to the correct strings. First, we setup
# the language hash that is used in the language filter with the setup_language
# subroutine.
#
webcalng_subs::setup_language();
$::language_filter = \&webcalng_subs::language;
#
# Determine if we are using SSL or not for links that need to be
# fully qualified.
#
if (($ENV{'HTTPS'}) && ($ENV{'HTTPS'} eq "on")) {
$::HTTP = "https://";
} else {
$::HTTP = "http://";
}
#
# If we are using basic authentication, check if they are accessing this
# via the private URL or not. If they are accessing it via the private URL,
# then we need to override the default URL with the private one.
#
if (! $::webcalng_conf{'USE_COOKIES'}) {
if ($ENV{'REQUEST_URI'} =~ /$::webcalng_conf{'PRIVATE'}/) {
# First, save the original public URL in case they logout.
$::webcalng_conf{'PUBLIC'} = $::webcalng_conf{'WEBCAL'};
$::webcalng_conf{'WEBCAL'} = $::webcalng_conf{'PRIVATE'};
}
}
#
# Make sure that if they are accessing this via a wap device, they are using
# session based authentication.
#
if (($::wap) && (! $::webcalng_conf{'USE_COOKIES'})) {
hard_error("Session based authentication must be used with WAP devices");
}
#
# Main Program section.
#
#
# Before we do anything, check to see if an upgrade to preferences
# or database formats is needed. These things only change in major
# webcalng revisions - 1.x to 2.x, etc. If we still need to do an
# upgrade, then override the given op and make them login as admin
# to complete the upgrade process.
#
if (-f "$::db_dir/.upgrade") {
$::op = "upgrade" unless ($::op eq "process_login");
}
# No matter what we do, we usually want to start out with the output
# from the css template.
webcalng_subs::css() unless (($::op eq "admindoc") || ($::op eq "userdoc") || ($::op eq "sqauth") || ($::op eq "sqlogout") || ($::op eq "sqconnection") || ($::op eq "sqgetsalt") || ($::op eq "syncauthtype") || ($::op eq "syncget") || ($::op eq "syncmod"));
# Authentication. First, setup what permissions this calendar allows, if we
# are looking at a calendar. Then get the username that they are logged in as,
# if they are logged in. Finally, call the authorize subroutine to determine if
# they are allowed to do what they are requesting.
if (($::calendar) && ($::op ne "list")) {
$::permissions_ref = webcalng_io::get_calendar_permissions($::calendar);
if ($::webcalng_conf{'ADMIN_FULL_CONTROL'}) {
$::permissions_ref->{'read'} .= "|admin";
$::permissions_ref->{'write'} .= "|admin";
}
}
if ($::wap) {
$::username = webcalng_auth::wap_get_username();
} else {
$::username = webcalng_auth::get_username();
}
if (! webcalng_subs::authorize()) {
$::nocache = 1;
webcalng_subs::login($::language{'permissions'});
webcalng_subs::version();
$::op = "null";
}
# Call appropriate subroutine to handle request. In many places, we immediately call
# a redirect after doing an action that would update data. This is so that things don't
# get done twice if the user would hit reload (which would repost form data if we didn't
# do a redirect to a clean page).
if ((! $::op) || ($::op eq "start")) {
webcalng_subs::start();
webcalng_subs::version();
} elsif ($::op eq "login") {
if ($::username) {
webcalng_subs::start();
webcalng_subs::version();
} else {
$::nocache = 1;
webcalng_subs::login();
webcalng_subs::version();
}
} elsif ($::op eq "process_login") {
# The process_login subroutine would only get used with
# a session based authentication method.
if ($::wap) {
# If they are accessing this from a wap browser, then we can not
# use cookies to store the session key. We will just URL encode it.
my ($valid_login,$sessionkey,$url);
($valid_login,$sessionkey) = webcalng_auth::wap_process_login();
$url = $::cleanq->{'next_url'} || $::webcalng_conf{'WEBCAL'};
$url =~ s/--/=/g unless ($url =~ /return_link/);
$url =~ s/\.\./&/g unless ($url =~ /return_link/);
$url =~ s/sessionkey=&//g;
$url .= "?" unless ($url =~ /\?/);
$url .= "&" unless ($url =~ /\?$/);
$url .= "sessionkey=$sessionkey";
if ($valid_login) {
webcalng_subs::redirect($url);
} else {
$::nocache = 1;
webcalng_subs::login($::language{'invalid'});
webcalng_subs::version();
}
} else {
# If they are accessing this from a http browser, then we just
# use cookies to store the session key.
my ($valid_login,@cookies,$url);
($valid_login,@cookies) = webcalng_auth::process_login();
$url = $::cleanq->{'next_url'} || $::webcalng_conf{'WEBCAL'};
$url =~ s/--/=/g unless ($url =~ /return_link/);
$url =~ s/\.\./&/g unless ($url =~ /return_link/);
if ($valid_login) {
webcalng_subs::redirect($url,@cookies);
} else {
$::nocache = 1;
webcalng_subs::login($::language{'invalid'});
webcalng_subs::version();
}
}
} elsif ($::op eq "logout") {
if (! $::username) {
webcalng_subs::redirect($::webcalng_conf{'WEBCAL'});
} else {
if ($::webcalng_conf{'USE_COOKIES'}) {
if ($::wap) {
# If they are using a wap browser, we just need to remove
# the session key from the database.
webcalng_auth::wap_logout();
webcalng_subs::redirect($::webcalng_conf{'WEBCAL'});
} else {
# If they are using a http browser, we need to remove the
# session key from the database and clear their session cookie.
my $cookie = webcalng_auth::logout();
webcalng_subs::redirect($::webcalng_conf{'WEBCAL'},$cookie);
}
} else {
webcalng_subs::basic_logout();
webcalng_subs::version();
}
}
} elsif ($::op eq "year") {
webcalng_subs::header($::op);
webcalng_subs::year();
webcalng_subs::footer();
webcalng_subs::version();
} elsif ($::op eq "month") {
webcalng_subs::header($::op);
webcalng_subs::month();
webcalng_subs::footer();
webcalng_subs::version();
} elsif ($::op eq "week") {
webcalng_subs::header($::op);
webcalng_subs::week();
webcalng_subs::footer();
webcalng_subs::version();
} elsif ($::op eq "sqauth") {
webcalng_subs::sqauth();
} elsif ($::op eq "sqweek") {
webcalng_subs::week();
webcalng_subs::sqweek();
} elsif ($::op eq "sqlogout") {
webcalng_subs::sqlogout();
} elsif ($::op eq "sqgetsalt") {
webcalng_subs::sqgetsalt();
} elsif ($::op eq "sqconnection") {
webcalng_subs::sqconnection();
} elsif ($::op eq "day") {
webcalng_subs::header($::op);
webcalng_subs::day();
webcalng_subs::footer();
webcalng_subs::version();
} elsif ($::op eq "minical") {
webcalng_subs::minical();
} elsif ($::op eq "wapnav") {
webcalng_subs::wapnav();
webcalng_subs::footer();
webcalng_subs::version();
} elsif ($::op eq "search") {
webcalng_subs::search();
webcalng_subs::version();
} elsif ($::op eq "additem") {
webcalng_subs::additem();
webcalng_subs::version();
} elsif ($::op eq "additem2") {
webcalng_subs::additem2();
my $day = $::cleanq->{'day'};
my $month = $::cleanq->{'month'};
my $year = $::cleanq->{'year'};
my $url = "$::webcalng_conf{'WEBCAL'}?op=day&calendar=$::cgi_calendar&day=${day}&month=${month}&year=${year}";
$url .= "&sessionkey=$::sessionkey" if ($::sessionkey);
webcalng_subs::redirect($url);
} elsif ($::op eq "edititem") {
webcalng_subs::edititem();
webcalng_subs::version();
} elsif ($::op eq "edititemmulti") {
webcalng_subs::edititemmulti();
webcalng_subs::version();
} elsif ($::op eq "edititem2") {
webcalng_subs::additem2();
my $day = $::cleanq->{'editday'};
my $month = $::cleanq->{'editmonth'};
my $year = $::cleanq->{'edityear'};
my $url = "$::webcalng_conf{'WEBCAL'}?op=day&calendar=$::cgi_calendar&day=${day}&month=${month}&year=${year}";
$url .= "&sessionkey=$::sessionkey" if ($::sessionkey);
webcalng_subs::redirect($url);
} elsif ($::op eq "delitem") {
webcalng_subs::delitem();
my $day = $::cleanq->{'day'};
my $month = $::cleanq->{'month'};
my $year = $::cleanq->{'year'};
my $url = "$::webcalng_conf{'WEBCAL'}?op=day&calendar=$::cgi_calendar&day=${day}&month=${month}&year=${year}";
$url .= "&sessionkey=$::sessionkey" if ($::sessionkey);
webcalng_subs::redirect($url);
} elsif ($::op eq "delitemmulti") {
webcalng_subs::delitemmulti();
webcalng_subs::version();
} elsif ($::op eq "address") {
webcalng_subs::address();
webcalng_subs::version();
} elsif ($::op eq "addaddress") {
webcalng_subs::addaddress();
webcalng_subs::version();
} elsif ($::op eq "addaddress2") {
webcalng_subs::addaddress2();
my $url = "$::webcalng_conf{'WEBCAL'}?op=address&calendar=$::cgi_calendar";
$url .= "&sessionkey=$::sessionkey" if ($::sessionkey);
webcalng_subs::redirect($url);
} elsif ($::op eq "editaddress") {
webcalng_subs::editaddress();
webcalng_subs::version();
} elsif ($::op eq "editaddress2") {
webcalng_subs::editaddress2();
my $url = "$::webcalng_conf{'WEBCAL'}?op=address&calendar=$::cgi_calendar";
$url .= "&sessionkey=$::sessionkey" if ($::sessionkey);
webcalng_subs::redirect($url);
} elsif ($::op eq "deladdress") {
webcalng_subs::deladdress();
my $url = "$::webcalng_conf{'WEBCAL'}?op=address&calendar=$::cgi_calendar";
$url .= "&sessionkey=$::sessionkey" if ($::sessionkey);
webcalng_subs::redirect($url);
} elsif ($::op eq "task") {
webcalng_subs::task();
webcalng_subs::version();
} elsif ($::op eq "addtask") {
webcalng_subs::addtask();
webcalng_subs::version();
} elsif ($::op eq "addtask2") {
webcalng_subs::addtask2();
my $url = "$::webcalng_conf{'WEBCAL'}?op=task&calendar=$::cgi_calendar";
$url .= "&sessionkey=$::sessionkey" if ($::sessionkey);
webcalng_subs::redirect($url);
} elsif ($::op eq "edittask") {
webcalng_subs::edittask();
webcalng_subs::version();
} elsif ($::op eq "edittask2") {
webcalng_subs::edittask2();
my $url = "$::webcalng_conf{'WEBCAL'}?op=task&calendar=$::cgi_calendar";
$url .= "&sessionkey=$::sessionkey" if ($::sessionkey);
webcalng_subs::redirect($url);
} elsif ($::op eq "marktask") {
webcalng_subs::marktask();
my $url = "$::webcalng_conf{'WEBCAL'}?op=task&calendar=$::cgi_calendar";
$url .= "&sessionkey=$::sessionkey" if ($::sessionkey);
webcalng_subs::redirect($url);
} elsif ($::op eq "deltask") {
webcalng_subs::deltask();
my $url = "$::webcalng_conf{'WEBCAL'}?op=task&calendar=$::cgi_calendar";
$url .= "&sessionkey=$::sessionkey" if ($::sessionkey);
webcalng_subs::redirect($url);
} elsif ($::op eq "notes") {
webcalng_subs::notes();
webcalng_subs::version();
} elsif ($::op eq "preferences") {
webcalng_subs::preferences();
webcalng_subs::version();
} elsif ($::op eq "colors") {
webcalng_subs::colors();
webcalng_subs::version();
} elsif ($::op eq "save_preferences") {
$::output = "";
webcalng_subs::save_preferences();
webcalng_subs::read_preferences();
webcalng_subs::css();
webcalng_subs::setup_language();
webcalng_subs::preferences();
webcalng_subs::version();
} elsif ($::op eq "list") {
webcalng_subs::list();
webcalng_subs::version();
} elsif ($::op eq "respond") {
webcalng_subs::respond();
webcalng_subs::version();
} elsif ($::op eq "respond2") {
webcalng_subs::respond2();
webcalng_subs::version();
} elsif ($::op eq "meeting") {
webcalng_subs::meeting();
webcalng_subs::version();
} elsif ($::op eq "availability") {
webcalng_subs::availability();
webcalng_subs::version();
} elsif ($::op eq "addcal") {
webcalng_subs::addcal();
webcalng_subs::version();
} elsif ($::op eq "addcal2") {
webcalng_subs::addcal2();
my $url = "$::webcalng_conf{'WEBCAL'}?op=list&next=month";
$url .= "&sessionkey=$::sessionkey" if ($::sessionkey);
webcalng_subs::redirect($url);
} elsif ($::op eq "delcal") {
webcalng_subs::delcal();
webcalng_subs::version();
} elsif ($::op eq "delcal2") {
webcalng_subs::delcal2();
webcalng_subs::version();
} elsif ($::op eq "modify") {
webcalng_subs::modify();
webcalng_subs::version();
} elsif ($::op eq "modify2") {
webcalng_subs::modify2();
webcalng_subs::version();
} elsif ($::op eq "adduser") {
webcalng_subs::adduser();
webcalng_subs::version();
} elsif ($::op eq "adduser2") {
webcalng_subs::adduser2();
webcalng_subs::version();
} elsif ($::op eq "deluser") {
webcalng_subs::deluser();
webcalng_subs::version();
} elsif ($::op eq "deluser2") {
webcalng_subs::deluser2();
webcalng_subs::version();
} elsif ($::op eq "changepw") {
webcalng_subs::changepw();
webcalng_subs::version();
} elsif ($::op eq "changepw2") {
webcalng_subs::changepw2();
webcalng_subs::version();
} elsif ($::op eq "userdoc") {
webcalng_subs::userdoc();
webcalng_subs::version();
} elsif ($::op eq "admindoc") {
webcalng_subs::admindoc();
webcalng_subs::version();
} elsif ($::op eq "syncauthtype") {
$::output .= "RESULT=SESSION_AUTH:$::webcalng_conf{'USE_COOKIES'}\n";
} elsif ($::op eq "sync_process_login") {
webcalng_subs::sync_process_login();
} elsif ($::op eq "syncget") {
webcalng_subs::syncget();
} elsif ($::op eq "syncmod") {
webcalng_subs::syncmod();
} elsif ($::op eq "upgrade") {
webcalng_subs::upgrade();
} elsif ($::op eq "null") {
# Do nothing.
} else {
# Should never see this, unless the user is screwing around.
webcalng_subs::hard_error("Bad op: $::op\n");
}
# Disconnect from the database if need be.
$::dbh->disconnect() if ($::webcalng_conf{'DB'});
# If we get this far, print a header and display $::output.
webcalng_subs::http_header($::nocache);
webcalng_subs::end() unless (($::op eq "sqweek") || ($::op eq "minical") || ($::op eq "sqauth") || ($::op eq "sqlogout") || ($::op eq "sqconnection") || ($::op eq "sqgetsalt") || ($::op eq "syncauthtype") || ($::op eq "syncget") || ($::op eq "syncmod"));
print $::output;
EXIT: