#!/usr/bin/env perl
# conf.pl
-# Luke Ehresman (luke@squirrelmail.org)
#
-# A simple configure script to configure squirrelmail
+# Copyright (c) 1999-2003 The SquirrelMail Project Team
+# Licensed under the GNU GPL. For full terms see COPYING.
+#
+# A simple configure script to configure SquirrelMail
#
# $Id$
############################################################
-$conf_pl_version = "1.2.0";
+$conf_pl_version = "1.4.0";
############################################################
# Check what directory we're supposed to be running in, and
}
if ( !$imap_auth_mech ) {
- $imap_auth_mech = 'plain';
+ $imap_auth_mech = 'login';
+}
+
+if (!$session_name ) {
+ $session_name = 'SQMSESSID';
}
if ( $ARGV[0] eq '--install-plugin' ) {
print "R Return to Main Menu\n";
} elsif ( $menu == 4 ) {
print $WHT. "General Options\n" . $NRM;
- print "1. Default Charset : $WHT$default_charset$NRM\n";
- print "2. Data Directory : $WHT$data_dir$NRM\n";
- print "3. Attachment Directory : $WHT$attachment_dir$NRM\n";
- print "4. Directory Hash Level : $WHT$dir_hash_level$NRM\n";
- print "5. Default Left Size : $WHT$default_left_size$NRM\n";
- print "6. Usernames in Lowercase : $WHT$force_username_lowercase$NRM\n";
- print "7. Allow use of priority : $WHT$default_use_priority$NRM\n";
- print "8. Hide SM attributions : $WHT$hide_sm_attributions$NRM\n";
- print "9. Allow use of receipts : $WHT$default_use_mdn$NRM\n";
- print "10. Allow editing of identity : $WHT$edit_identity$NRM\n";
- print "11. Allow server thread sort : $WHT$allow_thread_sort$NRM\n";
- print "12. Allow server-side sorting : $WHT$allow_server_sort$NRM\n";
+ print "1. Default Charset : $WHT$default_charset$NRM\n";
+ print "2. Data Directory : $WHT$data_dir$NRM\n";
+ print "3. Attachment Directory : $WHT$attachment_dir$NRM\n";
+ print "4. Directory Hash Level : $WHT$dir_hash_level$NRM\n";
+ print "5. Default Left Size : $WHT$default_left_size$NRM\n";
+ print "6. Usernames in Lowercase : $WHT$force_username_lowercase$NRM\n";
+ print "7. Allow use of priority : $WHT$default_use_priority$NRM\n";
+ print "8. Hide SM attributions : $WHT$hide_sm_attributions$NRM\n";
+ print "9. Allow use of receipts : $WHT$default_use_mdn$NRM\n";
+ print "10. Allow editing of identity : $WHT$edit_identity$NRM\n";
+ print "11. Allow server thread sort : $WHT$allow_thread_sort$NRM\n";
+ print "12. Allow server-side sorting : $WHT$allow_server_sort$NRM\n";
if ( lc($edit_identity) eq "false" ) {
print "13. Allow editing of name : $WHT$edit_name$NRM\n";
}
print "14. Allow server charset search : $WHT$allow_charset_search$NRM\n";
- print "15. Enable UID support : $WHT$uid_support$NRM\n";
+ print "15. Enable UID support : $WHT$uid_support$NRM\n";
+ print "16. PHP session name : $WHT$session_name$NRM\n";
print "\n";
print "R Return to Main Menu\n";
} elsif ( $menu == 5 ) {
} elsif ( $show_imap_settings ) {
if ( $command == 4 ) { $imapServerAddress = command12(); }
elsif ( $command == 5 ) { $imapPort = command13(); }
- elsif ( $command == 6 ) { $imap_auth_mech = command112("IMAP",$imap_auth_mech); }
+ elsif ( $command == 6 ) { $imap_auth_mech = command112a(); }
elsif ( $command == 7 ) { $use_imap_tls = command113("IMAP",$use_imap_tls); }
elsif ( $command == 8 ) { $imap_server_type = command19(); }
elsif ( $command == 9 ) { $optional_delimiter = command111(); }
if ( $command == 4 ) { $smtpServerAddress = command16(); }
elsif ( $command == 5 ) { $smtpPort = command17(); }
elsif ( $command == 6 ) { $pop_before_smtp = command18a(); }
- elsif ( $command == 7 ) { $smtp_auth_mech = command112("SMTP",$smtp_auth_mech); }
+ elsif ( $command == 7 ) { $smtp_auth_mech = command112b(); }
elsif ( $command == 8 ) { $use_smtp_tls = command113("SMTP",$use_smtp_tls); }
}
} elsif ( $menu == 3 ) {
elsif ( $command == 13 ) { $edit_name = command311(); }
elsif ( $command == 14 ) { $allow_charset_search = command314(); }
elsif ( $command == 15 ) { $uid_support = command315(); }
+ elsif ( $command == 16 ) { $session_name = command316(); }
} elsif ( $menu == 5 ) {
if ( $command == 1 ) { command41(); }
elsif ( $command == 2 ) { $theme_css = command42(); }
print "possible. If you set up an organization name, most places where\n";
print "SquirrelMail would take credit will be credited to your organization.\n";
print "\n";
+ print "If your Organization Name includes a '\$', please precede it with a \\. \n";
+ print "Other '\$' will be considered the beginning of a variable that\n";
+ print "must be defined before the \$org_name is printed.\n";
+ print "\$version, for example, is included by default, and will print the\n";
+ print "string representing the current SquirrelMail version.\n";
+ print "\n";
print "[$WHT$org_name$NRM]: $WHT";
$new_org_name = <STDIN>;
if ( $new_org_name eq "\n" ) {
print "Your organization's logo is an image that will be displayed at\n";
print "different times throughout SquirrelMail. This is asking for the\n";
print "literal (/usr/local/squirrelmail/images/logo.png) or relative\n";
- print "(../images/logo.png) path to your logo.\n";
+ print "(../images/logo.png) path from the config directory to your logo.\n";
print "Relative paths to files outside the SquirrelMail distribution\n";
print "will be converted to their absolute path equivalents in config.php.\n";
print "\n";
print "the titlebar. Usually this will end up looking something like:\n";
print "\"Netscape: $org_title\"\n";
print "\n";
+ print "If your Organization Title includes a '\$', please precede it with a \\. \n";
+ print "Other '\$' will be considered the beginning of a variable that\n";
+ print "must be defined before the \$org_title is printed.\n";
+ print "\$version, for example, is included by default, and will print the\n";
+ print "string representing the current SquirrelMail version.\n";
+ print "\n";
print "[$WHT$org_title$NRM]: $WHT";
$new_org_title = <STDIN>;
if ( $new_org_title eq "\n" ) {
}
return $new_optional_delimiter;
}
+# IMAP authentication type
+# Possible values: login, cram-md5, digest-md5
+# Now offers to detect supported mechs, assuming server & port are set correctly
+
+sub command112a {
+ print "If you have already set the hostname and port number, I can try to\n";
+ print "detect the mechanisms your IMAP server supports.\n";
+ print "I will try to detect CRAM-MD5 and DIGEST-MD5 support. I can't test\n";
+ print "for \"login\" without knowing a username and password.\n";
+ print "Auto-detecting is optional - you can safely say \"n\" here.\n";
+ print "\nTry to detect supported mechanisms? [y/N]: ";
+ $inval=<STDIN>;
+ chomp($inval);
+ if ($inval =~ /^y\b/i) {
+ # Yes, let's try to detect.
+ print "Trying to detect IMAP capabilities...\n";
+ my $host = $imapServerAddress . ':'. $imapPort;
+ print "CRAM-MD5:\t";
+ my $tmp = detect_auth_support('IMAP',$host,'CRAM-MD5');
+ if (defined($tmp)) {
+ if ($tmp eq 'YES') {
+ print "$WHT SUPPORTED$NRM\n";
+ } else {
+ print "$WHT NOT SUPPORTED$NRM\n";
+ }
+ } else {
+ print $WHT . " ERROR DETECTING$NRM\n";
+ }
+
+ print "DIGEST-MD5:\t";
+ $tmp = detect_auth_support('IMAP',$host,'DIGEST-MD5');
+ if (defined($tmp)) {
+ if ($tmp eq 'YES') {
+ print "$WHT SUPPORTED$NRM\n";
+ } else {
+ print "$WHT NOT SUPPORTED$NRM\n";
+ }
+ } else {
+ print $WHT . " ERROR DETECTING$NRM\n";
+ }
+
+ }
+ print "\nWhat authentication mechanism do you want to use for IMAP connections?\n\n";
+ print $WHT . "login" . $NRM . " - Plaintext. If you can do better, you probably should.\n";
+ print $WHT . "cram-md5" . $NRM . " - Slightly better than plaintext methods.\n";
+ print $WHT . "digest-md5" . $NRM . " - Privacy protection - better than cram-md5.\n";
+ print "\n*** YOUR IMAP SERVER MUST SUPPORT THE MECHANISM YOU CHOOSE HERE ***\n";
+ print "If you don't understand or are unsure, you probably want \"login\"\n\n";
+ print "login, cram-md5, or digest-md5 [$WHT$imap_auth_mech$NRM]: $WHT";
+ $inval=<STDIN>;
+ chomp($inval);
+ if ( ($inval =~ /^cram-md5\b/i) || ($inval =~ /^digest-md5\b/i) || ($inval =~ /^login\b/i)) {
+ return lc($inval);
+ } else {
+ # user entered garbage or default value so nothing needs to be set
+ return $imap_auth_mech;
+ }
+}
-# authentication type
-# This sub gets reused for IMAP and SMTP, so pass in the server type as an arg
-# Second arg is the default value to use
-# Possible choices: plain, cram-md5, digest-md5
-# SMTP also can be disabled with 'none'
-sub command112 {
- my($default_val,$service,$inval);
- $service=$_[0];
- $default_val=$_[1];
- print "What authentication mechanism do you want to use for " . $service . " logins?\n";
- if ($service eq "SMTP") {
- print $WHT . "none" . $NRM . " - Your SMTP server does not require authorization.\n";
- }
- print $WHT . "plain" . $NRM . " - Plaintext. If you can do better, you probably should.\n";
- print $WHT . "cram-md5" . $NRM . " - Slightly better than plaintext. (Requires PHP mhash extension)\n";
- print $WHT . "digest-md5" . $NRM . " - Privacy protection - better than cram-md5. (Requires PHP mhash extension)\n";
- print "\n*** YOUR " . $service . " SERVER MUST SUPPORT THE MECHANISM YOU CHOOSE ***\n";
- print "If you don't understand or are unsure, you probably want \"plain\"\n\n";
- if ($service eq "SMTP") {
- print "none, ";
- }
- print "plain, cram-md5, or digest-md5 [$WHT$default_val$NRM]: $WHT";
+
+# SMTP authentication type
+# Possible choices: none, plain, cram-md5, digest-md5
+sub command112b {
+ print "If you have already set the hostname and port number, I can try to\n";
+ print "automatically detect the mechanisms your SMTP server supports.\n";
+ print "Auto-detection is *optional* - you can safely say \"n\" here.\n";
+ print "\nTry to detect auth mechanisms? [y/N]: ";
$inval=<STDIN>;
chomp($inval);
- if ( ($service eq "SMTP") && ($inval =~ /^none\b/i) ) {
+ if ($inval =~ /^y\b/i) {
+ # Yes, let's try to detect.
+ print "Trying to detect supported methods (SMTP)...\n";
+
+ # Special case!
+ # Check none by trying to relay to junk@microsoft.com
+ $host = $smtpServerAddress . ':' . $smtpPort;
+ use IO::Socket;
+ my $sock = IO::Socket::INET->new($host);
+ print "Testing none:\t\t$WHT";
+ if (!defined($sock)) {
+ print " ERROR TESTING\n";
+ close $sock;
+ } else {
+ print $sock "mail from: tester\@squirrelmail.org\n";
+ $got = <$sock>; # Discard
+ print $sock "rcpt to: junk\@microsoft.com\n";
+ $got = <$sock>; # This is the important line
+ if ($got =~ /^250\b/) { # SMTP will relay without auth
+ print "SUPPORTED$NRM\n";
+ } else {
+ print "NOT SUPPORTED$NRM\n";
+ }
+ print $sock "rset\n";
+ print $sock "quit\n";
+ close $sock;
+ }
+ # Try login (SquirrelMail default)
+ print "Testing login:\t\t";
+ $tmp=detect_auth_support('SMTP',$host,'LOGIN');
+ if (defined($tmp)) {
+ if ($tmp eq 'YES') {
+ print $WHT . "SUPPORTED$NRM\n";
+ } else {
+ print $WHT . "NOT SUPPORTED$NRM\n";
+ }
+ } else {
+ print $WHT . "ERROR DETECTING$NRM\n";
+ }
+
+ # Try CRAM-MD5
+ print "Testing CRAM-MD5:\t";
+ $tmp=detect_auth_support('SMTP',$host,'CRAM-MD5');
+ if (defined($tmp)) {
+ if ($tmp eq 'YES') {
+ print $WHT . "SUPPORTED$NRM\n";
+ } else {
+ print $WHT . "NOT SUPPORTED$NRM\n";
+ }
+ } else {
+ print $WHT . "ERROR DETECTING$NRM\n";
+ }
+
+
+ print "Testing DIGEST-MD5:\t";
+ $tmp=detect_auth_support('SMTP',$host,'DIGEST-MD5');
+ if (defined($tmp)) {
+ if ($tmp eq 'YES') {
+ print $WHT . "SUPPORTED$NRM\n";
+ } else {
+ print $WHT . "NOT SUPPORTED$NRM\n";
+ }
+ } else {
+ print $WHT . "ERROR DETECTING$NRM\n";
+ }
+ }
+ print "\tWhat authentication mechanism do you want to use for SMTP connections?\n";
+ print $WHT . "none" . $NRM . " - Your SMTP server does not require authorization.\n";
+ print $WHT . "login" . $NRM . " - Plaintext. If you can do better, you probably should.\n";
+ print $WHT . "cram-md5" . $NRM . " - Slightly better than plaintext.\n";
+ print $WHT . "digest-md5" . $NRM . " - Privacy protection - better than cram-md5.\n";
+ print $WHT . "\n*** YOUR SMTP SERVER MUST SUPPORT THE MECHANISM YOU CHOOSE HERE ***\n" . $NRM;
+ print "If you don't understand or are unsure, you probably want \"none\"\n\n";
+ print "none, login, cram-md5, or digest-md5 [$WHT$smtp_auth_mech$NRM]: $WHT";
+ $inval=<STDIN>;
+ chomp($inval);
+ if ($inval =~ /^none\b/i) {
# SMTP doesn't necessarily require logins
return "none";
}
if ( ($inval =~ /^cram-md5\b/i) || ($inval =~ /^digest-md5\b/i) ||
- ($inval =~ /^plain\b/i)) {
+ ($inval =~ /^login\b/i)) {
return lc($inval);
} else {
- return $default_val;
+ # user entered garbage, or default value so nothing needs to be set
+ return $smtp_auth_mech;
}
}
# Data directory
sub command33a {
- print "It is a possible security hole to have a writable directory\n";
- print "under the web server's root directory (ex: /home/httpd/html).\n";
- print "For this reason, it is possible to put the data directory\n";
- print "anywhere you would like. The path name can be absolute or\n";
- print "relative (to the config directory). It doesn't matter. Here\n";
- print "are two examples:\n";
- print " Absolute: /usr/local/squirrelmail/data/\n";
- print " Relative: ../data/\n";
+ print "Specify the location for your data directory.\n";
+ print "The path name can be absolute or relative (to the config directory).\n";
+ print "It doesn't matter. Here are two examples:\n";
+ print " Absolute: /var/spool/data/\n";
+ print " Relative: ../data/\n";
print "Relative paths to directories outside of the SquirrelMail distribution\n";
- print "will be converted to their absolute path equivalents in config.php.\n";
+ print "will be converted to their absolute path equivalents in config.php.\n\n";
+ print "Note: There are potential security risks with having a writable directory\n";
+ print "under the web server's root directory (ex: /home/httpd/html).\n";
+ print "For this reason, it is recommended to put the data directory\n";
+ print "in an alternate location of your choice. \n";
print "\n";
print "[$WHT$data_dir$NRM]: $WHT";
# Attachment directory
sub command33b {
print "Path to directory used for storing attachments while a mail is\n";
- print "being sent. There are a few security considerations regarding this\n";
+ print "being sent. The path name can be absolute or relative (to the config directory).\n";
+ print "It doesn't matter. Here are two examples:\n";
+ print " Absolute: /var/spool/attach/\n";
+ print " Relative: ../attach/\n";
+ print "Relative paths to directories outside of the SquirrelMail distribution\n";
+ print "will be converted to their absolute path equivalents in config.php.\n\n";
+ print "Note: There are a few security considerations regarding this\n";
print "directory:\n";
print " 1. It should have the permission 733 (rwx-wx-wx) to make it\n";
print " impossible for a random person with access to the webserver\n";
print " to list files in this directory. Confidential data might\n";
print " be laying around in there.\n";
+ print " Depending on your user:group assignments, 730 (rwx-wx---)\n";
+ print " may be possible, and more secure (e.g. root:apache)\n";
print " 2. Since the webserver is not able to list the files in the\n";
print " content is also impossible for the webserver to delete files\n";
print " lying around there for too long.\n";
print " 3. It should probably be another directory than the data\n";
print " directory specified in option 3.\n";
- print "Relative paths to directories outside of the SquirrelMail distribution\n";
- print "will be converted to their absolute path equivalents in config.php.\n";
print "\n";
print "[$WHT$attachment_dir$NRM]: $WHT";
return $uid_support;
}
+sub command316 {
+ print "This option allows you to change the name of the PHP session used\n";
+ print "by SquirrelMail. Unless you know what you are doing, you probably\n";
+ print "don't need or want to change this from the default of SQMSESSID.\n";
+ print "[$WHT$session_name$NRM]: $WHT";
+ $new_session_name = <STDIN>;
+ chomp($new_session_name);
+ if ( $new_session_name eq "" ) {
+ $new_session_name = $session_name;
+ }
+ return $new_session_name;
+}
+
+
sub command41 {
print "\nNow we will define the themes that you wish to use. If you have added\n";
print CF " * Created using the configure script, conf.pl\n";
print CF " */\n";
print CF "\n";
-
+ print CF "global \$version;\n";
+
if ($print_config_version) {
print CF "\$config_version = '$print_config_version';\n";
}
print CF "\$use_imap_tls = $use_imap_tls;\n";
print CF "\$use_smtp_tls = $use_smtp_tls;\n";
- print CF "\n";
+ print CF "\$session_name = '$session_name';\n";
- if ( open(LOCAL,"config_local.php") ) {
- # A config_local.php file exists - add it to the bottom of config.php
- while ( $line = <LOCAL> ) {
- print CF $line;
- }
- close LOCAL;
- }
+ print CF "\n";
+ print CF "\@include SM_PATH . 'config/config_local.php';\n";
print CF "\n/**\n";
print CF " * Make sure there are no characters after the PHP closing\n";
$tmp = <STDIN>;
}
-############################################################
# This subroutine corrects relative paths to ensure they
# will work within the SM space. If the path falls within
# the SM directory tree, the SM_PATH variable will be
# prepended to the path, if not, then the path will be
-# converted to an absolute path.
-############################################################
+# converted to an absolute path, e.g.
+# '../images/logo.gif' --> SM_PATH . 'images/logo.gif'
+# 'images/logo.gif' --> SM_PATH . 'config/images/logo.gif'
+# '/absolute/path/logo.gif' --> '/absolute/path/logo.gif'
+# 'http://whatever/' --> 'http://whatever'
sub change_to_SM_path() {
my ($old_path) = @_;
my $new_path = '';
# If the path is absolute, don't bother.
return "\'" . $old_path . "\'" if ( $old_path eq '');
- return "\'" . $old_path . "\'" if ( $old_path =~ /^\// );
- return $old_path if ( $old_path =~ /^\$/);
- return $old_path if ( $old_path =~ /^SM_PATH/ );
-
+ return "\'" . $old_path . "\'" if ( $old_path =~ /^(\/|http)/ );
+ return $old_path if ( $old_path =~ /^(\$|SM_PATH)/);
+
# For relative paths, split on '../'
@rel_path = split(/\.\.\//, $old_path);
$new_path .= '\'';
} else {
# Last, it's a relative path without any leading '.'
- # Prepend SM_PATH (no substitution required)
- $new_path = "SM_PATH . \'" . $old_path . "\'";
+ # Prepend SM_PATH and config, since the paths are
+ # relative to the config directory
+ $new_path = "SM_PATH . \'config/" . $old_path . "\'";
}
return $new_path;
}
+
+# Change SM_PATH to admin-friendly version, e.g.:
+# SM_PATH . 'images/logo.gif' --> '../images/logo.gif'
+# SM_PATH . 'config/some.php' --> 'some.php'
+# '/absolute/path/logo.gif' --> '/absolute/path/logo.gif'
+# 'http://whatever/' --> 'http://whatever'
sub change_to_rel_path() {
my ($old_path) = @_;
- my $new_path = '';
-
- return $old_path if ( $old_path eq '');
- return $old_path if ( $old_path =~ /^\$/ );
- return $old_path if ( $old_path =~ /^\// );
- return $old_path if ( $old_path =~ /^\.\./ );
+ my $new_path = $old_path;
if ( $old_path =~ /^SM_PATH/ ) {
- $new_path = $old_path;
$new_path =~ s/^SM_PATH . \'/\.\.\//;
+ $new_path =~ s/\.\.\/config\///;
}
return $new_path;
}
+
+sub detect_auth_support {
+# Attempts to auto-detect if a specific auth mechanism is supported.
+# Called by 'command112a' and 'command112b'
+# ARGS: service-name (IMAP or SMTP), host:port, mech-name (ie. CRAM-MD5)
+
+ # Misc setup
+ use IO::Socket;
+ my $service = shift;
+ my $host = shift;
+ my $mech = shift;
+ # Sanity checks
+ if ((!defined($service)) or (!defined($host)) or (!defined($mech))) {
+ # Error - wrong # of args
+ print "BAD ARGS!\n";
+ return undef;
+ }
+
+ if ($service eq 'SMTP') {
+ $cmd = "AUTH $mech\n";
+ $logout = "QUIT\n";
+ } elsif ($service eq 'IMAP') {
+ $cmd = "A01 AUTHENTICATE $mech\n";
+ $logout = "C01 LOGOUT\n";
+ } else {
+ # unknown service - whoops.
+ return undef;
+ }
+
+ # Get this show on the road
+ my $sock=IO::Socket::INET->new($host);
+ if (!defined($sock)) {
+ # Connect failed
+ return undef;
+ }
+ my $discard = <$sock>; # Server greeting/banner - who cares..
+
+ if ($service eq 'SMTP') {
+ # Say hello first..
+ print $sock "helo $domain\n";
+ $discard = <$sock>; # Yeah yeah, you're happy to see me..
+ }
+ print $sock $cmd;
+
+ my $response = <$sock>;
+ chomp($response);
+ if (!defined($response)) {
+ return undef;
+ }
+
+ # So at this point, we have a response, and it is (hopefully) valid.
+ if ($service eq 'SMTP') {
+ if (($response =~ /^535/) or ($response =~/^502/)) {
+ # Not supported
+ close $sock;
+ return 'NO';
+ } elsif ($response =~ /^503/) {
+ #Something went wrong
+ return undef;
+ }
+ } elsif ($service eq 'IMAP') {
+ if ($response =~ /^A01/) {
+ # Not supported
+ close $sock;
+ return 'NO';
+ }
+ } else {
+ # Unknown service - this shouldn't be able to happen.
+ close $sock;
+ return undef;
+ }
+
+ # If it gets here, the mech is supported
+ print $sock "*\n"; # Attempt to cancel authentication
+ print $sock $logout; # Try to log out, but we don't really care if this fails
+ close $sock;
+ return 'YES';
+}