Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock
Please unblock package otrs2. -security also ACKed this upload. diff -Naur '--exclude=.svn' 3.3.9-2/debian/changelog 3.3.9-3/debian/changelog --- 3.3.9-2/debian/changelog 2014-10-29 09:32:47.224286362 +0100 +++ 3.3.9-3/debian/changelog 2014-12-18 19:57:30.862192259 +0100 @@ -1,3 +1,13 @@ +otrs2 (3.3.9-3) unstable; urgency=medium + + * Add patch 16-CVE-2014-9324.diff which fixes CVE-2014-9324, also known as + OSA-2014-06: + An attacker with valid OTRS credentials could access and manipulate ticket + data of other users via the GenericInterface, if a ticket webservice is + configured and not additionally secured. + + -- Patrick Matthäi <pmatth...@debian.org> Thu, 18 Dec 2014 19:02:56 +0100 + otrs2 (3.3.9-2) unstable; urgency=low * Drop libjs-jquery dependency and use the emebedded version again to avoid diff -Naur '--exclude=.svn' 3.3.9-2/debian/patches/16-CVE-2014-9324.diff 3.3.9-3/debian/patches/16-CVE-2014-9324.diff --- 3.3.9-2/debian/patches/16-CVE-2014-9324.diff 1970-01-01 01:00:00.000000000 +0100 +++ 3.3.9-3/debian/patches/16-CVE-2014-9324.diff 2014-12-18 19:57:30.874192201 +0100 @@ -0,0 +1,1528 @@ +# Upstream patch to fix CVE-2014-9324, also known as OSA-2014-06: +# An attacker with valid OTRS credentials could access and manipulate ticket +# data of other users via the GenericInterface, if a ticket webservice is +# configured and not additionally secured. +# URL: +# https://www.otrs.com/security-advisory-2014-06-incomplete-access-control/ + +diff -Naur otrs2-3.3.9.orig/Kernel/GenericInterface/Operation/Ticket/Common.pm otrs2-3.3.9/Kernel/GenericInterface/Operation/Ticket/Common.pm +--- otrs2-3.3.9.orig/Kernel/GenericInterface/Operation/Ticket/Common.pm 2014-09-03 15:15:41.000000000 +0200 ++++ otrs2-3.3.9/Kernel/GenericInterface/Operation/Ticket/Common.pm 2014-12-18 18:54:26.386869907 +0100 +@@ -1369,6 +1369,17 @@ + + =item CheckCreatePermissions () + ++Tests if the user have the permissions to create a ticket on a determined queue ++ ++ my $Result = $CommonObject->CheckCreatePermissions( ++ Ticket => $TicketHashReference, ++ UserID => 123, # or 'CustomerLogin' ++ UserType => 'Agent', # or 'Customer' ++ ); ++ ++returns: ++ $Success = 1 # if everything is OK ++ + =cut + + sub CheckCreatePermissions { +@@ -1413,6 +1424,45 @@ + return 1; + } + ++=item CheckAccessPermissions() ++ ++Tests if the user have access permissions over a ticket ++ ++ my $Result = $CommonObject->CheckAccessPermissions( ++ TicketID => 123, ++ UserID => 123, # or 'CustomerLogin' ++ UserType => 'Agent', # or 'Customer' ++ ); ++ ++returns: ++ $Success = 1 # if everything is OK ++ ++=cut ++ ++sub CheckAccessPermissions { ++ my ( $Self, %Param ) = @_; ++ ++ # check needed stuff ++ for my $Needed (qw(TicketID UserID UserType)) { ++ if ( !$Param{$Needed} ) { ++ return; ++ } ++ } ++ ++ my $TicketPermissionFunction = 'TicketPermission'; ++ if ( $Param{UserType} eq 'Customer' ) { ++ $TicketPermissionFunction = 'TicketCustomerPermission'; ++ } ++ ++ my $Access = $Self->{TicketObject}->$TicketPermissionFunction( ++ Type => 'ro', ++ TicketID => $Param{TicketID}, ++ UserID => $Param{UserID}, ++ ); ++ ++ return $Access; ++} ++ + =begin Internal: + + =item _ValidateUser() +diff -Naur otrs2-3.3.9.orig/Kernel/GenericInterface/Operation/Ticket/TicketCreate.pm otrs2-3.3.9/Kernel/GenericInterface/Operation/Ticket/TicketCreate.pm +--- otrs2-3.3.9.orig/Kernel/GenericInterface/Operation/Ticket/TicketCreate.pm 2014-09-03 15:15:41.000000000 +0200 ++++ otrs2-3.3.9/Kernel/GenericInterface/Operation/Ticket/TicketCreate.pm 2014-12-18 18:54:26.390869876 +0100 +@@ -238,6 +238,7 @@ + ); + } + ++ my $PermissionUserID = $UserID; + if ( $UserType eq 'Customer' ) { + $UserID = $Self->{ConfigObject}->Get('CustomerPanelUserID') + } +@@ -304,7 +305,7 @@ + # check create permissions + my $Permission = $Self->{TicketCommonObject}->CheckCreatePermissions( + Ticket => $Ticket, +- UserID => $UserID, ++ UserID => $PermissionUserID, + UserType => $UserType, + ); + +diff -Naur otrs2-3.3.9.orig/Kernel/GenericInterface/Operation/Ticket/TicketGet.pm otrs2-3.3.9/Kernel/GenericInterface/Operation/Ticket/TicketGet.pm +--- otrs2-3.3.9.orig/Kernel/GenericInterface/Operation/Ticket/TicketGet.pm 2014-09-03 15:15:41.000000000 +0200 ++++ otrs2-3.3.9/Kernel/GenericInterface/Operation/Ticket/TicketGet.pm 2014-12-18 18:54:26.390869876 +0100 +@@ -271,6 +271,24 @@ + ErrorMessage => "TicketGet: Structure for TicketID is not correct!", + ); + } ++ ++ TICKET: ++ for my $TicketID (@TicketIDs) { ++ ++ my $Access = $Self->{TicketCommonObject}->CheckAccessPermissions( ++ TicketID => $TicketID, ++ UserID => $UserID, ++ UserType => $UserType, ++ ); ++ ++ next TICKET if $Access; ++ ++ return $Self->{TicketCommonObject}->ReturnError( ++ ErrorCode => 'TicketGet.AccessDenied', ++ ErrorMessage => 'TicketGet: User does not have access to the ticket!', ++ ); ++ } ++ + my $DynamicFields = $Param{Data}->{DynamicFields} || 0; + my $Extended = $Param{Data}->{Extended} || 0; + my $AllArticles = $Param{Data}->{AllArticles} || 0; +diff -Naur otrs2-3.3.9.orig/Kernel/GenericInterface/Operation/Ticket/TicketUpdate.pm otrs2-3.3.9/Kernel/GenericInterface/Operation/Ticket/TicketUpdate.pm +--- otrs2-3.3.9.orig/Kernel/GenericInterface/Operation/Ticket/TicketUpdate.pm 2014-09-03 15:15:41.000000000 +0200 ++++ otrs2-3.3.9/Kernel/GenericInterface/Operation/Ticket/TicketUpdate.pm 2014-12-18 18:54:26.390869876 +0100 +@@ -251,8 +251,10 @@ + ); + } + ++ my $PermissionUserID = $UserID; ++ + if ( $UserType eq 'Customer' ) { +- $UserID = $Self->{ConfigObject}->Get('CustomerPanelUserID') ++ $UserID = $Self->{ConfigObject}->Get('CustomerPanelUserID'); + } + + # check TicketID +@@ -289,10 +291,10 @@ + } + + # check basic needed permissions +- my $Access = $Self->{TicketObject}->TicketPermission( +- Type => 'ro', ++ my $Access = $Self->{TicketCommonObject}->CheckAccessPermissions( + TicketID => $TicketID, +- UserID => $UserID ++ UserID => $PermissionUserID, ++ UserType => $UserType, + ); + + if ( !$Access ) { +diff -Naur otrs2-3.3.9.orig/scripts/test/GenericInterface/Operation/Ticket/TicketCreate.t otrs2-3.3.9/scripts/test/GenericInterface/Operation/Ticket/TicketCreate.t +--- otrs2-3.3.9.orig/scripts/test/GenericInterface/Operation/Ticket/TicketCreate.t 2014-09-03 15:15:43.000000000 +0200 ++++ otrs2-3.3.9/scripts/test/GenericInterface/Operation/Ticket/TicketCreate.t 2014-12-18 18:54:26.394869808 +0100 +@@ -199,6 +199,32 @@ + "QueueGet() - for testing queue", + ); + ++# create new queue (Admin) ++my $QueueID2 = $QueueObject->QueueAdd( ++ Name => 'TestQueue2' . $RandomID, ++ ValidID => 1, ++ GroupID => 2, ++ SystemAddressID => 1, ++ SalutationID => 1, ++ SignatureID => 1, ++ Comment => 'Some comment', ++ UserID => 1, ++); ++ ++# sanity check ++$Self->True( ++ $QueueID2, ++ "QueueAdd() - create testing queue2", ++); ++ ++my %QueueData2 = $QueueObject->QueueGet( ID => $QueueID2 ); ++ ++# sanity check ++$Self->True( ++ IsHashRefWithData( \%QueueData2 ), ++ "QueueGet() - for testing queue2", ++); ++ + # create new type + my $TypeID = $TypeObject->TypeAdd( + Name => 'TestType' . $RandomID, +@@ -498,6 +524,18 @@ + ); + my $Password = $UserLogin; + ++# create a new user without permissions for current test ++my $UserLogin2 = $HelperObject->TestUserCreate(); ++my $Password2 = $UserLogin2; ++ ++# create a customer where a ticket will use and will have permissions ++my $CustomerUserLogin = $HelperObject->TestCustomerUserCreate(); ++my $CustomerPassword = $CustomerUserLogin; ++ ++# create a customer that will not have permissions ++my $CustomerUserLogin2 = $HelperObject->TestCustomerUserCreate(); ++my $CustomerPassword2 = $CustomerUserLogin2; ++ + # start requester with our webservice + my $RequesterSessionResult = $RequesterSessionObject->Run( + WebserviceID => $WebserviceID, +@@ -3053,6 +3091,61 @@ + Operation => 'TicketCreate', + }, + { ++ Name => 'Ticket with IDs (Using Session)', ++ SuccessRequest => 1, ++ SuccessCreate => 1, ++ RequestData => { ++ Ticket => { ++ Title => 'Ticket Title', ++ CustomerUser => $TestCustomerUserLogin, ++ QueueID => $QueueID, ++ TypeID => $TypeID, ++ ServiceID => $ServiceID, ++ SLAID => $SLAID, ++ StateID => $StateID, ++ PriorityID => $PriorityID, ++ OwnerID => $OwnerID, ++ ResponsibleID => $ResponsibleID, ++ PendingTime => { ++ Year => 2012, ++ Month => 12, ++ Day => 16, ++ Hour => 20, ++ Minute => 48, ++ }, ++ }, ++ Article => { ++ Subject => 'Article subject', ++ Body => 'Article body', ++ AutoResponseType => 'auto reply', ++ ArticleTypeID => 1, ++ SenderTypeID => 1, ++ From => 'en...@otrs.com', ++ ContentType => 'text/plain; charset=UTF8', ++ HistoryType => 'NewTicket', ++ HistoryComment => '% % ', ++ TimeUnit => 25, ++ ForceNotificationToUserID => [1], ++ ExcludeNotificationToUserID => [1], ++ ExcludeMuteNotificationToUserID => [1], ++ }, ++ DynamicField => { ++ Name => $DynamicFieldData->{Name}, ++ Value => '2012-01-17 12:40:00', ++ }, ++ Attachment => { ++ Content => 'VGhpcyBpcyBhIHRlc3QgdGV4dC4=', ++ ContentType => 'text/plain; charset=UTF8', ++ Filename => 'Test.txt', ++ }, ++ }, ++ Auth => { ++ SessionID => $NewSessionID, ++ }, ++ Operation => 'TicketCreate', ++ }, ++ ++ { + Name => 'Ticket with Names', + SuccessRequest => 1, + SuccessCreate => 1, +@@ -3153,7 +3246,188 @@ + }, + Operation => 'TicketCreate', + }, ++ { ++ Name => 'Ticket with IDs Agent (No Permission)', ++ SuccessRequest => 1, ++ SuccessCreate => 0, ++ RequestData => { ++ Ticket => { ++ Title => 'Ticket Title', ++ CustomerUser => $TestCustomerUserLogin, ++ QueueID => $QueueID, ++ TypeID => $TypeID, ++ ServiceID => $ServiceID, ++ SLAID => $SLAID, ++ StateID => $StateID, ++ PriorityID => $PriorityID, ++ OwnerID => $OwnerID, ++ ResponsibleID => $ResponsibleID, ++ PendingTime => { ++ Year => 2012, ++ Month => 12, ++ Day => 16, ++ Hour => 20, ++ Minute => 48, ++ }, ++ }, ++ Article => { ++ Subject => 'Article subject', ++ Body => 'Article body', ++ AutoResponseType => 'auto reply', ++ ArticleTypeID => 1, ++ SenderTypeID => 1, ++ From => 'en...@otrs.com', ++ ContentType => 'text/plain; charset=UTF8', ++ HistoryType => 'NewTicket', ++ HistoryComment => '% % ', ++ TimeUnit => 25, ++ ForceNotificationToUserID => [1], ++ ExcludeNotificationToUserID => [1], ++ ExcludeMuteNotificationToUserID => [1], ++ }, ++ DynamicField => { ++ Name => $DynamicFieldData->{Name}, ++ Value => '2012-01-17 12:40:00', ++ }, ++ Attachment => { ++ Content => 'VGhpcyBpcyBhIHRlc3QgdGV4dC4=', ++ ContentType => 'text/plain; charset=UTF8', ++ Filename => 'Test.txt', ++ }, ++ }, ++ Auth => { ++ UserLogin => $UserLogin2, ++ Password => $Password2, ++ }, ++ ExpectedData => { ++ Data => { ++ Error => { ++ ErrorCode => 'TicketCreate.AccessDenied', ++ } ++ }, ++ Success => 1 ++ }, + ++ Operation => 'TicketCreate', ++ }, ++ { ++ Name => 'Ticket with IDs Customer (With Permissions)', ++ SuccessRequest => 1, ++ SuccessCreate => 1, ++ RequestData => { ++ Ticket => { ++ Title => 'Ticket Title', ++ CustomerUser => $TestCustomerUserLogin, ++ QueueID => $QueueID, ++ TypeID => $TypeID, ++ ServiceID => $ServiceID, ++ SLAID => $SLAID, ++ StateID => $StateID, ++ PriorityID => $PriorityID, ++ OwnerID => $OwnerID, ++ ResponsibleID => $ResponsibleID, ++ PendingTime => { ++ Year => 2012, ++ Month => 12, ++ Day => 16, ++ Hour => 20, ++ Minute => 48, ++ }, ++ }, ++ Article => { ++ Subject => 'Article subject', ++ Body => 'Article body', ++ AutoResponseType => 'auto reply', ++ ArticleTypeID => 1, ++ SenderTypeID => 1, ++ From => 'en...@otrs.com', ++ ContentType => 'text/plain; charset=UTF8', ++ HistoryType => 'NewTicket', ++ HistoryComment => '% % ', ++ TimeUnit => 25, ++ ForceNotificationToUserID => [1], ++ ExcludeNotificationToUserID => [1], ++ ExcludeMuteNotificationToUserID => [1], ++ }, ++ DynamicField => { ++ Name => $DynamicFieldData->{Name}, ++ Value => '2012-01-17 12:40:00', ++ }, ++ Attachment => { ++ Content => 'VGhpcyBpcyBhIHRlc3QgdGV4dC4=', ++ ContentType => 'text/plain; charset=UTF8', ++ Filename => 'Test.txt', ++ }, ++ }, ++ Auth => { ++ CustomerUserLogin => $CustomerUserLogin, ++ Password => $CustomerPassword, ++ }, ++ Operation => 'TicketCreate', ++ }, ++ { ++ Name => 'Ticket with IDs Customer (No Permission)', ++ SuccessRequest => 1, ++ SuccessCreate => 0, ++ RequestData => { ++ Ticket => { ++ Title => 'Ticket Title', ++ CustomerUser => $TestCustomerUserLogin, ++ QueueID => $QueueID2, ++ TypeID => $TypeID, ++ ServiceID => $ServiceID, ++ SLAID => $SLAID, ++ StateID => $StateID, ++ PriorityID => $PriorityID, ++ OwnerID => $OwnerID, ++ ResponsibleID => $ResponsibleID, ++ PendingTime => { ++ Year => 2012, ++ Month => 12, ++ Day => 16, ++ Hour => 20, ++ Minute => 48, ++ }, ++ }, ++ Article => { ++ Subject => 'Article subject', ++ Body => 'Article body', ++ AutoResponseType => 'auto reply', ++ ArticleTypeID => 1, ++ SenderTypeID => 1, ++ From => 'en...@otrs.com', ++ ContentType => 'text/plain; charset=UTF8', ++ HistoryType => 'NewTicket', ++ HistoryComment => '% % ', ++ TimeUnit => 25, ++ ForceNotificationToUserID => [1], ++ ExcludeNotificationToUserID => [1], ++ ExcludeMuteNotificationToUserID => [1], ++ }, ++ DynamicField => { ++ Name => $DynamicFieldData->{Name}, ++ Value => '2012-01-17 12:40:00', ++ }, ++ Attachment => { ++ Content => 'VGhpcyBpcyBhIHRlc3QgdGV4dC4=', ++ ContentType => 'text/plain; charset=UTF8', ++ Filename => 'Test.txt', ++ }, ++ }, ++ Auth => { ++ CustomerUserLogin => $CustomerUserLogin2, ++ Password => $CustomerPassword2, ++ }, ++ ExpectedData => { ++ Data => { ++ Error => { ++ ErrorCode => 'TicketCreate.AccessDenied', ++ } ++ }, ++ Success => 1 ++ }, ++ Operation => 'TicketCreate', ++ }, + ); + + # debugger object +@@ -3189,15 +3463,22 @@ + "$Test->{Name} - Create local object", + ); + ++ my %Auth = ( ++ UserLogin => $UserLogin, ++ Password => $Password, ++ ); ++ if ( IsHashRefWithData( $Test->{Auth} ) ) { ++ %Auth = %{ $Test->{Auth} }; ++ } ++ + # start requester with our webservice + my $LocalResult = $LocalObject->Run( + WebserviceID => $WebserviceID, + Invoker => $Test->{Operation}, + Data => { +- UserLogin => $UserLogin, +- Password => $Password, ++ %Auth, + %{ $Test->{RequestData} }, +- } ++ }, + ); + + # check result +@@ -3223,9 +3504,9 @@ + WebserviceID => $WebserviceID, + Invoker => $Test->{Operation}, + Data => { +- SessionID => $NewSessionID, ++ %Auth, + %{ $Test->{RequestData} }, +- } ++ }, + ); + + # check result +@@ -3572,7 +3853,7 @@ + "Deleted Webservice $WebserviceID", + ); + +-# invalidate queue ++# invalidate queues + { + my $Success = $QueueObject->QueueUpdate( + %QueueData, +@@ -3585,6 +3866,19 @@ + $Success, + "QueueUpdate() set queue $QueueData{Name} to invalid", + ); ++ ++ $Success = $QueueObject->QueueUpdate( ++ %QueueData2, ++ ValidID => $InvalidID, ++ UserID => 1, ++ ); ++ ++ # sanity check ++ $Self->True( ++ $Success, ++ "QueueUpdate() set queue $QueueData2{Name} to invalid", ++ ); ++ + } + + # invalidate type +diff -Naur otrs2-3.3.9.orig/scripts/test/GenericInterface/Operation/Ticket/TicketGet.t otrs2-3.3.9/scripts/test/GenericInterface/Operation/Ticket/TicketGet.t +--- otrs2-3.3.9.orig/scripts/test/GenericInterface/Operation/Ticket/TicketGet.t 2014-09-03 15:15:43.000000000 +0200 ++++ otrs2-3.3.9/scripts/test/GenericInterface/Operation/Ticket/TicketGet.t 2014-12-18 18:54:26.394869808 +0100 +@@ -7,6 +7,7 @@ + # did not receive this file, see http://www.gnu.org/licenses/agpl.txt. + # -- + ++## no critic (Modules::RequireExplicitPackage) + use strict; + use warnings; + use utf8; +@@ -47,13 +48,27 @@ + ); + + # create a new user for current test +-my $UserLogin = $HelperObject->TestUserCreate(); +-my $Password = $UserLogin; ++my $UserLogin = $HelperObject->TestUserCreate( ++ Groups => ['users'], ++); ++my $Password = $UserLogin; + + $Self->{UserID} = $UserObject->UserLookup( + UserLogin => $UserLogin, + ); + ++# create a new user without permissions for current test ++my $UserLogin2 = $HelperObject->TestUserCreate(); ++my $Password2 = $UserLogin2; ++ ++# create a customer where a ticket will use and will have permissions ++my $CustomerUserLogin = $HelperObject->TestCustomerUserCreate(); ++my $CustomerPassword = $CustomerUserLogin; ++ ++# create a customer that will not have permissions ++my $CustomerUserLogin2 = $HelperObject->TestCustomerUserCreate(); ++my $CustomerPassword2 = $CustomerUserLogin2; ++ + my %SkipFields = ( + Age => 1, + AgeTimeUnix => 1, +@@ -82,7 +97,7 @@ + $Self->Is( + ref $BackendObject, + 'Kernel::System::DynamicField::Backend', +- 'Backend object was created successfuly', ++ 'Backend object was created successfully', + ); + + my @TestDynamicFields; +@@ -377,7 +392,7 @@ + ); + + # get the Ticket entry +-# withpout DF ++# without DF + my %TicketEntryTwo = $TicketObject->TicketGet( + TicketID => $TicketID2, + DynamicFields => 0, +@@ -473,7 +488,7 @@ + Lock => 'lock', + Priority => '3 normal', + State => 'new', +- CustomerID => '654321', ++ CustomerID => $CustomerUserLogin, + CustomerUser => 'customerf...@example.com', + OwnerID => 1, + UserID => 1, +@@ -508,7 +523,7 @@ + TicketID => $TicketID4, + ArticleType => 'phone', + SenderType => 'agent', +- From => 'Anot Real Agent <em...@example.com>', ++ From => 'A not Real Agent <em...@example.com>', + To => 'Customer A <custome...@example.com>', + Cc => 'Customer B <custome...@example.com>', + ReplyTo => 'Customer B <custome...@example.com>', +@@ -641,10 +656,10 @@ + # add ticket id + push @TicketIDs, $TicketID4; + +-# set webservice name ++# set web-service name + my $WebserviceName = '-Test-' . $RandomID; + +-# create webservice object ++# create web-service object + my $WebserviceObject = Kernel::System::GenericInterface::Webservice->new( + %{$Self}, + ConfigObject => $ConfigObject, +@@ -679,22 +694,22 @@ + my $Host; + my $FQDN = $Self->{ConfigObject}->Get('FQDN'); + +-# try to resolve fqdn host ++# try to resolve FQDN host + if ( $FQDN ne 'yourhost.example.com' && gethostbyname($FQDN) ) { + $Host = $FQDN; + } + +-# try to resolve localhost instead ++# try to resolve local-host instead + if ( !$Host && gethostbyname('localhost') ) { + $Host = 'localhost'; + } + +-# use hardcoded localhost ip address ++# use hard-coded local-host IP address + if ( !$Host ) { + $Host = '127.0.0.1'; + } + +-# prepare webservice config ++# prepare web-service config + my $RemoteSystem = + $Self->{ConfigObject}->Get('HttpType') + . '://' +@@ -751,7 +766,7 @@ + }, + }; + +-# update webservice with real config ++# update web-service with real config + # the update is needed because we are using + # the WebserviceID for the Endpoint in config + my $WebserviceUpdate = $WebserviceObject->WebserviceUpdate( +@@ -778,7 +793,7 @@ + "SessionID - Create requester object", + ); + +-# start requester with our webservice ++# start requester with our web-service + my $RequesterSessionResult = $RequesterSessionObject->Run( + WebserviceID => $WebserviceID, + Invoker => 'SessionCreate', +@@ -789,7 +804,8 @@ + ); + + my $NewSessionID = $RequesterSessionResult->{Data}->{SessionID}; +-my @Tests = ( ++ ++my @Tests = ( + { + Name => 'Test 1', + SuccessRequest => 1, +@@ -823,9 +839,9 @@ + ExpectedReturnLocalData => { + Data => { + Error => { +- ErrorCode => 'TicketGet.NotValidTicketID', ++ ErrorCode => 'TicketGet.AccessDenied', + ErrorMessage => +- 'TicketGet: Could not get Ticket data in Kernel::GenericInterface::Operation::Ticket::TicketGet::Run()' ++ 'TicketGet: User does not have access to the ticket!' + } + }, + Success => 1 +@@ -833,9 +849,9 @@ + ExpectedReturnRemoteData => { + Data => { + Error => { +- ErrorCode => 'TicketGet.NotValidTicketID', ++ ErrorCode => 'TicketGet.AccessDenied', + ErrorMessage => +- 'TicketGet: Could not get Ticket data in Kernel::GenericInterface::Operation::Ticket::TicketGet::Run()' ++ 'TicketGet: User does not have access to the ticket!' + } + }, + Success => 1 +@@ -862,7 +878,7 @@ + Ticket => [ + { + %TicketEntryOne, +- } ++ }, + ], + }, + }, +@@ -888,7 +904,7 @@ + Ticket => [ + { + %TicketEntryTwo, +- } ++ }, + ], + }, + }, +@@ -914,7 +930,7 @@ + Ticket => [ + { + %TicketEntryThree, +- } ++ }, + ], + }, + }, +@@ -940,7 +956,7 @@ + Ticket => [ + { + %TicketEntryFour, +- } ++ }, + ], + }, + }, +@@ -967,7 +983,7 @@ + Ticket => [ + { + %TicketEntryOneDF, +- } ++ }, + ], + }, + }, +@@ -994,7 +1010,7 @@ + Ticket => [ + { + %TicketEntryTwoDF, +- } ++ }, + ], + }, + }, +@@ -1030,7 +1046,7 @@ + { + %TicketEntryTwoDF, + }, +- ] ++ ], + }, + }, + Operation => 'TicketGet', +@@ -1058,7 +1074,7 @@ + { + %TicketEntryFour, + Article => \@ArticleWithoutAttachments, +- } ++ }, + ], + }, + }, +@@ -1088,12 +1104,147 @@ + { + %TicketEntryFour, + Article => \@ArticleBox, ++ }, ++ ], ++ }, ++ }, ++ Operation => 'TicketGet', ++ }, ++ { ++ Name => 'Test 11 (With sessionID', ++ SuccessRequest => '1', ++ RequestData => { ++ TicketID => $TicketID4, ++ AllArticles => 1, ++ Attachments => 1, ++ }, ++ Auth => { ++ SessionID => $NewSessionID, ++ }, ++ ExpectedReturnRemoteData => { ++ Success => 1, ++ Data => { ++ Ticket => { ++ %TicketEntryFour, ++ Article => \@ArticleBox, ++ }, ++ }, ++ }, ++ ExpectedReturnLocalData => { ++ Success => 1, ++ Data => { ++ Ticket => [ ++ { ++ %TicketEntryFour, ++ Article => \@ArticleBox, ++ }, ++ ], ++ }, ++ }, ++ Operation => 'TicketGet', ++ }, ++ { ++ Name => 'Test 11 (No Permission)', ++ SuccessRequest => '1', ++ RequestData => { ++ TicketID => $TicketID4, ++ AllArticles => 1, ++ Attachments => 1, ++ }, ++ Auth => { ++ UserLogin => $UserLogin2, ++ Password => $Password2, ++ }, ++ ExpectedReturnLocalData => { ++ Data => { ++ Error => { ++ ErrorCode => 'TicketGet.AccessDenied', ++ ErrorMessage => ++ 'TicketGet: User does not have access to the ticket!' + } ++ }, ++ Success => 1 ++ }, ++ ExpectedReturnRemoteData => { ++ Data => { ++ Error => { ++ ErrorCode => 'TicketGet.AccessDenied', ++ ErrorMessage => ++ 'TicketGet: User does not have access to the ticket!' ++ } ++ }, ++ Success => 1 ++ }, ++ Operation => 'TicketGet', ++ }, ++ { ++ Name => 'Test 11 (Customer)', ++ SuccessRequest => '1', ++ RequestData => { ++ TicketID => $TicketID4, ++ AllArticles => 1, ++ Attachments => 1, ++ }, ++ Auth => { ++ CustomerUserLogin => $CustomerUserLogin, ++ Password => $CustomerPassword, ++ }, ++ ExpectedReturnRemoteData => { ++ Success => 1, ++ Data => { ++ Ticket => { ++ %TicketEntryFour, ++ Article => \@ArticleBox, ++ }, ++ }, ++ }, ++ ExpectedReturnLocalData => { ++ Success => 1, ++ Data => { ++ Ticket => [ ++ { ++ %TicketEntryFour, ++ Article => \@ArticleBox, ++ }, + ], + }, + }, + Operation => 'TicketGet', + }, ++ { ++ Name => 'Test 11 (Customer No Permission)', ++ SuccessRequest => '1', ++ RequestData => { ++ TicketID => $TicketID4, ++ AllArticles => 1, ++ Attachments => 1, ++ }, ++ Auth => { ++ CustomerUserLogin => $CustomerUserLogin2, ++ Password => $CustomerPassword2, ++ }, ++ ExpectedReturnLocalData => { ++ Data => { ++ Error => { ++ ErrorCode => 'TicketGet.AccessDenied', ++ ErrorMessage => ++ 'TicketGet: User does not have access to the ticket!' ++ } ++ }, ++ Success => 1 ++ }, ++ ExpectedReturnRemoteData => { ++ Data => { ++ Error => { ++ ErrorCode => 'TicketGet.AccessDenied', ++ ErrorMessage => ++ 'TicketGet: User does not have access to the ticket!' ++ } ++ }, ++ Success => 1 ++ }, ++ Operation => 'TicketGet', ++ }, + ); + + # debugger object +@@ -1110,7 +1261,7 @@ + $Self->Is( + ref $DebuggerObject, + 'Kernel::GenericInterface::Debugger', +- 'DebuggerObject instanciate correctly', ++ 'DebuggerObject instantiate correctly', + ); + + for my $Test (@Tests) { +@@ -1129,15 +1280,22 @@ + "$Test->{Name} - Create local object", + ); + +- # start requester with our webservice ++ my %Auth = ( ++ UserLogin => $UserLogin, ++ Password => $Password, ++ ); ++ if ( IsHashRefWithData( $Test->{Auth} ) ) { ++ %Auth = %{ $Test->{Auth} }; ++ } ++ ++ # start requester with our web-service + my $LocalResult = $LocalObject->Run( + WebserviceID => $WebserviceID, + Invoker => $Test->{Operation}, + Data => { +- UserLogin => $UserLogin, +- Password => $Password, ++ %Auth, + %{ $Test->{RequestData} }, +- } ++ }, + ); + + # check result +@@ -1158,14 +1316,14 @@ + "$Test->{Name} - Create requester object", + ); + +- # start requester with our webservice ++ # start requester with our web-service + my $RequesterResult = $RequesterObject->Run( + WebserviceID => $WebserviceID, + Invoker => $Test->{Operation}, + Data => { +- SessionID => $NewSessionID, ++ %Auth, + %{ $Test->{RequestData} }, +- } ++ }, + ); + + # check result +@@ -1302,7 +1460,7 @@ + + # clean up + +-# clean up webservice ++# clean up web-service + my $WebserviceDelete = $WebserviceObject->WebserviceDelete( + ID => $WebserviceID, + UserID => $Self->{UserID}, +diff -Naur otrs2-3.3.9.orig/scripts/test/GenericInterface/Operation/Ticket/TicketUpdate.t otrs2-3.3.9/scripts/test/GenericInterface/Operation/Ticket/TicketUpdate.t +--- otrs2-3.3.9.orig/scripts/test/GenericInterface/Operation/Ticket/TicketUpdate.t 1970-01-01 01:00:00.000000000 +0100 ++++ otrs2-3.3.9/scripts/test/GenericInterface/Operation/Ticket/TicketUpdate.t 2014-12-18 18:54:26.394869808 +0100 +@@ -0,0 +1,548 @@ ++# -- ++# TicketUpdate.t - GenericInterface TicketCreate tests for TicketConnector backend ++# Copyright (C) 2001-2014 OTRS AG, http://otrs.com/ ++# -- ++# This software comes with ABSOLUTELY NO WARRANTY. For details, see ++# the enclosed file COPYING for license information (AGPL). If you ++# did not receive this file, see http://www.gnu.org/licenses/agpl.txt. ++# -- ++ ++## no critic (Modules::RequireExplicitPackage) ++use strict; ++use warnings; ++use utf8; ++use vars (qw($Self)); ++ ++use Kernel::GenericInterface::Debugger; ++use Kernel::GenericInterface::Operation::Session::SessionCreate; ++use Kernel::GenericInterface::Operation::Ticket::TicketUpdate; ++use Kernel::GenericInterface::Requester; ++use Kernel::System::GenericInterface::Webservice; ++use Kernel::System::Ticket; ++use Kernel::System::UnitTest::Helper; ++use Kernel::System::User; ++ ++use Kernel::System::VariableCheck qw(:all); ++ ++# helper object ++# skip SSL certificate verification ++my $HelperObject = Kernel::System::UnitTest::Helper->new( ++ %{$Self}, ++ UnitTestObject => $Self, ++ RestoreSystemConfiguration => 1, ++ SkipSSLVerify => 1, ++); ++ ++# new user object ++my $UserObject = Kernel::System::User->new( ++ %{$Self}, ++); ++ ++# create a new user for current test ++my $UserLogin = $HelperObject->TestUserCreate( ++ Groups => ['users'], ++); ++my $Password = $UserLogin; ++ ++$Self->{UserID} = $UserObject->UserLookup( ++ UserLogin => $UserLogin, ++); ++ ++# create a new user without permissions for current test ++my $UserLogin2 = $HelperObject->TestUserCreate(); ++my $Password2 = $UserLogin2; ++ ++# create a customer where a ticket will use and will have permissions ++my $CustomerUserLogin = $HelperObject->TestCustomerUserCreate(); ++my $CustomerPassword = $CustomerUserLogin; ++ ++# create a customer that will not have permissions ++my $CustomerUserLogin2 = $HelperObject->TestCustomerUserCreate(); ++my $CustomerPassword2 = $CustomerUserLogin2; ++ ++# create ticket object ++my $TicketObject = Kernel::System::Ticket->new( ++ %{$Self}, ++); ++ ++#ticket id container ++my @TicketIDs; ++ ++# create ticket 1 ++my $TicketID1 = $TicketObject->TicketCreate( ++ Title => 'Ticket One Title', ++ Queue => 'Raw', ++ Lock => 'unlock', ++ Priority => '3 normal', ++ State => 'new', ++ CustomerID => $CustomerUserLogin, ++ CustomerUser => 'customer...@example.com', ++ OwnerID => 1, ++ UserID => 1, ++); ++ ++# sanity check ++$Self->True( ++ $TicketID1, ++ "TicketCreate() successful for Ticket One ID $TicketID1", ++); ++ ++my %Ticket = $TicketObject->TicketGet( ++ TicketID => $TicketID1, ++ UserID => 1, ++); ++ ++# remember ticket id ++push @TicketIDs, $TicketID1; ++ ++#get a random id ++my $RandomID = int rand 1_000_000_000; ++ ++# set web-service name ++my $WebserviceName = '-Test-' . $RandomID; ++ ++# create web-service object ++my $WebserviceObject = Kernel::System::GenericInterface::Webservice->new( ++ %{$Self}, ++); ++$Self->Is( ++ 'Kernel::System::GenericInterface::Webservice', ++ ref $WebserviceObject, ++ "Create webservice object", ++); ++ ++my $WebserviceID = $WebserviceObject->WebserviceAdd( ++ Name => $WebserviceName, ++ Config => { ++ Debugger => { ++ DebugThreshold => 'debug', ++ }, ++ Provider => { ++ Transport => { ++ Type => '', ++ }, ++ }, ++ }, ++ ValidID => 1, ++ UserID => 1, ++); ++$Self->True( ++ $WebserviceID, ++ "Added Webservice", ++); ++ ++# get remote host with some precautions for certain unit test systems ++my $Host; ++my $FQDN = $Self->{ConfigObject}->Get('FQDN'); ++ ++# try to resolve FQDN host ++if ( $FQDN ne 'yourhost.example.com' && gethostbyname($FQDN) ) { ++ $Host = $FQDN; ++} ++ ++# try to resolve local-host instead ++if ( !$Host && gethostbyname('localhost') ) { ++ $Host = 'localhost'; ++} ++ ++# use hard-coded local-host IP address ++if ( !$Host ) { ++ $Host = '127.0.0.1'; ++} ++ ++# prepare web-service config ++my $RemoteSystem = ++ $Self->{ConfigObject}->Get('HttpType') ++ . '://' ++ . $Host ++ . '/' ++ . $Self->{ConfigObject}->Get('ScriptAlias') ++ . '/nph-genericinterface.pl/WebserviceID/' ++ . $WebserviceID; ++ ++my $WebserviceConfig = { ++ ++ # Name => '', ++ Description => ++ 'Test for Ticket Connector using SOAP transport backend.', ++ Debugger => { ++ DebugThreshold => 'debug', ++ TestMode => 1, ++ }, ++ Provider => { ++ Transport => { ++ Type => 'HTTP::SOAP', ++ Config => { ++ MaxLength => 10000000, ++ NameSpace => 'http://otrs.org/SoapTestInterface/', ++ Endpoint => $RemoteSystem, ++ }, ++ }, ++ Operation => { ++ TicketUpdate => { ++ Type => 'Ticket::TicketUpdate', ++ }, ++ SessionCreate => { ++ Type => 'Session::SessionCreate', ++ }, ++ }, ++ }, ++ Requester => { ++ Transport => { ++ Type => 'HTTP::SOAP', ++ Config => { ++ NameSpace => 'http://otrs.org/SoapTestInterface/', ++ Encoding => 'UTF-8', ++ Endpoint => $RemoteSystem, ++ }, ++ }, ++ Invoker => { ++ TicketUpdate => { ++ Type => 'Test::TestSimple', ++ }, ++ SessionCreate => { ++ Type => 'Test::TestSimple', ++ }, ++ }, ++ }, ++}; ++ ++# update web-service with real config ++# the update is needed because we are using ++# the WebserviceID for the Endpoint in config ++my $WebserviceUpdate = $WebserviceObject->WebserviceUpdate( ++ ID => $WebserviceID, ++ Name => $WebserviceName, ++ Config => $WebserviceConfig, ++ ValidID => 1, ++ UserID => $Self->{UserID}, ++); ++$Self->True( ++ $WebserviceUpdate, ++ "Updated Webservice $WebserviceID - $WebserviceName", ++); ++ ++# Get SessionID ++# create requester object ++my $RequesterSessionObject = Kernel::GenericInterface::Requester->new( ++ %{$Self}, ++); ++$Self->Is( ++ 'Kernel::GenericInterface::Requester', ++ ref $RequesterSessionObject, ++ "SessionID - Create requester object", ++); ++ ++# start requester with our web-service ++my $RequesterSessionResult = $RequesterSessionObject->Run( ++ WebserviceID => $WebserviceID, ++ Invoker => 'SessionCreate', ++ Data => { ++ UserLogin => $UserLogin, ++ Password => $Password, ++ }, ++); ++ ++my $NewSessionID = $RequesterSessionResult->{Data}->{SessionID}; ++ ++my @Tests = ( ++ { ++ Name => 'Update Agent (With Permissions)', ++ SuccessRequest => '1', ++ RequestData => { ++ TicketID => $TicketID1, ++ Ticket => { ++ Title => 'Updated', ++ }, ++ }, ++ ExpectedReturnRemoteData => { ++ Success => 1, ++ Data => { ++ TicketID => $Ticket{TicketID}, ++ TicketNumber => $Ticket{TicketNumber}, ++ }, ++ }, ++ ExpectedReturnLocalData => { ++ Success => 1, ++ Data => { ++ TicketID => $Ticket{TicketID}, ++ TicketNumber => $Ticket{TicketNumber}, ++ }, ++ }, ++ Operation => 'TicketUpdate', ++ }, ++ { ++ Name => 'Update Agent (With SessionID)', ++ SuccessRequest => '1', ++ RequestData => { ++ TicketID => $TicketID1, ++ Ticket => { ++ Title => 'Updated', ++ }, ++ }, ++ Auth => { ++ SessionID => $NewSessionID, ++ }, ++ ExpectedReturnRemoteData => { ++ Success => 1, ++ Data => { ++ TicketID => $Ticket{TicketID}, ++ TicketNumber => $Ticket{TicketNumber}, ++ }, ++ }, ++ ExpectedReturnLocalData => { ++ Success => 1, ++ Data => { ++ TicketID => $Ticket{TicketID}, ++ TicketNumber => $Ticket{TicketNumber}, ++ }, ++ }, ++ Operation => 'TicketUpdate', ++ }, ++ { ++ Name => 'Update Agent (No Permission)', ++ SuccessRequest => '1', ++ RequestData => { ++ TicketID => $TicketID1, ++ Ticket => { ++ Title => 'Updated', ++ }, ++ }, ++ Auth => { ++ UserLogin => $UserLogin2, ++ Password => $Password2, ++ }, ++ ExpectedReturnLocalData => { ++ Data => { ++ Error => { ++ ErrorCode => 'TicketUpdate.AccessDenied', ++ ErrorMessage => ++ 'TicketUpdate: User does not have access to the ticket!' ++ }, ++ }, ++ Success => 1 ++ }, ++ ExpectedReturnRemoteData => { ++ Data => { ++ Error => { ++ ErrorCode => 'TicketUpdate.AccessDenied', ++ ErrorMessage => ++ 'TicketUpdate: User does not have access to the ticket!' ++ }, ++ }, ++ Success => 1 ++ }, ++ Operation => 'TicketUpdate', ++ }, ++ { ++ Name => 'Update Customer (With Permissions)', ++ SuccessRequest => '1', ++ RequestData => { ++ TicketID => $TicketID1, ++ Ticket => { ++ Title => 'Updated', ++ }, ++ }, ++ Auth => { ++ CustomerUserLogin => $CustomerUserLogin, ++ Password => $CustomerPassword, ++ }, ++ ExpectedReturnRemoteData => { ++ Success => 1, ++ Data => { ++ TicketID => $Ticket{TicketID}, ++ TicketNumber => $Ticket{TicketNumber}, ++ }, ++ }, ++ ExpectedReturnLocalData => { ++ Success => 1, ++ Data => { ++ TicketID => $Ticket{TicketID}, ++ TicketNumber => $Ticket{TicketNumber}, ++ }, ++ }, ++ Operation => 'TicketUpdate', ++ }, ++ { ++ Name => 'Update Customer (No Permission)', ++ SuccessRequest => '1', ++ RequestData => { ++ TicketID => $TicketID1, ++ Ticket => { ++ Title => 'Updated', ++ }, ++ }, ++ Auth => { ++ CustomerUserLogin => $CustomerUserLogin2, ++ Password => $CustomerPassword2, ++ }, ++ ExpectedReturnLocalData => { ++ Data => { ++ Error => { ++ ErrorCode => 'TicketUpdate.AccessDenied', ++ ErrorMessage => ++ 'TicketUpdate: User does not have access to the ticket!' ++ }, ++ }, ++ Success => 1 ++ }, ++ ExpectedReturnRemoteData => { ++ Data => { ++ Error => { ++ ErrorCode => 'TicketUpdate.AccessDenied', ++ ErrorMessage => ++ 'TicketUpdate: User does not have access to the ticket!' ++ }, ++ }, ++ Success => 1 ++ }, ++ Operation => 'TicketUpdate', ++ }, ++); ++ ++# debugger object ++my $DebuggerObject = Kernel::GenericInterface::Debugger->new( ++ %{$Self}, ++ DebuggerConfig => { ++ DebugThreshold => 'debug', ++ TestMode => 1, ++ }, ++ WebserviceID => $WebserviceID, ++ CommunicationType => 'Provider', ++); ++$Self->Is( ++ ref $DebuggerObject, ++ 'Kernel::GenericInterface::Debugger', ++ 'DebuggerObject instantiate correctly', ++); ++ ++for my $Test (@Tests) { ++ ++ # create local object ++ my $LocalObject = "Kernel::GenericInterface::Operation::Ticket::$Test->{Operation}"->new( ++ %{$Self}, ++ DebuggerObject => $DebuggerObject, ++ WebserviceID => $WebserviceID, ++ ); ++ ++ $Self->Is( ++ "Kernel::GenericInterface::Operation::Ticket::$Test->{Operation}", ++ ref $LocalObject, ++ "$Test->{Name} - Create local object", ++ ); ++ ++ my %Auth = ( ++ UserLogin => $UserLogin, ++ Password => $Password, ++ ); ++ if ( IsHashRefWithData( $Test->{Auth} ) ) { ++ %Auth = %{ $Test->{Auth} }; ++ } ++ ++ # start requester with our web-service ++ my $LocalResult = $LocalObject->Run( ++ WebserviceID => $WebserviceID, ++ Invoker => $Test->{Operation}, ++ Data => { ++ %Auth, ++ %{ $Test->{RequestData} }, ++ }, ++ ); ++ ++ # check result ++ $Self->Is( ++ 'HASH', ++ ref $LocalResult, ++ "$Test->{Name} - Local result structure is valid", ++ ); ++ ++ # create requester object ++ my $RequesterObject = Kernel::GenericInterface::Requester->new( ++ %{$Self}, ++ ); ++ $Self->Is( ++ 'Kernel::GenericInterface::Requester', ++ ref $RequesterObject, ++ "$Test->{Name} - Create requester object", ++ ); ++ ++ # start requester with our web-service ++ my $RequesterResult = $RequesterObject->Run( ++ WebserviceID => $WebserviceID, ++ Invoker => $Test->{Operation}, ++ Data => { ++ %Auth, ++ %{ $Test->{RequestData} }, ++ }, ++ ); ++ ++ # check result ++ $Self->Is( ++ 'HASH', ++ ref $RequesterResult, ++ "$Test->{Name} - Requester result structure is valid", ++ ); ++ ++ $Self->Is( ++ $RequesterResult->{Success}, ++ $Test->{SuccessRequest}, ++ "$Test->{Name} - Requester successful result", ++ ); ++ ++ # remove ErrorMessage parameter from direct call ++ # result to be consistent with SOAP call result ++ if ( $LocalResult->{ErrorMessage} ) { ++ delete $LocalResult->{ErrorMessage}; ++ } ++ ++ $Self->IsDeeply( ++ $RequesterResult, ++ $Test->{ExpectedReturnRemoteData}, ++ "$Test->{Name} - Requester success status (needs configured and running webserver)", ++ ); ++ ++ if ( $Test->{ExpectedReturnLocalData} ) { ++ $Self->IsDeeply( ++ $LocalResult, ++ $Test->{ExpectedReturnLocalData}, ++ "$Test->{Name} - Local result matched with expected local call result.", ++ ); ++ } ++ else { ++ $Self->IsDeeply( ++ $LocalResult, ++ $Test->{ExpectedReturnRemoteData}, ++ "$Test->{Name} - Local result matched with remote result.", ++ ); ++ } ++} ++ ++# clean up ++ ++# clean up web-service ++my $WebserviceDelete = $WebserviceObject->WebserviceDelete( ++ ID => $WebserviceID, ++ UserID => $Self->{UserID}, ++); ++$Self->True( ++ $WebserviceDelete, ++ "Deleted Webservice $WebserviceID", ++); ++ ++# remove tickets ++for my $TicketID (@TicketIDs) { ++ ++ # delete the ticket Three ++ my $TicketDelete = $TicketObject->TicketDelete( ++ TicketID => $TicketID, ++ UserID => $Self->{UserID}, ++ ); ++ ++ # sanity check ++ $Self->True( ++ $TicketDelete, ++ "TicketDelete() successful for Ticket ID $TicketID", ++ ); ++} ++ ++1; diff -Naur '--exclude=.svn' 3.3.9-2/debian/patches/series 3.3.9-3/debian/patches/series --- 3.3.9-2/debian/patches/series 2014-10-29 09:32:47.200286363 +0100 +++ 3.3.9-3/debian/patches/series 2014-12-18 19:57:30.874192201 +0100 @@ -12,3 +12,4 @@ 13-load-debian-libjs.diff 14-font-paths.diff 15-dbupdate-as-root.diff +16-CVE-2014-9324.diff unblock otrs2/3.3.9-3 -- System Information: Debian Release: 7.7 APT prefers stable-updates APT policy: (500, 'stable-updates'), (500, 'stable') Architecture: amd64 (x86_64) Kernel: Linux 3.2.0-4-amd64 (SMP w/2 CPU cores) Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash -- To UNSUBSCRIBE, email to debian-release-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: https://lists.debian.org/20141222104722.6916.90670.report...@srv1.linux-dev.org