Stunnel: Resolved

Revision as of 12:05, 23 January 2010 by BobS (talk | contribs) (Undo revision 4025 by EwanJosef (Talk) This is a spam link, not relevant.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Stunnel Issues Resolved
Uniform Server 3.5-Apollo

Moving over to the Wiki is not just a copy and paste exercise I am updating where possible and adding new material. My original Stunnel write-up finished with some unresolved issues see background below. I find solutions come with experience and thought it worthwhile adding my findings to this page.

Background

On UniCenter I published this: "I vowed not to publish this write-up until I had resolved three problems. Stunnel’s insistence on absolute paths for certificate files and its dislike to spaces in file names. The third problem, using a Perl script to start Stunnel, causes the web page to continuously load. Resolving the first two problems makes Stunnel path independent hence portable. I never fully resolved the continuous page-loading problem however my proposed solution works, as for the root cause still eludes me."

After upgrading to Stunnel 4.24 gave the scripts a bashing I was surprised to find my hack for the continuous page-loading problem failed, clearly I had not resolved the issue. Root cause, Perl! I remember reading that one version had a bug and would produce the result I was finding, yep upgraded to the latest version same problem. I backed tracked, on a clean version of Uniform Server installed the original plug in and run the scripts created by Anatoliy and Taras Slobodskyy they failed with the same problem. Thinking it still is a Perl issue I wrote a quick test script in PHP and that resulted in a continuous page-loading scenario. What really puzzled and threw me both Perl and PHP stop scripts worked perfectly.

Top

Problem - continuously loading page

Both Perl and PHP start scripts actually start Stunnel and work perfectly apart from the page being continuously loaded. However killing the Stunnel process using Task Manger I found the page completed loading. Root cause, both Perl and PHP “system” command waits for a process to complete before continuing.

Understanding the failure mechanism makes it easy to find a solution! I tried things like the following even resorted to trying the Unix & at the end:

  • exec("cmd");
  • exec("cmd >NUL");
  • exec("cmd /c cmd");
  • exec("start /b cmd");

No not an easy solution if it was life would not be so much fun!

Solution

Well this is certainly no fun however the last resort is to RTFM

Perl:

A good bedtime read man1 only joking however towards the end of the page I found this:

               As an optimization, may not call the command shell specified in
               $ENV{PERL5SHELL}.  "system(1, @args)" spawns an external pro-
               cess and immediately returns its process designator, without
               waiting for it to terminate.  Return value may be used subse-
               quently in "wait" or "waitpid".  Failure to spawn() a subpro-
               cess is indicated by setting $? to "255 << 8".  $? is set in a
               way compatible with Unix (i.e. the exitstatus of the subprocess
               is obtained by "$? >> 8", as described in the documentation).
               (Win32)

The line that's important is "system(1, @args)" spawns an external process and immediately returns" what's more its in the standard library. That failed as did numerous other things pipes, handles, back ticks, spawn process, create process and detach. In the end I just admitted defeat in part due to a lack of knowledge and its not that important. Would be interested in a pure Perl solution. I have always know there is an alternate see practical solutions below.

PHP:

Another story worth a read Manual

resource popen  ( string $command  , string $mode  )

Whats important it runs the command and returns. We are not interested in the returned pointer hence immediately close it with pclose. A quick piece of test code confirmed it’s a viable solution I was certainly surprised because it tends to be the other way around. It you can’t do it with PHP use Perl ho well.

Top

Practical Solutions

Although I never start Stunnel from a web page thought it would be reasonable to offer two solutions the first is based on original Perl scripts slightly modified the second solution uses PHP which is useful for comparison.

uniserv.exe

Uniform Server has a neat little piece of software (uniserv.exe) that runs a process (program) in the background what’s more important detaches that from the calling process and immediately returns. The original Perl scripts have been modified to start Stunnel using this program.

You will find this code in file sslstart.cgi located in folder *\Uniform Server\udrive\home\admin\www\plugins\stunnel_424

system("/home/admin/www/plugins/stunnel_424/bin/mpg_perl_start.bat");

It runs the batch file containing these lines:

pushd %~dp0
start ../../../../program/uniserv.exe "stunnel_424.exe stunnel.conf"
popd
ex

pclose() and popen()

This really is how Perl should work but for whatever reason it does not. Process open “popen()” opens a pipe to a process executed by forking the command given by command. Meaning it runs our program in parallel with the calling script, it returns an handle that could be used for reading (hence the second parameter) however we close this and the program that is run is detached and left to close on its own.

You will find this code in file stunnel.php located in folder *\Uniform Server\udrive\home\admin\www\plugins\stunnel_424

pclose(popen("/home/admin/www/plugins/stunnel_424/bin/mpg_php_start.bat", "r"));

It runs the batch file containing these lines:

pushd %~dp0
start stunnel_424.exe stunnel.conf
popd
exit

Note: Using the above methods you can run a process directly however the batch files are specific to Stunnel for the reasons explained below.

Top

Stunnel Path Independence

Path independence, in this respect Stunnel is its own best friend, states you must use complete paths for cert and key for example:

  • cert = w:\home\admin\www\plugins\stunnel_424\bin\stunnel.pem
  • key = w:\home\admin\www\plugins\stunnel_424\bin\stunnel.pem

Not exactly path independent however starting Stunnel from the folder where its executable is contained resolves this issue. It will look in that folder for both cert and key files. Hence the above two lines become:

  • cert = stunnel.pem
  • key = stunnel.pem

These are path independent. Whatever program is used to start Stunnel must ensure that the current working directory is set to Stunnels’s executable.

Batch file

This solution uses a batch file placed in Stunnels executable folder. Any program that starts Stunnel must do it via this batch file. The batch file looks similar to this (I have show only the important parts of the code):

pushd %~dp0
start stunnel_424.exe stunnel.conf
popd

The key player is pushd %~dp0 it first stores the current working directory and then forces the current working directory to be the folder where this batch file is contained. Hence Stunnel is started from this location, popd restores the original working directory.

Using this method also resolves the space within path name problem for both the key and cert paths.

Conclusion

The above solution are neat and require no kludges.


Top


  Ric