[Rt-commit] r7710 - in rt/branches/3.7-EXPERIMENTAL-TUNIS: . etc
etc/upgrade/3.7.10 html/Admin/CustomFields
html/Admin/Elements html/Elements html/Ticket lib/RT/Action
lib/RT/Crypt lib/RT/Interface
clkao at bestpractical.com
clkao at bestpractical.com
Fri Apr 27 02:45:56 EDT 2007
Author: clkao
Date: Fri Apr 27 02:45:54 2007
New Revision: 7710
Added:
rt/branches/3.7-EXPERIMENTAL-TUNIS/etc/upgrade/3.7.10/
rt/branches/3.7-EXPERIMENTAL-TUNIS/etc/upgrade/3.7.10/content
Modified:
rt/branches/3.7-EXPERIMENTAL-TUNIS/ (props changed)
rt/branches/3.7-EXPERIMENTAL-TUNIS/etc/initialdata
rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Admin/CustomFields/Modify.html
rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Admin/Elements/PickObjects
rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Admin/Elements/SelectCustomFieldLookupType
rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Elements/Logo
rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Ticket/ShowEmailRecord.html
rt/branches/3.7-EXPERIMENTAL-TUNIS/lib/RT/Action/SendEmail.pm
rt/branches/3.7-EXPERIMENTAL-TUNIS/lib/RT/Crypt/GnuPG.pm
rt/branches/3.7-EXPERIMENTAL-TUNIS/lib/RT/Interface/Email.pm
rt/branches/3.7-EXPERIMENTAL-TUNIS/lib/RT/Interface/Email/Auth/GnuPGNG.pm
rt/branches/3.7-EXPERIMENTAL-TUNIS/releng.cnf
Log:
merge down for tunis.
Modified: rt/branches/3.7-EXPERIMENTAL-TUNIS/etc/initialdata
==============================================================================
--- rt/branches/3.7-EXPERIMENTAL-TUNIS/etc/initialdata (original)
+++ rt/branches/3.7-EXPERIMENTAL-TUNIS/etc/initialdata Fri Apr 27 02:45:54 2007
@@ -409,11 +409,9 @@
You received this message as RT has problems with public keys of the following user:
{
- my $res = '';
foreach my $e ( @BadRecipients ) {
- $res .= "* ". $e->{'Message'} ."\n";
+ $OUT .= "* ". $e->{'Message'} ."\n";
}
- $res
}}
},
{ Queue => 0,
@@ -428,6 +426,18 @@
Please, check that you encrypt messages with correct keys
or contact the system administrator.}
},
+ { Queue => 0,
+ Name => "Error: bad GnuPG data", # loc
+ Description =>
+ "Inform user that a message he sent has invalid GnuPG data", # loc
+ Content => q{Subject: We received a message we cannot handle
+
+You sent us a message that we cannot handle due to corrupted GnuPG signature or encrypted block. we get the following error(s):
+{ foreach my $msg ( @Messages ) {
+ $OUT .= "* $msg\n";
+ }
+}}
+ },
);
# }}}
Added: rt/branches/3.7-EXPERIMENTAL-TUNIS/etc/upgrade/3.7.10/content
==============================================================================
--- (empty file)
+++ rt/branches/3.7-EXPERIMENTAL-TUNIS/etc/upgrade/3.7.10/content Fri Apr 27 02:45:54 2007
@@ -0,0 +1,49 @@
+
+ at Templates = (
+ { Queue => 0,
+ Name => "Error: public key", # loc
+ Description =>
+ "Inform user that he has problems with public key and couldn't recieve encrypted content", # loc
+ Content => q{Subject: We have no your public key or it's wrong
+
+You received this message as we have no your public PGP key or we have a problem with your key. Inform the administrator about the problem.
+}
+ },
+ { Queue => 0,
+ Name => "Error to RT owner: public key", # loc
+ Description =>
+ "Inform RT owner that user(s) have problems with public keys", # loc
+ Content => q{Subject: Some users have problems with public keys
+
+You received this message as RT has problems with public keys of the following user:
+{
+ foreach my $e ( @BadRecipients ) {
+ $OUT .= "* ". $e->{'Message'} ."\n";
+ }
+}}
+ },
+ { Queue => 0,
+ Name => "Error: no private key", # loc
+ Description =>
+ "Inform user that we received an encrypted email and we have no private keys to decrypt", # loc
+ Content => q{Subject: we received message we cannot decrypt
+
+You sent an encrypted message with subject '{ $Message->head->get('Subject') }',
+but we have no private key it's encrypted to.
+
+Please, check that you encrypt messages with correct keys
+or contact the system administrator.}
+ },
+ { Queue => 0,
+ Name => "Error: bad GnuPG data", # loc
+ Description =>
+ "Inform user that a message he sent has invalid GnuPG data", # loc
+ Content => q{Subject: We received a message we cannot handle
+
+You sent us a message that we cannot handle due to corrupted GnuPG signature or encrypted block. we get the following error(s):
+{ foreach my $msg ( @Messages ) {
+ $OUT .= "* $msg\n";
+ }
+}}
+ },
+);
Modified: rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Admin/CustomFields/Modify.html
==============================================================================
--- rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Admin/CustomFields/Modify.html (original)
+++ rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Admin/CustomFields/Modify.html Fri Apr 27 02:45:54 2007
@@ -186,6 +186,7 @@
while ( my $value = $values->Next ) {
foreach my $attr qw(Name Description SortOrder Category) {
my $param = "$paramtag-". $value->Id ."-". $attr;
+ next unless exists $ARGS{$param};
next if ($value->$attr()||'') eq ($ARGS{$param}||'');
my $mutator = "Set$attr";
Modified: rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Admin/Elements/PickObjects
==============================================================================
--- rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Admin/Elements/PickObjects (original)
+++ rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Admin/Elements/PickObjects Fri Apr 27 02:45:54 2007
@@ -66,7 +66,7 @@
% } else {
<i>(<%loc("no name")%>)</i><br />
% }
- <%$Object->can('Description') && $Object->Description%>
+ <%$Object->can('Description') ? ($Object->Description||'') : '' %>
</label>
</td>
</tr>
Modified: rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Admin/Elements/SelectCustomFieldLookupType
==============================================================================
--- rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Admin/Elements/SelectCustomFieldLookupType (original)
+++ rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Admin/Elements/SelectCustomFieldLookupType Fri Apr 27 02:45:54 2007
@@ -47,7 +47,7 @@
%# END BPS TAGGED BLOCK }}}
<select NAME ="<%$Name%>">
%for my $option ($cf->LookupTypes) {
-<option value="<%$option%>" <%$option eq $Default && "SELECTED"%>><% $cf->FriendlyLookupType($option) %></option>
+<option value="<%$option%>" <%$option eq $Default ? "SELECTED" : ''%>><% $cf->FriendlyLookupType($option) %></option>
%}
</select>
<%INIT>
@@ -55,6 +55,6 @@
</%INIT>
<%ARGS>
-$Default=>undef
+$Default=> ''
$Name => 'LookupType'
</%ARGS>
Modified: rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Elements/Logo
==============================================================================
--- rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Elements/Logo (original)
+++ rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Elements/Logo Fri Apr 27 02:45:54 2007
@@ -47,7 +47,7 @@
%# END BPS TAGGED BLOCK }}}
<div id="logo">
<a href="http://bestpractical.com"><img
- src="<%RT->Config->Get('WebImagesURL')%>/bplogo.gif"
+ src="<%$ARGS{'LogoURL'}||RT->Config->Get('LogoURL')%>"
alt="<% loc("Best Practical Solutions, LLC corporate logo") %>"
width="177" height="33" /></a>
% if ( $ShowName ) {
Modified: rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Ticket/ShowEmailRecord.html
==============================================================================
--- rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Ticket/ShowEmailRecord.html (original)
+++ rt/branches/3.7-EXPERIMENTAL-TUNIS/html/Ticket/ShowEmailRecord.html Fri Apr 27 02:45:54 2007
@@ -49,25 +49,48 @@
$Attachment => undef
$Transaction => undef
</%ARGS>
-<%init>
- my $AttachmentObj = new RT::Attachment($session{'CurrentUser'});
- $AttachmentObj->Load($Attachment) || Abort(loc("Attachment '[_1]' could not be loaded", $Attachment));
-
+<%INIT>
+my $show_content = sub {
+ my $attach = shift;
+ if ( $attach->ContentType =~ m{^(?:text|message)/}i ) {
+ $m->out( $m->interp->apply_escapes( $attach->Content, 'h' ) );
+ return;
+ }
+ my $href = RT->Config->Get('WebPath') .'/Ticket/Attachment/'
+ . $attach->TransactionId .'/'. $attach->id .'/'
+ . $m->interp->apply_escapes( $attach->Filename, 'u' );
+ $m->out( '<a href="'. $href .'">'. loc('download') .'</a>' );
+};
- unless ($AttachmentObj->id) {
- Abort(loc("Attachment '[_1]' could not be loaded", $Attachment));
+my $show;
+$show = sub {
+ my $attach = shift;
+ $m->out( '<pre style="padding: 2em;">' );
+ $m->out( $m->interp->apply_escapes( $attach->Headers, 'h' ) );
+ $m->out( "\n\n" );
+ if ( $attach->ContentType =~ m{^multipart/}i ) {
+ my $children = $attach->Children;
+ while ( my $child = $children->Next ) {
+ $show->( $child );
+ }
+ } else {
+ $show_content->( $attach );
}
- unless ($AttachmentObj->TransactionId() == $Transaction ) {
- Abort(loc("Attachment '[_1]' could not be loaded", $Attachment));
- }
+ $m->out( '</pre>' );
+};
-</%init>
-<& /Elements/Header, ShowBar => 0 &>
-<pre style="padding: 2em;">
-<%$AttachmentObj->Headers%>
+my $AttachmentObj = new RT::Attachment($session{'CurrentUser'});
+$AttachmentObj->Load($Attachment) || Abort(loc("Attachment '[_1]' could not be loaded", $Attachment));
+unless ( $AttachmentObj->id ) {
+ Abort(loc("Attachment '[_1]' could not be loaded", $Attachment));
+}
+unless ($AttachmentObj->TransactionId() == $Transaction ) {
+ Abort(loc("Attachment '[_1]' could not be loaded", $Attachment));
+}
-<%$AttachmentObj->Content%>
-</pre>
+</%INIT>
+<& /Elements/Header, ShowBar => 0 &>
+% $show->( $AttachmentObj );
</body>
</html>
-%$m->abort;
+% $m->abort;
Modified: rt/branches/3.7-EXPERIMENTAL-TUNIS/lib/RT/Action/SendEmail.pm
==============================================================================
--- rt/branches/3.7-EXPERIMENTAL-TUNIS/lib/RT/Action/SendEmail.pm (original)
+++ rt/branches/3.7-EXPERIMENTAL-TUNIS/lib/RT/Action/SendEmail.pm Fri Apr 27 02:45:54 2007
@@ -101,9 +101,37 @@
sub Commit {
my $self = shift;
- my ($ret) = $self->SendMessage( $self->TemplateObj->MIMEObj );
+ my $message = $self->TemplateObj->MIMEObj;
+
+ my $orig_message;
+ if ( RT->Config->Get('RecordOutgoingEmail') ) {
+ # it's hacky, but we should know if we're going to crypt things
+ my $attachment = $self->TransactionObj->Attachments->First;
+
+ my %crypt;
+ foreach my $argument ( qw(Sign Encrypt) ) {
+ if ( $attachment && defined $attachment->GetHeader("X-RT-$argument") ) {
+ $crypt{$argument} = $attachment->GetHeader("X-RT-$argument");
+ } else {
+ $crypt{$argument} = $self->TicketObj->QueueObj->$argument();
+ }
+ }
+ if ( $crypt{'Sign'} || $crypt{'Encrypt'} ) {
+ $orig_message = $message->dup;
+ }
+ }
+
+
+ my ($ret) = $self->SendMessage( $message );
if ( $ret > 0 && RT->Config->Get('RecordOutgoingEmail') ) {
- $self->RecordOutgoingMailTransaction( $self->TemplateObj->MIMEObj )
+ if ( $orig_message ) {
+ $message->attach(
+ Type => 'application/x-rt-original-message',
+ Disposition => 'inline',
+ Data => $orig_message->as_string,
+ );
+ }
+ $self->RecordOutgoingMailTransaction( $message );
}
return (abs $ret);
}
Modified: rt/branches/3.7-EXPERIMENTAL-TUNIS/lib/RT/Crypt/GnuPG.pm
==============================================================================
--- rt/branches/3.7-EXPERIMENTAL-TUNIS/lib/RT/Crypt/GnuPG.pm (original)
+++ rt/branches/3.7-EXPERIMENTAL-TUNIS/lib/RT/Crypt/GnuPG.pm Fri Apr 27 02:45:54 2007
@@ -82,21 +82,6 @@
verbose
);
-=head2 SignEncrypt Entity => MIME::Entity, [ Encrypt => 1, Sign => 1, Passphrase => undef ]
-
-Signs and/or encrypts an email message with GnuPG utility. A passphrase is required
-only during signing, if value is undefined then L</GetPassphrase> called to get it.
-
-Returns a hash with the following keys:
-
-* exit_code
-* error
-* logger
-* status
-* message
-
-=cut
-
sub _safe_run_child (&) {
# We need to reopen stdout temporarily, because in FCGI
# environment, stdout is tied to FCGI::Stream, and the child
@@ -117,24 +102,76 @@
return shift->();
}
+=head2 SignEncrypt Entity => MIME::Entity, [ Encrypt => 1, Sign => 1, ... ]
+
+Signs and/or encrypts an email message with GnuPG utility.
+
+=over
+
+=item Signing
+
+During signing you can pass C<Signer> argument to set key we sign with this option
+overrides gnupg's C<default-key> option. If C<Signer> argument is not provided
+then address of a message sender is used.
+
+As well you can pass C<Passphrase>, but if value is undefined then L</GetPassphrase>
+called to get it.
+
+=item Encrypting
+
+During encryption you can pass a C<Recipients> array, otherwise C<To>, C<Cc> and
+C<Bcc> fields of the message are used to fetch the list.
+
+=back
+
+Returns a hash with the following keys:
+
+* exit_code
+* error
+* logger
+* status
+* message
+
+=cut
+
sub SignEncrypt {
+ my %args = (@_);
+
+ my $entity = $args{'Entity'};
+ if ( $args{'Sign'} && !defined $args{'Signer'} ) {
+ $args{'Signer'} = (Mail::Address->parse( $entity->head->get( 'From' ) ))[0]->address;
+ }
+ if ( $args{'Encrypt'} && !$args{'Recipients'} ) {
+ my %seen;
+ $args{'Recipients'} = [
+ grep $_ && !$seen{ $_ }++, map $_->address,
+ map Mail::Address->parse( $entity->head->get( $_ ) ),
+ qw(To Cc Bcc)
+ ];
+ }
my $format = lc RT->Config->Get('GnuPG')->{'OutgoingMessagesFormat'} || 'RFC';
if ( $format eq 'inline' ) {
- return SignEncryptInline( @_ );
+ return SignEncryptInline( %args );
} else {
- return SignEncryptRFC3156( @_ );
+ return SignEncryptRFC3156( %args );
}
}
sub SignEncryptRFC3156 {
my %args = (
Entity => undef,
- Encrypt => 1,
+
Sign => 1,
+ Signer => undef,
Passphrase => undef,
+
+ Encrypt => 1,
+ Recipients => undef,
+
@_
);
+
my $entity = $args{'Entity'};
if ( $args{'Sign'} && !defined $args{'Passphrase'} ) {
@@ -144,13 +181,12 @@
my $gnupg = new GnuPG::Interface;
my %opt = RT->Config->Get('GnuPGOptions');
$opt{'digest-algo'} ||= 'SHA1';
- # address of the queue
- my $sign_as = (Mail::Address->parse( $entity->head->get( 'From' ) ))[0]->address;
+ $opt{'default_key'} = $args{'Signer'}
+ if $args{'Sign'} && $args{'Signer'};
$gnupg->options->hash_init(
_PrepareGnuPGOptions( %opt ),
armor => 1,
meta_interactive => 0,
- default_key => $sign_as,
);
my %res;
@@ -275,36 +311,24 @@
}
sub SignEncryptInline {
- my %args = (@_);
+ my %args = ( @_ );
my $entity = $args{'Entity'};
- if ( $args{'Sign'} && !defined $args{'Signer'} ) {
- $args{'Signer'} = (Mail::Address->parse( $entity->head->get( 'From' ) ))[0]->address;
- }
- if ( $args{'Encrypt'} && !$args{'Recipients'} ) {
- my %seen;
- $args{'Recipients'} = [
- grep $_ && !$seen{ $_ }++, map $_->address,
- map Mail::Address->parse( $entity->head->get( $_ ) ),
- qw(To Cc Bcc)
- ];
- }
my %res;
-
$entity->make_singlepart;
if ( $entity->is_multipart ) {
foreach ( $entity->parts ) {
- %res = SignEncryptInline( %args, Entity => $_ );
+ %res = SignEncryptInline( @_, Entity => $_ );
return %res if $res{'exit_code'};
}
return %res;
}
- return _SignEncryptTextInline( %args )
+ return _SignEncryptTextInline( @_ )
if $entity->effective_type =~ /^text\//i;
- return _SignEncryptAttachmentInline( %args );
+ return _SignEncryptAttachmentInline( @_ );
}
sub _SignEncryptTextInline {
@@ -329,25 +353,17 @@
my $gnupg = new GnuPG::Interface;
my %opt = RT->Config->Get('GnuPGOptions');
$opt{'digest-algo'} ||= 'SHA1';
+ $opt{'default_key'} = $args{'Signer'}
+ if $args{'Sign'} && $args{'Signer'};
$gnupg->options->hash_init(
_PrepareGnuPGOptions( %opt ),
armor => 1,
meta_interactive => 0,
- ( $args{'Sign'} && $args{'Signer'}? (default_key => $args{'Signer'}): () ),
);
- my $entity = $args{'Entity'};
if ( $args{'Encrypt'} ) {
- unless ( $args{'Recipients'} ) {
- my %seen;
- $gnupg->options->push_recipients( $_ )
- foreach grep $_ && !$seen{ $_ }++, map $_->address,
- map Mail::Address->parse( $entity->head->get( $_ ) ),
- qw(To Cc Bcc);
- } else {
- $gnupg->options->push_recipients( $_ )
- foreach @{ $args{'Recipients'} };
- }
+ $gnupg->options->push_recipients( $_ )
+ foreach @{ $args{'Recipients'} || [] };
}
my %res;
@@ -366,6 +382,7 @@
$handles->options( 'stdout' )->{'direct'} = 1;
$gnupg->passphrase( $args{'Passphrase'} ) if $args{'Sign'};
+ my $entity = $args{'Entity'};
eval {
local $SIG{'CHLD'} = 'DEFAULT';
my $method = $args{'Sign'} && $args{'Encrypt'}
@@ -420,25 +437,18 @@
my $gnupg = new GnuPG::Interface;
my %opt = RT->Config->Get('GnuPGOptions');
$opt{'digest-algo'} ||= 'SHA1';
+ $opt{'default_key'} = $args{'Signer'}
+ if $args{'Sign'} && $args{'Signer'};
$gnupg->options->hash_init(
_PrepareGnuPGOptions( %opt ),
armor => 1,
meta_interactive => 0,
- ( $args{'Sign'} && $args{'Signer'}? (default_key => $args{'Signer'}): () ),
);
my $entity = $args{'Entity'};
if ( $args{'Encrypt'} ) {
- unless ( $args{'Recipients'} ) {
- my %seen;
- $gnupg->options->push_recipients( $_ )
- foreach grep $_ && !$seen{ $_ }++, map $_->address,
- map Mail::Address->parse( $entity->head->get( $_ ) ),
- qw(To Cc Bcc);
- } else {
- $gnupg->options->push_recipients( $_ )
- foreach @{ $args{'Recipients'} };
- }
+ $gnupg->options->push_recipients( $_ )
+ foreach @{ $args{'Recipients'} || [] };
}
my %res;
@@ -1242,6 +1252,7 @@
my $reason = ReasonCodeToText( $keyword, $rcode );
push @res, {
Operation => 'Data',
+ Status => 'ERROR',
Message => "No data has been found. The reason is '$reason'",
ReasonCode => $rcode,
Reason => $reason,
Modified: rt/branches/3.7-EXPERIMENTAL-TUNIS/lib/RT/Interface/Email.pm
==============================================================================
--- rt/branches/3.7-EXPERIMENTAL-TUNIS/lib/RT/Interface/Email.pm (original)
+++ rt/branches/3.7-EXPERIMENTAL-TUNIS/lib/RT/Interface/Email.pm Fri Apr 27 02:45:54 2007
@@ -351,7 +351,7 @@
foreach my $argument ( qw(Sign Encrypt) ) {
if ( $attachment && defined $attachment->GetHeader("X-RT-$argument") ) {
$crypt{$argument} = $attachment->GetHeader("X-RT-$argument");
- } else {
+ } else {
$crypt{$argument} = $args{'Ticket'}->QueueObj->$argument();
}
}
Modified: rt/branches/3.7-EXPERIMENTAL-TUNIS/lib/RT/Interface/Email/Auth/GnuPGNG.pm
==============================================================================
--- rt/branches/3.7-EXPERIMENTAL-TUNIS/lib/RT/Interface/Email/Auth/GnuPGNG.pm (original)
+++ rt/branches/3.7-EXPERIMENTAL-TUNIS/lib/RT/Interface/Email/Auth/GnuPGNG.pm Fri Apr 27 02:45:54 2007
@@ -95,7 +95,7 @@
unless ( $status ) {
$RT::Logger->error("Had a problem during decrypting and verifying");
my $reject = HandleErrors( Message => $args{'Message'}, Result => \@res );
- return $args{'CurrentUser'}, -2;
+ return $args{'CurrentUser'}, -2 if $reject;
}
# attach the original encrypted message
@@ -149,6 +149,12 @@
$reject = 1;
}
}
+ unless ( $sent_once{'BadData'} ) {
+ unless ( CheckBadData( Message => $args{'Message'}, Status => \@status ) ) {
+ $sent_once{'BadData'}++;
+ $reject = 1;
+ }
+ }
}
return $reject;
}
@@ -178,6 +184,31 @@
return 0;
}
+sub CheckBadData {
+ my %args = (Message => undef, Status => [], @_ );
+ my @bad_data_messages =
+ map $_->{'Message'},
+ grep $_->{'Status'} ne 'DONE' && $_->{'Operation'} eq 'Data',
+ @{ $args{'Status'} };
+ return 1 unless @bad_data_messages;
+
+ $RT::Logger->error("Couldn't process a message: ". join ', ', @bad_data_messages );
+
+ my $address = (RT::Interface::Email::ParseSenderAddressFromHead( $args{'Message'}->head ))[0];
+ my $status = RT::Interface::Email::SendEmailUsingTemplate(
+ To => $address,
+ Template => 'Error: bad GnuPG data',
+ Arguments => {
+ Messages => [ @bad_data_messages ],
+ TicketObj => $args{'Ticket'},
+ },
+ );
+ unless ( $status ) {
+ $RT::Logger->error("Couldn't send 'Error: bad GnuPG data'");
+ }
+ return 0;
+}
+
sub VerifyDecrypt {
my %args = (
Entity => undef,
Modified: rt/branches/3.7-EXPERIMENTAL-TUNIS/releng.cnf
==============================================================================
--- rt/branches/3.7-EXPERIMENTAL-TUNIS/releng.cnf (original)
+++ rt/branches/3.7-EXPERIMENTAL-TUNIS/releng.cnf Fri Apr 27 02:45:54 2007
@@ -1,5 +1,5 @@
PRODUCT = rt
-TAG = 3.7.4
+TAG = 3.7.10
CANONICAL_REPO = svn+ssh://svn.bestpractical.com/svn/bps-public/rt/
TAGS = tags/
TRUNK = branches/3.7-EXPERIMENTAL
More information about the Rt-commit
mailing list