Update ooo320-m1
[ooovba.git] / scripting / source / storage / ScriptSecurityManager.cxx
blobf84dbbec6d910afb17a6c67028c3993aa090f7ca
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ScriptSecurityManager.cxx,v $
10 * $Revision: 1.23 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_scripting.hxx"
34 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
35 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
36 #include <com/sun/star/lang/XComponent.hpp>
37 #include <com/sun/star/lang/WrappedTargetException.hpp>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/beans/PropertyValue.hpp>
40 #include <com/sun/star/beans/UnknownPropertyException.hpp>
41 #include <com/sun/star/container/XNameReplace.hpp>
42 #include <com/sun/star/util/XChangesBatch.hpp>
43 #include <com/sun/star/util/XMacroExpander.hpp>
44 #include <com/sun/star/util/XStringSubstitution.hpp>
45 #include <com/sun/star/awt/XDialog.hpp>
46 #include <com/sun/star/security/AccessControlException.hpp>
47 #include <com/sun/star/security/RuntimePermission.hpp>
48 #include <drafts/com/sun/star/script/framework/storage/XScriptStorageManager.hpp>
49 #include <drafts/com/sun/star/script/framework/storage/XScriptInfoAccess.hpp>
50 #include "ScriptSecurityManager.hxx"
51 #include <util/util.hxx>
52 #include <util/scriptingconstants.hxx>
55 using namespace ::rtl;
56 using namespace ::osl;
57 using namespace ::com::sun::star;
58 using namespace ::com::sun::star::uno;
59 using namespace ::drafts::com::sun::star::script::framework;
61 // is this in the utils?
62 const char* const SCRIPTSTORAGEMANAGER_SERVICE =
63 "/singletons/drafts.com.sun.star.script.framework.storage.theScriptStorageManager";
65 namespace scripting_securitymgr
68 static OUString s_configProv = ::rtl::OUString::createFromAscii(
69 "com.sun.star.configuration.ConfigurationProvider");
71 static OUString s_configAccess = ::rtl::OUString::createFromAscii(
72 "com.sun.star.configuration.ConfigurationAccess");
74 static OUString s_configUpdate = ::rtl::OUString::createFromAscii(
75 "com.sun.star.configuration.ConfigurationUpdateAccess");
77 static OUString s_securityDialog = ::rtl::OUString::createFromAscii(
78 "com.sun.star.script.framework.security.SecurityDialog");
80 static const int PERMISSION_NEVER = 0;
81 static const int PERMISSION_PATHLIST = 1;
82 static const int PERMISSION_ALWAYS = 2;
84 static const int ALLOW_RUN = 1;
85 static const int ADD_TO_PATH = 2;
87 //*************************************************************************
88 // ScriptSecurityManager Constructor
89 ScriptSecurityManager::ScriptSecurityManager(
90 const Reference< XComponentContext > & xContext ) throw ( RuntimeException )
91 : m_xContext( xContext)
93 OSL_TRACE( "< ScriptSecurityManager ctor called >\n" );
94 validateXRef( m_xContext,
95 "ScriptSecurityManager::ScriptSecurityManager: invalid context" );
97 // get the service manager from the context
98 Reference< lang::XMultiComponentFactory > xMgr = m_xContext->getServiceManager();
99 validateXRef( xMgr,
100 "ScriptSecurityManager::ScriptSecurityManager: cannot get ServiceManager" );
102 // create an instance of the ConfigurationProvider
103 Reference< XInterface > xInterface = xMgr->createInstanceWithContext(
104 s_configProv, m_xContext );
105 validateXRef( xInterface,
106 "ScriptSecurityManager::ScriptSecurityManager: cannot get ConfigurationProvider" );
107 // create an instance of the ConfigurationAccess for accessing the
108 // scripting security settings
109 m_xConfigProvFactory = Reference < lang::XMultiServiceFactory > ( xInterface, UNO_QUERY );
110 validateXRef( m_xConfigProvFactory,
111 "ScriptSecurityManager::ScriptSecurityManager: cannot get XMultiServiceFactory interface from ConfigurationProvider" );
115 void ScriptSecurityManager::addScriptStorage( rtl::OUString scriptStorageURL,
116 sal_Int32 storageID)
117 throw ( RuntimeException )
119 Permission_Hash::const_iterator ph_it = m_permissionSettings.find( scriptStorageURL );
120 if ( ph_it != m_permissionSettings.end() )
122 OSL_TRACE( "ScriptSecurityManager::addScriptStorage: already called for %s",
123 ::rtl::OUStringToOString( scriptStorageURL,
124 RTL_TEXTENCODING_ASCII_US ).pData->buffer);
125 return;
127 StoragePerm newPerm;
128 newPerm.scriptStorageURL=scriptStorageURL;
129 newPerm.storageID=storageID;
131 // we err on the side of caution!!
132 newPerm.execPermission=sal_False;
134 //need to check if storage has any scripts
135 try
137 /* need to replace this with something better, now logical names are
138 * gone
140 Reference< XInterface > xInterface;
141 Any a = m_xContext->getValueByName(
142 OUString::createFromAscii( SCRIPTSTORAGEMANAGER_SERVICE ) );
143 if ( sal_False == ( a >>= xInterface ) )
145 throw RuntimeException(
146 OUSTR( "ScriptSecurityManager::addScriptStorage: could not obtain ScriptStorageManager singleton" ),
147 Reference< XInterface >() );
149 validateXRef( xInterface,
150 "ScriptSecurityManager::addScriptStorage: cannot get Storage service" );
151 Reference< storage::XScriptStorageManager > xScriptStorageManager(
152 xInterface, UNO_QUERY_THROW );
153 Reference< XInterface > xScriptStorage =
154 xScriptStorageManager->getScriptStorage( storageID );
155 validateXRef( xScriptStorage,
156 "ScriptNameResolverImpl::getStorageInstance: cannot get Script Storage service" );
157 Reference< storage::XScriptInfoAccess > xScriptInfoAccess =
158 Reference< storage::XScriptInfoAccess > ( xScriptStorage,
159 UNO_QUERY_THROW );
160 Sequence< ::rtl::OUString > logicalNames = xScriptInfoAccess->getScriptLogicalNames();
161 if( !logicalNames.getLength() ) // we have no logical names
163 return;
164 } */
166 // we have some scripts so read config & decide on that basis
167 // Setup flags: m_runMacroSetting, m_warning, m_confirmationRequired,
168 readConfiguration();
170 catch ( RuntimeException & rte )
172 OSL_TRACE( "ScriptSecurityManager::addScriptStorage: caught RuntimeException: %s",
173 ::rtl::OUStringToOString( rte.Message,
174 RTL_TEXTENCODING_ASCII_US ).pData->buffer);
175 throw RuntimeException(
176 OUSTR( "ScriptSecurityManager::addScriptStorage: caught RuntimeException" ).concat( rte.Message ),
177 Reference< XInterface >() );
180 switch( m_runMacroSetting )
182 case PERMISSION_NEVER: // never
184 OSL_TRACE("never run");
185 break;
187 case PERMISSION_PATHLIST: // according to path list
189 OSL_TRACE("according to path");
190 // check path
191 rtl::OUString path = scriptStorageURL.copy( 0, scriptStorageURL.lastIndexOf( '/' ) );
192 OSL_TRACE( "no of elts in path list = %d",
193 (int)m_secureURL.getLength() );
194 bool match = isSecureURL( path );
195 if( match && ( m_warning == sal_True ) )
197 OSL_TRACE("path match & warning dialog");
198 int result = (int)executeStandardDialog();
199 OSL_TRACE("result = %d", (int)result);
200 if ( (result&ALLOW_RUN) == ALLOW_RUN )
202 newPerm.execPermission=sal_True;
204 break;
206 else if ( match )
208 OSL_TRACE("path match & no warning dialog");
209 newPerm.execPermission=sal_True;
210 break;
212 else if( m_confirmationRequired == sal_True )
214 OSL_TRACE("no path match & confirmation dialog");
215 int result = (int)executePathDialog( path );
216 OSL_TRACE("result = %d", (int)result);
217 if ( (result&ALLOW_RUN) == ALLOW_RUN )
219 newPerm.execPermission=sal_True;
221 if ( (result&ADD_TO_PATH) == ADD_TO_PATH )
223 /* if checkbox clicked then need to add path to registry*/
224 addToSecurePaths(path);
227 break;
229 case PERMISSION_ALWAYS: // always
230 if( m_warning == sal_True )
232 OSL_TRACE("always & warning dialog");
233 short result = executeStandardDialog();
234 if ( (result&ALLOW_RUN) == ALLOW_RUN )
236 newPerm.execPermission=sal_True;
239 else
241 OSL_TRACE("always & no warning dialog");
242 newPerm.execPermission=sal_True;
244 break;
245 default:
247 throw RuntimeException(
248 OUSTR( "ScriptSecurityManager::addScriptStorage got invalid OfficeBasic setting"),
249 Reference< XInterface > ());
252 if ( newPerm.execPermission == sal_True )
254 OSL_TRACE("setting exec permission to true for %s",
255 ::rtl::OUStringToOString( scriptStorageURL,
256 RTL_TEXTENCODING_ASCII_US ).pData->buffer );
258 else
260 OSL_TRACE("setting exec permission to false for %s",
261 ::rtl::OUStringToOString( scriptStorageURL,
262 RTL_TEXTENCODING_ASCII_US ).pData->buffer );
265 m_permissionSettings[ scriptStorageURL ] = newPerm;
268 bool ScriptSecurityManager::isSecureURL( const OUString & path )
270 bool match = false;
271 OSL_TRACE( "no of elts in path list = %d",
272 (int)m_secureURL.getLength() );
273 OSL_TRACE("document path: %s",
274 ::rtl::OUStringToOString( path,
275 RTL_TEXTENCODING_ASCII_US ).pData->buffer);
276 int length = m_secureURL.getLength();
277 for( int j = 0; j < length ; j++ )
279 OSL_TRACE("path list element: %s",
280 ::rtl::OUStringToOString( m_secureURL[j],
281 RTL_TEXTENCODING_ASCII_US ).pData->buffer);
282 #ifdef WIN32
283 OSL_TRACE("case insensitive comparison");
284 if( path.equalsIgnoreAsciiCase( m_secureURL[j] ) )
285 #else
286 OSL_TRACE("case sensitive comparison");
287 if( path.equals( m_secureURL[j] ) )
288 #endif
290 match = true;
291 break;
294 return match;
297 short ScriptSecurityManager::executeStandardDialog()
298 throw ( RuntimeException )
300 OUString dummyString;
301 return executeDialog( dummyString );
304 short ScriptSecurityManager::executePathDialog( const OUString & path )
305 throw ( RuntimeException )
307 return executeDialog( path );
310 short ScriptSecurityManager::executeDialog( const OUString & path )
311 throw ( RuntimeException )
313 Sequence < Any > aArgs;
314 if( path.getLength() != 0 )
316 OSL_TRACE("reallocing");
317 aArgs.realloc(1);
318 aArgs[ 0 ] <<= path;
320 short result;
323 Reference< lang::XMultiComponentFactory > xMgr = m_xContext->getServiceManager();
324 validateXRef( xMgr,
325 "ScriptSecurityManager::executeDialog: cannot get ServiceManager" );
326 Reference< XInterface > xInterface =
327 xMgr->createInstanceWithArgumentsAndContext( s_securityDialog,
328 aArgs, m_xContext );
329 validateXRef( xInterface, "ScriptSecurityManager::executeDialog: Can't create SecurityDialog" );
330 Reference< awt::XDialog > xDialog( xInterface, UNO_QUERY_THROW );
331 result = xDialog->execute();
332 Reference< lang::XComponent > xComponent( xInterface, UNO_QUERY_THROW );
333 validateXRef( xInterface, "ScriptSecurityManager::executeDialog: Can't get XComponent to dispose dialog" );
334 xComponent->dispose();
336 catch ( RuntimeException & rte )
338 throw RuntimeException(
339 OUSTR( "ScriptSecurityManager::executeDialog: caught RuntimeException: ").concat( rte.Message ),
340 Reference< XInterface > ());
342 catch ( Exception & e )
344 throw RuntimeException(
345 OUSTR( "ScriptSecurityManager::executeDialog: caught Exception: ").concat( e.Message ),
346 Reference< XInterface > ());
348 return result;
352 * checks to see whether the requested ScriptPermission is allowed.
353 * This was modelled after the Java AccessController, but at this time
354 * we can't see a good reason not to return a bool, rather than throw
355 * an exception if the request is not granted (as is the case in Java).
357 void ScriptSecurityManager::checkPermission( const OUString & scriptStorageURL,
358 const OUString & permissionRequest )
359 throw ( RuntimeException, lang::IllegalArgumentException, security::AccessControlException )
361 if( permissionRequest.equals( OUString::createFromAscii( "execute" ) ) )
363 OSL_TRACE(
364 "ScriptSecurityManager::checkPermission: execute permission request for %s",
365 ::rtl::OUStringToOString( scriptStorageURL,
366 RTL_TEXTENCODING_ASCII_US ).pData->buffer);
367 Permission_Hash::const_iterator ph_it = m_permissionSettings.find( scriptStorageURL );
368 Permission_Hash::const_iterator ph_itend =
369 m_permissionSettings.end();
370 if ( ph_it != ph_itend )
372 if ( ph_it->second.execPermission )
374 return;
376 else
378 OSL_TRACE( "permission refused" );
379 Any aPermission;
380 security::RuntimePermission permission;
381 permission.Name = OUString::createFromAscii( "execute" ).concat( scriptStorageURL );
382 aPermission <<= permission;
383 throw security::AccessControlException(
384 OUString::createFromAscii( "ScriptSecurityManager::checkPermission: no execute permission for URL" ).concat( scriptStorageURL ),
385 Reference< XInterface > (), aPermission );
388 // we should never get here!!
389 throw lang::IllegalArgumentException( OUString::createFromAscii( "ScriptSecurityManager::checkPermission: storageURL not found" ), Reference< XInterface > (), 0 );
391 // inappropriate permission request
392 throw lang::IllegalArgumentException( OUString::createFromAscii( "ScriptSecurityManager::checkPermission: storageURL not found" ), Reference< XInterface > (), 1 );
395 void ScriptSecurityManager::removePermissionSettings ( ::rtl::OUString & scriptStorageURL )
397 Permission_Hash::const_iterator ph_it =
398 m_permissionSettings.find( scriptStorageURL );
400 if ( ph_it == m_permissionSettings.end() )
402 OSL_TRACE( "Entry for storage url %s doesn't exist in map",
403 ::rtl::OUStringToOString( scriptStorageURL,
404 RTL_TEXTENCODING_ASCII_US ).pData->buffer);
405 return;
408 // erase the entry from the hash
409 m_permissionSettings.erase( scriptStorageURL );
413 void ScriptSecurityManager::readConfiguration()
414 throw ( RuntimeException)
416 Reference< XInterface > xInterface;
417 try
419 beans::PropertyValue configPath;
420 configPath.Name = ::rtl::OUString::createFromAscii( "nodepath" );
421 configPath.Value <<= ::rtl::OUString::createFromAscii( "org.openoffice.Office.Common/Security/Scripting" );
422 Sequence < Any > aargs( 1 );
423 aargs[ 0 ] <<= configPath;
424 validateXRef( m_xConfigProvFactory,
425 "ScriptSecurityManager::readConfiguration: ConfigProviderFactory no longer valid!" );
426 xInterface = m_xConfigProvFactory->createInstanceWithArguments( s_configAccess,
427 aargs );
428 validateXRef( xInterface,
429 "ScriptSecurityManager::readConfiguration: cannot get ConfigurationAccess" );
430 // get the XPropertySet interface from the ConfigurationAccess service
431 Reference < beans::XPropertySet > xPropSet( xInterface, UNO_QUERY );
432 Any value;
434 value=xPropSet->getPropertyValue( OUSTR( "Confirmation" ) );
435 if ( sal_False == ( value >>= m_confirmationRequired ) )
437 throw RuntimeException(
438 OUSTR( "ScriptSecurityManager:readConfiguration: can't get Confirmation setting" ),
439 Reference< XInterface > () );
441 if ( m_confirmationRequired == sal_True )
443 OSL_TRACE( "ScriptSecurityManager:readConfiguration: confirmation is true" );
445 else
447 OSL_TRACE( "ScriptSecurityManager:readConfiguration: confirmation is false" );
449 value=xPropSet->getPropertyValue( OUSTR( "Warning" ) );
450 if ( sal_False == ( value >>= m_warning ) )
452 throw RuntimeException(
453 OUSTR( "ScriptSecurityManager:readConfiguration: can't get Warning setting" ),
454 Reference< XInterface > () );
456 if ( m_warning == sal_True )
458 OSL_TRACE( "ScriptSecurityManager:readConfiguration: warning is true" );
460 else
462 OSL_TRACE( "ScriptSecurityManager:readConfiguration: warning is false" );
464 value=xPropSet->getPropertyValue( OUSTR( "OfficeBasic" ) );
465 if ( sal_False == ( value >>= m_runMacroSetting ) )
467 throw RuntimeException(
468 OUSTR( "ScriptSecurityManager:readConfiguration: can't get OfficeBasic setting" ),
469 Reference< XInterface > () );
471 OSL_TRACE( "ScriptSecurityManager:readConfiguration: OfficeBasic = %d", m_runMacroSetting );
472 value=xPropSet->getPropertyValue( OUSTR( "SecureURL" ) );
473 if ( sal_False == ( value >>= m_secureURL ) )
475 throw RuntimeException(
476 OUSTR( "ScriptSecurityManager:readConfiguration: can't get SecureURL setting" ),
477 Reference< XInterface > () );
480 catch ( beans::UnknownPropertyException & upe )
482 throw RuntimeException(
483 OUSTR( "ScriptSecurityManager:readConfiguration: Attempt to read unknown property: " ).concat( upe.Message ),
484 Reference< XInterface > () );
486 catch ( lang::WrappedTargetException & wte )
488 throw RuntimeException(
489 OUSTR( "ScriptSecurityManager:readConfiguration: wrapped target exception? :" ).concat( wte.Message ),
490 Reference< XInterface > () );
492 catch ( Exception & e )
494 OSL_TRACE( "Unknown exception in readconf: %s",
495 ::rtl::OUStringToOString(e.Message ,
496 RTL_TEXTENCODING_ASCII_US ).pData->buffer );
497 throw RuntimeException(
498 OUSTR( "ScriptSecurityManager:readConfiguration: exception? :" ).concat( e.Message ),
499 Reference< XInterface > () );
501 #ifdef _DEBUG
502 catch ( ... )
504 OSL_TRACE( "Completely Unknown exception in readconf!!!!!!");
505 throw RuntimeException(
506 OUSTR( "ScriptSecurityManager:readConfiguration: exception? :" ),
507 Reference< XInterface > () );
509 #endif
511 int length = m_secureURL.getLength();
513 // PathSubstitution needed to interpret variables found in config
514 Reference< lang::XMultiComponentFactory > xMgr = m_xContext->getServiceManager();
515 validateXRef( xMgr,
516 "ScriptSecurityManager::readConfiguration: cannot get XMultiComponentFactory" );
517 xInterface = xMgr->createInstanceWithContext(
518 ::rtl::OUString::createFromAscii(
519 "com.sun.star.util.PathSubstitution"), m_xContext);
520 validateXRef( xInterface,
521 "ScriptSecurityManager::readConfiguration: cannot get ConfigurationProvider" );
522 Reference< util::XStringSubstitution > xStringSubstitution(
523 xInterface, UNO_QUERY);
524 validateXRef( xStringSubstitution,
525 "ScriptSecurityManager::readConfiguration: cannot get ConfigurationProvider" );
526 for( int i = 0; i < length; i++ )
528 OSL_TRACE( "ScriptSecurityManager:readConfiguration path = %s",
529 ::rtl::OUStringToOString(m_secureURL[i] ,
530 RTL_TEXTENCODING_ASCII_US ).pData->buffer );
532 OSL_TRACE( "ScriptSecurityManager: subpath = %s",
533 ::rtl::OUStringToOString(
534 xStringSubstitution->substituteVariables( m_secureURL[i], true ),
535 RTL_TEXTENCODING_ASCII_US ).pData->buffer );
536 m_secureURL[i] = xStringSubstitution->substituteVariables( m_secureURL[i], true );
538 #ifdef _DEBUG
539 int length2 = m_secureURL.getLength();
540 for( int j = 0; j < length2 ; j++ )
542 OSL_TRACE( "ScriptSecurityManager: path = %s",
543 ::rtl::OUStringToOString(m_secureURL[j] ,
544 RTL_TEXTENCODING_ASCII_US ).pData->buffer );
546 #endif
549 void ScriptSecurityManager::addToSecurePaths( const OUString & path )
550 throw ( RuntimeException )
552 OSL_TRACE( "--->ScriptSecurityManager::addToSecurePaths" );
553 beans::PropertyValue configPath;
554 configPath.Name = ::rtl::OUString::createFromAscii( "nodepath" );
555 configPath.Value <<= ::rtl::OUString::createFromAscii( "org.openoffice.Office.Common/Security/Scripting" );
556 Sequence < Any > aargs( 1 );
557 aargs[ 0 ] <<= configPath;
558 Reference< XInterface > xInterface = m_xConfigProvFactory->createInstanceWithArguments( s_configUpdate,
559 aargs );
560 validateXRef( xInterface,
561 "ScriptSecurityManager::addToSecurePaths: ScriptSecurityManager: cannot get ConfigurationUpdateAccess" );
562 Reference < container::XNameReplace > xNameReplace( xInterface, UNO_QUERY );
563 validateXRef( xNameReplace,
564 "ScriptSecurityManager::addToSecurePaths: ScriptSecurityManager: cannot get XNameReplace" );
565 Reference < util::XChangesBatch > xChangesBatch( xInterface, UNO_QUERY );
566 validateXRef( xChangesBatch,
567 "ScriptSecurityManager::addToSecurePaths: cannot get XChangesBatch" );
569 OSL_TRACE( "--->ScriptSecurityManager::addToSecurePaths: after if stuff" );
570 Reference < beans::XPropertySet > xPropSet( xInterface, UNO_QUERY );
571 css::uno::Sequence< rtl::OUString > newSecureURL;
572 Any value;
573 OUString pathListPropName = OUSTR ( "SecureURL" );
574 value=xPropSet->getPropertyValue( pathListPropName );
575 if ( sal_False == ( value >>= newSecureURL ) )
577 throw RuntimeException(
578 OUSTR( "ScriptSecurityManager::addToSecurePaths: can't get SecureURL setting" ),
579 Reference< XInterface > () );
583 sal_Int32 length = newSecureURL.getLength();
584 newSecureURL.realloc( length + 1 );
585 newSecureURL[ length ] = path;
586 Any aNewSecureURL;
587 aNewSecureURL <<= newSecureURL;
588 xNameReplace->replaceByName( pathListPropName, aNewSecureURL );
589 xChangesBatch->commitChanges();
590 m_secureURL = newSecureURL;
592 catch ( Exception & e )
594 OSL_TRACE( "Error updating secure paths: " );
595 throw RuntimeException(
596 OUSTR( "ScriptSecurityManager::addToSecurePaths: error updating SecureURL setting" ).concat( e.Message ),
597 Reference< XInterface > () );
601 //*************************************************************************
602 // ScriptSecurityManager Destructor
603 ScriptSecurityManager::~ScriptSecurityManager()
605 OSL_TRACE( "< ScriptSecurityManager dtor called >\n" );
608 } // Namespace