summaryrefslogtreecommitdiff
path: root/0.4.2/hardening-patch-4.3.11-0.4.2.patch
diff options
context:
space:
mode:
authorjvoisin2019-10-13 12:35:52 +0200
committerjvoisin2019-10-13 12:35:52 +0200
commit7ce0f98b0be3ad15a664e506dff461cf6d633a69 (patch)
tree1aae4c7d8fa8ac62609824629db9ba46add728cc /0.4.2/hardening-patch-4.3.11-0.4.2.patch
parentd24fe97bf9a1614acf4e7431d17b762a73642e15 (diff)
Add more patches
Diffstat (limited to '0.4.2/hardening-patch-4.3.11-0.4.2.patch')
-rw-r--r--0.4.2/hardening-patch-4.3.11-0.4.2.patch14426
1 files changed, 14426 insertions, 0 deletions
diff --git a/0.4.2/hardening-patch-4.3.11-0.4.2.patch b/0.4.2/hardening-patch-4.3.11-0.4.2.patch
new file mode 100644
index 0000000..c22d3a3
--- /dev/null
+++ b/0.4.2/hardening-patch-4.3.11-0.4.2.patch
@@ -0,0 +1,14426 @@
1diff -Nura php-4.3.11/acinclude.m4 hardening-patch-4.3.11-0.4.2/acinclude.m4
2--- php-4.3.11/acinclude.m4 2005-01-25 14:03:06.000000000 +0100
3+++ hardening-patch-4.3.11-0.4.2/acinclude.m4 2005-09-07 18:41:00.920109032 +0200
4@@ -1173,6 +1173,36 @@
5 fi
6 ])
7
8+dnl
9+dnl Check for broken realpath()
10+dnl
11+dnl realpath("/etc/hosts/../passwd",XXX) should not return
12+dnl "/etc/passwd"
13+dnl
14+AC_DEFUN([PHP_AC_BROKEN_REALPATH],[
15+ AC_CACHE_CHECK(whether realpath is broken, ac_cv_broken_realpath,[
16+ AC_TRY_RUN([
17+main() {
18+ char buf[4096+1];
19+ buf[0] = 0;
20+ realpath("/etc/hosts/../passwd", buf);
21+ exit(strcmp(buf, "/etc/passwd")==0);
22+}
23+ ],[
24+ ac_cv_broken_realpath=no
25+ ],[
26+ ac_cv_broken_realpath=yes
27+ ],[
28+ ac_cv_broken_realpath=no
29+ ])
30+ ])
31+ if test "$ac_cv_broken_realpath" = "yes"; then
32+ AC_DEFINE(PHP_BROKEN_REALPATH, 1, [Whether realpath is broken])
33+ else
34+ AC_DEFINE(PHP_BROKEN_REALPATH, 0, [Whether realpath is broken])
35+ fi
36+])
37+
38 dnl PHP_SHARED_MODULE(module-name, object-var, build-dir, cxx)
39 dnl
40 dnl Basically sets up the link-stage for building module-name
41diff -Nura php-4.3.11/configure hardening-patch-4.3.11-0.4.2/configure
42--- php-4.3.11/configure 2005-03-30 16:35:34.000000000 +0200
43+++ hardening-patch-4.3.11-0.4.2/configure 2005-09-07 19:04:56.159919416 +0200
44@@ -394,6 +394,16 @@
45 ac_default_prefix=/usr/local
46 # Any additions from configure.in:
47 ac_help="$ac_help
48+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection."
49+ac_help="$ac_help
50+ --disable-hardening-patch-ll-protect Disable the Linked List protection."
51+ac_help="$ac_help
52+ --disable-hardening-patch-inc-protect Disable include/require protection."
53+ac_help="$ac_help
54+ --disable-hardening-patch-fmt-protect Disable format string protection."
55+ac_help="$ac_help
56+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection."
57+ac_help="$ac_help
58
59 SAPI modules:
60 "
61@@ -846,6 +856,8 @@
62 ac_help="$ac_help
63 --disable-tokenizer Disable tokenizer support"
64 ac_help="$ac_help
65+ --disable-varfilter Disable Hardening-Patch's variable filter"
66+ac_help="$ac_help
67 --enable-wddx Enable WDDX support."
68 ac_help="$ac_help
69 --disable-xml Disable XML support using bundled expat lib"
70@@ -2669,6 +2681,157 @@
71
72
73
74+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given.
75+if test "${enable_hardening_patch_mm_protect+set}" = set; then
76+ enableval="$enable_hardening_patch_mm_protect"
77+
78+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
79+
80+else
81+
82+ DO_HARDENING_PATCH_MM_PROTECT=yes
83+
84+fi
85+
86+
87+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given.
88+if test "${enable_hardening_patch_ll_protect+set}" = set; then
89+ enableval="$enable_hardening_patch_ll_protect"
90+
91+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
92+
93+else
94+
95+ DO_HARDENING_PATCH_LL_PROTECT=yes
96+
97+fi
98+
99+
100+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given.
101+if test "${enable_hardening_patch_inc_protect+set}" = set; then
102+ enableval="$enable_hardening_patch_inc_protect"
103+
104+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
105+
106+else
107+
108+ DO_HARDENING_PATCH_INC_PROTECT=yes
109+
110+fi
111+
112+
113+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given.
114+if test "${enable_hardening_patch_fmt_protect+set}" = set; then
115+ enableval="$enable_hardening_patch_fmt_protect"
116+
117+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
118+
119+else
120+
121+ DO_HARDENING_PATCH_FMT_PROTECT=yes
122+
123+fi
124+
125+
126+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given.
127+if test "${enable_hardening_patch_hash_protect+set}" = set; then
128+ enableval="$enable_hardening_patch_hash_protect"
129+
130+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
131+
132+else
133+
134+ DO_HARDENING_PATCH_HASH_PROTECT=yes
135+
136+fi
137+
138+
139+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6
140+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5
141+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6
142+
143+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6
144+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5
145+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6
146+
147+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6
148+echo "configure:2733: checking whether to protect include/require statements" >&5
149+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6
150+
151+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6
152+echo "configure:2737: checking whether to protect PHP Format String functions" >&5
153+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6
154+
155+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6
156+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5
157+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6
158+
159+
160+cat >> confdefs.h <<\EOF
161+#define HARDENING_PATCH 1
162+EOF
163+
164+
165+
166+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
167+ cat >> confdefs.h <<\EOF
168+#define HARDENING_PATCH_MM_PROTECT 1
169+EOF
170+
171+else
172+ cat >> confdefs.h <<\EOF
173+#define HARDENING_PATCH_MM_PROTECT 0
174+EOF
175+
176+fi
177+
178+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
179+ cat >> confdefs.h <<\EOF
180+#define HARDENING_PATCH_LL_PROTECT 1
181+EOF
182+
183+else
184+ cat >> confdefs.h <<\EOF
185+#define HARDENING_PATCH_LL_PROTECT 0
186+EOF
187+
188+fi
189+
190+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
191+ cat >> confdefs.h <<\EOF
192+#define HARDENING_PATCH_INC_PROTECT 1
193+EOF
194+
195+else
196+ cat >> confdefs.h <<\EOF
197+#define HARDENING_PATCH_INC_PROTECT 0
198+EOF
199+
200+fi
201+
202+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
203+ cat >> confdefs.h <<\EOF
204+#define HARDENING_PATCH_FMT_PROTECT 1
205+EOF
206+
207+else
208+ cat >> confdefs.h <<\EOF
209+#define HARDENING_PATCH_FMT_PROTECT 0
210+EOF
211+
212+fi
213+
214+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
215+ cat >> confdefs.h <<\EOF
216+#define HARDENING_PATCH_HASH_PROTECT 1
217+EOF
218+
219+else
220+ cat >> confdefs.h <<\EOF
221+#define HARDENING_PATCH_HASH_PROTECT 0
222+EOF
223+
224+fi
225
226
227
228@@ -15486,6 +15649,62 @@
229 fi
230
231
232+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6
233+echo "configure:14928: checking whether realpath is broken" >&5
234+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then
235+ echo $ac_n "(cached) $ac_c" 1>&6
236+else
237+
238+ if test "$cross_compiling" = yes; then
239+
240+ ac_cv_broken_realpath=no
241+
242+else
243+ cat > conftest.$ac_ext <<EOF
244+#line 14939 "configure"
245+#include "confdefs.h"
246+
247+main() {
248+ char buf[4096+1];
249+ buf[0] = 0;
250+ realpath("/etc/hosts/../passwd", buf);
251+ exit(strcmp(buf, "/etc/passwd")==0);
252+}
253+
254+EOF
255+if { (eval echo configure:14958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
256+then
257+
258+ ac_cv_broken_realpath=no
259+
260+else
261+ echo "configure: failed program was:" >&5
262+ cat conftest.$ac_ext >&5
263+ rm -fr conftest*
264+
265+ ac_cv_broken_realpath=yes
266+
267+fi
268+rm -fr conftest*
269+fi
270+
271+
272+fi
273+
274+echo "$ac_t""$ac_cv_broken_realpath" 1>&6
275+ if test "$ac_cv_broken_realpath" = "yes"; then
276+ cat >> confdefs.h <<\EOF
277+#define PHP_BROKEN_REALPATH 1
278+EOF
279+
280+ else
281+ cat >> confdefs.h <<\EOF
282+#define PHP_BROKEN_REALPATH 0
283+EOF
284+
285+ fi
286+
287+
288 echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
289 echo "configure:15491: checking for declared timezone" >&5
290 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
291@@ -81938,7 +82157,7 @@
292 if test "$ac_cv_crypt_blowfish" = "yes"; then
293 ac_result=1
294 else
295- ac_result=0
296+ ac_result=1
297 fi
298 cat >> confdefs.h <<EOF
299 #define PHP_BLOWFISH_CRYPT $ac_result
300@@ -82603,7 +82822,7 @@
301 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
302 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
303 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
304- var_unserializer.c ftok.c aggregation.c sha1.c ; do
305+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
306
307 IFS=.
308 set $ac_src
309@@ -82658,7 +82877,7 @@
310 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
311 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
312 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
313- var_unserializer.c ftok.c aggregation.c sha1.c ; do
314+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
315
316 IFS=.
317 set $ac_src
318@@ -82743,7 +82962,7 @@
319 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
320 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
321 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
322- var_unserializer.c ftok.c aggregation.c sha1.c ; do
323+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
324
325 IFS=.
326 set $ac_src
327@@ -82795,7 +83014,7 @@
328 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
329 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
330 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
331- var_unserializer.c ftok.c aggregation.c sha1.c ; do
332+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
333
334 IFS=.
335 set $ac_src
336@@ -85975,6 +86194,265 @@
337 fi
338
339
340+echo $ac_n "checking whether to enable Hardening-Patch's variable filter""... $ac_c" 1>&6
341+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5
342+# Check whether --enable-varfilter or --disable-varfilter was given.
343+if test "${enable_varfilter+set}" = set; then
344+ enableval="$enable_varfilter"
345+ PHP_VARFILTER=$enableval
346+else
347+
348+ PHP_VARFILTER=yes
349+
350+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
351+ PHP_VARFILTER=$PHP_ENABLE_ALL
352+ fi
353+
354+fi
355+
356+
357+
358+ext_output="yes, shared"
359+ext_shared=yes
360+case $PHP_VARFILTER in
361+shared,*)
362+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
363+ ;;
364+shared)
365+ PHP_VARFILTER=yes
366+ ;;
367+no)
368+ ext_output=no
369+ ext_shared=no
370+ ;;
371+*)
372+ ext_output=yes
373+ ext_shared=no
374+ ;;
375+esac
376+
377+
378+
379+echo "$ac_t""$ext_output" 1>&6
380+
381+
382+
383+
384+if test "$PHP_VARFILTER" != "no"; then
385+ cat >> confdefs.h <<\EOF
386+#define HAVE_VARFILTER 1
387+EOF
388+
389+
390+ ext_builddir=ext/varfilter
391+ ext_srcdir=$abs_srcdir/ext/varfilter
392+
393+ ac_extra=
394+
395+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
396+
397+
398+
399+ case ext/varfilter in
400+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
401+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
402+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
403+ esac
404+
405+
406+
407+ b_c_pre=$php_c_pre
408+ b_cxx_pre=$php_cxx_pre
409+ b_c_meta=$php_c_meta
410+ b_cxx_meta=$php_cxx_meta
411+ b_c_post=$php_c_post
412+ b_cxx_post=$php_cxx_post
413+ b_lo=$php_lo
414+
415+
416+ old_IFS=$IFS
417+ for ac_src in varfilter.c; do
418+
419+ IFS=.
420+ set $ac_src
421+ ac_obj=$1
422+ IFS=$old_IFS
423+
424+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
425+
426+ case $ac_src in
427+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
428+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
429+ esac
430+
431+ cat >>Makefile.objects<<EOF
432+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
433+ $ac_comp
434+EOF
435+ done
436+
437+
438+ EXT_STATIC="$EXT_STATIC varfilter"
439+ if test "$ext_shared" != "nocli"; then
440+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
441+ fi
442+ else
443+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
444+
445+ case ext/varfilter in
446+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
447+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
448+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
449+ esac
450+
451+
452+
453+ b_c_pre=$shared_c_pre
454+ b_cxx_pre=$shared_cxx_pre
455+ b_c_meta=$shared_c_meta
456+ b_cxx_meta=$shared_cxx_meta
457+ b_c_post=$shared_c_post
458+ b_cxx_post=$shared_cxx_post
459+ b_lo=$shared_lo
460+
461+
462+ old_IFS=$IFS
463+ for ac_src in varfilter.c; do
464+
465+ IFS=.
466+ set $ac_src
467+ ac_obj=$1
468+ IFS=$old_IFS
469+
470+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
471+
472+ case $ac_src in
473+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
474+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
475+ esac
476+
477+ cat >>Makefile.objects<<EOF
478+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
479+ $ac_comp
480+EOF
481+ done
482+
483+
484+ install_modules="install-modules"
485+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
486+
487+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
488+
489+ cat >>Makefile.objects<<EOF
490+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
491+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
492+
493+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
494+ \$(LIBTOOL) --mode=link \$(CC) \$(COMMON_FLAGS) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(LDFLAGS) -o \$@ -export-dynamic -avoid-version -prefer-pic -module -rpath \$(phplibdir) \$(EXTRA_LDFLAGS) \$(shared_objects_varfilter) \$(VARFILTER_SHARED_LIBADD)
495+
496+EOF
497+
498+ cat >> confdefs.h <<EOF
499+#define COMPILE_DL_VARFILTER 1
500+EOF
501+
502+ fi
503+ fi
504+
505+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
506+ if test "$PHP_SAPI" = "cgi"; then
507+
508+
509+ case ext/varfilter in
510+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
511+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
512+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
513+ esac
514+
515+
516+
517+ b_c_pre=$php_c_pre
518+ b_cxx_pre=$php_cxx_pre
519+ b_c_meta=$php_c_meta
520+ b_cxx_meta=$php_cxx_meta
521+ b_c_post=$php_c_post
522+ b_cxx_post=$php_cxx_post
523+ b_lo=$php_lo
524+
525+
526+ old_IFS=$IFS
527+ for ac_src in varfilter.c; do
528+
529+ IFS=.
530+ set $ac_src
531+ ac_obj=$1
532+ IFS=$old_IFS
533+
534+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
535+
536+ case $ac_src in
537+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
538+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
539+ esac
540+
541+ cat >>Makefile.objects<<EOF
542+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
543+ $ac_comp
544+EOF
545+ done
546+
547+
548+ EXT_STATIC="$EXT_STATIC varfilter"
549+ else
550+
551+
552+ case ext/varfilter in
553+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
554+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
555+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
556+ esac
557+
558+
559+
560+ b_c_pre=$php_c_pre
561+ b_cxx_pre=$php_cxx_pre
562+ b_c_meta=$php_c_meta
563+ b_cxx_meta=$php_cxx_meta
564+ b_c_post=$php_c_post
565+ b_cxx_post=$php_cxx_post
566+ b_lo=$php_lo
567+
568+
569+ old_IFS=$IFS
570+ for ac_src in varfilter.c; do
571+
572+ IFS=.
573+ set $ac_src
574+ ac_obj=$1
575+ IFS=$old_IFS
576+
577+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
578+
579+ case $ac_src in
580+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
581+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
582+ esac
583+
584+ cat >>Makefile.objects<<EOF
585+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
586+ $ac_comp
587+EOF
588+ done
589+
590+
591+ fi
592+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
593+ fi
594+
595+ BUILD_DIR="$BUILD_DIR $ext_builddir"
596+
597+
598+fi
599
600
601 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
602@@ -98629,7 +99107,7 @@
603 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
604 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
605 streams.c network.c php_open_temporary_file.c php_logos.c \
606- output.c memory_streams.c user_streams.c; do
607+ output.c memory_streams.c user_streams.c hardening_patch.c; do
608
609 IFS=.
610 set $ac_src
611@@ -98802,7 +99280,7 @@
612 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
613 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
614 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
615- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do
616+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do
617
618 IFS=.
619 set $ac_src
620diff -Nura php-4.3.11/configure.in hardening-patch-4.3.11-0.4.2/configure.in
621--- php-4.3.11/configure.in 2005-03-30 16:18:36.000000000 +0200
622+++ hardening-patch-4.3.11-0.4.2/configure.in 2005-09-07 18:41:00.957103408 +0200
623@@ -227,7 +227,7 @@
624 sinclude(Zend/acinclude.m4)
625 sinclude(Zend/Zend.m4)
626 sinclude(TSRM/tsrm.m4)
627-
628+sinclude(main/hardening_patch.m4)
629
630
631 divert(2)
632@@ -595,6 +595,7 @@
633 AC_FUNC_ALLOCA
634 dnl PHP_AC_BROKEN_SPRINTF
635 dnl PHP_AC_BROKEN_SNPRINTF
636+PHP_AC_BROKEN_REALPATH
637 PHP_DECLARED_TIMEZONE
638 PHP_TIME_R_TYPE
639 PHP_READDIR_R_TYPE
640@@ -1224,7 +1225,7 @@
641 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
642 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
643 streams.c network.c php_open_temporary_file.c php_logos.c \
644- output.c memory_streams.c user_streams.c)
645+ output.c memory_streams.c user_streams.c hardening_patch.c)
646 PHP_ADD_SOURCES(/main, internal_functions.c,, sapi)
647 PHP_ADD_SOURCES(/main, internal_functions_cli.c,, cli)
648
649@@ -1237,7 +1238,7 @@
650 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
651 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
652 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
653- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c)
654+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c )
655
656 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
657 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c)
658diff -Nura php-4.3.11/ext/calendar/calendar.c hardening-patch-4.3.11-0.4.2/ext/calendar/calendar.c
659--- php-4.3.11/ext/calendar/calendar.c 2003-08-28 22:01:24.000000000 +0200
660+++ hardening-patch-4.3.11-0.4.2/ext/calendar/calendar.c 2005-09-07 18:41:00.958103256 +0200
661@@ -300,7 +300,7 @@
662 {
663 pval **julday;
664 int year, month, day;
665- char date[10];
666+ char date[16];
667
668 if (zend_get_parameters_ex(1, &julday) != SUCCESS) {
669 WRONG_PARAM_COUNT;
670@@ -341,7 +341,7 @@
671 {
672 pval **julday;
673 int year, month, day;
674- char date[10];
675+ char date[16];
676
677 if (zend_get_parameters_ex(1, &julday) != SUCCESS) {
678 WRONG_PARAM_COUNT;
679@@ -453,7 +453,7 @@
680 {
681 long julday, fl;
682 int year, month, day;
683- char date[10], hebdate[25];
684+ char date[16], hebdate[25];
685 char *dayp, *yearp;
686
687 if (ZEND_NUM_ARGS() == 1) {
688@@ -521,7 +521,7 @@
689 {
690 pval **julday;
691 int year, month, day;
692- char date[10];
693+ char date[16];
694
695 if (zend_get_parameters_ex(1, &julday) != SUCCESS) {
696 WRONG_PARAM_COUNT;
697diff -Nura php-4.3.11/ext/fbsql/php_fbsql.c hardening-patch-4.3.11-0.4.2/ext/fbsql/php_fbsql.c
698--- php-4.3.11/ext/fbsql/php_fbsql.c 2005-02-09 20:33:32.000000000 +0100
699+++ hardening-patch-4.3.11-0.4.2/ext/fbsql/php_fbsql.c 2005-09-07 18:41:00.960102952 +0200
700@@ -1797,8 +1797,24 @@
701 }
702 else if (fbcmdErrorsFound(md))
703 {
704+#if HARDENING_PATCH
705+ char* query_copy;
706+ int i;
707+#endif
708 FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
709 char* emg = fbcemdAllErrorMessages(emd);
710+#if HARDENING_PATCH
711+ query_copy=estrdup(query_copy);
712+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
713+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
714+ efree(query_copy);
715+ if (HG(hphp_sql_bailout_on_error)) {
716+ free(emg);
717+ fbcemdRelease(emd);
718+ result = 0;
719+ zend_bailout();
720+ }
721+#endif
722 if (FB_SQL_G(generateWarnings))
723 {
724 if (emg)
725diff -Nura php-4.3.11/ext/mbstring/mbstring.c hardening-patch-4.3.11-0.4.2/ext/mbstring/mbstring.c
726--- php-4.3.11/ext/mbstring/mbstring.c 2005-02-21 09:03:47.000000000 +0100
727+++ hardening-patch-4.3.11-0.4.2/ext/mbstring/mbstring.c 2005-09-07 18:41:00.962102648 +0200
728@@ -1487,6 +1487,7 @@
729 char *strtok_buf = NULL, **val_list;
730 zval *array_ptr = (zval *) arg;
731 int n, num, val_len, *len_list;
732+ unsigned int new_val_len;
733 enum mbfl_no_encoding from_encoding;
734 mbfl_string string, resvar, resval;
735 mbfl_encoding_detector *identd = NULL;
736@@ -1609,8 +1610,14 @@
737 val_len = len_list[n];
738 }
739 n++;
740- /* add variable to symbol table */
741- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
742+ /* we need val to be emalloc()ed */
743+ val = estrndup(val, val_len);
744+ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) {
745+ /* add variable to symbol table */
746+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
747+ }
748+ efree(val);
749+
750 if (convd != NULL){
751 mbfl_string_clear(&resvar);
752 mbfl_string_clear(&resval);
753diff -Nura php-4.3.11/ext/mysql/php_mysql.c hardening-patch-4.3.11-0.4.2/ext/mysql/php_mysql.c
754--- php-4.3.11/ext/mysql/php_mysql.c 2005-02-22 16:00:49.000000000 +0100
755+++ hardening-patch-4.3.11-0.4.2/ext/mysql/php_mysql.c 2005-09-07 18:41:00.963102496 +0200
756@@ -1215,6 +1215,8 @@
757 {
758 php_mysql_conn *mysql;
759 MYSQL_RES *mysql_result;
760+ char *copy_query;
761+ int i;
762
763 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
764
765@@ -1265,6 +1267,13 @@
766 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
767 }
768 }
769+ copy_query = estrdup(Z_STRVAL_PP(query));
770+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
771+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
772+ efree(copy_query);
773+ if (HG(hphp_sql_bailout_on_error)) {
774+ zend_bailout();
775+ }
776 RETURN_FALSE;
777 }
778 #else
779@@ -1272,12 +1281,20 @@
780 /* check possible error */
781 if (MySG(trace_mode)){
782 if (mysql_errno(&mysql->conn)){
783- php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, mysql_error(&mysql->conn));
784+ php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
785 }
786 }
787+ copy_query = estrdup(Z_STRVAL_PP(query));
788+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
789+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
790+ efree(copy_query);
791+ if (HG(hphp_sql_bailout_on_error)) {
792+ zend_bailout();
793+ }
794 RETURN_FALSE;
795 }
796 #endif
797+
798 if(use_store == MYSQL_USE_RESULT) {
799 mysql_result=mysql_use_result(&mysql->conn);
800 } else {
801diff -Nura php-4.3.11/ext/pgsql/pgsql.c hardening-patch-4.3.11-0.4.2/ext/pgsql/pgsql.c
802--- php-4.3.11/ext/pgsql/pgsql.c 2004-05-12 18:49:56.000000000 +0200
803+++ hardening-patch-4.3.11-0.4.2/ext/pgsql/pgsql.c 2005-09-07 18:41:00.965102192 +0200
804@@ -997,10 +997,28 @@
805 case PGRES_EMPTY_QUERY:
806 case PGRES_BAD_RESPONSE:
807 case PGRES_NONFATAL_ERROR:
808- case PGRES_FATAL_ERROR:
809- PHP_PQ_ERROR("Query failed: %s", pgsql);
810- PQclear(pgsql_result);
811- RETURN_FALSE;
812+ case PGRES_FATAL_ERROR:
813+ {
814+#if HARDENING_PATCH
815+ int i;
816+ char *query_copy;
817+#endif
818+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
819+ PQclear(pgsql_result);
820+#if HARDENING_PATCH
821+ query_copy = estrdup(Z_STRVAL_PP(query));
822+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
823+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy);
824+ efree(query_copy);
825+ if (HG(hphp_sql_bailout_on_error)) {
826+ efree(msgbuf);
827+ zend_bailout();
828+ }
829+#endif
830+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf);
831+ efree(msgbuf);
832+ RETURN_FALSE;
833+ }
834 break;
835 case PGRES_COMMAND_OK: /* successful command that did not return rows */
836 default:
837diff -Nura php-4.3.11/ext/standard/array.c hardening-patch-4.3.11-0.4.2/ext/standard/array.c
838--- php-4.3.11/ext/standard/array.c 2004-12-23 17:40:03.000000000 +0100
839+++ hardening-patch-4.3.11-0.4.2/ext/standard/array.c 2005-09-07 18:41:00.967101888 +0200
840@@ -1153,6 +1153,32 @@
841 }
842 }
843 }
844+
845+ if (var_name[0] == 'H') {
846+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
847+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
848+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
849+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
850+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
851+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
852+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
853+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
854+ return 0;
855+ }
856+ } else if (var_name[0] == '_') {
857+ if ((strcmp(var_name, "_COOKIE")==0)||
858+ (strcmp(var_name, "_ENV")==0)||
859+ (strcmp(var_name, "_FILES")==0)||
860+ (strcmp(var_name, "_GET")==0)||
861+ (strcmp(var_name, "_POST")==0)||
862+ (strcmp(var_name, "_REQUEST")==0)||
863+ (strcmp(var_name, "_SESSION")==0)||
864+ (strcmp(var_name, "_SERVER")==0)) {
865+ return 0;
866+ }
867+ } else if (strcmp(var_name, "GLOBALS")==0) {
868+ return 0;
869+ }
870
871 return 1;
872 }
873diff -Nura php-4.3.11/ext/standard/basic_functions.c hardening-patch-4.3.11-0.4.2/ext/standard/basic_functions.c
874--- php-4.3.11/ext/standard/basic_functions.c 2005-01-18 12:01:20.000000000 +0100
875+++ hardening-patch-4.3.11-0.4.2/ext/standard/basic_functions.c 2005-09-07 19:04:56.161919112 +0200
876@@ -118,12 +118,14 @@
877 typedef struct _php_shutdown_function_entry {
878 zval **arguments;
879 int arg_count;
880+ zend_bool created_by_eval;
881 } php_shutdown_function_entry;
882
883 typedef struct _user_tick_function_entry {
884 zval **arguments;
885 int arg_count;
886 int calling;
887+ zend_bool created_by_eval;
888 } user_tick_function_entry;
889
890 /* some prototypes for local functions */
891@@ -306,6 +308,8 @@
892 PHP_FE(get_html_translation_table, NULL)
893 PHP_FE(sha1, NULL)
894 PHP_FE(sha1_file, NULL)
895+ PHP_FE(sha256, NULL)
896+ PHP_FE(sha256_file, NULL)
897 PHP_NAMED_FE(md5,php_if_md5, NULL)
898 PHP_NAMED_FE(md5_file,php_if_md5_file, NULL)
899 PHP_NAMED_FE(crc32,php_if_crc32, NULL)
900@@ -687,7 +691,7 @@
901 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
902
903 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
904- PHP_FE(realpath, NULL)
905+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
906 #endif
907
908 #ifdef HAVE_FNMATCH
909@@ -2089,6 +2093,13 @@
910 static int user_shutdown_function_call(php_shutdown_function_entry *shutdown_function_entry TSRMLS_DC)
911 {
912 zval retval;
913+#if HARDENING_PATCH
914+ zend_uint orig_code_type = EG(in_code_type);
915+
916+ if (shutdown_function_entry->created_by_eval) {
917+ EG(in_code_type) = ZEND_EVAL_CODE;
918+ }
919+#endif
920
921 if (call_user_function( EG(function_table), NULL,
922 shutdown_function_entry->arguments[0],
923@@ -2101,6 +2112,9 @@
924 } else {
925 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s() - function does not exist", Z_STRVAL_P(shutdown_function_entry->arguments[0]));
926 }
927+#if HARDENING_PATCH
928+ EG(in_code_type) = orig_code_type;
929+#endif
930 return 0;
931 }
932
933@@ -2108,6 +2122,13 @@
934 {
935 zval retval;
936 zval *function = tick_fe->arguments[0];
937+#if HARDENING_PATCH
938+ zend_uint orig_code_type = EG(in_code_type);
939+
940+ if (tick_fe->created_by_eval) {
941+ EG(in_code_type) = ZEND_EVAL_CODE;
942+ }
943+#endif
944
945 /* Prevent reentrant calls to the same user ticks function */
946 if (! tick_fe->calling) {
947@@ -2139,6 +2160,9 @@
948
949 tick_fe->calling = 0;
950 }
951+#if HARDENING_PATCH
952+ EG(in_code_type) = orig_code_type;
953+#endif
954 }
955
956 static void run_user_tick_functions(int tick_count)
957@@ -2205,6 +2229,13 @@
958 if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
959 RETURN_FALSE;
960 }
961+#if HARDENING_PATCH
962+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
963+ shutdown_function_entry.created_by_eval = 1;
964+ } else {
965+ shutdown_function_entry.created_by_eval = 0;
966+ }
967+#endif
968
969 /* Prevent entering of anything but arrays/strings */
970 if (Z_TYPE_P(shutdown_function_entry.arguments[0]) != IS_ARRAY) {
971@@ -2737,6 +2768,13 @@
972 }
973
974 tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
975+#if HARDENING_PATCH
976+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
977+ tick_fe.created_by_eval = 1;
978+ } else {
979+ tick_fe.created_by_eval = 0;
980+ }
981+#endif
982
983 if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
984 RETURN_FALSE;
985@@ -3020,6 +3058,35 @@
986 memcpy(new_key, prefix, prefix_len);
987 memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength);
988
989+ if (new_key[0] == 'H') {
990+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
991+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
992+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
993+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
994+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
995+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
996+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
997+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
998+ efree(new_key);
999+ return 0;
1000+ }
1001+ } else if (new_key[0] == '_') {
1002+ if ((strcmp(new_key, "_COOKIE")==0)||
1003+ (strcmp(new_key, "_ENV")==0)||
1004+ (strcmp(new_key, "_FILES")==0)||
1005+ (strcmp(new_key, "_GET")==0)||
1006+ (strcmp(new_key, "_POST")==0)||
1007+ (strcmp(new_key, "_REQUEST")==0)||
1008+ (strcmp(new_key, "_SESSION")==0)||
1009+ (strcmp(new_key, "_SERVER")==0)) {
1010+ efree(new_key);
1011+ return 0;
1012+ }
1013+ } else if (strcmp(new_key, "GLOBALS")==0) {
1014+ efree(new_key);
1015+ return 0;
1016+ }
1017+
1018 zend_hash_del(&EG(symbol_table), new_key, new_key_len);
1019 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
1020
1021diff -Nura php-4.3.11/ext/standard/config.m4 hardening-patch-4.3.11-0.4.2/ext/standard/config.m4
1022--- php-4.3.11/ext/standard/config.m4 2004-12-30 08:02:18.000000000 +0100
1023+++ hardening-patch-4.3.11-0.4.2/ext/standard/config.m4 2005-09-07 19:04:56.161919112 +0200
1024@@ -203,7 +203,7 @@
1025 if test "$ac_cv_crypt_blowfish" = "yes"; then
1026 ac_result=1
1027 else
1028- ac_result=0
1029+ ac_result=1
1030 fi
1031 AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt])
1032 ])
1033@@ -419,6 +419,6 @@
1034 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
1035 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
1036 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
1037- var_unserializer.c ftok.c aggregation.c sha1.c )
1038+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c )
1039
1040 PHP_ADD_MAKEFILE_FRAGMENT
1041diff -Nura php-4.3.11/ext/standard/crypt_blowfish.c hardening-patch-4.3.11-0.4.2/ext/standard/crypt_blowfish.c
1042--- php-4.3.11/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100
1043+++ hardening-patch-4.3.11-0.4.2/ext/standard/crypt_blowfish.c 2005-09-07 19:04:56.163918808 +0200
1044@@ -0,0 +1,748 @@
1045+/*
1046+ * This code comes from John the Ripper password cracker, with reentrant
1047+ * and crypt(3) interfaces added, but optimizations specific to password
1048+ * cracking removed.
1049+ *
1050+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
1051+ * placed in the public domain.
1052+ *
1053+ * There's absolutely no warranty.
1054+ *
1055+ * It is my intent that you should be able to use this on your system,
1056+ * as a part of a software package, or anywhere else to improve security,
1057+ * ensure compatibility, or for any other purpose. I would appreciate
1058+ * it if you give credit where it is due and keep your modifications in
1059+ * the public domain as well, but I don't require that in order to let
1060+ * you place this code and any modifications you make under a license
1061+ * of your choice.
1062+ *
1063+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
1064+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
1065+ * ideas. The password hashing algorithm was designed by David Mazieres
1066+ * <dm at lcs.mit.edu>.
1067+ *
1068+ * There's a paper on the algorithm that explains its design decisions:
1069+ *
1070+ * http://www.usenix.org/events/usenix99/provos.html
1071+ *
1072+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
1073+ * Blowfish library (I can't be sure if I would think of something if I
1074+ * hadn't seen his code).
1075+ */
1076+
1077+#include <string.h>
1078+
1079+#include <errno.h>
1080+#ifndef __set_errno
1081+#define __set_errno(val) errno = (val)
1082+#endif
1083+
1084+#undef __CONST
1085+#ifdef __GNUC__
1086+#define __CONST __const
1087+#else
1088+#define __CONST
1089+#endif
1090+
1091+#ifdef __i386__
1092+#define BF_ASM 0
1093+#define BF_SCALE 1
1094+#elif defined(__alpha__) || defined(__hppa__)
1095+#define BF_ASM 0
1096+#define BF_SCALE 1
1097+#else
1098+#define BF_ASM 0
1099+#define BF_SCALE 0
1100+#endif
1101+
1102+typedef unsigned int BF_word;
1103+
1104+/* Number of Blowfish rounds, this is also hardcoded into a few places */
1105+#define BF_N 16
1106+
1107+typedef BF_word BF_key[BF_N + 2];
1108+
1109+typedef struct {
1110+ BF_word S[4][0x100];
1111+ BF_key P;
1112+} BF_ctx;
1113+
1114+/*
1115+ * Magic IV for 64 Blowfish encryptions that we do at the end.
1116+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
1117+ */
1118+static BF_word BF_magic_w[6] = {
1119+ 0x4F727068, 0x65616E42, 0x65686F6C,
1120+ 0x64657253, 0x63727944, 0x6F756274
1121+};
1122+
1123+/*
1124+ * P-box and S-box tables initialized with digits of Pi.
1125+ */
1126+static BF_ctx BF_init_state = {
1127+ {
1128+ {
1129+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
1130+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
1131+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
1132+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
1133+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
1134+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
1135+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
1136+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
1137+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
1138+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
1139+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
1140+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
1141+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
1142+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
1143+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
1144+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
1145+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
1146+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
1147+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
1148+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
1149+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
1150+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
1151+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
1152+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
1153+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
1154+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
1155+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
1156+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
1157+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
1158+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
1159+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
1160+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
1161+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
1162+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
1163+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
1164+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
1165+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
1166+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
1167+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
1168+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
1169+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
1170+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
1171+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
1172+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
1173+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
1174+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
1175+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
1176+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
1177+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
1178+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
1179+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
1180+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
1181+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
1182+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
1183+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
1184+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
1185+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
1186+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
1187+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
1188+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
1189+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
1190+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
1191+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
1192+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
1193+ }, {
1194+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
1195+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
1196+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
1197+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
1198+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
1199+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
1200+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
1201+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
1202+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
1203+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
1204+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
1205+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
1206+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
1207+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
1208+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
1209+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
1210+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
1211+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
1212+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
1213+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
1214+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
1215+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
1216+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
1217+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
1218+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
1219+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
1220+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
1221+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
1222+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
1223+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
1224+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
1225+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
1226+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
1227+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
1228+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
1229+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
1230+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
1231+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
1232+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
1233+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
1234+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
1235+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
1236+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
1237+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
1238+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
1239+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
1240+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
1241+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
1242+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
1243+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
1244+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
1245+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
1246+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
1247+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
1248+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
1249+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
1250+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
1251+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
1252+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
1253+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
1254+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
1255+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
1256+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
1257+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
1258+ }, {
1259+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
1260+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
1261+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
1262+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
1263+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
1264+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
1265+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
1266+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
1267+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
1268+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
1269+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
1270+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
1271+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
1272+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
1273+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
1274+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
1275+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
1276+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
1277+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
1278+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
1279+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
1280+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
1281+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
1282+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
1283+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
1284+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
1285+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
1286+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
1287+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
1288+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
1289+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
1290+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
1291+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
1292+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
1293+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
1294+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
1295+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
1296+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
1297+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
1298+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
1299+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
1300+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
1301+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
1302+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
1303+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
1304+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
1305+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
1306+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
1307+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
1308+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
1309+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
1310+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
1311+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
1312+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
1313+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
1314+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
1315+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
1316+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
1317+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
1318+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
1319+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
1320+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
1321+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
1322+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
1323+ }, {
1324+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
1325+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
1326+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
1327+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
1328+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
1329+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
1330+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
1331+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
1332+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
1333+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
1334+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
1335+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
1336+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
1337+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
1338+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
1339+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
1340+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
1341+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
1342+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
1343+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
1344+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
1345+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
1346+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
1347+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
1348+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
1349+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
1350+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
1351+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
1352+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
1353+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
1354+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
1355+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
1356+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
1357+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
1358+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
1359+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
1360+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
1361+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
1362+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
1363+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
1364+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
1365+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
1366+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
1367+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
1368+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
1369+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
1370+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
1371+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
1372+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
1373+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
1374+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
1375+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
1376+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
1377+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
1378+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
1379+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
1380+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
1381+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
1382+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
1383+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
1384+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
1385+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
1386+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
1387+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
1388+ }
1389+ }, {
1390+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
1391+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
1392+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
1393+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
1394+ 0x9216d5d9, 0x8979fb1b
1395+ }
1396+};
1397+
1398+static unsigned char BF_itoa64[64 + 1] =
1399+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1400+
1401+static unsigned char BF_atoi64[0x60] = {
1402+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
1403+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
1404+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1405+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
1406+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
1407+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
1408+};
1409+
1410+/*
1411+ * This may be optimized out if built with function inlining and no BF_ASM.
1412+ */
1413+static void clean(void *data, int size)
1414+{
1415+#if BF_ASM
1416+ extern void _BF_clean(void *data);
1417+#endif
1418+ memset(data, 0, size);
1419+#if BF_ASM
1420+ _BF_clean(data);
1421+#endif
1422+}
1423+
1424+#define BF_safe_atoi64(dst, src) \
1425+{ \
1426+ tmp = (unsigned char)(src); \
1427+ if (tmp == '$') break; \
1428+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
1429+ tmp = BF_atoi64[tmp]; \
1430+ if (tmp > 63) return -1; \
1431+ (dst) = tmp; \
1432+}
1433+
1434+static int BF_decode(BF_word *dst, __CONST char *src, int size)
1435+{
1436+ unsigned char *dptr = (unsigned char *)dst;
1437+ unsigned char *end = dptr + size;
1438+ unsigned char *sptr = (unsigned char *)src;
1439+ unsigned int tmp, c1, c2, c3, c4;
1440+
1441+ do {
1442+ BF_safe_atoi64(c1, *sptr++);
1443+ BF_safe_atoi64(c2, *sptr++);
1444+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
1445+ if (dptr >= end) break;
1446+
1447+ BF_safe_atoi64(c3, *sptr++);
1448+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
1449+ if (dptr >= end) break;
1450+
1451+ BF_safe_atoi64(c4, *sptr++);
1452+ *dptr++ = ((c3 & 0x03) << 6) | c4;
1453+ } while (dptr < end);
1454+
1455+ while (dptr < end)
1456+ *dptr++ = 0;
1457+
1458+ return 0;
1459+}
1460+
1461+static void BF_encode(char *dst, __CONST BF_word *src, int size)
1462+{
1463+ unsigned char *sptr = (unsigned char *)src;
1464+ unsigned char *end = sptr + size;
1465+ unsigned char *dptr = (unsigned char *)dst;
1466+ unsigned int c1, c2;
1467+
1468+ do {
1469+ c1 = *sptr++;
1470+ *dptr++ = BF_itoa64[c1 >> 2];
1471+ c1 = (c1 & 0x03) << 4;
1472+ if (sptr >= end) {
1473+ *dptr++ = BF_itoa64[c1];
1474+ break;
1475+ }
1476+
1477+ c2 = *sptr++;
1478+ c1 |= c2 >> 4;
1479+ *dptr++ = BF_itoa64[c1];
1480+ c1 = (c2 & 0x0f) << 2;
1481+ if (sptr >= end) {
1482+ *dptr++ = BF_itoa64[c1];
1483+ break;
1484+ }
1485+
1486+ c2 = *sptr++;
1487+ c1 |= c2 >> 6;
1488+ *dptr++ = BF_itoa64[c1];
1489+ *dptr++ = BF_itoa64[c2 & 0x3f];
1490+ } while (sptr < end);
1491+}
1492+
1493+static void BF_swap(BF_word *x, int count)
1494+{
1495+ static int endianness_check = 1;
1496+ char *is_little_endian = (char *)&endianness_check;
1497+ BF_word tmp;
1498+
1499+ if (*is_little_endian)
1500+ do {
1501+ tmp = *x;
1502+ tmp = (tmp << 16) | (tmp >> 16);
1503+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
1504+ } while (--count);
1505+}
1506+
1507+#if BF_SCALE
1508+/* Architectures which can shift addresses left by 2 bits with no extra cost */
1509+#define BF_ROUND(L, R, N) \
1510+ tmp1 = L & 0xFF; \
1511+ tmp2 = L >> 8; \
1512+ tmp2 &= 0xFF; \
1513+ tmp3 = L >> 16; \
1514+ tmp3 &= 0xFF; \
1515+ tmp4 = L >> 24; \
1516+ tmp1 = data.ctx.S[3][tmp1]; \
1517+ tmp2 = data.ctx.S[2][tmp2]; \
1518+ tmp3 = data.ctx.S[1][tmp3]; \
1519+ tmp3 += data.ctx.S[0][tmp4]; \
1520+ tmp3 ^= tmp2; \
1521+ R ^= data.ctx.P[N + 1]; \
1522+ tmp3 += tmp1; \
1523+ R ^= tmp3;
1524+#else
1525+/* Architectures with no complicated addressing modes supported */
1526+#define BF_INDEX(S, i) \
1527+ (*((BF_word *)(((unsigned char *)S) + (i))))
1528+#define BF_ROUND(L, R, N) \
1529+ tmp1 = L & 0xFF; \
1530+ tmp1 <<= 2; \
1531+ tmp2 = L >> 6; \
1532+ tmp2 &= 0x3FC; \
1533+ tmp3 = L >> 14; \
1534+ tmp3 &= 0x3FC; \
1535+ tmp4 = L >> 22; \
1536+ tmp4 &= 0x3FC; \
1537+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
1538+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
1539+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
1540+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
1541+ tmp3 ^= tmp2; \
1542+ R ^= data.ctx.P[N + 1]; \
1543+ tmp3 += tmp1; \
1544+ R ^= tmp3;
1545+#endif
1546+
1547+/*
1548+ * Encrypt one block, BF_N is hardcoded here.
1549+ */
1550+#define BF_ENCRYPT \
1551+ L ^= data.ctx.P[0]; \
1552+ BF_ROUND(L, R, 0); \
1553+ BF_ROUND(R, L, 1); \
1554+ BF_ROUND(L, R, 2); \
1555+ BF_ROUND(R, L, 3); \
1556+ BF_ROUND(L, R, 4); \
1557+ BF_ROUND(R, L, 5); \
1558+ BF_ROUND(L, R, 6); \
1559+ BF_ROUND(R, L, 7); \
1560+ BF_ROUND(L, R, 8); \
1561+ BF_ROUND(R, L, 9); \
1562+ BF_ROUND(L, R, 10); \
1563+ BF_ROUND(R, L, 11); \
1564+ BF_ROUND(L, R, 12); \
1565+ BF_ROUND(R, L, 13); \
1566+ BF_ROUND(L, R, 14); \
1567+ BF_ROUND(R, L, 15); \
1568+ tmp4 = R; \
1569+ R = L; \
1570+ L = tmp4 ^ data.ctx.P[BF_N + 1];
1571+
1572+#if BF_ASM
1573+#define BF_body() \
1574+ _BF_body_r(&data.ctx);
1575+#else
1576+#define BF_body() \
1577+ L = R = 0; \
1578+ ptr = data.ctx.P; \
1579+ do { \
1580+ ptr += 2; \
1581+ BF_ENCRYPT; \
1582+ *(ptr - 2) = L; \
1583+ *(ptr - 1) = R; \
1584+ } while (ptr < &data.ctx.P[BF_N + 2]); \
1585+\
1586+ ptr = data.ctx.S[0]; \
1587+ do { \
1588+ ptr += 2; \
1589+ BF_ENCRYPT; \
1590+ *(ptr - 2) = L; \
1591+ *(ptr - 1) = R; \
1592+ } while (ptr < &data.ctx.S[3][0xFF]);
1593+#endif
1594+
1595+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial)
1596+{
1597+ __CONST char *ptr = key;
1598+ int i, j;
1599+ BF_word tmp;
1600+
1601+ for (i = 0; i < BF_N + 2; i++) {
1602+ tmp = 0;
1603+ for (j = 0; j < 4; j++) {
1604+ tmp <<= 8;
1605+ tmp |= *ptr;
1606+
1607+ if (!*ptr) ptr = key; else ptr++;
1608+ }
1609+
1610+ expanded[i] = tmp;
1611+ initial[i] = BF_init_state.P[i] ^ tmp;
1612+ }
1613+}
1614+
1615+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
1616+ char *output, int size)
1617+{
1618+#if BF_ASM
1619+ extern void _BF_body_r(BF_ctx *ctx);
1620+#endif
1621+ struct {
1622+ BF_ctx ctx;
1623+ BF_key expanded_key;
1624+ union {
1625+ BF_word salt[4];
1626+ BF_word output[6];
1627+ } binary;
1628+ } data;
1629+ BF_word L, R;
1630+ BF_word tmp1, tmp2, tmp3, tmp4;
1631+ BF_word *ptr;
1632+ BF_word count;
1633+ int i;
1634+
1635+ if (size < 7 + 22 + 31 + 1) {
1636+ __set_errno(ERANGE);
1637+ return NULL;
1638+ }
1639+
1640+ if (setting[0] != '$' ||
1641+ setting[1] != '2' ||
1642+ setting[2] != 'a' ||
1643+ setting[3] != '$' ||
1644+ setting[4] < '0' || setting[4] > '3' ||
1645+ setting[5] < '0' || setting[5] > '9' ||
1646+ setting[6] != '$') {
1647+ __set_errno(EINVAL);
1648+ return NULL;
1649+ }
1650+
1651+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
1652+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) {
1653+ clean(data.binary.salt, sizeof(data.binary.salt));
1654+ __set_errno(EINVAL);
1655+ return NULL;
1656+ }
1657+
1658+ BF_swap(data.binary.salt, 4);
1659+
1660+ BF_set_key(key, data.expanded_key, data.ctx.P);
1661+
1662+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
1663+
1664+ L = R = 0;
1665+ for (i = 0; i < BF_N + 2; i += 2) {
1666+ L ^= data.binary.salt[i & 2];
1667+ R ^= data.binary.salt[(i & 2) + 1];
1668+ BF_ENCRYPT;
1669+ data.ctx.P[i] = L;
1670+ data.ctx.P[i + 1] = R;
1671+ }
1672+
1673+ ptr = data.ctx.S[0];
1674+ do {
1675+ ptr += 4;
1676+ L ^= data.binary.salt[(BF_N + 2) & 3];
1677+ R ^= data.binary.salt[(BF_N + 3) & 3];
1678+ BF_ENCRYPT;
1679+ *(ptr - 4) = L;
1680+ *(ptr - 3) = R;
1681+
1682+ L ^= data.binary.salt[(BF_N + 4) & 3];
1683+ R ^= data.binary.salt[(BF_N + 5) & 3];
1684+ BF_ENCRYPT;
1685+ *(ptr - 2) = L;
1686+ *(ptr - 1) = R;
1687+ } while (ptr < &data.ctx.S[3][0xFF]);
1688+
1689+ do {
1690+ data.ctx.P[0] ^= data.expanded_key[0];
1691+ data.ctx.P[1] ^= data.expanded_key[1];
1692+ data.ctx.P[2] ^= data.expanded_key[2];
1693+ data.ctx.P[3] ^= data.expanded_key[3];
1694+ data.ctx.P[4] ^= data.expanded_key[4];
1695+ data.ctx.P[5] ^= data.expanded_key[5];
1696+ data.ctx.P[6] ^= data.expanded_key[6];
1697+ data.ctx.P[7] ^= data.expanded_key[7];
1698+ data.ctx.P[8] ^= data.expanded_key[8];
1699+ data.ctx.P[9] ^= data.expanded_key[9];
1700+ data.ctx.P[10] ^= data.expanded_key[10];
1701+ data.ctx.P[11] ^= data.expanded_key[11];
1702+ data.ctx.P[12] ^= data.expanded_key[12];
1703+ data.ctx.P[13] ^= data.expanded_key[13];
1704+ data.ctx.P[14] ^= data.expanded_key[14];
1705+ data.ctx.P[15] ^= data.expanded_key[15];
1706+ data.ctx.P[16] ^= data.expanded_key[16];
1707+ data.ctx.P[17] ^= data.expanded_key[17];
1708+
1709+ BF_body();
1710+
1711+ tmp1 = data.binary.salt[0];
1712+ tmp2 = data.binary.salt[1];
1713+ tmp3 = data.binary.salt[2];
1714+ tmp4 = data.binary.salt[3];
1715+ data.ctx.P[0] ^= tmp1;
1716+ data.ctx.P[1] ^= tmp2;
1717+ data.ctx.P[2] ^= tmp3;
1718+ data.ctx.P[3] ^= tmp4;
1719+ data.ctx.P[4] ^= tmp1;
1720+ data.ctx.P[5] ^= tmp2;
1721+ data.ctx.P[6] ^= tmp3;
1722+ data.ctx.P[7] ^= tmp4;
1723+ data.ctx.P[8] ^= tmp1;
1724+ data.ctx.P[9] ^= tmp2;
1725+ data.ctx.P[10] ^= tmp3;
1726+ data.ctx.P[11] ^= tmp4;
1727+ data.ctx.P[12] ^= tmp1;
1728+ data.ctx.P[13] ^= tmp2;
1729+ data.ctx.P[14] ^= tmp3;
1730+ data.ctx.P[15] ^= tmp4;
1731+ data.ctx.P[16] ^= tmp1;
1732+ data.ctx.P[17] ^= tmp2;
1733+
1734+ BF_body();
1735+ } while (--count);
1736+
1737+ for (i = 0; i < 6; i += 2) {
1738+ L = BF_magic_w[i];
1739+ R = BF_magic_w[i + 1];
1740+
1741+ count = 64;
1742+ do {
1743+ BF_ENCRYPT;
1744+ } while (--count);
1745+
1746+ data.binary.output[i] = L;
1747+ data.binary.output[i + 1] = R;
1748+ }
1749+
1750+ memcpy(output, setting, 7 + 22 - 1);
1751+ output[7 + 22 - 1] = BF_itoa64[(int)
1752+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
1753+
1754+/* This has to be bug-compatible with the original implementation, so
1755+ * only encode 23 of the 24 bytes. :-) */
1756+ BF_swap(data.binary.output, 6);
1757+ BF_encode(&output[7 + 22], data.binary.output, 23);
1758+ output[7 + 22 + 31] = '\0';
1759+
1760+/* Overwrite the most obvious sensitive data we have on the stack. Note
1761+ * that this does not guarantee there's no sensitive data left on the
1762+ * stack and/or in registers; I'm not aware of portable code that does. */
1763+ clean(&data, sizeof(data));
1764+
1765+ return output;
1766+}
1767+
1768+char *_crypt_gensalt_blowfish_rn(unsigned long count,
1769+ __CONST char *input, int size, char *output, int output_size)
1770+{
1771+ if (size < 16 || output_size < 7 + 22 + 1 ||
1772+ (count && (count < 4 || count > 31))) {
1773+ if (output_size > 0) output[0] = '\0';
1774+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
1775+ return NULL;
1776+ }
1777+
1778+ if (!count) count = 5;
1779+
1780+ output[0] = '$';
1781+ output[1] = '2';
1782+ output[2] = 'a';
1783+ output[3] = '$';
1784+ output[4] = '0' + count / 10;
1785+ output[5] = '0' + count % 10;
1786+ output[6] = '$';
1787+
1788+ BF_encode(&output[7], (BF_word *)input, 16);
1789+ output[7 + 22] = '\0';
1790+
1791+ return output;
1792+}
1793diff -Nura php-4.3.11/ext/standard/crypt.c hardening-patch-4.3.11-0.4.2/ext/standard/crypt.c
1794--- php-4.3.11/ext/standard/crypt.c 2004-01-19 04:16:04.000000000 +0100
1795+++ hardening-patch-4.3.11-0.4.2/ext/standard/crypt.c 2005-09-07 19:04:56.163918808 +0200
1796@@ -100,6 +100,8 @@
1797 return SUCCESS;
1798 }
1799
1800+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size);
1801+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size);
1802
1803 static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1804
1805@@ -135,7 +137,14 @@
1806
1807 /* The automatic salt generation only covers standard DES and md5-crypt */
1808 if(!*salt) {
1809-#if PHP_MD5_CRYPT
1810+#if PHP_BLOWFISH_CRYPT
1811+ char randat[16];
1812+ int i;
1813+
1814+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND;
1815+
1816+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt));
1817+#elif PHP_MD5_CRYPT
1818 strcpy(salt, "$1$");
1819 php_to64(&salt[3], PHP_CRYPT_RAND, 4);
1820 php_to64(&salt[7], PHP_CRYPT_RAND, 4);
1821@@ -145,8 +154,24 @@
1822 salt[2] = '\0';
1823 #endif
1824 }
1825-
1826- RETVAL_STRING(crypt(str, salt), 1);
1827+
1828+ if (salt[0] == '$' &&
1829+ salt[1] == '2' &&
1830+ salt[2] == 'a' &&
1831+ salt[3] == '$' &&
1832+ salt[4] >= '0' && salt[4] <= '3' &&
1833+ salt[5] >= '0' && salt[5] <= '9' &&
1834+ salt[6] == '$') {
1835+
1836+ char output[PHP_MAX_SALT_LEN+1];
1837+
1838+ output[0] = 0;
1839+ _crypt_blowfish_rn(str, salt, output, sizeof(output));
1840+ RETVAL_STRING(output, 1);
1841+
1842+ } else {
1843+ RETVAL_STRING(crypt(str, salt), 1);
1844+ }
1845 }
1846 /* }}} */
1847 #endif
1848diff -Nura php-4.3.11/ext/standard/dl.c hardening-patch-4.3.11-0.4.2/ext/standard/dl.c
1849--- php-4.3.11/ext/standard/dl.c 2003-01-29 16:40:24.000000000 +0100
1850+++ hardening-patch-4.3.11-0.4.2/ext/standard/dl.c 2005-09-07 18:41:00.970101432 +0200
1851@@ -182,8 +182,35 @@
1852 RETURN_FALSE;
1853 }
1854 module_entry = get_module();
1855+
1856+ /* check if Hardening-Patch is installed */
1857+ if (module_entry->zend_api < 1000000000) {
1858+ php_error_docref(NULL TSRMLS_CC, error_type,
1859+ "%s: Unable to initialize module\n"
1860+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n"
1861+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
1862+ "These options need to match\n",
1863+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts,
1864+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
1865+ DL_UNLOAD(handle);
1866+ RETURN_FALSE;
1867+ }
1868+
1869+ /* check if correct Hardening-Patch is installed */
1870+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) {
1871+ php_error_docref(NULL TSRMLS_CC, error_type,
1872+ "%s: Unable to initialize module\n"
1873+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
1874+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
1875+ "These options need to match\n",
1876+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts,
1877+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
1878+ DL_UNLOAD(handle);
1879+ RETURN_FALSE;
1880+ }
1881+
1882 if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS)
1883- || (module_entry->zend_api != ZEND_MODULE_API_NO)) {
1884+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) {
1885 /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
1886 struct pre_4_1_0_module_entry {
1887 char *name;
1888@@ -217,7 +244,7 @@
1889 zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts;
1890 } else {
1891 name = module_entry->name;
1892- zend_api = module_entry->zend_api;
1893+ zend_api = module_entry->real_zend_api;
1894 zend_debug = module_entry->zend_debug;
1895 zts = module_entry->zts;
1896 }
1897diff -Nura php-4.3.11/ext/standard/file.c hardening-patch-4.3.11-0.4.2/ext/standard/file.c
1898--- php-4.3.11/ext/standard/file.c 2005-03-27 17:53:59.000000000 +0200
1899+++ hardening-patch-4.3.11-0.4.2/ext/standard/file.c 2005-09-07 18:41:00.971101280 +0200
1900@@ -2469,7 +2469,7 @@
1901 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1902 /* {{{ proto string realpath(string path)
1903 Return the resolved path */
1904-PHP_FUNCTION(realpath)
1905+PHP_FUNCTION(real_path)
1906 {
1907 zval **path;
1908 char resolved_path_buff[MAXPATHLEN];
1909diff -Nura php-4.3.11/ext/standard/file.h hardening-patch-4.3.11-0.4.2/ext/standard/file.h
1910--- php-4.3.11/ext/standard/file.h 2004-06-21 21:33:47.000000000 +0200
1911+++ hardening-patch-4.3.11-0.4.2/ext/standard/file.h 2005-09-07 18:41:00.971101280 +0200
1912@@ -64,7 +64,7 @@
1913 PHP_FUNCTION(fd_set);
1914 PHP_FUNCTION(fd_isset);
1915 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1916-PHP_FUNCTION(realpath);
1917+PHP_FUNCTION(real_path);
1918 #endif
1919 #ifdef HAVE_FNMATCH
1920 PHP_FUNCTION(fnmatch);
1921diff -Nura php-4.3.11/ext/standard/ftp_fopen_wrapper.c hardening-patch-4.3.11-0.4.2/ext/standard/ftp_fopen_wrapper.c
1922--- php-4.3.11/ext/standard/ftp_fopen_wrapper.c 2003-08-26 00:26:37.000000000 +0200
1923+++ hardening-patch-4.3.11-0.4.2/ext/standard/ftp_fopen_wrapper.c 2005-09-07 18:41:00.972101128 +0200
1924@@ -17,7 +17,7 @@
1925 | Hartmut Holzgraefe <hholzgra@php.net> |
1926 +----------------------------------------------------------------------+
1927 */
1928-/* $Id: ftp_fopen_wrapper.c,v 1.38.2.6 2003/08/25 22:26:37 pollita Exp $ */
1929+/* $Id: ftp_fopen_wrapper.c,v 1.38.2.8.2.1 2005/06/27 08:27:23 sesser Exp $ */
1930
1931 #include "php.h"
1932 #include "php_globals.h"
1933@@ -142,7 +142,7 @@
1934 unsigned short portno;
1935 char *scratch;
1936 int result;
1937- int i, use_ssl;
1938+ int i, use_ssl, tmp_len;
1939 #ifdef HAVE_OPENSSL_EXT
1940 int use_ssl_on_data=0;
1941 php_stream *reuseid=NULL;
1942@@ -243,10 +243,25 @@
1943
1944 #endif
1945
1946+#define PHP_FTP_CNTRL_CHK(val, val_len, err_msg) { \
1947+ unsigned char *s = val, *e = s + val_len; \
1948+ while (s < e) { \
1949+ if (iscntrl(*s)) { \
1950+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, err_msg, val); \
1951+ goto errexit; \
1952+ } \
1953+ s++; \
1954+ } \
1955+}
1956+
1957 /* send the user name */
1958 php_stream_write_string(stream, "USER ");
1959 if (resource->user != NULL) {
1960- php_raw_url_decode(resource->user, strlen(resource->user));
1961+ unsigned char *s, *e;
1962+ tmp_len = php_raw_url_decode(resource->user, strlen(resource->user));
1963+
1964+ PHP_FTP_CNTRL_CHK(resource->user, tmp_len, "Invalid login %s")
1965+
1966 php_stream_write_string(stream, resource->user);
1967 } else {
1968 php_stream_write_string(stream, "anonymous");
1969@@ -262,7 +277,10 @@
1970
1971 php_stream_write_string(stream, "PASS ");
1972 if (resource->pass != NULL) {
1973- php_raw_url_decode(resource->pass, strlen(resource->pass));
1974+ tmp_len = php_raw_url_decode(resource->pass, strlen(resource->pass));
1975+
1976+ PHP_FTP_CNTRL_CHK(resource->pass, tmp_len, "Invalid password %s")
1977+
1978 php_stream_write_string(stream, resource->pass);
1979 } else {
1980 /* if the user has configured who they are,
1981diff -Nura php-4.3.11/ext/standard/head.c hardening-patch-4.3.11-0.4.2/ext/standard/head.c
1982--- php-4.3.11/ext/standard/head.c 2005-01-07 22:14:23.000000000 +0100
1983+++ hardening-patch-4.3.11-0.4.2/ext/standard/head.c 2005-09-07 18:41:00.972101128 +0200
1984@@ -45,10 +45,31 @@
1985 {
1986 zend_bool rep = 1;
1987 sapi_header_line ctr = {0};
1988+#if HARDENING_PATCH
1989+ int i;
1990+#endif
1991
1992 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
1993 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
1994 return;
1995+
1996+#if HARDENING_PATCH
1997+ if (!HG(hphp_multiheader)) {
1998+ for (i=0; i<ctr.line_len; i++) {
1999+ if (ctr.line[i]==0) {
2000+ php_security_log(S_MISC, "header(): headerline truncated by an ASCII-NUL char");
2001+ ctr.line_len=i;
2002+ break;
2003+ } else if (ctr.line[i]=='\n') {
2004+ if (i>0 && (i<ctr.line_len-1) && (ctr.line[i+1]==' ' || ctr.line[i+1]=='\t')) {
2005+ continue;
2006+ }
2007+ php_security_log(S_MISC, "header(): headerline contains more than one header");
2008+ ctr.line_len=i;
2009+ }
2010+ }
2011+ }
2012+#endif
2013
2014 sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
2015 }
2016diff -Nura php-4.3.11/ext/standard/info.c hardening-patch-4.3.11-0.4.2/ext/standard/info.c
2017--- php-4.3.11/ext/standard/info.c 2004-06-09 17:10:19.000000000 +0200
2018+++ hardening-patch-4.3.11-0.4.2/ext/standard/info.c 2005-09-07 18:41:00.973100976 +0200
2019@@ -397,7 +397,7 @@
2020
2021 if (flag & PHP_INFO_GENERAL) {
2022 char *zend_version = get_zend_version();
2023- char temp_api[9];
2024+ char temp_api[11];
2025
2026 php_uname = php_get_uname('a');
2027
2028@@ -417,11 +417,22 @@
2029 }
2030 }
2031
2032+#if HARDENING_PATCH
2033+ if (!sapi_module.phpinfo_as_text) {
2034+ php_printf("<h1 class=\"p\">PHP Version %s with Hardening-Patch %s</h1>\n", PHP_VERSION, HARDENING_PATCH_VERSION);
2035+ } else {
2036+ char temp_ver[40];
2037+
2038+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION);
2039+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver);
2040+ }
2041+#else
2042 if (!sapi_module.phpinfo_as_text) {
2043 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
2044 } else {
2045 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
2046 }
2047+#endif
2048 php_info_print_box_end();
2049 php_info_print_table_start();
2050 php_info_print_table_row(2, "System", php_uname );
2051diff -Nura php-4.3.11/ext/standard/php_standard.h hardening-patch-4.3.11-0.4.2/ext/standard/php_standard.h
2052--- php-4.3.11/ext/standard/php_standard.h 2002-12-31 17:35:33.000000000 +0100
2053+++ hardening-patch-4.3.11-0.4.2/ext/standard/php_standard.h 2005-09-07 19:04:56.163918808 +0200
2054@@ -28,6 +28,7 @@
2055 #include "php_mail.h"
2056 #include "md5.h"
2057 #include "sha1.h"
2058+#include "sha256.h"
2059 #include "html.h"
2060 #include "exec.h"
2061 #include "file.h"
2062diff -Nura php-4.3.11/ext/standard/sha256.c hardening-patch-4.3.11-0.4.2/ext/standard/sha256.c
2063--- php-4.3.11/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100
2064+++ hardening-patch-4.3.11-0.4.2/ext/standard/sha256.c 2005-09-07 19:04:56.164918656 +0200
2065@@ -0,0 +1,398 @@
2066+/*
2067+ +----------------------------------------------------------------------+
2068+ | PHP Version 5 |
2069+ +----------------------------------------------------------------------+
2070+ | Copyright (c) 1997-2004 The PHP Group |
2071+ +----------------------------------------------------------------------+
2072+ | This source file is subject to version 3.0 of the PHP license, |
2073+ | that is bundled with this package in the file LICENSE, and is |
2074+ | available through the world-wide-web at the following url: |
2075+ | http://www.php.net/license/3_0.txt. |
2076+ | If you did not receive a copy of the PHP license and are unable to |
2077+ | obtain it through the world-wide-web, please send a note to |
2078+ | license@php.net so we can mail you a copy immediately. |
2079+ +----------------------------------------------------------------------+
2080+ | Author: Stefan Esser <sesser@php.net> |
2081+ +----------------------------------------------------------------------+
2082+*/
2083+
2084+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */
2085+
2086+#include <stdio.h>
2087+#include "php.h"
2088+
2089+/* This code is heavily based on the PHP md5/sha1 implementations */
2090+
2091+#include "sha256.h"
2092+
2093+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest)
2094+{
2095+ int i;
2096+
2097+ for (i = 0; i < 32; i++) {
2098+ sprintf(sha256str, "%02x", digest[i]);
2099+ sha256str += 2;
2100+ }
2101+
2102+ *sha256str = '\0';
2103+}
2104+
2105+/* {{{ proto string sha256(string str [, bool raw_output])
2106+ Calculate the sha256 hash of a string */
2107+PHP_FUNCTION(sha256)
2108+{
2109+ char *arg;
2110+ int arg_len;
2111+ zend_bool raw_output = 0;
2112+ char sha256str[65];
2113+ PHP_SHA256_CTX context;
2114+ unsigned char digest[32];
2115+
2116+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2117+ return;
2118+ }
2119+
2120+ sha256str[0] = '\0';
2121+ PHP_SHA256Init(&context);
2122+ PHP_SHA256Update(&context, arg, arg_len);
2123+ PHP_SHA256Final(digest, &context);
2124+ if (raw_output) {
2125+ RETURN_STRINGL(digest, 32, 1);
2126+ } else {
2127+ make_sha256_digest(sha256str, digest);
2128+ RETVAL_STRING(sha256str, 1);
2129+ }
2130+
2131+}
2132+
2133+/* }}} */
2134+
2135+/* {{{ proto string sha256_file(string filename [, bool raw_output])
2136+ Calculate the sha256 hash of given filename */
2137+PHP_FUNCTION(sha256_file)
2138+{
2139+ char *arg;
2140+ int arg_len;
2141+ zend_bool raw_output = 0;
2142+ char sha256str[65];
2143+ unsigned char buf[1024];
2144+ unsigned char digest[32];
2145+ PHP_SHA256_CTX context;
2146+ int n;
2147+ FILE *fp;
2148+
2149+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2150+ return;
2151+ }
2152+
2153+ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
2154+ RETURN_FALSE;
2155+ }
2156+
2157+ if (php_check_open_basedir(arg TSRMLS_CC)) {
2158+ RETURN_FALSE;
2159+ }
2160+
2161+ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) {
2162+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file");
2163+ RETURN_FALSE;
2164+ }
2165+
2166+ PHP_SHA256Init(&context);
2167+
2168+ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
2169+ PHP_SHA256Update(&context, buf, n);
2170+ }
2171+
2172+ PHP_SHA256Final(digest, &context);
2173+
2174+ if (ferror(fp)) {
2175+ fclose(fp);
2176+ RETURN_FALSE;
2177+ }
2178+
2179+ fclose(fp);
2180+
2181+ if (raw_output) {
2182+ RETURN_STRINGL(digest, 32, 1);
2183+ } else {
2184+ make_sha256_digest(sha256str, digest);
2185+ RETVAL_STRING(sha256str, 1);
2186+ }
2187+}
2188+/* }}} */
2189+
2190+
2191+static void SHA256Transform(php_uint32[8], const unsigned char[64]);
2192+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int);
2193+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int);
2194+
2195+static unsigned char PADDING[64] =
2196+{
2197+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2198+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2199+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2200+};
2201+
2202+/* F, G, H and I are basic SHA256 functions.
2203+ */
2204+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22))
2205+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x))))
2206+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25))
2207+#define I(x, y, z) (((x) & (y)) | ((~x) & z))
2208+
2209+/* ROTATE_RIGHT rotates x right n bits.
2210+ */
2211+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n))))
2212+
2213+/* W[i]
2214+ */
2215+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \
2216+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \
2217+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) )
2218+
2219+/* ROUND function of sha256
2220+ */
2221+
2222+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \
2223+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \
2224+ (h) = F((a)) + G((a), (b), (c)) + t1; \
2225+ (d) += t1; \
2226+ }
2227+
2228+
2229+/* {{{ PHP_SHA256Init
2230+ * SHA256 initialization. Begins an SHA256 operation, writing a new context.
2231+ */
2232+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context)
2233+{
2234+ context->count[0] = context->count[1] = 0;
2235+ /* Load magic initialization constants.
2236+ */
2237+ context->state[0] = 0x6a09e667;
2238+ context->state[1] = 0xbb67ae85;
2239+ context->state[2] = 0x3c6ef372;
2240+ context->state[3] = 0xa54ff53a;
2241+ context->state[4] = 0x510e527f;
2242+ context->state[5] = 0x9b05688c;
2243+ context->state[6] = 0x1f83d9ab;
2244+ context->state[7] = 0x5be0cd19;
2245+}
2246+/* }}} */
2247+
2248+/* {{{ PHP_SHA256Update
2249+ SHA256 block update operation. Continues an SHA256 message-digest
2250+ operation, processing another message block, and updating the
2251+ context.
2252+ */
2253+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input,
2254+ unsigned int inputLen)
2255+{
2256+ unsigned int i, index, partLen;
2257+
2258+ /* Compute number of bytes mod 64 */
2259+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
2260+
2261+ /* Update number of bits */
2262+ if ((context->count[0] += ((php_uint32) inputLen << 3))
2263+ < ((php_uint32) inputLen << 3))
2264+ context->count[1]++;
2265+ context->count[1] += ((php_uint32) inputLen >> 29);
2266+
2267+ partLen = 64 - index;
2268+
2269+ /* Transform as many times as possible.
2270+ */
2271+ if (inputLen >= partLen) {
2272+ memcpy
2273+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
2274+ SHA256Transform(context->state, context->buffer);
2275+
2276+ for (i = partLen; i + 63 < inputLen; i += 64)
2277+ SHA256Transform(context->state, &input[i]);
2278+
2279+ index = 0;
2280+ } else
2281+ i = 0;
2282+
2283+ /* Buffer remaining input */
2284+ memcpy
2285+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
2286+ inputLen - i);
2287+}
2288+/* }}} */
2289+
2290+/* {{{ PHP_SHA256Final
2291+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the
2292+ the message digest and zeroizing the context.
2293+ */
2294+PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
2295+{
2296+ unsigned char bits[8];
2297+ unsigned int index, padLen;
2298+
2299+ /* Save number of bits */
2300+ bits[7] = context->count[0] & 0xFF;
2301+ bits[6] = (context->count[0] >> 8) & 0xFF;
2302+ bits[5] = (context->count[0] >> 16) & 0xFF;
2303+ bits[4] = (context->count[0] >> 24) & 0xFF;
2304+ bits[3] = context->count[1] & 0xFF;
2305+ bits[2] = (context->count[1] >> 8) & 0xFF;
2306+ bits[1] = (context->count[1] >> 16) & 0xFF;
2307+ bits[0] = (context->count[1] >> 24) & 0xFF;
2308+
2309+ /* Pad out to 56 mod 64.
2310+ */
2311+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
2312+ padLen = (index < 56) ? (56 - index) : (120 - index);
2313+ PHP_SHA256Update(context, PADDING, padLen);
2314+
2315+ /* Append length (before padding) */
2316+ PHP_SHA256Update(context, bits, 8);
2317+
2318+ /* Store state in digest */
2319+ SHA256Encode(digest, context->state, 32);
2320+
2321+ /* Zeroize sensitive information.
2322+ */
2323+ memset((unsigned char*) context, 0, sizeof(*context));
2324+}
2325+/* }}} */
2326+
2327+/* {{{ SHA256Transform
2328+ * SHA256 basic transformation. Transforms state based on block.
2329+ */
2330+static void SHA256Transform(state, block)
2331+php_uint32 state[8];
2332+const unsigned char block[64];
2333+{
2334+ php_uint32 a = state[0], b = state[1], c = state[2];
2335+ php_uint32 d = state[3], e = state[4], f = state[5];
2336+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1;
2337+
2338+ SHA256Decode(x, block, 64);
2339+
2340+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98)
2341+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491)
2342+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf)
2343+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5)
2344+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b)
2345+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1)
2346+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4)
2347+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5)
2348+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98)
2349+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01)
2350+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be)
2351+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3)
2352+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74)
2353+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe)
2354+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7)
2355+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174)
2356+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1)
2357+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786)
2358+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6)
2359+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc)
2360+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f)
2361+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa)
2362+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc)
2363+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da)
2364+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152)
2365+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d)
2366+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8)
2367+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7)
2368+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3)
2369+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147)
2370+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351)
2371+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967)
2372+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85)
2373+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138)
2374+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc)
2375+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13)
2376+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354)
2377+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb)
2378+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e)
2379+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85)
2380+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1)
2381+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b)
2382+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70)
2383+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3)
2384+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819)
2385+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624)
2386+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585)
2387+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070)
2388+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116)
2389+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08)
2390+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c)
2391+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5)
2392+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3)
2393+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a)
2394+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f)
2395+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3)
2396+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee)
2397+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f)
2398+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814)
2399+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208)
2400+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa)
2401+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb)
2402+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7)
2403+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2)
2404+
2405+ state[0] += a;
2406+ state[1] += b;
2407+ state[2] += c;
2408+ state[3] += d;
2409+ state[4] += e;
2410+ state[5] += f;
2411+ state[6] += g;
2412+ state[7] += h;
2413+
2414+ /* Zeroize sensitive information. */
2415+ memset((unsigned char*) x, 0, sizeof(x));
2416+}
2417+/* }}} */
2418+
2419+/* {{{ SHA256Encode
2420+ Encodes input (php_uint32) into output (unsigned char). Assumes len is
2421+ a multiple of 4.
2422+ */
2423+static void SHA256Encode(output, input, len)
2424+unsigned char *output;
2425+php_uint32 *input;
2426+unsigned int len;
2427+{
2428+ unsigned int i, j;
2429+
2430+ for (i = 0, j = 0; j < len; i++, j += 4) {
2431+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
2432+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
2433+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
2434+ output[j + 3] = (unsigned char) (input[i] & 0xff);
2435+ }
2436+}
2437+/* }}} */
2438+
2439+/* {{{ SHA256Decode
2440+ Decodes input (unsigned char) into output (php_uint32). Assumes len is
2441+ a multiple of 4.
2442+ */
2443+static void SHA256Decode(output, input, len)
2444+php_uint32 *output;
2445+const unsigned char *input;
2446+unsigned int len;
2447+{
2448+ unsigned int i, j;
2449+
2450+ for (i = 0, j = 0; j < len; i++, j += 4)
2451+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
2452+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
2453+}
2454+/* }}} */
2455+
2456+/*
2457+ * Local variables:
2458+ * tab-width: 4
2459+ * c-basic-offset: 4
2460+ * End:
2461+ * vim600: sw=4 ts=4 fdm=marker
2462+ * vim<600: sw=4 ts=4
2463+ */
2464diff -Nura php-4.3.11/ext/standard/sha256.h hardening-patch-4.3.11-0.4.2/ext/standard/sha256.h
2465--- php-4.3.11/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100
2466+++ hardening-patch-4.3.11-0.4.2/ext/standard/sha256.h 2005-09-07 19:04:56.164918656 +0200
2467@@ -0,0 +1,40 @@
2468+/*
2469+ +----------------------------------------------------------------------+
2470+ | PHP Version 5 |
2471+ +----------------------------------------------------------------------+
2472+ | Copyright (c) 1997-2004 The PHP Group |
2473+ +----------------------------------------------------------------------+
2474+ | This source file is subject to version 3.0 of the PHP license, |
2475+ | that is bundled with this package in the file LICENSE, and is |
2476+ | available through the world-wide-web at the following url: |
2477+ | http://www.php.net/license/3_0.txt. |
2478+ | If you did not receive a copy of the PHP license and are unable to |
2479+ | obtain it through the world-wide-web, please send a note to |
2480+ | license@php.net so we can mail you a copy immediately. |
2481+ +----------------------------------------------------------------------+
2482+ | Author: Stefan Esser <sesser@php.net> |
2483+ +----------------------------------------------------------------------+
2484+*/
2485+
2486+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */
2487+
2488+#ifndef SHA256_H
2489+#define SHA256_H
2490+
2491+#include "ext/standard/basic_functions.h"
2492+
2493+/* SHA1 context. */
2494+typedef struct {
2495+ php_uint32 state[8]; /* state (ABCD) */
2496+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */
2497+ unsigned char buffer[64]; /* input buffer */
2498+} PHP_SHA256_CTX;
2499+
2500+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *);
2501+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int);
2502+PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *);
2503+
2504+PHP_FUNCTION(sha256);
2505+PHP_FUNCTION(sha256_file);
2506+
2507+#endif
2508diff -Nura php-4.3.11/ext/standard/syslog.c hardening-patch-4.3.11-0.4.2/ext/standard/syslog.c
2509--- php-4.3.11/ext/standard/syslog.c 2004-07-30 16:38:29.000000000 +0200
2510+++ hardening-patch-4.3.11-0.4.2/ext/standard/syslog.c 2005-09-07 18:41:00.974100824 +0200
2511@@ -42,6 +42,7 @@
2512 */
2513 PHP_MINIT_FUNCTION(syslog)
2514 {
2515+#if !HARDENING_PATCH
2516 /* error levels */
2517 REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
2518 REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
2519@@ -97,7 +98,7 @@
2520 /* AIX doesn't have LOG_PERROR */
2521 REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
2522 #endif
2523-
2524+#endif
2525 return SUCCESS;
2526 }
2527 /* }}} */
2528diff -Nura php-4.3.11/ext/varfilter/config.m4 hardening-patch-4.3.11-0.4.2/ext/varfilter/config.m4
2529--- php-4.3.11/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
2530+++ hardening-patch-4.3.11-0.4.2/ext/varfilter/config.m4 2005-09-07 18:41:00.974100824 +0200
2531@@ -0,0 +1,11 @@
2532+dnl
2533+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
2534+dnl
2535+
2536+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
2537+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes)
2538+
2539+if test "$PHP_VARFILTER" != "no"; then
2540+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
2541+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
2542+fi
2543diff -Nura php-4.3.11/ext/varfilter/CREDITS hardening-patch-4.3.11-0.4.2/ext/varfilter/CREDITS
2544--- php-4.3.11/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
2545+++ hardening-patch-4.3.11-0.4.2/ext/varfilter/CREDITS 2005-09-07 18:41:00.974100824 +0200
2546@@ -0,0 +1,2 @@
2547+varfilter
2548+Stefan Esser
2549\ Kein Zeilenumbruch am Dateiende.
2550diff -Nura php-4.3.11/ext/varfilter/php_varfilter.h hardening-patch-4.3.11-0.4.2/ext/varfilter/php_varfilter.h
2551--- php-4.3.11/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
2552+++ hardening-patch-4.3.11-0.4.2/ext/varfilter/php_varfilter.h 2005-09-07 18:41:00.975100672 +0200
2553@@ -0,0 +1,111 @@
2554+/*
2555+ +----------------------------------------------------------------------+
2556+ | Hardened-PHP Project's varfilter extension |
2557+ +----------------------------------------------------------------------+
2558+ | Copyright (c) 2004-2005 Stefan Esser |
2559+ +----------------------------------------------------------------------+
2560+ | This source file is subject to version 2.02 of the PHP license, |
2561+ | that is bundled with this package in the file LICENSE, and is |
2562+ | available at through the world-wide-web at |
2563+ | http://www.php.net/license/2_02.txt. |
2564+ | If you did not receive a copy of the PHP license and are unable to |
2565+ | obtain it through the world-wide-web, please send a note to |
2566+ | license@php.net so we can mail you a copy immediately. |
2567+ +----------------------------------------------------------------------+
2568+ | Author: Stefan Esser <sesser@hardened-php.net> |
2569+ +----------------------------------------------------------------------+
2570+
2571+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
2572+*/
2573+
2574+#ifndef PHP_VARFILTER_H
2575+#define PHP_VARFILTER_H
2576+
2577+extern zend_module_entry varfilter_module_entry;
2578+#define phpext_varfilter_ptr &varfilter_module_entry
2579+
2580+#ifdef PHP_WIN32
2581+#define PHP_VARFILTER_API __declspec(dllexport)
2582+#else
2583+#define PHP_VARFILTER_API
2584+#endif
2585+
2586+#ifdef ZTS
2587+#include "TSRM.h"
2588+#endif
2589+
2590+#include "SAPI.h"
2591+
2592+#include "php_variables.h"
2593+
2594+
2595+PHP_MINIT_FUNCTION(varfilter);
2596+PHP_MSHUTDOWN_FUNCTION(varfilter);
2597+PHP_RINIT_FUNCTION(varfilter);
2598+PHP_RSHUTDOWN_FUNCTION(varfilter);
2599+PHP_MINFO_FUNCTION(varfilter);
2600+
2601+
2602+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
2603+/* request variables */
2604+ long max_request_variables;
2605+ long cur_request_variables;
2606+ long max_varname_length;
2607+ long max_totalname_length;
2608+ long max_value_length;
2609+ long max_array_depth;
2610+ long max_array_index_length;
2611+/* cookie variables */
2612+ long max_cookie_vars;
2613+ long cur_cookie_vars;
2614+ long max_cookie_name_length;
2615+ long max_cookie_totalname_length;
2616+ long max_cookie_value_length;
2617+ long max_cookie_array_depth;
2618+ long max_cookie_array_index_length;
2619+/* get variables */
2620+ long max_get_vars;
2621+ long cur_get_vars;
2622+ long max_get_name_length;
2623+ long max_get_totalname_length;
2624+ long max_get_value_length;
2625+ long max_get_array_depth;
2626+ long max_get_array_index_length;
2627+/* post variables */
2628+ long max_post_vars;
2629+ long cur_post_vars;
2630+ long max_post_name_length;
2631+ long max_post_totalname_length;
2632+ long max_post_value_length;
2633+ long max_post_array_depth;
2634+ long max_post_array_index_length;
2635+/* fileupload */
2636+ long max_uploads;
2637+ long cur_uploads;
2638+ zend_bool disallow_elf_files;
2639+ char *verification_script;
2640+
2641+ZEND_END_MODULE_GLOBALS(varfilter)
2642+
2643+
2644+#ifdef ZTS
2645+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
2646+#else
2647+#define VARFILTER_G(v) (varfilter_globals.v)
2648+#endif
2649+
2650+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
2651+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
2652+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
2653+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
2654+
2655+#endif /* PHP_VARFILTER_H */
2656+
2657+
2658+/*
2659+ * Local variables:
2660+ * tab-width: 4
2661+ * c-basic-offset: 4
2662+ * indent-tabs-mode: t
2663+ * End:
2664+ */
2665diff -Nura php-4.3.11/ext/varfilter/varfilter.c hardening-patch-4.3.11-0.4.2/ext/varfilter/varfilter.c
2666--- php-4.3.11/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
2667+++ hardening-patch-4.3.11-0.4.2/ext/varfilter/varfilter.c 2005-09-07 19:04:56.164918656 +0200
2668@@ -0,0 +1,602 @@
2669+/*
2670+ +----------------------------------------------------------------------+
2671+ | Hardened-PHP Project's varfilter extension |
2672+ +----------------------------------------------------------------------+
2673+ | Copyright (c) 2004-2005 Stefan Esser |
2674+ +----------------------------------------------------------------------+
2675+ | This source file is subject to version 2.02 of the PHP license, |
2676+ | that is bundled with this package in the file LICENSE, and is |
2677+ | available at through the world-wide-web at |
2678+ | http://www.php.net/license/2_02.txt. |
2679+ | If you did not receive a copy of the PHP license and are unable to |
2680+ | obtain it through the world-wide-web, please send a note to |
2681+ | license@php.net so we can mail you a copy immediately. |
2682+ +----------------------------------------------------------------------+
2683+ | Author: Stefan Esser <sesser@hardened-php.net> |
2684+ +----------------------------------------------------------------------+
2685+
2686+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
2687+*/
2688+
2689+#ifdef HAVE_CONFIG_H
2690+#include "config.h"
2691+#endif
2692+
2693+#include "php.h"
2694+#include "php_ini.h"
2695+#include "ext/standard/info.h"
2696+#include "php_varfilter.h"
2697+#include "hardening_patch.h"
2698+
2699+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
2700+
2701+/* True global resources - no need for thread safety here */
2702+static int le_varfilter;
2703+
2704+/* {{{ varfilter_module_entry
2705+ */
2706+zend_module_entry varfilter_module_entry = {
2707+#if ZEND_MODULE_API_NO >= 20010901
2708+ STANDARD_MODULE_HEADER,
2709+#endif
2710+ "varfilter",
2711+ NULL,
2712+ PHP_MINIT(varfilter),
2713+ PHP_MSHUTDOWN(varfilter),
2714+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
2715+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
2716+ PHP_MINFO(varfilter),
2717+#if ZEND_MODULE_API_NO >= 20010901
2718+ "0.3.2", /* Replace with version number for your extension */
2719+#endif
2720+ STANDARD_MODULE_PROPERTIES
2721+};
2722+/* }}} */
2723+
2724+#ifdef COMPILE_DL_VARFILTER
2725+ZEND_GET_MODULE(varfilter)
2726+#endif
2727+
2728+/* {{{ PHP_INI
2729+ */
2730+PHP_INI_BEGIN()
2731+ /* for backward compatibility */
2732+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
2733+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
2734+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
2735+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
2736+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
2737+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
2738+
2739+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
2740+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
2741+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
2742+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
2743+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
2744+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
2745+
2746+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
2747+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
2748+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
2749+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
2750+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
2751+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_index_length, zend_varfilter_globals, varfilter_globals)
2752+
2753+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
2754+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
2755+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
2756+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
2757+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
2758+ STD_PHP_INI_ENTRY("hphp.get.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_array_index_length, zend_varfilter_globals, varfilter_globals)
2759+
2760+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
2761+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
2762+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
2763+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
2764+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
2765+ STD_PHP_INI_ENTRY("hphp.post.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_array_index_length, zend_varfilter_globals, varfilter_globals)
2766+
2767+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
2768+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
2769+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
2770+
2771+
2772+PHP_INI_END()
2773+/* }}} */
2774+
2775+/* {{{ php_varfilter_init_globals
2776+ */
2777+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
2778+{
2779+ varfilter_globals->max_request_variables = 200;
2780+ varfilter_globals->max_varname_length = 64;
2781+ varfilter_globals->max_value_length = 10000;
2782+ varfilter_globals->max_array_depth = 100;
2783+ varfilter_globals->max_totalname_length = 256;
2784+ varfilter_globals->max_array_index_length = 64;
2785+
2786+ varfilter_globals->max_cookie_vars = 100;
2787+ varfilter_globals->max_cookie_name_length = 64;
2788+ varfilter_globals->max_cookie_totalname_length = 256;
2789+ varfilter_globals->max_cookie_value_length = 10000;
2790+ varfilter_globals->max_cookie_array_depth = 100;
2791+ varfilter_globals->max_cookie_array_index_length = 64;
2792+
2793+ varfilter_globals->max_get_vars = 100;
2794+ varfilter_globals->max_get_name_length = 64;
2795+ varfilter_globals->max_get_totalname_length = 256;
2796+ varfilter_globals->max_get_value_length = 512;
2797+ varfilter_globals->max_get_array_depth = 50;
2798+ varfilter_globals->max_get_array_index_length = 64;
2799+
2800+ varfilter_globals->max_post_vars = 200;
2801+ varfilter_globals->max_post_name_length = 64;
2802+ varfilter_globals->max_post_totalname_length = 256;
2803+ varfilter_globals->max_post_value_length = 65000;
2804+ varfilter_globals->max_post_array_depth = 100;
2805+ varfilter_globals->max_post_array_index_length = 64;
2806+
2807+ varfilter_globals->max_uploads = 25;
2808+ varfilter_globals->disallow_elf_files = 1;
2809+ varfilter_globals->verification_script = NULL;
2810+}
2811+/* }}} */
2812+
2813+/* {{{ PHP_MINIT_FUNCTION
2814+ */
2815+PHP_MINIT_FUNCTION(varfilter)
2816+{
2817+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
2818+ REGISTER_INI_ENTRIES();
2819+
2820+ sapi_register_input_filter(varfilter_input_filter);
2821+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
2822+ sapi_register_upload_content_filter(varfilter_upload_content_filter);
2823+ sapi_register_post_upload_filter(varfilter_post_upload_filter);
2824+
2825+ return SUCCESS;
2826+}
2827+/* }}} */
2828+
2829+/* {{{ PHP_MSHUTDOWN_FUNCTION
2830+ */
2831+PHP_MSHUTDOWN_FUNCTION(varfilter)
2832+{
2833+ UNREGISTER_INI_ENTRIES();
2834+
2835+ return SUCCESS;
2836+}
2837+/* }}} */
2838+
2839+/* Remove if there's nothing to do at request start */
2840+/* {{{ PHP_RINIT_FUNCTION
2841+ */
2842+PHP_RINIT_FUNCTION(varfilter)
2843+{
2844+ VARFILTER_G(cur_request_variables) = 0;
2845+ VARFILTER_G(cur_get_vars) = 0;
2846+ VARFILTER_G(cur_post_vars) = 0;
2847+ VARFILTER_G(cur_cookie_vars) = 0;
2848+
2849+ VARFILTER_G(cur_uploads) = 0;
2850+
2851+ return SUCCESS;
2852+}
2853+/* }}} */
2854+
2855+/* Remove if there's nothing to do at request end */
2856+/* {{{ PHP_RSHUTDOWN_FUNCTION
2857+ */
2858+PHP_RSHUTDOWN_FUNCTION(varfilter)
2859+{
2860+ return SUCCESS;
2861+}
2862+/* }}} */
2863+
2864+/* {{{ PHP_MINFO_FUNCTION
2865+ */
2866+PHP_MINFO_FUNCTION(varfilter)
2867+{
2868+ php_info_print_table_start();
2869+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
2870+ php_info_print_table_end();
2871+
2872+ DISPLAY_INI_ENTRIES();
2873+}
2874+/* }}} */
2875+
2876+/* {{{ normalize_varname
2877+ */
2878+static void normalize_varname(char *varname)
2879+{
2880+ char *s=varname, *index=NULL, *indexend=NULL, *p;
2881+
2882+ /* overjump leading space */
2883+ while (*s == ' ') {
2884+ s++;
2885+ }
2886+
2887+ /* and remove it */
2888+ if (s != varname) {
2889+ memmove(varname, s, strlen(s)+1);
2890+ }
2891+
2892+ for (p=varname; *p && *p != '['; p++) {
2893+ switch(*p) {
2894+ case ' ':
2895+ case '.':
2896+ *p='_';
2897+ break;
2898+ }
2899+ }
2900+
2901+ /* find index */
2902+ index = strchr(varname, '[');
2903+ if (index) {
2904+ index++;
2905+ s=index;
2906+ } else {
2907+ return;
2908+ }
2909+
2910+ /* done? */
2911+ while (index) {
2912+
2913+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
2914+ index++;
2915+ }
2916+ indexend = strchr(index, ']');
2917+ indexend = indexend ? indexend + 1 : index + strlen(index);
2918+
2919+ if (s != index) {
2920+ memmove(s, index, strlen(index)+1);
2921+ s += indexend-index;
2922+ } else {
2923+ s = indexend;
2924+ }
2925+
2926+ if (*s == '[') {
2927+ s++;
2928+ index = s;
2929+ } else {
2930+ index = NULL;
2931+ }
2932+ }
2933+ *s++='\0';
2934+}
2935+/* }}} */
2936+
2937+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
2938+ */
2939+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
2940+{
2941+ /* Drop this fileupload if the limit is reached */
2942+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
2943+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
2944+ return FAILURE;
2945+ }
2946+
2947+ return SUCCESS;
2948+}
2949+/* }}} */
2950+
2951+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
2952+ */
2953+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
2954+{
2955+
2956+ if (VARFILTER_G(disallow_elf_files)) {
2957+
2958+ if (offset == 0 && buffer_len > 10) {
2959+
2960+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
2961+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
2962+ return FAILURE;
2963+ }
2964+ }
2965+
2966+ }
2967+
2968+ return SUCCESS;
2969+}
2970+/* }}} */
2971+
2972+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
2973+ */
2974+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
2975+{
2976+ int retval = SUCCESS;
2977+
2978+ if (VARFILTER_G(verification_script)) {
2979+ char cmd[8192];
2980+ FILE *in;
2981+ int first=1;
2982+
2983+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
2984+
2985+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
2986+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script));
2987+ return FAILURE;
2988+ }
2989+
2990+ retval = FAILURE;
2991+
2992+ /* read and forget the result */
2993+ while (1) {
2994+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
2995+ if (readbytes<=0) {
2996+ break;
2997+ }
2998+ if (first) {
2999+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
3000+ first = 0;
3001+ }
3002+ }
3003+ pclose(in);
3004+ }
3005+
3006+ if (retval != SUCCESS) {
3007+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
3008+ return FAILURE;
3009+ }
3010+
3011+ VARFILTER_G(cur_uploads)++;
3012+ return SUCCESS;
3013+}
3014+/* }}} */
3015+
3016+/* {{{ SAPI_INPUT_FILTER_FUNC
3017+ */
3018+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
3019+{
3020+ char *index, *prev_index = NULL, *copy_var;
3021+ unsigned int var_len, total_len, depth = 0, rv;
3022+
3023+ /* Drop this variable if the limit is reached */
3024+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
3025+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
3026+ return 0;
3027+ }
3028+ switch (arg) {
3029+ case PARSE_GET:
3030+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
3031+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
3032+ return 0;
3033+ }
3034+ break;
3035+ case PARSE_COOKIE:
3036+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
3037+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
3038+ return 0;
3039+ }
3040+ break;
3041+ case PARSE_POST:
3042+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
3043+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
3044+ return 0;
3045+ }
3046+ break;
3047+ }
3048+
3049+
3050+ /* Drop this variable if it exceeds the value length limit */
3051+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
3052+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
3053+ return 0;
3054+ }
3055+ switch (arg) {
3056+ case PARSE_GET:
3057+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
3058+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
3059+ return 0;
3060+ }
3061+ break;
3062+ case PARSE_COOKIE:
3063+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
3064+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
3065+ return 0;
3066+ }
3067+ break;
3068+ case PARSE_POST:
3069+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
3070+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
3071+ return 0;
3072+ }
3073+ break;
3074+ }
3075+
3076+ /* Normalize the variable name */
3077+ normalize_varname(var);
3078+
3079+ /* Find length of variable name */
3080+ index = strchr(var, '[');
3081+ total_len = strlen(var);
3082+ var_len = index ? index-var : total_len;
3083+
3084+ /* Drop this variable if it exceeds the varname/total length limit */
3085+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3086+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
3087+ return 0;
3088+ }
3089+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3090+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
3091+ return 0;
3092+ }
3093+ switch (arg) {
3094+ case PARSE_GET:
3095+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
3096+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
3097+ return 0;
3098+ }
3099+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
3100+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
3101+ return 0;
3102+ }
3103+ break;
3104+ case PARSE_COOKIE:
3105+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
3106+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
3107+ return 0;
3108+ }
3109+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
3110+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
3111+ return 0;
3112+ }
3113+ break;
3114+ case PARSE_POST:
3115+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3116+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
3117+ return 0;
3118+ }
3119+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3120+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
3121+ return 0;
3122+ }
3123+ break;
3124+ }
3125+
3126+ /* Find out array depth */
3127+ while (index) {
3128+ unsigned int index_length;
3129+
3130+ depth++;
3131+ index = strchr(index+1, '[');
3132+
3133+ if (prev_index) {
3134+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3135+
3136+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3137+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
3138+ return 0;
3139+ }
3140+ switch (arg) {
3141+ case PARSE_GET:
3142+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
3143+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
3144+ return 0;
3145+ }
3146+ break;
3147+ case PARSE_COOKIE:
3148+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
3149+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
3150+ return 0;
3151+ }
3152+ break;
3153+ case PARSE_POST:
3154+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3155+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
3156+ return 0;
3157+ }
3158+ break;
3159+ }
3160+ prev_index = index;
3161+ }
3162+
3163+ }
3164+
3165+ /* Drop this variable if it exceeds the array depth limit */
3166+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3167+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
3168+ return 0;
3169+ }
3170+ switch (arg) {
3171+ case PARSE_GET:
3172+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
3173+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
3174+ return 0;
3175+ }
3176+ break;
3177+ case PARSE_COOKIE:
3178+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
3179+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
3180+ return 0;
3181+ }
3182+ break;
3183+ case PARSE_POST:
3184+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3185+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
3186+ return 0;
3187+ }
3188+ break;
3189+ }
3190+
3191+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3192+ /* This is to protect several silly scripts that do globalizing themself */
3193+
3194+ switch (var_len) {
3195+ case 18:
3196+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
3197+ break;
3198+ case 17:
3199+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
3200+ break;
3201+ case 16:
3202+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
3203+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
3204+ break;
3205+ case 15:
3206+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
3207+ break;
3208+ case 14:
3209+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
3210+ break;
3211+ case 13:
3212+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
3213+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
3214+ break;
3215+ case 8:
3216+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
3217+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
3218+ break;
3219+ case 7:
3220+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
3221+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
3222+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
3223+ break;
3224+ case 6:
3225+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
3226+ break;
3227+ case 5:
3228+ if (memcmp(var, "_POST", 5)==0) goto protected_varname;
3229+ break;
3230+ case 4:
3231+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
3232+ if (memcmp(var, "_GET", 4)==0) goto protected_varname;
3233+ break;
3234+ }
3235+
3236+ /* Okay let PHP register this variable */
3237+ VARFILTER_G(cur_request_variables)++;
3238+ switch (arg) {
3239+ case PARSE_GET:
3240+ VARFILTER_G(cur_get_vars)++;
3241+ break;
3242+ case PARSE_COOKIE:
3243+ VARFILTER_G(cur_cookie_vars)++;
3244+ break;
3245+ case PARSE_POST:
3246+ VARFILTER_G(cur_post_vars)++;
3247+ break;
3248+ }
3249+
3250+ if (new_val_len) {
3251+ *new_val_len = val_len;
3252+ }
3253+
3254+ return 1;
3255+protected_varname:
3256+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
3257+ return 0;
3258+}
3259+/* }}} */
3260+
3261+/*
3262+ * Local variables:
3263+ * tab-width: 4
3264+ * c-basic-offset: 4
3265+ * End:
3266+ * vim600: noet sw=4 ts=4 fdm=marker
3267+ * vim<600: noet sw=4 ts=4
3268+ */
3269+
3270+
3271diff -Nura php-4.3.11/main/fopen_wrappers.c hardening-patch-4.3.11-0.4.2/main/fopen_wrappers.c
3272--- php-4.3.11/main/fopen_wrappers.c 2005-02-03 00:44:07.000000000 +0100
3273+++ hardening-patch-4.3.11-0.4.2/main/fopen_wrappers.c 2005-09-07 18:41:00.976100520 +0200
3274@@ -166,6 +166,21 @@
3275 char *pathbuf;
3276 char *ptr;
3277 char *end;
3278+ char path_copy[MAXPATHLEN];
3279+ int path_len;
3280+
3281+ /* Special case path ends with a trailing slash */
3282+ path_len = strlen(path);
3283+ if (path_len >= MAXPATHLEN) {
3284+ errno = EPERM; /* we deny permission to open it */
3285+ return -1;
3286+ }
3287+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
3288+ memcpy(path_copy, path, path_len+1);
3289+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
3290+ path_copy[path_len] = '\0';
3291+ path = (const char *)&path_copy;
3292+ }
3293
3294 pathbuf = estrdup(PG(open_basedir));
3295
3296diff -Nura php-4.3.11/main/hardened_globals.h hardening-patch-4.3.11-0.4.2/main/hardened_globals.h
3297--- php-4.3.11/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
3298+++ hardening-patch-4.3.11-0.4.2/main/hardened_globals.h 2005-09-07 18:41:00.977100368 +0200
3299@@ -0,0 +1,60 @@
3300+/*
3301+ +----------------------------------------------------------------------+
3302+ | Hardening-Patch for PHP |
3303+ +----------------------------------------------------------------------+
3304+ | Copyright (c) 2004-2005 Stefan Esser |
3305+ +----------------------------------------------------------------------+
3306+ | This source file is subject to version 2.02 of the PHP license, |
3307+ | that is bundled with this package in the file LICENSE, and is |
3308+ | available at through the world-wide-web at |
3309+ | http://www.php.net/license/2_02.txt. |
3310+ | If you did not receive a copy of the PHP license and are unable to |
3311+ | obtain it through the world-wide-web, please send a note to |
3312+ | license@php.net so we can mail you a copy immediately. |
3313+ +----------------------------------------------------------------------+
3314+ | Author: Stefan Esser <sesser@hardened-php.net> |
3315+ +----------------------------------------------------------------------+
3316+ */
3317+
3318+#ifndef HARDENED_GLOBALS_H
3319+#define HARDENED_GLOBALS_H
3320+
3321+typedef struct _hardened_globals hardened_globals_struct;
3322+
3323+#ifdef ZTS
3324+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
3325+extern int hardened_globals_id;
3326+#else
3327+# define HG(v) (hardened_globals.v)
3328+extern struct _hardened_globals hardened_globals;
3329+#endif
3330+
3331+
3332+struct _hardened_globals {
3333+#if HARDENING_PATCH_MM_PROTECT
3334+ unsigned int canary_1;
3335+ unsigned int canary_2;
3336+#endif
3337+#if HARDENING_PATCH_LL_PROTECT
3338+ unsigned int canary_3;
3339+ unsigned int canary_4;
3340+ unsigned int ll_canary_inited;
3341+#endif
3342+ zend_bool hphp_sql_bailout_on_error;
3343+ zend_bool hphp_multiheader;
3344+ HashTable *eval_whitelist;
3345+ HashTable *eval_blacklist;
3346+ HashTable *func_whitelist;
3347+ HashTable *func_blacklist;
3348+ unsigned int dummy;
3349+};
3350+
3351+
3352+#endif /* HARDENED_GLOBALS_H */
3353+
3354+/*
3355+ * Local variables:
3356+ * tab-width: 4
3357+ * c-basic-offset: 4
3358+ * End:
3359+ */
3360diff -Nura php-4.3.11/main/hardening_patch.c hardening-patch-4.3.11-0.4.2/main/hardening_patch.c
3361--- php-4.3.11/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100
3362+++ hardening-patch-4.3.11-0.4.2/main/hardening_patch.c 2005-09-07 19:04:56.164918656 +0200
3363@@ -0,0 +1,323 @@
3364+/*
3365+ +----------------------------------------------------------------------+
3366+ | Hardening Patch for PHP |
3367+ +----------------------------------------------------------------------+
3368+ | Copyright (c) 2004-2005 Stefan Esser |
3369+ +----------------------------------------------------------------------+
3370+ | This source file is subject to version 2.02 of the PHP license, |
3371+ | that is bundled with this package in the file LICENSE, and is |
3372+ | available at through the world-wide-web at |
3373+ | http://www.php.net/license/2_02.txt. |
3374+ | If you did not receive a copy of the PHP license and are unable to |
3375+ | obtain it through the world-wide-web, please send a note to |
3376+ | license@php.net so we can mail you a copy immediately. |
3377+ +----------------------------------------------------------------------+
3378+ | Author: Stefan Esser <sesser@hardened-php.net> |
3379+ +----------------------------------------------------------------------+
3380+ */
3381+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
3382+
3383+#include "php.h"
3384+
3385+#include <stdio.h>
3386+#include <stdlib.h>
3387+
3388+#if HAVE_UNISTD_H
3389+#include <unistd.h>
3390+#endif
3391+#include "SAPI.h"
3392+#include "php_globals.h"
3393+
3394+#if HARDENING_PATCH
3395+
3396+#ifdef HAVE_SYS_SOCKET_H
3397+#include <sys/socket.h>
3398+#endif
3399+
3400+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
3401+#undef AF_UNIX
3402+#endif
3403+
3404+#if defined(AF_UNIX)
3405+#include <sys/un.h>
3406+#endif
3407+
3408+#define SYSLOG_PATH "/dev/log"
3409+
3410+#include "snprintf.h"
3411+
3412+#include "hardening_patch.h"
3413+
3414+#ifdef ZTS
3415+#include "hardened_globals.h"
3416+int hardened_globals_id;
3417+#else
3418+struct _hardened_globals hardened_globals;
3419+#endif
3420+
3421+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
3422+{
3423+ memset(hardened_globals, 0, sizeof(*hardened_globals));
3424+}
3425+
3426+
3427+PHPAPI void hardened_startup()
3428+{
3429+#ifdef ZTS
3430+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
3431+#else
3432+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
3433+#endif
3434+}
3435+
3436+char *loglevel2string(int loglevel)
3437+{
3438+ switch (loglevel) {
3439+ case S_FILES:
3440+ return "FILES";
3441+ case S_INCLUDE:
3442+ return "INCLUDE";
3443+ case S_MEMORY:
3444+ return "MEMORY";
3445+ case S_MISC:
3446+ return "MISC";
3447+ case S_SQL:
3448+ return "SQL";
3449+ case S_EXECUTOR:
3450+ return "EXECUTOR";
3451+ case S_VARS:
3452+ return "VARS";
3453+ default:
3454+ return "UNKNOWN";
3455+ }
3456+}
3457+
3458+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
3459+{
3460+#if defined(AF_UNIX)
3461+ int s, r, i=0;
3462+ struct sockaddr_un saun;
3463+ char buf[4096+64];
3464+ char error[4096+100];
3465+ char *ip_address;
3466+ char *fname;
3467+ int lineno;
3468+ va_list ap;
3469+ TSRMLS_FETCH();
3470+
3471+ if (EG(hphp_log_use_x_forwarded_for)) {
3472+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
3473+ if (ip_address == NULL) {
3474+ ip_address = "X-FORWARDED-FOR not set";
3475+ }
3476+ } else {
3477+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
3478+ if (ip_address == NULL) {
3479+ ip_address = "REMOTE_ADDR not set";
3480+ }
3481+ }
3482+
3483+
3484+ va_start(ap, fmt);
3485+ ap_php_vsnprintf(error, sizeof(error), fmt, ap);
3486+ va_end(ap);
3487+ while (error[i]) {
3488+ if (error[i] < 32) error[i] = '.';
3489+ i++;
3490+ }
3491+
3492+ if (zend_is_executing(TSRMLS_C)) {
3493+ lineno = zend_get_executed_lineno(TSRMLS_C);
3494+ fname = zend_get_executed_filename(TSRMLS_C);
3495+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
3496+ } else {
3497+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
3498+ if (fname==NULL) {
3499+ fname = "unknown";
3500+ }
3501+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
3502+ }
3503+
3504+ /* Syslog-Logging disabled? */
3505+ if ((EG(hphp_log_syslog) & loglevel)==0) {
3506+ goto log_sapi;
3507+ }
3508+
3509+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
3510+
3511+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
3512+ if (s == -1) {
3513+ goto log_sapi;
3514+ }
3515+
3516+ memset(&saun, 0, sizeof(saun));
3517+ saun.sun_family = AF_UNIX;
3518+ strcpy(saun.sun_path, SYSLOG_PATH);
3519+ /*saun.sun_len = sizeof(saun);*/
3520+
3521+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
3522+ if (r) {
3523+ close(s);
3524+ s = socket(AF_UNIX, SOCK_STREAM, 0);
3525+ if (s == -1) {
3526+ goto log_sapi;
3527+ }
3528+
3529+ memset(&saun, 0, sizeof(saun));
3530+ saun.sun_family = AF_UNIX;
3531+ strcpy(saun.sun_path, SYSLOG_PATH);
3532+ /*saun.sun_len = sizeof(saun);*/
3533+
3534+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
3535+ if (r) {
3536+ close(s);
3537+ goto log_sapi;
3538+ }
3539+ }
3540+ send(s, error, strlen(error), 0);
3541+
3542+ close(s);
3543+
3544+log_sapi:
3545+ /* SAPI Logging activated? */
3546+ if ((EG(hphp_log_syslog) & loglevel)!=0) {
3547+ sapi_module.log_message(buf);
3548+ }
3549+
3550+log_script:
3551+ /* script logging activaed? */
3552+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
3553+ char cmd[8192], *cmdpos, *bufpos;
3554+ FILE *in;
3555+ int space;
3556+
3557+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
3558+ space = sizeof(cmd) - strlen(cmd);
3559+ cmdpos = cmd + strlen(cmd);
3560+ bufpos = buf;
3561+ if (space <= 1) return;
3562+ while (space > 2 && *bufpos) {
3563+ if (*bufpos == '\'') {
3564+ if (space<=5) break;
3565+ *cmdpos++ = '\'';
3566+ *cmdpos++ = '\\';
3567+ *cmdpos++ = '\'';
3568+ *cmdpos++ = '\'';
3569+ bufpos++;
3570+ space-=4;
3571+ } else {
3572+ *cmdpos++ = *bufpos++;
3573+ space--;
3574+ }
3575+ }
3576+ *cmdpos++ = '\'';
3577+ *cmdpos = 0;
3578+
3579+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
3580+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname));
3581+ return;
3582+ }
3583+ /* read and forget the result */
3584+ while (1) {
3585+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
3586+ if (readbytes<=0) {
3587+ break;
3588+ }
3589+ }
3590+ pclose(in);
3591+ }
3592+
3593+#endif
3594+}
3595+#endif
3596+
3597+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
3598+
3599+/* will be replaced later with more compatible method */
3600+PHPAPI unsigned int php_canary()
3601+{
3602+ time_t t;
3603+ unsigned int canary;
3604+ int fd;
3605+
3606+ fd = open("/dev/urandom", 0);
3607+ if (fd != -1) {
3608+ int r = read(fd, &canary, sizeof(canary));
3609+ close(fd);
3610+ if (r == sizeof(canary)) {
3611+ return (canary);
3612+ }
3613+ }
3614+ /* not good but we never want to do this */
3615+ time(&t);
3616+ canary = *(unsigned int *)&t + getpid() << 16;
3617+ return (canary);
3618+}
3619+#endif
3620+
3621+#if HARDENING_PATCH_INC_PROTECT
3622+
3623+PHPAPI int php_is_valid_include(zval *z)
3624+{
3625+ char *filename;
3626+ int len, i;
3627+ TSRMLS_FETCH();
3628+
3629+ /* must be of type string */
3630+ if (z->type != IS_STRING || z->value.str.val == NULL) {
3631+ return (0);
3632+ }
3633+
3634+ /* short cut */
3635+ filename = z->value.str.val;
3636+ len = z->value.str.len;
3637+
3638+ /* 1. must be shorter than MAXPATHLEN */
3639+ if (len > MAXPATHLEN) {
3640+ char *fname = estrndup(filename, len);
3641+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
3642+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
3643+ efree(fname);
3644+ return (0);
3645+ }
3646+
3647+ /* 2. must not be cutted */
3648+ if (len != strlen(filename)) {
3649+ char *fname = estrndup(filename, len);
3650+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
3651+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
3652+ efree(fname);
3653+ return (0);
3654+ }
3655+
3656+ /* 3. must not be a URL */
3657+ if (strstr(filename, "://")) {
3658+ char *fname = estrndup(filename, len);
3659+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
3660+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
3661+ efree(fname);
3662+ return (0);
3663+ }
3664+
3665+ /* 4. must not be an uploaded file */
3666+ if (SG(rfc1867_uploaded_files)) {
3667+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
3668+ php_security_log(S_INCLUDE, "Include filename is an uploaded file");
3669+ return (0);
3670+ }
3671+ }
3672+
3673+ /* passed all tests */
3674+ return (1);
3675+}
3676+
3677+#endif
3678+
3679+/*
3680+ * Local variables:
3681+ * tab-width: 4
3682+ * c-basic-offset: 4
3683+ * End:
3684+ * vim600: sw=4 ts=4 fdm=marker
3685+ * vim<600: sw=4 ts=4
3686+ */
3687diff -Nura php-4.3.11/main/hardening_patch.h hardening-patch-4.3.11-0.4.2/main/hardening_patch.h
3688--- php-4.3.11/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100
3689+++ hardening-patch-4.3.11-0.4.2/main/hardening_patch.h 2005-09-07 19:04:56.165918504 +0200
3690@@ -0,0 +1,46 @@
3691+/*
3692+ +----------------------------------------------------------------------+
3693+ | Hardening Patch for PHP |
3694+ +----------------------------------------------------------------------+
3695+ | Copyright (c) 2004-2005 Stefan Esser |
3696+ +----------------------------------------------------------------------+
3697+ | This source file is subject to version 2.02 of the PHP license, |
3698+ | that is bundled with this package in the file LICENSE, and is |
3699+ | available at through the world-wide-web at |
3700+ | http://www.php.net/license/2_02.txt. |
3701+ | If you did not receive a copy of the PHP license and are unable to |
3702+ | obtain it through the world-wide-web, please send a note to |
3703+ | license@php.net so we can mail you a copy immediately. |
3704+ +----------------------------------------------------------------------+
3705+ | Author: Stefan Esser <sesser@hardened-php.net> |
3706+ +----------------------------------------------------------------------+
3707+ */
3708+
3709+#ifndef HARDENING_PATCH_H
3710+#define HARDENING_PATCH_H
3711+
3712+#include "zend.h"
3713+
3714+#if HARDENING_PATCH
3715+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
3716+PHPAPI void hardened_startup();
3717+#define HARDENING_PATCH_VERSION "0.4.2"
3718+
3719+#endif
3720+
3721+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
3722+PHPAPI unsigned int php_canary();
3723+#endif
3724+
3725+#if HARDENING_PATCH_INC_PROTECT
3726+PHPAPI int php_is_valid_include(zval *z);
3727+#endif
3728+
3729+#endif /* HARDENING_PATCH_H */
3730+
3731+/*
3732+ * Local variables:
3733+ * tab-width: 4
3734+ * c-basic-offset: 4
3735+ * End:
3736+ */
3737diff -Nura php-4.3.11/main/hardening_patch.m4 hardening-patch-4.3.11-0.4.2/main/hardening_patch.m4
3738--- php-4.3.11/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100
3739+++ hardening-patch-4.3.11-0.4.2/main/hardening_patch.m4 2005-09-07 18:41:00.979100064 +0200
3740@@ -0,0 +1,95 @@
3741+dnl
3742+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
3743+dnl
3744+dnl This file contains Hardening Patch for PHP specific autoconf functions.
3745+dnl
3746+
3747+AC_ARG_ENABLE(hardening-patch-mm-protect,
3748+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[
3749+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
3750+],[
3751+ DO_HARDENING_PATCH_MM_PROTECT=yes
3752+])
3753+
3754+AC_ARG_ENABLE(hardening-patch-ll-protect,
3755+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[
3756+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
3757+],[
3758+ DO_HARDENING_PATCH_LL_PROTECT=yes
3759+])
3760+
3761+AC_ARG_ENABLE(hardening-patch-inc-protect,
3762+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[
3763+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
3764+],[
3765+ DO_HARDENING_PATCH_INC_PROTECT=yes
3766+])
3767+
3768+AC_ARG_ENABLE(hardening-patch-fmt-protect,
3769+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[
3770+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
3771+],[
3772+ DO_HARDENING_PATCH_FMT_PROTECT=yes
3773+])
3774+
3775+AC_ARG_ENABLE(hardening-patch-hash-protect,
3776+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[
3777+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
3778+],[
3779+ DO_HARDENING_PATCH_HASH_PROTECT=yes
3780+])
3781+
3782+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
3783+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
3784+
3785+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
3786+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
3787+
3788+AC_MSG_CHECKING(whether to protect include/require statements)
3789+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
3790+
3791+AC_MSG_CHECKING(whether to protect PHP Format String functions)
3792+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
3793+
3794+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
3795+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
3796+
3797+
3798+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3799+
3800+
3801+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
3802+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3803+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
3804+else
3805+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
3806+fi
3807+
3808+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
3809+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3810+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
3811+else
3812+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
3813+fi
3814+
3815+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
3816+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3817+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
3818+else
3819+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
3820+fi
3821+
3822+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
3823+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3824+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
3825+else
3826+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
3827+fi
3828+
3829+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
3830+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3831+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
3832+else
3833+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
3834+fi
3835+
3836diff -Nura php-4.3.11/main/main.c hardening-patch-4.3.11-0.4.2/main/main.c
3837--- php-4.3.11/main/main.c 2005-03-08 22:45:51.000000000 +0100
3838+++ hardening-patch-4.3.11-0.4.2/main/main.c 2005-09-07 18:41:00.980099912 +0200
3839@@ -100,6 +100,10 @@
3840 PHPAPI int core_globals_id;
3841 #endif
3842
3843+#if HARDENING_PATCH
3844+#include "hardened_globals.h"
3845+#endif
3846+
3847 #define ERROR_BUF_LEN 1024
3848
3849 typedef struct {
3850@@ -150,10 +154,33 @@
3851 */
3852 static PHP_INI_MH(OnChangeMemoryLimit)
3853 {
3854+#if HARDENING_PATCH
3855+ long orig_memory_limit;
3856+
3857+ if (entry->modified) {
3858+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
3859+ } else {
3860+ orig_memory_limit = 1<<30;
3861+ }
3862+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
3863+ orig_memory_limit = 1<<30;
3864+ }
3865+#endif
3866 if (new_value) {
3867 PG(memory_limit) = zend_atoi(new_value, new_value_length);
3868+#if HARDENING_PATCH
3869+ if (PG(memory_limit) > orig_memory_limit) {
3870+ PG(memory_limit) = orig_memory_limit;
3871+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
3872+ return FAILURE;
3873+ }
3874+#endif
3875 } else {
3876+#if HARDENING_PATCH
3877+ PG(memory_limit) = orig_memory_limit;
3878+#else
3879 PG(memory_limit) = 1<<30; /* effectively, no limit */
3880+#endif
3881 }
3882 return zend_set_memory_limit(PG(memory_limit));
3883 }
3884@@ -1092,6 +1119,10 @@
3885 tsrm_ls = ts_resource(0);
3886 #endif
3887
3888+#if HARDENING_PATCH
3889+ hardened_startup();
3890+#endif
3891+
3892 sapi_initialize_empty_request(TSRMLS_C);
3893 sapi_activate(TSRMLS_C);
3894
3895@@ -1104,6 +1135,12 @@
3896 php_output_startup();
3897 php_output_activate(TSRMLS_C);
3898
3899+#if HARDENING_PATCH_INC_PROTECT
3900+ zuf.is_valid_include = php_is_valid_include;
3901+#endif
3902+#if HARDENING_PATCH
3903+ zuf.security_log_function = php_security_log;
3904+#endif
3905 zuf.error_function = php_error_cb;
3906 zuf.printf_function = php_printf;
3907 zuf.write_function = php_body_write_wrapper;
3908@@ -1205,6 +1242,10 @@
3909 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
3910 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_SCAN_DIR", PHP_CONFIG_FILE_SCAN_DIR, sizeof(PHP_CONFIG_FILE_SCAN_DIR)-1, CONST_PERSISTENT | CONST_CS);
3911 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
3912+#if HARDENING_PATCH
3913+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
3914+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
3915+#endif
3916 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
3917 php_output_register_constants(TSRMLS_C);
3918 php_rfc1867_register_constants(TSRMLS_C);
3919@@ -1310,7 +1351,7 @@
3920 */
3921 static inline void php_register_server_variables(TSRMLS_D)
3922 {
3923- zval *array_ptr=NULL;
3924+ zval *array_ptr=NULL, *vptr;
3925
3926 ALLOC_ZVAL(array_ptr);
3927 array_init(array_ptr);
3928@@ -1320,6 +1361,16 @@
3929 /* Server variables */
3930 if (sapi_module.register_server_variables) {
3931 sapi_module.register_server_variables(array_ptr TSRMLS_CC);
3932+ if (zend_hash_find(array_ptr->value.ht, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), (void **)&vptr)==SUCCESS) {
3933+ char *str;
3934+ if (vptr->type != IS_STRING) {
3935+ str = "Array";
3936+ } else {
3937+ str = vptr->value.str.val;
3938+ }
3939+ php_security_log(S_VARS, "Attacker tried to overwrite HTTP_RAW_POST_DATA with '%s' through a HTTP header", str);
3940+ zend_hash_del(array_ptr->value.ht, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"));
3941+ }
3942 }
3943
3944 /* PHP Authentication support */
3945diff -Nura php-4.3.11/main/php_config.h.in hardening-patch-4.3.11-0.4.2/main/php_config.h.in
3946--- php-4.3.11/main/php_config.h.in 2005-03-30 16:35:47.000000000 +0200
3947+++ hardening-patch-4.3.11-0.4.2/main/php_config.h.in 2005-09-07 18:41:00.981099760 +0200
3948@@ -839,6 +839,39 @@
3949 /* Enabling BIND8 compatibility for Panther */
3950 #undef BIND_8_COMPAT
3951
3952+/* Hardening-Patch */
3953+#undef HARDENING_PATCH
3954+
3955+/* Memory Manager Protection */
3956+#undef HARDENING_PATCH_MM_PROTECT
3957+
3958+/* Memory Manager Protection */
3959+#undef HARDENING_PATCH_MM_PROTECT
3960+
3961+/* Linked List Protection */
3962+#undef HARDENING_PATCH_LL_PROTECT
3963+
3964+/* Linked List Protection */
3965+#undef HARDENING_PATCH_LL_PROTECT
3966+
3967+/* Include/Require Protection */
3968+#undef HARDENING_PATCH_INC_PROTECT
3969+
3970+/* Include/Require Protection */
3971+#undef HARDENING_PATCH_INC_PROTECT
3972+
3973+/* Fmt String Protection */
3974+#undef HARDENING_PATCH_FMT_PROTECT
3975+
3976+/* Fmt String Protection */
3977+#undef HARDENING_PATCH_FMT_PROTECT
3978+
3979+/* HashTable DTOR Protection */
3980+#undef HARDENING_PATCH_HASH_PROTECT
3981+
3982+/* HashTable DTOR Protection */
3983+#undef HARDENING_PATCH_HASH_PROTECT
3984+
3985 /* Whether you have AOLserver */
3986 #undef HAVE_AOLSERVER
3987
3988@@ -1122,6 +1155,12 @@
3989 /* Define if you have the getaddrinfo function */
3990 #undef HAVE_GETADDRINFO
3991
3992+/* Whether realpath is broken */
3993+#undef PHP_BROKEN_REALPATH
3994+
3995+/* Whether realpath is broken */
3996+#undef PHP_BROKEN_REALPATH
3997+
3998 /* Whether system headers declare timezone */
3999 #undef HAVE_DECLARED_TIMEZONE
4000
4001diff -Nura php-4.3.11/main/php_content_types.c hardening-patch-4.3.11-0.4.2/main/php_content_types.c
4002--- php-4.3.11/main/php_content_types.c 2002-12-31 17:26:14.000000000 +0100
4003+++ hardening-patch-4.3.11-0.4.2/main/php_content_types.c 2005-09-07 18:41:00.981099760 +0200
4004@@ -77,6 +77,7 @@
4005 sapi_register_post_entries(php_post_entries);
4006 sapi_register_default_post_reader(php_default_post_reader);
4007 sapi_register_treat_data(php_default_treat_data);
4008+ sapi_register_input_filter(php_default_input_filter);
4009 return SUCCESS;
4010 }
4011 /* }}} */
4012diff -Nura php-4.3.11/main/php.h hardening-patch-4.3.11-0.4.2/main/php.h
4013--- php-4.3.11/main/php.h 2005-03-08 22:45:51.000000000 +0100
4014+++ hardening-patch-4.3.11-0.4.2/main/php.h 2005-09-07 18:41:00.982099608 +0200
4015@@ -35,11 +35,19 @@
4016 #include "zend_qsort.h"
4017 #include "php_compat.h"
4018
4019+
4020 #include "zend_API.h"
4021
4022 #undef sprintf
4023 #define sprintf php_sprintf
4024
4025+#if HARDENING_PATCH
4026+#if HAVE_REALPATH
4027+#undef realpath
4028+#define realpath php_realpath
4029+#endif
4030+#endif
4031+
4032 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
4033 #undef PHP_DEBUG
4034 #define PHP_DEBUG ZEND_DEBUG
4035@@ -436,6 +444,10 @@
4036 #endif
4037 #endif /* !XtOffsetOf */
4038
4039+#if HARDENING_PATCH
4040+#include "hardening_patch.h"
4041+#endif
4042+
4043 #endif
4044
4045 /*
4046diff -Nura php-4.3.11/main/php_variables.c hardening-patch-4.3.11-0.4.2/main/php_variables.c
4047--- php-4.3.11/main/php_variables.c 2004-10-18 17:08:46.000000000 +0200
4048+++ hardening-patch-4.3.11-0.4.2/main/php_variables.c 2005-09-07 18:41:00.982099608 +0200
4049@@ -211,17 +211,28 @@
4050 while (var) {
4051 val = strchr(var, '=');
4052 if (val) { /* have a value */
4053- int val_len;
4054+ unsigned int val_len, new_val_len;
4055
4056 *val++ = '\0';
4057 php_url_decode(var, strlen(var));
4058 val_len = php_url_decode(val, strlen(val));
4059- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
4060+ val = estrndup(val, val_len);
4061+ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) {
4062+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
4063+ }
4064+ efree(val);
4065 }
4066 var = php_strtok_r(NULL, "&", &strtok_buf);
4067 }
4068 }
4069
4070+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter)
4071+{
4072+ /* TODO: check .ini setting here and apply user-defined input filter */
4073+ *new_val_len = val_len;
4074+ return 1;
4075+}
4076+
4077 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
4078 {
4079 char *res = NULL, *var, *val, *separator=NULL;
4080@@ -299,15 +310,26 @@
4081 while (var) {
4082 val = strchr(var, '=');
4083 if (val) { /* have a value */
4084- int val_len;
4085+ unsigned int val_len, new_val_len;
4086
4087 *val++ = '\0';
4088 php_url_decode(var, strlen(var));
4089 val_len = php_url_decode(val, strlen(val));
4090- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
4091+ val = estrndup(val, val_len);
4092+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
4093+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
4094+ }
4095+ efree(val);
4096 } else {
4097+ unsigned int val_len, new_val_len;
4098+
4099 php_url_decode(var, strlen(var));
4100- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC);
4101+ val_len = 0;
4102+ val = estrndup("", 0);
4103+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
4104+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
4105+ }
4106+ efree(val);
4107 }
4108 var = php_strtok_r(NULL, separator, &strtok_buf);
4109 }
4110diff -Nura php-4.3.11/main/rfc1867.c hardening-patch-4.3.11-0.4.2/main/rfc1867.c
4111--- php-4.3.11/main/rfc1867.c 2005-02-15 01:28:39.000000000 +0100
4112+++ hardening-patch-4.3.11-0.4.2/main/rfc1867.c 2005-09-07 18:41:00.983099456 +0200
4113@@ -127,6 +127,7 @@
4114 #define UPLOAD_ERROR_C 3 /* Partially uploaded */
4115 #define UPLOAD_ERROR_D 4 /* No file uploaded */
4116 #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
4117+#define UPLOAD_ERROR_F 7 /* Filter forbids upload */
4118
4119 void php_rfc1867_register_constants(TSRMLS_D)
4120 {
4121@@ -136,6 +137,7 @@
4122 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_PARTIAL", UPLOAD_ERROR_C, CONST_CS | CONST_PERSISTENT);
4123 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT);
4124 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT);
4125+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT);
4126 }
4127
4128 static void normalize_protected_variable(char *varname TSRMLS_DC)
4129@@ -844,6 +846,7 @@
4130 char buff[FILLUNIT];
4131 char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
4132 int blen=0, wlen=0;
4133+ unsigned long offset;
4134
4135 zend_llist_clean(&header);
4136
4137@@ -891,21 +894,24 @@
4138 if (!filename && param) {
4139
4140 char *value = multipart_buffer_read_body(mbuff TSRMLS_CC);
4141+ unsigned int new_val_len; /* Dummy variable */
4142
4143 if (!value) {
4144 value = estrdup("");
4145 }
4146
4147+ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) {
4148 #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
4149- if (php_mb_encoding_translation(TSRMLS_C)) {
4150- php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
4151- &num_vars, &num_vars_max TSRMLS_CC);
4152- } else {
4153- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4154- }
4155+ if (php_mb_encoding_translation(TSRMLS_C)) {
4156+ php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
4157+ &num_vars, &num_vars_max TSRMLS_CC);
4158+ } else {
4159+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4160+ }
4161 #else
4162- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4163+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4164 #endif
4165+ }
4166 if (!strcasecmp(param, "MAX_FILE_SIZE")) {
4167 max_file_size = atol(value);
4168 }
4169@@ -981,6 +987,11 @@
4170 cancel_upload = UPLOAD_ERROR_D;
4171 }
4172
4173+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
4174+ cancel_upload = UPLOAD_ERROR_F;
4175+ }
4176+
4177+ offset = 0;
4178 while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff) TSRMLS_CC)))
4179 {
4180 if (PG(upload_max_filesize) > 0 && total_bytes > PG(upload_max_filesize)) {
4181@@ -990,6 +1001,11 @@
4182 sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename);
4183 cancel_upload = UPLOAD_ERROR_B;
4184 } else if (blen > 0) {
4185+
4186+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
4187+ cancel_upload = UPLOAD_ERROR_F;
4188+ }
4189+
4190 wlen = fwrite(buff, 1, blen, fp);
4191
4192 if (wlen < blen) {
4193@@ -997,6 +1013,7 @@
4194 cancel_upload = UPLOAD_ERROR_C;
4195 } else {
4196 total_bytes += wlen;
4197+ offset += wlen;
4198 }
4199 }
4200 }
4201@@ -1011,6 +1028,10 @@
4202 }
4203 #endif
4204
4205+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
4206+ cancel_upload = UPLOAD_ERROR_F;
4207+ }
4208+
4209 if (cancel_upload) {
4210 if (temp_filename) {
4211 if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
4212diff -Nura php-4.3.11/main/SAPI.c hardening-patch-4.3.11-0.4.2/main/SAPI.c
4213--- php-4.3.11/main/SAPI.c 2005-02-22 15:46:24.000000000 +0100
4214+++ hardening-patch-4.3.11-0.4.2/main/SAPI.c 2005-09-07 18:41:00.984099304 +0200
4215@@ -831,6 +831,31 @@
4216 return SUCCESS;
4217 }
4218
4219+SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC))
4220+{
4221+ sapi_module.input_filter = input_filter;
4222+ return SUCCESS;
4223+}
4224+
4225+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
4226+{
4227+ sapi_module.pre_upload_filter = pre_upload_filter;
4228+ return SUCCESS;
4229+}
4230+
4231+SAPI_API int sapi_register_upload_content_filter(unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC))
4232+{
4233+ sapi_module.upload_content_filter = upload_content_filter;
4234+ return SUCCESS;
4235+}
4236+
4237+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
4238+{
4239+ sapi_module.post_upload_filter = post_upload_filter;
4240+ return SUCCESS;
4241+}
4242+
4243+
4244
4245 SAPI_API int sapi_flush(TSRMLS_D)
4246 {
4247diff -Nura php-4.3.11/main/SAPI.h hardening-patch-4.3.11-0.4.2/main/SAPI.h
4248--- php-4.3.11/main/SAPI.h 2003-04-09 22:27:55.000000000 +0200
4249+++ hardening-patch-4.3.11-0.4.2/main/SAPI.h 2005-09-07 18:41:00.985099152 +0200
4250@@ -101,9 +101,10 @@
4251 char *current_user;
4252 int current_user_length;
4253
4254- /* this is necessary for CLI module */
4255- int argc;
4256- char **argv;
4257+ /* this is necessary for CLI module */
4258+ int argc;
4259+ char **argv;
4260+
4261 } sapi_request_info;
4262
4263
4264@@ -177,6 +178,10 @@
4265 SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry);
4266 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D));
4267 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
4268+SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC));
4269+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
4270+SAPI_API int sapi_register_upload_content_filter(unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC));
4271+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
4272
4273 SAPI_API int sapi_flush(TSRMLS_D);
4274 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
4275@@ -238,8 +243,15 @@
4276 int (*get_target_uid)(uid_t * TSRMLS_DC);
4277 int (*get_target_gid)(gid_t * TSRMLS_DC);
4278
4279+ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
4280+
4281+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
4282+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
4283+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
4284+
4285 void (*ini_defaults)(HashTable *configuration_hash);
4286 int phpinfo_as_text;
4287+
4288 };
4289
4290
4291@@ -262,16 +274,26 @@
4292
4293 #define SAPI_DEFAULT_MIMETYPE "text/html"
4294 #define SAPI_DEFAULT_CHARSET ""
4295+
4296+#if HARDENING_PATCH
4297+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
4298+#else
4299 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
4300+#endif
4301
4302 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
4303 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
4304
4305 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
4306+#define SAPI_INPUT_FILTER_FUNC(input_filter) unsigned int input_filter(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC)
4307+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
4308+#define SAPI_UPLOAD_CONTENT_FILTER_FUNC(upload_content_filter) unsigned int upload_content_filter(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC)
4309+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
4310
4311 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
4312 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
4313 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data);
4314+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter);
4315
4316 #define STANDARD_SAPI_MODULE_PROPERTIES
4317
4318diff -Nura php-4.3.11/main/snprintf.c hardening-patch-4.3.11-0.4.2/main/snprintf.c
4319--- php-4.3.11/main/snprintf.c 2004-11-16 00:27:26.000000000 +0100
4320+++ hardening-patch-4.3.11-0.4.2/main/snprintf.c 2005-09-07 18:41:00.985099152 +0200
4321@@ -850,7 +850,11 @@
4322
4323
4324 case 'n':
4325+#if HARDENING_PATCH_FMT_PROTECT
4326+ php_security_log(S_MISC, "'n' specifier within format string");
4327+#else
4328 *(va_arg(ap, int *)) = cc;
4329+#endif
4330 break;
4331
4332 /*
4333diff -Nura php-4.3.11/main/spprintf.c hardening-patch-4.3.11-0.4.2/main/spprintf.c
4334--- php-4.3.11/main/spprintf.c 2003-09-29 03:09:36.000000000 +0200
4335+++ hardening-patch-4.3.11-0.4.2/main/spprintf.c 2005-09-07 18:41:00.986099000 +0200
4336@@ -531,7 +531,11 @@
4337
4338
4339 case 'n':
4340+#if HARDENING_PATCH_FMT_PROTECT
4341+ php_security_log(S_MISC, "'n' specifier within format string");
4342+#else
4343 *(va_arg(ap, int *)) = cc;
4344+#endif
4345 break;
4346
4347 /*
4348diff -Nura php-4.3.11/pear/go-pear-list.php hardening-patch-4.3.11-0.4.2/pear/go-pear-list.php
4349--- php-4.3.11/pear/go-pear-list.php 2005-03-18 02:58:20.000000000 +0100
4350+++ hardening-patch-4.3.11-0.4.2/pear/go-pear-list.php 2005-09-07 19:04:56.234908016 +0200
4351@@ -8,7 +8,7 @@
4352 $packages = array(
4353 // required packages for the installer
4354 "PEAR" => "1.3.5",
4355-"XML_RPC" => "1.2.2",
4356+"XML_RPC" => "1.4.0",
4357 "Console_Getopt" => "1.2",
4358 "Archive_Tar" => "1.3.1",
4359
4360diff -Nura php-4.3.11/pear/packages/XML_RPC-1.2.2.tar hardening-patch-4.3.11-0.4.2/pear/packages/XML_RPC-1.2.2.tar
4361--- php-4.3.11/pear/packages/XML_RPC-1.2.2.tar 2005-03-28 19:02:28.000000000 +0200
4362+++ hardening-patch-4.3.11-0.4.2/pear/packages/XML_RPC-1.2.2.tar 1970-01-01 01:00:00.000000000 +0100
4363@@ -1,3393 +0,0 @@
4364-package2.xml
4365-<package packagerversion="1.4.0a1" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
4366- <name>XML_RPC</name>
4367- <channel>pear.php.net</channel>
4368- <summary>PHP implementation of the XML-RPC protocol</summary>
4369- <description>A PEAR-ified version of Useful Inc&apos;s XML-RPC for PHP.
4370-
4371-It has support for HTTP/HTTPS transport, proxies and authentication.</description>
4372- <lead>
4373- <name>Stig Bakken</name>
4374- <user>ssb</user>
4375- <email>stig@php.net</email>
4376- <active>no</active>
4377- </lead>
4378- <lead>
4379- <name>Daniel Convissor</name>
4380- <user>danielc</user>
4381- <email>danielc@php.net</email>
4382- <active>yes</active>
4383- </lead>
4384- <date>2005-03-07</date>
4385- <time>12:54:49</time>
4386- <version>
4387- <release>1.2.2</release>
4388- <api>1.2.0</api>
4389- </version>
4390- <stability>
4391- <release>stable</release>
4392- <api>stable</api>
4393- </stability>
4394- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4395- <notes>* When using a proxy, add the protocol to the Request-URI, making it an &quot;absoluteURI&quot; as per the HTTP 1.0 spec. Bug 3679.</notes>
4396- <contents>
4397- <dir name="/">
4398- <file md5sum="9aca4434f486b517a75c7f2878fb1e9c" name="tests/protoport.php" role="test">
4399- <tasks:replace from="@package_version@" to="version" type="package-info" />
4400- </file>
4401- <file md5sum="49639b76a2296777a1dfa076ae41024a" name="tests/test_Dump.php" role="test">
4402- <tasks:replace from="@package_version@" to="version" type="package-info" />
4403- </file>
4404- <file baseinstalldir="XML/RPC" md5sum="2fb141b1f8927ef27ab0c222f2117d77" name="Dump.php" role="php">
4405- <tasks:replace from="@package_version@" to="version" type="package-info" />
4406- </file>
4407- <file baseinstalldir="XML" md5sum="fbfa3c674175786cc95893cc5192d910" name="RPC.php" role="php">
4408- <tasks:replace from="@package_version@" to="version" type="package-info" />
4409- </file>
4410- <file baseinstalldir="XML/RPC" md5sum="6fc2498def65f09d4ae535fa5f987f62" name="Server.php" role="php">
4411- <tasks:replace from="@package_version@" to="version" type="package-info" />
4412- </file>
4413- </dir>
4414- </contents>
4415- <compatible>
4416- <name>PEAR</name>
4417- <channel>pear.php.net</channel>
4418- <min>1.4.0a1</min>
4419- <max>1.4.0a4</max>
4420- </compatible>
4421- <dependencies>
4422- <required>
4423- <php>
4424- <min>4.2.0</min>
4425- <max>6.0.0</max>
4426- </php>
4427- <pearinstaller>
4428- <min>1.4.0a1</min>
4429- </pearinstaller>
4430- </required>
4431- </dependencies>
4432- <phprelease />
4433- <changelog>
4434- <release>
4435- <version>
4436- <release>1.2.1</release>
4437- <api>1.2.0</api>
4438- </version>
4439- <stability>
4440- <release>stable</release>
4441- <api>stable</api>
4442- </stability>
4443- <date>2005-03-01</date>
4444- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4445- <notes>* Add isset() check before examining the dispatch map. Bug 3658.</notes>
4446- </release>
4447- <release>
4448- <version>
4449- <release>1.2.0</release>
4450- <api>1.2.0</api>
4451- </version>
4452- <stability>
4453- <release>stable</release>
4454- <api>stable</api>
4455- </stability>
4456- <date>2005-02-27</date>
4457- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4458- <notes>* Provide the &quot;stable&quot; release.
4459-* Add package2.xml for compatibility with PEAR 1.4.0.
4460-* For changes since 1.1.0, see the changelogs for the various RC releases.</notes>
4461- </release>
4462- <release>
4463- <version>
4464- <release>1.2.0RC7</release>
4465- <api>1.2.0RC7</api>
4466- </version>
4467- <stability>
4468- <release>beta</release>
4469- <api>beta</api>
4470- </stability>
4471- <date>2005-02-22</date>
4472- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4473- <notes>* Add the setSendEncoding() method and $send_encoding
4474- property to XML_RPC_Message. Request 3537.
4475-* Allow class methods to be mapped using either syntax:
4476- &apos;function&apos; =&gt; &apos;hello::sayHello&apos;,
4477- or
4478- &apos;function&apos; =&gt; array(&apos;hello&apos;, &apos;sayhello&apos;),
4479- Bug 3363.
4480-* Use 8192 instead of 32768 for bytes in fread()
4481- in parseResponseFile(). Bug 3340.</notes>
4482- </release>
4483- <release>
4484- <version>
4485- <release>1.2.0RC6</release>
4486- <api>1.2.0RC6</api>
4487- </version>
4488- <stability>
4489- <release>beta</release>
4490- <api>beta</api>
4491- </stability>
4492- <date>2005-01-25</date>
4493- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4494- <notes>* Don&apos;t put the protocol in the Host field of the POST data. (danielc)</notes>
4495- </release>
4496- <release>
4497- <version>
4498- <release>1.2.0RC5</release>
4499- <api>1.2.0RC5</api>
4500- </version>
4501- <stability>
4502- <release>beta</release>
4503- <api>beta</api>
4504- </stability>
4505- <date>2005-01-24</date>
4506- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4507- <notes>* If $port is 443 but a protocol isn&apos;t specified in $server, assume ssl:// is the protocol.</notes>
4508- </release>
4509- <release>
4510- <version>
4511- <release>1.2.0RC4</release>
4512- <api>1.2.0RC4</api>
4513- </version>
4514- <stability>
4515- <release>beta</release>
4516- <api>beta</api>
4517- </stability>
4518- <date>2005-01-24</date>
4519- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4520- <notes>* When a connection attempt fails, have the method return 0. (danielc)
4521-* Move the protocol/port checking/switching and the property settings from sendPayloadHTTP10() to the XML_RPC_Client constructor. (danielc)
4522-* Add tests for setting the client properties. (danielc)
4523-* Remove $GLOBALS[&apos;XML_RPC_twoslash&apos;] since it&apos;s not used. (danielc)
4524-* Bundle the tests with the package. (danielc)</notes>
4525- </release>
4526- <release>
4527- <version>
4528- <release>1.2.0RC3</release>
4529- <api>1.2.0RC3</api>
4530- </version>
4531- <stability>
4532- <release>beta</release>
4533- <api>beta</api>
4534- </stability>
4535- <date>2005-01-19</date>
4536- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4537- <notes>* ssl uses port 443, not 445.</notes>
4538- </release>
4539- <release>
4540- <version>
4541- <release>1.2.0RC2</release>
4542- <api>1.2.0RC2</api>
4543- </version>
4544- <stability>
4545- <release>beta</release>
4546- <api>beta</api>
4547- </stability>
4548- <date>2005-01-11</date>
4549- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4550- <notes>* Handle ssl:// in the $server string. (danielc)
4551-* Also default to port 445 for ssl:// requests as well. (danielc)
4552-* Enhance debugging in the server. (danielc)</notes>
4553- </release>
4554- <release>
4555- <version>
4556- <release>1.2.0RC1</release>
4557- <api>1.2.0RC1</api>
4558- </version>
4559- <stability>
4560- <release>beta</release>
4561- <api>beta</api>
4562- </stability>
4563- <date>2004-12-30</date>
4564- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4565- <notes>* Make things work with SSL. Bug 2489. (nkukard lbsd net)
4566-* Allow array function callbacks (Matt Kane)
4567-* Some minor speed-ups (Matt Kane)
4568-* Add Dump.php to the package (Christian Weiske)
4569-* Replace all line endings with \r\n. Had only done replacements on \n. Bug 2521. (danielc)
4570-* Silence fsockopen() errors. Bug 1714. (danielc)
4571-* Encode empty arrays as an array. Bug 1493. (danielc)
4572-* Eliminate undefined index notice when submitting empty arrays to XML_RPC_Encode(). Bug 1819. (danielc)
4573-* Speed up check for enumerated arrays in XML_RPC_Encode(). (danielc)
4574-* Prepend &quot;XML_RPC_&quot; to ERROR_NON_NUMERIC_FOUND, eliminating problem when eval()&apos;ing error messages. (danielc)
4575-* Use XML_RPC_Base::raiseError() instead of PEAR::raiseError() in XML_RPC_ee() because PEAR.php is lazy loaded. (danielc)
4576-* Allow raiseError() to be called statically. (danielc)
4577-* Stop double escaping of character entities. Bug 987. (danielc)
4578- NOTICE: the following have been removed:
4579- * XML_RPC_dh()
4580- * $GLOBALS[&apos;XML_RPC_entities&apos;]
4581- * XML_RPC_entity_decode()
4582- * XML_RPC_lookup_entity()
4583-* Determine the XML&apos;s encoding via the encoding attribute in the XML declaration. Bug 52. (danielc)</notes>
4584- </release>
4585- <release>
4586- <version>
4587- <release>1.1.0</release>
4588- <api>1.1.0</api>
4589- </version>
4590- <stability>
4591- <release>stable</release>
4592- <api>stable</api>
4593- </stability>
4594- <date>2004-03-15</date>
4595- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4596- <notes>* Added support for sequential arrays to XML_RPC_encode() (mroch)
4597-* Cleaned up new XML_RPC_encode() changes a bit (mroch, pierre)
4598-* Remove &quot;require_once &apos;PEAR.php&apos;&quot;, include only when needed to raise an error
4599-* Replace echo and error_log() with raiseError() (mroch)
4600-* Make all classes extend XML_RPC_Base, which will handle common functions (mroch)
4601-* be tolerant of junk after methodResponse (Luca Mariano, mroch)
4602-* Silent notice even in the error log (pierre)
4603-* fix include of shared xml extension on win32 (pierre)</notes>
4604- </release>
4605- <release>
4606- <version>
4607- <release>1.0.4</release>
4608- <api>1.0.4</api>
4609- </version>
4610- <stability>
4611- <release>stable</release>
4612- <api>stable</api>
4613- </stability>
4614- <date>2002-10-02</date>
4615- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4616- <notes>* added HTTP proxy authorization support (thanks to Arnaud Limbourg)</notes>
4617- </release>
4618- <release>
4619- <version>
4620- <release>1.0.3</release>
4621- <api>1.0.3</api>
4622- </version>
4623- <stability>
4624- <release>stable</release>
4625- <api>stable</api>
4626- </stability>
4627- <date>2002-05-19</date>
4628- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4629- <notes>* fix bug when parsing responses with boolean types</notes>
4630- </release>
4631- <release>
4632- <version>
4633- <release>1.0.2</release>
4634- <api>1.0.2</api>
4635- </version>
4636- <stability>
4637- <release>stable</release>
4638- <api>stable</api>
4639- </stability>
4640- <date>2002-04-16</date>
4641- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4642- <notes>* E_ALL fixes
4643-* fix HTTP response header parsing</notes>
4644- </release>
4645- <release>
4646- <version>
4647- <release>1.0.1</release>
4648- <api>1.0.1</api>
4649- </version>
4650- <stability>
4651- <release>stable</release>
4652- <api>stable</api>
4653- </stability>
4654- <date>2001-09-25</date>
4655- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4656- <notes>This is a PEAR-ified version of Useful Inc&apos;s 1.0.1 release.
4657-Includes an urgent security fix identified by Dan Libby &lt;dan@libby.com&gt;.</notes>
4658- </release>
4659- </changelog>
4660-</package>
4661-
4662-/**
4663- * Tests that properties of XML_RPC_Client get properly set
4664- *
4665- * Any individual tests that fail will have their name, expected result
4666- * and actual result printed out. So seeing no output when executing
4667- * this file is a good thing.
4668- *
4669- * Can be run via CLI or a web server.
4670- *
4671- * PHP versions 4 and 5
4672- *
4673- * LICENSE: This source file is subject to version 3.0 of the PHP license
4674- * that is available through the world-wide-web at the following URI:
4675- * http://www.php.net/license/3_0.txt. If you did not receive a copy of
4676- * the PHP License and are unable to obtain it through the web, please
4677- * send a note to license@php.net so we can mail you a copy immediately.
4678- *
4679- * @category Web Services
4680- * @package XML_RPC
4681- * @author Daniel Convissor <danielc@php.net>
4682- * @copyright 2005 The PHP Group
4683- * @license http://www.php.net/license/3_0.txt PHP License
4684- * @version CVS: $Id: protoport.php,v 1.4 2005/01/24 17:48:47 danielc Exp $
4685- * @link http://pear.php.net/package/XML_RPC
4686- * @since File available since Release 1.2
4687- */
4688-
4689-/*
4690- * If the package version number is found in the left hand
4691- * portion of the if() expression below, that means this file has
4692- * come from the PEAR installer. Therefore, let's test the
4693- * installed version of XML_RPC which should be in the include path.
4694- *
4695- * If the version has not been substituted in the if() expression,
4696- * this file has likely come from a CVS checkout or a .tar file.
4697- * Therefore, we'll assume the tests should use the version of
4698- * XML_RPC that has come from there as well.
4699- */
4700-if ('1.2.2' != '@'.'package_version'.'@') {
4701- /**
4702- * Get the needed class from the PEAR installation
4703- */
4704- require_once 'XML/RPC.php';
4705-} else {
4706- /**
4707- * Get the needed class from the parent directory
4708- */
4709- require_once '../RPC.php';
4710-}
4711-
4712-/**
4713- * Compare the test result to the expected result
4714- *
4715- * If the test fails, echo out the results.
4716- *
4717- * @param array $expect the array of object properties you expect
4718- * from the test
4719- * @param object $actual the object results from the test
4720- * @param string $test_name the name of the test
4721- *
4722- * @return void
4723- */
4724-function compare($expect, $actual, $test_name) {
4725- $actual = get_object_vars($actual);
4726- if (count(array_diff($actual, $expect))) {
4727- echo "$test_name failed.\nExpect: ";
4728- print_r($expect);
4729- echo "Actual: ";
4730- print_r($actual);
4731- echo "\n";
4732- }
4733-}
4734-
4735-if (php_sapi_name() != 'cli') {
4736- echo "<pre>\n";
4737-}
4738-
4739-
4740-$x = array(
4741- 'path' => 'thepath',
4742- 'server' => 'theserver',
4743- 'protocol' => 'http://',
4744- 'port' => 80,
4745- 'proxy' => '',
4746- 'proxy_protocol' => 'http://',
4747- 'proxy_port' => 8080,
4748- 'proxy_user' => '',
4749- 'proxy_pass' => '',
4750- 'errno' => 0,
4751- 'errstring' => '',
4752- 'debug' => 0,
4753- 'username' => '',
4754- 'password' => '',
4755-);
4756-$c = new XML_RPC_Client('thepath', 'theserver');
4757-compare($x, $c, 'defaults');
4758-
4759-$x = array(
4760- 'path' => 'thepath',
4761- 'server' => 'theserver',
4762- 'protocol' => 'http://',
4763- 'port' => 80,
4764- 'proxy' => '',
4765- 'proxy_protocol' => 'http://',
4766- 'proxy_port' => 8080,
4767- 'proxy_user' => '',
4768- 'proxy_pass' => '',
4769- 'errno' => 0,
4770- 'errstring' => '',
4771- 'debug' => 0,
4772- 'username' => '',
4773- 'password' => '',
4774-);
4775-$c = new XML_RPC_Client('thepath', 'http://theserver');
4776-compare($x, $c, 'defaults with http');
4777-
4778-$x = array(
4779- 'path' => 'thepath',
4780- 'server' => 'theserver',
4781- 'protocol' => 'ssl://',
4782- 'port' => 443,
4783- 'proxy' => '',
4784- 'proxy_protocol' => 'http://',
4785- 'proxy_port' => 8080,
4786- 'proxy_user' => '',
4787- 'proxy_pass' => '',
4788- 'errno' => 0,
4789- 'errstring' => '',
4790- 'debug' => 0,
4791- 'username' => '',
4792- 'password' => '',
4793-);
4794-$c = new XML_RPC_Client('thepath', 'https://theserver');
4795-compare($x, $c, 'defaults with https');
4796-
4797-$x = array(
4798- 'path' => 'thepath',
4799- 'server' => 'theserver',
4800- 'protocol' => 'ssl://',
4801- 'port' => 443,
4802- 'proxy' => '',
4803- 'proxy_protocol' => 'http://',
4804- 'proxy_port' => 8080,
4805- 'proxy_user' => '',
4806- 'proxy_pass' => '',
4807- 'errno' => 0,
4808- 'errstring' => '',
4809- 'debug' => 0,
4810- 'username' => '',
4811- 'password' => '',
4812-);
4813-$c = new XML_RPC_Client('thepath', 'ssl://theserver');
4814-compare($x, $c, 'defaults with ssl');
4815-
4816-
4817-$x = array(
4818- 'path' => 'thepath',
4819- 'server' => 'theserver',
4820- 'protocol' => 'http://',
4821- 'port' => 65,
4822- 'proxy' => '',
4823- 'proxy_protocol' => 'http://',
4824- 'proxy_port' => 8080,
4825- 'proxy_user' => '',
4826- 'proxy_pass' => '',
4827- 'errno' => 0,
4828- 'errstring' => '',
4829- 'debug' => 0,
4830- 'username' => '',
4831- 'password' => '',
4832-);
4833-$c = new XML_RPC_Client('thepath', 'theserver', 65);
4834-compare($x, $c, 'port 65');
4835-
4836-$x = array(
4837- 'path' => 'thepath',
4838- 'server' => 'theserver',
4839- 'protocol' => 'http://',
4840- 'port' => 65,
4841- 'proxy' => '',
4842- 'proxy_protocol' => 'http://',
4843- 'proxy_port' => 8080,
4844- 'proxy_user' => '',
4845- 'proxy_pass' => '',
4846- 'errno' => 0,
4847- 'errstring' => '',
4848- 'debug' => 0,
4849- 'username' => '',
4850- 'password' => '',
4851-);
4852-$c = new XML_RPC_Client('thepath', 'http://theserver', 65);
4853-compare($x, $c, 'port 65 with http');
4854-
4855-$x = array(
4856- 'path' => 'thepath',
4857- 'server' => 'theserver',
4858- 'protocol' => 'ssl://',
4859- 'port' => 65,
4860- 'proxy' => '',
4861- 'proxy_protocol' => 'http://',
4862- 'proxy_port' => 8080,
4863- 'proxy_user' => '',
4864- 'proxy_pass' => '',
4865- 'errno' => 0,
4866- 'errstring' => '',
4867- 'debug' => 0,
4868- 'username' => '',
4869- 'password' => '',
4870-);
4871-$c = new XML_RPC_Client('thepath', 'https://theserver', 65);
4872-compare($x, $c, 'port 65 with https');
4873-
4874-$x = array(
4875- 'path' => 'thepath',
4876- 'server' => 'theserver',
4877- 'protocol' => 'ssl://',
4878- 'port' => 65,
4879- 'proxy' => '',
4880- 'proxy_protocol' => 'http://',
4881- 'proxy_port' => 8080,
4882- 'proxy_user' => '',
4883- 'proxy_pass' => '',
4884- 'errno' => 0,
4885- 'errstring' => '',
4886- 'debug' => 0,
4887- 'username' => '',
4888- 'password' => '',
4889-);
4890-$c = new XML_RPC_Client('thepath', 'ssl://theserver', 65);
4891-compare($x, $c, 'port 65 with ssl');
4892-
4893-
4894-$x = array(
4895- 'path' => 'thepath',
4896- 'server' => 'theserver',
4897- 'protocol' => 'http://',
4898- 'port' => 80,
4899- 'proxy' => 'theproxy',
4900- 'proxy_protocol' => 'http://',
4901- 'proxy_port' => 8080,
4902- 'proxy_user' => '',
4903- 'proxy_pass' => '',
4904- 'errno' => 0,
4905- 'errstring' => '',
4906- 'debug' => 0,
4907- 'username' => '',
4908- 'password' => '',
4909-);
4910-$c = new XML_RPC_Client('thepath', 'theserver', 0,
4911- 'theproxy');
4912-compare($x, $c, 'defaults proxy');
4913-
4914-$x = array(
4915- 'path' => 'thepath',
4916- 'server' => 'theserver',
4917- 'protocol' => 'http://',
4918- 'port' => 80,
4919- 'proxy' => 'theproxy',
4920- 'proxy_protocol' => 'http://',
4921- 'proxy_port' => 8080,
4922- 'proxy_user' => '',
4923- 'proxy_pass' => '',
4924- 'errno' => 0,
4925- 'errstring' => '',
4926- 'debug' => 0,
4927- 'username' => '',
4928- 'password' => '',
4929-);
4930-$c = new XML_RPC_Client('thepath', 'http://theserver', 0,
4931- 'http://theproxy');
4932-compare($x, $c, 'defaults with http proxy');
4933-
4934-$x = array(
4935- 'path' => 'thepath',
4936- 'server' => 'theserver',
4937- 'protocol' => 'ssl://',
4938- 'port' => 443,
4939- 'proxy' => 'theproxy',
4940- 'proxy_protocol' => 'ssl://',
4941- 'proxy_port' => 443,
4942- 'proxy_user' => '',
4943- 'proxy_pass' => '',
4944- 'errno' => 0,
4945- 'errstring' => '',
4946- 'debug' => 0,
4947- 'username' => '',
4948- 'password' => '',
4949-);
4950-$c = new XML_RPC_Client('thepath', 'https://theserver', 0,
4951- 'https://theproxy');
4952-compare($x, $c, 'defaults with https proxy');
4953-
4954-$x = array(
4955- 'path' => 'thepath',
4956- 'server' => 'theserver',
4957- 'protocol' => 'ssl://',
4958- 'port' => 443,
4959- 'proxy' => 'theproxy',
4960- 'proxy_protocol' => 'ssl://',
4961- 'proxy_port' => 443,
4962- 'proxy_user' => '',
4963- 'proxy_pass' => '',
4964- 'errno' => 0,
4965- 'errstring' => '',
4966- 'debug' => 0,
4967- 'username' => '',
4968- 'password' => '',
4969-);
4970-$c = new XML_RPC_Client('thepath', 'ssl://theserver', 0,
4971- 'ssl://theproxy');
4972-compare($x, $c, 'defaults with ssl proxy');
4973-
4974-
4975-$x = array(
4976- 'path' => 'thepath',
4977- 'server' => 'theserver',
4978- 'protocol' => 'http://',
4979- 'port' => 65,
4980- 'proxy' => 'theproxy',
4981- 'proxy_protocol' => 'http://',
4982- 'proxy_port' => 6565,
4983- 'proxy_user' => '',
4984- 'proxy_pass' => '',
4985- 'errno' => 0,
4986- 'errstring' => '',
4987- 'debug' => 0,
4988- 'username' => '',
4989- 'password' => '',
4990-);
4991-$c = new XML_RPC_Client('thepath', 'theserver', 65,
4992- 'theproxy', 6565);
4993-compare($x, $c, 'port 65 proxy 6565');
4994-
4995-$x = array(
4996- 'path' => 'thepath',
4997- 'server' => 'theserver',
4998- 'protocol' => 'http://',
4999- 'port' => 65,
5000- 'proxy' => 'theproxy',
5001- 'proxy_protocol' => 'http://',
5002- 'proxy_port' => 6565,
5003- 'proxy_user' => '',
5004- 'proxy_pass' => '',
5005- 'errno' => 0,
5006- 'errstring' => '',
5007- 'debug' => 0,
5008- 'username' => '',
5009- 'password' => '',
5010-);
5011-$c = new XML_RPC_Client('thepath', 'http://theserver', 65,
5012- 'http://theproxy', 6565);
5013-compare($x, $c, 'port 65 with http proxy 6565');
5014-
5015-$x = array(
5016- 'path' => 'thepath',
5017- 'server' => 'theserver',
5018- 'protocol' => 'ssl://',
5019- 'port' => 65,
5020- 'proxy' => 'theproxy',
5021- 'proxy_protocol' => 'ssl://',
5022- 'proxy_port' => 6565,
5023- 'proxy_user' => '',
5024- 'proxy_pass' => '',
5025- 'errno' => 0,
5026- 'errstring' => '',
5027- 'debug' => 0,
5028- 'username' => '',
5029- 'password' => '',
5030-);
5031-$c = new XML_RPC_Client('thepath', 'https://theserver', 65,
5032- 'https://theproxy', 6565);
5033-compare($x, $c, 'port 65 with https proxy 6565');
5034-
5035-$x = array(
5036- 'path' => 'thepath',
5037- 'server' => 'theserver',
5038- 'protocol' => 'ssl://',
5039- 'port' => 65,
5040- 'proxy' => 'theproxy',
5041- 'proxy_protocol' => 'ssl://',
5042- 'proxy_port' => 6565,
5043- 'proxy_user' => '',
5044- 'proxy_pass' => '',
5045- 'errno' => 0,
5046- 'errstring' => '',
5047- 'debug' => 0,
5048- 'username' => '',
5049- 'password' => '',
5050-);
5051-$c = new XML_RPC_Client('thepath', 'ssl://theserver', 65,
5052- 'ssl://theproxy', 6565);
5053-compare($x, $c, 'port 65 with ssl proxy 6565');
5054-
5055-
5056-$x = array(
5057- 'path' => 'thepath',
5058- 'server' => 'theserver',
5059- 'protocol' => 'ssl://',
5060- 'port' => 443,
5061- 'proxy' => 'theproxy',
5062- 'proxy_protocol' => 'ssl://',
5063- 'proxy_port' => 443,
5064- 'proxy_user' => '',
5065- 'proxy_pass' => '',
5066- 'errno' => 0,
5067- 'errstring' => '',
5068- 'debug' => 0,
5069- 'username' => '',
5070- 'password' => '',
5071-);
5072-$c = new XML_RPC_Client('thepath', 'theserver', 443,
5073- 'theproxy', 443);
5074-compare($x, $c, 'port 443 no protocol and proxy port 443 no protocol');
5075-
5076-$x = array(
5077- 'path' => 'thepath',
5078- 'server' => 'theserver',
5079- 'protocol' => 'http://',
5080- 'port' => 80,
5081- 'proxy' => 'theproxy',
5082- 'proxy_protocol' => 'ssl://',
5083- 'proxy_port' => 6565,
5084- 'proxy_user' => '',
5085- 'proxy_pass' => '',
5086- 'errno' => 0,
5087- 'errstring' => '',
5088- 'debug' => 0,
5089- 'username' => '',
5090- 'password' => '',
5091-);
5092-$c = new XML_RPC_Client('thepath', 'theserver', 0,
5093- 'ssl://theproxy', 6565);
5094-compare($x, $c, 'port 443 no protocol and proxy port 443 no protocol');
5095-
5096-
5097-/*
5098- * If the package version number is found in the left hand
5099- * portion of the if() expression below, that means this file has
5100- * come from the PEAR installer. Therefore, let's test the
5101- * installed version of XML_RPC which should be in the include path.
5102- *
5103- * If the version has not been substituted in the if() expression,
5104- * this file has likely come from a CVS checkout or a .tar file.
5105- * Therefore, we'll assume the tests should use the version of
5106- * XML_RPC that has come from there as well.
5107- */
5108-if ('1.2.2' != '@'.'package_version'.'@') {
5109- /**
5110- * Get the needed class from the PEAR installation
5111- */
5112- require_once 'XML/RPC/Dump.php';
5113-} else {
5114- /**
5115- * Get the needed class from the parent directory
5116- */
5117- require_once '../Dump.php';
5118-}
5119-
5120-$val = new XML_RPC_Value(array(
5121- 'title' =>new XML_RPC_Value('das ist der Titel', 'string'),
5122- 'startDate'=>new XML_RPC_Value(mktime(0,0,0,13,11,2004), 'dateTime.iso8601'),
5123- 'endDate' =>new XML_RPC_Value(mktime(0,0,0,15,11,2004), 'dateTime.iso8601'),
5124- 'error' =>'string',
5125- 'arkey' => new XML_RPC_Value( array(
5126- new XML_RPC_Value('simple string'),
5127- new XML_RPC_Value(12345, 'int')
5128- ), 'array')
5129- )
5130- ,'struct');
5131-
5132-XML_RPC_Dump($val);
5133-
5134-echo '==============' . "\r\n";
5135-$val2 = new XML_RPC_Value(44353, 'int');
5136-XML_RPC_Dump($val2);
5137-
5138-echo '==============' . "\r\n";
5139-$val3 = new XML_RPC_Value('this should be a string', 'string');
5140-XML_RPC_Dump($val3);
5141-
5142-echo '==============' . "\r\n";
5143-$val4 = new XML_RPC_Value(true, 'boolean');
5144-XML_RPC_Dump($val4);
5145-
5146-
5147-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
5148-
5149-/**
5150- * Function and class to dump XML_RPC_Value objects in a nice way
5151- *
5152- * Should be helpful as a normal var_dump(..) displays all internals which
5153- * doesn't really give you an overview due to too much information.
5154- *
5155- * @category Web Services
5156- * @package XML_RPC
5157- * @author Christian Weiske <cweiske@php.net>
5158- * @version CVS: $Id: Dump.php,v 1.7 2005/01/24 03:47:55 danielc Exp $
5159- * @link http://pear.php.net/package/XML_RPC
5160- */
5161-
5162-
5163-/**
5164- * Pull in the XML_RPC class
5165- */
5166-require_once 'XML/RPC.php';
5167-
5168-
5169-/**
5170- * Generates the dump of the XML_RPC_Value and echoes it
5171- *
5172- * @param object $value the XML_RPC_Value object to dump
5173- *
5174- * @return void
5175- */
5176-function XML_RPC_Dump($value)
5177-{
5178- $dumper = new XML_RPC_Dump();
5179- echo $dumper->generateDump($value);
5180-}
5181-
5182-
5183-/**
5184- * Class which generates a dump of a XML_RPC_Value object
5185- *
5186- * @category Web Services
5187- * @package XML_RPC
5188- * @author Christian Weiske <cweiske@php.net>
5189- * @version Release: 1.2.2
5190- * @link http://pear.php.net/package/XML_RPC
5191- */
5192-class XML_RPC_Dump
5193-{
5194- /**
5195- * The indentation array cache
5196- * @var array
5197- */
5198- var $arIndent = array();
5199-
5200- /**
5201- * The spaces used for indenting the XML
5202- * @var string
5203- */
5204- var $strBaseIndent = ' ';
5205-
5206- /**
5207- * Returns the dump in XML format without printing it out
5208- *
5209- * @param object $value the XML_RPC_Value object to dump
5210- * @param int $nLevel the level of indentation
5211- *
5212- * @return string the dump
5213- */
5214- function generateDump($value, $nLevel = 0)
5215- {
5216- if (!is_object($value) && get_class($value) != 'xml_rpc_value') {
5217- require_once 'PEAR.php';
5218- PEAR::raiseError('Tried to dump non-XML_RPC_Value variable' . "\r\n",
5219- 0, PEAR_ERROR_PRINT);
5220- if (is_object($value)) {
5221- $strType = get_class($value);
5222- } else {
5223- $strType = gettype($value);
5224- }
5225- return $this->getIndent($nLevel) . 'NOT A XML_RPC_Value: '
5226- . $strType . "\r\n";
5227- }
5228-
5229- switch ($value->kindOf()) {
5230- case 'struct':
5231- $ret = $this->genStruct($value, $nLevel);
5232- break;
5233- case 'array':
5234- $ret = $this->genArray($value, $nLevel);
5235- break;
5236- case 'scalar':
5237- $ret = $this->genScalar($value->scalarval(), $nLevel);
5238- break;
5239- default:
5240- require_once 'PEAR.php';
5241- PEAR::raiseError('Illegal type "' . $value->kindOf()
5242- . '" in XML_RPC_Value' . "\r\n", 0,
5243- PEAR_ERROR_PRINT);
5244- }
5245-
5246- return $ret;
5247- }
5248-
5249- /**
5250- * Returns the scalar value dump
5251- *
5252- * @param object $value the scalar XML_RPC_Value object to dump
5253- * @param int $nLevel the level of indentation
5254- *
5255- * @return string Dumped version of the scalar value
5256- */
5257- function genScalar($value, $nLevel)
5258- {
5259- if (gettype($value) == 'object') {
5260- $strClass = ' ' . get_class($value);
5261- } else {
5262- $strClass = '';
5263- }
5264- return $this->getIndent($nLevel) . gettype($value) . $strClass
5265- . ' ' . $value . "\r\n";
5266- }
5267-
5268- /**
5269- * Returns the dump of a struct
5270- *
5271- * @param object $value the struct XML_RPC_Value object to dump
5272- * @param int $nLevel the level of indentation
5273- *
5274- * @return string Dumped version of the scalar value
5275- */
5276- function genStruct($value, $nLevel)
5277- {
5278- $value->structreset();
5279- $strOutput = $this->getIndent($nLevel) . 'struct' . "\r\n";
5280- while (list($key, $keyval) = $value->structeach()) {
5281- $strOutput .= $this->getIndent($nLevel + 1) . $key . "\r\n";
5282- $strOutput .= $this->generateDump($keyval, $nLevel + 2);
5283- }
5284- return $strOutput;
5285- }
5286-
5287- /**
5288- * Returns the dump of an array
5289- *
5290- * @param object $value the array XML_RPC_Value object to dump
5291- * @param int $nLevel the level of indentation
5292- *
5293- * @return string Dumped version of the scalar value
5294- */
5295- function genArray($value, $nLevel)
5296- {
5297- $nSize = $value->arraysize();
5298- $strOutput = $this->getIndent($nLevel) . 'array' . "\r\n";
5299- for($nA = 0; $nA < $nSize; $nA++) {
5300- $strOutput .= $this->getIndent($nLevel + 1) . $nA . "\r\n";
5301- $strOutput .= $this->generateDump($value->arraymem($nA),
5302- $nLevel + 2);
5303- }
5304- return $strOutput;
5305- }
5306-
5307- /**
5308- * Returns the indent for a specific level and caches it for faster use
5309- *
5310- * @param int $nLevel the level
5311- *
5312- * @return string the indented string
5313- */
5314- function getIndent($nLevel)
5315- {
5316- if (!isset($this->arIndent[$nLevel])) {
5317- $this->arIndent[$nLevel] = str_repeat($this->strBaseIndent, $nLevel);
5318- }
5319- return $this->arIndent[$nLevel];
5320- }
5321-}
5322-
5323-/*
5324- * Local variables:
5325- * tab-width: 4
5326- * c-basic-offset: 4
5327- * c-hanging-comment-ender-p: nil
5328- * End:
5329- */
5330-
5331-?>
5332-
5333-
5334-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
5335-
5336-/**
5337- * PHP implementation of the XML-RPC protocol
5338- *
5339- * This is a PEAR-ified version of Useful inc's XML-RPC for PHP.
5340- * It has support for HTTP transport, proxies and authentication.
5341- *
5342- * PHP versions 4 and 5
5343- *
5344- * LICENSE: License is granted to use or modify this software
5345- * ("XML-RPC for PHP") for commercial or non-commercial use provided the
5346- * copyright of the author is preserved in any distributed or derivative work.
5347- *
5348- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESSED OR
5349- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
5350- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
5351- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
5352- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5353- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
5354- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
5355- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5356- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
5357- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5358- *
5359- * @category Web Services
5360- * @package XML_RPC
5361- * @author Edd Dumbill <edd@usefulinc.com>
5362- * @author Stig Bakken <stig@php.net>
5363- * @author Martin Jansen <mj@php.net>
5364- * @author Daniel Convissor <danielc@php.net>
5365- * @copyright 1999-2001 Edd Dumbill
5366- * @version CVS: $Id: RPC.php,v 1.60 2005/03/07 17:45:08 danielc Exp $
5367- * @link http://pear.php.net/package/XML_RPC
5368- */
5369-
5370-
5371-if (!function_exists('xml_parser_create')) {
5372- // Win 32 fix. From: "Leo West" <lwest@imaginet.fr>
5373- if ($WINDIR) {
5374- dl('php_xml.dll');
5375- } else {
5376- dl('xml.so');
5377- }
5378-}
5379-
5380-/**#@+
5381- * Error constants
5382- */
5383-define('XML_RPC_ERROR_INVALID_TYPE', 101);
5384-define('XML_RPC_ERROR_NON_NUMERIC_FOUND', 102);
5385-define('XML_RPC_ERROR_CONNECTION_FAILED', 103);
5386-define('XML_RPC_ERROR_ALREADY_INITIALIZED', 104);
5387-/**#@-*/
5388-
5389-
5390-/**
5391- * Data types
5392- * @global string $GLOBALS['XML_RPC_I4']
5393- */
5394-$GLOBALS['XML_RPC_I4'] = 'i4';
5395-
5396-/**
5397- * Data types
5398- * @global string $GLOBALS['XML_RPC_Int']
5399- */
5400-$GLOBALS['XML_RPC_Int'] = 'int';
5401-
5402-/**
5403- * Data types
5404- * @global string $GLOBALS['XML_RPC_Boolean']
5405- */
5406-$GLOBALS['XML_RPC_Boolean'] = 'boolean';
5407-
5408-/**
5409- * Data types
5410- * @global string $GLOBALS['XML_RPC_Double']
5411- */
5412-$GLOBALS['XML_RPC_Double'] = 'double';
5413-
5414-/**
5415- * Data types
5416- * @global string $GLOBALS['XML_RPC_String']
5417- */
5418-$GLOBALS['XML_RPC_String'] = 'string';
5419-
5420-/**
5421- * Data types
5422- * @global string $GLOBALS['XML_RPC_DateTime']
5423- */
5424-$GLOBALS['XML_RPC_DateTime'] = 'dateTime.iso8601';
5425-
5426-/**
5427- * Data types
5428- * @global string $GLOBALS['XML_RPC_Base64']
5429- */
5430-$GLOBALS['XML_RPC_Base64'] = 'base64';
5431-
5432-/**
5433- * Data types
5434- * @global string $GLOBALS['XML_RPC_Array']
5435- */
5436-$GLOBALS['XML_RPC_Array'] = 'array';
5437-
5438-/**
5439- * Data types
5440- * @global string $GLOBALS['XML_RPC_Struct']
5441- */
5442-$GLOBALS['XML_RPC_Struct'] = 'struct';
5443-
5444-
5445-/**
5446- * Data type meta-types
5447- * @global array $GLOBALS['XML_RPC_Types']
5448- */
5449-$GLOBALS['XML_RPC_Types'] = array(
5450- $GLOBALS['XML_RPC_I4'] => 1,
5451- $GLOBALS['XML_RPC_Int'] => 1,
5452- $GLOBALS['XML_RPC_Boolean'] => 1,
5453- $GLOBALS['XML_RPC_String'] => 1,
5454- $GLOBALS['XML_RPC_Double'] => 1,
5455- $GLOBALS['XML_RPC_DateTime'] => 1,
5456- $GLOBALS['XML_RPC_Base64'] => 1,
5457- $GLOBALS['XML_RPC_Array'] => 2,
5458- $GLOBALS['XML_RPC_Struct'] => 3,
5459-);
5460-
5461-
5462-/**
5463- * Error message numbers
5464- * @global array $GLOBALS['XML_RPC_err']
5465- */
5466-$GLOBALS['XML_RPC_err'] = array(
5467- 'unknown_method' => 1,
5468- 'invalid_return' => 2,
5469- 'incorrect_params' => 3,
5470- 'introspect_unknown' => 4,
5471- 'http_error' => 5,
5472-);
5473-
5474-/**
5475- * Error message strings
5476- * @global array $GLOBALS['XML_RPC_str']
5477- */
5478-$GLOBALS['XML_RPC_str'] = array(
5479- 'unknown_method' => 'Unknown method',
5480- 'invalid_return' => 'Invalid return payload: enable debugging to examine incoming payload',
5481- 'incorrect_params' => 'Incorrect parameters passed to method',
5482- 'introspect_unknown' => 'Can\'t introspect: method unknown',
5483- 'http_error' => 'Didn\'t receive 200 OK from remote server.',
5484-);
5485-
5486-
5487-/**
5488- * Default XML encoding (ISO-8859-1, UTF-8 or US-ASCII)
5489- * @global string $GLOBALS['XML_RPC_defencoding']
5490- */
5491-$GLOBALS['XML_RPC_defencoding'] = 'UTF-8';
5492-
5493-/**
5494- * User error codes start at 800
5495- * @global int $GLOBALS['XML_RPC_erruser']
5496- */
5497-$GLOBALS['XML_RPC_erruser'] = 800;
5498-
5499-/**
5500- * XML parse error codes start at 100
5501- * @global int $GLOBALS['XML_RPC_errxml']
5502- */
5503-$GLOBALS['XML_RPC_errxml'] = 100;
5504-
5505-
5506-/**
5507- * Compose backslashes for escaping regexp
5508- * @global string $GLOBALS['XML_RPC_backslash']
5509- */
5510-$GLOBALS['XML_RPC_backslash'] = chr(92) . chr(92);
5511-
5512-
5513-/**
5514- * Stores state during parsing
5515- *
5516- * quick explanation of components:
5517- * + st = builds up a string for evaluation
5518- * + ac = accumulates values
5519- * + qt = decides if quotes are needed for evaluation
5520- * + cm = denotes struct or array (comma needed)
5521- * + isf = indicates a fault
5522- * + lv = indicates "looking for a value": implements the logic
5523- * to allow values with no types to be strings
5524- * + params = stores parameters in method calls
5525- * + method = stores method name
5526- *
5527- * @global array $GLOBALS['XML_RPC_xh']
5528- */
5529-$GLOBALS['XML_RPC_xh'] = array();
5530-
5531-
5532-/**
5533- * Start element handler for the XML parser
5534- *
5535- * @return void
5536- */
5537-function XML_RPC_se($parser, $name, $attrs)
5538-{
5539- global $XML_RPC_xh, $XML_RPC_DateTime, $XML_RPC_String;
5540-
5541- switch ($name) {
5542- case 'STRUCT':
5543- case 'ARRAY':
5544- $XML_RPC_xh[$parser]['st'] .= 'array(';
5545- $XML_RPC_xh[$parser]['cm']++;
5546- // this last line turns quoting off
5547- // this means if we get an empty array we'll
5548- // simply get a bit of whitespace in the eval
5549- $XML_RPC_xh[$parser]['qt'] = 0;
5550- break;
5551-
5552- case 'NAME':
5553- $XML_RPC_xh[$parser]['st'] .= "'";
5554- $XML_RPC_xh[$parser]['ac'] = '';
5555- break;
5556-
5557- case 'FAULT':
5558- $XML_RPC_xh[$parser]['isf'] = 1;
5559- break;
5560-
5561- case 'PARAM':
5562- $XML_RPC_xh[$parser]['st'] = '';
5563- break;
5564-
5565- case 'VALUE':
5566- $XML_RPC_xh[$parser]['st'] .= 'new XML_RPC_Value(';
5567- $XML_RPC_xh[$parser]['lv'] = 1;
5568- $XML_RPC_xh[$parser]['vt'] = $XML_RPC_String;
5569- $XML_RPC_xh[$parser]['ac'] = '';
5570- $XML_RPC_xh[$parser]['qt'] = 0;
5571- // look for a value: if this is still 1 by the
5572- // time we reach the first data segment then the type is string
5573- // by implication and we need to add in a quote
5574- break;
5575-
5576- case 'I4':
5577- case 'INT':
5578- case 'STRING':
5579- case 'BOOLEAN':
5580- case 'DOUBLE':
5581- case 'DATETIME.ISO8601':
5582- case 'BASE64':
5583- $XML_RPC_xh[$parser]['ac'] = ''; // reset the accumulator
5584-
5585- if ($name == 'DATETIME.ISO8601' || $name == 'STRING') {
5586- $XML_RPC_xh[$parser]['qt'] = 1;
5587-
5588- if ($name == 'DATETIME.ISO8601') {
5589- $XML_RPC_xh[$parser]['vt'] = $XML_RPC_DateTime;
5590- }
5591-
5592- } elseif ($name == 'BASE64') {
5593- $XML_RPC_xh[$parser]['qt'] = 2;
5594- } else {
5595- // No quoting is required here -- but
5596- // at the end of the element we must check
5597- // for data format errors.
5598- $XML_RPC_xh[$parser]['qt'] = 0;
5599- }
5600- break;
5601-
5602- case 'MEMBER':
5603- $XML_RPC_xh[$parser]['ac'] = '';
5604- }
5605-
5606- if ($name != 'VALUE') {
5607- $XML_RPC_xh[$parser]['lv'] = 0;
5608- }
5609-}
5610-
5611-/**
5612- * End element handler for the XML parser
5613- *
5614- * @return void
5615- */
5616-function XML_RPC_ee($parser, $name)
5617-{
5618- global $XML_RPC_xh, $XML_RPC_Types, $XML_RPC_String;
5619-
5620- switch ($name) {
5621- case 'STRUCT':
5622- case 'ARRAY':
5623- if ($XML_RPC_xh[$parser]['cm']
5624- && substr($XML_RPC_xh[$parser]['st'], -1) == ',')
5625- {
5626- $XML_RPC_xh[$parser]['st'] = substr($XML_RPC_xh[$parser]['st'], 0, -1);
5627- }
5628-
5629- $XML_RPC_xh[$parser]['st'] .= ')';
5630- $XML_RPC_xh[$parser]['vt'] = strtolower($name);
5631- $XML_RPC_xh[$parser]['cm']--;
5632- break;
5633-
5634- case 'NAME':
5635- $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'] . "' => ";
5636- break;
5637-
5638- case 'BOOLEAN':
5639- // special case here: we translate boolean 1 or 0 into PHP
5640- // constants true or false
5641- if ($XML_RPC_xh[$parser]['ac'] == '1') {
5642- $XML_RPC_xh[$parser]['ac'] = 'true';
5643- } else {
5644- $XML_RPC_xh[$parser]['ac'] = 'false';
5645- }
5646-
5647- $XML_RPC_xh[$parser]['vt'] = strtolower($name);
5648- // Drop through intentionally.
5649-
5650- case 'I4':
5651- case 'INT':
5652- case 'STRING':
5653- case 'DOUBLE':
5654- case 'DATETIME.ISO8601':
5655- case 'BASE64':
5656- if ($XML_RPC_xh[$parser]['qt'] == 1) {
5657- // we use double quotes rather than single so backslashification works OK
5658- $XML_RPC_xh[$parser]['st'] .= '"' . $XML_RPC_xh[$parser]['ac'] . '"';
5659- } elseif ($XML_RPC_xh[$parser]['qt'] == 2) {
5660- $XML_RPC_xh[$parser]['st'] .= "base64_decode('"
5661- . $XML_RPC_xh[$parser]['ac'] . "')";
5662- } elseif ($name == 'BOOLEAN') {
5663- $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'];
5664- } else {
5665- // we have an I4, INT or a DOUBLE
5666- // we must check that only 0123456789-.<space> are characters here
5667- if (!ereg("^[+-]?[0123456789 \t\.]+$", $XML_RPC_xh[$parser]['ac'])) {
5668- XML_RPC_Base::raiseError('Non-numeric value received in INT or DOUBLE',
5669- XML_RPC_ERROR_NON_NUMERIC_FOUND);
5670- $XML_RPC_xh[$parser]['st'] .= 'XML_RPC_ERROR_NON_NUMERIC_FOUND';
5671- } else {
5672- // it's ok, add it on
5673- $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'];
5674- }
5675- }
5676-
5677- $XML_RPC_xh[$parser]['ac'] = '';
5678- $XML_RPC_xh[$parser]['qt'] = 0;
5679- $XML_RPC_xh[$parser]['lv'] = 3; // indicate we've found a value
5680- break;
5681-
5682- case 'VALUE':
5683- // deal with a string value
5684- if (strlen($XML_RPC_xh[$parser]['ac']) > 0 &&
5685- $XML_RPC_xh[$parser]['vt'] == $XML_RPC_String) {
5686-
5687- $XML_RPC_xh[$parser]['st'] .= '"' . $XML_RPC_xh[$parser]['ac'] . '"';
5688- }
5689-
5690- // This if () detects if no scalar was inside <VALUE></VALUE>
5691- // and pads an empty "".
5692- if ($XML_RPC_xh[$parser]['st'][strlen($XML_RPC_xh[$parser]['st'])-1] == '(') {
5693- $XML_RPC_xh[$parser]['st'] .= '""';
5694- }
5695- $XML_RPC_xh[$parser]['st'] .= ", '" . $XML_RPC_xh[$parser]['vt'] . "')";
5696- if ($XML_RPC_xh[$parser]['cm']) {
5697- $XML_RPC_xh[$parser]['st'] .= ',';
5698- }
5699- break;
5700-
5701- case 'MEMBER':
5702- $XML_RPC_xh[$parser]['ac'] = '';
5703- $XML_RPC_xh[$parser]['qt'] = 0;
5704- break;
5705-
5706- case 'DATA':
5707- $XML_RPC_xh[$parser]['ac'] = '';
5708- $XML_RPC_xh[$parser]['qt'] = 0;
5709- break;
5710-
5711- case 'PARAM':
5712- $XML_RPC_xh[$parser]['params'][] = $XML_RPC_xh[$parser]['st'];
5713- break;
5714-
5715- case 'METHODNAME':
5716- $XML_RPC_xh[$parser]['method'] = ereg_replace("^[\n\r\t ]+", '',
5717- $XML_RPC_xh[$parser]['ac']);
5718- break;
5719-
5720- case 'BOOLEAN':
5721- // special case here: we translate boolean 1 or 0 into PHP
5722- // constants true or false
5723- if ($XML_RPC_xh[$parser]['ac'] == '1') {
5724- $XML_RPC_xh[$parser]['ac'] = 'true';
5725- } else {
5726- $XML_RPC_xh[$parser]['ac'] = 'false';
5727- }
5728-
5729- $XML_RPC_xh[$parser]['vt'] = strtolower($name);
5730- }
5731-
5732- // if it's a valid type name, set the type
5733- if (isset($XML_RPC_Types[strtolower($name)])) {
5734- $XML_RPC_xh[$parser]['vt'] = strtolower($name);
5735- }
5736-}
5737-
5738-/**
5739- * Character data handler for the XML parser
5740- *
5741- * @return void
5742- */
5743-function XML_RPC_cd($parser, $data)
5744-{
5745- global $XML_RPC_xh, $XML_RPC_backslash;
5746-
5747- if ($XML_RPC_xh[$parser]['lv'] != 3) {
5748- // "lookforvalue==3" means that we've found an entire value
5749- // and should discard any further character data
5750-
5751- if ($XML_RPC_xh[$parser]['lv'] == 1) {
5752- // if we've found text and we're just in a <value> then
5753- // turn quoting on, as this will be a string
5754- $XML_RPC_xh[$parser]['qt'] = 1;
5755- // and say we've found a value
5756- $XML_RPC_xh[$parser]['lv'] = 2;
5757- }
5758-
5759- // replace characters that eval would
5760- // do special things with
5761- if (!isset($XML_RPC_xh[$parser]['ac'])) {
5762- $XML_RPC_xh[$parser]['ac'] = '';
5763- }
5764- $XML_RPC_xh[$parser]['ac'] .= str_replace('$', '\$',
5765- str_replace('"', '\"', str_replace(chr(92),
5766- $XML_RPC_backslash, $data)));
5767- }
5768-}
5769-
5770-/**
5771- * Base class
5772- *
5773- * This class provides common functions for all of the XML_RPC classes.
5774- *
5775- * @category Web Services
5776- * @package XML_RPC
5777- * @author Edd Dumbill <edd@usefulinc.com>
5778- * @author Stig Bakken <stig@php.net>
5779- * @author Martin Jansen <mj@php.net>
5780- * @copyright 1999-2001 Edd Dumbill
5781- * @version Release: 1.2.2
5782- * @link http://pear.php.net/package/XML_RPC
5783- */
5784-class XML_RPC_Base {
5785-
5786- /**
5787- * PEAR Error handling
5788- *
5789- * @return object PEAR_Error object
5790- */
5791- function raiseError($msg, $code)
5792- {
5793- include_once 'PEAR.php';
5794- if (is_object(@$this)) {
5795- return PEAR::raiseError(get_class($this) . ': ' . $msg, $code);
5796- } else {
5797- return PEAR::raiseError('XML_RPC: ' . $msg, $code);
5798- }
5799- }
5800-
5801- /**
5802- * Tell whether something is a PEAR_Error object
5803- *
5804- * @param mixed $value the item to check
5805- *
5806- * @return bool whether $value is a PEAR_Error object or not
5807- *
5808- * @access public
5809- */
5810- function isError($value)
5811- {
5812- return is_a($value, 'PEAR_Error');
5813- }
5814-}
5815-
5816-/**
5817- *
5818- *
5819- * @category Web Services
5820- * @package XML_RPC
5821- * @author Edd Dumbill <edd@usefulinc.com>
5822- * @author Stig Bakken <stig@php.net>
5823- * @author Martin Jansen <mj@php.net>
5824- * @author Daniel Convissor <danielc@php.net>
5825- * @copyright 1999-2001 Edd Dumbill
5826- * @version Release: 1.2.2
5827- * @link http://pear.php.net/package/XML_RPC
5828- */
5829-class XML_RPC_Client extends XML_RPC_Base {
5830-
5831- /**
5832- * The path and name of the RPC server script you want the request to go to
5833- * @var string
5834- */
5835- var $path = '';
5836-
5837- /**
5838- * The name of the remote server to connect to
5839- * @var string
5840- */
5841- var $server = '';
5842-
5843- /**
5844- * The protocol to use in contacting the remote server
5845- * @var string
5846- */
5847- var $protocol = 'http://';
5848-
5849- /**
5850- * The port for connecting to the remote server
5851- *
5852- * The default is 80 for http:// connections
5853- * and 443 for https:// and ssl:// connections.
5854- *
5855- * @var integer
5856- */
5857- var $port = 80;
5858-
5859- /**
5860- * A user name for accessing the RPC server
5861- * @var string
5862- * @see XML_RPC_Client::setCredentials()
5863- */
5864- var $username = '';
5865-
5866- /**
5867- * A password for accessing the RPC server
5868- * @var string
5869- * @see XML_RPC_Client::setCredentials()
5870- */
5871- var $password = '';
5872-
5873- /**
5874- * The name of the proxy server to use, if any
5875- * @var string
5876- */
5877- var $proxy = '';
5878-
5879- /**
5880- * The protocol to use in contacting the proxy server, if any
5881- * @var string
5882- */
5883- var $proxy_protocol = 'http://';
5884-
5885- /**
5886- * The port for connecting to the proxy server
5887- *
5888- * The default is 8080 for http:// connections
5889- * and 443 for https:// and ssl:// connections.
5890- *
5891- * @var integer
5892- */
5893- var $proxy_port = 8080;
5894-
5895- /**
5896- * A user name for accessing the proxy server
5897- * @var string
5898- */
5899- var $proxy_user = '';
5900-
5901- /**
5902- * A password for accessing the proxy server
5903- * @var string
5904- */
5905- var $proxy_pass = '';
5906-
5907- /**
5908- * The error number, if any
5909- * @var integer
5910- */
5911- var $errno = 0;
5912-
5913- /**
5914- * The error message, if any
5915- * @var string
5916- */
5917- var $errstring = '';
5918-
5919- /**
5920- * The current debug mode (1 = on, 0 = off)
5921- * @var integer
5922- */
5923- var $debug = 0;
5924-
5925-
5926- /**
5927- * Sets the object's properties
5928- *
5929- * @param string $path the path and name of the RPC server script
5930- * you want the request to go to
5931- * @param string $server the URL of the remote server to connect to.
5932- * If this parameter doesn't specify a
5933- * protocol and $port is 443, ssl:// is
5934- * assumed.
5935- * @param integer $port a port for connecting to the remote server.
5936- * Defaults to 80 for http:// connections and
5937- * 443 for https:// and ssl:// connections.
5938- * @param string $proxy the URL of the proxy server to use, if any.
5939- * If this parameter doesn't specify a
5940- * protocol and $port is 443, ssl:// is
5941- * assumed.
5942- * @param integer $proxy_port a port for connecting to the remote server.
5943- * Defaults to 8080 for http:// connections and
5944- * 443 for https:// and ssl:// connections.
5945- * @param string $proxy_user a user name for accessing the proxy server
5946- * @param string $proxy_pass a password for accessing the proxy server
5947- *
5948- * @return void
5949- */
5950- function XML_RPC_Client($path, $server, $port = 0,
5951- $proxy = '', $proxy_port = 0,
5952- $proxy_user = '', $proxy_pass = '')
5953- {
5954- $this->path = $path;
5955- $this->proxy_user = $proxy_user;
5956- $this->proxy_pass = $proxy_pass;
5957-
5958- preg_match('@^(http://|https://|ssl://)?(.*)$@', $server, $match);
5959- if ($match[1] == '') {
5960- if ($port == 443) {
5961- $this->server = $match[2];
5962- $this->protocol = 'ssl://';
5963- $this->port = 443;
5964- } else {
5965- $this->server = $match[2];
5966- if ($port) {
5967- $this->port = $port;
5968- }
5969- }
5970- } elseif ($match[1] == 'http://') {
5971- $this->server = $match[2];
5972- if ($port) {
5973- $this->port = $port;
5974- }
5975- } else {
5976- $this->server = $match[2];
5977- $this->protocol = 'ssl://';
5978- if ($port) {
5979- $this->port = $port;
5980- } else {
5981- $this->port = 443;
5982- }
5983- }
5984-
5985- if ($proxy) {
5986- preg_match('@^(http://|https://|ssl://)?(.*)$@', $proxy, $match);
5987- if ($match[1] == '') {
5988- if ($proxy_port == 443) {
5989- $this->proxy = $match[2];
5990- $this->proxy_protocol = 'ssl://';
5991- $this->proxy_port = 443;
5992- } else {
5993- $this->proxy = $match[2];
5994- if ($proxy_port) {
5995- $this->proxy_port = $proxy_port;
5996- }
5997- }
5998- } elseif ($match[1] == 'http://') {
5999- $this->proxy = $match[2];
6000- if ($proxy_port) {
6001- $this->proxy_port = $proxy_port;
6002- }
6003- } else {
6004- $this->proxy = $match[2];
6005- $this->proxy_protocol = 'ssl://';
6006- if ($proxy_port) {
6007- $this->proxy_port = $proxy_port;
6008- } else {
6009- $this->proxy_port = 443;
6010- }
6011- }
6012- }
6013- }
6014-
6015- /**
6016- * Change the current debug mode
6017- *
6018- * @param int $in where 1 = on, 0 = off
6019- *
6020- * @return void
6021- */
6022- function setDebug($in)
6023- {
6024- if ($in) {
6025- $this->debug = 1;
6026- } else {
6027- $this->debug = 0;
6028- }
6029- }
6030-
6031- /**
6032- * Set username and password properties for connecting to the RPC server
6033- *
6034- * @param string $u the user name
6035- * @param string $p the password
6036- *
6037- * @return void
6038- *
6039- * @see XML_RPC_Client::$username, XML_RPC_Client::$password
6040- */
6041- function setCredentials($u, $p)
6042- {
6043- $this->username = $u;
6044- $this->password = $p;
6045- }
6046-
6047- /**
6048- * Transmit the RPC request via HTTP 1.0 protocol
6049- *
6050- * @param object $msg the XML_RPC_Message object
6051- * @param int $timeout how many seconds to wait for the request
6052- *
6053- * @return object an XML_RPC_Response object. 0 is returned if any
6054- * problems happen.
6055- *
6056- * @see XML_RPC_Message, XML_RPC_Client::XML_RPC_Client(),
6057- * XML_RPC_Client::setCredentials()
6058- */
6059- function send($msg, $timeout = 0)
6060- {
6061- $msg->debug = $this->debug;
6062- return $this->sendPayloadHTTP10($msg, $this->server, $this->port,
6063- $timeout, $this->username,
6064- $this->password);
6065- }
6066-
6067- /**
6068- * Transmit the RPC request via HTTP 1.0 protocol
6069- *
6070- * Requests should be sent using XML_RPC_Client send() rather than
6071- * calling this method directly.
6072- *
6073- * @param object $msg the XML_RPC_Message object
6074- * @param string $server the server to send the request to
6075- * @param int $port the server port send the request to
6076- * @param int $timeout how many seconds to wait for the request
6077- * before giving up
6078- * @param string $username a user name for accessing the RPC server
6079- * @param string $password a password for accessing the RPC server
6080- *
6081- * @return object an XML_RPC_Response object. 0 is returned if any
6082- * problems happen.
6083- *
6084- * @see XML_RPC_Client::send()
6085- */
6086- function sendPayloadHTTP10($msg, $server, $port, $timeout = 0,
6087- $username = '', $password = '')
6088- {
6089- /*
6090- * If we're using a proxy open a socket to the proxy server
6091- * instead to the xml-rpc server
6092- */
6093- if ($this->proxy) {
6094- if ($this->proxy_protocol == 'http://') {
6095- $protocol = '';
6096- } else {
6097- $protocol = $this->proxy_protocol;
6098- }
6099- if ($timeout > 0) {
6100- $fp = @fsockopen($protocol . $this->proxy, $this->proxy_port,
6101- $this->errno, $this->errstr, $timeout);
6102- } else {
6103- $fp = @fsockopen($protocol . $this->proxy, $this->proxy_port,
6104- $this->errno, $this->errstr);
6105- }
6106- } else {
6107- if ($this->protocol == 'http://') {
6108- $protocol = '';
6109- } else {
6110- $protocol = $this->protocol;
6111- }
6112- if ($timeout > 0) {
6113- $fp = @fsockopen($protocol . $server, $port,
6114- $this->errno, $this->errstr, $timeout);
6115- } else {
6116- $fp = @fsockopen($protocol . $server, $port,
6117- $this->errno, $this->errstr);
6118- }
6119- }
6120-
6121- /*
6122- * Just raising the error without returning it is strange,
6123- * but keep it here for backwards compatibility.
6124- */
6125- if (!$fp && $this->proxy) {
6126- $this->raiseError('Connection to proxy server '
6127- . $this->proxy . ':' . $this->proxy_port
6128- . ' failed. ' . $this->errstr,
6129- XML_RPC_ERROR_CONNECTION_FAILED);
6130- return 0;
6131- } elseif (!$fp) {
6132- $this->raiseError('Connection to RPC server '
6133- . $server . ':' . $port
6134- . ' failed. ' . $this->errstr,
6135- XML_RPC_ERROR_CONNECTION_FAILED);
6136- return 0;
6137- }
6138-
6139- // Only create the payload if it was not created previously
6140- if (empty($msg->payload)) {
6141- $msg->createPayload();
6142- }
6143-
6144- // thanks to Grant Rauscher <grant7@firstworld.net> for this
6145- $credentials = '';
6146- if ($username != '') {
6147- $credentials = 'Authorization: Basic ' .
6148- base64_encode($username . ':' . $password) . "\r\n";
6149- }
6150-
6151- if ($this->proxy) {
6152- $op = 'POST ' . $this->protocol . $server;
6153- if ($this->proxy_port) {
6154- $op .= ':' . $this->port;
6155- }
6156- } else {
6157- $op = 'POST ';
6158- }
6159-
6160- $op .= $this->path. " HTTP/1.0\r\n" .
6161- "User-Agent: PEAR XML_RPC\r\n" .
6162- 'Host: ' . $server . "\r\n";
6163- if ($this->proxy && $this->proxy_user != '') {
6164- $op .= 'Proxy-Authorization: Basic ' .
6165- base64_encode($this->proxy_user . ':' . $this->proxy_pass) .
6166- "\r\n";
6167- }
6168- $op .= $credentials .
6169- "Content-Type: text/xml\r\n" .
6170- 'Content-Length: ' . strlen($msg->payload) . "\r\n\r\n" .
6171- $msg->payload;
6172-
6173- if (!fputs($fp, $op, strlen($op))) {
6174- $this->errstr = 'Write error';
6175- return 0;
6176- }
6177- $resp = $msg->parseResponseFile($fp);
6178- fclose($fp);
6179- return $resp;
6180- }
6181-}
6182-
6183-/**
6184- *
6185- *
6186- * @category Web Services
6187- * @package XML_RPC
6188- * @author Edd Dumbill <edd@usefulinc.com>
6189- * @author Stig Bakken <stig@php.net>
6190- * @author Martin Jansen <mj@php.net>
6191- * @copyright 1999-2001 Edd Dumbill
6192- * @version Release: 1.2.2
6193- * @link http://pear.php.net/package/XML_RPC
6194- */
6195-class XML_RPC_Response extends XML_RPC_Base
6196-{
6197- var $xv;
6198- var $fn;
6199- var $fs;
6200- var $hdrs;
6201-
6202- /**
6203- * @return void
6204- */
6205- function XML_RPC_Response($val, $fcode = 0, $fstr = '')
6206- {
6207- if ($fcode != 0) {
6208- $this->fn = $fcode;
6209- $this->fs = htmlspecialchars($fstr);
6210- } else {
6211- $this->xv = $val;
6212- }
6213- }
6214-
6215- /**
6216- * @return int the error code
6217- */
6218- function faultCode()
6219- {
6220- if (isset($this->fn)) {
6221- return $this->fn;
6222- } else {
6223- return 0;
6224- }
6225- }
6226-
6227- /**
6228- * @return string the error string
6229- */
6230- function faultString()
6231- {
6232- return $this->fs;
6233- }
6234-
6235- /**
6236- * @return mixed the value
6237- */
6238- function value()
6239- {
6240- return $this->xv;
6241- }
6242-
6243- /**
6244- * @return string the error message in XML format
6245- */
6246- function serialize()
6247- {
6248- $rs = "<methodResponse>\n";
6249- if ($this->fn) {
6250- $rs .= "<fault>
6251- <value>
6252- <struct>
6253- <member>
6254- <name>faultCode</name>
6255- <value><int>" . $this->fn . "</int></value>
6256- </member>
6257- <member>
6258- <name>faultString</name>
6259- <value><string>" . $this->fs . "</string></value>
6260- </member>
6261- </struct>
6262- </value>
6263-</fault>";
6264- } else {
6265- $rs .= "<params>\n<param>\n" . $this->xv->serialize() .
6266- "</param>\n</params>";
6267- }
6268- $rs .= "\n</methodResponse>";
6269- return $rs;
6270- }
6271-}
6272-
6273-/**
6274- *
6275- *
6276- * @category Web Services
6277- * @package XML_RPC
6278- * @author Edd Dumbill <edd@usefulinc.com>
6279- * @author Stig Bakken <stig@php.net>
6280- * @author Martin Jansen <mj@php.net>
6281- * @author Daniel Convissor <danielc@php.net>
6282- * @copyright 1999-2001 Edd Dumbill
6283- * @version Release: 1.2.2
6284- * @link http://pear.php.net/package/XML_RPC
6285- */
6286-class XML_RPC_Message extends XML_RPC_Base
6287-{
6288- /**
6289- * The current debug mode (1 = on, 0 = off)
6290- * @var integer
6291- */
6292- var $debug = 0;
6293-
6294- /**
6295- * The encoding to be used for outgoing messages
6296- *
6297- * Defaults to the value of <var>$GLOBALS['XML_RPC_defencoding']</var>
6298- *
6299- * @var string
6300- * @see XML_RPC_Message::setSendEncoding(),
6301- * $GLOBALS['XML_RPC_defencoding'], XML_RPC_Message::xml_header()
6302- */
6303- var $send_encoding = '';
6304-
6305- /**
6306- * The method presently being evaluated
6307- * @var string
6308- */
6309- var $methodname = '';
6310-
6311- /**
6312- * @var array
6313- */
6314- var $params = array();
6315-
6316- /**
6317- * The XML message being generated
6318- * @var string
6319- */
6320- var $payload = '';
6321-
6322- /**
6323- * @return void
6324- */
6325- function XML_RPC_Message($meth, $pars = 0)
6326- {
6327- $this->methodname = $meth;
6328- if (is_array($pars) && sizeof($pars) > 0) {
6329- for ($i = 0; $i < sizeof($pars); $i++) {
6330- $this->addParam($pars[$i]);
6331- }
6332- }
6333- }
6334-
6335- /**
6336- * Produces the XML declaration including the encoding attribute
6337- *
6338- * The encoding is determined by this class' <var>$send_encoding</var>
6339- * property. If the <var>$send_encoding</var> property is not set, use
6340- * <var>$GLOBALS['XML_RPC_defencoding']</var>.
6341- *
6342- * @return string the XML declaration and <methodCall> element
6343- *
6344- * @see XML_RPC_Message::setSendEncoding(),
6345- * XML_RPC_Message::$send_encoding, $GLOBALS['XML_RPC_defencoding']
6346- */
6347- function xml_header()
6348- {
6349- global $XML_RPC_defencoding;
6350- if (!$this->send_encoding) {
6351- $this->send_encoding = $XML_RPC_defencoding;
6352- }
6353- return '<?xml version="1.0" encoding="' . $this->send_encoding . '"?>'
6354- . "\n<methodCall>\n";
6355- }
6356-
6357- /**
6358- * @return string the closing </methodCall> tag
6359- */
6360- function xml_footer()
6361- {
6362- return "</methodCall>\n";
6363- }
6364-
6365- /**
6366- * @return void
6367- *
6368- * @uses XML_RPC_Message::xml_header(), XML_RPC_Message::xml_footer()
6369- */
6370- function createPayload()
6371- {
6372- $this->payload = $this->xml_header();
6373- $this->payload .= '<methodName>' . $this->methodname . "</methodName>\n";
6374- $this->payload .= "<params>\n";
6375- for ($i = 0; $i < sizeof($this->params); $i++) {
6376- $p = $this->params[$i];
6377- $this->payload .= "<param>\n" . $p->serialize() . "</param>\n";
6378- }
6379- $this->payload .= "</params>\n";
6380- $this->payload .= $this->xml_footer();
6381- $this->payload = ereg_replace("[\r\n]+", "\r\n", $this->payload);
6382- }
6383-
6384- /**
6385- * @return string the name of the method
6386- */
6387- function method($meth = '')
6388- {
6389- if ($meth != '') {
6390- $this->methodname = $meth;
6391- }
6392- return $this->methodname;
6393- }
6394-
6395- /**
6396- * @return string the payload
6397- */
6398- function serialize()
6399- {
6400- $this->createPayload();
6401- return $this->payload;
6402- }
6403-
6404- /**
6405- * @return void
6406- */
6407- function addParam($par)
6408- {
6409- $this->params[] = $par;
6410- }
6411-
6412- /**
6413- * @return void
6414- */
6415- function getParam($i)
6416- {
6417- return $this->params[$i];
6418- }
6419-
6420- /**
6421- * @return int the number of parameters
6422- */
6423- function getNumParams()
6424- {
6425- return sizeof($this->params);
6426- }
6427-
6428- /**
6429- * Sets the XML declaration's encoding attribute
6430- *
6431- * @param string $type the encoding type (ISO-8859-1, UTF-8 or US-ASCII)
6432- *
6433- * @return void
6434- *
6435- * @see XML_RPC_Message::$send_encoding, XML_RPC_Message::xml_header()
6436- * @since Method available since Release 1.2.0
6437- */
6438- function setSendEncoding($type)
6439- {
6440- $this->send_encoding = $type;
6441- }
6442-
6443- /**
6444- * Determine the XML's encoding via the encoding attribute
6445- * in the XML declaration
6446- *
6447- * If the encoding parameter is not set or is not ISO-8859-1, UTF-8
6448- * or US-ASCII, $XML_RPC_defencoding will be returned.
6449- *
6450- * @param string $data the XML that will be parsed
6451- *
6452- * @return string the encoding to be used
6453- *
6454- * @link http://php.net/xml_parser_create
6455- * @since Method available since Release 1.2.0
6456- */
6457- function getEncoding($data)
6458- {
6459- global $XML_RPC_defencoding;
6460-
6461- if (preg_match('/<\?xml[^>]*\s*encoding\s*=\s*[\'"]([^"\']*)[\'"]/i',
6462- $data, $match))
6463- {
6464- $match[1] = trim(strtoupper($match[1]));
6465- switch ($match[1]) {
6466- case 'ISO-8859-1':
6467- case 'UTF-8':
6468- case 'US-ASCII':
6469- return $match[1];
6470- break;
6471-
6472- default:
6473- return $XML_RPC_defencoding;
6474- }
6475- } else {
6476- return $XML_RPC_defencoding;
6477- }
6478- }
6479-
6480- /**
6481- * @return object a new XML_RPC_Response object
6482- */
6483- function parseResponseFile($fp)
6484- {
6485- $ipd = '';
6486- while ($data = @fread($fp, 8192)) {
6487- $ipd .= $data;
6488- }
6489- return $this->parseResponse($ipd);
6490- }
6491-
6492- /**
6493- * @return object a new XML_RPC_Response object
6494- */
6495- function parseResponse($data = '')
6496- {
6497- global $XML_RPC_xh, $XML_RPC_err, $XML_RPC_str, $XML_RPC_defencoding;
6498-
6499- $encoding = $this->getEncoding($data);
6500- $parser = xml_parser_create($encoding);
6501-
6502- $XML_RPC_xh[$parser] = array();
6503-
6504- $XML_RPC_xh[$parser]['st'] = '';
6505- $XML_RPC_xh[$parser]['cm'] = 0;
6506- $XML_RPC_xh[$parser]['isf'] = 0;
6507- $XML_RPC_xh[$parser]['ac'] = '';
6508- $XML_RPC_xh[$parser]['qt'] = '';
6509-
6510- xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
6511- xml_set_element_handler($parser, 'XML_RPC_se', 'XML_RPC_ee');
6512- xml_set_character_data_handler($parser, 'XML_RPC_cd');
6513-
6514- $hdrfnd = 0;
6515- if ($this->debug) {
6516- print "<PRE>---GOT---\n";
6517- print isset($_SERVER['SERVER_PROTOCOL']) ? htmlspecialchars($data) : $data;
6518- print "\n---END---\n</PRE>";
6519- }
6520-
6521- // see if we got an HTTP 200 OK, else bomb
6522- // but only do this if we're using the HTTP protocol.
6523- if (ereg('^HTTP', $data) &&
6524- !ereg('^HTTP/[0-9\.]+ 200 ', $data)) {
6525- $errstr = substr($data, 0, strpos($data, "\n") - 1);
6526- error_log('HTTP error, got response: ' . $errstr);
6527- $r = new XML_RPC_Response(0, $XML_RPC_err['http_error'],
6528- $XML_RPC_str['http_error'] . ' (' .
6529- $errstr . ')');
6530- xml_parser_free($parser);
6531- return $r;
6532- }
6533- // gotta get rid of headers here
6534-
6535-
6536- if ((!$hdrfnd) && ($brpos = strpos($data,"\r\n\r\n"))) {
6537- $XML_RPC_xh[$parser]['ha'] = substr($data, 0, $brpos);
6538- $data = substr($data, $brpos + 4);
6539- $hdrfnd = 1;
6540- }
6541-
6542- /*
6543- * be tolerant of junk after methodResponse
6544- * (e.g. javascript automatically inserted by free hosts)
6545- * thanks to Luca Mariano <luca.mariano@email.it>
6546- */
6547- $data = substr($data, 0, strpos($data, "</methodResponse>") + 17);
6548-
6549- if (!xml_parse($parser, $data, sizeof($data))) {
6550- // thanks to Peter Kocks <peter.kocks@baygate.com>
6551- if ((xml_get_current_line_number($parser)) == 1) {
6552- $errstr = 'XML error at line 1, check URL';
6553- } else {
6554- $errstr = sprintf('XML error: %s at line %d',
6555- xml_error_string(xml_get_error_code($parser)),
6556- xml_get_current_line_number($parser));
6557- }
6558- error_log($errstr);
6559- $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'],
6560- $XML_RPC_str['invalid_return']);
6561- xml_parser_free($parser);
6562- return $r;
6563- }
6564- xml_parser_free($parser);
6565- if ($this->debug) {
6566- print '<PRE>---EVALING---[' .
6567- strlen($XML_RPC_xh[$parser]['st']) . " chars]---\n" .
6568- htmlspecialchars($XML_RPC_xh[$parser]['st']) . ";\n---END---</PRE>";
6569- }
6570- if (strlen($XML_RPC_xh[$parser]['st']) == 0) {
6571- // then something odd has happened
6572- // and it's time to generate a client side error
6573- // indicating something odd went on
6574- $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'],
6575- $XML_RPC_str['invalid_return']);
6576- } else {
6577- eval('$v=' . $XML_RPC_xh[$parser]['st'] . '; $allOK=1;');
6578- if ($XML_RPC_xh[$parser]['isf']) {
6579- $f = $v->structmem('faultCode');
6580- $fs = $v->structmem('faultString');
6581- $r = new XML_RPC_Response($v, $f->scalarval(),
6582- $fs->scalarval());
6583- } else {
6584- $r = new XML_RPC_Response($v);
6585- }
6586- }
6587- $r->hdrs = split("\r?\n", $XML_RPC_xh[$parser]['ha'][1]);
6588- return $r;
6589- }
6590-}
6591-
6592-/**
6593- *
6594- *
6595- * @category Web Services
6596- * @package XML_RPC
6597- * @author Edd Dumbill <edd@usefulinc.com>
6598- * @author Stig Bakken <stig@php.net>
6599- * @author Martin Jansen <mj@php.net>
6600- * @copyright 1999-2001 Edd Dumbill
6601- * @version Release: 1.2.2
6602- * @link http://pear.php.net/package/XML_RPC
6603- */
6604-class XML_RPC_Value extends XML_RPC_Base
6605-{
6606- var $me = array();
6607- var $mytype = 0;
6608-
6609- /**
6610- * @return void
6611- */
6612- function XML_RPC_Value($val = -1, $type = '')
6613- {
6614- global $XML_RPC_Types;
6615- $this->me = array();
6616- $this->mytype = 0;
6617- if ($val != -1 || $type != '') {
6618- if ($type == '') {
6619- $type = 'string';
6620- }
6621- if (!array_key_exists($type, $XML_RPC_Types)) {
6622- // XXX
6623- // need some way to report this error
6624- } elseif ($XML_RPC_Types[$type] == 1) {
6625- $this->addScalar($val, $type);
6626- } elseif ($XML_RPC_Types[$type] == 2) {
6627- $this->addArray($val);
6628- } elseif ($XML_RPC_Types[$type] == 3) {
6629- $this->addStruct($val);
6630- }
6631- }
6632- }
6633-
6634- /**
6635- * @return int returns 1 if successful or 0 if there are problems
6636- */
6637- function addScalar($val, $type = 'string')
6638- {
6639- global $XML_RPC_Types, $XML_RPC_Boolean;
6640-
6641- if ($this->mytype == 1) {
6642- $this->raiseError('Scalar can have only one value',
6643- XML_RPC_ERROR_INVALID_TYPE);
6644- return 0;
6645- }
6646- $typeof = $XML_RPC_Types[$type];
6647- if ($typeof != 1) {
6648- $this->raiseError("Not a scalar type (${typeof})",
6649- XML_RPC_ERROR_INVALID_TYPE);
6650- return 0;
6651- }
6652-
6653- if ($type == $XML_RPC_Boolean) {
6654- if (strcasecmp($val, 'true') == 0
6655- || $val == 1
6656- || ($val == true && strcasecmp($val, 'false')))
6657- {
6658- $val = 1;
6659- } else {
6660- $val = 0;
6661- }
6662- }
6663-
6664- if ($this->mytype == 2) {
6665- // we're adding to an array here
6666- $ar = $this->me['array'];
6667- $ar[] = new XML_RPC_Value($val, $type);
6668- $this->me['array'] = $ar;
6669- } else {
6670- // a scalar, so set the value and remember we're scalar
6671- $this->me[$type] = $val;
6672- $this->mytype = $typeof;
6673- }
6674- return 1;
6675- }
6676-
6677- /**
6678- * @return int returns 1 if successful or 0 if there are problems
6679- */
6680- function addArray($vals)
6681- {
6682- global $XML_RPC_Types;
6683- if ($this->mytype != 0) {
6684- $this->raiseError(
6685- 'Already initialized as a [' . $this->kindOf() . ']',
6686- XML_RPC_ERROR_ALREADY_INITIALIZED);
6687- return 0;
6688- }
6689- $this->mytype = $XML_RPC_Types['array'];
6690- $this->me['array'] = $vals;
6691- return 1;
6692- }
6693-
6694- /**
6695- * @return int returns 1 if successful or 0 if there are problems
6696- */
6697- function addStruct($vals)
6698- {
6699- global $XML_RPC_Types;
6700- if ($this->mytype != 0) {
6701- $this->raiseError(
6702- 'Already initialized as a [' . $this->kindOf() . ']',
6703- XML_RPC_ERROR_ALREADY_INITIALIZED);
6704- return 0;
6705- }
6706- $this->mytype = $XML_RPC_Types['struct'];
6707- $this->me['struct'] = $vals;
6708- return 1;
6709- }
6710-
6711- /**
6712- * @return void
6713- */
6714- function dump($ar)
6715- {
6716- reset($ar);
6717- while (list($key, $val) = each($ar)) {
6718- echo "$key => $val<br>";
6719- if ($key == 'array') {
6720- while (list($key2, $val2) = each($val)) {
6721- echo "-- $key2 => $val2<br>";
6722- }
6723- }
6724- }
6725- }
6726-
6727- /**
6728- * @return string the data type of the current value
6729- */
6730- function kindOf()
6731- {
6732- switch ($this->mytype) {
6733- case 3:
6734- return 'struct';
6735-
6736- case 2:
6737- return 'array';
6738-
6739- case 1:
6740- return 'scalar';
6741-
6742- default:
6743- return 'undef';
6744- }
6745- }
6746-
6747- /**
6748- * @return string the data in XML format
6749- */
6750- function serializedata($typ, $val)
6751- {
6752- $rs = '';
6753- global $XML_RPC_Types, $XML_RPC_Base64, $XML_RPC_String, $XML_RPC_Boolean;
6754- if (!array_key_exists($typ, $XML_RPC_Types)) {
6755- // XXX
6756- // need some way to report this error
6757- return;
6758- }
6759- switch ($XML_RPC_Types[$typ]) {
6760- case 3:
6761- // struct
6762- $rs .= "<struct>\n";
6763- reset($val);
6764- while (list($key2, $val2) = each($val)) {
6765- $rs .= "<member><name>${key2}</name>\n";
6766- $rs .= $this->serializeval($val2);
6767- $rs .= "</member>\n";
6768- }
6769- $rs .= '</struct>';
6770- break;
6771-
6772- case 2:
6773- // array
6774- $rs .= "<array>\n<data>\n";
6775- for ($i = 0; $i < sizeof($val); $i++) {
6776- $rs .= $this->serializeval($val[$i]);
6777- }
6778- $rs .= "</data>\n</array>";
6779- break;
6780-
6781- case 1:
6782- switch ($typ) {
6783- case $XML_RPC_Base64:
6784- $rs .= "<${typ}>" . base64_encode($val) . "</${typ}>";
6785- break;
6786- case $XML_RPC_Boolean:
6787- $rs .= "<${typ}>" . ($val ? '1' : '0') . "</${typ}>";
6788- break;
6789- case $XML_RPC_String:
6790- $rs .= "<${typ}>" . htmlspecialchars($val). "</${typ}>";
6791- break;
6792- default:
6793- $rs .= "<${typ}>${val}</${typ}>";
6794- }
6795- }
6796- return $rs;
6797- }
6798-
6799- /**
6800- * @return string the data in XML format
6801- */
6802- function serialize()
6803- {
6804- return $this->serializeval($this);
6805- }
6806-
6807- /**
6808- * @return string the data in XML format
6809- */
6810- function serializeval($o)
6811- {
6812- $rs = '';
6813- $ar = $o->me;
6814- reset($ar);
6815- list($typ, $val) = each($ar);
6816- $rs .= '<value>';
6817- $rs .= $this->serializedata($typ, $val);
6818- $rs .= "</value>\n";
6819- return $rs;
6820- }
6821-
6822- /**
6823- * @return mixed the contents of the element requested
6824- */
6825- function structmem($m)
6826- {
6827- return $this->me['struct'][$m];
6828- }
6829-
6830- /**
6831- * @return void
6832- */
6833- function structreset()
6834- {
6835- reset($this->me['struct']);
6836- }
6837-
6838- /**
6839- * @return the key/value pair of the struct's current element
6840- */
6841- function structeach()
6842- {
6843- return each($this->me['struct']);
6844- }
6845-
6846- /**
6847- * @return mixed the current value
6848- */
6849- function getval() {
6850- // UNSTABLE
6851- global $XML_RPC_BOOLEAN, $XML_RPC_Base64;
6852-
6853- reset($this->me);
6854- list($a, $b) = each($this->me);
6855-
6856- // contributed by I Sofer, 2001-03-24
6857- // add support for nested arrays to scalarval
6858- // i've created a new method here, so as to
6859- // preserve back compatibility
6860-
6861- if (is_array($b)) {
6862- foreach ($b as $id => $cont) {
6863- $b[$id] = $cont->scalarval();
6864- }
6865- }
6866-
6867- // add support for structures directly encoding php objects
6868- if (is_object($b)) {
6869- $t = get_object_vars($b);
6870- foreach ($t as $id => $cont) {
6871- $t[$id] = $cont->scalarval();
6872- }
6873- foreach ($t as $id => $cont) {
6874- eval('$b->'.$id.' = $cont;');
6875- }
6876- }
6877-
6878- // end contrib
6879- return $b;
6880- }
6881-
6882- /**
6883- * @return mixed
6884- */
6885- function scalarval()
6886- {
6887- global $XML_RPC_Boolean, $XML_RPC_Base64;
6888- reset($this->me);
6889- list($a, $b) = each($this->me);
6890- return $b;
6891- }
6892-
6893- /**
6894- * @return string
6895- */
6896- function scalartyp()
6897- {
6898- global $XML_RPC_I4, $XML_RPC_Int;
6899- reset($this->me);
6900- list($a, $b) = each($this->me);
6901- if ($a == $XML_RPC_I4) {
6902- $a = $XML_RPC_Int;
6903- }
6904- return $a;
6905- }
6906-
6907- /**
6908- * @return mixed the struct's current element
6909- */
6910- function arraymem($m)
6911- {
6912- return $this->me['array'][$m];
6913- }
6914-
6915- /**
6916- * @return int the number of elements in the array
6917- */
6918- function arraysize()
6919- {
6920- reset($this->me);
6921- list($a, $b) = each($this->me);
6922- return sizeof($b);
6923- }
6924-}
6925-
6926-/**
6927- * Return an ISO8601 encoded string
6928- *
6929- * While timezones ought to be supported, the XML-RPC spec says:
6930- *
6931- * "Don't assume a timezone. It should be specified by the server in its
6932- * documentation what assumptions it makes about timezones."
6933- *
6934- * This routine always assumes localtime unless $utc is set to 1, in which
6935- * case UTC is assumed and an adjustment for locale is made when encoding.
6936- *
6937- * @return string the formatted date
6938- */
6939-function XML_RPC_iso8601_encode($timet, $utc = 0) {
6940- if (!$utc) {
6941- $t = strftime('%Y%m%dT%H:%M:%S', $timet);
6942- } else {
6943- if (function_exists('gmstrftime')) {
6944- // gmstrftime doesn't exist in some versions
6945- // of PHP
6946- $t = gmstrftime('%Y%m%dT%H:%M:%S', $timet);
6947- } else {
6948- $t = strftime('%Y%m%dT%H:%M:%S', $timet - date('Z'));
6949- }
6950- }
6951- return $t;
6952-}
6953-
6954-/**
6955- * Convert a datetime string into a Unix timestamp
6956- *
6957- * While timezones ought to be supported, the XML-RPC spec says:
6958- *
6959- * "Don't assume a timezone. It should be specified by the server in its
6960- * documentation what assumptions it makes about timezones."
6961- *
6962- * This routine always assumes localtime unless $utc is set to 1, in which
6963- * case UTC is assumed and an adjustment for locale is made when encoding.
6964- *
6965- * @return int the unix timestamp of the date submitted
6966- */
6967-function XML_RPC_iso8601_decode($idate, $utc = 0) {
6968- $t = 0;
6969- if (ereg('([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})', $idate, $regs)) {
6970- if ($utc) {
6971- $t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
6972- } else {
6973- $t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
6974- }
6975- }
6976- return $t;
6977-}
6978-
6979-/**
6980- * Takes a message in PHP XML_RPC object format and translates it into
6981- * native PHP types
6982- *
6983- * @return mixed
6984- *
6985- * @author Dan Libby <dan@libby.com>
6986- */
6987-function XML_RPC_decode($XML_RPC_val)
6988-{
6989- $kind = $XML_RPC_val->kindOf();
6990-
6991- if ($kind == 'scalar') {
6992- return $XML_RPC_val->scalarval();
6993-
6994- } elseif ($kind == 'array') {
6995- $size = $XML_RPC_val->arraysize();
6996- $arr = array();
6997- for ($i = 0; $i < $size; $i++) {
6998- $arr[] = XML_RPC_decode($XML_RPC_val->arraymem($i));
6999- }
7000- return $arr;
7001-
7002- } elseif ($kind == 'struct') {
7003- $XML_RPC_val->structreset();
7004- $arr = array();
7005- while (list($key, $value) = $XML_RPC_val->structeach()) {
7006- $arr[$key] = XML_RPC_decode($value);
7007- }
7008- return $arr;
7009- }
7010-}
7011-
7012-/**
7013- * Takes native php types and encodes them into XML_RPC PHP object format
7014- *
7015- * Feature creep -- could support more types via optional type argument.
7016- *
7017- * @return string
7018- *
7019- * @author Dan Libby <dan@libby.com>
7020- */
7021-function XML_RPC_encode($php_val) {
7022- global $XML_RPC_Boolean, $XML_RPC_Int, $XML_RPC_Double, $XML_RPC_String,
7023- $XML_RPC_Array, $XML_RPC_Struct;
7024-
7025- $type = gettype($php_val);
7026- $XML_RPC_val = new XML_RPC_Value;
7027-
7028- switch ($type) {
7029- case 'array':
7030- if (empty($php_val)) {
7031- $XML_RPC_val->addArray($php_val);
7032- break;
7033- }
7034- $tmp = array_diff(array_keys($php_val), range(0, count($php_val)-1));
7035- if (empty($tmp)) {
7036- $arr = array();
7037- foreach ($php_val as $k => $v) {
7038- $arr[$k] = XML_RPC_encode($v);
7039- }
7040- $XML_RPC_val->addArray($arr);
7041- break;
7042- }
7043- // fall though if it's not an enumerated array
7044-
7045- case 'object':
7046- $arr = array();
7047- foreach ($php_val as $k => $v) {
7048- $arr[$k] = XML_RPC_encode($v);
7049- }
7050- $XML_RPC_val->addStruct($arr);
7051- break;
7052-
7053- case 'integer':
7054- $XML_RPC_val->addScalar($php_val, $XML_RPC_Int);
7055- break;
7056-
7057- case 'double':
7058- $XML_RPC_val->addScalar($php_val, $XML_RPC_Double);
7059- break;
7060-
7061- case 'string':
7062- case 'NULL':
7063- $XML_RPC_val->addScalar($php_val, $XML_RPC_String);
7064- break;
7065-
7066- case 'boolean':
7067- // Add support for encoding/decoding of booleans, since they
7068- // are supported in PHP
7069- // by <G_Giunta_2001-02-29>
7070- $XML_RPC_val->addScalar($php_val, $XML_RPC_Boolean);
7071- break;
7072-
7073- case 'unknown type':
7074- default:
7075- $XML_RPC_val = false;
7076- }
7077- return $XML_RPC_val;
7078-}
7079-
7080-/*
7081- * Local variables:
7082- * tab-width: 4
7083- * c-basic-offset: 4
7084- * c-hanging-comment-ender-p: nil
7085- * End:
7086- */
7087-
7088-?>
7089-XML_RPC-1.2.2/Server.php
7090-
7091-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
7092-
7093-/**
7094- * PHP implementation of the XML-RPC protocol
7095- *
7096- * This is a PEAR-ified version of Useful inc's XML-RPC for PHP.
7097- * It has support for HTTP transport, proxies and authentication.
7098- *
7099- * PHP versions 4 and 5
7100- *
7101- * LICENSE: License is granted to use or modify this software
7102- * ("XML-RPC for PHP") for commercial or non-commercial use provided the
7103- * copyright of the author is preserved in any distributed or derivative work.
7104- *
7105- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESSED OR
7106- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
7107- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
7108- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
7109- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
7110- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
7111- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
7112- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7113- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
7114- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7115- *
7116- * @category Web Services
7117- * @package XML_RPC
7118- * @author Edd Dumbill <edd@usefulinc.com>
7119- * @author Stig Bakken <stig@php.net>
7120- * @author Martin Jansen <mj@php.net>
7121- * @copyright 1999-2001 Edd Dumbill
7122- * @version CVS: $Id: Server.php,v 1.17 2005/03/01 17:09:49 danielc Exp $
7123- * @link http://pear.php.net/package/XML_RPC
7124- */
7125-
7126-
7127-/**
7128- * Pull in the XML_RPC class
7129- */
7130-require_once 'XML/RPC.php';
7131-
7132-
7133-/**
7134- * listMethods: either a string, or nothing
7135- * @global array $GLOBALS['XML_RPC_Server_listMethods_sig']
7136- */
7137-$GLOBALS['XML_RPC_Server_listMethods_sig'] = array(
7138- array($GLOBALS['XML_RPC_Array'],
7139- $GLOBALS['XML_RPC_String']
7140- ),
7141- array($GLOBALS['XML_RPC_Array'])
7142-);
7143-
7144-/**
7145- * @global string $GLOBALS['XML_RPC_Server_listMethods_doc']
7146- */
7147-$GLOBALS['XML_RPC_Server_listMethods_doc'] = 'This method lists all the'
7148- . ' methods that the XML-RPC server knows how to dispatch';
7149-
7150-/**
7151- * @global array $GLOBALS['XML_RPC_Server_methodSignature_sig']
7152- */
7153-$GLOBALS['XML_RPC_Server_methodSignature_sig'] = array(
7154- array($GLOBALS['XML_RPC_Array'],
7155- $GLOBALS['XML_RPC_String']
7156- )
7157-);
7158-
7159-/**
7160- * @global string $GLOBALS['XML_RPC_Server_methodSignature_doc']
7161- */
7162-$GLOBALS['XML_RPC_Server_methodSignature_doc'] = 'Returns an array of known'
7163- . ' signatures (an array of arrays) for the method name passed. If'
7164- . ' no signatures are known, returns a none-array (test for type !='
7165- . ' array to detect missing signature)';
7166-
7167-/**
7168- * @global array $GLOBALS['XML_RPC_Server_methodHelp_sig']
7169- */
7170-$GLOBALS['XML_RPC_Server_methodHelp_sig'] = array(
7171- array($GLOBALS['XML_RPC_String'],
7172- $GLOBALS['XML_RPC_String']
7173- )
7174-);
7175-
7176-/**
7177- * @global string $GLOBALS['XML_RPC_Server_methodHelp_doc']
7178- */
7179-$GLOBALS['XML_RPC_Server_methodHelp_doc'] = 'Returns help text if defined'
7180- . ' for the method passed, otherwise returns an empty string';
7181-
7182-/**
7183- * @global array $GLOBALS['XML_RPC_Server_dmap']
7184- */
7185-$GLOBALS['XML_RPC_Server_dmap'] = array(
7186- 'system.listMethods' => array(
7187- 'function' => 'XML_RPC_Server_listMethods',
7188- 'signature' => $GLOBALS['XML_RPC_Server_listMethods_sig'],
7189- 'docstring' => $GLOBALS['XML_RPC_Server_listMethods_doc']
7190- ),
7191- 'system.methodHelp' => array(
7192- 'function' => 'XML_RPC_Server_methodHelp',
7193- 'signature' => $GLOBALS['XML_RPC_Server_methodHelp_sig'],
7194- 'docstring' => $GLOBALS['XML_RPC_Server_methodHelp_doc']
7195- ),
7196- 'system.methodSignature' => array(
7197- 'function' => 'XML_RPC_Server_methodSignature',
7198- 'signature' => $GLOBALS['XML_RPC_Server_methodSignature_sig'],
7199- 'docstring' => $GLOBALS['XML_RPC_Server_methodSignature_doc']
7200- )
7201-);
7202-
7203-/**
7204- * @global string $GLOBALS['XML_RPC_Server_debuginfo']
7205- */
7206-$GLOBALS['XML_RPC_Server_debuginfo'] = '';
7207-
7208-
7209-/**
7210- * Lists all the methods that the XML-RPC server knows how to dispatch
7211- *
7212- * @return object a new XML_RPC_Response object
7213- */
7214-function XML_RPC_Server_listMethods($server, $m)
7215-{
7216- global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
7217-
7218- $v = new XML_RPC_Value();
7219- $dmap = $server->dmap;
7220- $outAr = array();
7221- for (reset($dmap); list($key, $val) = each($dmap); ) {
7222- $outAr[] = new XML_RPC_Value($key, 'string');
7223- }
7224- $dmap = $XML_RPC_Server_dmap;
7225- for (reset($dmap); list($key, $val) = each($dmap); ) {
7226- $outAr[] = new XML_RPC_Value($key, 'string');
7227- }
7228- $v->addArray($outAr);
7229- return new XML_RPC_Response($v);
7230-}
7231-
7232-/**
7233- * Returns an array of known signatures (an array of arrays)
7234- * for the given method
7235- *
7236- * If no signatures are known, returns a none-array
7237- * (test for type != array to detect missing signature)
7238- *
7239- * @return object a new XML_RPC_Response object
7240- */
7241-function XML_RPC_Server_methodSignature($server, $m)
7242-{
7243- global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
7244-
7245- $methName = $m->getParam(0);
7246- $methName = $methName->scalarval();
7247- if (strpos($methName, 'system.') === 0) {
7248- $dmap = $XML_RPC_Server_dmap;
7249- $sysCall = 1;
7250- } else {
7251- $dmap = $server->dmap;
7252- $sysCall = 0;
7253- }
7254- // print "<!-- ${methName} -->\n";
7255- if (isset($dmap[$methName])) {
7256- if ($dmap[$methName]['signature']) {
7257- $sigs = array();
7258- $thesigs = $dmap[$methName]['signature'];
7259- for ($i = 0; $i < sizeof($thesigs); $i++) {
7260- $cursig = array();
7261- $inSig = $thesigs[$i];
7262- for ($j = 0; $j < sizeof($inSig); $j++) {
7263- $cursig[] = new XML_RPC_Value($inSig[$j], 'string');
7264- }
7265- $sigs[] = new XML_RPC_Value($cursig, 'array');
7266- }
7267- $r = new XML_RPC_Response(new XML_RPC_Value($sigs, 'array'));
7268- } else {
7269- $r = new XML_RPC_Response(new XML_RPC_Value('undef', 'string'));
7270- }
7271- } else {
7272- $r = new XML_RPC_Response(0, $XML_RPC_err['introspect_unknown'],
7273- $XML_RPC_str['introspect_unknown']);
7274- }
7275- return $r;
7276-}
7277-
7278-/**
7279- * Returns help text if defined for the method passed, otherwise returns
7280- * an empty string
7281- *
7282- * @return object a new XML_RPC_Response object
7283- */
7284-function XML_RPC_Server_methodHelp($server, $m)
7285-{
7286- global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
7287-
7288- $methName = $m->getParam(0);
7289- $methName = $methName->scalarval();
7290- if (strpos($methName, 'system.') === 0) {
7291- $dmap = $XML_RPC_Server_dmap;
7292- $sysCall = 1;
7293- } else {
7294- $dmap = $server->dmap;
7295- $sysCall = 0;
7296- }
7297- // print "<!-- ${methName} -->\n";
7298- if (isset($dmap[$methName])) {
7299- if ($dmap[$methName]['docstring']) {
7300- $r = new XML_RPC_Response(new XML_RPC_Value($dmap[$methName]['docstring']),
7301- 'string');
7302- } else {
7303- $r = new XML_RPC_Response(new XML_RPC_Value('', 'string'));
7304- }
7305- } else {
7306- $r = new XML_RPC_Response(0, $XML_RPC_err['introspect_unknown'],
7307- $XML_RPC_str['introspect_unknown']);
7308- }
7309- return $r;
7310-}
7311-
7312-/**
7313- * @return void
7314- */
7315-function XML_RPC_Server_debugmsg($m)
7316-{
7317- global $XML_RPC_Server_debuginfo;
7318- $XML_RPC_Server_debuginfo = $XML_RPC_Server_debuginfo . $m . "\n";
7319-}
7320-
7321-
7322-/**
7323- *
7324- *
7325- * @category Web Services
7326- * @package XML_RPC
7327- * @author Edd Dumbill <edd@usefulinc.com>
7328- * @author Stig Bakken <stig@php.net>
7329- * @author Martin Jansen <mj@php.net>
7330- * @copyright 1999-2001 Edd Dumbill
7331- * @version Release: 1.2.2
7332- * @link http://pear.php.net/package/XML_RPC
7333- */
7334-class XML_RPC_Server
7335-{
7336- var $dmap = array();
7337- var $encoding = '';
7338- var $debug = 0;
7339-
7340- /**
7341- * @return void
7342- */
7343- function XML_RPC_Server($dispMap, $serviceNow = 1, $debug = 0)
7344- {
7345- global $HTTP_RAW_POST_DATA;
7346-
7347- if ($debug) {
7348- $this->debug = 1;
7349- } else {
7350- $this->debug = 0;
7351- }
7352-
7353- // dispMap is a despatch array of methods
7354- // mapped to function names and signatures
7355- // if a method
7356- // doesn't appear in the map then an unknown
7357- // method error is generated
7358- $this->dmap = $dispMap;
7359- if ($serviceNow) {
7360- $this->service();
7361- }
7362- }
7363-
7364- /**
7365- * @return string the debug information if debug debug mode is on
7366- */
7367- function serializeDebug()
7368- {
7369- global $XML_RPC_Server_debuginfo, $HTTP_RAW_POST_DATA;
7370-
7371- if ($this->debug) {
7372- XML_RPC_Server_debugmsg('vvv POST DATA RECEIVED BY SERVER vvv' . "\n"
7373- . $HTTP_RAW_POST_DATA
7374- . "\n" . '^^^ END POST DATA ^^^');
7375- }
7376-
7377- if ($XML_RPC_Server_debuginfo != '') {
7378- return "<!-- PEAR XML_RPC SERVER DEBUG INFO:\n\n"
7379- . preg_replace('/-(?=-)/', '- ', $XML_RPC_Server_debuginfo)
7380- . "-->\n";
7381- } else {
7382- return '';
7383- }
7384- }
7385-
7386- /**
7387- * Print out the result
7388- *
7389- * The encoding and content-type are determined by
7390- * XML_RPC_Message::getEncoding()
7391- *
7392- * @return void
7393- *
7394- * @see XML_RPC_Message::getEncoding()
7395- */
7396- function service()
7397- {
7398- $r = $this->parseRequest();
7399- $payload = '<?xml version="1.0" encoding="'
7400- . $this->encoding . '"?>' . "\n"
7401- . $this->serializeDebug()
7402- . $r->serialize();
7403- header('Content-Length: ' . strlen($payload));
7404- header('Content-Type: text/xml; charset=' . $this->encoding);
7405- print $payload;
7406- }
7407-
7408- /**
7409- * @return array
7410- */
7411- function verifySignature($in, $sig)
7412- {
7413- for ($i = 0; $i < sizeof($sig); $i++) {
7414- // check each possible signature in turn
7415- $cursig = $sig[$i];
7416- if (sizeof($cursig) == $in->getNumParams() + 1) {
7417- $itsOK = 1;
7418- for ($n = 0; $n < $in->getNumParams(); $n++) {
7419- $p = $in->getParam($n);
7420- // print "<!-- $p -->\n";
7421- if ($p->kindOf() == 'scalar') {
7422- $pt = $p->scalartyp();
7423- } else {
7424- $pt = $p->kindOf();
7425- }
7426- // $n+1 as first type of sig is return type
7427- if ($pt != $cursig[$n+1]) {
7428- $itsOK = 0;
7429- $pno = $n+1;
7430- $wanted = $cursig[$n+1];
7431- $got = $pt;
7432- break;
7433- }
7434- }
7435- if ($itsOK) {
7436- return array(1);
7437- }
7438- }
7439- }
7440- return array(0, "Wanted ${wanted}, got ${got} at param ${pno})");
7441- }
7442-
7443- /**
7444- * @return object a new XML_RPC_Response object
7445- */
7446- function parseRequest($data = '')
7447- {
7448- global $XML_RPC_xh, $HTTP_RAW_POST_DATA,
7449- $XML_RPC_err, $XML_RPC_str, $XML_RPC_errxml,
7450- $XML_RPC_defencoding, $XML_RPC_Server_dmap;
7451-
7452- if ($data == '') {
7453- $data = $HTTP_RAW_POST_DATA;
7454- }
7455-
7456- $this->encoding = XML_RPC_Message::getEncoding($data);
7457- $parser = xml_parser_create($this->encoding);
7458-
7459- $XML_RPC_xh[$parser] = array();
7460- $XML_RPC_xh[$parser]['st'] = '';
7461- $XML_RPC_xh[$parser]['cm'] = 0;
7462- $XML_RPC_xh[$parser]['isf'] = 0;
7463- $XML_RPC_xh[$parser]['params'] = array();
7464- $XML_RPC_xh[$parser]['method'] = '';
7465-
7466- $plist = '';
7467-
7468- // decompose incoming XML into request structure
7469-
7470- xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
7471- xml_set_element_handler($parser, 'XML_RPC_se', 'XML_RPC_ee');
7472- xml_set_character_data_handler($parser, 'XML_RPC_cd');
7473- if (!xml_parse($parser, $data, 1)) {
7474- // return XML error as a faultCode
7475- $r = new XML_RPC_Response(0,
7476- $XML_RPC_errxml+xml_get_error_code($parser),
7477- sprintf('XML error: %s at line %d',
7478- xml_error_string(xml_get_error_code($parser)),
7479- xml_get_current_line_number($parser)));
7480- xml_parser_free($parser);
7481- } else {
7482- xml_parser_free($parser);
7483- $m = new XML_RPC_Message($XML_RPC_xh[$parser]['method']);
7484- // now add parameters in
7485- for ($i = 0; $i < sizeof($XML_RPC_xh[$parser]['params']); $i++) {
7486- // print '<!-- ' . $XML_RPC_xh[$parser]['params'][$i]. "-->\n";
7487- $plist .= "$i - " . $XML_RPC_xh[$parser]['params'][$i] . " \n";
7488- eval('$m->addParam(' . $XML_RPC_xh[$parser]['params'][$i] . ');');
7489- }
7490- XML_RPC_Server_debugmsg($plist);
7491-
7492- // now to deal with the method
7493- $methName = $XML_RPC_xh[$parser]['method'];
7494- if (strpos($methName, 'system.') === 0) {
7495- $dmap = $XML_RPC_Server_dmap;
7496- $sysCall = 1;
7497- } else {
7498- $dmap = $this->dmap;
7499- $sysCall = 0;
7500- }
7501-
7502- if (isset($dmap[$methName]['function'])
7503- && is_string($dmap[$methName]['function'])
7504- && strpos($dmap[$methName]['function'], '::') !== false)
7505- {
7506- $dmap[$methName]['function'] =
7507- explode('::', $dmap[$methName]['function']);
7508- }
7509-
7510- if (isset($dmap[$methName]['function'])
7511- && is_callable($dmap[$methName]['function']))
7512- {
7513- // dispatch if exists
7514- if (isset($dmap[$methName]['signature'])) {
7515- $sr = $this->verifySignature($m,
7516- $dmap[$methName]['signature'] );
7517- }
7518- if ( (!isset($dmap[$methName]['signature'])) || $sr[0]) {
7519- // if no signature or correct signature
7520- if ($sysCall) {
7521- $r = call_user_func($dmap[$methName]['function'], $this, $m);
7522- } else {
7523- $r = call_user_func($dmap[$methName]['function'], $m);
7524- }
7525- } else {
7526- $r = new XML_RPC_Response(0, $XML_RPC_err['incorrect_params'],
7527- $XML_RPC_str['incorrect_params']
7528- . ': ' . $sr[1]);
7529- }
7530- } else {
7531- // else prepare error response
7532- $r = new XML_RPC_Response(0, $XML_RPC_err['unknown_method'],
7533- $XML_RPC_str['unknown_method']);
7534- }
7535- }
7536- return $r;
7537- }
7538-
7539- /**
7540- * Echos back the input packet as a string value
7541- *
7542- * @return void
7543- *
7544- * Useful for debugging.
7545- */
7546- function echoInput() {
7547- global $HTTP_RAW_POST_DATA;
7548-
7549- $r = new XML_RPC_Response(0);
7550- $r->xv = new XML_RPC_Value("'Aha said I: '" . $HTTP_RAW_POST_DATA, 'string');
7551- print $r->serialize();
7552- }
7553-}
7554-
7555-/*
7556- * Local variables:
7557- * tab-width: 4
7558- * c-basic-offset: 4
7559- * c-hanging-comment-ender-p: nil
7560- * End:
7561- */
7562-
7563-?>
7564-
7565-<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/package-1.0">
7566-<package version="1.0" packagerversion="1.4.0a1">
7567- <name>XML_RPC</name>
7568- <summary>PHP implementation of the XML-RPC protocol</summary>
7569- <description>A PEAR-ified version of Useful Inc's XML-RPC for PHP.
7570-
7571-It has support for HTTP/HTTPS transport, proxies and authentication.
7572- </description>
7573- <maintainers>
7574- <maintainer>
7575- <user>ssb</user>
7576- <name>Stig Bakken</name>
7577- <email>stig@php.net</email>
7578- <role>lead</role>
7579- </maintainer>
7580- <maintainer>
7581- <user>danielc</user>
7582- <name>Daniel Convissor</name>
7583- <email>danielc@php.net</email>
7584- <role>lead</role>
7585- </maintainer>
7586- </maintainers>
7587- <release>
7588- <version>1.2.2</version>
7589- <date>2005-03-07</date>
7590- <license>PHP License</license>
7591- <state>stable</state>
7592- <notes>* When using a proxy, add the protocol to the Request-URI, making it an &quot;absoluteURI&quot; as per the HTTP 1.0 spec. Bug 3679.
7593- </notes>
7594- <filelist>
7595- <file role="php" baseinstalldir="XML" name="RPC.php">
7596- <replace from="@package_version@" to="version" type="package-info"/>
7597- </file>
7598- <file role="php" baseinstalldir="XML/RPC" name="Server.php">
7599- <replace from="@package_version@" to="version" type="package-info"/>
7600- </file>
7601- <file role="php" baseinstalldir="XML/RPC" name="Dump.php">
7602- <replace from="@package_version@" to="version" type="package-info"/>
7603- </file>
7604- <file role="test" name="tests/protoport.php">
7605- <replace from="@package_version@" to="version" type="package-info"/>
7606- </file>
7607- <file role="test" name="tests/test_Dump.php">
7608- <replace from="@package_version@" to="version" type="package-info"/>
7609- </file>
7610- </filelist>
7611- </release>
7612- <changelog>
7613- <release>
7614- <version>1.2.1</version>
7615- <date>2005-03-01</date>
7616- <state>stable</state>
7617- <notes>* Add isset() check before examining the dispatch map. Bug 3658.
7618- </notes>
7619- </release>
7620- <release>
7621- <version>1.2.0</version>
7622- <date>2005-02-27</date>
7623- <state>stable</state>
7624- <notes>* Provide the &quot;stable&quot; release.
7625-* Add package2.xml for compatibility with PEAR 1.4.0.
7626-* For changes since 1.1.0, see the changelogs for the various RC releases.
7627- </notes>
7628- </release>
7629- <release>
7630- <version>1.2.0RC7</version>
7631- <date>2005-02-22</date>
7632- <state>beta</state>
7633- <notes>* Add the setSendEncoding() method and $send_encoding
7634- property to XML_RPC_Message. Request 3537.
7635-* Allow class methods to be mapped using either syntax:
7636- 'function' =&gt; 'hello::sayHello',
7637- or
7638- 'function' =&gt; array('hello', 'sayhello'),
7639- Bug 3363.
7640-* Use 8192 instead of 32768 for bytes in fread()
7641- in parseResponseFile(). Bug 3340.
7642- </notes>
7643- </release>
7644- <release>
7645- <version>1.2.0RC6</version>
7646- <date>2005-01-25</date>
7647- <state>beta</state>
7648- <notes>* Don't put the protocol in the Host field of the POST data. (danielc)
7649- </notes>
7650- </release>
7651- <release>
7652- <version>1.2.0RC5</version>
7653- <date>2005-01-24</date>
7654- <state>beta</state>
7655- <notes>* If $port is 443 but a protocol isn't specified in $server, assume ssl:// is the protocol.
7656- </notes>
7657- </release>
7658- <release>
7659- <version>1.2.0RC4</version>
7660- <date>2005-01-24</date>
7661- <state>beta</state>
7662- <notes>* When a connection attempt fails, have the method return 0. (danielc)
7663-* Move the protocol/port checking/switching and the property settings from sendPayloadHTTP10() to the XML_RPC_Client constructor. (danielc)
7664-* Add tests for setting the client properties. (danielc)
7665-* Remove $GLOBALS['XML_RPC_twoslash'] since it's not used. (danielc)
7666-* Bundle the tests with the package. (danielc)
7667- </notes>
7668- </release>
7669- <release>
7670- <version>1.2.0RC3</version>
7671- <date>2005-01-19</date>
7672- <state>beta</state>
7673- <notes>* ssl uses port 443, not 445.
7674- </notes>
7675- </release>
7676- <release>
7677- <version>1.2.0RC2</version>
7678- <date>2005-01-11</date>
7679- <state>beta</state>
7680- <notes>* Handle ssl:// in the $server string. (danielc)
7681-* Also default to port 445 for ssl:// requests as well. (danielc)
7682-* Enhance debugging in the server. (danielc)
7683- </notes>
7684- </release>
7685- <release>
7686- <version>1.2.0RC1</version>
7687- <date>2004-12-30</date>
7688- <state>beta</state>
7689- <notes>* Make things work with SSL. Bug 2489. (nkukard lbsd net)
7690-* Allow array function callbacks (Matt Kane)
7691-* Some minor speed-ups (Matt Kane)
7692-* Add Dump.php to the package (Christian Weiske)
7693-* Replace all line endings with \r\n. Had only done replacements on \n. Bug 2521. (danielc)
7694-* Silence fsockopen() errors. Bug 1714. (danielc)
7695-* Encode empty arrays as an array. Bug 1493. (danielc)
7696-* Eliminate undefined index notice when submitting empty arrays to XML_RPC_Encode(). Bug 1819. (danielc)
7697-* Speed up check for enumerated arrays in XML_RPC_Encode(). (danielc)
7698-* Prepend &quot;XML_RPC_&quot; to ERROR_NON_NUMERIC_FOUND, eliminating problem when eval()'ing error messages. (danielc)
7699-* Use XML_RPC_Base::raiseError() instead of PEAR::raiseError() in XML_RPC_ee() because PEAR.php is lazy loaded. (danielc)
7700-* Allow raiseError() to be called statically. (danielc)
7701-* Stop double escaping of character entities. Bug 987. (danielc)
7702- NOTICE: the following have been removed:
7703- * XML_RPC_dh()
7704- * $GLOBALS['XML_RPC_entities']
7705- * XML_RPC_entity_decode()
7706- * XML_RPC_lookup_entity()
7707-* Determine the XML's encoding via the encoding attribute in the XML declaration. Bug 52. (danielc)
7708- </notes>
7709- </release>
7710- <release>
7711- <version>1.1.0</version>
7712- <date>2004-03-15</date>
7713- <state>stable</state>
7714- <notes>* Added support for sequential arrays to XML_RPC_encode() (mroch)
7715-* Cleaned up new XML_RPC_encode() changes a bit (mroch, pierre)
7716-* Remove &quot;require_once 'PEAR.php'&quot;, include only when needed to raise an error
7717-* Replace echo and error_log() with raiseError() (mroch)
7718-* Make all classes extend XML_RPC_Base, which will handle common functions (mroch)
7719-* be tolerant of junk after methodResponse (Luca Mariano, mroch)
7720-* Silent notice even in the error log (pierre)
7721-* fix include of shared xml extension on win32 (pierre)
7722- </notes>
7723- </release>
7724- <release>
7725- <version>1.0.4</version>
7726- <date>2002-10-02</date>
7727- <state>stable</state>
7728- <notes>* added HTTP proxy authorization support (thanks to Arnaud Limbourg)
7729- </notes>
7730- </release>
7731- <release>
7732- <version>1.0.3</version>
7733- <date>2002-05-19</date>
7734- <state>stable</state>
7735- <notes>* fix bug when parsing responses with boolean types
7736- </notes>
7737- </release>
7738- <release>
7739- <version>1.0.2</version>
7740- <date>2002-04-16</date>
7741- <state>stable</state>
7742- <notes>* E_ALL fixes
7743-* fix HTTP response header parsing
7744- </notes>
7745- </release>
7746- <release>
7747- <version>1.0.1</version>
7748- <date>2001-09-25</date>
7749- <state>stable</state>
7750- <notes>This is a PEAR-ified version of Useful Inc's 1.0.1 release.
7751-Includes an urgent security fix identified by Dan Libby &lt;dan@libby.com&gt;.
7752- </notes>
7753- </release>
7754- </changelog>
7755-</package>
7756-
7757\ Kein Zeilenumbruch am Dateiende.
7758diff -Nura php-4.3.11/pear/packages/XML_RPC-1.4.0.tar hardening-patch-4.3.11-0.4.2/pear/packages/XML_RPC-1.4.0.tar
7759--- php-4.3.11/pear/packages/XML_RPC-1.4.0.tar 1970-01-01 01:00:00.000000000 +0100
7760+++ hardening-patch-4.3.11-0.4.2/pear/packages/XML_RPC-1.4.0.tar 2005-09-07 19:04:56.246906192 +0200
7761@@ -0,0 +1,3933 @@
7762+package2.xml
7763+<package packagerversion="1.4.0a12" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
7764+ <name>XML_RPC</name>
7765+ <channel>pear.php.net</channel>
7766+ <summary>PHP implementation of the XML-RPC protocol</summary>
7767+ <description>A PEAR-ified version of Useful Inc&apos;s XML-RPC for PHP.
7768+
7769+It has support for HTTP/HTTPS transport, proxies and authentication.</description>
7770+ <lead>
7771+ <name>Stig Bakken</name>
7772+ <user>ssb</user>
7773+ <email>stig@php.net</email>
7774+ <active>no</active>
7775+ </lead>
7776+ <lead>
7777+ <name>Daniel Convissor</name>
7778+ <user>danielc</user>
7779+ <email>danielc@php.net</email>
7780+ <active>yes</active>
7781+ </lead>
7782+ <date>2005-08-14</date>
7783+ <time>16:30:30</time>
7784+ <version>
7785+ <release>1.4.0</release>
7786+ <api>1.4.0</api>
7787+ </version>
7788+ <stability>
7789+ <release>stable</release>
7790+ <api>stable</api>
7791+ </stability>
7792+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
7793+ <notes>* MAJOR SECURITY FIX: eliminate use of eval().
7794+* Using socket_get_status() because stream_get_meta_data() was introduced in 4.3.0, but we need to support 4.2.0. Bug 4805.</notes>
7795+ <contents>
7796+ <dir name="/">
7797+ <file md5sum="952733184950487ec0cee78cf05bedc4" name="tests/protoport.php" role="test">
7798+ <tasks:replace from="@package_version@" to="version" type="package-info" />
7799+ </file>
7800+ <file md5sum="239a5b407054852b6f470f043a44d8be" name="tests/test_Dump.php" role="test">
7801+ <tasks:replace from="@package_version@" to="version" type="package-info" />
7802+ </file>
7803+ <file baseinstalldir="XML/RPC" md5sum="80df8443b5e6c2919de012df1f1d7997" name="Dump.php" role="php">
7804+ <tasks:replace from="@package_version@" to="version" type="package-info" />
7805+ </file>
7806+ <file baseinstalldir="XML" md5sum="5c26e8fae482ba8c123c71c2c8c3fabc" name="RPC.php" role="php">
7807+ <tasks:replace from="@package_version@" to="version" type="package-info" />
7808+ </file>
7809+ <file baseinstalldir="XML/RPC" md5sum="8bded286786fb010879abdf88493ecca" name="Server.php" role="php">
7810+ <tasks:replace from="@package_version@" to="version" type="package-info" />
7811+ </file>
7812+ </dir>
7813+ </contents>
7814+ <compatible>
7815+ <name>PEAR</name>
7816+ <channel>pear.php.net</channel>
7817+ <min>1.4.0a1</min>
7818+ <max>1.4.0a12</max>
7819+ </compatible>
7820+ <dependencies>
7821+ <required>
7822+ <php>
7823+ <min>4.2.0</min>
7824+ <max>6.0.0</max>
7825+ </php>
7826+ <pearinstaller>
7827+ <min>1.4.0a1</min>
7828+ </pearinstaller>
7829+ </required>
7830+ </dependencies>
7831+ <phprelease />
7832+ <changelog>
7833+ <release>
7834+ <version>
7835+ <release>1.3.3</release>
7836+ <api>1.3.0</api>
7837+ </version>
7838+ <stability>
7839+ <release>stable</release>
7840+ <api>stable</api>
7841+ </stability>
7842+ <date>2005-07-15</date>
7843+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
7844+ <notes>* Eliminate memory leak by resetting $XML_RPC_xh each time parseResponse() is called. Bug 4780.
7845+* Using socket_set_timeout() because stream_set_timeout() was introduced in 4.3.0, but we need to support 4.2.0. Bug 4805.</notes>
7846+ </release>
7847+ <release>
7848+ <version>
7849+ <release>1.3.2</release>
7850+ <api>1.3.0</api>
7851+ </version>
7852+ <stability>
7853+ <release>stable</release>
7854+ <api>stable</api>
7855+ </stability>
7856+ <date>2005-07-07</date>
7857+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
7858+ <notes>* Eliminate path disclosure vulnerabilities by suppressing error messages when eval()&apos;ing.
7859+* Eliminate path disclosure vulnerability by catching bogus parameters submitted to XML_RPC_Value::serializeval().
7860+* In XML_RPC_Server::service(), only call createServerPayload() and createServerHeaders() if necessary. Fixes compatibility issue introduced in Release 1.3.0RC1 for users who set the $serviceNow parameter of XML_RPC_Server() to 0. Bug 4757.
7861+* Change &quot;var $errstring&quot; to &quot;var $errstr&quot;. Bug 4582. Was put into CVS version 1.75 of RPC.php but didn&apos;t make it into RELEASE_1_3_1.</notes>
7862+ </release>
7863+ <release>
7864+ <version>
7865+ <release>1.3.1</release>
7866+ <api>1.3.0</api>
7867+ </version>
7868+ <stability>
7869+ <release>stable</release>
7870+ <api>stable</api>
7871+ </stability>
7872+ <date>2005-06-29</date>
7873+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
7874+ <notes>* Security fix. Update highly recommended!</notes>
7875+ </release>
7876+ <release>
7877+ <version>
7878+ <release>1.3.0</release>
7879+ <api>1.3.0</api>
7880+ </version>
7881+ <stability>
7882+ <release>stable</release>
7883+ <api>stable</api>
7884+ </stability>
7885+ <date>2005-06-13</date>
7886+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
7887+ <notes>* Stable release. See earlier releases for changes since 1.2.2.</notes>
7888+ </release>
7889+ <release>
7890+ <version>
7891+ <release>1.3.0RC3</release>
7892+ <api>1.3.0</api>
7893+ </version>
7894+ <stability>
7895+ <release>beta</release>
7896+ <api>stable</api>
7897+ </stability>
7898+ <date>2005-05-10</date>
7899+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
7900+ <notes>* When verifying requests against function signatures, if the number of parameters don&apos;t match, provide an appropriate message. NOTE: this resolves a path disclosure vulnerability. (Refines the changes made in the last commit.) Bug 4231.
7901+* XML_RPC_Message::getParam() now returns an XML_RPC_Response object upon error. Changed from Release 1.3.0RC2.
7902+* Add the XML_RPC_Value::isValue() method. For testing if an item is an XML_RPC_Value object.
7903+* If XML_RPC_Client::send() is given an incorrect $msg parameter, raise an error with the new XML_RPC_ERROR_PROGRAMMING code and return 0.
7904+* Improve cross-platform operation by using PEAR::loadExtension() instead of dl().
7905+* Use &lt;br /&gt; instead of &lt;br&gt; in XML_RPC_Value::dump().</notes>
7906+ </release>
7907+ <release>
7908+ <version>
7909+ <release>1.3.0RC2</release>
7910+ <api>1.3.0</api>
7911+ </version>
7912+ <stability>
7913+ <release>beta</release>
7914+ <api>beta</api>
7915+ </stability>
7916+ <date>2005-05-05</date>
7917+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
7918+ <notes>* If XML_RPC_Message::getParam() is given an incorrect parameter, raise an error with the new XML_RPC_ERROR_INCORRECT_PARAMS code and return FALSE.
7919+* Handle improper requests to XML_RPC_Server::verifySignature(). Bug 4231.
7920+* Try to allow HTTP 100 responses if followed by a 200 response. Bug 4116.
7921+* Help Delphi users by making RPCMETHODNAME an alias for METHODNAME. Request 4205.</notes>
7922+ </release>
7923+ <release>
7924+ <version>
7925+ <release>1.3.0RC1</release>
7926+ <api>1.3.0</api>
7927+ </version>
7928+ <stability>
7929+ <release>beta</release>
7930+ <api>beta</api>
7931+ </stability>
7932+ <date>2005-04-07</date>
7933+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
7934+ <notes>* Improve timeout handling for situations where connection to server is made but no response is not received in time. Accomplished via stream_set_timeout(). Request 3963.
7935+* Add Fault Code 6: &quot;The requested method didn&apos;t return an XML_RPC_Response object.&quot; Request 4032.
7936+* Add the createServerPayload() and createServerHeaders() methods and the $server_payload and $server_headers properties. Request 3121.
7937+* As in earlier versions, if the $serviceNow parameter to XML_RPC_Server() is 0, no data will be returned, but now the new $server_payload and $server_headers properties will be set.
7938+* Convert the parser handle to an integer before using it as an index for $XML_RPC_xh[$parser]. Reduces E_STRICT notices. Bug 3782.
7939+* Add createHeaders() method and $headers property to XML_RPC_Client to make testing easier.</notes>
7940+ </release>
7941+ <release>
7942+ <version>
7943+ <release>1.2.2</release>
7944+ <api>1.2.0</api>
7945+ </version>
7946+ <stability>
7947+ <release>stable</release>
7948+ <api>stable</api>
7949+ </stability>
7950+ <date>2005-03-07</date>
7951+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
7952+ <notes>* When using a proxy, add the protocol to the Request-URI, making it an &quot;absoluteURI&quot; as per the HTTP 1.0 spec. Bug 3679.</notes>
7953+ </release>
7954+ <release>
7955+ <version>
7956+ <release>1.2.1</release>
7957+ <api>1.2.0</api>
7958+ </version>
7959+ <stability>
7960+ <release>stable</release>
7961+ <api>stable</api>
7962+ </stability>
7963+ <date>2005-03-01</date>
7964+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
7965+ <notes>* Add isset() check before examining the dispatch map. Bug 3658.</notes>
7966+ </release>
7967+ <release>
7968+ <version>
7969+ <release>1.2.0</release>
7970+ <api>1.2.0</api>
7971+ </version>
7972+ <stability>
7973+ <release>stable</release>
7974+ <api>stable</api>
7975+ </stability>
7976+ <date>2005-02-27</date>
7977+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
7978+ <notes>* Provide the &quot;stable&quot; release.
7979+* Add package2.xml for compatibility with PEAR 1.4.0.
7980+* For changes since 1.1.0, see the changelogs for the various RC releases.</notes>
7981+ </release>
7982+ <release>
7983+ <version>
7984+ <release>1.2.0RC7</release>
7985+ <api>1.2.0RC7</api>
7986+ </version>
7987+ <stability>
7988+ <release>beta</release>
7989+ <api>beta</api>
7990+ </stability>
7991+ <date>2005-02-22</date>
7992+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
7993+ <notes>* Add the setSendEncoding() method and $send_encoding
7994+ property to XML_RPC_Message. Request 3537.
7995+* Allow class methods to be mapped using either syntax:
7996+ &apos;function&apos; =&gt; &apos;hello::sayHello&apos;,
7997+ or
7998+ &apos;function&apos; =&gt; array(&apos;hello&apos;, &apos;sayhello&apos;),
7999+ Bug 3363.
8000+* Use 8192 instead of 32768 for bytes in fread()
8001+ in parseResponseFile(). Bug 3340.</notes>
8002+ </release>
8003+ <release>
8004+ <version>
8005+ <release>1.2.0RC6</release>
8006+ <api>1.2.0RC6</api>
8007+ </version>
8008+ <stability>
8009+ <release>beta</release>
8010+ <api>beta</api>
8011+ </stability>
8012+ <date>2005-01-25</date>
8013+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8014+ <notes>* Don&apos;t put the protocol in the Host field of the POST data. (danielc)</notes>
8015+ </release>
8016+ <release>
8017+ <version>
8018+ <release>1.2.0RC5</release>
8019+ <api>1.2.0RC5</api>
8020+ </version>
8021+ <stability>
8022+ <release>beta</release>
8023+ <api>beta</api>
8024+ </stability>
8025+ <date>2005-01-24</date>
8026+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8027+ <notes>* If $port is 443 but a protocol isn&apos;t specified in $server, assume ssl:// is the protocol.</notes>
8028+ </release>
8029+ <release>
8030+ <version>
8031+ <release>1.2.0RC4</release>
8032+ <api>1.2.0RC4</api>
8033+ </version>
8034+ <stability>
8035+ <release>beta</release>
8036+ <api>beta</api>
8037+ </stability>
8038+ <date>2005-01-24</date>
8039+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8040+ <notes>* When a connection attempt fails, have the method return 0. (danielc)
8041+* Move the protocol/port checking/switching and the property settings from sendPayloadHTTP10() to the XML_RPC_Client constructor. (danielc)
8042+* Add tests for setting the client properties. (danielc)
8043+* Remove $GLOBALS[&apos;XML_RPC_twoslash&apos;] since it&apos;s not used. (danielc)
8044+* Bundle the tests with the package. (danielc)</notes>
8045+ </release>
8046+ <release>
8047+ <version>
8048+ <release>1.2.0RC3</release>
8049+ <api>1.2.0RC3</api>
8050+ </version>
8051+ <stability>
8052+ <release>beta</release>
8053+ <api>beta</api>
8054+ </stability>
8055+ <date>2005-01-19</date>
8056+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8057+ <notes>* ssl uses port 443, not 445.</notes>
8058+ </release>
8059+ <release>
8060+ <version>
8061+ <release>1.2.0RC2</release>
8062+ <api>1.2.0RC2</api>
8063+ </version>
8064+ <stability>
8065+ <release>beta</release>
8066+ <api>beta</api>
8067+ </stability>
8068+ <date>2005-01-11</date>
8069+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8070+ <notes>* Handle ssl:// in the $server string. (danielc)
8071+* Also default to port 445 for ssl:// requests as well. (danielc)
8072+* Enhance debugging in the server. (danielc)</notes>
8073+ </release>
8074+ <release>
8075+ <version>
8076+ <release>1.2.0RC1</release>
8077+ <api>1.2.0RC1</api>
8078+ </version>
8079+ <stability>
8080+ <release>beta</release>
8081+ <api>beta</api>
8082+ </stability>
8083+ <date>2004-12-30</date>
8084+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8085+ <notes>* Make things work with SSL. Bug 2489. (nkukard lbsd net)
8086+* Allow array function callbacks (Matt Kane)
8087+* Some minor speed-ups (Matt Kane)
8088+* Add Dump.php to the package (Christian Weiske)
8089+* Replace all line endings with \r\n. Had only done replacements on \n. Bug 2521. (danielc)
8090+* Silence fsockopen() errors. Bug 1714. (danielc)
8091+* Encode empty arrays as an array. Bug 1493. (danielc)
8092+* Eliminate undefined index notice when submitting empty arrays to XML_RPC_Encode(). Bug 1819. (danielc)
8093+* Speed up check for enumerated arrays in XML_RPC_Encode(). (danielc)
8094+* Prepend &quot;XML_RPC_&quot; to ERROR_NON_NUMERIC_FOUND, eliminating problem when eval()&apos;ing error messages. (danielc)
8095+* Use XML_RPC_Base::raiseError() instead of PEAR::raiseError() in XML_RPC_ee() because PEAR.php is lazy loaded. (danielc)
8096+* Allow raiseError() to be called statically. (danielc)
8097+* Stop double escaping of character entities. Bug 987. (danielc)
8098+ NOTICE: the following have been removed:
8099+ * XML_RPC_dh()
8100+ * $GLOBALS[&apos;XML_RPC_entities&apos;]
8101+ * XML_RPC_entity_decode()
8102+ * XML_RPC_lookup_entity()
8103+* Determine the XML&apos;s encoding via the encoding attribute in the XML declaration. Bug 52. (danielc)</notes>
8104+ </release>
8105+ <release>
8106+ <version>
8107+ <release>1.1.0</release>
8108+ <api>1.1.0</api>
8109+ </version>
8110+ <stability>
8111+ <release>stable</release>
8112+ <api>stable</api>
8113+ </stability>
8114+ <date>2004-03-15</date>
8115+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8116+ <notes>* Added support for sequential arrays to XML_RPC_encode() (mroch)
8117+* Cleaned up new XML_RPC_encode() changes a bit (mroch, pierre)
8118+* Remove &quot;require_once &apos;PEAR.php&apos;&quot;, include only when needed to raise an error
8119+* Replace echo and error_log() with raiseError() (mroch)
8120+* Make all classes extend XML_RPC_Base, which will handle common functions (mroch)
8121+* be tolerant of junk after methodResponse (Luca Mariano, mroch)
8122+* Silent notice even in the error log (pierre)
8123+* fix include of shared xml extension on win32 (pierre)</notes>
8124+ </release>
8125+ <release>
8126+ <version>
8127+ <release>1.0.4</release>
8128+ <api>1.0.4</api>
8129+ </version>
8130+ <stability>
8131+ <release>stable</release>
8132+ <api>stable</api>
8133+ </stability>
8134+ <date>2002-10-02</date>
8135+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8136+ <notes>* added HTTP proxy authorization support (thanks to Arnaud Limbourg)</notes>
8137+ </release>
8138+ <release>
8139+ <version>
8140+ <release>1.0.3</release>
8141+ <api>1.0.3</api>
8142+ </version>
8143+ <stability>
8144+ <release>stable</release>
8145+ <api>stable</api>
8146+ </stability>
8147+ <date>2002-05-19</date>
8148+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8149+ <notes>* fix bug when parsing responses with boolean types</notes>
8150+ </release>
8151+ <release>
8152+ <version>
8153+ <release>1.0.2</release>
8154+ <api>1.0.2</api>
8155+ </version>
8156+ <stability>
8157+ <release>stable</release>
8158+ <api>stable</api>
8159+ </stability>
8160+ <date>2002-04-16</date>
8161+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8162+ <notes>* E_ALL fixes
8163+* fix HTTP response header parsing</notes>
8164+ </release>
8165+ <release>
8166+ <version>
8167+ <release>1.0.1</release>
8168+ <api>1.0.1</api>
8169+ </version>
8170+ <stability>
8171+ <release>stable</release>
8172+ <api>stable</api>
8173+ </stability>
8174+ <date>2001-09-25</date>
8175+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8176+ <notes>This is a PEAR-ified version of Useful Inc&apos;s 1.0.1 release.
8177+Includes an urgent security fix identified by Dan Libby &lt;dan@libby.com&gt;.</notes>
8178+ </release>
8179+ </changelog>
8180+</package>
8181+
8182+
8183+/**
8184+ * Tests that properties of XML_RPC_Client get properly set
8185+ *
8186+ * Any individual tests that fail will have their name, expected result
8187+ * and actual result printed out. So seeing no output when executing
8188+ * this file is a good thing.
8189+ *
8190+ * Can be run via CLI or a web server.
8191+ *
8192+ * PHP versions 4 and 5
8193+ *
8194+ * LICENSE: This source file is subject to version 3.0 of the PHP license
8195+ * that is available through the world-wide-web at the following URI:
8196+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
8197+ * the PHP License and are unable to obtain it through the web, please
8198+ * send a note to license@php.net so we can mail you a copy immediately.
8199+ *
8200+ * @category Web Services
8201+ * @package XML_RPC
8202+ * @author Daniel Convissor <danielc@php.net>
8203+ * @copyright 2005 The PHP Group
8204+ * @license http://www.php.net/license/3_0.txt PHP License
8205+ * @version CVS: $Id: protoport.php,v 1.4 2005/01/24 17:48:47 danielc Exp $
8206+ * @link http://pear.php.net/package/XML_RPC
8207+ * @since File available since Release 1.2
8208+ */
8209+
8210+/*
8211+ * If the package version number is found in the left hand
8212+ * portion of the if() expression below, that means this file has
8213+ * come from the PEAR installer. Therefore, let's test the
8214+ * installed version of XML_RPC which should be in the include path.
8215+ *
8216+ * If the version has not been substituted in the if() expression,
8217+ * this file has likely come from a CVS checkout or a .tar file.
8218+ * Therefore, we'll assume the tests should use the version of
8219+ * XML_RPC that has come from there as well.
8220+ */
8221+if ('1.4.0' != '@'.'package_version'.'@') {
8222+ /**
8223+ * Get the needed class from the PEAR installation
8224+ */
8225+ require_once 'XML/RPC.php';
8226+} else {
8227+ /**
8228+ * Get the needed class from the parent directory
8229+ */
8230+ require_once '../RPC.php';
8231+}
8232+
8233+/**
8234+ * Compare the test result to the expected result
8235+ *
8236+ * If the test fails, echo out the results.
8237+ *
8238+ * @param array $expect the array of object properties you expect
8239+ * from the test
8240+ * @param object $actual the object results from the test
8241+ * @param string $test_name the name of the test
8242+ *
8243+ * @return void
8244+ */
8245+function compare($expect, $actual, $test_name) {
8246+ $actual = get_object_vars($actual);
8247+ if (count(array_diff($actual, $expect))) {
8248+ echo "$test_name failed.\nExpect: ";
8249+ print_r($expect);
8250+ echo "Actual: ";
8251+ print_r($actual);
8252+ echo "\n";
8253+ }
8254+}
8255+
8256+if (php_sapi_name() != 'cli') {
8257+ echo "<pre>\n";
8258+}
8259+
8260+
8261+$x = array(
8262+ 'path' => 'thepath',
8263+ 'server' => 'theserver',
8264+ 'protocol' => 'http://',
8265+ 'port' => 80,
8266+ 'proxy' => '',
8267+ 'proxy_protocol' => 'http://',
8268+ 'proxy_port' => 8080,
8269+ 'proxy_user' => '',
8270+ 'proxy_pass' => '',
8271+ 'errno' => 0,
8272+ 'errstring' => '',
8273+ 'debug' => 0,
8274+ 'username' => '',
8275+ 'password' => '',
8276+);
8277+$c = new XML_RPC_Client('thepath', 'theserver');
8278+compare($x, $c, 'defaults');
8279+
8280+$x = array(
8281+ 'path' => 'thepath',
8282+ 'server' => 'theserver',
8283+ 'protocol' => 'http://',
8284+ 'port' => 80,
8285+ 'proxy' => '',
8286+ 'proxy_protocol' => 'http://',
8287+ 'proxy_port' => 8080,
8288+ 'proxy_user' => '',
8289+ 'proxy_pass' => '',
8290+ 'errno' => 0,
8291+ 'errstring' => '',
8292+ 'debug' => 0,
8293+ 'username' => '',
8294+ 'password' => '',
8295+);
8296+$c = new XML_RPC_Client('thepath', 'http://theserver');
8297+compare($x, $c, 'defaults with http');
8298+
8299+$x = array(
8300+ 'path' => 'thepath',
8301+ 'server' => 'theserver',
8302+ 'protocol' => 'ssl://',
8303+ 'port' => 443,
8304+ 'proxy' => '',
8305+ 'proxy_protocol' => 'http://',
8306+ 'proxy_port' => 8080,
8307+ 'proxy_user' => '',
8308+ 'proxy_pass' => '',
8309+ 'errno' => 0,
8310+ 'errstring' => '',
8311+ 'debug' => 0,
8312+ 'username' => '',
8313+ 'password' => '',
8314+);
8315+$c = new XML_RPC_Client('thepath', 'https://theserver');
8316+compare($x, $c, 'defaults with https');
8317+
8318+$x = array(
8319+ 'path' => 'thepath',
8320+ 'server' => 'theserver',
8321+ 'protocol' => 'ssl://',
8322+ 'port' => 443,
8323+ 'proxy' => '',
8324+ 'proxy_protocol' => 'http://',
8325+ 'proxy_port' => 8080,
8326+ 'proxy_user' => '',
8327+ 'proxy_pass' => '',
8328+ 'errno' => 0,
8329+ 'errstring' => '',
8330+ 'debug' => 0,
8331+ 'username' => '',
8332+ 'password' => '',
8333+);
8334+$c = new XML_RPC_Client('thepath', 'ssl://theserver');
8335+compare($x, $c, 'defaults with ssl');
8336+
8337+
8338+$x = array(
8339+ 'path' => 'thepath',
8340+ 'server' => 'theserver',
8341+ 'protocol' => 'http://',
8342+ 'port' => 65,
8343+ 'proxy' => '',
8344+ 'proxy_protocol' => 'http://',
8345+ 'proxy_port' => 8080,
8346+ 'proxy_user' => '',
8347+ 'proxy_pass' => '',
8348+ 'errno' => 0,
8349+ 'errstring' => '',
8350+ 'debug' => 0,
8351+ 'username' => '',
8352+ 'password' => '',
8353+);
8354+$c = new XML_RPC_Client('thepath', 'theserver', 65);
8355+compare($x, $c, 'port 65');
8356+
8357+$x = array(
8358+ 'path' => 'thepath',
8359+ 'server' => 'theserver',
8360+ 'protocol' => 'http://',
8361+ 'port' => 65,
8362+ 'proxy' => '',
8363+ 'proxy_protocol' => 'http://',
8364+ 'proxy_port' => 8080,
8365+ 'proxy_user' => '',
8366+ 'proxy_pass' => '',
8367+ 'errno' => 0,
8368+ 'errstring' => '',
8369+ 'debug' => 0,
8370+ 'username' => '',
8371+ 'password' => '',
8372+);
8373+$c = new XML_RPC_Client('thepath', 'http://theserver', 65);
8374+compare($x, $c, 'port 65 with http');
8375+
8376+$x = array(
8377+ 'path' => 'thepath',
8378+ 'server' => 'theserver',
8379+ 'protocol' => 'ssl://',
8380+ 'port' => 65,
8381+ 'proxy' => '',
8382+ 'proxy_protocol' => 'http://',
8383+ 'proxy_port' => 8080,
8384+ 'proxy_user' => '',
8385+ 'proxy_pass' => '',
8386+ 'errno' => 0,
8387+ 'errstring' => '',
8388+ 'debug' => 0,
8389+ 'username' => '',
8390+ 'password' => '',
8391+);
8392+$c = new XML_RPC_Client('thepath', 'https://theserver', 65);
8393+compare($x, $c, 'port 65 with https');
8394+
8395+$x = array(
8396+ 'path' => 'thepath',
8397+ 'server' => 'theserver',
8398+ 'protocol' => 'ssl://',
8399+ 'port' => 65,
8400+ 'proxy' => '',
8401+ 'proxy_protocol' => 'http://',
8402+ 'proxy_port' => 8080,
8403+ 'proxy_user' => '',
8404+ 'proxy_pass' => '',
8405+ 'errno' => 0,
8406+ 'errstring' => '',
8407+ 'debug' => 0,
8408+ 'username' => '',
8409+ 'password' => '',
8410+);
8411+$c = new XML_RPC_Client('thepath', 'ssl://theserver', 65);
8412+compare($x, $c, 'port 65 with ssl');
8413+
8414+
8415+$x = array(
8416+ 'path' => 'thepath',
8417+ 'server' => 'theserver',
8418+ 'protocol' => 'http://',
8419+ 'port' => 80,
8420+ 'proxy' => 'theproxy',
8421+ 'proxy_protocol' => 'http://',
8422+ 'proxy_port' => 8080,
8423+ 'proxy_user' => '',
8424+ 'proxy_pass' => '',
8425+ 'errno' => 0,
8426+ 'errstring' => '',
8427+ 'debug' => 0,
8428+ 'username' => '',
8429+ 'password' => '',
8430+);
8431+$c = new XML_RPC_Client('thepath', 'theserver', 0,
8432+ 'theproxy');
8433+compare($x, $c, 'defaults proxy');
8434+
8435+$x = array(
8436+ 'path' => 'thepath',
8437+ 'server' => 'theserver',
8438+ 'protocol' => 'http://',
8439+ 'port' => 80,
8440+ 'proxy' => 'theproxy',
8441+ 'proxy_protocol' => 'http://',
8442+ 'proxy_port' => 8080,
8443+ 'proxy_user' => '',
8444+ 'proxy_pass' => '',
8445+ 'errno' => 0,
8446+ 'errstring' => '',
8447+ 'debug' => 0,
8448+ 'username' => '',
8449+ 'password' => '',
8450+);
8451+$c = new XML_RPC_Client('thepath', 'http://theserver', 0,
8452+ 'http://theproxy');
8453+compare($x, $c, 'defaults with http proxy');
8454+
8455+$x = array(
8456+ 'path' => 'thepath',
8457+ 'server' => 'theserver',
8458+ 'protocol' => 'ssl://',
8459+ 'port' => 443,
8460+ 'proxy' => 'theproxy',
8461+ 'proxy_protocol' => 'ssl://',
8462+ 'proxy_port' => 443,
8463+ 'proxy_user' => '',
8464+ 'proxy_pass' => '',
8465+ 'errno' => 0,
8466+ 'errstring' => '',
8467+ 'debug' => 0,
8468+ 'username' => '',
8469+ 'password' => '',
8470+);
8471+$c = new XML_RPC_Client('thepath', 'https://theserver', 0,
8472+ 'https://theproxy');
8473+compare($x, $c, 'defaults with https proxy');
8474+
8475+$x = array(
8476+ 'path' => 'thepath',
8477+ 'server' => 'theserver',
8478+ 'protocol' => 'ssl://',
8479+ 'port' => 443,
8480+ 'proxy' => 'theproxy',
8481+ 'proxy_protocol' => 'ssl://',
8482+ 'proxy_port' => 443,
8483+ 'proxy_user' => '',
8484+ 'proxy_pass' => '',
8485+ 'errno' => 0,
8486+ 'errstring' => '',
8487+ 'debug' => 0,
8488+ 'username' => '',
8489+ 'password' => '',
8490+);
8491+$c = new XML_RPC_Client('thepath', 'ssl://theserver', 0,
8492+ 'ssl://theproxy');
8493+compare($x, $c, 'defaults with ssl proxy');
8494+
8495+
8496+$x = array(
8497+ 'path' => 'thepath',
8498+ 'server' => 'theserver',
8499+ 'protocol' => 'http://',
8500+ 'port' => 65,
8501+ 'proxy' => 'theproxy',
8502+ 'proxy_protocol' => 'http://',
8503+ 'proxy_port' => 6565,
8504+ 'proxy_user' => '',
8505+ 'proxy_pass' => '',
8506+ 'errno' => 0,
8507+ 'errstring' => '',
8508+ 'debug' => 0,
8509+ 'username' => '',
8510+ 'password' => '',
8511+);
8512+$c = new XML_RPC_Client('thepath', 'theserver', 65,
8513+ 'theproxy', 6565);
8514+compare($x, $c, 'port 65 proxy 6565');
8515+
8516+$x = array(
8517+ 'path' => 'thepath',
8518+ 'server' => 'theserver',
8519+ 'protocol' => 'http://',
8520+ 'port' => 65,
8521+ 'proxy' => 'theproxy',
8522+ 'proxy_protocol' => 'http://',
8523+ 'proxy_port' => 6565,
8524+ 'proxy_user' => '',
8525+ 'proxy_pass' => '',
8526+ 'errno' => 0,
8527+ 'errstring' => '',
8528+ 'debug' => 0,
8529+ 'username' => '',
8530+ 'password' => '',
8531+);
8532+$c = new XML_RPC_Client('thepath', 'http://theserver', 65,
8533+ 'http://theproxy', 6565);
8534+compare($x, $c, 'port 65 with http proxy 6565');
8535+
8536+$x = array(
8537+ 'path' => 'thepath',
8538+ 'server' => 'theserver',
8539+ 'protocol' => 'ssl://',
8540+ 'port' => 65,
8541+ 'proxy' => 'theproxy',
8542+ 'proxy_protocol' => 'ssl://',
8543+ 'proxy_port' => 6565,
8544+ 'proxy_user' => '',
8545+ 'proxy_pass' => '',
8546+ 'errno' => 0,
8547+ 'errstring' => '',
8548+ 'debug' => 0,
8549+ 'username' => '',
8550+ 'password' => '',
8551+);
8552+$c = new XML_RPC_Client('thepath', 'https://theserver', 65,
8553+ 'https://theproxy', 6565);
8554+compare($x, $c, 'port 65 with https proxy 6565');
8555+
8556+$x = array(
8557+ 'path' => 'thepath',
8558+ 'server' => 'theserver',
8559+ 'protocol' => 'ssl://',
8560+ 'port' => 65,
8561+ 'proxy' => 'theproxy',
8562+ 'proxy_protocol' => 'ssl://',
8563+ 'proxy_port' => 6565,
8564+ 'proxy_user' => '',
8565+ 'proxy_pass' => '',
8566+ 'errno' => 0,
8567+ 'errstring' => '',
8568+ 'debug' => 0,
8569+ 'username' => '',
8570+ 'password' => '',
8571+);
8572+$c = new XML_RPC_Client('thepath', 'ssl://theserver', 65,
8573+ 'ssl://theproxy', 6565);
8574+compare($x, $c, 'port 65 with ssl proxy 6565');
8575+
8576+
8577+$x = array(
8578+ 'path' => 'thepath',
8579+ 'server' => 'theserver',
8580+ 'protocol' => 'ssl://',
8581+ 'port' => 443,
8582+ 'proxy' => 'theproxy',
8583+ 'proxy_protocol' => 'ssl://',
8584+ 'proxy_port' => 443,
8585+ 'proxy_user' => '',
8586+ 'proxy_pass' => '',
8587+ 'errno' => 0,
8588+ 'errstring' => '',
8589+ 'debug' => 0,
8590+ 'username' => '',
8591+ 'password' => '',
8592+);
8593+$c = new XML_RPC_Client('thepath', 'theserver', 443,
8594+ 'theproxy', 443);
8595+compare($x, $c, 'port 443 no protocol and proxy port 443 no protocol');
8596+
8597+$x = array(
8598+ 'path' => 'thepath',
8599+ 'server' => 'theserver',
8600+ 'protocol' => 'http://',
8601+ 'port' => 80,
8602+ 'proxy' => 'theproxy',
8603+ 'proxy_protocol' => 'ssl://',
8604+ 'proxy_port' => 6565,
8605+ 'proxy_user' => '',
8606+ 'proxy_pass' => '',
8607+ 'errno' => 0,
8608+ 'errstring' => '',
8609+ 'debug' => 0,
8610+ 'username' => '',
8611+ 'password' => '',
8612+);
8613+$c = new XML_RPC_Client('thepath', 'theserver', 0,
8614+ 'ssl://theproxy', 6565);
8615+compare($x, $c, 'port 443 no protocol and proxy port 443 no protocol');
8616+
8617+
8618+/*
8619+ * If the package version number is found in the left hand
8620+ * portion of the if() expression below, that means this file has
8621+ * come from the PEAR installer. Therefore, let's test the
8622+ * installed version of XML_RPC which should be in the include path.
8623+ *
8624+ * If the version has not been substituted in the if() expression,
8625+ * this file has likely come from a CVS checkout or a .tar file.
8626+ * Therefore, we'll assume the tests should use the version of
8627+ * XML_RPC that has come from there as well.
8628+ */
8629+if ('1.4.0' != '@'.'package_version'.'@') {
8630+ /**
8631+ * Get the needed class from the PEAR installation
8632+ */
8633+ require_once 'XML/RPC/Dump.php';
8634+} else {
8635+ /**
8636+ * Get the needed class from the parent directory
8637+ */
8638+ require_once '../Dump.php';
8639+}
8640+
8641+$val = new XML_RPC_Value(array(
8642+ 'title' =>new XML_RPC_Value('das ist der Titel', 'string'),
8643+ 'startDate'=>new XML_RPC_Value(mktime(0,0,0,13,11,2004), 'dateTime.iso8601'),
8644+ 'endDate' =>new XML_RPC_Value(mktime(0,0,0,15,11,2004), 'dateTime.iso8601'),
8645+ 'error' =>'string',
8646+ 'arkey' => new XML_RPC_Value( array(
8647+ new XML_RPC_Value('simple string'),
8648+ new XML_RPC_Value(12345, 'int')
8649+ ), 'array')
8650+ )
8651+ ,'struct');
8652+
8653+XML_RPC_Dump($val);
8654+
8655+echo '==============' . "\r\n";
8656+$val2 = new XML_RPC_Value(44353, 'int');
8657+XML_RPC_Dump($val2);
8658+
8659+echo '==============' . "\r\n";
8660+$val3 = new XML_RPC_Value('this should be a string', 'string');
8661+XML_RPC_Dump($val3);
8662+
8663+echo '==============' . "\r\n";
8664+$val4 = new XML_RPC_Value(true, 'boolean');
8665+XML_RPC_Dump($val4);
8666+
8667+
8668+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
8669+
8670+/**
8671+ * Function and class to dump XML_RPC_Value objects in a nice way
8672+ *
8673+ * Should be helpful as a normal var_dump(..) displays all internals which
8674+ * doesn't really give you an overview due to too much information.
8675+ *
8676+ * @category Web Services
8677+ * @package XML_RPC
8678+ * @author Christian Weiske <cweiske@php.net>
8679+ * @version CVS: $Id: Dump.php,v 1.7 2005/01/24 03:47:55 danielc Exp $
8680+ * @link http://pear.php.net/package/XML_RPC
8681+ */
8682+
8683+
8684+/**
8685+ * Pull in the XML_RPC class
8686+ */
8687+require_once 'XML/RPC.php';
8688+
8689+
8690+/**
8691+ * Generates the dump of the XML_RPC_Value and echoes it
8692+ *
8693+ * @param object $value the XML_RPC_Value object to dump
8694+ *
8695+ * @return void
8696+ */
8697+function XML_RPC_Dump($value)
8698+{
8699+ $dumper = new XML_RPC_Dump();
8700+ echo $dumper->generateDump($value);
8701+}
8702+
8703+
8704+/**
8705+ * Class which generates a dump of a XML_RPC_Value object
8706+ *
8707+ * @category Web Services
8708+ * @package XML_RPC
8709+ * @author Christian Weiske <cweiske@php.net>
8710+ * @version Release: 1.4.0
8711+ * @link http://pear.php.net/package/XML_RPC
8712+ */
8713+class XML_RPC_Dump
8714+{
8715+ /**
8716+ * The indentation array cache
8717+ * @var array
8718+ */
8719+ var $arIndent = array();
8720+
8721+ /**
8722+ * The spaces used for indenting the XML
8723+ * @var string
8724+ */
8725+ var $strBaseIndent = ' ';
8726+
8727+ /**
8728+ * Returns the dump in XML format without printing it out
8729+ *
8730+ * @param object $value the XML_RPC_Value object to dump
8731+ * @param int $nLevel the level of indentation
8732+ *
8733+ * @return string the dump
8734+ */
8735+ function generateDump($value, $nLevel = 0)
8736+ {
8737+ if (!is_object($value) && get_class($value) != 'xml_rpc_value') {
8738+ require_once 'PEAR.php';
8739+ PEAR::raiseError('Tried to dump non-XML_RPC_Value variable' . "\r\n",
8740+ 0, PEAR_ERROR_PRINT);
8741+ if (is_object($value)) {
8742+ $strType = get_class($value);
8743+ } else {
8744+ $strType = gettype($value);
8745+ }
8746+ return $this->getIndent($nLevel) . 'NOT A XML_RPC_Value: '
8747+ . $strType . "\r\n";
8748+ }
8749+
8750+ switch ($value->kindOf()) {
8751+ case 'struct':
8752+ $ret = $this->genStruct($value, $nLevel);
8753+ break;
8754+ case 'array':
8755+ $ret = $this->genArray($value, $nLevel);
8756+ break;
8757+ case 'scalar':
8758+ $ret = $this->genScalar($value->scalarval(), $nLevel);
8759+ break;
8760+ default:
8761+ require_once 'PEAR.php';
8762+ PEAR::raiseError('Illegal type "' . $value->kindOf()
8763+ . '" in XML_RPC_Value' . "\r\n", 0,
8764+ PEAR_ERROR_PRINT);
8765+ }
8766+
8767+ return $ret;
8768+ }
8769+
8770+ /**
8771+ * Returns the scalar value dump
8772+ *
8773+ * @param object $value the scalar XML_RPC_Value object to dump
8774+ * @param int $nLevel the level of indentation
8775+ *
8776+ * @return string Dumped version of the scalar value
8777+ */
8778+ function genScalar($value, $nLevel)
8779+ {
8780+ if (gettype($value) == 'object') {
8781+ $strClass = ' ' . get_class($value);
8782+ } else {
8783+ $strClass = '';
8784+ }
8785+ return $this->getIndent($nLevel) . gettype($value) . $strClass
8786+ . ' ' . $value . "\r\n";
8787+ }
8788+
8789+ /**
8790+ * Returns the dump of a struct
8791+ *
8792+ * @param object $value the struct XML_RPC_Value object to dump
8793+ * @param int $nLevel the level of indentation
8794+ *
8795+ * @return string Dumped version of the scalar value
8796+ */
8797+ function genStruct($value, $nLevel)
8798+ {
8799+ $value->structreset();
8800+ $strOutput = $this->getIndent($nLevel) . 'struct' . "\r\n";
8801+ while (list($key, $keyval) = $value->structeach()) {
8802+ $strOutput .= $this->getIndent($nLevel + 1) . $key . "\r\n";
8803+ $strOutput .= $this->generateDump($keyval, $nLevel + 2);
8804+ }
8805+ return $strOutput;
8806+ }
8807+
8808+ /**
8809+ * Returns the dump of an array
8810+ *
8811+ * @param object $value the array XML_RPC_Value object to dump
8812+ * @param int $nLevel the level of indentation
8813+ *
8814+ * @return string Dumped version of the scalar value
8815+ */
8816+ function genArray($value, $nLevel)
8817+ {
8818+ $nSize = $value->arraysize();
8819+ $strOutput = $this->getIndent($nLevel) . 'array' . "\r\n";
8820+ for($nA = 0; $nA < $nSize; $nA++) {
8821+ $strOutput .= $this->getIndent($nLevel + 1) . $nA . "\r\n";
8822+ $strOutput .= $this->generateDump($value->arraymem($nA),
8823+ $nLevel + 2);
8824+ }
8825+ return $strOutput;
8826+ }
8827+
8828+ /**
8829+ * Returns the indent for a specific level and caches it for faster use
8830+ *
8831+ * @param int $nLevel the level
8832+ *
8833+ * @return string the indented string
8834+ */
8835+ function getIndent($nLevel)
8836+ {
8837+ if (!isset($this->arIndent[$nLevel])) {
8838+ $this->arIndent[$nLevel] = str_repeat($this->strBaseIndent, $nLevel);
8839+ }
8840+ return $this->arIndent[$nLevel];
8841+ }
8842+}
8843+
8844+/*
8845+ * Local variables:
8846+ * tab-width: 4
8847+ * c-basic-offset: 4
8848+ * c-hanging-comment-ender-p: nil
8849+ * End:
8850+ */
8851+
8852+?>
8853+
8854+
8855+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
8856+
8857+/**
8858+ * PHP implementation of the XML-RPC protocol
8859+ *
8860+ * This is a PEAR-ified version of Useful inc's XML-RPC for PHP.
8861+ * It has support for HTTP transport, proxies and authentication.
8862+ *
8863+ * PHP versions 4 and 5
8864+ *
8865+ * LICENSE: License is granted to use or modify this software
8866+ * ("XML-RPC for PHP") for commercial or non-commercial use provided the
8867+ * copyright of the author is preserved in any distributed or derivative work.
8868+ *
8869+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESSED OR
8870+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
8871+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
8872+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
8873+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
8874+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
8875+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
8876+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8877+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
8878+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8879+ *
8880+ * @category Web Services
8881+ * @package XML_RPC
8882+ * @author Edd Dumbill <edd@usefulinc.com>
8883+ * @author Stig Bakken <stig@php.net>
8884+ * @author Martin Jansen <mj@php.net>
8885+ * @author Daniel Convissor <danielc@php.net>
8886+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
8887+ * @version CVS: $Id: RPC.php,v 1.83 2005/08/14 20:25:35 danielc Exp $
8888+ * @link http://pear.php.net/package/XML_RPC
8889+ */
8890+
8891+
8892+if (!function_exists('xml_parser_create')) {
8893+ PEAR::loadExtension('xml');
8894+}
8895+
8896+/**#@+
8897+ * Error constants
8898+ */
8899+/**
8900+ * Parameter values don't match parameter types
8901+ */
8902+define('XML_RPC_ERROR_INVALID_TYPE', 101);
8903+/**
8904+ * Parameter declared to be numeric but the values are not
8905+ */
8906+define('XML_RPC_ERROR_NON_NUMERIC_FOUND', 102);
8907+/**
8908+ * Communication error
8909+ */
8910+define('XML_RPC_ERROR_CONNECTION_FAILED', 103);
8911+/**
8912+ * The array or struct has already been started
8913+ */
8914+define('XML_RPC_ERROR_ALREADY_INITIALIZED', 104);
8915+/**
8916+ * Incorrect parameters submitted
8917+ */
8918+define('XML_RPC_ERROR_INCORRECT_PARAMS', 105);
8919+/**
8920+ * Programming error by developer
8921+ */
8922+define('XML_RPC_ERROR_PROGRAMMING', 106);
8923+/**#@-*/
8924+
8925+
8926+/**
8927+ * Data types
8928+ * @global string $GLOBALS['XML_RPC_I4']
8929+ */
8930+$GLOBALS['XML_RPC_I4'] = 'i4';
8931+
8932+/**
8933+ * Data types
8934+ * @global string $GLOBALS['XML_RPC_Int']
8935+ */
8936+$GLOBALS['XML_RPC_Int'] = 'int';
8937+
8938+/**
8939+ * Data types
8940+ * @global string $GLOBALS['XML_RPC_Boolean']
8941+ */
8942+$GLOBALS['XML_RPC_Boolean'] = 'boolean';
8943+
8944+/**
8945+ * Data types
8946+ * @global string $GLOBALS['XML_RPC_Double']
8947+ */
8948+$GLOBALS['XML_RPC_Double'] = 'double';
8949+
8950+/**
8951+ * Data types
8952+ * @global string $GLOBALS['XML_RPC_String']
8953+ */
8954+$GLOBALS['XML_RPC_String'] = 'string';
8955+
8956+/**
8957+ * Data types
8958+ * @global string $GLOBALS['XML_RPC_DateTime']
8959+ */
8960+$GLOBALS['XML_RPC_DateTime'] = 'dateTime.iso8601';
8961+
8962+/**
8963+ * Data types
8964+ * @global string $GLOBALS['XML_RPC_Base64']
8965+ */
8966+$GLOBALS['XML_RPC_Base64'] = 'base64';
8967+
8968+/**
8969+ * Data types
8970+ * @global string $GLOBALS['XML_RPC_Array']
8971+ */
8972+$GLOBALS['XML_RPC_Array'] = 'array';
8973+
8974+/**
8975+ * Data types
8976+ * @global string $GLOBALS['XML_RPC_Struct']
8977+ */
8978+$GLOBALS['XML_RPC_Struct'] = 'struct';
8979+
8980+
8981+/**
8982+ * Data type meta-types
8983+ * @global array $GLOBALS['XML_RPC_Types']
8984+ */
8985+$GLOBALS['XML_RPC_Types'] = array(
8986+ $GLOBALS['XML_RPC_I4'] => 1,
8987+ $GLOBALS['XML_RPC_Int'] => 1,
8988+ $GLOBALS['XML_RPC_Boolean'] => 1,
8989+ $GLOBALS['XML_RPC_String'] => 1,
8990+ $GLOBALS['XML_RPC_Double'] => 1,
8991+ $GLOBALS['XML_RPC_DateTime'] => 1,
8992+ $GLOBALS['XML_RPC_Base64'] => 1,
8993+ $GLOBALS['XML_RPC_Array'] => 2,
8994+ $GLOBALS['XML_RPC_Struct'] => 3,
8995+);
8996+
8997+
8998+/**
8999+ * Error message numbers
9000+ * @global array $GLOBALS['XML_RPC_err']
9001+ */
9002+$GLOBALS['XML_RPC_err'] = array(
9003+ 'unknown_method' => 1,
9004+ 'invalid_return' => 2,
9005+ 'incorrect_params' => 3,
9006+ 'introspect_unknown' => 4,
9007+ 'http_error' => 5,
9008+ 'not_response_object' => 6,
9009+ 'invalid_request' => 7,
9010+);
9011+
9012+/**
9013+ * Error message strings
9014+ * @global array $GLOBALS['XML_RPC_str']
9015+ */
9016+$GLOBALS['XML_RPC_str'] = array(
9017+ 'unknown_method' => 'Unknown method',
9018+ 'invalid_return' => 'Invalid return payload: enable debugging to examine incoming payload',
9019+ 'incorrect_params' => 'Incorrect parameters passed to method',
9020+ 'introspect_unknown' => 'Can\'t introspect: method unknown',
9021+ 'http_error' => 'Didn\'t receive 200 OK from remote server.',
9022+ 'not_response_object' => 'The requested method didn\'t return an XML_RPC_Response object.',
9023+ 'invalid_request' => 'Invalid request payload',
9024+);
9025+
9026+
9027+/**
9028+ * Default XML encoding (ISO-8859-1, UTF-8 or US-ASCII)
9029+ * @global string $GLOBALS['XML_RPC_defencoding']
9030+ */
9031+$GLOBALS['XML_RPC_defencoding'] = 'UTF-8';
9032+
9033+/**
9034+ * User error codes start at 800
9035+ * @global int $GLOBALS['XML_RPC_erruser']
9036+ */
9037+$GLOBALS['XML_RPC_erruser'] = 800;
9038+
9039+/**
9040+ * XML parse error codes start at 100
9041+ * @global int $GLOBALS['XML_RPC_errxml']
9042+ */
9043+$GLOBALS['XML_RPC_errxml'] = 100;
9044+
9045+
9046+/**
9047+ * Compose backslashes for escaping regexp
9048+ * @global string $GLOBALS['XML_RPC_backslash']
9049+ */
9050+$GLOBALS['XML_RPC_backslash'] = chr(92) . chr(92);
9051+
9052+
9053+/**
9054+ * Valid parents of XML elements
9055+ * @global array $GLOBALS['XML_RPC_valid_parents']
9056+ */
9057+$GLOBALS['XML_RPC_valid_parents'] = array(
9058+ 'BOOLEAN' => array('VALUE'),
9059+ 'I4' => array('VALUE'),
9060+ 'INT' => array('VALUE'),
9061+ 'STRING' => array('VALUE'),
9062+ 'DOUBLE' => array('VALUE'),
9063+ 'DATETIME.ISO8601' => array('VALUE'),
9064+ 'BASE64' => array('VALUE'),
9065+ 'ARRAY' => array('VALUE'),
9066+ 'STRUCT' => array('VALUE'),
9067+ 'PARAM' => array('PARAMS'),
9068+ 'METHODNAME' => array('METHODCALL'),
9069+ 'PARAMS' => array('METHODCALL', 'METHODRESPONSE'),
9070+ 'MEMBER' => array('STRUCT'),
9071+ 'NAME' => array('MEMBER'),
9072+ 'DATA' => array('ARRAY'),
9073+ 'FAULT' => array('METHODRESPONSE'),
9074+ 'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT'),
9075+);
9076+
9077+
9078+/**
9079+ * Stores state during parsing
9080+ *
9081+ * quick explanation of components:
9082+ * + ac = accumulates values
9083+ * + qt = decides if quotes are needed for evaluation
9084+ * + cm = denotes struct or array (comma needed)
9085+ * + isf = indicates a fault
9086+ * + lv = indicates "looking for a value": implements the logic
9087+ * to allow values with no types to be strings
9088+ * + params = stores parameters in method calls
9089+ * + method = stores method name
9090+ *
9091+ * @global array $GLOBALS['XML_RPC_xh']
9092+ */
9093+$GLOBALS['XML_RPC_xh'] = array();
9094+
9095+
9096+/**
9097+ * Start element handler for the XML parser
9098+ *
9099+ * @return void
9100+ */
9101+function XML_RPC_se($parser_resource, $name, $attrs)
9102+{
9103+ global $XML_RPC_xh, $XML_RPC_DateTime, $XML_RPC_String, $XML_RPC_valid_parents;
9104+ $parser = (int) $parser_resource;
9105+
9106+ // if invalid xmlrpc already detected, skip all processing
9107+ if ($XML_RPC_xh[$parser]['isf'] >= 2) {
9108+ return;
9109+ }
9110+
9111+ // check for correct element nesting
9112+ // top level element can only be of 2 types
9113+ if (count($XML_RPC_xh[$parser]['stack']) == 0) {
9114+ if ($name != 'METHODRESPONSE' && $name != 'METHODCALL') {
9115+ $XML_RPC_xh[$parser]['isf'] = 2;
9116+ $XML_RPC_xh[$parser]['isf_reason'] = 'missing top level xmlrpc element';
9117+ return;
9118+ }
9119+ } else {
9120+ // not top level element: see if parent is OK
9121+ if (!in_array($XML_RPC_xh[$parser]['stack'][0], $XML_RPC_valid_parents[$name])) {
9122+ $name = preg_replace('[^a-zA-Z0-9._-]', '', $name);
9123+ $XML_RPC_xh[$parser]['isf'] = 2;
9124+ $XML_RPC_xh[$parser]['isf_reason'] = "xmlrpc element $name cannot be child of {$XML_RPC_xh[$parser]['stack'][0]}";
9125+ return;
9126+ }
9127+ }
9128+
9129+ switch ($name) {
9130+ case 'STRUCT':
9131+ $XML_RPC_xh[$parser]['cm']++;
9132+
9133+ // turn quoting off
9134+ $XML_RPC_xh[$parser]['qt'] = 0;
9135+
9136+ $cur_val = array();
9137+ $cur_val['value'] = array();
9138+ $cur_val['members'] = 1;
9139+ array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val);
9140+ break;
9141+
9142+ case 'ARRAY':
9143+ $XML_RPC_xh[$parser]['cm']++;
9144+
9145+ // turn quoting off
9146+ $XML_RPC_xh[$parser]['qt'] = 0;
9147+
9148+ $cur_val = array();
9149+ $cur_val['value'] = array();
9150+ $cur_val['members'] = 0;
9151+ array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val);
9152+ break;
9153+
9154+ case 'NAME':
9155+ $XML_RPC_xh[$parser]['ac'] = '';
9156+ break;
9157+
9158+ case 'FAULT':
9159+ $XML_RPC_xh[$parser]['isf'] = 1;
9160+ break;
9161+
9162+ case 'PARAM':
9163+ $XML_RPC_xh[$parser]['valuestack'] = array();
9164+ break;
9165+
9166+ case 'VALUE':
9167+ $XML_RPC_xh[$parser]['lv'] = 1;
9168+ $XML_RPC_xh[$parser]['vt'] = $XML_RPC_String;
9169+ $XML_RPC_xh[$parser]['ac'] = '';
9170+ $XML_RPC_xh[$parser]['qt'] = 0;
9171+ // look for a value: if this is still 1 by the
9172+ // time we reach the first data segment then the type is string
9173+ // by implication and we need to add in a quote
9174+ break;
9175+
9176+ case 'I4':
9177+ case 'INT':
9178+ case 'STRING':
9179+ case 'BOOLEAN':
9180+ case 'DOUBLE':
9181+ case 'DATETIME.ISO8601':
9182+ case 'BASE64':
9183+ $XML_RPC_xh[$parser]['ac'] = ''; // reset the accumulator
9184+
9185+ if ($name == 'DATETIME.ISO8601' || $name == 'STRING') {
9186+ $XML_RPC_xh[$parser]['qt'] = 1;
9187+
9188+ if ($name == 'DATETIME.ISO8601') {
9189+ $XML_RPC_xh[$parser]['vt'] = $XML_RPC_DateTime;
9190+ }
9191+
9192+ } elseif ($name == 'BASE64') {
9193+ $XML_RPC_xh[$parser]['qt'] = 2;
9194+ } else {
9195+ // No quoting is required here -- but
9196+ // at the end of the element we must check
9197+ // for data format errors.
9198+ $XML_RPC_xh[$parser]['qt'] = 0;
9199+ }
9200+ break;
9201+
9202+ case 'MEMBER':
9203+ $XML_RPC_xh[$parser]['ac'] = '';
9204+ break;
9205+
9206+ case 'DATA':
9207+ case 'METHODCALL':
9208+ case 'METHODNAME':
9209+ case 'METHODRESPONSE':
9210+ case 'PARAMS':
9211+ // valid elements that add little to processing
9212+ break;
9213+ }
9214+
9215+
9216+ // Save current element to stack
9217+ array_unshift($XML_RPC_xh[$parser]['stack'], $name);
9218+
9219+ if ($name != 'VALUE') {
9220+ $XML_RPC_xh[$parser]['lv'] = 0;
9221+ }
9222+}
9223+
9224+/**
9225+ * End element handler for the XML parser
9226+ *
9227+ * @return void
9228+ */
9229+function XML_RPC_ee($parser_resource, $name)
9230+{
9231+ global $XML_RPC_xh, $XML_RPC_Types, $XML_RPC_String;
9232+ $parser = (int) $parser_resource;
9233+
9234+ if ($XML_RPC_xh[$parser]['isf'] >= 2) {
9235+ return;
9236+ }
9237+
9238+ // push this element from stack
9239+ // NB: if XML validates, correct opening/closing is guaranteed and
9240+ // we do not have to check for $name == $curr_elem.
9241+ // we also checked for proper nesting at start of elements...
9242+ $curr_elem = array_shift($XML_RPC_xh[$parser]['stack']);
9243+
9244+ switch ($name) {
9245+ case 'STRUCT':
9246+ case 'ARRAY':
9247+ $cur_val = array_shift($XML_RPC_xh[$parser]['valuestack']);
9248+ $XML_RPC_xh[$parser]['value'] = $cur_val['value'];
9249+ $XML_RPC_xh[$parser]['vt'] = strtolower($name);
9250+ $XML_RPC_xh[$parser]['cm']--;
9251+ break;
9252+
9253+ case 'NAME':
9254+ $XML_RPC_xh[$parser]['valuestack'][0]['name'] = $XML_RPC_xh[$parser]['ac'];
9255+ break;
9256+
9257+ case 'BOOLEAN':
9258+ // special case here: we translate boolean 1 or 0 into PHP
9259+ // constants true or false
9260+ if ($XML_RPC_xh[$parser]['ac'] == '1') {
9261+ $XML_RPC_xh[$parser]['ac'] = 'true';
9262+ } else {
9263+ $XML_RPC_xh[$parser]['ac'] = 'false';
9264+ }
9265+
9266+ $XML_RPC_xh[$parser]['vt'] = strtolower($name);
9267+ // Drop through intentionally.
9268+
9269+ case 'I4':
9270+ case 'INT':
9271+ case 'STRING':
9272+ case 'DOUBLE':
9273+ case 'DATETIME.ISO8601':
9274+ case 'BASE64':
9275+ if ($XML_RPC_xh[$parser]['qt'] == 1) {
9276+ // we use double quotes rather than single so backslashification works OK
9277+ $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac'];
9278+ } elseif ($XML_RPC_xh[$parser]['qt'] == 2) {
9279+ $XML_RPC_xh[$parser]['value'] = base64_decode($XML_RPC_xh[$parser]['ac']);
9280+ } elseif ($name == 'BOOLEAN') {
9281+ $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac'];
9282+ } else {
9283+ // we have an I4, INT or a DOUBLE
9284+ // we must check that only 0123456789-.<space> are characters here
9285+ if (!ereg("^[+-]?[0123456789 \t\.]+$", $XML_RPC_xh[$parser]['ac'])) {
9286+ XML_RPC_Base::raiseError('Non-numeric value received in INT or DOUBLE',
9287+ XML_RPC_ERROR_NON_NUMERIC_FOUND);
9288+ $XML_RPC_xh[$parser]['value'] = XML_RPC_ERROR_NON_NUMERIC_FOUND;
9289+ } else {
9290+ // it's ok, add it on
9291+ $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac'];
9292+ }
9293+ }
9294+
9295+ $XML_RPC_xh[$parser]['ac'] = '';
9296+ $XML_RPC_xh[$parser]['qt'] = 0;
9297+ $XML_RPC_xh[$parser]['lv'] = 3; // indicate we've found a value
9298+ break;
9299+
9300+ case 'VALUE':
9301+ // deal with a string value
9302+ if (strlen($XML_RPC_xh[$parser]['ac']) > 0 &&
9303+ $XML_RPC_xh[$parser]['vt'] == $XML_RPC_String) {
9304+ $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac'];
9305+ }
9306+
9307+ $temp = new XML_RPC_Value($XML_RPC_xh[$parser]['value'], $XML_RPC_xh[$parser]['vt']);
9308+
9309+ $cur_val = array_shift($XML_RPC_xh[$parser]['valuestack']);
9310+ if (is_array($cur_val)) {
9311+ if ($cur_val['members']==0) {
9312+ $cur_val['value'][] = $temp;
9313+ } else {
9314+ $XML_RPC_xh[$parser]['value'] = $temp;
9315+ }
9316+ array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val);
9317+ } else {
9318+ $XML_RPC_xh[$parser]['value'] = $temp;
9319+ }
9320+ break;
9321+
9322+ case 'MEMBER':
9323+ $XML_RPC_xh[$parser]['ac'] = '';
9324+ $XML_RPC_xh[$parser]['qt'] = 0;
9325+
9326+ $cur_val = array_shift($XML_RPC_xh[$parser]['valuestack']);
9327+ if (is_array($cur_val)) {
9328+ if ($cur_val['members']==1) {
9329+ $cur_val['value'][$cur_val['name']] = $XML_RPC_xh[$parser]['value'];
9330+ }
9331+ array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val);
9332+ }
9333+ break;
9334+
9335+ case 'DATA':
9336+ $XML_RPC_xh[$parser]['ac'] = '';
9337+ $XML_RPC_xh[$parser]['qt'] = 0;
9338+ break;
9339+
9340+ case 'PARAM':
9341+ $XML_RPC_xh[$parser]['params'][] = $XML_RPC_xh[$parser]['value'];
9342+ break;
9343+
9344+ case 'METHODNAME':
9345+ case 'RPCMETHODNAME':
9346+ $XML_RPC_xh[$parser]['method'] = ereg_replace("^[\n\r\t ]+", '',
9347+ $XML_RPC_xh[$parser]['ac']);
9348+ break;
9349+ }
9350+
9351+ // if it's a valid type name, set the type
9352+ if (isset($XML_RPC_Types[strtolower($name)])) {
9353+ $XML_RPC_xh[$parser]['vt'] = strtolower($name);
9354+ }
9355+}
9356+
9357+/**
9358+ * Character data handler for the XML parser
9359+ *
9360+ * @return void
9361+ */
9362+function XML_RPC_cd($parser_resource, $data)
9363+{
9364+ global $XML_RPC_xh, $XML_RPC_backslash;
9365+ $parser = (int) $parser_resource;
9366+
9367+ if ($XML_RPC_xh[$parser]['lv'] != 3) {
9368+ // "lookforvalue==3" means that we've found an entire value
9369+ // and should discard any further character data
9370+
9371+ if ($XML_RPC_xh[$parser]['lv'] == 1) {
9372+ // if we've found text and we're just in a <value> then
9373+ // turn quoting on, as this will be a string
9374+ $XML_RPC_xh[$parser]['qt'] = 1;
9375+ // and say we've found a value
9376+ $XML_RPC_xh[$parser]['lv'] = 2;
9377+ }
9378+
9379+ // replace characters that eval would
9380+ // do special things with
9381+ if (!isset($XML_RPC_xh[$parser]['ac'])) {
9382+ $XML_RPC_xh[$parser]['ac'] = '';
9383+ }
9384+ $XML_RPC_xh[$parser]['ac'] .= $data;
9385+ }
9386+}
9387+
9388+/**
9389+ * The common methods and properties for all of the XML_RPC classes
9390+ *
9391+ * @category Web Services
9392+ * @package XML_RPC
9393+ * @author Edd Dumbill <edd@usefulinc.com>
9394+ * @author Stig Bakken <stig@php.net>
9395+ * @author Martin Jansen <mj@php.net>
9396+ * @author Daniel Convissor <danielc@php.net>
9397+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
9398+ * @version Release: 1.4.0
9399+ * @link http://pear.php.net/package/XML_RPC
9400+ */
9401+class XML_RPC_Base {
9402+
9403+ /**
9404+ * PEAR Error handling
9405+ *
9406+ * @return object PEAR_Error object
9407+ */
9408+ function raiseError($msg, $code)
9409+ {
9410+ include_once 'PEAR.php';
9411+ if (is_object(@$this)) {
9412+ return PEAR::raiseError(get_class($this) . ': ' . $msg, $code);
9413+ } else {
9414+ return PEAR::raiseError('XML_RPC: ' . $msg, $code);
9415+ }
9416+ }
9417+
9418+ /**
9419+ * Tell whether something is a PEAR_Error object
9420+ *
9421+ * @param mixed $value the item to check
9422+ *
9423+ * @return bool whether $value is a PEAR_Error object or not
9424+ *
9425+ * @access public
9426+ */
9427+ function isError($value)
9428+ {
9429+ return is_a($value, 'PEAR_Error');
9430+ }
9431+}
9432+
9433+/**
9434+ * The methods and properties for submitting XML RPC requests
9435+ *
9436+ * @category Web Services
9437+ * @package XML_RPC
9438+ * @author Edd Dumbill <edd@usefulinc.com>
9439+ * @author Stig Bakken <stig@php.net>
9440+ * @author Martin Jansen <mj@php.net>
9441+ * @author Daniel Convissor <danielc@php.net>
9442+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
9443+ * @version Release: 1.4.0
9444+ * @link http://pear.php.net/package/XML_RPC
9445+ */
9446+class XML_RPC_Client extends XML_RPC_Base {
9447+
9448+ /**
9449+ * The path and name of the RPC server script you want the request to go to
9450+ * @var string
9451+ */
9452+ var $path = '';
9453+
9454+ /**
9455+ * The name of the remote server to connect to
9456+ * @var string
9457+ */
9458+ var $server = '';
9459+
9460+ /**
9461+ * The protocol to use in contacting the remote server
9462+ * @var string
9463+ */
9464+ var $protocol = 'http://';
9465+
9466+ /**
9467+ * The port for connecting to the remote server
9468+ *
9469+ * The default is 80 for http:// connections
9470+ * and 443 for https:// and ssl:// connections.
9471+ *
9472+ * @var integer
9473+ */
9474+ var $port = 80;
9475+
9476+ /**
9477+ * A user name for accessing the RPC server
9478+ * @var string
9479+ * @see XML_RPC_Client::setCredentials()
9480+ */
9481+ var $username = '';
9482+
9483+ /**
9484+ * A password for accessing the RPC server
9485+ * @var string
9486+ * @see XML_RPC_Client::setCredentials()
9487+ */
9488+ var $password = '';
9489+
9490+ /**
9491+ * The name of the proxy server to use, if any
9492+ * @var string
9493+ */
9494+ var $proxy = '';
9495+
9496+ /**
9497+ * The protocol to use in contacting the proxy server, if any
9498+ * @var string
9499+ */
9500+ var $proxy_protocol = 'http://';
9501+
9502+ /**
9503+ * The port for connecting to the proxy server
9504+ *
9505+ * The default is 8080 for http:// connections
9506+ * and 443 for https:// and ssl:// connections.
9507+ *
9508+ * @var integer
9509+ */
9510+ var $proxy_port = 8080;
9511+
9512+ /**
9513+ * A user name for accessing the proxy server
9514+ * @var string
9515+ */
9516+ var $proxy_user = '';
9517+
9518+ /**
9519+ * A password for accessing the proxy server
9520+ * @var string
9521+ */
9522+ var $proxy_pass = '';
9523+
9524+ /**
9525+ * The error number, if any
9526+ * @var integer
9527+ */
9528+ var $errno = 0;
9529+
9530+ /**
9531+ * The error message, if any
9532+ * @var string
9533+ */
9534+ var $errstr = '';
9535+
9536+ /**
9537+ * The current debug mode (1 = on, 0 = off)
9538+ * @var integer
9539+ */
9540+ var $debug = 0;
9541+
9542+ /**
9543+ * The HTTP headers for the current request.
9544+ * @var string
9545+ */
9546+ var $headers = '';
9547+
9548+
9549+ /**
9550+ * Sets the object's properties
9551+ *
9552+ * @param string $path the path and name of the RPC server script
9553+ * you want the request to go to
9554+ * @param string $server the URL of the remote server to connect to.
9555+ * If this parameter doesn't specify a
9556+ * protocol and $port is 443, ssl:// is
9557+ * assumed.
9558+ * @param integer $port a port for connecting to the remote server.
9559+ * Defaults to 80 for http:// connections and
9560+ * 443 for https:// and ssl:// connections.
9561+ * @param string $proxy the URL of the proxy server to use, if any.
9562+ * If this parameter doesn't specify a
9563+ * protocol and $port is 443, ssl:// is
9564+ * assumed.
9565+ * @param integer $proxy_port a port for connecting to the remote server.
9566+ * Defaults to 8080 for http:// connections and
9567+ * 443 for https:// and ssl:// connections.
9568+ * @param string $proxy_user a user name for accessing the proxy server
9569+ * @param string $proxy_pass a password for accessing the proxy server
9570+ *
9571+ * @return void
9572+ */
9573+ function XML_RPC_Client($path, $server, $port = 0,
9574+ $proxy = '', $proxy_port = 0,
9575+ $proxy_user = '', $proxy_pass = '')
9576+ {
9577+ $this->path = $path;
9578+ $this->proxy_user = $proxy_user;
9579+ $this->proxy_pass = $proxy_pass;
9580+
9581+ preg_match('@^(http://|https://|ssl://)?(.*)$@', $server, $match);
9582+ if ($match[1] == '') {
9583+ if ($port == 443) {
9584+ $this->server = $match[2];
9585+ $this->protocol = 'ssl://';
9586+ $this->port = 443;
9587+ } else {
9588+ $this->server = $match[2];
9589+ if ($port) {
9590+ $this->port = $port;
9591+ }
9592+ }
9593+ } elseif ($match[1] == 'http://') {
9594+ $this->server = $match[2];
9595+ if ($port) {
9596+ $this->port = $port;
9597+ }
9598+ } else {
9599+ $this->server = $match[2];
9600+ $this->protocol = 'ssl://';
9601+ if ($port) {
9602+ $this->port = $port;
9603+ } else {
9604+ $this->port = 443;
9605+ }
9606+ }
9607+
9608+ if ($proxy) {
9609+ preg_match('@^(http://|https://|ssl://)?(.*)$@', $proxy, $match);
9610+ if ($match[1] == '') {
9611+ if ($proxy_port == 443) {
9612+ $this->proxy = $match[2];
9613+ $this->proxy_protocol = 'ssl://';
9614+ $this->proxy_port = 443;
9615+ } else {
9616+ $this->proxy = $match[2];
9617+ if ($proxy_port) {
9618+ $this->proxy_port = $proxy_port;
9619+ }
9620+ }
9621+ } elseif ($match[1] == 'http://') {
9622+ $this->proxy = $match[2];
9623+ if ($proxy_port) {
9624+ $this->proxy_port = $proxy_port;
9625+ }
9626+ } else {
9627+ $this->proxy = $match[2];
9628+ $this->proxy_protocol = 'ssl://';
9629+ if ($proxy_port) {
9630+ $this->proxy_port = $proxy_port;
9631+ } else {
9632+ $this->proxy_port = 443;
9633+ }
9634+ }
9635+ }
9636+ }
9637+
9638+ /**
9639+ * Change the current debug mode
9640+ *
9641+ * @param int $in where 1 = on, 0 = off
9642+ *
9643+ * @return void
9644+ */
9645+ function setDebug($in)
9646+ {
9647+ if ($in) {
9648+ $this->debug = 1;
9649+ } else {
9650+ $this->debug = 0;
9651+ }
9652+ }
9653+
9654+ /**
9655+ * Set username and password properties for connecting to the RPC server
9656+ *
9657+ * @param string $u the user name
9658+ * @param string $p the password
9659+ *
9660+ * @return void
9661+ *
9662+ * @see XML_RPC_Client::$username, XML_RPC_Client::$password
9663+ */
9664+ function setCredentials($u, $p)
9665+ {
9666+ $this->username = $u;
9667+ $this->password = $p;
9668+ }
9669+
9670+ /**
9671+ * Transmit the RPC request via HTTP 1.0 protocol
9672+ *
9673+ * @param object $msg the XML_RPC_Message object
9674+ * @param int $timeout how many seconds to wait for the request
9675+ *
9676+ * @return object an XML_RPC_Response object. 0 is returned if any
9677+ * problems happen.
9678+ *
9679+ * @see XML_RPC_Message, XML_RPC_Client::XML_RPC_Client(),
9680+ * XML_RPC_Client::setCredentials()
9681+ */
9682+ function send($msg, $timeout = 0)
9683+ {
9684+ if (strtolower(get_class($msg)) != 'xml_rpc_message') {
9685+ $this->errstr = 'send()\'s $msg parameter must be an'
9686+ . ' XML_RPC_Message object.';
9687+ $this->raiseError($this->errstr, XML_RPC_ERROR_PROGRAMMING);
9688+ return 0;
9689+ }
9690+ $msg->debug = $this->debug;
9691+ return $this->sendPayloadHTTP10($msg, $this->server, $this->port,
9692+ $timeout, $this->username,
9693+ $this->password);
9694+ }
9695+
9696+ /**
9697+ * Transmit the RPC request via HTTP 1.0 protocol
9698+ *
9699+ * Requests should be sent using XML_RPC_Client send() rather than
9700+ * calling this method directly.
9701+ *
9702+ * @param object $msg the XML_RPC_Message object
9703+ * @param string $server the server to send the request to
9704+ * @param int $port the server port send the request to
9705+ * @param int $timeout how many seconds to wait for the request
9706+ * before giving up
9707+ * @param string $username a user name for accessing the RPC server
9708+ * @param string $password a password for accessing the RPC server
9709+ *
9710+ * @return object an XML_RPC_Response object. 0 is returned if any
9711+ * problems happen.
9712+ *
9713+ * @access protected
9714+ * @see XML_RPC_Client::send()
9715+ */
9716+ function sendPayloadHTTP10($msg, $server, $port, $timeout = 0,
9717+ $username = '', $password = '')
9718+ {
9719+ /*
9720+ * If we're using a proxy open a socket to the proxy server
9721+ * instead to the xml-rpc server
9722+ */
9723+ if ($this->proxy) {
9724+ if ($this->proxy_protocol == 'http://') {
9725+ $protocol = '';
9726+ } else {
9727+ $protocol = $this->proxy_protocol;
9728+ }
9729+ if ($timeout > 0) {
9730+ $fp = @fsockopen($protocol . $this->proxy, $this->proxy_port,
9731+ $this->errno, $this->errstr, $timeout);
9732+ } else {
9733+ $fp = @fsockopen($protocol . $this->proxy, $this->proxy_port,
9734+ $this->errno, $this->errstr);
9735+ }
9736+ } else {
9737+ if ($this->protocol == 'http://') {
9738+ $protocol = '';
9739+ } else {
9740+ $protocol = $this->protocol;
9741+ }
9742+ if ($timeout > 0) {
9743+ $fp = @fsockopen($protocol . $server, $port,
9744+ $this->errno, $this->errstr, $timeout);
9745+ } else {
9746+ $fp = @fsockopen($protocol . $server, $port,
9747+ $this->errno, $this->errstr);
9748+ }
9749+ }
9750+
9751+ /*
9752+ * Just raising the error without returning it is strange,
9753+ * but keep it here for backwards compatibility.
9754+ */
9755+ if (!$fp && $this->proxy) {
9756+ $this->raiseError('Connection to proxy server '
9757+ . $this->proxy . ':' . $this->proxy_port
9758+ . ' failed. ' . $this->errstr,
9759+ XML_RPC_ERROR_CONNECTION_FAILED);
9760+ return 0;
9761+ } elseif (!$fp) {
9762+ $this->raiseError('Connection to RPC server '
9763+ . $server . ':' . $port
9764+ . ' failed. ' . $this->errstr,
9765+ XML_RPC_ERROR_CONNECTION_FAILED);
9766+ return 0;
9767+ }
9768+
9769+ if ($timeout) {
9770+ /*
9771+ * Using socket_set_timeout() because stream_set_timeout()
9772+ * was introduced in 4.3.0, but we need to support 4.2.0.
9773+ */
9774+ socket_set_timeout($fp, $timeout);
9775+ }
9776+
9777+ // Pre-emptive BC hacks for fools calling sendPayloadHTTP10() directly
9778+ if ($username != $this->username) {
9779+ $this->setCredentials($username, $password);
9780+ }
9781+
9782+ // Only create the payload if it was not created previously
9783+ if (empty($msg->payload)) {
9784+ $msg->createPayload();
9785+ }
9786+ $this->createHeaders($msg);
9787+
9788+ $op = $this->headers . "\r\n\r\n";
9789+ $op .= $msg->payload;
9790+
9791+ if (!fputs($fp, $op, strlen($op))) {
9792+ $this->errstr = 'Write error';
9793+ return 0;
9794+ }
9795+ $resp = $msg->parseResponseFile($fp);
9796+
9797+ $meta = socket_get_status($fp);
9798+ if ($meta['timed_out']) {
9799+ fclose($fp);
9800+ $this->errstr = 'RPC server did not send response before timeout.';
9801+ $this->raiseError($this->errstr, XML_RPC_ERROR_CONNECTION_FAILED);
9802+ return 0;
9803+ }
9804+
9805+ fclose($fp);
9806+ return $resp;
9807+ }
9808+
9809+ /**
9810+ * Determines the HTTP headers and puts it in the $headers property
9811+ *
9812+ * @param object $msg the XML_RPC_Message object
9813+ *
9814+ * @return boolean TRUE if okay, FALSE if the message payload isn't set.
9815+ *
9816+ * @access protected
9817+ */
9818+ function createHeaders($msg)
9819+ {
9820+ if (empty($msg->payload)) {
9821+ return false;
9822+ }
9823+ if ($this->proxy) {
9824+ $this->headers = 'POST ' . $this->protocol . $this->server;
9825+ if ($this->proxy_port) {
9826+ $this->headers .= ':' . $this->port;
9827+ }
9828+ } else {
9829+ $this->headers = 'POST ';
9830+ }
9831+ $this->headers .= $this->path. " HTTP/1.0\r\n";
9832+
9833+ $this->headers .= "User-Agent: PEAR XML_RPC\r\n";
9834+ $this->headers .= 'Host: ' . $this->server . "\r\n";
9835+
9836+ if ($this->proxy && $this->proxy_user) {
9837+ $this->headers .= 'Proxy-Authorization: Basic '
9838+ . base64_encode("$this->proxy_user:$this->proxy_pass")
9839+ . "\r\n";
9840+ }
9841+
9842+ // thanks to Grant Rauscher <grant7@firstworld.net> for this
9843+ if ($this->username) {
9844+ $this->headers .= 'Authorization: Basic '
9845+ . base64_encode("$this->username:$this->password")
9846+ . "\r\n";
9847+ }
9848+
9849+ $this->headers .= "Content-Type: text/xml\r\n";
9850+ $this->headers .= 'Content-Length: ' . strlen($msg->payload);
9851+ return true;
9852+ }
9853+}
9854+
9855+/**
9856+ * The methods and properties for interpreting responses to XML RPC requests
9857+ *
9858+ * @category Web Services
9859+ * @package XML_RPC
9860+ * @author Edd Dumbill <edd@usefulinc.com>
9861+ * @author Stig Bakken <stig@php.net>
9862+ * @author Martin Jansen <mj@php.net>
9863+ * @author Daniel Convissor <danielc@php.net>
9864+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
9865+ * @version Release: 1.4.0
9866+ * @link http://pear.php.net/package/XML_RPC
9867+ */
9868+class XML_RPC_Response extends XML_RPC_Base
9869+{
9870+ var $xv;
9871+ var $fn;
9872+ var $fs;
9873+ var $hdrs;
9874+
9875+ /**
9876+ * @return void
9877+ */
9878+ function XML_RPC_Response($val, $fcode = 0, $fstr = '')
9879+ {
9880+ if ($fcode != 0) {
9881+ $this->fn = $fcode;
9882+ $this->fs = htmlspecialchars($fstr);
9883+ } else {
9884+ $this->xv = $val;
9885+ }
9886+ }
9887+
9888+ /**
9889+ * @return int the error code
9890+ */
9891+ function faultCode()
9892+ {
9893+ if (isset($this->fn)) {
9894+ return $this->fn;
9895+ } else {
9896+ return 0;
9897+ }
9898+ }
9899+
9900+ /**
9901+ * @return string the error string
9902+ */
9903+ function faultString()
9904+ {
9905+ return $this->fs;
9906+ }
9907+
9908+ /**
9909+ * @return mixed the value
9910+ */
9911+ function value()
9912+ {
9913+ return $this->xv;
9914+ }
9915+
9916+ /**
9917+ * @return string the error message in XML format
9918+ */
9919+ function serialize()
9920+ {
9921+ $rs = "<methodResponse>\n";
9922+ if ($this->fn) {
9923+ $rs .= "<fault>
9924+ <value>
9925+ <struct>
9926+ <member>
9927+ <name>faultCode</name>
9928+ <value><int>" . $this->fn . "</int></value>
9929+ </member>
9930+ <member>
9931+ <name>faultString</name>
9932+ <value><string>" . $this->fs . "</string></value>
9933+ </member>
9934+ </struct>
9935+ </value>
9936+</fault>";
9937+ } else {
9938+ $rs .= "<params>\n<param>\n" . $this->xv->serialize() .
9939+ "</param>\n</params>";
9940+ }
9941+ $rs .= "\n</methodResponse>";
9942+ return $rs;
9943+ }
9944+}
9945+
9946+/**
9947+ * The methods and properties for composing XML RPC messages
9948+ *
9949+ * @category Web Services
9950+ * @package XML_RPC
9951+ * @author Edd Dumbill <edd@usefulinc.com>
9952+ * @author Stig Bakken <stig@php.net>
9953+ * @author Martin Jansen <mj@php.net>
9954+ * @author Daniel Convissor <danielc@php.net>
9955+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
9956+ * @version Release: 1.4.0
9957+ * @link http://pear.php.net/package/XML_RPC
9958+ */
9959+class XML_RPC_Message extends XML_RPC_Base
9960+{
9961+ /**
9962+ * The current debug mode (1 = on, 0 = off)
9963+ * @var integer
9964+ */
9965+ var $debug = 0;
9966+
9967+ /**
9968+ * The encoding to be used for outgoing messages
9969+ *
9970+ * Defaults to the value of <var>$GLOBALS['XML_RPC_defencoding']</var>
9971+ *
9972+ * @var string
9973+ * @see XML_RPC_Message::setSendEncoding(),
9974+ * $GLOBALS['XML_RPC_defencoding'], XML_RPC_Message::xml_header()
9975+ */
9976+ var $send_encoding = '';
9977+
9978+ /**
9979+ * The method presently being evaluated
9980+ * @var string
9981+ */
9982+ var $methodname = '';
9983+
9984+ /**
9985+ * @var array
9986+ */
9987+ var $params = array();
9988+
9989+ /**
9990+ * The XML message being generated
9991+ * @var string
9992+ */
9993+ var $payload = '';
9994+
9995+ /**
9996+ * @return void
9997+ */
9998+ function XML_RPC_Message($meth, $pars = 0)
9999+ {
10000+ $this->methodname = $meth;
10001+ if (is_array($pars) && sizeof($pars) > 0) {
10002+ for ($i = 0; $i < sizeof($pars); $i++) {
10003+ $this->addParam($pars[$i]);
10004+ }
10005+ }
10006+ }
10007+
10008+ /**
10009+ * Produces the XML declaration including the encoding attribute
10010+ *
10011+ * The encoding is determined by this class' <var>$send_encoding</var>
10012+ * property. If the <var>$send_encoding</var> property is not set, use
10013+ * <var>$GLOBALS['XML_RPC_defencoding']</var>.
10014+ *
10015+ * @return string the XML declaration and <methodCall> element
10016+ *
10017+ * @see XML_RPC_Message::setSendEncoding(),
10018+ * XML_RPC_Message::$send_encoding, $GLOBALS['XML_RPC_defencoding']
10019+ */
10020+ function xml_header()
10021+ {
10022+ global $XML_RPC_defencoding;
10023+ if (!$this->send_encoding) {
10024+ $this->send_encoding = $XML_RPC_defencoding;
10025+ }
10026+ return '<?xml version="1.0" encoding="' . $this->send_encoding . '"?>'
10027+ . "\n<methodCall>\n";
10028+ }
10029+
10030+ /**
10031+ * @return string the closing </methodCall> tag
10032+ */
10033+ function xml_footer()
10034+ {
10035+ return "</methodCall>\n";
10036+ }
10037+
10038+ /**
10039+ * @return void
10040+ *
10041+ * @uses XML_RPC_Message::xml_header(), XML_RPC_Message::xml_footer()
10042+ */
10043+ function createPayload()
10044+ {
10045+ $this->payload = $this->xml_header();
10046+ $this->payload .= '<methodName>' . $this->methodname . "</methodName>\n";
10047+ $this->payload .= "<params>\n";
10048+ for ($i = 0; $i < sizeof($this->params); $i++) {
10049+ $p = $this->params[$i];
10050+ $this->payload .= "<param>\n" . $p->serialize() . "</param>\n";
10051+ }
10052+ $this->payload .= "</params>\n";
10053+ $this->payload .= $this->xml_footer();
10054+ $this->payload = ereg_replace("[\r\n]+", "\r\n", $this->payload);
10055+ }
10056+
10057+ /**
10058+ * @return string the name of the method
10059+ */
10060+ function method($meth = '')
10061+ {
10062+ if ($meth != '') {
10063+ $this->methodname = $meth;
10064+ }
10065+ return $this->methodname;
10066+ }
10067+
10068+ /**
10069+ * @return string the payload
10070+ */
10071+ function serialize()
10072+ {
10073+ $this->createPayload();
10074+ return $this->payload;
10075+ }
10076+
10077+ /**
10078+ * @return void
10079+ */
10080+ function addParam($par)
10081+ {
10082+ $this->params[] = $par;
10083+ }
10084+
10085+ /**
10086+ * Obtains an XML_RPC_Value object for the given parameter
10087+ *
10088+ * @param int $i the index number of the parameter to obtain
10089+ *
10090+ * @return object the XML_RPC_Value object.
10091+ * If the parameter doesn't exist, an XML_RPC_Response object.
10092+ *
10093+ * @since Returns XML_RPC_Response object on error since Release 1.3.0
10094+ */
10095+ function getParam($i)
10096+ {
10097+ global $XML_RPC_err, $XML_RPC_str;
10098+
10099+ if (isset($this->params[$i])) {
10100+ return $this->params[$i];
10101+ } else {
10102+ $this->raiseError('The submitted request did not contain this parameter',
10103+ XML_RPC_ERROR_INCORRECT_PARAMS);
10104+ return new XML_RPC_Response(0, $XML_RPC_err['incorrect_params'],
10105+ $XML_RPC_str['incorrect_params']);
10106+ }
10107+ }
10108+
10109+ /**
10110+ * @return int the number of parameters
10111+ */
10112+ function getNumParams()
10113+ {
10114+ return sizeof($this->params);
10115+ }
10116+
10117+ /**
10118+ * Sets the XML declaration's encoding attribute
10119+ *
10120+ * @param string $type the encoding type (ISO-8859-1, UTF-8 or US-ASCII)
10121+ *
10122+ * @return void
10123+ *
10124+ * @see XML_RPC_Message::$send_encoding, XML_RPC_Message::xml_header()
10125+ * @since Method available since Release 1.2.0
10126+ */
10127+ function setSendEncoding($type)
10128+ {
10129+ $this->send_encoding = $type;
10130+ }
10131+
10132+ /**
10133+ * Determine the XML's encoding via the encoding attribute
10134+ * in the XML declaration
10135+ *
10136+ * If the encoding parameter is not set or is not ISO-8859-1, UTF-8
10137+ * or US-ASCII, $XML_RPC_defencoding will be returned.
10138+ *
10139+ * @param string $data the XML that will be parsed
10140+ *
10141+ * @return string the encoding to be used
10142+ *
10143+ * @link http://php.net/xml_parser_create
10144+ * @since Method available since Release 1.2.0
10145+ */
10146+ function getEncoding($data)
10147+ {
10148+ global $XML_RPC_defencoding;
10149+
10150+ if (preg_match('/<\?xml[^>]*\s*encoding\s*=\s*[\'"]([^"\']*)[\'"]/i',
10151+ $data, $match))
10152+ {
10153+ $match[1] = trim(strtoupper($match[1]));
10154+ switch ($match[1]) {
10155+ case 'ISO-8859-1':
10156+ case 'UTF-8':
10157+ case 'US-ASCII':
10158+ return $match[1];
10159+ break;
10160+
10161+ default:
10162+ return $XML_RPC_defencoding;
10163+ }
10164+ } else {
10165+ return $XML_RPC_defencoding;
10166+ }
10167+ }
10168+
10169+ /**
10170+ * @return object a new XML_RPC_Response object
10171+ */
10172+ function parseResponseFile($fp)
10173+ {
10174+ $ipd = '';
10175+ while ($data = @fread($fp, 8192)) {
10176+ $ipd .= $data;
10177+ }
10178+ return $this->parseResponse($ipd);
10179+ }
10180+
10181+ /**
10182+ * @return object a new XML_RPC_Response object
10183+ */
10184+ function parseResponse($data = '')
10185+ {
10186+ global $XML_RPC_xh, $XML_RPC_err, $XML_RPC_str, $XML_RPC_defencoding;
10187+
10188+ $encoding = $this->getEncoding($data);
10189+ $parser_resource = xml_parser_create($encoding);
10190+ $parser = (int) $parser_resource;
10191+
10192+ $XML_RPC_xh = array();
10193+ $XML_RPC_xh[$parser] = array();
10194+
10195+ $XML_RPC_xh[$parser]['cm'] = 0;
10196+ $XML_RPC_xh[$parser]['isf'] = 0;
10197+ $XML_RPC_xh[$parser]['ac'] = '';
10198+ $XML_RPC_xh[$parser]['qt'] = '';
10199+ $XML_RPC_xh[$parser]['stack'] = array();
10200+ $XML_RPC_xh[$parser]['valuestack'] = array();
10201+
10202+ xml_parser_set_option($parser_resource, XML_OPTION_CASE_FOLDING, true);
10203+ xml_set_element_handler($parser_resource, 'XML_RPC_se', 'XML_RPC_ee');
10204+ xml_set_character_data_handler($parser_resource, 'XML_RPC_cd');
10205+
10206+ $hdrfnd = 0;
10207+ if ($this->debug) {
10208+ print "\n<pre>---GOT---\n";
10209+ print isset($_SERVER['SERVER_PROTOCOL']) ? htmlspecialchars($data) : $data;
10210+ print "\n---END---</pre>\n";
10211+ }
10212+
10213+ // See if response is a 200 or a 100 then a 200, else raise error.
10214+ // But only do this if we're using the HTTP protocol.
10215+ if (ereg('^HTTP', $data) &&
10216+ !ereg('^HTTP/[0-9\.]+ 200 ', $data) &&
10217+ !preg_match('@^HTTP/[0-9\.]+ 10[0-9]([A-Za-z ]+)?[\r\n]+HTTP/[0-9\.]+ 200@', $data))
10218+ {
10219+ $errstr = substr($data, 0, strpos($data, "\n") - 1);
10220+ error_log('HTTP error, got response: ' . $errstr);
10221+ $r = new XML_RPC_Response(0, $XML_RPC_err['http_error'],
10222+ $XML_RPC_str['http_error'] . ' (' .
10223+ $errstr . ')');
10224+ xml_parser_free($parser_resource);
10225+ return $r;
10226+ }
10227+
10228+ // gotta get rid of headers here
10229+ if (!$hdrfnd && ($brpos = strpos($data,"\r\n\r\n"))) {
10230+ $XML_RPC_xh[$parser]['ha'] = substr($data, 0, $brpos);
10231+ $data = substr($data, $brpos + 4);
10232+ $hdrfnd = 1;
10233+ }
10234+
10235+ /*
10236+ * be tolerant of junk after methodResponse
10237+ * (e.g. javascript automatically inserted by free hosts)
10238+ * thanks to Luca Mariano <luca.mariano@email.it>
10239+ */
10240+ $data = substr($data, 0, strpos($data, "</methodResponse>") + 17);
10241+
10242+ if (!xml_parse($parser_resource, $data, sizeof($data))) {
10243+ // thanks to Peter Kocks <peter.kocks@baygate.com>
10244+ if (xml_get_current_line_number($parser_resource) == 1) {
10245+ $errstr = 'XML error at line 1, check URL';
10246+ } else {
10247+ $errstr = sprintf('XML error: %s at line %d',
10248+ xml_error_string(xml_get_error_code($parser_resource)),
10249+ xml_get_current_line_number($parser_resource));
10250+ }
10251+ error_log($errstr);
10252+ $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'],
10253+ $XML_RPC_str['invalid_return']);
10254+ xml_parser_free($parser_resource);
10255+ return $r;
10256+ }
10257+
10258+ xml_parser_free($parser_resource);
10259+
10260+ if ($this->debug) {
10261+ print "\n<pre>---PARSED---\n";
10262+ var_dump($XML_RPC_xh[$parser]['value']);
10263+ print "---END---</pre>\n";
10264+ }
10265+
10266+ if ($XML_RPC_xh[$parser]['isf'] > 1) {
10267+ $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'],
10268+ $XML_RPC_str['invalid_return'].' '.$XML_RPC_xh[$parser]['isf_reason']);
10269+ } elseif (!is_object($XML_RPC_xh[$parser]['value'])) {
10270+ // then something odd has happened
10271+ // and it's time to generate a client side error
10272+ // indicating something odd went on
10273+ $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'],
10274+ $XML_RPC_str['invalid_return']);
10275+ } else {
10276+ $v = $XML_RPC_xh[$parser]['value'];
10277+ $allOK=1;
10278+ if ($XML_RPC_xh[$parser]['isf']) {
10279+ $f = $v->structmem('faultCode');
10280+ $fs = $v->structmem('faultString');
10281+ $r = new XML_RPC_Response($v, $f->scalarval(),
10282+ $fs->scalarval());
10283+ } else {
10284+ $r = new XML_RPC_Response($v);
10285+ }
10286+ }
10287+ $r->hdrs = split("\r?\n", $XML_RPC_xh[$parser]['ha'][1]);
10288+ return $r;
10289+ }
10290+}
10291+
10292+/**
10293+ * The methods and properties that represent data in XML RPC format
10294+ *
10295+ * @category Web Services
10296+ * @package XML_RPC
10297+ * @author Edd Dumbill <edd@usefulinc.com>
10298+ * @author Stig Bakken <stig@php.net>
10299+ * @author Martin Jansen <mj@php.net>
10300+ * @author Daniel Convissor <danielc@php.net>
10301+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
10302+ * @version Release: 1.4.0
10303+ * @link http://pear.php.net/package/XML_RPC
10304+ */
10305+class XML_RPC_Value extends XML_RPC_Base
10306+{
10307+ var $me = array();
10308+ var $mytype = 0;
10309+
10310+ /**
10311+ * @return void
10312+ */
10313+ function XML_RPC_Value($val = -1, $type = '')
10314+ {
10315+ global $XML_RPC_Types;
10316+ $this->me = array();
10317+ $this->mytype = 0;
10318+ if ($val != -1 || $type != '') {
10319+ if ($type == '') {
10320+ $type = 'string';
10321+ }
10322+ if (!array_key_exists($type, $XML_RPC_Types)) {
10323+ // XXX
10324+ // need some way to report this error
10325+ } elseif ($XML_RPC_Types[$type] == 1) {
10326+ $this->addScalar($val, $type);
10327+ } elseif ($XML_RPC_Types[$type] == 2) {
10328+ $this->addArray($val);
10329+ } elseif ($XML_RPC_Types[$type] == 3) {
10330+ $this->addStruct($val);
10331+ }
10332+ }
10333+ }
10334+
10335+ /**
10336+ * @return int returns 1 if successful or 0 if there are problems
10337+ */
10338+ function addScalar($val, $type = 'string')
10339+ {
10340+ global $XML_RPC_Types, $XML_RPC_Boolean;
10341+
10342+ if ($this->mytype == 1) {
10343+ $this->raiseError('Scalar can have only one value',
10344+ XML_RPC_ERROR_INVALID_TYPE);
10345+ return 0;
10346+ }
10347+ $typeof = $XML_RPC_Types[$type];
10348+ if ($typeof != 1) {
10349+ $this->raiseError("Not a scalar type (${typeof})",
10350+ XML_RPC_ERROR_INVALID_TYPE);
10351+ return 0;
10352+ }
10353+
10354+ if ($type == $XML_RPC_Boolean) {
10355+ if (strcasecmp($val, 'true') == 0
10356+ || $val == 1
10357+ || ($val == true && strcasecmp($val, 'false')))
10358+ {
10359+ $val = 1;
10360+ } else {
10361+ $val = 0;
10362+ }
10363+ }
10364+
10365+ if ($this->mytype == 2) {
10366+ // we're adding to an array here
10367+ $ar = $this->me['array'];
10368+ $ar[] = new XML_RPC_Value($val, $type);
10369+ $this->me['array'] = $ar;
10370+ } else {
10371+ // a scalar, so set the value and remember we're scalar
10372+ $this->me[$type] = $val;
10373+ $this->mytype = $typeof;
10374+ }
10375+ return 1;
10376+ }
10377+
10378+ /**
10379+ * @return int returns 1 if successful or 0 if there are problems
10380+ */
10381+ function addArray($vals)
10382+ {
10383+ global $XML_RPC_Types;
10384+ if ($this->mytype != 0) {
10385+ $this->raiseError(
10386+ 'Already initialized as a [' . $this->kindOf() . ']',
10387+ XML_RPC_ERROR_ALREADY_INITIALIZED);
10388+ return 0;
10389+ }
10390+ $this->mytype = $XML_RPC_Types['array'];
10391+ $this->me['array'] = $vals;
10392+ return 1;
10393+ }
10394+
10395+ /**
10396+ * @return int returns 1 if successful or 0 if there are problems
10397+ */
10398+ function addStruct($vals)
10399+ {
10400+ global $XML_RPC_Types;
10401+ if ($this->mytype != 0) {
10402+ $this->raiseError(
10403+ 'Already initialized as a [' . $this->kindOf() . ']',
10404+ XML_RPC_ERROR_ALREADY_INITIALIZED);
10405+ return 0;
10406+ }
10407+ $this->mytype = $XML_RPC_Types['struct'];
10408+ $this->me['struct'] = $vals;
10409+ return 1;
10410+ }
10411+
10412+ /**
10413+ * @return void
10414+ */
10415+ function dump($ar)
10416+ {
10417+ reset($ar);
10418+ foreach ($ar as $key => $val) {
10419+ echo "$key => $val<br />";
10420+ if ($key == 'array') {
10421+ foreach ($val as $key2 => $val2) {
10422+ echo "-- $key2 => $val2<br />";
10423+ }
10424+ }
10425+ }
10426+ }
10427+
10428+ /**
10429+ * @return string the data type of the current value
10430+ */
10431+ function kindOf()
10432+ {
10433+ switch ($this->mytype) {
10434+ case 3:
10435+ return 'struct';
10436+
10437+ case 2:
10438+ return 'array';
10439+
10440+ case 1:
10441+ return 'scalar';
10442+
10443+ default:
10444+ return 'undef';
10445+ }
10446+ }
10447+
10448+ /**
10449+ * @return string the data in XML format
10450+ */
10451+ function serializedata($typ, $val)
10452+ {
10453+ $rs = '';
10454+ global $XML_RPC_Types, $XML_RPC_Base64, $XML_RPC_String, $XML_RPC_Boolean;
10455+ if (!array_key_exists($typ, $XML_RPC_Types)) {
10456+ // XXX
10457+ // need some way to report this error
10458+ return;
10459+ }
10460+ switch ($XML_RPC_Types[$typ]) {
10461+ case 3:
10462+ // struct
10463+ $rs .= "<struct>\n";
10464+ reset($val);
10465+ foreach ($val as $key2 => $val2) {
10466+ $rs .= "<member><name>${key2}</name>\n";
10467+ $rs .= $this->serializeval($val2);
10468+ $rs .= "</member>\n";
10469+ }
10470+ $rs .= '</struct>';
10471+ break;
10472+
10473+ case 2:
10474+ // array
10475+ $rs .= "<array>\n<data>\n";
10476+ for ($i = 0; $i < sizeof($val); $i++) {
10477+ $rs .= $this->serializeval($val[$i]);
10478+ }
10479+ $rs .= "</data>\n</array>";
10480+ break;
10481+
10482+ case 1:
10483+ switch ($typ) {
10484+ case $XML_RPC_Base64:
10485+ $rs .= "<${typ}>" . base64_encode($val) . "</${typ}>";
10486+ break;
10487+ case $XML_RPC_Boolean:
10488+ $rs .= "<${typ}>" . ($val ? '1' : '0') . "</${typ}>";
10489+ break;
10490+ case $XML_RPC_String:
10491+ $rs .= "<${typ}>" . htmlspecialchars($val). "</${typ}>";
10492+ break;
10493+ default:
10494+ $rs .= "<${typ}>${val}</${typ}>";
10495+ }
10496+ }
10497+ return $rs;
10498+ }
10499+
10500+ /**
10501+ * @return string the data in XML format
10502+ */
10503+ function serialize()
10504+ {
10505+ return $this->serializeval($this);
10506+ }
10507+
10508+ /**
10509+ * @return string the data in XML format
10510+ */
10511+ function serializeval($o)
10512+ {
10513+ if (!is_object($o) || empty($o->me) || !is_array($o->me)) {
10514+ return '';
10515+ }
10516+ $ar = $o->me;
10517+ reset($ar);
10518+ list($typ, $val) = each($ar);
10519+ return '<value>' . $this->serializedata($typ, $val) . "</value>\n";
10520+ }
10521+
10522+ /**
10523+ * @return mixed the contents of the element requested
10524+ */
10525+ function structmem($m)
10526+ {
10527+ return $this->me['struct'][$m];
10528+ }
10529+
10530+ /**
10531+ * @return void
10532+ */
10533+ function structreset()
10534+ {
10535+ reset($this->me['struct']);
10536+ }
10537+
10538+ /**
10539+ * @return the key/value pair of the struct's current element
10540+ */
10541+ function structeach()
10542+ {
10543+ return each($this->me['struct']);
10544+ }
10545+
10546+ /**
10547+ * @return mixed the current value
10548+ */
10549+ function getval()
10550+ {
10551+ // UNSTABLE
10552+ global $XML_RPC_BOOLEAN, $XML_RPC_Base64;
10553+
10554+ reset($this->me);
10555+ $b = current($this->me);
10556+
10557+ // contributed by I Sofer, 2001-03-24
10558+ // add support for nested arrays to scalarval
10559+ // i've created a new method here, so as to
10560+ // preserve back compatibility
10561+
10562+ if (is_array($b)) {
10563+ foreach ($b as $id => $cont) {
10564+ $b[$id] = $cont->scalarval();
10565+ }
10566+ }
10567+
10568+ // add support for structures directly encoding php objects
10569+ if (is_object($b)) {
10570+ $t = get_object_vars($b);
10571+ foreach ($t as $id => $cont) {
10572+ $t[$id] = $cont->scalarval();
10573+ }
10574+ foreach ($t as $id => $cont) {
10575+ $b->$id = $cont;
10576+ }
10577+ }
10578+
10579+ // end contrib
10580+ return $b;
10581+ }
10582+
10583+ /**
10584+ * @return mixed
10585+ */
10586+ function scalarval()
10587+ {
10588+ global $XML_RPC_Boolean, $XML_RPC_Base64;
10589+ reset($this->me);
10590+ return current($this->me);
10591+ }
10592+
10593+ /**
10594+ * @return string
10595+ */
10596+ function scalartyp()
10597+ {
10598+ global $XML_RPC_I4, $XML_RPC_Int;
10599+ reset($this->me);
10600+ $a = key($this->me);
10601+ if ($a == $XML_RPC_I4) {
10602+ $a = $XML_RPC_Int;
10603+ }
10604+ return $a;
10605+ }
10606+
10607+ /**
10608+ * @return mixed the struct's current element
10609+ */
10610+ function arraymem($m)
10611+ {
10612+ return $this->me['array'][$m];
10613+ }
10614+
10615+ /**
10616+ * @return int the number of elements in the array
10617+ */
10618+ function arraysize()
10619+ {
10620+ reset($this->me);
10621+ list($a, $b) = each($this->me);
10622+ return sizeof($b);
10623+ }
10624+
10625+ /**
10626+ * Determines if the item submitted is an XML_RPC_Value object
10627+ *
10628+ * @param mixed $val the variable to be evaluated
10629+ *
10630+ * @return bool TRUE if the item is an XML_RPC_Value object
10631+ *
10632+ * @static
10633+ * @since Method available since Release 1.3.0
10634+ */
10635+ function isValue($val)
10636+ {
10637+ return (strtolower(get_class($val)) == 'xml_rpc_value');
10638+ }
10639+}
10640+
10641+/**
10642+ * Return an ISO8601 encoded string
10643+ *
10644+ * While timezones ought to be supported, the XML-RPC spec says:
10645+ *
10646+ * "Don't assume a timezone. It should be specified by the server in its
10647+ * documentation what assumptions it makes about timezones."
10648+ *
10649+ * This routine always assumes localtime unless $utc is set to 1, in which
10650+ * case UTC is assumed and an adjustment for locale is made when encoding.
10651+ *
10652+ * @return string the formatted date
10653+ */
10654+function XML_RPC_iso8601_encode($timet, $utc = 0)
10655+{
10656+ if (!$utc) {
10657+ $t = strftime('%Y%m%dT%H:%M:%S', $timet);
10658+ } else {
10659+ if (function_exists('gmstrftime')) {
10660+ // gmstrftime doesn't exist in some versions
10661+ // of PHP
10662+ $t = gmstrftime('%Y%m%dT%H:%M:%S', $timet);
10663+ } else {
10664+ $t = strftime('%Y%m%dT%H:%M:%S', $timet - date('Z'));
10665+ }
10666+ }
10667+ return $t;
10668+}
10669+
10670+/**
10671+ * Convert a datetime string into a Unix timestamp
10672+ *
10673+ * While timezones ought to be supported, the XML-RPC spec says:
10674+ *
10675+ * "Don't assume a timezone. It should be specified by the server in its
10676+ * documentation what assumptions it makes about timezones."
10677+ *
10678+ * This routine always assumes localtime unless $utc is set to 1, in which
10679+ * case UTC is assumed and an adjustment for locale is made when encoding.
10680+ *
10681+ * @return int the unix timestamp of the date submitted
10682+ */
10683+function XML_RPC_iso8601_decode($idate, $utc = 0)
10684+{
10685+ $t = 0;
10686+ if (ereg('([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})', $idate, $regs)) {
10687+ if ($utc) {
10688+ $t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
10689+ } else {
10690+ $t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
10691+ }
10692+ }
10693+ return $t;
10694+}
10695+
10696+/**
10697+ * Converts an XML_RPC_Value object into native PHP types
10698+ *
10699+ * @param object $XML_RPC_val the XML_RPC_Value object to decode
10700+ *
10701+ * @return mixed the PHP values
10702+ */
10703+function XML_RPC_decode($XML_RPC_val)
10704+{
10705+ $kind = $XML_RPC_val->kindOf();
10706+
10707+ if ($kind == 'scalar') {
10708+ return $XML_RPC_val->scalarval();
10709+
10710+ } elseif ($kind == 'array') {
10711+ $size = $XML_RPC_val->arraysize();
10712+ $arr = array();
10713+ for ($i = 0; $i < $size; $i++) {
10714+ $arr[] = XML_RPC_decode($XML_RPC_val->arraymem($i));
10715+ }
10716+ return $arr;
10717+
10718+ } elseif ($kind == 'struct') {
10719+ $XML_RPC_val->structreset();
10720+ $arr = array();
10721+ while (list($key, $value) = $XML_RPC_val->structeach()) {
10722+ $arr[$key] = XML_RPC_decode($value);
10723+ }
10724+ return $arr;
10725+ }
10726+}
10727+
10728+/**
10729+ * Converts native PHP types into an XML_RPC_Value object
10730+ *
10731+ * @param mixed $php_val the PHP value or variable you want encoded
10732+ *
10733+ * @return object the XML_RPC_Value object
10734+ */
10735+function XML_RPC_encode($php_val)
10736+{
10737+ global $XML_RPC_Boolean, $XML_RPC_Int, $XML_RPC_Double, $XML_RPC_String,
10738+ $XML_RPC_Array, $XML_RPC_Struct;
10739+
10740+ $type = gettype($php_val);
10741+ $XML_RPC_val = new XML_RPC_Value;
10742+
10743+ switch ($type) {
10744+ case 'array':
10745+ if (empty($php_val)) {
10746+ $XML_RPC_val->addArray($php_val);
10747+ break;
10748+ }
10749+ $tmp = array_diff(array_keys($php_val), range(0, count($php_val)-1));
10750+ if (empty($tmp)) {
10751+ $arr = array();
10752+ foreach ($php_val as $k => $v) {
10753+ $arr[$k] = XML_RPC_encode($v);
10754+ }
10755+ $XML_RPC_val->addArray($arr);
10756+ break;
10757+ }
10758+ // fall though if it's not an enumerated array
10759+
10760+ case 'object':
10761+ $arr = array();
10762+ foreach ($php_val as $k => $v) {
10763+ $arr[$k] = XML_RPC_encode($v);
10764+ }
10765+ $XML_RPC_val->addStruct($arr);
10766+ break;
10767+
10768+ case 'integer':
10769+ $XML_RPC_val->addScalar($php_val, $XML_RPC_Int);
10770+ break;
10771+
10772+ case 'double':
10773+ $XML_RPC_val->addScalar($php_val, $XML_RPC_Double);
10774+ break;
10775+
10776+ case 'string':
10777+ case 'NULL':
10778+ $XML_RPC_val->addScalar($php_val, $XML_RPC_String);
10779+ break;
10780+
10781+ case 'boolean':
10782+ // Add support for encoding/decoding of booleans, since they
10783+ // are supported in PHP
10784+ // by <G_Giunta_2001-02-29>
10785+ $XML_RPC_val->addScalar($php_val, $XML_RPC_Boolean);
10786+ break;
10787+
10788+ case 'unknown type':
10789+ default:
10790+ $XML_RPC_val = false;
10791+ }
10792+ return $XML_RPC_val;
10793+}
10794+
10795+/*
10796+ * Local variables:
10797+ * tab-width: 4
10798+ * c-basic-offset: 4
10799+ * c-hanging-comment-ender-p: nil
10800+ * End:
10801+ */
10802+
10803+?>
10804+
10805+
10806+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
10807+
10808+/**
10809+ * Server commands for our PHP implementation of the XML-RPC protocol
10810+ *
10811+ * This is a PEAR-ified version of Useful inc's XML-RPC for PHP.
10812+ * It has support for HTTP transport, proxies and authentication.
10813+ *
10814+ * PHP versions 4 and 5
10815+ *
10816+ * LICENSE: License is granted to use or modify this software
10817+ * ("XML-RPC for PHP") for commercial or non-commercial use provided the
10818+ * copyright of the author is preserved in any distributed or derivative work.
10819+ *
10820+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESSED OR
10821+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
10822+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
10823+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
10824+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
10825+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10826+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
10827+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10828+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
10829+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10830+ *
10831+ * @category Web Services
10832+ * @package XML_RPC
10833+ * @author Edd Dumbill <edd@usefulinc.com>
10834+ * @author Stig Bakken <stig@php.net>
10835+ * @author Martin Jansen <mj@php.net>
10836+ * @author Daniel Convissor <danielc@php.net>
10837+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
10838+ * @version CVS: $Id: Server.php,v 1.29 2005/08/14 20:25:35 danielc Exp $
10839+ * @link http://pear.php.net/package/XML_RPC
10840+ */
10841+
10842+
10843+/**
10844+ * Pull in the XML_RPC class
10845+ */
10846+require_once 'XML/RPC.php';
10847+
10848+
10849+/**
10850+ * signature for system.listMethods: return = array,
10851+ * parameters = a string or nothing
10852+ * @global array $GLOBALS['XML_RPC_Server_listMethods_sig']
10853+ */
10854+$GLOBALS['XML_RPC_Server_listMethods_sig'] = array(
10855+ array($GLOBALS['XML_RPC_Array'],
10856+ $GLOBALS['XML_RPC_String']
10857+ ),
10858+ array($GLOBALS['XML_RPC_Array'])
10859+);
10860+
10861+/**
10862+ * docstring for system.listMethods
10863+ * @global string $GLOBALS['XML_RPC_Server_listMethods_doc']
10864+ */
10865+$GLOBALS['XML_RPC_Server_listMethods_doc'] = 'This method lists all the'
10866+ . ' methods that the XML-RPC server knows how to dispatch';
10867+
10868+/**
10869+ * signature for system.methodSignature: return = array,
10870+ * parameters = string
10871+ * @global array $GLOBALS['XML_RPC_Server_methodSignature_sig']
10872+ */
10873+$GLOBALS['XML_RPC_Server_methodSignature_sig'] = array(
10874+ array($GLOBALS['XML_RPC_Array'],
10875+ $GLOBALS['XML_RPC_String']
10876+ )
10877+);
10878+
10879+/**
10880+ * docstring for system.methodSignature
10881+ * @global string $GLOBALS['XML_RPC_Server_methodSignature_doc']
10882+ */
10883+$GLOBALS['XML_RPC_Server_methodSignature_doc'] = 'Returns an array of known'
10884+ . ' signatures (an array of arrays) for the method name passed. If'
10885+ . ' no signatures are known, returns a none-array (test for type !='
10886+ . ' array to detect missing signature)';
10887+
10888+/**
10889+ * signature for system.methodHelp: return = string,
10890+ * parameters = string
10891+ * @global array $GLOBALS['XML_RPC_Server_methodHelp_sig']
10892+ */
10893+$GLOBALS['XML_RPC_Server_methodHelp_sig'] = array(
10894+ array($GLOBALS['XML_RPC_String'],
10895+ $GLOBALS['XML_RPC_String']
10896+ )
10897+);
10898+
10899+/**
10900+ * docstring for methodHelp
10901+ * @global string $GLOBALS['XML_RPC_Server_methodHelp_doc']
10902+ */
10903+$GLOBALS['XML_RPC_Server_methodHelp_doc'] = 'Returns help text if defined'
10904+ . ' for the method passed, otherwise returns an empty string';
10905+
10906+/**
10907+ * dispatch map for the automatically declared XML-RPC methods.
10908+ * @global array $GLOBALS['XML_RPC_Server_dmap']
10909+ */
10910+$GLOBALS['XML_RPC_Server_dmap'] = array(
10911+ 'system.listMethods' => array(
10912+ 'function' => 'XML_RPC_Server_listMethods',
10913+ 'signature' => $GLOBALS['XML_RPC_Server_listMethods_sig'],
10914+ 'docstring' => $GLOBALS['XML_RPC_Server_listMethods_doc']
10915+ ),
10916+ 'system.methodHelp' => array(
10917+ 'function' => 'XML_RPC_Server_methodHelp',
10918+ 'signature' => $GLOBALS['XML_RPC_Server_methodHelp_sig'],
10919+ 'docstring' => $GLOBALS['XML_RPC_Server_methodHelp_doc']
10920+ ),
10921+ 'system.methodSignature' => array(
10922+ 'function' => 'XML_RPC_Server_methodSignature',
10923+ 'signature' => $GLOBALS['XML_RPC_Server_methodSignature_sig'],
10924+ 'docstring' => $GLOBALS['XML_RPC_Server_methodSignature_doc']
10925+ )
10926+);
10927+
10928+/**
10929+ * @global string $GLOBALS['XML_RPC_Server_debuginfo']
10930+ */
10931+$GLOBALS['XML_RPC_Server_debuginfo'] = '';
10932+
10933+
10934+/**
10935+ * Lists all the methods that the XML-RPC server knows how to dispatch
10936+ *
10937+ * @return object a new XML_RPC_Response object
10938+ */
10939+function XML_RPC_Server_listMethods($server, $m)
10940+{
10941+ global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
10942+
10943+ $v = new XML_RPC_Value();
10944+ $outAr = array();
10945+ foreach ($server->dmap as $key => $val) {
10946+ $outAr[] = new XML_RPC_Value($key, 'string');
10947+ }
10948+ foreach ($XML_RPC_Server_dmap as $key => $val) {
10949+ $outAr[] = new XML_RPC_Value($key, 'string');
10950+ }
10951+ $v->addArray($outAr);
10952+ return new XML_RPC_Response($v);
10953+}
10954+
10955+/**
10956+ * Returns an array of known signatures (an array of arrays)
10957+ * for the given method
10958+ *
10959+ * If no signatures are known, returns a none-array
10960+ * (test for type != array to detect missing signature)
10961+ *
10962+ * @return object a new XML_RPC_Response object
10963+ */
10964+function XML_RPC_Server_methodSignature($server, $m)
10965+{
10966+ global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
10967+
10968+ $methName = $m->getParam(0);
10969+ $methName = $methName->scalarval();
10970+ if (strpos($methName, 'system.') === 0) {
10971+ $dmap = $XML_RPC_Server_dmap;
10972+ $sysCall = 1;
10973+ } else {
10974+ $dmap = $server->dmap;
10975+ $sysCall = 0;
10976+ }
10977+ // print "<!-- ${methName} -->\n";
10978+ if (isset($dmap[$methName])) {
10979+ if ($dmap[$methName]['signature']) {
10980+ $sigs = array();
10981+ $thesigs = $dmap[$methName]['signature'];
10982+ for ($i = 0; $i < sizeof($thesigs); $i++) {
10983+ $cursig = array();
10984+ $inSig = $thesigs[$i];
10985+ for ($j = 0; $j < sizeof($inSig); $j++) {
10986+ $cursig[] = new XML_RPC_Value($inSig[$j], 'string');
10987+ }
10988+ $sigs[] = new XML_RPC_Value($cursig, 'array');
10989+ }
10990+ $r = new XML_RPC_Response(new XML_RPC_Value($sigs, 'array'));
10991+ } else {
10992+ $r = new XML_RPC_Response(new XML_RPC_Value('undef', 'string'));
10993+ }
10994+ } else {
10995+ $r = new XML_RPC_Response(0, $XML_RPC_err['introspect_unknown'],
10996+ $XML_RPC_str['introspect_unknown']);
10997+ }
10998+ return $r;
10999+}
11000+
11001+/**
11002+ * Returns help text if defined for the method passed, otherwise returns
11003+ * an empty string
11004+ *
11005+ * @return object a new XML_RPC_Response object
11006+ */
11007+function XML_RPC_Server_methodHelp($server, $m)
11008+{
11009+ global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
11010+
11011+ $methName = $m->getParam(0);
11012+ $methName = $methName->scalarval();
11013+ if (strpos($methName, 'system.') === 0) {
11014+ $dmap = $XML_RPC_Server_dmap;
11015+ $sysCall = 1;
11016+ } else {
11017+ $dmap = $server->dmap;
11018+ $sysCall = 0;
11019+ }
11020+
11021+ if (isset($dmap[$methName])) {
11022+ if ($dmap[$methName]['docstring']) {
11023+ $r = new XML_RPC_Response(new XML_RPC_Value($dmap[$methName]['docstring']),
11024+ 'string');
11025+ } else {
11026+ $r = new XML_RPC_Response(new XML_RPC_Value('', 'string'));
11027+ }
11028+ } else {
11029+ $r = new XML_RPC_Response(0, $XML_RPC_err['introspect_unknown'],
11030+ $XML_RPC_str['introspect_unknown']);
11031+ }
11032+ return $r;
11033+}
11034+
11035+/**
11036+ * @return void
11037+ */
11038+function XML_RPC_Server_debugmsg($m)
11039+{
11040+ global $XML_RPC_Server_debuginfo;
11041+ $XML_RPC_Server_debuginfo = $XML_RPC_Server_debuginfo . $m . "\n";
11042+}
11043+
11044+
11045+/**
11046+ * A server for receiving and replying to XML RPC requests
11047+ *
11048+ * <code>
11049+ * $server = new XML_RPC_Server(
11050+ * array(
11051+ * 'isan8' =>
11052+ * array(
11053+ * 'function' => 'is_8',
11054+ * 'signature' =>
11055+ * array(
11056+ * array('boolean', 'int'),
11057+ * array('boolean', 'int', 'boolean'),
11058+ * array('boolean', 'string'),
11059+ * array('boolean', 'string', 'boolean'),
11060+ * ),
11061+ * 'docstring' => 'Is the value an 8?'
11062+ * ),
11063+ * ),
11064+ * 1,
11065+ * 0
11066+ * );
11067+ * </code>
11068+ *
11069+ * @category Web Services
11070+ * @package XML_RPC
11071+ * @author Edd Dumbill <edd@usefulinc.com>
11072+ * @author Stig Bakken <stig@php.net>
11073+ * @author Martin Jansen <mj@php.net>
11074+ * @author Daniel Convissor <danielc@php.net>
11075+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
11076+ * @version Release: 1.4.0
11077+ * @link http://pear.php.net/package/XML_RPC
11078+ */
11079+class XML_RPC_Server
11080+{
11081+ /**
11082+ * The dispatch map, listing the methods this server provides.
11083+ * @var array
11084+ */
11085+ var $dmap = array();
11086+
11087+ /**
11088+ * The present response's encoding
11089+ * @var string
11090+ * @see XML_RPC_Message::getEncoding()
11091+ */
11092+ var $encoding = '';
11093+
11094+ /**
11095+ * Debug mode (0 = off, 1 = on)
11096+ * @var integer
11097+ */
11098+ var $debug = 0;
11099+
11100+ /**
11101+ * The response's HTTP headers
11102+ * @var string
11103+ */
11104+ var $server_headers = '';
11105+
11106+ /**
11107+ * The response's XML payload
11108+ * @var string
11109+ */
11110+ var $server_payload = '';
11111+
11112+
11113+ /**
11114+ * Constructor for the XML_RPC_Server class
11115+ *
11116+ * @param array $dispMap the dispatch map. An associative array
11117+ * explaining each function. The keys of the main
11118+ * array are the procedure names used by the
11119+ * clients. The value is another associative array
11120+ * that contains up to three elements:
11121+ * + The 'function' element's value is the name
11122+ * of the function or method that gets called.
11123+ * To define a class' method: 'class::method'.
11124+ * + The 'signature' element (optional) is an
11125+ * array describing the return values and
11126+ * parameters
11127+ * + The 'docstring' element (optional) is a
11128+ * string describing what the method does
11129+ * @param int $serviceNow should the HTTP response be sent now?
11130+ * (1 = yes, 0 = no)
11131+ * @param int $debug should debug output be displayed?
11132+ * (1 = yes, 0 = no)
11133+ *
11134+ * @return void
11135+ */
11136+ function XML_RPC_Server($dispMap, $serviceNow = 1, $debug = 0)
11137+ {
11138+ global $HTTP_RAW_POST_DATA;
11139+
11140+ if ($debug) {
11141+ $this->debug = 1;
11142+ } else {
11143+ $this->debug = 0;
11144+ }
11145+
11146+ $this->dmap = $dispMap;
11147+
11148+ if ($serviceNow) {
11149+ $this->service();
11150+ } else {
11151+ $this->createServerPayload();
11152+ $this->createServerHeaders();
11153+ }
11154+ }
11155+
11156+ /**
11157+ * @return string the debug information if debug debug mode is on
11158+ */
11159+ function serializeDebug()
11160+ {
11161+ global $XML_RPC_Server_debuginfo, $HTTP_RAW_POST_DATA;
11162+
11163+ if ($this->debug) {
11164+ XML_RPC_Server_debugmsg('vvv POST DATA RECEIVED BY SERVER vvv' . "\n"
11165+ . $HTTP_RAW_POST_DATA
11166+ . "\n" . '^^^ END POST DATA ^^^');
11167+ }
11168+
11169+ if ($XML_RPC_Server_debuginfo != '') {
11170+ return "<!-- PEAR XML_RPC SERVER DEBUG INFO:\n\n"
11171+ . preg_replace('/-(?=-)/', '- ', $XML_RPC_Server_debuginfo)
11172+ . "-->\n";
11173+ } else {
11174+ return '';
11175+ }
11176+ }
11177+
11178+ /**
11179+ * Sends the response
11180+ *
11181+ * The encoding and content-type are determined by
11182+ * XML_RPC_Message::getEncoding()
11183+ *
11184+ * @return void
11185+ *
11186+ * @uses XML_RPC_Server::createServerPayload(),
11187+ * XML_RPC_Server::createServerHeaders()
11188+ */
11189+ function service()
11190+ {
11191+ if (!$this->server_payload) {
11192+ $this->createServerPayload();
11193+ }
11194+ if (!$this->server_headers) {
11195+ $this->createServerHeaders();
11196+ }
11197+ header($this->server_headers);
11198+ print $this->server_payload;
11199+ }
11200+
11201+ /**
11202+ * Generates the payload and puts it in the $server_payload property
11203+ *
11204+ * @return void
11205+ *
11206+ * @uses XML_RPC_Server::parseRequest(), XML_RPC_Server::$encoding,
11207+ * XML_RPC_Response::serialize(), XML_RPC_Server::serializeDebug()
11208+ */
11209+ function createServerPayload()
11210+ {
11211+ $r = $this->parseRequest();
11212+ $this->server_payload = '<?xml version="1.0" encoding="'
11213+ . $this->encoding . '"?>' . "\n"
11214+ . $this->serializeDebug()
11215+ . $r->serialize();
11216+ }
11217+
11218+ /**
11219+ * Determines the HTTP headers and puts them in the $server_headers
11220+ * property
11221+ *
11222+ * @return boolean TRUE if okay, FALSE if $server_payload isn't set.
11223+ *
11224+ * @uses XML_RPC_Server::createServerPayload(),
11225+ * XML_RPC_Server::$server_headers
11226+ */
11227+ function createServerHeaders()
11228+ {
11229+ if (!$this->server_payload) {
11230+ return false;
11231+ }
11232+ $this->server_headers = 'Content-Length: '
11233+ . strlen($this->server_payload) . "\r\n"
11234+ . 'Content-Type: text/xml;'
11235+ . ' charset=' . $this->encoding;
11236+ return true;
11237+ }
11238+
11239+ /**
11240+ * @return array
11241+ */
11242+ function verifySignature($in, $sig)
11243+ {
11244+ for ($i = 0; $i < sizeof($sig); $i++) {
11245+ // check each possible signature in turn
11246+ $cursig = $sig[$i];
11247+ if (sizeof($cursig) == $in->getNumParams() + 1) {
11248+ $itsOK = 1;
11249+ for ($n = 0; $n < $in->getNumParams(); $n++) {
11250+ $p = $in->getParam($n);
11251+ // print "<!-- $p -->\n";
11252+ if ($p->kindOf() == 'scalar') {
11253+ $pt = $p->scalartyp();
11254+ } else {
11255+ $pt = $p->kindOf();
11256+ }
11257+ // $n+1 as first type of sig is return type
11258+ if ($pt != $cursig[$n+1]) {
11259+ $itsOK = 0;
11260+ $pno = $n+1;
11261+ $wanted = $cursig[$n+1];
11262+ $got = $pt;
11263+ break;
11264+ }
11265+ }
11266+ if ($itsOK) {
11267+ return array(1);
11268+ }
11269+ }
11270+ }
11271+ if (isset($wanted)) {
11272+ return array(0, "Wanted ${wanted}, got ${got} at param ${pno}");
11273+ } else {
11274+ $allowed = array();
11275+ foreach ($sig as $val) {
11276+ end($val);
11277+ $allowed[] = key($val);
11278+ }
11279+ $allowed = array_unique($allowed);
11280+ $last = count($allowed) - 1;
11281+ if ($last > 0) {
11282+ $allowed[$last] = 'or ' . $allowed[$last];
11283+ }
11284+ return array(0,
11285+ 'Signature permits ' . implode(', ', $allowed)
11286+ . ' parameters but the request had '
11287+ . $in->getNumParams());
11288+ }
11289+ }
11290+
11291+ /**
11292+ * @return object a new XML_RPC_Response object
11293+ *
11294+ * @uses XML_RPC_Message::getEncoding(), XML_RPC_Server::$encoding
11295+ */
11296+ function parseRequest($data = '')
11297+ {
11298+ global $XML_RPC_xh, $HTTP_RAW_POST_DATA,
11299+ $XML_RPC_err, $XML_RPC_str, $XML_RPC_errxml,
11300+ $XML_RPC_defencoding, $XML_RPC_Server_dmap;
11301+
11302+ if ($data == '') {
11303+ $data = $HTTP_RAW_POST_DATA;
11304+ }
11305+
11306+ $this->encoding = XML_RPC_Message::getEncoding($data);
11307+ $parser_resource = xml_parser_create($this->encoding);
11308+ $parser = (int) $parser_resource;
11309+
11310+ $XML_RPC_xh[$parser] = array();
11311+ $XML_RPC_xh[$parser]['cm'] = 0;
11312+ $XML_RPC_xh[$parser]['isf'] = 0;
11313+ $XML_RPC_xh[$parser]['params'] = array();
11314+ $XML_RPC_xh[$parser]['method'] = '';
11315+ $XML_RPC_xh[$parser]['stack'] = array();
11316+ $XML_RPC_xh[$parser]['valuestack'] = array();
11317+
11318+ $plist = '';
11319+
11320+ // decompose incoming XML into request structure
11321+
11322+ xml_parser_set_option($parser_resource, XML_OPTION_CASE_FOLDING, true);
11323+ xml_set_element_handler($parser_resource, 'XML_RPC_se', 'XML_RPC_ee');
11324+ xml_set_character_data_handler($parser_resource, 'XML_RPC_cd');
11325+ if (!xml_parse($parser_resource, $data, 1)) {
11326+ // return XML error as a faultCode
11327+ $r = new XML_RPC_Response(0,
11328+ $XML_RPC_errxml+xml_get_error_code($parser_resource),
11329+ sprintf('XML error: %s at line %d',
11330+ xml_error_string(xml_get_error_code($parser_resource)),
11331+ xml_get_current_line_number($parser_resource)));
11332+ xml_parser_free($parser_resource);
11333+ } elseif ($XML_RPC_xh[$parser]['isf']>1) {
11334+ $r = new XML_RPC_Response(0,
11335+ $XML_RPC_err['invalid_request'],
11336+ $XML_RPC_str['invalid_request']
11337+ . ': '
11338+ . $XML_RPC_xh[$parser]['isf_reason']);
11339+ xml_parser_free($parser_resource);
11340+ } else {
11341+ xml_parser_free($parser_resource);
11342+ $m = new XML_RPC_Message($XML_RPC_xh[$parser]['method']);
11343+ // now add parameters in
11344+ for ($i = 0; $i < sizeof($XML_RPC_xh[$parser]['params']); $i++) {
11345+ // print '<!-- ' . $XML_RPC_xh[$parser]['params'][$i]. "-->\n";
11346+ $plist .= "$i - " . var_export($XML_RPC_xh[$parser]['params'][$i], true) . " \n";
11347+ $m->addParam($XML_RPC_xh[$parser]['params'][$i]);
11348+ }
11349+ XML_RPC_Server_debugmsg($plist);
11350+
11351+ // now to deal with the method
11352+ $methName = $XML_RPC_xh[$parser]['method'];
11353+ if (strpos($methName, 'system.') === 0) {
11354+ $dmap = $XML_RPC_Server_dmap;
11355+ $sysCall = 1;
11356+ } else {
11357+ $dmap = $this->dmap;
11358+ $sysCall = 0;
11359+ }
11360+
11361+ if (isset($dmap[$methName]['function'])
11362+ && is_string($dmap[$methName]['function'])
11363+ && strpos($dmap[$methName]['function'], '::') !== false)
11364+ {
11365+ $dmap[$methName]['function'] =
11366+ explode('::', $dmap[$methName]['function']);
11367+ }
11368+
11369+ if (isset($dmap[$methName]['function'])
11370+ && is_callable($dmap[$methName]['function']))
11371+ {
11372+ // dispatch if exists
11373+ if (isset($dmap[$methName]['signature'])) {
11374+ $sr = $this->verifySignature($m,
11375+ $dmap[$methName]['signature'] );
11376+ }
11377+ if (!isset($dmap[$methName]['signature']) || $sr[0]) {
11378+ // if no signature or correct signature
11379+ if ($sysCall) {
11380+ $r = call_user_func($dmap[$methName]['function'], $this, $m);
11381+ } else {
11382+ $r = call_user_func($dmap[$methName]['function'], $m);
11383+ }
11384+ if (!is_a($r, 'XML_RPC_Response')) {
11385+ $r = new XML_RPC_Response(0, $XML_RPC_err['not_response_object'],
11386+ $XML_RPC_str['not_response_object']);
11387+ }
11388+ } else {
11389+ $r = new XML_RPC_Response(0, $XML_RPC_err['incorrect_params'],
11390+ $XML_RPC_str['incorrect_params']
11391+ . ': ' . $sr[1]);
11392+ }
11393+ } else {
11394+ // else prepare error response
11395+ $r = new XML_RPC_Response(0, $XML_RPC_err['unknown_method'],
11396+ $XML_RPC_str['unknown_method']);
11397+ }
11398+ }
11399+ return $r;
11400+ }
11401+
11402+ /**
11403+ * Echos back the input packet as a string value
11404+ *
11405+ * @return void
11406+ *
11407+ * Useful for debugging.
11408+ */
11409+ function echoInput()
11410+ {
11411+ global $HTTP_RAW_POST_DATA;
11412+
11413+ $r = new XML_RPC_Response(0);
11414+ $r->xv = new XML_RPC_Value("'Aha said I: '" . $HTTP_RAW_POST_DATA, 'string');
11415+ print $r->serialize();
11416+ }
11417+}
11418+
11419+/*
11420+ * Local variables:
11421+ * tab-width: 4
11422+ * c-basic-offset: 4
11423+ * c-hanging-comment-ender-p: nil
11424+ * End:
11425+ */
11426+
11427+?>
11428+
11429+<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/package-1.0">
11430+<package version="1.0" packagerversion="1.4.0a12">
11431+ <name>XML_RPC</name>
11432+ <summary>PHP implementation of the XML-RPC protocol</summary>
11433+ <description>A PEAR-ified version of Useful Inc's XML-RPC for PHP.
11434+
11435+It has support for HTTP/HTTPS transport, proxies and authentication.
11436+ </description>
11437+ <maintainers>
11438+ <maintainer>
11439+ <user>ssb</user>
11440+ <name>Stig Bakken</name>
11441+ <email>stig@php.net</email>
11442+ <role>lead</role>
11443+ </maintainer>
11444+ <maintainer>
11445+ <user>danielc</user>
11446+ <name>Daniel Convissor</name>
11447+ <email>danielc@php.net</email>
11448+ <role>lead</role>
11449+ </maintainer>
11450+ </maintainers>
11451+ <release>
11452+ <version>1.4.0</version>
11453+ <date>2005-08-14</date>
11454+ <license>PHP License</license>
11455+ <state>stable</state>
11456+ <notes>* MAJOR SECURITY FIX: eliminate use of eval().
11457+* Using socket_get_status() because stream_get_meta_data() was introduced in 4.3.0, but we need to support 4.2.0. Bug 4805.
11458+ </notes>
11459+ <filelist>
11460+ <file role="php" baseinstalldir="XML" name="RPC.php">
11461+ <replace from="@package_version@" to="version" type="package-info"/>
11462+ </file>
11463+ <file role="php" baseinstalldir="XML/RPC" name="Server.php">
11464+ <replace from="@package_version@" to="version" type="package-info"/>
11465+ </file>
11466+ <file role="php" baseinstalldir="XML/RPC" name="Dump.php">
11467+ <replace from="@package_version@" to="version" type="package-info"/>
11468+ </file>
11469+ <file role="test" name="tests/protoport.php">
11470+ <replace from="@package_version@" to="version" type="package-info"/>
11471+ </file>
11472+ <file role="test" name="tests/test_Dump.php">
11473+ <replace from="@package_version@" to="version" type="package-info"/>
11474+ </file>
11475+ </filelist>
11476+ </release>
11477+ <changelog>
11478+ <release>
11479+ <version>1.3.3</version>
11480+ <date>2005-07-15</date>
11481+ <state>stable</state>
11482+ <notes>* Eliminate memory leak by resetting $XML_RPC_xh each time parseResponse() is called. Bug 4780.
11483+* Using socket_set_timeout() because stream_set_timeout() was introduced in 4.3.0, but we need to support 4.2.0. Bug 4805.
11484+ </notes>
11485+ </release>
11486+ <release>
11487+ <version>1.3.2</version>
11488+ <date>2005-07-07</date>
11489+ <state>stable</state>
11490+ <notes>* Eliminate path disclosure vulnerabilities by suppressing error messages when eval()'ing.
11491+* Eliminate path disclosure vulnerability by catching bogus parameters submitted to XML_RPC_Value::serializeval().
11492+* In XML_RPC_Server::service(), only call createServerPayload() and createServerHeaders() if necessary. Fixes compatibility issue introduced in Release 1.3.0RC1 for users who set the $serviceNow parameter of XML_RPC_Server() to 0. Bug 4757.
11493+* Change &quot;var $errstring&quot; to &quot;var $errstr&quot;. Bug 4582. Was put into CVS version 1.75 of RPC.php but didn't make it into RELEASE_1_3_1.
11494+ </notes>
11495+ </release>
11496+ <release>
11497+ <version>1.3.1</version>
11498+ <date>2005-06-29</date>
11499+ <state>stable</state>
11500+ <notes>* Security fix. Update highly recommended!
11501+ </notes>
11502+ </release>
11503+ <release>
11504+ <version>1.3.0</version>
11505+ <date>2005-06-13</date>
11506+ <state>stable</state>
11507+ <notes>* Stable release. See earlier releases for changes since 1.2.2.
11508+ </notes>
11509+ </release>
11510+ <release>
11511+ <version>1.3.0RC3</version>
11512+ <date>2005-05-10</date>
11513+ <state>beta</state>
11514+ <notes>* When verifying requests against function signatures, if the number of parameters don't match, provide an appropriate message. NOTE: this resolves a path disclosure vulnerability. (Refines the changes made in the last commit.) Bug 4231.
11515+* XML_RPC_Message::getParam() now returns an XML_RPC_Response object upon error. Changed from Release 1.3.0RC2.
11516+* Add the XML_RPC_Value::isValue() method. For testing if an item is an XML_RPC_Value object.
11517+* If XML_RPC_Client::send() is given an incorrect $msg parameter, raise an error with the new XML_RPC_ERROR_PROGRAMMING code and return 0.
11518+* Improve cross-platform operation by using PEAR::loadExtension() instead of dl().
11519+* Use &lt;br /&gt; instead of &lt;br&gt; in XML_RPC_Value::dump().
11520+ </notes>
11521+ </release>
11522+ <release>
11523+ <version>1.3.0RC2</version>
11524+ <date>2005-05-05</date>
11525+ <state>beta</state>
11526+ <notes>* If XML_RPC_Message::getParam() is given an incorrect parameter, raise an error with the new XML_RPC_ERROR_INCORRECT_PARAMS code and return FALSE.
11527+* Handle improper requests to XML_RPC_Server::verifySignature(). Bug 4231.
11528+* Try to allow HTTP 100 responses if followed by a 200 response. Bug 4116.
11529+* Help Delphi users by making RPCMETHODNAME an alias for METHODNAME. Request 4205.
11530+ </notes>
11531+ </release>
11532+ <release>
11533+ <version>1.3.0RC1</version>
11534+ <date>2005-04-07</date>
11535+ <state>beta</state>
11536+ <notes>* Improve timeout handling for situations where connection to server is made but no response is not received in time. Accomplished via stream_set_timeout(). Request 3963.
11537+* Add Fault Code 6: &quot;The requested method didn't return an XML_RPC_Response object.&quot; Request 4032.
11538+* Add the createServerPayload() and createServerHeaders() methods and the $server_payload and $server_headers properties. Request 3121.
11539+* As in earlier versions, if the $serviceNow parameter to XML_RPC_Server() is 0, no data will be returned, but now the new $server_payload and $server_headers properties will be set.
11540+* Convert the parser handle to an integer before using it as an index for $XML_RPC_xh[$parser]. Reduces E_STRICT notices. Bug 3782.
11541+* Add createHeaders() method and $headers property to XML_RPC_Client to make testing easier.
11542+ </notes>
11543+ </release>
11544+ <release>
11545+ <version>1.2.2</version>
11546+ <date>2005-03-07</date>
11547+ <state>stable</state>
11548+ <notes>* When using a proxy, add the protocol to the Request-URI, making it an &quot;absoluteURI&quot; as per the HTTP 1.0 spec. Bug 3679.
11549+ </notes>
11550+ </release>
11551+ <release>
11552+ <version>1.2.1</version>
11553+ <date>2005-03-01</date>
11554+ <state>stable</state>
11555+ <notes>* Add isset() check before examining the dispatch map. Bug 3658.
11556+ </notes>
11557+ </release>
11558+ <release>
11559+ <version>1.2.0</version>
11560+ <date>2005-02-27</date>
11561+ <state>stable</state>
11562+ <notes>* Provide the &quot;stable&quot; release.
11563+* Add package2.xml for compatibility with PEAR 1.4.0.
11564+* For changes since 1.1.0, see the changelogs for the various RC releases.
11565+ </notes>
11566+ </release>
11567+ <release>
11568+ <version>1.2.0RC7</version>
11569+ <date>2005-02-22</date>
11570+ <state>beta</state>
11571+ <notes>* Add the setSendEncoding() method and $send_encoding
11572+ property to XML_RPC_Message. Request 3537.
11573+* Allow class methods to be mapped using either syntax:
11574+ 'function' =&gt; 'hello::sayHello',
11575+ or
11576+ 'function' =&gt; array('hello', 'sayhello'),
11577+ Bug 3363.
11578+* Use 8192 instead of 32768 for bytes in fread()
11579+ in parseResponseFile(). Bug 3340.
11580+ </notes>
11581+ </release>
11582+ <release>
11583+ <version>1.2.0RC6</version>
11584+ <date>2005-01-25</date>
11585+ <state>beta</state>
11586+ <notes>* Don't put the protocol in the Host field of the POST data. (danielc)
11587+ </notes>
11588+ </release>
11589+ <release>
11590+ <version>1.2.0RC5</version>
11591+ <date>2005-01-24</date>
11592+ <state>beta</state>
11593+ <notes>* If $port is 443 but a protocol isn't specified in $server, assume ssl:// is the protocol.
11594+ </notes>
11595+ </release>
11596+ <release>
11597+ <version>1.2.0RC4</version>
11598+ <date>2005-01-24</date>
11599+ <state>beta</state>
11600+ <notes>* When a connection attempt fails, have the method return 0. (danielc)
11601+* Move the protocol/port checking/switching and the property settings from sendPayloadHTTP10() to the XML_RPC_Client constructor. (danielc)
11602+* Add tests for setting the client properties. (danielc)
11603+* Remove $GLOBALS['XML_RPC_twoslash'] since it's not used. (danielc)
11604+* Bundle the tests with the package. (danielc)
11605+ </notes>
11606+ </release>
11607+ <release>
11608+ <version>1.2.0RC3</version>
11609+ <date>2005-01-19</date>
11610+ <state>beta</state>
11611+ <notes>* ssl uses port 443, not 445.
11612+ </notes>
11613+ </release>
11614+ <release>
11615+ <version>1.2.0RC2</version>
11616+ <date>2005-01-11</date>
11617+ <state>beta</state>
11618+ <notes>* Handle ssl:// in the $server string. (danielc)
11619+* Also default to port 445 for ssl:// requests as well. (danielc)
11620+* Enhance debugging in the server. (danielc)
11621+ </notes>
11622+ </release>
11623+ <release>
11624+ <version>1.2.0RC1</version>
11625+ <date>2004-12-30</date>
11626+ <state>beta</state>
11627+ <notes>* Make things work with SSL. Bug 2489. (nkukard lbsd net)
11628+* Allow array function callbacks (Matt Kane)
11629+* Some minor speed-ups (Matt Kane)
11630+* Add Dump.php to the package (Christian Weiske)
11631+* Replace all line endings with \r\n. Had only done replacements on \n. Bug 2521. (danielc)
11632+* Silence fsockopen() errors. Bug 1714. (danielc)
11633+* Encode empty arrays as an array. Bug 1493. (danielc)
11634+* Eliminate undefined index notice when submitting empty arrays to XML_RPC_Encode(). Bug 1819. (danielc)
11635+* Speed up check for enumerated arrays in XML_RPC_Encode(). (danielc)
11636+* Prepend &quot;XML_RPC_&quot; to ERROR_NON_NUMERIC_FOUND, eliminating problem when eval()'ing error messages. (danielc)
11637+* Use XML_RPC_Base::raiseError() instead of PEAR::raiseError() in XML_RPC_ee() because PEAR.php is lazy loaded. (danielc)
11638+* Allow raiseError() to be called statically. (danielc)
11639+* Stop double escaping of character entities. Bug 987. (danielc)
11640+ NOTICE: the following have been removed:
11641+ * XML_RPC_dh()
11642+ * $GLOBALS['XML_RPC_entities']
11643+ * XML_RPC_entity_decode()
11644+ * XML_RPC_lookup_entity()
11645+* Determine the XML's encoding via the encoding attribute in the XML declaration. Bug 52. (danielc)
11646+ </notes>
11647+ </release>
11648+ <release>
11649+ <version>1.1.0</version>
11650+ <date>2004-03-15</date>
11651+ <state>stable</state>
11652+ <notes>* Added support for sequential arrays to XML_RPC_encode() (mroch)
11653+* Cleaned up new XML_RPC_encode() changes a bit (mroch, pierre)
11654+* Remove &quot;require_once 'PEAR.php'&quot;, include only when needed to raise an error
11655+* Replace echo and error_log() with raiseError() (mroch)
11656+* Make all classes extend XML_RPC_Base, which will handle common functions (mroch)
11657+* be tolerant of junk after methodResponse (Luca Mariano, mroch)
11658+* Silent notice even in the error log (pierre)
11659+* fix include of shared xml extension on win32 (pierre)
11660+ </notes>
11661+ </release>
11662+ <release>
11663+ <version>1.0.4</version>
11664+ <date>2002-10-02</date>
11665+ <state>stable</state>
11666+ <notes>* added HTTP proxy authorization support (thanks to Arnaud Limbourg)
11667+ </notes>
11668+ </release>
11669+ <release>
11670+ <version>1.0.3</version>
11671+ <date>2002-05-19</date>
11672+ <state>stable</state>
11673+ <notes>* fix bug when parsing responses with boolean types
11674+ </notes>
11675+ </release>
11676+ <release>
11677+ <version>1.0.2</version>
11678+ <date>2002-04-16</date>
11679+ <state>stable</state>
11680+ <notes>* E_ALL fixes
11681+* fix HTTP response header parsing
11682+ </notes>
11683+ </release>
11684+ <release>
11685+ <version>1.0.1</version>
11686+ <date>2001-09-25</date>
11687+ <state>stable</state>
11688+ <notes>This is a PEAR-ified version of Useful Inc's 1.0.1 release.
11689+Includes an urgent security fix identified by Dan Libby &lt;dan@libby.com&gt;.
11690+ </notes>
11691+ </release>
11692+ </changelog>
11693+</package>
11694+
11695\ Kein Zeilenumbruch am Dateiende.
11696diff -Nura php-4.3.11/php.ini-dist hardening-patch-4.3.11-0.4.2/php.ini-dist
11697--- php-4.3.11/php.ini-dist 2005-02-14 09:26:10.000000000 +0100
11698+++ hardening-patch-4.3.11-0.4.2/php.ini-dist 2005-09-07 18:41:01.008095656 +0200
11699@@ -1109,6 +1109,185 @@
11700 ;exif.decode_jis_motorola = JIS
11701 ;exif.decode_jis_intel = JIS
11702
11703+[hardening-patch]
11704+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11705+; Hardening-Patch's logging ;
11706+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11707+
11708+;
11709+; hphp.log.syslog - Configures level for alerts reported through syslog
11710+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
11711+; hphp.log.script - Configures level for alerts reported through external script
11712+;
11713+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
11714+; Or each number up to get desired Hardening-Patch's reporting level
11715+;
11716+; S_ALL - All alerts
11717+; S_MEMORY - All canary violations and the safe unlink protection use this class
11718+; S_VARS - All variable filters trigger this class
11719+; S_FILES - All violation of uploaded files filter use this class
11720+; S_INCLUDE - The protection against malicious include filenames use this class
11721+; S_SQL - Failed SQL queries in MySQL are logged with this class
11722+; S_EXECUTOR - The execution depth protection uses this logging class
11723+; S_MISC - All other log messages (f.e. format string protection) use this class
11724+;
11725+; Example:
11726+;
11727+; - Report all alerts (except memory alerts) to the SAPI errorlog,
11728+; memory alerts through syslog and SQL+Include alerts fo the script
11729+;
11730+;hphp.log.syslog = S_MEMORY
11731+;hphp.log.sapi = S_ALL & ~S_MEMORY
11732+;hphp.log.script = S_INCLUDE | S_SQL
11733+;
11734+; Syslog logging:
11735+;
11736+; - Facility configuration: one of the following facilities
11737+;
11738+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
11739+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
11740+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
11741+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
11742+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
11743+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
11744+; LOG_PERROR
11745+;
11746+; - Priority configuration: one of the followinf priorities
11747+;
11748+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
11749+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
11750+;
11751+hphp.log.syslog.priority = LOG_ALERT
11752+hphp.log.syslog.facility = LOG_USER
11753+;
11754+; Script logging:
11755+;
11756+;hphp.log.script.name = /home/hphp/log_script
11757+;
11758+; Alert configuration:
11759+;
11760+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
11761+;
11762+;hphp.log.use-x-forwarded-for = On
11763+;
11764+
11765+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11766+; Hardening-Patch's Executor options ;
11767+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11768+
11769+; Execution depth limit
11770+;hphp.executor.max_depth = 8000
11771+
11772+; White-/blacklist for function calls during normal execution
11773+;hphp.executor.func.whitelist = ord,chr
11774+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
11775+
11776+; White-/blacklist for function calls during eval() execution
11777+;hphp.executor.eval.whitelist = ord,chr
11778+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
11779+
11780+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11781+; Hardening-Patch's REQUEST variable filters ;
11782+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11783+
11784+; Limits the number of REQUEST variables
11785+hphp.request.max_vars = 200
11786+
11787+; Limits the length of variable names (without indices)
11788+hphp.request.max_varname_length = 64
11789+
11790+; Limits the length of complete variable names (with indices)
11791+hphp.request.max_totalname_length = 256
11792+
11793+; Limits the length of array indices
11794+hphp.request.max_array_index_length = 64
11795+
11796+; Limits the depth of arrays
11797+hphp.request.max_array_depth = 100
11798+
11799+; Limits the length of variable values
11800+hphp.request.max_value_length = 65000
11801+
11802+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11803+; Hardening-Patch's COOKIE variable filters ;
11804+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11805+
11806+; Limits the number of COOKIE variables
11807+hphp.cookie.max_vars = 100
11808+
11809+; Limits the length of variable names (without indices)
11810+hphp.cookie.max_name_length = 64
11811+
11812+; Limits the length of complete variable names (with indices)
11813+hphp.cookie.max_totalname_length = 256
11814+
11815+; Limits the length of array indices
11816+hphp.cookie.max_array_index_length = 64
11817+
11818+; Limits the depth of arrays
11819+hphp.cookie.max_array_depth = 100
11820+
11821+; Limits the length of variable values
11822+hphp.cookie.max_value_length = 10000
11823+
11824+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11825+; Hardening-Patch's GET variable filters ;
11826+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11827+
11828+; Limits the number of COOKIE variables
11829+hphp.get.max_vars = 100
11830+
11831+; Limits the length of variable names (without indices)
11832+hphp.get.max_name_length = 64
11833+
11834+; Limits the length of complete variable names (with indices)
11835+hphp.get.max_totalname_length = 256
11836+
11837+; Limits the length of array indices
11838+hphp.get.max_array_index_length = 64
11839+
11840+; Limits the depth of arrays
11841+hphp.get.max_array_depth = 50
11842+
11843+; Limits the length of variable values
11844+hphp.get.max_value_length = 512
11845+
11846+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11847+; Hardening-Patch's POST variable filters ;
11848+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11849+
11850+; Limits the number of POST variables
11851+hphp.post.max_vars = 200
11852+
11853+; Limits the length of variable names (without indices)
11854+hphp.post.max_name_length = 64
11855+
11856+; Limits the length of complete variable names (with indices)
11857+hphp.post.max_totalname_length = 256
11858+
11859+; Limits the length of array indices
11860+hphp.post.max_array_index_length = 64
11861+
11862+; Limits the depth of arrays
11863+hphp.post.max_array_depth = 100
11864+
11865+; Limits the length of variable values
11866+hphp.post.max_value_length = 65000
11867+
11868+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11869+; Hardening-Patch's fileupload variable filters ;
11870+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11871+
11872+; Limits the number of uploadable files
11873+hphp.upload.max_uploads = 25
11874+
11875+; Filter out the upload of ELF executables
11876+hphp.upload.disallow_elf_files = On
11877+
11878+; External filterscript for upload verification
11879+;hphp.upload.verification_script = /home/hphp/verify_script
11880+
11881+
11882 ; Local Variables:
11883 ; tab-width: 4
11884 ; End:
11885diff -Nura php-4.3.11/php.ini-recommended hardening-patch-4.3.11-0.4.2/php.ini-recommended
11886--- php-4.3.11/php.ini-recommended 2005-02-14 09:26:10.000000000 +0100
11887+++ hardening-patch-4.3.11-0.4.2/php.ini-recommended 2005-09-07 18:41:01.009095504 +0200
11888@@ -1107,6 +1107,185 @@
11889 ;exif.decode_jis_motorola = JIS
11890 ;exif.decode_jis_intel = JIS
11891
11892+[hardening-patch]
11893+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11894+; Hardening-Patch's logging ;
11895+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11896+
11897+;
11898+; hphp.log.syslog - Configures level for alerts reported through syslog
11899+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
11900+; hphp.log.script - Configures level for alerts reported through external script
11901+;
11902+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
11903+; Or each number up to get desired Hardening-Patch's reporting level
11904+;
11905+; S_ALL - All alerts
11906+; S_MEMORY - All canary violations and the safe unlink protection use this class
11907+; S_VARS - All variable filters trigger this class
11908+; S_FILES - All violation of uploaded files filter use this class
11909+; S_INCLUDE - The protection against malicious include filenames use this class
11910+; S_SQL - Failed SQL queries in MySQL are logged with this class
11911+; S_EXECUTOR - The execution depth protection uses this logging class
11912+; S_MISC - All other log messages (f.e. format string protection) use this class
11913+;
11914+; Example:
11915+;
11916+; - Report all alerts (except memory alerts) to the SAPI errorlog,
11917+; memory alerts through syslog and SQL+Include alerts fo the script
11918+;
11919+;hphp.log.syslog = S_MEMORY
11920+;hphp.log.sapi = S_ALL & ~S_MEMORY
11921+;hphp.log.script = S_INCLUDE | S_SQL
11922+;
11923+; Syslog logging:
11924+;
11925+; - Facility configuration: one of the following facilities
11926+;
11927+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
11928+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
11929+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
11930+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
11931+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
11932+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
11933+; LOG_PERROR
11934+;
11935+; - Priority configuration: one of the followinf priorities
11936+;
11937+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
11938+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
11939+;
11940+hphp.log.syslog.priority = LOG_ALERT
11941+hphp.log.syslog.facility = LOG_USER
11942+;
11943+; Script logging:
11944+;
11945+;hphp.log.script.name = /home/hphp/log_script
11946+;
11947+; Alert configuration:
11948+;
11949+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
11950+;
11951+;hphp.log.use-x-forwarded-for = On
11952+;
11953+
11954+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11955+; Hardening-Patch's Executor options ;
11956+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11957+
11958+; Execution depth limit
11959+;hphp.executor.max_depth = 8000
11960+
11961+; White-/blacklist for function calls during normal execution
11962+;hphp.executor.func.whitelist = ord,chr
11963+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
11964+
11965+; White-/blacklist for function calls during eval() execution
11966+;hphp.executor.eval.whitelist = ord,chr
11967+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
11968+
11969+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11970+; Hardening-Patch's REQUEST variable filters ;
11971+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11972+
11973+; Limits the number of REQUEST variables
11974+hphp.request.max_vars = 200
11975+
11976+; Limits the length of variable names (without indices)
11977+hphp.request.max_varname_length = 64
11978+
11979+; Limits the length of complete variable names (with indices)
11980+hphp.request.max_totalname_length = 256
11981+
11982+; Limits the length of array indices
11983+hphp.request.max_array_index_length = 64
11984+
11985+; Limits the depth of arrays
11986+hphp.request.max_array_depth = 100
11987+
11988+; Limits the length of variable values
11989+hphp.request.max_value_length = 65000
11990+
11991+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11992+; Hardening-Patch's COOKIE variable filters ;
11993+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11994+
11995+; Limits the number of COOKIE variables
11996+hphp.cookie.max_vars = 100
11997+
11998+; Limits the length of variable names (without indices)
11999+hphp.cookie.max_name_length = 64
12000+
12001+; Limits the length of complete variable names (with indices)
12002+hphp.cookie.max_totalname_length = 256
12003+
12004+; Limits the length of array indices
12005+hphp.cookie.max_array_index_length = 64
12006+
12007+; Limits the depth of arrays
12008+hphp.cookie.max_array_depth = 100
12009+
12010+; Limits the length of variable values
12011+hphp.cookie.max_value_length = 10000
12012+
12013+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12014+; Hardening-Patch's GET variable filters ;
12015+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12016+
12017+; Limits the number of COOKIE variables
12018+hphp.get.max_vars = 100
12019+
12020+; Limits the length of variable names (without indices)
12021+hphp.get.max_name_length = 64
12022+
12023+; Limits the length of complete variable names (with indices)
12024+hphp.get.max_totalname_length = 256
12025+
12026+; Limits the length of array indices
12027+hphp.get.max_array_index_length = 64
12028+
12029+; Limits the depth of arrays
12030+hphp.get.max_array_depth = 50
12031+
12032+; Limits the length of variable values
12033+hphp.get.max_value_length = 512
12034+
12035+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12036+; Hardening-Patch's POST variable filters ;
12037+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12038+
12039+; Limits the number of POST variables
12040+hphp.post.max_vars = 200
12041+
12042+; Limits the length of variable names (without indices)
12043+hphp.post.max_name_length = 64
12044+
12045+; Limits the length of complete variable names (with indices)
12046+hphp.post.max_totalname_length = 256
12047+
12048+; Limits the length of array indices
12049+hphp.post.max_array_index_length = 64
12050+
12051+; Limits the depth of arrays
12052+hphp.post.max_array_depth = 100
12053+
12054+; Limits the length of variable values
12055+hphp.post.max_value_length = 65000
12056+
12057+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12058+; Hardening-Patch's fileupload variable filters ;
12059+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12060+
12061+; Limits the number of uploadable files
12062+hphp.upload.max_uploads = 25
12063+
12064+; Filter out the upload of ELF executables
12065+hphp.upload.disallow_elf_files = On
12066+
12067+; External filterscript for upload verification
12068+;hphp.upload.verification_script = /home/hphp/verify_script
12069+
12070+
12071 ; Local Variables:
12072 ; tab-width: 4
12073 ; End:
12074diff -Nura php-4.3.11/README.input_filter hardening-patch-4.3.11-0.4.2/README.input_filter
12075--- php-4.3.11/README.input_filter 1970-01-01 01:00:00.000000000 +0100
12076+++ hardening-patch-4.3.11-0.4.2/README.input_filter 2005-09-07 18:41:01.010095352 +0200
12077@@ -0,0 +1,193 @@
12078+Input Filter Support ported from PHP 5
12079+--------------------------------------
12080+
12081+XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
12082+and can be quite difficult to prevent. Whenever you accept user data
12083+and somehow display this data back to users, you are likely vulnerable
12084+to XSS hacks.
12085+
12086+The Input Filter support in PHP 5 is aimed at providing the framework
12087+through which a company-wide or site-wide security policy can be
12088+enforced. It is implemented as a SAPI hook and is called from the
12089+treat_data and post handler functions. To implement your own security
12090+policy you will need to write a standard PHP extension.
12091+
12092+A simple implementation might look like the following. This stores the
12093+original raw user data and adds a my_get_raw() function while the normal
12094+$_POST, $_GET and $_COOKIE arrays are only populated with stripped
12095+data. In this simple example all I am doing is calling strip_tags() on
12096+the data. If register_globals is turned on, the default globals that
12097+are created will be stripped ($foo) while a $RAW_foo is created with the
12098+original user input.
12099+
12100+ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
12101+ zval *post_array;
12102+ zval *get_array;
12103+ zval *cookie_array;
12104+ZEND_END_MODULE_GLOBALS(my_input_filter)
12105+
12106+#ifdef ZTS
12107+#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v)
12108+#else
12109+#define IF_G(v) (my_input_filter_globals.v)
12110+#endif
12111+
12112+ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
12113+
12114+function_entry my_input_filter_functions[] = {
12115+ PHP_FE(my_get_raw, NULL)
12116+ {NULL, NULL, NULL}
12117+};
12118+
12119+zend_module_entry my_input_filter_module_entry = {
12120+ STANDARD_MODULE_HEADER,
12121+ "my_input_filter",
12122+ my_input_filter_functions,
12123+ PHP_MINIT(my_input_filter),
12124+ PHP_MSHUTDOWN(my_input_filter),
12125+ NULL,
12126+ PHP_RSHUTDOWN(my_input_filter),
12127+ PHP_MINFO(my_input_filter),
12128+ "0.1",
12129+ STANDARD_MODULE_PROPERTIES
12130+};
12131+
12132+PHP_MINIT_FUNCTION(my_input_filter)
12133+{
12134+ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
12135+
12136+ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
12137+ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
12138+ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
12139+
12140+ sapi_register_input_filter(my_sapi_input_filter);
12141+ return SUCCESS;
12142+}
12143+
12144+PHP_RSHUTDOWN_FUNCTION(my_input_filter)
12145+{
12146+ if(IF_G(get_array)) {
12147+ zval_ptr_dtor(&IF_G(get_array));
12148+ IF_G(get_array) = NULL;
12149+ }
12150+ if(IF_G(post_array)) {
12151+ zval_ptr_dtor(&IF_G(post_array));
12152+ IF_G(post_array) = NULL;
12153+ }
12154+ if(IF_G(cookie_array)) {
12155+ zval_ptr_dtor(&IF_G(cookie_array));
12156+ IF_G(cookie_array) = NULL;
12157+ }
12158+ return SUCCESS;
12159+}
12160+
12161+PHP_MINFO_FUNCTION(my_input_filter)
12162+{
12163+ php_info_print_table_start();
12164+ php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
12165+ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $");
12166+ php_info_print_table_end();
12167+}
12168+
12169+/* The filter handler. If you return 1 from it, then PHP also registers the
12170+ * (modified) variable. Returning 0 prevents PHP from registering the variable;
12171+ * you can use this if your filter already registers the variable under a
12172+ * different name, or if you just don't want the variable registered at all. */
12173+SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
12174+{
12175+ zval new_var;
12176+ zval *array_ptr = NULL;
12177+ char *raw_var;
12178+ int var_len;
12179+
12180+ assert(*val != NULL);
12181+
12182+ switch(arg) {
12183+ case PARSE_GET:
12184+ if(!IF_G(get_array)) {
12185+ ALLOC_ZVAL(array_ptr);
12186+ array_init(array_ptr);
12187+ INIT_PZVAL(array_ptr);
12188+ }
12189+ IF_G(get_array) = array_ptr;
12190+ break;
12191+ case PARSE_POST:
12192+ if(!IF_G(post_array)) {
12193+ ALLOC_ZVAL(array_ptr);
12194+ array_init(array_ptr);
12195+ INIT_PZVAL(array_ptr);
12196+ }
12197+ IF_G(post_array) = array_ptr;
12198+ break;
12199+ case PARSE_COOKIE:
12200+ if(!IF_G(cookie_array)) {
12201+ ALLOC_ZVAL(array_ptr);
12202+ array_init(array_ptr);
12203+ INIT_PZVAL(array_ptr);
12204+ }
12205+ IF_G(cookie_array) = array_ptr;
12206+ break;
12207+ }
12208+ Z_STRLEN(new_var) = val_len;
12209+ Z_STRVAL(new_var) = estrndup(*val, val_len);
12210+ Z_TYPE(new_var) = IS_STRING;
12211+
12212+ var_len = strlen(var);
12213+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
12214+ strcpy(raw_var, "RAW_");
12215+ strlcat(raw_var,var,var_len+5);
12216+
12217+ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
12218+
12219+ php_strip_tags(*val, val_len, NULL, NULL, 0);
12220+
12221+ *new_val_len = strlen(*val);
12222+ return 1;
12223+}
12224+
12225+PHP_FUNCTION(my_get_raw)
12226+{
12227+ long arg;
12228+ char *var;
12229+ int var_len;
12230+ zval **tmp;
12231+ zval *array_ptr = NULL;
12232+ HashTable *hash_ptr;
12233+ char *raw_var;
12234+
12235+ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
12236+ return;
12237+ }
12238+
12239+ switch(arg) {
12240+ case PARSE_GET:
12241+ array_ptr = IF_G(get_array);
12242+ break;
12243+ case PARSE_POST:
12244+ array_ptr = IF_G(post_array);
12245+ break;
12246+ case PARSE_COOKIE:
12247+ array_ptr = IF_G(post_array);
12248+ break;
12249+ }
12250+
12251+ if(!array_ptr) RETURN_FALSE;
12252+
12253+ /*
12254+ * I'm changing the variable name here because when running with register_globals on,
12255+ * the variable will end up in the global symbol table
12256+ */
12257+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
12258+ strcpy(raw_var, "RAW_");
12259+ strlcat(raw_var,var,var_len+5);
12260+ hash_ptr = HASH_OF(array_ptr);
12261+
12262+ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) {
12263+ *return_value = **tmp;
12264+ zval_copy_ctor(return_value);
12265+ } else {
12266+ RETVAL_FALSE;
12267+ }
12268+ efree(raw_var);
12269+}
12270+
12271diff -Nura php-4.3.11/sapi/apache/mod_php4.c hardening-patch-4.3.11-0.4.2/sapi/apache/mod_php4.c
12272--- php-4.3.11/sapi/apache/mod_php4.c 2004-07-21 18:25:28.000000000 +0200
12273+++ hardening-patch-4.3.11-0.4.2/sapi/apache/mod_php4.c 2005-09-07 18:41:01.010095352 +0200
12274@@ -446,7 +446,7 @@
12275 sapi_apache_get_fd,
12276 sapi_apache_force_http_10,
12277 sapi_apache_get_target_uid,
12278- sapi_apache_get_target_gid
12279+ sapi_apache_get_target_gid,
12280 };
12281 /* }}} */
12282
12283@@ -892,7 +892,11 @@
12284 {
12285 TSRMLS_FETCH();
12286 if (PG(expose_php)) {
12287+#if HARDENING_PATCH
12288+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
12289+#else
12290 ap_add_version_component("PHP/" PHP_VERSION);
12291+#endif
12292 }
12293 }
12294 #endif
12295diff -Nura php-4.3.11/sapi/apache2filter/sapi_apache2.c hardening-patch-4.3.11-0.4.2/sapi/apache2filter/sapi_apache2.c
12296--- php-4.3.11/sapi/apache2filter/sapi_apache2.c 2005-01-07 07:28:36.000000000 +0100
12297+++ hardening-patch-4.3.11-0.4.2/sapi/apache2filter/sapi_apache2.c 2005-09-07 18:41:01.011095200 +0200
12298@@ -563,7 +563,11 @@
12299 {
12300 TSRMLS_FETCH();
12301 if (PG(expose_php)) {
12302+#if HARDENING_PATCH
12303+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
12304+#else
12305 ap_add_version_component(p, "PHP/" PHP_VERSION);
12306+#endif
12307 }
12308 }
12309
12310diff -Nura php-4.3.11/sapi/apache2handler/sapi_apache2.c hardening-patch-4.3.11-0.4.2/sapi/apache2handler/sapi_apache2.c
12311--- php-4.3.11/sapi/apache2handler/sapi_apache2.c 2005-03-10 12:39:04.000000000 +0100
12312+++ hardening-patch-4.3.11-0.4.2/sapi/apache2handler/sapi_apache2.c 2005-09-07 18:41:01.011095200 +0200
12313@@ -345,7 +345,11 @@
12314 {
12315 TSRMLS_FETCH();
12316 if (PG(expose_php)) {
12317+#if HARDENING_PATCH
12318+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
12319+#else
12320 ap_add_version_component(p, "PHP/" PHP_VERSION);
12321+#endif
12322 }
12323 }
12324
12325diff -Nura php-4.3.11/sapi/cgi/cgi_main.c hardening-patch-4.3.11-0.4.2/sapi/cgi/cgi_main.c
12326--- php-4.3.11/sapi/cgi/cgi_main.c 2005-02-11 03:12:30.000000000 +0100
12327+++ hardening-patch-4.3.11-0.4.2/sapi/cgi/cgi_main.c 2005-09-07 18:41:01.012095048 +0200
12328@@ -1435,11 +1435,19 @@
12329 SG(headers_sent) = 1;
12330 SG(request_info).no_headers = 1;
12331 }
12332+#if HARDENING_PATCH
12333+#if ZEND_DEBUG
12334+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
12335+#else
12336+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
12337+#endif
12338+#else
12339 #if ZEND_DEBUG
12340 php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
12341 #else
12342 php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
12343 #endif
12344+#endif
12345 php_end_ob_buffers(1 TSRMLS_CC);
12346 exit(1);
12347 break;
12348diff -Nura php-4.3.11/sapi/cli/php_cli.c hardening-patch-4.3.11-0.4.2/sapi/cli/php_cli.c
12349--- php-4.3.11/sapi/cli/php_cli.c 2005-03-22 16:09:36.000000000 +0100
12350+++ hardening-patch-4.3.11-0.4.2/sapi/cli/php_cli.c 2005-09-07 18:41:01.013094896 +0200
12351@@ -652,11 +652,19 @@
12352 if (php_request_startup(TSRMLS_C)==FAILURE) {
12353 goto err;
12354 }
12355+#if HARDENING_PATCH
12356+#if ZEND_DEBUG
12357+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
12358+#else
12359+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
12360+#endif
12361+#else
12362 #if ZEND_DEBUG
12363 php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
12364 #else
12365 php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
12366 #endif
12367+#endif
12368 php_end_ob_buffers(1 TSRMLS_CC);
12369 exit_status=1;
12370 goto out;
12371diff -Nura php-4.3.11/TSRM/TSRM.h hardening-patch-4.3.11-0.4.2/TSRM/TSRM.h
12372--- php-4.3.11/TSRM/TSRM.h 2005-02-11 04:34:04.000000000 +0100
12373+++ hardening-patch-4.3.11-0.4.2/TSRM/TSRM.h 2005-09-07 18:41:01.014094744 +0200
12374@@ -33,6 +33,13 @@
12375 # define TSRM_API
12376 #endif
12377
12378+#if HARDENING_PATCH
12379+# if HAVE_REALPATH
12380+# undef realpath
12381+# define realpath php_realpath
12382+# endif
12383+#endif
12384+
12385 /* Only compile multi-threading functions if we're in ZTS mode */
12386 #ifdef ZTS
12387
12388@@ -90,6 +97,7 @@
12389
12390 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
12391
12392+
12393 #ifdef __cplusplus
12394 extern "C" {
12395 #endif
12396diff -Nura php-4.3.11/TSRM/tsrm_virtual_cwd.c hardening-patch-4.3.11-0.4.2/TSRM/tsrm_virtual_cwd.c
12397--- php-4.3.11/TSRM/tsrm_virtual_cwd.c 2005-02-11 04:34:04.000000000 +0100
12398+++ hardening-patch-4.3.11-0.4.2/TSRM/tsrm_virtual_cwd.c 2005-09-07 18:41:01.014094744 +0200
12399@@ -192,6 +192,165 @@
12400 return p;
12401 }
12402
12403+#if HARDENING_PATCH
12404+CWD_API char *php_realpath(const char *path, char *resolved)
12405+{
12406+ struct stat sb;
12407+ char *p, *q, *s;
12408+ size_t left_len, resolved_len;
12409+ unsigned symlinks;
12410+ int serrno, slen;
12411+ int is_dir = 1;
12412+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
12413+
12414+ serrno = errno;
12415+ symlinks = 0;
12416+ if (path[0] == '/') {
12417+ resolved[0] = '/';
12418+ resolved[1] = '\0';
12419+ if (path[1] == '\0')
12420+ return (resolved);
12421+ resolved_len = 1;
12422+ left_len = strlcpy(left, path + 1, sizeof(left));
12423+ } else {
12424+ if (getcwd(resolved, PATH_MAX) == NULL) {
12425+ strlcpy(resolved, ".", PATH_MAX);
12426+ return (NULL);
12427+ }
12428+ resolved_len = strlen(resolved);
12429+ left_len = strlcpy(left, path, sizeof(left));
12430+ }
12431+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
12432+ errno = ENAMETOOLONG;
12433+ return (NULL);
12434+ }
12435+
12436+ /*
12437+ * Iterate over path components in `left'.
12438+ */
12439+ while (left_len != 0) {
12440+ /*
12441+ * Extract the next path component and adjust `left'
12442+ * and its length.
12443+ */
12444+ p = strchr(left, '/');
12445+ s = p ? p : left + left_len;
12446+ if (s - left >= sizeof(next_token)) {
12447+ errno = ENAMETOOLONG;
12448+ return (NULL);
12449+ }
12450+ memcpy(next_token, left, s - left);
12451+ next_token[s - left] = '\0';
12452+ left_len -= s - left;
12453+ if (p != NULL)
12454+ memmove(left, s + 1, left_len + 1);
12455+ if (resolved[resolved_len - 1] != '/') {
12456+ if (resolved_len + 1 >= PATH_MAX) {
12457+ errno = ENAMETOOLONG;
12458+ return (NULL);
12459+ }
12460+ resolved[resolved_len++] = '/';
12461+ resolved[resolved_len] = '\0';
12462+ }
12463+ if (next_token[0] == '\0')
12464+ continue;
12465+ else if (strcmp(next_token, ".") == 0)
12466+ continue;
12467+ else if (strcmp(next_token, "..") == 0) {
12468+ /*
12469+ * Strip the last path component except when we have
12470+ * single "/"
12471+ */
12472+ if (!is_dir) {
12473+ errno = ENOENT;
12474+ return (NULL);
12475+ }
12476+ if (resolved_len > 1) {
12477+ resolved[resolved_len - 1] = '\0';
12478+ q = strrchr(resolved, '/');
12479+ *q = '\0';
12480+ resolved_len = q - resolved;
12481+ }
12482+ continue;
12483+ }
12484+
12485+ /*
12486+ * Append the next path component and lstat() it. If
12487+ * lstat() fails we still can return successfully if
12488+ * there are no more path components left.
12489+ */
12490+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
12491+ if (resolved_len >= PATH_MAX) {
12492+ errno = ENAMETOOLONG;
12493+ return (NULL);
12494+ }
12495+ if (lstat(resolved, &sb) != 0) {
12496+ if (errno == ENOENT && p == NULL) {
12497+ errno = serrno;
12498+ return (resolved);
12499+ }
12500+ return (NULL);
12501+ }
12502+ if (S_ISLNK(sb.st_mode)) {
12503+ if (symlinks++ > MAXSYMLINKS) {
12504+ errno = ELOOP;
12505+ return (NULL);
12506+ }
12507+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
12508+ if (slen < 0)
12509+ return (NULL);
12510+ symlink[slen] = '\0';
12511+ if (symlink[0] == '/') {
12512+ resolved[1] = 0;
12513+ resolved_len = 1;
12514+ } else if (resolved_len > 1) {
12515+ /* Strip the last path component. */
12516+ resolved[resolved_len - 1] = '\0';
12517+ q = strrchr(resolved, '/');
12518+ *q = '\0';
12519+ resolved_len = q - resolved;
12520+ }
12521+
12522+ /*
12523+ * If there are any path components left, then
12524+ * append them to symlink. The result is placed
12525+ * in `left'.
12526+ */
12527+ if (p != NULL) {
12528+ if (symlink[slen - 1] != '/') {
12529+ if (slen + 1 >= sizeof(symlink)) {
12530+ errno = ENAMETOOLONG;
12531+ return (NULL);
12532+ }
12533+ symlink[slen] = '/';
12534+ symlink[slen + 1] = 0;
12535+ }
12536+ left_len = strlcat(symlink, left, sizeof(left));
12537+ if (left_len >= sizeof(left)) {
12538+ errno = ENAMETOOLONG;
12539+ return (NULL);
12540+ }
12541+ }
12542+ left_len = strlcpy(left, symlink, sizeof(left));
12543+ } else {
12544+ if (S_ISDIR(sb.st_mode)) {
12545+ is_dir = 1;
12546+ } else {
12547+ is_dir = 0;
12548+ }
12549+ }
12550+ }
12551+
12552+ /*
12553+ * Remove trailing slash except when the resolved pathname
12554+ * is a single "/".
12555+ */
12556+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
12557+ resolved[resolved_len - 1] = '\0';
12558+ return (resolved);
12559+}
12560+#endif
12561+
12562 CWD_API void virtual_cwd_startup(void)
12563 {
12564 char cwd[MAXPATHLEN];
12565@@ -314,8 +473,7 @@
12566 path = resolved_path;
12567 path_length = strlen(path);
12568 } else {
12569- /* disable for now
12570- return 1; */
12571+ return 1;
12572 }
12573 }
12574 } else { /* Concat current directory with relative path and then run realpath() on it */
12575@@ -341,9 +499,8 @@
12576 path = resolved_path;
12577 path_length = strlen(path);
12578 } else {
12579- /* disable for now
12580 free(tmp);
12581- return 1; */
12582+ return 1;
12583 }
12584 }
12585 free(tmp);
12586diff -Nura php-4.3.11/TSRM/tsrm_virtual_cwd.h hardening-patch-4.3.11-0.4.2/TSRM/tsrm_virtual_cwd.h
12587--- php-4.3.11/TSRM/tsrm_virtual_cwd.h 2005-02-11 04:34:04.000000000 +0100
12588+++ hardening-patch-4.3.11-0.4.2/TSRM/tsrm_virtual_cwd.h 2005-09-07 18:41:01.015094592 +0200
12589@@ -128,6 +128,22 @@
12590
12591 typedef int (*verify_path_func)(const cwd_state *);
12592
12593+#ifndef HAVE_STRLCPY
12594+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
12595+#undef strlcpy
12596+#define strlcpy php_strlcpy
12597+#endif
12598+
12599+#ifndef HAVE_STRLCAT
12600+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
12601+#undef strlcat
12602+#define strlcat php_strlcat
12603+#endif
12604+
12605+
12606+#if HARDENING_PATCH
12607+CWD_API char *php_realpath(const char *path, char *resolved);
12608+#endif
12609 CWD_API void virtual_cwd_startup(void);
12610 CWD_API void virtual_cwd_shutdown(void);
12611 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
12612diff -Nura php-4.3.11/Zend/zend_alloc.c hardening-patch-4.3.11-0.4.2/Zend/zend_alloc.c
12613--- php-4.3.11/Zend/zend_alloc.c 2004-08-27 18:51:25.000000000 +0200
12614+++ hardening-patch-4.3.11-0.4.2/Zend/zend_alloc.c 2005-09-07 18:41:01.016094440 +0200
12615@@ -56,6 +56,11 @@
12616 # define END_MAGIC_SIZE 0
12617 #endif
12618
12619+#if HARDENING_PATCH_MM_PROTECT
12620+# define CANARY_SIZE sizeof(unsigned int)
12621+#else
12622+# define CANARY_SIZE 0
12623+#endif
12624
12625 # if MEMORY_LIMIT
12626 # if ZEND_DEBUG
12627@@ -95,9 +100,17 @@
12628 if (p==AG(head)) { \
12629 AG(head) = p->pNext; \
12630 } else { \
12631+ if (p != p->pLast->pNext) { \
12632+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
12633+ exit(1); \
12634+ } \
12635 p->pLast->pNext = p->pNext; \
12636 } \
12637 if (p->pNext) { \
12638+ if (p != p->pNext->pLast) { \
12639+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
12640+ exit(1); \
12641+ } \
12642 p->pNext->pLast = p->pLast; \
12643 }
12644
12645@@ -129,6 +142,12 @@
12646 DECLARE_CACHE_VARS();
12647 TSRMLS_FETCH();
12648
12649+#if HARDENING_PATCH_MM_PROTECT
12650+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
12651+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
12652+ exit(1);
12653+ }
12654+#endif
12655 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
12656
12657 if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
12658@@ -146,6 +165,10 @@
12659 AG(cache_stats)[CACHE_INDEX][1]++;
12660 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
12661 #endif
12662+#if HARDENING_PATCH_MM_PROTECT
12663+ p->canary = HG(canary_1);
12664+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
12665+#endif
12666 p->cached = 0;
12667 p->size = size;
12668 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
12669@@ -161,7 +184,7 @@
12670 AG(allocated_memory_peak) = AG(allocated_memory);
12671 }
12672 #endif
12673- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
12674+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
12675 }
12676
12677 HANDLE_BLOCK_INTERRUPTIONS();
12678@@ -191,7 +214,10 @@
12679 # endif
12680 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
12681 #endif
12682-
12683+#if HARDENING_PATCH_MM_PROTECT
12684+ p->canary = HG(canary_1);
12685+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
12686+#endif
12687 HANDLE_UNBLOCK_INTERRUPTIONS();
12688 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
12689 }
12690@@ -218,17 +244,36 @@
12691 return emalloc_rel(lval + offset);
12692 }
12693 }
12694-
12695+
12696+#if HARDENING_PATCH
12697+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
12698+#endif
12699 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset);
12700 return 0;
12701 }
12702
12703 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
12704 {
12705+#if HARDENING_PATCH_MM_PROTECT
12706+ unsigned int canary_2;
12707+#endif
12708 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
12709 DECLARE_CACHE_VARS();
12710 TSRMLS_FETCH();
12711
12712+#if HARDENING_PATCH_MM_PROTECT
12713+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch;
12714+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
12715+ if (canary_2 != HG(canary_2)) {
12716+efree_canary_mismatch:
12717+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
12718+ exit(1);
12719+ }
12720+ /* to catch double efree()s */
12721+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE);
12722+ p->canary = 0;
12723+#endif
12724+
12725 #if defined(ZTS) && TSRM_DEBUG
12726 if (p->thread_id != tsrm_thread_id()) {
12727 tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring",
12728@@ -273,6 +318,9 @@
12729 size_t _size = nmemb * size;
12730
12731 if (nmemb && (_size/nmemb!=size)) {
12732+#if HARDENING_PATCH
12733+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
12734+#endif
12735 fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
12736 #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
12737 kill(getpid(), SIGSEGV);
12738@@ -292,6 +340,9 @@
12739
12740 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
12741 {
12742+#if HARDENING_PATCH_MM_PROTECT
12743+ unsigned int canary_2;
12744+#endif
12745 zend_mem_header *p;
12746 zend_mem_header *orig;
12747 DECLARE_CACHE_VARS();
12748@@ -303,6 +354,16 @@
12749
12750 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
12751
12752+#if HARDENING_PATCH_MM_PROTECT
12753+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch;
12754+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
12755+ if (canary_2 != HG(canary_2)) {
12756+erealloc_canary_mismatch:
12757+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
12758+ exit(1);
12759+ }
12760+#endif
12761+
12762 #if defined(ZTS) && TSRM_DEBUG
12763 if (p->thread_id != tsrm_thread_id()) {
12764 void *new_p;
12765@@ -326,7 +387,7 @@
12766 }
12767 #endif
12768 REMOVE_POINTER_FROM_LIST(p);
12769- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
12770+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
12771 if (!p) {
12772 if (!allow_failure) {
12773 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
12774@@ -348,6 +409,9 @@
12775 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
12776 #endif
12777
12778+#if HARDENING_PATCH_MM_PROTECT
12779+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
12780+#endif
12781 p->size = size;
12782
12783 HANDLE_UNBLOCK_INTERRUPTIONS();
12784@@ -423,6 +487,10 @@
12785 {
12786 AG(head) = NULL;
12787
12788+#if HARDENING_PATCH_MM_PROTECT
12789+ HG(canary_1) = zend_canary();
12790+ HG(canary_2) = zend_canary();
12791+#endif
12792 #if MEMORY_LIMIT
12793 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
12794 AG(allocated_memory) = 0;
12795diff -Nura php-4.3.11/Zend/zend_alloc.h hardening-patch-4.3.11-0.4.2/Zend/zend_alloc.h
12796--- php-4.3.11/Zend/zend_alloc.h 2004-08-11 08:10:46.000000000 +0200
12797+++ hardening-patch-4.3.11-0.4.2/Zend/zend_alloc.h 2005-09-07 18:41:01.016094440 +0200
12798@@ -32,6 +32,9 @@
12799 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
12800
12801 typedef struct _zend_mem_header {
12802+#if HARDENING_PATCH_MM_PROTECT
12803+ unsigned int canary;
12804+#endif
12805 #if ZEND_DEBUG
12806 long magic;
12807 char *filename;
12808diff -Nura php-4.3.11/Zend/zend_builtin_functions.c hardening-patch-4.3.11-0.4.2/Zend/zend_builtin_functions.c
12809--- php-4.3.11/Zend/zend_builtin_functions.c 2004-12-27 20:28:35.000000000 +0100
12810+++ hardening-patch-4.3.11-0.4.2/Zend/zend_builtin_functions.c 2005-09-07 18:41:01.017094288 +0200
12811@@ -49,6 +49,9 @@
12812 static ZEND_FUNCTION(crash);
12813 #endif
12814 #endif
12815+#if HARDENING_PATCH_MM_PROTECT_DEBUG
12816+static ZEND_FUNCTION(heap_overflow);
12817+#endif
12818 static ZEND_FUNCTION(get_included_files);
12819 static ZEND_FUNCTION(is_subclass_of);
12820 static ZEND_FUNCTION(is_a);
12821@@ -101,6 +104,9 @@
12822 ZEND_FE(crash, NULL)
12823 #endif
12824 #endif
12825+#if HARDENING_PATCH_MM_PROTECT_DEBUG
12826+ ZEND_FE(heap_overflow, NULL)
12827+#endif
12828 ZEND_FE(get_included_files, NULL)
12829 ZEND_FALIAS(get_required_files, get_included_files, NULL)
12830 ZEND_FE(is_subclass_of, NULL)
12831@@ -805,6 +811,19 @@
12832
12833 #endif /* ZEND_DEBUG */
12834
12835+
12836+#if HARDENING_PATCH_MM_PROTECT_DEBUG
12837+ZEND_FUNCTION(heap_overflow)
12838+{
12839+ char *nowhere = emalloc(10);
12840+
12841+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
12842+
12843+ efree(nowhere);
12844+}
12845+#endif
12846+
12847+
12848 /* {{{ proto array get_included_files(void)
12849 Returns an array with the file names that were include_once()'d */
12850 ZEND_FUNCTION(get_included_files)
12851diff -Nura php-4.3.11/Zend/zend.c hardening-patch-4.3.11-0.4.2/Zend/zend.c
12852--- php-4.3.11/Zend/zend.c 2005-01-22 21:36:34.000000000 +0100
12853+++ hardening-patch-4.3.11-0.4.2/Zend/zend.c 2005-09-07 19:04:56.247906040 +0200
12854@@ -53,6 +53,12 @@
12855 ZEND_API void (*zend_unblock_interruptions)(void);
12856 ZEND_API void (*zend_ticks_function)(int ticks);
12857 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
12858+#if HARDENING_PATCH
12859+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
12860+#endif
12861+#if HARDENING_PATCH_INC_PROTECT
12862+ZEND_API int (*zend_is_valid_include)(zval *z);
12863+#endif
12864
12865 void (*zend_on_timeout)(int seconds TSRMLS_DC);
12866
12867@@ -70,9 +76,289 @@
12868 return SUCCESS;
12869 }
12870
12871+#if HARDENING_PATCH
12872+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
12873+{
12874+ if (!new_value) {
12875+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL;
12876+ } else {
12877+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL;
12878+ }
12879+ return SUCCESS;
12880+}
12881+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
12882+{
12883+ if (!new_value) {
12884+ EG(hphp_log_syslog_facility) = LOG_USER;
12885+ } else {
12886+ EG(hphp_log_syslog_facility) = atoi(new_value);
12887+ }
12888+ return SUCCESS;
12889+}
12890+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
12891+{
12892+ if (!new_value) {
12893+ EG(hphp_log_syslog_priority) = LOG_ALERT;
12894+ } else {
12895+ EG(hphp_log_syslog_priority) = atoi(new_value);
12896+ }
12897+ return SUCCESS;
12898+}
12899+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
12900+{
12901+ if (!new_value) {
12902+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL;
12903+ } else {
12904+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL;
12905+ }
12906+ return SUCCESS;
12907+}
12908+static ZEND_INI_MH(OnUpdateHPHP_log_script)
12909+{
12910+ if (!new_value) {
12911+ EG(hphp_log_script) = S_ALL & (~S_MEMORY) & (~S_INTERNAL);
12912+ } else {
12913+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
12914+ }
12915+ return SUCCESS;
12916+}
12917+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
12918+{
12919+ if (!new_value) {
12920+ EG(hphp_log_scriptname) = NULL;
12921+ } else {
12922+ if (EG(hphp_log_scriptname)) {
12923+ pefree(EG(hphp_log_scriptname),1);
12924+ }
12925+ EG(hphp_log_scriptname) = pestrdup(new_value,1);
12926+ }
12927+ return SUCCESS;
12928+}
12929+
12930+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist)
12931+{
12932+ char *s = NULL, *e, *val;
12933+ unsigned long dummy = 1;
12934+
12935+ if (!new_value) {
12936+eval_whitelist_destroy:
12937+ if (HG(eval_whitelist)) {
12938+ zend_hash_destroy(HG(eval_whitelist));
12939+ efree(HG(eval_whitelist));
12940+ }
12941+ HG(eval_whitelist) = NULL;
12942+ return SUCCESS;
12943+ }
12944+ if (!(*new_value)) {
12945+ goto eval_whitelist_destroy;
12946+ }
12947+
12948+ ALLOC_HASHTABLE(HG(eval_whitelist));
12949+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 0);
12950+
12951+ val = zend_str_tolower_dup(new_value, strlen(new_value));
12952+ e = val;
12953+
12954+ while (*e) {
12955+ switch (*e) {
12956+ case ' ':
12957+ case ',':
12958+ if (s) {
12959+ *e = '\0';
12960+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
12961+ s = NULL;
12962+ }
12963+ break;
12964+ default:
12965+ if (!s) {
12966+ s = e;
12967+ }
12968+ break;
12969+ }
12970+ e++;
12971+ }
12972+ if (s) {
12973+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
12974+ }
12975+ efree(val);
12976+
12977+ return SUCCESS;
12978+}
12979+
12980+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist)
12981+{
12982+ char *s = NULL, *e, *val;
12983+ unsigned long dummy = 1;
12984+
12985+ if (!new_value) {
12986+eval_blacklist_destroy:
12987+ if (HG(eval_blacklist)) {
12988+ zend_hash_destroy(HG(eval_blacklist));
12989+ efree(HG(eval_blacklist));
12990+ }
12991+ HG(eval_blacklist) = NULL;
12992+ return SUCCESS;
12993+ }
12994+ if (!(*new_value)) {
12995+ goto eval_blacklist_destroy;
12996+ }
12997+
12998+ ALLOC_HASHTABLE(HG(eval_blacklist));
12999+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 0);
13000+
13001+ val = zend_str_tolower_dup(new_value, strlen(new_value));
13002+ e = val;
13003+
13004+ while (*e) {
13005+ switch (*e) {
13006+ case ' ':
13007+ case ',':
13008+ if (s) {
13009+ *e = '\0';
13010+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
13011+ s = NULL;
13012+ }
13013+ break;
13014+ default:
13015+ if (!s) {
13016+ s = e;
13017+ }
13018+ break;
13019+ }
13020+ e++;
13021+ }
13022+ if (s) {
13023+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
13024+ }
13025+ efree(val);
13026+
13027+
13028+ return SUCCESS;
13029+}
13030+
13031+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist)
13032+{
13033+ char *s = NULL, *e, *val;
13034+ unsigned long dummy = 1;
13035+
13036+ if (!new_value) {
13037+func_whitelist_destroy:
13038+ if (HG(func_whitelist)) {
13039+ zend_hash_destroy(HG(func_whitelist));
13040+ efree(HG(func_whitelist));
13041+ }
13042+ HG(func_whitelist) = NULL;
13043+ return SUCCESS;
13044+ }
13045+ if (!(*new_value)) {
13046+ goto func_whitelist_destroy;
13047+ }
13048+
13049+ ALLOC_HASHTABLE(HG(func_whitelist));
13050+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 0);
13051+
13052+ val = zend_str_tolower_dup(new_value, strlen(new_value));
13053+ e = val;
13054+
13055+ while (*e) {
13056+ switch (*e) {
13057+ case ' ':
13058+ case ',':
13059+ if (s) {
13060+ *e = '\0';
13061+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
13062+ s = NULL;
13063+ }
13064+ break;
13065+ default:
13066+ if (!s) {
13067+ s = e;
13068+ }
13069+ break;
13070+ }
13071+ e++;
13072+ }
13073+ if (s) {
13074+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
13075+ }
13076+ efree(val);
13077+
13078+ return SUCCESS;
13079+}
13080+
13081+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist)
13082+{
13083+ char *s = NULL, *e, *val;
13084+ unsigned long dummy = 1;
13085+
13086+ if (!new_value) {
13087+func_blacklist_destroy:
13088+ if (HG(func_blacklist)) {
13089+ zend_hash_destroy(HG(func_blacklist));
13090+ efree(HG(func_blacklist));
13091+ }
13092+ HG(func_blacklist) = NULL;
13093+ return SUCCESS;
13094+ }
13095+ if (!(*new_value)) {
13096+ goto func_blacklist_destroy;
13097+ }
13098+
13099+ ALLOC_HASHTABLE(HG(func_blacklist));
13100+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 0);
13101+
13102+ val = zend_str_tolower_dup(new_value, strlen(new_value));
13103+ e = val;
13104+
13105+ while (*e) {
13106+ switch (*e) {
13107+ case ' ':
13108+ case ',':
13109+ if (s) {
13110+ *e = '\0';
13111+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
13112+ s = NULL;
13113+ }
13114+ break;
13115+ default:
13116+ if (!s) {
13117+ s = e;
13118+ }
13119+ break;
13120+ }
13121+ e++;
13122+ }
13123+ if (s) {
13124+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
13125+ }
13126+ efree(val);
13127+
13128+
13129+ return SUCCESS;
13130+}
13131+
13132+#endif
13133
13134 ZEND_INI_BEGIN()
13135 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
13136+#if HARDENING_PATCH
13137+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog)
13138+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility)
13139+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority)
13140+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi)
13141+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script)
13142+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname)
13143+ STD_ZEND_INI_BOOLEAN("hphp.log.use-x-forwarded-for", "0", ZEND_INI_SYSTEM, OnUpdateBool, hphp_log_use_x_forwarded_for, zend_executor_globals, executor_globals)
13144+
13145+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist)
13146+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist)
13147+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist)
13148+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist)
13149+
13150+ STD_ZEND_INI_ENTRY("hphp.executor.max_depth", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_executor_max_depth, zend_executor_globals, executor_globals)
13151+ STD_ZEND_INI_BOOLEAN("hphp.sql.bailout_on_error", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_sql_bailout_on_error, hardened_globals_struct, hardened_globals)
13152+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals)
13153+#endif
13154 ZEND_INI_END()
13155
13156
13157@@ -354,6 +640,7 @@
13158 zend_init_rsrc_plist(TSRMLS_C);
13159 EG(lambda_count)=0;
13160 EG(user_error_handler) = NULL;
13161+ EG(in_code_type) = 0;
13162 EG(in_execution) = 0;
13163 EG(current_execute_data) = NULL;
13164 }
13165@@ -420,6 +707,14 @@
13166 extern zend_scanner_globals language_scanner_globals;
13167 #endif
13168
13169+ /* Set up Hardening-Patch utility functions first */
13170+#if HARDENING_PATCH
13171+ zend_security_log = utility_functions->security_log_function;
13172+#endif
13173+#if HARDENING_PATCH_INC_PROTECT
13174+ zend_is_valid_include = utility_functions->is_valid_include;
13175+#endif
13176+
13177 #ifdef ZTS
13178 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
13179 #else
13180@@ -623,6 +918,7 @@
13181 }
13182 CG(unclean_shutdown) = 1;
13183 CG(in_compilation) = EG(in_execution) = 0;
13184+ EG(in_code_type) = 0;
13185 EG(current_execute_data) = NULL;
13186 longjmp(EG(bailout), FAILURE);
13187 }
13188diff -Nura php-4.3.11/Zend/zend_canary.c hardening-patch-4.3.11-0.4.2/Zend/zend_canary.c
13189--- php-4.3.11/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
13190+++ hardening-patch-4.3.11-0.4.2/Zend/zend_canary.c 2005-09-07 18:41:01.019093984 +0200
13191@@ -0,0 +1,58 @@
13192+/*
13193+ +----------------------------------------------------------------------+
13194+ | Hardening-Patch for PHP |
13195+ +----------------------------------------------------------------------+
13196+ | Copyright (c) 2004-2005 Stefan Esser |
13197+ +----------------------------------------------------------------------+
13198+ | This source file is subject to version 2.02 of the PHP license, |
13199+ | that is bundled with this package in the file LICENSE, and is |
13200+ | available at through the world-wide-web at |
13201+ | http://www.php.net/license/2_02.txt. |
13202+ | If you did not receive a copy of the PHP license and are unable to |
13203+ | obtain it through the world-wide-web, please send a note to |
13204+ | license@php.net so we can mail you a copy immediately. |
13205+ +----------------------------------------------------------------------+
13206+ | Author: Stefan Esser <sesser@hardened-php.net> |
13207+ +----------------------------------------------------------------------+
13208+ */
13209+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
13210+
13211+#include "zend.h"
13212+
13213+#include <stdio.h>
13214+#include <stdlib.h>
13215+
13216+
13217+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
13218+
13219+/* will be replaced later with more compatible method */
13220+ZEND_API unsigned int zend_canary()
13221+{
13222+ time_t t;
13223+ unsigned int canary;
13224+ int fd;
13225+
13226+ fd = open("/dev/urandom", 0);
13227+ if (fd != -1) {
13228+ int r = read(fd, &canary, sizeof(canary));
13229+ close(fd);
13230+ if (r == sizeof(canary)) {
13231+ return (canary);
13232+ }
13233+ }
13234+ /* not good but we never want to do this */
13235+ time(&t);
13236+ canary = *(unsigned int *)&t + getpid() << 16;
13237+ return (canary);
13238+}
13239+#endif
13240+
13241+
13242+/*
13243+ * Local variables:
13244+ * tab-width: 4
13245+ * c-basic-offset: 4
13246+ * End:
13247+ * vim600: sw=4 ts=4 fdm=marker
13248+ * vim<600: sw=4 ts=4
13249+ */
13250diff -Nura php-4.3.11/Zend/zend_compile.c hardening-patch-4.3.11-0.4.2/Zend/zend_compile.c
13251--- php-4.3.11/Zend/zend_compile.c 2004-12-30 16:22:52.000000000 +0100
13252+++ hardening-patch-4.3.11-0.4.2/Zend/zend_compile.c 2005-09-07 18:41:01.020093832 +0200
13253@@ -750,6 +750,13 @@
13254 op_array.function_name = name;
13255 op_array.arg_types = NULL;
13256 op_array.return_reference = return_reference;
13257+#if HARDENING_PATCH
13258+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
13259+ op_array.created_by_eval = 1;
13260+ } else {
13261+ op_array.created_by_eval = 0;
13262+ }
13263+#endif
13264
13265 if (is_method) {
13266 if (zend_hash_add(&CG(active_class_entry)->function_table, name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) {
13267diff -Nura php-4.3.11/Zend/zend_compile.h hardening-patch-4.3.11-0.4.2/Zend/zend_compile.h
13268--- php-4.3.11/Zend/zend_compile.h 2004-09-24 15:15:14.000000000 +0200
13269+++ hardening-patch-4.3.11-0.4.2/Zend/zend_compile.h 2005-09-07 18:41:01.021093680 +0200
13270@@ -106,6 +106,9 @@
13271 char *filename;
13272
13273 void *reserved[ZEND_MAX_RESERVED_RESOURCES];
13274+#if HARDENING_PATCH
13275+ zend_bool created_by_eval;
13276+#endif
13277 };
13278
13279
13280@@ -546,6 +549,7 @@
13281 #define ZEND_USER_FUNCTION 2
13282 #define ZEND_OVERLOADED_FUNCTION 3
13283 #define ZEND_EVAL_CODE 4
13284+#define ZEND_SANDBOX_CODE 6
13285
13286 #define ZEND_INTERNAL_CLASS 1
13287 #define ZEND_USER_CLASS 2
13288diff -Nura php-4.3.11/Zend/zend_constants.c hardening-patch-4.3.11-0.4.2/Zend/zend_constants.c
13289--- php-4.3.11/Zend/zend_constants.c 2004-07-13 21:29:45.000000000 +0200
13290+++ hardening-patch-4.3.11-0.4.2/Zend/zend_constants.c 2005-09-07 19:04:56.247906040 +0200
13291@@ -111,6 +111,73 @@
13292 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
13293
13294 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
13295+#if HARDENING_PATCH
13296+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
13297+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
13298+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
13299+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
13300+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
13301+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
13302+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
13303+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
13304+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
13305+
13306+ /* error levels */
13307+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
13308+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
13309+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
13310+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
13311+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
13312+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
13313+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
13314+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
13315+ /* facility: type of program logging the message */
13316+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
13317+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
13318+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
13319+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
13320+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
13321+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
13322+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
13323+#ifdef LOG_NEWS
13324+ /* No LOG_NEWS on HP-UX */
13325+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
13326+#endif
13327+#ifdef LOG_UUCP
13328+ /* No LOG_UUCP on HP-UX */
13329+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
13330+#endif
13331+#ifdef LOG_CRON
13332+ /* apparently some systems don't have this one */
13333+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
13334+#endif
13335+#ifdef LOG_AUTHPRIV
13336+ /* AIX doesn't have LOG_AUTHPRIV */
13337+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
13338+#endif
13339+#if !defined(PHP_WIN32) && !defined(NETWARE)
13340+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
13341+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
13342+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
13343+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
13344+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
13345+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
13346+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
13347+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
13348+#endif
13349+ /* options */
13350+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
13351+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
13352+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
13353+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
13354+#ifdef LOG_NOWAIT
13355+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
13356+#endif
13357+#ifdef LOG_PERROR
13358+ /* AIX doesn't have LOG_PERROR */
13359+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
13360+#endif
13361+#endif
13362
13363 /* true/false constants */
13364 {
13365diff -Nura php-4.3.11/Zend/zend_errors.h hardening-patch-4.3.11-0.4.2/Zend/zend_errors.h
13366--- php-4.3.11/Zend/zend_errors.h 2002-12-31 17:22:59.000000000 +0100
13367+++ hardening-patch-4.3.11-0.4.2/Zend/zend_errors.h 2005-09-07 19:04:56.248905888 +0200
13368@@ -36,5 +36,17 @@
13369 #define E_ALL (E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE)
13370 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
13371
13372+#if HARDENING_PATCH
13373+#define S_MEMORY (1<<0L)
13374+#define S_VARS (1<<1L)
13375+#define S_FILES (1<<2L)
13376+#define S_INCLUDE (1<<3L)
13377+#define S_SQL (1<<4L)
13378+#define S_EXECUTOR (1<<5L)
13379+#define S_MISC (1<<30L)
13380+#define S_INTERNAL (1<<29L)
13381+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MISC | S_SQL | S_EXECUTOR)
13382+#endif
13383+
13384 #endif /* ZEND_ERRORS_H */
13385
13386diff -Nura php-4.3.11/Zend/zend_execute_API.c hardening-patch-4.3.11-0.4.2/Zend/zend_execute_API.c
13387--- php-4.3.11/Zend/zend_execute_API.c 2004-11-04 00:15:05.000000000 +0100
13388+++ hardening-patch-4.3.11-0.4.2/Zend/zend_execute_API.c 2005-09-07 18:41:01.022093528 +0200
13389@@ -142,6 +142,7 @@
13390 EG(class_table) = CG(class_table);
13391
13392 EG(in_execution) = 0;
13393+ EG(in_code_type) = 0;
13394
13395 zend_ptr_stack_init(&EG(argument_stack));
13396
13397@@ -431,12 +432,14 @@
13398 zend_execute_data execute_data;
13399
13400 /* Initialize execute_data */
13401+ memset(&execute_data, 0, sizeof(execute_data));
13402 EX(fbc) = NULL;
13403 EX(object).ptr = NULL;
13404 EX(ce) = NULL;
13405 EX(Ts) = NULL;
13406 EX(op_array) = NULL;
13407 EX(opline) = NULL;
13408+ EX(execute_depth) = 0;
13409
13410 *retval_ptr_ptr = NULL;
13411
13412@@ -494,6 +497,39 @@
13413 zval_dtor(&function_name_copy);
13414 return FAILURE;
13415 }
13416+#if HARDENING_PATCH
13417+ if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
13418+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
13419+ if (HG(eval_whitelist) != NULL) {
13420+ if (!zend_hash_exists(HG(eval_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
13421+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_copy.value.str.val);
13422+ zval_dtor(&function_name_copy);
13423+ zend_bailout();
13424+ }
13425+ } else if (HG(eval_blacklist) != NULL) {
13426+ if (zend_hash_exists(HG(eval_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
13427+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_copy.value.str.val);
13428+ zval_dtor(&function_name_copy);
13429+ zend_bailout();
13430+ }
13431+ }
13432+ }
13433+
13434+ if (HG(func_whitelist) != NULL) {
13435+ if (!zend_hash_exists(HG(func_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
13436+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_copy.value.str.val);
13437+ zval_dtor(&function_name_copy);
13438+ zend_bailout();
13439+ }
13440+ } else if (HG(func_blacklist) != NULL) {
13441+ if (zend_hash_exists(HG(func_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
13442+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_copy.value.str.val);
13443+ zval_dtor(&function_name_copy);
13444+ zend_bailout();
13445+ }
13446+ }
13447+ }
13448+#endif
13449 zval_dtor(&function_name_copy);
13450
13451 for (i=0; i<param_count; i++) {
13452@@ -601,8 +637,7 @@
13453 return SUCCESS;
13454 }
13455
13456-
13457-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
13458+ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
13459 {
13460 zval pv;
13461 zend_op_array *new_op_array;
13462@@ -635,6 +670,7 @@
13463 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
13464 zend_op **original_opline_ptr = EG(opline_ptr);
13465
13466+ new_op_array->type = type;
13467 EG(return_value_ptr_ptr) = &local_retval_ptr;
13468 EG(active_op_array) = new_op_array;
13469 EG(no_extensions)=1;
13470@@ -668,6 +704,10 @@
13471 return retval;
13472 }
13473
13474+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
13475+{
13476+ return (zend_eval_string_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
13477+}
13478
13479 void execute_new_code(TSRMLS_D)
13480 {
13481diff -Nura php-4.3.11/Zend/zend_execute.c hardening-patch-4.3.11-0.4.2/Zend/zend_execute.c
13482--- php-4.3.11/Zend/zend_execute.c 2005-02-21 13:38:54.000000000 +0100
13483+++ hardening-patch-4.3.11-0.4.2/Zend/zend_execute.c 2005-09-07 18:41:01.024093224 +0200
13484@@ -1042,6 +1042,7 @@
13485 zend_execute_data execute_data;
13486
13487 /* Initialize execute_data */
13488+ memset(&execute_data, 0, sizeof(execute_data));
13489 EX(fbc) = NULL;
13490 EX(ce) = NULL;
13491 EX(object).ptr = NULL;
13492@@ -1053,9 +1054,21 @@
13493 }
13494 EX(prev_execute_data) = EG(current_execute_data);
13495 EX(original_in_execution)=EG(in_execution);
13496+ EX(original_in_code_type)=EG(in_code_type);
13497
13498 EG(current_execute_data) = &execute_data;
13499
13500+#if HARDENING_PATCH
13501+ EX(execute_depth) = 0;
13502+
13503+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval) && EG(in_code_type) != ZEND_SANDBOX_CODE) {
13504+ EG(in_code_type) = ZEND_EVAL_CODE;
13505+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
13506+ EG(in_code_type) = ZEND_SANDBOX_CODE;
13507+ op_array->type = ZEND_EVAL_CODE;
13508+ }
13509+#endif
13510+
13511 EG(in_execution) = 1;
13512 if (op_array->start_op) {
13513 EX(opline) = op_array->start_op;
13514@@ -1087,6 +1100,19 @@
13515 }
13516 }
13517
13518+#if HARDENING_PATCH
13519+ if (EX(prev_execute_data) == NULL) {
13520+ EX(execute_depth) = 0;
13521+ } else {
13522+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
13523+ }
13524+
13525+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
13526+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
13527+ zend_bailout();
13528+ }
13529+#endif
13530+
13531 while (1) {
13532 #ifdef ZEND_WIN32
13533 if (EG(timed_out)) {
13534@@ -1615,6 +1641,36 @@
13535 if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) {
13536 zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val);
13537 }
13538+#if HARDENING_PATCH
13539+ if (active_function_table == EG(function_table)) {
13540+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
13541+ if (HG(eval_whitelist) != NULL) {
13542+ if (!zend_hash_exists(HG(eval_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
13543+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name->value.str.val);
13544+ zend_bailout();
13545+ }
13546+ } else if (HG(eval_blacklist) != NULL) {
13547+ if (zend_hash_exists(HG(eval_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
13548+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name->value.str.val);
13549+ zend_bailout();
13550+ }
13551+ }
13552+ }
13553+
13554+ if (HG(func_whitelist) != NULL) {
13555+ if (!zend_hash_exists(HG(func_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
13556+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name->value.str.val);
13557+ zend_bailout();
13558+ }
13559+ } else if (HG(func_blacklist) != NULL) {
13560+ if (zend_hash_exists(HG(func_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
13561+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name->value.str.val);
13562+ zend_bailout();
13563+ }
13564+ }
13565+ }
13566+#endif
13567+
13568 zval_dtor(&tmp);
13569 EX(fbc) = function;
13570 overloaded_function_call_cont:
13571@@ -1630,6 +1686,35 @@
13572 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
13573 zend_error(E_ERROR, "Unknown function: %s()", fname->value.str.val);
13574 }
13575+#if HARDENING_PATCH
13576+ if (EX(function_state).function->type==ZEND_INTERNAL_FUNCTION) {
13577+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
13578+ if (HG(eval_whitelist) != NULL) {
13579+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
13580+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
13581+ zend_bailout();
13582+ }
13583+ } else if (HG(eval_blacklist) != NULL) {
13584+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
13585+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
13586+ zend_bailout();
13587+ }
13588+ }
13589+ }
13590+
13591+ if (HG(func_whitelist) != NULL) {
13592+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
13593+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
13594+ zend_bailout();
13595+ }
13596+ } else if (HG(func_blacklist) != NULL) {
13597+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
13598+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
13599+ zend_bailout();
13600+ }
13601+ }
13602+ }
13603+#endif
13604 FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1));
13605 zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(object).ptr, EX(ce));
13606 EX(object).ptr = NULL;
13607@@ -1782,6 +1867,7 @@
13608 efree(EX(Ts));
13609 }
13610 EG(in_execution) = EX(original_in_execution);
13611+ EG(in_code_type) = EX(original_in_code_type);
13612 EG(current_execute_data) = EX(prev_execute_data);
13613 return;
13614 }
13615@@ -2161,7 +2247,12 @@
13616 int dummy = 1;
13617 zend_file_handle file_handle = {0};
13618
13619+#if HARDENING_PATCH_INC_PROTECT
13620+ if (zend_is_valid_include(inc_filename)
13621+ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
13622+#else
13623 if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
13624+#endif
13625 && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) {
13626
13627 file_handle.filename = inc_filename->value.str.val;
13628@@ -2190,6 +2281,11 @@
13629 break;
13630 case ZEND_INCLUDE:
13631 case ZEND_REQUIRE:
13632+#if HARDENING_PATCH_INC_PROTECT
13633+ if (!zend_is_valid_include(inc_filename)) {
13634+ break;
13635+ }
13636+#endif
13637 new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
13638 break;
13639 case ZEND_EVAL: {
13640diff -Nura php-4.3.11/Zend/zend_execute_globals.h hardening-patch-4.3.11-0.4.2/Zend/zend_execute_globals.h
13641--- php-4.3.11/Zend/zend_execute_globals.h 2002-12-31 17:23:00.000000000 +0100
13642+++ hardening-patch-4.3.11-0.4.2/Zend/zend_execute_globals.h 2005-09-07 18:41:01.025093072 +0200
13643@@ -59,6 +59,8 @@
13644 object_info object;
13645 temp_variable *Ts;
13646 zend_bool original_in_execution;
13647+ zend_uint original_in_code_type;
13648+ zend_uint execute_depth;
13649 zend_op_array *op_array;
13650 struct _zend_execute_data *prev_execute_data;
13651 } zend_execute_data;
13652diff -Nura php-4.3.11/Zend/zend_extensions.c hardening-patch-4.3.11-0.4.2/Zend/zend_extensions.c
13653--- php-4.3.11/Zend/zend_extensions.c 2003-03-19 19:00:57.000000000 +0100
13654+++ hardening-patch-4.3.11-0.4.2/Zend/zend_extensions.c 2005-09-07 18:41:01.025093072 +0200
13655@@ -54,23 +54,44 @@
13656 return FAILURE;
13657 }
13658
13659+ /* check if module is compiled against Hardening-Patch */
13660+ if (extension_version_info->zend_extension_api_no < 1000000000) {
13661+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n"
13662+ "The Hardening-Patch version %d is installed.\n\n",
13663+ new_extension->name,
13664+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
13665+ DL_UNLOAD(handle);
13666+ return FAILURE;
13667+ }
13668+
13669+
13670+ /* check if module is compiled against correct Hardening-Patch version */
13671+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) {
13672+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n"
13673+ "The Hardening-Patch version %d is installed.\n\n",
13674+ new_extension->name,
13675+ extension_version_info->zend_extension_api_no,
13676+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
13677+ DL_UNLOAD(handle);
13678+ return FAILURE;
13679+ }
13680
13681 /* allow extension to proclaim compatibility with any Zend version */
13682- if (extension_version_info->zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
13683- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
13684+ if (extension_version_info->real_zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
13685+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) {
13686 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
13687 "The Zend Engine API version %d which is installed, is outdated.\n\n",
13688 new_extension->name,
13689- extension_version_info->zend_extension_api_no,
13690+ extension_version_info->real_zend_extension_api_no,
13691 ZEND_EXTENSION_API_NO);
13692 DL_UNLOAD(handle);
13693 return FAILURE;
13694- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
13695+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) {
13696 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
13697 "The Zend Engine API version %d which is installed, is newer.\n"
13698 "Contact %s at %s for a later version of %s.\n\n",
13699 new_extension->name,
13700- extension_version_info->zend_extension_api_no,
13701+ extension_version_info->real_zend_extension_api_no,
13702 ZEND_EXTENSION_API_NO,
13703 new_extension->author,
13704 new_extension->URL,
13705diff -Nura php-4.3.11/Zend/zend_extensions.h hardening-patch-4.3.11-0.4.2/Zend/zend_extensions.h
13706--- php-4.3.11/Zend/zend_extensions.h 2002-12-31 17:23:02.000000000 +0100
13707+++ hardening-patch-4.3.11-0.4.2/Zend/zend_extensions.h 2005-09-07 18:41:01.026092920 +0200
13708@@ -23,6 +23,9 @@
13709
13710 #include "zend_compile.h"
13711
13712+/* Create own API version number for Hardening-Patch */
13713+
13714+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1000050805
13715 #define ZEND_EXTENSION_API_NO 20021010
13716
13717 typedef struct _zend_extension_version_info {
13718@@ -30,6 +33,7 @@
13719 char *required_zend_version;
13720 unsigned char thread_safe;
13721 unsigned char debug;
13722+ int real_zend_extension_api_no;
13723 } zend_extension_version_info;
13724
13725
13726@@ -96,7 +100,7 @@
13727
13728
13729 #define ZEND_EXTENSION() \
13730- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
13731+ ZEND_EXT_API zend_extension_version_info extension_version_info = { HARDENING_PATCH_ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG, ZEND_EXTENSION_API_NO }
13732
13733 #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
13734 #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
13735diff -Nura php-4.3.11/Zend/zend_globals.h hardening-patch-4.3.11-0.4.2/Zend/zend_globals.h
13736--- php-4.3.11/Zend/zend_globals.h 2004-11-04 00:15:05.000000000 +0100
13737+++ hardening-patch-4.3.11-0.4.2/Zend/zend_globals.h 2005-09-07 18:41:01.026092920 +0200
13738@@ -163,6 +163,16 @@
13739
13740 int error_reporting;
13741 int orig_error_reporting;
13742+#if HARDENING_PATCH
13743+ int hphp_log_syslog;
13744+ int hphp_log_syslog_facility;
13745+ int hphp_log_syslog_priority;
13746+ int hphp_log_sapi;
13747+ int hphp_log_script;
13748+ char *hphp_log_scriptname;
13749+ zend_bool hphp_log_use_x_forwarded_for;
13750+ long hphp_executor_max_depth;
13751+#endif
13752 int exit_status;
13753
13754 zend_op_array *active_op_array;
13755@@ -176,6 +186,7 @@
13756 int ticks_count;
13757
13758 zend_bool in_execution;
13759+ zend_uint in_code_type;
13760 zend_bool bailout_set;
13761 zend_bool full_tables_cleanup;
13762
13763diff -Nura php-4.3.11/Zend/zend.h hardening-patch-4.3.11-0.4.2/Zend/zend.h
13764--- php-4.3.11/Zend/zend.h 2005-01-25 14:08:41.000000000 +0100
13765+++ hardening-patch-4.3.11-0.4.2/Zend/zend.h 2005-09-07 18:41:01.027092768 +0200
13766@@ -275,9 +275,10 @@
13767 struct _zval_struct {
13768 /* Variable information */
13769 zvalue_value value; /* value */
13770+ zend_uint refcount;
13771+ zend_ushort flags;
13772 zend_uchar type; /* active type */
13773 zend_uchar is_ref;
13774- zend_ushort refcount;
13775 };
13776
13777
13778@@ -338,6 +339,12 @@
13779 void (*ticks_function)(int ticks);
13780 void (*on_timeout)(int seconds TSRMLS_DC);
13781 zend_bool (*open_function)(const char *filename, struct _zend_file_handle *);
13782+#if HARDENING_PATCH
13783+ void (*security_log_function)(int loglevel, char *fmt, ...);
13784+#endif
13785+#if HARDENING_PATCH_INC_PROTECT
13786+ int (*is_valid_include)(zval *z);
13787+#endif
13788 } zend_utility_functions;
13789
13790
13791@@ -469,7 +476,16 @@
13792 extern ZEND_API void (*zend_ticks_function)(int ticks);
13793 extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0);
13794 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
13795+#if HARDENING_PATCH
13796+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
13797+#endif
13798+#if HARDENING_PATCH_INC_PROTECT
13799+extern ZEND_API int (*zend_is_valid_include)(zval *z);
13800+#endif
13801
13802+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
13803+ZEND_API unsigned int zend_canary(void);
13804+#endif
13805
13806 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3);
13807
13808@@ -576,6 +592,11 @@
13809
13810 #define ZEND_MAX_RESERVED_RESOURCES 4
13811
13812+#if HARDENING_PATCH
13813+#include "hardened_globals.h"
13814+#include "php_syslog.h"
13815+#endif
13816+
13817 #endif /* ZEND_H */
13818
13819 /*
13820diff -Nura php-4.3.11/Zend/zend_hash.c hardening-patch-4.3.11-0.4.2/Zend/zend_hash.c
13821--- php-4.3.11/Zend/zend_hash.c 2004-07-12 23:26:46.000000000 +0200
13822+++ hardening-patch-4.3.11-0.4.2/Zend/zend_hash.c 2005-09-07 18:41:01.028092616 +0200
13823@@ -26,6 +26,17 @@
13824 # include <stdlib.h>
13825 #endif
13826
13827+#if HARDENING_PATCH_HASH_PROTECT
13828+ unsigned int zend_hash_canary = 0x1234567;
13829+ zend_bool zend_hash_canary_inited = 0;
13830+#endif
13831+
13832+#define CHECK_HASH_CANARY(hash) \
13833+ if (zend_hash_canary != (hash)->canary) { \
13834+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
13835+ exit(1); \
13836+ }
13837+
13838 #define HANDLE_NUMERIC(key, length, func) { \
13839 register char *tmp=key; \
13840 \
13841@@ -175,6 +186,9 @@
13842 {
13843 uint i = 3;
13844 Bucket **tmp;
13845+#if HARDENING_PATCH_HASH_PROTECT
13846+ TSRMLS_FETCH();
13847+#endif
13848
13849 SET_INCONSISTENT(HT_OK);
13850
13851@@ -184,6 +198,13 @@
13852
13853 ht->nTableSize = 1 << i;
13854 ht->nTableMask = ht->nTableSize - 1;
13855+#if HARDENING_PATCH_HASH_PROTECT
13856+ if (zend_hash_canary_inited==0) {
13857+ zend_hash_canary = zend_canary();
13858+ zend_hash_canary_inited = 1;
13859+ }
13860+ ht->canary = zend_hash_canary;
13861+#endif
13862 ht->pDestructor = pDestructor;
13863 ht->pListHead = NULL;
13864 ht->pListTail = NULL;
13865@@ -259,6 +280,9 @@
13866 }
13867 #endif
13868 if (ht->pDestructor) {
13869+#if HARDENING_PATCH_HASH_PROTECT
13870+ CHECK_HASH_CANARY(ht);
13871+#endif
13872 ht->pDestructor(p->pData);
13873 }
13874 UPDATE_DATA(ht, p, pData, nDataSize);
13875@@ -327,6 +351,9 @@
13876 }
13877 #endif
13878 if (ht->pDestructor) {
13879+#if HARDENING_PATCH_HASH_PROTECT
13880+ CHECK_HASH_CANARY(ht);
13881+#endif
13882 ht->pDestructor(p->pData);
13883 }
13884 UPDATE_DATA(ht, p, pData, nDataSize);
13885@@ -402,6 +429,9 @@
13886 }
13887 #endif
13888 if (ht->pDestructor) {
13889+#if HARDENING_PATCH_HASH_PROTECT
13890+ CHECK_HASH_CANARY(ht);
13891+#endif
13892 ht->pDestructor(p->pData);
13893 }
13894 UPDATE_DATA(ht, p, pData, nDataSize);
13895@@ -450,7 +480,7 @@
13896 IS_CONSISTENT(ht);
13897
13898 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
13899- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
13900+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
13901 if (t) {
13902 HANDLE_BLOCK_INTERRUPTIONS();
13903 ht->arBuckets = t;
13904@@ -460,6 +490,7 @@
13905 HANDLE_UNBLOCK_INTERRUPTIONS();
13906 return SUCCESS;
13907 }
13908+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
13909 return FAILURE;
13910 }
13911 return SUCCESS;
13912@@ -524,6 +555,9 @@
13913 ht->pInternalPointer = p->pListNext;
13914 }
13915 if (ht->pDestructor) {
13916+#if HARDENING_PATCH_HASH_PROTECT
13917+ CHECK_HASH_CANARY(ht);
13918+#endif
13919 ht->pDestructor(p->pData);
13920 }
13921 if (!p->pDataPtr) {
13922@@ -553,6 +587,9 @@
13923 q = p;
13924 p = p->pListNext;
13925 if (ht->pDestructor) {
13926+#if HARDENING_PATCH_HASH_PROTECT
13927+ CHECK_HASH_CANARY(ht);
13928+#endif
13929 ht->pDestructor(q->pData);
13930 }
13931 if (!q->pDataPtr && q->pData) {
13932@@ -579,6 +616,9 @@
13933 q = p;
13934 p = p->pListNext;
13935 if (ht->pDestructor) {
13936+#if HARDENING_PATCH_HASH_PROTECT
13937+ CHECK_HASH_CANARY(ht);
13938+#endif
13939 ht->pDestructor(q->pData);
13940 }
13941 if (!q->pDataPtr && q->pData) {
13942@@ -608,6 +648,9 @@
13943 HANDLE_BLOCK_INTERRUPTIONS();
13944
13945 if (ht->pDestructor) {
13946+#if HARDENING_PATCH_HASH_PROTECT
13947+ CHECK_HASH_CANARY(ht);
13948+#endif
13949 ht->pDestructor(p->pData);
13950 }
13951 if (!p->pDataPtr) {
13952diff -Nura php-4.3.11/Zend/zend_hash.h hardening-patch-4.3.11-0.4.2/Zend/zend_hash.h
13953--- php-4.3.11/Zend/zend_hash.h 2002-12-31 17:23:03.000000000 +0100
13954+++ hardening-patch-4.3.11-0.4.2/Zend/zend_hash.h 2005-09-07 18:41:01.028092616 +0200
13955@@ -54,6 +54,9 @@
13956 } Bucket;
13957
13958 typedef struct _hashtable {
13959+#if HARDENING_PATCH_HASH_PROTECT
13960+ unsigned int canary;
13961+#endif
13962 uint nTableSize;
13963 uint nTableMask;
13964 uint nNumOfElements;
13965diff -Nura php-4.3.11/Zend/zend_ini.h hardening-patch-4.3.11-0.4.2/Zend/zend_ini.h
13966--- php-4.3.11/Zend/zend_ini.h 2005-01-09 18:00:16.000000000 +0100
13967+++ hardening-patch-4.3.11-0.4.2/Zend/zend_ini.h 2005-09-07 18:41:01.029092464 +0200
13968@@ -174,6 +174,7 @@
13969 /* Standard message handlers */
13970 BEGIN_EXTERN_C()
13971 ZEND_API ZEND_INI_MH(OnUpdateBool);
13972+#define OnUpdateLong OnUpdateInt
13973 ZEND_API ZEND_INI_MH(OnUpdateInt);
13974 ZEND_API ZEND_INI_MH(OnUpdateReal);
13975 ZEND_API ZEND_INI_MH(OnUpdateString);
13976diff -Nura php-4.3.11/Zend/zend_language_scanner.l hardening-patch-4.3.11-0.4.2/Zend/zend_language_scanner.l
13977--- php-4.3.11/Zend/zend_language_scanner.l 2005-03-09 16:07:19.000000000 +0100
13978+++ hardening-patch-4.3.11-0.4.2/Zend/zend_language_scanner.l 2005-09-07 18:41:01.033091856 +0200
13979@@ -393,6 +393,13 @@
13980 compilation_successful=0;
13981 } else {
13982 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
13983+#if HARDENING_PATCH
13984+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
13985+ op_array->created_by_eval = 1;
13986+ } else {
13987+ op_array->created_by_eval = 0;
13988+ }
13989+#endif
13990 CG(in_compilation) = 1;
13991 CG(active_op_array) = op_array;
13992 compiler_result = zendparse(TSRMLS_C);
13993diff -Nura php-4.3.11/Zend/zend_language_scanner.c hardening-patch-4.3.11-0.4.2/Zend/zend_language_scanner.c
13994--- php-4.3.11/Zend/zend_language_scanner.c 2005-03-30 16:35:47.000000000 +0200
13995+++ hardening-patch-4.3.11-0.4.2/Zend/zend_language_scanner.c 2005-09-07 18:41:01.031092160 +0200
13996@@ -3121,6 +3121,13 @@
13997 compilation_successful=0;
13998 } else {
13999 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
14000+#if HARDENING_PATCH
14001+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
14002+ op_array->created_by_eval = 1;
14003+ } else {
14004+ op_array->created_by_eval = 0;
14005+ }
14006+#endif
14007 CG(in_compilation) = 1;
14008 CG(active_op_array) = op_array;
14009 compiler_result = zendparse(TSRMLS_C);
14010diff -Nura php-4.3.11/Zend/zend_llist.c hardening-patch-4.3.11-0.4.2/Zend/zend_llist.c
14011--- php-4.3.11/Zend/zend_llist.c 2002-12-31 17:23:04.000000000 +0100
14012+++ hardening-patch-4.3.11-0.4.2/Zend/zend_llist.c 2005-09-07 18:41:01.034091704 +0200
14013@@ -21,9 +21,34 @@
14014 #include "zend.h"
14015 #include "zend_llist.h"
14016 #include "zend_qsort.h"
14017+#include "zend_globals.h"
14018+
14019+#define CHECK_LIST_CANARY(list) \
14020+ if (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t) { \
14021+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
14022+ exit(1); \
14023+ }
14024+
14025+#define CHECK_LISTELEMENT_CANARY(elem) \
14026+ if (HG(canary_3) != (elem)->canary) { \
14027+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
14028+ exit(1); \
14029+ }
14030+
14031
14032 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
14033 {
14034+#if HARDENING_PATCH_LL_PROTECT
14035+ TSRMLS_FETCH();
14036+
14037+ if (!HG(ll_canary_inited)) {
14038+ HG(canary_3) = zend_canary();
14039+ HG(canary_4) = zend_canary();
14040+ HG(ll_canary_inited) = 1;
14041+ }
14042+ l->canary_h = HG(canary_3);
14043+ l->canary_t = HG(canary_4);
14044+#endif
14045 l->head = NULL;
14046 l->tail = NULL;
14047 l->count = 0;
14048@@ -37,6 +62,11 @@
14049 {
14050 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
14051
14052+#if HARDENING_PATCH_LL_PROTECT
14053+ TSRMLS_FETCH();
14054+ CHECK_LIST_CANARY(l)
14055+ tmp->canary = HG(canary_3);
14056+#endif
14057 tmp->prev = l->tail;
14058 tmp->next = NULL;
14059 if (l->tail) {
14060@@ -55,6 +85,11 @@
14061 {
14062 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
14063
14064+#if HARDENING_PATCH_LL_PROTECT
14065+ TSRMLS_FETCH();
14066+ CHECK_LIST_CANARY(l)
14067+ tmp->canary = HG(canary_3);
14068+#endif
14069 tmp->next = l->head;
14070 tmp->prev = NULL;
14071 if (l->head) {
14072@@ -91,10 +126,20 @@
14073 zend_llist_element *current=l->head;
14074 zend_llist_element *next;
14075
14076+#if HARDENING_PATCH_LL_PROTECT
14077+ TSRMLS_FETCH();
14078+ CHECK_LIST_CANARY(l)
14079+#endif
14080 while (current) {
14081+#if HARDENING_PATCH_LL_PROTECT
14082+ CHECK_LISTELEMENT_CANARY(current)
14083+#endif
14084 next = current->next;
14085 if (compare(current->data, element)) {
14086 DEL_LLIST_ELEMENT(current, l);
14087+#if HARDENING_PATCH_LL_PROTECT
14088+ current->canary = 0;
14089+#endif
14090 break;
14091 }
14092 current = next;
14093@@ -106,7 +151,14 @@
14094 {
14095 zend_llist_element *current=l->head, *next;
14096
14097+#if HARDENING_PATCH_LL_PROTECT
14098+ TSRMLS_FETCH();
14099+ CHECK_LIST_CANARY(l)
14100+#endif
14101 while (current) {
14102+#if HARDENING_PATCH_LL_PROTECT
14103+ CHECK_LISTELEMENT_CANARY(current)
14104+#endif
14105 next = current->next;
14106 if (l->dtor) {
14107 l->dtor(current->data);
14108@@ -131,7 +183,14 @@
14109 zend_llist_element *old_tail;
14110 void *data;
14111
14112+#if HARDENING_PATCH_LL_PROTECT
14113+ TSRMLS_FETCH();
14114+ CHECK_LIST_CANARY(l)
14115+#endif
14116 if ((old_tail = l->tail)) {
14117+#if HARDENING_PATCH_LL_PROTECT
14118+ CHECK_LISTELEMENT_CANARY(old_tail)
14119+#endif
14120 if (l->tail->prev) {
14121 l->tail->prev->next = NULL;
14122 }
14123@@ -157,9 +216,16 @@
14124 {
14125 zend_llist_element *ptr;
14126
14127+#if HARDENING_PATCH_LL_PROTECT
14128+ TSRMLS_FETCH();
14129+ CHECK_LIST_CANARY(src)
14130+#endif
14131 zend_llist_init(dst, src->size, src->dtor, src->persistent);
14132 ptr = src->head;
14133 while (ptr) {
14134+#if HARDENING_PATCH_LL_PROTECT
14135+ CHECK_LISTELEMENT_CANARY(ptr)
14136+#endif
14137 zend_llist_add_element(dst, ptr->data);
14138 ptr = ptr->next;
14139 }
14140@@ -170,11 +236,21 @@
14141 {
14142 zend_llist_element *element, *next;
14143
14144+#if HARDENING_PATCH_LL_PROTECT
14145+ TSRMLS_FETCH();
14146+ CHECK_LIST_CANARY(l)
14147+#endif
14148 element=l->head;
14149 while (element) {
14150+#if HARDENING_PATCH_LL_PROTECT
14151+ CHECK_LISTELEMENT_CANARY(element)
14152+#endif
14153 next = element->next;
14154 if (func(element->data)) {
14155 DEL_LLIST_ELEMENT(element, l);
14156+#if HARDENING_PATCH_LL_PROTECT
14157+ element->canary = 0;
14158+#endif
14159 }
14160 element = next;
14161 }
14162@@ -185,7 +261,13 @@
14163 {
14164 zend_llist_element *element;
14165
14166+#if HARDENING_PATCH_LL_PROTECT
14167+ CHECK_LIST_CANARY(l)
14168+#endif
14169 for (element=l->head; element; element=element->next) {
14170+#if HARDENING_PATCH_LL_PROTECT
14171+ CHECK_LISTELEMENT_CANARY(element)
14172+#endif
14173 func(element->data TSRMLS_CC);
14174 }
14175 }
14176@@ -197,6 +279,9 @@
14177 zend_llist_element **elements;
14178 zend_llist_element *element, **ptr;
14179
14180+#if HARDENING_PATCH_LL_PROTECT
14181+ CHECK_LIST_CANARY(l)
14182+#endif
14183 if (l->count <= 0) {
14184 return;
14185 }
14186@@ -206,6 +291,9 @@
14187 ptr = &elements[0];
14188
14189 for (element=l->head; element; element=element->next) {
14190+#if HARDENING_PATCH_LL_PROTECT
14191+ CHECK_LISTELEMENT_CANARY(element)
14192+#endif
14193 *ptr++ = element;
14194 }
14195
14196@@ -228,7 +316,13 @@
14197 {
14198 zend_llist_element *element;
14199
14200+#if HARDENING_PATCH_LL_PROTECT
14201+ CHECK_LIST_CANARY(l)
14202+#endif
14203 for (element=l->head; element; element=element->next) {
14204+#if HARDENING_PATCH_LL_PROTECT
14205+ CHECK_LISTELEMENT_CANARY(element)
14206+#endif
14207 func(element->data, arg TSRMLS_CC);
14208 }
14209 }
14210@@ -239,8 +333,14 @@
14211 zend_llist_element *element;
14212 va_list args;
14213
14214+#if HARDENING_PATCH_LL_PROTECT
14215+ CHECK_LIST_CANARY(l)
14216+#endif
14217 va_start(args, num_args);
14218 for (element=l->head; element; element=element->next) {
14219+#if HARDENING_PATCH_LL_PROTECT
14220+ CHECK_LISTELEMENT_CANARY(element)
14221+#endif
14222 func(element->data, num_args, args TSRMLS_CC);
14223 }
14224 va_end(args);
14225@@ -249,6 +349,10 @@
14226
14227 ZEND_API int zend_llist_count(zend_llist *l)
14228 {
14229+#if HARDENING_PATCH_LL_PROTECT
14230+ TSRMLS_FETCH();
14231+ CHECK_LIST_CANARY(l)
14232+#endif
14233 return l->count;
14234 }
14235
14236@@ -256,8 +360,15 @@
14237 {
14238 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
14239
14240+#if HARDENING_PATCH_LL_PROTECT
14241+ TSRMLS_FETCH();
14242+ CHECK_LIST_CANARY(l)
14243+#endif
14244 *current = l->head;
14245 if (*current) {
14246+#if HARDENING_PATCH_LL_PROTECT
14247+ CHECK_LISTELEMENT_CANARY(*current)
14248+#endif
14249 return (*current)->data;
14250 } else {
14251 return NULL;
14252@@ -269,8 +380,15 @@
14253 {
14254 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
14255
14256+#if HARDENING_PATCH_LL_PROTECT
14257+ TSRMLS_FETCH();
14258+ CHECK_LIST_CANARY(l)
14259+#endif
14260 *current = l->tail;
14261 if (*current) {
14262+#if HARDENING_PATCH_LL_PROTECT
14263+ CHECK_LISTELEMENT_CANARY(*current)
14264+#endif
14265 return (*current)->data;
14266 } else {
14267 return NULL;
14268@@ -282,9 +400,19 @@
14269 {
14270 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
14271
14272+#if HARDENING_PATCH_LL_PROTECT
14273+ TSRMLS_FETCH();
14274+ CHECK_LIST_CANARY(l)
14275+#endif
14276 if (*current) {
14277+#if HARDENING_PATCH_LL_PROTECT
14278+ CHECK_LISTELEMENT_CANARY(*current)
14279+#endif
14280 *current = (*current)->next;
14281 if (*current) {
14282+#if HARDENING_PATCH_LL_PROTECT
14283+ CHECK_LISTELEMENT_CANARY(*current)
14284+#endif
14285 return (*current)->data;
14286 }
14287 }
14288@@ -296,9 +424,19 @@
14289 {
14290 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
14291
14292+#if HARDENING_PATCH_LL_PROTECT
14293+ TSRMLS_FETCH();
14294+ CHECK_LIST_CANARY(l)
14295+#endif
14296 if (*current) {
14297+#if HARDENING_PATCH_LL_PROTECT
14298+ CHECK_LISTELEMENT_CANARY(*current)
14299+#endif
14300 *current = (*current)->prev;
14301 if (*current) {
14302+#if HARDENING_PATCH_LL_PROTECT
14303+ CHECK_LISTELEMENT_CANARY(*current)
14304+#endif
14305 return (*current)->data;
14306 }
14307 }
14308diff -Nura php-4.3.11/Zend/zend_llist.h hardening-patch-4.3.11-0.4.2/Zend/zend_llist.h
14309--- php-4.3.11/Zend/zend_llist.h 2002-12-31 17:23:04.000000000 +0100
14310+++ hardening-patch-4.3.11-0.4.2/Zend/zend_llist.h 2005-09-07 18:41:01.034091704 +0200
14311@@ -24,6 +24,9 @@
14312 #include <stdlib.h>
14313
14314 typedef struct _zend_llist_element {
14315+#if HARDENING_PATCH_LL_PROTECT
14316+ unsigned int canary;
14317+#endif
14318 struct _zend_llist_element *next;
14319 struct _zend_llist_element *prev;
14320 char data[1]; /* Needs to always be last in the struct */
14321@@ -36,6 +39,9 @@
14322 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
14323
14324 typedef struct _zend_llist {
14325+#if HARDENING_PATCH_LL_PROTECT
14326+ unsigned int canary_h; /* head */
14327+#endif
14328 zend_llist_element *head;
14329 zend_llist_element *tail;
14330 size_t size;
14331@@ -43,6 +49,9 @@
14332 llist_dtor_func_t dtor;
14333 unsigned char persistent;
14334 zend_llist_element *traverse_ptr;
14335+#if HARDENING_PATCH_LL_PROTECT
14336+ unsigned int canary_t; /* tail */
14337+#endif
14338 } zend_llist;
14339
14340 typedef zend_llist_element* zend_llist_position;
14341diff -Nura php-4.3.11/Zend/zend_modules.h hardening-patch-4.3.11-0.4.2/Zend/zend_modules.h
14342--- php-4.3.11/Zend/zend_modules.h 2002-12-31 17:23:04.000000000 +0100
14343+++ hardening-patch-4.3.11-0.4.2/Zend/zend_modules.h 2005-09-07 18:41:01.034091704 +0200
14344@@ -34,6 +34,7 @@
14345 ZEND_API extern unsigned char second_arg_force_ref[];
14346 ZEND_API extern unsigned char third_arg_force_ref[];
14347
14348+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1000050805
14349 #define ZEND_MODULE_API_NO 20020429
14350 #ifdef ZTS
14351 #define USING_ZTS 1
14352@@ -41,9 +42,9 @@
14353 #define USING_ZTS 0
14354 #endif
14355
14356-#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
14357+#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
14358
14359-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0
14360+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO
14361
14362 #define STANDARD_MODULE_PROPERTIES \
14363 NULL, NULL, STANDARD_MODULE_PROPERTIES_EX
14364@@ -75,6 +76,7 @@
14365 unsigned char type;
14366 void *handle;
14367 int module_number;
14368+ unsigned int real_zend_api;
14369 };
14370
14371
14372diff -Nura php-4.3.11/Zend/zend_opcode.c hardening-patch-4.3.11-0.4.2/Zend/zend_opcode.c
14373--- php-4.3.11/Zend/zend_opcode.c 2002-12-31 17:23:04.000000000 +0100
14374+++ hardening-patch-4.3.11-0.4.2/Zend/zend_opcode.c 2005-09-07 18:41:01.035091552 +0200
14375@@ -88,6 +88,9 @@
14376 op_array->done_pass_two = 0;
14377
14378 op_array->start_op = NULL;
14379+#if HARDENING_PATCH
14380+ op_array->created_by_eval = 0;
14381+#endif
14382
14383 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
14384 }
14385diff -Nura php-4.3.11/Zend/zend_operators.c hardening-patch-4.3.11-0.4.2/Zend/zend_operators.c
14386--- php-4.3.11/Zend/zend_operators.c 2004-11-29 10:15:28.000000000 +0100
14387+++ hardening-patch-4.3.11-0.4.2/Zend/zend_operators.c 2005-09-07 18:41:01.036091400 +0200
14388@@ -1575,6 +1575,20 @@
14389 return (op->value.lval ? 1 : 0);
14390 }
14391
14392+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length)
14393+{
14394+ register unsigned char *str = (unsigned char*)source;
14395+ register unsigned char *result = (unsigned char*)dest;
14396+ register unsigned char *end = str + length;
14397+
14398+ while (str < end) {
14399+ *result++ = tolower((int)*str++);
14400+ }
14401+ *result = *end;
14402+
14403+ return dest;
14404+}
14405+
14406 ZEND_API void zend_str_tolower(char *str, unsigned int length)
14407 {
14408 register char *p=str, *end=p+length;
14409diff -Nura php-4.3.11/Zend/zend_operators.h hardening-patch-4.3.11-0.4.2/Zend/zend_operators.h
14410--- php-4.3.11/Zend/zend_operators.h 2005-03-15 16:49:29.000000000 +0100
14411+++ hardening-patch-4.3.11-0.4.2/Zend/zend_operators.h 2005-09-07 18:41:01.036091400 +0200
14412@@ -171,6 +171,14 @@
14413 ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
14414
14415 ZEND_API void zend_str_tolower(char *str, unsigned int length);
14416+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length);
14417+
14418+static inline char *
14419+zend_str_tolower_dup(const char *source, unsigned int length)
14420+{
14421+ return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
14422+}
14423+
14424 ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
14425 ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
14426 ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2);