Update ooo320-m1
[ooovba.git] / stoc / source / security / file_policy.cxx
blob475734f356c76fcadb23f2ef8a2a82b42e73a7d5
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: file_policy.cxx,v $
10 * $Revision: 1.9 $
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_stoc.hxx"
34 #include <hash_map>
36 #include <osl/diagnose.h>
37 #include <osl/file.h>
38 #include <rtl/byteseq.hxx>
39 #include <rtl/string.hxx>
40 #include <rtl/ustrbuf.hxx>
42 #include <cppuhelper/access_control.hxx>
43 #include <cppuhelper/compbase2.hxx>
44 #include <cppuhelper/implementationentry.hxx>
46 #include <com/sun/star/lang/XServiceInfo.hpp>
47 #include <com/sun/star/security/XAccessController.hpp>
48 #include <com/sun/star/security/XPolicy.hpp>
49 #include <com/sun/star/security/AllPermission.hpp>
50 #include <com/sun/star/security/RuntimePermission.hpp>
51 #include <com/sun/star/io/FilePermission.hpp>
52 #include <com/sun/star/connection/SocketPermission.hpp>
54 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
55 #define SERVICE_NAME "com.sun.star.security.Policy"
56 #define IMPL_NAME "com.sun.star.security.comp.stoc.FilePolicy"
59 using namespace ::osl;
60 using namespace ::rtl;
61 using namespace ::cppu;
62 using namespace ::com::sun::star;
63 using namespace ::com::sun::star::uno;
65 extern ::rtl_StandardModuleCount g_moduleCount;
67 namespace stoc_sec
69 // static stuff initialized when loading lib
70 static OUString s_implName = OUSTR(IMPL_NAME);
71 static OUString s_serviceName = OUSTR(SERVICE_NAME);
73 static Sequence< OUString > s_serviceNames = Sequence< OUString >( &s_serviceName, 1 );
74 //##################################################################################################
76 //--------------------------------------------------------------------------------------------------
77 static inline void dispose( Reference< XInterface > const & x )
78 SAL_THROW( (RuntimeException) )
80 Reference< lang::XComponent > xComp( x, UNO_QUERY );
81 if (xComp.is())
83 xComp->dispose();
87 //##################################################################################################
89 struct MutexHolder
91 Mutex m_mutex;
93 typedef WeakComponentImplHelper2< security::XPolicy, lang::XServiceInfo > t_helper;
95 //==================================================================================================
96 class FilePolicy
97 : public MutexHolder
98 , public t_helper
100 Reference< XComponentContext > m_xComponentContext;
101 AccessControl m_ac;
103 Sequence< Any > m_defaultPermissions;
104 typedef std::hash_map< OUString, Sequence< Any >, OUStringHash > t_permissions;
105 t_permissions m_userPermissions;
106 bool m_init;
108 protected:
109 virtual void SAL_CALL disposing();
111 public:
112 FilePolicy( Reference< XComponentContext > const & xComponentContext )
113 SAL_THROW( () );
114 virtual ~FilePolicy()
115 SAL_THROW( () );
117 // XPolicy impl
118 virtual Sequence< Any > SAL_CALL getPermissions(
119 OUString const & userId )
120 throw (RuntimeException);
121 virtual Sequence< Any > SAL_CALL getDefaultPermissions()
122 throw (RuntimeException);
123 virtual void SAL_CALL refresh()
124 throw (RuntimeException);
126 // XServiceInfo impl
127 virtual OUString SAL_CALL getImplementationName()
128 throw (RuntimeException);
129 virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName )
130 throw (RuntimeException);
131 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
132 throw (RuntimeException);
134 //__________________________________________________________________________________________________
135 FilePolicy::FilePolicy( Reference< XComponentContext > const & xComponentContext )
136 SAL_THROW( () )
137 : t_helper( m_mutex )
138 , m_xComponentContext( xComponentContext )
139 , m_ac( xComponentContext )
140 , m_init( false )
142 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
144 //__________________________________________________________________________________________________
145 FilePolicy::~FilePolicy()
146 SAL_THROW( () )
148 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
150 //__________________________________________________________________________________________________
151 void FilePolicy::disposing()
153 m_userPermissions.clear();
154 m_defaultPermissions = Sequence< Any >();
155 m_xComponentContext.clear();
158 //__________________________________________________________________________________________________
159 Sequence< Any > FilePolicy::getPermissions(
160 OUString const & userId )
161 throw (RuntimeException)
163 if (! m_init)
165 refresh();
166 m_init = true;
169 MutexGuard guard( m_mutex );
170 t_permissions::iterator iFind( m_userPermissions.find( userId ) );
171 if (m_userPermissions.end() == iFind)
173 return Sequence< Any >();
175 else
177 return iFind->second;
180 //__________________________________________________________________________________________________
181 Sequence< Any > FilePolicy::getDefaultPermissions()
182 throw (RuntimeException)
184 if (! m_init)
186 refresh();
187 m_init = true;
190 MutexGuard guard( m_mutex );
191 return m_defaultPermissions;
194 //==================================================================================================
195 class PolicyReader
197 OUString m_fileName;
198 oslFileHandle m_file;
200 sal_Int32 m_linepos;
201 ByteSequence m_line;
202 sal_Int32 m_pos;
203 sal_Unicode m_back;
205 sal_Unicode get()
206 SAL_THROW( (RuntimeException) );
207 inline void back( sal_Unicode c ) SAL_THROW( () )
208 { m_back = c; }
210 inline bool isWhiteSpace( sal_Unicode c ) SAL_THROW( () )
211 { return (' ' == c || '\t' == c || '\n' == c || '\r' == c); }
212 void skipWhiteSpace()
213 SAL_THROW( (RuntimeException) );
215 inline bool isCharToken( sal_Unicode c ) SAL_THROW( () )
216 { return (';' == c || ',' == c || '{' == c || '}' == c); }
218 public:
219 PolicyReader( OUString const & file, AccessControl & ac )
220 SAL_THROW( (RuntimeException) );
221 ~PolicyReader()
222 SAL_THROW( () );
224 void error( OUString const & msg )
225 SAL_THROW( (RuntimeException) );
227 OUString getToken()
228 SAL_THROW( (RuntimeException) );
229 OUString assureToken()
230 SAL_THROW( (RuntimeException) );
231 OUString getQuotedToken()
232 SAL_THROW( (RuntimeException) );
233 OUString assureQuotedToken()
234 SAL_THROW( (RuntimeException) );
235 void assureToken( sal_Unicode token )
236 SAL_THROW( (RuntimeException) );
238 //__________________________________________________________________________________________________
239 void PolicyReader::assureToken( sal_Unicode token )
240 SAL_THROW( (RuntimeException) )
242 skipWhiteSpace();
243 sal_Unicode c = get();
244 if (c == token)
245 return;
246 OUStringBuffer buf( 16 );
247 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("expected >") );
248 buf.append( c );
249 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("<!") );
250 error( buf.makeStringAndClear() );
252 //__________________________________________________________________________________________________
253 OUString PolicyReader::assureQuotedToken()
254 SAL_THROW( (RuntimeException) )
256 OUString token( getQuotedToken() );
257 if (! token.getLength())
258 error( OUSTR("unexpected end of file!") );
259 return token;
261 //__________________________________________________________________________________________________
262 OUString PolicyReader::getQuotedToken()
263 SAL_THROW( (RuntimeException) )
265 skipWhiteSpace();
266 OUStringBuffer buf( 32 );
267 sal_Unicode c = get();
268 if ('\"' != c)
269 error( OUSTR("expected quoting >\"< character!") );
270 c = get();
271 while ('\0' != c && '\"' != c)
273 buf.append( c );
274 c = get();
276 return buf.makeStringAndClear();
278 //__________________________________________________________________________________________________
279 OUString PolicyReader::assureToken()
280 SAL_THROW( (RuntimeException) )
282 OUString token( getToken() );
283 if (! token.getLength())
284 error( OUSTR("unexpected end of file!") );
285 return token;
287 //__________________________________________________________________________________________________
288 OUString PolicyReader::getToken()
289 SAL_THROW( (RuntimeException) )
291 skipWhiteSpace();
292 sal_Unicode c = get();
293 if (isCharToken( c ))
294 return OUString( &c, 1 );
295 OUStringBuffer buf( 32 );
296 while ('\0' != c && !isCharToken( c ) && !isWhiteSpace( c ))
298 buf.append( c );
299 c = get();
301 back( c );
302 return buf.makeStringAndClear();
304 //__________________________________________________________________________________________________
305 void PolicyReader::skipWhiteSpace()
306 SAL_THROW( (RuntimeException) )
308 sal_Unicode c;
311 c = get();
313 while (isWhiteSpace( c )); // seeking next non-whitespace char
315 if ('/' == c) // C/C++ like comment
317 c = get();
318 if ('/' == c) // C++ like comment
322 c = get();
324 while ('\n' != c && '\0' != c); // seek eol/eof
325 skipWhiteSpace(); // cont skip on next line
327 else if ('*' == c) // C like comment
329 bool fini = true;
332 c = get();
333 if ('*' == c)
335 c = get();
336 fini = ('/' == c || '\0' == c);
338 else
340 fini = ('\0' == c);
343 while (! fini);
344 skipWhiteSpace(); // cont skip on next line
346 else
348 error( OUSTR("expected C/C++ like comment!") );
351 else if ('#' == c) // script like comment
355 c = get();
357 while ('\n' != c && '\0' != c); // seek eol/eof
358 skipWhiteSpace(); // cont skip on next line
361 else // is token char
363 back( c );
366 //__________________________________________________________________________________________________
367 sal_Unicode PolicyReader::get()
368 SAL_THROW( (RuntimeException) )
370 if ('\0' != m_back) // one char push back possible
372 sal_Unicode c = m_back;
373 m_back = '\0';
374 return c;
376 else if (m_pos == m_line.getLength()) // provide newline as whitespace
378 ++m_pos;
379 return '\n';
381 else if (m_pos > m_line.getLength()) // read new line
383 sal_Bool eof;
384 oslFileError rc = ::osl_isEndOfFile( m_file, &eof );
385 if (osl_File_E_None != rc)
386 error( OUSTR("checking eof failed!") );
387 if (eof)
388 return '\0';
390 rc = ::osl_readLine( m_file, reinterpret_cast< sal_Sequence ** >( &m_line ) );
391 if (osl_File_E_None != rc)
392 error( OUSTR("read line failed!") );
393 ++m_linepos;
394 if (! m_line.getLength()) // empty line read
396 m_pos = 1; // read new line next time
397 return '\n';
399 m_pos = 0;
401 return (m_line.getConstArray()[ m_pos++ ]);
403 //__________________________________________________________________________________________________
404 void PolicyReader::error( OUString const & msg )
405 SAL_THROW( (RuntimeException) )
407 OUStringBuffer buf( 32 );
408 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("error processing file \"") );
409 buf.append( m_fileName );
410 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" [line ") );
411 buf.append( m_linepos );
412 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", column ") );
413 buf.append( m_pos );
414 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
415 buf.append( msg );
416 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
418 //__________________________________________________________________________________________________
419 PolicyReader::PolicyReader( OUString const & fileName, AccessControl & ac )
420 SAL_THROW( (RuntimeException) )
421 : m_fileName( fileName )
422 , m_linepos( 0 )
423 , m_pos( 1 ) // force readline
424 , m_back( '\0' )
426 ac.checkFilePermission( m_fileName, OUSTR("read") );
427 if (osl_File_E_None != ::osl_openFile( m_fileName.pData, &m_file, osl_File_OpenFlag_Read ))
429 OUStringBuffer buf( 32 );
430 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot open file \"") );
431 buf.append( m_fileName );
432 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
433 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
436 //__________________________________________________________________________________________________
437 PolicyReader::~PolicyReader()
438 SAL_THROW( () )
440 if ( ::osl_closeFile( m_file ) != osl_File_E_None ) {
441 OSL_ASSERT( false );
445 static OUString s_grant = OUSTR("grant");
446 static OUString s_user = OUSTR("user");
447 static OUString s_permission = OUSTR("permission");
448 static OUString s_openBrace = OUSTR("{");
449 static OUString s_closingBrace = OUSTR("}");
450 static OUString s_semi = OUSTR(";");
452 static OUString s_filePermission = OUSTR("com.sun.star.io.FilePermission");
453 static OUString s_socketPermission = OUSTR("com.sun.star.connection.SocketPermission");
454 static OUString s_runtimePermission = OUSTR("com.sun.star.security.RuntimePermission");
455 static OUString s_allPermission = OUSTR("com.sun.star.security.AllPermission");
457 //__________________________________________________________________________________________________
458 void FilePolicy::refresh()
459 throw (RuntimeException)
461 // read out file
462 OUString fileName;
463 m_xComponentContext->getValueByName(
464 OUSTR("/implementations/" IMPL_NAME "/file-name") ) >>= fileName;
465 if (! fileName.getLength())
467 throw RuntimeException(
468 OUSTR("name of policy file unknown!"),
469 (OWeakObject *)this );
472 PolicyReader reader( fileName, m_ac );
474 // fill these two
475 Sequence< Any > defaultPermissions;
476 t_permissions userPermissions;
478 OUString token( reader.getToken() );
479 while (token.getLength())
481 if (! token.equals( s_grant ))
482 reader.error( OUSTR("expected >grant< token!") );
483 OUString userId;
484 token = reader.assureToken();
485 if (token.equals( s_user )) // next token is user-id
487 userId = reader.assureQuotedToken();
488 token = reader.assureToken();
490 if (! token.equals( s_openBrace ))
491 reader.error( OUSTR("expected opening brace >{<!") );
492 token = reader.assureToken();
493 // permissions list
494 while (! token.equals( s_closingBrace ))
496 if (! token.equals( s_permission ))
497 reader.error( OUSTR("expected >permission< or closing brace >}<!") );
499 token = reader.assureToken(); // permission type
500 Any perm;
501 if (token.equals( s_filePermission )) // FilePermission
503 OUString url( reader.assureQuotedToken() );
504 reader.assureToken( ',' );
505 OUString actions( reader.assureQuotedToken() );
506 perm <<= io::FilePermission( url, actions );
508 else if (token.equals( s_socketPermission )) // SocketPermission
510 OUString host( reader.assureQuotedToken() );
511 reader.assureToken( ',' );
512 OUString actions( reader.assureQuotedToken() );
513 perm <<= connection::SocketPermission( host, actions );
515 else if (token.equals( s_runtimePermission )) // RuntimePermission
517 OUString name( reader.assureQuotedToken() );
518 perm <<= security::RuntimePermission( name );
520 else if (token.equals( s_allPermission )) // AllPermission
522 perm <<= security::AllPermission();
524 else
526 reader.error( OUSTR("expected permission type!") );
529 reader.assureToken( ';' );
531 // insert
532 if (userId.getLength())
534 Sequence< Any > perms( userPermissions[ userId ] );
535 sal_Int32 len = perms.getLength();
536 perms.realloc( len +1 );
537 perms[ len ] = perm;
538 userPermissions[ userId ] = perms;
540 else
542 sal_Int32 len = defaultPermissions.getLength();
543 defaultPermissions.realloc( len +1 );
544 defaultPermissions[ len ] = perm;
547 token = reader.assureToken(); // next permissions token
550 reader.assureToken( ';' ); // semi
551 token = reader.getToken(); // next grant token
554 // assign new ones
555 MutexGuard guard( m_mutex );
556 m_defaultPermissions = defaultPermissions;
557 m_userPermissions = userPermissions;
560 //__________________________________________________________________________________________________
561 OUString FilePolicy::getImplementationName()
562 throw (RuntimeException)
564 return s_implName;
566 //__________________________________________________________________________________________________
567 sal_Bool FilePolicy::supportsService( OUString const & serviceName )
568 throw (RuntimeException)
570 OUString const * pNames = s_serviceNames.getConstArray();
571 for ( sal_Int32 nPos = s_serviceNames.getLength(); nPos--; )
573 if (serviceName.equals( pNames[ nPos ] ))
575 return sal_True;
578 return sal_False;
580 //__________________________________________________________________________________________________
581 Sequence< OUString > FilePolicy::getSupportedServiceNames()
582 throw (RuntimeException)
584 return s_serviceNames;
587 //##################################################################################################
588 namespace stoc_bootstrap
590 //--------------------------------------------------------------------------------------------------
591 Reference< XInterface > SAL_CALL filepolicy_create(
592 Reference< XComponentContext > const & xComponentContext )
593 SAL_THROW( (Exception) )
595 return (OWeakObject *)new stoc_sec::FilePolicy( xComponentContext );
597 //--------------------------------------------------------------------------------------------------
598 Sequence< OUString > filepolicy_getSupportedServiceNames() SAL_THROW( () )
600 return stoc_sec::s_serviceNames;
602 //--------------------------------------------------------------------------------------------------
603 OUString filepolicy_getImplementationName() SAL_THROW( () )
605 return stoc_sec::s_implName;