This FAQ is a broad introduction to using the Perl module Image::Magick in CGI scripts.
Topics covered:
Be warned that this is not a CGI security FAQ. See below for such resources.
I will assume you have Perl installed and running, and can use Image::Magick in command line scripts, and you have a web server installed and running, and can run Perl CGI scripts.
Specifically, this means you have dealt with these issues, among others:
Permissions vary from operating system to operating system.
If you stuck at this point, you're reading the wrong FAQ.
These instructions have only been tested under MS Windows NT aka WinNT. The web server I use is Apache V 1.3.23.
However, the problem of precisely what environment variables are available to CGI scripts, and which environment variables are required by CGI scripts using Image::Magick, concerns users of all web servers and all operating systems.
First let me repeat the warning about security. Changing the set of environment variables passed to CGI scripts has security implications. Below I give instructions on how to configure Apache to accept requests from the machine its running on (IP address 127.0.0.1), and to reject requests from all other machines (ie all other IP addresses). Despite this, you are still responsible for the security of machines you are in charge of. Don't blame me if the black hats end up calling your machine Hack-o-Rama Holiday.
While testing this stuff I used the simple CGI script env.cgi to see what was happening.
What complicates the issue is that, under WinNT, a web server like Apache can be run from 2 different default accounts.
The account the web server uses determines which set of environment variables are passed from the operating system to the web server, and from there to CGI scripts. In what follows, these accounts are called System Account and Administrator.
I log on to the machine as Administrator, but a service, ie a web server, can log on as (run as) either the System Account or the Administrator.
Environment variables are basically supplied to a CGI script from 2 sources:
For instance, when you install Apache V 1.3.23 for WinNT, as a service, you can navigate thus:
and you will see under Log On As, it says (by default) System Account.
But what does this mean?
It means that the service, here the web server, is provided by the operating system with a set of environment variables, some of which are passed to CGI scripts, and that this set belongs to the System Account.
I say 'some of' since web servers can, for security reasons, suppress some environment variables from the set passed from the web server to CGI scripts.
How do we find out which environment variables are available to the web server? Navigate thus:
Remember this 'top window' and 'bottom window' stuff. I will be referring to it at various times.
The environment variables in the top window are those passed from the operating system to the web server, when the web server runs under the System Account.
At this point, I have found a bug in the interaction between Apache and WinNT. When you change or add a variable in the top window, and then stop and restart the Apache service, WinNT does not pass the change to Apache.
I am not able to find any reference to this problem in the Apache bug database.
Even if you uninstall and reinstall the Apache service, from the command line, with:
and then restart the service via the control panel, the change is not visible to Apache. You have to reboot to effect the change. Yes, even under WinNT a reboot is necessary.
Note again that these 3 shell commands, being issued in a DOS box, are issued by the user you are logged on as. For me, this is Administrator, which is not the same as the System Account under which Apache is running.
In the next section, I discuss how to get Apache to log on as Administrator.
Let's start again, and this time we'll take an Administrator's point of view. Navigate thus:
Now, how do we get the web server to use the set of environment variables given in the bottom window?
There are 2 ways:
In each case the web server has access to the environment variables in the top window too.
To use the control panel method, navigate in exactly the same manner as discussed first:
So far, as before. What follows is new.
Note that in the text box beside the prompt This Account, it does not say Administrator, it says LocalSystem.
Why? Feel free the quiz Microsoft on that one.
Now when you stop and start the web server service, it will log on as Administrator, and hence will have access to the environment variables listed in the bottom window discussed above.
Alternately, do things from the command line, almost exactly as we went through some time above:
Now you have started Apache from a DOS box, and since the user who has the DOS box open is Administrator, the web server will have available the set of environment variables belonging to the Administrator, which are those in the bottom window.
It should be obvious now how people become confused. They firstly start the web server in the default manner, as a service which logs on as System Account, with one set of environment variables. Then they stop the service, and restart it from the command line, whereupon it logs on as Administrator with a different set of environment variables.
But wait, there's more!
I've mentioned that the web server will suppress some environment variables from the set it has available to pass to CGI scripts.
You can tell Apache, with the PassEnv command, via its configuration file httpd.conf, to pass the named environment variables to CGI scripts instead of suppressing them.
Such a command appears on a line by itself. Try not to put it inside a container like <directory> ... </directory>. I don't know what happens in such a case. Just use:
PassEnv MAGICK_HOME
and the environment variable MAGICK_HOME, and its value, will become available to CGI scripts.
Don't forget to restart the web server after each edit of its configuration file.
A moment's reflection will tell you that Apache can only pass on environment variables which exist! Hence, in the top window and bottom window mentioned above, if you've configured the service to run from the System Account, so it gets its environment variables from the top window, and MAGICK_HOME is defined in the bottom window, then CGI scripts will still not see MAGICK_HOME. This is because MAGICK_HOME does not exist from the point of view of the System Account, which only sees top window environment variables. Clear? I'm so glad...
There are other Apache environment manipulation commands, but this one is, I feel, the only one relevant at this point.
Obviously, web servers need to be installed and configured before CGI scripts can be run.
Now, this document is not about how to do that, but rather it is about how to adjust the configuration so as to help protect your machine against hacking, and about how to make life easy if you wish to run CGI scripts which use the Perl module Image::Magick.
At around line 345 of httpd.conf, you'll find these lines:
# Controls who can get stuff from this server. # Order allow,deny Allow from all </Directory>
I suggest you change these to:
# Controls who can get stuff from this server. # #! Order allow,deny #! Allow from all Order deny,allow Deny from all Allow from 127.0.0.1 </Directory> <Location */cgi-bin/*> Options Indexes FollowSymLinks MultiViews Order deny,allow Deny from all Allow from 127.0.0.1 </Location> PassEnv MAGICK_HOME
Now when you restart Apache, it will only accept requests from 127.0.0.1.
Further, if you have defined MAGICK_HOME in the appropriate window, top or bottom, it will be passed to CGI scripts.
The point of making MAGICK_HOME available is that you can use Image::Magick in your Perl CGI scripts without the script having to do a chdir to the directory containing the ImageMagick DLLs, and without having to copy those DLLs out of a convenient place, such as D:\ImageMagick or D:\ImageMagick\VisualMagick\bin, to a tacky place, such as D:\Perl\Site\Lib\Auto\Image\Magick.
In other words, you can upgrade Perl and simply re-install Image::Magick with 'nmake install', just like any other Perl module, without having to manually shift ImageMagick files. That's what I do.
If you wish to use the same she-bang line (line 1; starts with #!) for both Unix and WinNT Perl scripts, and you have installed Apache somewhere on c:, and Perl in c:\perl, then under WinNT you can create the directory c:\usr\bin, and copy just perl.exe into that directory.
If you have installed Apache and Perl on d:, then create d:\usr\bin, and copy d:\perl\bin\perl.exe there.
After that you can just use #!/usr/bin/perl. Neat, huh?
In January 2002 I tested this under Apache V 2, and it does not work, although using #!d:/usr/bin/perl works in some circumstances.
See im-faq-1.cgi. Downloading instructions are below. It can be run as-is, and also contains embedded comments at a few points, highlighting some confusing aspects of mixing CGI and Image::Magick.
Consider: system('/bin/mv', '/apache/htdocs/smile.gif', '/home/some-user/smile.gif');
If you run a system command to copy or move files between directories, other factors arise:
Your script is trying to run a program called '/bin/mv', say.
The first question is: Does the web server user have permission to run '/bin/mv'?
Commonly, web servers run as a special user called 'nobody', who may have very few permissions indeed.
Contains im-faq.pod and .html, im-faq-1.cgi and env.cgi.
Contains im-faq.pod and .html, im-faq-1.cgi and env.cgi.
Ron Savage .
Home page: http://savage.net.au/index.html
This version disguises my email address.
Original version.
Australian Copyright © 2002 Ron Savage. All rights reserved.
All Programs of mine are 'OSI Certified Open Source Software'; you can redistribute them and/or modify them under the terms of The Artistic License, a copy of which is available at: http://www.opensource.org/licenses/index.html