Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Adds support for the Suhosin patch.

The Suhosin patch will automatically be applied (if available) when the
"suhosin" flag is used in the version string (as in "5.3.9-suhosin").

The scripts were also slightly modified to output all error messages to
stderr instead of stdout.

The README has been updated and now contains an example on how to use
a post-install customization script to install some PEAR extension.
  • Loading branch information...
commit 58949ebebee4263b5589f16a15b3a1a64add52be 1 parent 98eefab
@fpoirotte authored
View
84 README.rst
@@ -1,13 +1,24 @@
phpfarm
=======
-Set of scripts to install a dozen of PHP versions in parallel on a system.
-It also creates a Pyrus installation for each PHP version.
-Primarily developed for PEAR's continuous integration machine.
+phpfarm is a set of scripts to install a dozen of PHP versions in parallel
+on a single system. It also installs the pear and pyrus installers and
+creates a local Pyrus installation for each PHP version as well.
+
+This tool was primarily developed for PEAR's continuous integration machine.
+
+The PHP source packages are fetched from http://museum.php.net/ (which is not
+always up-to-date), the official php.net download pages and the pre-release
+channels.
+
+The Pyrus PHAR archive is fetched from http://pear2.php.net/pyrus.phar (which
+always refers the latest version).
+
+Last but not least, phpfarm can automatically apply the Suhosin patch
+for the version of PHP you are installing. It does so by looking at
+http://www.hardened-php.net/suhosin/download.html for compatible versions
+of the patch.
-The PHP source packages are fetched from ``museum.php.net`` (which is not
-always up-to-date), the official php.net download pages and the
-pre-release channels.
If a file cannot be found, try to fetch it manually and put it into
``src/bzips/``.
@@ -61,6 +72,8 @@ variables are substitued:
path for those extensions.
+.. _`post-install script`:
+
Post-install customization
--------------------------
You may also create version-specific scripts that will be run after
@@ -74,30 +87,69 @@ the PHP binary has been successfully compiled, installed and configured:
These scripts can be used for example to discover PEAR channels
and pre-install some extensions/packages needed by your project.
+Each script is called with three arguments:
+
+- The PHP version that was just installed (eg. ``5.3.1-zts-suhosin-debug``).
+- The full path to the folder where that version was install
+ (eg. ``/home/clicky/phpfarm/inst/php-5.3.1-zts-suhosin-debug/``).
+- The full path to the shared folder containing the links to the main
+ executables for each version (eg. ``/home/clicky/phpfarm/inst/bin/``).
+
+.. note::
+ You do not need to specify a "shebang line" (``#!...``) at the beginning
+ of the scripts. Bash will always be used to execute them.
-Special tokens in version strings
----------------------------------
+Given all the previous bits of information, the following shell script may
+be used to discover a PEAR channel and install a PEAR extension::
-phpfarm recognizes a few special tokens in the version string.
-These tokens must be appended to the version string and separated
+ # "$3/pear-$1" could also be used in place of "$2/bin/pear" to refer
+ # to the pear installer for this specific version of PHP.
+ "$2/bin/pear" channel-discover pear.phpunit.de
+ "$2/bin/pear" install pear.phpunit.de/PHPUnit
+
+ # The exit status must be 0 when the scripts terminates without any error.
+ # Any other value will be treated as an error.
+ exit 0
+
+.. warning::
+ Your post-install customization script should always exit with a zero
+ status when they terminate normally. Any other value will be considered
+ a failure and will make phpfarm exit immediately with an error.
+
+
+Special flags in version strings
+--------------------------------
+
+phpfarm recognizes a few special flags in the version string.
+These flags must be appended to the version string and separated
from it and from one another by dashes (-).
-The following tokens are currently accepted:
+The following flags are currently accepted:
- ``debug`` to compile a version with debugging symbols.
- ``zts`` to enable thread safety.
-- ``32bits`` to force the creation of a 32 bits version of PHP on a
- 64 bits machine.
+- ``32bits`` to force the creation of a 32 bits version of PHP on a 64 bits
+ machine.
- ``gcov`` to enable GCOV code coverage information (requires LTP).
+- ``suhosin`` to apply the Suhosin patch before compiling PHP.
+ This patch provides several enhancements to build an hardened PHP binary.
+
+.. warning::
+ The ``suhosin`` flag only applies the Suhosin patch. It does not
+ automatically install the Suhosin extension. If you want to benefit
+ from the whole set of attack mitigation techniques provided by Suhosin,
+ you must also install the Suhosin extension separately (and manually),
+ using a `post-install script`_
For example, to build a thread-safe version of PHP 5.3.1 with debugging
symboles, use::
./main.sh 5.3.1-zts-debug
-**Note**: the order in which the tokens appear does not matter,
-phpfarm will reorganize them if needed. Hence, ``5.3.1-zts-debug``
-is effectively the same as ``5.3.1-debug-zts``.
+.. note::
+ The order in which the flags appear does not matter, phpfarm will
+ reorganize them if needed. Hence, ``5.3.1-zts-debug`` is effectively
+ the same as ``5.3.1-debug-zts``.
Bonus features
--------------
View
10 src/.gitignore
@@ -1,4 +1,14 @@
+# Compilation directories for the various PHP versions.
php-*/
+
+# Source archives for PHP.
bzips/*.bz2
+
+# Source archive for Pyrus.
bzips/*.phar
+
+# Source archives for Suhosin.
+bzips/*.patch.gz
+
+# Customizations.
custom/*
View
73 src/compile.sh
@@ -34,7 +34,7 @@ basedir=`pwd`
source helpers.sh
parse_version $1
if [ $? -ne 0 ]; then
- echo 'Please specify a valid php version'
+ echo 'Please specify a valid php version' >&2
exit 1
fi
@@ -92,8 +92,8 @@ if [ ! -d "$srcdir" ]; then
fi
if [ ! -f "$srcfile" ]; then
- echo "Fetching sources failed:"
- echo $url
+ echo "Fetching sources failed:" >&2
+ echo $url >&2
exit 2
fi
fi
@@ -101,6 +101,53 @@ if [ ! -d "$srcdir" ]; then
tar xjvf "$srcfile" --show-transformed-names --xform 's#^[^/]*#php-'"$VERSION"'#'
fi
+#do we need the Suhosin patch?
+if [ $SUHOSIN = 1 ]; then
+ echo "Grabbing the appropriate Suhosin patch for PHP $SHORT_VERSION"
+ verfile="$bzipsdir/suhosin-patch-$SHORT_VERSION.patch.gz"
+ if [ ! -e "$verfile" ]; then
+ # Suhosin adds its own version to the patch's name,
+ # hence we must find the correct name first.
+ re_version=`echo "$SHORT_VERSION" | sed 's/\./\\\\./g'`
+ url=`wget -O- http://www.hardened-php.net/suhosin/download.html 2> /dev/null | grep -o 'href="http://download.suhosin.org/suhosin-patch-'"$re_version"'-[0-9.]\+.patch.gz"' | cut -d'"' -f2 | head -n 1`
+ if [ -z "$url" ]; then
+ echo "ERROR: no version of the Suhosin patch applies to PHP $SHORT_VERSION" >&2
+ exit 2
+ fi
+
+ # Ok, so now we have an applicable patch.
+ srcfile="$bzipsdir/`basename "$url"`"
+ suhosin_ver=`basename "$url" .patch.gz | cut -d- -f4`
+ echo "Found Suhosin patch version $suhosin_ver ..."
+
+ # The patch was never downloaded before. Download it now.
+ if [ ! -e "$srcfile" ]; then
+ wget -P "$bzipsdir" -O "$srcfile" "$url"
+ if [ ! -s "$srcfile" -a -f "$srcfile" ]; then
+ rm "$srcfile"
+ fi
+ fi
+
+ if [ ! -f "$srcfile" ]; then
+ echo "Fetching sources failed:" >&2
+ echo $patch_url >&2
+ exit 2
+ fi
+
+ # Add a symlink whose name is based on PHP version only.
+ # eg. suhosin-patch-5.3.9.patch.gz -> suhosin-patch-5.3.9-0.9.10.patch.gz
+ ln -sT "`basename "$url"`" "$verfile"
+
+ # Apply the patch.
+ echo "Applying Suhosin patch (v$suhosin_ver) for PHP $SHORT_VERSION"
+ gunzip -c -d "$verfile" | patch -p1 -d "$basedir/$srcdir" >&2
+ if [ $? -ne 0 ]; then
+ echo "Failed to apply Suhosin patch"
+ exit 2
+ fi
+ fi
+fi
+
#read customizations
source 'options.sh' "$VERSION" "$VMAJOR" "$VMINOR" "$VPATCH"
cd "$srcdir"
@@ -138,7 +185,7 @@ if [ $configure -gt $tstamp ]; then
--with-pear="$instdir/pear"
if [ $? -gt 0 ]; then
- echo configure.sh failed.
+ echo configure.sh failed. >&2
exit 3
fi
else
@@ -160,13 +207,13 @@ if [ -n "$unknown_options" ]; then
# If the error comes from a previous run, ./configure won't kick in and
# it won't display the error message. We do the work in its place here.
if [ $configure -le $tstamp ]; then
- echo "ERROR: The following unrecognized configure options were used:"
- echo ""
- echo $unknown_options
- echo ""
- echo "Check 'configure --help' for available options."
+ echo "ERROR: The following unrecognized configure options were used:" >&2
+ echo "" >&2
+ echo $unknown_options >&2
+ echo "" >&2
+ echo "Check 'configure --help' for available options." >&2
fi
- echo "Please fix your configure options and try again."
+ echo "Please fix your configure options and try again." >&2
exit 3
fi
@@ -216,7 +263,7 @@ fi
#create bin
[ ! -d "$shbindir" ] && mkdir "$shbindir"
if [ ! -d "$shbindir" ]; then
- echo "Cannot create shared bin dir"
+ echo "Cannot create shared bin dir" >&2
exit 6
fi
#symlink all files
@@ -229,7 +276,7 @@ if [ -f "$bphp" ]; then
elif [ -f "$bphpgcno" ]; then
ln -fs "$bphpgcno" "$shbindir/php-$VERSION"
else
- echo "no php binary found"
+ echo "no php binary found" >&2
exit 7
fi
@@ -241,7 +288,7 @@ if [ -f "$bphpcgi" ]; then
elif [ -f "$bphpcgigcno" ]; then
ln -fs "$bphpcgigcno" "$shbindir/php-cgi-$VERSION"
else
- echo "no php-cgi binary found"
+ echo "no php-cgi binary found" >&2
exit 8
fi
View
20 src/helpers.sh
@@ -7,7 +7,7 @@ parse_version() {
# Inputs:
# $1: version string to parse.
# Eg. "5.4.0RC1-debug-unknown_token"
- # Valid tokens: zts, debug, 32bits, gcov.
+ # Valid tokens: zts, debug, 32bits, gcov, suhosin.
#
# Outputs:
# $VMAJOR: major number (5)
@@ -17,6 +17,7 @@ parse_version() {
# $ZTS: set to 1 if asked for ZTS support
# $ARCH32: set to 1 for a 32bits build on a 64bits machine
# $GCOV: set to 1 if asked for GCOV support
+ # $SUHOSIN: set to 1 if asked for Suhosin patch
# $SHORT_VERSION: same as $VMAJOR.$VMINOR.$VPATCH
# $VERSION: full version string, normalized.
# Eg. "5.4.0RC1-debug-zts-32bits-gcov"
@@ -39,20 +40,25 @@ parse_version() {
ZTS=0
ARCH32=0
GCOV=0
+ SUHOSIN=0
for p in $v; do
case $p in
- debug) DEBUG=1;;
- zts) ZTS=1;;
- 32bits) ARCH32=1;;
- gcov) GCOV=1;;
- *) echo "Unsupported token '$p'";
- return 2;;
+ debug) DEBUG=1;;
+ zts) ZTS=1;;
+ 32bits) ARCH32=1;;
+ gcov) GCOV=1;;
+ suhosin) SUHOSIN=1;;
+ *) echo "Unsupported token '$p'";
+ return 2;;
esac
done
# normalize version string
VERSION="$VMAJOR.$VMINOR.$VPATCH"
SHORT_VERSION="$VERSION"
+ if [ $SUHOSIN = 1 ]; then
+ VERSION="$VERSION-suhosin"
+ fi
if [ $DEBUG = 1 ]; then
VERSION="$VERSION-debug"
fi
View
4 src/main.sh
@@ -54,7 +54,7 @@ if [ $# -eq 0 ]; then
fi
if [ ${#versions[@]} -eq 0 ]; then
- echo 'Please specify php version or create "custom/default-versions.txt" file'
+ echo 'Please specify php version or create "custom/default-versions.txt" file' >&2
exit 1
fi
@@ -62,7 +62,7 @@ for version in "${versions[@]}"; do
./compile.sh "$version"
res=$?
if [ $res -ne 0 ]; then
- echo "An error occurred while trying to install PHP $version."
+ echo "An error occurred while trying to install PHP $version." >&2
exit $res
fi
done
View
4 src/pyrus.sh
@@ -16,7 +16,7 @@ instdir="$2"
if [ ! -d "$instdir" ]; then
echo "PHP installation directory does not exist: $instdir"
- exit 2
+ exit 1
fi
test $vmajor -gt 5 -o \( $vmajor -eq 5 -a $vminor -ge 3 \)
@@ -39,7 +39,7 @@ if [ ! -e "$pyrusphar" ]; then
fi
if [ ! -e "$pyrusphar" ]; then
echo "Please put pyrus.phar into bzips/"
- exit 3
+ exit 2
fi
ln -sfT "../../src/bzips/pyrus.phar" "$pyrustarget"
Please sign in to comment.
Something went wrong with that request. Please try again.