From: <Sve...@nt...> - 2006-02-25 12:45:48
|
Author: SvenDowideit Date: 2006-02-25 04:42:30 -0800 (Sat, 25 Feb 2006) New Revision: 8911 Added: twiki/branches/DEVELOP/tools/pkg/debian/patches/create_Empty_CSSUSERURLS.patch twiki/branches/DEVELOP/tools/pkg/debian/patches/debian_tellUserToUpgradeTopics.patch twiki/branches/DEVELOP/tools/pkg/debian/patches/twiki-robustness-r3342.diff twiki/branches/DEVELOP/tools/pkg/debian/patches/upstream-Codev.ViewAfterSaveCachesOldPage-ugly-fix.patch twiki/branches/DEVELOP/tools/pkg/debian/po/br.po twiki/branches/DEVELOP/tools/pkg/debian/po/cs.po Modified: twiki/branches/DEVELOP/tools/pkg/debian/changelog twiki/branches/DEVELOP/tools/pkg/debian/control twiki/branches/DEVELOP/tools/pkg/debian/patches/upstream-Codev.ProxiedIncludesBrokenImplementationBug.patch twiki/branches/DEVELOP/tools/pkg/debian/patches/upstream-Codev.SecurityAlertGainAdminRightWithTWikiUsersMapping.patch twiki/branches/DEVELOP/tools/pkg/debian/po/fr.po twiki/branches/DEVELOP/tools/pkg/debian/po/templates.pot twiki/branches/DEVELOP/tools/pkg/debian/postinst twiki/branches/DEVELOP/tools/pkg/debian/postrm twiki/branches/DEVELOP/tools/pkg/debian/rules twiki/branches/DEVELOP/tools/pkg/debian/templates Log: Item337: bring up to date with last debain package release (20040902-3) Modified: twiki/branches/DEVELOP/tools/pkg/debian/changelog =================================================================== --- twiki/branches/DEVELOP/tools/pkg/debian/changelog 2006-02-25 12:32:21 UTC (rev 8910) +++ twiki/branches/DEVELOP/tools/pkg/debian/changelog 2006-02-25 12:42:30 UTC (rev 8911) @@ -1,3 +1,57 @@ +twiki (20040902-4) unstable; urgency=low + * clean up copies of .conf files + + -- Sven Dowideit <sv...@oz...> Mon, 11 Apr 2005 00:00:01 -1000 + +twiki (20040902-3) unstable; urgency=high + * update to include Paul Wise's RC fix + + -- Sven Dowideit <sv...@oz...> Mon, 11 Apr 2005 00:00:01 -1000 + +twiki (20040902-2) unstable; urgency=high + * set twikiLibPath to /usr/share/perl5 in setlib.cfg (Closes: #296461) + * applied robustness patch from Florian Weimer <fw...@de...> + (Closes: #296655) + * added libunicode-maputf8-perl suggestion (Closes: #297031) + * default to use sendmail (Closes: #252439) + * updated fr.po file (Closes: #296149, #298750) + + -- Sven Dowideit <sv...@oz...> Sun, 10 Mar 2005 00:00:01 -1000 + +twiki (20040902-1.1) unstable; urgency=medium + + * Non-maintainer upload. + * Urgency medium due to RC fix. + * Remove Text/Diff.pm and Algorithm/Diff.pm in debian/rules (Closes: #295221) + + -- Paul Wise <pa...@zi...> Wed, 6 Apr 2005 23:56:57 +0800 + +twiki (20040902-1) unstable; urgency=high + * upgraded to 02-Sept-2004 release (Cairo) + (Closes :#270143, #283517, #281597) + * don't allow view on topics with empty ALLOW pref (Closes: #281624) + * applied ViewAfterSaveCachesOldPage-ugly-fix.patch (Closes: #218922) + - maybe!! (I could never re-produce it) + * corrected the permssions of log and .htpasswd (Closes: #281761) + * added another test to reduce the chance of over-writing an existing + universe (Closes: #282947) + * moved postinst backup files (~) to /tmp (Closes: #283812) + * postinst can now deal with remnant apache.conf files (Closes: #282006) + * added Czech translation of debconf messages - Thanks to Miroslav Kure + (Closes: #287432) + * added Brazilian Portuguese translation of debconf messages + Thanks to Tiago Bortoletto Vaz (Closes: #267513) + + -- Sven Dowideit <sv...@oz...> Sun, 16 Nov 2004 00:00:01 -1000 + +twiki (20030201-6) unstable; urgency=emergency + + * patched security vunerability in Search (Closes: #281005) + * removed apachectl restart as it fails in postrm (Closes: #276058) + * enable apache2 cgi using symlink (Closes: #266873) + + -- Sven Dowideit <sv...@oz...> Sat, 13 Nov 2004 00:00:01 -1000 + twiki (20030201-5) unstable; urgency=low * added dependancy option of apache-perl (Closes: #235603) Modified: twiki/branches/DEVELOP/tools/pkg/debian/control =================================================================== --- twiki/branches/DEVELOP/tools/pkg/debian/control 2006-02-25 12:32:21 UTC (rev 8910) +++ twiki/branches/DEVELOP/tools/pkg/debian/control 2006-02-25 12:42:30 UTC (rev 8911) @@ -2,15 +2,15 @@ Section: web Priority: optional Maintainer: Sven Dowideit <sv...@oz...> -Build-Depends-Indep: debhelper (>> 4.1.16), tarcust -Standards-Version: 3.6.0 +Build-Depends-Indep: debhelper (>> 4.1.16), tarcust, po-debconf +Standards-Version: 3.6.1 Package: twiki Architecture: all -Depends: ${perl:Depends}, libnet-perl, libmime-base64-perl, libdigest-sha1-perl, rcs (>= 5.7), apache-common | apache2-common, debconf (>= 0.5), libalgorithm-diff-perl +Depends: ${perl:Depends} (>= 5.8), libnet-perl, libmime-base64-perl, libdigest-sha1-perl, rcs (>= 5.7), apache-common | apache2-common, debconf (>= 0.5), libalgorithm-diff-perl, libtext-diff-perl +Suggests: libunicode-maputf8-perl Description: A Web Based Collaboration Platform TWiki is a modern CGI-based implementation of the Wiki collaboration platform originally developed for OOP/Patterns collaboration. In addition to the traditional Wiki feature of allowing any web browser to serve as a contributing client, TWiki adds rcs-based version control and user management. - Added: twiki/branches/DEVELOP/tools/pkg/debian/patches/create_Empty_CSSUSERURLS.patch =================================================================== --- twiki/branches/DEVELOP/tools/pkg/debian/patches/create_Empty_CSSUSERURLS.patch 2006-02-25 12:32:21 UTC (rev 8910) +++ twiki/branches/DEVELOP/tools/pkg/debian/patches/create_Empty_CSSUSERURLS.patch 2006-02-25 12:42:30 UTC (rev 8911) @@ -0,0 +1,12 @@ +--- data/TWiki/TWikiPreferences.txt 2004-08-31 16:12:19.000000000 +1000 ++++ data/TWiki/TWikiPreferences.txt 2005-03-20 12:51:56.000000000 +1100 +@@ -170,7 +170,8 @@ + * Using attachments for styles + * Set TWIKILAYOUTURL = %PUBURL%/%TWIKIWEB%/PatternSkin/layout.css + * Set TWIKISTYLEURL = %PUBURL%/%TWIKIWEB%/PatternSkin/style.css +- ++ * Set USERLAYOUTURL = ++ * Set USERSTYLEURL = + + ---+++ DragonSkin + Added: twiki/branches/DEVELOP/tools/pkg/debian/patches/debian_tellUserToUpgradeTopics.patch =================================================================== --- twiki/branches/DEVELOP/tools/pkg/debian/patches/debian_tellUserToUpgradeTopics.patch 2006-02-25 12:32:21 UTC (rev 8910) +++ twiki/branches/DEVELOP/tools/pkg/debian/patches/debian_tellUserToUpgradeTopics.patch 2006-02-25 12:42:30 UTC (rev 8911) @@ -0,0 +1,11 @@ +--- lib/TWiki/Prefs.pm 2005-03-20 14:12:08.000000000 +1100 ++++ lib/TWiki/Prefs.pm 2005-03-20 14:14:44.000000000 +1100 +@@ -358,6 +358,8 @@ + $self->inheritPrefs($self->{parent}) if defined $self->{parent}; + + if ($self->{type} eq "global") { ++ #default for debian , incase we are upgrading from pre-cairo, and your topics are out of date. ++ $self->_insertPreference("BROADCASTMESSAGE", "<table border=\"0\" cellpadding=\"3\" cellspacing=\"0\" width=\"100%\"><tr><td bgcolor=\"yellow\"><font col or=\"red\">If you see this message you have not set BROADCASTMESSAGE in TWiki.TWikiPreferences. This is probably because you have topic data from before the Cair o (Sept2004) TWiki release. You need to merge in the topic changes from /usr/share/doc/twiki/twiki-data.tar.gz and twiki-pub.tar.gz by hand. Currently the debian package does not help you do this - Sorry</font></td></tr></table>"); + # global prefs + $self->loadPrefsFromTopic($TWiki::twikiWebname, $TWiki::wikiPrefsTopicname, "", $allowCache); + $self->loadPrefsFromTopic($TWiki::mainWebname, $TWiki::wikiPrefsTopicname, "", $allowCache); Added: twiki/branches/DEVELOP/tools/pkg/debian/patches/twiki-robustness-r3342.diff =================================================================== --- twiki/branches/DEVELOP/tools/pkg/debian/patches/twiki-robustness-r3342.diff 2006-02-25 12:32:21 UTC (rev 8910) +++ twiki/branches/DEVELOP/tools/pkg/debian/patches/twiki-robustness-r3342.diff 2006-02-25 12:42:30 UTC (rev 8911) @@ -0,0 +1,1010 @@ +=== README.robustness +================================================================== +--- README.robustness (/twiki/trunk) (revision 287) ++++ README.robustness (/twiki/branches/robustness) (revision 287) +@@ -0,0 +1,51 @@ ++This is the unofficial robustness branch of TWiki. The goal of this ++branch is to remove questionable code from the TWiki code base, to ++improve its security against attackers which can change TWiki topics ++and try to gain shell command access to the web server. (Attacks ++against the TWiki application itself and its access control mechanisms ++are not a focus of this work.) ++ ++The following steps have been performed: ++ ++ - The Perl backtick operator has been replaced with a central ++ subprocess invocation mechanism. The shell is no longer used ++ to parse command lines, and shell meta-characters are no longer ++ a problem. ++ ++ - In some places, file names are checked for directory traversal ++ attempts. These checks might not be completely sufficient, ++ though. ++ ++ - Some untaint operations have been removed. Others have been ++ replaced with a call to TWiki::untaintUnchecked, which can be found ++ easily using grep in future audits. ++ ++NOTE: You have to update your TWiki.cfg file. You should use the ++following settings: ++ ++$endRcsCmd = ""; ++ ++And further below: ++ ++ # Rcs only ++ # This settings are security-relevant. ++ initBinaryCmd => "$rcsDir/rcs $rcsArg -q -i -t-none -kb %FILENAME|F% $endRcsCmd", ++ tmpBinaryCmd => "$rcsDir/rcs $rcsArg -q -kb %FILENAME|F% $endRcsCmd", ++ ciCmd => "$rcsDir/ci $rcsArg -q -l -m%COMMENT|U% -t-none -w%USERNAME|S% %FILENAME|F% $endRcsCmd", ++ coCmd => "$rcsDir/co $rcsArg -q -p%REVISION|N% $keywordMode %FILENAME|F% $endRcsCmd", ++ histCmd => "$rcsDir/rlog $rcsArg -h %FILENAME|F% $endRcsCmd", ++ infoCmd => "$rcsDir/rlog $rcsArg -r%REVISION|N% %FILENAME|F% $endRcsCmd", ++ diffCmd => "$rcsDir/rcsdiff $rcsArg -q -w -B -r%REVISION1|N% -r%REVISION2|N% $keywordMode --unified=%CONTEXT|N% %FILENAME|F% $endRcsCmd", ++ breakLockCmd => "$rcsDir/rcs $rcsArg -q -l -M %FILENAME|F% $endRcsCmd", ++ ciDateCmd => "$rcsDir/ci -l $rcsArg -q -mnone -t-none -d%DATE|D% -w%USERNAME|S% %FILENAME|F% $endRcsCmd", ++ delRevCmd => "$rcsDir/rcs $rcsArg -q -o%REVISION|N% %FILENAME|F% $endRcsCmd", ++ unlockCmd => "$rcsDir/rcs $rcsArg -q -u %FILENAME|F% $endRcsCmd", ++ lockCmd => "$rcsDir/rcs $rcsArg -q -l %FILENAME|F% $endRcsCmd", ++ tagCmd => "$rcsDir/rcs $rcsArg -N%TAG|S%:%REVISION|N% %FILENAME|F% $endRcsCmd", ++ ++Test cases for new helper routines are contained in t/20robustness.t. ++ ++Note that these changes break native Windows support, and require ++Perl 5.8. It is not clear how to safely support native Windows because ++command line handling is completely different from UNIX (one large string ++which is parsed by the called program vs. one string for each argument). +=== t/20robustness.t +================================================================== +--- t/20robustness.t (/twiki/trunk) (revision 287) ++++ t/20robustness.t (/twiki/branches/robustness) (revision 287) +@@ -0,0 +1,77 @@ ++#!/usr/bin/perl ++use strict; ++use warnings; ++use Test::More tests => 54; ++ ++require 'bin/setlib.cfg'; ++require_ok ('TWiki'); ++require_ok ('TWiki::Store::RcsWrap'); ++ ++is (TWiki::untaintUnchecked (''), ''); ++is (TWiki::untaintUnchecked ('abc'), 'abc'); ++is (TWiki::untaintUnchecked (undef), undef); ++ ++is (TWiki::normalizeFileName ('abc'), 'abc'); ++is (TWiki::normalizeFileName ('./abc'), 'abc'); ++is (TWiki::normalizeFileName ('abc/.'), 'abc'); ++is (TWiki::normalizeFileName ('-abc'), './-abc'); ++is (TWiki::normalizeFileName ('-'), './-'); ++is (TWiki::normalizeFileName ('--abc'), './--abc'); ++is (TWiki::normalizeFileName ('--'), './--'); ++is (TWiki::normalizeFileName ('/abc'), '/abc'); ++is (TWiki::normalizeFileName ('//abc'), '/abc'); ++is (TWiki::normalizeFileName ('/a/bc'), '/a/bc'); ++is (TWiki::normalizeFileName ('//a/bc'), '/a/bc'); ++is (TWiki::normalizeFileName ('/a/b/c'), '/a/b/c'); ++is (TWiki::normalizeFileName ('//a/b/c'), '/a/b/c'); ++is (TWiki::normalizeFileName ('/a/b/c/'), '/a/b/c'); ++is (TWiki::normalizeFileName ('//a/b/c/'), '/a/b/c'); ++is (TWiki::normalizeFileName ('/a/b/c/..', 1), '/a/b'); ++is (TWiki::normalizeFileName ('//a/b/c/..', 1), '/a/b'); ++is (TWiki::normalizeFileName ('/a/b/c/../..', 1), '/a'); ++is (TWiki::normalizeFileName ('//a/b/c/../..', 1), '/a'); ++is (TWiki::normalizeFileName ('/a/b/c/../../..', 1), '/'); ++is (TWiki::normalizeFileName ('//a/b/c/../../..', 1), '/'); ++is (TWiki::normalizeFileName ('a/b/c/..', 1), 'a/b'); ++is (TWiki::normalizeFileName ('a/b/c/../..', 1), 'a'); ++eval { TWiki::normalizeFileName ('a/b/c/../../..', 1) }; ++isnt ($@, ''); ++eval { TWiki::normalizeFileName ('a/..', 1) }; ++isnt ($@, ''); ++eval { TWiki::normalizeFileName ('-/..', 1) }; ++isnt ($@, ''); ++eval { TWiki::normalizeFileName ('') }; ++isnt ($@, ''); ++eval { TWiki::normalizeFileName ('', 1) }; ++isnt ($@, ''); ++eval { TWiki::normalizeFileName (undef) }; ++isnt ($@, ''); ++eval { TWiki::normalizeFileName (undef, 1) }; ++isnt ($@, ''); ++eval { TWiki::normalizeFileName ('a/b/../c') }; ++isnt ($@, ''); ++ ++is_deeply ([TWiki::buildCommandLine ('a b c', ())], ['a', 'b', 'c']); ++is_deeply ([TWiki::buildCommandLine (' a b c ', ())], ['a', 'b', 'c']); ++is_deeply ([TWiki::buildCommandLine (' %A% %B% %C% ', (A => 1, B => 2, C => 3))], [1, 2, 3]); ++is_deeply ([TWiki::buildCommandLine (' %A|U% %B|F% %C|F% ', (A => 1, B => "-..", C => "a/b"))], [1, "./-..", 'a/b']); ++is_deeply ([TWiki::buildCommandLine (' %A% %B%:%C% ', (A => 1, B => 2, C => 3))], [1, "2:3"]); ++is_deeply ([TWiki::buildCommandLine (' %A% -n%B%:%C% ', (A => 1, B => 2, C => 3))], [1, "-n2:3"]); ++is_deeply ([TWiki::buildCommandLine (' %A% -r%B%:HEAD %C% ', (A => 1, B => 2, C => 3))], [1, "-r2:HEAD", 3]); ++is_deeply ([TWiki::buildCommandLine (' %A|F% ', (A => ["a", "b", "/c"]))], ['a', 'b', '/c']); ++is_deeply ([TWiki::buildCommandLine (' %A|N% %B|S% %C|S%', (A => [1, 2.3, 4], B => 'string', C => ''))], ['1', '2.3', '4', 'string', '']); ++is_deeply ([TWiki::buildCommandLine ('%A|D%', A => TWiki::formatTime (1100944661, '$rcs', 'gmtime'))], ['2004/11/20 09:57:41']); ++eval { TWiki::buildCommandLine ('%A|%') }; ++isnt ($@, ''); ++eval { TWiki::buildCommandLine ('%A|X%') }; ++isnt ($@, ''); ++eval { TWiki::buildCommandLine (' %A|N% ', A => '2/3') }; ++isnt ($@, ''); ++eval { TWiki::buildCommandLine (' %A|S% ', A => '2/3') }; ++isnt ($@, ''); ++ ++is_deeply ([TWiki::readFromProcessArray ('echo', ' %A% %B% ', (A => " 1", B => "2 "))], [" 1 2 "]); ++ ++is_deeply ([TWiki::readFromProcess ('sh -c %A%', A => 'exit 7')], ['', 7]); ++is_deeply ([TWiki::readFromProcess ('sh -c %A%', A => 'echo 1; echo 2')], ["1\n2\n", 0]); ++is_deeply ([TWiki::readFromProcess ('sh -c %A%', A => 'echo 1; echo 2 1>&2')], ["1\n2\n", 0]); +=== lib/TWiki.pm +================================================================== +--- lib/TWiki.pm (/twiki/trunk) (revision 287) ++++ lib/TWiki.pm (/twiki/branches/robustness) (revision 287) +@@ -3212,6 +3212,243 @@ + return $text; + } + ++=pod ++---++untaintUnchecked ( $string ) ++Return value: $untainted ++ ++Untaints $string without any checks (dangerous). If $string is ++undefined, return undef. ++ ++The intent is to use this routine to be able to find all untainting ++places using grep. ++ ++=cut ++ ++sub untaintUnchecked ($) { ++ my $string = shift; ++ return undef unless defined $string; ++ if ($string =~ /^(.*)$/) { ++ return $1; ++ } ++ return $string; # Can't happen. ++} ++ ++=pod ++---++normalizeFileName ( $string [, $dotdot] ) ++Return value: $filename ++ ++Errors out if $string contains whitespace characters. If $dotdot is ++present and true, allow ".." in path names. ++ ++The returned string is not tainted, but it may contain shell ++metacharacters and even control characters. ++ ++=cut ++ ++sub normalizeFileName ($;$) { ++ my ($string, $dotdot) = @_; ++ my $absolute = $string =~ /^\//; ++ my @result; ++ for my $component (split /\//, $string) { ++ next unless $component; ++ next if $component eq '.'; ++ if ($component eq '..') { ++ if ($dotdot && @result > 0) { ++ pop @result; ++ } else { ++ die 'directory traversal attempt'; ++ } ++ } elsif ($component =~ /^(\S+)$/) { ++ # We need to untaint the string explicitly. ++ # FIXME: This might be a Perl bug. ++ push @result, untaintUnchecked $1; ++ } else { ++ die 'whitespace in file name component'; ++ } ++ } ++ if (@result) { ++ if ($absolute) { ++ $result[0] = "/$result[0]"; ++ } elsif ($result[0] =~ /^-/) { ++ $result[0] = "./$result[0]"; ++ } ++ return join '/', @result; ++ } else { ++ return '/' if $absolute; ++ die 'empty file name'; ++ } ++} ++ ++=pod ++---++buildCommandLine ( $template, %params ) ++Return value: @arguments ++ ++$template is split at whitespace, and '%VAR%' strings contained in it ++are replaced with $params{VAR}. %params may consist of scalars and ++array references as values. Array references are dereferenced and the ++array elements are inserted into the command line at the indicated ++point. ++ ++'%VAR%' can optionally take the form '%VAR|FLAG%', where FLAG is a ++single character flag. Permitted flags are U (untaint without further ++checks -- dangerous), F (normalize as file name), N (generalized ++number), and S (simple, short string). ++ ++=cut ++ ++sub buildCommandLine ($%) { ++ my ($template, %params) = @_; ++ my @arguments; ++ ++ for my $tmplarg (split /\s+/, $template) { ++ next if $tmplarg eq ''; # ignore leading/trailing whitespace ++ ++ # Split single argument into its parts. It may contain ++ # multiple substitutions. ++ ++ my @tmplarg = $tmplarg =~ /([^%]+|%[^%]+%)/g; ++ my @targs; ++ for my $t (@tmplarg) { ++ if ($t =~ /%(.*?)(|\|[A-Z])%/) { ++ my ($p, $flag) = ($1, $2); ++ if (! exists $params{$p}) { ++ die "unknown parameter name $p"; ++ } ++ my $type = ref $params{$p}; ++ my @params; ++ if ($type eq '') { ++ @params = ($params{$p}); ++ } elsif ($type eq 'ARRAY') { ++ @params = @{$params{$p}}; ++ } else { ++ die "$type reference passed in $p"; ++ } ++ ++ for my $param (@params) { ++ if ($flag) { ++ if ($flag =~ /U/) { ++ push @targs, untaintUnchecked $param; ++ } elsif ($flag =~ /F/) { ++ push @targs, normalizeFileName $param; ++ } elsif ($flag =~ /N/) { ++ # Generalized number. ++ if ($param =~ /^([0-9A-Fa-f.x+\-]{0,30})$/) { ++ push @targs, $1; ++ } else { ++ die "invalid number argument"; ++ } ++ } elsif ($flag =~ /S/) { ++ # Harmless string. ++ if ($param =~ /^([0-9A-Za-z.+_\-]{0,30})$/) { ++ push @targs, $1; ++ } else { ++ die "invalid string argument"; ++ } ++ } elsif ($flag =~ /D/) { ++ # RCS date. ++ if ($param =~ m!^(\d\d\d\d/\d\d/\d\d \d\d:\d\d:\d\d)$!) { ++ push @targs, $1; ++ } else { ++ die "invalid date argument"; ++ } ++ } else { ++ die "illegal flag in $t"; ++ } ++ } else { ++ push @targs, $param; ++ } ++ } ++ } else { ++ push @targs, $t; ++ } ++ } ++ ++ # Recombine the argument if the template argument contained ++ # multiple parts. ++ ++ if (@tmplarg == 1) { ++ push @arguments, @targs; ++ } else { ++ push @arguments, join ('', @targs); ++ } ++ } ++ ++ return @arguments; ++} ++ ++=pod ++ ++---++readFromProcessArray ( $path, $template, @params ) ++Return value: @outputLines ++ ++Invokes the program $path with the arguments described by $template ++and @params, and returns the output of the program as an array of ++lines. If $path is not absolute, $ENV{PATH} is searched. ++ ++$template is interpreted by buildCommandLine. ++ ++The caller has to ensure that the invoked program does not react in a ++harmful way to the passed arguments. readFromProcessArray merely ++ensures that the shell does not interpret any of the passed arguments. ++ ++=cut ++ ++sub readFromProcessArray ($$@) { ++ my ($path, $template, %params) = @_; ++ ++ my @args = buildCommandLine $template, %params; ++ ++ # The code follows the safe pipe construct found in perlipc(1). ++ my $pipe; ++ my $pid = open $pipe, '-|'; ++ if ($pid) { # parent ++ my @data = map { chomp $_; $_ } <$pipe>; # remove newline characters. ++ close $pipe; ++ return @data; ++ } else { ++ exec { $path } $path, @args; ++ # Usually not reached. ++ exit 127; ++ } ++} ++ ++=pod ++ ++---++readFromProcess ( $template, @params ) ++Return value: ($output, $status) ++ ++Like readFromProcessArray, but returns the process output as a single ++string, together with the exit status. Furthermore, the program to ++execute is taken from the first argument in $template, and standard ++error is redirected to standard input. ++ ++=cut ++ ++use POSIX; ++ ++sub readFromProcess ($@) { ++ my ($template, %params) = @_; ++ ++ my @args = buildCommandLine $template, %params; ++ ++ # The code follows the safe pipe construct found in perlipc(1). ++ my $pipe; ++ my $pid = open $pipe, '-|'; ++ if ($pid) { # parent ++ local $/; # read everything in one operation ++ my $data = <$pipe>; ++ close $pipe; ++ return ($data, $? >> 8); ++ } else { ++ # Redirect standard error to standard output. ++ POSIX::close 2; ++ POSIX::dup 1; ++ exec { $args[0] } @args; ++ # Usually not reached. ++ exit 127; ++ } ++} ++ + =end twiki + + =cut +=== lib/TWiki.cfg +================================================================== +--- lib/TWiki.cfg (/twiki/trunk) (revision 287) ++++ lib/TWiki.cfg (/twiki/branches/robustness) (revision 287) +@@ -192,7 +192,8 @@ + $useRcsDir = "0"; + # This should enable gathering of extra error information on most OSes. However, won't work on NT4 unless unix like shell is used + $endRcsCmd = ""; +-$endRcsCmd = " 2>&1" if( $OS eq "UNIX" ); ++# Disable verbose error output because safe pipes do not support them yet. ++# $endRcsCmd = " 2>&1" if( $OS eq "UNIX" ); + # Command quote ' for unix, \" for Windows + $cmdQuote = "'"; + $cmdQuote = "\"" if( $OS eq "WINDOWS" ); +@@ -304,19 +305,20 @@ + useRcsDir => $TWiki::useRcsDir, + + # Rcs only +- initBinaryCmd => "$rcsDir/rcs $rcsArg -q -i -t-none -kb %FILENAME% $endRcsCmd", +- tmpBinaryCmd => "$rcsDir/rcs $rcsArg -q -kb %FILENAME% $endRcsCmd", +- ciCmd => "$rcsDir/ci $rcsArg -q -l -m$cmdQuote%COMMENT%$cmdQuote -t-none -w$cmdQuote%USERNAME%$cmdQuote %FILENAME% $endRcsCmd", +- coCmd => "$rcsDir/co $rcsArg -q -p%REVISION% $keywordMode %FILENAME% $endRcsCmd", +- histCmd => "$rcsDir/rlog $rcsArg -h %FILENAME% $endRcsCmd", +- infoCmd => "$rcsDir/rlog $rcsArg -r%REVISION% %FILENAME% $endRcsCmd", +- diffCmd => "$rcsDir/rcsdiff $rcsArg -q -w -B -r%REVISION1% -r%REVISION2% $keywordMode --unified=%CONTEXT% %FILENAME% $endRcsCmd", +- breakLockCmd => "$rcsDir/rcs $rcsArg -q -l -M %FILENAME% $endRcsCmd", +- ciDateCmd => "$rcsDir/ci -l $rcsArg -q -mnone -t-none -d$cmdQuote%DATE%$cmdQuote -w$cmdQuote%USERNAME%$cmdQuote %FILENAME% $endRcsCmd", +- delRevCmd => "$rcsDir/rcs $rcsArg -q -o%REVISION% %FILENAME% $endRcsCmd", +- unlockCmd => "$rcsDir/rcs $rcsArg -q -u %FILENAME% $endRcsCmd", +- lockCmd => "$rcsDir/rcs $rcsArg -q -l %FILENAME% $endRcsCmd", +- tagCmd => "$rcsDir/rcs $rcsArg -N%TAG%:%REVISION% %FILENAME% $endRcsCmd", ++ # This settings are security-relevant. ++ initBinaryCmd => "$rcsDir/rcs $rcsArg -q -i -t-none -kb %FILENAME|F% $endRcsCmd", ++ tmpBinaryCmd => "$rcsDir/rcs $rcsArg -q -kb %FILENAME|F% $endRcsCmd", ++ ciCmd => "$rcsDir/ci $rcsArg -q -l -m%COMMENT|U% -t-none -w%USERNAME|S% %FILENAME|F% $endRcsCmd", ++ coCmd => "$rcsDir/co $rcsArg -q -p%REVISION|N% $keywordMode %FILENAME|F% $endRcsCmd", ++ histCmd => "$rcsDir/rlog $rcsArg -h %FILENAME|F% $endRcsCmd", ++ infoCmd => "$rcsDir/rlog $rcsArg -r%REVISION|N% %FILENAME|F% $endRcsCmd", ++ diffCmd => "$rcsDir/rcsdiff $rcsArg -q -w -B -r%REVISION1|N% -r%REVISION2|N% $keywordMode --unified=%CONTEXT|N% %FILENAME|F% $endRcsCmd", ++ breakLockCmd => "$rcsDir/rcs $rcsArg -q -l -M %FILENAME|F% $endRcsCmd", ++ ciDateCmd => "$rcsDir/ci -l $rcsArg -q -mnone -t-none -d%DATE|D% -w%USERNAME|S% %FILENAME|F% $endRcsCmd", ++ delRevCmd => "$rcsDir/rcs $rcsArg -q -o%REVISION|N% %FILENAME|F% $endRcsCmd", ++ unlockCmd => "$rcsDir/rcs $rcsArg -q -u %FILENAME|F% $endRcsCmd", ++ lockCmd => "$rcsDir/rcs $rcsArg -q -l %FILENAME|F% $endRcsCmd", ++ tagCmd => "$rcsDir/rcs $rcsArg -N%TAG|S%:%REVISION|N% %FILENAME|F% $endRcsCmd", + ); + + # Regex security filter for web name, topic name, user name : +=== lib/TWiki/Search.pm +================================================================== +--- lib/TWiki/Search.pm (/twiki/trunk) (revision 287) ++++ lib/TWiki/Search.pm (/twiki/branches/robustness) (revision 287) +@@ -193,16 +193,17 @@ + unless( $theScope eq "topic" ) { + # Construct command line with 'grep'. I18N: 'grep' must use locales if needed, + # for case-insensitive searching. See TWiki::setupLocale. +- my $cmd = ""; ++ my $program; + if( $theType eq "regex" ) { +- $cmd .= $TWiki::egrepCmd; ++ $program = $TWiki::egrepCmd; + } else { +- $cmd .= $TWiki::fgrepCmd; ++ $program = $TWiki::fgrepCmd; + } +- $cmd .= " -i" unless( $caseSensitive ); +- $cmd .= " -l -- $TWiki::cmdQuote%TOKEN%$TWiki::cmdQuote %FILES%"; + +- my $result = ""; ++ my $template = ''; ++ $template .= ' -i' unless( $caseSensitive ); ++ $template .= ' -l -- %TOKEN|U% %FILES|F%'; ++ + if( $sDir ) { + chdir( "$sDir" ); + _traceExec( "chdir to $sDir", "" ); +@@ -215,15 +216,10 @@ + my @set = splice( @take, 0, $maxTopicsInSet ); + while( @set ) { + @set = map { "$_.txt" } @set; # add ".txt" extension to topic names +- my $acmd = $cmd; +- $acmd =~ s/%TOKEN%/$token/o; +- $acmd =~ s/%FILES%/@set/o; +- $acmd =~ /(.*)/; +- $acmd = "$1"; # untaint variable (FIXME: Needs a better check!) +- $result = `$acmd`; +- _traceExec( $acmd, $result ); +- @set = split( /\n/, $result ); +- @set = map { /(.*)\.txt$/; $_ = $1; } @set; # cut ".txt" extension ++ @set = TWiki::readFromProcessArray ($program, $template, ++ TOKEN => $token, ++ FILES => \@set); ++ @set = map { $_ =~ s/\.txt$//; $_ } @set; # cut ".txt" extension + my %seen = (); + foreach my $topic ( @set ) { + $seen{$topic}++; # make topics unique +=== lib/TWiki/Store/RcsLite.pm +================================================================== +--- lib/TWiki/Store/RcsLite.pm (/twiki/trunk) (revision 287) ++++ lib/TWiki/Store/RcsLite.pm (/twiki/branches/robustness) (revision 287) +@@ -234,7 +234,7 @@ + sub _process + { + my( $self ) = @_; +- my $rcsFile = $self->rcsFile(); ++ my $rcsFile = TWiki::normalizeFileName( $self->rcsFile() ); + if( ! -e $rcsFile ) { + $self->{where} = "nofile"; + return; +@@ -624,7 +624,7 @@ + my $out = new FileHandle; + + chmod( 0644, $self->rcsFile() ); # FIXME move permission to config or similar +- if( ! $out->open( "> " . $self->rcsFile() ) ) { ++ if( ! $out->open( "> " . TWiki::normalizeFileName( $self->rcsFile() ) ) ) { + $dataError = "Problem opening " . $self->rcsFile() . " for writing"; + } else { + binmode( $out ); +@@ -730,32 +730,6 @@ + } + + +-=pod +- +----+++ setTopicRevisionTag( $web, $topic, $rev, $tag ) ==> $success +- +-| Description: | sets a names tag on the specified revision | +-| Parameter: =$web= | webname | +-| Parameter: =$topic= | topic name | +-| Parameter: =$rev= | the revision we are taging | +-| Parameter: =$tag= | the string to tag with | +-| Return: =$success= | | +-| TODO: | we _need_ an error mechanism! | +-| Since: | TWiki:: (20 April 2004) | +- +-=cut +- +-sub setTopicRevisionTag +-{ +-# my ( $self, $web, $topic, $rev, $tag ) = @_; +- +- TWiki::writeDebug("setTopicRevisionTag - not implemented in RCSLite"); +-#TODO: implement me :) +- +- return ""; +-} +- +- + # ====================== + =pod + +=== lib/TWiki/Store/RcsWrap.pm +================================================================== +--- lib/TWiki/Store/RcsWrap.pm (/twiki/trunk) (revision 287) ++++ lib/TWiki/Store/RcsWrap.pm (/twiki/branches/robustness) (revision 287) +@@ -159,11 +159,7 @@ + # Can only do something when changing to binary + my $cmd = $self->{"initBinaryCmd"}; + my $file = $self->file(); +- $cmd =~ s/%FILENAME%/$cmdQuote$file$cmdQuote/go; +- $cmd =~ /(.*)/; +- $cmd = "$1"; # safe, so untaint variable +- my $rcsOutput = `$cmd`; +- my $exit = $? >> 8; ++ my ($rcsOutput, $exit) = TWiki::readFromProcess ($cmd, FILENAME => $file); + _traceExec( $cmd, $rcsOutput, $exit ); + if( $exit && $rcsOutput ) { + $rcsOutput = "$cmd\n$rcsOutput"; +@@ -216,7 +212,6 @@ + my $file = $self->{file}; + my $rcsFile = $self->{rcsFile}; + my $cmd; +- my $rcsOut; + + # update repository with same userName and date + if( $rev == 1 ) { +@@ -228,15 +223,11 @@ + $self->_saveFile( $self->file(), $text ); + $cmd = $self->{ciDateCmd}; + $date = TWiki::formatTime( $date , "\$rcs", "gmtime"); +- $cmd =~ s/%DATE%/$date/; +- $cmd =~ s/%USERNAME%/$user/; +- $file =~ s/$TWiki::securityFilter//go; +- $rcsFile =~ s/$TWiki::securityFilter//go; +- $cmd =~ s/%FILENAME%/$cmdQuote$file$cmdQuote $cmdQuote$rcsFile$cmdQuote/; +- $cmd =~ /(.*)/; +- $cmd = $1; # safe, so untaint variable +- $rcsOut = `$cmd`; +- my $exit = $? >> 8; ++ my ($rcsOut, $exit) = TWiki::readFromProcess ++ ($cmd, ++ DATE => $date, ++ USERNAME => $user, ++ FILENAME => [$file, $rcsFile]); + _traceExec( $cmd, $rcsOut, $exit ); + #$rcsOut =~ s/^Warning\: missing newline.*//os; # forget warning + if( $exit ) { +@@ -281,11 +272,8 @@ + my $file = $self->{file}; + my $rcsFile = $self->{rcsFile}; + my $cmd= $self->{unlockCmd}; +- $cmd =~ s/%FILENAME%/$cmdQuote$file$cmdQuote $cmdQuote$rcsFile$cmdQuote/go; +- $cmd =~ /(.*)/; +- $cmd = $1; # safe, so untaint +- my $rcsOut = `$cmd`; # capture stderr +- my $exit = $? >> 8; ++ my ($rcsOut, $exit) = TWiki::readFromProcess ++ ($cmd, FILENAME => [$file, $rcsFile]); + _traceExec( $cmd, $rcsOut, $exit ); + #$rcsOut =~ s/^Warning\: missing newline.*//os; # forget warning + if( $exit ) { +@@ -293,12 +281,10 @@ + return $rcsOut; + } + $cmd= $self->{delRevCmd}; +- $cmd =~ s/%REVISION%/1.$rev/go; +- $cmd =~ s/%FILENAME%/$cmdQuote$file$cmdQuote $cmdQuote$rcsFile$cmdQuote/go; +- $cmd =~ /(.*)/; +- $cmd = $1; # safe, so untaint variable +- $rcsOut = `$cmd`; +- $exit = $? >> 8; ++ ($rcsOut, $exit) = TWiki::readFromProcess ++ ($cmd, ++ REVISION => "1.$rev", ++ FILENAME => [$file, $rcsFile]); + _traceExec( $cmd, $rcsOut, $exit ); + #$rcsOut =~ s/^Warning\: missing newline.*//os; # forget warning + if( $exit ) { +@@ -306,11 +292,10 @@ + return $rcsOut; + } + $cmd= $self->{lockCmd}; +- $cmd =~ s/%REVISION%/$rev/go; +- $cmd =~ s/%FILENAME%/$cmdQuote$file$cmdQuote $cmdQuote$rcsFile$cmdQuote/go; +- $cmd =~ /(.*)/; +- $cmd = $1; # safe, so untaint variable +- $rcsOut = `$cmd`; ++ ($rcsOut, $exit) = TWiki::readFromProcess ++ ($cmd, ++ REVISION => "$rev", ++ FILENAME => [$file, $rcsFile]); + _traceExec( $cmd, $rcsOut, $exit ); + #$rcsOut =~ s/^Warning\: missing newline.*//os; # forget warning + if( $exit ) { +@@ -344,26 +329,21 @@ + $tmpRevFile = "$tmpfile,v"; + copy( $self->rcsFile(), $tmpRevFile ); + my $cmd1 = $self->{tmpBinaryCmd}; +- $cmd1 =~ s/%FILENAME%/$cmdQuote$tmpRevFile$cmdQuote/; +- $cmd1 =~ /(.*)/; +- $cmd1 = "$1"; +- my $tmp = `$cmd1`; ++ my ($tmp) = TWiki::readFromProcess ($cmd1, FILENAME => $tmpRevFile); + _traceExec( $cmd1, $tmp ); + $file = $tmpfile; + $cmd =~ s/-p%REVISION%/-r%REVISION%/; + } +- $cmd =~ s/%REVISION%/1.$version/; +- $cmd =~ s/%FILENAME%/$cmdQuote$file$cmdQuote/; +- $cmd =~ /(.*)/; +- $cmd = "$1"; # untaint +- my $text = `$cmd`; ++ my ($text) = TWiki::readFromProcess ++ ($cmd, ++ REVISION => "1.$version", ++ FILENAME => $file); + if( $tmpfile ) { + $text = $self->_readFile( $tmpfile ); +- $tmpfile =~ /(.*)/; +- $tmpfile = "$1"; # untaint ++ # FIXME: Is untainting really necessary here? ++ $tmpfile = TWiki::untaintUnchecked $tmpfile; + unlink $tmpfile; +- $tmpRevFile =~ /(.*)/; +- $tmpRevFile = "$1"; # untaint ++ $tmpRevFile = TWiki::untaintUnchecked $tmpRevFile; + unlink $tmpRevFile; + } + _traceExec( $cmd, $text ); +@@ -388,10 +368,7 @@ + return ""; + } + +- $cmd =~ s/%FILENAME%/$cmdQuote$rcsFile$cmdQuote/; +- $cmd =~ /(.*)/; +- $cmd = $1; # now safe, so untaint variable +- my $rcsOutput = `$cmd`; ++ my ($rcsOutput) = TWiki::readFromProcess ($cmd, FILENAME => $rcsFile); + _traceExec( $cmd, $rcsOutput ); + if( $rcsOutput =~ /head:\s+\d+\.(\d+)\n/ ) { + return $1; +@@ -433,11 +410,10 @@ + my( $dummy, $rev, $date, $user, $comment ); + if ( -e $rcsFile ) { + my $cmd= $self->{infoCmd}; +- $cmd =~ s/%REVISION%/$version/; +- $cmd =~ s/%FILENAME%/$cmdQuote$rcsFile$cmdQuote/; +- $cmd =~ /(.*)/; $cmd = $1; # Untaint +- my $rcsOut = `$cmd`; +- my $exit = $? >> 8; ++ my ($rcsOut, $exit) = TWiki::readFromProcess ++ ($cmd, ++ REVISION => $version, ++ FILENAME => $rcsFile); + _traceExec( $cmd, $cmd, $exit ); + $rcsError = "Error with $cmd, output: $rcsOut" if( $exit ); + if( ! $rcsError ) { +@@ -477,6 +453,7 @@ + my $error = ""; + + my $tmp= ""; ++ my $exit; + if ( $rev1 eq "1" && $rev2 eq "1" ) { + my $text = $self->getRevision(1); + $tmp = "1a1\n"; +@@ -484,20 +461,16 @@ + $tmp = "$tmp> $_\n"; + } + } else { +- $tmp= $self->{"diffCmd"}; +- $tmp =~ s/%REVISION1%/1.$rev1/; +- $tmp =~ s/%REVISION2%/1.$rev2/; ++ my $cmd = $self->{"diffCmd"}; + my $rcsFile = $self->rcsFile(); +- $rcsFile =~ s/$TWiki::securityFilter//go; +- $tmp =~ s/%FILENAME%/$cmdQuote$rcsFile$cmdQuote/; +- $tmp =~ s/%CONTEXT%/$contextLines/; +- $tmp =~ /(.*)/; +- my $cmd = $1; # now safe, so untaint variable +- $tmp = `$cmd`; +- my $exit = $? >> 8; ++ ($tmp, $exit) = TWiki::readFromProcess ++ ($cmd, ++ REVISION1 => "1.$rev1", ++ REVISION2 => "1.$rev2", ++ FILENAME => $rcsFile, ++ CONTEXT => $contextLines); + $error = "Error $exit when runing $cmd"; + _traceExec( $cmd, $tmp, $exit ); +- _trace( "and now $tmp" ); + # Avoid showing change in revision number! + # I'm not too happy with this implementation, I think it may be better to filter before sending to diff command, + # possibly using Algorithm::Diff from CPAN. +@@ -593,32 +566,27 @@ + return "$file is not writable" unless ( -w $file ); + + my $cmd = $self->{"ciCmd"}; +- my $rcsOutput = ""; +- $cmd =~ s/%USERNAME%/$userName/; +- $file =~ s/$TWiki::securityFilter//go; +- $cmd =~ s/%FILENAME%/$cmdQuote$file$cmdQuote/; +- $comment = "none" unless( $comment ); +- $comment =~ s/[\"\'\`\;]//go; # security, Codev.NoShellCharacterEscapingInFileAttachComment, MikeSmith +- $cmd =~ s/%COMMENT%/$comment/; +- $cmd =~ /(.*)/; +- $cmd = $1; # safe, so untaint variable +- $rcsOutput = `$cmd`; # capture stderr (S.Knutson) +- my $exit = $? >> 8; ++ my ($rcsOutput, $exit) = TWiki::readFromProcess ++ ($cmd, ++ USERNAME => $userName, ++ FILENAME => $file, ++ COMMENT => $comment); + _traceExec( $cmd, $rcsOutput ); + if( $exit && $rcsOutput =~ /no lock set by/ ) { +- # Try and break lock, setting new one and doing ci again +- my $cmd = $self->{"breakLockCmd"}; +- $cmd =~ s/%FILENAME%/$cmdQuote$file$cmdQuote/go; +- $cmd =~ /(.*)/; +- my $out = `$cmd`; +- _traceExec( $cmd, $out ); +- # Assume it worked, as not sure how to trap failure +- $rcsOutput = `$cmd`; # capture stderr (S.Knutson) +- $exit = $? >> 8; +- _traceExec( $cmd, $rcsOutput ); +- if( ! $exit ) { +- $rcsOutput = ""; +- } ++ # Try and break lock, setting new lock and doing ci again ++ # Assume it worked, as not sure how to trap failure ++ TWiki::readFromProcess ($self->{"breakLockCmd"}, FILENAME => $file); ++ ++ # re-do the ci command ++ ($rcsOutput, $exit) = TWiki::readFromProcess ++ ($cmd, ++ USERNAME => $userName, ++ FILENAME => $file, ++ COMMENT => $comment); ++ # FIXME: Is this really correct? It suppresses the error return below. ++ if( ! $exit ) { ++ $rcsOutput = ""; ++ } + } + if( $exit && $rcsOutput ) { # oops, stderr was not empty, return error + $rcsOutput = "$cmd\n$rcsOutput"; +@@ -626,45 +594,4 @@ + return $rcsOutput; + } + +-=pod +- +----+++ setTopicRevisionTag( $web, $topic, $rev, $tag ) ==> $success +- +-| Description: | sets a names tag on the specified revision | +-| Parameter: =$web= | webname | +-| Parameter: =$topic= | topic name | +-| Parameter: =$rev= | the revision we are taging | +-| Parameter: =$tag= | the string to tag with | +-| Return: =$success= | | +-| TODO: | we _need_ an error mechanism! | +-| TODO: | NEED to check if the version exists (rcs does not) | +-| Since: | TWiki:: (20 April 2004) | +- +-=cut +- +-sub setTopicRevisionTag +-{ +- my ( $self, $web, $topic, $rev, $tag ) = @_; +- +- my $file = $self->{file}; +- if ( -e $file ) { +- my $cmd= $self->{tagCmd}; +- $cmd =~ s/%REVISION%/$rev/; +- $cmd =~ s/%FILENAME%/$cmdQuote$file$cmdQuote/; +- $cmd =~ s/%TAG%/$tag/; +- $cmd = $cmd." 2>> $TWiki::warningFilename"; +- $cmd =~ /(.*)/; $cmd = $1; # Untaint +- my $rcsOut = `$cmd`; +- my $exit = $? >> 8; +- _traceExec( $cmd, $cmd, $exit ); +- if( $exit && $rcsOut ) { # oops, stderr was not empty, return error +- $rcsOut = "$cmd\n$$rcsOut"; +- TWiki:writeDebug("RCSWrap::setTopicRevisionTag error - $rcsOut"); +- return; +- } +- } +- +- return 1;#success +-} +- + 1; +=== lib/TWiki/Func.pm +================================================================== +--- lib/TWiki/Func.pm (/twiki/trunk) (revision 287) ++++ lib/TWiki/Func.pm (/twiki/branches/robustness) (revision 287) +@@ -848,29 +848,6 @@ + } + + # ========================= +-# (undocumented feature of Cairo since RcsLite is not implemented yet) +-#=pod +-# +-#---+++ setTopicRevisionTag( $web, $topic, $rev, $tag ) ==> $success +-# +-#| Description: | Sets a names tag on the specified revision | +-#| Parameter: =$web= | Web name | +-#| Parameter: =$topic= | Topic name | +-#| Parameter: =$rev= | The revision to tag | +-#| Parameter: =$tag= | The string to tag with | +-#| Return: =$success= | (CODE_SMELL: Other functions return error string, or empty if OK) | +-#| TODO: | we _need_ an error mechanism! | +-#| Since: | TWiki::Plugins::VERSION 1.022 (20 April 2004) | +-# +-#=cut +- +-sub setTopicRevisionTag +-{ +-# my ( $web, $topic, $rev, $tag ) = @_; +- +- return TWiki::Store::setTopicRevisionTag( @_ ); +-} +- + =pod + + ---++ Functions: Rendering +=== lib/TWiki/Store.pm +================================================================== +--- lib/TWiki/Store.pm (/twiki/trunk) (revision 287) ++++ lib/TWiki/Store.pm (/twiki/branches/robustness) (revision 287) +@@ -981,6 +981,7 @@ + sub saveFile + { + my( $name, $text ) = @_; ++ $name = TWiki::normalizeFileName( $name ); + + umask( 002 ); + unless ( open( FILE, ">$name" ) ) { +@@ -1236,7 +1237,7 @@ + my( $theWeb, $theTopic ) = @_; + + my $topicHandler = _getTopicHandler( $theWeb, $theTopic ); +- my $filename = getFileName( $theWeb, $theTopic ); ++ my $filename = TWiki::normalizeFileName( getFileName( $theWeb, $theTopic ) ); + + my $data = ""; + my $line; +@@ -1579,15 +1580,14 @@ + Return value: $fileContents + + Returns the entire contents of the given file, which can be specified in any +-format acceptable to the Perl open() function. SECURITY NOTE: make sure +-any $filename coming from a user is stripped of special characters that might +-change Perl's open() semantics. ++format acceptable to the Perl open() function. + + =cut + + sub readFile + { + my( $name ) = @_; ++ $name = TWiki::normalizeFileName( $name ); + my $data = ""; + undef $/; # set to read to EOF + open( IN_FILE, "<$name" ) || return ""; +@@ -1610,6 +1610,7 @@ + sub readFileHead + { + my( $name, $maxLines ) = @_; ++ $name = TWiki::normalizeFileName( $name ); + my $data = ""; + my $line; + my $l = 0; +@@ -1727,34 +1728,6 @@ + } + #/AS + +-=pod +- +----+++ setTopicRevisionTag( $web, $topic, $rev, $tag ) ==> $success +- +-| Description: | sets a names tag on the specified revision | +-| Parameter: =$web= | webname | +-| Parameter: =$topic= | topic name | +-| Parameter: =$rev= | the revision we are taging | +-| Parameter: =$tag= | the string to tag with | +-| Return: =$success= | | +-| TODO: | we _need_ an error mechanism! | +-| Since: | TWiki:: (20 April 2004) | +- +-=cut +- +-sub setTopicRevisionTag +-{ +- my ( $web, $topic, $rev, $tag ) = @_; +- +- my $topicHandler = _getTopicHandler( $web, $topic ); +-# TWiki::writeDebug("Store - setTopicRevisionTag ( $web, $topic, $rev, $tag )"); +- return $topicHandler->setTopicRevisionTag( $web, $topic, $rev, $tag ); +-} +- +- +- +-# ========================= +- + 1; + + # EOF +=== lib/TWiki/Access.pm +================================================================== +--- lib/TWiki/Access.pm (/twiki/trunk) (revision 287) ++++ lib/TWiki/Access.pm (/twiki/branches/robustness) (revision 287) +@@ -140,6 +140,10 @@ + @denyList = @tmpList; + } else { + @allowList = @tmpList; ++ if ($2 =~ /\S/ && !@allowList) { ++ ##&TWiki::writeDebug( " return 0, empty ALLOWTOPIC" ); ++ return 0; ++ } + } + } + } +@@ -159,6 +163,10 @@ + prvGetUserList( $tmpVal ); + ##my $tmp = join( ', ', @allowList ); + ##&TWiki::writeDebug( " Prefs ALLOWWEB$theAccessType: {$tmp}" ); ++ if ($tmpVal && $tmpVal =~ /\S/ && !@allowList) { ++ ##&TWiki::writeDebug( " return 0, empty ALLOWWEB" ); ++ return 0; ++ } + } + + # access permission logic +=== lib/TWiki/UI/Upload.pm +================================================================== +--- lib/TWiki/UI/Upload.pm (/twiki/trunk) (revision 287) ++++ lib/TWiki/UI/Upload.pm (/twiki/branches/robustness) (revision 287) +@@ -119,6 +119,7 @@ + my( $file ) = shift @_; + my( $x, $y) = ( 0, 0 ); + ++ $file = TWiki::normalizeFileName( $file ); + if( defined( $file ) && open( STRM, "<$file" ) ) { + binmode( STRM ); # for crappy MS OSes - Win/Dos/NT use is NOT SUPPORTED + if( $file =~ /\.jpg$/i || $file =~ /\.jpeg$/i ) { +=== bin/manage +================================================================== +--- bin/manage (/twiki/trunk) (revision 287) ++++ bin/manage (/twiki/branches/robustness) (revision 287) +@@ -87,8 +87,10 @@ + + TWiki::UI::Manage::removeUser($webName, $topic, $wikiName, $query); + +-} elsif( $action eq "relockrcs" ) { +- TWiki::UI::Manage::relockRcsFiles(); ++# FIXME: Contains backticks, needs refactoring, upstream has been informed. ++# } elsif( $action eq "relockrcs" ) { ++# TWiki::UI::Manage::relockRcsFiles(); ++ + } elsif( $action ) { + + my( $topic, $webName, $dummy, $userName ) = + +Property changes on: +___________________________________________________________________ +Name: svk:merge + +a00a5322-12db-0310-a70b-8735589c885e:/twiki/trunk:3342 +Name: svm:source + -http://ntwiki.ethermage.net:8181/svn!/twiki/trunk + +svn://subversion.enyo.de/twiki!/twiki/branches/robustness +Name: svm:uuid + -a00a5322-12db-0310-a70b-8735589c885e + +0d0f78c6-ffe8-0310-8651-bed26cca55cd + Modified: twiki/branches/DEVELOP/tools/pkg/debian/patches/upstream-Codev.ProxiedIncludesBrokenImplementationBug.patch =================================================================== --- twiki/branches/DEVELOP/tools/pkg/debian/patches/upstream-Codev.ProxiedIncludesBrokenImplementationBug.patch 2006-02-25 12:32:21 UTC (rev 8910) +++ twiki/branches/DEVELOP/tools/pkg/debian/patches/upstream-Codev.ProxiedIncludesBrokenImplementationBug.patch 2006-02-25 12:42:30 UTC (rev 8911) @@ -4,8 +4,7 @@ my $base64; my $result = ''; $theUrl = "/" unless( $theUrl ); -- my $req = "GET $theUrl HTTP/1.1\r\n"; -+ my $req = "GET $theUrl HTTP/1.0\r\n"; + my $req = "GET $theUrl HTTP/1.0\r\n"; + $req .= "User-Agent: TWiki-Net-Pm\r\n"; # RNF 22 Jan 2002 Support for vhosts and user authentication. Modified: twiki/branches/DEVELOP/tools/pkg/debian/patches/upstream-Codev.SecurityAlertGainAdminRightWithTWikiUsersMapping.patch =================================================================== --- twiki/branches/DEVELOP/tools/pkg/debian/patches/upstream-Codev.SecurityAlertGainAdminRightWithTWikiUsersMapping.patch 2006-02-25 12:32:21 UTC (rev 8910) +++ twiki/branches/DEVELOP/tools/pkg/debian/patches/upstream-Codev.SecurityAlertGainAdminRightWithTWikiUsersMapping.patch 2006-02-25 12:42:30 UTC (rev 8911) @@ -1,35 +1,14 @@ ---- lib/TWiki.cfg 2003-02-02 13:45:15.000000000 +1100 -+++ lib/TWiki.cfg 2004-01-17 21:49:49.000000000 +1100 -@@ -326,6 +326,8 @@ +--- lib/TWiki.cfg 2004-09-01 02:35:19.000000000 +1000 ++++ lib/TWiki.cfg 2005-01-16 12:50:00.000000000 +1100 +@@ -367,8 +367,10 @@ # (e.g. 'fsmith') to Wiki name (e.g. 'FredSmith') : $userListFilename = "$dataDir/$mainWebname/$wikiUsersTopicname.txt"; + # Map login name to Wiki name, default "1", set to "0" for .htpasswd authenticated sites : +-$doMapUserToWikiName = "1"; ++$doMapUserToWikiName = "0"; # %HOMETOPIC% : Name of main topic in a web, default "WebHome" : +# Map login name to Wiki name, default "1", set to "0" for .htpasswd authenticated sites : +$doMapUserToWikiName = "0"; $mainTopicname = "WebHome"; # %NOTIFYTOPIC% : Name of topic for email notifications, default "WebNotify" : $notifyTopicname = "WebNotify"; ---- lib/TWiki.pm 2003-02-02 11:55:21.000000000 +1100 -+++ lib/TWiki.pm 2004-01-17 22:12:30.000000000 +1100 -@@ -57,7 +57,7 @@ - $siteWebTopicName $wikiToolName $securityFilter $uploadFilter - $debugFilename $warningFilename $htpasswdFilename - $logFilename $remoteUserFilename $wikiUsersTopicname -- $userListFilename %userToWikiList %wikiToUserList -+ $userListFilename $doMapUserToWikiName %userToWikiList %wikiToUserList - $twikiWebname $mainWebname $mainTopicname $notifyTopicname - $wikiPrefsTopicname $webPrefsTopicname - $statisticsTopicname $statsTopViews $statsTopContrib $doDebugStatistics -@@ -766,6 +766,12 @@ - # WikiName (e.g. JaneSmith) - sub userToWikiListInit - { -+ %userToWikiList = (); -+ %wikiToUserList = (); -+ -+ # bail out in .htpasswd authenticated sites -+ return unless( $doMapUserToWikiName ); -+ - my $text = &TWiki::Store::readFile( $userListFilename ); - my @list = split( /\n/, $text ); - Added: twiki/branches/DEVELOP/tools/pkg/debian/patches/upstream-Codev.ViewAfterSaveCachesOldPage-ugly-fix.patch =================================================================== --- twiki/branches/DEVELOP/tools/pkg/debian/patches/upstream-Codev.ViewAfterSaveCachesOldPage-ugly-fix.patch 2006-02-25 12:32:21 UTC (rev 8910) +++ twiki/branches/DEVELOP/tools/pkg/debian/patches/upstream-Codev.ViewAfterSaveCachesOldPage-ugly-fix.patch 2006-02-25 12:42:30 UTC (rev 8911) @@ -0,0 +1,41 @@ +diff -urw lib/TWiki.pm lib/TWiki.pm +--- lib/TWiki.pm 2004-11-11 15:30:17.000000000 -0500 ++++ lib/TWiki.pm 2004-11-19 13:57:03.000000000 -0500 +@@ -527,6 +527,9 @@ + + $contentType .= "; charset=$siteCharset"; + ++ my $expireHours = 24; ++ my $expireSeconds = $expireHours * 60 * 60; ++ + if ($pageType eq 'edit') { + # Get time now in HTTP header format + my $lastModifiedString = formatTime(time, 'http', 'gmtime'); +@@ -537,8 +540,6 @@ + # browser Back button always works. The next Edit on this page + # will use another URL and therefore won't use any cached + # version of this Edit page. +- my $expireHours = 24; +- my $expireSeconds = $expireHours * 60 * 60; + + # Set content length, to enable HTTP/1.1 persistent connections + # (aka HTTP keepalive), and cache control headers, to ensure edit page +@@ -551,8 +552,18 @@ + -cache_control => "max-age=$expireSeconds", + ); + } elsif ($pageType eq 'basic') { ++ # Set cache control to force unconditional reloading of this page ++ # to work around so the first view after an edit is never cached. ++ # See http://twiki.org/cgi-bin/view/Codev/ViewAfterSaveCachesOldPage ++ # for discussion of this bug. ++ ++ my $expiresString = formatTime(time - 2 * $expireSeconds, 'http', 'gmtime'); ++ my $lastModifiedString = formatTime(time - $expireSeconds, 'http', 'gmtime'); ++ + $coreHeaders = $query->header( + -content_type => $contentType, ++ -expires => $expiresString, ++ -last_modified => $lastModifiedString, + ); + } else { + writeWarning( "===== invalid page type in TWiki.pm, writeHeaderFull(): $pageType" ); Added: twiki/branches/DEVELOP/tools/pkg/debian/po/br.po =================================================================== --- twiki/branches/DEVELOP/tools/pkg/debian/po/br.po 2006-02-25 12:32:21 UTC (rev 8910) +++ twiki/branches/DEVELOP/tools/pkg/debian/po/br.po 2006-02-25 12:42:30 UTC (rev 8911) @@ -0,0 +1,125 @@ +# +# Translators, if you are not familiar with the PO format, gettext +# documentation is worth reading, especially sections dedicated to +# this format, e.g. by running: +# info -n '(gettext)PO Files' +# info -n '(gettext)Header Entry' +# +# Some information specific to po-debconf are available at +# /usr/share/doc/po-debconf/README-trans +# or http://www.debian.org/intl/l10n/po-debconf/README-trans +# +# Developers do not need to manually edit POT or PO files. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: TWiki\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-01-17 21:38+1100\n" +"PO-Revision-Date: 2004-08-23 00:00-0300\n" +"Last-Translator: Tiago Bortoletto Vaz <tia...@im...>\n" +"Language-Team: Debian-BR Project <deb...@li...>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: string +#. Default +#: ../templates:3 +msgid "http://localhost/" +msgstr "" + +#. Type: string +#. Description +#: ../templates:4 +msgid "What is the top-level URL of the server TWiki runs under?" +msgstr "Qual URL de mais alto nl do servidor que o TWiki irodar?" + +#. Type: string +#. Description +#: ../templates:4 +msgid "" +"For a normal install, this should be a URL for your web server's full name, " +"which is used to construct urls on some pages. The install will serve up " +"the data by adding \"twiki\" to the end of this setting; it is also needed " +"for certain redirections." +msgstr "" +"Para uma instala normal, isto deve ser uma URL do nome completo do seu " +"servidor WEB, que sada como base das urls de algumas pnas. A " +"instala irrover os dados adicionando \"twiki\" no final desta URL; " +"isso tambecesso para alguns redirecionamentos." + +#. Type: string +#. Default +#: ../templates:12 +msgid "webmaster@localhost" +msgstr "" + +#. Type: string +#. Description +#: ../templates:13 +msgid "What is the email address of the webmaster for this TWiki?" +msgstr "Qual o enderede email do webmaster deste TWiki?" + +#. Type: string +#. Description +#: ../templates:13 +msgid "" +"This email address gets mail for new user registration, and is listed on the " +"\"oops\" page when things go wrong." +msgstr "" +"Este enderede email recebe os emails dos novos registros de usuos, e +"listado na pna \"oops\" quando algo der errado." + +#. Type: boolean +#. Description +#: ../templates:20 +msgid "Install sample wiki universe on initial install?" +msgstr "Instalar os exemplos padrde wiki na instala inicial?" + +#. Type: boolean +#. Description +#: ../templates:20 +#, fuzzy +msgid "" +"TWiki includes a complete \"starter kit\" which includes user registration " +"pages, documentation, and tutorials. If you're re-installing twiki after " +"deleting the package and want to keep the old data, or if you've got a twiki " +"data set from your own manual install, you should say \"no\" here. On a " +"normal initial install, say \"yes\", and a sample data set will be installed " +"in /var/lib/twiki/data (and /var/www/twiki/pub). (In either case, if data/" +"Main/WebHome.txt is present, the starter kit will not be unpacked; you can " +"look in /usr/share/doc/twiki/twiki-data.tar.gz (and twiki-pub.tar.zg) if you " +"wish to install it manually or compare a new version.)" +msgstr "" +"O TWiki inclui um completo \"kit de inicializa\" que inclui pnas de " +"registro de usuo, documenta e tutoriais. Se vocsteinstalando o " +"twiki depois de ter removido o pacote anterior e quer preservar os dados " +"antigos, ou se vocem os dados de configura do twiki a partir do seu " +"pro manual de instala, voceve recusar aqui. Numa instala " +"inicial normal, aceitando essa op, dados de exemplo de configura ser" +"instalados em /var/lib/twiki/data. (Num outro caso, se data/Main/WebHome.txt " +"estresente, o kit de inicializa nseresempacotado; vocode " +"encontro em /usr/share/doc/twiki/twiki-data.tar.gz se quiser instalo " +"manualmente ou comparar com uma nova vers)" + +#. Type: note +#. Description +#: ../templates:34 +msgid "User Registration configuration required" +msgstr "" + +#. Type: note +#. Description +#: ../templates:34 +msgid "" +"The default debian installation of the TWiki is configured to create new " +"users automatically when a user Registers. This is not as secure as the " +"default TWiki but is more useful for trying TWiki out. To change it so the " +"users are created manually by the administrator use TWiki RenameTopic to " +"rename the TWikiRegistration to TWikiRegistrationPub, and " +"TWikiRegistrationDefault to TWikiRegistration. IMPORTANT: After you have " +"created yourself a user, edit the Main.TWikiAdminGroup to restrict Admin " +"privileges" +msgstr "" Added: twiki/branches/DEVELOP/tools/pkg/debian/po/cs.po =================================================================== --- twiki/branches/DEVELOP/tools/pkg/debian/po/cs.po 2006-02-25 12:32:21 UTC (rev 8910) +++ twiki/branches/DEVELOP/tools/pkg/debian/po/cs.po 2006-02-25 12:42:30 UTC (rev 8911) @@ -0,0 +1,123 @@ +# +# Translators, if you are not familiar with the PO format, gettext +# documentation is worth reading, especially sections dedicated to +# this format, e.g. by running: +# info -n '(gettext)PO Files' +# info -n '(gettext)Header Entry' +# +# Some information specific to po-debconf are available at +# /usr/share/doc/po-debconf/README-trans +# or http://www.debian.org/intl/l10n/po-debconf/README-trans +# +# Developers do not need to manually edit POT or PO files. +# +msgid "" +msgstr "" +"Project-Id-Version: twiki\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-01-17 21:38+1100\n" +"PO-Revision-Date: 2004-12-27 13:01+0100\n" +"Last-Translator: Miroslav Kure <ku...@de...>\n" +"Language-Team: Czech <pr...@de...>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-2\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: string +#. Default +#: ../templates:3 +msgid "http://localhost/" +msgstr "" + +#. Type: string +#. Description +#: ../templates:4 +msgid "What is the top-level URL of the server TWiki runs under?" +msgstr "Jake vrcholovRL serveru, pod kterki pob?" + +#. Type: string +#. Description +#: ../templates:4 +msgid "" +"For a normal install, this should be a URL for your web server's full name, " +"which is used to construct urls on some pages. The install will serve up " +"the data by adding \"twiki\" to the end of this setting; it is also needed " +"for certain redirections." +msgstr "" +"Pro bnstalace by to m bdresa vaeho webov serveru. " +"Instalace pna konec t adresy ec \"twiki\", vznikne URL, " +"pod ktere vae wiki dostupnZadanRL se pouije pro vytvn +"odkaznerr." + +#. Type: string +#. Default +#: ../templates:12 +msgid "webmaster@localhost" +msgstr "" + +#. Type: string +#. Description +#: ../templates:13 +msgid "What is the email address of the webmaster for this TWiki?" +msgstr "Jake e-mailovdresa spre tohoto TWiki?" + +#. Type: string +#. Description +#: ../templates:13 +msgid "" +"This email address gets mail for new user registration, and is listed on the " +"\"oops\" page when things go wrong." +msgstr "" +"Na tuto emailovou adresu budou zasny poadavky o registraci nov+"uiavtelake bude zobrazovat na webovtre v pe se v " +"pokaz + +#. Type: boolean +#. Description +#: ../templates:20 +msgid "Install sample wiki universe on initial install?" +msgstr "Instalovat pvotnnstalaci vzorov web?" + +#. Type: boolean +#. Description +#: ../templates:20 +#, fuzzy +msgid "" +"TWiki includes a complete \"starter kit\" which includes user registration " +"pages, documentation, and tutorials. If you're re-installing twiki after " +"deleting the package and want to keep the old data, or if you've got a twiki " +"data set from your own manual install, you should say \"no\" here. On a " +"normal initial install, say \"yes\", and a sample data set will be installed " +"in /var/lib/twiki/data (and /var/www/twiki/pub). (In either case, if data/" +"Main/WebHome.txt is present, the starter kit will not be unpacked; you can " +"look in /usr/share/doc/twiki/twiki-data.tar.gz (and twiki-pub.tar.zg) if you " +"wish to install it manually or compare a new version.)" +msgstr "" +"TWiki obsahuje kompletn"sadu pro zaeky\", terahrnuje stry s " +"registracivatelkumentac ndy. Reinstalujete-li twiki po " +"pozodstran bal a chcete zachovat svtarata, nebo pokud " +"m data po du instalaci, m byste zde zamout. Pn +"prvnnstalaci akceptujte, co vnainstaluje vzorovata do /var/lib/" +"twiki/data. (Sada pro zaeky se nerozbalpokud existuje soubor data/" +"Main/WebHome.txt; budete-li ji chtnainstalovat ru, nach se v " +"souboru /usr/share/doc/twiki/twiki-data.tar.gz.)" + +#. Type: note +#. Description +#: ../templates:34 +msgid "User Registration configuration required" +msgstr "" + +#. Type: note +#. Description +#: ../templates:34 +msgid "" +"The default debian installation of the TWiki is configured to create new " +"users automatically when a user Registers. This is not as secure as the " +"default TWiki but is more useful for trying TWiki out. To change it so the " +"users are created manually by the administrator use... [truncated message content] |