by the IMAP server. (Such as THREAD=SORT, THREAD=REFERENCES).
- Inclusion of Compatibility plugin automatic (no patch needed for plugin)
- Moved sqm_baseuri() into more centralized location (strings.php)
+ - Introduced $sendmail_args configuration variable in order to control
+ /usr/sbin/sendmail command arguments (#1365779). Deliver_SendMail class was
+ modified to provide support of $sendmail_args. Modifications broke backwards
+ compatibility with qmail-inject workarounds.
+ - Added execution error handling in Deliver_SendMail class (#1374174).
+ - Sanitized message composition error messages.
Version 1.5.0 - 2 February 2004
-------------------------------
* @package squirrelmail
*/
+/** @ignore */
+if (!defined('SM_PATH')) define('SM_PATH','../../');
/** This of course depends upon Deliver */
require_once(SM_PATH . 'class/deliver/Deliver.class.php');
* @package squirrelmail
*/
class Deliver_SendMail extends Deliver {
+ /**
+ * Extra sendmail arguments
+ *
+ * Parameter can be set in class constructor function.
+ *
+ * WARNING: Introduction of this parameter broke backwards compatibility
+ * with workarounds specific to qmail-inject.
+ *
+ * If parameter needs some security modifications, it should be set to
+ * private in PHP 5+ in order to prevent uncontrolled access.
+ * @var string
+ * @since 1.5.1
+ */
+ var $sendmail_args = '-i -t';
+
+ /**
+ * Stores used sendmail command
+ * Private variable that is used to inform about used sendmail command.
+ * @var string
+ * @since 1.5.1
+ */
+ var $sendmail_command = '';
+
+ /**
+ * Constructor function
+ * @param array configuration options. array key = option name,
+ * array value = option value.
+ * @return void
+ * @since 1.5.1
+ */
+ function Deliver_SendMail($params=array()) {
+ if (!empty($params) && is_array($params)) {
+ // set extra sendmail arguments
+ if (isset($params['sendmail_args'])) {
+ $this->sendmail_args = $params['sendmail_args'];
+ }
+ }
+ }
/**
* function preWriteToStream
*
* @param Message $message Message object containing the from address
* @param string $sendmail_path Location of sendmail binary
- * @return void
+ * @return resource
* @access public
*/
function initStream($message, $sendmail_path) {
$from = $rfc822_header->from[0];
$envelopefrom = trim($from->mailbox.'@'.$from->host);
$envelopefrom = str_replace(array("\0","\n"),array('',''),$envelopefrom);
- if (strstr($sendmail_path, "qmail-inject")) {
- $stream = popen (escapeshellcmd("$sendmail_path -f$envelopefrom"), "w");
- } else {
- $stream = popen (escapeshellcmd("$sendmail_path -i -t -f$envelopefrom"), "w");
- }
+ // save executed command for future reference
+ $this->sendmail_command = "$sendmail_path $this->sendmail_args -f$envelopefrom";
+ // open process handle for writing
+ $stream = popen (escapeshellcmd($this->sendmail_command), "w");
return $stream;
}
/**
- * function finalizeStream
- *
- * Close the stream.
+ * Closes process handle.
*
* @param resource $stream
* @return boolean
* @access public
*/
function finalizeStream($stream) {
- pclose($stream);
- return true;
+ $ret = true;
+ $status = pclose($stream);
+ // check pclose() status.
+ if ($status!=0) {
+ $ret = false;
+ $this->dlv_msg=_("Email delivery error");
+ $this->dlv_ret_nr=$status;
+ // we can get better error messsage only if we switch to php 4.3+ and proc_open().
+ $this->dlv_server_msg=sprintf(_("Can't execute command '%s'."),$this->sendmail_command);
+ }
+ return $ret;
}
/**
$prefs_user_size = 128 if ( !$prefs_user_size );
$prefs_key_size = 64 if ( !$prefs_key_size );
$prefs_val_size = 65536 if ( !$prefs_val_size );
+# add qmail-inject test here for backwards compatibility
+if ( !$sendmail_args && $sendmail_path =~ /qmail-inject/ ) {
+ $sendmail_args = '';
+} elsif ( !$sendmail_args ) {
+ $sendmail_args = '-i -t';
+}
if ( $ARGV[0] eq '--install-plugin' ) {
print "Activating plugin " . $ARGV[1] . "\n";
if ( lc($useSendmail) eq 'true' ) {
print $WHT . "Sendmail" . $NRM . "\n--------\n";
print "4. Sendmail Path : $WHT$sendmail_path$NRM\n";
- print "5. Header encryption key : $WHT$encode_header_key$NRM\n";
+ print "5. Sendmail arguments : $WHT$sendmail_args$NRM\n";
+ print "6. Header encryption key : $WHT$encode_header_key$NRM\n";
print "\n";
} else {
print $WHT . "SMTP Settings" . $NRM . "\n-------------\n";
elsif ( $command == 9 ) { $optional_delimiter = command111(); }
} elsif ( $show_smtp_settings && lc($useSendmail) eq 'true' ) {
if ( $command == 4 ) { $sendmail_path = command15(); }
- elsif ( $command == 5 ) { $encode_header_key = command114(); }
+ elsif ( $command == 5 ) { $sendmail_args = command_sendmail_args(); }
+ elsif ( $command == 6 ) { $encode_header_key = command114(); }
} elsif ( $show_smtp_settings ) {
if ( $command == 4 ) { $smtpServerAddress = command16(); }
elsif ( $command == 5 ) { $smtpPort = command17(); }
# sendmail_path
sub command15 {
+ # TODO: fix check
if ( $sendmail_path[0] !~ /./ ) {
$sendmail_path = "/usr/sbin/sendmail";
}
return $new_sendmail_path;
}
+# Extra sendmail arguments
+sub command_sendmail_args {
+ print "Specify additional sendmail program arguments.\n";
+ print "\n";
+ print "Make sure that arguments are supported by your sendmail program. -f argument \n";
+ print "is added automatically by SquirrelMail scripts. Variable defaults to standard\n";
+ print "/usr/sbin/sendmail arguments. If you use qmail-inject, nbsmtp or any other \n";
+ print "sendmail wrapper, which does not support -i and -t arguments, set variable to\n";
+ print "empty string or use arguments suitable for your mailer.\n";
+ print "\n";
+ print "[$WHT$sendmail_args$NRM]: $WHT";
+ $new_sendmail_args = <STDIN>;
+ if ( $new_sendmail_args eq "\n" ) {
+ $new_sendmail_args = $sendmail_args;
+ } else {
+ # strip linefeeds and crs.
+ $new_sendmail_args =~ s/[\r\n]//g;
+ }
+ return trim($new_sendmail_args);
+}
+
# smtpServerAddress
sub command16 {
print "This is the hostname of your SMTP server.\n";
print CF "\$smtpPort = $smtpPort;\n";
# string
print CF "\$sendmail_path = '$sendmail_path';\n";
+ # string
+ print CF "\$sendmail_args = '$sendmail_args';\n";
# boolean
# print CF "\$use_authenticated_smtp = $use_authenticated_smtp;\n";
# boolean
return 'YES';
}
+# trims whitespace
+# Example code from O'Reilly Perl Cookbook
+sub trim {
+ my @out = @_;
+ for (@out) {
+ s/^\s+//;
+ s/\s+$//;
+ }
+ return wantarray ? @out : $out[0];
+}
+
sub clear_screen() {
if ( $^O =~ /^mswin/i) {
system "cls";
*
* Program that should be used when sending email. SquirrelMail expects that
* this program will follow options used by original sendmail
- * (http://www.sendmail.org).
+ * (http://www.sendmail.org). Support of -f argument is required.
* @global string $sendmail_path
*/
$sendmail_path = '/usr/sbin/sendmail';
+/**
+ * Extra sendmail command arguments.
+ *
+ * Sets additional sendmail command arguments. Make sure that arguments are
+ * supported by your sendmail program. -f argument is added automatically by
+ * SquirrelMail scripts. Variable defaults to standard /usr/sbin/sendmail
+ * arguments. If you use qmail-inject, nbsmtp or any other sendmail wrapper,
+ * which does not support -t and -i arguments, set variable to empty string
+ * or use arguments suitable for your mailer.
+ * @global string $sendmail_args
+ * @since 1.5.1
+ */
+$sendmail_args = '-i -t';
+
/**
* IMAP server address
*
/** @ignore */
if (!defined('SM_PATH')) define('SM_PATH','../../');
-/** */
+/**
+ * Load SquirrelMail SMPREF constants for default_unseen_notify and
+ * default_unseen_type variables.
+ */
require_once( SM_PATH . 'functions/constants.php' );
/* Define constants for the various option types. */
'$sendmail_path' => array( 'name' => _("Sendmail Path"),
'type' => SMOPT_TYPE_STRING,
'size' => 40 ),
+ '$sendmail_args' => array( 'name' => _("Sendmail Arguments"),
+ 'type' => SMOPT_TYPE_STRING,
+ 'size' => 40 ),
'$smtpServerAddress' => array( 'name' => _("SMTP Server Address"),
'type' => SMOPT_TYPE_STRING,
'size' => 40 ),
$smtpServerAddress, $smtpPort, $user, $pass, $authPop);
} elseif (!$draft) {
require_once(SM_PATH . 'class/deliver/Deliver_SendMail.class.php');
- global $sendmail_path;
- $deliver = new Deliver_SendMail();
+ global $sendmail_path, $sendmail_args;
+ $deliver = new Deliver_SendMail(array('sendmail_args'=>$sendmail_args));
$stream = $deliver->initStream($composeMessage,$sendmail_path);
} elseif ($draft) {
global $draft_folder;
$composeMessage->purgeAttachments();
return $length;
} else {
- $msg = '<br />'.sprintf(_("Error: Draft folder %s does not exist."), $draft_folder);
+ $msg = '<br />'.sprintf(_("Error: Draft folder %s does not exist."), htmlspecialchars($draft_folder));
plain_error_message($msg, $color);
return false;
}
$success = $deliver->finalizeStream($stream);
}
if (!$success) {
- $msg = $deliver->dlv_msg . '<br />' .
- _("Server replied:") . ' ' . $deliver->dlv_ret_nr . ' ' .
- $deliver->dlv_server_msg;
+ // $deliver->dlv_server_msg is not always server's reply
+ $msg = htmlspecialchars($deliver->dlv_msg) . '<br />' .
+ _("Server replied:") . ' ' . htmlspecialchars($deliver->dlv_ret_nr) . ' ' .
+ htmlspecialchars($deliver->dlv_server_msg);
plain_error_message($msg, $color);
} else {
unset ($deliver);