===================================================================
RCS file: /cvs/cvsweb/cvsweb.cgi,v
retrieving revision 1.1.1.29
retrieving revision 1.1.1.31
diff -u -p -r1.1.1.29 -r1.1.1.31
--- cvsweb/cvsweb.cgi 2002/04/10 20:03:49 1.1.1.29
+++ cvsweb/cvsweb.cgi 2002/05/22 08:16:25 1.1.1.31
@@ -43,7 +43,7 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
-# $FreeBSD: projects/cvsweb/cvsweb.cgi,v 1.90 2002/04/10 19:25:11 knu Exp $
+# $FreeBSD: projects/cvsweb/cvsweb.cgi,v 1.104 2002/05/22 08:10:18 knu Exp $
# $zId: cvsweb.cgi,v 1.112 2001/07/24 13:03:16 hzeller Exp $
# $Idaemons: /home/cvs/cvsweb/cvsweb.cgi,v 1.84 2001/10/07 20:50:10 knu Exp $
#
@@ -64,7 +64,8 @@ use vars qw (
@revisions %state %difflines %log %branchpoint @revorder
$prcgi @prcategories $re_prcategories $prkeyword $re_prkeyword $mancgi
$checkoutMagic $doCheckout $scriptname $scriptwhere
- $where $pathinfo $Browser $nofilelinks $maycompress @stickyvars
+ $where $pathinfo $Browser $nofilelinks $maycompress
+ @stickyvars @unsafevars
%funcline_regexp $is_mod_perl
$is_links $is_lynx $is_w3m $is_msie $is_mozilla3 $is_textbased
%input $query $barequery $sortby $bydate $byrev $byauthor
@@ -79,8 +80,10 @@ use vars qw (
$columnHeaderColorSorted $hr_breakable $showfunc $hr_ignwhite
$hr_ignkeysubst $diffcolorHeading $diffcolorEmpty $diffcolorRemove
$diffcolorChange $diffcolorAdd $diffcolorDarkChange $difffontface
- $difffontsize $inputTextSize $mime_types $allow_annotate
- $allow_markup $use_java_script $open_extern_window
+ $difffontsize $inputTextSize $mime_types
+ $allow_annotate $allow_markup
+ $allow_log_extra $allow_dir_extra $allow_source_extra
+ $use_java_script $open_extern_window
$extern_window_width $extern_window_height $edit_option_form
$show_subdir_lastmod $show_log_in_markup $preformat_in_markup $v
$navigationHeaderColor $tableBorderColor $markupLogColor
@@ -89,7 +92,7 @@ use vars qw (
$use_moddate $has_zlib $gzip_open
$allow_tar @tar_options @gzip_options @zip_options @cvs_options
$LOG_FILESEPARATOR $LOG_REVSEPARATOR
- $tmpdir
+ $tmpdir $HTML_DOCTYPE
);
sub printDiffSelect($);
@@ -101,7 +104,7 @@ sub htmlify($;$);
sub spacedHtmlText($;$);
sub link($$);
sub revcmp($$);
-sub fatal($$);
+sub fatal($$@);
sub redirect($);
sub safeglob($);
sub search_path($);
@@ -144,11 +147,11 @@ sub forbidden_module($);
##### Start of Configuration Area ########
delete $ENV{PATH};
-$cvsweb_revision = '2.0.1';
+$cvsweb_revision = '2.0.3';
-use File::Basename;
+use File::Basename ();
-($mydir) = (dirname($0) =~ /(.*)/); # untaint
+($mydir) = (File::Basename::dirname($0) =~ /(.*)/); # untaint
# == EDIT this ==
# Locations to search for user configuration, in order:
@@ -163,6 +166,7 @@ for ("$mydir/cvsweb.conf", '/usr/local/etc/cvsweb/cvsw
# Defaults for configuration variables that shouldn't need
# to be configured..
$allow_version_select = 1;
+$allow_log_extra = 1;
##### End of Configuration Area ########
@@ -181,7 +185,7 @@ $cvstreedefault = $body_tag = $body_tag_for_src = $log
$extern_window_width = $extern_window_height = $edit_option_form =
$show_subdir_lastmod = $show_log_in_markup = $v = $navigationHeaderColor =
$tableBorderColor = $markupLogColor = $tabstop = $use_moddate = $moddate =
- $gzip_open = undef;
+ $gzip_open = $HTML_DOCTYPE = undef;
$tmpdir = defined($ENV{TMPDIR}) ? $ENV{TMPDIR} : "/var/tmp";
$LOG_FILESEPARATOR = q/^={77}$/;
@@ -229,10 +233,13 @@ $LOG_REVSEPARATOR = q/^-{28}$/;
},
);
+$HTML_DOCTYPE =
+ '';
+
##### End of configuration variables #####
-use Time::Local;
-use IPC::Open2;
+use Time::Local ();
+use IPC::Open2 qw(open2);
# Check if the zlib C library interface is installed, and if yes
# we can avoid using the extra gzip process.
@@ -295,21 +302,16 @@ $maycompress =
# their current value) to any link/query string
# you construct
@stickyvars = qw(cvsroot hideattic sortby logsort f only_with_tag);
+@unsafevars = qw(logsort only_with_tag r1 r2 rev sortby tr1 tr2);
if (-f $config) {
- require $config || &fatal(
- "500 Internal Error",
- sprintf(
- 'Error in loading configuration file: %s
%s
',
- $config,
- &htmlify($@)
- )
- );
+ do "$config" or fatal("500 Internal Error",
+ 'Error in loading configuration file: %s
%s
',
+ $config, $@);
} else {
- &fatal("500 Internal Error",
- 'Configuration not found. Set the variable $config
'
- . 'in cvsweb.cgi to your cvsweb.conf configuration file first.'
- );
+ fatal("500 Internal Error",
+ 'Configuration not found. Set the variable $config
in cvsweb.cgi to your cvsweb.conf configuration file first.'
+ );
}
undef %input;
@@ -331,6 +333,20 @@ if (defined($query) && $query ne '') {
$input{only_with_tag} = $input{only_on_branch}
if (defined($input{only_on_branch}));
+# Prevent cross-site scripting
+foreach (@unsafevars) {
+ if (defined($input{$_}) && $input{$_} =~ /[^\w\-.]/) {
+ fatal("500 Internal Error",
+ 'Malformed query (%s=%s)',
+ $_, $input{$_});
+ }
+}
+
+if (defined($input{"content-type"})) {
+ fatal("500 Internal Error", "Unsupported content-type")
+ if ($input{"content-type"} !~ /^[-0-9A-Za-z]+\/[-0-9A-Za-z]+$/);
+}
+
$DEFAULTVALUE{'cvsroot'} = $cvstreedefault;
foreach (keys %DEFAULTVALUE) {
@@ -409,28 +425,27 @@ $defaultDiffType = $input{'f'};
$logsort = $input{'logsort'};
-my @tmp = @CVSrepositories;
-my @pair;
+{
+ my @tmp = @CVSrepositories;
+ my @pair;
-while (@pair = splice(@tmp, 0, 2)) {
- my ($key, $val) = @pair;
- my ($descr, $cvsroot) = @$val;
+ while (@pair = splice(@tmp, 0, 2)) {
+ my ($key, $val) = @pair;
+ my ($descr, $cvsroot) = @$val;
- next if !-d $cvsroot;
+ next if !-d $cvsroot;
- $CVSROOTdescr{$key} = $descr;
- $CVSROOT{$key} = $cvsroot;
- push @CVSROOT, $key;
+ $CVSROOTdescr{$key} = $descr;
+ $CVSROOT{$key} = $cvsroot;
+ push @CVSROOT, $key;
+ }
}
-undef @tmp;
-undef @pair;
## Default CVS-Tree
if (!defined($CVSROOT{$cvstreedefault})) {
- &fatal("500 Internal Error",
- "\$cvstreedefault
points to a repository ($cvstreedefault) "
- . "not defined in %CVSROOT
"
- . "(edit your configuration file $config)");
+ fatal("500 Internal Error",
+ '$cvstreedefault
points to a repository (%s) not defined in %%CVSROOT
(edit your configuration file %s)',
+ $cvstreedefault, $config);
}
# alternate CVS-Tree, configured in cvsweb.conf
@@ -462,14 +477,10 @@ my $config_cvstree = "$config-$cvstree";
# Do some special configuration for cvstrees
if (-f $config_cvstree) {
- require $config_cvstree || &fatal(
- "500 Internal Error",
- sprintf(
- 'Error in loading configuration file: %s
%s
',
- $config_cvstree,
- &htmlify($@)
- )
- );
+ do "$config_cvstree" or
+ fatal("500 Internal Error",
+ 'Error in loading configuration file: %s
%s
',
+ $config_cvstree, $@);
}
undef $config_cvstree;
@@ -506,9 +517,8 @@ if ($rewrite) {
undef $rewrite;
if (!-d $cvsroot) {
- &fatal("500 Internal Error",
- '$CVSROOT not found!
The server on which the CVS tree lives is probably down. Please try again in a few minutes.' - ); + fatal("500 Internal Error", + '$CVSROOT not found!
The server on which the CVS tree lives is probably down. Please try again in a few minutes.'); } # @@ -517,14 +527,17 @@ if (!-d $cvsroot) { $where =~ m:([^/]*):; $module = $1; if ($module && &forbidden_module($module)) { - &fatal("403 Forbidden", "Access to $where forbidden."); + fatal("403 Forbidden", + 'Access to %s forbidden.', + $where); } # # Handle tarball downloads before any headers are output. # if ($input{tarball}) { - &fatal("403 Forbidden", "Downloading tarballs is prohibited.") + fatal("403 Forbidden", + 'Downloading tarballs is prohibited.') unless $allow_tar; my ($module) = ($where =~ m,^/?(.*),); # untaint $module =~ s,/([^/]*)$,,; @@ -532,15 +545,16 @@ if ($input{tarball}) { my ($basedir) = ($module =~ m,([^/]+)$,); if ($basedir eq '' || $module eq '') { - &fatal("500 Internal Error", - "You cannot download the top level directory."); + fatal("500 Internal Error", + 'You cannot download the top level directory.'); } my $tmpexportdir = "$tmpdir/.cvsweb.$$." . int(time); mkdir($tmpexportdir, 0700) - or &fatal("500 Internal Error", - "Unable to make temporary directory: $!"); + or fatal("500 Internal Error", + 'Unable to make temporary directory: %s', + $!); my @fatal; @@ -555,7 +569,9 @@ if ($input{tarball}) { if (system $CMD{cvs}, @cvs_options, '-Qd', $cvsroot, 'export', '-r', $tag, '-d', "$tmpexportdir/$basedir", $module) { - @fatal = ("500 Internal Error", "cvs co failure: $!: $module"); + @fatal = ("500 Internal Error", + 'cvs co failure: %s: %s', + $!, $module); } else { $| = 1; # Essential to get the buffering right. @@ -565,18 +581,22 @@ if ($input{tarball}) { system "$CMD{tar} @tar_options -cf - -C $tmpexportdir $basedir | $CMD{gzip} @gzip_options -c" and @fatal = - ("500 Internal Error", - "tar zc failure: $!: $basedir"); + ("500 Internal Error", + 'tar zc failure: %s: %s', + $!, $basedir); } elsif ($ext eq '.zip' && $CMD{zip}) { print "Content-Type: application/zip\r\n\r\n"; system "cd $tmpexportdir && $CMD{zip} @zip_options -r - $basedir" and @fatal = - ("500 Internal Error", "zip failure: $!: $basedir"); + ("500 Internal Error", + 'zip failure: %s: %s', + $!, $basedir); } else { @fatal = - ("500 Internal Error", "unsupported file type"); + ("500 Internal Error", + 'unsupported file type'); } } @@ -592,7 +612,9 @@ if ($input{tarball}) { ############################### if (-d $fullname) { my $dh = do { local (*DH); }; - opendir($dh, $fullname) || &fatal("404 Not Found", "$where: $!"); + opendir($dh, $fullname) or fatal("404 Not Found", + '%s: %s', + $where, $!); my @dir = readdir($dh); closedir($dh); my @subLevelFiles = findLastModifiedSubdirs(@dir) @@ -641,16 +663,12 @@ if (-d $fullname) { my $infocols = 0; if ($dirtable) { - if (defined($tableBorderColor)) { - - # Can't this be done by defining the border for the inner table? - print - "