Code Search for Developers
 
 
  

configure_apache.pl from AlphaMail at Krugle


Show configure_apache.pl syntax highlighted

#!/usr/bin/perl -w
use strict;

our $apache_root;
our $apache_modules;
our $alphamail;
our $config_dir;
our $log_dir;
our $message_cache_dir;
our $session_dir;
our $max_message_size; # bytes
our $large_file_dir;
our $large_file_limit; # bytes
our $max_downloads;
our $post_limit; # bytes
our $scratch_space_dir; 
our $user;
our $group;
our $ip;
our $port;
our $ssl_port;
our $domain;
our $host;
our $session_timeout;
our $preferences_dir;
our $webcache_port;
our $spam_address;
our $allowed_per_page;
our $default_app;
our $sandbox_dir;
our $sandbox_user;
our $sandbox_util;

our %progs = ( 
               jpegtopnm => qx(which jpegtopnm 2> /dev/null),
               tifftopnm => qx(which tifftopnm 2> /dev/null),
               giftopnm => qx(which giftopnm 2> /dev/null),
               pngtopnm => qx(which pngtopnm 2> /dev/null),
               pnmscale => qx(which pnmscale 2> /dev/null),
               pnmtojpeg => qx(which pnmtojpeg 2> /dev/null),
               xlhtml => qx(which xlhtml 2> /dev/null),
               antiword => qx(which antiword 2> /dev/null),
               elinks => qx(which elinks 2> /dev/null),
               tar => qx(which tar 2> /dev/null),
               unzip => qx(which unzip 2> /dev/null),
               openssl => qx(which openssl 2> /dev/null),
               pnmscale => qx(which pnmscale 2> /dev/null) 
              );

sub check
{
   my $pkg = shift;
   my $version = shift;
   my $t;

   print STDERR "Checking for at least version $version of $pkg: \n";
   eval {
      my $v = `perl -M$pkg -e 'print \$${pkg}::VERSION' 2> /dev/null`;
      $v =~ s/\s*//g;
      die "\t$pkg IS NOT INSTALLED.\n" if($v =~ m/^\s*$/);
      die "\tThe installed version of $pkg is $v. \tAlpha Mail requires at least version $version.\n" if($v < $version);
      print STDERR "OK\n";
   };
   if($@) {
      print STDERR "NO: $@";
      return 0;
   }
   return 1;
}

# Check for required packages:
sub verify_packages
{
   my $ok = 1;
   print STDERR "Checking for required packages (use cpan(1) to update/install on errors).\n";
   $ok &= check('Apache::SiteControl', 1.0);
   $ok &= check('Apache::AuthCookie', 3.04);
   $ok &= check('MIME::Parser', 5.4);
   $ok &= check('Net::SMTP', 2.29);
   $ok &= check('HTML::Entities', 1.29);
   $ok &= check('Log::Log4perl', 0.47);
   $ok &= check('Unicode::IMAPUtf7', 2.0);
   $ok &= check('Time::Format', 1.0);
   $ok &= check('Text::Wrap', 2001.0929);
   $ok &= check('Crypt::CBC', 2.14);
   $ok &= check('Crypt::CAST5', 0.04);
   $ok &= check('Data::Dumper', 2.0);
   $ok &= check('Carp', 1.0);
   $ok &= check('Encode', 2.0);
   $ok &= check('IO::File', 1.0);
   $ok &= check('IO::Socket', 1.25);
   $ok &= check('IO::Socket::INET', 1.24);
   $ok &= check('Text::Aspell', 0.04);
   $ok &= check('MIME::Words', 5.417);
   $ok &= check('Time::HiRes', 1.59);
   $ok &= check('Digest::MD5', 2.33);
   $ok &= check('Email::Address', 1.80);
   $ok &= check('Bundle::HTML::Mason', 0.09);
   if(!$ok) {
      print STDERR "Please install the missing packages and re-run.\n";
      exit 1;
   } else {
      print STDERR "OK\n";
   }
      
}

