Commit f9cd15c7 authored by mkanat%bugzilla.org's avatar mkanat%bugzilla.org

Bug 523495: Re-work attachment.cgi and the general attachment_base-checking code…

Bug 523495: Re-work attachment.cgi and the general attachment_base-checking code to prevent an infinite redirect loop when ssl_redirect is on and Bugzilla has an attachment_base set. Patch by Max Kanat-Alexander <mkanat@bugzilla.org> r=LpSolit, a=LpSolit
parent a2dd3b00
...@@ -113,7 +113,10 @@ sub init_page { ...@@ -113,7 +113,10 @@ sub init_page {
}; };
} }
do_ssl_redirect_if_required(); # Because of attachment_base, attachment.cgi handles this itself.
if (basename($0) ne 'attachment.cgi') {
do_ssl_redirect_if_required();
}
# If Bugzilla is shut down, do not allow anything to run, just display a # If Bugzilla is shut down, do not allow anything to run, just display a
# message to the user about the downtime and log out. Scripts listed in # message to the user about the downtime and log out. Scripts listed in
......
...@@ -28,6 +28,8 @@ use Bugzilla::Constants; ...@@ -28,6 +28,8 @@ use Bugzilla::Constants;
use Bugzilla::Error; use Bugzilla::Error;
use Bugzilla::Util; use Bugzilla::Util;
use File::Basename;
BEGIN { BEGIN {
if (ON_WINDOWS) { if (ON_WINDOWS) {
# Help CGI find the correct temp directory as the default list # Help CGI find the correct temp directory as the default list
...@@ -71,15 +73,9 @@ sub new { ...@@ -71,15 +73,9 @@ sub new {
$self->charset(Bugzilla->params->{'utf8'} ? 'UTF-8' : ''); $self->charset(Bugzilla->params->{'utf8'} ? 'UTF-8' : '');
# Redirect to urlbase/sslbase if we are not viewing an attachment. # Redirect to urlbase/sslbase if we are not viewing an attachment.
if (use_attachbase() && i_am_cgi()) { my $script = basename($0);
my $cgi_file = $self->url('-path_info' => 0, '-query' => 0, '-relative' => 1); if ($self->url_is_attachment_base and $script ne 'attachment.cgi') {
$cgi_file =~ s/\?$//; $self->redirect_to_urlbase();
my $urlbase = Bugzilla->params->{'urlbase'};
my $sslbase = Bugzilla->params->{'sslbase'};
my $path_regexp = $sslbase ? qr/^(\Q$urlbase\E|\Q$sslbase\E)/ : qr/^\Q$urlbase\E/;
if ($cgi_file ne 'attachment.cgi' && $self->self_url !~ /$path_regexp/) {
$self->redirect_to_urlbase;
}
} }
# Check for errors # Check for errors
...@@ -398,6 +394,28 @@ sub redirect_to_urlbase { ...@@ -398,6 +394,28 @@ sub redirect_to_urlbase {
exit; exit;
} }
sub url_is_attachment_base {
my ($self, $id) = @_;
return 0 if !use_attachbase() or !i_am_cgi();
my $attach_base = Bugzilla->params->{'attachment_base'};
# If we're passed an id, we only want one specific attachment base
# for a particular bug. If we're not passed an ID, we just want to
# know if our current URL matches the attachment_base *pattern*.
my $regex;
if ($id) {
$attach_base =~ s/\%bugid\%/$id/;
$regex = quotemeta($attach_base);
}
else {
# In this circumstance we run quotemeta first because we need to
# insert an active regex meta-character afterward.
$regex = quotemeta($attach_base);
$regex =~ s/\\\%bugid\\\%/\\d+/;
}
$regex = "^$regex";
return ($self->self_url =~ $regex) ? 1 : 0;
}
1; 1;
__END__ __END__
......
...@@ -77,10 +77,8 @@ my $action = $cgi->param('action') || 'view'; ...@@ -77,10 +77,8 @@ my $action = $cgi->param('action') || 'view';
# You must use the appropriate urlbase/sslbase param when doing anything # You must use the appropriate urlbase/sslbase param when doing anything
# but viewing an attachment. # but viewing an attachment.
if ($action ne 'view') { if ($action ne 'view') {
my $urlbase = Bugzilla->params->{'urlbase'}; do_ssl_redirect_if_required();
my $sslbase = Bugzilla->params->{'sslbase'}; if ($cgi->url_is_attachment_base) {
my $path_regexp = $sslbase ? qr/^(\Q$urlbase\E|\Q$sslbase\E)/ : qr/^\Q$urlbase\E/;
if (use_attachbase() && $cgi->self_url !~ /$path_regexp/) {
$cgi->redirect_to_urlbase; $cgi->redirect_to_urlbase;
} }
Bugzilla->login(); Bugzilla->login();
...@@ -243,10 +241,6 @@ sub view { ...@@ -243,10 +241,6 @@ sub view {
if (use_attachbase()) { if (use_attachbase()) {
$attachment = validateID(undef, 1); $attachment = validateID(undef, 1);
# Replace %bugid% by the ID of the bug the attachment belongs to, if present.
my $attachbase = Bugzilla->params->{'attachment_base'};
my $bug_id = $attachment->bug_id;
$attachbase =~ s/%bugid%/$bug_id/;
my $path = 'attachment.cgi?id=' . $attachment->id; my $path = 'attachment.cgi?id=' . $attachment->id;
# The user is allowed to override the content type of the attachment. # The user is allowed to override the content type of the attachment.
if (defined $cgi->param('content_type')) { if (defined $cgi->param('content_type')) {
...@@ -254,10 +248,16 @@ sub view { ...@@ -254,10 +248,16 @@ sub view {
} }
# Make sure the attachment is served from the correct server. # Make sure the attachment is served from the correct server.
if ($cgi->self_url !~ /^\Q$attachbase\E/) { my $bug_id = $attachment->bug_id;
# We couldn't call Bugzilla->login earlier as we first had to make sure if (!$cgi->url_is_attachment_base($bug_id)) {
# we were not going to request credentials on the alternate host. # We couldn't call Bugzilla->login earlier as we first had to
# make sure we were not going to request credentials on the
# alternate host.
Bugzilla->login(); Bugzilla->login();
my $attachbase = Bugzilla->params->{'attachment_base'};
# Replace %bugid% by the ID of the bug the attachment
# belongs to, if present.
$attachbase =~ s/\%bugid\%/$bug_id/;
if (attachmentIsPublic($attachment)) { if (attachmentIsPublic($attachment)) {
# No need for a token; redirect to attachment base. # No need for a token; redirect to attachment base.
print $cgi->redirect(-location => $attachbase . $path); print $cgi->redirect(-location => $attachbase . $path);
...@@ -291,6 +291,7 @@ sub view { ...@@ -291,6 +291,7 @@ sub view {
} }
} }
} else { } else {
do_ssl_redirect_if_required();
# No alternate host is used. Request credentials if required. # No alternate host is used. Request credentials if required.
Bugzilla->login(); Bugzilla->login();
$attachment = validateID(); $attachment = validateID();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment