[Rt-commit] r12080 - in rt/branches/3.8-TESTING: . html lib/RT/Crypt lib/RT/Interface

ruz at bestpractical.com ruz at bestpractical.com
Mon May 5 19:43:57 EDT 2008


Author: ruz
Date: Mon May  5 19:43:57 2008
New Revision: 12080

Modified:
   rt/branches/3.8-TESTING/   (props changed)
   rt/branches/3.8-TESTING/configure.ac
   rt/branches/3.8-TESTING/html/autohandler
   rt/branches/3.8-TESTING/lib/RT/Crypt/GnuPG.pm
   rt/branches/3.8-TESTING/lib/RT/CustomField_Overlay.pm
   rt/branches/3.8-TESTING/lib/RT/Interface/Web.pm
   rt/branches/3.8-TESTING/lib/RT/Ticket_Overlay.pm
   rt/branches/3.8-TESTING/releng.cnf

Log:
3.7-RTIR-RELENG -> 3.8-TESTING

 r11807 at cubic-pc (orig r11770):  ruz | 2008-04-18 03:59:56 +0400
 * it's pretty strange, but in Footer we call abort,
   nobody knows why but we do that
 r11808 at cubic-pc (orig r11771):  ruz | 2008-04-18 04:00:44 +0400
 * return correct empty object
 r11809 at cubic-pc (orig r11772):  ruz | 2008-04-18 04:01:43 +0400
 * actually use value we were fetching so hard from the DB
 r11815 at cubic-pc (orig r11778):  ruz | 2008-04-18 21:17:10 +0400
 * bump version
 r12033 at cubic-pc (orig r11996):  ruz | 2008-05-02 01:06:25 +0400
 * skip category on CF update
 r12076 at cubic-pc (orig r12039):  ruz | 2008-05-04 15:43:15 +0400
 * we don't support some combinations of CF type and max values,
   check input in CF->Create method
 r12077 at cubic-pc (orig r12040):  ruz | 2008-05-04 15:52:01 +0400
 * check should match wikitext as well
 r12112 at cubic-pc (orig r12075):  ruz | 2008-05-06 02:07:31 +0400
 * decrypt/verify inline GPG parts using blocks to avoid loosing of literals
 r12113 at cubic-pc (orig r12076):  ruz | 2008-05-06 02:13:42 +0400
 * bump version


Modified: rt/branches/3.8-TESTING/configure.ac
==============================================================================

Modified: rt/branches/3.8-TESTING/html/autohandler
==============================================================================
--- rt/branches/3.8-TESTING/html/autohandler	(original)
+++ rt/branches/3.8-TESTING/html/autohandler	Mon May  5 19:43:57 2008
@@ -61,8 +61,9 @@
 # Roll back any dangling transactions from a previous failed connection
 $RT::Handle->ForceRollback() if $RT::Handle->TransactionDepth;
 
+my $log_sql_statements = RT->Config->Get('StatementLog');
 
-if (RT->Config->Get('StatementLog')) {
+if ( $log_sql_statements ) {
     $RT::Handle->ClearSQLStatementLog;
     $RT::Handle->LogSQLStatements(1);
 }
@@ -305,9 +306,7 @@
     $m->comp( { base_comp => $m->request_comp }, $m->fetch_next, %ARGS);
 }
 
-$m->comp( '/Elements/Footer', %ARGS );
-
-if (RT->Config->Get('StatementLog')) {
+if ( $log_sql_statements ) {
     my @log = $RT::Handle->SQLStatementLog;
     $RT::Handle->ClearSQLStatementLog;
     for my $stmt (@log) {
@@ -322,13 +321,15 @@
             $duration = $bind;
         }
         $RT::Logger->log(
-            level => RT->Config->Get('StatementLog'),
+            level => $log_sql_statements,
             message => "SQL(" . sprintf( "%.2f", $duration ) . "s): $sql;"
                 . ( @bind ? "  [ bound values: @{[map{qq|'$_'|} @bind]} ]" : "" )
         );
     }
 }
 
+$m->comp( '/Elements/Footer', %ARGS );
+
 </%INIT>
 <%ARGS>
 $user => undef

Modified: rt/branches/3.8-TESTING/lib/RT/Crypt/GnuPG.pm
==============================================================================
--- rt/branches/3.8-TESTING/lib/RT/Crypt/GnuPG.pm	(original)
+++ rt/branches/3.8-TESTING/lib/RT/Crypt/GnuPG.pm	Mon May  5 19:43:57 2008
@@ -1082,10 +1082,7 @@
     return @res;
 }
 
-sub VerifyInline {
-    my %args = ( Data => undef, Top => undef, @_ );
-    return DecryptInline( %args );
-}
+sub VerifyInline { return DecryptInline( @_ ) }
 
 sub VerifyAttachment {
     my %args = ( Data => undef, Signature => undef, Top => undef, @_ );
@@ -1287,7 +1284,7 @@
         RT::EmailParser->_DecodeBody($args{'Data'});
     }
 
-    # handling passphrase in GnupGOptions
+    # handling passphrase in GnuPGOptions
     $args{'Passphrase'} = delete $opt{'passphrase'}
         if !defined($args{'Passphrase'});
 
@@ -1297,24 +1294,84 @@
     my ($tmp_fh, $tmp_fn) = File::Temp::tempfile();
     binmode $tmp_fh, ':raw';
 
+    my $io = $args{'Data'}->open('r');
+    unless ( $io ) {
+        die "Entity has no body, never should happen";
+    }
+
+    my ($had_literal, $in_block) = ('', 0);
+    my ($block_fh, $block_fn) = File::Temp::tempfile();
+    binmode $block_fh, ':raw';
+
+    my %res;
+    while ( defined(my $str = $io->getline) ) {
+        if ( $in_block && $str =~ /-----END PGP (?:MESSAGE|SIGNATURE)-----/ ) {
+            print $block_fh $str;
+            seek $block_fh, 0, 0;
+
+            my ($res_fh, $res_fn);
+            ($res_fh, $res_fn, %res) = _DecryptInlineBlock(
+                %args,
+                GnuPG => $gnupg,
+                BlockHandle => $block_fh,
+            );
+            return %res unless $res_fh;
+
+            print $tmp_fh "-----BEGIN OF PGP PROTECTED PART-----\n" if $had_literal;
+            while (my $buf = <$res_fh> ) {
+                print $tmp_fh $buf;
+            }
+            print $tmp_fh "-----END OF PART-----\n" if $had_literal;
+
+            ($block_fh, $block_fn) = File::Temp::tempfile();
+            binmode $block_fh, ':raw';
+            $in_block = 0;
+        }
+        elsif ( $in_block || $str =~ /-----BEGIN PGP (SIGNED )?MESSAGE-----/ ) {
+            $in_block = 1;
+            print $block_fh $str;
+        }
+        else {
+            print $tmp_fh $str;
+            $had_literal = 1 if /\S/s;
+        }
+    }
+    $io->close;
+
+    seek $tmp_fh, 0, 0;
+    $args{'Data'}->bodyhandle( new MIME::Body::File $tmp_fn );
+    $args{'Data'}->{'__store_tmp_handle_to_avoid_early_cleanup'} = $tmp_fh;
+    return %res;
+}
+
+sub _DecryptInlineBlock {
+    my %args = (
+        GnuPG => undef,
+        BlockHandle => undef,
+        Passphrase => undef,
+        @_
+    );
+    my $gnupg = $args{'GnuPG'};
+
+    my ($tmp_fh, $tmp_fn) = File::Temp::tempfile();
+    binmode $tmp_fh, ':raw';
+
     my %handle;
     my $handles = GnuPG::Handles->new(
-        stdin  => ($handle{'input'}  = new IO::Handle),
+        stdin  => $args{'BlockHandle'},
         stdout => $tmp_fh,
         stderr => ($handle{'error'}  = new IO::Handle),
         logger => ($handle{'logger'} = new IO::Handle),
         status => ($handle{'status'} = new IO::Handle),
     );
     $handles->options( 'stdout' )->{'direct'} = 1;
+    $handles->options( 'stdin' )->{'direct'} = 1;
 
     my %res;
     eval {
         local $SIG{'CHLD'} = 'DEFAULT';
         $gnupg->passphrase( $args{'Passphrase'} );
         my $pid = _safe_run_child { $gnupg->decrypt( handles => $handles ) };
-        $args{'Data'}->bodyhandle->print( $handle{'input'} );
-        close $handle{'input'};
-
         waitpid $pid, 0;
     };
     $res{'exit_code'} = $?;
@@ -1333,14 +1390,12 @@
     if ( $res{'status'} !~ /DECRYPTION_OKAY/ ) {
         if ( $@ || $? ) {
             $res{'message'} = $@? $@: "gpg exitted with error code ". ($? >> 8);
-            return %res;
+            return (undef, undef, %res);
         }
     }
 
     seek $tmp_fh, 0, 0;
-    $args{'Data'}->bodyhandle( new MIME::Body::File $tmp_fn );
-    $args{'Data'}->{'__store_tmp_handle_to_avoid_early_cleanup'} = $tmp_fh;
-    return %res;
+    return ($tmp_fh, $tmp_fn, %res);
 }
 
 sub DecryptAttachment {
@@ -1350,8 +1405,41 @@
         Passphrase => undef,
         @_
     );
-    my %res = DecryptInline( %args );
-    return %res if $res{'exit_code'};
+
+    my $gnupg = new GnuPG::Interface;
+    my %opt = RT->Config->Get('GnuPGOptions');
+    $opt{'digest-algo'} ||= 'SHA1';
+    $gnupg->options->hash_init(
+        _PrepareGnuPGOptions( %opt ),
+        meta_interactive => 0,
+    );
+
+    if ( $args{'Data'}->bodyhandle->is_encoded ) {
+        require RT::EmailParser;
+        RT::EmailParser->_DecodeBody($args{'Data'});
+    }
+
+    # handling passphrase in GnuPGOptions
+    $args{'Passphrase'} = delete $opt{'passphrase'}
+        if !defined($args{'Passphrase'});
+
+    $args{'Passphrase'} = GetPassphrase()
+        unless defined $args{'Passphrase'};
+
+    my ($tmp_fh, $tmp_fn) = File::Temp::tempfile();
+    binmode $tmp_fh, ':raw';
+    $args{'Data'}->bodyhandle->print( $tmp_fh );
+    seek $tmp_fh, 0, 0;
+
+    my ($res_fh, $res_fn, %res) = _DecryptInlineBlock(
+        %args,
+        GnuPG => $gnupg,
+        BlockHandle => $tmp_fh,
+    );
+    return %res unless $res_fh;
+
+    $args{'Data'}->bodyhandle( new MIME::Body::File $res_fn );
+    $args{'Data'}->{'__store_tmp_handle_to_avoid_early_cleanup'} = $res_fh;
 
     my $filename = $args{'Data'}->head->recommended_filename;
     $filename =~ s/\.pgp$//i;

Modified: rt/branches/3.8-TESTING/lib/RT/CustomField_Overlay.pm
==============================================================================
--- rt/branches/3.8-TESTING/lib/RT/CustomField_Overlay.pm	(original)
+++ rt/branches/3.8-TESTING/lib/RT/CustomField_Overlay.pm	Mon May  5 19:43:57 2008
@@ -177,7 +177,8 @@
         # old style Type string
         $args{'MaxValues'} = $1 ? 1 : 0;
     }
-    
+    $args{'MaxValues'} = int $args{'MaxValues'};
+
     if ( !exists $args{'Queue'}) {
     # do nothing -- things below are strictly backward compat
     }
@@ -203,6 +204,11 @@
     my ($ok, $msg) = $self->_IsValidRegex( $args{'Pattern'} );
     return (0, $self->loc("Invalid pattern: [_1]", $msg)) unless $ok;
 
+    if ( $args{'MaxValues'} != 1 && $args{'Type'} =~ /(text|combobox)$/i ) {
+        $RT::Logger->warning("Support for 'multiple' Texts or Comboboxes is not implemented");
+        $args{'MaxValues'} = 1;
+    }
+
     (my $rv, $msg) = $self->SUPER::Create(
         Name        => $args{'Name'},
         Type        => $args{'Type'},

Modified: rt/branches/3.8-TESTING/lib/RT/Interface/Web.pm
==============================================================================
--- rt/branches/3.8-TESTING/lib/RT/Interface/Web.pm	(original)
+++ rt/branches/3.8-TESTING/lib/RT/Interface/Web.pm	Mon May  5 19:43:57 2008
@@ -1262,7 +1262,8 @@
 
     my @results;
     foreach my $arg ( keys %{ $args{'ARGS'} } ) {
-        next if $arg =~ /Category$/;
+        # skip category argument
+        next if $arg eq 'Category';
 
         # since http won't pass in a form element with a null value, we need
         # to fake it

Modified: rt/branches/3.8-TESTING/lib/RT/Ticket_Overlay.pm
==============================================================================
--- rt/branches/3.8-TESTING/lib/RT/Ticket_Overlay.pm	(original)
+++ rt/branches/3.8-TESTING/lib/RT/Ticket_Overlay.pm	Mon May  5 19:43:57 2008
@@ -3468,8 +3468,9 @@
         }
         unless ( $cf->id ) {
             # If we didn't find a valid cfid, give up.
-            return RT::CustomFieldValues->new($self->CurrentUser);
+            return RT::ObjectCustomFieldValues->new($self->CurrentUser);
         }
+        $field = $cf->id;
     }
     return $self->SUPER::CustomFieldValues($field);
 }

Modified: rt/branches/3.8-TESTING/releng.cnf
==============================================================================


More information about the Rt-commit mailing list