1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmlsecurity.hxx"
30 
31 #include <xmlsecurity/macrosecurity.hxx>
32 #include <xmlsecurity/certificatechooser.hxx>
33 #include <xmlsecurity/certificateviewer.hxx>
34 #include <xmlsecurity/biginteger.hxx>
35 
36 #include <osl/file.hxx>
37 #include <vcl/help.hxx>
38 
39 
40 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
41 #include <com/sun/star/security/SerialNumberAdapter.hpp>
42 #include <comphelper/sequence.hxx>
43 #include <sfx2/filedlghelper.hxx>
44 #include <comphelper/processfactory.hxx>
45 #include <com/sun/star/uno/Exception.hpp>
46 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 #include <com/sun/star/ui/dialogs/XFolderPicker.hpp>
48 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
49 #include <tools/urlobj.hxx>
50 
51 #include <vcl/msgbox.hxx>
52 
53 #include "dialogs.hrc"
54 #include "resourcemanager.hxx"
55 
56 /* HACK: disable some warnings for MS-C */
57 #ifdef _MSC_VER
58 #pragma warning (disable : 4355)	// 4355: this used in initializer-list
59 #endif
60 
61 using namespace ::com::sun::star;
62 
63 
64 IMPL_LINK( MacroSecurity, OkBtnHdl, void*, EMPTYARG )
65 {
66 	mpLevelTP->ClosePage();
67 	mpTrustSrcTP->ClosePage();
68 
69 	EndDialog( RET_OK );
70 
71 	return 0;
72 }
73 
74 MacroSecurity::MacroSecurity( Window* _pParent, const cssu::Reference< cssu::XComponentContext> &_rxCtx, const cssu::Reference< dcss::xml::crypto::XSecurityEnvironment >& _rxSecurityEnvironment )
75 	:TabDialog			( _pParent, XMLSEC_RES( RID_XMLSECTP_MACROSEC ) )
76 	,maTabCtrl			( this, XMLSEC_RES( 1 ) )
77 	,maOkBtn			( this, XMLSEC_RES( BTN_OK ) )
78 	,maCancelBtn		( this, XMLSEC_RES( BTN_CANCEL ) )
79 	,maHelpBtn			( this, XMLSEC_RES( BTN_HELP ) )
80 	,maResetBtn			( this, XMLSEC_RES( BTN_RESET ) )
81 {
82 	FreeResource();
83 
84 	mxCtx = _rxCtx;
85 	mxSecurityEnvironment = _rxSecurityEnvironment;
86 
87 	mpLevelTP = new MacroSecurityLevelTP( &maTabCtrl, this );
88 	mpTrustSrcTP = new MacroSecurityTrustedSourcesTP( &maTabCtrl, this );
89 
90 	maTabCtrl.SetTabPage( RID_XMLSECTP_SECLEVEL, mpLevelTP );
91 	maTabCtrl.SetTabPage( RID_XMLSECTP_TRUSTSOURCES, mpTrustSrcTP );
92 	maTabCtrl.SetCurPageId( RID_XMLSECTP_SECLEVEL );
93 
94 	maOkBtn.SetClickHdl( LINK( this, MacroSecurity, OkBtnHdl ) );
95 }
96 
97 MacroSecurity::~MacroSecurity()
98 {
99 	delete maTabCtrl.GetTabPage( RID_XMLSECTP_TRUSTSOURCES );
100 	delete maTabCtrl.GetTabPage( RID_XMLSECTP_SECLEVEL );
101 }
102 
103 
104 MacroSecurityTP::MacroSecurityTP( Window* _pParent, const ResId& _rResId, MacroSecurity* _pDlg )
105 	:TabPage		( _pParent, _rResId )
106 	,mpDlg			( _pDlg )
107 {
108 }
109 
110 MacroSecurityLevelTP::MacroSecurityLevelTP( Window* _pParent, MacroSecurity* _pDlg )
111 	:MacroSecurityTP	( _pParent, XMLSEC_RES( RID_XMLSECTP_SECLEVEL ), _pDlg )
112 	,maSecLevelFL		( this, XMLSEC_RES( FL_SECLEVEL ) )
113     ,maSecReadonlyFI    ( this, XMLSEC_RES( FI_SEC_READONLY ))
114     ,maVeryHighRB       ( this, XMLSEC_RES( RB_VERYHIGH ) )
115 	,maHighRB			( this, XMLSEC_RES( RB_HIGH ) )
116 	,maMediumRB			( this, XMLSEC_RES( RB_MEDIUM ) )
117 	,maLowRB			( this, XMLSEC_RES( RB_LOW ) )
118 {
119 	FreeResource();
120 
121     maLowRB.SetClickHdl( LINK( this, MacroSecurityLevelTP, RadioButtonHdl ) );
122     maMediumRB.SetClickHdl( LINK( this, MacroSecurityLevelTP, RadioButtonHdl ) );
123     maHighRB.SetClickHdl( LINK( this, MacroSecurityLevelTP, RadioButtonHdl ) );
124     maVeryHighRB.SetClickHdl( LINK( this, MacroSecurityLevelTP, RadioButtonHdl ) );
125 
126 	mnCurLevel = (sal_uInt16) mpDlg->maSecOptions.GetMacroSecurityLevel();
127     sal_Bool bReadonly = mpDlg->maSecOptions.IsReadOnly( SvtSecurityOptions::E_MACRO_SECLEVEL );
128 
129     RadioButton* pCheck = 0;
130     switch( mnCurLevel )
131 	{
132         case 3: pCheck = &maVeryHighRB;   break;
133         case 2: pCheck = &maHighRB;       break;
134         case 1: pCheck = &maMediumRB;     break;
135         case 0: pCheck = &maLowRB;        break;
136 	}
137     if(pCheck)
138         pCheck->Check();
139     else
140     {
141         DBG_ERROR("illegal macro security level");
142     }
143     maSecReadonlyFI.Show(bReadonly);
144     if(bReadonly)
145     {
146         //move to the selected button
147         if( pCheck && pCheck != &maVeryHighRB)
148         {
149             long nDiff = pCheck->GetPosPixel().Y() - maVeryHighRB.GetPosPixel().Y();
150             Point aPos(maSecReadonlyFI.GetPosPixel());
151             aPos.Y() += nDiff;
152             maSecReadonlyFI.SetPosPixel(aPos);
153         }
154         maVeryHighRB.Enable(sal_False);
155         maHighRB.Enable(sal_False);
156         maMediumRB.Enable(sal_False);
157         maLowRB.Enable(sal_False);
158     }
159 
160 }
161 
162 IMPL_LINK( MacroSecurityLevelTP, RadioButtonHdl, RadioButton*, EMPTYARG )
163 {
164     sal_uInt16 nNewLevel = 0;
165 	if( maVeryHighRB.IsChecked() )
166 		nNewLevel = 3;
167 	else if( maHighRB.IsChecked() )
168 		nNewLevel = 2;
169 	else if( maMediumRB.IsChecked() )
170 		nNewLevel = 1;
171 
172     if ( nNewLevel != mnCurLevel )
173     {
174         mnCurLevel = nNewLevel;
175         mpDlg->EnableReset();
176     }
177 
178     return 0;
179 }
180 
181 void MacroSecurityLevelTP::ClosePage( void )
182 {
183     mpDlg->maSecOptions.SetMacroSecurityLevel( mnCurLevel );
184 }
185 
186 void MacroSecurityTrustedSourcesTP::ImplCheckButtons()
187 {
188 	bool bCertSelected = maTrustCertLB.FirstSelected() != NULL;
189 	maViewCertPB.Enable( bCertSelected );
190     maRemoveCertPB.Enable( bCertSelected && !mbAuthorsReadonly);
191 
192     bool bLocationSelected = maTrustFileLocLB.GetSelectEntryPos() != LISTBOX_ENTRY_NOTFOUND;
193     maRemoveLocPB.Enable( bLocationSelected && !mbURLsReadonly);
194 }
195 
196 
197 IMPL_LINK( MacroSecurityTrustedSourcesTP, ViewCertPBHdl, void*, EMPTYARG )
198 {
199 	if( maTrustCertLB.FirstSelected() )
200 	{
201         sal_uInt16 nSelected = sal_uInt16( sal_uIntPtr( maTrustCertLB.FirstSelected()->GetUserData() ) );
202 
203 		uno::Reference< dcss::security::XSerialNumberAdapter > xSerialNumberAdapter =
204             ::com::sun::star::security::SerialNumberAdapter::create(mpDlg->mxCtx);
205 
206 		uno::Reference< dcss::security::XCertificate > xCert = mpDlg->mxSecurityEnvironment->getCertificate( maTrustedAuthors[nSelected][0], xSerialNumberAdapter->toSequence( maTrustedAuthors[nSelected][1] ) );
207 
208         // If we don't get it, create it from signature data:
209         if ( !xCert.is() )
210 			xCert = mpDlg->mxSecurityEnvironment->createCertificateFromAscii( maTrustedAuthors[nSelected][2] ) ;
211 
212 		DBG_ASSERT( xCert.is(), "*MacroSecurityTrustedSourcesTP::ViewCertPBHdl(): Certificate not found and can't be created!" );
213 
214         if ( xCert.is() )
215         {
216 		    CertificateViewer aViewer( this, mpDlg->mxSecurityEnvironment, xCert, sal_False );
217 		    aViewer.Execute();
218         }
219 	}
220     return 0;
221 }
222 
223 IMPL_LINK( MacroSecurityTrustedSourcesTP, RemoveCertPBHdl, void*, EMPTYARG )
224 {
225 	if( maTrustCertLB.FirstSelected() )
226 	{
227 		sal_uInt16 nAuthor = sal_uInt16( sal_uIntPtr( maTrustCertLB.FirstSelected()->GetUserData() ) );
228         ::comphelper::removeElementAt( maTrustedAuthors, nAuthor );
229 
230 		FillCertLB();
231         ImplCheckButtons();
232 	}
233 
234     return 0;
235 }
236 
237 IMPL_LINK( MacroSecurityTrustedSourcesTP, AddLocPBHdl, void*, EMPTYARG )
238 {
239 	try
240 	{
241 		rtl::OUString aService( RTL_CONSTASCII_USTRINGPARAM( FOLDER_PICKER_SERVICE_NAME ) );
242 		uno::Reference < lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
243 		uno::Reference < ui::dialogs::XFolderPicker > xFolderPicker( xFactory->createInstance( aService ), uno::UNO_QUERY );
244 
245 		short nRet = xFolderPicker->execute();
246 
247 		if( ui::dialogs::ExecutableDialogResults::OK != nRet )
248 			return 0;
249 
250 		rtl::OUString aPathStr = xFolderPicker->getDirectory();
251 		INetURLObject aNewObj( aPathStr );
252 		aNewObj.removeFinalSlash();
253 
254 		// then the new path also an URL else system path
255 		::rtl::OUString aSystemFileURL = ( aNewObj.GetProtocol() != INET_PROT_NOT_VALID ) ?
256 			aPathStr : aNewObj.getFSysPath( INetURLObject::FSYS_DETECT );
257 
258 		String aNewPathStr(aSystemFileURL);
259 
260         if ( osl::FileBase::getSystemPathFromFileURL( aSystemFileURL, aSystemFileURL ) == osl::FileBase::E_None )
261             aNewPathStr = aSystemFileURL;
262 
263 		if( maTrustFileLocLB.GetEntryPos( aNewPathStr ) == LISTBOX_ENTRY_NOTFOUND )
264 		{
265 			maTrustFileLocLB.InsertEntry( aNewPathStr );
266 		}
267 
268         ImplCheckButtons();
269 	}
270 	catch( uno::Exception& )
271 	{
272 		DBG_ERRORFILE( "MacroSecurityTrustedSourcesTP::AddLocPBHdl(): exception from folder picker" );
273 	}
274 
275 	return 0;
276 }
277 
278 IMPL_LINK( MacroSecurityTrustedSourcesTP, RemoveLocPBHdl, void*, EMPTYARG )
279 {
280 	sal_uInt16	nSel = maTrustFileLocLB.GetSelectEntryPos();
281 	if( nSel != LISTBOX_ENTRY_NOTFOUND )
282 	{
283 		maTrustFileLocLB.RemoveEntry( nSel );
284         // --> PB 2004-09-21 #i33584#
285         // after remove an entry, select another one if exists
286         sal_uInt16 nNewCount = maTrustFileLocLB.GetEntryCount();
287         if ( nNewCount > 0 )
288         {
289             if ( nSel >= nNewCount )
290                 nSel = nNewCount - 1;
291             maTrustFileLocLB.SelectEntryPos( nSel );
292         }
293         // <--
294         ImplCheckButtons();
295 	}
296 
297     return 0;
298 }
299 
300 IMPL_LINK( MacroSecurityTrustedSourcesTP, TrustCertLBSelectHdl, void*, EMPTYARG )
301 {
302     ImplCheckButtons();
303 	return 0;
304 }
305 
306 IMPL_LINK( MacroSecurityTrustedSourcesTP, TrustFileLocLBSelectHdl, void*, EMPTYARG )
307 {
308     ImplCheckButtons();
309 	return 0;
310 }
311 
312 void MacroSecurityTrustedSourcesTP::FillCertLB( void )
313 {
314     maTrustCertLB.Clear();
315 
316     sal_uInt32 nEntries = maTrustedAuthors.getLength();
317 
318 	if ( nEntries && mpDlg->mxSecurityEnvironment.is() )
319 	{
320 		for( sal_uInt32 nEntry = 0 ; nEntry < nEntries ; ++nEntry )
321 		{
322 			cssu::Sequence< ::rtl::OUString >&				rEntry = maTrustedAuthors[ nEntry ];
323 			uno::Reference< css::security::XCertificate >	xCert;
324 
325 			// create from RawData
326 			xCert = mpDlg->mxSecurityEnvironment->createCertificateFromAscii( rEntry[ 2 ] );
327 
328 			SvLBoxEntry*    pLBEntry = maTrustCertLB.InsertEntry( XmlSec::GetContentPart( xCert->getSubjectName() ) );
329 			maTrustCertLB.SetEntryText( XmlSec::GetContentPart( xCert->getIssuerName() ), pLBEntry, 1 );
330 			maTrustCertLB.SetEntryText( XmlSec::GetDateTimeString( xCert->getNotValidAfter() ), pLBEntry, 2 );
331 			pLBEntry->SetUserData( ( void* ) sal_Int32( nEntry ) );		// missuse user data as index
332 		}
333 	}
334 }
335 
336 MacroSecurityTrustedSourcesTP::MacroSecurityTrustedSourcesTP( Window* _pParent, MacroSecurity* _pDlg )
337 	:MacroSecurityTP	( _pParent, XMLSEC_RES( RID_XMLSECTP_TRUSTSOURCES ), _pDlg )
338 	,maTrustCertFL		( this, XMLSEC_RES( FL_TRUSTCERT ) )
339     ,maTrustCertROFI    ( this, XMLSEC_RES( FI_TRUSTCERT_RO ) )
340     ,maTrustCertLB      ( this, XMLSEC_RES( LB_TRUSTCERT ) )
341 	,maAddCertPB		( this, XMLSEC_RES( PB_ADD_TRUSTCERT ) )
342 	,maViewCertPB		( this, XMLSEC_RES( PB_VIEW_TRUSTCERT ) )
343 	,maRemoveCertPB		( this, XMLSEC_RES( PB_REMOVE_TRUSTCERT ) )
344 	,maTrustFileLocFL	( this, XMLSEC_RES( FL_TRUSTFILELOC ) )
345     ,maTrustFileROFI    ( this, XMLSEC_RES( FI_TRUSTFILE_RO ) )
346     ,maTrustFileLocFI   ( this, XMLSEC_RES( FI_TRUSTFILELOC ) )
347 	,maTrustFileLocLB	( this, XMLSEC_RES( LB_TRUSTFILELOC ) )
348 	,maAddLocPB			( this, XMLSEC_RES( FL_ADD_TRUSTFILELOC ) )
349 	,maRemoveLocPB		( this, XMLSEC_RES( FL_REMOVE_TRUSTFILELOC ) )
350 {
351 	static long	nTabs[] = { 3, 0, 35*CS_LB_WIDTH/100, 70*CS_LB_WIDTH/100 };
352 	maTrustCertLB.SetTabs( &nTabs[ 0 ] );
353 	maTrustCertLB.InsertHeaderEntry( String( XMLSEC_RES( STR_HEADERBAR ) ) );
354 
355 	FreeResource();
356 
357 	maTrustCertLB.SetSelectHdl( LINK( this, MacroSecurityTrustedSourcesTP, TrustCertLBSelectHdl ) );
358 	maAddCertPB.Hide();		// not used in the moment...
359 	maViewCertPB.SetClickHdl( LINK( this, MacroSecurityTrustedSourcesTP, ViewCertPBHdl ) );
360 	maViewCertPB.Disable();
361 	maRemoveCertPB.SetClickHdl( LINK( this, MacroSecurityTrustedSourcesTP, RemoveCertPBHdl ) );
362 	maRemoveCertPB.Disable();
363 
364 	maTrustFileLocLB.SetSelectHdl( LINK( this, MacroSecurityTrustedSourcesTP, TrustFileLocLBSelectHdl ) );
365 	maAddLocPB.SetClickHdl( LINK( this, MacroSecurityTrustedSourcesTP, AddLocPBHdl ) );
366 	maRemoveLocPB.SetClickHdl( LINK( this, MacroSecurityTrustedSourcesTP, RemoveLocPBHdl ) );
367 	maRemoveLocPB.Disable();
368 
369     maTrustedAuthors = mpDlg->maSecOptions.GetTrustedAuthors();
370     mbAuthorsReadonly = mpDlg->maSecOptions.IsReadOnly( SvtSecurityOptions::E_MACRO_TRUSTEDAUTHORS );
371     maTrustCertROFI.Show( mbAuthorsReadonly );
372     mbAuthorsReadonly ? maTrustCertLB.DisableTable() : maTrustCertLB.EnableTable();
373 //  unused button
374 //    maAddCertPB.Enable( !mbAuthorsReadonly );
375 
376     FillCertLB();
377 
378 	cssu::Sequence< rtl::OUString >	aSecureURLs = mpDlg->maSecOptions.GetSecureURLs();
379     mbURLsReadonly = mpDlg->maSecOptions.IsReadOnly( SvtSecurityOptions::E_SECUREURLS );
380     maTrustFileROFI.Show( mbURLsReadonly );
381     maTrustFileLocLB.Enable( !mbURLsReadonly );
382     maAddLocPB      .Enable( !mbURLsReadonly );
383 
384     sal_Int32 nEntryCnt = aSecureURLs.getLength();
385 	for( sal_Int32 i = 0 ; i < nEntryCnt ; ++i )
386     {
387         ::rtl::OUString aSystemFileURL( aSecureURLs[ i ] );
388         osl::FileBase::getSystemPathFromFileURL( aSystemFileURL, aSystemFileURL );
389 		maTrustFileLocLB.InsertEntry( aSystemFileURL );
390     }
391 }
392 
393 void MacroSecurityTrustedSourcesTP::ActivatePage()
394 {
395 	mpDlg->EnableReset( false );
396 	FillCertLB();
397 }
398 
399 void MacroSecurityTrustedSourcesTP::ClosePage( void )
400 {
401 	sal_uInt16	nEntryCnt = maTrustFileLocLB.GetEntryCount();
402 	if( nEntryCnt )
403 	{
404 		cssu::Sequence< rtl::OUString >	aSecureURLs( nEntryCnt );
405 		for( sal_uInt16 i = 0 ; i < nEntryCnt ; ++i )
406         {
407             ::rtl::OUString aURL( maTrustFileLocLB.GetEntry( i ) );
408             osl::FileBase::getFileURLFromSystemPath( aURL, aURL );
409 			aSecureURLs[ i ] = aURL;
410         }
411 
412 		mpDlg->maSecOptions.SetSecureURLs( aSecureURLs );
413 	}
414     // --> PB 2004-09-21 #i33584#
415     // don't forget to remove the old saved SecureURLs
416     else
417         mpDlg->maSecOptions.SetSecureURLs( cssu::Sequence< rtl::OUString >() );
418     // <--
419 
420 	mpDlg->maSecOptions.SetTrustedAuthors( maTrustedAuthors );
421 }
422 /*-- 26.02.2004 13:31:04---------------------------------------------------
423 
424   -----------------------------------------------------------------------*/
425 ReadOnlyImage::ReadOnlyImage(Window* pParent, const ResId rResId) :
426             FixedImage(pParent, rResId)
427 {
428     sal_Bool bHighContrast = pParent->GetSettings().GetStyleSettings().GetHighContrastMode();
429     SetImage( Image(XMLSEC_RES( bHighContrast ? RID_XMLSECTP_LOCK_HC : RID_XMLSECTP_LOCK )));
430 }
431 
432 /*-- 26.02.2004 13:31:04---------------------------------------------------
433 
434   -----------------------------------------------------------------------*/
435 ReadOnlyImage::~ReadOnlyImage()
436 {
437 }
438 /*-- 26.02.2004 13:31:04---------------------------------------------------
439 
440   -----------------------------------------------------------------------*/
441 void ReadOnlyImage::RequestHelp( const HelpEvent& rHEvt )
442 {
443     if( Help::IsBalloonHelpEnabled() || Help::IsQuickHelpEnabled() )
444     {
445         Rectangle   aLogicPix( LogicToPixel( Rectangle( Point(), GetOutputSize() ) ) );
446         Rectangle   aScreenRect( OutputToScreenPixel( aLogicPix.TopLeft() ),
447                                      OutputToScreenPixel( aLogicPix.BottomRight() ) );
448 
449         String aStr(ReadOnlyImage::GetHelpTip());
450         if ( Help::IsBalloonHelpEnabled() )
451             Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), aScreenRect,
452             aStr );
453         else if ( Help::IsQuickHelpEnabled() )
454             Help::ShowQuickHelp( this, aScreenRect, aStr );
455     }
456     else
457         Window::RequestHelp( rHEvt );
458 }
459 
460 /*-- 26.02.2004 14:20:21---------------------------------------------------
461 
462   -----------------------------------------------------------------------*/
463 const String& ReadOnlyImage::GetHelpTip()
464 {
465      static String  aStr(XMLSEC_RES( RID_XMLSECTP_READONLY_CONFIG_TIP));
466      return aStr;
467 }
468 
469