summaryrefslogtreecommitdiff
path: root/0.4.2/hardening-patch-4.4.0-0.4.2.patch
diff options
context:
space:
mode:
Diffstat (limited to '0.4.2/hardening-patch-4.4.0-0.4.2.patch')
-rw-r--r--0.4.2/hardening-patch-4.4.0-0.4.2.patch14668
1 files changed, 14668 insertions, 0 deletions
diff --git a/0.4.2/hardening-patch-4.4.0-0.4.2.patch b/0.4.2/hardening-patch-4.4.0-0.4.2.patch
new file mode 100644
index 0000000..51aef54
--- /dev/null
+++ b/0.4.2/hardening-patch-4.4.0-0.4.2.patch
@@ -0,0 +1,14668 @@
1diff -Nura php-4.4.0/acinclude.m4 hardening-patch-4.4.0-0.4.2/acinclude.m4
2--- php-4.4.0/acinclude.m4 2005-04-30 11:31:09.000000000 +0200
3+++ hardening-patch-4.4.0-0.4.2/acinclude.m4 2005-09-07 18:40:29.039955552 +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.4.0/configure hardening-patch-4.4.0-0.4.2/configure
42--- php-4.4.0/configure 2005-07-11 12:07:33.000000000 +0200
43+++ hardening-patch-4.4.0-0.4.2/configure 2005-09-07 18:45:59.447725936 +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@@ -2682,6 +2694,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@@ -15733,6 +15896,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:15738: checking for declared timezone" >&5
290 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
291@@ -83268,7 +83487,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@@ -83933,7 +84152,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@@ -83988,7 +84207,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@@ -84073,7 +84292,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@@ -84125,7 +84344,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@@ -87305,6 +87524,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@@ -99988,7 +100466,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@@ -100161,7 +100639,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.4.0/configure.in hardening-patch-4.4.0-0.4.2/configure.in
621--- php-4.4.0/configure.in 2005-07-11 09:45:09.000000000 +0200
622+++ hardening-patch-4.4.0-0.4.2/configure.in 2005-09-07 18:40:29.076949928 +0200
623@@ -238,7 +238,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@@ -612,6 +612,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@@ -1241,7 +1242,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@@ -1254,7 +1255,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.4.0/ext/fbsql/php_fbsql.c hardening-patch-4.4.0-0.4.2/ext/fbsql/php_fbsql.c
659--- php-4.4.0/ext/fbsql/php_fbsql.c 2005-02-09 20:33:32.000000000 +0100
660+++ hardening-patch-4.4.0-0.4.2/ext/fbsql/php_fbsql.c 2005-09-07 18:40:29.078949624 +0200
661@@ -1797,8 +1797,24 @@
662 }
663 else if (fbcmdErrorsFound(md))
664 {
665+#if HARDENING_PATCH
666+ char* query_copy;
667+ int i;
668+#endif
669 FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
670 char* emg = fbcemdAllErrorMessages(emd);
671+#if HARDENING_PATCH
672+ query_copy=estrdup(query_copy);
673+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
674+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
675+ efree(query_copy);
676+ if (HG(hphp_sql_bailout_on_error)) {
677+ free(emg);
678+ fbcemdRelease(emd);
679+ result = 0;
680+ zend_bailout();
681+ }
682+#endif
683 if (FB_SQL_G(generateWarnings))
684 {
685 if (emg)
686diff -Nura php-4.4.0/ext/mbstring/mbstring.c hardening-patch-4.4.0-0.4.2/ext/mbstring/mbstring.c
687--- php-4.4.0/ext/mbstring/mbstring.c 2005-02-21 09:03:47.000000000 +0100
688+++ hardening-patch-4.4.0-0.4.2/ext/mbstring/mbstring.c 2005-09-07 18:40:29.080949320 +0200
689@@ -1487,6 +1487,7 @@
690 char *strtok_buf = NULL, **val_list;
691 zval *array_ptr = (zval *) arg;
692 int n, num, val_len, *len_list;
693+ unsigned int new_val_len;
694 enum mbfl_no_encoding from_encoding;
695 mbfl_string string, resvar, resval;
696 mbfl_encoding_detector *identd = NULL;
697@@ -1609,8 +1610,14 @@
698 val_len = len_list[n];
699 }
700 n++;
701- /* add variable to symbol table */
702- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
703+ /* we need val to be emalloc()ed */
704+ val = estrndup(val, val_len);
705+ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) {
706+ /* add variable to symbol table */
707+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
708+ }
709+ efree(val);
710+
711 if (convd != NULL){
712 mbfl_string_clear(&resvar);
713 mbfl_string_clear(&resval);
714diff -Nura php-4.4.0/ext/mysql/php_mysql.c hardening-patch-4.4.0-0.4.2/ext/mysql/php_mysql.c
715--- php-4.4.0/ext/mysql/php_mysql.c 2005-04-08 00:23:01.000000000 +0200
716+++ hardening-patch-4.4.0-0.4.2/ext/mysql/php_mysql.c 2005-09-07 18:40:29.082949016 +0200
717@@ -1218,6 +1218,8 @@
718 {
719 php_mysql_conn *mysql;
720 MYSQL_RES *mysql_result;
721+ char *copy_query;
722+ int i;
723
724 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
725
726@@ -1268,6 +1270,13 @@
727 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
728 }
729 }
730+ copy_query = estrdup(Z_STRVAL_PP(query));
731+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
732+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
733+ efree(copy_query);
734+ if (HG(hphp_sql_bailout_on_error)) {
735+ zend_bailout();
736+ }
737 RETURN_FALSE;
738 }
739 #else
740@@ -1275,12 +1284,20 @@
741 /* check possible error */
742 if (MySG(trace_mode)){
743 if (mysql_errno(&mysql->conn)){
744- php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, mysql_error(&mysql->conn));
745+ php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
746 }
747 }
748+ copy_query = estrdup(Z_STRVAL_PP(query));
749+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
750+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
751+ efree(copy_query);
752+ if (HG(hphp_sql_bailout_on_error)) {
753+ zend_bailout();
754+ }
755 RETURN_FALSE;
756 }
757 #endif
758+
759 if(use_store == MYSQL_USE_RESULT) {
760 mysql_result=mysql_use_result(&mysql->conn);
761 } else {
762diff -Nura php-4.4.0/ext/pgsql/pgsql.c hardening-patch-4.4.0-0.4.2/ext/pgsql/pgsql.c
763--- php-4.4.0/ext/pgsql/pgsql.c 2005-07-05 14:50:03.000000000 +0200
764+++ hardening-patch-4.4.0-0.4.2/ext/pgsql/pgsql.c 2005-09-07 18:40:29.084948712 +0200
765@@ -1001,10 +1001,28 @@
766 case PGRES_EMPTY_QUERY:
767 case PGRES_BAD_RESPONSE:
768 case PGRES_NONFATAL_ERROR:
769- case PGRES_FATAL_ERROR:
770- PHP_PQ_ERROR("Query failed: %s", pgsql);
771- PQclear(pgsql_result);
772- RETURN_FALSE;
773+ case PGRES_FATAL_ERROR:
774+ {
775+#if HARDENING_PATCH
776+ int i;
777+ char *query_copy;
778+#endif
779+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
780+ PQclear(pgsql_result);
781+#if HARDENING_PATCH
782+ query_copy = estrdup(Z_STRVAL_PP(query));
783+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
784+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy);
785+ efree(query_copy);
786+ if (HG(hphp_sql_bailout_on_error)) {
787+ efree(msgbuf);
788+ zend_bailout();
789+ }
790+#endif
791+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf);
792+ efree(msgbuf);
793+ RETURN_FALSE;
794+ }
795 break;
796 case PGRES_COMMAND_OK: /* successful command that did not return rows */
797 default:
798diff -Nura php-4.4.0/ext/standard/array.c hardening-patch-4.4.0-0.4.2/ext/standard/array.c
799--- php-4.4.0/ext/standard/array.c 2005-06-21 14:11:19.000000000 +0200
800+++ hardening-patch-4.4.0-0.4.2/ext/standard/array.c 2005-09-07 18:40:29.086948408 +0200
801@@ -1162,6 +1162,32 @@
802 }
803 }
804 }
805+
806+ if (var_name[0] == 'H') {
807+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
808+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
809+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
810+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
811+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
812+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
813+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
814+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
815+ return 0;
816+ }
817+ } else if (var_name[0] == '_') {
818+ if ((strcmp(var_name, "_COOKIE")==0)||
819+ (strcmp(var_name, "_ENV")==0)||
820+ (strcmp(var_name, "_FILES")==0)||
821+ (strcmp(var_name, "_GET")==0)||
822+ (strcmp(var_name, "_POST")==0)||
823+ (strcmp(var_name, "_REQUEST")==0)||
824+ (strcmp(var_name, "_SESSION")==0)||
825+ (strcmp(var_name, "_SERVER")==0)) {
826+ return 0;
827+ }
828+ } else if (strcmp(var_name, "GLOBALS")==0) {
829+ return 0;
830+ }
831
832 return 1;
833 }
834diff -Nura php-4.4.0/ext/standard/basic_functions.c hardening-patch-4.4.0-0.4.2/ext/standard/basic_functions.c
835--- php-4.4.0/ext/standard/basic_functions.c 2005-05-16 10:55:31.000000000 +0200
836+++ hardening-patch-4.4.0-0.4.2/ext/standard/basic_functions.c 2005-09-07 18:58:15.014902728 +0200
837@@ -118,12 +118,14 @@
838 typedef struct _php_shutdown_function_entry {
839 zval **arguments;
840 int arg_count;
841+ zend_bool created_by_eval;
842 } php_shutdown_function_entry;
843
844 typedef struct _user_tick_function_entry {
845 zval **arguments;
846 int arg_count;
847 int calling;
848+ zend_bool created_by_eval;
849 } user_tick_function_entry;
850
851 /* some prototypes for local functions */
852@@ -306,6 +308,8 @@
853 PHP_FE(get_html_translation_table, NULL)
854 PHP_FE(sha1, NULL)
855 PHP_FE(sha1_file, NULL)
856+ PHP_FE(sha256, NULL)
857+ PHP_FE(sha256_file, NULL)
858 PHP_NAMED_FE(md5,php_if_md5, NULL)
859 PHP_NAMED_FE(md5_file,php_if_md5_file, NULL)
860 PHP_NAMED_FE(crc32,php_if_crc32, NULL)
861@@ -687,7 +691,7 @@
862 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
863
864 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
865- PHP_FE(realpath, NULL)
866+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
867 #endif
868
869 #ifdef HAVE_FNMATCH
870@@ -2104,6 +2108,13 @@
871 {
872 zval retval;
873 char *function_name = NULL;
874+#if HARDENING_PATCH
875+ zend_uint orig_code_type = EG(in_code_type);
876+
877+ if (shutdown_function_entry->created_by_eval) {
878+ EG(in_code_type) = ZEND_EVAL_CODE;
879+ }
880+#endif
881
882 if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) {
883 php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name);
884@@ -2119,6 +2130,9 @@
885 if (function_name) {
886 efree(function_name);
887 }
888+#if HARDENING_PATCH
889+ EG(in_code_type) = orig_code_type;
890+#endif
891 return 0;
892 }
893
894@@ -2126,6 +2140,13 @@
895 {
896 zval retval;
897 zval *function = tick_fe->arguments[0];
898+#if HARDENING_PATCH
899+ zend_uint orig_code_type = EG(in_code_type);
900+
901+ if (tick_fe->created_by_eval) {
902+ EG(in_code_type) = ZEND_EVAL_CODE;
903+ }
904+#endif
905
906 /* Prevent reentrant calls to the same user ticks function */
907 if (! tick_fe->calling) {
908@@ -2157,6 +2178,9 @@
909
910 tick_fe->calling = 0;
911 }
912+#if HARDENING_PATCH
913+ EG(in_code_type) = orig_code_type;
914+#endif
915 }
916
917 static void run_user_tick_functions(int tick_count)
918@@ -2224,6 +2248,13 @@
919 if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
920 RETURN_FALSE;
921 }
922+#if HARDENING_PATCH
923+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
924+ shutdown_function_entry.created_by_eval = 1;
925+ } else {
926+ shutdown_function_entry.created_by_eval = 0;
927+ }
928+#endif
929
930 /* Prevent entering of anything but valid callback (syntax check only!) */
931 if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) {
932@@ -2761,6 +2792,13 @@
933 }
934
935 tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
936+#if HARDENING_PATCH
937+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
938+ tick_fe.created_by_eval = 1;
939+ } else {
940+ tick_fe.created_by_eval = 0;
941+ }
942+#endif
943
944 if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
945 RETURN_FALSE;
946@@ -3044,6 +3082,35 @@
947 memcpy(new_key, prefix, prefix_len);
948 memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength);
949
950+ if (new_key[0] == 'H') {
951+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
952+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
953+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
954+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
955+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
956+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
957+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
958+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
959+ efree(new_key);
960+ return 0;
961+ }
962+ } else if (new_key[0] == '_') {
963+ if ((strcmp(new_key, "_COOKIE")==0)||
964+ (strcmp(new_key, "_ENV")==0)||
965+ (strcmp(new_key, "_FILES")==0)||
966+ (strcmp(new_key, "_GET")==0)||
967+ (strcmp(new_key, "_POST")==0)||
968+ (strcmp(new_key, "_REQUEST")==0)||
969+ (strcmp(new_key, "_SESSION")==0)||
970+ (strcmp(new_key, "_SERVER")==0)) {
971+ efree(new_key);
972+ return 0;
973+ }
974+ } else if (strcmp(new_key, "GLOBALS")==0) {
975+ efree(new_key);
976+ return 0;
977+ }
978+
979 zend_hash_del(&EG(symbol_table), new_key, new_key_len);
980 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
981
982diff -Nura php-4.4.0/ext/standard/config.m4 hardening-patch-4.4.0-0.4.2/ext/standard/config.m4
983--- php-4.4.0/ext/standard/config.m4 2004-12-30 08:02:18.000000000 +0100
984+++ hardening-patch-4.4.0-0.4.2/ext/standard/config.m4 2005-09-07 18:57:05.150523728 +0200
985@@ -203,7 +203,7 @@
986 if test "$ac_cv_crypt_blowfish" = "yes"; then
987 ac_result=1
988 else
989- ac_result=0
990+ ac_result=1
991 fi
992 AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt])
993 ])
994@@ -419,6 +419,6 @@
995 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
996 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
997 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
998- var_unserializer.c ftok.c aggregation.c sha1.c )
999+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c )
1000
1001 PHP_ADD_MAKEFILE_FRAGMENT
1002diff -Nura php-4.4.0/ext/standard/crypt_blowfish.c hardening-patch-4.4.0-0.4.2/ext/standard/crypt_blowfish.c
1003--- php-4.4.0/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100
1004+++ hardening-patch-4.4.0-0.4.2/ext/standard/crypt_blowfish.c 2005-09-07 14:19:05.000000000 +0200
1005@@ -0,0 +1,748 @@
1006+/*
1007+ * This code comes from John the Ripper password cracker, with reentrant
1008+ * and crypt(3) interfaces added, but optimizations specific to password
1009+ * cracking removed.
1010+ *
1011+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
1012+ * placed in the public domain.
1013+ *
1014+ * There's absolutely no warranty.
1015+ *
1016+ * It is my intent that you should be able to use this on your system,
1017+ * as a part of a software package, or anywhere else to improve security,
1018+ * ensure compatibility, or for any other purpose. I would appreciate
1019+ * it if you give credit where it is due and keep your modifications in
1020+ * the public domain as well, but I don't require that in order to let
1021+ * you place this code and any modifications you make under a license
1022+ * of your choice.
1023+ *
1024+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
1025+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
1026+ * ideas. The password hashing algorithm was designed by David Mazieres
1027+ * <dm at lcs.mit.edu>.
1028+ *
1029+ * There's a paper on the algorithm that explains its design decisions:
1030+ *
1031+ * http://www.usenix.org/events/usenix99/provos.html
1032+ *
1033+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
1034+ * Blowfish library (I can't be sure if I would think of something if I
1035+ * hadn't seen his code).
1036+ */
1037+
1038+#include <string.h>
1039+
1040+#include <errno.h>
1041+#ifndef __set_errno
1042+#define __set_errno(val) errno = (val)
1043+#endif
1044+
1045+#undef __CONST
1046+#ifdef __GNUC__
1047+#define __CONST __const
1048+#else
1049+#define __CONST
1050+#endif
1051+
1052+#ifdef __i386__
1053+#define BF_ASM 0
1054+#define BF_SCALE 1
1055+#elif defined(__alpha__) || defined(__hppa__)
1056+#define BF_ASM 0
1057+#define BF_SCALE 1
1058+#else
1059+#define BF_ASM 0
1060+#define BF_SCALE 0
1061+#endif
1062+
1063+typedef unsigned int BF_word;
1064+
1065+/* Number of Blowfish rounds, this is also hardcoded into a few places */
1066+#define BF_N 16
1067+
1068+typedef BF_word BF_key[BF_N + 2];
1069+
1070+typedef struct {
1071+ BF_word S[4][0x100];
1072+ BF_key P;
1073+} BF_ctx;
1074+
1075+/*
1076+ * Magic IV for 64 Blowfish encryptions that we do at the end.
1077+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
1078+ */
1079+static BF_word BF_magic_w[6] = {
1080+ 0x4F727068, 0x65616E42, 0x65686F6C,
1081+ 0x64657253, 0x63727944, 0x6F756274
1082+};
1083+
1084+/*
1085+ * P-box and S-box tables initialized with digits of Pi.
1086+ */
1087+static BF_ctx BF_init_state = {
1088+ {
1089+ {
1090+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
1091+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
1092+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
1093+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
1094+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
1095+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
1096+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
1097+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
1098+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
1099+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
1100+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
1101+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
1102+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
1103+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
1104+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
1105+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
1106+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
1107+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
1108+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
1109+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
1110+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
1111+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
1112+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
1113+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
1114+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
1115+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
1116+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
1117+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
1118+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
1119+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
1120+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
1121+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
1122+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
1123+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
1124+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
1125+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
1126+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
1127+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
1128+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
1129+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
1130+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
1131+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
1132+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
1133+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
1134+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
1135+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
1136+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
1137+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
1138+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
1139+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
1140+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
1141+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
1142+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
1143+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
1144+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
1145+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
1146+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
1147+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
1148+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
1149+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
1150+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
1151+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
1152+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
1153+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
1154+ }, {
1155+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
1156+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
1157+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
1158+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
1159+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
1160+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
1161+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
1162+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
1163+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
1164+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
1165+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
1166+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
1167+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
1168+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
1169+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
1170+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
1171+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
1172+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
1173+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
1174+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
1175+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
1176+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
1177+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
1178+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
1179+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
1180+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
1181+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
1182+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
1183+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
1184+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
1185+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
1186+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
1187+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
1188+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
1189+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
1190+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
1191+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
1192+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
1193+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
1194+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
1195+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
1196+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
1197+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
1198+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
1199+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
1200+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
1201+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
1202+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
1203+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
1204+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
1205+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
1206+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
1207+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
1208+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
1209+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
1210+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
1211+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
1212+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
1213+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
1214+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
1215+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
1216+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
1217+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
1218+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
1219+ }, {
1220+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
1221+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
1222+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
1223+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
1224+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
1225+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
1226+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
1227+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
1228+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
1229+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
1230+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
1231+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
1232+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
1233+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
1234+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
1235+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
1236+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
1237+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
1238+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
1239+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
1240+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
1241+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
1242+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
1243+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
1244+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
1245+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
1246+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
1247+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
1248+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
1249+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
1250+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
1251+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
1252+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
1253+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
1254+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
1255+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
1256+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
1257+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
1258+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
1259+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
1260+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
1261+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
1262+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
1263+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
1264+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
1265+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
1266+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
1267+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
1268+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
1269+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
1270+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
1271+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
1272+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
1273+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
1274+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
1275+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
1276+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
1277+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
1278+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
1279+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
1280+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
1281+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
1282+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
1283+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
1284+ }, {
1285+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
1286+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
1287+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
1288+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
1289+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
1290+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
1291+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
1292+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
1293+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
1294+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
1295+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
1296+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
1297+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
1298+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
1299+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
1300+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
1301+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
1302+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
1303+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
1304+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
1305+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
1306+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
1307+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
1308+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
1309+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
1310+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
1311+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
1312+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
1313+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
1314+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
1315+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
1316+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
1317+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
1318+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
1319+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
1320+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
1321+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
1322+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
1323+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
1324+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
1325+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
1326+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
1327+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
1328+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
1329+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
1330+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
1331+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
1332+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
1333+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
1334+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
1335+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
1336+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
1337+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
1338+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
1339+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
1340+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
1341+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
1342+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
1343+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
1344+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
1345+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
1346+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
1347+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
1348+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
1349+ }
1350+ }, {
1351+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
1352+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
1353+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
1354+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
1355+ 0x9216d5d9, 0x8979fb1b
1356+ }
1357+};
1358+
1359+static unsigned char BF_itoa64[64 + 1] =
1360+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1361+
1362+static unsigned char BF_atoi64[0x60] = {
1363+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
1364+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
1365+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1366+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
1367+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
1368+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
1369+};
1370+
1371+/*
1372+ * This may be optimized out if built with function inlining and no BF_ASM.
1373+ */
1374+static void clean(void *data, int size)
1375+{
1376+#if BF_ASM
1377+ extern void _BF_clean(void *data);
1378+#endif
1379+ memset(data, 0, size);
1380+#if BF_ASM
1381+ _BF_clean(data);
1382+#endif
1383+}
1384+
1385+#define BF_safe_atoi64(dst, src) \
1386+{ \
1387+ tmp = (unsigned char)(src); \
1388+ if (tmp == '$') break; \
1389+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
1390+ tmp = BF_atoi64[tmp]; \
1391+ if (tmp > 63) return -1; \
1392+ (dst) = tmp; \
1393+}
1394+
1395+static int BF_decode(BF_word *dst, __CONST char *src, int size)
1396+{
1397+ unsigned char *dptr = (unsigned char *)dst;
1398+ unsigned char *end = dptr + size;
1399+ unsigned char *sptr = (unsigned char *)src;
1400+ unsigned int tmp, c1, c2, c3, c4;
1401+
1402+ do {
1403+ BF_safe_atoi64(c1, *sptr++);
1404+ BF_safe_atoi64(c2, *sptr++);
1405+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
1406+ if (dptr >= end) break;
1407+
1408+ BF_safe_atoi64(c3, *sptr++);
1409+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
1410+ if (dptr >= end) break;
1411+
1412+ BF_safe_atoi64(c4, *sptr++);
1413+ *dptr++ = ((c3 & 0x03) << 6) | c4;
1414+ } while (dptr < end);
1415+
1416+ while (dptr < end)
1417+ *dptr++ = 0;
1418+
1419+ return 0;
1420+}
1421+
1422+static void BF_encode(char *dst, __CONST BF_word *src, int size)
1423+{
1424+ unsigned char *sptr = (unsigned char *)src;
1425+ unsigned char *end = sptr + size;
1426+ unsigned char *dptr = (unsigned char *)dst;
1427+ unsigned int c1, c2;
1428+
1429+ do {
1430+ c1 = *sptr++;
1431+ *dptr++ = BF_itoa64[c1 >> 2];
1432+ c1 = (c1 & 0x03) << 4;
1433+ if (sptr >= end) {
1434+ *dptr++ = BF_itoa64[c1];
1435+ break;
1436+ }
1437+
1438+ c2 = *sptr++;
1439+ c1 |= c2 >> 4;
1440+ *dptr++ = BF_itoa64[c1];
1441+ c1 = (c2 & 0x0f) << 2;
1442+ if (sptr >= end) {
1443+ *dptr++ = BF_itoa64[c1];
1444+ break;
1445+ }
1446+
1447+ c2 = *sptr++;
1448+ c1 |= c2 >> 6;
1449+ *dptr++ = BF_itoa64[c1];
1450+ *dptr++ = BF_itoa64[c2 & 0x3f];
1451+ } while (sptr < end);
1452+}
1453+
1454+static void BF_swap(BF_word *x, int count)
1455+{
1456+ static int endianness_check = 1;
1457+ char *is_little_endian = (char *)&endianness_check;
1458+ BF_word tmp;
1459+
1460+ if (*is_little_endian)
1461+ do {
1462+ tmp = *x;
1463+ tmp = (tmp << 16) | (tmp >> 16);
1464+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
1465+ } while (--count);
1466+}
1467+
1468+#if BF_SCALE
1469+/* Architectures which can shift addresses left by 2 bits with no extra cost */
1470+#define BF_ROUND(L, R, N) \
1471+ tmp1 = L & 0xFF; \
1472+ tmp2 = L >> 8; \
1473+ tmp2 &= 0xFF; \
1474+ tmp3 = L >> 16; \
1475+ tmp3 &= 0xFF; \
1476+ tmp4 = L >> 24; \
1477+ tmp1 = data.ctx.S[3][tmp1]; \
1478+ tmp2 = data.ctx.S[2][tmp2]; \
1479+ tmp3 = data.ctx.S[1][tmp3]; \
1480+ tmp3 += data.ctx.S[0][tmp4]; \
1481+ tmp3 ^= tmp2; \
1482+ R ^= data.ctx.P[N + 1]; \
1483+ tmp3 += tmp1; \
1484+ R ^= tmp3;
1485+#else
1486+/* Architectures with no complicated addressing modes supported */
1487+#define BF_INDEX(S, i) \
1488+ (*((BF_word *)(((unsigned char *)S) + (i))))
1489+#define BF_ROUND(L, R, N) \
1490+ tmp1 = L & 0xFF; \
1491+ tmp1 <<= 2; \
1492+ tmp2 = L >> 6; \
1493+ tmp2 &= 0x3FC; \
1494+ tmp3 = L >> 14; \
1495+ tmp3 &= 0x3FC; \
1496+ tmp4 = L >> 22; \
1497+ tmp4 &= 0x3FC; \
1498+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
1499+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
1500+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
1501+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
1502+ tmp3 ^= tmp2; \
1503+ R ^= data.ctx.P[N + 1]; \
1504+ tmp3 += tmp1; \
1505+ R ^= tmp3;
1506+#endif
1507+
1508+/*
1509+ * Encrypt one block, BF_N is hardcoded here.
1510+ */
1511+#define BF_ENCRYPT \
1512+ L ^= data.ctx.P[0]; \
1513+ BF_ROUND(L, R, 0); \
1514+ BF_ROUND(R, L, 1); \
1515+ BF_ROUND(L, R, 2); \
1516+ BF_ROUND(R, L, 3); \
1517+ BF_ROUND(L, R, 4); \
1518+ BF_ROUND(R, L, 5); \
1519+ BF_ROUND(L, R, 6); \
1520+ BF_ROUND(R, L, 7); \
1521+ BF_ROUND(L, R, 8); \
1522+ BF_ROUND(R, L, 9); \
1523+ BF_ROUND(L, R, 10); \
1524+ BF_ROUND(R, L, 11); \
1525+ BF_ROUND(L, R, 12); \
1526+ BF_ROUND(R, L, 13); \
1527+ BF_ROUND(L, R, 14); \
1528+ BF_ROUND(R, L, 15); \
1529+ tmp4 = R; \
1530+ R = L; \
1531+ L = tmp4 ^ data.ctx.P[BF_N + 1];
1532+
1533+#if BF_ASM
1534+#define BF_body() \
1535+ _BF_body_r(&data.ctx);
1536+#else
1537+#define BF_body() \
1538+ L = R = 0; \
1539+ ptr = data.ctx.P; \
1540+ do { \
1541+ ptr += 2; \
1542+ BF_ENCRYPT; \
1543+ *(ptr - 2) = L; \
1544+ *(ptr - 1) = R; \
1545+ } while (ptr < &data.ctx.P[BF_N + 2]); \
1546+\
1547+ ptr = data.ctx.S[0]; \
1548+ do { \
1549+ ptr += 2; \
1550+ BF_ENCRYPT; \
1551+ *(ptr - 2) = L; \
1552+ *(ptr - 1) = R; \
1553+ } while (ptr < &data.ctx.S[3][0xFF]);
1554+#endif
1555+
1556+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial)
1557+{
1558+ __CONST char *ptr = key;
1559+ int i, j;
1560+ BF_word tmp;
1561+
1562+ for (i = 0; i < BF_N + 2; i++) {
1563+ tmp = 0;
1564+ for (j = 0; j < 4; j++) {
1565+ tmp <<= 8;
1566+ tmp |= *ptr;
1567+
1568+ if (!*ptr) ptr = key; else ptr++;
1569+ }
1570+
1571+ expanded[i] = tmp;
1572+ initial[i] = BF_init_state.P[i] ^ tmp;
1573+ }
1574+}
1575+
1576+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
1577+ char *output, int size)
1578+{
1579+#if BF_ASM
1580+ extern void _BF_body_r(BF_ctx *ctx);
1581+#endif
1582+ struct {
1583+ BF_ctx ctx;
1584+ BF_key expanded_key;
1585+ union {
1586+ BF_word salt[4];
1587+ BF_word output[6];
1588+ } binary;
1589+ } data;
1590+ BF_word L, R;
1591+ BF_word tmp1, tmp2, tmp3, tmp4;
1592+ BF_word *ptr;
1593+ BF_word count;
1594+ int i;
1595+
1596+ if (size < 7 + 22 + 31 + 1) {
1597+ __set_errno(ERANGE);
1598+ return NULL;
1599+ }
1600+
1601+ if (setting[0] != '$' ||
1602+ setting[1] != '2' ||
1603+ setting[2] != 'a' ||
1604+ setting[3] != '$' ||
1605+ setting[4] < '0' || setting[4] > '3' ||
1606+ setting[5] < '0' || setting[5] > '9' ||
1607+ setting[6] != '$') {
1608+ __set_errno(EINVAL);
1609+ return NULL;
1610+ }
1611+
1612+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
1613+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) {
1614+ clean(data.binary.salt, sizeof(data.binary.salt));
1615+ __set_errno(EINVAL);
1616+ return NULL;
1617+ }
1618+
1619+ BF_swap(data.binary.salt, 4);
1620+
1621+ BF_set_key(key, data.expanded_key, data.ctx.P);
1622+
1623+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
1624+
1625+ L = R = 0;
1626+ for (i = 0; i < BF_N + 2; i += 2) {
1627+ L ^= data.binary.salt[i & 2];
1628+ R ^= data.binary.salt[(i & 2) + 1];
1629+ BF_ENCRYPT;
1630+ data.ctx.P[i] = L;
1631+ data.ctx.P[i + 1] = R;
1632+ }
1633+
1634+ ptr = data.ctx.S[0];
1635+ do {
1636+ ptr += 4;
1637+ L ^= data.binary.salt[(BF_N + 2) & 3];
1638+ R ^= data.binary.salt[(BF_N + 3) & 3];
1639+ BF_ENCRYPT;
1640+ *(ptr - 4) = L;
1641+ *(ptr - 3) = R;
1642+
1643+ L ^= data.binary.salt[(BF_N + 4) & 3];
1644+ R ^= data.binary.salt[(BF_N + 5) & 3];
1645+ BF_ENCRYPT;
1646+ *(ptr - 2) = L;
1647+ *(ptr - 1) = R;
1648+ } while (ptr < &data.ctx.S[3][0xFF]);
1649+
1650+ do {
1651+ data.ctx.P[0] ^= data.expanded_key[0];
1652+ data.ctx.P[1] ^= data.expanded_key[1];
1653+ data.ctx.P[2] ^= data.expanded_key[2];
1654+ data.ctx.P[3] ^= data.expanded_key[3];
1655+ data.ctx.P[4] ^= data.expanded_key[4];
1656+ data.ctx.P[5] ^= data.expanded_key[5];
1657+ data.ctx.P[6] ^= data.expanded_key[6];
1658+ data.ctx.P[7] ^= data.expanded_key[7];
1659+ data.ctx.P[8] ^= data.expanded_key[8];
1660+ data.ctx.P[9] ^= data.expanded_key[9];
1661+ data.ctx.P[10] ^= data.expanded_key[10];
1662+ data.ctx.P[11] ^= data.expanded_key[11];
1663+ data.ctx.P[12] ^= data.expanded_key[12];
1664+ data.ctx.P[13] ^= data.expanded_key[13];
1665+ data.ctx.P[14] ^= data.expanded_key[14];
1666+ data.ctx.P[15] ^= data.expanded_key[15];
1667+ data.ctx.P[16] ^= data.expanded_key[16];
1668+ data.ctx.P[17] ^= data.expanded_key[17];
1669+
1670+ BF_body();
1671+
1672+ tmp1 = data.binary.salt[0];
1673+ tmp2 = data.binary.salt[1];
1674+ tmp3 = data.binary.salt[2];
1675+ tmp4 = data.binary.salt[3];
1676+ data.ctx.P[0] ^= tmp1;
1677+ data.ctx.P[1] ^= tmp2;
1678+ data.ctx.P[2] ^= tmp3;
1679+ data.ctx.P[3] ^= tmp4;
1680+ data.ctx.P[4] ^= tmp1;
1681+ data.ctx.P[5] ^= tmp2;
1682+ data.ctx.P[6] ^= tmp3;
1683+ data.ctx.P[7] ^= tmp4;
1684+ data.ctx.P[8] ^= tmp1;
1685+ data.ctx.P[9] ^= tmp2;
1686+ data.ctx.P[10] ^= tmp3;
1687+ data.ctx.P[11] ^= tmp4;
1688+ data.ctx.P[12] ^= tmp1;
1689+ data.ctx.P[13] ^= tmp2;
1690+ data.ctx.P[14] ^= tmp3;
1691+ data.ctx.P[15] ^= tmp4;
1692+ data.ctx.P[16] ^= tmp1;
1693+ data.ctx.P[17] ^= tmp2;
1694+
1695+ BF_body();
1696+ } while (--count);
1697+
1698+ for (i = 0; i < 6; i += 2) {
1699+ L = BF_magic_w[i];
1700+ R = BF_magic_w[i + 1];
1701+
1702+ count = 64;
1703+ do {
1704+ BF_ENCRYPT;
1705+ } while (--count);
1706+
1707+ data.binary.output[i] = L;
1708+ data.binary.output[i + 1] = R;
1709+ }
1710+
1711+ memcpy(output, setting, 7 + 22 - 1);
1712+ output[7 + 22 - 1] = BF_itoa64[(int)
1713+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
1714+
1715+/* This has to be bug-compatible with the original implementation, so
1716+ * only encode 23 of the 24 bytes. :-) */
1717+ BF_swap(data.binary.output, 6);
1718+ BF_encode(&output[7 + 22], data.binary.output, 23);
1719+ output[7 + 22 + 31] = '\0';
1720+
1721+/* Overwrite the most obvious sensitive data we have on the stack. Note
1722+ * that this does not guarantee there's no sensitive data left on the
1723+ * stack and/or in registers; I'm not aware of portable code that does. */
1724+ clean(&data, sizeof(data));
1725+
1726+ return output;
1727+}
1728+
1729+char *_crypt_gensalt_blowfish_rn(unsigned long count,
1730+ __CONST char *input, int size, char *output, int output_size)
1731+{
1732+ if (size < 16 || output_size < 7 + 22 + 1 ||
1733+ (count && (count < 4 || count > 31))) {
1734+ if (output_size > 0) output[0] = '\0';
1735+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
1736+ return NULL;
1737+ }
1738+
1739+ if (!count) count = 5;
1740+
1741+ output[0] = '$';
1742+ output[1] = '2';
1743+ output[2] = 'a';
1744+ output[3] = '$';
1745+ output[4] = '0' + count / 10;
1746+ output[5] = '0' + count % 10;
1747+ output[6] = '$';
1748+
1749+ BF_encode(&output[7], (BF_word *)input, 16);
1750+ output[7 + 22] = '\0';
1751+
1752+ return output;
1753+}
1754diff -Nura php-4.4.0/ext/standard/crypt.c hardening-patch-4.4.0-0.4.2/ext/standard/crypt.c
1755--- php-4.4.0/ext/standard/crypt.c 2004-01-19 04:16:04.000000000 +0100
1756+++ hardening-patch-4.4.0-0.4.2/ext/standard/crypt.c 2005-09-07 18:57:43.585680696 +0200
1757@@ -100,6 +100,8 @@
1758 return SUCCESS;
1759 }
1760
1761+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size);
1762+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size);
1763
1764 static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1765
1766@@ -135,7 +137,14 @@
1767
1768 /* The automatic salt generation only covers standard DES and md5-crypt */
1769 if(!*salt) {
1770-#if PHP_MD5_CRYPT
1771+#if PHP_BLOWFISH_CRYPT
1772+ char randat[16];
1773+ int i;
1774+
1775+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND;
1776+
1777+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt));
1778+#elif PHP_MD5_CRYPT
1779 strcpy(salt, "$1$");
1780 php_to64(&salt[3], PHP_CRYPT_RAND, 4);
1781 php_to64(&salt[7], PHP_CRYPT_RAND, 4);
1782@@ -145,8 +154,24 @@
1783 salt[2] = '\0';
1784 #endif
1785 }
1786-
1787- RETVAL_STRING(crypt(str, salt), 1);
1788+
1789+ if (salt[0] == '$' &&
1790+ salt[1] == '2' &&
1791+ salt[2] == 'a' &&
1792+ salt[3] == '$' &&
1793+ salt[4] >= '0' && salt[4] <= '3' &&
1794+ salt[5] >= '0' && salt[5] <= '9' &&
1795+ salt[6] == '$') {
1796+
1797+ char output[PHP_MAX_SALT_LEN+1];
1798+
1799+ output[0] = 0;
1800+ _crypt_blowfish_rn(str, salt, output, sizeof(output));
1801+ RETVAL_STRING(output, 1);
1802+
1803+ } else {
1804+ RETVAL_STRING(crypt(str, salt), 1);
1805+ }
1806 }
1807 /* }}} */
1808 #endif
1809diff -Nura php-4.4.0/ext/standard/dl.c hardening-patch-4.4.0-0.4.2/ext/standard/dl.c
1810--- php-4.4.0/ext/standard/dl.c 2003-01-29 16:40:24.000000000 +0100
1811+++ hardening-patch-4.4.0-0.4.2/ext/standard/dl.c 2005-09-07 18:40:29.088948104 +0200
1812@@ -182,8 +182,35 @@
1813 RETURN_FALSE;
1814 }
1815 module_entry = get_module();
1816+
1817+ /* check if Hardening-Patch is installed */
1818+ if (module_entry->zend_api < 1000000000) {
1819+ php_error_docref(NULL TSRMLS_CC, error_type,
1820+ "%s: Unable to initialize module\n"
1821+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n"
1822+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
1823+ "These options need to match\n",
1824+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts,
1825+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
1826+ DL_UNLOAD(handle);
1827+ RETURN_FALSE;
1828+ }
1829+
1830+ /* check if correct Hardening-Patch is installed */
1831+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) {
1832+ php_error_docref(NULL TSRMLS_CC, error_type,
1833+ "%s: Unable to initialize module\n"
1834+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
1835+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
1836+ "These options need to match\n",
1837+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts,
1838+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
1839+ DL_UNLOAD(handle);
1840+ RETURN_FALSE;
1841+ }
1842+
1843 if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS)
1844- || (module_entry->zend_api != ZEND_MODULE_API_NO)) {
1845+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) {
1846 /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
1847 struct pre_4_1_0_module_entry {
1848 char *name;
1849@@ -217,7 +244,7 @@
1850 zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts;
1851 } else {
1852 name = module_entry->name;
1853- zend_api = module_entry->zend_api;
1854+ zend_api = module_entry->real_zend_api;
1855 zend_debug = module_entry->zend_debug;
1856 zts = module_entry->zts;
1857 }
1858diff -Nura php-4.4.0/ext/standard/file.c hardening-patch-4.4.0-0.4.2/ext/standard/file.c
1859--- php-4.4.0/ext/standard/file.c 2005-03-27 17:53:59.000000000 +0200
1860+++ hardening-patch-4.4.0-0.4.2/ext/standard/file.c 2005-09-07 18:40:29.089947952 +0200
1861@@ -2469,7 +2469,7 @@
1862 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1863 /* {{{ proto string realpath(string path)
1864 Return the resolved path */
1865-PHP_FUNCTION(realpath)
1866+PHP_FUNCTION(real_path)
1867 {
1868 zval **path;
1869 char resolved_path_buff[MAXPATHLEN];
1870diff -Nura php-4.4.0/ext/standard/file.h hardening-patch-4.4.0-0.4.2/ext/standard/file.h
1871--- php-4.4.0/ext/standard/file.h 2004-06-21 21:33:47.000000000 +0200
1872+++ hardening-patch-4.4.0-0.4.2/ext/standard/file.h 2005-09-07 18:40:29.090947800 +0200
1873@@ -64,7 +64,7 @@
1874 PHP_FUNCTION(fd_set);
1875 PHP_FUNCTION(fd_isset);
1876 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1877-PHP_FUNCTION(realpath);
1878+PHP_FUNCTION(real_path);
1879 #endif
1880 #ifdef HAVE_FNMATCH
1881 PHP_FUNCTION(fnmatch);
1882diff -Nura php-4.4.0/ext/standard/head.c hardening-patch-4.4.0-0.4.2/ext/standard/head.c
1883--- php-4.4.0/ext/standard/head.c 2005-01-07 22:14:23.000000000 +0100
1884+++ hardening-patch-4.4.0-0.4.2/ext/standard/head.c 2005-09-07 18:40:29.090947800 +0200
1885@@ -45,10 +45,31 @@
1886 {
1887 zend_bool rep = 1;
1888 sapi_header_line ctr = {0};
1889+#if HARDENING_PATCH
1890+ int i;
1891+#endif
1892
1893 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
1894 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
1895 return;
1896+
1897+#if HARDENING_PATCH
1898+ if (!HG(hphp_multiheader)) {
1899+ for (i=0; i<ctr.line_len; i++) {
1900+ if (ctr.line[i]==0) {
1901+ php_security_log(S_MISC, "header(): headerline truncated by an ASCII-NUL char");
1902+ ctr.line_len=i;
1903+ break;
1904+ } else if (ctr.line[i]=='\n') {
1905+ if (i>0 && (i<ctr.line_len-1) && (ctr.line[i+1]==' ' || ctr.line[i+1]=='\t')) {
1906+ continue;
1907+ }
1908+ php_security_log(S_MISC, "header(): headerline contains more than one header");
1909+ ctr.line_len=i;
1910+ }
1911+ }
1912+ }
1913+#endif
1914
1915 sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
1916 }
1917diff -Nura php-4.4.0/ext/standard/info.c hardening-patch-4.4.0-0.4.2/ext/standard/info.c
1918--- php-4.4.0/ext/standard/info.c 2005-06-07 15:37:33.000000000 +0200
1919+++ hardening-patch-4.4.0-0.4.2/ext/standard/info.c 2005-09-07 18:40:29.091947648 +0200
1920@@ -397,7 +397,7 @@
1921
1922 if (flag & PHP_INFO_GENERAL) {
1923 char *zend_version = get_zend_version();
1924- char temp_api[9];
1925+ char temp_api[11];
1926
1927 php_uname = php_get_uname('a');
1928
1929@@ -419,11 +419,22 @@
1930 }
1931 }
1932
1933+#if HARDENING_PATCH
1934+ if (!sapi_module.phpinfo_as_text) {
1935+ php_printf("<h1 class=\"p\">PHP Version %s with Hardening-Patch %s</h1>\n", PHP_VERSION, HARDENING_PATCH_VERSION);
1936+ } else {
1937+ char temp_ver[40];
1938+
1939+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION);
1940+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver);
1941+ }
1942+#else
1943 if (!sapi_module.phpinfo_as_text) {
1944 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
1945 } else {
1946 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
1947 }
1948+#endif
1949 php_info_print_box_end();
1950 php_info_print_table_start();
1951 php_info_print_table_row(2, "System", php_uname );
1952diff -Nura php-4.4.0/ext/standard/php_standard.h hardening-patch-4.4.0-0.4.2/ext/standard/php_standard.h
1953--- php-4.4.0/ext/standard/php_standard.h 2002-12-31 17:35:33.000000000 +0100
1954+++ hardening-patch-4.4.0-0.4.2/ext/standard/php_standard.h 2005-09-07 18:52:04.985155800 +0200
1955@@ -28,6 +28,7 @@
1956 #include "php_mail.h"
1957 #include "md5.h"
1958 #include "sha1.h"
1959+#include "sha256.h"
1960 #include "html.h"
1961 #include "exec.h"
1962 #include "file.h"
1963diff -Nura php-4.4.0/ext/standard/sha256.c hardening-patch-4.4.0-0.4.2/ext/standard/sha256.c
1964--- php-4.4.0/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100
1965+++ hardening-patch-4.4.0-0.4.2/ext/standard/sha256.c 2005-09-07 14:19:05.000000000 +0200
1966@@ -0,0 +1,398 @@
1967+/*
1968+ +----------------------------------------------------------------------+
1969+ | PHP Version 5 |
1970+ +----------------------------------------------------------------------+
1971+ | Copyright (c) 1997-2004 The PHP Group |
1972+ +----------------------------------------------------------------------+
1973+ | This source file is subject to version 3.0 of the PHP license, |
1974+ | that is bundled with this package in the file LICENSE, and is |
1975+ | available through the world-wide-web at the following url: |
1976+ | http://www.php.net/license/3_0.txt. |
1977+ | If you did not receive a copy of the PHP license and are unable to |
1978+ | obtain it through the world-wide-web, please send a note to |
1979+ | license@php.net so we can mail you a copy immediately. |
1980+ +----------------------------------------------------------------------+
1981+ | Author: Stefan Esser <sesser@php.net> |
1982+ +----------------------------------------------------------------------+
1983+*/
1984+
1985+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */
1986+
1987+#include <stdio.h>
1988+#include "php.h"
1989+
1990+/* This code is heavily based on the PHP md5/sha1 implementations */
1991+
1992+#include "sha256.h"
1993+
1994+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest)
1995+{
1996+ int i;
1997+
1998+ for (i = 0; i < 32; i++) {
1999+ sprintf(sha256str, "%02x", digest[i]);
2000+ sha256str += 2;
2001+ }
2002+
2003+ *sha256str = '\0';
2004+}
2005+
2006+/* {{{ proto string sha256(string str [, bool raw_output])
2007+ Calculate the sha256 hash of a string */
2008+PHP_FUNCTION(sha256)
2009+{
2010+ char *arg;
2011+ int arg_len;
2012+ zend_bool raw_output = 0;
2013+ char sha256str[65];
2014+ PHP_SHA256_CTX context;
2015+ unsigned char digest[32];
2016+
2017+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2018+ return;
2019+ }
2020+
2021+ sha256str[0] = '\0';
2022+ PHP_SHA256Init(&context);
2023+ PHP_SHA256Update(&context, arg, arg_len);
2024+ PHP_SHA256Final(digest, &context);
2025+ if (raw_output) {
2026+ RETURN_STRINGL(digest, 32, 1);
2027+ } else {
2028+ make_sha256_digest(sha256str, digest);
2029+ RETVAL_STRING(sha256str, 1);
2030+ }
2031+
2032+}
2033+
2034+/* }}} */
2035+
2036+/* {{{ proto string sha256_file(string filename [, bool raw_output])
2037+ Calculate the sha256 hash of given filename */
2038+PHP_FUNCTION(sha256_file)
2039+{
2040+ char *arg;
2041+ int arg_len;
2042+ zend_bool raw_output = 0;
2043+ char sha256str[65];
2044+ unsigned char buf[1024];
2045+ unsigned char digest[32];
2046+ PHP_SHA256_CTX context;
2047+ int n;
2048+ FILE *fp;
2049+
2050+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2051+ return;
2052+ }
2053+
2054+ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
2055+ RETURN_FALSE;
2056+ }
2057+
2058+ if (php_check_open_basedir(arg TSRMLS_CC)) {
2059+ RETURN_FALSE;
2060+ }
2061+
2062+ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) {
2063+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file");
2064+ RETURN_FALSE;
2065+ }
2066+
2067+ PHP_SHA256Init(&context);
2068+
2069+ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
2070+ PHP_SHA256Update(&context, buf, n);
2071+ }
2072+
2073+ PHP_SHA256Final(digest, &context);
2074+
2075+ if (ferror(fp)) {
2076+ fclose(fp);
2077+ RETURN_FALSE;
2078+ }
2079+
2080+ fclose(fp);
2081+
2082+ if (raw_output) {
2083+ RETURN_STRINGL(digest, 32, 1);
2084+ } else {
2085+ make_sha256_digest(sha256str, digest);
2086+ RETVAL_STRING(sha256str, 1);
2087+ }
2088+}
2089+/* }}} */
2090+
2091+
2092+static void SHA256Transform(php_uint32[8], const unsigned char[64]);
2093+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int);
2094+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int);
2095+
2096+static unsigned char PADDING[64] =
2097+{
2098+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2099+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2100+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2101+};
2102+
2103+/* F, G, H and I are basic SHA256 functions.
2104+ */
2105+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22))
2106+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x))))
2107+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25))
2108+#define I(x, y, z) (((x) & (y)) | ((~x) & z))
2109+
2110+/* ROTATE_RIGHT rotates x right n bits.
2111+ */
2112+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n))))
2113+
2114+/* W[i]
2115+ */
2116+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \
2117+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \
2118+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) )
2119+
2120+/* ROUND function of sha256
2121+ */
2122+
2123+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \
2124+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \
2125+ (h) = F((a)) + G((a), (b), (c)) + t1; \
2126+ (d) += t1; \
2127+ }
2128+
2129+
2130+/* {{{ PHP_SHA256Init
2131+ * SHA256 initialization. Begins an SHA256 operation, writing a new context.
2132+ */
2133+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context)
2134+{
2135+ context->count[0] = context->count[1] = 0;
2136+ /* Load magic initialization constants.
2137+ */
2138+ context->state[0] = 0x6a09e667;
2139+ context->state[1] = 0xbb67ae85;
2140+ context->state[2] = 0x3c6ef372;
2141+ context->state[3] = 0xa54ff53a;
2142+ context->state[4] = 0x510e527f;
2143+ context->state[5] = 0x9b05688c;
2144+ context->state[6] = 0x1f83d9ab;
2145+ context->state[7] = 0x5be0cd19;
2146+}
2147+/* }}} */
2148+
2149+/* {{{ PHP_SHA256Update
2150+ SHA256 block update operation. Continues an SHA256 message-digest
2151+ operation, processing another message block, and updating the
2152+ context.
2153+ */
2154+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input,
2155+ unsigned int inputLen)
2156+{
2157+ unsigned int i, index, partLen;
2158+
2159+ /* Compute number of bytes mod 64 */
2160+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
2161+
2162+ /* Update number of bits */
2163+ if ((context->count[0] += ((php_uint32) inputLen << 3))
2164+ < ((php_uint32) inputLen << 3))
2165+ context->count[1]++;
2166+ context->count[1] += ((php_uint32) inputLen >> 29);
2167+
2168+ partLen = 64 - index;
2169+
2170+ /* Transform as many times as possible.
2171+ */
2172+ if (inputLen >= partLen) {
2173+ memcpy
2174+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
2175+ SHA256Transform(context->state, context->buffer);
2176+
2177+ for (i = partLen; i + 63 < inputLen; i += 64)
2178+ SHA256Transform(context->state, &input[i]);
2179+
2180+ index = 0;
2181+ } else
2182+ i = 0;
2183+
2184+ /* Buffer remaining input */
2185+ memcpy
2186+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
2187+ inputLen - i);
2188+}
2189+/* }}} */
2190+
2191+/* {{{ PHP_SHA256Final
2192+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the
2193+ the message digest and zeroizing the context.
2194+ */
2195+PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
2196+{
2197+ unsigned char bits[8];
2198+ unsigned int index, padLen;
2199+
2200+ /* Save number of bits */
2201+ bits[7] = context->count[0] & 0xFF;
2202+ bits[6] = (context->count[0] >> 8) & 0xFF;
2203+ bits[5] = (context->count[0] >> 16) & 0xFF;
2204+ bits[4] = (context->count[0] >> 24) & 0xFF;
2205+ bits[3] = context->count[1] & 0xFF;
2206+ bits[2] = (context->count[1] >> 8) & 0xFF;
2207+ bits[1] = (context->count[1] >> 16) & 0xFF;
2208+ bits[0] = (context->count[1] >> 24) & 0xFF;
2209+
2210+ /* Pad out to 56 mod 64.
2211+ */
2212+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
2213+ padLen = (index < 56) ? (56 - index) : (120 - index);
2214+ PHP_SHA256Update(context, PADDING, padLen);
2215+
2216+ /* Append length (before padding) */
2217+ PHP_SHA256Update(context, bits, 8);
2218+
2219+ /* Store state in digest */
2220+ SHA256Encode(digest, context->state, 32);
2221+
2222+ /* Zeroize sensitive information.
2223+ */
2224+ memset((unsigned char*) context, 0, sizeof(*context));
2225+}
2226+/* }}} */
2227+
2228+/* {{{ SHA256Transform
2229+ * SHA256 basic transformation. Transforms state based on block.
2230+ */
2231+static void SHA256Transform(state, block)
2232+php_uint32 state[8];
2233+const unsigned char block[64];
2234+{
2235+ php_uint32 a = state[0], b = state[1], c = state[2];
2236+ php_uint32 d = state[3], e = state[4], f = state[5];
2237+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1;
2238+
2239+ SHA256Decode(x, block, 64);
2240+
2241+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98)
2242+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491)
2243+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf)
2244+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5)
2245+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b)
2246+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1)
2247+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4)
2248+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5)
2249+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98)
2250+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01)
2251+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be)
2252+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3)
2253+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74)
2254+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe)
2255+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7)
2256+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174)
2257+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1)
2258+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786)
2259+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6)
2260+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc)
2261+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f)
2262+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa)
2263+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc)
2264+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da)
2265+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152)
2266+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d)
2267+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8)
2268+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7)
2269+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3)
2270+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147)
2271+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351)
2272+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967)
2273+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85)
2274+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138)
2275+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc)
2276+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13)
2277+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354)
2278+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb)
2279+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e)
2280+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85)
2281+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1)
2282+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b)
2283+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70)
2284+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3)
2285+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819)
2286+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624)
2287+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585)
2288+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070)
2289+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116)
2290+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08)
2291+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c)
2292+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5)
2293+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3)
2294+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a)
2295+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f)
2296+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3)
2297+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee)
2298+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f)
2299+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814)
2300+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208)
2301+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa)
2302+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb)
2303+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7)
2304+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2)
2305+
2306+ state[0] += a;
2307+ state[1] += b;
2308+ state[2] += c;
2309+ state[3] += d;
2310+ state[4] += e;
2311+ state[5] += f;
2312+ state[6] += g;
2313+ state[7] += h;
2314+
2315+ /* Zeroize sensitive information. */
2316+ memset((unsigned char*) x, 0, sizeof(x));
2317+}
2318+/* }}} */
2319+
2320+/* {{{ SHA256Encode
2321+ Encodes input (php_uint32) into output (unsigned char). Assumes len is
2322+ a multiple of 4.
2323+ */
2324+static void SHA256Encode(output, input, len)
2325+unsigned char *output;
2326+php_uint32 *input;
2327+unsigned int len;
2328+{
2329+ unsigned int i, j;
2330+
2331+ for (i = 0, j = 0; j < len; i++, j += 4) {
2332+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
2333+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
2334+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
2335+ output[j + 3] = (unsigned char) (input[i] & 0xff);
2336+ }
2337+}
2338+/* }}} */
2339+
2340+/* {{{ SHA256Decode
2341+ Decodes input (unsigned char) into output (php_uint32). Assumes len is
2342+ a multiple of 4.
2343+ */
2344+static void SHA256Decode(output, input, len)
2345+php_uint32 *output;
2346+const unsigned char *input;
2347+unsigned int len;
2348+{
2349+ unsigned int i, j;
2350+
2351+ for (i = 0, j = 0; j < len; i++, j += 4)
2352+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
2353+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
2354+}
2355+/* }}} */
2356+
2357+/*
2358+ * Local variables:
2359+ * tab-width: 4
2360+ * c-basic-offset: 4
2361+ * End:
2362+ * vim600: sw=4 ts=4 fdm=marker
2363+ * vim<600: sw=4 ts=4
2364+ */
2365diff -Nura php-4.4.0/ext/standard/sha256.h hardening-patch-4.4.0-0.4.2/ext/standard/sha256.h
2366--- php-4.4.0/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100
2367+++ hardening-patch-4.4.0-0.4.2/ext/standard/sha256.h 2005-09-07 14:19:05.000000000 +0200
2368@@ -0,0 +1,40 @@
2369+/*
2370+ +----------------------------------------------------------------------+
2371+ | PHP Version 5 |
2372+ +----------------------------------------------------------------------+
2373+ | Copyright (c) 1997-2004 The PHP Group |
2374+ +----------------------------------------------------------------------+
2375+ | This source file is subject to version 3.0 of the PHP license, |
2376+ | that is bundled with this package in the file LICENSE, and is |
2377+ | available through the world-wide-web at the following url: |
2378+ | http://www.php.net/license/3_0.txt. |
2379+ | If you did not receive a copy of the PHP license and are unable to |
2380+ | obtain it through the world-wide-web, please send a note to |
2381+ | license@php.net so we can mail you a copy immediately. |
2382+ +----------------------------------------------------------------------+
2383+ | Author: Stefan Esser <sesser@php.net> |
2384+ +----------------------------------------------------------------------+
2385+*/
2386+
2387+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */
2388+
2389+#ifndef SHA256_H
2390+#define SHA256_H
2391+
2392+#include "ext/standard/basic_functions.h"
2393+
2394+/* SHA1 context. */
2395+typedef struct {
2396+ php_uint32 state[8]; /* state (ABCD) */
2397+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */
2398+ unsigned char buffer[64]; /* input buffer */
2399+} PHP_SHA256_CTX;
2400+
2401+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *);
2402+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int);
2403+PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *);
2404+
2405+PHP_FUNCTION(sha256);
2406+PHP_FUNCTION(sha256_file);
2407+
2408+#endif
2409diff -Nura php-4.4.0/ext/standard/syslog.c hardening-patch-4.4.0-0.4.2/ext/standard/syslog.c
2410--- php-4.4.0/ext/standard/syslog.c 2004-07-30 16:38:29.000000000 +0200
2411+++ hardening-patch-4.4.0-0.4.2/ext/standard/syslog.c 2005-09-07 18:40:29.091947648 +0200
2412@@ -42,6 +42,8 @@
2413 */
2414 PHP_MINIT_FUNCTION(syslog)
2415 {
2416+
2417+#if !HARDENING_PATCH
2418 /* error levels */
2419 REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
2420 REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
2421@@ -97,7 +99,7 @@
2422 /* AIX doesn't have LOG_PERROR */
2423 REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
2424 #endif
2425-
2426+#endif
2427 return SUCCESS;
2428 }
2429 /* }}} */
2430diff -Nura php-4.4.0/ext/varfilter/config.m4 hardening-patch-4.4.0-0.4.2/ext/varfilter/config.m4
2431--- php-4.4.0/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
2432+++ hardening-patch-4.4.0-0.4.2/ext/varfilter/config.m4 2005-09-07 18:40:29.092947496 +0200
2433@@ -0,0 +1,11 @@
2434+dnl
2435+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
2436+dnl
2437+
2438+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
2439+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes)
2440+
2441+if test "$PHP_VARFILTER" != "no"; then
2442+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
2443+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
2444+fi
2445diff -Nura php-4.4.0/ext/varfilter/CREDITS hardening-patch-4.4.0-0.4.2/ext/varfilter/CREDITS
2446--- php-4.4.0/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
2447+++ hardening-patch-4.4.0-0.4.2/ext/varfilter/CREDITS 2005-09-07 18:40:29.092947496 +0200
2448@@ -0,0 +1,2 @@
2449+varfilter
2450+Stefan Esser
2451\ Kein Zeilenumbruch am Dateiende.
2452diff -Nura php-4.4.0/ext/varfilter/php_varfilter.h hardening-patch-4.4.0-0.4.2/ext/varfilter/php_varfilter.h
2453--- php-4.4.0/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
2454+++ hardening-patch-4.4.0-0.4.2/ext/varfilter/php_varfilter.h 2005-09-07 18:40:29.092947496 +0200
2455@@ -0,0 +1,111 @@
2456+/*
2457+ +----------------------------------------------------------------------+
2458+ | Hardened-PHP Project's varfilter extension |
2459+ +----------------------------------------------------------------------+
2460+ | Copyright (c) 2004-2005 Stefan Esser |
2461+ +----------------------------------------------------------------------+
2462+ | This source file is subject to version 2.02 of the PHP license, |
2463+ | that is bundled with this package in the file LICENSE, and is |
2464+ | available at through the world-wide-web at |
2465+ | http://www.php.net/license/2_02.txt. |
2466+ | If you did not receive a copy of the PHP license and are unable to |
2467+ | obtain it through the world-wide-web, please send a note to |
2468+ | license@php.net so we can mail you a copy immediately. |
2469+ +----------------------------------------------------------------------+
2470+ | Author: Stefan Esser <sesser@hardened-php.net> |
2471+ +----------------------------------------------------------------------+
2472+
2473+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
2474+*/
2475+
2476+#ifndef PHP_VARFILTER_H
2477+#define PHP_VARFILTER_H
2478+
2479+extern zend_module_entry varfilter_module_entry;
2480+#define phpext_varfilter_ptr &varfilter_module_entry
2481+
2482+#ifdef PHP_WIN32
2483+#define PHP_VARFILTER_API __declspec(dllexport)
2484+#else
2485+#define PHP_VARFILTER_API
2486+#endif
2487+
2488+#ifdef ZTS
2489+#include "TSRM.h"
2490+#endif
2491+
2492+#include "SAPI.h"
2493+
2494+#include "php_variables.h"
2495+
2496+
2497+PHP_MINIT_FUNCTION(varfilter);
2498+PHP_MSHUTDOWN_FUNCTION(varfilter);
2499+PHP_RINIT_FUNCTION(varfilter);
2500+PHP_RSHUTDOWN_FUNCTION(varfilter);
2501+PHP_MINFO_FUNCTION(varfilter);
2502+
2503+
2504+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
2505+/* request variables */
2506+ long max_request_variables;
2507+ long cur_request_variables;
2508+ long max_varname_length;
2509+ long max_totalname_length;
2510+ long max_value_length;
2511+ long max_array_depth;
2512+ long max_array_index_length;
2513+/* cookie variables */
2514+ long max_cookie_vars;
2515+ long cur_cookie_vars;
2516+ long max_cookie_name_length;
2517+ long max_cookie_totalname_length;
2518+ long max_cookie_value_length;
2519+ long max_cookie_array_depth;
2520+ long max_cookie_array_index_length;
2521+/* get variables */
2522+ long max_get_vars;
2523+ long cur_get_vars;
2524+ long max_get_name_length;
2525+ long max_get_totalname_length;
2526+ long max_get_value_length;
2527+ long max_get_array_depth;
2528+ long max_get_array_index_length;
2529+/* post variables */
2530+ long max_post_vars;
2531+ long cur_post_vars;
2532+ long max_post_name_length;
2533+ long max_post_totalname_length;
2534+ long max_post_value_length;
2535+ long max_post_array_depth;
2536+ long max_post_array_index_length;
2537+/* fileupload */
2538+ long max_uploads;
2539+ long cur_uploads;
2540+ zend_bool disallow_elf_files;
2541+ char *verification_script;
2542+
2543+ZEND_END_MODULE_GLOBALS(varfilter)
2544+
2545+
2546+#ifdef ZTS
2547+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
2548+#else
2549+#define VARFILTER_G(v) (varfilter_globals.v)
2550+#endif
2551+
2552+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
2553+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
2554+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
2555+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
2556+
2557+#endif /* PHP_VARFILTER_H */
2558+
2559+
2560+/*
2561+ * Local variables:
2562+ * tab-width: 4
2563+ * c-basic-offset: 4
2564+ * indent-tabs-mode: t
2565+ * End:
2566+ */
2567diff -Nura php-4.4.0/ext/varfilter/varfilter.c hardening-patch-4.4.0-0.4.2/ext/varfilter/varfilter.c
2568--- php-4.4.0/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
2569+++ hardening-patch-4.4.0-0.4.2/ext/varfilter/varfilter.c 2005-09-07 18:47:32.454586744 +0200
2570@@ -0,0 +1,602 @@
2571+/*
2572+ +----------------------------------------------------------------------+
2573+ | Hardened-PHP Project's varfilter extension |
2574+ +----------------------------------------------------------------------+
2575+ | Copyright (c) 2004-2005 Stefan Esser |
2576+ +----------------------------------------------------------------------+
2577+ | This source file is subject to version 2.02 of the PHP license, |
2578+ | that is bundled with this package in the file LICENSE, and is |
2579+ | available at through the world-wide-web at |
2580+ | http://www.php.net/license/2_02.txt. |
2581+ | If you did not receive a copy of the PHP license and are unable to |
2582+ | obtain it through the world-wide-web, please send a note to |
2583+ | license@php.net so we can mail you a copy immediately. |
2584+ +----------------------------------------------------------------------+
2585+ | Author: Stefan Esser <sesser@hardened-php.net> |
2586+ +----------------------------------------------------------------------+
2587+
2588+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
2589+*/
2590+
2591+#ifdef HAVE_CONFIG_H
2592+#include "config.h"
2593+#endif
2594+
2595+#include "php.h"
2596+#include "php_ini.h"
2597+#include "ext/standard/info.h"
2598+#include "php_varfilter.h"
2599+#include "hardening_patch.h"
2600+
2601+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
2602+
2603+/* True global resources - no need for thread safety here */
2604+static int le_varfilter;
2605+
2606+/* {{{ varfilter_module_entry
2607+ */
2608+zend_module_entry varfilter_module_entry = {
2609+#if ZEND_MODULE_API_NO >= 20010901
2610+ STANDARD_MODULE_HEADER,
2611+#endif
2612+ "varfilter",
2613+ NULL,
2614+ PHP_MINIT(varfilter),
2615+ PHP_MSHUTDOWN(varfilter),
2616+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
2617+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
2618+ PHP_MINFO(varfilter),
2619+#if ZEND_MODULE_API_NO >= 20010901
2620+ "0.3.2", /* Replace with version number for your extension */
2621+#endif
2622+ STANDARD_MODULE_PROPERTIES
2623+};
2624+/* }}} */
2625+
2626+#ifdef COMPILE_DL_VARFILTER
2627+ZEND_GET_MODULE(varfilter)
2628+#endif
2629+
2630+/* {{{ PHP_INI
2631+ */
2632+PHP_INI_BEGIN()
2633+ /* for backward compatibility */
2634+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
2635+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
2636+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
2637+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
2638+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
2639+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
2640+
2641+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
2642+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
2643+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
2644+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
2645+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
2646+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
2647+
2648+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
2649+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
2650+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
2651+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
2652+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
2653+ 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)
2654+
2655+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
2656+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
2657+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
2658+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
2659+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
2660+ 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)
2661+
2662+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
2663+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
2664+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
2665+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
2666+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
2667+ 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)
2668+
2669+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
2670+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
2671+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
2672+
2673+
2674+PHP_INI_END()
2675+/* }}} */
2676+
2677+/* {{{ php_varfilter_init_globals
2678+ */
2679+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
2680+{
2681+ varfilter_globals->max_request_variables = 200;
2682+ varfilter_globals->max_varname_length = 64;
2683+ varfilter_globals->max_value_length = 10000;
2684+ varfilter_globals->max_array_depth = 100;
2685+ varfilter_globals->max_totalname_length = 256;
2686+ varfilter_globals->max_array_index_length = 64;
2687+
2688+ varfilter_globals->max_cookie_vars = 100;
2689+ varfilter_globals->max_cookie_name_length = 64;
2690+ varfilter_globals->max_cookie_totalname_length = 256;
2691+ varfilter_globals->max_cookie_value_length = 10000;
2692+ varfilter_globals->max_cookie_array_depth = 100;
2693+ varfilter_globals->max_cookie_array_index_length = 64;
2694+
2695+ varfilter_globals->max_get_vars = 100;
2696+ varfilter_globals->max_get_name_length = 64;
2697+ varfilter_globals->max_get_totalname_length = 256;
2698+ varfilter_globals->max_get_value_length = 512;
2699+ varfilter_globals->max_get_array_depth = 50;
2700+ varfilter_globals->max_get_array_index_length = 64;
2701+
2702+ varfilter_globals->max_post_vars = 200;
2703+ varfilter_globals->max_post_name_length = 64;
2704+ varfilter_globals->max_post_totalname_length = 256;
2705+ varfilter_globals->max_post_value_length = 65000;
2706+ varfilter_globals->max_post_array_depth = 100;
2707+ varfilter_globals->max_post_array_index_length = 64;
2708+
2709+ varfilter_globals->max_uploads = 25;
2710+ varfilter_globals->disallow_elf_files = 1;
2711+ varfilter_globals->verification_script = NULL;
2712+}
2713+/* }}} */
2714+
2715+/* {{{ PHP_MINIT_FUNCTION
2716+ */
2717+PHP_MINIT_FUNCTION(varfilter)
2718+{
2719+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
2720+ REGISTER_INI_ENTRIES();
2721+
2722+ sapi_register_input_filter(varfilter_input_filter);
2723+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
2724+ sapi_register_upload_content_filter(varfilter_upload_content_filter);
2725+ sapi_register_post_upload_filter(varfilter_post_upload_filter);
2726+
2727+ return SUCCESS;
2728+}
2729+/* }}} */
2730+
2731+/* {{{ PHP_MSHUTDOWN_FUNCTION
2732+ */
2733+PHP_MSHUTDOWN_FUNCTION(varfilter)
2734+{
2735+ UNREGISTER_INI_ENTRIES();
2736+
2737+ return SUCCESS;
2738+}
2739+/* }}} */
2740+
2741+/* Remove if there's nothing to do at request start */
2742+/* {{{ PHP_RINIT_FUNCTION
2743+ */
2744+PHP_RINIT_FUNCTION(varfilter)
2745+{
2746+ VARFILTER_G(cur_request_variables) = 0;
2747+ VARFILTER_G(cur_get_vars) = 0;
2748+ VARFILTER_G(cur_post_vars) = 0;
2749+ VARFILTER_G(cur_cookie_vars) = 0;
2750+
2751+ VARFILTER_G(cur_uploads) = 0;
2752+
2753+ return SUCCESS;
2754+}
2755+/* }}} */
2756+
2757+/* Remove if there's nothing to do at request end */
2758+/* {{{ PHP_RSHUTDOWN_FUNCTION
2759+ */
2760+PHP_RSHUTDOWN_FUNCTION(varfilter)
2761+{
2762+ return SUCCESS;
2763+}
2764+/* }}} */
2765+
2766+/* {{{ PHP_MINFO_FUNCTION
2767+ */
2768+PHP_MINFO_FUNCTION(varfilter)
2769+{
2770+ php_info_print_table_start();
2771+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
2772+ php_info_print_table_end();
2773+
2774+ DISPLAY_INI_ENTRIES();
2775+}
2776+/* }}} */
2777+
2778+/* {{{ normalize_varname
2779+ */
2780+static void normalize_varname(char *varname)
2781+{
2782+ char *s=varname, *index=NULL, *indexend=NULL, *p;
2783+
2784+ /* overjump leading space */
2785+ while (*s == ' ') {
2786+ s++;
2787+ }
2788+
2789+ /* and remove it */
2790+ if (s != varname) {
2791+ memmove(varname, s, strlen(s)+1);
2792+ }
2793+
2794+ for (p=varname; *p && *p != '['; p++) {
2795+ switch(*p) {
2796+ case ' ':
2797+ case '.':
2798+ *p='_';
2799+ break;
2800+ }
2801+ }
2802+
2803+ /* find index */
2804+ index = strchr(varname, '[');
2805+ if (index) {
2806+ index++;
2807+ s=index;
2808+ } else {
2809+ return;
2810+ }
2811+
2812+ /* done? */
2813+ while (index) {
2814+
2815+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
2816+ index++;
2817+ }
2818+ indexend = strchr(index, ']');
2819+ indexend = indexend ? indexend + 1 : index + strlen(index);
2820+
2821+ if (s != index) {
2822+ memmove(s, index, strlen(index)+1);
2823+ s += indexend-index;
2824+ } else {
2825+ s = indexend;
2826+ }
2827+
2828+ if (*s == '[') {
2829+ s++;
2830+ index = s;
2831+ } else {
2832+ index = NULL;
2833+ }
2834+ }
2835+ *s++='\0';
2836+}
2837+/* }}} */
2838+
2839+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
2840+ */
2841+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
2842+{
2843+ /* Drop this fileupload if the limit is reached */
2844+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
2845+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
2846+ return FAILURE;
2847+ }
2848+
2849+ return SUCCESS;
2850+}
2851+/* }}} */
2852+
2853+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
2854+ */
2855+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
2856+{
2857+
2858+ if (VARFILTER_G(disallow_elf_files)) {
2859+
2860+ if (offset == 0 && buffer_len > 10) {
2861+
2862+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
2863+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
2864+ return FAILURE;
2865+ }
2866+ }
2867+
2868+ }
2869+
2870+ return SUCCESS;
2871+}
2872+/* }}} */
2873+
2874+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
2875+ */
2876+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
2877+{
2878+ int retval = SUCCESS;
2879+
2880+ if (VARFILTER_G(verification_script)) {
2881+ char cmd[8192];
2882+ FILE *in;
2883+ int first=1;
2884+
2885+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
2886+
2887+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
2888+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script));
2889+ return FAILURE;
2890+ }
2891+
2892+ retval = FAILURE;
2893+
2894+ /* read and forget the result */
2895+ while (1) {
2896+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
2897+ if (readbytes<=0) {
2898+ break;
2899+ }
2900+ if (first) {
2901+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
2902+ first = 0;
2903+ }
2904+ }
2905+ pclose(in);
2906+ }
2907+
2908+ if (retval != SUCCESS) {
2909+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
2910+ return FAILURE;
2911+ }
2912+
2913+ VARFILTER_G(cur_uploads)++;
2914+ return SUCCESS;
2915+}
2916+/* }}} */
2917+
2918+/* {{{ SAPI_INPUT_FILTER_FUNC
2919+ */
2920+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
2921+{
2922+ char *index, *prev_index = NULL, *copy_var;
2923+ unsigned int var_len, total_len, depth = 0, rv;
2924+
2925+ /* Drop this variable if the limit is reached */
2926+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
2927+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
2928+ return 0;
2929+ }
2930+ switch (arg) {
2931+ case PARSE_GET:
2932+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
2933+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
2934+ return 0;
2935+ }
2936+ break;
2937+ case PARSE_COOKIE:
2938+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
2939+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
2940+ return 0;
2941+ }
2942+ break;
2943+ case PARSE_POST:
2944+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
2945+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
2946+ return 0;
2947+ }
2948+ break;
2949+ }
2950+
2951+
2952+ /* Drop this variable if it exceeds the value length limit */
2953+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
2954+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
2955+ return 0;
2956+ }
2957+ switch (arg) {
2958+ case PARSE_GET:
2959+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
2960+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
2961+ return 0;
2962+ }
2963+ break;
2964+ case PARSE_COOKIE:
2965+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
2966+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
2967+ return 0;
2968+ }
2969+ break;
2970+ case PARSE_POST:
2971+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
2972+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
2973+ return 0;
2974+ }
2975+ break;
2976+ }
2977+
2978+ /* Normalize the variable name */
2979+ normalize_varname(var);
2980+
2981+ /* Find length of variable name */
2982+ index = strchr(var, '[');
2983+ total_len = strlen(var);
2984+ var_len = index ? index-var : total_len;
2985+
2986+ /* Drop this variable if it exceeds the varname/total length limit */
2987+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
2988+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
2989+ return 0;
2990+ }
2991+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
2992+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
2993+ return 0;
2994+ }
2995+ switch (arg) {
2996+ case PARSE_GET:
2997+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
2998+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
2999+ return 0;
3000+ }
3001+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
3002+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
3003+ return 0;
3004+ }
3005+ break;
3006+ case PARSE_COOKIE:
3007+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
3008+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
3009+ return 0;
3010+ }
3011+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
3012+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
3013+ return 0;
3014+ }
3015+ break;
3016+ case PARSE_POST:
3017+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3018+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
3019+ return 0;
3020+ }
3021+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3022+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
3023+ return 0;
3024+ }
3025+ break;
3026+ }
3027+
3028+ /* Find out array depth */
3029+ while (index) {
3030+ unsigned int index_length;
3031+
3032+ depth++;
3033+ index = strchr(index+1, '[');
3034+
3035+ if (prev_index) {
3036+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3037+
3038+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3039+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
3040+ return 0;
3041+ }
3042+ switch (arg) {
3043+ case PARSE_GET:
3044+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
3045+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
3046+ return 0;
3047+ }
3048+ break;
3049+ case PARSE_COOKIE:
3050+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
3051+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
3052+ return 0;
3053+ }
3054+ break;
3055+ case PARSE_POST:
3056+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3057+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
3058+ return 0;
3059+ }
3060+ break;
3061+ }
3062+ prev_index = index;
3063+ }
3064+
3065+ }
3066+
3067+ /* Drop this variable if it exceeds the array depth limit */
3068+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3069+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
3070+ return 0;
3071+ }
3072+ switch (arg) {
3073+ case PARSE_GET:
3074+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
3075+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
3076+ return 0;
3077+ }
3078+ break;
3079+ case PARSE_COOKIE:
3080+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
3081+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
3082+ return 0;
3083+ }
3084+ break;
3085+ case PARSE_POST:
3086+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3087+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
3088+ return 0;
3089+ }
3090+ break;
3091+ }
3092+
3093+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3094+ /* This is to protect several silly scripts that do globalizing themself */
3095+
3096+ switch (var_len) {
3097+ case 18:
3098+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
3099+ break;
3100+ case 17:
3101+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
3102+ break;
3103+ case 16:
3104+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
3105+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
3106+ break;
3107+ case 15:
3108+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
3109+ break;
3110+ case 14:
3111+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
3112+ break;
3113+ case 13:
3114+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
3115+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
3116+ break;
3117+ case 8:
3118+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
3119+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
3120+ break;
3121+ case 7:
3122+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
3123+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
3124+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
3125+ break;
3126+ case 6:
3127+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
3128+ break;
3129+ case 5:
3130+ if (memcmp(var, "_POST", 5)==0) goto protected_varname;
3131+ break;
3132+ case 4:
3133+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
3134+ if (memcmp(var, "_GET", 4)==0) goto protected_varname;
3135+ break;
3136+ }
3137+
3138+ /* Okay let PHP register this variable */
3139+ VARFILTER_G(cur_request_variables)++;
3140+ switch (arg) {
3141+ case PARSE_GET:
3142+ VARFILTER_G(cur_get_vars)++;
3143+ break;
3144+ case PARSE_COOKIE:
3145+ VARFILTER_G(cur_cookie_vars)++;
3146+ break;
3147+ case PARSE_POST:
3148+ VARFILTER_G(cur_post_vars)++;
3149+ break;
3150+ }
3151+
3152+ if (new_val_len) {
3153+ *new_val_len = val_len;
3154+ }
3155+
3156+ return 1;
3157+protected_varname:
3158+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
3159+ return 0;
3160+}
3161+/* }}} */
3162+
3163+/*
3164+ * Local variables:
3165+ * tab-width: 4
3166+ * c-basic-offset: 4
3167+ * End:
3168+ * vim600: noet sw=4 ts=4 fdm=marker
3169+ * vim<600: noet sw=4 ts=4
3170+ */
3171+
3172+
3173diff -Nura php-4.4.0/main/fopen_wrappers.c hardening-patch-4.4.0-0.4.2/main/fopen_wrappers.c
3174--- php-4.4.0/main/fopen_wrappers.c 2005-02-03 00:44:07.000000000 +0100
3175+++ hardening-patch-4.4.0-0.4.2/main/fopen_wrappers.c 2005-09-07 18:40:29.094947192 +0200
3176@@ -166,6 +166,21 @@
3177 char *pathbuf;
3178 char *ptr;
3179 char *end;
3180+ char path_copy[MAXPATHLEN];
3181+ int path_len;
3182+
3183+ /* Special case path ends with a trailing slash */
3184+ path_len = strlen(path);
3185+ if (path_len >= MAXPATHLEN) {
3186+ errno = EPERM; /* we deny permission to open it */
3187+ return -1;
3188+ }
3189+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
3190+ memcpy(path_copy, path, path_len+1);
3191+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
3192+ path_copy[path_len] = '\0';
3193+ path = (const char *)&path_copy;
3194+ }
3195
3196 pathbuf = estrdup(PG(open_basedir));
3197
3198diff -Nura php-4.4.0/main/hardened_globals.h hardening-patch-4.4.0-0.4.2/main/hardened_globals.h
3199--- php-4.4.0/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
3200+++ hardening-patch-4.4.0-0.4.2/main/hardened_globals.h 2005-09-07 18:40:29.094947192 +0200
3201@@ -0,0 +1,60 @@
3202+/*
3203+ +----------------------------------------------------------------------+
3204+ | Hardening-Patch for PHP |
3205+ +----------------------------------------------------------------------+
3206+ | Copyright (c) 2004-2005 Stefan Esser |
3207+ +----------------------------------------------------------------------+
3208+ | This source file is subject to version 2.02 of the PHP license, |
3209+ | that is bundled with this package in the file LICENSE, and is |
3210+ | available at through the world-wide-web at |
3211+ | http://www.php.net/license/2_02.txt. |
3212+ | If you did not receive a copy of the PHP license and are unable to |
3213+ | obtain it through the world-wide-web, please send a note to |
3214+ | license@php.net so we can mail you a copy immediately. |
3215+ +----------------------------------------------------------------------+
3216+ | Author: Stefan Esser <sesser@hardened-php.net> |
3217+ +----------------------------------------------------------------------+
3218+ */
3219+
3220+#ifndef HARDENED_GLOBALS_H
3221+#define HARDENED_GLOBALS_H
3222+
3223+typedef struct _hardened_globals hardened_globals_struct;
3224+
3225+#ifdef ZTS
3226+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
3227+extern int hardened_globals_id;
3228+#else
3229+# define HG(v) (hardened_globals.v)
3230+extern struct _hardened_globals hardened_globals;
3231+#endif
3232+
3233+
3234+struct _hardened_globals {
3235+#if HARDENING_PATCH_MM_PROTECT
3236+ unsigned int canary_1;
3237+ unsigned int canary_2;
3238+#endif
3239+#if HARDENING_PATCH_LL_PROTECT
3240+ unsigned int canary_3;
3241+ unsigned int canary_4;
3242+ unsigned int ll_canary_inited;
3243+#endif
3244+ zend_bool hphp_sql_bailout_on_error;
3245+ zend_bool hphp_multiheader;
3246+ HashTable *eval_whitelist;
3247+ HashTable *eval_blacklist;
3248+ HashTable *func_whitelist;
3249+ HashTable *func_blacklist;
3250+ unsigned int dummy;
3251+};
3252+
3253+
3254+#endif /* HARDENED_GLOBALS_H */
3255+
3256+/*
3257+ * Local variables:
3258+ * tab-width: 4
3259+ * c-basic-offset: 4
3260+ * End:
3261+ */
3262diff -Nura php-4.4.0/main/hardening_patch.c hardening-patch-4.4.0-0.4.2/main/hardening_patch.c
3263--- php-4.4.0/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100
3264+++ hardening-patch-4.4.0-0.4.2/main/hardening_patch.c 2005-09-07 18:43:50.698298824 +0200
3265@@ -0,0 +1,323 @@
3266+/*
3267+ +----------------------------------------------------------------------+
3268+ | Hardening Patch for PHP |
3269+ +----------------------------------------------------------------------+
3270+ | Copyright (c) 2004-2005 Stefan Esser |
3271+ +----------------------------------------------------------------------+
3272+ | This source file is subject to version 2.02 of the PHP license, |
3273+ | that is bundled with this package in the file LICENSE, and is |
3274+ | available at through the world-wide-web at |
3275+ | http://www.php.net/license/2_02.txt. |
3276+ | If you did not receive a copy of the PHP license and are unable to |
3277+ | obtain it through the world-wide-web, please send a note to |
3278+ | license@php.net so we can mail you a copy immediately. |
3279+ +----------------------------------------------------------------------+
3280+ | Author: Stefan Esser <sesser@hardened-php.net> |
3281+ +----------------------------------------------------------------------+
3282+ */
3283+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
3284+
3285+#include "php.h"
3286+
3287+#include <stdio.h>
3288+#include <stdlib.h>
3289+
3290+#if HAVE_UNISTD_H
3291+#include <unistd.h>
3292+#endif
3293+#include "SAPI.h"
3294+#include "php_globals.h"
3295+
3296+#if HARDENING_PATCH
3297+
3298+#ifdef HAVE_SYS_SOCKET_H
3299+#include <sys/socket.h>
3300+#endif
3301+
3302+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
3303+#undef AF_UNIX
3304+#endif
3305+
3306+#if defined(AF_UNIX)
3307+#include <sys/un.h>
3308+#endif
3309+
3310+#define SYSLOG_PATH "/dev/log"
3311+
3312+#include "snprintf.h"
3313+
3314+#include "hardening_patch.h"
3315+
3316+#ifdef ZTS
3317+#include "hardened_globals.h"
3318+int hardened_globals_id;
3319+#else
3320+struct _hardened_globals hardened_globals;
3321+#endif
3322+
3323+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
3324+{
3325+ memset(hardened_globals, 0, sizeof(*hardened_globals));
3326+}
3327+
3328+
3329+PHPAPI void hardened_startup()
3330+{
3331+#ifdef ZTS
3332+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
3333+#else
3334+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
3335+#endif
3336+}
3337+
3338+char *loglevel2string(int loglevel)
3339+{
3340+ switch (loglevel) {
3341+ case S_FILES:
3342+ return "FILES";
3343+ case S_INCLUDE:
3344+ return "INCLUDE";
3345+ case S_MEMORY:
3346+ return "MEMORY";
3347+ case S_MISC:
3348+ return "MISC";
3349+ case S_SQL:
3350+ return "SQL";
3351+ case S_EXECUTOR:
3352+ return "EXECUTOR";
3353+ case S_VARS:
3354+ return "VARS";
3355+ default:
3356+ return "UNKNOWN";
3357+ }
3358+}
3359+
3360+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
3361+{
3362+#if defined(AF_UNIX)
3363+ int s, r, i=0;
3364+ struct sockaddr_un saun;
3365+ char buf[4096+64];
3366+ char error[4096+100];
3367+ char *ip_address;
3368+ char *fname;
3369+ int lineno;
3370+ va_list ap;
3371+ TSRMLS_FETCH();
3372+
3373+ if (EG(hphp_log_use_x_forwarded_for)) {
3374+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
3375+ if (ip_address == NULL) {
3376+ ip_address = "X-FORWARDED-FOR not set";
3377+ }
3378+ } else {
3379+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
3380+ if (ip_address == NULL) {
3381+ ip_address = "REMOTE_ADDR not set";
3382+ }
3383+ }
3384+
3385+
3386+ va_start(ap, fmt);
3387+ ap_php_vsnprintf(error, sizeof(error), fmt, ap);
3388+ va_end(ap);
3389+ while (error[i]) {
3390+ if (error[i] < 32) error[i] = '.';
3391+ i++;
3392+ }
3393+
3394+ if (zend_is_executing(TSRMLS_C)) {
3395+ lineno = zend_get_executed_lineno(TSRMLS_C);
3396+ fname = zend_get_executed_filename(TSRMLS_C);
3397+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
3398+ } else {
3399+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
3400+ if (fname==NULL) {
3401+ fname = "unknown";
3402+ }
3403+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
3404+ }
3405+
3406+ /* Syslog-Logging disabled? */
3407+ if ((EG(hphp_log_syslog) & loglevel)==0) {
3408+ goto log_sapi;
3409+ }
3410+
3411+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
3412+
3413+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
3414+ if (s == -1) {
3415+ goto log_sapi;
3416+ }
3417+
3418+ memset(&saun, 0, sizeof(saun));
3419+ saun.sun_family = AF_UNIX;
3420+ strcpy(saun.sun_path, SYSLOG_PATH);
3421+ /*saun.sun_len = sizeof(saun);*/
3422+
3423+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
3424+ if (r) {
3425+ close(s);
3426+ s = socket(AF_UNIX, SOCK_STREAM, 0);
3427+ if (s == -1) {
3428+ goto log_sapi;
3429+ }
3430+
3431+ memset(&saun, 0, sizeof(saun));
3432+ saun.sun_family = AF_UNIX;
3433+ strcpy(saun.sun_path, SYSLOG_PATH);
3434+ /*saun.sun_len = sizeof(saun);*/
3435+
3436+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
3437+ if (r) {
3438+ close(s);
3439+ goto log_sapi;
3440+ }
3441+ }
3442+ send(s, error, strlen(error), 0);
3443+
3444+ close(s);
3445+
3446+log_sapi:
3447+ /* SAPI Logging activated? */
3448+ if ((EG(hphp_log_syslog) & loglevel)!=0) {
3449+ sapi_module.log_message(buf);
3450+ }
3451+
3452+log_script:
3453+ /* script logging activaed? */
3454+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
3455+ char cmd[8192], *cmdpos, *bufpos;
3456+ FILE *in;
3457+ int space;
3458+
3459+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
3460+ space = sizeof(cmd) - strlen(cmd);
3461+ cmdpos = cmd + strlen(cmd);
3462+ bufpos = buf;
3463+ if (space <= 1) return;
3464+ while (space > 2 && *bufpos) {
3465+ if (*bufpos == '\'') {
3466+ if (space<=5) break;
3467+ *cmdpos++ = '\'';
3468+ *cmdpos++ = '\\';
3469+ *cmdpos++ = '\'';
3470+ *cmdpos++ = '\'';
3471+ bufpos++;
3472+ space-=4;
3473+ } else {
3474+ *cmdpos++ = *bufpos++;
3475+ space--;
3476+ }
3477+ }
3478+ *cmdpos++ = '\'';
3479+ *cmdpos = 0;
3480+
3481+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
3482+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname));
3483+ return;
3484+ }
3485+ /* read and forget the result */
3486+ while (1) {
3487+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
3488+ if (readbytes<=0) {
3489+ break;
3490+ }
3491+ }
3492+ pclose(in);
3493+ }
3494+
3495+#endif
3496+}
3497+#endif
3498+
3499+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
3500+
3501+/* will be replaced later with more compatible method */
3502+PHPAPI unsigned int php_canary()
3503+{
3504+ time_t t;
3505+ unsigned int canary;
3506+ int fd;
3507+
3508+ fd = open("/dev/urandom", 0);
3509+ if (fd != -1) {
3510+ int r = read(fd, &canary, sizeof(canary));
3511+ close(fd);
3512+ if (r == sizeof(canary)) {
3513+ return (canary);
3514+ }
3515+ }
3516+ /* not good but we never want to do this */
3517+ time(&t);
3518+ canary = *(unsigned int *)&t + getpid() << 16;
3519+ return (canary);
3520+}
3521+#endif
3522+
3523+#if HARDENING_PATCH_INC_PROTECT
3524+
3525+PHPAPI int php_is_valid_include(zval *z)
3526+{
3527+ char *filename;
3528+ int len, i;
3529+ TSRMLS_FETCH();
3530+
3531+ /* must be of type string */
3532+ if (z->type != IS_STRING || z->value.str.val == NULL) {
3533+ return (0);
3534+ }
3535+
3536+ /* short cut */
3537+ filename = z->value.str.val;
3538+ len = z->value.str.len;
3539+
3540+ /* 1. must be shorter than MAXPATHLEN */
3541+ if (len > MAXPATHLEN) {
3542+ char *fname = estrndup(filename, len);
3543+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
3544+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
3545+ efree(fname);
3546+ return (0);
3547+ }
3548+
3549+ /* 2. must not be cutted */
3550+ if (len != strlen(filename)) {
3551+ char *fname = estrndup(filename, len);
3552+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
3553+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
3554+ efree(fname);
3555+ return (0);
3556+ }
3557+
3558+ /* 3. must not be a URL */
3559+ if (strstr(filename, "://")) {
3560+ char *fname = estrndup(filename, len);
3561+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
3562+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
3563+ efree(fname);
3564+ return (0);
3565+ }
3566+
3567+ /* 4. must not be an uploaded file */
3568+ if (SG(rfc1867_uploaded_files)) {
3569+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
3570+ php_security_log(S_INCLUDE, "Include filename is an uploaded file");
3571+ return (0);
3572+ }
3573+ }
3574+
3575+ /* passed all tests */
3576+ return (1);
3577+}
3578+
3579+#endif
3580+
3581+/*
3582+ * Local variables:
3583+ * tab-width: 4
3584+ * c-basic-offset: 4
3585+ * End:
3586+ * vim600: sw=4 ts=4 fdm=marker
3587+ * vim<600: sw=4 ts=4
3588+ */
3589diff -Nura php-4.4.0/main/hardening_patch.h hardening-patch-4.4.0-0.4.2/main/hardening_patch.h
3590--- php-4.4.0/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100
3591+++ hardening-patch-4.4.0-0.4.2/main/hardening_patch.h 2005-09-07 18:43:16.603482024 +0200
3592@@ -0,0 +1,46 @@
3593+/*
3594+ +----------------------------------------------------------------------+
3595+ | Hardening Patch for PHP |
3596+ +----------------------------------------------------------------------+
3597+ | Copyright (c) 2004-2005 Stefan Esser |
3598+ +----------------------------------------------------------------------+
3599+ | This source file is subject to version 2.02 of the PHP license, |
3600+ | that is bundled with this package in the file LICENSE, and is |
3601+ | available at through the world-wide-web at |
3602+ | http://www.php.net/license/2_02.txt. |
3603+ | If you did not receive a copy of the PHP license and are unable to |
3604+ | obtain it through the world-wide-web, please send a note to |
3605+ | license@php.net so we can mail you a copy immediately. |
3606+ +----------------------------------------------------------------------+
3607+ | Author: Stefan Esser <sesser@hardened-php.net> |
3608+ +----------------------------------------------------------------------+
3609+ */
3610+
3611+#ifndef HARDENING_PATCH_H
3612+#define HARDENING_PATCH_H
3613+
3614+#include "zend.h"
3615+
3616+#if HARDENING_PATCH
3617+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
3618+PHPAPI void hardened_startup();
3619+#define HARDENING_PATCH_VERSION "0.4.2"
3620+
3621+#endif
3622+
3623+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
3624+PHPAPI unsigned int php_canary();
3625+#endif
3626+
3627+#if HARDENING_PATCH_INC_PROTECT
3628+PHPAPI int php_is_valid_include(zval *z);
3629+#endif
3630+
3631+#endif /* HARDENING_PATCH_H */
3632+
3633+/*
3634+ * Local variables:
3635+ * tab-width: 4
3636+ * c-basic-offset: 4
3637+ * End:
3638+ */
3639diff -Nura php-4.4.0/main/hardening_patch.m4 hardening-patch-4.4.0-0.4.2/main/hardening_patch.m4
3640--- php-4.4.0/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100
3641+++ hardening-patch-4.4.0-0.4.2/main/hardening_patch.m4 2005-09-07 18:40:29.097946736 +0200
3642@@ -0,0 +1,95 @@
3643+dnl
3644+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
3645+dnl
3646+dnl This file contains Hardening Patch for PHP specific autoconf functions.
3647+dnl
3648+
3649+AC_ARG_ENABLE(hardening-patch-mm-protect,
3650+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[
3651+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
3652+],[
3653+ DO_HARDENING_PATCH_MM_PROTECT=yes
3654+])
3655+
3656+AC_ARG_ENABLE(hardening-patch-ll-protect,
3657+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[
3658+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
3659+],[
3660+ DO_HARDENING_PATCH_LL_PROTECT=yes
3661+])
3662+
3663+AC_ARG_ENABLE(hardening-patch-inc-protect,
3664+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[
3665+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
3666+],[
3667+ DO_HARDENING_PATCH_INC_PROTECT=yes
3668+])
3669+
3670+AC_ARG_ENABLE(hardening-patch-fmt-protect,
3671+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[
3672+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
3673+],[
3674+ DO_HARDENING_PATCH_FMT_PROTECT=yes
3675+])
3676+
3677+AC_ARG_ENABLE(hardening-patch-hash-protect,
3678+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[
3679+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
3680+],[
3681+ DO_HARDENING_PATCH_HASH_PROTECT=yes
3682+])
3683+
3684+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
3685+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
3686+
3687+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
3688+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
3689+
3690+AC_MSG_CHECKING(whether to protect include/require statements)
3691+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
3692+
3693+AC_MSG_CHECKING(whether to protect PHP Format String functions)
3694+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
3695+
3696+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
3697+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
3698+
3699+
3700+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3701+
3702+
3703+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
3704+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3705+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
3706+else
3707+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
3708+fi
3709+
3710+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
3711+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3712+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
3713+else
3714+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
3715+fi
3716+
3717+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
3718+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3719+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
3720+else
3721+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
3722+fi
3723+
3724+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
3725+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3726+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
3727+else
3728+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
3729+fi
3730+
3731+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
3732+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3733+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
3734+else
3735+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
3736+fi
3737+
3738diff -Nura php-4.4.0/main/main.c hardening-patch-4.4.0-0.4.2/main/main.c
3739--- php-4.4.0/main/main.c 2005-06-20 21:59:43.000000000 +0200
3740+++ hardening-patch-4.4.0-0.4.2/main/main.c 2005-09-07 18:40:29.098946584 +0200
3741@@ -100,6 +100,10 @@
3742 PHPAPI int core_globals_id;
3743 #endif
3744
3745+#if HARDENING_PATCH
3746+#include "hardened_globals.h"
3747+#endif
3748+
3749 #define ERROR_BUF_LEN 1024
3750
3751 typedef struct {
3752@@ -150,10 +154,33 @@
3753 */
3754 static PHP_INI_MH(OnChangeMemoryLimit)
3755 {
3756+#if HARDENING_PATCH
3757+ long orig_memory_limit;
3758+
3759+ if (entry->modified) {
3760+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
3761+ } else {
3762+ orig_memory_limit = 1<<30;
3763+ }
3764+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
3765+ orig_memory_limit = 1<<30;
3766+ }
3767+#endif
3768 if (new_value) {
3769 PG(memory_limit) = zend_atoi(new_value, new_value_length);
3770+#if HARDENING_PATCH
3771+ if (PG(memory_limit) > orig_memory_limit) {
3772+ PG(memory_limit) = orig_memory_limit;
3773+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
3774+ return FAILURE;
3775+ }
3776+#endif
3777 } else {
3778+#if HARDENING_PATCH
3779+ PG(memory_limit) = orig_memory_limit;
3780+#else
3781 PG(memory_limit) = 1<<30; /* effectively, no limit */
3782+#endif
3783 }
3784 return zend_set_memory_limit(PG(memory_limit));
3785 }
3786@@ -1096,6 +1123,10 @@
3787 tsrm_ls = ts_resource(0);
3788 #endif
3789
3790+#if HARDENING_PATCH
3791+ hardened_startup();
3792+#endif
3793+
3794 sapi_initialize_empty_request(TSRMLS_C);
3795 sapi_activate(TSRMLS_C);
3796
3797@@ -1108,6 +1139,12 @@
3798 php_output_startup();
3799 php_output_activate(TSRMLS_C);
3800
3801+#if HARDENING_PATCH_INC_PROTECT
3802+ zuf.is_valid_include = php_is_valid_include;
3803+#endif
3804+#if HARDENING_PATCH
3805+ zuf.security_log_function = php_security_log;
3806+#endif
3807 zuf.error_function = php_error_cb;
3808 zuf.printf_function = php_printf;
3809 zuf.write_function = php_body_write_wrapper;
3810@@ -1209,6 +1246,10 @@
3811 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
3812 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);
3813 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
3814+#if HARDENING_PATCH
3815+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
3816+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
3817+#endif
3818 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
3819 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
3820 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
3821@@ -1316,7 +1357,7 @@
3822 */
3823 static inline void php_register_server_variables(TSRMLS_D)
3824 {
3825- zval *array_ptr=NULL;
3826+ zval *array_ptr=NULL, *vptr;
3827
3828 ALLOC_ZVAL(array_ptr);
3829 array_init(array_ptr);
3830@@ -1326,6 +1367,16 @@
3831 /* Server variables */
3832 if (sapi_module.register_server_variables) {
3833 sapi_module.register_server_variables(array_ptr TSRMLS_CC);
3834+ if (zend_hash_find(array_ptr->value.ht, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), (void **)&vptr)==SUCCESS) {
3835+ char *str;
3836+ if (vptr->type != IS_STRING) {
3837+ str = "Array";
3838+ } else {
3839+ str = vptr->value.str.val;
3840+ }
3841+ php_security_log(S_VARS, "Attacker tried to overwrite HTTP_RAW_POST_DATA with '%s' through a HTTP header", str);
3842+ zend_hash_del(array_ptr->value.ht, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"));
3843+ }
3844 }
3845
3846 /* PHP Authentication support */
3847diff -Nura php-4.4.0/main/php_config.h.in hardening-patch-4.4.0-0.4.2/main/php_config.h.in
3848--- php-4.4.0/main/php_config.h.in 2005-07-11 12:07:41.000000000 +0200
3849+++ hardening-patch-4.4.0-0.4.2/main/php_config.h.in 2005-09-07 18:40:29.099946432 +0200
3850@@ -860,6 +860,39 @@
3851 /* Enabling BIND8 compatibility for Panther */
3852 #undef BIND_8_COMPAT
3853
3854+/* Hardening-Patch */
3855+#undef HARDENING_PATCH
3856+
3857+/* Memory Manager Protection */
3858+#undef HARDENING_PATCH_MM_PROTECT
3859+
3860+/* Memory Manager Protection */
3861+#undef HARDENING_PATCH_MM_PROTECT
3862+
3863+/* Linked List Protection */
3864+#undef HARDENING_PATCH_LL_PROTECT
3865+
3866+/* Linked List Protection */
3867+#undef HARDENING_PATCH_LL_PROTECT
3868+
3869+/* Include/Require Protection */
3870+#undef HARDENING_PATCH_INC_PROTECT
3871+
3872+/* Include/Require Protection */
3873+#undef HARDENING_PATCH_INC_PROTECT
3874+
3875+/* Fmt String Protection */
3876+#undef HARDENING_PATCH_FMT_PROTECT
3877+
3878+/* Fmt String Protection */
3879+#undef HARDENING_PATCH_FMT_PROTECT
3880+
3881+/* HashTable DTOR Protection */
3882+#undef HARDENING_PATCH_HASH_PROTECT
3883+
3884+/* HashTable DTOR Protection */
3885+#undef HARDENING_PATCH_HASH_PROTECT
3886+
3887 /* Whether you have AOLserver */
3888 #undef HAVE_AOLSERVER
3889
3890@@ -1143,6 +1176,12 @@
3891 /* Define if you have the getaddrinfo function */
3892 #undef HAVE_GETADDRINFO
3893
3894+/* Whether realpath is broken */
3895+#undef PHP_BROKEN_REALPATH
3896+
3897+/* Whether realpath is broken */
3898+#undef PHP_BROKEN_REALPATH
3899+
3900 /* Whether system headers declare timezone */
3901 #undef HAVE_DECLARED_TIMEZONE
3902
3903diff -Nura php-4.4.0/main/php_content_types.c hardening-patch-4.4.0-0.4.2/main/php_content_types.c
3904--- php-4.4.0/main/php_content_types.c 2002-12-31 17:26:14.000000000 +0100
3905+++ hardening-patch-4.4.0-0.4.2/main/php_content_types.c 2005-09-07 18:40:29.099946432 +0200
3906@@ -77,6 +77,7 @@
3907 sapi_register_post_entries(php_post_entries);
3908 sapi_register_default_post_reader(php_default_post_reader);
3909 sapi_register_treat_data(php_default_treat_data);
3910+ sapi_register_input_filter(php_default_input_filter);
3911 return SUCCESS;
3912 }
3913 /* }}} */
3914diff -Nura php-4.4.0/main/php.h hardening-patch-4.4.0-0.4.2/main/php.h
3915--- php-4.4.0/main/php.h 2005-04-17 15:37:29.000000000 +0200
3916+++ hardening-patch-4.4.0-0.4.2/main/php.h 2005-09-07 18:40:29.100946280 +0200
3917@@ -35,11 +35,19 @@
3918 #include "zend_qsort.h"
3919 #include "php_compat.h"
3920
3921+
3922 #include "zend_API.h"
3923
3924 #undef sprintf
3925 #define sprintf php_sprintf
3926
3927+#if HARDENING_PATCH
3928+#if HAVE_REALPATH
3929+#undef realpath
3930+#define realpath php_realpath
3931+#endif
3932+#endif
3933+
3934 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
3935 #undef PHP_DEBUG
3936 #define PHP_DEBUG ZEND_DEBUG
3937@@ -435,6 +443,10 @@
3938 #endif
3939 #endif /* !XtOffsetOf */
3940
3941+#if HARDENING_PATCH
3942+#include "hardening_patch.h"
3943+#endif
3944+
3945 #endif
3946
3947 /*
3948diff -Nura php-4.4.0/main/php_variables.c hardening-patch-4.4.0-0.4.2/main/php_variables.c
3949--- php-4.4.0/main/php_variables.c 2005-05-17 20:42:35.000000000 +0200
3950+++ hardening-patch-4.4.0-0.4.2/main/php_variables.c 2005-09-07 18:40:29.100946280 +0200
3951@@ -225,17 +225,28 @@
3952 while (var) {
3953 val = strchr(var, '=');
3954 if (val) { /* have a value */
3955- int val_len;
3956+ unsigned int val_len, new_val_len;
3957
3958 *val++ = '\0';
3959 php_url_decode(var, strlen(var));
3960 val_len = php_url_decode(val, strlen(val));
3961- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
3962+ val = estrndup(val, val_len);
3963+ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) {
3964+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
3965+ }
3966+ efree(val);
3967 }
3968 var = php_strtok_r(NULL, "&", &strtok_buf);
3969 }
3970 }
3971
3972+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter)
3973+{
3974+ /* TODO: check .ini setting here and apply user-defined input filter */
3975+ *new_val_len = val_len;
3976+ return 1;
3977+}
3978+
3979 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
3980 {
3981 char *res = NULL, *var, *val, *separator=NULL;
3982@@ -313,15 +324,26 @@
3983 while (var) {
3984 val = strchr(var, '=');
3985 if (val) { /* have a value */
3986- int val_len;
3987+ unsigned int val_len, new_val_len;
3988
3989 *val++ = '\0';
3990 php_url_decode(var, strlen(var));
3991 val_len = php_url_decode(val, strlen(val));
3992- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
3993+ val = estrndup(val, val_len);
3994+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
3995+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
3996+ }
3997+ efree(val);
3998 } else {
3999+ unsigned int val_len, new_val_len;
4000+
4001 php_url_decode(var, strlen(var));
4002- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC);
4003+ val_len = 0;
4004+ val = estrndup("", 0);
4005+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
4006+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
4007+ }
4008+ efree(val);
4009 }
4010 var = php_strtok_r(NULL, separator, &strtok_buf);
4011 }
4012diff -Nura php-4.4.0/main/rfc1867.c hardening-patch-4.4.0-0.4.2/main/rfc1867.c
4013--- php-4.4.0/main/rfc1867.c 2005-04-04 16:59:58.000000000 +0200
4014+++ hardening-patch-4.4.0-0.4.2/main/rfc1867.c 2005-09-07 18:40:29.101946128 +0200
4015@@ -127,6 +127,7 @@
4016 #define UPLOAD_ERROR_C 3 /* Partially uploaded */
4017 #define UPLOAD_ERROR_D 4 /* No file uploaded */
4018 #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
4019+#define UPLOAD_ERROR_F 7 /* Filter forbids upload */
4020
4021 void php_rfc1867_register_constants(TSRMLS_D)
4022 {
4023@@ -136,6 +137,7 @@
4024 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_PARTIAL", UPLOAD_ERROR_C, CONST_CS | CONST_PERSISTENT);
4025 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT);
4026 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT);
4027+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT);
4028 }
4029
4030 static void normalize_protected_variable(char *varname TSRMLS_DC)
4031@@ -844,6 +846,7 @@
4032 char buff[FILLUNIT];
4033 char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
4034 int blen=0, wlen=0;
4035+ unsigned long offset;
4036
4037 zend_llist_clean(&header);
4038
4039@@ -891,21 +894,24 @@
4040 if (!filename && param) {
4041
4042 char *value = multipart_buffer_read_body(mbuff TSRMLS_CC);
4043+ unsigned int new_val_len; /* Dummy variable */
4044
4045 if (!value) {
4046 value = estrdup("");
4047 }
4048
4049+ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) {
4050 #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
4051- if (php_mb_encoding_translation(TSRMLS_C)) {
4052- php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
4053- &num_vars, &num_vars_max TSRMLS_CC);
4054- } else {
4055- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4056- }
4057+ if (php_mb_encoding_translation(TSRMLS_C)) {
4058+ php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
4059+ &num_vars, &num_vars_max TSRMLS_CC);
4060+ } else {
4061+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4062+ }
4063 #else
4064- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4065+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4066 #endif
4067+ }
4068 if (!strcasecmp(param, "MAX_FILE_SIZE")) {
4069 max_file_size = atol(value);
4070 }
4071@@ -981,6 +987,11 @@
4072 cancel_upload = UPLOAD_ERROR_D;
4073 }
4074
4075+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
4076+ cancel_upload = UPLOAD_ERROR_F;
4077+ }
4078+
4079+ offset = 0;
4080 while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff) TSRMLS_CC)))
4081 {
4082 if (PG(upload_max_filesize) > 0 && total_bytes > PG(upload_max_filesize)) {
4083@@ -990,6 +1001,11 @@
4084 sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename);
4085 cancel_upload = UPLOAD_ERROR_B;
4086 } else if (blen > 0) {
4087+
4088+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
4089+ cancel_upload = UPLOAD_ERROR_F;
4090+ }
4091+
4092 wlen = write(fd, buff, blen);
4093
4094 if (wlen < blen) {
4095@@ -997,6 +1013,7 @@
4096 cancel_upload = UPLOAD_ERROR_C;
4097 } else {
4098 total_bytes += wlen;
4099+ offset += wlen;
4100 }
4101 }
4102 }
4103@@ -1011,6 +1028,10 @@
4104 }
4105 #endif
4106
4107+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
4108+ cancel_upload = UPLOAD_ERROR_F;
4109+ }
4110+
4111 if (cancel_upload) {
4112 if (temp_filename) {
4113 if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
4114diff -Nura php-4.4.0/main/SAPI.c hardening-patch-4.4.0-0.4.2/main/SAPI.c
4115--- php-4.4.0/main/SAPI.c 2005-02-22 15:46:24.000000000 +0100
4116+++ hardening-patch-4.4.0-0.4.2/main/SAPI.c 2005-09-07 18:40:29.102945976 +0200
4117@@ -831,6 +831,31 @@
4118 return SUCCESS;
4119 }
4120
4121+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))
4122+{
4123+ sapi_module.input_filter = input_filter;
4124+ return SUCCESS;
4125+}
4126+
4127+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
4128+{
4129+ sapi_module.pre_upload_filter = pre_upload_filter;
4130+ return SUCCESS;
4131+}
4132+
4133+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))
4134+{
4135+ sapi_module.upload_content_filter = upload_content_filter;
4136+ return SUCCESS;
4137+}
4138+
4139+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
4140+{
4141+ sapi_module.post_upload_filter = post_upload_filter;
4142+ return SUCCESS;
4143+}
4144+
4145+
4146
4147 SAPI_API int sapi_flush(TSRMLS_D)
4148 {
4149diff -Nura php-4.4.0/main/SAPI.h hardening-patch-4.4.0-0.4.2/main/SAPI.h
4150--- php-4.4.0/main/SAPI.h 2003-04-09 22:27:55.000000000 +0200
4151+++ hardening-patch-4.4.0-0.4.2/main/SAPI.h 2005-09-07 18:40:29.103945824 +0200
4152@@ -101,9 +101,10 @@
4153 char *current_user;
4154 int current_user_length;
4155
4156- /* this is necessary for CLI module */
4157- int argc;
4158- char **argv;
4159+ /* this is necessary for CLI module */
4160+ int argc;
4161+ char **argv;
4162+
4163 } sapi_request_info;
4164
4165
4166@@ -177,6 +178,10 @@
4167 SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry);
4168 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D));
4169 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
4170+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));
4171+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
4172+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));
4173+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
4174
4175 SAPI_API int sapi_flush(TSRMLS_D);
4176 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
4177@@ -238,8 +243,15 @@
4178 int (*get_target_uid)(uid_t * TSRMLS_DC);
4179 int (*get_target_gid)(gid_t * TSRMLS_DC);
4180
4181+ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
4182+
4183+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
4184+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
4185+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
4186+
4187 void (*ini_defaults)(HashTable *configuration_hash);
4188 int phpinfo_as_text;
4189+
4190 };
4191
4192
4193@@ -262,16 +274,26 @@
4194
4195 #define SAPI_DEFAULT_MIMETYPE "text/html"
4196 #define SAPI_DEFAULT_CHARSET ""
4197+
4198+#if HARDENING_PATCH
4199+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
4200+#else
4201 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
4202+#endif
4203
4204 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
4205 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
4206
4207 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
4208+#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)
4209+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
4210+#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)
4211+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
4212
4213 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
4214 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
4215 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data);
4216+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter);
4217
4218 #define STANDARD_SAPI_MODULE_PROPERTIES
4219
4220diff -Nura php-4.4.0/main/snprintf.c hardening-patch-4.4.0-0.4.2/main/snprintf.c
4221--- php-4.4.0/main/snprintf.c 2005-04-08 07:44:53.000000000 +0200
4222+++ hardening-patch-4.4.0-0.4.2/main/snprintf.c 2005-09-07 18:40:29.103945824 +0200
4223@@ -1013,7 +1013,11 @@
4224
4225
4226 case 'n':
4227+#if HARDENING_PATCH_FMT_PROTECT
4228+ php_security_log(S_MISC, "'n' specifier within format string");
4229+#else
4230 *(va_arg(ap, int *)) = cc;
4231+#endif
4232 break;
4233
4234 /*
4235diff -Nura php-4.4.0/main/spprintf.c hardening-patch-4.4.0-0.4.2/main/spprintf.c
4236--- php-4.4.0/main/spprintf.c 2005-04-08 07:44:53.000000000 +0200
4237+++ hardening-patch-4.4.0-0.4.2/main/spprintf.c 2005-09-07 18:40:29.104945672 +0200
4238@@ -630,7 +630,11 @@
4239
4240
4241 case 'n':
4242+#if HARDENING_PATCH_FMT_PROTECT
4243+ php_security_log(S_MISC, "'n' specifier within format string");
4244+#else
4245 *(va_arg(ap, int *)) = xbuf->len;
4246+#endif
4247 break;
4248
4249 /*
4250diff -Nura php-4.4.0/pear/go-pear-list.php hardening-patch-4.4.0-0.4.2/pear/go-pear-list.php
4251--- php-4.4.0/pear/go-pear-list.php 2005-07-01 11:41:04.000000000 +0200
4252+++ hardening-patch-4.4.0-0.4.2/pear/go-pear-list.php 2005-09-07 19:03:13.095587576 +0200
4253@@ -8,7 +8,7 @@
4254 $packages = array(
4255 // required packages for the installer
4256 "PEAR" => "1.3.5",
4257-"XML_RPC" => "1.3.1",
4258+"XML_RPC" => "1.4.0",
4259 "Console_Getopt" => "1.2",
4260 "Archive_Tar" => "1.3.1",
4261
4262diff -Nura php-4.4.0/pear/packages/XML_RPC-1.3.1.tar hardening-patch-4.4.0-0.4.2/pear/packages/XML_RPC-1.3.1.tar
4263--- php-4.4.0/pear/packages/XML_RPC-1.3.1.tar 2005-07-01 11:42:14.000000000 +0200
4264+++ hardening-patch-4.4.0-0.4.2/pear/packages/XML_RPC-1.3.1.tar 1970-01-01 01:00:00.000000000 +0100
4265@@ -1,3733 +0,0 @@
4266-package2.xml
4267-<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">
4268- <name>XML_RPC</name>
4269- <channel>pear.php.net</channel>
4270- <summary>PHP implementation of the XML-RPC protocol</summary>
4271- <description>A PEAR-ified version of Useful Inc&apos;s XML-RPC for PHP.
4272-
4273-It has support for HTTP/HTTPS transport, proxies and authentication.</description>
4274- <lead>
4275- <name>Stig Bakken</name>
4276- <user>ssb</user>
4277- <email>stig@php.net</email>
4278- <active>no</active>
4279- </lead>
4280- <lead>
4281- <name>Daniel Convissor</name>
4282- <user>danielc</user>
4283- <email>danielc@php.net</email>
4284- <active>yes</active>
4285- </lead>
4286- <date>2005-06-29</date>
4287- <time>15:09:18</time>
4288- <version>
4289- <release>1.3.1</release>
4290- <api>1.3.0</api>
4291- </version>
4292- <stability>
4293- <release>stable</release>
4294- <api>stable</api>
4295- </stability>
4296- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4297- <notes>* Security fix. Update highly recommended!</notes>
4298- <contents>
4299- <dir name="/">
4300- <file md5sum="9b06c053e8e534f8d731eb90de2d0681" name="tests/protoport.php" role="test">
4301- <tasks:replace from="@package_version@" to="version" type="package-info" />
4302- </file>
4303- <file md5sum="74d1c90ae551d28bd40030fcc0b0f38d" name="tests/test_Dump.php" role="test">
4304- <tasks:replace from="@package_version@" to="version" type="package-info" />
4305- </file>
4306- <file baseinstalldir="XML/RPC" md5sum="5e2dfc5771116965655e07b4665563ce" name="Dump.php" role="php">
4307- <tasks:replace from="@package_version@" to="version" type="package-info" />
4308- </file>
4309- <file baseinstalldir="XML" md5sum="1e79cf06ae3ada5a6603c003ac0521e3" name="RPC.php" role="php">
4310- <tasks:replace from="@package_version@" to="version" type="package-info" />
4311- </file>
4312- <file baseinstalldir="XML/RPC" md5sum="6a750e3517d25ca01e685e8afe3976d6" name="Server.php" role="php">
4313- <tasks:replace from="@package_version@" to="version" type="package-info" />
4314- </file>
4315- </dir>
4316- </contents>
4317- <compatible>
4318- <name>PEAR</name>
4319- <channel>pear.php.net</channel>
4320- <min>1.4.0a1</min>
4321- <max>1.4.0a12</max>
4322- </compatible>
4323- <dependencies>
4324- <required>
4325- <php>
4326- <min>4.2.0</min>
4327- <max>6.0.0</max>
4328- </php>
4329- <pearinstaller>
4330- <min>1.4.0a1</min>
4331- </pearinstaller>
4332- </required>
4333- </dependencies>
4334- <phprelease />
4335- <changelog>
4336- <release>
4337- <version>
4338- <release>1.3.0RC3</release>
4339- <api>1.3.0</api>
4340- </version>
4341- <stability>
4342- <release>beta</release>
4343- <api>stable</api>
4344- </stability>
4345- <date>2005-05-10</date>
4346- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4347- <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.
4348-* XML_RPC_Message::getParam() now returns an XML_RPC_Response object upon error. Changed from Release 1.3.0RC2.
4349-* Add the XML_RPC_Value::isValue() method. For testing if an item is an XML_RPC_Value object.
4350-* 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.
4351-* Improve cross-platform operation by using PEAR::loadExtension() instead of dl().
4352-* Use &lt;br /&gt; instead of &lt;br&gt; in XML_RPC_Value::dump().</notes>
4353- </release>
4354- <release>
4355- <version>
4356- <release>1.3.0RC2</release>
4357- <api>1.3.0</api>
4358- </version>
4359- <stability>
4360- <release>beta</release>
4361- <api>beta</api>
4362- </stability>
4363- <date>2005-05-05</date>
4364- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4365- <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.
4366-* Handle improper requests to XML_RPC_Server::verifySignature(). Bug 4231.
4367-* Try to allow HTTP 100 responses if followed by a 200 response. Bug 4116.
4368-* Help Delphi users by making RPCMETHODNAME an alias for METHODNAME. Request 4205.</notes>
4369- </release>
4370- <release>
4371- <version>
4372- <release>1.3.0RC1</release>
4373- <api>1.3.0</api>
4374- </version>
4375- <stability>
4376- <release>beta</release>
4377- <api>beta</api>
4378- </stability>
4379- <date>2005-04-07</date>
4380- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4381- <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.
4382-* Add Fault Code 6: &quot;The requested method didn&apos;t return an XML_RPC_Response object.&quot; Request 4032.
4383-* Add the createServerPayload() and createServerHeaders() methods and the $server_payload and $server_headers properties. Request 3121.
4384-* 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.
4385-* Convert the parser handle to an integer before using it as an index for $XML_RPC_xh[$parser]. Reduces E_STRICT notices. Bug 3782.
4386-* Add createHeaders() method and $headers property to XML_RPC_Client to make testing easier.</notes>
4387- </release>
4388- <release>
4389- <version>
4390- <release>1.2.2</release>
4391- <api>1.2.0</api>
4392- </version>
4393- <stability>
4394- <release>stable</release>
4395- <api>stable</api>
4396- </stability>
4397- <date>2005-03-07</date>
4398- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4399- <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>
4400- </release>
4401- <release>
4402- <version>
4403- <release>1.2.1</release>
4404- <api>1.2.0</api>
4405- </version>
4406- <stability>
4407- <release>stable</release>
4408- <api>stable</api>
4409- </stability>
4410- <date>2005-03-01</date>
4411- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4412- <notes>* Add isset() check before examining the dispatch map. Bug 3658.</notes>
4413- </release>
4414- <release>
4415- <version>
4416- <release>1.2.0</release>
4417- <api>1.2.0</api>
4418- </version>
4419- <stability>
4420- <release>stable</release>
4421- <api>stable</api>
4422- </stability>
4423- <date>2005-02-27</date>
4424- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4425- <notes>* Provide the &quot;stable&quot; release.
4426-* Add package2.xml for compatibility with PEAR 1.4.0.
4427-* For changes since 1.1.0, see the changelogs for the various RC releases.</notes>
4428- </release>
4429- <release>
4430- <version>
4431- <release>1.2.0RC7</release>
4432- <api>1.2.0RC7</api>
4433- </version>
4434- <stability>
4435- <release>beta</release>
4436- <api>beta</api>
4437- </stability>
4438- <date>2005-02-22</date>
4439- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4440- <notes>* Add the setSendEncoding() method and $send_encoding
4441- property to XML_RPC_Message. Request 3537.
4442-* Allow class methods to be mapped using either syntax:
4443- &apos;function&apos; =&gt; &apos;hello::sayHello&apos;,
4444- or
4445- &apos;function&apos; =&gt; array(&apos;hello&apos;, &apos;sayhello&apos;),
4446- Bug 3363.
4447-* Use 8192 instead of 32768 for bytes in fread()
4448- in parseResponseFile(). Bug 3340.</notes>
4449- </release>
4450- <release>
4451- <version>
4452- <release>1.2.0RC6</release>
4453- <api>1.2.0RC6</api>
4454- </version>
4455- <stability>
4456- <release>beta</release>
4457- <api>beta</api>
4458- </stability>
4459- <date>2005-01-25</date>
4460- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4461- <notes>* Don&apos;t put the protocol in the Host field of the POST data. (danielc)</notes>
4462- </release>
4463- <release>
4464- <version>
4465- <release>1.2.0RC5</release>
4466- <api>1.2.0RC5</api>
4467- </version>
4468- <stability>
4469- <release>beta</release>
4470- <api>beta</api>
4471- </stability>
4472- <date>2005-01-24</date>
4473- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4474- <notes>* If $port is 443 but a protocol isn&apos;t specified in $server, assume ssl:// is the protocol.</notes>
4475- </release>
4476- <release>
4477- <version>
4478- <release>1.2.0RC4</release>
4479- <api>1.2.0RC4</api>
4480- </version>
4481- <stability>
4482- <release>beta</release>
4483- <api>beta</api>
4484- </stability>
4485- <date>2005-01-24</date>
4486- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4487- <notes>* When a connection attempt fails, have the method return 0. (danielc)
4488-* Move the protocol/port checking/switching and the property settings from sendPayloadHTTP10() to the XML_RPC_Client constructor. (danielc)
4489-* Add tests for setting the client properties. (danielc)
4490-* Remove $GLOBALS[&apos;XML_RPC_twoslash&apos;] since it&apos;s not used. (danielc)
4491-* Bundle the tests with the package. (danielc)</notes>
4492- </release>
4493- <release>
4494- <version>
4495- <release>1.2.0RC3</release>
4496- <api>1.2.0RC3</api>
4497- </version>
4498- <stability>
4499- <release>beta</release>
4500- <api>beta</api>
4501- </stability>
4502- <date>2005-01-19</date>
4503- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4504- <notes>* ssl uses port 443, not 445.</notes>
4505- </release>
4506- <release>
4507- <version>
4508- <release>1.2.0RC2</release>
4509- <api>1.2.0RC2</api>
4510- </version>
4511- <stability>
4512- <release>beta</release>
4513- <api>beta</api>
4514- </stability>
4515- <date>2005-01-11</date>
4516- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4517- <notes>* Handle ssl:// in the $server string. (danielc)
4518-* Also default to port 445 for ssl:// requests as well. (danielc)
4519-* Enhance debugging in the server. (danielc)</notes>
4520- </release>
4521- <release>
4522- <version>
4523- <release>1.2.0RC1</release>
4524- <api>1.2.0RC1</api>
4525- </version>
4526- <stability>
4527- <release>beta</release>
4528- <api>beta</api>
4529- </stability>
4530- <date>2004-12-30</date>
4531- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4532- <notes>* Make things work with SSL. Bug 2489. (nkukard lbsd net)
4533-* Allow array function callbacks (Matt Kane)
4534-* Some minor speed-ups (Matt Kane)
4535-* Add Dump.php to the package (Christian Weiske)
4536-* Replace all line endings with \r\n. Had only done replacements on \n. Bug 2521. (danielc)
4537-* Silence fsockopen() errors. Bug 1714. (danielc)
4538-* Encode empty arrays as an array. Bug 1493. (danielc)
4539-* Eliminate undefined index notice when submitting empty arrays to XML_RPC_Encode(). Bug 1819. (danielc)
4540-* Speed up check for enumerated arrays in XML_RPC_Encode(). (danielc)
4541-* Prepend &quot;XML_RPC_&quot; to ERROR_NON_NUMERIC_FOUND, eliminating problem when eval()&apos;ing error messages. (danielc)
4542-* Use XML_RPC_Base::raiseError() instead of PEAR::raiseError() in XML_RPC_ee() because PEAR.php is lazy loaded. (danielc)
4543-* Allow raiseError() to be called statically. (danielc)
4544-* Stop double escaping of character entities. Bug 987. (danielc)
4545- NOTICE: the following have been removed:
4546- * XML_RPC_dh()
4547- * $GLOBALS[&apos;XML_RPC_entities&apos;]
4548- * XML_RPC_entity_decode()
4549- * XML_RPC_lookup_entity()
4550-* Determine the XML&apos;s encoding via the encoding attribute in the XML declaration. Bug 52. (danielc)</notes>
4551- </release>
4552- <release>
4553- <version>
4554- <release>1.1.0</release>
4555- <api>1.1.0</api>
4556- </version>
4557- <stability>
4558- <release>stable</release>
4559- <api>stable</api>
4560- </stability>
4561- <date>2004-03-15</date>
4562- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4563- <notes>* Added support for sequential arrays to XML_RPC_encode() (mroch)
4564-* Cleaned up new XML_RPC_encode() changes a bit (mroch, pierre)
4565-* Remove &quot;require_once &apos;PEAR.php&apos;&quot;, include only when needed to raise an error
4566-* Replace echo and error_log() with raiseError() (mroch)
4567-* Make all classes extend XML_RPC_Base, which will handle common functions (mroch)
4568-* be tolerant of junk after methodResponse (Luca Mariano, mroch)
4569-* Silent notice even in the error log (pierre)
4570-* fix include of shared xml extension on win32 (pierre)</notes>
4571- </release>
4572- <release>
4573- <version>
4574- <release>1.0.4</release>
4575- <api>1.0.4</api>
4576- </version>
4577- <stability>
4578- <release>stable</release>
4579- <api>stable</api>
4580- </stability>
4581- <date>2002-10-02</date>
4582- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4583- <notes>* added HTTP proxy authorization support (thanks to Arnaud Limbourg)</notes>
4584- </release>
4585- <release>
4586- <version>
4587- <release>1.0.3</release>
4588- <api>1.0.3</api>
4589- </version>
4590- <stability>
4591- <release>stable</release>
4592- <api>stable</api>
4593- </stability>
4594- <date>2002-05-19</date>
4595- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4596- <notes>* fix bug when parsing responses with boolean types</notes>
4597- </release>
4598- <release>
4599- <version>
4600- <release>1.0.2</release>
4601- <api>1.0.2</api>
4602- </version>
4603- <stability>
4604- <release>stable</release>
4605- <api>stable</api>
4606- </stability>
4607- <date>2002-04-16</date>
4608- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4609- <notes>* E_ALL fixes
4610-* fix HTTP response header parsing</notes>
4611- </release>
4612- <release>
4613- <version>
4614- <release>1.0.1</release>
4615- <api>1.0.1</api>
4616- </version>
4617- <stability>
4618- <release>stable</release>
4619- <api>stable</api>
4620- </stability>
4621- <date>2001-09-25</date>
4622- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
4623- <notes>This is a PEAR-ified version of Useful Inc&apos;s 1.0.1 release.
4624-Includes an urgent security fix identified by Dan Libby &lt;dan@libby.com&gt;.</notes>
4625- </release>
4626- </changelog>
4627-</package>
4628-
4629-
4630-/**
4631- * Tests that properties of XML_RPC_Client get properly set
4632- *
4633- * Any individual tests that fail will have their name, expected result
4634- * and actual result printed out. So seeing no output when executing
4635- * this file is a good thing.
4636- *
4637- * Can be run via CLI or a web server.
4638- *
4639- * PHP versions 4 and 5
4640- *
4641- * LICENSE: This source file is subject to version 3.0 of the PHP license
4642- * that is available through the world-wide-web at the following URI:
4643- * http://www.php.net/license/3_0.txt. If you did not receive a copy of
4644- * the PHP License and are unable to obtain it through the web, please
4645- * send a note to license@php.net so we can mail you a copy immediately.
4646- *
4647- * @category Web Services
4648- * @package XML_RPC
4649- * @author Daniel Convissor <danielc@php.net>
4650- * @copyright 2005 The PHP Group
4651- * @license http://www.php.net/license/3_0.txt PHP License
4652- * @version CVS: $Id: protoport.php,v 1.4 2005/01/24 17:48:47 danielc Exp $
4653- * @link http://pear.php.net/package/XML_RPC
4654- * @since File available since Release 1.2
4655- */
4656-
4657-/*
4658- * If the package version number is found in the left hand
4659- * portion of the if() expression below, that means this file has
4660- * come from the PEAR installer. Therefore, let's test the
4661- * installed version of XML_RPC which should be in the include path.
4662- *
4663- * If the version has not been substituted in the if() expression,
4664- * this file has likely come from a CVS checkout or a .tar file.
4665- * Therefore, we'll assume the tests should use the version of
4666- * XML_RPC that has come from there as well.
4667- */
4668-if ('1.3.1' != '@'.'package_version'.'@') {
4669- /**
4670- * Get the needed class from the PEAR installation
4671- */
4672- require_once 'XML/RPC.php';
4673-} else {
4674- /**
4675- * Get the needed class from the parent directory
4676- */
4677- require_once '../RPC.php';
4678-}
4679-
4680-/**
4681- * Compare the test result to the expected result
4682- *
4683- * If the test fails, echo out the results.
4684- *
4685- * @param array $expect the array of object properties you expect
4686- * from the test
4687- * @param object $actual the object results from the test
4688- * @param string $test_name the name of the test
4689- *
4690- * @return void
4691- */
4692-function compare($expect, $actual, $test_name) {
4693- $actual = get_object_vars($actual);
4694- if (count(array_diff($actual, $expect))) {
4695- echo "$test_name failed.\nExpect: ";
4696- print_r($expect);
4697- echo "Actual: ";
4698- print_r($actual);
4699- echo "\n";
4700- }
4701-}
4702-
4703-if (php_sapi_name() != 'cli') {
4704- echo "<pre>\n";
4705-}
4706-
4707-
4708-$x = array(
4709- 'path' => 'thepath',
4710- 'server' => 'theserver',
4711- 'protocol' => 'http://',
4712- 'port' => 80,
4713- 'proxy' => '',
4714- 'proxy_protocol' => 'http://',
4715- 'proxy_port' => 8080,
4716- 'proxy_user' => '',
4717- 'proxy_pass' => '',
4718- 'errno' => 0,
4719- 'errstring' => '',
4720- 'debug' => 0,
4721- 'username' => '',
4722- 'password' => '',
4723-);
4724-$c = new XML_RPC_Client('thepath', 'theserver');
4725-compare($x, $c, 'defaults');
4726-
4727-$x = array(
4728- 'path' => 'thepath',
4729- 'server' => 'theserver',
4730- 'protocol' => 'http://',
4731- 'port' => 80,
4732- 'proxy' => '',
4733- 'proxy_protocol' => 'http://',
4734- 'proxy_port' => 8080,
4735- 'proxy_user' => '',
4736- 'proxy_pass' => '',
4737- 'errno' => 0,
4738- 'errstring' => '',
4739- 'debug' => 0,
4740- 'username' => '',
4741- 'password' => '',
4742-);
4743-$c = new XML_RPC_Client('thepath', 'http://theserver');
4744-compare($x, $c, 'defaults with http');
4745-
4746-$x = array(
4747- 'path' => 'thepath',
4748- 'server' => 'theserver',
4749- 'protocol' => 'ssl://',
4750- 'port' => 443,
4751- 'proxy' => '',
4752- 'proxy_protocol' => 'http://',
4753- 'proxy_port' => 8080,
4754- 'proxy_user' => '',
4755- 'proxy_pass' => '',
4756- 'errno' => 0,
4757- 'errstring' => '',
4758- 'debug' => 0,
4759- 'username' => '',
4760- 'password' => '',
4761-);
4762-$c = new XML_RPC_Client('thepath', 'https://theserver');
4763-compare($x, $c, 'defaults with https');
4764-
4765-$x = array(
4766- 'path' => 'thepath',
4767- 'server' => 'theserver',
4768- 'protocol' => 'ssl://',
4769- 'port' => 443,
4770- 'proxy' => '',
4771- 'proxy_protocol' => 'http://',
4772- 'proxy_port' => 8080,
4773- 'proxy_user' => '',
4774- 'proxy_pass' => '',
4775- 'errno' => 0,
4776- 'errstring' => '',
4777- 'debug' => 0,
4778- 'username' => '',
4779- 'password' => '',
4780-);
4781-$c = new XML_RPC_Client('thepath', 'ssl://theserver');
4782-compare($x, $c, 'defaults with ssl');
4783-
4784-
4785-$x = array(
4786- 'path' => 'thepath',
4787- 'server' => 'theserver',
4788- 'protocol' => 'http://',
4789- 'port' => 65,
4790- 'proxy' => '',
4791- 'proxy_protocol' => 'http://',
4792- 'proxy_port' => 8080,
4793- 'proxy_user' => '',
4794- 'proxy_pass' => '',
4795- 'errno' => 0,
4796- 'errstring' => '',
4797- 'debug' => 0,
4798- 'username' => '',
4799- 'password' => '',
4800-);
4801-$c = new XML_RPC_Client('thepath', 'theserver', 65);
4802-compare($x, $c, 'port 65');
4803-
4804-$x = array(
4805- 'path' => 'thepath',
4806- 'server' => 'theserver',
4807- 'protocol' => 'http://',
4808- 'port' => 65,
4809- 'proxy' => '',
4810- 'proxy_protocol' => 'http://',
4811- 'proxy_port' => 8080,
4812- 'proxy_user' => '',
4813- 'proxy_pass' => '',
4814- 'errno' => 0,
4815- 'errstring' => '',
4816- 'debug' => 0,
4817- 'username' => '',
4818- 'password' => '',
4819-);
4820-$c = new XML_RPC_Client('thepath', 'http://theserver', 65);
4821-compare($x, $c, 'port 65 with http');
4822-
4823-$x = array(
4824- 'path' => 'thepath',
4825- 'server' => 'theserver',
4826- 'protocol' => 'ssl://',
4827- 'port' => 65,
4828- 'proxy' => '',
4829- 'proxy_protocol' => 'http://',
4830- 'proxy_port' => 8080,
4831- 'proxy_user' => '',
4832- 'proxy_pass' => '',
4833- 'errno' => 0,
4834- 'errstring' => '',
4835- 'debug' => 0,
4836- 'username' => '',
4837- 'password' => '',
4838-);
4839-$c = new XML_RPC_Client('thepath', 'https://theserver', 65);
4840-compare($x, $c, 'port 65 with https');
4841-
4842-$x = array(
4843- 'path' => 'thepath',
4844- 'server' => 'theserver',
4845- 'protocol' => 'ssl://',
4846- 'port' => 65,
4847- 'proxy' => '',
4848- 'proxy_protocol' => 'http://',
4849- 'proxy_port' => 8080,
4850- 'proxy_user' => '',
4851- 'proxy_pass' => '',
4852- 'errno' => 0,
4853- 'errstring' => '',
4854- 'debug' => 0,
4855- 'username' => '',
4856- 'password' => '',
4857-);
4858-$c = new XML_RPC_Client('thepath', 'ssl://theserver', 65);
4859-compare($x, $c, 'port 65 with ssl');
4860-
4861-
4862-$x = array(
4863- 'path' => 'thepath',
4864- 'server' => 'theserver',
4865- 'protocol' => 'http://',
4866- 'port' => 80,
4867- 'proxy' => 'theproxy',
4868- 'proxy_protocol' => 'http://',
4869- 'proxy_port' => 8080,
4870- 'proxy_user' => '',
4871- 'proxy_pass' => '',
4872- 'errno' => 0,
4873- 'errstring' => '',
4874- 'debug' => 0,
4875- 'username' => '',
4876- 'password' => '',
4877-);
4878-$c = new XML_RPC_Client('thepath', 'theserver', 0,
4879- 'theproxy');
4880-compare($x, $c, 'defaults proxy');
4881-
4882-$x = array(
4883- 'path' => 'thepath',
4884- 'server' => 'theserver',
4885- 'protocol' => 'http://',
4886- 'port' => 80,
4887- 'proxy' => 'theproxy',
4888- 'proxy_protocol' => 'http://',
4889- 'proxy_port' => 8080,
4890- 'proxy_user' => '',
4891- 'proxy_pass' => '',
4892- 'errno' => 0,
4893- 'errstring' => '',
4894- 'debug' => 0,
4895- 'username' => '',
4896- 'password' => '',
4897-);
4898-$c = new XML_RPC_Client('thepath', 'http://theserver', 0,
4899- 'http://theproxy');
4900-compare($x, $c, 'defaults with http proxy');
4901-
4902-$x = array(
4903- 'path' => 'thepath',
4904- 'server' => 'theserver',
4905- 'protocol' => 'ssl://',
4906- 'port' => 443,
4907- 'proxy' => 'theproxy',
4908- 'proxy_protocol' => 'ssl://',
4909- 'proxy_port' => 443,
4910- 'proxy_user' => '',
4911- 'proxy_pass' => '',
4912- 'errno' => 0,
4913- 'errstring' => '',
4914- 'debug' => 0,
4915- 'username' => '',
4916- 'password' => '',
4917-);
4918-$c = new XML_RPC_Client('thepath', 'https://theserver', 0,
4919- 'https://theproxy');
4920-compare($x, $c, 'defaults with https proxy');
4921-
4922-$x = array(
4923- 'path' => 'thepath',
4924- 'server' => 'theserver',
4925- 'protocol' => 'ssl://',
4926- 'port' => 443,
4927- 'proxy' => 'theproxy',
4928- 'proxy_protocol' => 'ssl://',
4929- 'proxy_port' => 443,
4930- 'proxy_user' => '',
4931- 'proxy_pass' => '',
4932- 'errno' => 0,
4933- 'errstring' => '',
4934- 'debug' => 0,
4935- 'username' => '',
4936- 'password' => '',
4937-);
4938-$c = new XML_RPC_Client('thepath', 'ssl://theserver', 0,
4939- 'ssl://theproxy');
4940-compare($x, $c, 'defaults with ssl proxy');
4941-
4942-
4943-$x = array(
4944- 'path' => 'thepath',
4945- 'server' => 'theserver',
4946- 'protocol' => 'http://',
4947- 'port' => 65,
4948- 'proxy' => 'theproxy',
4949- 'proxy_protocol' => 'http://',
4950- 'proxy_port' => 6565,
4951- 'proxy_user' => '',
4952- 'proxy_pass' => '',
4953- 'errno' => 0,
4954- 'errstring' => '',
4955- 'debug' => 0,
4956- 'username' => '',
4957- 'password' => '',
4958-);
4959-$c = new XML_RPC_Client('thepath', 'theserver', 65,
4960- 'theproxy', 6565);
4961-compare($x, $c, 'port 65 proxy 6565');
4962-
4963-$x = array(
4964- 'path' => 'thepath',
4965- 'server' => 'theserver',
4966- 'protocol' => 'http://',
4967- 'port' => 65,
4968- 'proxy' => 'theproxy',
4969- 'proxy_protocol' => 'http://',
4970- 'proxy_port' => 6565,
4971- 'proxy_user' => '',
4972- 'proxy_pass' => '',
4973- 'errno' => 0,
4974- 'errstring' => '',
4975- 'debug' => 0,
4976- 'username' => '',
4977- 'password' => '',
4978-);
4979-$c = new XML_RPC_Client('thepath', 'http://theserver', 65,
4980- 'http://theproxy', 6565);
4981-compare($x, $c, 'port 65 with http proxy 6565');
4982-
4983-$x = array(
4984- 'path' => 'thepath',
4985- 'server' => 'theserver',
4986- 'protocol' => 'ssl://',
4987- 'port' => 65,
4988- 'proxy' => 'theproxy',
4989- 'proxy_protocol' => 'ssl://',
4990- 'proxy_port' => 6565,
4991- 'proxy_user' => '',
4992- 'proxy_pass' => '',
4993- 'errno' => 0,
4994- 'errstring' => '',
4995- 'debug' => 0,
4996- 'username' => '',
4997- 'password' => '',
4998-);
4999-$c = new XML_RPC_Client('thepath', 'https://theserver', 65,
5000- 'https://theproxy', 6565);
5001-compare($x, $c, 'port 65 with https proxy 6565');
5002-
5003-$x = array(
5004- 'path' => 'thepath',
5005- 'server' => 'theserver',
5006- 'protocol' => 'ssl://',
5007- 'port' => 65,
5008- 'proxy' => 'theproxy',
5009- 'proxy_protocol' => 'ssl://',
5010- 'proxy_port' => 6565,
5011- 'proxy_user' => '',
5012- 'proxy_pass' => '',
5013- 'errno' => 0,
5014- 'errstring' => '',
5015- 'debug' => 0,
5016- 'username' => '',
5017- 'password' => '',
5018-);
5019-$c = new XML_RPC_Client('thepath', 'ssl://theserver', 65,
5020- 'ssl://theproxy', 6565);
5021-compare($x, $c, 'port 65 with ssl proxy 6565');
5022-
5023-
5024-$x = array(
5025- 'path' => 'thepath',
5026- 'server' => 'theserver',
5027- 'protocol' => 'ssl://',
5028- 'port' => 443,
5029- 'proxy' => 'theproxy',
5030- 'proxy_protocol' => 'ssl://',
5031- 'proxy_port' => 443,
5032- 'proxy_user' => '',
5033- 'proxy_pass' => '',
5034- 'errno' => 0,
5035- 'errstring' => '',
5036- 'debug' => 0,
5037- 'username' => '',
5038- 'password' => '',
5039-);
5040-$c = new XML_RPC_Client('thepath', 'theserver', 443,
5041- 'theproxy', 443);
5042-compare($x, $c, 'port 443 no protocol and proxy port 443 no protocol');
5043-
5044-$x = array(
5045- 'path' => 'thepath',
5046- 'server' => 'theserver',
5047- 'protocol' => 'http://',
5048- 'port' => 80,
5049- 'proxy' => 'theproxy',
5050- 'proxy_protocol' => 'ssl://',
5051- 'proxy_port' => 6565,
5052- 'proxy_user' => '',
5053- 'proxy_pass' => '',
5054- 'errno' => 0,
5055- 'errstring' => '',
5056- 'debug' => 0,
5057- 'username' => '',
5058- 'password' => '',
5059-);
5060-$c = new XML_RPC_Client('thepath', 'theserver', 0,
5061- 'ssl://theproxy', 6565);
5062-compare($x, $c, 'port 443 no protocol and proxy port 443 no protocol');
5063-
5064-
5065-/*
5066- * If the package version number is found in the left hand
5067- * portion of the if() expression below, that means this file has
5068- * come from the PEAR installer. Therefore, let's test the
5069- * installed version of XML_RPC which should be in the include path.
5070- *
5071- * If the version has not been substituted in the if() expression,
5072- * this file has likely come from a CVS checkout or a .tar file.
5073- * Therefore, we'll assume the tests should use the version of
5074- * XML_RPC that has come from there as well.
5075- */
5076-if ('1.3.1' != '@'.'package_version'.'@') {
5077- /**
5078- * Get the needed class from the PEAR installation
5079- */
5080- require_once 'XML/RPC/Dump.php';
5081-} else {
5082- /**
5083- * Get the needed class from the parent directory
5084- */
5085- require_once '../Dump.php';
5086-}
5087-
5088-$val = new XML_RPC_Value(array(
5089- 'title' =>new XML_RPC_Value('das ist der Titel', 'string'),
5090- 'startDate'=>new XML_RPC_Value(mktime(0,0,0,13,11,2004), 'dateTime.iso8601'),
5091- 'endDate' =>new XML_RPC_Value(mktime(0,0,0,15,11,2004), 'dateTime.iso8601'),
5092- 'error' =>'string',
5093- 'arkey' => new XML_RPC_Value( array(
5094- new XML_RPC_Value('simple string'),
5095- new XML_RPC_Value(12345, 'int')
5096- ), 'array')
5097- )
5098- ,'struct');
5099-
5100-XML_RPC_Dump($val);
5101-
5102-echo '==============' . "\r\n";
5103-$val2 = new XML_RPC_Value(44353, 'int');
5104-XML_RPC_Dump($val2);
5105-
5106-echo '==============' . "\r\n";
5107-$val3 = new XML_RPC_Value('this should be a string', 'string');
5108-XML_RPC_Dump($val3);
5109-
5110-echo '==============' . "\r\n";
5111-$val4 = new XML_RPC_Value(true, 'boolean');
5112-XML_RPC_Dump($val4);
5113-
5114-
5115-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
5116-
5117-/**
5118- * Function and class to dump XML_RPC_Value objects in a nice way
5119- *
5120- * Should be helpful as a normal var_dump(..) displays all internals which
5121- * doesn't really give you an overview due to too much information.
5122- *
5123- * @category Web Services
5124- * @package XML_RPC
5125- * @author Christian Weiske <cweiske@php.net>
5126- * @version CVS: $Id: Dump.php,v 1.7 2005/01/24 03:47:55 danielc Exp $
5127- * @link http://pear.php.net/package/XML_RPC
5128- */
5129-
5130-
5131-/**
5132- * Pull in the XML_RPC class
5133- */
5134-require_once 'XML/RPC.php';
5135-
5136-
5137-/**
5138- * Generates the dump of the XML_RPC_Value and echoes it
5139- *
5140- * @param object $value the XML_RPC_Value object to dump
5141- *
5142- * @return void
5143- */
5144-function XML_RPC_Dump($value)
5145-{
5146- $dumper = new XML_RPC_Dump();
5147- echo $dumper->generateDump($value);
5148-}
5149-
5150-
5151-/**
5152- * Class which generates a dump of a XML_RPC_Value object
5153- *
5154- * @category Web Services
5155- * @package XML_RPC
5156- * @author Christian Weiske <cweiske@php.net>
5157- * @version Release: 1.3.1
5158- * @link http://pear.php.net/package/XML_RPC
5159- */
5160-class XML_RPC_Dump
5161-{
5162- /**
5163- * The indentation array cache
5164- * @var array
5165- */
5166- var $arIndent = array();
5167-
5168- /**
5169- * The spaces used for indenting the XML
5170- * @var string
5171- */
5172- var $strBaseIndent = ' ';
5173-
5174- /**
5175- * Returns the dump in XML format without printing it out
5176- *
5177- * @param object $value the XML_RPC_Value object to dump
5178- * @param int $nLevel the level of indentation
5179- *
5180- * @return string the dump
5181- */
5182- function generateDump($value, $nLevel = 0)
5183- {
5184- if (!is_object($value) && get_class($value) != 'xml_rpc_value') {
5185- require_once 'PEAR.php';
5186- PEAR::raiseError('Tried to dump non-XML_RPC_Value variable' . "\r\n",
5187- 0, PEAR_ERROR_PRINT);
5188- if (is_object($value)) {
5189- $strType = get_class($value);
5190- } else {
5191- $strType = gettype($value);
5192- }
5193- return $this->getIndent($nLevel) . 'NOT A XML_RPC_Value: '
5194- . $strType . "\r\n";
5195- }
5196-
5197- switch ($value->kindOf()) {
5198- case 'struct':
5199- $ret = $this->genStruct($value, $nLevel);
5200- break;
5201- case 'array':
5202- $ret = $this->genArray($value, $nLevel);
5203- break;
5204- case 'scalar':
5205- $ret = $this->genScalar($value->scalarval(), $nLevel);
5206- break;
5207- default:
5208- require_once 'PEAR.php';
5209- PEAR::raiseError('Illegal type "' . $value->kindOf()
5210- . '" in XML_RPC_Value' . "\r\n", 0,
5211- PEAR_ERROR_PRINT);
5212- }
5213-
5214- return $ret;
5215- }
5216-
5217- /**
5218- * Returns the scalar value dump
5219- *
5220- * @param object $value the scalar XML_RPC_Value object to dump
5221- * @param int $nLevel the level of indentation
5222- *
5223- * @return string Dumped version of the scalar value
5224- */
5225- function genScalar($value, $nLevel)
5226- {
5227- if (gettype($value) == 'object') {
5228- $strClass = ' ' . get_class($value);
5229- } else {
5230- $strClass = '';
5231- }
5232- return $this->getIndent($nLevel) . gettype($value) . $strClass
5233- . ' ' . $value . "\r\n";
5234- }
5235-
5236- /**
5237- * Returns the dump of a struct
5238- *
5239- * @param object $value the struct XML_RPC_Value object to dump
5240- * @param int $nLevel the level of indentation
5241- *
5242- * @return string Dumped version of the scalar value
5243- */
5244- function genStruct($value, $nLevel)
5245- {
5246- $value->structreset();
5247- $strOutput = $this->getIndent($nLevel) . 'struct' . "\r\n";
5248- while (list($key, $keyval) = $value->structeach()) {
5249- $strOutput .= $this->getIndent($nLevel + 1) . $key . "\r\n";
5250- $strOutput .= $this->generateDump($keyval, $nLevel + 2);
5251- }
5252- return $strOutput;
5253- }
5254-
5255- /**
5256- * Returns the dump of an array
5257- *
5258- * @param object $value the array XML_RPC_Value object to dump
5259- * @param int $nLevel the level of indentation
5260- *
5261- * @return string Dumped version of the scalar value
5262- */
5263- function genArray($value, $nLevel)
5264- {
5265- $nSize = $value->arraysize();
5266- $strOutput = $this->getIndent($nLevel) . 'array' . "\r\n";
5267- for($nA = 0; $nA < $nSize; $nA++) {
5268- $strOutput .= $this->getIndent($nLevel + 1) . $nA . "\r\n";
5269- $strOutput .= $this->generateDump($value->arraymem($nA),
5270- $nLevel + 2);
5271- }
5272- return $strOutput;
5273- }
5274-
5275- /**
5276- * Returns the indent for a specific level and caches it for faster use
5277- *
5278- * @param int $nLevel the level
5279- *
5280- * @return string the indented string
5281- */
5282- function getIndent($nLevel)
5283- {
5284- if (!isset($this->arIndent[$nLevel])) {
5285- $this->arIndent[$nLevel] = str_repeat($this->strBaseIndent, $nLevel);
5286- }
5287- return $this->arIndent[$nLevel];
5288- }
5289-}
5290-
5291-/*
5292- * Local variables:
5293- * tab-width: 4
5294- * c-basic-offset: 4
5295- * c-hanging-comment-ender-p: nil
5296- * End:
5297- */
5298-
5299-?>
5300-
5301-
5302-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
5303-
5304-/**
5305- * PHP implementation of the XML-RPC protocol
5306- *
5307- * This is a PEAR-ified version of Useful inc's XML-RPC for PHP.
5308- * It has support for HTTP transport, proxies and authentication.
5309- *
5310- * PHP versions 4 and 5
5311- *
5312- * LICENSE: License is granted to use or modify this software
5313- * ("XML-RPC for PHP") for commercial or non-commercial use provided the
5314- * copyright of the author is preserved in any distributed or derivative work.
5315- *
5316- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESSED OR
5317- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
5318- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
5319- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
5320- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5321- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
5322- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
5323- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5324- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
5325- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5326- *
5327- * @category Web Services
5328- * @package XML_RPC
5329- * @author Edd Dumbill <edd@usefulinc.com>
5330- * @author Stig Bakken <stig@php.net>
5331- * @author Martin Jansen <mj@php.net>
5332- * @author Daniel Convissor <danielc@php.net>
5333- * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
5334- * @version CVS: $Id: RPC.php,v 1.74 2005/05/09 20:51:54 danielc Exp $
5335- * @link http://pear.php.net/package/XML_RPC
5336- */
5337-
5338-
5339-if (!function_exists('xml_parser_create')) {
5340- PEAR::loadExtension('xml');
5341-}
5342-
5343-/**#@+
5344- * Error constants
5345- */
5346-/**
5347- * Parameter values don't match parameter types
5348- */
5349-define('XML_RPC_ERROR_INVALID_TYPE', 101);
5350-/**
5351- * Parameter declared to be numeric but the values are not
5352- */
5353-define('XML_RPC_ERROR_NON_NUMERIC_FOUND', 102);
5354-/**
5355- * Communication error
5356- */
5357-define('XML_RPC_ERROR_CONNECTION_FAILED', 103);
5358-/**
5359- * The array or struct has already been started
5360- */
5361-define('XML_RPC_ERROR_ALREADY_INITIALIZED', 104);
5362-/**
5363- * Incorrect parameters submitted
5364- */
5365-define('XML_RPC_ERROR_INCORRECT_PARAMS', 105);
5366-/**
5367- * Programming error by developer
5368- */
5369-define('XML_RPC_ERROR_PROGRAMMING', 106);
5370-/**#@-*/
5371-
5372-
5373-/**
5374- * Data types
5375- * @global string $GLOBALS['XML_RPC_I4']
5376- */
5377-$GLOBALS['XML_RPC_I4'] = 'i4';
5378-
5379-/**
5380- * Data types
5381- * @global string $GLOBALS['XML_RPC_Int']
5382- */
5383-$GLOBALS['XML_RPC_Int'] = 'int';
5384-
5385-/**
5386- * Data types
5387- * @global string $GLOBALS['XML_RPC_Boolean']
5388- */
5389-$GLOBALS['XML_RPC_Boolean'] = 'boolean';
5390-
5391-/**
5392- * Data types
5393- * @global string $GLOBALS['XML_RPC_Double']
5394- */
5395-$GLOBALS['XML_RPC_Double'] = 'double';
5396-
5397-/**
5398- * Data types
5399- * @global string $GLOBALS['XML_RPC_String']
5400- */
5401-$GLOBALS['XML_RPC_String'] = 'string';
5402-
5403-/**
5404- * Data types
5405- * @global string $GLOBALS['XML_RPC_DateTime']
5406- */
5407-$GLOBALS['XML_RPC_DateTime'] = 'dateTime.iso8601';
5408-
5409-/**
5410- * Data types
5411- * @global string $GLOBALS['XML_RPC_Base64']
5412- */
5413-$GLOBALS['XML_RPC_Base64'] = 'base64';
5414-
5415-/**
5416- * Data types
5417- * @global string $GLOBALS['XML_RPC_Array']
5418- */
5419-$GLOBALS['XML_RPC_Array'] = 'array';
5420-
5421-/**
5422- * Data types
5423- * @global string $GLOBALS['XML_RPC_Struct']
5424- */
5425-$GLOBALS['XML_RPC_Struct'] = 'struct';
5426-
5427-
5428-/**
5429- * Data type meta-types
5430- * @global array $GLOBALS['XML_RPC_Types']
5431- */
5432-$GLOBALS['XML_RPC_Types'] = array(
5433- $GLOBALS['XML_RPC_I4'] => 1,
5434- $GLOBALS['XML_RPC_Int'] => 1,
5435- $GLOBALS['XML_RPC_Boolean'] => 1,
5436- $GLOBALS['XML_RPC_String'] => 1,
5437- $GLOBALS['XML_RPC_Double'] => 1,
5438- $GLOBALS['XML_RPC_DateTime'] => 1,
5439- $GLOBALS['XML_RPC_Base64'] => 1,
5440- $GLOBALS['XML_RPC_Array'] => 2,
5441- $GLOBALS['XML_RPC_Struct'] => 3,
5442-);
5443-
5444-
5445-/**
5446- * Error message numbers
5447- * @global array $GLOBALS['XML_RPC_err']
5448- */
5449-$GLOBALS['XML_RPC_err'] = array(
5450- 'unknown_method' => 1,
5451- 'invalid_return' => 2,
5452- 'incorrect_params' => 3,
5453- 'introspect_unknown' => 4,
5454- 'http_error' => 5,
5455- 'not_response_object' => 6,
5456-);
5457-
5458-/**
5459- * Error message strings
5460- * @global array $GLOBALS['XML_RPC_str']
5461- */
5462-$GLOBALS['XML_RPC_str'] = array(
5463- 'unknown_method' => 'Unknown method',
5464- 'invalid_return' => 'Invalid return payload: enable debugging to examine incoming payload',
5465- 'incorrect_params' => 'Incorrect parameters passed to method',
5466- 'introspect_unknown' => 'Can\'t introspect: method unknown',
5467- 'http_error' => 'Didn\'t receive 200 OK from remote server.',
5468- 'not_response_object' => 'The requested method didn\'t return an XML_RPC_Response object.',
5469-);
5470-
5471-
5472-/**
5473- * Default XML encoding (ISO-8859-1, UTF-8 or US-ASCII)
5474- * @global string $GLOBALS['XML_RPC_defencoding']
5475- */
5476-$GLOBALS['XML_RPC_defencoding'] = 'UTF-8';
5477-
5478-/**
5479- * User error codes start at 800
5480- * @global int $GLOBALS['XML_RPC_erruser']
5481- */
5482-$GLOBALS['XML_RPC_erruser'] = 800;
5483-
5484-/**
5485- * XML parse error codes start at 100
5486- * @global int $GLOBALS['XML_RPC_errxml']
5487- */
5488-$GLOBALS['XML_RPC_errxml'] = 100;
5489-
5490-
5491-/**
5492- * Compose backslashes for escaping regexp
5493- * @global string $GLOBALS['XML_RPC_backslash']
5494- */
5495-$GLOBALS['XML_RPC_backslash'] = chr(92) . chr(92);
5496-
5497-
5498-/**
5499- * Stores state during parsing
5500- *
5501- * quick explanation of components:
5502- * + st = builds up a string for evaluation
5503- * + ac = accumulates values
5504- * + qt = decides if quotes are needed for evaluation
5505- * + cm = denotes struct or array (comma needed)
5506- * + isf = indicates a fault
5507- * + lv = indicates "looking for a value": implements the logic
5508- * to allow values with no types to be strings
5509- * + params = stores parameters in method calls
5510- * + method = stores method name
5511- *
5512- * @global array $GLOBALS['XML_RPC_xh']
5513- */
5514-$GLOBALS['XML_RPC_xh'] = array();
5515-
5516-
5517-/**
5518- * Start element handler for the XML parser
5519- *
5520- * @return void
5521- */
5522-function XML_RPC_se($parser_resource, $name, $attrs)
5523-{
5524- global $XML_RPC_xh, $XML_RPC_DateTime, $XML_RPC_String;
5525- $parser = (int) $parser_resource;
5526-
5527- switch ($name) {
5528- case 'STRUCT':
5529- case 'ARRAY':
5530- $XML_RPC_xh[$parser]['st'] .= 'array(';
5531- $XML_RPC_xh[$parser]['cm']++;
5532- // this last line turns quoting off
5533- // this means if we get an empty array we'll
5534- // simply get a bit of whitespace in the eval
5535- $XML_RPC_xh[$parser]['qt'] = 0;
5536- break;
5537-
5538- case 'NAME':
5539- $XML_RPC_xh[$parser]['st'] .= '"';
5540- $XML_RPC_xh[$parser]['ac'] = '';
5541- break;
5542-
5543- case 'FAULT':
5544- $XML_RPC_xh[$parser]['isf'] = 1;
5545- break;
5546-
5547- case 'PARAM':
5548- $XML_RPC_xh[$parser]['st'] = '';
5549- break;
5550-
5551- case 'VALUE':
5552- $XML_RPC_xh[$parser]['st'] .= 'new XML_RPC_Value(';
5553- $XML_RPC_xh[$parser]['lv'] = 1;
5554- $XML_RPC_xh[$parser]['vt'] = $XML_RPC_String;
5555- $XML_RPC_xh[$parser]['ac'] = '';
5556- $XML_RPC_xh[$parser]['qt'] = 0;
5557- // look for a value: if this is still 1 by the
5558- // time we reach the first data segment then the type is string
5559- // by implication and we need to add in a quote
5560- break;
5561-
5562- case 'I4':
5563- case 'INT':
5564- case 'STRING':
5565- case 'BOOLEAN':
5566- case 'DOUBLE':
5567- case 'DATETIME.ISO8601':
5568- case 'BASE64':
5569- $XML_RPC_xh[$parser]['ac'] = ''; // reset the accumulator
5570-
5571- if ($name == 'DATETIME.ISO8601' || $name == 'STRING') {
5572- $XML_RPC_xh[$parser]['qt'] = 1;
5573-
5574- if ($name == 'DATETIME.ISO8601') {
5575- $XML_RPC_xh[$parser]['vt'] = $XML_RPC_DateTime;
5576- }
5577-
5578- } elseif ($name == 'BASE64') {
5579- $XML_RPC_xh[$parser]['qt'] = 2;
5580- } else {
5581- // No quoting is required here -- but
5582- // at the end of the element we must check
5583- // for data format errors.
5584- $XML_RPC_xh[$parser]['qt'] = 0;
5585- }
5586- break;
5587-
5588- case 'MEMBER':
5589- $XML_RPC_xh[$parser]['ac'] = '';
5590- }
5591-
5592- if ($name != 'VALUE') {
5593- $XML_RPC_xh[$parser]['lv'] = 0;
5594- }
5595-}
5596-
5597-/**
5598- * End element handler for the XML parser
5599- *
5600- * @return void
5601- */
5602-function XML_RPC_ee($parser_resource, $name)
5603-{
5604- global $XML_RPC_xh, $XML_RPC_Types, $XML_RPC_String;
5605- $parser = (int) $parser_resource;
5606-
5607- switch ($name) {
5608- case 'STRUCT':
5609- case 'ARRAY':
5610- if ($XML_RPC_xh[$parser]['cm']
5611- && substr($XML_RPC_xh[$parser]['st'], -1) == ',')
5612- {
5613- $XML_RPC_xh[$parser]['st'] = substr($XML_RPC_xh[$parser]['st'], 0, -1);
5614- }
5615-
5616- $XML_RPC_xh[$parser]['st'] .= ')';
5617- $XML_RPC_xh[$parser]['vt'] = strtolower($name);
5618- $XML_RPC_xh[$parser]['cm']--;
5619- break;
5620-
5621- case 'NAME':
5622- $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'] . '" => ';
5623- break;
5624-
5625- case 'BOOLEAN':
5626- // special case here: we translate boolean 1 or 0 into PHP
5627- // constants true or false
5628- if ($XML_RPC_xh[$parser]['ac'] == '1') {
5629- $XML_RPC_xh[$parser]['ac'] = 'true';
5630- } else {
5631- $XML_RPC_xh[$parser]['ac'] = 'false';
5632- }
5633-
5634- $XML_RPC_xh[$parser]['vt'] = strtolower($name);
5635- // Drop through intentionally.
5636-
5637- case 'I4':
5638- case 'INT':
5639- case 'STRING':
5640- case 'DOUBLE':
5641- case 'DATETIME.ISO8601':
5642- case 'BASE64':
5643- if ($XML_RPC_xh[$parser]['qt'] == 1) {
5644- // we use double quotes rather than single so backslashification works OK
5645- $XML_RPC_xh[$parser]['st'] .= '"' . $XML_RPC_xh[$parser]['ac'] . '"';
5646- } elseif ($XML_RPC_xh[$parser]['qt'] == 2) {
5647- $XML_RPC_xh[$parser]['st'] .= 'base64_decode("'
5648- . $XML_RPC_xh[$parser]['ac'] . '")';
5649- } elseif ($name == 'BOOLEAN') {
5650- $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'];
5651- } else {
5652- // we have an I4, INT or a DOUBLE
5653- // we must check that only 0123456789-.<space> are characters here
5654- if (!ereg("^[+-]?[0123456789 \t\.]+$", $XML_RPC_xh[$parser]['ac'])) {
5655- XML_RPC_Base::raiseError('Non-numeric value received in INT or DOUBLE',
5656- XML_RPC_ERROR_NON_NUMERIC_FOUND);
5657- $XML_RPC_xh[$parser]['st'] .= 'XML_RPC_ERROR_NON_NUMERIC_FOUND';
5658- } else {
5659- // it's ok, add it on
5660- $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'];
5661- }
5662- }
5663-
5664- $XML_RPC_xh[$parser]['ac'] = '';
5665- $XML_RPC_xh[$parser]['qt'] = 0;
5666- $XML_RPC_xh[$parser]['lv'] = 3; // indicate we've found a value
5667- break;
5668-
5669- case 'VALUE':
5670- // deal with a string value
5671- if (strlen($XML_RPC_xh[$parser]['ac']) > 0 &&
5672- $XML_RPC_xh[$parser]['vt'] == $XML_RPC_String) {
5673-
5674- $XML_RPC_xh[$parser]['st'] .= '"' . $XML_RPC_xh[$parser]['ac'] . '"';
5675- }
5676-
5677- // This if () detects if no scalar was inside <VALUE></VALUE>
5678- // and pads an empty "".
5679- if ($XML_RPC_xh[$parser]['st'][strlen($XML_RPC_xh[$parser]['st'])-1] == '(') {
5680- $XML_RPC_xh[$parser]['st'] .= '""';
5681- }
5682- $XML_RPC_xh[$parser]['st'] .= ", '" . $XML_RPC_xh[$parser]['vt'] . "')";
5683- if ($XML_RPC_xh[$parser]['cm']) {
5684- $XML_RPC_xh[$parser]['st'] .= ',';
5685- }
5686- break;
5687-
5688- case 'MEMBER':
5689- $XML_RPC_xh[$parser]['ac'] = '';
5690- $XML_RPC_xh[$parser]['qt'] = 0;
5691- break;
5692-
5693- case 'DATA':
5694- $XML_RPC_xh[$parser]['ac'] = '';
5695- $XML_RPC_xh[$parser]['qt'] = 0;
5696- break;
5697-
5698- case 'PARAM':
5699- $XML_RPC_xh[$parser]['params'][] = $XML_RPC_xh[$parser]['st'];
5700- break;
5701-
5702- case 'METHODNAME':
5703- case 'RPCMETHODNAME':
5704- $XML_RPC_xh[$parser]['method'] = ereg_replace("^[\n\r\t ]+", '',
5705- $XML_RPC_xh[$parser]['ac']);
5706- break;
5707- }
5708-
5709- // if it's a valid type name, set the type
5710- if (isset($XML_RPC_Types[strtolower($name)])) {
5711- $XML_RPC_xh[$parser]['vt'] = strtolower($name);
5712- }
5713-}
5714-
5715-/**
5716- * Character data handler for the XML parser
5717- *
5718- * @return void
5719- */
5720-function XML_RPC_cd($parser_resource, $data)
5721-{
5722- global $XML_RPC_xh, $XML_RPC_backslash;
5723- $parser = (int) $parser_resource;
5724-
5725- if ($XML_RPC_xh[$parser]['lv'] != 3) {
5726- // "lookforvalue==3" means that we've found an entire value
5727- // and should discard any further character data
5728-
5729- if ($XML_RPC_xh[$parser]['lv'] == 1) {
5730- // if we've found text and we're just in a <value> then
5731- // turn quoting on, as this will be a string
5732- $XML_RPC_xh[$parser]['qt'] = 1;
5733- // and say we've found a value
5734- $XML_RPC_xh[$parser]['lv'] = 2;
5735- }
5736-
5737- // replace characters that eval would
5738- // do special things with
5739- if (!isset($XML_RPC_xh[$parser]['ac'])) {
5740- $XML_RPC_xh[$parser]['ac'] = '';
5741- }
5742- $XML_RPC_xh[$parser]['ac'] .= str_replace('$', '\$',
5743- str_replace('"', '\"', str_replace(chr(92),
5744- $XML_RPC_backslash, $data)));
5745- }
5746-}
5747-
5748-/**
5749- * The common methods and properties for all of the XML_RPC classes
5750- *
5751- * @category Web Services
5752- * @package XML_RPC
5753- * @author Edd Dumbill <edd@usefulinc.com>
5754- * @author Stig Bakken <stig@php.net>
5755- * @author Martin Jansen <mj@php.net>
5756- * @author Daniel Convissor <danielc@php.net>
5757- * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
5758- * @version Release: 1.3.1
5759- * @link http://pear.php.net/package/XML_RPC
5760- */
5761-class XML_RPC_Base {
5762-
5763- /**
5764- * PEAR Error handling
5765- *
5766- * @return object PEAR_Error object
5767- */
5768- function raiseError($msg, $code)
5769- {
5770- include_once 'PEAR.php';
5771- if (is_object(@$this)) {
5772- return PEAR::raiseError(get_class($this) . ': ' . $msg, $code);
5773- } else {
5774- return PEAR::raiseError('XML_RPC: ' . $msg, $code);
5775- }
5776- }
5777-
5778- /**
5779- * Tell whether something is a PEAR_Error object
5780- *
5781- * @param mixed $value the item to check
5782- *
5783- * @return bool whether $value is a PEAR_Error object or not
5784- *
5785- * @access public
5786- */
5787- function isError($value)
5788- {
5789- return is_a($value, 'PEAR_Error');
5790- }
5791-}
5792-
5793-/**
5794- * The methods and properties for submitting XML RPC requests
5795- *
5796- * @category Web Services
5797- * @package XML_RPC
5798- * @author Edd Dumbill <edd@usefulinc.com>
5799- * @author Stig Bakken <stig@php.net>
5800- * @author Martin Jansen <mj@php.net>
5801- * @author Daniel Convissor <danielc@php.net>
5802- * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
5803- * @version Release: 1.3.1
5804- * @link http://pear.php.net/package/XML_RPC
5805- */
5806-class XML_RPC_Client extends XML_RPC_Base {
5807-
5808- /**
5809- * The path and name of the RPC server script you want the request to go to
5810- * @var string
5811- */
5812- var $path = '';
5813-
5814- /**
5815- * The name of the remote server to connect to
5816- * @var string
5817- */
5818- var $server = '';
5819-
5820- /**
5821- * The protocol to use in contacting the remote server
5822- * @var string
5823- */
5824- var $protocol = 'http://';
5825-
5826- /**
5827- * The port for connecting to the remote server
5828- *
5829- * The default is 80 for http:// connections
5830- * and 443 for https:// and ssl:// connections.
5831- *
5832- * @var integer
5833- */
5834- var $port = 80;
5835-
5836- /**
5837- * A user name for accessing the RPC server
5838- * @var string
5839- * @see XML_RPC_Client::setCredentials()
5840- */
5841- var $username = '';
5842-
5843- /**
5844- * A password for accessing the RPC server
5845- * @var string
5846- * @see XML_RPC_Client::setCredentials()
5847- */
5848- var $password = '';
5849-
5850- /**
5851- * The name of the proxy server to use, if any
5852- * @var string
5853- */
5854- var $proxy = '';
5855-
5856- /**
5857- * The protocol to use in contacting the proxy server, if any
5858- * @var string
5859- */
5860- var $proxy_protocol = 'http://';
5861-
5862- /**
5863- * The port for connecting to the proxy server
5864- *
5865- * The default is 8080 for http:// connections
5866- * and 443 for https:// and ssl:// connections.
5867- *
5868- * @var integer
5869- */
5870- var $proxy_port = 8080;
5871-
5872- /**
5873- * A user name for accessing the proxy server
5874- * @var string
5875- */
5876- var $proxy_user = '';
5877-
5878- /**
5879- * A password for accessing the proxy server
5880- * @var string
5881- */
5882- var $proxy_pass = '';
5883-
5884- /**
5885- * The error number, if any
5886- * @var integer
5887- */
5888- var $errno = 0;
5889-
5890- /**
5891- * The error message, if any
5892- * @var string
5893- */
5894- var $errstring = '';
5895-
5896- /**
5897- * The current debug mode (1 = on, 0 = off)
5898- * @var integer
5899- */
5900- var $debug = 0;
5901-
5902- /**
5903- * The HTTP headers for the current request.
5904- * @var string
5905- */
5906- var $headers = '';
5907-
5908-
5909- /**
5910- * Sets the object's properties
5911- *
5912- * @param string $path the path and name of the RPC server script
5913- * you want the request to go to
5914- * @param string $server the URL of the remote server to connect to.
5915- * If this parameter doesn't specify a
5916- * protocol and $port is 443, ssl:// is
5917- * assumed.
5918- * @param integer $port a port for connecting to the remote server.
5919- * Defaults to 80 for http:// connections and
5920- * 443 for https:// and ssl:// connections.
5921- * @param string $proxy the URL of the proxy server to use, if any.
5922- * If this parameter doesn't specify a
5923- * protocol and $port is 443, ssl:// is
5924- * assumed.
5925- * @param integer $proxy_port a port for connecting to the remote server.
5926- * Defaults to 8080 for http:// connections and
5927- * 443 for https:// and ssl:// connections.
5928- * @param string $proxy_user a user name for accessing the proxy server
5929- * @param string $proxy_pass a password for accessing the proxy server
5930- *
5931- * @return void
5932- */
5933- function XML_RPC_Client($path, $server, $port = 0,
5934- $proxy = '', $proxy_port = 0,
5935- $proxy_user = '', $proxy_pass = '')
5936- {
5937- $this->path = $path;
5938- $this->proxy_user = $proxy_user;
5939- $this->proxy_pass = $proxy_pass;
5940-
5941- preg_match('@^(http://|https://|ssl://)?(.*)$@', $server, $match);
5942- if ($match[1] == '') {
5943- if ($port == 443) {
5944- $this->server = $match[2];
5945- $this->protocol = 'ssl://';
5946- $this->port = 443;
5947- } else {
5948- $this->server = $match[2];
5949- if ($port) {
5950- $this->port = $port;
5951- }
5952- }
5953- } elseif ($match[1] == 'http://') {
5954- $this->server = $match[2];
5955- if ($port) {
5956- $this->port = $port;
5957- }
5958- } else {
5959- $this->server = $match[2];
5960- $this->protocol = 'ssl://';
5961- if ($port) {
5962- $this->port = $port;
5963- } else {
5964- $this->port = 443;
5965- }
5966- }
5967-
5968- if ($proxy) {
5969- preg_match('@^(http://|https://|ssl://)?(.*)$@', $proxy, $match);
5970- if ($match[1] == '') {
5971- if ($proxy_port == 443) {
5972- $this->proxy = $match[2];
5973- $this->proxy_protocol = 'ssl://';
5974- $this->proxy_port = 443;
5975- } else {
5976- $this->proxy = $match[2];
5977- if ($proxy_port) {
5978- $this->proxy_port = $proxy_port;
5979- }
5980- }
5981- } elseif ($match[1] == 'http://') {
5982- $this->proxy = $match[2];
5983- if ($proxy_port) {
5984- $this->proxy_port = $proxy_port;
5985- }
5986- } else {
5987- $this->proxy = $match[2];
5988- $this->proxy_protocol = 'ssl://';
5989- if ($proxy_port) {
5990- $this->proxy_port = $proxy_port;
5991- } else {
5992- $this->proxy_port = 443;
5993- }
5994- }
5995- }
5996- }
5997-
5998- /**
5999- * Change the current debug mode
6000- *
6001- * @param int $in where 1 = on, 0 = off
6002- *
6003- * @return void
6004- */
6005- function setDebug($in)
6006- {
6007- if ($in) {
6008- $this->debug = 1;
6009- } else {
6010- $this->debug = 0;
6011- }
6012- }
6013-
6014- /**
6015- * Set username and password properties for connecting to the RPC server
6016- *
6017- * @param string $u the user name
6018- * @param string $p the password
6019- *
6020- * @return void
6021- *
6022- * @see XML_RPC_Client::$username, XML_RPC_Client::$password
6023- */
6024- function setCredentials($u, $p)
6025- {
6026- $this->username = $u;
6027- $this->password = $p;
6028- }
6029-
6030- /**
6031- * Transmit the RPC request via HTTP 1.0 protocol
6032- *
6033- * @param object $msg the XML_RPC_Message object
6034- * @param int $timeout how many seconds to wait for the request
6035- *
6036- * @return object an XML_RPC_Response object. 0 is returned if any
6037- * problems happen.
6038- *
6039- * @see XML_RPC_Message, XML_RPC_Client::XML_RPC_Client(),
6040- * XML_RPC_Client::setCredentials()
6041- */
6042- function send($msg, $timeout = 0)
6043- {
6044- if (strtolower(get_class($msg)) != 'xml_rpc_message') {
6045- $this->errstr = 'send()\'s $msg parameter must be an'
6046- . ' XML_RPC_Message object.';
6047- $this->raiseError($this->errstr, XML_RPC_ERROR_PROGRAMMING);
6048- return 0;
6049- }
6050- $msg->debug = $this->debug;
6051- return $this->sendPayloadHTTP10($msg, $this->server, $this->port,
6052- $timeout, $this->username,
6053- $this->password);
6054- }
6055-
6056- /**
6057- * Transmit the RPC request via HTTP 1.0 protocol
6058- *
6059- * Requests should be sent using XML_RPC_Client send() rather than
6060- * calling this method directly.
6061- *
6062- * @param object $msg the XML_RPC_Message object
6063- * @param string $server the server to send the request to
6064- * @param int $port the server port send the request to
6065- * @param int $timeout how many seconds to wait for the request
6066- * before giving up
6067- * @param string $username a user name for accessing the RPC server
6068- * @param string $password a password for accessing the RPC server
6069- *
6070- * @return object an XML_RPC_Response object. 0 is returned if any
6071- * problems happen.
6072- *
6073- * @access protected
6074- * @see XML_RPC_Client::send()
6075- */
6076- function sendPayloadHTTP10($msg, $server, $port, $timeout = 0,
6077- $username = '', $password = '')
6078- {
6079- /*
6080- * If we're using a proxy open a socket to the proxy server
6081- * instead to the xml-rpc server
6082- */
6083- if ($this->proxy) {
6084- if ($this->proxy_protocol == 'http://') {
6085- $protocol = '';
6086- } else {
6087- $protocol = $this->proxy_protocol;
6088- }
6089- if ($timeout > 0) {
6090- $fp = @fsockopen($protocol . $this->proxy, $this->proxy_port,
6091- $this->errno, $this->errstr, $timeout);
6092- } else {
6093- $fp = @fsockopen($protocol . $this->proxy, $this->proxy_port,
6094- $this->errno, $this->errstr);
6095- }
6096- } else {
6097- if ($this->protocol == 'http://') {
6098- $protocol = '';
6099- } else {
6100- $protocol = $this->protocol;
6101- }
6102- if ($timeout > 0) {
6103- $fp = @fsockopen($protocol . $server, $port,
6104- $this->errno, $this->errstr, $timeout);
6105- } else {
6106- $fp = @fsockopen($protocol . $server, $port,
6107- $this->errno, $this->errstr);
6108- }
6109- }
6110-
6111- /*
6112- * Just raising the error without returning it is strange,
6113- * but keep it here for backwards compatibility.
6114- */
6115- if (!$fp && $this->proxy) {
6116- $this->raiseError('Connection to proxy server '
6117- . $this->proxy . ':' . $this->proxy_port
6118- . ' failed. ' . $this->errstr,
6119- XML_RPC_ERROR_CONNECTION_FAILED);
6120- return 0;
6121- } elseif (!$fp) {
6122- $this->raiseError('Connection to RPC server '
6123- . $server . ':' . $port
6124- . ' failed. ' . $this->errstr,
6125- XML_RPC_ERROR_CONNECTION_FAILED);
6126- return 0;
6127- }
6128-
6129- if ($timeout) {
6130- stream_set_timeout($fp, $timeout);
6131- }
6132-
6133- // Pre-emptive BC hacks for fools calling sendPayloadHTTP10() directly
6134- if ($username != $this->username) {
6135- $this->setCredentials($username, $password);
6136- }
6137-
6138- // Only create the payload if it was not created previously
6139- if (empty($msg->payload)) {
6140- $msg->createPayload();
6141- }
6142- $this->createHeaders($msg);
6143-
6144- $op = $this->headers . "\r\n\r\n";
6145- $op .= $msg->payload;
6146-
6147- if (!fputs($fp, $op, strlen($op))) {
6148- $this->errstr = 'Write error';
6149- return 0;
6150- }
6151- $resp = $msg->parseResponseFile($fp);
6152-
6153- $meta = stream_get_meta_data($fp);
6154- if ($meta['timed_out']) {
6155- fclose($fp);
6156- $this->errstr = 'RPC server did not send response before timeout.';
6157- $this->raiseError($this->errstr, XML_RPC_ERROR_CONNECTION_FAILED);
6158- return 0;
6159- }
6160-
6161- fclose($fp);
6162- return $resp;
6163- }
6164-
6165- /**
6166- * Determines the HTTP headers and puts it in the $headers property
6167- *
6168- * @param object $msg the XML_RPC_Message object
6169- *
6170- * @return boolean TRUE if okay, FALSE if the message payload isn't set.
6171- *
6172- * @access protected
6173- */
6174- function createHeaders($msg)
6175- {
6176- if (empty($msg->payload)) {
6177- return false;
6178- }
6179- if ($this->proxy) {
6180- $this->headers = 'POST ' . $this->protocol . $this->server;
6181- if ($this->proxy_port) {
6182- $this->headers .= ':' . $this->port;
6183- }
6184- } else {
6185- $this->headers = 'POST ';
6186- }
6187- $this->headers .= $this->path. " HTTP/1.0\r\n";
6188-
6189- $this->headers .= "User-Agent: PEAR XML_RPC\r\n";
6190- $this->headers .= 'Host: ' . $this->server . "\r\n";
6191-
6192- if ($this->proxy && $this->proxy_user) {
6193- $this->headers .= 'Proxy-Authorization: Basic '
6194- . base64_encode("$this->proxy_user:$this->proxy_pass")
6195- . "\r\n";
6196- }
6197-
6198- // thanks to Grant Rauscher <grant7@firstworld.net> for this
6199- if ($this->username) {
6200- $this->headers .= 'Authorization: Basic '
6201- . base64_encode("$this->username:$this->password")
6202- . "\r\n";
6203- }
6204-
6205- $this->headers .= "Content-Type: text/xml\r\n";
6206- $this->headers .= 'Content-Length: ' . strlen($msg->payload);
6207- return true;
6208- }
6209-}
6210-
6211-/**
6212- * The methods and properties for interpreting responses to XML RPC requests
6213- *
6214- * @category Web Services
6215- * @package XML_RPC
6216- * @author Edd Dumbill <edd@usefulinc.com>
6217- * @author Stig Bakken <stig@php.net>
6218- * @author Martin Jansen <mj@php.net>
6219- * @author Daniel Convissor <danielc@php.net>
6220- * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
6221- * @version Release: 1.3.1
6222- * @link http://pear.php.net/package/XML_RPC
6223- */
6224-class XML_RPC_Response extends XML_RPC_Base
6225-{
6226- var $xv;
6227- var $fn;
6228- var $fs;
6229- var $hdrs;
6230-
6231- /**
6232- * @return void
6233- */
6234- function XML_RPC_Response($val, $fcode = 0, $fstr = '')
6235- {
6236- if ($fcode != 0) {
6237- $this->fn = $fcode;
6238- $this->fs = htmlspecialchars($fstr);
6239- } else {
6240- $this->xv = $val;
6241- }
6242- }
6243-
6244- /**
6245- * @return int the error code
6246- */
6247- function faultCode()
6248- {
6249- if (isset($this->fn)) {
6250- return $this->fn;
6251- } else {
6252- return 0;
6253- }
6254- }
6255-
6256- /**
6257- * @return string the error string
6258- */
6259- function faultString()
6260- {
6261- return $this->fs;
6262- }
6263-
6264- /**
6265- * @return mixed the value
6266- */
6267- function value()
6268- {
6269- return $this->xv;
6270- }
6271-
6272- /**
6273- * @return string the error message in XML format
6274- */
6275- function serialize()
6276- {
6277- $rs = "<methodResponse>\n";
6278- if ($this->fn) {
6279- $rs .= "<fault>
6280- <value>
6281- <struct>
6282- <member>
6283- <name>faultCode</name>
6284- <value><int>" . $this->fn . "</int></value>
6285- </member>
6286- <member>
6287- <name>faultString</name>
6288- <value><string>" . $this->fs . "</string></value>
6289- </member>
6290- </struct>
6291- </value>
6292-</fault>";
6293- } else {
6294- $rs .= "<params>\n<param>\n" . $this->xv->serialize() .
6295- "</param>\n</params>";
6296- }
6297- $rs .= "\n</methodResponse>";
6298- return $rs;
6299- }
6300-}
6301-
6302-/**
6303- * The methods and properties for composing XML RPC messages
6304- *
6305- * @category Web Services
6306- * @package XML_RPC
6307- * @author Edd Dumbill <edd@usefulinc.com>
6308- * @author Stig Bakken <stig@php.net>
6309- * @author Martin Jansen <mj@php.net>
6310- * @author Daniel Convissor <danielc@php.net>
6311- * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
6312- * @version Release: 1.3.1
6313- * @link http://pear.php.net/package/XML_RPC
6314- */
6315-class XML_RPC_Message extends XML_RPC_Base
6316-{
6317- /**
6318- * The current debug mode (1 = on, 0 = off)
6319- * @var integer
6320- */
6321- var $debug = 0;
6322-
6323- /**
6324- * The encoding to be used for outgoing messages
6325- *
6326- * Defaults to the value of <var>$GLOBALS['XML_RPC_defencoding']</var>
6327- *
6328- * @var string
6329- * @see XML_RPC_Message::setSendEncoding(),
6330- * $GLOBALS['XML_RPC_defencoding'], XML_RPC_Message::xml_header()
6331- */
6332- var $send_encoding = '';
6333-
6334- /**
6335- * The method presently being evaluated
6336- * @var string
6337- */
6338- var $methodname = '';
6339-
6340- /**
6341- * @var array
6342- */
6343- var $params = array();
6344-
6345- /**
6346- * The XML message being generated
6347- * @var string
6348- */
6349- var $payload = '';
6350-
6351- /**
6352- * @return void
6353- */
6354- function XML_RPC_Message($meth, $pars = 0)
6355- {
6356- $this->methodname = $meth;
6357- if (is_array($pars) && sizeof($pars) > 0) {
6358- for ($i = 0; $i < sizeof($pars); $i++) {
6359- $this->addParam($pars[$i]);
6360- }
6361- }
6362- }
6363-
6364- /**
6365- * Produces the XML declaration including the encoding attribute
6366- *
6367- * The encoding is determined by this class' <var>$send_encoding</var>
6368- * property. If the <var>$send_encoding</var> property is not set, use
6369- * <var>$GLOBALS['XML_RPC_defencoding']</var>.
6370- *
6371- * @return string the XML declaration and <methodCall> element
6372- *
6373- * @see XML_RPC_Message::setSendEncoding(),
6374- * XML_RPC_Message::$send_encoding, $GLOBALS['XML_RPC_defencoding']
6375- */
6376- function xml_header()
6377- {
6378- global $XML_RPC_defencoding;
6379- if (!$this->send_encoding) {
6380- $this->send_encoding = $XML_RPC_defencoding;
6381- }
6382- return '<?xml version="1.0" encoding="' . $this->send_encoding . '"?>'
6383- . "\n<methodCall>\n";
6384- }
6385-
6386- /**
6387- * @return string the closing </methodCall> tag
6388- */
6389- function xml_footer()
6390- {
6391- return "</methodCall>\n";
6392- }
6393-
6394- /**
6395- * @return void
6396- *
6397- * @uses XML_RPC_Message::xml_header(), XML_RPC_Message::xml_footer()
6398- */
6399- function createPayload()
6400- {
6401- $this->payload = $this->xml_header();
6402- $this->payload .= '<methodName>' . $this->methodname . "</methodName>\n";
6403- $this->payload .= "<params>\n";
6404- for ($i = 0; $i < sizeof($this->params); $i++) {
6405- $p = $this->params[$i];
6406- $this->payload .= "<param>\n" . $p->serialize() . "</param>\n";
6407- }
6408- $this->payload .= "</params>\n";
6409- $this->payload .= $this->xml_footer();
6410- $this->payload = ereg_replace("[\r\n]+", "\r\n", $this->payload);
6411- }
6412-
6413- /**
6414- * @return string the name of the method
6415- */
6416- function method($meth = '')
6417- {
6418- if ($meth != '') {
6419- $this->methodname = $meth;
6420- }
6421- return $this->methodname;
6422- }
6423-
6424- /**
6425- * @return string the payload
6426- */
6427- function serialize()
6428- {
6429- $this->createPayload();
6430- return $this->payload;
6431- }
6432-
6433- /**
6434- * @return void
6435- */
6436- function addParam($par)
6437- {
6438- $this->params[] = $par;
6439- }
6440-
6441- /**
6442- * Obtains an XML_RPC_Value object for the given parameter
6443- *
6444- * @param int $i the index number of the parameter to obtain
6445- *
6446- * @return object the XML_RPC_Value object.
6447- * If the parameter doesn't exist, an XML_RPC_Response object.
6448- *
6449- * @since Returns XML_RPC_Response object on error since Release 1.3.0
6450- */
6451- function getParam($i)
6452- {
6453- global $XML_RPC_err, $XML_RPC_str;
6454-
6455- if (isset($this->params[$i])) {
6456- return $this->params[$i];
6457- } else {
6458- $this->raiseError('The submitted request did not contain this parameter',
6459- XML_RPC_ERROR_INCORRECT_PARAMS);
6460- return new XML_RPC_Response(0, $XML_RPC_err['incorrect_params'],
6461- $XML_RPC_str['incorrect_params']);
6462- }
6463- }
6464-
6465- /**
6466- * @return int the number of parameters
6467- */
6468- function getNumParams()
6469- {
6470- return sizeof($this->params);
6471- }
6472-
6473- /**
6474- * Sets the XML declaration's encoding attribute
6475- *
6476- * @param string $type the encoding type (ISO-8859-1, UTF-8 or US-ASCII)
6477- *
6478- * @return void
6479- *
6480- * @see XML_RPC_Message::$send_encoding, XML_RPC_Message::xml_header()
6481- * @since Method available since Release 1.2.0
6482- */
6483- function setSendEncoding($type)
6484- {
6485- $this->send_encoding = $type;
6486- }
6487-
6488- /**
6489- * Determine the XML's encoding via the encoding attribute
6490- * in the XML declaration
6491- *
6492- * If the encoding parameter is not set or is not ISO-8859-1, UTF-8
6493- * or US-ASCII, $XML_RPC_defencoding will be returned.
6494- *
6495- * @param string $data the XML that will be parsed
6496- *
6497- * @return string the encoding to be used
6498- *
6499- * @link http://php.net/xml_parser_create
6500- * @since Method available since Release 1.2.0
6501- */
6502- function getEncoding($data)
6503- {
6504- global $XML_RPC_defencoding;
6505-
6506- if (preg_match('/<\?xml[^>]*\s*encoding\s*=\s*[\'"]([^"\']*)[\'"]/i',
6507- $data, $match))
6508- {
6509- $match[1] = trim(strtoupper($match[1]));
6510- switch ($match[1]) {
6511- case 'ISO-8859-1':
6512- case 'UTF-8':
6513- case 'US-ASCII':
6514- return $match[1];
6515- break;
6516-
6517- default:
6518- return $XML_RPC_defencoding;
6519- }
6520- } else {
6521- return $XML_RPC_defencoding;
6522- }
6523- }
6524-
6525- /**
6526- * @return object a new XML_RPC_Response object
6527- */
6528- function parseResponseFile($fp)
6529- {
6530- $ipd = '';
6531- while ($data = @fread($fp, 8192)) {
6532- $ipd .= $data;
6533- }
6534- return $this->parseResponse($ipd);
6535- }
6536-
6537- /**
6538- * @return object a new XML_RPC_Response object
6539- */
6540- function parseResponse($data = '')
6541- {
6542- global $XML_RPC_xh, $XML_RPC_err, $XML_RPC_str, $XML_RPC_defencoding;
6543-
6544- $encoding = $this->getEncoding($data);
6545- $parser_resource = xml_parser_create($encoding);
6546- $parser = (int) $parser_resource;
6547-
6548- $XML_RPC_xh[$parser] = array();
6549-
6550- $XML_RPC_xh[$parser]['st'] = '';
6551- $XML_RPC_xh[$parser]['cm'] = 0;
6552- $XML_RPC_xh[$parser]['isf'] = 0;
6553- $XML_RPC_xh[$parser]['ac'] = '';
6554- $XML_RPC_xh[$parser]['qt'] = '';
6555-
6556- xml_parser_set_option($parser_resource, XML_OPTION_CASE_FOLDING, true);
6557- xml_set_element_handler($parser_resource, 'XML_RPC_se', 'XML_RPC_ee');
6558- xml_set_character_data_handler($parser_resource, 'XML_RPC_cd');
6559-
6560- $hdrfnd = 0;
6561- if ($this->debug) {
6562- print "<PRE>---GOT---\n";
6563- print isset($_SERVER['SERVER_PROTOCOL']) ? htmlspecialchars($data) : $data;
6564- print "\n---END---\n</PRE>";
6565- }
6566-
6567- // See if response is a 200 or a 100 then a 200, else raise error.
6568- // But only do this if we're using the HTTP protocol.
6569- if (ereg('^HTTP', $data) &&
6570- !ereg('^HTTP/[0-9\.]+ 200 ', $data) &&
6571- !preg_match('@^HTTP/[0-9\.]+ 10[0-9]([A-Za-z ]+)?[\r\n]+HTTP/[0-9\.]+ 200@', $data))
6572- {
6573- $errstr = substr($data, 0, strpos($data, "\n") - 1);
6574- error_log('HTTP error, got response: ' . $errstr);
6575- $r = new XML_RPC_Response(0, $XML_RPC_err['http_error'],
6576- $XML_RPC_str['http_error'] . ' (' .
6577- $errstr . ')');
6578- xml_parser_free($parser_resource);
6579- return $r;
6580- }
6581- // gotta get rid of headers here
6582-
6583-
6584- if (!$hdrfnd && ($brpos = strpos($data,"\r\n\r\n"))) {
6585- $XML_RPC_xh[$parser]['ha'] = substr($data, 0, $brpos);
6586- $data = substr($data, $brpos + 4);
6587- $hdrfnd = 1;
6588- }
6589-
6590- /*
6591- * be tolerant of junk after methodResponse
6592- * (e.g. javascript automatically inserted by free hosts)
6593- * thanks to Luca Mariano <luca.mariano@email.it>
6594- */
6595- $data = substr($data, 0, strpos($data, "</methodResponse>") + 17);
6596-
6597- if (!xml_parse($parser_resource, $data, sizeof($data))) {
6598- // thanks to Peter Kocks <peter.kocks@baygate.com>
6599- if (xml_get_current_line_number($parser_resource) == 1) {
6600- $errstr = 'XML error at line 1, check URL';
6601- } else {
6602- $errstr = sprintf('XML error: %s at line %d',
6603- xml_error_string(xml_get_error_code($parser_resource)),
6604- xml_get_current_line_number($parser_resource));
6605- }
6606- error_log($errstr);
6607- $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'],
6608- $XML_RPC_str['invalid_return']);
6609- xml_parser_free($parser_resource);
6610- return $r;
6611- }
6612- xml_parser_free($parser_resource);
6613- if ($this->debug) {
6614- print '<PRE>---EVALING---[' .
6615- strlen($XML_RPC_xh[$parser]['st']) . " chars]---\n" .
6616- htmlspecialchars($XML_RPC_xh[$parser]['st']) . ";\n---END---</PRE>";
6617- }
6618- if (strlen($XML_RPC_xh[$parser]['st']) == 0) {
6619- // then something odd has happened
6620- // and it's time to generate a client side error
6621- // indicating something odd went on
6622- $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'],
6623- $XML_RPC_str['invalid_return']);
6624- } else {
6625- eval('$v=' . $XML_RPC_xh[$parser]['st'] . '; $allOK=1;');
6626- if ($XML_RPC_xh[$parser]['isf']) {
6627- $f = $v->structmem('faultCode');
6628- $fs = $v->structmem('faultString');
6629- $r = new XML_RPC_Response($v, $f->scalarval(),
6630- $fs->scalarval());
6631- } else {
6632- $r = new XML_RPC_Response($v);
6633- }
6634- }
6635- $r->hdrs = split("\r?\n", $XML_RPC_xh[$parser]['ha'][1]);
6636- return $r;
6637- }
6638-}
6639-
6640-/**
6641- * The methods and properties that represent data in XML RPC format
6642- *
6643- * @category Web Services
6644- * @package XML_RPC
6645- * @author Edd Dumbill <edd@usefulinc.com>
6646- * @author Stig Bakken <stig@php.net>
6647- * @author Martin Jansen <mj@php.net>
6648- * @author Daniel Convissor <danielc@php.net>
6649- * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
6650- * @version Release: 1.3.1
6651- * @link http://pear.php.net/package/XML_RPC
6652- */
6653-class XML_RPC_Value extends XML_RPC_Base
6654-{
6655- var $me = array();
6656- var $mytype = 0;
6657-
6658- /**
6659- * @return void
6660- */
6661- function XML_RPC_Value($val = -1, $type = '')
6662- {
6663- global $XML_RPC_Types;
6664- $this->me = array();
6665- $this->mytype = 0;
6666- if ($val != -1 || $type != '') {
6667- if ($type == '') {
6668- $type = 'string';
6669- }
6670- if (!array_key_exists($type, $XML_RPC_Types)) {
6671- // XXX
6672- // need some way to report this error
6673- } elseif ($XML_RPC_Types[$type] == 1) {
6674- $this->addScalar($val, $type);
6675- } elseif ($XML_RPC_Types[$type] == 2) {
6676- $this->addArray($val);
6677- } elseif ($XML_RPC_Types[$type] == 3) {
6678- $this->addStruct($val);
6679- }
6680- }
6681- }
6682-
6683- /**
6684- * @return int returns 1 if successful or 0 if there are problems
6685- */
6686- function addScalar($val, $type = 'string')
6687- {
6688- global $XML_RPC_Types, $XML_RPC_Boolean;
6689-
6690- if ($this->mytype == 1) {
6691- $this->raiseError('Scalar can have only one value',
6692- XML_RPC_ERROR_INVALID_TYPE);
6693- return 0;
6694- }
6695- $typeof = $XML_RPC_Types[$type];
6696- if ($typeof != 1) {
6697- $this->raiseError("Not a scalar type (${typeof})",
6698- XML_RPC_ERROR_INVALID_TYPE);
6699- return 0;
6700- }
6701-
6702- if ($type == $XML_RPC_Boolean) {
6703- if (strcasecmp($val, 'true') == 0
6704- || $val == 1
6705- || ($val == true && strcasecmp($val, 'false')))
6706- {
6707- $val = 1;
6708- } else {
6709- $val = 0;
6710- }
6711- }
6712-
6713- if ($this->mytype == 2) {
6714- // we're adding to an array here
6715- $ar = $this->me['array'];
6716- $ar[] = new XML_RPC_Value($val, $type);
6717- $this->me['array'] = $ar;
6718- } else {
6719- // a scalar, so set the value and remember we're scalar
6720- $this->me[$type] = $val;
6721- $this->mytype = $typeof;
6722- }
6723- return 1;
6724- }
6725-
6726- /**
6727- * @return int returns 1 if successful or 0 if there are problems
6728- */
6729- function addArray($vals)
6730- {
6731- global $XML_RPC_Types;
6732- if ($this->mytype != 0) {
6733- $this->raiseError(
6734- 'Already initialized as a [' . $this->kindOf() . ']',
6735- XML_RPC_ERROR_ALREADY_INITIALIZED);
6736- return 0;
6737- }
6738- $this->mytype = $XML_RPC_Types['array'];
6739- $this->me['array'] = $vals;
6740- return 1;
6741- }
6742-
6743- /**
6744- * @return int returns 1 if successful or 0 if there are problems
6745- */
6746- function addStruct($vals)
6747- {
6748- global $XML_RPC_Types;
6749- if ($this->mytype != 0) {
6750- $this->raiseError(
6751- 'Already initialized as a [' . $this->kindOf() . ']',
6752- XML_RPC_ERROR_ALREADY_INITIALIZED);
6753- return 0;
6754- }
6755- $this->mytype = $XML_RPC_Types['struct'];
6756- $this->me['struct'] = $vals;
6757- return 1;
6758- }
6759-
6760- /**
6761- * @return void
6762- */
6763- function dump($ar)
6764- {
6765- reset($ar);
6766- foreach ($ar as $key => $val) {
6767- echo "$key => $val<br />";
6768- if ($key == 'array') {
6769- foreach ($val as $key2 => $val2) {
6770- echo "-- $key2 => $val2<br />";
6771- }
6772- }
6773- }
6774- }
6775-
6776- /**
6777- * @return string the data type of the current value
6778- */
6779- function kindOf()
6780- {
6781- switch ($this->mytype) {
6782- case 3:
6783- return 'struct';
6784-
6785- case 2:
6786- return 'array';
6787-
6788- case 1:
6789- return 'scalar';
6790-
6791- default:
6792- return 'undef';
6793- }
6794- }
6795-
6796- /**
6797- * @return string the data in XML format
6798- */
6799- function serializedata($typ, $val)
6800- {
6801- $rs = '';
6802- global $XML_RPC_Types, $XML_RPC_Base64, $XML_RPC_String, $XML_RPC_Boolean;
6803- if (!array_key_exists($typ, $XML_RPC_Types)) {
6804- // XXX
6805- // need some way to report this error
6806- return;
6807- }
6808- switch ($XML_RPC_Types[$typ]) {
6809- case 3:
6810- // struct
6811- $rs .= "<struct>\n";
6812- reset($val);
6813- foreach ($val as $key2 => $val2) {
6814- $rs .= "<member><name>${key2}</name>\n";
6815- $rs .= $this->serializeval($val2);
6816- $rs .= "</member>\n";
6817- }
6818- $rs .= '</struct>';
6819- break;
6820-
6821- case 2:
6822- // array
6823- $rs .= "<array>\n<data>\n";
6824- for ($i = 0; $i < sizeof($val); $i++) {
6825- $rs .= $this->serializeval($val[$i]);
6826- }
6827- $rs .= "</data>\n</array>";
6828- break;
6829-
6830- case 1:
6831- switch ($typ) {
6832- case $XML_RPC_Base64:
6833- $rs .= "<${typ}>" . base64_encode($val) . "</${typ}>";
6834- break;
6835- case $XML_RPC_Boolean:
6836- $rs .= "<${typ}>" . ($val ? '1' : '0') . "</${typ}>";
6837- break;
6838- case $XML_RPC_String:
6839- $rs .= "<${typ}>" . htmlspecialchars($val). "</${typ}>";
6840- break;
6841- default:
6842- $rs .= "<${typ}>${val}</${typ}>";
6843- }
6844- }
6845- return $rs;
6846- }
6847-
6848- /**
6849- * @return string the data in XML format
6850- */
6851- function serialize()
6852- {
6853- return $this->serializeval($this);
6854- }
6855-
6856- /**
6857- * @return string the data in XML format
6858- */
6859- function serializeval($o)
6860- {
6861- $rs = '';
6862- $ar = $o->me;
6863- reset($ar);
6864- list($typ, $val) = each($ar);
6865- $rs .= '<value>';
6866- $rs .= $this->serializedata($typ, $val);
6867- $rs .= "</value>\n";
6868- return $rs;
6869- }
6870-
6871- /**
6872- * @return mixed the contents of the element requested
6873- */
6874- function structmem($m)
6875- {
6876- return $this->me['struct'][$m];
6877- }
6878-
6879- /**
6880- * @return void
6881- */
6882- function structreset()
6883- {
6884- reset($this->me['struct']);
6885- }
6886-
6887- /**
6888- * @return the key/value pair of the struct's current element
6889- */
6890- function structeach()
6891- {
6892- return each($this->me['struct']);
6893- }
6894-
6895- /**
6896- * @return mixed the current value
6897- */
6898- function getval()
6899- {
6900- // UNSTABLE
6901- global $XML_RPC_BOOLEAN, $XML_RPC_Base64;
6902-
6903- reset($this->me);
6904- $b = current($this->me);
6905-
6906- // contributed by I Sofer, 2001-03-24
6907- // add support for nested arrays to scalarval
6908- // i've created a new method here, so as to
6909- // preserve back compatibility
6910-
6911- if (is_array($b)) {
6912- foreach ($b as $id => $cont) {
6913- $b[$id] = $cont->scalarval();
6914- }
6915- }
6916-
6917- // add support for structures directly encoding php objects
6918- if (is_object($b)) {
6919- $t = get_object_vars($b);
6920- foreach ($t as $id => $cont) {
6921- $t[$id] = $cont->scalarval();
6922- }
6923- foreach ($t as $id => $cont) {
6924- eval('$b->'.$id.' = $cont;');
6925- }
6926- }
6927-
6928- // end contrib
6929- return $b;
6930- }
6931-
6932- /**
6933- * @return mixed
6934- */
6935- function scalarval()
6936- {
6937- global $XML_RPC_Boolean, $XML_RPC_Base64;
6938- reset($this->me);
6939- return current($this->me);
6940- }
6941-
6942- /**
6943- * @return string
6944- */
6945- function scalartyp()
6946- {
6947- global $XML_RPC_I4, $XML_RPC_Int;
6948- reset($this->me);
6949- $a = key($this->me);
6950- if ($a == $XML_RPC_I4) {
6951- $a = $XML_RPC_Int;
6952- }
6953- return $a;
6954- }
6955-
6956- /**
6957- * @return mixed the struct's current element
6958- */
6959- function arraymem($m)
6960- {
6961- return $this->me['array'][$m];
6962- }
6963-
6964- /**
6965- * @return int the number of elements in the array
6966- */
6967- function arraysize()
6968- {
6969- reset($this->me);
6970- list($a, $b) = each($this->me);
6971- return sizeof($b);
6972- }
6973-
6974- /**
6975- * Determines if the item submitted is an XML_RPC_Value object
6976- *
6977- * @param mixed $val the variable to be evaluated
6978- *
6979- * @return bool TRUE if the item is an XML_RPC_Value object
6980- *
6981- * @static
6982- * @since Method available since Release 1.3.0
6983- */
6984- function isValue($val)
6985- {
6986- return (strtolower(get_class($val)) == 'xml_rpc_value');
6987- }
6988-}
6989-
6990-/**
6991- * Return an ISO8601 encoded string
6992- *
6993- * While timezones ought to be supported, the XML-RPC spec says:
6994- *
6995- * "Don't assume a timezone. It should be specified by the server in its
6996- * documentation what assumptions it makes about timezones."
6997- *
6998- * This routine always assumes localtime unless $utc is set to 1, in which
6999- * case UTC is assumed and an adjustment for locale is made when encoding.
7000- *
7001- * @return string the formatted date
7002- */
7003-function XML_RPC_iso8601_encode($timet, $utc = 0)
7004-{
7005- if (!$utc) {
7006- $t = strftime('%Y%m%dT%H:%M:%S', $timet);
7007- } else {
7008- if (function_exists('gmstrftime')) {
7009- // gmstrftime doesn't exist in some versions
7010- // of PHP
7011- $t = gmstrftime('%Y%m%dT%H:%M:%S', $timet);
7012- } else {
7013- $t = strftime('%Y%m%dT%H:%M:%S', $timet - date('Z'));
7014- }
7015- }
7016- return $t;
7017-}
7018-
7019-/**
7020- * Convert a datetime string into a Unix timestamp
7021- *
7022- * While timezones ought to be supported, the XML-RPC spec says:
7023- *
7024- * "Don't assume a timezone. It should be specified by the server in its
7025- * documentation what assumptions it makes about timezones."
7026- *
7027- * This routine always assumes localtime unless $utc is set to 1, in which
7028- * case UTC is assumed and an adjustment for locale is made when encoding.
7029- *
7030- * @return int the unix timestamp of the date submitted
7031- */
7032-function XML_RPC_iso8601_decode($idate, $utc = 0)
7033-{
7034- $t = 0;
7035- if (ereg('([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})', $idate, $regs)) {
7036- if ($utc) {
7037- $t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
7038- } else {
7039- $t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
7040- }
7041- }
7042- return $t;
7043-}
7044-
7045-/**
7046- * Converts an XML_RPC_Value object into native PHP types
7047- *
7048- * @param object $XML_RPC_val the XML_RPC_Value object to decode
7049- *
7050- * @return mixed the PHP values
7051- */
7052-function XML_RPC_decode($XML_RPC_val)
7053-{
7054- $kind = $XML_RPC_val->kindOf();
7055-
7056- if ($kind == 'scalar') {
7057- return $XML_RPC_val->scalarval();
7058-
7059- } elseif ($kind == 'array') {
7060- $size = $XML_RPC_val->arraysize();
7061- $arr = array();
7062- for ($i = 0; $i < $size; $i++) {
7063- $arr[] = XML_RPC_decode($XML_RPC_val->arraymem($i));
7064- }
7065- return $arr;
7066-
7067- } elseif ($kind == 'struct') {
7068- $XML_RPC_val->structreset();
7069- $arr = array();
7070- while (list($key, $value) = $XML_RPC_val->structeach()) {
7071- $arr[$key] = XML_RPC_decode($value);
7072- }
7073- return $arr;
7074- }
7075-}
7076-
7077-/**
7078- * Converts native PHP types into an XML_RPC_Value object
7079- *
7080- * @param mixed $php_val the PHP value or variable you want encoded
7081- *
7082- * @return object the XML_RPC_Value object
7083- */
7084-function XML_RPC_encode($php_val)
7085-{
7086- global $XML_RPC_Boolean, $XML_RPC_Int, $XML_RPC_Double, $XML_RPC_String,
7087- $XML_RPC_Array, $XML_RPC_Struct;
7088-
7089- $type = gettype($php_val);
7090- $XML_RPC_val = new XML_RPC_Value;
7091-
7092- switch ($type) {
7093- case 'array':
7094- if (empty($php_val)) {
7095- $XML_RPC_val->addArray($php_val);
7096- break;
7097- }
7098- $tmp = array_diff(array_keys($php_val), range(0, count($php_val)-1));
7099- if (empty($tmp)) {
7100- $arr = array();
7101- foreach ($php_val as $k => $v) {
7102- $arr[$k] = XML_RPC_encode($v);
7103- }
7104- $XML_RPC_val->addArray($arr);
7105- break;
7106- }
7107- // fall though if it's not an enumerated array
7108-
7109- case 'object':
7110- $arr = array();
7111- foreach ($php_val as $k => $v) {
7112- $arr[$k] = XML_RPC_encode($v);
7113- }
7114- $XML_RPC_val->addStruct($arr);
7115- break;
7116-
7117- case 'integer':
7118- $XML_RPC_val->addScalar($php_val, $XML_RPC_Int);
7119- break;
7120-
7121- case 'double':
7122- $XML_RPC_val->addScalar($php_val, $XML_RPC_Double);
7123- break;
7124-
7125- case 'string':
7126- case 'NULL':
7127- $XML_RPC_val->addScalar($php_val, $XML_RPC_String);
7128- break;
7129-
7130- case 'boolean':
7131- // Add support for encoding/decoding of booleans, since they
7132- // are supported in PHP
7133- // by <G_Giunta_2001-02-29>
7134- $XML_RPC_val->addScalar($php_val, $XML_RPC_Boolean);
7135- break;
7136-
7137- case 'unknown type':
7138- default:
7139- $XML_RPC_val = false;
7140- }
7141- return $XML_RPC_val;
7142-}
7143-
7144-/*
7145- * Local variables:
7146- * tab-width: 4
7147- * c-basic-offset: 4
7148- * c-hanging-comment-ender-p: nil
7149- * End:
7150- */
7151-
7152-?>
7153-
7154-
7155-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
7156-
7157-/**
7158- * Server commands for our PHP implementation of the XML-RPC protocol
7159- *
7160- * This is a PEAR-ified version of Useful inc's XML-RPC for PHP.
7161- * It has support for HTTP transport, proxies and authentication.
7162- *
7163- * PHP versions 4 and 5
7164- *
7165- * LICENSE: License is granted to use or modify this software
7166- * ("XML-RPC for PHP") for commercial or non-commercial use provided the
7167- * copyright of the author is preserved in any distributed or derivative work.
7168- *
7169- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESSED OR
7170- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
7171- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
7172- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
7173- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
7174- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
7175- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
7176- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7177- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
7178- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7179- *
7180- * @category Web Services
7181- * @package XML_RPC
7182- * @author Edd Dumbill <edd@usefulinc.com>
7183- * @author Stig Bakken <stig@php.net>
7184- * @author Martin Jansen <mj@php.net>
7185- * @author Daniel Convissor <danielc@php.net>
7186- * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
7187- * @version CVS: $Id: Server.php,v 1.26 2005/05/09 21:39:47 danielc Exp $
7188- * @link http://pear.php.net/package/XML_RPC
7189- */
7190-
7191-
7192-/**
7193- * Pull in the XML_RPC class
7194- */
7195-require_once 'XML/RPC.php';
7196-
7197-
7198-/**
7199- * signature for system.listMethods: return = array,
7200- * parameters = a string or nothing
7201- * @global array $GLOBALS['XML_RPC_Server_listMethods_sig']
7202- */
7203-$GLOBALS['XML_RPC_Server_listMethods_sig'] = array(
7204- array($GLOBALS['XML_RPC_Array'],
7205- $GLOBALS['XML_RPC_String']
7206- ),
7207- array($GLOBALS['XML_RPC_Array'])
7208-);
7209-
7210-/**
7211- * docstring for system.listMethods
7212- * @global string $GLOBALS['XML_RPC_Server_listMethods_doc']
7213- */
7214-$GLOBALS['XML_RPC_Server_listMethods_doc'] = 'This method lists all the'
7215- . ' methods that the XML-RPC server knows how to dispatch';
7216-
7217-/**
7218- * signature for system.methodSignature: return = array,
7219- * parameters = string
7220- * @global array $GLOBALS['XML_RPC_Server_methodSignature_sig']
7221- */
7222-$GLOBALS['XML_RPC_Server_methodSignature_sig'] = array(
7223- array($GLOBALS['XML_RPC_Array'],
7224- $GLOBALS['XML_RPC_String']
7225- )
7226-);
7227-
7228-/**
7229- * docstring for system.methodSignature
7230- * @global string $GLOBALS['XML_RPC_Server_methodSignature_doc']
7231- */
7232-$GLOBALS['XML_RPC_Server_methodSignature_doc'] = 'Returns an array of known'
7233- . ' signatures (an array of arrays) for the method name passed. If'
7234- . ' no signatures are known, returns a none-array (test for type !='
7235- . ' array to detect missing signature)';
7236-
7237-/**
7238- * signature for system.methodHelp: return = string,
7239- * parameters = string
7240- * @global array $GLOBALS['XML_RPC_Server_methodHelp_sig']
7241- */
7242-$GLOBALS['XML_RPC_Server_methodHelp_sig'] = array(
7243- array($GLOBALS['XML_RPC_String'],
7244- $GLOBALS['XML_RPC_String']
7245- )
7246-);
7247-
7248-/**
7249- * docstring for methodHelp
7250- * @global string $GLOBALS['XML_RPC_Server_methodHelp_doc']
7251- */
7252-$GLOBALS['XML_RPC_Server_methodHelp_doc'] = 'Returns help text if defined'
7253- . ' for the method passed, otherwise returns an empty string';
7254-
7255-/**
7256- * dispatch map for the automatically declared XML-RPC methods.
7257- * @global array $GLOBALS['XML_RPC_Server_dmap']
7258- */
7259-$GLOBALS['XML_RPC_Server_dmap'] = array(
7260- 'system.listMethods' => array(
7261- 'function' => 'XML_RPC_Server_listMethods',
7262- 'signature' => $GLOBALS['XML_RPC_Server_listMethods_sig'],
7263- 'docstring' => $GLOBALS['XML_RPC_Server_listMethods_doc']
7264- ),
7265- 'system.methodHelp' => array(
7266- 'function' => 'XML_RPC_Server_methodHelp',
7267- 'signature' => $GLOBALS['XML_RPC_Server_methodHelp_sig'],
7268- 'docstring' => $GLOBALS['XML_RPC_Server_methodHelp_doc']
7269- ),
7270- 'system.methodSignature' => array(
7271- 'function' => 'XML_RPC_Server_methodSignature',
7272- 'signature' => $GLOBALS['XML_RPC_Server_methodSignature_sig'],
7273- 'docstring' => $GLOBALS['XML_RPC_Server_methodSignature_doc']
7274- )
7275-);
7276-
7277-/**
7278- * @global string $GLOBALS['XML_RPC_Server_debuginfo']
7279- */
7280-$GLOBALS['XML_RPC_Server_debuginfo'] = '';
7281-
7282-
7283-/**
7284- * Lists all the methods that the XML-RPC server knows how to dispatch
7285- *
7286- * @return object a new XML_RPC_Response object
7287- */
7288-function XML_RPC_Server_listMethods($server, $m)
7289-{
7290- global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
7291-
7292- $v = new XML_RPC_Value();
7293- $outAr = array();
7294- foreach ($server->dmap as $key => $val) {
7295- $outAr[] = new XML_RPC_Value($key, 'string');
7296- }
7297- foreach ($XML_RPC_Server_dmap as $key => $val) {
7298- $outAr[] = new XML_RPC_Value($key, 'string');
7299- }
7300- $v->addArray($outAr);
7301- return new XML_RPC_Response($v);
7302-}
7303-
7304-/**
7305- * Returns an array of known signatures (an array of arrays)
7306- * for the given method
7307- *
7308- * If no signatures are known, returns a none-array
7309- * (test for type != array to detect missing signature)
7310- *
7311- * @return object a new XML_RPC_Response object
7312- */
7313-function XML_RPC_Server_methodSignature($server, $m)
7314-{
7315- global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
7316-
7317- $methName = $m->getParam(0);
7318- $methName = $methName->scalarval();
7319- if (strpos($methName, 'system.') === 0) {
7320- $dmap = $XML_RPC_Server_dmap;
7321- $sysCall = 1;
7322- } else {
7323- $dmap = $server->dmap;
7324- $sysCall = 0;
7325- }
7326- // print "<!-- ${methName} -->\n";
7327- if (isset($dmap[$methName])) {
7328- if ($dmap[$methName]['signature']) {
7329- $sigs = array();
7330- $thesigs = $dmap[$methName]['signature'];
7331- for ($i = 0; $i < sizeof($thesigs); $i++) {
7332- $cursig = array();
7333- $inSig = $thesigs[$i];
7334- for ($j = 0; $j < sizeof($inSig); $j++) {
7335- $cursig[] = new XML_RPC_Value($inSig[$j], 'string');
7336- }
7337- $sigs[] = new XML_RPC_Value($cursig, 'array');
7338- }
7339- $r = new XML_RPC_Response(new XML_RPC_Value($sigs, 'array'));
7340- } else {
7341- $r = new XML_RPC_Response(new XML_RPC_Value('undef', 'string'));
7342- }
7343- } else {
7344- $r = new XML_RPC_Response(0, $XML_RPC_err['introspect_unknown'],
7345- $XML_RPC_str['introspect_unknown']);
7346- }
7347- return $r;
7348-}
7349-
7350-/**
7351- * Returns help text if defined for the method passed, otherwise returns
7352- * an empty string
7353- *
7354- * @return object a new XML_RPC_Response object
7355- */
7356-function XML_RPC_Server_methodHelp($server, $m)
7357-{
7358- global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
7359-
7360- $methName = $m->getParam(0);
7361- $methName = $methName->scalarval();
7362- if (strpos($methName, 'system.') === 0) {
7363- $dmap = $XML_RPC_Server_dmap;
7364- $sysCall = 1;
7365- } else {
7366- $dmap = $server->dmap;
7367- $sysCall = 0;
7368- }
7369- // print "<!-- ${methName} -->\n";
7370- if (isset($dmap[$methName])) {
7371- if ($dmap[$methName]['docstring']) {
7372- $r = new XML_RPC_Response(new XML_RPC_Value($dmap[$methName]['docstring']),
7373- 'string');
7374- } else {
7375- $r = new XML_RPC_Response(new XML_RPC_Value('', 'string'));
7376- }
7377- } else {
7378- $r = new XML_RPC_Response(0, $XML_RPC_err['introspect_unknown'],
7379- $XML_RPC_str['introspect_unknown']);
7380- }
7381- return $r;
7382-}
7383-
7384-/**
7385- * @return void
7386- */
7387-function XML_RPC_Server_debugmsg($m)
7388-{
7389- global $XML_RPC_Server_debuginfo;
7390- $XML_RPC_Server_debuginfo = $XML_RPC_Server_debuginfo . $m . "\n";
7391-}
7392-
7393-
7394-/**
7395- * A server for receiving and replying to XML RPC requests
7396- *
7397- * <code>
7398- * $server = new XML_RPC_Server(
7399- * array(
7400- * 'isan8' =>
7401- * array(
7402- * 'function' => 'is_8',
7403- * 'signature' =>
7404- * array(
7405- * array('boolean', 'int'),
7406- * array('boolean', 'int', 'boolean'),
7407- * array('boolean', 'string'),
7408- * array('boolean', 'string', 'boolean'),
7409- * ),
7410- * 'docstring' => 'Is the value an 8?'
7411- * ),
7412- * ),
7413- * 1,
7414- * 0
7415- * );
7416- * </code>
7417- *
7418- * @category Web Services
7419- * @package XML_RPC
7420- * @author Edd Dumbill <edd@usefulinc.com>
7421- * @author Stig Bakken <stig@php.net>
7422- * @author Martin Jansen <mj@php.net>
7423- * @author Daniel Convissor <danielc@php.net>
7424- * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
7425- * @version Release: 1.3.1
7426- * @link http://pear.php.net/package/XML_RPC
7427- */
7428-class XML_RPC_Server
7429-{
7430- /**
7431- * The dispatch map, listing the methods this server provides.
7432- * @var array
7433- */
7434- var $dmap = array();
7435-
7436- /**
7437- * The present response's encoding
7438- * @var string
7439- * @see XML_RPC_Message::getEncoding()
7440- */
7441- var $encoding = '';
7442-
7443- /**
7444- * Debug mode (0 = off, 1 = on)
7445- * @var integer
7446- */
7447- var $debug = 0;
7448-
7449- /**
7450- * The response's HTTP headers
7451- * @var string
7452- */
7453- var $server_headers = '';
7454-
7455- /**
7456- * The response's XML payload
7457- * @var string
7458- */
7459- var $server_payload = '';
7460-
7461-
7462- /**
7463- * Constructor for the XML_RPC_Server class
7464- *
7465- * @param array $dispMap the dispatch map. An associative array
7466- * explaining each function. The keys of the main
7467- * array are the procedure names used by the
7468- * clients. The value is another associative array
7469- * that contains up to three elements:
7470- * + The 'function' element's value is the name
7471- * of the function or method that gets called.
7472- * To define a class' method: 'class::method'.
7473- * + The 'signature' element (optional) is an
7474- * array describing the return values and
7475- * parameters
7476- * + The 'docstring' element (optional) is a
7477- * string describing what the method does
7478- * @param int $serviceNow should the HTTP response be sent now?
7479- * (1 = yes, 0 = no)
7480- * @param int $debug should debug output be displayed?
7481- * (1 = yes, 0 = no)
7482- *
7483- * @return void
7484- */
7485- function XML_RPC_Server($dispMap, $serviceNow = 1, $debug = 0)
7486- {
7487- global $HTTP_RAW_POST_DATA;
7488-
7489- if ($debug) {
7490- $this->debug = 1;
7491- } else {
7492- $this->debug = 0;
7493- }
7494-
7495- $this->dmap = $dispMap;
7496-
7497- if ($serviceNow) {
7498- $this->service();
7499- } else {
7500- $this->createServerPayload();
7501- $this->createServerHeaders();
7502- }
7503- }
7504-
7505- /**
7506- * @return string the debug information if debug debug mode is on
7507- */
7508- function serializeDebug()
7509- {
7510- global $XML_RPC_Server_debuginfo, $HTTP_RAW_POST_DATA;
7511-
7512- if ($this->debug) {
7513- XML_RPC_Server_debugmsg('vvv POST DATA RECEIVED BY SERVER vvv' . "\n"
7514- . $HTTP_RAW_POST_DATA
7515- . "\n" . '^^^ END POST DATA ^^^');
7516- }
7517-
7518- if ($XML_RPC_Server_debuginfo != '') {
7519- return "<!-- PEAR XML_RPC SERVER DEBUG INFO:\n\n"
7520- . preg_replace('/-(?=-)/', '- ', $XML_RPC_Server_debuginfo)
7521- . "-->\n";
7522- } else {
7523- return '';
7524- }
7525- }
7526-
7527- /**
7528- * Sends the response
7529- *
7530- * The encoding and content-type are determined by
7531- * XML_RPC_Message::getEncoding()
7532- *
7533- * @return void
7534- *
7535- * @uses XML_RPC_Server::createServerPayload(),
7536- * XML_RPC_Server::createServerHeaders()
7537- */
7538- function service()
7539- {
7540- $this->createServerPayload();
7541- $this->createServerHeaders();
7542- header($this->server_headers);
7543- print $this->server_payload;
7544- }
7545-
7546- /**
7547- * Generates the payload and puts it in the $server_payload property
7548- *
7549- * @return void
7550- *
7551- * @uses XML_RPC_Server::parseRequest(), XML_RPC_Server::$encoding,
7552- * XML_RPC_Response::serialize(), XML_RPC_Server::serializeDebug()
7553- */
7554- function createServerPayload()
7555- {
7556- $r = $this->parseRequest();
7557- $this->server_payload = '<?xml version="1.0" encoding="'
7558- . $this->encoding . '"?>' . "\n"
7559- . $this->serializeDebug()
7560- . $r->serialize();
7561- }
7562-
7563- /**
7564- * Determines the HTTP headers and puts them in the $server_headers
7565- * property
7566- *
7567- * @return boolean TRUE if okay, FALSE if $server_payload isn't set.
7568- *
7569- * @uses XML_RPC_Server::createServerPayload(),
7570- * XML_RPC_Server::$server_headers
7571- */
7572- function createServerHeaders()
7573- {
7574- if (!$this->server_payload) {
7575- return false;
7576- }
7577- $this->server_headers = 'Content-Length: '
7578- . strlen($this->server_payload) . "\r\n"
7579- . 'Content-Type: text/xml;'
7580- . ' charset=' . $this->encoding;
7581- return true;
7582- }
7583-
7584- /**
7585- * @return array
7586- */
7587- function verifySignature($in, $sig)
7588- {
7589- for ($i = 0; $i < sizeof($sig); $i++) {
7590- // check each possible signature in turn
7591- $cursig = $sig[$i];
7592- if (sizeof($cursig) == $in->getNumParams() + 1) {
7593- $itsOK = 1;
7594- for ($n = 0; $n < $in->getNumParams(); $n++) {
7595- $p = $in->getParam($n);
7596- // print "<!-- $p -->\n";
7597- if ($p->kindOf() == 'scalar') {
7598- $pt = $p->scalartyp();
7599- } else {
7600- $pt = $p->kindOf();
7601- }
7602- // $n+1 as first type of sig is return type
7603- if ($pt != $cursig[$n+1]) {
7604- $itsOK = 0;
7605- $pno = $n+1;
7606- $wanted = $cursig[$n+1];
7607- $got = $pt;
7608- break;
7609- }
7610- }
7611- if ($itsOK) {
7612- return array(1);
7613- }
7614- }
7615- }
7616- if (isset($wanted)) {
7617- return array(0, "Wanted ${wanted}, got ${got} at param ${pno}");
7618- } else {
7619- $allowed = array();
7620- foreach ($sig as $val) {
7621- end($val);
7622- $allowed[] = key($val);
7623- }
7624- $allowed = array_unique($allowed);
7625- $last = count($allowed) - 1;
7626- if ($last > 0) {
7627- $allowed[$last] = 'or ' . $allowed[$last];
7628- }
7629- return array(0,
7630- 'Signature permits ' . implode(', ', $allowed)
7631- . ' parameters but the request had '
7632- . $in->getNumParams());
7633- }
7634- }
7635-
7636- /**
7637- * @return object a new XML_RPC_Response object
7638- *
7639- * @uses XML_RPC_Message::getEncoding(), XML_RPC_Server::$encoding
7640- */
7641- function parseRequest($data = '')
7642- {
7643- global $XML_RPC_xh, $HTTP_RAW_POST_DATA,
7644- $XML_RPC_err, $XML_RPC_str, $XML_RPC_errxml,
7645- $XML_RPC_defencoding, $XML_RPC_Server_dmap;
7646-
7647- if ($data == '') {
7648- $data = $HTTP_RAW_POST_DATA;
7649- }
7650-
7651- $this->encoding = XML_RPC_Message::getEncoding($data);
7652- $parser_resource = xml_parser_create($this->encoding);
7653- $parser = (int) $parser_resource;
7654-
7655- $XML_RPC_xh[$parser] = array();
7656- $XML_RPC_xh[$parser]['st'] = '';
7657- $XML_RPC_xh[$parser]['cm'] = 0;
7658- $XML_RPC_xh[$parser]['isf'] = 0;
7659- $XML_RPC_xh[$parser]['params'] = array();
7660- $XML_RPC_xh[$parser]['method'] = '';
7661-
7662- $plist = '';
7663-
7664- // decompose incoming XML into request structure
7665-
7666- xml_parser_set_option($parser_resource, XML_OPTION_CASE_FOLDING, true);
7667- xml_set_element_handler($parser_resource, 'XML_RPC_se', 'XML_RPC_ee');
7668- xml_set_character_data_handler($parser_resource, 'XML_RPC_cd');
7669- if (!xml_parse($parser_resource, $data, 1)) {
7670- // return XML error as a faultCode
7671- $r = new XML_RPC_Response(0,
7672- $XML_RPC_errxml+xml_get_error_code($parser_resource),
7673- sprintf('XML error: %s at line %d',
7674- xml_error_string(xml_get_error_code($parser_resource)),
7675- xml_get_current_line_number($parser_resource)));
7676- xml_parser_free($parser_resource);
7677- } else {
7678- xml_parser_free($parser_resource);
7679- $m = new XML_RPC_Message($XML_RPC_xh[$parser]['method']);
7680- // now add parameters in
7681- for ($i = 0; $i < sizeof($XML_RPC_xh[$parser]['params']); $i++) {
7682- // print '<!-- ' . $XML_RPC_xh[$parser]['params'][$i]. "-->\n";
7683- $plist .= "$i - " . $XML_RPC_xh[$parser]['params'][$i] . " \n";
7684- eval('$m->addParam(' . $XML_RPC_xh[$parser]['params'][$i] . ');');
7685- }
7686- XML_RPC_Server_debugmsg($plist);
7687-
7688- // now to deal with the method
7689- $methName = $XML_RPC_xh[$parser]['method'];
7690- if (strpos($methName, 'system.') === 0) {
7691- $dmap = $XML_RPC_Server_dmap;
7692- $sysCall = 1;
7693- } else {
7694- $dmap = $this->dmap;
7695- $sysCall = 0;
7696- }
7697-
7698- if (isset($dmap[$methName]['function'])
7699- && is_string($dmap[$methName]['function'])
7700- && strpos($dmap[$methName]['function'], '::') !== false)
7701- {
7702- $dmap[$methName]['function'] =
7703- explode('::', $dmap[$methName]['function']);
7704- }
7705-
7706- if (isset($dmap[$methName]['function'])
7707- && is_callable($dmap[$methName]['function']))
7708- {
7709- // dispatch if exists
7710- if (isset($dmap[$methName]['signature'])) {
7711- $sr = $this->verifySignature($m,
7712- $dmap[$methName]['signature'] );
7713- }
7714- if (!isset($dmap[$methName]['signature']) || $sr[0]) {
7715- // if no signature or correct signature
7716- if ($sysCall) {
7717- $r = call_user_func($dmap[$methName]['function'], $this, $m);
7718- } else {
7719- $r = call_user_func($dmap[$methName]['function'], $m);
7720- }
7721- if (!is_a($r, 'XML_RPC_Response')) {
7722- $r = new XML_RPC_Response(0, $XML_RPC_err['not_response_object'],
7723- $XML_RPC_str['not_response_object']);
7724- }
7725- } else {
7726- $r = new XML_RPC_Response(0, $XML_RPC_err['incorrect_params'],
7727- $XML_RPC_str['incorrect_params']
7728- . ': ' . $sr[1]);
7729- }
7730- } else {
7731- // else prepare error response
7732- $r = new XML_RPC_Response(0, $XML_RPC_err['unknown_method'],
7733- $XML_RPC_str['unknown_method']);
7734- }
7735- }
7736- return $r;
7737- }
7738-
7739- /**
7740- * Echos back the input packet as a string value
7741- *
7742- * @return void
7743- *
7744- * Useful for debugging.
7745- */
7746- function echoInput()
7747- {
7748- global $HTTP_RAW_POST_DATA;
7749-
7750- $r = new XML_RPC_Response(0);
7751- $r->xv = new XML_RPC_Value("'Aha said I: '" . $HTTP_RAW_POST_DATA, 'string');
7752- print $r->serialize();
7753- }
7754-}
7755-
7756-/*
7757- * Local variables:
7758- * tab-width: 4
7759- * c-basic-offset: 4
7760- * c-hanging-comment-ender-p: nil
7761- * End:
7762- */
7763-
7764-?>
7765-
7766-<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/package-1.0">
7767-<package version="1.0" packagerversion="1.4.0a12">
7768- <name>XML_RPC</name>
7769- <summary>PHP implementation of the XML-RPC protocol</summary>
7770- <description>A PEAR-ified version of Useful Inc's XML-RPC for PHP.
7771-
7772-It has support for HTTP/HTTPS transport, proxies and authentication.
7773- </description>
7774- <maintainers>
7775- <maintainer>
7776- <user>ssb</user>
7777- <name>Stig Bakken</name>
7778- <email>stig@php.net</email>
7779- <role>lead</role>
7780- </maintainer>
7781- <maintainer>
7782- <user>danielc</user>
7783- <name>Daniel Convissor</name>
7784- <email>danielc@php.net</email>
7785- <role>lead</role>
7786- </maintainer>
7787- </maintainers>
7788- <release>
7789- <version>1.3.1</version>
7790- <date>2005-06-29</date>
7791- <license>PHP License</license>
7792- <state>stable</state>
7793- <notes>* Security fix. Update highly recommended!
7794- </notes>
7795- <filelist>
7796- <file role="php" baseinstalldir="XML" name="RPC.php">
7797- <replace from="@package_version@" to="version" type="package-info"/>
7798- </file>
7799- <file role="php" baseinstalldir="XML/RPC" name="Server.php">
7800- <replace from="@package_version@" to="version" type="package-info"/>
7801- </file>
7802- <file role="php" baseinstalldir="XML/RPC" name="Dump.php">
7803- <replace from="@package_version@" to="version" type="package-info"/>
7804- </file>
7805- <file role="test" name="tests/protoport.php">
7806- <replace from="@package_version@" to="version" type="package-info"/>
7807- </file>
7808- <file role="test" name="tests/test_Dump.php">
7809- <replace from="@package_version@" to="version" type="package-info"/>
7810- </file>
7811- </filelist>
7812- </release>
7813- <changelog>
7814- <release>
7815- <version>1.3.0RC3</version>
7816- <date>2005-05-10</date>
7817- <state>beta</state>
7818- <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.
7819-* XML_RPC_Message::getParam() now returns an XML_RPC_Response object upon error. Changed from Release 1.3.0RC2.
7820-* Add the XML_RPC_Value::isValue() method. For testing if an item is an XML_RPC_Value object.
7821-* 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.
7822-* Improve cross-platform operation by using PEAR::loadExtension() instead of dl().
7823-* Use &lt;br /&gt; instead of &lt;br&gt; in XML_RPC_Value::dump().
7824- </notes>
7825- </release>
7826- <release>
7827- <version>1.3.0RC2</version>
7828- <date>2005-05-05</date>
7829- <state>beta</state>
7830- <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.
7831-* Handle improper requests to XML_RPC_Server::verifySignature(). Bug 4231.
7832-* Try to allow HTTP 100 responses if followed by a 200 response. Bug 4116.
7833-* Help Delphi users by making RPCMETHODNAME an alias for METHODNAME. Request 4205.
7834- </notes>
7835- </release>
7836- <release>
7837- <version>1.3.0RC1</version>
7838- <date>2005-04-07</date>
7839- <state>beta</state>
7840- <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.
7841-* Add Fault Code 6: &quot;The requested method didn't return an XML_RPC_Response object.&quot; Request 4032.
7842-* Add the createServerPayload() and createServerHeaders() methods and the $server_payload and $server_headers properties. Request 3121.
7843-* 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.
7844-* Convert the parser handle to an integer before using it as an index for $XML_RPC_xh[$parser]. Reduces E_STRICT notices. Bug 3782.
7845-* Add createHeaders() method and $headers property to XML_RPC_Client to make testing easier.
7846- </notes>
7847- </release>
7848- <release>
7849- <version>1.2.2</version>
7850- <date>2005-03-07</date>
7851- <state>stable</state>
7852- <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.
7853- </notes>
7854- </release>
7855- <release>
7856- <version>1.2.1</version>
7857- <date>2005-03-01</date>
7858- <state>stable</state>
7859- <notes>* Add isset() check before examining the dispatch map. Bug 3658.
7860- </notes>
7861- </release>
7862- <release>
7863- <version>1.2.0</version>
7864- <date>2005-02-27</date>
7865- <state>stable</state>
7866- <notes>* Provide the &quot;stable&quot; release.
7867-* Add package2.xml for compatibility with PEAR 1.4.0.
7868-* For changes since 1.1.0, see the changelogs for the various RC releases.
7869- </notes>
7870- </release>
7871- <release>
7872- <version>1.2.0RC7</version>
7873- <date>2005-02-22</date>
7874- <state>beta</state>
7875- <notes>* Add the setSendEncoding() method and $send_encoding
7876- property to XML_RPC_Message. Request 3537.
7877-* Allow class methods to be mapped using either syntax:
7878- 'function' =&gt; 'hello::sayHello',
7879- or
7880- 'function' =&gt; array('hello', 'sayhello'),
7881- Bug 3363.
7882-* Use 8192 instead of 32768 for bytes in fread()
7883- in parseResponseFile(). Bug 3340.
7884- </notes>
7885- </release>
7886- <release>
7887- <version>1.2.0RC6</version>
7888- <date>2005-01-25</date>
7889- <state>beta</state>
7890- <notes>* Don't put the protocol in the Host field of the POST data. (danielc)
7891- </notes>
7892- </release>
7893- <release>
7894- <version>1.2.0RC5</version>
7895- <date>2005-01-24</date>
7896- <state>beta</state>
7897- <notes>* If $port is 443 but a protocol isn't specified in $server, assume ssl:// is the protocol.
7898- </notes>
7899- </release>
7900- <release>
7901- <version>1.2.0RC4</version>
7902- <date>2005-01-24</date>
7903- <state>beta</state>
7904- <notes>* When a connection attempt fails, have the method return 0. (danielc)
7905-* Move the protocol/port checking/switching and the property settings from sendPayloadHTTP10() to the XML_RPC_Client constructor. (danielc)
7906-* Add tests for setting the client properties. (danielc)
7907-* Remove $GLOBALS['XML_RPC_twoslash'] since it's not used. (danielc)
7908-* Bundle the tests with the package. (danielc)
7909- </notes>
7910- </release>
7911- <release>
7912- <version>1.2.0RC3</version>
7913- <date>2005-01-19</date>
7914- <state>beta</state>
7915- <notes>* ssl uses port 443, not 445.
7916- </notes>
7917- </release>
7918- <release>
7919- <version>1.2.0RC2</version>
7920- <date>2005-01-11</date>
7921- <state>beta</state>
7922- <notes>* Handle ssl:// in the $server string. (danielc)
7923-* Also default to port 445 for ssl:// requests as well. (danielc)
7924-* Enhance debugging in the server. (danielc)
7925- </notes>
7926- </release>
7927- <release>
7928- <version>1.2.0RC1</version>
7929- <date>2004-12-30</date>
7930- <state>beta</state>
7931- <notes>* Make things work with SSL. Bug 2489. (nkukard lbsd net)
7932-* Allow array function callbacks (Matt Kane)
7933-* Some minor speed-ups (Matt Kane)
7934-* Add Dump.php to the package (Christian Weiske)
7935-* Replace all line endings with \r\n. Had only done replacements on \n. Bug 2521. (danielc)
7936-* Silence fsockopen() errors. Bug 1714. (danielc)
7937-* Encode empty arrays as an array. Bug 1493. (danielc)
7938-* Eliminate undefined index notice when submitting empty arrays to XML_RPC_Encode(). Bug 1819. (danielc)
7939-* Speed up check for enumerated arrays in XML_RPC_Encode(). (danielc)
7940-* Prepend &quot;XML_RPC_&quot; to ERROR_NON_NUMERIC_FOUND, eliminating problem when eval()'ing error messages. (danielc)
7941-* Use XML_RPC_Base::raiseError() instead of PEAR::raiseError() in XML_RPC_ee() because PEAR.php is lazy loaded. (danielc)
7942-* Allow raiseError() to be called statically. (danielc)
7943-* Stop double escaping of character entities. Bug 987. (danielc)
7944- NOTICE: the following have been removed:
7945- * XML_RPC_dh()
7946- * $GLOBALS['XML_RPC_entities']
7947- * XML_RPC_entity_decode()
7948- * XML_RPC_lookup_entity()
7949-* Determine the XML's encoding via the encoding attribute in the XML declaration. Bug 52. (danielc)
7950- </notes>
7951- </release>
7952- <release>
7953- <version>1.1.0</version>
7954- <date>2004-03-15</date>
7955- <state>stable</state>
7956- <notes>* Added support for sequential arrays to XML_RPC_encode() (mroch)
7957-* Cleaned up new XML_RPC_encode() changes a bit (mroch, pierre)
7958-* Remove &quot;require_once 'PEAR.php'&quot;, include only when needed to raise an error
7959-* Replace echo and error_log() with raiseError() (mroch)
7960-* Make all classes extend XML_RPC_Base, which will handle common functions (mroch)
7961-* be tolerant of junk after methodResponse (Luca Mariano, mroch)
7962-* Silent notice even in the error log (pierre)
7963-* fix include of shared xml extension on win32 (pierre)
7964- </notes>
7965- </release>
7966- <release>
7967- <version>1.0.4</version>
7968- <date>2002-10-02</date>
7969- <state>stable</state>
7970- <notes>* added HTTP proxy authorization support (thanks to Arnaud Limbourg)
7971- </notes>
7972- </release>
7973- <release>
7974- <version>1.0.3</version>
7975- <date>2002-05-19</date>
7976- <state>stable</state>
7977- <notes>* fix bug when parsing responses with boolean types
7978- </notes>
7979- </release>
7980- <release>
7981- <version>1.0.2</version>
7982- <date>2002-04-16</date>
7983- <state>stable</state>
7984- <notes>* E_ALL fixes
7985-* fix HTTP response header parsing
7986- </notes>
7987- </release>
7988- <release>
7989- <version>1.0.1</version>
7990- <date>2001-09-25</date>
7991- <state>stable</state>
7992- <notes>This is a PEAR-ified version of Useful Inc's 1.0.1 release.
7993-Includes an urgent security fix identified by Dan Libby &lt;dan@libby.com&gt;.
7994- </notes>
7995- </release>
7996- </changelog>
7997-</package>
7998-
7999\ Kein Zeilenumbruch am Dateiende.
8000diff -Nura php-4.4.0/pear/packages/XML_RPC-1.4.0.tar hardening-patch-4.4.0-0.4.2/pear/packages/XML_RPC-1.4.0.tar
8001--- php-4.4.0/pear/packages/XML_RPC-1.4.0.tar 1970-01-01 01:00:00.000000000 +0100
8002+++ hardening-patch-4.4.0-0.4.2/pear/packages/XML_RPC-1.4.0.tar 2005-08-22 23:59:57.000000000 +0200
8003@@ -0,0 +1,3933 @@
8004+package2.xml
8005+<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">
8006+ <name>XML_RPC</name>
8007+ <channel>pear.php.net</channel>
8008+ <summary>PHP implementation of the XML-RPC protocol</summary>
8009+ <description>A PEAR-ified version of Useful Inc&apos;s XML-RPC for PHP.
8010+
8011+It has support for HTTP/HTTPS transport, proxies and authentication.</description>
8012+ <lead>
8013+ <name>Stig Bakken</name>
8014+ <user>ssb</user>
8015+ <email>stig@php.net</email>
8016+ <active>no</active>
8017+ </lead>
8018+ <lead>
8019+ <name>Daniel Convissor</name>
8020+ <user>danielc</user>
8021+ <email>danielc@php.net</email>
8022+ <active>yes</active>
8023+ </lead>
8024+ <date>2005-08-14</date>
8025+ <time>16:30:30</time>
8026+ <version>
8027+ <release>1.4.0</release>
8028+ <api>1.4.0</api>
8029+ </version>
8030+ <stability>
8031+ <release>stable</release>
8032+ <api>stable</api>
8033+ </stability>
8034+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8035+ <notes>* MAJOR SECURITY FIX: eliminate use of eval().
8036+* 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>
8037+ <contents>
8038+ <dir name="/">
8039+ <file md5sum="952733184950487ec0cee78cf05bedc4" name="tests/protoport.php" role="test">
8040+ <tasks:replace from="@package_version@" to="version" type="package-info" />
8041+ </file>
8042+ <file md5sum="239a5b407054852b6f470f043a44d8be" name="tests/test_Dump.php" role="test">
8043+ <tasks:replace from="@package_version@" to="version" type="package-info" />
8044+ </file>
8045+ <file baseinstalldir="XML/RPC" md5sum="80df8443b5e6c2919de012df1f1d7997" name="Dump.php" role="php">
8046+ <tasks:replace from="@package_version@" to="version" type="package-info" />
8047+ </file>
8048+ <file baseinstalldir="XML" md5sum="5c26e8fae482ba8c123c71c2c8c3fabc" name="RPC.php" role="php">
8049+ <tasks:replace from="@package_version@" to="version" type="package-info" />
8050+ </file>
8051+ <file baseinstalldir="XML/RPC" md5sum="8bded286786fb010879abdf88493ecca" name="Server.php" role="php">
8052+ <tasks:replace from="@package_version@" to="version" type="package-info" />
8053+ </file>
8054+ </dir>
8055+ </contents>
8056+ <compatible>
8057+ <name>PEAR</name>
8058+ <channel>pear.php.net</channel>
8059+ <min>1.4.0a1</min>
8060+ <max>1.4.0a12</max>
8061+ </compatible>
8062+ <dependencies>
8063+ <required>
8064+ <php>
8065+ <min>4.2.0</min>
8066+ <max>6.0.0</max>
8067+ </php>
8068+ <pearinstaller>
8069+ <min>1.4.0a1</min>
8070+ </pearinstaller>
8071+ </required>
8072+ </dependencies>
8073+ <phprelease />
8074+ <changelog>
8075+ <release>
8076+ <version>
8077+ <release>1.3.3</release>
8078+ <api>1.3.0</api>
8079+ </version>
8080+ <stability>
8081+ <release>stable</release>
8082+ <api>stable</api>
8083+ </stability>
8084+ <date>2005-07-15</date>
8085+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8086+ <notes>* Eliminate memory leak by resetting $XML_RPC_xh each time parseResponse() is called. Bug 4780.
8087+* 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>
8088+ </release>
8089+ <release>
8090+ <version>
8091+ <release>1.3.2</release>
8092+ <api>1.3.0</api>
8093+ </version>
8094+ <stability>
8095+ <release>stable</release>
8096+ <api>stable</api>
8097+ </stability>
8098+ <date>2005-07-07</date>
8099+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8100+ <notes>* Eliminate path disclosure vulnerabilities by suppressing error messages when eval()&apos;ing.
8101+* Eliminate path disclosure vulnerability by catching bogus parameters submitted to XML_RPC_Value::serializeval().
8102+* 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.
8103+* 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>
8104+ </release>
8105+ <release>
8106+ <version>
8107+ <release>1.3.1</release>
8108+ <api>1.3.0</api>
8109+ </version>
8110+ <stability>
8111+ <release>stable</release>
8112+ <api>stable</api>
8113+ </stability>
8114+ <date>2005-06-29</date>
8115+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8116+ <notes>* Security fix. Update highly recommended!</notes>
8117+ </release>
8118+ <release>
8119+ <version>
8120+ <release>1.3.0</release>
8121+ <api>1.3.0</api>
8122+ </version>
8123+ <stability>
8124+ <release>stable</release>
8125+ <api>stable</api>
8126+ </stability>
8127+ <date>2005-06-13</date>
8128+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8129+ <notes>* Stable release. See earlier releases for changes since 1.2.2.</notes>
8130+ </release>
8131+ <release>
8132+ <version>
8133+ <release>1.3.0RC3</release>
8134+ <api>1.3.0</api>
8135+ </version>
8136+ <stability>
8137+ <release>beta</release>
8138+ <api>stable</api>
8139+ </stability>
8140+ <date>2005-05-10</date>
8141+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8142+ <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.
8143+* XML_RPC_Message::getParam() now returns an XML_RPC_Response object upon error. Changed from Release 1.3.0RC2.
8144+* Add the XML_RPC_Value::isValue() method. For testing if an item is an XML_RPC_Value object.
8145+* 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.
8146+* Improve cross-platform operation by using PEAR::loadExtension() instead of dl().
8147+* Use &lt;br /&gt; instead of &lt;br&gt; in XML_RPC_Value::dump().</notes>
8148+ </release>
8149+ <release>
8150+ <version>
8151+ <release>1.3.0RC2</release>
8152+ <api>1.3.0</api>
8153+ </version>
8154+ <stability>
8155+ <release>beta</release>
8156+ <api>beta</api>
8157+ </stability>
8158+ <date>2005-05-05</date>
8159+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8160+ <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.
8161+* Handle improper requests to XML_RPC_Server::verifySignature(). Bug 4231.
8162+* Try to allow HTTP 100 responses if followed by a 200 response. Bug 4116.
8163+* Help Delphi users by making RPCMETHODNAME an alias for METHODNAME. Request 4205.</notes>
8164+ </release>
8165+ <release>
8166+ <version>
8167+ <release>1.3.0RC1</release>
8168+ <api>1.3.0</api>
8169+ </version>
8170+ <stability>
8171+ <release>beta</release>
8172+ <api>beta</api>
8173+ </stability>
8174+ <date>2005-04-07</date>
8175+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8176+ <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.
8177+* Add Fault Code 6: &quot;The requested method didn&apos;t return an XML_RPC_Response object.&quot; Request 4032.
8178+* Add the createServerPayload() and createServerHeaders() methods and the $server_payload and $server_headers properties. Request 3121.
8179+* 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.
8180+* Convert the parser handle to an integer before using it as an index for $XML_RPC_xh[$parser]. Reduces E_STRICT notices. Bug 3782.
8181+* Add createHeaders() method and $headers property to XML_RPC_Client to make testing easier.</notes>
8182+ </release>
8183+ <release>
8184+ <version>
8185+ <release>1.2.2</release>
8186+ <api>1.2.0</api>
8187+ </version>
8188+ <stability>
8189+ <release>stable</release>
8190+ <api>stable</api>
8191+ </stability>
8192+ <date>2005-03-07</date>
8193+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8194+ <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>
8195+ </release>
8196+ <release>
8197+ <version>
8198+ <release>1.2.1</release>
8199+ <api>1.2.0</api>
8200+ </version>
8201+ <stability>
8202+ <release>stable</release>
8203+ <api>stable</api>
8204+ </stability>
8205+ <date>2005-03-01</date>
8206+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8207+ <notes>* Add isset() check before examining the dispatch map. Bug 3658.</notes>
8208+ </release>
8209+ <release>
8210+ <version>
8211+ <release>1.2.0</release>
8212+ <api>1.2.0</api>
8213+ </version>
8214+ <stability>
8215+ <release>stable</release>
8216+ <api>stable</api>
8217+ </stability>
8218+ <date>2005-02-27</date>
8219+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8220+ <notes>* Provide the &quot;stable&quot; release.
8221+* Add package2.xml for compatibility with PEAR 1.4.0.
8222+* For changes since 1.1.0, see the changelogs for the various RC releases.</notes>
8223+ </release>
8224+ <release>
8225+ <version>
8226+ <release>1.2.0RC7</release>
8227+ <api>1.2.0RC7</api>
8228+ </version>
8229+ <stability>
8230+ <release>beta</release>
8231+ <api>beta</api>
8232+ </stability>
8233+ <date>2005-02-22</date>
8234+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8235+ <notes>* Add the setSendEncoding() method and $send_encoding
8236+ property to XML_RPC_Message. Request 3537.
8237+* Allow class methods to be mapped using either syntax:
8238+ &apos;function&apos; =&gt; &apos;hello::sayHello&apos;,
8239+ or
8240+ &apos;function&apos; =&gt; array(&apos;hello&apos;, &apos;sayhello&apos;),
8241+ Bug 3363.
8242+* Use 8192 instead of 32768 for bytes in fread()
8243+ in parseResponseFile(). Bug 3340.</notes>
8244+ </release>
8245+ <release>
8246+ <version>
8247+ <release>1.2.0RC6</release>
8248+ <api>1.2.0RC6</api>
8249+ </version>
8250+ <stability>
8251+ <release>beta</release>
8252+ <api>beta</api>
8253+ </stability>
8254+ <date>2005-01-25</date>
8255+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8256+ <notes>* Don&apos;t put the protocol in the Host field of the POST data. (danielc)</notes>
8257+ </release>
8258+ <release>
8259+ <version>
8260+ <release>1.2.0RC5</release>
8261+ <api>1.2.0RC5</api>
8262+ </version>
8263+ <stability>
8264+ <release>beta</release>
8265+ <api>beta</api>
8266+ </stability>
8267+ <date>2005-01-24</date>
8268+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8269+ <notes>* If $port is 443 but a protocol isn&apos;t specified in $server, assume ssl:// is the protocol.</notes>
8270+ </release>
8271+ <release>
8272+ <version>
8273+ <release>1.2.0RC4</release>
8274+ <api>1.2.0RC4</api>
8275+ </version>
8276+ <stability>
8277+ <release>beta</release>
8278+ <api>beta</api>
8279+ </stability>
8280+ <date>2005-01-24</date>
8281+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8282+ <notes>* When a connection attempt fails, have the method return 0. (danielc)
8283+* Move the protocol/port checking/switching and the property settings from sendPayloadHTTP10() to the XML_RPC_Client constructor. (danielc)
8284+* Add tests for setting the client properties. (danielc)
8285+* Remove $GLOBALS[&apos;XML_RPC_twoslash&apos;] since it&apos;s not used. (danielc)
8286+* Bundle the tests with the package. (danielc)</notes>
8287+ </release>
8288+ <release>
8289+ <version>
8290+ <release>1.2.0RC3</release>
8291+ <api>1.2.0RC3</api>
8292+ </version>
8293+ <stability>
8294+ <release>beta</release>
8295+ <api>beta</api>
8296+ </stability>
8297+ <date>2005-01-19</date>
8298+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8299+ <notes>* ssl uses port 443, not 445.</notes>
8300+ </release>
8301+ <release>
8302+ <version>
8303+ <release>1.2.0RC2</release>
8304+ <api>1.2.0RC2</api>
8305+ </version>
8306+ <stability>
8307+ <release>beta</release>
8308+ <api>beta</api>
8309+ </stability>
8310+ <date>2005-01-11</date>
8311+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8312+ <notes>* Handle ssl:// in the $server string. (danielc)
8313+* Also default to port 445 for ssl:// requests as well. (danielc)
8314+* Enhance debugging in the server. (danielc)</notes>
8315+ </release>
8316+ <release>
8317+ <version>
8318+ <release>1.2.0RC1</release>
8319+ <api>1.2.0RC1</api>
8320+ </version>
8321+ <stability>
8322+ <release>beta</release>
8323+ <api>beta</api>
8324+ </stability>
8325+ <date>2004-12-30</date>
8326+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8327+ <notes>* Make things work with SSL. Bug 2489. (nkukard lbsd net)
8328+* Allow array function callbacks (Matt Kane)
8329+* Some minor speed-ups (Matt Kane)
8330+* Add Dump.php to the package (Christian Weiske)
8331+* Replace all line endings with \r\n. Had only done replacements on \n. Bug 2521. (danielc)
8332+* Silence fsockopen() errors. Bug 1714. (danielc)
8333+* Encode empty arrays as an array. Bug 1493. (danielc)
8334+* Eliminate undefined index notice when submitting empty arrays to XML_RPC_Encode(). Bug 1819. (danielc)
8335+* Speed up check for enumerated arrays in XML_RPC_Encode(). (danielc)
8336+* Prepend &quot;XML_RPC_&quot; to ERROR_NON_NUMERIC_FOUND, eliminating problem when eval()&apos;ing error messages. (danielc)
8337+* Use XML_RPC_Base::raiseError() instead of PEAR::raiseError() in XML_RPC_ee() because PEAR.php is lazy loaded. (danielc)
8338+* Allow raiseError() to be called statically. (danielc)
8339+* Stop double escaping of character entities. Bug 987. (danielc)
8340+ NOTICE: the following have been removed:
8341+ * XML_RPC_dh()
8342+ * $GLOBALS[&apos;XML_RPC_entities&apos;]
8343+ * XML_RPC_entity_decode()
8344+ * XML_RPC_lookup_entity()
8345+* Determine the XML&apos;s encoding via the encoding attribute in the XML declaration. Bug 52. (danielc)</notes>
8346+ </release>
8347+ <release>
8348+ <version>
8349+ <release>1.1.0</release>
8350+ <api>1.1.0</api>
8351+ </version>
8352+ <stability>
8353+ <release>stable</release>
8354+ <api>stable</api>
8355+ </stability>
8356+ <date>2004-03-15</date>
8357+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8358+ <notes>* Added support for sequential arrays to XML_RPC_encode() (mroch)
8359+* Cleaned up new XML_RPC_encode() changes a bit (mroch, pierre)
8360+* Remove &quot;require_once &apos;PEAR.php&apos;&quot;, include only when needed to raise an error
8361+* Replace echo and error_log() with raiseError() (mroch)
8362+* Make all classes extend XML_RPC_Base, which will handle common functions (mroch)
8363+* be tolerant of junk after methodResponse (Luca Mariano, mroch)
8364+* Silent notice even in the error log (pierre)
8365+* fix include of shared xml extension on win32 (pierre)</notes>
8366+ </release>
8367+ <release>
8368+ <version>
8369+ <release>1.0.4</release>
8370+ <api>1.0.4</api>
8371+ </version>
8372+ <stability>
8373+ <release>stable</release>
8374+ <api>stable</api>
8375+ </stability>
8376+ <date>2002-10-02</date>
8377+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8378+ <notes>* added HTTP proxy authorization support (thanks to Arnaud Limbourg)</notes>
8379+ </release>
8380+ <release>
8381+ <version>
8382+ <release>1.0.3</release>
8383+ <api>1.0.3</api>
8384+ </version>
8385+ <stability>
8386+ <release>stable</release>
8387+ <api>stable</api>
8388+ </stability>
8389+ <date>2002-05-19</date>
8390+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8391+ <notes>* fix bug when parsing responses with boolean types</notes>
8392+ </release>
8393+ <release>
8394+ <version>
8395+ <release>1.0.2</release>
8396+ <api>1.0.2</api>
8397+ </version>
8398+ <stability>
8399+ <release>stable</release>
8400+ <api>stable</api>
8401+ </stability>
8402+ <date>2002-04-16</date>
8403+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8404+ <notes>* E_ALL fixes
8405+* fix HTTP response header parsing</notes>
8406+ </release>
8407+ <release>
8408+ <version>
8409+ <release>1.0.1</release>
8410+ <api>1.0.1</api>
8411+ </version>
8412+ <stability>
8413+ <release>stable</release>
8414+ <api>stable</api>
8415+ </stability>
8416+ <date>2001-09-25</date>
8417+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
8418+ <notes>This is a PEAR-ified version of Useful Inc&apos;s 1.0.1 release.
8419+Includes an urgent security fix identified by Dan Libby &lt;dan@libby.com&gt;.</notes>
8420+ </release>
8421+ </changelog>
8422+</package>
8423+
8424+
8425+/**
8426+ * Tests that properties of XML_RPC_Client get properly set
8427+ *
8428+ * Any individual tests that fail will have their name, expected result
8429+ * and actual result printed out. So seeing no output when executing
8430+ * this file is a good thing.
8431+ *
8432+ * Can be run via CLI or a web server.
8433+ *
8434+ * PHP versions 4 and 5
8435+ *
8436+ * LICENSE: This source file is subject to version 3.0 of the PHP license
8437+ * that is available through the world-wide-web at the following URI:
8438+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
8439+ * the PHP License and are unable to obtain it through the web, please
8440+ * send a note to license@php.net so we can mail you a copy immediately.
8441+ *
8442+ * @category Web Services
8443+ * @package XML_RPC
8444+ * @author Daniel Convissor <danielc@php.net>
8445+ * @copyright 2005 The PHP Group
8446+ * @license http://www.php.net/license/3_0.txt PHP License
8447+ * @version CVS: $Id: protoport.php,v 1.4 2005/01/24 17:48:47 danielc Exp $
8448+ * @link http://pear.php.net/package/XML_RPC
8449+ * @since File available since Release 1.2
8450+ */
8451+
8452+/*
8453+ * If the package version number is found in the left hand
8454+ * portion of the if() expression below, that means this file has
8455+ * come from the PEAR installer. Therefore, let's test the
8456+ * installed version of XML_RPC which should be in the include path.
8457+ *
8458+ * If the version has not been substituted in the if() expression,
8459+ * this file has likely come from a CVS checkout or a .tar file.
8460+ * Therefore, we'll assume the tests should use the version of
8461+ * XML_RPC that has come from there as well.
8462+ */
8463+if ('1.4.0' != '@'.'package_version'.'@') {
8464+ /**
8465+ * Get the needed class from the PEAR installation
8466+ */
8467+ require_once 'XML/RPC.php';
8468+} else {
8469+ /**
8470+ * Get the needed class from the parent directory
8471+ */
8472+ require_once '../RPC.php';
8473+}
8474+
8475+/**
8476+ * Compare the test result to the expected result
8477+ *
8478+ * If the test fails, echo out the results.
8479+ *
8480+ * @param array $expect the array of object properties you expect
8481+ * from the test
8482+ * @param object $actual the object results from the test
8483+ * @param string $test_name the name of the test
8484+ *
8485+ * @return void
8486+ */
8487+function compare($expect, $actual, $test_name) {
8488+ $actual = get_object_vars($actual);
8489+ if (count(array_diff($actual, $expect))) {
8490+ echo "$test_name failed.\nExpect: ";
8491+ print_r($expect);
8492+ echo "Actual: ";
8493+ print_r($actual);
8494+ echo "\n";
8495+ }
8496+}
8497+
8498+if (php_sapi_name() != 'cli') {
8499+ echo "<pre>\n";
8500+}
8501+
8502+
8503+$x = array(
8504+ 'path' => 'thepath',
8505+ 'server' => 'theserver',
8506+ 'protocol' => 'http://',
8507+ 'port' => 80,
8508+ 'proxy' => '',
8509+ 'proxy_protocol' => 'http://',
8510+ 'proxy_port' => 8080,
8511+ 'proxy_user' => '',
8512+ 'proxy_pass' => '',
8513+ 'errno' => 0,
8514+ 'errstring' => '',
8515+ 'debug' => 0,
8516+ 'username' => '',
8517+ 'password' => '',
8518+);
8519+$c = new XML_RPC_Client('thepath', 'theserver');
8520+compare($x, $c, 'defaults');
8521+
8522+$x = array(
8523+ 'path' => 'thepath',
8524+ 'server' => 'theserver',
8525+ 'protocol' => 'http://',
8526+ 'port' => 80,
8527+ 'proxy' => '',
8528+ 'proxy_protocol' => 'http://',
8529+ 'proxy_port' => 8080,
8530+ 'proxy_user' => '',
8531+ 'proxy_pass' => '',
8532+ 'errno' => 0,
8533+ 'errstring' => '',
8534+ 'debug' => 0,
8535+ 'username' => '',
8536+ 'password' => '',
8537+);
8538+$c = new XML_RPC_Client('thepath', 'http://theserver');
8539+compare($x, $c, 'defaults with http');
8540+
8541+$x = array(
8542+ 'path' => 'thepath',
8543+ 'server' => 'theserver',
8544+ 'protocol' => 'ssl://',
8545+ 'port' => 443,
8546+ 'proxy' => '',
8547+ 'proxy_protocol' => 'http://',
8548+ 'proxy_port' => 8080,
8549+ 'proxy_user' => '',
8550+ 'proxy_pass' => '',
8551+ 'errno' => 0,
8552+ 'errstring' => '',
8553+ 'debug' => 0,
8554+ 'username' => '',
8555+ 'password' => '',
8556+);
8557+$c = new XML_RPC_Client('thepath', 'https://theserver');
8558+compare($x, $c, 'defaults with https');
8559+
8560+$x = array(
8561+ 'path' => 'thepath',
8562+ 'server' => 'theserver',
8563+ 'protocol' => 'ssl://',
8564+ 'port' => 443,
8565+ 'proxy' => '',
8566+ 'proxy_protocol' => 'http://',
8567+ 'proxy_port' => 8080,
8568+ 'proxy_user' => '',
8569+ 'proxy_pass' => '',
8570+ 'errno' => 0,
8571+ 'errstring' => '',
8572+ 'debug' => 0,
8573+ 'username' => '',
8574+ 'password' => '',
8575+);
8576+$c = new XML_RPC_Client('thepath', 'ssl://theserver');
8577+compare($x, $c, 'defaults with ssl');
8578+
8579+
8580+$x = array(
8581+ 'path' => 'thepath',
8582+ 'server' => 'theserver',
8583+ 'protocol' => 'http://',
8584+ 'port' => 65,
8585+ 'proxy' => '',
8586+ 'proxy_protocol' => 'http://',
8587+ 'proxy_port' => 8080,
8588+ 'proxy_user' => '',
8589+ 'proxy_pass' => '',
8590+ 'errno' => 0,
8591+ 'errstring' => '',
8592+ 'debug' => 0,
8593+ 'username' => '',
8594+ 'password' => '',
8595+);
8596+$c = new XML_RPC_Client('thepath', 'theserver', 65);
8597+compare($x, $c, 'port 65');
8598+
8599+$x = array(
8600+ 'path' => 'thepath',
8601+ 'server' => 'theserver',
8602+ 'protocol' => 'http://',
8603+ 'port' => 65,
8604+ 'proxy' => '',
8605+ 'proxy_protocol' => 'http://',
8606+ 'proxy_port' => 8080,
8607+ 'proxy_user' => '',
8608+ 'proxy_pass' => '',
8609+ 'errno' => 0,
8610+ 'errstring' => '',
8611+ 'debug' => 0,
8612+ 'username' => '',
8613+ 'password' => '',
8614+);
8615+$c = new XML_RPC_Client('thepath', 'http://theserver', 65);
8616+compare($x, $c, 'port 65 with http');
8617+
8618+$x = array(
8619+ 'path' => 'thepath',
8620+ 'server' => 'theserver',
8621+ 'protocol' => 'ssl://',
8622+ 'port' => 65,
8623+ 'proxy' => '',
8624+ 'proxy_protocol' => 'http://',
8625+ 'proxy_port' => 8080,
8626+ 'proxy_user' => '',
8627+ 'proxy_pass' => '',
8628+ 'errno' => 0,
8629+ 'errstring' => '',
8630+ 'debug' => 0,
8631+ 'username' => '',
8632+ 'password' => '',
8633+);
8634+$c = new XML_RPC_Client('thepath', 'https://theserver', 65);
8635+compare($x, $c, 'port 65 with https');
8636+
8637+$x = array(
8638+ 'path' => 'thepath',
8639+ 'server' => 'theserver',
8640+ 'protocol' => 'ssl://',
8641+ 'port' => 65,
8642+ 'proxy' => '',
8643+ 'proxy_protocol' => 'http://',
8644+ 'proxy_port' => 8080,
8645+ 'proxy_user' => '',
8646+ 'proxy_pass' => '',
8647+ 'errno' => 0,
8648+ 'errstring' => '',
8649+ 'debug' => 0,
8650+ 'username' => '',
8651+ 'password' => '',
8652+);
8653+$c = new XML_RPC_Client('thepath', 'ssl://theserver', 65);
8654+compare($x, $c, 'port 65 with ssl');
8655+
8656+
8657+$x = array(
8658+ 'path' => 'thepath',
8659+ 'server' => 'theserver',
8660+ 'protocol' => 'http://',
8661+ 'port' => 80,
8662+ 'proxy' => 'theproxy',
8663+ 'proxy_protocol' => 'http://',
8664+ 'proxy_port' => 8080,
8665+ 'proxy_user' => '',
8666+ 'proxy_pass' => '',
8667+ 'errno' => 0,
8668+ 'errstring' => '',
8669+ 'debug' => 0,
8670+ 'username' => '',
8671+ 'password' => '',
8672+);
8673+$c = new XML_RPC_Client('thepath', 'theserver', 0,
8674+ 'theproxy');
8675+compare($x, $c, 'defaults proxy');
8676+
8677+$x = array(
8678+ 'path' => 'thepath',
8679+ 'server' => 'theserver',
8680+ 'protocol' => 'http://',
8681+ 'port' => 80,
8682+ 'proxy' => 'theproxy',
8683+ 'proxy_protocol' => 'http://',
8684+ 'proxy_port' => 8080,
8685+ 'proxy_user' => '',
8686+ 'proxy_pass' => '',
8687+ 'errno' => 0,
8688+ 'errstring' => '',
8689+ 'debug' => 0,
8690+ 'username' => '',
8691+ 'password' => '',
8692+);
8693+$c = new XML_RPC_Client('thepath', 'http://theserver', 0,
8694+ 'http://theproxy');
8695+compare($x, $c, 'defaults with http proxy');
8696+
8697+$x = array(
8698+ 'path' => 'thepath',
8699+ 'server' => 'theserver',
8700+ 'protocol' => 'ssl://',
8701+ 'port' => 443,
8702+ 'proxy' => 'theproxy',
8703+ 'proxy_protocol' => 'ssl://',
8704+ 'proxy_port' => 443,
8705+ 'proxy_user' => '',
8706+ 'proxy_pass' => '',
8707+ 'errno' => 0,
8708+ 'errstring' => '',
8709+ 'debug' => 0,
8710+ 'username' => '',
8711+ 'password' => '',
8712+);
8713+$c = new XML_RPC_Client('thepath', 'https://theserver', 0,
8714+ 'https://theproxy');
8715+compare($x, $c, 'defaults with https proxy');
8716+
8717+$x = array(
8718+ 'path' => 'thepath',
8719+ 'server' => 'theserver',
8720+ 'protocol' => 'ssl://',
8721+ 'port' => 443,
8722+ 'proxy' => 'theproxy',
8723+ 'proxy_protocol' => 'ssl://',
8724+ 'proxy_port' => 443,
8725+ 'proxy_user' => '',
8726+ 'proxy_pass' => '',
8727+ 'errno' => 0,
8728+ 'errstring' => '',
8729+ 'debug' => 0,
8730+ 'username' => '',
8731+ 'password' => '',
8732+);
8733+$c = new XML_RPC_Client('thepath', 'ssl://theserver', 0,
8734+ 'ssl://theproxy');
8735+compare($x, $c, 'defaults with ssl proxy');
8736+
8737+
8738+$x = array(
8739+ 'path' => 'thepath',
8740+ 'server' => 'theserver',
8741+ 'protocol' => 'http://',
8742+ 'port' => 65,
8743+ 'proxy' => 'theproxy',
8744+ 'proxy_protocol' => 'http://',
8745+ 'proxy_port' => 6565,
8746+ 'proxy_user' => '',
8747+ 'proxy_pass' => '',
8748+ 'errno' => 0,
8749+ 'errstring' => '',
8750+ 'debug' => 0,
8751+ 'username' => '',
8752+ 'password' => '',
8753+);
8754+$c = new XML_RPC_Client('thepath', 'theserver', 65,
8755+ 'theproxy', 6565);
8756+compare($x, $c, 'port 65 proxy 6565');
8757+
8758+$x = array(
8759+ 'path' => 'thepath',
8760+ 'server' => 'theserver',
8761+ 'protocol' => 'http://',
8762+ 'port' => 65,
8763+ 'proxy' => 'theproxy',
8764+ 'proxy_protocol' => 'http://',
8765+ 'proxy_port' => 6565,
8766+ 'proxy_user' => '',
8767+ 'proxy_pass' => '',
8768+ 'errno' => 0,
8769+ 'errstring' => '',
8770+ 'debug' => 0,
8771+ 'username' => '',
8772+ 'password' => '',
8773+);
8774+$c = new XML_RPC_Client('thepath', 'http://theserver', 65,
8775+ 'http://theproxy', 6565);
8776+compare($x, $c, 'port 65 with http proxy 6565');
8777+
8778+$x = array(
8779+ 'path' => 'thepath',
8780+ 'server' => 'theserver',
8781+ 'protocol' => 'ssl://',
8782+ 'port' => 65,
8783+ 'proxy' => 'theproxy',
8784+ 'proxy_protocol' => 'ssl://',
8785+ 'proxy_port' => 6565,
8786+ 'proxy_user' => '',
8787+ 'proxy_pass' => '',
8788+ 'errno' => 0,
8789+ 'errstring' => '',
8790+ 'debug' => 0,
8791+ 'username' => '',
8792+ 'password' => '',
8793+);
8794+$c = new XML_RPC_Client('thepath', 'https://theserver', 65,
8795+ 'https://theproxy', 6565);
8796+compare($x, $c, 'port 65 with https proxy 6565');
8797+
8798+$x = array(
8799+ 'path' => 'thepath',
8800+ 'server' => 'theserver',
8801+ 'protocol' => 'ssl://',
8802+ 'port' => 65,
8803+ 'proxy' => 'theproxy',
8804+ 'proxy_protocol' => 'ssl://',
8805+ 'proxy_port' => 6565,
8806+ 'proxy_user' => '',
8807+ 'proxy_pass' => '',
8808+ 'errno' => 0,
8809+ 'errstring' => '',
8810+ 'debug' => 0,
8811+ 'username' => '',
8812+ 'password' => '',
8813+);
8814+$c = new XML_RPC_Client('thepath', 'ssl://theserver', 65,
8815+ 'ssl://theproxy', 6565);
8816+compare($x, $c, 'port 65 with ssl proxy 6565');
8817+
8818+
8819+$x = array(
8820+ 'path' => 'thepath',
8821+ 'server' => 'theserver',
8822+ 'protocol' => 'ssl://',
8823+ 'port' => 443,
8824+ 'proxy' => 'theproxy',
8825+ 'proxy_protocol' => 'ssl://',
8826+ 'proxy_port' => 443,
8827+ 'proxy_user' => '',
8828+ 'proxy_pass' => '',
8829+ 'errno' => 0,
8830+ 'errstring' => '',
8831+ 'debug' => 0,
8832+ 'username' => '',
8833+ 'password' => '',
8834+);
8835+$c = new XML_RPC_Client('thepath', 'theserver', 443,
8836+ 'theproxy', 443);
8837+compare($x, $c, 'port 443 no protocol and proxy port 443 no protocol');
8838+
8839+$x = array(
8840+ 'path' => 'thepath',
8841+ 'server' => 'theserver',
8842+ 'protocol' => 'http://',
8843+ 'port' => 80,
8844+ 'proxy' => 'theproxy',
8845+ 'proxy_protocol' => 'ssl://',
8846+ 'proxy_port' => 6565,
8847+ 'proxy_user' => '',
8848+ 'proxy_pass' => '',
8849+ 'errno' => 0,
8850+ 'errstring' => '',
8851+ 'debug' => 0,
8852+ 'username' => '',
8853+ 'password' => '',
8854+);
8855+$c = new XML_RPC_Client('thepath', 'theserver', 0,
8856+ 'ssl://theproxy', 6565);
8857+compare($x, $c, 'port 443 no protocol and proxy port 443 no protocol');
8858+
8859+
8860+/*
8861+ * If the package version number is found in the left hand
8862+ * portion of the if() expression below, that means this file has
8863+ * come from the PEAR installer. Therefore, let's test the
8864+ * installed version of XML_RPC which should be in the include path.
8865+ *
8866+ * If the version has not been substituted in the if() expression,
8867+ * this file has likely come from a CVS checkout or a .tar file.
8868+ * Therefore, we'll assume the tests should use the version of
8869+ * XML_RPC that has come from there as well.
8870+ */
8871+if ('1.4.0' != '@'.'package_version'.'@') {
8872+ /**
8873+ * Get the needed class from the PEAR installation
8874+ */
8875+ require_once 'XML/RPC/Dump.php';
8876+} else {
8877+ /**
8878+ * Get the needed class from the parent directory
8879+ */
8880+ require_once '../Dump.php';
8881+}
8882+
8883+$val = new XML_RPC_Value(array(
8884+ 'title' =>new XML_RPC_Value('das ist der Titel', 'string'),
8885+ 'startDate'=>new XML_RPC_Value(mktime(0,0,0,13,11,2004), 'dateTime.iso8601'),
8886+ 'endDate' =>new XML_RPC_Value(mktime(0,0,0,15,11,2004), 'dateTime.iso8601'),
8887+ 'error' =>'string',
8888+ 'arkey' => new XML_RPC_Value( array(
8889+ new XML_RPC_Value('simple string'),
8890+ new XML_RPC_Value(12345, 'int')
8891+ ), 'array')
8892+ )
8893+ ,'struct');
8894+
8895+XML_RPC_Dump($val);
8896+
8897+echo '==============' . "\r\n";
8898+$val2 = new XML_RPC_Value(44353, 'int');
8899+XML_RPC_Dump($val2);
8900+
8901+echo '==============' . "\r\n";
8902+$val3 = new XML_RPC_Value('this should be a string', 'string');
8903+XML_RPC_Dump($val3);
8904+
8905+echo '==============' . "\r\n";
8906+$val4 = new XML_RPC_Value(true, 'boolean');
8907+XML_RPC_Dump($val4);
8908+
8909+
8910+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
8911+
8912+/**
8913+ * Function and class to dump XML_RPC_Value objects in a nice way
8914+ *
8915+ * Should be helpful as a normal var_dump(..) displays all internals which
8916+ * doesn't really give you an overview due to too much information.
8917+ *
8918+ * @category Web Services
8919+ * @package XML_RPC
8920+ * @author Christian Weiske <cweiske@php.net>
8921+ * @version CVS: $Id: Dump.php,v 1.7 2005/01/24 03:47:55 danielc Exp $
8922+ * @link http://pear.php.net/package/XML_RPC
8923+ */
8924+
8925+
8926+/**
8927+ * Pull in the XML_RPC class
8928+ */
8929+require_once 'XML/RPC.php';
8930+
8931+
8932+/**
8933+ * Generates the dump of the XML_RPC_Value and echoes it
8934+ *
8935+ * @param object $value the XML_RPC_Value object to dump
8936+ *
8937+ * @return void
8938+ */
8939+function XML_RPC_Dump($value)
8940+{
8941+ $dumper = new XML_RPC_Dump();
8942+ echo $dumper->generateDump($value);
8943+}
8944+
8945+
8946+/**
8947+ * Class which generates a dump of a XML_RPC_Value object
8948+ *
8949+ * @category Web Services
8950+ * @package XML_RPC
8951+ * @author Christian Weiske <cweiske@php.net>
8952+ * @version Release: 1.4.0
8953+ * @link http://pear.php.net/package/XML_RPC
8954+ */
8955+class XML_RPC_Dump
8956+{
8957+ /**
8958+ * The indentation array cache
8959+ * @var array
8960+ */
8961+ var $arIndent = array();
8962+
8963+ /**
8964+ * The spaces used for indenting the XML
8965+ * @var string
8966+ */
8967+ var $strBaseIndent = ' ';
8968+
8969+ /**
8970+ * Returns the dump in XML format without printing it out
8971+ *
8972+ * @param object $value the XML_RPC_Value object to dump
8973+ * @param int $nLevel the level of indentation
8974+ *
8975+ * @return string the dump
8976+ */
8977+ function generateDump($value, $nLevel = 0)
8978+ {
8979+ if (!is_object($value) && get_class($value) != 'xml_rpc_value') {
8980+ require_once 'PEAR.php';
8981+ PEAR::raiseError('Tried to dump non-XML_RPC_Value variable' . "\r\n",
8982+ 0, PEAR_ERROR_PRINT);
8983+ if (is_object($value)) {
8984+ $strType = get_class($value);
8985+ } else {
8986+ $strType = gettype($value);
8987+ }
8988+ return $this->getIndent($nLevel) . 'NOT A XML_RPC_Value: '
8989+ . $strType . "\r\n";
8990+ }
8991+
8992+ switch ($value->kindOf()) {
8993+ case 'struct':
8994+ $ret = $this->genStruct($value, $nLevel);
8995+ break;
8996+ case 'array':
8997+ $ret = $this->genArray($value, $nLevel);
8998+ break;
8999+ case 'scalar':
9000+ $ret = $this->genScalar($value->scalarval(), $nLevel);
9001+ break;
9002+ default:
9003+ require_once 'PEAR.php';
9004+ PEAR::raiseError('Illegal type "' . $value->kindOf()
9005+ . '" in XML_RPC_Value' . "\r\n", 0,
9006+ PEAR_ERROR_PRINT);
9007+ }
9008+
9009+ return $ret;
9010+ }
9011+
9012+ /**
9013+ * Returns the scalar value dump
9014+ *
9015+ * @param object $value the scalar XML_RPC_Value object to dump
9016+ * @param int $nLevel the level of indentation
9017+ *
9018+ * @return string Dumped version of the scalar value
9019+ */
9020+ function genScalar($value, $nLevel)
9021+ {
9022+ if (gettype($value) == 'object') {
9023+ $strClass = ' ' . get_class($value);
9024+ } else {
9025+ $strClass = '';
9026+ }
9027+ return $this->getIndent($nLevel) . gettype($value) . $strClass
9028+ . ' ' . $value . "\r\n";
9029+ }
9030+
9031+ /**
9032+ * Returns the dump of a struct
9033+ *
9034+ * @param object $value the struct XML_RPC_Value object to dump
9035+ * @param int $nLevel the level of indentation
9036+ *
9037+ * @return string Dumped version of the scalar value
9038+ */
9039+ function genStruct($value, $nLevel)
9040+ {
9041+ $value->structreset();
9042+ $strOutput = $this->getIndent($nLevel) . 'struct' . "\r\n";
9043+ while (list($key, $keyval) = $value->structeach()) {
9044+ $strOutput .= $this->getIndent($nLevel + 1) . $key . "\r\n";
9045+ $strOutput .= $this->generateDump($keyval, $nLevel + 2);
9046+ }
9047+ return $strOutput;
9048+ }
9049+
9050+ /**
9051+ * Returns the dump of an array
9052+ *
9053+ * @param object $value the array XML_RPC_Value object to dump
9054+ * @param int $nLevel the level of indentation
9055+ *
9056+ * @return string Dumped version of the scalar value
9057+ */
9058+ function genArray($value, $nLevel)
9059+ {
9060+ $nSize = $value->arraysize();
9061+ $strOutput = $this->getIndent($nLevel) . 'array' . "\r\n";
9062+ for($nA = 0; $nA < $nSize; $nA++) {
9063+ $strOutput .= $this->getIndent($nLevel + 1) . $nA . "\r\n";
9064+ $strOutput .= $this->generateDump($value->arraymem($nA),
9065+ $nLevel + 2);
9066+ }
9067+ return $strOutput;
9068+ }
9069+
9070+ /**
9071+ * Returns the indent for a specific level and caches it for faster use
9072+ *
9073+ * @param int $nLevel the level
9074+ *
9075+ * @return string the indented string
9076+ */
9077+ function getIndent($nLevel)
9078+ {
9079+ if (!isset($this->arIndent[$nLevel])) {
9080+ $this->arIndent[$nLevel] = str_repeat($this->strBaseIndent, $nLevel);
9081+ }
9082+ return $this->arIndent[$nLevel];
9083+ }
9084+}
9085+
9086+/*
9087+ * Local variables:
9088+ * tab-width: 4
9089+ * c-basic-offset: 4
9090+ * c-hanging-comment-ender-p: nil
9091+ * End:
9092+ */
9093+
9094+?>
9095+
9096+
9097+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
9098+
9099+/**
9100+ * PHP implementation of the XML-RPC protocol
9101+ *
9102+ * This is a PEAR-ified version of Useful inc's XML-RPC for PHP.
9103+ * It has support for HTTP transport, proxies and authentication.
9104+ *
9105+ * PHP versions 4 and 5
9106+ *
9107+ * LICENSE: License is granted to use or modify this software
9108+ * ("XML-RPC for PHP") for commercial or non-commercial use provided the
9109+ * copyright of the author is preserved in any distributed or derivative work.
9110+ *
9111+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESSED OR
9112+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
9113+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
9114+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
9115+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
9116+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
9117+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
9118+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9119+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
9120+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9121+ *
9122+ * @category Web Services
9123+ * @package XML_RPC
9124+ * @author Edd Dumbill <edd@usefulinc.com>
9125+ * @author Stig Bakken <stig@php.net>
9126+ * @author Martin Jansen <mj@php.net>
9127+ * @author Daniel Convissor <danielc@php.net>
9128+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
9129+ * @version CVS: $Id: RPC.php,v 1.83 2005/08/14 20:25:35 danielc Exp $
9130+ * @link http://pear.php.net/package/XML_RPC
9131+ */
9132+
9133+
9134+if (!function_exists('xml_parser_create')) {
9135+ PEAR::loadExtension('xml');
9136+}
9137+
9138+/**#@+
9139+ * Error constants
9140+ */
9141+/**
9142+ * Parameter values don't match parameter types
9143+ */
9144+define('XML_RPC_ERROR_INVALID_TYPE', 101);
9145+/**
9146+ * Parameter declared to be numeric but the values are not
9147+ */
9148+define('XML_RPC_ERROR_NON_NUMERIC_FOUND', 102);
9149+/**
9150+ * Communication error
9151+ */
9152+define('XML_RPC_ERROR_CONNECTION_FAILED', 103);
9153+/**
9154+ * The array or struct has already been started
9155+ */
9156+define('XML_RPC_ERROR_ALREADY_INITIALIZED', 104);
9157+/**
9158+ * Incorrect parameters submitted
9159+ */
9160+define('XML_RPC_ERROR_INCORRECT_PARAMS', 105);
9161+/**
9162+ * Programming error by developer
9163+ */
9164+define('XML_RPC_ERROR_PROGRAMMING', 106);
9165+/**#@-*/
9166+
9167+
9168+/**
9169+ * Data types
9170+ * @global string $GLOBALS['XML_RPC_I4']
9171+ */
9172+$GLOBALS['XML_RPC_I4'] = 'i4';
9173+
9174+/**
9175+ * Data types
9176+ * @global string $GLOBALS['XML_RPC_Int']
9177+ */
9178+$GLOBALS['XML_RPC_Int'] = 'int';
9179+
9180+/**
9181+ * Data types
9182+ * @global string $GLOBALS['XML_RPC_Boolean']
9183+ */
9184+$GLOBALS['XML_RPC_Boolean'] = 'boolean';
9185+
9186+/**
9187+ * Data types
9188+ * @global string $GLOBALS['XML_RPC_Double']
9189+ */
9190+$GLOBALS['XML_RPC_Double'] = 'double';
9191+
9192+/**
9193+ * Data types
9194+ * @global string $GLOBALS['XML_RPC_String']
9195+ */
9196+$GLOBALS['XML_RPC_String'] = 'string';
9197+
9198+/**
9199+ * Data types
9200+ * @global string $GLOBALS['XML_RPC_DateTime']
9201+ */
9202+$GLOBALS['XML_RPC_DateTime'] = 'dateTime.iso8601';
9203+
9204+/**
9205+ * Data types
9206+ * @global string $GLOBALS['XML_RPC_Base64']
9207+ */
9208+$GLOBALS['XML_RPC_Base64'] = 'base64';
9209+
9210+/**
9211+ * Data types
9212+ * @global string $GLOBALS['XML_RPC_Array']
9213+ */
9214+$GLOBALS['XML_RPC_Array'] = 'array';
9215+
9216+/**
9217+ * Data types
9218+ * @global string $GLOBALS['XML_RPC_Struct']
9219+ */
9220+$GLOBALS['XML_RPC_Struct'] = 'struct';
9221+
9222+
9223+/**
9224+ * Data type meta-types
9225+ * @global array $GLOBALS['XML_RPC_Types']
9226+ */
9227+$GLOBALS['XML_RPC_Types'] = array(
9228+ $GLOBALS['XML_RPC_I4'] => 1,
9229+ $GLOBALS['XML_RPC_Int'] => 1,
9230+ $GLOBALS['XML_RPC_Boolean'] => 1,
9231+ $GLOBALS['XML_RPC_String'] => 1,
9232+ $GLOBALS['XML_RPC_Double'] => 1,
9233+ $GLOBALS['XML_RPC_DateTime'] => 1,
9234+ $GLOBALS['XML_RPC_Base64'] => 1,
9235+ $GLOBALS['XML_RPC_Array'] => 2,
9236+ $GLOBALS['XML_RPC_Struct'] => 3,
9237+);
9238+
9239+
9240+/**
9241+ * Error message numbers
9242+ * @global array $GLOBALS['XML_RPC_err']
9243+ */
9244+$GLOBALS['XML_RPC_err'] = array(
9245+ 'unknown_method' => 1,
9246+ 'invalid_return' => 2,
9247+ 'incorrect_params' => 3,
9248+ 'introspect_unknown' => 4,
9249+ 'http_error' => 5,
9250+ 'not_response_object' => 6,
9251+ 'invalid_request' => 7,
9252+);
9253+
9254+/**
9255+ * Error message strings
9256+ * @global array $GLOBALS['XML_RPC_str']
9257+ */
9258+$GLOBALS['XML_RPC_str'] = array(
9259+ 'unknown_method' => 'Unknown method',
9260+ 'invalid_return' => 'Invalid return payload: enable debugging to examine incoming payload',
9261+ 'incorrect_params' => 'Incorrect parameters passed to method',
9262+ 'introspect_unknown' => 'Can\'t introspect: method unknown',
9263+ 'http_error' => 'Didn\'t receive 200 OK from remote server.',
9264+ 'not_response_object' => 'The requested method didn\'t return an XML_RPC_Response object.',
9265+ 'invalid_request' => 'Invalid request payload',
9266+);
9267+
9268+
9269+/**
9270+ * Default XML encoding (ISO-8859-1, UTF-8 or US-ASCII)
9271+ * @global string $GLOBALS['XML_RPC_defencoding']
9272+ */
9273+$GLOBALS['XML_RPC_defencoding'] = 'UTF-8';
9274+
9275+/**
9276+ * User error codes start at 800
9277+ * @global int $GLOBALS['XML_RPC_erruser']
9278+ */
9279+$GLOBALS['XML_RPC_erruser'] = 800;
9280+
9281+/**
9282+ * XML parse error codes start at 100
9283+ * @global int $GLOBALS['XML_RPC_errxml']
9284+ */
9285+$GLOBALS['XML_RPC_errxml'] = 100;
9286+
9287+
9288+/**
9289+ * Compose backslashes for escaping regexp
9290+ * @global string $GLOBALS['XML_RPC_backslash']
9291+ */
9292+$GLOBALS['XML_RPC_backslash'] = chr(92) . chr(92);
9293+
9294+
9295+/**
9296+ * Valid parents of XML elements
9297+ * @global array $GLOBALS['XML_RPC_valid_parents']
9298+ */
9299+$GLOBALS['XML_RPC_valid_parents'] = array(
9300+ 'BOOLEAN' => array('VALUE'),
9301+ 'I4' => array('VALUE'),
9302+ 'INT' => array('VALUE'),
9303+ 'STRING' => array('VALUE'),
9304+ 'DOUBLE' => array('VALUE'),
9305+ 'DATETIME.ISO8601' => array('VALUE'),
9306+ 'BASE64' => array('VALUE'),
9307+ 'ARRAY' => array('VALUE'),
9308+ 'STRUCT' => array('VALUE'),
9309+ 'PARAM' => array('PARAMS'),
9310+ 'METHODNAME' => array('METHODCALL'),
9311+ 'PARAMS' => array('METHODCALL', 'METHODRESPONSE'),
9312+ 'MEMBER' => array('STRUCT'),
9313+ 'NAME' => array('MEMBER'),
9314+ 'DATA' => array('ARRAY'),
9315+ 'FAULT' => array('METHODRESPONSE'),
9316+ 'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT'),
9317+);
9318+
9319+
9320+/**
9321+ * Stores state during parsing
9322+ *
9323+ * quick explanation of components:
9324+ * + ac = accumulates values
9325+ * + qt = decides if quotes are needed for evaluation
9326+ * + cm = denotes struct or array (comma needed)
9327+ * + isf = indicates a fault
9328+ * + lv = indicates "looking for a value": implements the logic
9329+ * to allow values with no types to be strings
9330+ * + params = stores parameters in method calls
9331+ * + method = stores method name
9332+ *
9333+ * @global array $GLOBALS['XML_RPC_xh']
9334+ */
9335+$GLOBALS['XML_RPC_xh'] = array();
9336+
9337+
9338+/**
9339+ * Start element handler for the XML parser
9340+ *
9341+ * @return void
9342+ */
9343+function XML_RPC_se($parser_resource, $name, $attrs)
9344+{
9345+ global $XML_RPC_xh, $XML_RPC_DateTime, $XML_RPC_String, $XML_RPC_valid_parents;
9346+ $parser = (int) $parser_resource;
9347+
9348+ // if invalid xmlrpc already detected, skip all processing
9349+ if ($XML_RPC_xh[$parser]['isf'] >= 2) {
9350+ return;
9351+ }
9352+
9353+ // check for correct element nesting
9354+ // top level element can only be of 2 types
9355+ if (count($XML_RPC_xh[$parser]['stack']) == 0) {
9356+ if ($name != 'METHODRESPONSE' && $name != 'METHODCALL') {
9357+ $XML_RPC_xh[$parser]['isf'] = 2;
9358+ $XML_RPC_xh[$parser]['isf_reason'] = 'missing top level xmlrpc element';
9359+ return;
9360+ }
9361+ } else {
9362+ // not top level element: see if parent is OK
9363+ if (!in_array($XML_RPC_xh[$parser]['stack'][0], $XML_RPC_valid_parents[$name])) {
9364+ $name = preg_replace('[^a-zA-Z0-9._-]', '', $name);
9365+ $XML_RPC_xh[$parser]['isf'] = 2;
9366+ $XML_RPC_xh[$parser]['isf_reason'] = "xmlrpc element $name cannot be child of {$XML_RPC_xh[$parser]['stack'][0]}";
9367+ return;
9368+ }
9369+ }
9370+
9371+ switch ($name) {
9372+ case 'STRUCT':
9373+ $XML_RPC_xh[$parser]['cm']++;
9374+
9375+ // turn quoting off
9376+ $XML_RPC_xh[$parser]['qt'] = 0;
9377+
9378+ $cur_val = array();
9379+ $cur_val['value'] = array();
9380+ $cur_val['members'] = 1;
9381+ array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val);
9382+ break;
9383+
9384+ case 'ARRAY':
9385+ $XML_RPC_xh[$parser]['cm']++;
9386+
9387+ // turn quoting off
9388+ $XML_RPC_xh[$parser]['qt'] = 0;
9389+
9390+ $cur_val = array();
9391+ $cur_val['value'] = array();
9392+ $cur_val['members'] = 0;
9393+ array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val);
9394+ break;
9395+
9396+ case 'NAME':
9397+ $XML_RPC_xh[$parser]['ac'] = '';
9398+ break;
9399+
9400+ case 'FAULT':
9401+ $XML_RPC_xh[$parser]['isf'] = 1;
9402+ break;
9403+
9404+ case 'PARAM':
9405+ $XML_RPC_xh[$parser]['valuestack'] = array();
9406+ break;
9407+
9408+ case 'VALUE':
9409+ $XML_RPC_xh[$parser]['lv'] = 1;
9410+ $XML_RPC_xh[$parser]['vt'] = $XML_RPC_String;
9411+ $XML_RPC_xh[$parser]['ac'] = '';
9412+ $XML_RPC_xh[$parser]['qt'] = 0;
9413+ // look for a value: if this is still 1 by the
9414+ // time we reach the first data segment then the type is string
9415+ // by implication and we need to add in a quote
9416+ break;
9417+
9418+ case 'I4':
9419+ case 'INT':
9420+ case 'STRING':
9421+ case 'BOOLEAN':
9422+ case 'DOUBLE':
9423+ case 'DATETIME.ISO8601':
9424+ case 'BASE64':
9425+ $XML_RPC_xh[$parser]['ac'] = ''; // reset the accumulator
9426+
9427+ if ($name == 'DATETIME.ISO8601' || $name == 'STRING') {
9428+ $XML_RPC_xh[$parser]['qt'] = 1;
9429+
9430+ if ($name == 'DATETIME.ISO8601') {
9431+ $XML_RPC_xh[$parser]['vt'] = $XML_RPC_DateTime;
9432+ }
9433+
9434+ } elseif ($name == 'BASE64') {
9435+ $XML_RPC_xh[$parser]['qt'] = 2;
9436+ } else {
9437+ // No quoting is required here -- but
9438+ // at the end of the element we must check
9439+ // for data format errors.
9440+ $XML_RPC_xh[$parser]['qt'] = 0;
9441+ }
9442+ break;
9443+
9444+ case 'MEMBER':
9445+ $XML_RPC_xh[$parser]['ac'] = '';
9446+ break;
9447+
9448+ case 'DATA':
9449+ case 'METHODCALL':
9450+ case 'METHODNAME':
9451+ case 'METHODRESPONSE':
9452+ case 'PARAMS':
9453+ // valid elements that add little to processing
9454+ break;
9455+ }
9456+
9457+
9458+ // Save current element to stack
9459+ array_unshift($XML_RPC_xh[$parser]['stack'], $name);
9460+
9461+ if ($name != 'VALUE') {
9462+ $XML_RPC_xh[$parser]['lv'] = 0;
9463+ }
9464+}
9465+
9466+/**
9467+ * End element handler for the XML parser
9468+ *
9469+ * @return void
9470+ */
9471+function XML_RPC_ee($parser_resource, $name)
9472+{
9473+ global $XML_RPC_xh, $XML_RPC_Types, $XML_RPC_String;
9474+ $parser = (int) $parser_resource;
9475+
9476+ if ($XML_RPC_xh[$parser]['isf'] >= 2) {
9477+ return;
9478+ }
9479+
9480+ // push this element from stack
9481+ // NB: if XML validates, correct opening/closing is guaranteed and
9482+ // we do not have to check for $name == $curr_elem.
9483+ // we also checked for proper nesting at start of elements...
9484+ $curr_elem = array_shift($XML_RPC_xh[$parser]['stack']);
9485+
9486+ switch ($name) {
9487+ case 'STRUCT':
9488+ case 'ARRAY':
9489+ $cur_val = array_shift($XML_RPC_xh[$parser]['valuestack']);
9490+ $XML_RPC_xh[$parser]['value'] = $cur_val['value'];
9491+ $XML_RPC_xh[$parser]['vt'] = strtolower($name);
9492+ $XML_RPC_xh[$parser]['cm']--;
9493+ break;
9494+
9495+ case 'NAME':
9496+ $XML_RPC_xh[$parser]['valuestack'][0]['name'] = $XML_RPC_xh[$parser]['ac'];
9497+ break;
9498+
9499+ case 'BOOLEAN':
9500+ // special case here: we translate boolean 1 or 0 into PHP
9501+ // constants true or false
9502+ if ($XML_RPC_xh[$parser]['ac'] == '1') {
9503+ $XML_RPC_xh[$parser]['ac'] = 'true';
9504+ } else {
9505+ $XML_RPC_xh[$parser]['ac'] = 'false';
9506+ }
9507+
9508+ $XML_RPC_xh[$parser]['vt'] = strtolower($name);
9509+ // Drop through intentionally.
9510+
9511+ case 'I4':
9512+ case 'INT':
9513+ case 'STRING':
9514+ case 'DOUBLE':
9515+ case 'DATETIME.ISO8601':
9516+ case 'BASE64':
9517+ if ($XML_RPC_xh[$parser]['qt'] == 1) {
9518+ // we use double quotes rather than single so backslashification works OK
9519+ $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac'];
9520+ } elseif ($XML_RPC_xh[$parser]['qt'] == 2) {
9521+ $XML_RPC_xh[$parser]['value'] = base64_decode($XML_RPC_xh[$parser]['ac']);
9522+ } elseif ($name == 'BOOLEAN') {
9523+ $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac'];
9524+ } else {
9525+ // we have an I4, INT or a DOUBLE
9526+ // we must check that only 0123456789-.<space> are characters here
9527+ if (!ereg("^[+-]?[0123456789 \t\.]+$", $XML_RPC_xh[$parser]['ac'])) {
9528+ XML_RPC_Base::raiseError('Non-numeric value received in INT or DOUBLE',
9529+ XML_RPC_ERROR_NON_NUMERIC_FOUND);
9530+ $XML_RPC_xh[$parser]['value'] = XML_RPC_ERROR_NON_NUMERIC_FOUND;
9531+ } else {
9532+ // it's ok, add it on
9533+ $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac'];
9534+ }
9535+ }
9536+
9537+ $XML_RPC_xh[$parser]['ac'] = '';
9538+ $XML_RPC_xh[$parser]['qt'] = 0;
9539+ $XML_RPC_xh[$parser]['lv'] = 3; // indicate we've found a value
9540+ break;
9541+
9542+ case 'VALUE':
9543+ // deal with a string value
9544+ if (strlen($XML_RPC_xh[$parser]['ac']) > 0 &&
9545+ $XML_RPC_xh[$parser]['vt'] == $XML_RPC_String) {
9546+ $XML_RPC_xh[$parser]['value'] = $XML_RPC_xh[$parser]['ac'];
9547+ }
9548+
9549+ $temp = new XML_RPC_Value($XML_RPC_xh[$parser]['value'], $XML_RPC_xh[$parser]['vt']);
9550+
9551+ $cur_val = array_shift($XML_RPC_xh[$parser]['valuestack']);
9552+ if (is_array($cur_val)) {
9553+ if ($cur_val['members']==0) {
9554+ $cur_val['value'][] = $temp;
9555+ } else {
9556+ $XML_RPC_xh[$parser]['value'] = $temp;
9557+ }
9558+ array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val);
9559+ } else {
9560+ $XML_RPC_xh[$parser]['value'] = $temp;
9561+ }
9562+ break;
9563+
9564+ case 'MEMBER':
9565+ $XML_RPC_xh[$parser]['ac'] = '';
9566+ $XML_RPC_xh[$parser]['qt'] = 0;
9567+
9568+ $cur_val = array_shift($XML_RPC_xh[$parser]['valuestack']);
9569+ if (is_array($cur_val)) {
9570+ if ($cur_val['members']==1) {
9571+ $cur_val['value'][$cur_val['name']] = $XML_RPC_xh[$parser]['value'];
9572+ }
9573+ array_unshift($XML_RPC_xh[$parser]['valuestack'], $cur_val);
9574+ }
9575+ break;
9576+
9577+ case 'DATA':
9578+ $XML_RPC_xh[$parser]['ac'] = '';
9579+ $XML_RPC_xh[$parser]['qt'] = 0;
9580+ break;
9581+
9582+ case 'PARAM':
9583+ $XML_RPC_xh[$parser]['params'][] = $XML_RPC_xh[$parser]['value'];
9584+ break;
9585+
9586+ case 'METHODNAME':
9587+ case 'RPCMETHODNAME':
9588+ $XML_RPC_xh[$parser]['method'] = ereg_replace("^[\n\r\t ]+", '',
9589+ $XML_RPC_xh[$parser]['ac']);
9590+ break;
9591+ }
9592+
9593+ // if it's a valid type name, set the type
9594+ if (isset($XML_RPC_Types[strtolower($name)])) {
9595+ $XML_RPC_xh[$parser]['vt'] = strtolower($name);
9596+ }
9597+}
9598+
9599+/**
9600+ * Character data handler for the XML parser
9601+ *
9602+ * @return void
9603+ */
9604+function XML_RPC_cd($parser_resource, $data)
9605+{
9606+ global $XML_RPC_xh, $XML_RPC_backslash;
9607+ $parser = (int) $parser_resource;
9608+
9609+ if ($XML_RPC_xh[$parser]['lv'] != 3) {
9610+ // "lookforvalue==3" means that we've found an entire value
9611+ // and should discard any further character data
9612+
9613+ if ($XML_RPC_xh[$parser]['lv'] == 1) {
9614+ // if we've found text and we're just in a <value> then
9615+ // turn quoting on, as this will be a string
9616+ $XML_RPC_xh[$parser]['qt'] = 1;
9617+ // and say we've found a value
9618+ $XML_RPC_xh[$parser]['lv'] = 2;
9619+ }
9620+
9621+ // replace characters that eval would
9622+ // do special things with
9623+ if (!isset($XML_RPC_xh[$parser]['ac'])) {
9624+ $XML_RPC_xh[$parser]['ac'] = '';
9625+ }
9626+ $XML_RPC_xh[$parser]['ac'] .= $data;
9627+ }
9628+}
9629+
9630+/**
9631+ * The common methods and properties for all of the XML_RPC classes
9632+ *
9633+ * @category Web Services
9634+ * @package XML_RPC
9635+ * @author Edd Dumbill <edd@usefulinc.com>
9636+ * @author Stig Bakken <stig@php.net>
9637+ * @author Martin Jansen <mj@php.net>
9638+ * @author Daniel Convissor <danielc@php.net>
9639+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
9640+ * @version Release: 1.4.0
9641+ * @link http://pear.php.net/package/XML_RPC
9642+ */
9643+class XML_RPC_Base {
9644+
9645+ /**
9646+ * PEAR Error handling
9647+ *
9648+ * @return object PEAR_Error object
9649+ */
9650+ function raiseError($msg, $code)
9651+ {
9652+ include_once 'PEAR.php';
9653+ if (is_object(@$this)) {
9654+ return PEAR::raiseError(get_class($this) . ': ' . $msg, $code);
9655+ } else {
9656+ return PEAR::raiseError('XML_RPC: ' . $msg, $code);
9657+ }
9658+ }
9659+
9660+ /**
9661+ * Tell whether something is a PEAR_Error object
9662+ *
9663+ * @param mixed $value the item to check
9664+ *
9665+ * @return bool whether $value is a PEAR_Error object or not
9666+ *
9667+ * @access public
9668+ */
9669+ function isError($value)
9670+ {
9671+ return is_a($value, 'PEAR_Error');
9672+ }
9673+}
9674+
9675+/**
9676+ * The methods and properties for submitting XML RPC requests
9677+ *
9678+ * @category Web Services
9679+ * @package XML_RPC
9680+ * @author Edd Dumbill <edd@usefulinc.com>
9681+ * @author Stig Bakken <stig@php.net>
9682+ * @author Martin Jansen <mj@php.net>
9683+ * @author Daniel Convissor <danielc@php.net>
9684+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
9685+ * @version Release: 1.4.0
9686+ * @link http://pear.php.net/package/XML_RPC
9687+ */
9688+class XML_RPC_Client extends XML_RPC_Base {
9689+
9690+ /**
9691+ * The path and name of the RPC server script you want the request to go to
9692+ * @var string
9693+ */
9694+ var $path = '';
9695+
9696+ /**
9697+ * The name of the remote server to connect to
9698+ * @var string
9699+ */
9700+ var $server = '';
9701+
9702+ /**
9703+ * The protocol to use in contacting the remote server
9704+ * @var string
9705+ */
9706+ var $protocol = 'http://';
9707+
9708+ /**
9709+ * The port for connecting to the remote server
9710+ *
9711+ * The default is 80 for http:// connections
9712+ * and 443 for https:// and ssl:// connections.
9713+ *
9714+ * @var integer
9715+ */
9716+ var $port = 80;
9717+
9718+ /**
9719+ * A user name for accessing the RPC server
9720+ * @var string
9721+ * @see XML_RPC_Client::setCredentials()
9722+ */
9723+ var $username = '';
9724+
9725+ /**
9726+ * A password for accessing the RPC server
9727+ * @var string
9728+ * @see XML_RPC_Client::setCredentials()
9729+ */
9730+ var $password = '';
9731+
9732+ /**
9733+ * The name of the proxy server to use, if any
9734+ * @var string
9735+ */
9736+ var $proxy = '';
9737+
9738+ /**
9739+ * The protocol to use in contacting the proxy server, if any
9740+ * @var string
9741+ */
9742+ var $proxy_protocol = 'http://';
9743+
9744+ /**
9745+ * The port for connecting to the proxy server
9746+ *
9747+ * The default is 8080 for http:// connections
9748+ * and 443 for https:// and ssl:// connections.
9749+ *
9750+ * @var integer
9751+ */
9752+ var $proxy_port = 8080;
9753+
9754+ /**
9755+ * A user name for accessing the proxy server
9756+ * @var string
9757+ */
9758+ var $proxy_user = '';
9759+
9760+ /**
9761+ * A password for accessing the proxy server
9762+ * @var string
9763+ */
9764+ var $proxy_pass = '';
9765+
9766+ /**
9767+ * The error number, if any
9768+ * @var integer
9769+ */
9770+ var $errno = 0;
9771+
9772+ /**
9773+ * The error message, if any
9774+ * @var string
9775+ */
9776+ var $errstr = '';
9777+
9778+ /**
9779+ * The current debug mode (1 = on, 0 = off)
9780+ * @var integer
9781+ */
9782+ var $debug = 0;
9783+
9784+ /**
9785+ * The HTTP headers for the current request.
9786+ * @var string
9787+ */
9788+ var $headers = '';
9789+
9790+
9791+ /**
9792+ * Sets the object's properties
9793+ *
9794+ * @param string $path the path and name of the RPC server script
9795+ * you want the request to go to
9796+ * @param string $server the URL of the remote server to connect to.
9797+ * If this parameter doesn't specify a
9798+ * protocol and $port is 443, ssl:// is
9799+ * assumed.
9800+ * @param integer $port a port for connecting to the remote server.
9801+ * Defaults to 80 for http:// connections and
9802+ * 443 for https:// and ssl:// connections.
9803+ * @param string $proxy the URL of the proxy server to use, if any.
9804+ * If this parameter doesn't specify a
9805+ * protocol and $port is 443, ssl:// is
9806+ * assumed.
9807+ * @param integer $proxy_port a port for connecting to the remote server.
9808+ * Defaults to 8080 for http:// connections and
9809+ * 443 for https:// and ssl:// connections.
9810+ * @param string $proxy_user a user name for accessing the proxy server
9811+ * @param string $proxy_pass a password for accessing the proxy server
9812+ *
9813+ * @return void
9814+ */
9815+ function XML_RPC_Client($path, $server, $port = 0,
9816+ $proxy = '', $proxy_port = 0,
9817+ $proxy_user = '', $proxy_pass = '')
9818+ {
9819+ $this->path = $path;
9820+ $this->proxy_user = $proxy_user;
9821+ $this->proxy_pass = $proxy_pass;
9822+
9823+ preg_match('@^(http://|https://|ssl://)?(.*)$@', $server, $match);
9824+ if ($match[1] == '') {
9825+ if ($port == 443) {
9826+ $this->server = $match[2];
9827+ $this->protocol = 'ssl://';
9828+ $this->port = 443;
9829+ } else {
9830+ $this->server = $match[2];
9831+ if ($port) {
9832+ $this->port = $port;
9833+ }
9834+ }
9835+ } elseif ($match[1] == 'http://') {
9836+ $this->server = $match[2];
9837+ if ($port) {
9838+ $this->port = $port;
9839+ }
9840+ } else {
9841+ $this->server = $match[2];
9842+ $this->protocol = 'ssl://';
9843+ if ($port) {
9844+ $this->port = $port;
9845+ } else {
9846+ $this->port = 443;
9847+ }
9848+ }
9849+
9850+ if ($proxy) {
9851+ preg_match('@^(http://|https://|ssl://)?(.*)$@', $proxy, $match);
9852+ if ($match[1] == '') {
9853+ if ($proxy_port == 443) {
9854+ $this->proxy = $match[2];
9855+ $this->proxy_protocol = 'ssl://';
9856+ $this->proxy_port = 443;
9857+ } else {
9858+ $this->proxy = $match[2];
9859+ if ($proxy_port) {
9860+ $this->proxy_port = $proxy_port;
9861+ }
9862+ }
9863+ } elseif ($match[1] == 'http://') {
9864+ $this->proxy = $match[2];
9865+ if ($proxy_port) {
9866+ $this->proxy_port = $proxy_port;
9867+ }
9868+ } else {
9869+ $this->proxy = $match[2];
9870+ $this->proxy_protocol = 'ssl://';
9871+ if ($proxy_port) {
9872+ $this->proxy_port = $proxy_port;
9873+ } else {
9874+ $this->proxy_port = 443;
9875+ }
9876+ }
9877+ }
9878+ }
9879+
9880+ /**
9881+ * Change the current debug mode
9882+ *
9883+ * @param int $in where 1 = on, 0 = off
9884+ *
9885+ * @return void
9886+ */
9887+ function setDebug($in)
9888+ {
9889+ if ($in) {
9890+ $this->debug = 1;
9891+ } else {
9892+ $this->debug = 0;
9893+ }
9894+ }
9895+
9896+ /**
9897+ * Set username and password properties for connecting to the RPC server
9898+ *
9899+ * @param string $u the user name
9900+ * @param string $p the password
9901+ *
9902+ * @return void
9903+ *
9904+ * @see XML_RPC_Client::$username, XML_RPC_Client::$password
9905+ */
9906+ function setCredentials($u, $p)
9907+ {
9908+ $this->username = $u;
9909+ $this->password = $p;
9910+ }
9911+
9912+ /**
9913+ * Transmit the RPC request via HTTP 1.0 protocol
9914+ *
9915+ * @param object $msg the XML_RPC_Message object
9916+ * @param int $timeout how many seconds to wait for the request
9917+ *
9918+ * @return object an XML_RPC_Response object. 0 is returned if any
9919+ * problems happen.
9920+ *
9921+ * @see XML_RPC_Message, XML_RPC_Client::XML_RPC_Client(),
9922+ * XML_RPC_Client::setCredentials()
9923+ */
9924+ function send($msg, $timeout = 0)
9925+ {
9926+ if (strtolower(get_class($msg)) != 'xml_rpc_message') {
9927+ $this->errstr = 'send()\'s $msg parameter must be an'
9928+ . ' XML_RPC_Message object.';
9929+ $this->raiseError($this->errstr, XML_RPC_ERROR_PROGRAMMING);
9930+ return 0;
9931+ }
9932+ $msg->debug = $this->debug;
9933+ return $this->sendPayloadHTTP10($msg, $this->server, $this->port,
9934+ $timeout, $this->username,
9935+ $this->password);
9936+ }
9937+
9938+ /**
9939+ * Transmit the RPC request via HTTP 1.0 protocol
9940+ *
9941+ * Requests should be sent using XML_RPC_Client send() rather than
9942+ * calling this method directly.
9943+ *
9944+ * @param object $msg the XML_RPC_Message object
9945+ * @param string $server the server to send the request to
9946+ * @param int $port the server port send the request to
9947+ * @param int $timeout how many seconds to wait for the request
9948+ * before giving up
9949+ * @param string $username a user name for accessing the RPC server
9950+ * @param string $password a password for accessing the RPC server
9951+ *
9952+ * @return object an XML_RPC_Response object. 0 is returned if any
9953+ * problems happen.
9954+ *
9955+ * @access protected
9956+ * @see XML_RPC_Client::send()
9957+ */
9958+ function sendPayloadHTTP10($msg, $server, $port, $timeout = 0,
9959+ $username = '', $password = '')
9960+ {
9961+ /*
9962+ * If we're using a proxy open a socket to the proxy server
9963+ * instead to the xml-rpc server
9964+ */
9965+ if ($this->proxy) {
9966+ if ($this->proxy_protocol == 'http://') {
9967+ $protocol = '';
9968+ } else {
9969+ $protocol = $this->proxy_protocol;
9970+ }
9971+ if ($timeout > 0) {
9972+ $fp = @fsockopen($protocol . $this->proxy, $this->proxy_port,
9973+ $this->errno, $this->errstr, $timeout);
9974+ } else {
9975+ $fp = @fsockopen($protocol . $this->proxy, $this->proxy_port,
9976+ $this->errno, $this->errstr);
9977+ }
9978+ } else {
9979+ if ($this->protocol == 'http://') {
9980+ $protocol = '';
9981+ } else {
9982+ $protocol = $this->protocol;
9983+ }
9984+ if ($timeout > 0) {
9985+ $fp = @fsockopen($protocol . $server, $port,
9986+ $this->errno, $this->errstr, $timeout);
9987+ } else {
9988+ $fp = @fsockopen($protocol . $server, $port,
9989+ $this->errno, $this->errstr);
9990+ }
9991+ }
9992+
9993+ /*
9994+ * Just raising the error without returning it is strange,
9995+ * but keep it here for backwards compatibility.
9996+ */
9997+ if (!$fp && $this->proxy) {
9998+ $this->raiseError('Connection to proxy server '
9999+ . $this->proxy . ':' . $this->proxy_port
10000+ . ' failed. ' . $this->errstr,
10001+ XML_RPC_ERROR_CONNECTION_FAILED);
10002+ return 0;
10003+ } elseif (!$fp) {
10004+ $this->raiseError('Connection to RPC server '
10005+ . $server . ':' . $port
10006+ . ' failed. ' . $this->errstr,
10007+ XML_RPC_ERROR_CONNECTION_FAILED);
10008+ return 0;
10009+ }
10010+
10011+ if ($timeout) {
10012+ /*
10013+ * Using socket_set_timeout() because stream_set_timeout()
10014+ * was introduced in 4.3.0, but we need to support 4.2.0.
10015+ */
10016+ socket_set_timeout($fp, $timeout);
10017+ }
10018+
10019+ // Pre-emptive BC hacks for fools calling sendPayloadHTTP10() directly
10020+ if ($username != $this->username) {
10021+ $this->setCredentials($username, $password);
10022+ }
10023+
10024+ // Only create the payload if it was not created previously
10025+ if (empty($msg->payload)) {
10026+ $msg->createPayload();
10027+ }
10028+ $this->createHeaders($msg);
10029+
10030+ $op = $this->headers . "\r\n\r\n";
10031+ $op .= $msg->payload;
10032+
10033+ if (!fputs($fp, $op, strlen($op))) {
10034+ $this->errstr = 'Write error';
10035+ return 0;
10036+ }
10037+ $resp = $msg->parseResponseFile($fp);
10038+
10039+ $meta = socket_get_status($fp);
10040+ if ($meta['timed_out']) {
10041+ fclose($fp);
10042+ $this->errstr = 'RPC server did not send response before timeout.';
10043+ $this->raiseError($this->errstr, XML_RPC_ERROR_CONNECTION_FAILED);
10044+ return 0;
10045+ }
10046+
10047+ fclose($fp);
10048+ return $resp;
10049+ }
10050+
10051+ /**
10052+ * Determines the HTTP headers and puts it in the $headers property
10053+ *
10054+ * @param object $msg the XML_RPC_Message object
10055+ *
10056+ * @return boolean TRUE if okay, FALSE if the message payload isn't set.
10057+ *
10058+ * @access protected
10059+ */
10060+ function createHeaders($msg)
10061+ {
10062+ if (empty($msg->payload)) {
10063+ return false;
10064+ }
10065+ if ($this->proxy) {
10066+ $this->headers = 'POST ' . $this->protocol . $this->server;
10067+ if ($this->proxy_port) {
10068+ $this->headers .= ':' . $this->port;
10069+ }
10070+ } else {
10071+ $this->headers = 'POST ';
10072+ }
10073+ $this->headers .= $this->path. " HTTP/1.0\r\n";
10074+
10075+ $this->headers .= "User-Agent: PEAR XML_RPC\r\n";
10076+ $this->headers .= 'Host: ' . $this->server . "\r\n";
10077+
10078+ if ($this->proxy && $this->proxy_user) {
10079+ $this->headers .= 'Proxy-Authorization: Basic '
10080+ . base64_encode("$this->proxy_user:$this->proxy_pass")
10081+ . "\r\n";
10082+ }
10083+
10084+ // thanks to Grant Rauscher <grant7@firstworld.net> for this
10085+ if ($this->username) {
10086+ $this->headers .= 'Authorization: Basic '
10087+ . base64_encode("$this->username:$this->password")
10088+ . "\r\n";
10089+ }
10090+
10091+ $this->headers .= "Content-Type: text/xml\r\n";
10092+ $this->headers .= 'Content-Length: ' . strlen($msg->payload);
10093+ return true;
10094+ }
10095+}
10096+
10097+/**
10098+ * The methods and properties for interpreting responses to XML RPC requests
10099+ *
10100+ * @category Web Services
10101+ * @package XML_RPC
10102+ * @author Edd Dumbill <edd@usefulinc.com>
10103+ * @author Stig Bakken <stig@php.net>
10104+ * @author Martin Jansen <mj@php.net>
10105+ * @author Daniel Convissor <danielc@php.net>
10106+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
10107+ * @version Release: 1.4.0
10108+ * @link http://pear.php.net/package/XML_RPC
10109+ */
10110+class XML_RPC_Response extends XML_RPC_Base
10111+{
10112+ var $xv;
10113+ var $fn;
10114+ var $fs;
10115+ var $hdrs;
10116+
10117+ /**
10118+ * @return void
10119+ */
10120+ function XML_RPC_Response($val, $fcode = 0, $fstr = '')
10121+ {
10122+ if ($fcode != 0) {
10123+ $this->fn = $fcode;
10124+ $this->fs = htmlspecialchars($fstr);
10125+ } else {
10126+ $this->xv = $val;
10127+ }
10128+ }
10129+
10130+ /**
10131+ * @return int the error code
10132+ */
10133+ function faultCode()
10134+ {
10135+ if (isset($this->fn)) {
10136+ return $this->fn;
10137+ } else {
10138+ return 0;
10139+ }
10140+ }
10141+
10142+ /**
10143+ * @return string the error string
10144+ */
10145+ function faultString()
10146+ {
10147+ return $this->fs;
10148+ }
10149+
10150+ /**
10151+ * @return mixed the value
10152+ */
10153+ function value()
10154+ {
10155+ return $this->xv;
10156+ }
10157+
10158+ /**
10159+ * @return string the error message in XML format
10160+ */
10161+ function serialize()
10162+ {
10163+ $rs = "<methodResponse>\n";
10164+ if ($this->fn) {
10165+ $rs .= "<fault>
10166+ <value>
10167+ <struct>
10168+ <member>
10169+ <name>faultCode</name>
10170+ <value><int>" . $this->fn . "</int></value>
10171+ </member>
10172+ <member>
10173+ <name>faultString</name>
10174+ <value><string>" . $this->fs . "</string></value>
10175+ </member>
10176+ </struct>
10177+ </value>
10178+</fault>";
10179+ } else {
10180+ $rs .= "<params>\n<param>\n" . $this->xv->serialize() .
10181+ "</param>\n</params>";
10182+ }
10183+ $rs .= "\n</methodResponse>";
10184+ return $rs;
10185+ }
10186+}
10187+
10188+/**
10189+ * The methods and properties for composing XML RPC messages
10190+ *
10191+ * @category Web Services
10192+ * @package XML_RPC
10193+ * @author Edd Dumbill <edd@usefulinc.com>
10194+ * @author Stig Bakken <stig@php.net>
10195+ * @author Martin Jansen <mj@php.net>
10196+ * @author Daniel Convissor <danielc@php.net>
10197+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
10198+ * @version Release: 1.4.0
10199+ * @link http://pear.php.net/package/XML_RPC
10200+ */
10201+class XML_RPC_Message extends XML_RPC_Base
10202+{
10203+ /**
10204+ * The current debug mode (1 = on, 0 = off)
10205+ * @var integer
10206+ */
10207+ var $debug = 0;
10208+
10209+ /**
10210+ * The encoding to be used for outgoing messages
10211+ *
10212+ * Defaults to the value of <var>$GLOBALS['XML_RPC_defencoding']</var>
10213+ *
10214+ * @var string
10215+ * @see XML_RPC_Message::setSendEncoding(),
10216+ * $GLOBALS['XML_RPC_defencoding'], XML_RPC_Message::xml_header()
10217+ */
10218+ var $send_encoding = '';
10219+
10220+ /**
10221+ * The method presently being evaluated
10222+ * @var string
10223+ */
10224+ var $methodname = '';
10225+
10226+ /**
10227+ * @var array
10228+ */
10229+ var $params = array();
10230+
10231+ /**
10232+ * The XML message being generated
10233+ * @var string
10234+ */
10235+ var $payload = '';
10236+
10237+ /**
10238+ * @return void
10239+ */
10240+ function XML_RPC_Message($meth, $pars = 0)
10241+ {
10242+ $this->methodname = $meth;
10243+ if (is_array($pars) && sizeof($pars) > 0) {
10244+ for ($i = 0; $i < sizeof($pars); $i++) {
10245+ $this->addParam($pars[$i]);
10246+ }
10247+ }
10248+ }
10249+
10250+ /**
10251+ * Produces the XML declaration including the encoding attribute
10252+ *
10253+ * The encoding is determined by this class' <var>$send_encoding</var>
10254+ * property. If the <var>$send_encoding</var> property is not set, use
10255+ * <var>$GLOBALS['XML_RPC_defencoding']</var>.
10256+ *
10257+ * @return string the XML declaration and <methodCall> element
10258+ *
10259+ * @see XML_RPC_Message::setSendEncoding(),
10260+ * XML_RPC_Message::$send_encoding, $GLOBALS['XML_RPC_defencoding']
10261+ */
10262+ function xml_header()
10263+ {
10264+ global $XML_RPC_defencoding;
10265+ if (!$this->send_encoding) {
10266+ $this->send_encoding = $XML_RPC_defencoding;
10267+ }
10268+ return '<?xml version="1.0" encoding="' . $this->send_encoding . '"?>'
10269+ . "\n<methodCall>\n";
10270+ }
10271+
10272+ /**
10273+ * @return string the closing </methodCall> tag
10274+ */
10275+ function xml_footer()
10276+ {
10277+ return "</methodCall>\n";
10278+ }
10279+
10280+ /**
10281+ * @return void
10282+ *
10283+ * @uses XML_RPC_Message::xml_header(), XML_RPC_Message::xml_footer()
10284+ */
10285+ function createPayload()
10286+ {
10287+ $this->payload = $this->xml_header();
10288+ $this->payload .= '<methodName>' . $this->methodname . "</methodName>\n";
10289+ $this->payload .= "<params>\n";
10290+ for ($i = 0; $i < sizeof($this->params); $i++) {
10291+ $p = $this->params[$i];
10292+ $this->payload .= "<param>\n" . $p->serialize() . "</param>\n";
10293+ }
10294+ $this->payload .= "</params>\n";
10295+ $this->payload .= $this->xml_footer();
10296+ $this->payload = ereg_replace("[\r\n]+", "\r\n", $this->payload);
10297+ }
10298+
10299+ /**
10300+ * @return string the name of the method
10301+ */
10302+ function method($meth = '')
10303+ {
10304+ if ($meth != '') {
10305+ $this->methodname = $meth;
10306+ }
10307+ return $this->methodname;
10308+ }
10309+
10310+ /**
10311+ * @return string the payload
10312+ */
10313+ function serialize()
10314+ {
10315+ $this->createPayload();
10316+ return $this->payload;
10317+ }
10318+
10319+ /**
10320+ * @return void
10321+ */
10322+ function addParam($par)
10323+ {
10324+ $this->params[] = $par;
10325+ }
10326+
10327+ /**
10328+ * Obtains an XML_RPC_Value object for the given parameter
10329+ *
10330+ * @param int $i the index number of the parameter to obtain
10331+ *
10332+ * @return object the XML_RPC_Value object.
10333+ * If the parameter doesn't exist, an XML_RPC_Response object.
10334+ *
10335+ * @since Returns XML_RPC_Response object on error since Release 1.3.0
10336+ */
10337+ function getParam($i)
10338+ {
10339+ global $XML_RPC_err, $XML_RPC_str;
10340+
10341+ if (isset($this->params[$i])) {
10342+ return $this->params[$i];
10343+ } else {
10344+ $this->raiseError('The submitted request did not contain this parameter',
10345+ XML_RPC_ERROR_INCORRECT_PARAMS);
10346+ return new XML_RPC_Response(0, $XML_RPC_err['incorrect_params'],
10347+ $XML_RPC_str['incorrect_params']);
10348+ }
10349+ }
10350+
10351+ /**
10352+ * @return int the number of parameters
10353+ */
10354+ function getNumParams()
10355+ {
10356+ return sizeof($this->params);
10357+ }
10358+
10359+ /**
10360+ * Sets the XML declaration's encoding attribute
10361+ *
10362+ * @param string $type the encoding type (ISO-8859-1, UTF-8 or US-ASCII)
10363+ *
10364+ * @return void
10365+ *
10366+ * @see XML_RPC_Message::$send_encoding, XML_RPC_Message::xml_header()
10367+ * @since Method available since Release 1.2.0
10368+ */
10369+ function setSendEncoding($type)
10370+ {
10371+ $this->send_encoding = $type;
10372+ }
10373+
10374+ /**
10375+ * Determine the XML's encoding via the encoding attribute
10376+ * in the XML declaration
10377+ *
10378+ * If the encoding parameter is not set or is not ISO-8859-1, UTF-8
10379+ * or US-ASCII, $XML_RPC_defencoding will be returned.
10380+ *
10381+ * @param string $data the XML that will be parsed
10382+ *
10383+ * @return string the encoding to be used
10384+ *
10385+ * @link http://php.net/xml_parser_create
10386+ * @since Method available since Release 1.2.0
10387+ */
10388+ function getEncoding($data)
10389+ {
10390+ global $XML_RPC_defencoding;
10391+
10392+ if (preg_match('/<\?xml[^>]*\s*encoding\s*=\s*[\'"]([^"\']*)[\'"]/i',
10393+ $data, $match))
10394+ {
10395+ $match[1] = trim(strtoupper($match[1]));
10396+ switch ($match[1]) {
10397+ case 'ISO-8859-1':
10398+ case 'UTF-8':
10399+ case 'US-ASCII':
10400+ return $match[1];
10401+ break;
10402+
10403+ default:
10404+ return $XML_RPC_defencoding;
10405+ }
10406+ } else {
10407+ return $XML_RPC_defencoding;
10408+ }
10409+ }
10410+
10411+ /**
10412+ * @return object a new XML_RPC_Response object
10413+ */
10414+ function parseResponseFile($fp)
10415+ {
10416+ $ipd = '';
10417+ while ($data = @fread($fp, 8192)) {
10418+ $ipd .= $data;
10419+ }
10420+ return $this->parseResponse($ipd);
10421+ }
10422+
10423+ /**
10424+ * @return object a new XML_RPC_Response object
10425+ */
10426+ function parseResponse($data = '')
10427+ {
10428+ global $XML_RPC_xh, $XML_RPC_err, $XML_RPC_str, $XML_RPC_defencoding;
10429+
10430+ $encoding = $this->getEncoding($data);
10431+ $parser_resource = xml_parser_create($encoding);
10432+ $parser = (int) $parser_resource;
10433+
10434+ $XML_RPC_xh = array();
10435+ $XML_RPC_xh[$parser] = array();
10436+
10437+ $XML_RPC_xh[$parser]['cm'] = 0;
10438+ $XML_RPC_xh[$parser]['isf'] = 0;
10439+ $XML_RPC_xh[$parser]['ac'] = '';
10440+ $XML_RPC_xh[$parser]['qt'] = '';
10441+ $XML_RPC_xh[$parser]['stack'] = array();
10442+ $XML_RPC_xh[$parser]['valuestack'] = array();
10443+
10444+ xml_parser_set_option($parser_resource, XML_OPTION_CASE_FOLDING, true);
10445+ xml_set_element_handler($parser_resource, 'XML_RPC_se', 'XML_RPC_ee');
10446+ xml_set_character_data_handler($parser_resource, 'XML_RPC_cd');
10447+
10448+ $hdrfnd = 0;
10449+ if ($this->debug) {
10450+ print "\n<pre>---GOT---\n";
10451+ print isset($_SERVER['SERVER_PROTOCOL']) ? htmlspecialchars($data) : $data;
10452+ print "\n---END---</pre>\n";
10453+ }
10454+
10455+ // See if response is a 200 or a 100 then a 200, else raise error.
10456+ // But only do this if we're using the HTTP protocol.
10457+ if (ereg('^HTTP', $data) &&
10458+ !ereg('^HTTP/[0-9\.]+ 200 ', $data) &&
10459+ !preg_match('@^HTTP/[0-9\.]+ 10[0-9]([A-Za-z ]+)?[\r\n]+HTTP/[0-9\.]+ 200@', $data))
10460+ {
10461+ $errstr = substr($data, 0, strpos($data, "\n") - 1);
10462+ error_log('HTTP error, got response: ' . $errstr);
10463+ $r = new XML_RPC_Response(0, $XML_RPC_err['http_error'],
10464+ $XML_RPC_str['http_error'] . ' (' .
10465+ $errstr . ')');
10466+ xml_parser_free($parser_resource);
10467+ return $r;
10468+ }
10469+
10470+ // gotta get rid of headers here
10471+ if (!$hdrfnd && ($brpos = strpos($data,"\r\n\r\n"))) {
10472+ $XML_RPC_xh[$parser]['ha'] = substr($data, 0, $brpos);
10473+ $data = substr($data, $brpos + 4);
10474+ $hdrfnd = 1;
10475+ }
10476+
10477+ /*
10478+ * be tolerant of junk after methodResponse
10479+ * (e.g. javascript automatically inserted by free hosts)
10480+ * thanks to Luca Mariano <luca.mariano@email.it>
10481+ */
10482+ $data = substr($data, 0, strpos($data, "</methodResponse>") + 17);
10483+
10484+ if (!xml_parse($parser_resource, $data, sizeof($data))) {
10485+ // thanks to Peter Kocks <peter.kocks@baygate.com>
10486+ if (xml_get_current_line_number($parser_resource) == 1) {
10487+ $errstr = 'XML error at line 1, check URL';
10488+ } else {
10489+ $errstr = sprintf('XML error: %s at line %d',
10490+ xml_error_string(xml_get_error_code($parser_resource)),
10491+ xml_get_current_line_number($parser_resource));
10492+ }
10493+ error_log($errstr);
10494+ $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'],
10495+ $XML_RPC_str['invalid_return']);
10496+ xml_parser_free($parser_resource);
10497+ return $r;
10498+ }
10499+
10500+ xml_parser_free($parser_resource);
10501+
10502+ if ($this->debug) {
10503+ print "\n<pre>---PARSED---\n";
10504+ var_dump($XML_RPC_xh[$parser]['value']);
10505+ print "---END---</pre>\n";
10506+ }
10507+
10508+ if ($XML_RPC_xh[$parser]['isf'] > 1) {
10509+ $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'],
10510+ $XML_RPC_str['invalid_return'].' '.$XML_RPC_xh[$parser]['isf_reason']);
10511+ } elseif (!is_object($XML_RPC_xh[$parser]['value'])) {
10512+ // then something odd has happened
10513+ // and it's time to generate a client side error
10514+ // indicating something odd went on
10515+ $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'],
10516+ $XML_RPC_str['invalid_return']);
10517+ } else {
10518+ $v = $XML_RPC_xh[$parser]['value'];
10519+ $allOK=1;
10520+ if ($XML_RPC_xh[$parser]['isf']) {
10521+ $f = $v->structmem('faultCode');
10522+ $fs = $v->structmem('faultString');
10523+ $r = new XML_RPC_Response($v, $f->scalarval(),
10524+ $fs->scalarval());
10525+ } else {
10526+ $r = new XML_RPC_Response($v);
10527+ }
10528+ }
10529+ $r->hdrs = split("\r?\n", $XML_RPC_xh[$parser]['ha'][1]);
10530+ return $r;
10531+ }
10532+}
10533+
10534+/**
10535+ * The methods and properties that represent data in XML RPC format
10536+ *
10537+ * @category Web Services
10538+ * @package XML_RPC
10539+ * @author Edd Dumbill <edd@usefulinc.com>
10540+ * @author Stig Bakken <stig@php.net>
10541+ * @author Martin Jansen <mj@php.net>
10542+ * @author Daniel Convissor <danielc@php.net>
10543+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
10544+ * @version Release: 1.4.0
10545+ * @link http://pear.php.net/package/XML_RPC
10546+ */
10547+class XML_RPC_Value extends XML_RPC_Base
10548+{
10549+ var $me = array();
10550+ var $mytype = 0;
10551+
10552+ /**
10553+ * @return void
10554+ */
10555+ function XML_RPC_Value($val = -1, $type = '')
10556+ {
10557+ global $XML_RPC_Types;
10558+ $this->me = array();
10559+ $this->mytype = 0;
10560+ if ($val != -1 || $type != '') {
10561+ if ($type == '') {
10562+ $type = 'string';
10563+ }
10564+ if (!array_key_exists($type, $XML_RPC_Types)) {
10565+ // XXX
10566+ // need some way to report this error
10567+ } elseif ($XML_RPC_Types[$type] == 1) {
10568+ $this->addScalar($val, $type);
10569+ } elseif ($XML_RPC_Types[$type] == 2) {
10570+ $this->addArray($val);
10571+ } elseif ($XML_RPC_Types[$type] == 3) {
10572+ $this->addStruct($val);
10573+ }
10574+ }
10575+ }
10576+
10577+ /**
10578+ * @return int returns 1 if successful or 0 if there are problems
10579+ */
10580+ function addScalar($val, $type = 'string')
10581+ {
10582+ global $XML_RPC_Types, $XML_RPC_Boolean;
10583+
10584+ if ($this->mytype == 1) {
10585+ $this->raiseError('Scalar can have only one value',
10586+ XML_RPC_ERROR_INVALID_TYPE);
10587+ return 0;
10588+ }
10589+ $typeof = $XML_RPC_Types[$type];
10590+ if ($typeof != 1) {
10591+ $this->raiseError("Not a scalar type (${typeof})",
10592+ XML_RPC_ERROR_INVALID_TYPE);
10593+ return 0;
10594+ }
10595+
10596+ if ($type == $XML_RPC_Boolean) {
10597+ if (strcasecmp($val, 'true') == 0
10598+ || $val == 1
10599+ || ($val == true && strcasecmp($val, 'false')))
10600+ {
10601+ $val = 1;
10602+ } else {
10603+ $val = 0;
10604+ }
10605+ }
10606+
10607+ if ($this->mytype == 2) {
10608+ // we're adding to an array here
10609+ $ar = $this->me['array'];
10610+ $ar[] = new XML_RPC_Value($val, $type);
10611+ $this->me['array'] = $ar;
10612+ } else {
10613+ // a scalar, so set the value and remember we're scalar
10614+ $this->me[$type] = $val;
10615+ $this->mytype = $typeof;
10616+ }
10617+ return 1;
10618+ }
10619+
10620+ /**
10621+ * @return int returns 1 if successful or 0 if there are problems
10622+ */
10623+ function addArray($vals)
10624+ {
10625+ global $XML_RPC_Types;
10626+ if ($this->mytype != 0) {
10627+ $this->raiseError(
10628+ 'Already initialized as a [' . $this->kindOf() . ']',
10629+ XML_RPC_ERROR_ALREADY_INITIALIZED);
10630+ return 0;
10631+ }
10632+ $this->mytype = $XML_RPC_Types['array'];
10633+ $this->me['array'] = $vals;
10634+ return 1;
10635+ }
10636+
10637+ /**
10638+ * @return int returns 1 if successful or 0 if there are problems
10639+ */
10640+ function addStruct($vals)
10641+ {
10642+ global $XML_RPC_Types;
10643+ if ($this->mytype != 0) {
10644+ $this->raiseError(
10645+ 'Already initialized as a [' . $this->kindOf() . ']',
10646+ XML_RPC_ERROR_ALREADY_INITIALIZED);
10647+ return 0;
10648+ }
10649+ $this->mytype = $XML_RPC_Types['struct'];
10650+ $this->me['struct'] = $vals;
10651+ return 1;
10652+ }
10653+
10654+ /**
10655+ * @return void
10656+ */
10657+ function dump($ar)
10658+ {
10659+ reset($ar);
10660+ foreach ($ar as $key => $val) {
10661+ echo "$key => $val<br />";
10662+ if ($key == 'array') {
10663+ foreach ($val as $key2 => $val2) {
10664+ echo "-- $key2 => $val2<br />";
10665+ }
10666+ }
10667+ }
10668+ }
10669+
10670+ /**
10671+ * @return string the data type of the current value
10672+ */
10673+ function kindOf()
10674+ {
10675+ switch ($this->mytype) {
10676+ case 3:
10677+ return 'struct';
10678+
10679+ case 2:
10680+ return 'array';
10681+
10682+ case 1:
10683+ return 'scalar';
10684+
10685+ default:
10686+ return 'undef';
10687+ }
10688+ }
10689+
10690+ /**
10691+ * @return string the data in XML format
10692+ */
10693+ function serializedata($typ, $val)
10694+ {
10695+ $rs = '';
10696+ global $XML_RPC_Types, $XML_RPC_Base64, $XML_RPC_String, $XML_RPC_Boolean;
10697+ if (!array_key_exists($typ, $XML_RPC_Types)) {
10698+ // XXX
10699+ // need some way to report this error
10700+ return;
10701+ }
10702+ switch ($XML_RPC_Types[$typ]) {
10703+ case 3:
10704+ // struct
10705+ $rs .= "<struct>\n";
10706+ reset($val);
10707+ foreach ($val as $key2 => $val2) {
10708+ $rs .= "<member><name>${key2}</name>\n";
10709+ $rs .= $this->serializeval($val2);
10710+ $rs .= "</member>\n";
10711+ }
10712+ $rs .= '</struct>';
10713+ break;
10714+
10715+ case 2:
10716+ // array
10717+ $rs .= "<array>\n<data>\n";
10718+ for ($i = 0; $i < sizeof($val); $i++) {
10719+ $rs .= $this->serializeval($val[$i]);
10720+ }
10721+ $rs .= "</data>\n</array>";
10722+ break;
10723+
10724+ case 1:
10725+ switch ($typ) {
10726+ case $XML_RPC_Base64:
10727+ $rs .= "<${typ}>" . base64_encode($val) . "</${typ}>";
10728+ break;
10729+ case $XML_RPC_Boolean:
10730+ $rs .= "<${typ}>" . ($val ? '1' : '0') . "</${typ}>";
10731+ break;
10732+ case $XML_RPC_String:
10733+ $rs .= "<${typ}>" . htmlspecialchars($val). "</${typ}>";
10734+ break;
10735+ default:
10736+ $rs .= "<${typ}>${val}</${typ}>";
10737+ }
10738+ }
10739+ return $rs;
10740+ }
10741+
10742+ /**
10743+ * @return string the data in XML format
10744+ */
10745+ function serialize()
10746+ {
10747+ return $this->serializeval($this);
10748+ }
10749+
10750+ /**
10751+ * @return string the data in XML format
10752+ */
10753+ function serializeval($o)
10754+ {
10755+ if (!is_object($o) || empty($o->me) || !is_array($o->me)) {
10756+ return '';
10757+ }
10758+ $ar = $o->me;
10759+ reset($ar);
10760+ list($typ, $val) = each($ar);
10761+ return '<value>' . $this->serializedata($typ, $val) . "</value>\n";
10762+ }
10763+
10764+ /**
10765+ * @return mixed the contents of the element requested
10766+ */
10767+ function structmem($m)
10768+ {
10769+ return $this->me['struct'][$m];
10770+ }
10771+
10772+ /**
10773+ * @return void
10774+ */
10775+ function structreset()
10776+ {
10777+ reset($this->me['struct']);
10778+ }
10779+
10780+ /**
10781+ * @return the key/value pair of the struct's current element
10782+ */
10783+ function structeach()
10784+ {
10785+ return each($this->me['struct']);
10786+ }
10787+
10788+ /**
10789+ * @return mixed the current value
10790+ */
10791+ function getval()
10792+ {
10793+ // UNSTABLE
10794+ global $XML_RPC_BOOLEAN, $XML_RPC_Base64;
10795+
10796+ reset($this->me);
10797+ $b = current($this->me);
10798+
10799+ // contributed by I Sofer, 2001-03-24
10800+ // add support for nested arrays to scalarval
10801+ // i've created a new method here, so as to
10802+ // preserve back compatibility
10803+
10804+ if (is_array($b)) {
10805+ foreach ($b as $id => $cont) {
10806+ $b[$id] = $cont->scalarval();
10807+ }
10808+ }
10809+
10810+ // add support for structures directly encoding php objects
10811+ if (is_object($b)) {
10812+ $t = get_object_vars($b);
10813+ foreach ($t as $id => $cont) {
10814+ $t[$id] = $cont->scalarval();
10815+ }
10816+ foreach ($t as $id => $cont) {
10817+ $b->$id = $cont;
10818+ }
10819+ }
10820+
10821+ // end contrib
10822+ return $b;
10823+ }
10824+
10825+ /**
10826+ * @return mixed
10827+ */
10828+ function scalarval()
10829+ {
10830+ global $XML_RPC_Boolean, $XML_RPC_Base64;
10831+ reset($this->me);
10832+ return current($this->me);
10833+ }
10834+
10835+ /**
10836+ * @return string
10837+ */
10838+ function scalartyp()
10839+ {
10840+ global $XML_RPC_I4, $XML_RPC_Int;
10841+ reset($this->me);
10842+ $a = key($this->me);
10843+ if ($a == $XML_RPC_I4) {
10844+ $a = $XML_RPC_Int;
10845+ }
10846+ return $a;
10847+ }
10848+
10849+ /**
10850+ * @return mixed the struct's current element
10851+ */
10852+ function arraymem($m)
10853+ {
10854+ return $this->me['array'][$m];
10855+ }
10856+
10857+ /**
10858+ * @return int the number of elements in the array
10859+ */
10860+ function arraysize()
10861+ {
10862+ reset($this->me);
10863+ list($a, $b) = each($this->me);
10864+ return sizeof($b);
10865+ }
10866+
10867+ /**
10868+ * Determines if the item submitted is an XML_RPC_Value object
10869+ *
10870+ * @param mixed $val the variable to be evaluated
10871+ *
10872+ * @return bool TRUE if the item is an XML_RPC_Value object
10873+ *
10874+ * @static
10875+ * @since Method available since Release 1.3.0
10876+ */
10877+ function isValue($val)
10878+ {
10879+ return (strtolower(get_class($val)) == 'xml_rpc_value');
10880+ }
10881+}
10882+
10883+/**
10884+ * Return an ISO8601 encoded string
10885+ *
10886+ * While timezones ought to be supported, the XML-RPC spec says:
10887+ *
10888+ * "Don't assume a timezone. It should be specified by the server in its
10889+ * documentation what assumptions it makes about timezones."
10890+ *
10891+ * This routine always assumes localtime unless $utc is set to 1, in which
10892+ * case UTC is assumed and an adjustment for locale is made when encoding.
10893+ *
10894+ * @return string the formatted date
10895+ */
10896+function XML_RPC_iso8601_encode($timet, $utc = 0)
10897+{
10898+ if (!$utc) {
10899+ $t = strftime('%Y%m%dT%H:%M:%S', $timet);
10900+ } else {
10901+ if (function_exists('gmstrftime')) {
10902+ // gmstrftime doesn't exist in some versions
10903+ // of PHP
10904+ $t = gmstrftime('%Y%m%dT%H:%M:%S', $timet);
10905+ } else {
10906+ $t = strftime('%Y%m%dT%H:%M:%S', $timet - date('Z'));
10907+ }
10908+ }
10909+ return $t;
10910+}
10911+
10912+/**
10913+ * Convert a datetime string into a Unix timestamp
10914+ *
10915+ * While timezones ought to be supported, the XML-RPC spec says:
10916+ *
10917+ * "Don't assume a timezone. It should be specified by the server in its
10918+ * documentation what assumptions it makes about timezones."
10919+ *
10920+ * This routine always assumes localtime unless $utc is set to 1, in which
10921+ * case UTC is assumed and an adjustment for locale is made when encoding.
10922+ *
10923+ * @return int the unix timestamp of the date submitted
10924+ */
10925+function XML_RPC_iso8601_decode($idate, $utc = 0)
10926+{
10927+ $t = 0;
10928+ if (ereg('([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})', $idate, $regs)) {
10929+ if ($utc) {
10930+ $t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
10931+ } else {
10932+ $t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
10933+ }
10934+ }
10935+ return $t;
10936+}
10937+
10938+/**
10939+ * Converts an XML_RPC_Value object into native PHP types
10940+ *
10941+ * @param object $XML_RPC_val the XML_RPC_Value object to decode
10942+ *
10943+ * @return mixed the PHP values
10944+ */
10945+function XML_RPC_decode($XML_RPC_val)
10946+{
10947+ $kind = $XML_RPC_val->kindOf();
10948+
10949+ if ($kind == 'scalar') {
10950+ return $XML_RPC_val->scalarval();
10951+
10952+ } elseif ($kind == 'array') {
10953+ $size = $XML_RPC_val->arraysize();
10954+ $arr = array();
10955+ for ($i = 0; $i < $size; $i++) {
10956+ $arr[] = XML_RPC_decode($XML_RPC_val->arraymem($i));
10957+ }
10958+ return $arr;
10959+
10960+ } elseif ($kind == 'struct') {
10961+ $XML_RPC_val->structreset();
10962+ $arr = array();
10963+ while (list($key, $value) = $XML_RPC_val->structeach()) {
10964+ $arr[$key] = XML_RPC_decode($value);
10965+ }
10966+ return $arr;
10967+ }
10968+}
10969+
10970+/**
10971+ * Converts native PHP types into an XML_RPC_Value object
10972+ *
10973+ * @param mixed $php_val the PHP value or variable you want encoded
10974+ *
10975+ * @return object the XML_RPC_Value object
10976+ */
10977+function XML_RPC_encode($php_val)
10978+{
10979+ global $XML_RPC_Boolean, $XML_RPC_Int, $XML_RPC_Double, $XML_RPC_String,
10980+ $XML_RPC_Array, $XML_RPC_Struct;
10981+
10982+ $type = gettype($php_val);
10983+ $XML_RPC_val = new XML_RPC_Value;
10984+
10985+ switch ($type) {
10986+ case 'array':
10987+ if (empty($php_val)) {
10988+ $XML_RPC_val->addArray($php_val);
10989+ break;
10990+ }
10991+ $tmp = array_diff(array_keys($php_val), range(0, count($php_val)-1));
10992+ if (empty($tmp)) {
10993+ $arr = array();
10994+ foreach ($php_val as $k => $v) {
10995+ $arr[$k] = XML_RPC_encode($v);
10996+ }
10997+ $XML_RPC_val->addArray($arr);
10998+ break;
10999+ }
11000+ // fall though if it's not an enumerated array
11001+
11002+ case 'object':
11003+ $arr = array();
11004+ foreach ($php_val as $k => $v) {
11005+ $arr[$k] = XML_RPC_encode($v);
11006+ }
11007+ $XML_RPC_val->addStruct($arr);
11008+ break;
11009+
11010+ case 'integer':
11011+ $XML_RPC_val->addScalar($php_val, $XML_RPC_Int);
11012+ break;
11013+
11014+ case 'double':
11015+ $XML_RPC_val->addScalar($php_val, $XML_RPC_Double);
11016+ break;
11017+
11018+ case 'string':
11019+ case 'NULL':
11020+ $XML_RPC_val->addScalar($php_val, $XML_RPC_String);
11021+ break;
11022+
11023+ case 'boolean':
11024+ // Add support for encoding/decoding of booleans, since they
11025+ // are supported in PHP
11026+ // by <G_Giunta_2001-02-29>
11027+ $XML_RPC_val->addScalar($php_val, $XML_RPC_Boolean);
11028+ break;
11029+
11030+ case 'unknown type':
11031+ default:
11032+ $XML_RPC_val = false;
11033+ }
11034+ return $XML_RPC_val;
11035+}
11036+
11037+/*
11038+ * Local variables:
11039+ * tab-width: 4
11040+ * c-basic-offset: 4
11041+ * c-hanging-comment-ender-p: nil
11042+ * End:
11043+ */
11044+
11045+?>
11046+
11047+
11048+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
11049+
11050+/**
11051+ * Server commands for our PHP implementation of the XML-RPC protocol
11052+ *
11053+ * This is a PEAR-ified version of Useful inc's XML-RPC for PHP.
11054+ * It has support for HTTP transport, proxies and authentication.
11055+ *
11056+ * PHP versions 4 and 5
11057+ *
11058+ * LICENSE: License is granted to use or modify this software
11059+ * ("XML-RPC for PHP") for commercial or non-commercial use provided the
11060+ * copyright of the author is preserved in any distributed or derivative work.
11061+ *
11062+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESSED OR
11063+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
11064+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11065+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
11066+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
11067+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11068+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11069+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11070+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
11071+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11072+ *
11073+ * @category Web Services
11074+ * @package XML_RPC
11075+ * @author Edd Dumbill <edd@usefulinc.com>
11076+ * @author Stig Bakken <stig@php.net>
11077+ * @author Martin Jansen <mj@php.net>
11078+ * @author Daniel Convissor <danielc@php.net>
11079+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
11080+ * @version CVS: $Id: Server.php,v 1.29 2005/08/14 20:25:35 danielc Exp $
11081+ * @link http://pear.php.net/package/XML_RPC
11082+ */
11083+
11084+
11085+/**
11086+ * Pull in the XML_RPC class
11087+ */
11088+require_once 'XML/RPC.php';
11089+
11090+
11091+/**
11092+ * signature for system.listMethods: return = array,
11093+ * parameters = a string or nothing
11094+ * @global array $GLOBALS['XML_RPC_Server_listMethods_sig']
11095+ */
11096+$GLOBALS['XML_RPC_Server_listMethods_sig'] = array(
11097+ array($GLOBALS['XML_RPC_Array'],
11098+ $GLOBALS['XML_RPC_String']
11099+ ),
11100+ array($GLOBALS['XML_RPC_Array'])
11101+);
11102+
11103+/**
11104+ * docstring for system.listMethods
11105+ * @global string $GLOBALS['XML_RPC_Server_listMethods_doc']
11106+ */
11107+$GLOBALS['XML_RPC_Server_listMethods_doc'] = 'This method lists all the'
11108+ . ' methods that the XML-RPC server knows how to dispatch';
11109+
11110+/**
11111+ * signature for system.methodSignature: return = array,
11112+ * parameters = string
11113+ * @global array $GLOBALS['XML_RPC_Server_methodSignature_sig']
11114+ */
11115+$GLOBALS['XML_RPC_Server_methodSignature_sig'] = array(
11116+ array($GLOBALS['XML_RPC_Array'],
11117+ $GLOBALS['XML_RPC_String']
11118+ )
11119+);
11120+
11121+/**
11122+ * docstring for system.methodSignature
11123+ * @global string $GLOBALS['XML_RPC_Server_methodSignature_doc']
11124+ */
11125+$GLOBALS['XML_RPC_Server_methodSignature_doc'] = 'Returns an array of known'
11126+ . ' signatures (an array of arrays) for the method name passed. If'
11127+ . ' no signatures are known, returns a none-array (test for type !='
11128+ . ' array to detect missing signature)';
11129+
11130+/**
11131+ * signature for system.methodHelp: return = string,
11132+ * parameters = string
11133+ * @global array $GLOBALS['XML_RPC_Server_methodHelp_sig']
11134+ */
11135+$GLOBALS['XML_RPC_Server_methodHelp_sig'] = array(
11136+ array($GLOBALS['XML_RPC_String'],
11137+ $GLOBALS['XML_RPC_String']
11138+ )
11139+);
11140+
11141+/**
11142+ * docstring for methodHelp
11143+ * @global string $GLOBALS['XML_RPC_Server_methodHelp_doc']
11144+ */
11145+$GLOBALS['XML_RPC_Server_methodHelp_doc'] = 'Returns help text if defined'
11146+ . ' for the method passed, otherwise returns an empty string';
11147+
11148+/**
11149+ * dispatch map for the automatically declared XML-RPC methods.
11150+ * @global array $GLOBALS['XML_RPC_Server_dmap']
11151+ */
11152+$GLOBALS['XML_RPC_Server_dmap'] = array(
11153+ 'system.listMethods' => array(
11154+ 'function' => 'XML_RPC_Server_listMethods',
11155+ 'signature' => $GLOBALS['XML_RPC_Server_listMethods_sig'],
11156+ 'docstring' => $GLOBALS['XML_RPC_Server_listMethods_doc']
11157+ ),
11158+ 'system.methodHelp' => array(
11159+ 'function' => 'XML_RPC_Server_methodHelp',
11160+ 'signature' => $GLOBALS['XML_RPC_Server_methodHelp_sig'],
11161+ 'docstring' => $GLOBALS['XML_RPC_Server_methodHelp_doc']
11162+ ),
11163+ 'system.methodSignature' => array(
11164+ 'function' => 'XML_RPC_Server_methodSignature',
11165+ 'signature' => $GLOBALS['XML_RPC_Server_methodSignature_sig'],
11166+ 'docstring' => $GLOBALS['XML_RPC_Server_methodSignature_doc']
11167+ )
11168+);
11169+
11170+/**
11171+ * @global string $GLOBALS['XML_RPC_Server_debuginfo']
11172+ */
11173+$GLOBALS['XML_RPC_Server_debuginfo'] = '';
11174+
11175+
11176+/**
11177+ * Lists all the methods that the XML-RPC server knows how to dispatch
11178+ *
11179+ * @return object a new XML_RPC_Response object
11180+ */
11181+function XML_RPC_Server_listMethods($server, $m)
11182+{
11183+ global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
11184+
11185+ $v = new XML_RPC_Value();
11186+ $outAr = array();
11187+ foreach ($server->dmap as $key => $val) {
11188+ $outAr[] = new XML_RPC_Value($key, 'string');
11189+ }
11190+ foreach ($XML_RPC_Server_dmap as $key => $val) {
11191+ $outAr[] = new XML_RPC_Value($key, 'string');
11192+ }
11193+ $v->addArray($outAr);
11194+ return new XML_RPC_Response($v);
11195+}
11196+
11197+/**
11198+ * Returns an array of known signatures (an array of arrays)
11199+ * for the given method
11200+ *
11201+ * If no signatures are known, returns a none-array
11202+ * (test for type != array to detect missing signature)
11203+ *
11204+ * @return object a new XML_RPC_Response object
11205+ */
11206+function XML_RPC_Server_methodSignature($server, $m)
11207+{
11208+ global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
11209+
11210+ $methName = $m->getParam(0);
11211+ $methName = $methName->scalarval();
11212+ if (strpos($methName, 'system.') === 0) {
11213+ $dmap = $XML_RPC_Server_dmap;
11214+ $sysCall = 1;
11215+ } else {
11216+ $dmap = $server->dmap;
11217+ $sysCall = 0;
11218+ }
11219+ // print "<!-- ${methName} -->\n";
11220+ if (isset($dmap[$methName])) {
11221+ if ($dmap[$methName]['signature']) {
11222+ $sigs = array();
11223+ $thesigs = $dmap[$methName]['signature'];
11224+ for ($i = 0; $i < sizeof($thesigs); $i++) {
11225+ $cursig = array();
11226+ $inSig = $thesigs[$i];
11227+ for ($j = 0; $j < sizeof($inSig); $j++) {
11228+ $cursig[] = new XML_RPC_Value($inSig[$j], 'string');
11229+ }
11230+ $sigs[] = new XML_RPC_Value($cursig, 'array');
11231+ }
11232+ $r = new XML_RPC_Response(new XML_RPC_Value($sigs, 'array'));
11233+ } else {
11234+ $r = new XML_RPC_Response(new XML_RPC_Value('undef', 'string'));
11235+ }
11236+ } else {
11237+ $r = new XML_RPC_Response(0, $XML_RPC_err['introspect_unknown'],
11238+ $XML_RPC_str['introspect_unknown']);
11239+ }
11240+ return $r;
11241+}
11242+
11243+/**
11244+ * Returns help text if defined for the method passed, otherwise returns
11245+ * an empty string
11246+ *
11247+ * @return object a new XML_RPC_Response object
11248+ */
11249+function XML_RPC_Server_methodHelp($server, $m)
11250+{
11251+ global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
11252+
11253+ $methName = $m->getParam(0);
11254+ $methName = $methName->scalarval();
11255+ if (strpos($methName, 'system.') === 0) {
11256+ $dmap = $XML_RPC_Server_dmap;
11257+ $sysCall = 1;
11258+ } else {
11259+ $dmap = $server->dmap;
11260+ $sysCall = 0;
11261+ }
11262+
11263+ if (isset($dmap[$methName])) {
11264+ if ($dmap[$methName]['docstring']) {
11265+ $r = new XML_RPC_Response(new XML_RPC_Value($dmap[$methName]['docstring']),
11266+ 'string');
11267+ } else {
11268+ $r = new XML_RPC_Response(new XML_RPC_Value('', 'string'));
11269+ }
11270+ } else {
11271+ $r = new XML_RPC_Response(0, $XML_RPC_err['introspect_unknown'],
11272+ $XML_RPC_str['introspect_unknown']);
11273+ }
11274+ return $r;
11275+}
11276+
11277+/**
11278+ * @return void
11279+ */
11280+function XML_RPC_Server_debugmsg($m)
11281+{
11282+ global $XML_RPC_Server_debuginfo;
11283+ $XML_RPC_Server_debuginfo = $XML_RPC_Server_debuginfo . $m . "\n";
11284+}
11285+
11286+
11287+/**
11288+ * A server for receiving and replying to XML RPC requests
11289+ *
11290+ * <code>
11291+ * $server = new XML_RPC_Server(
11292+ * array(
11293+ * 'isan8' =>
11294+ * array(
11295+ * 'function' => 'is_8',
11296+ * 'signature' =>
11297+ * array(
11298+ * array('boolean', 'int'),
11299+ * array('boolean', 'int', 'boolean'),
11300+ * array('boolean', 'string'),
11301+ * array('boolean', 'string', 'boolean'),
11302+ * ),
11303+ * 'docstring' => 'Is the value an 8?'
11304+ * ),
11305+ * ),
11306+ * 1,
11307+ * 0
11308+ * );
11309+ * </code>
11310+ *
11311+ * @category Web Services
11312+ * @package XML_RPC
11313+ * @author Edd Dumbill <edd@usefulinc.com>
11314+ * @author Stig Bakken <stig@php.net>
11315+ * @author Martin Jansen <mj@php.net>
11316+ * @author Daniel Convissor <danielc@php.net>
11317+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
11318+ * @version Release: 1.4.0
11319+ * @link http://pear.php.net/package/XML_RPC
11320+ */
11321+class XML_RPC_Server
11322+{
11323+ /**
11324+ * The dispatch map, listing the methods this server provides.
11325+ * @var array
11326+ */
11327+ var $dmap = array();
11328+
11329+ /**
11330+ * The present response's encoding
11331+ * @var string
11332+ * @see XML_RPC_Message::getEncoding()
11333+ */
11334+ var $encoding = '';
11335+
11336+ /**
11337+ * Debug mode (0 = off, 1 = on)
11338+ * @var integer
11339+ */
11340+ var $debug = 0;
11341+
11342+ /**
11343+ * The response's HTTP headers
11344+ * @var string
11345+ */
11346+ var $server_headers = '';
11347+
11348+ /**
11349+ * The response's XML payload
11350+ * @var string
11351+ */
11352+ var $server_payload = '';
11353+
11354+
11355+ /**
11356+ * Constructor for the XML_RPC_Server class
11357+ *
11358+ * @param array $dispMap the dispatch map. An associative array
11359+ * explaining each function. The keys of the main
11360+ * array are the procedure names used by the
11361+ * clients. The value is another associative array
11362+ * that contains up to three elements:
11363+ * + The 'function' element's value is the name
11364+ * of the function or method that gets called.
11365+ * To define a class' method: 'class::method'.
11366+ * + The 'signature' element (optional) is an
11367+ * array describing the return values and
11368+ * parameters
11369+ * + The 'docstring' element (optional) is a
11370+ * string describing what the method does
11371+ * @param int $serviceNow should the HTTP response be sent now?
11372+ * (1 = yes, 0 = no)
11373+ * @param int $debug should debug output be displayed?
11374+ * (1 = yes, 0 = no)
11375+ *
11376+ * @return void
11377+ */
11378+ function XML_RPC_Server($dispMap, $serviceNow = 1, $debug = 0)
11379+ {
11380+ global $HTTP_RAW_POST_DATA;
11381+
11382+ if ($debug) {
11383+ $this->debug = 1;
11384+ } else {
11385+ $this->debug = 0;
11386+ }
11387+
11388+ $this->dmap = $dispMap;
11389+
11390+ if ($serviceNow) {
11391+ $this->service();
11392+ } else {
11393+ $this->createServerPayload();
11394+ $this->createServerHeaders();
11395+ }
11396+ }
11397+
11398+ /**
11399+ * @return string the debug information if debug debug mode is on
11400+ */
11401+ function serializeDebug()
11402+ {
11403+ global $XML_RPC_Server_debuginfo, $HTTP_RAW_POST_DATA;
11404+
11405+ if ($this->debug) {
11406+ XML_RPC_Server_debugmsg('vvv POST DATA RECEIVED BY SERVER vvv' . "\n"
11407+ . $HTTP_RAW_POST_DATA
11408+ . "\n" . '^^^ END POST DATA ^^^');
11409+ }
11410+
11411+ if ($XML_RPC_Server_debuginfo != '') {
11412+ return "<!-- PEAR XML_RPC SERVER DEBUG INFO:\n\n"
11413+ . preg_replace('/-(?=-)/', '- ', $XML_RPC_Server_debuginfo)
11414+ . "-->\n";
11415+ } else {
11416+ return '';
11417+ }
11418+ }
11419+
11420+ /**
11421+ * Sends the response
11422+ *
11423+ * The encoding and content-type are determined by
11424+ * XML_RPC_Message::getEncoding()
11425+ *
11426+ * @return void
11427+ *
11428+ * @uses XML_RPC_Server::createServerPayload(),
11429+ * XML_RPC_Server::createServerHeaders()
11430+ */
11431+ function service()
11432+ {
11433+ if (!$this->server_payload) {
11434+ $this->createServerPayload();
11435+ }
11436+ if (!$this->server_headers) {
11437+ $this->createServerHeaders();
11438+ }
11439+ header($this->server_headers);
11440+ print $this->server_payload;
11441+ }
11442+
11443+ /**
11444+ * Generates the payload and puts it in the $server_payload property
11445+ *
11446+ * @return void
11447+ *
11448+ * @uses XML_RPC_Server::parseRequest(), XML_RPC_Server::$encoding,
11449+ * XML_RPC_Response::serialize(), XML_RPC_Server::serializeDebug()
11450+ */
11451+ function createServerPayload()
11452+ {
11453+ $r = $this->parseRequest();
11454+ $this->server_payload = '<?xml version="1.0" encoding="'
11455+ . $this->encoding . '"?>' . "\n"
11456+ . $this->serializeDebug()
11457+ . $r->serialize();
11458+ }
11459+
11460+ /**
11461+ * Determines the HTTP headers and puts them in the $server_headers
11462+ * property
11463+ *
11464+ * @return boolean TRUE if okay, FALSE if $server_payload isn't set.
11465+ *
11466+ * @uses XML_RPC_Server::createServerPayload(),
11467+ * XML_RPC_Server::$server_headers
11468+ */
11469+ function createServerHeaders()
11470+ {
11471+ if (!$this->server_payload) {
11472+ return false;
11473+ }
11474+ $this->server_headers = 'Content-Length: '
11475+ . strlen($this->server_payload) . "\r\n"
11476+ . 'Content-Type: text/xml;'
11477+ . ' charset=' . $this->encoding;
11478+ return true;
11479+ }
11480+
11481+ /**
11482+ * @return array
11483+ */
11484+ function verifySignature($in, $sig)
11485+ {
11486+ for ($i = 0; $i < sizeof($sig); $i++) {
11487+ // check each possible signature in turn
11488+ $cursig = $sig[$i];
11489+ if (sizeof($cursig) == $in->getNumParams() + 1) {
11490+ $itsOK = 1;
11491+ for ($n = 0; $n < $in->getNumParams(); $n++) {
11492+ $p = $in->getParam($n);
11493+ // print "<!-- $p -->\n";
11494+ if ($p->kindOf() == 'scalar') {
11495+ $pt = $p->scalartyp();
11496+ } else {
11497+ $pt = $p->kindOf();
11498+ }
11499+ // $n+1 as first type of sig is return type
11500+ if ($pt != $cursig[$n+1]) {
11501+ $itsOK = 0;
11502+ $pno = $n+1;
11503+ $wanted = $cursig[$n+1];
11504+ $got = $pt;
11505+ break;
11506+ }
11507+ }
11508+ if ($itsOK) {
11509+ return array(1);
11510+ }
11511+ }
11512+ }
11513+ if (isset($wanted)) {
11514+ return array(0, "Wanted ${wanted}, got ${got} at param ${pno}");
11515+ } else {
11516+ $allowed = array();
11517+ foreach ($sig as $val) {
11518+ end($val);
11519+ $allowed[] = key($val);
11520+ }
11521+ $allowed = array_unique($allowed);
11522+ $last = count($allowed) - 1;
11523+ if ($last > 0) {
11524+ $allowed[$last] = 'or ' . $allowed[$last];
11525+ }
11526+ return array(0,
11527+ 'Signature permits ' . implode(', ', $allowed)
11528+ . ' parameters but the request had '
11529+ . $in->getNumParams());
11530+ }
11531+ }
11532+
11533+ /**
11534+ * @return object a new XML_RPC_Response object
11535+ *
11536+ * @uses XML_RPC_Message::getEncoding(), XML_RPC_Server::$encoding
11537+ */
11538+ function parseRequest($data = '')
11539+ {
11540+ global $XML_RPC_xh, $HTTP_RAW_POST_DATA,
11541+ $XML_RPC_err, $XML_RPC_str, $XML_RPC_errxml,
11542+ $XML_RPC_defencoding, $XML_RPC_Server_dmap;
11543+
11544+ if ($data == '') {
11545+ $data = $HTTP_RAW_POST_DATA;
11546+ }
11547+
11548+ $this->encoding = XML_RPC_Message::getEncoding($data);
11549+ $parser_resource = xml_parser_create($this->encoding);
11550+ $parser = (int) $parser_resource;
11551+
11552+ $XML_RPC_xh[$parser] = array();
11553+ $XML_RPC_xh[$parser]['cm'] = 0;
11554+ $XML_RPC_xh[$parser]['isf'] = 0;
11555+ $XML_RPC_xh[$parser]['params'] = array();
11556+ $XML_RPC_xh[$parser]['method'] = '';
11557+ $XML_RPC_xh[$parser]['stack'] = array();
11558+ $XML_RPC_xh[$parser]['valuestack'] = array();
11559+
11560+ $plist = '';
11561+
11562+ // decompose incoming XML into request structure
11563+
11564+ xml_parser_set_option($parser_resource, XML_OPTION_CASE_FOLDING, true);
11565+ xml_set_element_handler($parser_resource, 'XML_RPC_se', 'XML_RPC_ee');
11566+ xml_set_character_data_handler($parser_resource, 'XML_RPC_cd');
11567+ if (!xml_parse($parser_resource, $data, 1)) {
11568+ // return XML error as a faultCode
11569+ $r = new XML_RPC_Response(0,
11570+ $XML_RPC_errxml+xml_get_error_code($parser_resource),
11571+ sprintf('XML error: %s at line %d',
11572+ xml_error_string(xml_get_error_code($parser_resource)),
11573+ xml_get_current_line_number($parser_resource)));
11574+ xml_parser_free($parser_resource);
11575+ } elseif ($XML_RPC_xh[$parser]['isf']>1) {
11576+ $r = new XML_RPC_Response(0,
11577+ $XML_RPC_err['invalid_request'],
11578+ $XML_RPC_str['invalid_request']
11579+ . ': '
11580+ . $XML_RPC_xh[$parser]['isf_reason']);
11581+ xml_parser_free($parser_resource);
11582+ } else {
11583+ xml_parser_free($parser_resource);
11584+ $m = new XML_RPC_Message($XML_RPC_xh[$parser]['method']);
11585+ // now add parameters in
11586+ for ($i = 0; $i < sizeof($XML_RPC_xh[$parser]['params']); $i++) {
11587+ // print '<!-- ' . $XML_RPC_xh[$parser]['params'][$i]. "-->\n";
11588+ $plist .= "$i - " . var_export($XML_RPC_xh[$parser]['params'][$i], true) . " \n";
11589+ $m->addParam($XML_RPC_xh[$parser]['params'][$i]);
11590+ }
11591+ XML_RPC_Server_debugmsg($plist);
11592+
11593+ // now to deal with the method
11594+ $methName = $XML_RPC_xh[$parser]['method'];
11595+ if (strpos($methName, 'system.') === 0) {
11596+ $dmap = $XML_RPC_Server_dmap;
11597+ $sysCall = 1;
11598+ } else {
11599+ $dmap = $this->dmap;
11600+ $sysCall = 0;
11601+ }
11602+
11603+ if (isset($dmap[$methName]['function'])
11604+ && is_string($dmap[$methName]['function'])
11605+ && strpos($dmap[$methName]['function'], '::') !== false)
11606+ {
11607+ $dmap[$methName]['function'] =
11608+ explode('::', $dmap[$methName]['function']);
11609+ }
11610+
11611+ if (isset($dmap[$methName]['function'])
11612+ && is_callable($dmap[$methName]['function']))
11613+ {
11614+ // dispatch if exists
11615+ if (isset($dmap[$methName]['signature'])) {
11616+ $sr = $this->verifySignature($m,
11617+ $dmap[$methName]['signature'] );
11618+ }
11619+ if (!isset($dmap[$methName]['signature']) || $sr[0]) {
11620+ // if no signature or correct signature
11621+ if ($sysCall) {
11622+ $r = call_user_func($dmap[$methName]['function'], $this, $m);
11623+ } else {
11624+ $r = call_user_func($dmap[$methName]['function'], $m);
11625+ }
11626+ if (!is_a($r, 'XML_RPC_Response')) {
11627+ $r = new XML_RPC_Response(0, $XML_RPC_err['not_response_object'],
11628+ $XML_RPC_str['not_response_object']);
11629+ }
11630+ } else {
11631+ $r = new XML_RPC_Response(0, $XML_RPC_err['incorrect_params'],
11632+ $XML_RPC_str['incorrect_params']
11633+ . ': ' . $sr[1]);
11634+ }
11635+ } else {
11636+ // else prepare error response
11637+ $r = new XML_RPC_Response(0, $XML_RPC_err['unknown_method'],
11638+ $XML_RPC_str['unknown_method']);
11639+ }
11640+ }
11641+ return $r;
11642+ }
11643+
11644+ /**
11645+ * Echos back the input packet as a string value
11646+ *
11647+ * @return void
11648+ *
11649+ * Useful for debugging.
11650+ */
11651+ function echoInput()
11652+ {
11653+ global $HTTP_RAW_POST_DATA;
11654+
11655+ $r = new XML_RPC_Response(0);
11656+ $r->xv = new XML_RPC_Value("'Aha said I: '" . $HTTP_RAW_POST_DATA, 'string');
11657+ print $r->serialize();
11658+ }
11659+}
11660+
11661+/*
11662+ * Local variables:
11663+ * tab-width: 4
11664+ * c-basic-offset: 4
11665+ * c-hanging-comment-ender-p: nil
11666+ * End:
11667+ */
11668+
11669+?>
11670+
11671+<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/package-1.0">
11672+<package version="1.0" packagerversion="1.4.0a12">
11673+ <name>XML_RPC</name>
11674+ <summary>PHP implementation of the XML-RPC protocol</summary>
11675+ <description>A PEAR-ified version of Useful Inc's XML-RPC for PHP.
11676+
11677+It has support for HTTP/HTTPS transport, proxies and authentication.
11678+ </description>
11679+ <maintainers>
11680+ <maintainer>
11681+ <user>ssb</user>
11682+ <name>Stig Bakken</name>
11683+ <email>stig@php.net</email>
11684+ <role>lead</role>
11685+ </maintainer>
11686+ <maintainer>
11687+ <user>danielc</user>
11688+ <name>Daniel Convissor</name>
11689+ <email>danielc@php.net</email>
11690+ <role>lead</role>
11691+ </maintainer>
11692+ </maintainers>
11693+ <release>
11694+ <version>1.4.0</version>
11695+ <date>2005-08-14</date>
11696+ <license>PHP License</license>
11697+ <state>stable</state>
11698+ <notes>* MAJOR SECURITY FIX: eliminate use of eval().
11699+* 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.
11700+ </notes>
11701+ <filelist>
11702+ <file role="php" baseinstalldir="XML" name="RPC.php">
11703+ <replace from="@package_version@" to="version" type="package-info"/>
11704+ </file>
11705+ <file role="php" baseinstalldir="XML/RPC" name="Server.php">
11706+ <replace from="@package_version@" to="version" type="package-info"/>
11707+ </file>
11708+ <file role="php" baseinstalldir="XML/RPC" name="Dump.php">
11709+ <replace from="@package_version@" to="version" type="package-info"/>
11710+ </file>
11711+ <file role="test" name="tests/protoport.php">
11712+ <replace from="@package_version@" to="version" type="package-info"/>
11713+ </file>
11714+ <file role="test" name="tests/test_Dump.php">
11715+ <replace from="@package_version@" to="version" type="package-info"/>
11716+ </file>
11717+ </filelist>
11718+ </release>
11719+ <changelog>
11720+ <release>
11721+ <version>1.3.3</version>
11722+ <date>2005-07-15</date>
11723+ <state>stable</state>
11724+ <notes>* Eliminate memory leak by resetting $XML_RPC_xh each time parseResponse() is called. Bug 4780.
11725+* Using socket_set_timeout() because stream_set_timeout() was introduced in 4.3.0, but we need to support 4.2.0. Bug 4805.
11726+ </notes>
11727+ </release>
11728+ <release>
11729+ <version>1.3.2</version>
11730+ <date>2005-07-07</date>
11731+ <state>stable</state>
11732+ <notes>* Eliminate path disclosure vulnerabilities by suppressing error messages when eval()'ing.
11733+* Eliminate path disclosure vulnerability by catching bogus parameters submitted to XML_RPC_Value::serializeval().
11734+* 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.
11735+* 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.
11736+ </notes>
11737+ </release>
11738+ <release>
11739+ <version>1.3.1</version>
11740+ <date>2005-06-29</date>
11741+ <state>stable</state>
11742+ <notes>* Security fix. Update highly recommended!
11743+ </notes>
11744+ </release>
11745+ <release>
11746+ <version>1.3.0</version>
11747+ <date>2005-06-13</date>
11748+ <state>stable</state>
11749+ <notes>* Stable release. See earlier releases for changes since 1.2.2.
11750+ </notes>
11751+ </release>
11752+ <release>
11753+ <version>1.3.0RC3</version>
11754+ <date>2005-05-10</date>
11755+ <state>beta</state>
11756+ <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.
11757+* XML_RPC_Message::getParam() now returns an XML_RPC_Response object upon error. Changed from Release 1.3.0RC2.
11758+* Add the XML_RPC_Value::isValue() method. For testing if an item is an XML_RPC_Value object.
11759+* 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.
11760+* Improve cross-platform operation by using PEAR::loadExtension() instead of dl().
11761+* Use &lt;br /&gt; instead of &lt;br&gt; in XML_RPC_Value::dump().
11762+ </notes>
11763+ </release>
11764+ <release>
11765+ <version>1.3.0RC2</version>
11766+ <date>2005-05-05</date>
11767+ <state>beta</state>
11768+ <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.
11769+* Handle improper requests to XML_RPC_Server::verifySignature(). Bug 4231.
11770+* Try to allow HTTP 100 responses if followed by a 200 response. Bug 4116.
11771+* Help Delphi users by making RPCMETHODNAME an alias for METHODNAME. Request 4205.
11772+ </notes>
11773+ </release>
11774+ <release>
11775+ <version>1.3.0RC1</version>
11776+ <date>2005-04-07</date>
11777+ <state>beta</state>
11778+ <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.
11779+* Add Fault Code 6: &quot;The requested method didn't return an XML_RPC_Response object.&quot; Request 4032.
11780+* Add the createServerPayload() and createServerHeaders() methods and the $server_payload and $server_headers properties. Request 3121.
11781+* 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.
11782+* Convert the parser handle to an integer before using it as an index for $XML_RPC_xh[$parser]. Reduces E_STRICT notices. Bug 3782.
11783+* Add createHeaders() method and $headers property to XML_RPC_Client to make testing easier.
11784+ </notes>
11785+ </release>
11786+ <release>
11787+ <version>1.2.2</version>
11788+ <date>2005-03-07</date>
11789+ <state>stable</state>
11790+ <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.
11791+ </notes>
11792+ </release>
11793+ <release>
11794+ <version>1.2.1</version>
11795+ <date>2005-03-01</date>
11796+ <state>stable</state>
11797+ <notes>* Add isset() check before examining the dispatch map. Bug 3658.
11798+ </notes>
11799+ </release>
11800+ <release>
11801+ <version>1.2.0</version>
11802+ <date>2005-02-27</date>
11803+ <state>stable</state>
11804+ <notes>* Provide the &quot;stable&quot; release.
11805+* Add package2.xml for compatibility with PEAR 1.4.0.
11806+* For changes since 1.1.0, see the changelogs for the various RC releases.
11807+ </notes>
11808+ </release>
11809+ <release>
11810+ <version>1.2.0RC7</version>
11811+ <date>2005-02-22</date>
11812+ <state>beta</state>
11813+ <notes>* Add the setSendEncoding() method and $send_encoding
11814+ property to XML_RPC_Message. Request 3537.
11815+* Allow class methods to be mapped using either syntax:
11816+ 'function' =&gt; 'hello::sayHello',
11817+ or
11818+ 'function' =&gt; array('hello', 'sayhello'),
11819+ Bug 3363.
11820+* Use 8192 instead of 32768 for bytes in fread()
11821+ in parseResponseFile(). Bug 3340.
11822+ </notes>
11823+ </release>
11824+ <release>
11825+ <version>1.2.0RC6</version>
11826+ <date>2005-01-25</date>
11827+ <state>beta</state>
11828+ <notes>* Don't put the protocol in the Host field of the POST data. (danielc)
11829+ </notes>
11830+ </release>
11831+ <release>
11832+ <version>1.2.0RC5</version>
11833+ <date>2005-01-24</date>
11834+ <state>beta</state>
11835+ <notes>* If $port is 443 but a protocol isn't specified in $server, assume ssl:// is the protocol.
11836+ </notes>
11837+ </release>
11838+ <release>
11839+ <version>1.2.0RC4</version>
11840+ <date>2005-01-24</date>
11841+ <state>beta</state>
11842+ <notes>* When a connection attempt fails, have the method return 0. (danielc)
11843+* Move the protocol/port checking/switching and the property settings from sendPayloadHTTP10() to the XML_RPC_Client constructor. (danielc)
11844+* Add tests for setting the client properties. (danielc)
11845+* Remove $GLOBALS['XML_RPC_twoslash'] since it's not used. (danielc)
11846+* Bundle the tests with the package. (danielc)
11847+ </notes>
11848+ </release>
11849+ <release>
11850+ <version>1.2.0RC3</version>
11851+ <date>2005-01-19</date>
11852+ <state>beta</state>
11853+ <notes>* ssl uses port 443, not 445.
11854+ </notes>
11855+ </release>
11856+ <release>
11857+ <version>1.2.0RC2</version>
11858+ <date>2005-01-11</date>
11859+ <state>beta</state>
11860+ <notes>* Handle ssl:// in the $server string. (danielc)
11861+* Also default to port 445 for ssl:// requests as well. (danielc)
11862+* Enhance debugging in the server. (danielc)
11863+ </notes>
11864+ </release>
11865+ <release>
11866+ <version>1.2.0RC1</version>
11867+ <date>2004-12-30</date>
11868+ <state>beta</state>
11869+ <notes>* Make things work with SSL. Bug 2489. (nkukard lbsd net)
11870+* Allow array function callbacks (Matt Kane)
11871+* Some minor speed-ups (Matt Kane)
11872+* Add Dump.php to the package (Christian Weiske)
11873+* Replace all line endings with \r\n. Had only done replacements on \n. Bug 2521. (danielc)
11874+* Silence fsockopen() errors. Bug 1714. (danielc)
11875+* Encode empty arrays as an array. Bug 1493. (danielc)
11876+* Eliminate undefined index notice when submitting empty arrays to XML_RPC_Encode(). Bug 1819. (danielc)
11877+* Speed up check for enumerated arrays in XML_RPC_Encode(). (danielc)
11878+* Prepend &quot;XML_RPC_&quot; to ERROR_NON_NUMERIC_FOUND, eliminating problem when eval()'ing error messages. (danielc)
11879+* Use XML_RPC_Base::raiseError() instead of PEAR::raiseError() in XML_RPC_ee() because PEAR.php is lazy loaded. (danielc)
11880+* Allow raiseError() to be called statically. (danielc)
11881+* Stop double escaping of character entities. Bug 987. (danielc)
11882+ NOTICE: the following have been removed:
11883+ * XML_RPC_dh()
11884+ * $GLOBALS['XML_RPC_entities']
11885+ * XML_RPC_entity_decode()
11886+ * XML_RPC_lookup_entity()
11887+* Determine the XML's encoding via the encoding attribute in the XML declaration. Bug 52. (danielc)
11888+ </notes>
11889+ </release>
11890+ <release>
11891+ <version>1.1.0</version>
11892+ <date>2004-03-15</date>
11893+ <state>stable</state>
11894+ <notes>* Added support for sequential arrays to XML_RPC_encode() (mroch)
11895+* Cleaned up new XML_RPC_encode() changes a bit (mroch, pierre)
11896+* Remove &quot;require_once 'PEAR.php'&quot;, include only when needed to raise an error
11897+* Replace echo and error_log() with raiseError() (mroch)
11898+* Make all classes extend XML_RPC_Base, which will handle common functions (mroch)
11899+* be tolerant of junk after methodResponse (Luca Mariano, mroch)
11900+* Silent notice even in the error log (pierre)
11901+* fix include of shared xml extension on win32 (pierre)
11902+ </notes>
11903+ </release>
11904+ <release>
11905+ <version>1.0.4</version>
11906+ <date>2002-10-02</date>
11907+ <state>stable</state>
11908+ <notes>* added HTTP proxy authorization support (thanks to Arnaud Limbourg)
11909+ </notes>
11910+ </release>
11911+ <release>
11912+ <version>1.0.3</version>
11913+ <date>2002-05-19</date>
11914+ <state>stable</state>
11915+ <notes>* fix bug when parsing responses with boolean types
11916+ </notes>
11917+ </release>
11918+ <release>
11919+ <version>1.0.2</version>
11920+ <date>2002-04-16</date>
11921+ <state>stable</state>
11922+ <notes>* E_ALL fixes
11923+* fix HTTP response header parsing
11924+ </notes>
11925+ </release>
11926+ <release>
11927+ <version>1.0.1</version>
11928+ <date>2001-09-25</date>
11929+ <state>stable</state>
11930+ <notes>This is a PEAR-ified version of Useful Inc's 1.0.1 release.
11931+Includes an urgent security fix identified by Dan Libby &lt;dan@libby.com&gt;.
11932+ </notes>
11933+ </release>
11934+ </changelog>
11935+</package>
11936+
11937\ Kein Zeilenumbruch am Dateiende.
11938diff -Nura php-4.4.0/php.ini-dist hardening-patch-4.4.0-0.4.2/php.ini-dist
11939--- php-4.4.0/php.ini-dist 2005-04-28 15:14:45.000000000 +0200
11940+++ hardening-patch-4.4.0-0.4.2/php.ini-dist 2005-09-07 18:40:29.105945520 +0200
11941@@ -1112,6 +1112,185 @@
11942 ;exif.decode_jis_motorola = JIS
11943 ;exif.decode_jis_intel = JIS
11944
11945+[hardening-patch]
11946+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11947+; Hardening-Patch's logging ;
11948+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11949+
11950+;
11951+; hphp.log.syslog - Configures level for alerts reported through syslog
11952+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
11953+; hphp.log.script - Configures level for alerts reported through external script
11954+;
11955+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
11956+; Or each number up to get desired Hardening-Patch's reporting level
11957+;
11958+; S_ALL - All alerts
11959+; S_MEMORY - All canary violations and the safe unlink protection use this class
11960+; S_VARS - All variable filters trigger this class
11961+; S_FILES - All violation of uploaded files filter use this class
11962+; S_INCLUDE - The protection against malicious include filenames use this class
11963+; S_SQL - Failed SQL queries in MySQL are logged with this class
11964+; S_EXECUTOR - The execution depth protection uses this logging class
11965+; S_MISC - All other log messages (f.e. format string protection) use this class
11966+;
11967+; Example:
11968+;
11969+; - Report all alerts (except memory alerts) to the SAPI errorlog,
11970+; memory alerts through syslog and SQL+Include alerts fo the script
11971+;
11972+;hphp.log.syslog = S_MEMORY
11973+;hphp.log.sapi = S_ALL & ~S_MEMORY
11974+;hphp.log.script = S_INCLUDE | S_SQL
11975+;
11976+; Syslog logging:
11977+;
11978+; - Facility configuration: one of the following facilities
11979+;
11980+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
11981+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
11982+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
11983+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
11984+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
11985+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
11986+; LOG_PERROR
11987+;
11988+; - Priority configuration: one of the followinf priorities
11989+;
11990+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
11991+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
11992+;
11993+hphp.log.syslog.priority = LOG_ALERT
11994+hphp.log.syslog.facility = LOG_USER
11995+;
11996+; Script logging:
11997+;
11998+;hphp.log.script.name = /home/hphp/log_script
11999+;
12000+; Alert configuration:
12001+;
12002+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
12003+;
12004+;hphp.log.use-x-forwarded-for = On
12005+;
12006+
12007+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12008+; Hardening-Patch's Executor options ;
12009+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12010+
12011+; Execution depth limit
12012+;hphp.executor.max_depth = 8000
12013+
12014+; White-/blacklist for function calls during normal execution
12015+;hphp.executor.func.whitelist = ord,chr
12016+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
12017+
12018+; White-/blacklist for function calls during eval() execution
12019+;hphp.executor.eval.whitelist = ord,chr
12020+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
12021+
12022+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12023+; Hardening-Patch's REQUEST variable filters ;
12024+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12025+
12026+; Limits the number of REQUEST variables
12027+hphp.request.max_vars = 200
12028+
12029+; Limits the length of variable names (without indices)
12030+hphp.request.max_varname_length = 64
12031+
12032+; Limits the length of complete variable names (with indices)
12033+hphp.request.max_totalname_length = 256
12034+
12035+; Limits the length of array indices
12036+hphp.request.max_array_index_length = 64
12037+
12038+; Limits the depth of arrays
12039+hphp.request.max_array_depth = 100
12040+
12041+; Limits the length of variable values
12042+hphp.request.max_value_length = 65000
12043+
12044+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12045+; Hardening-Patch's COOKIE variable filters ;
12046+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12047+
12048+; Limits the number of COOKIE variables
12049+hphp.cookie.max_vars = 100
12050+
12051+; Limits the length of variable names (without indices)
12052+hphp.cookie.max_name_length = 64
12053+
12054+; Limits the length of complete variable names (with indices)
12055+hphp.cookie.max_totalname_length = 256
12056+
12057+; Limits the length of array indices
12058+hphp.cookie.max_array_index_length = 64
12059+
12060+; Limits the depth of arrays
12061+hphp.cookie.max_array_depth = 100
12062+
12063+; Limits the length of variable values
12064+hphp.cookie.max_value_length = 10000
12065+
12066+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12067+; Hardening-Patch's GET variable filters ;
12068+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12069+
12070+; Limits the number of COOKIE variables
12071+hphp.get.max_vars = 100
12072+
12073+; Limits the length of variable names (without indices)
12074+hphp.get.max_name_length = 64
12075+
12076+; Limits the length of complete variable names (with indices)
12077+hphp.get.max_totalname_length = 256
12078+
12079+; Limits the length of array indices
12080+hphp.get.max_array_index_length = 64
12081+
12082+; Limits the depth of arrays
12083+hphp.get.max_array_depth = 50
12084+
12085+; Limits the length of variable values
12086+hphp.get.max_value_length = 512
12087+
12088+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12089+; Hardening-Patch's POST variable filters ;
12090+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12091+
12092+; Limits the number of POST variables
12093+hphp.post.max_vars = 200
12094+
12095+; Limits the length of variable names (without indices)
12096+hphp.post.max_name_length = 64
12097+
12098+; Limits the length of complete variable names (with indices)
12099+hphp.post.max_totalname_length = 256
12100+
12101+; Limits the length of array indices
12102+hphp.post.max_array_index_length = 64
12103+
12104+; Limits the depth of arrays
12105+hphp.post.max_array_depth = 100
12106+
12107+; Limits the length of variable values
12108+hphp.post.max_value_length = 65000
12109+
12110+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12111+; Hardening-Patch's fileupload variable filters ;
12112+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12113+
12114+; Limits the number of uploadable files
12115+hphp.upload.max_uploads = 25
12116+
12117+; Filter out the upload of ELF executables
12118+hphp.upload.disallow_elf_files = On
12119+
12120+; External filterscript for upload verification
12121+;hphp.upload.verification_script = /home/hphp/verify_script
12122+
12123+
12124 ; Local Variables:
12125 ; tab-width: 4
12126 ; End:
12127diff -Nura php-4.4.0/php.ini-recommended hardening-patch-4.4.0-0.4.2/php.ini-recommended
12128--- php-4.4.0/php.ini-recommended 2005-04-28 15:14:46.000000000 +0200
12129+++ hardening-patch-4.4.0-0.4.2/php.ini-recommended 2005-09-07 18:40:29.106945368 +0200
12130@@ -1110,6 +1110,185 @@
12131 ;exif.decode_jis_motorola = JIS
12132 ;exif.decode_jis_intel = JIS
12133
12134+[hardening-patch]
12135+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12136+; Hardening-Patch's logging ;
12137+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12138+
12139+;
12140+; hphp.log.syslog - Configures level for alerts reported through syslog
12141+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
12142+; hphp.log.script - Configures level for alerts reported through external script
12143+;
12144+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
12145+; Or each number up to get desired Hardening-Patch's reporting level
12146+;
12147+; S_ALL - All alerts
12148+; S_MEMORY - All canary violations and the safe unlink protection use this class
12149+; S_VARS - All variable filters trigger this class
12150+; S_FILES - All violation of uploaded files filter use this class
12151+; S_INCLUDE - The protection against malicious include filenames use this class
12152+; S_SQL - Failed SQL queries in MySQL are logged with this class
12153+; S_EXECUTOR - The execution depth protection uses this logging class
12154+; S_MISC - All other log messages (f.e. format string protection) use this class
12155+;
12156+; Example:
12157+;
12158+; - Report all alerts (except memory alerts) to the SAPI errorlog,
12159+; memory alerts through syslog and SQL+Include alerts fo the script
12160+;
12161+;hphp.log.syslog = S_MEMORY
12162+;hphp.log.sapi = S_ALL & ~S_MEMORY
12163+;hphp.log.script = S_INCLUDE | S_SQL
12164+;
12165+; Syslog logging:
12166+;
12167+; - Facility configuration: one of the following facilities
12168+;
12169+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
12170+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
12171+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
12172+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
12173+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
12174+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
12175+; LOG_PERROR
12176+;
12177+; - Priority configuration: one of the followinf priorities
12178+;
12179+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
12180+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
12181+;
12182+hphp.log.syslog.priority = LOG_ALERT
12183+hphp.log.syslog.facility = LOG_USER
12184+;
12185+; Script logging:
12186+;
12187+;hphp.log.script.name = /home/hphp/log_script
12188+;
12189+; Alert configuration:
12190+;
12191+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
12192+;
12193+;hphp.log.use-x-forwarded-for = On
12194+;
12195+
12196+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12197+; Hardening-Patch's Executor options ;
12198+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12199+
12200+; Execution depth limit
12201+;hphp.executor.max_depth = 8000
12202+
12203+; White-/blacklist for function calls during normal execution
12204+;hphp.executor.func.whitelist = ord,chr
12205+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
12206+
12207+; White-/blacklist for function calls during eval() execution
12208+;hphp.executor.eval.whitelist = ord,chr
12209+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
12210+
12211+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12212+; Hardening-Patch's REQUEST variable filters ;
12213+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12214+
12215+; Limits the number of REQUEST variables
12216+hphp.request.max_vars = 200
12217+
12218+; Limits the length of variable names (without indices)
12219+hphp.request.max_varname_length = 64
12220+
12221+; Limits the length of complete variable names (with indices)
12222+hphp.request.max_totalname_length = 256
12223+
12224+; Limits the length of array indices
12225+hphp.request.max_array_index_length = 64
12226+
12227+; Limits the depth of arrays
12228+hphp.request.max_array_depth = 100
12229+
12230+; Limits the length of variable values
12231+hphp.request.max_value_length = 65000
12232+
12233+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12234+; Hardening-Patch's COOKIE variable filters ;
12235+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12236+
12237+; Limits the number of COOKIE variables
12238+hphp.cookie.max_vars = 100
12239+
12240+; Limits the length of variable names (without indices)
12241+hphp.cookie.max_name_length = 64
12242+
12243+; Limits the length of complete variable names (with indices)
12244+hphp.cookie.max_totalname_length = 256
12245+
12246+; Limits the length of array indices
12247+hphp.cookie.max_array_index_length = 64
12248+
12249+; Limits the depth of arrays
12250+hphp.cookie.max_array_depth = 100
12251+
12252+; Limits the length of variable values
12253+hphp.cookie.max_value_length = 10000
12254+
12255+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12256+; Hardening-Patch's GET variable filters ;
12257+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12258+
12259+; Limits the number of COOKIE variables
12260+hphp.get.max_vars = 100
12261+
12262+; Limits the length of variable names (without indices)
12263+hphp.get.max_name_length = 64
12264+
12265+; Limits the length of complete variable names (with indices)
12266+hphp.get.max_totalname_length = 256
12267+
12268+; Limits the length of array indices
12269+hphp.get.max_array_index_length = 64
12270+
12271+; Limits the depth of arrays
12272+hphp.get.max_array_depth = 50
12273+
12274+; Limits the length of variable values
12275+hphp.get.max_value_length = 512
12276+
12277+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12278+; Hardening-Patch's POST variable filters ;
12279+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12280+
12281+; Limits the number of POST variables
12282+hphp.post.max_vars = 200
12283+
12284+; Limits the length of variable names (without indices)
12285+hphp.post.max_name_length = 64
12286+
12287+; Limits the length of complete variable names (with indices)
12288+hphp.post.max_totalname_length = 256
12289+
12290+; Limits the length of array indices
12291+hphp.post.max_array_index_length = 64
12292+
12293+; Limits the depth of arrays
12294+hphp.post.max_array_depth = 100
12295+
12296+; Limits the length of variable values
12297+hphp.post.max_value_length = 65000
12298+
12299+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12300+; Hardening-Patch's fileupload variable filters ;
12301+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12302+
12303+; Limits the number of uploadable files
12304+hphp.upload.max_uploads = 25
12305+
12306+; Filter out the upload of ELF executables
12307+hphp.upload.disallow_elf_files = On
12308+
12309+; External filterscript for upload verification
12310+;hphp.upload.verification_script = /home/hphp/verify_script
12311+
12312+
12313 ; Local Variables:
12314 ; tab-width: 4
12315 ; End:
12316diff -Nura php-4.4.0/README.input_filter hardening-patch-4.4.0-0.4.2/README.input_filter
12317--- php-4.4.0/README.input_filter 1970-01-01 01:00:00.000000000 +0100
12318+++ hardening-patch-4.4.0-0.4.2/README.input_filter 2005-09-07 18:40:29.107945216 +0200
12319@@ -0,0 +1,193 @@
12320+Input Filter Support ported from PHP 5
12321+--------------------------------------
12322+
12323+XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
12324+and can be quite difficult to prevent. Whenever you accept user data
12325+and somehow display this data back to users, you are likely vulnerable
12326+to XSS hacks.
12327+
12328+The Input Filter support in PHP 5 is aimed at providing the framework
12329+through which a company-wide or site-wide security policy can be
12330+enforced. It is implemented as a SAPI hook and is called from the
12331+treat_data and post handler functions. To implement your own security
12332+policy you will need to write a standard PHP extension.
12333+
12334+A simple implementation might look like the following. This stores the
12335+original raw user data and adds a my_get_raw() function while the normal
12336+$_POST, $_GET and $_COOKIE arrays are only populated with stripped
12337+data. In this simple example all I am doing is calling strip_tags() on
12338+the data. If register_globals is turned on, the default globals that
12339+are created will be stripped ($foo) while a $RAW_foo is created with the
12340+original user input.
12341+
12342+ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
12343+ zval *post_array;
12344+ zval *get_array;
12345+ zval *cookie_array;
12346+ZEND_END_MODULE_GLOBALS(my_input_filter)
12347+
12348+#ifdef ZTS
12349+#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v)
12350+#else
12351+#define IF_G(v) (my_input_filter_globals.v)
12352+#endif
12353+
12354+ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
12355+
12356+function_entry my_input_filter_functions[] = {
12357+ PHP_FE(my_get_raw, NULL)
12358+ {NULL, NULL, NULL}
12359+};
12360+
12361+zend_module_entry my_input_filter_module_entry = {
12362+ STANDARD_MODULE_HEADER,
12363+ "my_input_filter",
12364+ my_input_filter_functions,
12365+ PHP_MINIT(my_input_filter),
12366+ PHP_MSHUTDOWN(my_input_filter),
12367+ NULL,
12368+ PHP_RSHUTDOWN(my_input_filter),
12369+ PHP_MINFO(my_input_filter),
12370+ "0.1",
12371+ STANDARD_MODULE_PROPERTIES
12372+};
12373+
12374+PHP_MINIT_FUNCTION(my_input_filter)
12375+{
12376+ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
12377+
12378+ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
12379+ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
12380+ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
12381+
12382+ sapi_register_input_filter(my_sapi_input_filter);
12383+ return SUCCESS;
12384+}
12385+
12386+PHP_RSHUTDOWN_FUNCTION(my_input_filter)
12387+{
12388+ if(IF_G(get_array)) {
12389+ zval_ptr_dtor(&IF_G(get_array));
12390+ IF_G(get_array) = NULL;
12391+ }
12392+ if(IF_G(post_array)) {
12393+ zval_ptr_dtor(&IF_G(post_array));
12394+ IF_G(post_array) = NULL;
12395+ }
12396+ if(IF_G(cookie_array)) {
12397+ zval_ptr_dtor(&IF_G(cookie_array));
12398+ IF_G(cookie_array) = NULL;
12399+ }
12400+ return SUCCESS;
12401+}
12402+
12403+PHP_MINFO_FUNCTION(my_input_filter)
12404+{
12405+ php_info_print_table_start();
12406+ php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
12407+ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $");
12408+ php_info_print_table_end();
12409+}
12410+
12411+/* The filter handler. If you return 1 from it, then PHP also registers the
12412+ * (modified) variable. Returning 0 prevents PHP from registering the variable;
12413+ * you can use this if your filter already registers the variable under a
12414+ * different name, or if you just don't want the variable registered at all. */
12415+SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
12416+{
12417+ zval new_var;
12418+ zval *array_ptr = NULL;
12419+ char *raw_var;
12420+ int var_len;
12421+
12422+ assert(*val != NULL);
12423+
12424+ switch(arg) {
12425+ case PARSE_GET:
12426+ if(!IF_G(get_array)) {
12427+ ALLOC_ZVAL(array_ptr);
12428+ array_init(array_ptr);
12429+ INIT_PZVAL(array_ptr);
12430+ }
12431+ IF_G(get_array) = array_ptr;
12432+ break;
12433+ case PARSE_POST:
12434+ if(!IF_G(post_array)) {
12435+ ALLOC_ZVAL(array_ptr);
12436+ array_init(array_ptr);
12437+ INIT_PZVAL(array_ptr);
12438+ }
12439+ IF_G(post_array) = array_ptr;
12440+ break;
12441+ case PARSE_COOKIE:
12442+ if(!IF_G(cookie_array)) {
12443+ ALLOC_ZVAL(array_ptr);
12444+ array_init(array_ptr);
12445+ INIT_PZVAL(array_ptr);
12446+ }
12447+ IF_G(cookie_array) = array_ptr;
12448+ break;
12449+ }
12450+ Z_STRLEN(new_var) = val_len;
12451+ Z_STRVAL(new_var) = estrndup(*val, val_len);
12452+ Z_TYPE(new_var) = IS_STRING;
12453+
12454+ var_len = strlen(var);
12455+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
12456+ strcpy(raw_var, "RAW_");
12457+ strlcat(raw_var,var,var_len+5);
12458+
12459+ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
12460+
12461+ php_strip_tags(*val, val_len, NULL, NULL, 0);
12462+
12463+ *new_val_len = strlen(*val);
12464+ return 1;
12465+}
12466+
12467+PHP_FUNCTION(my_get_raw)
12468+{
12469+ long arg;
12470+ char *var;
12471+ int var_len;
12472+ zval **tmp;
12473+ zval *array_ptr = NULL;
12474+ HashTable *hash_ptr;
12475+ char *raw_var;
12476+
12477+ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
12478+ return;
12479+ }
12480+
12481+ switch(arg) {
12482+ case PARSE_GET:
12483+ array_ptr = IF_G(get_array);
12484+ break;
12485+ case PARSE_POST:
12486+ array_ptr = IF_G(post_array);
12487+ break;
12488+ case PARSE_COOKIE:
12489+ array_ptr = IF_G(post_array);
12490+ break;
12491+ }
12492+
12493+ if(!array_ptr) RETURN_FALSE;
12494+
12495+ /*
12496+ * I'm changing the variable name here because when running with register_globals on,
12497+ * the variable will end up in the global symbol table
12498+ */
12499+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
12500+ strcpy(raw_var, "RAW_");
12501+ strlcat(raw_var,var,var_len+5);
12502+ hash_ptr = HASH_OF(array_ptr);
12503+
12504+ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) {
12505+ *return_value = **tmp;
12506+ zval_copy_ctor(return_value);
12507+ } else {
12508+ RETVAL_FALSE;
12509+ }
12510+ efree(raw_var);
12511+}
12512+
12513diff -Nura php-4.4.0/sapi/apache/mod_php4.c hardening-patch-4.4.0-0.4.2/sapi/apache/mod_php4.c
12514--- php-4.4.0/sapi/apache/mod_php4.c 2005-05-19 18:14:46.000000000 +0200
12515+++ hardening-patch-4.4.0-0.4.2/sapi/apache/mod_php4.c 2005-09-07 18:40:29.107945216 +0200
12516@@ -452,7 +452,7 @@
12517 sapi_apache_get_fd,
12518 sapi_apache_force_http_10,
12519 sapi_apache_get_target_uid,
12520- sapi_apache_get_target_gid
12521+ sapi_apache_get_target_gid,
12522 };
12523 /* }}} */
12524
12525@@ -898,7 +898,11 @@
12526 {
12527 TSRMLS_FETCH();
12528 if (PG(expose_php)) {
12529+#if HARDENING_PATCH
12530+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
12531+#else
12532 ap_add_version_component("PHP/" PHP_VERSION);
12533+#endif
12534 }
12535 }
12536 #endif
12537diff -Nura php-4.4.0/sapi/apache2filter/sapi_apache2.c hardening-patch-4.4.0-0.4.2/sapi/apache2filter/sapi_apache2.c
12538--- php-4.4.0/sapi/apache2filter/sapi_apache2.c 2005-04-08 22:35:02.000000000 +0200
12539+++ hardening-patch-4.4.0-0.4.2/sapi/apache2filter/sapi_apache2.c 2005-09-07 18:40:29.108945064 +0200
12540@@ -556,7 +556,11 @@
12541 {
12542 TSRMLS_FETCH();
12543 if (PG(expose_php)) {
12544+#if HARDENING_PATCH
12545+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
12546+#else
12547 ap_add_version_component(p, "PHP/" PHP_VERSION);
12548+#endif
12549 }
12550 }
12551
12552diff -Nura php-4.4.0/sapi/apache2handler/sapi_apache2.c hardening-patch-4.4.0-0.4.2/sapi/apache2handler/sapi_apache2.c
12553--- php-4.4.0/sapi/apache2handler/sapi_apache2.c 2005-04-08 22:35:02.000000000 +0200
12554+++ hardening-patch-4.4.0-0.4.2/sapi/apache2handler/sapi_apache2.c 2005-09-07 18:40:29.108945064 +0200
12555@@ -340,7 +340,11 @@
12556 {
12557 TSRMLS_FETCH();
12558 if (PG(expose_php)) {
12559+#if HARDENING_PATCH
12560+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
12561+#else
12562 ap_add_version_component(p, "PHP/" PHP_VERSION);
12563+#endif
12564 }
12565 }
12566
12567diff -Nura php-4.4.0/sapi/cgi/cgi_main.c hardening-patch-4.4.0-0.4.2/sapi/cgi/cgi_main.c
12568--- php-4.4.0/sapi/cgi/cgi_main.c 2005-04-28 16:24:47.000000000 +0200
12569+++ hardening-patch-4.4.0-0.4.2/sapi/cgi/cgi_main.c 2005-09-07 18:40:29.109944912 +0200
12570@@ -1440,11 +1440,19 @@
12571 SG(headers_sent) = 1;
12572 SG(request_info).no_headers = 1;
12573 }
12574+#if HARDENING_PATCH
12575+#if ZEND_DEBUG
12576+ 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());
12577+#else
12578+ 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());
12579+#endif
12580+#else
12581 #if ZEND_DEBUG
12582 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());
12583 #else
12584 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());
12585 #endif
12586+#endif
12587 php_end_ob_buffers(1 TSRMLS_CC);
12588 exit(1);
12589 break;
12590diff -Nura php-4.4.0/sapi/cli/php_cli.c hardening-patch-4.4.0-0.4.2/sapi/cli/php_cli.c
12591--- php-4.4.0/sapi/cli/php_cli.c 2005-03-22 16:09:36.000000000 +0100
12592+++ hardening-patch-4.4.0-0.4.2/sapi/cli/php_cli.c 2005-09-07 18:40:29.110944760 +0200
12593@@ -652,11 +652,19 @@
12594 if (php_request_startup(TSRMLS_C)==FAILURE) {
12595 goto err;
12596 }
12597+#if HARDENING_PATCH
12598+#if ZEND_DEBUG
12599+ 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());
12600+#else
12601+ 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());
12602+#endif
12603+#else
12604 #if ZEND_DEBUG
12605 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());
12606 #else
12607 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());
12608 #endif
12609+#endif
12610 php_end_ob_buffers(1 TSRMLS_CC);
12611 exit_status=1;
12612 goto out;
12613diff -Nura php-4.4.0/TSRM/TSRM.h hardening-patch-4.4.0-0.4.2/TSRM/TSRM.h
12614--- php-4.4.0/TSRM/TSRM.h 2005-02-11 04:34:04.000000000 +0100
12615+++ hardening-patch-4.4.0-0.4.2/TSRM/TSRM.h 2005-09-07 18:40:29.111944608 +0200
12616@@ -33,6 +33,13 @@
12617 # define TSRM_API
12618 #endif
12619
12620+#if HARDENING_PATCH
12621+# if HAVE_REALPATH
12622+# undef realpath
12623+# define realpath php_realpath
12624+# endif
12625+#endif
12626+
12627 /* Only compile multi-threading functions if we're in ZTS mode */
12628 #ifdef ZTS
12629
12630@@ -90,6 +97,7 @@
12631
12632 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
12633
12634+
12635 #ifdef __cplusplus
12636 extern "C" {
12637 #endif
12638diff -Nura php-4.4.0/TSRM/tsrm_virtual_cwd.c hardening-patch-4.4.0-0.4.2/TSRM/tsrm_virtual_cwd.c
12639--- php-4.4.0/TSRM/tsrm_virtual_cwd.c 2005-02-11 04:34:04.000000000 +0100
12640+++ hardening-patch-4.4.0-0.4.2/TSRM/tsrm_virtual_cwd.c 2005-09-07 18:40:29.111944608 +0200
12641@@ -192,6 +192,165 @@
12642 return p;
12643 }
12644
12645+#if HARDENING_PATCH
12646+CWD_API char *php_realpath(const char *path, char *resolved)
12647+{
12648+ struct stat sb;
12649+ char *p, *q, *s;
12650+ size_t left_len, resolved_len;
12651+ unsigned symlinks;
12652+ int serrno, slen;
12653+ int is_dir = 1;
12654+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
12655+
12656+ serrno = errno;
12657+ symlinks = 0;
12658+ if (path[0] == '/') {
12659+ resolved[0] = '/';
12660+ resolved[1] = '\0';
12661+ if (path[1] == '\0')
12662+ return (resolved);
12663+ resolved_len = 1;
12664+ left_len = strlcpy(left, path + 1, sizeof(left));
12665+ } else {
12666+ if (getcwd(resolved, PATH_MAX) == NULL) {
12667+ strlcpy(resolved, ".", PATH_MAX);
12668+ return (NULL);
12669+ }
12670+ resolved_len = strlen(resolved);
12671+ left_len = strlcpy(left, path, sizeof(left));
12672+ }
12673+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
12674+ errno = ENAMETOOLONG;
12675+ return (NULL);
12676+ }
12677+
12678+ /*
12679+ * Iterate over path components in `left'.
12680+ */
12681+ while (left_len != 0) {
12682+ /*
12683+ * Extract the next path component and adjust `left'
12684+ * and its length.
12685+ */
12686+ p = strchr(left, '/');
12687+ s = p ? p : left + left_len;
12688+ if (s - left >= sizeof(next_token)) {
12689+ errno = ENAMETOOLONG;
12690+ return (NULL);
12691+ }
12692+ memcpy(next_token, left, s - left);
12693+ next_token[s - left] = '\0';
12694+ left_len -= s - left;
12695+ if (p != NULL)
12696+ memmove(left, s + 1, left_len + 1);
12697+ if (resolved[resolved_len - 1] != '/') {
12698+ if (resolved_len + 1 >= PATH_MAX) {
12699+ errno = ENAMETOOLONG;
12700+ return (NULL);
12701+ }
12702+ resolved[resolved_len++] = '/';
12703+ resolved[resolved_len] = '\0';
12704+ }
12705+ if (next_token[0] == '\0')
12706+ continue;
12707+ else if (strcmp(next_token, ".") == 0)
12708+ continue;
12709+ else if (strcmp(next_token, "..") == 0) {
12710+ /*
12711+ * Strip the last path component except when we have
12712+ * single "/"
12713+ */
12714+ if (!is_dir) {
12715+ errno = ENOENT;
12716+ return (NULL);
12717+ }
12718+ if (resolved_len > 1) {
12719+ resolved[resolved_len - 1] = '\0';
12720+ q = strrchr(resolved, '/');
12721+ *q = '\0';
12722+ resolved_len = q - resolved;
12723+ }
12724+ continue;
12725+ }
12726+
12727+ /*
12728+ * Append the next path component and lstat() it. If
12729+ * lstat() fails we still can return successfully if
12730+ * there are no more path components left.
12731+ */
12732+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
12733+ if (resolved_len >= PATH_MAX) {
12734+ errno = ENAMETOOLONG;
12735+ return (NULL);
12736+ }
12737+ if (lstat(resolved, &sb) != 0) {
12738+ if (errno == ENOENT && p == NULL) {
12739+ errno = serrno;
12740+ return (resolved);
12741+ }
12742+ return (NULL);
12743+ }
12744+ if (S_ISLNK(sb.st_mode)) {
12745+ if (symlinks++ > MAXSYMLINKS) {
12746+ errno = ELOOP;
12747+ return (NULL);
12748+ }
12749+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
12750+ if (slen < 0)
12751+ return (NULL);
12752+ symlink[slen] = '\0';
12753+ if (symlink[0] == '/') {
12754+ resolved[1] = 0;
12755+ resolved_len = 1;
12756+ } else if (resolved_len > 1) {
12757+ /* Strip the last path component. */
12758+ resolved[resolved_len - 1] = '\0';
12759+ q = strrchr(resolved, '/');
12760+ *q = '\0';
12761+ resolved_len = q - resolved;
12762+ }
12763+
12764+ /*
12765+ * If there are any path components left, then
12766+ * append them to symlink. The result is placed
12767+ * in `left'.
12768+ */
12769+ if (p != NULL) {
12770+ if (symlink[slen - 1] != '/') {
12771+ if (slen + 1 >= sizeof(symlink)) {
12772+ errno = ENAMETOOLONG;
12773+ return (NULL);
12774+ }
12775+ symlink[slen] = '/';
12776+ symlink[slen + 1] = 0;
12777+ }
12778+ left_len = strlcat(symlink, left, sizeof(left));
12779+ if (left_len >= sizeof(left)) {
12780+ errno = ENAMETOOLONG;
12781+ return (NULL);
12782+ }
12783+ }
12784+ left_len = strlcpy(left, symlink, sizeof(left));
12785+ } else {
12786+ if (S_ISDIR(sb.st_mode)) {
12787+ is_dir = 1;
12788+ } else {
12789+ is_dir = 0;
12790+ }
12791+ }
12792+ }
12793+
12794+ /*
12795+ * Remove trailing slash except when the resolved pathname
12796+ * is a single "/".
12797+ */
12798+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
12799+ resolved[resolved_len - 1] = '\0';
12800+ return (resolved);
12801+}
12802+#endif
12803+
12804 CWD_API void virtual_cwd_startup(void)
12805 {
12806 char cwd[MAXPATHLEN];
12807@@ -314,8 +473,7 @@
12808 path = resolved_path;
12809 path_length = strlen(path);
12810 } else {
12811- /* disable for now
12812- return 1; */
12813+ return 1;
12814 }
12815 }
12816 } else { /* Concat current directory with relative path and then run realpath() on it */
12817@@ -341,9 +499,8 @@
12818 path = resolved_path;
12819 path_length = strlen(path);
12820 } else {
12821- /* disable for now
12822 free(tmp);
12823- return 1; */
12824+ return 1;
12825 }
12826 }
12827 free(tmp);
12828diff -Nura php-4.4.0/TSRM/tsrm_virtual_cwd.h hardening-patch-4.4.0-0.4.2/TSRM/tsrm_virtual_cwd.h
12829--- php-4.4.0/TSRM/tsrm_virtual_cwd.h 2005-02-11 04:34:04.000000000 +0100
12830+++ hardening-patch-4.4.0-0.4.2/TSRM/tsrm_virtual_cwd.h 2005-09-07 18:40:29.112944456 +0200
12831@@ -128,6 +128,22 @@
12832
12833 typedef int (*verify_path_func)(const cwd_state *);
12834
12835+#ifndef HAVE_STRLCPY
12836+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
12837+#undef strlcpy
12838+#define strlcpy php_strlcpy
12839+#endif
12840+
12841+#ifndef HAVE_STRLCAT
12842+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
12843+#undef strlcat
12844+#define strlcat php_strlcat
12845+#endif
12846+
12847+
12848+#if HARDENING_PATCH
12849+CWD_API char *php_realpath(const char *path, char *resolved);
12850+#endif
12851 CWD_API void virtual_cwd_startup(void);
12852 CWD_API void virtual_cwd_shutdown(void);
12853 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
12854diff -Nura php-4.4.0/Zend/zend_alloc.c hardening-patch-4.4.0-0.4.2/Zend/zend_alloc.c
12855--- php-4.4.0/Zend/zend_alloc.c 2005-04-07 22:54:33.000000000 +0200
12856+++ hardening-patch-4.4.0-0.4.2/Zend/zend_alloc.c 2005-09-07 18:40:29.113944304 +0200
12857@@ -56,6 +56,11 @@
12858 # define END_MAGIC_SIZE 0
12859 #endif
12860
12861+#if HARDENING_PATCH_MM_PROTECT
12862+# define CANARY_SIZE sizeof(unsigned int)
12863+#else
12864+# define CANARY_SIZE 0
12865+#endif
12866
12867 # if MEMORY_LIMIT
12868 # if ZEND_DEBUG
12869@@ -95,9 +100,17 @@
12870 if (p==AG(head)) { \
12871 AG(head) = p->pNext; \
12872 } else { \
12873+ if (p != p->pLast->pNext) { \
12874+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
12875+ exit(1); \
12876+ } \
12877 p->pLast->pNext = p->pNext; \
12878 } \
12879 if (p->pNext) { \
12880+ if (p != p->pNext->pLast) { \
12881+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
12882+ exit(1); \
12883+ } \
12884 p->pNext->pLast = p->pLast; \
12885 }
12886
12887@@ -129,6 +142,12 @@
12888 DECLARE_CACHE_VARS();
12889 TSRMLS_FETCH();
12890
12891+#if HARDENING_PATCH_MM_PROTECT
12892+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
12893+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
12894+ exit(1);
12895+ }
12896+#endif
12897 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
12898
12899 if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
12900@@ -146,6 +165,10 @@
12901 AG(cache_stats)[CACHE_INDEX][1]++;
12902 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
12903 #endif
12904+#if HARDENING_PATCH_MM_PROTECT
12905+ p->canary = HG(canary_1);
12906+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
12907+#endif
12908 p->cached = 0;
12909 p->size = size;
12910 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
12911@@ -161,7 +184,7 @@
12912 AG(allocated_memory_peak) = AG(allocated_memory);
12913 }
12914 #endif
12915- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
12916+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
12917 }
12918
12919 HANDLE_BLOCK_INTERRUPTIONS();
12920@@ -191,7 +214,10 @@
12921 # endif
12922 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
12923 #endif
12924-
12925+#if HARDENING_PATCH_MM_PROTECT
12926+ p->canary = HG(canary_1);
12927+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
12928+#endif
12929 HANDLE_UNBLOCK_INTERRUPTIONS();
12930 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
12931 }
12932@@ -218,17 +244,36 @@
12933 return emalloc_rel(lval + offset);
12934 }
12935 }
12936-
12937+
12938+#if HARDENING_PATCH
12939+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
12940+#endif
12941 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset);
12942 return 0;
12943 }
12944
12945 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
12946 {
12947+#if HARDENING_PATCH_MM_PROTECT
12948+ unsigned int canary_2;
12949+#endif
12950 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
12951 DECLARE_CACHE_VARS();
12952 TSRMLS_FETCH();
12953
12954+#if HARDENING_PATCH_MM_PROTECT
12955+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch;
12956+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
12957+ if (canary_2 != HG(canary_2)) {
12958+efree_canary_mismatch:
12959+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
12960+ exit(1);
12961+ }
12962+ /* to catch double efree()s */
12963+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE);
12964+ p->canary = 0;
12965+#endif
12966+
12967 #if defined(ZTS) && TSRM_DEBUG
12968 if (p->thread_id != tsrm_thread_id()) {
12969 tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring",
12970@@ -273,6 +318,9 @@
12971 size_t _size = nmemb * size;
12972
12973 if (nmemb && (_size/nmemb!=size)) {
12974+#if HARDENING_PATCH
12975+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
12976+#endif
12977 fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
12978 #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
12979 kill(getpid(), SIGSEGV);
12980@@ -292,6 +340,9 @@
12981
12982 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
12983 {
12984+#if HARDENING_PATCH_MM_PROTECT
12985+ unsigned int canary_2;
12986+#endif
12987 zend_mem_header *p;
12988 zend_mem_header *orig;
12989 DECLARE_CACHE_VARS();
12990@@ -303,6 +354,16 @@
12991
12992 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
12993
12994+#if HARDENING_PATCH_MM_PROTECT
12995+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch;
12996+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
12997+ if (canary_2 != HG(canary_2)) {
12998+erealloc_canary_mismatch:
12999+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
13000+ exit(1);
13001+ }
13002+#endif
13003+
13004 #if defined(ZTS) && TSRM_DEBUG
13005 if (p->thread_id != tsrm_thread_id()) {
13006 void *new_p;
13007@@ -326,7 +387,7 @@
13008 }
13009 #endif
13010 REMOVE_POINTER_FROM_LIST(p);
13011- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
13012+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
13013 if (!p) {
13014 if (!allow_failure) {
13015 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
13016@@ -348,6 +409,9 @@
13017 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
13018 #endif
13019
13020+#if HARDENING_PATCH_MM_PROTECT
13021+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
13022+#endif
13023 p->size = size;
13024
13025 HANDLE_UNBLOCK_INTERRUPTIONS();
13026@@ -422,6 +486,10 @@
13027 {
13028 AG(head) = NULL;
13029
13030+#if HARDENING_PATCH_MM_PROTECT
13031+ HG(canary_1) = zend_canary();
13032+ HG(canary_2) = zend_canary();
13033+#endif
13034 #if MEMORY_LIMIT
13035 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
13036 AG(allocated_memory) = 0;
13037diff -Nura php-4.4.0/Zend/zend_alloc.h hardening-patch-4.4.0-0.4.2/Zend/zend_alloc.h
13038--- php-4.4.0/Zend/zend_alloc.h 2005-06-07 15:37:33.000000000 +0200
13039+++ hardening-patch-4.4.0-0.4.2/Zend/zend_alloc.h 2005-09-07 18:40:29.113944304 +0200
13040@@ -32,6 +32,9 @@
13041 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
13042
13043 typedef struct _zend_mem_header {
13044+#if HARDENING_PATCH_MM_PROTECT
13045+ unsigned int canary;
13046+#endif
13047 #if ZEND_DEBUG
13048 long magic;
13049 char *filename;
13050diff -Nura php-4.4.0/Zend/zend_builtin_functions.c hardening-patch-4.4.0-0.4.2/Zend/zend_builtin_functions.c
13051--- php-4.4.0/Zend/zend_builtin_functions.c 2005-06-23 14:20:47.000000000 +0200
13052+++ hardening-patch-4.4.0-0.4.2/Zend/zend_builtin_functions.c 2005-09-07 18:40:29.115944000 +0200
13053@@ -49,6 +49,9 @@
13054 static ZEND_FUNCTION(crash);
13055 #endif
13056 #endif
13057+#if HARDENING_PATCH_MM_PROTECT_DEBUG
13058+static ZEND_FUNCTION(heap_overflow);
13059+#endif
13060 static ZEND_FUNCTION(get_included_files);
13061 static ZEND_FUNCTION(is_subclass_of);
13062 static ZEND_FUNCTION(is_a);
13063@@ -101,6 +104,9 @@
13064 ZEND_FE(crash, NULL)
13065 #endif
13066 #endif
13067+#if HARDENING_PATCH_MM_PROTECT_DEBUG
13068+ ZEND_FE(heap_overflow, NULL)
13069+#endif
13070 ZEND_FE(get_included_files, NULL)
13071 ZEND_FALIAS(get_required_files, get_included_files, NULL)
13072 ZEND_FE(is_subclass_of, NULL)
13073@@ -805,6 +811,19 @@
13074
13075 #endif /* ZEND_DEBUG */
13076
13077+
13078+#if HARDENING_PATCH_MM_PROTECT_DEBUG
13079+ZEND_FUNCTION(heap_overflow)
13080+{
13081+ char *nowhere = emalloc(10);
13082+
13083+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
13084+
13085+ efree(nowhere);
13086+}
13087+#endif
13088+
13089+
13090 /* {{{ proto array get_included_files(void)
13091 Returns an array with the file names that were include_once()'d */
13092 ZEND_FUNCTION(get_included_files)
13093diff -Nura php-4.4.0/Zend/zend.c hardening-patch-4.4.0-0.4.2/Zend/zend.c
13094--- php-4.4.0/Zend/zend.c 2005-06-09 12:14:25.000000000 +0200
13095+++ hardening-patch-4.4.0-0.4.2/Zend/zend.c 2005-09-07 18:49:42.847763968 +0200
13096@@ -53,6 +53,12 @@
13097 ZEND_API void (*zend_unblock_interruptions)(void);
13098 ZEND_API void (*zend_ticks_function)(int ticks);
13099 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
13100+#if HARDENING_PATCH
13101+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
13102+#endif
13103+#if HARDENING_PATCH_INC_PROTECT
13104+ZEND_API int (*zend_is_valid_include)(zval *z);
13105+#endif
13106
13107 void (*zend_on_timeout)(int seconds TSRMLS_DC);
13108
13109@@ -70,9 +76,289 @@
13110 return SUCCESS;
13111 }
13112
13113+#if HARDENING_PATCH
13114+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
13115+{
13116+ if (!new_value) {
13117+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL;
13118+ } else {
13119+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL;
13120+ }
13121+ return SUCCESS;
13122+}
13123+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
13124+{
13125+ if (!new_value) {
13126+ EG(hphp_log_syslog_facility) = LOG_USER;
13127+ } else {
13128+ EG(hphp_log_syslog_facility) = atoi(new_value);
13129+ }
13130+ return SUCCESS;
13131+}
13132+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
13133+{
13134+ if (!new_value) {
13135+ EG(hphp_log_syslog_priority) = LOG_ALERT;
13136+ } else {
13137+ EG(hphp_log_syslog_priority) = atoi(new_value);
13138+ }
13139+ return SUCCESS;
13140+}
13141+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
13142+{
13143+ if (!new_value) {
13144+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL;
13145+ } else {
13146+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL;
13147+ }
13148+ return SUCCESS;
13149+}
13150+static ZEND_INI_MH(OnUpdateHPHP_log_script)
13151+{
13152+ if (!new_value) {
13153+ EG(hphp_log_script) = S_ALL & (~S_MEMORY) & (~S_INTERNAL);
13154+ } else {
13155+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
13156+ }
13157+ return SUCCESS;
13158+}
13159+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
13160+{
13161+ if (!new_value) {
13162+ EG(hphp_log_scriptname) = NULL;
13163+ } else {
13164+ if (EG(hphp_log_scriptname)) {
13165+ pefree(EG(hphp_log_scriptname),1);
13166+ }
13167+ EG(hphp_log_scriptname) = pestrdup(new_value,1);
13168+ }
13169+ return SUCCESS;
13170+}
13171+
13172+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist)
13173+{
13174+ char *s = NULL, *e, *val;
13175+ unsigned long dummy = 1;
13176+
13177+ if (!new_value) {
13178+eval_whitelist_destroy:
13179+ if (HG(eval_whitelist)) {
13180+ zend_hash_destroy(HG(eval_whitelist));
13181+ efree(HG(eval_whitelist));
13182+ }
13183+ HG(eval_whitelist) = NULL;
13184+ return SUCCESS;
13185+ }
13186+ if (!(*new_value)) {
13187+ goto eval_whitelist_destroy;
13188+ }
13189+
13190+ ALLOC_HASHTABLE(HG(eval_whitelist));
13191+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 0);
13192+
13193+ val = zend_str_tolower_dup(new_value, strlen(new_value));
13194+ e = val;
13195+
13196+ while (*e) {
13197+ switch (*e) {
13198+ case ' ':
13199+ case ',':
13200+ if (s) {
13201+ *e = '\0';
13202+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
13203+ s = NULL;
13204+ }
13205+ break;
13206+ default:
13207+ if (!s) {
13208+ s = e;
13209+ }
13210+ break;
13211+ }
13212+ e++;
13213+ }
13214+ if (s) {
13215+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
13216+ }
13217+ efree(val);
13218+
13219+ return SUCCESS;
13220+}
13221+
13222+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist)
13223+{
13224+ char *s = NULL, *e, *val;
13225+ unsigned long dummy = 1;
13226+
13227+ if (!new_value) {
13228+eval_blacklist_destroy:
13229+ if (HG(eval_blacklist)) {
13230+ zend_hash_destroy(HG(eval_blacklist));
13231+ efree(HG(eval_blacklist));
13232+ }
13233+ HG(eval_blacklist) = NULL;
13234+ return SUCCESS;
13235+ }
13236+ if (!(*new_value)) {
13237+ goto eval_blacklist_destroy;
13238+ }
13239+
13240+ ALLOC_HASHTABLE(HG(eval_blacklist));
13241+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 0);
13242+
13243+ val = zend_str_tolower_dup(new_value, strlen(new_value));
13244+ e = val;
13245+
13246+ while (*e) {
13247+ switch (*e) {
13248+ case ' ':
13249+ case ',':
13250+ if (s) {
13251+ *e = '\0';
13252+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
13253+ s = NULL;
13254+ }
13255+ break;
13256+ default:
13257+ if (!s) {
13258+ s = e;
13259+ }
13260+ break;
13261+ }
13262+ e++;
13263+ }
13264+ if (s) {
13265+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
13266+ }
13267+ efree(val);
13268+
13269+
13270+ return SUCCESS;
13271+}
13272+
13273+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist)
13274+{
13275+ char *s = NULL, *e, *val;
13276+ unsigned long dummy = 1;
13277+
13278+ if (!new_value) {
13279+func_whitelist_destroy:
13280+ if (HG(func_whitelist)) {
13281+ zend_hash_destroy(HG(func_whitelist));
13282+ efree(HG(func_whitelist));
13283+ }
13284+ HG(func_whitelist) = NULL;
13285+ return SUCCESS;
13286+ }
13287+ if (!(*new_value)) {
13288+ goto func_whitelist_destroy;
13289+ }
13290+
13291+ ALLOC_HASHTABLE(HG(func_whitelist));
13292+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 0);
13293+
13294+ val = zend_str_tolower_dup(new_value, strlen(new_value));
13295+ e = val;
13296+
13297+ while (*e) {
13298+ switch (*e) {
13299+ case ' ':
13300+ case ',':
13301+ if (s) {
13302+ *e = '\0';
13303+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
13304+ s = NULL;
13305+ }
13306+ break;
13307+ default:
13308+ if (!s) {
13309+ s = e;
13310+ }
13311+ break;
13312+ }
13313+ e++;
13314+ }
13315+ if (s) {
13316+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
13317+ }
13318+ efree(val);
13319+
13320+ return SUCCESS;
13321+}
13322+
13323+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist)
13324+{
13325+ char *s = NULL, *e, *val;
13326+ unsigned long dummy = 1;
13327+
13328+ if (!new_value) {
13329+func_blacklist_destroy:
13330+ if (HG(func_blacklist)) {
13331+ zend_hash_destroy(HG(func_blacklist));
13332+ efree(HG(func_blacklist));
13333+ }
13334+ HG(func_blacklist) = NULL;
13335+ return SUCCESS;
13336+ }
13337+ if (!(*new_value)) {
13338+ goto func_blacklist_destroy;
13339+ }
13340+
13341+ ALLOC_HASHTABLE(HG(func_blacklist));
13342+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 0);
13343+
13344+ val = zend_str_tolower_dup(new_value, strlen(new_value));
13345+ e = val;
13346+
13347+ while (*e) {
13348+ switch (*e) {
13349+ case ' ':
13350+ case ',':
13351+ if (s) {
13352+ *e = '\0';
13353+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
13354+ s = NULL;
13355+ }
13356+ break;
13357+ default:
13358+ if (!s) {
13359+ s = e;
13360+ }
13361+ break;
13362+ }
13363+ e++;
13364+ }
13365+ if (s) {
13366+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
13367+ }
13368+ efree(val);
13369+
13370+
13371+ return SUCCESS;
13372+}
13373+
13374+#endif
13375
13376 ZEND_INI_BEGIN()
13377 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
13378+#if HARDENING_PATCH
13379+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog)
13380+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility)
13381+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority)
13382+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi)
13383+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script)
13384+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname)
13385+ 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)
13386+
13387+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist)
13388+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist)
13389+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist)
13390+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist)
13391+
13392+ 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)
13393+ 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)
13394+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals)
13395+#endif
13396 ZEND_INI_END()
13397
13398
13399@@ -354,6 +640,7 @@
13400 zend_init_rsrc_plist(TSRMLS_C);
13401 EG(lambda_count)=0;
13402 EG(user_error_handler) = NULL;
13403+ EG(in_code_type) = 0;
13404 EG(in_execution) = 0;
13405 EG(current_execute_data) = NULL;
13406 }
13407@@ -420,6 +707,14 @@
13408 extern zend_scanner_globals language_scanner_globals;
13409 #endif
13410
13411+ /* Set up Hardening-Patch utility functions first */
13412+#if HARDENING_PATCH
13413+ zend_security_log = utility_functions->security_log_function;
13414+#endif
13415+#if HARDENING_PATCH_INC_PROTECT
13416+ zend_is_valid_include = utility_functions->is_valid_include;
13417+#endif
13418+
13419 #ifdef ZTS
13420 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
13421 #else
13422@@ -623,6 +918,7 @@
13423 }
13424 CG(unclean_shutdown) = 1;
13425 CG(in_compilation) = EG(in_execution) = 0;
13426+ EG(in_code_type) = 0;
13427 EG(current_execute_data) = NULL;
13428 longjmp(EG(bailout), FAILURE);
13429 }
13430diff -Nura php-4.4.0/Zend/zend_canary.c hardening-patch-4.4.0-0.4.2/Zend/zend_canary.c
13431--- php-4.4.0/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
13432+++ hardening-patch-4.4.0-0.4.2/Zend/zend_canary.c 2005-09-07 18:40:29.116943848 +0200
13433@@ -0,0 +1,58 @@
13434+/*
13435+ +----------------------------------------------------------------------+
13436+ | Hardening-Patch for PHP |
13437+ +----------------------------------------------------------------------+
13438+ | Copyright (c) 2004-2005 Stefan Esser |
13439+ +----------------------------------------------------------------------+
13440+ | This source file is subject to version 2.02 of the PHP license, |
13441+ | that is bundled with this package in the file LICENSE, and is |
13442+ | available at through the world-wide-web at |
13443+ | http://www.php.net/license/2_02.txt. |
13444+ | If you did not receive a copy of the PHP license and are unable to |
13445+ | obtain it through the world-wide-web, please send a note to |
13446+ | license@php.net so we can mail you a copy immediately. |
13447+ +----------------------------------------------------------------------+
13448+ | Author: Stefan Esser <sesser@hardened-php.net> |
13449+ +----------------------------------------------------------------------+
13450+ */
13451+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
13452+
13453+#include "zend.h"
13454+
13455+#include <stdio.h>
13456+#include <stdlib.h>
13457+
13458+
13459+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
13460+
13461+/* will be replaced later with more compatible method */
13462+ZEND_API unsigned int zend_canary()
13463+{
13464+ time_t t;
13465+ unsigned int canary;
13466+ int fd;
13467+
13468+ fd = open("/dev/urandom", 0);
13469+ if (fd != -1) {
13470+ int r = read(fd, &canary, sizeof(canary));
13471+ close(fd);
13472+ if (r == sizeof(canary)) {
13473+ return (canary);
13474+ }
13475+ }
13476+ /* not good but we never want to do this */
13477+ time(&t);
13478+ canary = *(unsigned int *)&t + getpid() << 16;
13479+ return (canary);
13480+}
13481+#endif
13482+
13483+
13484+/*
13485+ * Local variables:
13486+ * tab-width: 4
13487+ * c-basic-offset: 4
13488+ * End:
13489+ * vim600: sw=4 ts=4 fdm=marker
13490+ * vim<600: sw=4 ts=4
13491+ */
13492diff -Nura php-4.4.0/Zend/zend_compile.c hardening-patch-4.4.0-0.4.2/Zend/zend_compile.c
13493--- php-4.4.0/Zend/zend_compile.c 2005-06-24 13:48:30.000000000 +0200
13494+++ hardening-patch-4.4.0-0.4.2/Zend/zend_compile.c 2005-09-07 18:40:29.118943544 +0200
13495@@ -763,6 +763,13 @@
13496 op_array.function_name = name;
13497 op_array.arg_types = NULL;
13498 op_array.return_reference = return_reference;
13499+#if HARDENING_PATCH
13500+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
13501+ op_array.created_by_eval = 1;
13502+ } else {
13503+ op_array.created_by_eval = 0;
13504+ }
13505+#endif
13506
13507 if (is_method) {
13508 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) {
13509diff -Nura php-4.4.0/Zend/zend_compile.h hardening-patch-4.4.0-0.4.2/Zend/zend_compile.h
13510--- php-4.4.0/Zend/zend_compile.h 2005-06-06 11:30:09.000000000 +0200
13511+++ hardening-patch-4.4.0-0.4.2/Zend/zend_compile.h 2005-09-07 18:40:29.118943544 +0200
13512@@ -106,6 +106,9 @@
13513 char *filename;
13514
13515 void *reserved[ZEND_MAX_RESERVED_RESOURCES];
13516+#if HARDENING_PATCH
13517+ zend_bool created_by_eval;
13518+#endif
13519 };
13520
13521
13522@@ -549,6 +552,7 @@
13523 #define ZEND_USER_FUNCTION 2
13524 #define ZEND_OVERLOADED_FUNCTION 3
13525 #define ZEND_EVAL_CODE 4
13526+#define ZEND_SANDBOX_CODE 6
13527
13528 #define ZEND_INTERNAL_CLASS 1
13529 #define ZEND_USER_CLASS 2
13530diff -Nura php-4.4.0/Zend/zend_constants.c hardening-patch-4.4.0-0.4.2/Zend/zend_constants.c
13531--- php-4.4.0/Zend/zend_constants.c 2004-07-13 21:29:45.000000000 +0200
13532+++ hardening-patch-4.4.0-0.4.2/Zend/zend_constants.c 2005-09-07 18:48:20.315310808 +0200
13533@@ -111,6 +111,73 @@
13534 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
13535
13536 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
13537+#if HARDENING_PATCH
13538+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
13539+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
13540+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
13541+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
13542+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
13543+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
13544+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
13545+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
13546+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
13547+
13548+ /* error levels */
13549+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
13550+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
13551+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
13552+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
13553+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
13554+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
13555+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
13556+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
13557+ /* facility: type of program logging the message */
13558+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
13559+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
13560+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
13561+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
13562+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
13563+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
13564+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
13565+#ifdef LOG_NEWS
13566+ /* No LOG_NEWS on HP-UX */
13567+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
13568+#endif
13569+#ifdef LOG_UUCP
13570+ /* No LOG_UUCP on HP-UX */
13571+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
13572+#endif
13573+#ifdef LOG_CRON
13574+ /* apparently some systems don't have this one */
13575+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
13576+#endif
13577+#ifdef LOG_AUTHPRIV
13578+ /* AIX doesn't have LOG_AUTHPRIV */
13579+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
13580+#endif
13581+#if !defined(PHP_WIN32) && !defined(NETWARE)
13582+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
13583+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
13584+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
13585+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
13586+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
13587+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
13588+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
13589+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
13590+#endif
13591+ /* options */
13592+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
13593+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
13594+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
13595+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
13596+#ifdef LOG_NOWAIT
13597+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
13598+#endif
13599+#ifdef LOG_PERROR
13600+ /* AIX doesn't have LOG_PERROR */
13601+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
13602+#endif
13603+#endif
13604
13605 /* true/false constants */
13606 {
13607diff -Nura php-4.4.0/Zend/zend_errors.h hardening-patch-4.4.0-0.4.2/Zend/zend_errors.h
13608--- php-4.4.0/Zend/zend_errors.h 2002-12-31 17:22:59.000000000 +0100
13609+++ hardening-patch-4.4.0-0.4.2/Zend/zend_errors.h 2005-09-07 18:42:19.580150888 +0200
13610@@ -36,5 +36,17 @@
13611 #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)
13612 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
13613
13614+#if HARDENING_PATCH
13615+#define S_MEMORY (1<<0L)
13616+#define S_VARS (1<<1L)
13617+#define S_FILES (1<<2L)
13618+#define S_INCLUDE (1<<3L)
13619+#define S_SQL (1<<4L)
13620+#define S_EXECUTOR (1<<5L)
13621+#define S_MISC (1<<30L)
13622+#define S_INTERNAL (1<<29L)
13623+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MISC | S_SQL | S_EXECUTOR)
13624+#endif
13625+
13626 #endif /* ZEND_ERRORS_H */
13627
13628diff -Nura php-4.4.0/Zend/zend_execute_API.c hardening-patch-4.4.0-0.4.2/Zend/zend_execute_API.c
13629--- php-4.4.0/Zend/zend_execute_API.c 2005-05-18 19:58:09.000000000 +0200
13630+++ hardening-patch-4.4.0-0.4.2/Zend/zend_execute_API.c 2005-09-07 18:40:29.120943240 +0200
13631@@ -142,6 +142,7 @@
13632 EG(class_table) = CG(class_table);
13633
13634 EG(in_execution) = 0;
13635+ EG(in_code_type) = 0;
13636
13637 zend_ptr_stack_init(&EG(argument_stack));
13638
13639@@ -431,12 +432,14 @@
13640 zend_execute_data execute_data;
13641
13642 /* Initialize execute_data */
13643+ memset(&execute_data, 0, sizeof(execute_data));
13644 EX(fbc) = NULL;
13645 EX(object).ptr = NULL;
13646 EX(ce) = NULL;
13647 EX(Ts) = NULL;
13648 EX(op_array) = NULL;
13649 EX(opline) = NULL;
13650+ EX(execute_depth) = 0;
13651
13652 *retval_ptr_ptr = NULL;
13653
13654@@ -494,6 +497,39 @@
13655 zval_dtor(&function_name_copy);
13656 return FAILURE;
13657 }
13658+#if HARDENING_PATCH
13659+ if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
13660+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
13661+ if (HG(eval_whitelist) != NULL) {
13662+ if (!zend_hash_exists(HG(eval_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
13663+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_copy.value.str.val);
13664+ zval_dtor(&function_name_copy);
13665+ zend_bailout();
13666+ }
13667+ } else if (HG(eval_blacklist) != NULL) {
13668+ if (zend_hash_exists(HG(eval_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
13669+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_copy.value.str.val);
13670+ zval_dtor(&function_name_copy);
13671+ zend_bailout();
13672+ }
13673+ }
13674+ }
13675+
13676+ if (HG(func_whitelist) != NULL) {
13677+ if (!zend_hash_exists(HG(func_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
13678+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_copy.value.str.val);
13679+ zval_dtor(&function_name_copy);
13680+ zend_bailout();
13681+ }
13682+ } else if (HG(func_blacklist) != NULL) {
13683+ if (zend_hash_exists(HG(func_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
13684+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_copy.value.str.val);
13685+ zval_dtor(&function_name_copy);
13686+ zend_bailout();
13687+ }
13688+ }
13689+ }
13690+#endif
13691 zval_dtor(&function_name_copy);
13692
13693 for (i=0; i<param_count; i++) {
13694@@ -606,8 +642,7 @@
13695 return SUCCESS;
13696 }
13697
13698-
13699-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
13700+ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
13701 {
13702 zval pv;
13703 zend_op_array *new_op_array;
13704@@ -640,6 +675,7 @@
13705 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
13706 zend_op **original_opline_ptr = EG(opline_ptr);
13707
13708+ new_op_array->type = type;
13709 EG(return_value_ptr_ptr) = &local_retval_ptr;
13710 EG(active_op_array) = new_op_array;
13711 EG(no_extensions)=1;
13712@@ -673,6 +709,10 @@
13713 return retval;
13714 }
13715
13716+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
13717+{
13718+ return (zend_eval_string_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
13719+}
13720
13721 void execute_new_code(TSRMLS_D)
13722 {
13723diff -Nura php-4.4.0/Zend/zend_execute.c hardening-patch-4.4.0-0.4.2/Zend/zend_execute.c
13724--- php-4.4.0/Zend/zend_execute.c 2005-06-27 08:15:48.000000000 +0200
13725+++ hardening-patch-4.4.0-0.4.2/Zend/zend_execute.c 2005-09-07 18:40:29.122942936 +0200
13726@@ -1042,6 +1042,7 @@
13727 zend_execute_data execute_data;
13728
13729 /* Initialize execute_data */
13730+ memset(&execute_data, 0, sizeof(execute_data));
13731 EX(fbc) = NULL;
13732 EX(ce) = NULL;
13733 EX(object).ptr = NULL;
13734@@ -1053,9 +1054,21 @@
13735 }
13736 EX(prev_execute_data) = EG(current_execute_data);
13737 EX(original_in_execution)=EG(in_execution);
13738+ EX(original_in_code_type)=EG(in_code_type);
13739
13740 EG(current_execute_data) = &execute_data;
13741
13742+#if HARDENING_PATCH
13743+ EX(execute_depth) = 0;
13744+
13745+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval) && EG(in_code_type) != ZEND_SANDBOX_CODE) {
13746+ EG(in_code_type) = ZEND_EVAL_CODE;
13747+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
13748+ EG(in_code_type) = ZEND_SANDBOX_CODE;
13749+ op_array->type = ZEND_EVAL_CODE;
13750+ }
13751+#endif
13752+
13753 EG(in_execution) = 1;
13754 if (op_array->start_op) {
13755 EX(opline) = op_array->start_op;
13756@@ -1087,6 +1100,19 @@
13757 }
13758 }
13759
13760+#if HARDENING_PATCH
13761+ if (EX(prev_execute_data) == NULL) {
13762+ EX(execute_depth) = 0;
13763+ } else {
13764+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
13765+ }
13766+
13767+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
13768+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
13769+ zend_bailout();
13770+ }
13771+#endif
13772+
13773 while (1) {
13774 #ifdef ZEND_WIN32
13775 if (EG(timed_out)) {
13776@@ -1631,6 +1657,36 @@
13777 if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) {
13778 zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val);
13779 }
13780+#if HARDENING_PATCH
13781+ if (active_function_table == EG(function_table)) {
13782+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
13783+ if (HG(eval_whitelist) != NULL) {
13784+ if (!zend_hash_exists(HG(eval_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
13785+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name->value.str.val);
13786+ zend_bailout();
13787+ }
13788+ } else if (HG(eval_blacklist) != NULL) {
13789+ if (zend_hash_exists(HG(eval_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
13790+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name->value.str.val);
13791+ zend_bailout();
13792+ }
13793+ }
13794+ }
13795+
13796+ if (HG(func_whitelist) != NULL) {
13797+ if (!zend_hash_exists(HG(func_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
13798+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name->value.str.val);
13799+ zend_bailout();
13800+ }
13801+ } else if (HG(func_blacklist) != NULL) {
13802+ if (zend_hash_exists(HG(func_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
13803+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name->value.str.val);
13804+ zend_bailout();
13805+ }
13806+ }
13807+ }
13808+#endif
13809+
13810 zval_dtor(&tmp);
13811 EX(fbc) = function;
13812 overloaded_function_call_cont:
13813@@ -1646,6 +1702,35 @@
13814 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
13815 zend_error(E_ERROR, "Unknown function: %s()", fname->value.str.val);
13816 }
13817+#if HARDENING_PATCH
13818+ if (EX(function_state).function->type==ZEND_INTERNAL_FUNCTION) {
13819+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
13820+ if (HG(eval_whitelist) != NULL) {
13821+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
13822+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
13823+ zend_bailout();
13824+ }
13825+ } else if (HG(eval_blacklist) != NULL) {
13826+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
13827+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
13828+ zend_bailout();
13829+ }
13830+ }
13831+ }
13832+
13833+ if (HG(func_whitelist) != NULL) {
13834+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
13835+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
13836+ zend_bailout();
13837+ }
13838+ } else if (HG(func_blacklist) != NULL) {
13839+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
13840+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
13841+ zend_bailout();
13842+ }
13843+ }
13844+ }
13845+#endif
13846 FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1));
13847 zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(object).ptr, EX(ce));
13848 EX(object).ptr = NULL;
13849@@ -1816,6 +1901,7 @@
13850 efree(EX(Ts));
13851 }
13852 EG(in_execution) = EX(original_in_execution);
13853+ EG(in_code_type) = EX(original_in_code_type);
13854 EG(current_execute_data) = EX(prev_execute_data);
13855 return;
13856 }
13857@@ -2195,7 +2281,12 @@
13858 int dummy = 1;
13859 zend_file_handle file_handle = {0};
13860
13861+#if HARDENING_PATCH_INC_PROTECT
13862+ if (zend_is_valid_include(inc_filename)
13863+ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
13864+#else
13865 if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
13866+#endif
13867 && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) {
13868
13869 file_handle.filename = inc_filename->value.str.val;
13870@@ -2224,6 +2315,11 @@
13871 break;
13872 case ZEND_INCLUDE:
13873 case ZEND_REQUIRE:
13874+#if HARDENING_PATCH_INC_PROTECT
13875+ if (!zend_is_valid_include(inc_filename)) {
13876+ break;
13877+ }
13878+#endif
13879 new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
13880 break;
13881 case ZEND_EVAL: {
13882diff -Nura php-4.4.0/Zend/zend_execute_globals.h hardening-patch-4.4.0-0.4.2/Zend/zend_execute_globals.h
13883--- php-4.4.0/Zend/zend_execute_globals.h 2005-06-06 11:30:09.000000000 +0200
13884+++ hardening-patch-4.4.0-0.4.2/Zend/zend_execute_globals.h 2005-09-07 18:40:29.122942936 +0200
13885@@ -60,6 +60,8 @@
13886 object_info object;
13887 temp_variable *Ts;
13888 zend_bool original_in_execution;
13889+ zend_uint original_in_code_type;
13890+ zend_uint execute_depth;
13891 zend_op_array *op_array;
13892 struct _zend_execute_data *prev_execute_data;
13893 } zend_execute_data;
13894diff -Nura php-4.4.0/Zend/zend_extensions.c hardening-patch-4.4.0-0.4.2/Zend/zend_extensions.c
13895--- php-4.4.0/Zend/zend_extensions.c 2003-03-19 19:00:57.000000000 +0100
13896+++ hardening-patch-4.4.0-0.4.2/Zend/zend_extensions.c 2005-09-07 18:40:29.123942784 +0200
13897@@ -54,23 +54,44 @@
13898 return FAILURE;
13899 }
13900
13901+ /* check if module is compiled against Hardening-Patch */
13902+ if (extension_version_info->zend_extension_api_no < 1000000000) {
13903+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n"
13904+ "The Hardening-Patch version %d is installed.\n\n",
13905+ new_extension->name,
13906+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
13907+ DL_UNLOAD(handle);
13908+ return FAILURE;
13909+ }
13910+
13911+
13912+ /* check if module is compiled against correct Hardening-Patch version */
13913+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) {
13914+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n"
13915+ "The Hardening-Patch version %d is installed.\n\n",
13916+ new_extension->name,
13917+ extension_version_info->zend_extension_api_no,
13918+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
13919+ DL_UNLOAD(handle);
13920+ return FAILURE;
13921+ }
13922
13923 /* allow extension to proclaim compatibility with any Zend version */
13924- 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)) {
13925- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
13926+ 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)) {
13927+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) {
13928 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
13929 "The Zend Engine API version %d which is installed, is outdated.\n\n",
13930 new_extension->name,
13931- extension_version_info->zend_extension_api_no,
13932+ extension_version_info->real_zend_extension_api_no,
13933 ZEND_EXTENSION_API_NO);
13934 DL_UNLOAD(handle);
13935 return FAILURE;
13936- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
13937+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) {
13938 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
13939 "The Zend Engine API version %d which is installed, is newer.\n"
13940 "Contact %s at %s for a later version of %s.\n\n",
13941 new_extension->name,
13942- extension_version_info->zend_extension_api_no,
13943+ extension_version_info->real_zend_extension_api_no,
13944 ZEND_EXTENSION_API_NO,
13945 new_extension->author,
13946 new_extension->URL,
13947diff -Nura php-4.4.0/Zend/zend_extensions.h hardening-patch-4.4.0-0.4.2/Zend/zend_extensions.h
13948--- php-4.4.0/Zend/zend_extensions.h 2005-06-06 11:44:59.000000000 +0200
13949+++ hardening-patch-4.4.0-0.4.2/Zend/zend_extensions.h 2005-09-07 18:40:29.123942784 +0200
13950@@ -23,6 +23,9 @@
13951
13952 #include "zend_compile.h"
13953
13954+/* Create own API version number for Hardening-Patch */
13955+
13956+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1001050805
13957 #define ZEND_EXTENSION_API_NO 20050606
13958
13959 typedef struct _zend_extension_version_info {
13960@@ -30,6 +33,7 @@
13961 char *required_zend_version;
13962 unsigned char thread_safe;
13963 unsigned char debug;
13964+ int real_zend_extension_api_no;
13965 } zend_extension_version_info;
13966
13967
13968@@ -96,7 +100,7 @@
13969
13970
13971 #define ZEND_EXTENSION() \
13972- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
13973+ 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 }
13974
13975 #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
13976 #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
13977diff -Nura php-4.4.0/Zend/zend_globals.h hardening-patch-4.4.0-0.4.2/Zend/zend_globals.h
13978--- php-4.4.0/Zend/zend_globals.h 2004-11-04 00:15:05.000000000 +0100
13979+++ hardening-patch-4.4.0-0.4.2/Zend/zend_globals.h 2005-09-07 18:40:29.124942632 +0200
13980@@ -163,6 +163,16 @@
13981
13982 int error_reporting;
13983 int orig_error_reporting;
13984+#if HARDENING_PATCH
13985+ int hphp_log_syslog;
13986+ int hphp_log_syslog_facility;
13987+ int hphp_log_syslog_priority;
13988+ int hphp_log_sapi;
13989+ int hphp_log_script;
13990+ char *hphp_log_scriptname;
13991+ zend_bool hphp_log_use_x_forwarded_for;
13992+ long hphp_executor_max_depth;
13993+#endif
13994 int exit_status;
13995
13996 zend_op_array *active_op_array;
13997@@ -176,6 +186,7 @@
13998 int ticks_count;
13999
14000 zend_bool in_execution;
14001+ zend_uint in_code_type;
14002 zend_bool bailout_set;
14003 zend_bool full_tables_cleanup;
14004
14005diff -Nura php-4.4.0/Zend/zend.h hardening-patch-4.4.0-0.4.2/Zend/zend.h
14006--- php-4.4.0/Zend/zend.h 2005-01-25 14:08:41.000000000 +0100
14007+++ hardening-patch-4.4.0-0.4.2/Zend/zend.h 2005-09-07 18:40:29.124942632 +0200
14008@@ -275,9 +275,10 @@
14009 struct _zval_struct {
14010 /* Variable information */
14011 zvalue_value value; /* value */
14012+ zend_uint refcount;
14013+ zend_ushort flags;
14014 zend_uchar type; /* active type */
14015 zend_uchar is_ref;
14016- zend_ushort refcount;
14017 };
14018
14019
14020@@ -338,6 +339,12 @@
14021 void (*ticks_function)(int ticks);
14022 void (*on_timeout)(int seconds TSRMLS_DC);
14023 zend_bool (*open_function)(const char *filename, struct _zend_file_handle *);
14024+#if HARDENING_PATCH
14025+ void (*security_log_function)(int loglevel, char *fmt, ...);
14026+#endif
14027+#if HARDENING_PATCH_INC_PROTECT
14028+ int (*is_valid_include)(zval *z);
14029+#endif
14030 } zend_utility_functions;
14031
14032
14033@@ -469,7 +476,16 @@
14034 extern ZEND_API void (*zend_ticks_function)(int ticks);
14035 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);
14036 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
14037+#if HARDENING_PATCH
14038+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
14039+#endif
14040+#if HARDENING_PATCH_INC_PROTECT
14041+extern ZEND_API int (*zend_is_valid_include)(zval *z);
14042+#endif
14043
14044+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
14045+ZEND_API unsigned int zend_canary(void);
14046+#endif
14047
14048 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3);
14049
14050@@ -576,6 +592,11 @@
14051
14052 #define ZEND_MAX_RESERVED_RESOURCES 4
14053
14054+#if HARDENING_PATCH
14055+#include "hardened_globals.h"
14056+#include "php_syslog.h"
14057+#endif
14058+
14059 #endif /* ZEND_H */
14060
14061 /*
14062diff -Nura php-4.4.0/Zend/zend_hash.c hardening-patch-4.4.0-0.4.2/Zend/zend_hash.c
14063--- php-4.4.0/Zend/zend_hash.c 2005-04-28 09:34:32.000000000 +0200
14064+++ hardening-patch-4.4.0-0.4.2/Zend/zend_hash.c 2005-09-07 18:40:29.125942480 +0200
14065@@ -26,6 +26,17 @@
14066 # include <stdlib.h>
14067 #endif
14068
14069+#if HARDENING_PATCH_HASH_PROTECT
14070+ unsigned int zend_hash_canary = 0x1234567;
14071+ zend_bool zend_hash_canary_inited = 0;
14072+#endif
14073+
14074+#define CHECK_HASH_CANARY(hash) \
14075+ if (zend_hash_canary != (hash)->canary) { \
14076+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
14077+ exit(1); \
14078+ }
14079+
14080 #define HANDLE_NUMERIC(key, length, func) { \
14081 register char *tmp=key; \
14082 \
14083@@ -175,6 +186,9 @@
14084 {
14085 uint i = 3;
14086 Bucket **tmp;
14087+#if HARDENING_PATCH_HASH_PROTECT
14088+ TSRMLS_FETCH();
14089+#endif
14090
14091 SET_INCONSISTENT(HT_OK);
14092
14093@@ -184,6 +198,13 @@
14094
14095 ht->nTableSize = 1 << i;
14096 ht->nTableMask = ht->nTableSize - 1;
14097+#if HARDENING_PATCH_HASH_PROTECT
14098+ if (zend_hash_canary_inited==0) {
14099+ zend_hash_canary = zend_canary();
14100+ zend_hash_canary_inited = 1;
14101+ }
14102+ ht->canary = zend_hash_canary;
14103+#endif
14104 ht->pDestructor = pDestructor;
14105 ht->pListHead = NULL;
14106 ht->pListTail = NULL;
14107@@ -259,6 +280,9 @@
14108 }
14109 #endif
14110 if (ht->pDestructor) {
14111+#if HARDENING_PATCH_HASH_PROTECT
14112+ CHECK_HASH_CANARY(ht);
14113+#endif
14114 ht->pDestructor(p->pData);
14115 }
14116 UPDATE_DATA(ht, p, pData, nDataSize);
14117@@ -327,6 +351,9 @@
14118 }
14119 #endif
14120 if (ht->pDestructor) {
14121+#if HARDENING_PATCH_HASH_PROTECT
14122+ CHECK_HASH_CANARY(ht);
14123+#endif
14124 ht->pDestructor(p->pData);
14125 }
14126 UPDATE_DATA(ht, p, pData, nDataSize);
14127@@ -402,6 +429,9 @@
14128 }
14129 #endif
14130 if (ht->pDestructor) {
14131+#if HARDENING_PATCH_HASH_PROTECT
14132+ CHECK_HASH_CANARY(ht);
14133+#endif
14134 ht->pDestructor(p->pData);
14135 }
14136 UPDATE_DATA(ht, p, pData, nDataSize);
14137@@ -450,7 +480,7 @@
14138 IS_CONSISTENT(ht);
14139
14140 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
14141- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
14142+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
14143 if (t) {
14144 HANDLE_BLOCK_INTERRUPTIONS();
14145 ht->arBuckets = t;
14146@@ -460,6 +490,7 @@
14147 HANDLE_UNBLOCK_INTERRUPTIONS();
14148 return SUCCESS;
14149 }
14150+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
14151 return FAILURE;
14152 }
14153 return SUCCESS;
14154@@ -524,6 +555,9 @@
14155 ht->pInternalPointer = p->pListNext;
14156 }
14157 if (ht->pDestructor) {
14158+#if HARDENING_PATCH_HASH_PROTECT
14159+ CHECK_HASH_CANARY(ht);
14160+#endif
14161 ht->pDestructor(p->pData);
14162 }
14163 if (!p->pDataPtr) {
14164@@ -553,6 +587,9 @@
14165 q = p;
14166 p = p->pListNext;
14167 if (ht->pDestructor) {
14168+#if HARDENING_PATCH_HASH_PROTECT
14169+ CHECK_HASH_CANARY(ht);
14170+#endif
14171 ht->pDestructor(q->pData);
14172 }
14173 if (!q->pDataPtr && q->pData) {
14174@@ -579,6 +616,9 @@
14175 q = p;
14176 p = p->pListNext;
14177 if (ht->pDestructor) {
14178+#if HARDENING_PATCH_HASH_PROTECT
14179+ CHECK_HASH_CANARY(ht);
14180+#endif
14181 ht->pDestructor(q->pData);
14182 }
14183 if (!q->pDataPtr && q->pData) {
14184@@ -608,6 +648,9 @@
14185 HANDLE_BLOCK_INTERRUPTIONS();
14186
14187 if (ht->pDestructor) {
14188+#if HARDENING_PATCH_HASH_PROTECT
14189+ CHECK_HASH_CANARY(ht);
14190+#endif
14191 ht->pDestructor(p->pData);
14192 }
14193 if (!p->pDataPtr) {
14194diff -Nura php-4.4.0/Zend/zend_hash.h hardening-patch-4.4.0-0.4.2/Zend/zend_hash.h
14195--- php-4.4.0/Zend/zend_hash.h 2002-12-31 17:23:03.000000000 +0100
14196+++ hardening-patch-4.4.0-0.4.2/Zend/zend_hash.h 2005-09-07 18:40:29.126942328 +0200
14197@@ -54,6 +54,9 @@
14198 } Bucket;
14199
14200 typedef struct _hashtable {
14201+#if HARDENING_PATCH_HASH_PROTECT
14202+ unsigned int canary;
14203+#endif
14204 uint nTableSize;
14205 uint nTableMask;
14206 uint nNumOfElements;
14207diff -Nura php-4.4.0/Zend/zend_ini.h hardening-patch-4.4.0-0.4.2/Zend/zend_ini.h
14208--- php-4.4.0/Zend/zend_ini.h 2005-01-09 18:00:16.000000000 +0100
14209+++ hardening-patch-4.4.0-0.4.2/Zend/zend_ini.h 2005-09-07 18:40:29.126942328 +0200
14210@@ -174,6 +174,7 @@
14211 /* Standard message handlers */
14212 BEGIN_EXTERN_C()
14213 ZEND_API ZEND_INI_MH(OnUpdateBool);
14214+#define OnUpdateLong OnUpdateInt
14215 ZEND_API ZEND_INI_MH(OnUpdateInt);
14216 ZEND_API ZEND_INI_MH(OnUpdateReal);
14217 ZEND_API ZEND_INI_MH(OnUpdateString);
14218diff -Nura php-4.4.0/Zend/zend_language_scanner.l hardening-patch-4.4.0-0.4.2/Zend/zend_language_scanner.l
14219--- php-4.4.0/Zend/zend_language_scanner.l 2005-03-09 16:07:19.000000000 +0100
14220+++ hardening-patch-4.4.0-0.4.2/Zend/zend_language_scanner.l 2005-09-07 18:40:29.131941568 +0200
14221@@ -393,6 +393,13 @@
14222 compilation_successful=0;
14223 } else {
14224 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
14225+#if HARDENING_PATCH
14226+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
14227+ op_array->created_by_eval = 1;
14228+ } else {
14229+ op_array->created_by_eval = 0;
14230+ }
14231+#endif
14232 CG(in_compilation) = 1;
14233 CG(active_op_array) = op_array;
14234 compiler_result = zendparse(TSRMLS_C);
14235diff -Nura php-4.4.0/Zend/zend_language_scanner.c hardening-patch-4.4.0-0.4.2/Zend/zend_language_scanner.c
14236--- php-4.4.0/Zend/zend_language_scanner.c 2005-07-11 12:07:41.000000000 +0200
14237+++ hardening-patch-4.4.0-0.4.2/Zend/zend_language_scanner.c 2005-09-07 18:40:29.129941872 +0200
14238@@ -3121,6 +3121,13 @@
14239 compilation_successful=0;
14240 } else {
14241 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
14242+#if HARDENING_PATCH
14243+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
14244+ op_array->created_by_eval = 1;
14245+ } else {
14246+ op_array->created_by_eval = 0;
14247+ }
14248+#endif
14249 CG(in_compilation) = 1;
14250 CG(active_op_array) = op_array;
14251 compiler_result = zendparse(TSRMLS_C);
14252diff -Nura php-4.4.0/Zend/zend_llist.c hardening-patch-4.4.0-0.4.2/Zend/zend_llist.c
14253--- php-4.4.0/Zend/zend_llist.c 2002-12-31 17:23:04.000000000 +0100
14254+++ hardening-patch-4.4.0-0.4.2/Zend/zend_llist.c 2005-09-07 18:40:29.131941568 +0200
14255@@ -21,9 +21,34 @@
14256 #include "zend.h"
14257 #include "zend_llist.h"
14258 #include "zend_qsort.h"
14259+#include "zend_globals.h"
14260+
14261+#define CHECK_LIST_CANARY(list) \
14262+ if (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t) { \
14263+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
14264+ exit(1); \
14265+ }
14266+
14267+#define CHECK_LISTELEMENT_CANARY(elem) \
14268+ if (HG(canary_3) != (elem)->canary) { \
14269+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
14270+ exit(1); \
14271+ }
14272+
14273
14274 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
14275 {
14276+#if HARDENING_PATCH_LL_PROTECT
14277+ TSRMLS_FETCH();
14278+
14279+ if (!HG(ll_canary_inited)) {
14280+ HG(canary_3) = zend_canary();
14281+ HG(canary_4) = zend_canary();
14282+ HG(ll_canary_inited) = 1;
14283+ }
14284+ l->canary_h = HG(canary_3);
14285+ l->canary_t = HG(canary_4);
14286+#endif
14287 l->head = NULL;
14288 l->tail = NULL;
14289 l->count = 0;
14290@@ -37,6 +62,11 @@
14291 {
14292 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
14293
14294+#if HARDENING_PATCH_LL_PROTECT
14295+ TSRMLS_FETCH();
14296+ CHECK_LIST_CANARY(l)
14297+ tmp->canary = HG(canary_3);
14298+#endif
14299 tmp->prev = l->tail;
14300 tmp->next = NULL;
14301 if (l->tail) {
14302@@ -55,6 +85,11 @@
14303 {
14304 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
14305
14306+#if HARDENING_PATCH_LL_PROTECT
14307+ TSRMLS_FETCH();
14308+ CHECK_LIST_CANARY(l)
14309+ tmp->canary = HG(canary_3);
14310+#endif
14311 tmp->next = l->head;
14312 tmp->prev = NULL;
14313 if (l->head) {
14314@@ -91,10 +126,20 @@
14315 zend_llist_element *current=l->head;
14316 zend_llist_element *next;
14317
14318+#if HARDENING_PATCH_LL_PROTECT
14319+ TSRMLS_FETCH();
14320+ CHECK_LIST_CANARY(l)
14321+#endif
14322 while (current) {
14323+#if HARDENING_PATCH_LL_PROTECT
14324+ CHECK_LISTELEMENT_CANARY(current)
14325+#endif
14326 next = current->next;
14327 if (compare(current->data, element)) {
14328 DEL_LLIST_ELEMENT(current, l);
14329+#if HARDENING_PATCH_LL_PROTECT
14330+ current->canary = 0;
14331+#endif
14332 break;
14333 }
14334 current = next;
14335@@ -106,7 +151,14 @@
14336 {
14337 zend_llist_element *current=l->head, *next;
14338
14339+#if HARDENING_PATCH_LL_PROTECT
14340+ TSRMLS_FETCH();
14341+ CHECK_LIST_CANARY(l)
14342+#endif
14343 while (current) {
14344+#if HARDENING_PATCH_LL_PROTECT
14345+ CHECK_LISTELEMENT_CANARY(current)
14346+#endif
14347 next = current->next;
14348 if (l->dtor) {
14349 l->dtor(current->data);
14350@@ -131,7 +183,14 @@
14351 zend_llist_element *old_tail;
14352 void *data;
14353
14354+#if HARDENING_PATCH_LL_PROTECT
14355+ TSRMLS_FETCH();
14356+ CHECK_LIST_CANARY(l)
14357+#endif
14358 if ((old_tail = l->tail)) {
14359+#if HARDENING_PATCH_LL_PROTECT
14360+ CHECK_LISTELEMENT_CANARY(old_tail)
14361+#endif
14362 if (l->tail->prev) {
14363 l->tail->prev->next = NULL;
14364 }
14365@@ -157,9 +216,16 @@
14366 {
14367 zend_llist_element *ptr;
14368
14369+#if HARDENING_PATCH_LL_PROTECT
14370+ TSRMLS_FETCH();
14371+ CHECK_LIST_CANARY(src)
14372+#endif
14373 zend_llist_init(dst, src->size, src->dtor, src->persistent);
14374 ptr = src->head;
14375 while (ptr) {
14376+#if HARDENING_PATCH_LL_PROTECT
14377+ CHECK_LISTELEMENT_CANARY(ptr)
14378+#endif
14379 zend_llist_add_element(dst, ptr->data);
14380 ptr = ptr->next;
14381 }
14382@@ -170,11 +236,21 @@
14383 {
14384 zend_llist_element *element, *next;
14385
14386+#if HARDENING_PATCH_LL_PROTECT
14387+ TSRMLS_FETCH();
14388+ CHECK_LIST_CANARY(l)
14389+#endif
14390 element=l->head;
14391 while (element) {
14392+#if HARDENING_PATCH_LL_PROTECT
14393+ CHECK_LISTELEMENT_CANARY(element)
14394+#endif
14395 next = element->next;
14396 if (func(element->data)) {
14397 DEL_LLIST_ELEMENT(element, l);
14398+#if HARDENING_PATCH_LL_PROTECT
14399+ element->canary = 0;
14400+#endif
14401 }
14402 element = next;
14403 }
14404@@ -185,7 +261,13 @@
14405 {
14406 zend_llist_element *element;
14407
14408+#if HARDENING_PATCH_LL_PROTECT
14409+ CHECK_LIST_CANARY(l)
14410+#endif
14411 for (element=l->head; element; element=element->next) {
14412+#if HARDENING_PATCH_LL_PROTECT
14413+ CHECK_LISTELEMENT_CANARY(element)
14414+#endif
14415 func(element->data TSRMLS_CC);
14416 }
14417 }
14418@@ -197,6 +279,9 @@
14419 zend_llist_element **elements;
14420 zend_llist_element *element, **ptr;
14421
14422+#if HARDENING_PATCH_LL_PROTECT
14423+ CHECK_LIST_CANARY(l)
14424+#endif
14425 if (l->count <= 0) {
14426 return;
14427 }
14428@@ -206,6 +291,9 @@
14429 ptr = &elements[0];
14430
14431 for (element=l->head; element; element=element->next) {
14432+#if HARDENING_PATCH_LL_PROTECT
14433+ CHECK_LISTELEMENT_CANARY(element)
14434+#endif
14435 *ptr++ = element;
14436 }
14437
14438@@ -228,7 +316,13 @@
14439 {
14440 zend_llist_element *element;
14441
14442+#if HARDENING_PATCH_LL_PROTECT
14443+ CHECK_LIST_CANARY(l)
14444+#endif
14445 for (element=l->head; element; element=element->next) {
14446+#if HARDENING_PATCH_LL_PROTECT
14447+ CHECK_LISTELEMENT_CANARY(element)
14448+#endif
14449 func(element->data, arg TSRMLS_CC);
14450 }
14451 }
14452@@ -239,8 +333,14 @@
14453 zend_llist_element *element;
14454 va_list args;
14455
14456+#if HARDENING_PATCH_LL_PROTECT
14457+ CHECK_LIST_CANARY(l)
14458+#endif
14459 va_start(args, num_args);
14460 for (element=l->head; element; element=element->next) {
14461+#if HARDENING_PATCH_LL_PROTECT
14462+ CHECK_LISTELEMENT_CANARY(element)
14463+#endif
14464 func(element->data, num_args, args TSRMLS_CC);
14465 }
14466 va_end(args);
14467@@ -249,6 +349,10 @@
14468
14469 ZEND_API int zend_llist_count(zend_llist *l)
14470 {
14471+#if HARDENING_PATCH_LL_PROTECT
14472+ TSRMLS_FETCH();
14473+ CHECK_LIST_CANARY(l)
14474+#endif
14475 return l->count;
14476 }
14477
14478@@ -256,8 +360,15 @@
14479 {
14480 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
14481
14482+#if HARDENING_PATCH_LL_PROTECT
14483+ TSRMLS_FETCH();
14484+ CHECK_LIST_CANARY(l)
14485+#endif
14486 *current = l->head;
14487 if (*current) {
14488+#if HARDENING_PATCH_LL_PROTECT
14489+ CHECK_LISTELEMENT_CANARY(*current)
14490+#endif
14491 return (*current)->data;
14492 } else {
14493 return NULL;
14494@@ -269,8 +380,15 @@
14495 {
14496 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
14497
14498+#if HARDENING_PATCH_LL_PROTECT
14499+ TSRMLS_FETCH();
14500+ CHECK_LIST_CANARY(l)
14501+#endif
14502 *current = l->tail;
14503 if (*current) {
14504+#if HARDENING_PATCH_LL_PROTECT
14505+ CHECK_LISTELEMENT_CANARY(*current)
14506+#endif
14507 return (*current)->data;
14508 } else {
14509 return NULL;
14510@@ -282,9 +400,19 @@
14511 {
14512 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
14513
14514+#if HARDENING_PATCH_LL_PROTECT
14515+ TSRMLS_FETCH();
14516+ CHECK_LIST_CANARY(l)
14517+#endif
14518 if (*current) {
14519+#if HARDENING_PATCH_LL_PROTECT
14520+ CHECK_LISTELEMENT_CANARY(*current)
14521+#endif
14522 *current = (*current)->next;
14523 if (*current) {
14524+#if HARDENING_PATCH_LL_PROTECT
14525+ CHECK_LISTELEMENT_CANARY(*current)
14526+#endif
14527 return (*current)->data;
14528 }
14529 }
14530@@ -296,9 +424,19 @@
14531 {
14532 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
14533
14534+#if HARDENING_PATCH_LL_PROTECT
14535+ TSRMLS_FETCH();
14536+ CHECK_LIST_CANARY(l)
14537+#endif
14538 if (*current) {
14539+#if HARDENING_PATCH_LL_PROTECT
14540+ CHECK_LISTELEMENT_CANARY(*current)
14541+#endif
14542 *current = (*current)->prev;
14543 if (*current) {
14544+#if HARDENING_PATCH_LL_PROTECT
14545+ CHECK_LISTELEMENT_CANARY(*current)
14546+#endif
14547 return (*current)->data;
14548 }
14549 }
14550diff -Nura php-4.4.0/Zend/zend_llist.h hardening-patch-4.4.0-0.4.2/Zend/zend_llist.h
14551--- php-4.4.0/Zend/zend_llist.h 2002-12-31 17:23:04.000000000 +0100
14552+++ hardening-patch-4.4.0-0.4.2/Zend/zend_llist.h 2005-09-07 18:40:29.132941416 +0200
14553@@ -24,6 +24,9 @@
14554 #include <stdlib.h>
14555
14556 typedef struct _zend_llist_element {
14557+#if HARDENING_PATCH_LL_PROTECT
14558+ unsigned int canary;
14559+#endif
14560 struct _zend_llist_element *next;
14561 struct _zend_llist_element *prev;
14562 char data[1]; /* Needs to always be last in the struct */
14563@@ -36,6 +39,9 @@
14564 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
14565
14566 typedef struct _zend_llist {
14567+#if HARDENING_PATCH_LL_PROTECT
14568+ unsigned int canary_h; /* head */
14569+#endif
14570 zend_llist_element *head;
14571 zend_llist_element *tail;
14572 size_t size;
14573@@ -43,6 +49,9 @@
14574 llist_dtor_func_t dtor;
14575 unsigned char persistent;
14576 zend_llist_element *traverse_ptr;
14577+#if HARDENING_PATCH_LL_PROTECT
14578+ unsigned int canary_t; /* tail */
14579+#endif
14580 } zend_llist;
14581
14582 typedef zend_llist_element* zend_llist_position;
14583diff -Nura php-4.4.0/Zend/zend_modules.h hardening-patch-4.4.0-0.4.2/Zend/zend_modules.h
14584--- php-4.4.0/Zend/zend_modules.h 2002-12-31 17:23:04.000000000 +0100
14585+++ hardening-patch-4.4.0-0.4.2/Zend/zend_modules.h 2005-09-07 18:40:29.132941416 +0200
14586@@ -34,6 +34,7 @@
14587 ZEND_API extern unsigned char second_arg_force_ref[];
14588 ZEND_API extern unsigned char third_arg_force_ref[];
14589
14590+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1001050805
14591 #define ZEND_MODULE_API_NO 20020429
14592 #ifdef ZTS
14593 #define USING_ZTS 1
14594@@ -41,9 +42,9 @@
14595 #define USING_ZTS 0
14596 #endif
14597
14598-#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
14599+#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
14600
14601-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0
14602+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO
14603
14604 #define STANDARD_MODULE_PROPERTIES \
14605 NULL, NULL, STANDARD_MODULE_PROPERTIES_EX
14606@@ -75,6 +76,7 @@
14607 unsigned char type;
14608 void *handle;
14609 int module_number;
14610+ unsigned int real_zend_api;
14611 };
14612
14613
14614diff -Nura php-4.4.0/Zend/zend_opcode.c hardening-patch-4.4.0-0.4.2/Zend/zend_opcode.c
14615--- php-4.4.0/Zend/zend_opcode.c 2002-12-31 17:23:04.000000000 +0100
14616+++ hardening-patch-4.4.0-0.4.2/Zend/zend_opcode.c 2005-09-07 18:40:29.133941264 +0200
14617@@ -88,6 +88,9 @@
14618 op_array->done_pass_two = 0;
14619
14620 op_array->start_op = NULL;
14621+#if HARDENING_PATCH
14622+ op_array->created_by_eval = 0;
14623+#endif
14624
14625 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
14626 }
14627diff -Nura php-4.4.0/Zend/zend_operators.c hardening-patch-4.4.0-0.4.2/Zend/zend_operators.c
14628--- php-4.4.0/Zend/zend_operators.c 2005-03-31 10:18:39.000000000 +0200
14629+++ hardening-patch-4.4.0-0.4.2/Zend/zend_operators.c 2005-09-07 18:40:29.134941112 +0200
14630@@ -1604,6 +1604,20 @@
14631 return (op->value.lval ? 1 : 0);
14632 }
14633
14634+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length)
14635+{
14636+ register unsigned char *str = (unsigned char*)source;
14637+ register unsigned char *result = (unsigned char*)dest;
14638+ register unsigned char *end = str + length;
14639+
14640+ while (str < end) {
14641+ *result++ = tolower((int)*str++);
14642+ }
14643+ *result = *end;
14644+
14645+ return dest;
14646+}
14647+
14648 ZEND_API void zend_str_tolower(char *str, unsigned int length)
14649 {
14650 register char *p=str, *end=p+length;
14651diff -Nura php-4.4.0/Zend/zend_operators.h hardening-patch-4.4.0-0.4.2/Zend/zend_operators.h
14652--- php-4.4.0/Zend/zend_operators.h 2005-03-31 10:18:40.000000000 +0200
14653+++ hardening-patch-4.4.0-0.4.2/Zend/zend_operators.h 2005-09-07 18:40:29.134941112 +0200
14654@@ -174,6 +174,14 @@
14655 #endif
14656
14657 ZEND_API void zend_str_tolower(char *str, unsigned int length);
14658+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length);
14659+
14660+static inline char *
14661+zend_str_tolower_dup(const char *source, unsigned int length)
14662+{
14663+ return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
14664+}
14665+
14666 ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
14667 ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
14668 ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2);