diff options
author | ivan <ivan> | 2011-04-18 23:15:19 +0000 |
---|---|---|
committer | ivan <ivan> | 2011-04-18 23:15:19 +0000 |
commit | 75162bb14b3e38d66617077843f4dfdcaf09d5c4 (patch) | |
tree | d89dd49a476cf2f0859ed6a0adc2992ea6d69d04 /rt/lib/RT/Interface | |
parent | fc6209f398899f0211cfcedeb81a3cd65e04a941 (diff) |
import rt 3.8.10
Diffstat (limited to 'rt/lib/RT/Interface')
-rw-r--r-- | rt/lib/RT/Interface/CLI.pm | 19 | ||||
-rwxr-xr-x | rt/lib/RT/Interface/Email.pm | 7 | ||||
-rwxr-xr-x | rt/lib/RT/Interface/Email/Auth/GnuPG.pm | 9 | ||||
-rw-r--r-- | rt/lib/RT/Interface/Email/Auth/MailFrom.pm | 7 | ||||
-rw-r--r-- | rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm | 7 | ||||
-rw-r--r-- | rt/lib/RT/Interface/REST.pm | 30 | ||||
-rw-r--r-- | rt/lib/RT/Interface/Web.pm | 56 | ||||
-rw-r--r-- | rt/lib/RT/Interface/Web/Handler.pm | 5 | ||||
-rw-r--r-- | rt/lib/RT/Interface/Web/Menu/Item.pm | 3 | ||||
-rwxr-xr-x | rt/lib/RT/Interface/Web/QueryBuilder.pm | 5 | ||||
-rwxr-xr-x | rt/lib/RT/Interface/Web/QueryBuilder/Tree.pm | 5 | ||||
-rwxr-xr-x | rt/lib/RT/Interface/Web/Standalone.pm | 9 |
12 files changed, 95 insertions, 67 deletions
diff --git a/rt/lib/RT/Interface/CLI.pm b/rt/lib/RT/Interface/CLI.pm index 00bd1b64e..5e1999816 100644 --- a/rt/lib/RT/Interface/CLI.pm +++ b/rt/lib/RT/Interface/CLI.pm @@ -58,7 +58,7 @@ BEGIN { use vars qw ($VERSION @EXPORT @EXPORT_OK %EXPORT_TAGS); # set the version for version checking - $VERSION = do { my @r = (q$Revision: 1.1.1.9 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; # must be all one line, for MakeMaker + $VERSION = do { my @r = (q$Revision: 1.1.1.10 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; # must be all one line, for MakeMaker # your exported package globals go here, # as well as any optionally exported functions @@ -200,9 +200,9 @@ sub GetMessageContent { #Load the sourcefile, if it's been handed to us if ($source) { - open (SOURCE, "<$source"); - @lines = (<SOURCE>); - close (SOURCE); + open( SOURCE, '<', $source ) or die $!; + @lines = (<SOURCE>) or die $!; + close (SOURCE) or die $!; } elsif ($args{'Content'}) { @lines = split('\n',$args{'Content'}); @@ -214,7 +214,7 @@ sub GetMessageContent { for (@lines) { print $fh $_; } - close ($fh); + close ($fh) or die $!; #Edit the file if we need to if ($edit) { @@ -226,9 +226,9 @@ sub GetMessageContent { system ($ENV{'EDITOR'}, $filename); } - open (READ, "<$filename"); + open( READ, '<', $filename ) or die $!; my @newlines = (<READ>); - close (READ); + close (READ) or die $!; unlink ($filename) unless (debug()); return(\@newlines); @@ -256,9 +256,6 @@ sub debug { # }}} -eval "require RT::Interface::CLI_Vendor"; -die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/CLI_Vendor.pm}); -eval "require RT::Interface::CLI_Local"; -die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/CLI_Local.pm}); +RT::Base->_ImportOverlays(); 1; diff --git a/rt/lib/RT/Interface/Email.pm b/rt/lib/RT/Interface/Email.pm index cda61305b..401e970e8 100755 --- a/rt/lib/RT/Interface/Email.pm +++ b/rt/lib/RT/Interface/Email.pm @@ -445,7 +445,7 @@ sub SendEmail { # don't ignore CHLD signal to get proper exit code local $SIG{'CHLD'} = 'DEFAULT'; - open my $mail, "|$path $args >/dev/null" + open( my $mail, '|-', "$path $args >/dev/null" ) or die "couldn't execute program: $!"; # if something wrong with $mail->print we will get PIPE signal, handle it @@ -1809,9 +1809,6 @@ sub _RecordSendEmailFailure { } } -eval "require RT::Interface::Email_Vendor"; -die $@ if ( $@ && $@ !~ qr{^Can't locate RT/Interface/Email_Vendor.pm} ); -eval "require RT::Interface::Email_Local"; -die $@ if ( $@ && $@ !~ qr{^Can't locate RT/Interface/Email_Local.pm} ); +RT::Base->_ImportOverlays(); 1; diff --git a/rt/lib/RT/Interface/Email/Auth/GnuPG.pm b/rt/lib/RT/Interface/Email/Auth/GnuPG.pm index cc15abbd1..6d43b9610 100755 --- a/rt/lib/RT/Interface/Email/Auth/GnuPG.pm +++ b/rt/lib/RT/Interface/Email/Auth/GnuPG.pm @@ -250,14 +250,7 @@ sub VerifyDecrypt { return $status, @res, @nested; } -eval "require RT::Interface::Email::Auth::GnuPG_Vendor"; -die $@ - if ( $@ - && $@ !~ qr{^Can't locate RT/Interface/Email/Auth/GnuPG_Vendor.pm} ); -eval "require RT::Interface::Email::Auth::GnuPG_Local"; -die $@ - if ( $@ - && $@ !~ qr{^Can't locate RT/Interface/Email/Auth/GnuPG_Local.pm} ); +RT::Base->_ImportOverlays(); 1; diff --git a/rt/lib/RT/Interface/Email/Auth/MailFrom.pm b/rt/lib/RT/Interface/Email/Auth/MailFrom.pm index a90306b67..be2f517e1 100644 --- a/rt/lib/RT/Interface/Email/Auth/MailFrom.pm +++ b/rt/lib/RT/Interface/Email/Auth/MailFrom.pm @@ -48,6 +48,8 @@ package RT::Interface::Email::Auth::MailFrom; use RT::Interface::Email qw(ParseSenderAddressFromHead CreateUser); +use strict; +use warnings; # This is what the ordinary, non-enhanced gateway does at the moment. @@ -174,9 +176,6 @@ sub GetCurrentUser { return ( $CurrentUser, 1 ); } -eval "require RT::Interface::Email::Auth::MailFrom_Vendor"; -die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Email/Auth/MailFrom_Vendor.pm}); -eval "require RT::Interface::Email::Auth::MailFrom_Local"; -die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Email/Auth/MailFrom_Local.pm}); +RT::Base->_ImportOverlays(); 1; diff --git a/rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm b/rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm index 6e99fec0b..0470e6340 100644 --- a/rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm +++ b/rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm @@ -47,6 +47,8 @@ # END BPS TAGGED BLOCK }}} package RT::Interface::Email::Filter::SpamAssassin; +use strict; +use warnings; use Mail::SpamAssassin; my $spamtest = Mail::SpamAssassin->new(); @@ -90,9 +92,6 @@ the floor; otherwise, it is passed on as normal. =cut -eval "require RT::Interface::Email::Filter::SpamAssassin_Vendor"; -die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Email/Filter/SpamAssassin_Vendor.pm}); -eval "require RT::Interface::Email::Filter::SpamAssassin_Local"; -die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Email/Filter/SpamAssassin_Local.pm}); +RT::Base->_ImportOverlays(); 1; diff --git a/rt/lib/RT/Interface/REST.pm b/rt/lib/RT/Interface/REST.pm index ae1d6ad1e..7f6c9ac54 100644 --- a/rt/lib/RT/Interface/REST.pm +++ b/rt/lib/RT/Interface/REST.pm @@ -51,13 +51,14 @@ package RT::Interface::REST; use strict; +use warnings; use RT; BEGIN { use base 'Exporter'; use vars qw($VERSION @EXPORT); - $VERSION = do { my @r = (q$Revision: 1.1.1.9 $ =~ /\d+/g); sprintf "%d."."%02d"x$#r, @r }; + $VERSION = do { my @r = (q$Revision: 1.1.1.10 $ =~ /\d+/g); sprintf "%d."."%02d"x$#r, @r }; @EXPORT = qw(expand_list form_parse form_compose vpush vsplit); } @@ -160,8 +161,8 @@ sub form_parse { pop @v while (@v && $v[-1] eq ''); # Strip longest common leading indent from text. - my ($ws, $ls) = (""); - foreach $ls (map {/^(\s+)/} @v[1..$#v]) { + my $ws = (""); + foreach my $ls (map {/^(\s+)/} @v[1..$#v]) { $ws = $ls if (!$ws || length($ls) < length($ws)); } s/^$ws// foreach @v; @@ -189,8 +190,7 @@ sub form_parse { } push(@forms, [ $c, $o, $k, $e ]) if ($e || $c || @$o); - my $l; - foreach $l (keys %$k) { + foreach my $l (keys %$k) { $k->{$l} = vsplit($k->{$l}) if (ref $k->{$l} eq 'ARRAY'); } @@ -202,7 +202,7 @@ sub form_compose { my ($forms) = @_; my (@text, $form); - foreach $form (@$forms) { + foreach my $form (@$forms) { my ($c, $o, $k, $e) = @$form; my $text = ""; @@ -216,7 +216,7 @@ sub form_compose { elsif ($o) { my (@lines, $key); - foreach $key (@$o) { + foreach my $key (@$o) { my ($line, $sp, $v); my @values = (ref $k->{$key} eq 'ARRAY') ? @{ $k->{$key} } : @@ -225,7 +225,7 @@ sub form_compose { $sp = " "x(length("$key: ")); $sp = " "x4 if length($sp) > 16; - foreach $v (@values) { + foreach my $v (@values) { $v = '' unless defined $v; if ( $v =~ /\n/) { $v =~ s/^/$sp/gm; @@ -293,9 +293,9 @@ sub vpush { # "Normalise" a hash key that's known to be multi-valued. sub vsplit { my ($val) = @_; - my ($line, $word, @words); + my @words; - foreach $line (map {split /\n/} (ref $val eq 'ARRAY') ? @$val : ($val||'')) + foreach my $line (map {split /\n/} (ref $val eq 'ARRAY') ? @$val : ($val||'')) { # XXX: This should become a real parser, ? la Text::ParseWords. $line =~ s/^\s+//; @@ -306,15 +306,7 @@ sub vsplit { return \@words; } -eval "require RT::Interface::REST_Vendor"; -if ($@ && $@ !~ qr{^Can't locate RT/Interface/REST_Vendor.pm}) { - die $@; -}; - -eval "require RT::Interface::REST_Local"; -if ($@ && $@ !~ qr{^Can't locate RT/Interface/REST_Local.pm}) { - die $@; -}; +RT::Base->_ImportOverlays(); 1; diff --git a/rt/lib/RT/Interface/Web.pm b/rt/lib/RT/Interface/Web.pm index ca357a31f..f56abb362 100644 --- a/rt/lib/RT/Interface/Web.pm +++ b/rt/lib/RT/Interface/Web.pm @@ -195,6 +195,8 @@ sub HandleRequest { # Process session-related callbacks before any auth attempts $HTML::Mason::Commands::m->callback( %$ARGS, CallbackName => 'Session', CallbackPage => '/autohandler' ); + MaybeRejectPrivateComponentRequest(); + MaybeShowNoAuthPage($ARGS); AttemptExternalAuth($ARGS) if RT->Config->Get('WebExternalAuthContinuous') or not _UserLoggedIn(); @@ -412,6 +414,37 @@ sub MaybeShowNoAuthPage { $m->abort; } +=head2 MaybeRejectPrivateComponentRequest + +This function will reject calls to private components, like those under +C</Elements>. If the requested path is a private component then we will +abort with a C<403> error. + +=cut + +sub MaybeRejectPrivateComponentRequest { + my $m = $HTML::Mason::Commands::m; + my $path = $m->request_comp->path; + + # We do not check for dhandler here, because requesting our dhandlers + # directly is okay. Mason will invoke the dhandler with a dhandler_arg of + # 'dhandler'. + + if ($path =~ m{ + / # leading slash + ( Elements | + _elements | # mobile UI + Widgets | + autohandler | # requesting this directly is suspicious + l ) # loc component + ( $ | / ) # trailing slash or end of path + }xi) { + $m->abort(403); + } + + return; +} + =head2 ShowRequestedPage \%ARGS This function, called exclusively by RT's autohandler, dispatches @@ -796,8 +829,15 @@ sub SendStaticFile { } $type ||= "application/octet-stream"; } + + # CGI.pm version 3.51 and 3.52 bang charset=iso-8859-1 onto our JS + # since we don't specify a charset + if ( $type =~ m{application/javascript} && + $type !~ m{charset=([\w-]+)$} ) { + $type .= "; charset=utf-8"; + } $HTML::Mason::Commands::r->content_type($type); - open my $fh, "<$file" or die "couldn't open file: $!"; + open( my $fh, '<', $file ) or die "couldn't open file: $!"; binmode($fh); { local $/ = \16384; @@ -841,8 +881,13 @@ sub StripContent { # Check for plaintext sig return '' if not $html and $content =~ /^(--)?\Q$sig\E$/; - # Check for html-formatted sig - RT::Interface::Web::EscapeUTF8( \$sig ); + # Check for html-formatted sig; we don't use EscapeUTF8 here + # because we want to precisely match the escaping that FCKEditor + # uses. see also 311223f5, which fixed this for 4.0 + $sig =~ s/&/&/g; + $sig =~ s/</</g; + $sig =~ s/>/>/g; + return '' if $html and $content =~ m{^(?:<p>)?(--)?\Q$sig\E(?:</p>)?$}s; @@ -2254,9 +2299,6 @@ sub _parse_saved_search { return ( _load_container_object( $obj_type, $obj_id ), $search_id ); } -eval "require RT::Interface::Web_Vendor"; -die $@ if ( $@ && $@ !~ qr{^Can't locate RT/Interface/Web_Vendor.pm} ); -eval "require RT::Interface::Web_Local"; -die $@ if ( $@ && $@ !~ qr{^Can't locate RT/Interface/Web_Local.pm} ); +RT::Base->_ImportOverlays(); 1; diff --git a/rt/lib/RT/Interface/Web/Handler.pm b/rt/lib/RT/Interface/Web/Handler.pm index 772fab0ca..4bb648451 100644 --- a/rt/lib/RT/Interface/Web/Handler.pm +++ b/rt/lib/RT/Interface/Web/Handler.pm @@ -260,6 +260,11 @@ sub CleanupRequest { %RT::Ticket::MERGE_CACHE = ( effective => {}, merged => {} ); + # RT::System persists between requests, so its attributes cache has to be + # cleared manually. Without this, for example, subject tags across multiple + # processes will remain cached incorrectly + delete $RT::System->{attributes}; + # Explicitly remove any tmpfiles that GPG opened, and close their # filehandles. File::Temp::cleanup; diff --git a/rt/lib/RT/Interface/Web/Menu/Item.pm b/rt/lib/RT/Interface/Web/Menu/Item.pm index 5d8e67528..29fb13bcc 100644 --- a/rt/lib/RT/Interface/Web/Menu/Item.pm +++ b/rt/lib/RT/Interface/Web/Menu/Item.pm @@ -47,7 +47,8 @@ # END BPS TAGGED BLOCK }}} package RT::Interface::Web::Menu::Item; - +use strict; +use warnings; sub new { my $class = shift; diff --git a/rt/lib/RT/Interface/Web/QueryBuilder.pm b/rt/lib/RT/Interface/Web/QueryBuilder.pm index 6e462ec6f..09b95398c 100755 --- a/rt/lib/RT/Interface/Web/QueryBuilder.pm +++ b/rt/lib/RT/Interface/Web/QueryBuilder.pm @@ -51,9 +51,6 @@ package RT::Interface::Web::QueryBuilder; use strict; use warnings; -eval "require RT::Interface::Web::QueryBuilder_Vendor"; -die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web/QueryBuilder_Vendor.pm}); -eval "require RT::Interface::Web::QueryBuilder_Local"; -die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web/QueryBuilder_Local.pm}); +RT::Base->_ImportOverlays(); 1; diff --git a/rt/lib/RT/Interface/Web/QueryBuilder/Tree.pm b/rt/lib/RT/Interface/Web/QueryBuilder/Tree.pm index f804e0968..493ab444d 100755 --- a/rt/lib/RT/Interface/Web/QueryBuilder/Tree.pm +++ b/rt/lib/RT/Interface/Web/QueryBuilder/Tree.pm @@ -285,9 +285,6 @@ sub ParseSQL { return @results; } -eval "require RT::Interface::Web::QueryBuilder::Tree_Vendor"; -die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web/QueryBuilder/Tree_Vendor.pm}); -eval "require RT::Interface::Web::QueryBuilder::Tree_Local"; -die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web/QueryBuilder/Tree_Local.pm}); +RT::Base->_ImportOverlays(); 1; diff --git a/rt/lib/RT/Interface/Web/Standalone.pm b/rt/lib/RT/Interface/Web/Standalone.pm index 91dbac33b..3157e315e 100755 --- a/rt/lib/RT/Interface/Web/Standalone.pm +++ b/rt/lib/RT/Interface/Web/Standalone.pm @@ -77,6 +77,15 @@ sub handle_request { Module::Refresh->refresh if RT->Config->Get('DevelMode'); RT::ConnectToDatabase() unless RT->InstallMode; + + # Each environment has its own way of handling .. and so on in paths, + # so RT consistently forbids such paths. + if ( $cgi->path_info =~ m{/\.} ) { + $RT::Logger->crit("Invalid request for ".$cgi->path_info." aborting"); + print STDOUT "HTTP/1.0 400\r\n\r\n"; + return RT::Interface::Web::Handler->CleanupRequest(); + } + $self->SUPER::handle_request($cgi); $RT::Logger->crit($@) if $@ && $RT::Logger; warn $@ if $@ && !$RT::Logger; |