sub ask
{
   my $question = shift;
   my $default = shift;
   my @responses = @_;
   my $resp;

   if(@responses) {
      do {
         $" = ", ";
         print "$question (@responses): [$default] ";
         $resp = <STDIN>;
         chomp $resp;
         $resp = $default if(length($resp) == 0);
      } while(!grep(!/\Q$resp\E/, @responses));
      $" = " ";
   } else {
      print "$question: [$default] ";
      $resp = <STDIN>;
      chomp $resp;
      $resp = $default if(length($resp) == 0);
   }

   return $resp;
}

sub ask_for_dir
{
   my $question = shift;
   my $default = shift;
   my $must_exist = shift;
   my $resp;
   my $yn;

   do {
      print "$question [$default]: ";
      $resp = <STDIN>;
      chomp $resp;
      $resp = $default if(length($resp) == 0);
      if(!$must_exist && (!-d $resp || !-w $resp)) {
         print STDERR "Cannot write to $resp\n";
         $yn = ask("Create the directory?", "y", "n");
         chomp $yn;
         mkdir $resp if($yn eq 'y');
      }
   } while(length($resp) == 0 || !-d $resp || !-w $resp);

   return $resp;
}

sub do_subs
{
   my %dirmap = (
      'alphamail.conf' => "$config_dir/apache",
      'apache.conf' => "$config_dir/apache",
      'init.pl' => "$config_dir/apache",
      'log4perl.conf' => "$config_dir",
      );
   my $fn;
   my $line;

   for my $file (keys %dirmap)
   {
      $file =~ s!^.*/!!g;
      print STDERR "Configuring $file to $dirmap{$file}/$file\n";
      open DATA, "<$alphamail/conf/$file";
      open OUT, ">$dirmap{$file}/$file";
      while($line = <DATA>)
      {
         $line =~ s/CONFIG_DIRECTORY/$config_dir/g;
         $line =~ s/APACHECONF_DIRECTORY/$config_dir\/apache/g;
         $line =~ s/ALPHAMAIL_DIRECTORY/$alphamail/g;
         $line =~ s/SESSION_DIRECTORY/$session_dir/g;
         $line =~ s/ALPHAMAIL_POSTLIMIT/$post_limit/g;
         $line =~ s/ALPHAMAIL_SCRATCHSPACE/$scratch_space_dir/g;
         $line =~ s/LOG_DIRECTORY/$log_dir/g;
         $line =~ s/ALPHA_USER/$user/g;
         $line =~ s/ALPHA_GROUP/$group/g;
         $line =~ s/ALPHA_ADDRESS/$ip/g;
         $line =~ s/ALPHA_PORT/$port/g;
         $line =~ s/ALPHA_DOMAIN/$domain/g;
         $line =~ s/ALPHA_SSL_PORT/$ssl_port/g;
         $line =~ s/ALPHA_HOST/$host.$domain/g;
         $line =~ s/APACHE_ROOT/$apache_root/g;
         $line =~ s/APACHE_MODDIR/$apache_modules/g;
         print OUT $line;
      }
      close OUT;
      close DATA;
   }
}

sub fix_permissions
{
   `chown -R $user "$apache_root/mason" "$alphamail/htdocs" "$alphamail/mason" "$config_dir" "$session_dir" "$message_cache_dir" "$log_dir" "$preferences_dir" "$large_file_dir" "$scratch_space_dir"`;
   `chmod 700 "$config_dir" "$session_dir" "$message_cache_dir" "$preferences_dir" "$large_file_dir" "$scratch_space_dir"`;
   `chmod 755 "$log_dir"`;
}

