On Sun, 24 Oct 1999, Raul Miller wrote: > What is the advantage of introducing a complex syntax which is not > robust?
In my opinion, using Net::SMTP as I outlined is at least as robust as invoking Sendmail directly, and provides several improvements. 1. There is no need to have any mail system whatsoever on the web server. 2. If there is a mail system on the web server, it can be any flavor of SMTP daemon and need not be Sendmail. 3. The CGI program written in Perl is not tied to any specific web server, Linux distribution, or Unix vendor, and would even work on Windows NT. > Here's an excerpt from a cgi script of mine where I elected to use > sendmail: > > open MAIL, "|/usr/lib/sendmail -oi -oem -t" > or die_cgi 503, "Can't send mail\n"; > print MAIL <<___ or die_cgi 503, "Can't compose email\n"; > To: $first_name $last_name <$email_address> > From: ... > Subject: ... > Hi $first_name, In order for this to work, the web server machine must have Sendmail installed and configured. There are a lot of legitimate reasons, including complexity and security, why someone might regard this as undesirable. By default, I believe that Debian usually installs Smail rather than Sendmail, although I am not sure (both packages are "extra") since I always use Sendmail personally. There are also several mail servers, including smtpd, which cannot be invoked directly from the console but can be used over an SMTP connection with Net::SMTP. > Naturally, all the shell variables come from a cgi script, and naturally > any would have been rejected if they contained problematic characters. > Now what you're saying is that I should replace this rather trivial perl > fragment with something more complicated? > > > until($smtp = Net::SMTP->new("localhost")) { > > sleep(int(rand 60) + 1); > > } > > > > The actual delivery of mail to the final recipient is processed through > > the queue just as if Sendmail had been invoked from the console and the > > message piped to its STDIN as you suggest. > > That depends on local policy. It's also possible to have a system > where there's no smtp listener but where sendmail is running and > will deliver mail elsewhere. This is actually what I would regard as the worst case scenario for your approach. If someone has Sendmail available and directly invokes it from the console, there is no legitimate expectation that the message will ever come out of the queue. If Sendmail is not running as a daemon to do SMTP listening, then it is quite likely that it is not running as a queue processor. As a result, messages in the queue may stay there forever. > > If you do not have an SMTP daemon on "localhost," then you can use > > Net::SMTP to point to the smart remailer used on your network, which > > will presumably also handle queue processing. This configuration is > > impossible by direct invocation of Sendmail. > > Note that /usr/lib/sendmail could be provided by smail (the case for > the machine which is running the above perl fragment), or postfix, or > whatever... No, I am making a stronger assertion than that. There need be no mail system running on the web server machine whatsoever. In such a case, the only way to send mail from CGI is to connect over the network to a smart remailer, and the best way to do this is to use Net::SMTP. > > You also have much greater control over the message format when you use > > Net::SMTP than if you invoke Sendmail directly. For example, since the > > web server usually runs as a low-privilege user ("www-data" on Debian, > > "nobody" by default), setting the "from" information with the "-f" switch > > when invoking Sendmail directly will cause the annoying "Authentication > > Warning: www-data set sender to whatever" text to be included if you > > attempt to use a valid bounce address, as is good practice. > > Again, this behavior is determined by local administrative decisions (such > as which implementation of /usr/lib/sendmail to use). It's perfectly > reasonable to have an implementation of /usr/lib/sendmail which does not > inject messages into the headers, while having an smtp listener which > does inject messages into the headers (and that's the kind of system > which the above perl fragment came from). This is precisely my objection: the command line syntax and switches for Sendmail are not standardized. Most of the basics are covered, but I have no idea what would happen if your particular set of switches, "-oi -oem -t," were passed to something like Smail. SMTP is a network standard that is defined across all vendors and platforms; the command line syntax of a mailer and its return codes are not. If we assume that the particular thing invoked by running a program called "sendmail" from CGI is, in fact, the thing that is conventionally known as "Sendmail" and which is contained in the Debian package of that name, rather than a symbolic link to something else, then I think it is clear that the end result is going to be authentication warning messages in the headers of outgoing mail. There are only two "local administrative" ways to avoid this: (1) run the CGI program suid as a "trusted" user, which is insane, or (2) add the web server owner uid ("www-data" for Debain, "nobody" by default) as a trusted user, which is only a bit less insane. In your example syntax, because you are not using the "-f" switch, you will not generate an "authentication warning." However, the sender envelope address, to which bounces and delivery notification failures will be sent, would be left as the process owner for the web server, such as "www-data" or "nobody." Assuming that a mail alias has been properly configured for this, it is almost certainly going to be the mailbox of the person responsible for the web server as a whole. Especially on a web server which has a lot of different virtual sites and many page authors, this is probably extremely undesirable, and such a recipient may not even be able to track down which CGI maintainer is responsible. Using the Net::SMTP approach, there is complete freedom to set different addresses for the sender evelope, the "From" header, the "Reply-To" header, and so on, and there are no security implications (such as whether the sender is "trusted") to worry about. > > Finally, the use of Net::SMTP promotes independence of the Perl code > > from mail program choices and even operating system choices. Sending > > into the "localhost" SMTP port with Net::SMTP provides a consistent > > interface regardless of whether the system runs Sendmail, Smail, > > smtpd, or even Microsoft Exchange on Windows NT! > > And running an smtp listener on a web server -- especially one which > runs Sendmail -- is just one more thing to go wrong from a security > point of view. > > And, even if there is a smarthost, there's no reason to assume it's > running on the local network. A high-volume, robust web provider > may have a number of web servers, some of which are co-located in > other cities. Accepting your argument that running an SMTP listener on the web server is a bad idea from a security point of view, what then is the best solution? What you are proposing is that someone would have to install Sendmail, configure it, and then manually modify the Debian-provided shell script which starts Sendmail ("/etc/init.d/sendmail") so that it could be run as a queue processing daemon but not an SMTP listening daemon. This implicates, I think, a Debian policy issue: it might be reasonable (although, I contend, unnecessary) for the "cgi-scripts" package to suggest the "sendmail" package, but certainly not to require hand-editing the daemon start-up shell script to implement a configuration that is so rarely used with Sendmail that the standard switches are hardcoded. It is important to remember that Sendmail will never take the mail out of the queue if it is not running as some sort of daemon. If someone regards Sendmail as a security risk on the web server, and I agree that this might be an entirely reasonable view, then it is more likely that they would either install no mail system at all, in which case there would be nothing on the machine for you to invoke directly, or they would install one of the "higher security" modular systems such as smtpd, in which case your direct invocation method would not work. Worse, if someone chose to run one of these higher security or alternative mail systems, and the "cgi-scripts" package suggested "sendmail," then this would cascade through the package-dependency tables because the "sendmail" package quite properly states "Conflicts: mail-transport-agent, smail." As long as there is a smart host, then it makes no difference whether it is on the local network. The particular code example I gave, which would work with any smart host simply by replacing "localhost" with the domain name of the smart host, could certainly be made more robust by trying a list of different smart hosts, and so on. At some point, however, that level of robustness begins to interfere with the tutorial value of the examples included in the "cgi-scripts" package. > > > In most (not all) cases, for cgi work, you want to use a mail system > > > which queues mail. In most cases where you need to use a mail system > > > which does not queue mail you also don't want that mail being delivered > > > from inside a cgi program. > > > I agree here, but using Net::SMTP has several major advantages over > > directly invoking Sendmail, and can fully preserve queue processing > > when used appropriately. Your points are well-taken and I would > > not recommend Net::SMTP if it did require the sacrifice of queue > > processing. > > Ok :) I think we are in broad philosophical agreement about what is and is not functionally desirable for a CGI script to do. My issue is that we are discussing this in the context of an example program in the Debian "cgi-scripts" package, and we have to try to make this work on the broadest possible range of systems without incurring package dependency penalties unless they are absolutely necessary. In particuar, if it is not absolutely essential that an example CGI script invoke Sendmail, which means that the "cgi-scripts" package is then in some way depenent upon the "sendmail" package, this should be avoided. -- Mike