1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: file_policy.cxx,v $
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"
36 #include <osl/diagnose.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
;
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
);
87 //##################################################################################################
93 typedef WeakComponentImplHelper2
< security::XPolicy
, lang::XServiceInfo
> t_helper
;
95 //==================================================================================================
100 Reference
< XComponentContext
> m_xComponentContext
;
103 Sequence
< Any
> m_defaultPermissions
;
104 typedef std::hash_map
< OUString
, Sequence
< Any
>, OUStringHash
> t_permissions
;
105 t_permissions m_userPermissions
;
109 virtual void SAL_CALL
disposing();
112 FilePolicy( Reference
< XComponentContext
> const & xComponentContext
)
114 virtual ~FilePolicy()
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
);
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
)
137 : t_helper( m_mutex
)
138 , m_xComponentContext( xComponentContext
)
139 , m_ac( xComponentContext
)
142 g_moduleCount
.modCnt
.acquire( &g_moduleCount
.modCnt
);
144 //__________________________________________________________________________________________________
145 FilePolicy::~FilePolicy()
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
)
169 MutexGuard
guard( m_mutex
);
170 t_permissions::iterator
iFind( m_userPermissions
.find( userId
) );
171 if (m_userPermissions
.end() == iFind
)
173 return Sequence
< Any
>();
177 return iFind
->second
;
180 //__________________________________________________________________________________________________
181 Sequence
< Any
> FilePolicy::getDefaultPermissions()
182 throw (RuntimeException
)
190 MutexGuard
guard( m_mutex
);
191 return m_defaultPermissions
;
194 //==================================================================================================
198 oslFileHandle m_file
;
206 SAL_THROW( (RuntimeException
) );
207 inline void back( sal_Unicode c
) SAL_THROW( () )
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
); }
219 PolicyReader( OUString
const & file
, AccessControl
& ac
)
220 SAL_THROW( (RuntimeException
) );
224 void error( OUString
const & msg
)
225 SAL_THROW( (RuntimeException
) );
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
) )
243 sal_Unicode c
= get();
246 OUStringBuffer
buf( 16 );
247 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("expected >") );
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!") );
261 //__________________________________________________________________________________________________
262 OUString
PolicyReader::getQuotedToken()
263 SAL_THROW( (RuntimeException
) )
266 OUStringBuffer
buf( 32 );
267 sal_Unicode c
= get();
269 error( OUSTR("expected quoting >\"< character!") );
271 while ('\0' != c
&& '\"' != c
)
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!") );
287 //__________________________________________________________________________________________________
288 OUString
PolicyReader::getToken()
289 SAL_THROW( (RuntimeException
) )
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
))
302 return buf
.makeStringAndClear();
304 //__________________________________________________________________________________________________
305 void PolicyReader::skipWhiteSpace()
306 SAL_THROW( (RuntimeException
) )
313 while (isWhiteSpace( c
)); // seeking next non-whitespace char
315 if ('/' == c
) // C/C++ like comment
318 if ('/' == c
) // C++ like comment
324 while ('\n' != c
&& '\0' != c
); // seek eol/eof
325 skipWhiteSpace(); // cont skip on next line
327 else if ('*' == c
) // C like comment
336 fini
= ('/' == c
|| '\0' == c
);
344 skipWhiteSpace(); // cont skip on next line
348 error( OUSTR("expected C/C++ like comment!") );
351 else if ('#' == c
) // script like comment
357 while ('\n' != c
&& '\0' != c
); // seek eol/eof
358 skipWhiteSpace(); // cont skip on next line
361 else // is token char
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
;
376 else if (m_pos
== m_line
.getLength()) // provide newline as whitespace
381 else if (m_pos
> m_line
.getLength()) // read new line
384 oslFileError rc
= ::osl_isEndOfFile( m_file
, &eof
);
385 if (osl_File_E_None
!= rc
)
386 error( OUSTR("checking eof failed!") );
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!") );
394 if (! m_line
.getLength()) // empty line read
396 m_pos
= 1; // read new line next time
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 ") );
414 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
416 throw RuntimeException( buf
.makeStringAndClear(), Reference
< XInterface
>() );
418 //__________________________________________________________________________________________________
419 PolicyReader::PolicyReader( OUString
const & fileName
, AccessControl
& ac
)
420 SAL_THROW( (RuntimeException
) )
421 : m_fileName( fileName
)
423 , m_pos( 1 ) // force readline
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()
440 if ( ::osl_closeFile( m_file
) != osl_File_E_None
) {
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
)
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
);
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!") );
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();
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
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();
526 reader
.error( OUSTR("expected permission type!") );
529 reader
.assureToken( ';' );
532 if (userId
.getLength())
534 Sequence
< Any
> perms( userPermissions
[ userId
] );
535 sal_Int32 len
= perms
.getLength();
536 perms
.realloc( len
+1 );
538 userPermissions
[ userId
] = perms
;
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
555 MutexGuard
guard( m_mutex
);
556 m_defaultPermissions
= defaultPermissions
;
557 m_userPermissions
= userPermissions
;
560 //__________________________________________________________________________________________________
561 OUString
FilePolicy::getImplementationName()
562 throw (RuntimeException
)
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
] ))
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
;