sub gen_adminconfig
{
   open DATA, ">$config_dir/alphamail_config";
   print DATA <<EOF;
# imap servers: mx=imap_server, ...
# for example:
imap_servers: uoregon.edu=imap.uoregon.edu, gladstone.uoregon.edu=gladstone.uoregon.edu

# Variables used for the login screen:
organization_name: University of Oregon

base_url: https://$host.$domain:$ssl_port

# Port where the imap_webcache daemon lives
webcache_port: $webcache_port

# folder_prefix is the prefix for the location where user folders are stored on
# the IMAP server(s). TODO: Add one of these for each server, in case they
# don't match.
folder_prefix: mail/

# session_timeout is the number of seconds of idle time before we ask for the
# user's password again.
session_timeout: $session_timeout

# User preferences and addressbook location
prefsdir: $preferences_dir

# The location of temporary message files, created while parsing MIME (incoming
# and outgoing). This will also be where attachments are decoded and stored.
message_tmpdir: $message_cache_dir

# These files should be scheduled for cleanup as they get old (i.e. not been
# accessed for 5 minutes).
message_tmpdir_cachetime: 300

# Some mail messages come in plain text with extremely long line lengths. This
# parameter indicates what width to wrap them to.
textwrap_columns: 80

# Sandbox parameters. Where to find the executable (which must be setuid root),
# and where to put the files that the external viewers will work on.
sandbox_util: $sandbox_util
sandbox: $sandbox_dir

# ATTACHMENT VIEWERS. 

# These utilities are needed by the attachment viewers. They (and all the files
# they use) must be hard linked into the sandbox directory.

# on-the-fly icon image generation
jpegtopnm: $progs{jpegtopnm}
pnmtojpeg: $progs{pnmtojpeg}
pnmscale: $progs{pnmscale}
tifftopnm: $progs{tifftopnm}
giftopnm: $progs{giftopnm}
pngtopnm: $progs{pngtopnm}
# Height of the attachment icons for images
iconsize: 50

# MUST support z option (use GNU tar)
tar: $progs{tar}
unzip: $progs{unzip}

# Word document converter
antiword: $progs{antiword}

# Excel spreadsheet converter
xlhtml: $progs{xlhtml}

# HTML to text conversion
elinks: $progs{elinks}

# COMPOSE OPTIONS

# If a to, cc, or bcc address is given without an @ sign, what domain should be
# assumed? The processing of messages happens as such: If the outgoing address
# has an @, then it is left alone. If it does not, then the address book alias
# are substituted. If that fails, @<default_domain> is appended.
# Set it to nothing, and no default domain will be appended.
default_domain: $domain

# User Preference defaults
default_trash: mail/Trash
default_sent: mail/sent-mail
default_drafts: none
default_signature_on_top: 0
default_icon_preview: 1
default_linkify: 0
default_messages_per_page: $default_app;
default_quicknav: 0

# Spam reporting
spam_address: $spam_address

# Allowed page sizes of message indexes
allowed_per_page: $allowed_per_page

# ATTACHMENT LIMITS
# Maximum message size with attachments (bytes)
max_message_size: $max_message_size

# FILE SHARING OPTIONS:
# File vault directory (large attachment alternative)
large_file_dir: $large_file_dir

# Maximum size of files in file vault (bytes)
large_file_limit: $large_file_limit
large_file_max_downloads: $max_downloads

# Openssl (used for encryption)
openssl: $progs{openssl}

EOF

   close DATA;
}

sub mkdir_p
{
   my $directory = shift;
   my $perms = shift;
   $perms = 0755 if(!defined($perms));
   my @comp = split '/', $directory;
   my $dir;

   $dir = "/";
   for my $c (@comp) {
      $dir .= "/$c";
      if(!-d $dir) {
         mkdir "$dir", $perms or die "Could not create $dir";
      }
   }
}

