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