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 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp> 29 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 30 #include <com/sun/star/security/XDocumentDigitalSignatures.hpp> 31 #include <comphelper/sequence.hxx> 32 #include "comphelper/documentconstants.hxx" 33 #include <comphelper/processfactory.hxx> 34 35 #include <vcl/msgbox.hxx> 36 #include <com/sun/star/security/NoPasswordException.hpp> 37 38 using namespace ::com::sun::star::security; 39 40 #include "ids.hrc" 41 #include "secmacrowarnings.hxx" 42 #include "secmacrowarnings.hrc" 43 44 #ifdef _MSC_VER 45 #pragma warning (disable : 4355) // 4355: this used in initializer-list 46 #endif 47 48 using namespace ::com::sun::star; 49 using namespace ::com::sun::star; 50 51 52 // HACK!!! copied from xmlsecurity/source/dialog/resourcemanager.cxx 53 54 namespace 55 { 56 String GetContentPart( const String& _rRawString, const String& _rPartId ) 57 { 58 String s; 59 60 xub_StrLen nContStart = _rRawString.Search( _rPartId ); 61 if( nContStart != STRING_NOTFOUND ) 62 { 63 nContStart = nContStart + _rPartId.Len(); 64 ++nContStart; // now it's start of content, directly after Id 65 66 xub_StrLen nContEnd = _rRawString.Search( sal_Unicode( ',' ), nContStart ); 67 68 s = String( _rRawString, nContStart, nContEnd - nContStart ); 69 } 70 71 return s; 72 } 73 } 74 75 76 MacroWarning::MacroWarning( Window* _pParent, bool _bWithSignatures, ResMgr& rResMgr ) 77 :ModalDialog ( _pParent, ResId( RID_XMLSECDLG_MACROWARN, rResMgr ) ) 78 ,mpInfos ( NULL ) 79 ,maSymbolImg ( this, ResId( IMG_SYMBOL, rResMgr ) ) 80 ,maDocNameFI ( this, ResId( FI_DOCNAME, rResMgr ) ) 81 ,maDescr1aFI ( this, ResId( FI_DESCR1A, rResMgr ) ) 82 ,maDescr1bFI ( this, ResId( FI_DESCR1B, rResMgr ) ) 83 ,maSignsFI ( this, ResId( FI_SIGNS, rResMgr ) ) 84 ,maViewSignsBtn ( this, ResId( PB_VIEWSIGNS, rResMgr ) ) 85 ,maDescr2FI ( this, ResId( FI_DESCR2, rResMgr ) ) 86 ,maAlwaysTrustCB ( this, ResId( CB_ALWAYSTRUST, rResMgr ) ) 87 ,maBottomSepFL ( this, ResId( FL_BOTTOM_SEP, rResMgr ) ) 88 ,maEnableBtn ( this, ResId( PB_ENABLE, rResMgr ) ) 89 ,maDisableBtn ( this, ResId( PB_DISABLE, rResMgr ) ) 90 ,maHelpBtn ( this, ResId( BTN_HELP, rResMgr ) ) 91 ,mbSignedMode ( true ) 92 ,mbShowSignatures ( _bWithSignatures ) 93 ,mnActSecLevel ( 0 ) 94 { 95 FreeResource(); 96 97 InitControls(); 98 99 maDisableBtn.SetClickHdl( LINK( this, MacroWarning, DisableBtnHdl ) ); 100 maEnableBtn.SetClickHdl( LINK( this, MacroWarning, EnableBtnHdl ) ); 101 maDisableBtn.GrabFocus(); // Default button, but focus is on view button 102 } 103 104 MacroWarning::~MacroWarning() 105 { 106 } 107 108 short MacroWarning::Execute() 109 { 110 FitControls(); 111 return ModalDialog::Execute(); 112 } 113 114 void MacroWarning::SetDocumentURL( const String& rDocURL ) 115 { 116 maDocNameFI.SetText( rDocURL ); 117 } 118 119 IMPL_LINK( MacroWarning, ViewSignsBtnHdl, void*, EMPTYARG ) 120 { 121 DBG_ASSERT( mxCert.is(), "*MacroWarning::ViewSignsBtnHdl(): no certificate set!" ); 122 123 uno::Sequence< uno::Any > aArgs( 1 ); 124 aArgs[0] = uno::makeAny( maODFVersion ); 125 uno::Reference< security::XDocumentDigitalSignatures > xD( 126 comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), aArgs ), uno::UNO_QUERY ); 127 if( xD.is() ) 128 { 129 if( mxCert.is() ) 130 xD->showCertificate( mxCert ); 131 else if( mxStore.is() ) 132 xD->showScriptingContentSignatures( mxStore, uno::Reference< io::XInputStream >() ); 133 } 134 135 return 0; 136 } 137 138 IMPL_LINK( MacroWarning, EnableBtnHdl, void*, EMPTYARG ) 139 { 140 if( mbSignedMode && maAlwaysTrustCB.IsChecked() ) 141 { // insert path into trusted path list 142 uno::Sequence< uno::Any > aArgs( 1 ); 143 aArgs[0] = uno::makeAny( maODFVersion ); 144 uno::Reference< security::XDocumentDigitalSignatures > xD( 145 comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), aArgs ), uno::UNO_QUERY ); 146 if( xD.is() ) 147 { 148 if( mxCert.is() ) 149 xD->addAuthorToTrustedSources( mxCert ); 150 else if( mxStore.is() ) 151 { 152 DBG_ASSERT( mpInfos, "-MacroWarning::EnableBtnHdl(): no infos, search in nirvana..." ); 153 154 sal_Int32 nCnt = mpInfos->getLength(); 155 for( sal_Int32 i = 0 ; i < nCnt ; ++i ) 156 xD->addAuthorToTrustedSources( (*mpInfos)[ i ].Signer ); 157 } 158 } 159 } 160 161 EndDialog( RET_OK ); 162 return 0; 163 } 164 165 IMPL_LINK( MacroWarning, DisableBtnHdl, void*, EMPTYARG ) 166 { 167 EndDialog( RET_CANCEL ); 168 return 0; 169 } 170 171 IMPL_LINK( MacroWarning, AlwaysTrustCheckHdl, void*, EMPTYARG ) 172 { 173 bool bEnable = ( mnActSecLevel < 2 || maAlwaysTrustCB.IsChecked() ); 174 maEnableBtn.Enable( bEnable ); 175 maDisableBtn.Enable( !maAlwaysTrustCB.IsChecked() ); 176 177 return 0; 178 } 179 180 void MacroWarning::InitControls() 181 { 182 // set warning image 183 Image aImg( WarningBox::GetStandardImage() ); 184 maSymbolImg.SetImage( aImg ); 185 maSymbolImg.SetSizePixel( aImg.GetSizePixel() ); 186 // set bold font and path ellipsis for docname fixedtext 187 Font aTmpFont = maDocNameFI.GetControlFont(); 188 aTmpFont.SetWeight( WEIGHT_BOLD ); 189 maDocNameFI.SetControlFont( aTmpFont ); 190 WinBits nStyle = maDocNameFI.GetStyle(); 191 nStyle |= WB_PATHELLIPSIS; 192 maDocNameFI.SetStyle( nStyle ); 193 // show signature controls? 194 if( mbShowSignatures ) 195 { 196 maDescr1bFI.Hide(); 197 maViewSignsBtn.SetClickHdl( LINK( this, MacroWarning, ViewSignsBtnHdl ) ); 198 maViewSignsBtn.Disable(); // default 199 maAlwaysTrustCB.SetClickHdl( LINK( this, MacroWarning, AlwaysTrustCheckHdl ) ); 200 201 mnActSecLevel = SvtSecurityOptions().GetMacroSecurityLevel(); 202 if ( mnActSecLevel >= 2 ) 203 maEnableBtn.Disable(); 204 } 205 else 206 { 207 maDescr1aFI.Hide(); 208 maSignsFI.Hide(); 209 maViewSignsBtn.Hide(); 210 maAlwaysTrustCB.Hide(); 211 212 // move hint up to position of signer list 213 maDescr2FI.SetPosPixel( maSignsFI.GetPosPixel() ); 214 } 215 // without signature controls could be smaller 216 if ( !mbShowSignatures ) 217 { 218 Point aPos = maDescr2FI.GetPosPixel(); 219 aPos.Y() += maDescr2FI.GetSizePixel().Height(); 220 aPos.Y() += LogicToPixel( Size( 3, 3 ) ).Height(); 221 long nDelta = maBottomSepFL.GetPosPixel().Y() - aPos.Y(); 222 Window* pWins[] = 223 { 224 &maBottomSepFL, &maEnableBtn, &maDisableBtn, &maHelpBtn 225 }; 226 Window** pCurrent = pWins; 227 for ( sal_uInt32 i = 0; i < sizeof( pWins ) / sizeof( pWins[ 0 ] ); ++i, ++pCurrent ) 228 { 229 Point aNewPos = (*pCurrent)->GetPosPixel(); 230 aNewPos.Y() -= nDelta; 231 (*pCurrent)->SetPosPixel( aNewPos ); 232 } 233 234 Size aDlgSz = GetSizePixel(); 235 aDlgSz.Height() -= nDelta; 236 SetSizePixel( aDlgSz ); 237 } 238 239 // check if some buttontexts are to wide 240 String sText = maViewSignsBtn.GetText(); 241 long nTxtW = maViewSignsBtn.GetTextWidth( sText ); 242 const long nOffset = 12; 243 if ( sText.Search( '~' ) == STRING_NOTFOUND ) 244 nTxtW += nOffset; 245 long nBtnW = maViewSignsBtn.GetSizePixel().Width(); 246 if ( nTxtW >= nBtnW ) 247 { 248 // broaden the button 249 long nDelta = Max( nTxtW - nBtnW, nOffset/3 ); 250 Size aNewSize = maViewSignsBtn.GetSizePixel(); 251 aNewSize.Width() += nDelta; 252 maViewSignsBtn.SetSizePixel( aNewSize ); 253 // and give it a new position 254 Point aNewPos = maViewSignsBtn.GetPosPixel(); 255 aNewPos.X() -= nDelta; 256 maViewSignsBtn.SetPosPixel( aNewPos ); 257 // the the left fixedtext must be smaller 258 aNewSize = maSignsFI.GetSizePixel(); 259 aNewSize.Width() -= nDelta; 260 maSignsFI.SetSizePixel( aNewSize ); 261 } 262 // if the button text (we compare with the longest of both) is too wide, then broaden the buttons 263 String sText1 = maEnableBtn.GetText(); 264 long nTxtW1 = maEnableBtn.GetTextWidth( sText1 ); 265 if ( sText1.Search( '~' ) == STRING_NOTFOUND ) 266 nTxtW1 += nOffset; 267 String sText2 = maDisableBtn.GetText(); 268 long nTxtW2 = maDisableBtn.GetTextWidth( sText2 ); 269 if ( sText2.Search( '~' ) == STRING_NOTFOUND ) 270 nTxtW2 += nOffset; 271 nTxtW = Max( nTxtW1, nTxtW2 ); 272 nBtnW = maEnableBtn.GetSizePixel().Width(); 273 if ( nTxtW > nBtnW ) 274 { 275 // broaden both buttons 276 long nDelta = nTxtW - nBtnW; 277 Size aNewSize = maEnableBtn.GetSizePixel(); 278 aNewSize.Width() += nDelta; 279 maEnableBtn.SetSizePixel( aNewSize ); 280 maDisableBtn.SetSizePixel( aNewSize ); 281 // and give them a new position 282 Point aNewPos = maEnableBtn.GetPosPixel(); 283 aNewPos.X() -= (2*nDelta); 284 maEnableBtn.SetPosPixel( aNewPos ); 285 aNewPos = maDisableBtn.GetPosPixel(); 286 aNewPos.X() -= nDelta; 287 maDisableBtn.SetPosPixel( aNewPos ); 288 } 289 } 290 291 void MacroWarning::FitControls() 292 { 293 Size a3Size = LogicToPixel( Size( 3, 3 ), MAP_APPFONT ); 294 Size aNewSize, aMinSize; 295 long nTxtH = 0; 296 long nCtrlH = 0; 297 long nDelta = 0; 298 299 if ( mbShowSignatures ) 300 { 301 aMinSize = maSignsFI.CalcMinimumSize( maSignsFI.GetSizePixel().Width() ); 302 nTxtH = Max( aMinSize.Height(), maViewSignsBtn.GetSizePixel().Height() ); 303 nTxtH += a3Size.Height() / 2; 304 nCtrlH = maSignsFI.GetSizePixel().Height(); 305 nDelta = Max( nCtrlH - nTxtH, static_cast< long >( -100 ) ); // not too large 306 aNewSize = maSignsFI.GetSizePixel(); 307 aNewSize.Height() -= nDelta; 308 maSignsFI.SetSizePixel( aNewSize ); 309 } 310 311 aMinSize = maDescr2FI.CalcMinimumSize( maDescr2FI.GetSizePixel().Width() ); 312 nTxtH = aMinSize.Height(); 313 nCtrlH = maDescr2FI.GetSizePixel().Height(); 314 long nDelta2 = ( nCtrlH - nTxtH ); 315 aNewSize = maDescr2FI.GetSizePixel(); 316 aNewSize.Height() -= nDelta2; 317 maDescr2FI.SetSizePixel( aNewSize ); 318 319 // new position for the succeeding windows 320 Window* pWins[] = 321 { 322 &maDescr2FI, &maAlwaysTrustCB, &maBottomSepFL, &maEnableBtn, &maDisableBtn, &maHelpBtn 323 }; 324 Window** pCurrent = pWins; 325 for ( sal_uInt32 i = 0; i < sizeof( pWins ) / sizeof( pWins[ 0 ] ); ++i, ++pCurrent ) 326 { 327 Point aNewPos = (*pCurrent)->GetPosPixel(); 328 aNewPos.Y() -= nDelta; 329 (*pCurrent)->SetPosPixel( aNewPos ); 330 331 if ( *pCurrent == &maDescr2FI ) 332 nDelta += nDelta2; 333 } 334 335 // new size of the dialog 336 aNewSize = GetSizePixel(); 337 aNewSize.Height() -= nDelta; 338 SetSizePixel( aNewSize ); 339 } 340 341 void MacroWarning::SetStorage( const cssu::Reference < css::embed::XStorage >& rxStore, 342 const ::rtl::OUString& aODFVersion, 343 const cssu::Sequence< security::DocumentSignatureInformation >& rInfos ) 344 { 345 mxStore = rxStore; 346 maODFVersion = aODFVersion; 347 sal_Int32 nCnt = rInfos.getLength(); 348 if( mxStore.is() && nCnt > 0 ) 349 { 350 mpInfos = &rInfos; 351 String aCN_Id( String::CreateFromAscii( "CN" ) ); 352 String s; 353 s = GetContentPart( rInfos[ 0 ].Signer->getSubjectName(), aCN_Id ); 354 355 for( sal_Int32 i = 1 ; i < nCnt ; ++i ) 356 { 357 s.AppendAscii( "\n" ); 358 s += GetContentPart( rInfos[ i ].Signer->getSubjectName(), aCN_Id ); 359 } 360 361 maSignsFI.SetText( s ); 362 maViewSignsBtn.Enable(); 363 } 364 } 365 366 void MacroWarning::SetCertificate( const cssu::Reference< css::security::XCertificate >& _rxCert ) 367 { 368 mxCert = _rxCert; 369 if( mxCert.is() ) 370 { 371 String aCN_Id( String::CreateFromAscii( "CN" ) ); 372 String s; 373 s = GetContentPart( mxCert->getSubjectName(), aCN_Id ); 374 maSignsFI.SetText( s ); 375 maViewSignsBtn.Enable(); 376 } 377 } 378 379