sub create_sandbox
{
   my %dep;
   my ($a, $b, $uid, $gid, $c, $d, $e, $homedir) = getpwnam($sandbox_user);

   die "No such user $sandbox_user" if(!defined($a));

   die "Unable to write to sandbox $sandbox_dir" if(-w $sandbox_dir);
   mkdir_p("$sandbox_dir/tmp", 0777);
   `chown $user "$sandbox_dir/tmp"`;
   `chmod 777 "$sandbox_dir/tmp"`;

   $homedir = "$sandbox_dir$homedir";
   mkdir_p($homedir);
   chown $uid, $gid, $homedir or die "Cannot change ownership of $homedir to $sandbox_user";

   # Collect all dependencies, and make links
   for my $prog (keys %progs) {
      my $loc = $progs{$prog};
      chomp $loc;
      $loc =~ m'^(.*)/[^/]*$';
      my $dirname = $1;
      mkdir_p("$sandbox_dir$dirname");
      link $loc, "$sandbox_dir$dirname/$prog" or die "Unable to link $loc to $sandbox_dir$dirname/$prog";

      # Do the same for dependencies
      my @deps = qx(ldd $progs{$prog});
      for my $d (@deps) {
         if($d =~ m'\s(/\S*)\s') {
            my $f = $1;
            $f =~ m'^(.*/)[^/]*$';
            my $base = $1;
            print "Adding dependency $f for $prog\n";
            $dep{$f} = 1;
            while(-l $f) { # Find the _real_ file as well
               $f = readlink $f;
               $f = $base . $f if($f !~ m'^/');
               $dep{$f} = 1;
               print "Adding dependency $f for $prog\n";
            }
         }
      }
   }

   for my $d (keys %dep) {
      $d =~ m'^(.*)/([^/]*)$';
      my $dirname = $1;
      my $filename = $2;
      mkdir_p("$sandbox_dir$dirname");
      link $d, "$sandbox_dir$d" or die "Unable to link $d to $sandbox_dir$d";
   }

   if(!-d "/usr/share/antiword") {
      print "\n\nERROR: Could not find antiword files in /usr/share/antiword. You will have to manually link them\n\n";
      sleep 5;
   } else  {
      print "linking anitword files";
      mkdir_p("$sandbox_dir/usr/share/antiword");
      for my $f (</usr/share/antiword/*>)
      {
         if(!-d $f) {
            link "$f", "$sandbox_dir$f" or die "Could not link $f to $sandbox_dir$f";
         }
      }
   }

   print "Building sandbox utility\n";
   my @lines = qx(cd $alphamail/util/sandbox; SANDBOX="$sandbox_dir" USER="$sandbox_user" make clean sandbox 2>&1);
   print "@lines";
   die "Build failed!" if(!-x "$alphamail/util/sandbox/sandbox");
   print "Build complete.\n";

   chown 0, 0, $sandbox_util or die "Could not set root permission on $sandbox_util";
   chmod 04755, $sandbox_util or die "Could not set setuid on $sandbox_util";
}

my $d = `pwd`;
chomp $d;

while(1) {
   $alphamail = ask_for_dir("Where are the Alpha Mail files?", $d, 1);
   if(!-r "$alphamail/lib/AlphaMail/Middleware.pm") {
      print STDERR "That does not appear to be the correct directory. Please give the directory name which contains lib, etc, htdocs, ...)\n";
      next;
   }
   else {
      last;
   }
}

print <<SANDBOX_MSG;

AlphaMail uses a sandbox when running external viewers (like elinks and
pnmtojpeg). This is a security feature that helps eliminates security problems
with the external viewer program weaknesses.

IMPORTANT NOTE: The sandbox MUST be on the same filesystem as the other
directories that alphamail uses, since it uses hard links to avoid copying
files from one place to another.
SANDBOX_MSG
$sandbox_dir = ask_for_dir("Where should the sandbox be created?", "$alphamail/sandbox", 0);
$sandbox_user = ask("What user should the sandbox be owned by?", "nobody");
`rm -rf $sandbox_dir` if(length($sandbox_dir) > 5);
$sandbox_util = "$alphamail/util/sandbox/sandbox";

create_sandbox;
verify_packages;

$config_dir = ask_for_dir("Directory for apache configuration files: ", "$alphamail/etc", 0);
mkdir "$config_dir/apache";
$log_dir = ask_for_dir("Directory for log files: ", "$alphamail/log", 0);
$message_cache_dir = ask_for_dir("Directory for message cache: ", "$alphamail/messages", 0);
$scratch_space_dir = ask_for_dir("Where should upload files be stored during upload? This MUST be on the same filesystem as the message cache", "$alphamail/tmp", 0);
$preferences_dir = ask_for_dir("Directory for user preferences and address books: ", "$alphamail/prefs", 0);
$session_dir = ask_for_dir("Directory for session info: ", "$alphamail/sessions", 0);
mkdir "$session_dir/locks";
$large_file_dir = ask_for_dir("Directory for file vault \n\t(large file attachment alternative):", "$alphamail/filevault", 0);

my @groups;
my @users;
my $t;
my $line;

my ($du, $dg) = (0,0);
my $i;

open GRP, "</etc/group";
$i = 0;
while($line = <GRP>) {
   $line =~ m/^([^:]*):/;
   push @groups, $1;
   $dg = $i if $1 =~ m/apache|www/;
   $i++;
}
close GRP;

open PW, "</etc/passwd";
$i=0;
while($line = <PW>) {
   $line =~ m/^([^:]*):/;
   push @users, $1;
   $du = $i if $1 =~ m/apache|www/;
   $i++;
}
close PW;

$apache_root = ask_for_dir("What is your apache's server root directory? ", "/usr/local/apache", 1);
mkdir "$apache_root/mason";
$apache_modules = ask_for_dir("What is your apache's module directory? ", "$apache_root/libexec", 1);
$user = ask("What user should apache run as? ", $users[$du], @users);
$group = ask("What group should apache run as?", $groups[$dg], @groups);
$ip = ask("What IP should be bound? (* for all)", "*");
$port = ask("What port should be used for HTTP?", 80);
$ssl_port = ask("What port should be used for HTTPS?", 443);
$domain = `domainname`;
chomp $domain;
$domain = ask("What domain name should be used (do NOT include the host's name)?", $domain);
$host = `hostname`;
chomp $host;
$host =~ s/^[^.]*\..*$//;
$host = ask("What host name should be used (not FQDN!)?", $host);

for my $prog (sort keys %progs) {
   chomp $progs{$prog};
   if(! -x $progs{$prog}) {
      print STDERR "Cannot find $prog.\n";
      $progs{$prog} = ask("Location and name of $prog: ", "/usr/bin/$prog");
      if(! -x $progs{$prog}) {
         print STDERR "WARNING: $progs{$prog} does not exist or is not executable.\n";
      }
   } else {
      print STDERR "Found $prog.\n";
   }
}

$session_timeout = ask("How long (in seconds) can a user be idle before session timeout?", 300);
$webcache_port = ask("What localhost port hosts the imap_webcache?", 1234);
$spam_address = ask("What email address should spam reports be sent to?", "");
$allowed_per_page = ask("Enter a comma separated list of allowed page sizes for message indexes. Larger page sizes tend to incur more overhead:", "10, 20, 35, 50");
$allowed_per_page =~ m/^(\d+)\D/;
$default_app = $1;
$max_message_size = ask("How big can a message (with attachments) be (in bytes)?", 5000000);
$large_file_limit = ask("What is the file size limit for the file vault (in bytes)?", 50000000);
$max_downloads = ask("How many times should I allow a shared file to be downloaded?", 7);

$post_limit = ask("\n\nWhat do you want for a hard limit on HTTP POST?\nThis should be a number much larger than the largest upload you see as\na non-attack. If this limit is reached, there is no good way to give the\nuser a proper error message, so it should be at least somewhat larger\nthan your file size limits for the file vault.\nZero means no limit.\nSize (in bytes): ", 0);

do_subs;

fix_permissions;

gen_adminconfig;

print <<EOF;



STATUS OF CONFIGURATION
=======================
Configuration files written to: $config_dir

Configured Apache for: $host.$domain
HTTP Port: $port
SSL Port: $ssl_port
Binding to IP: $ip
Running as $user/$group
Sandbox root configured to be: $sandbox_dir
Sandbox utility will run as: $sandbox_user

Logs will be stored in: $log_dir
Cached messages will be in $message_cache_dir
Session information will be in: $session_dir. 
User preferences will be in: $preferences_dir. 

Permissions have been restricted, but be aware that mail messages and temporary
transfer files will be visible in $message_cache_dir and $scratch_space_dir.

You should be able to start the system with:

# apache -f $config_dir/apache/apache.conf
or 
# httpd -f $config_dir/apache/apache.conf

EOF

print "The Alpha Mail URL will be: https://$host.$domain:$ssl_port/mail\n" if($ssl_port != 443);
print "The Alpha Mail URL will be: https://$host.$domain/mail\n" if($ssl_port == 443);

print "\n\nNOTE: If you are using the generated apache config, then you will need to install your SSL files as $config_dir/apache/ssl/server.key and $config_dir/apache/ssl/server.cert\n";




See more files for this project here

AlphaMail

AlphaMail is an accelerated web mail interface with a C++ middleware layer that is more effective than an IMAP proxy which is a highly scalable (10k+ users). The interface includes modern features, Section 508 compliance, and universal browser support.

Project homepage: http://sourceforge.net/projects/alphamail
Programming language(s): C++,Java,JavaScript,Perl
License: other

  configure_apache.pl