summaryrefslogtreecommitdiff
path: root/stoc/source/security/permissions.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'stoc/source/security/permissions.cxx')
-rw-r--r--stoc/source/security/permissions.cxx669
1 files changed, 669 insertions, 0 deletions
diff --git a/stoc/source/security/permissions.cxx b/stoc/source/security/permissions.cxx
new file mode 100644
index 000000000000..2d8a655dade6
--- /dev/null
+++ b/stoc/source/security/permissions.cxx
@@ -0,0 +1,669 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: permissions.cxx,v $
+ * $Revision: 1.11.16.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include <vector>
+
+#include <osl/process.h>
+#include <osl/socket.hxx>
+#include <osl/mutex.hxx>
+
+#include <rtl/string.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <com/sun/star/security/RuntimePermission.hpp>
+#include <com/sun/star/security/AllPermission.hpp>
+#include <com/sun/star/io/FilePermission.hpp>
+#include <com/sun/star/connection/SocketPermission.hpp>
+#include <com/sun/star/security/AccessControlException.hpp>
+
+#include "permissions.h"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+namespace stoc_sec
+{
+
+//--------------------------------------------------------------------------------------------------
+static inline sal_Int32 makeMask(
+ OUString const & items, char const * const * strings ) SAL_THROW( () )
+{
+ sal_Int32 mask = 0;
+
+ sal_Int32 n = 0;
+ do
+ {
+ OUString item( items.getToken( 0, ',', n ).trim() );
+ if (! item.getLength())
+ continue;
+ sal_Int32 nPos = 0;
+ while (strings[ nPos ])
+ {
+ if (item.equalsAscii( strings[ nPos ] ))
+ {
+ mask |= (0x80000000 >> nPos);
+ break;
+ }
+ ++nPos;
+ }
+#if OSL_DEBUG_LEVEL > 0
+ if (! strings[ nPos ])
+ {
+ OUStringBuffer buf( 48 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("### ignoring unknown socket action: ") );
+ buf.append( item );
+ ::rtl::OString str( ::rtl::OUStringToOString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( str.getStr() );
+ }
+#endif
+ }
+ while (n >= 0); // all items
+ return mask;
+}
+//--------------------------------------------------------------------------------------------------
+static inline OUString makeStrings(
+ sal_Int32 mask, char const * const * strings ) SAL_THROW( () )
+{
+ OUStringBuffer buf( 48 );
+ while (mask)
+ {
+ if (0x80000000 & mask)
+ {
+ buf.appendAscii( *strings );
+ if (mask << 1) // more items following
+ buf.append( (sal_Unicode)',' );
+ }
+ mask = (mask << 1);
+ ++strings;
+ }
+ return buf.makeStringAndClear();
+}
+
+//##################################################################################################
+
+//==================================================================================================
+class SocketPermission : public Permission
+{
+ static char const * s_actions [];
+ sal_Int32 m_actions;
+
+ OUString m_host;
+ sal_Int32 m_lowerPort;
+ sal_Int32 m_upperPort;
+ mutable OUString m_ip;
+ mutable bool m_resolveErr;
+ mutable bool m_resolvedHost;
+ bool m_wildCardHost;
+
+ inline bool resolveHost() const SAL_THROW( () );
+
+public:
+ SocketPermission(
+ connection::SocketPermission const & perm,
+ ::rtl::Reference< Permission > const & next = ::rtl::Reference< Permission >() )
+ SAL_THROW( () );
+ virtual bool implies( Permission const & perm ) const SAL_THROW( () );
+ virtual OUString toString() const SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+char const * SocketPermission::s_actions [] = { "accept", "connect", "listen", "resolve", 0 };
+//__________________________________________________________________________________________________
+SocketPermission::SocketPermission(
+ connection::SocketPermission const & perm,
+ ::rtl::Reference< Permission > const & next )
+ SAL_THROW( () )
+ : Permission( SOCKET, next )
+ , m_actions( makeMask( perm.Actions, s_actions ) )
+ , m_host( perm.Host )
+ , m_lowerPort( 0 )
+ , m_upperPort( 65535 )
+ , m_resolveErr( false )
+ , m_resolvedHost( false )
+ , m_wildCardHost( perm.Host.getLength() && '*' == perm.Host.pData->buffer[ 0 ] )
+{
+ if (0xe0000000 & m_actions) // if any (except resolve) is given => resolve implied
+ m_actions |= 0x10000000;
+
+ // separate host from portrange
+ sal_Int32 colon = m_host.indexOf( ':' );
+ if (colon >= 0) // port [range] given
+ {
+ sal_Int32 minus = m_host.indexOf( '-', colon +1 );
+ if (minus < 0)
+ {
+ m_lowerPort = m_upperPort = m_host.copy( colon +1 ).toInt32();
+ }
+ else if (minus == (colon +1)) // -N
+ {
+ m_upperPort = m_host.copy( minus +1 ).toInt32();
+ }
+ else if (minus == (m_host.getLength() -1)) // N-
+ {
+ m_lowerPort = m_host.copy( colon +1, m_host.getLength() -1 -colon -1 ).toInt32();
+ }
+ else // A-B
+ {
+ m_lowerPort = m_host.copy( colon +1, minus - colon -1 ).toInt32();
+ m_upperPort = m_host.copy( minus +1, m_host.getLength() -minus -1 ).toInt32();
+ }
+ m_host = m_host.copy( 0, colon );
+ }
+}
+//__________________________________________________________________________________________________
+inline bool SocketPermission::resolveHost() const SAL_THROW( () )
+{
+ if (m_resolveErr)
+ return false;
+
+ if (! m_resolvedHost)
+ {
+ // dns lookup
+ SocketAddr addr;
+ SocketAddr::resolveHostname( m_host, addr );
+ OUString ip;
+ m_resolveErr = (::osl_Socket_Ok != ::osl_getDottedInetAddrOfSocketAddr(
+ addr.getHandle(), &ip.pData ));
+ if (m_resolveErr)
+ return false;
+
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! m_resolvedHost)
+ {
+ m_ip = ip;
+ m_resolvedHost = true;
+ }
+ }
+ return m_resolvedHost;
+}
+//__________________________________________________________________________________________________
+bool SocketPermission::implies( Permission const & perm ) const SAL_THROW( () )
+{
+ // check type
+ if (SOCKET != perm.m_type)
+ return false;
+ SocketPermission const & demanded = static_cast< SocketPermission const & >( perm );
+
+ // check actions
+ if ((m_actions & demanded.m_actions) != demanded.m_actions)
+ return false;
+
+ // check ports
+ if (demanded.m_lowerPort < m_lowerPort)
+ return false;
+ if (demanded.m_upperPort > m_upperPort)
+ return false;
+
+ // quick check host (DNS names: RFC 1034/1035)
+ if (m_host.equalsIgnoreAsciiCase( demanded.m_host ))
+ return true;
+ // check for host wildcards
+ if (m_wildCardHost)
+ {
+ OUString const & demanded_host = demanded.m_host;
+ if (demanded_host.getLength() <= m_host.getLength())
+ return false;
+ sal_Int32 len = m_host.getLength() -1; // skip star
+ return (0 == ::rtl_ustr_compareIgnoreAsciiCase_WithLength(
+ demanded_host.getStr() + demanded_host.getLength() - len, len,
+ m_host.pData->buffer + 1, len ));
+ }
+ if (demanded.m_wildCardHost)
+ return false;
+
+ // compare IP addresses
+ if (! resolveHost())
+ return false;
+ if (! demanded.resolveHost())
+ return false;
+ return (sal_False != m_ip.equals( demanded.m_ip ));
+}
+//__________________________________________________________________________________________________
+OUString SocketPermission::toString() const SAL_THROW( () )
+{
+ OUStringBuffer buf( 48 );
+ // host
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.connection.SocketPermission (host=\"") );
+ buf.append( m_host );
+ if (m_resolvedHost)
+ {
+ buf.append( (sal_Unicode)'[' );
+ buf.append( m_ip );
+ buf.append( (sal_Unicode)']' );
+ }
+ // port
+ if (0 != m_lowerPort || 65535 != m_upperPort)
+ {
+ buf.append( (sal_Unicode)':' );
+ if (m_lowerPort > 0)
+ buf.append( m_lowerPort );
+ if (m_upperPort > m_lowerPort)
+ {
+ buf.append( (sal_Unicode)'-' );
+ if (m_upperPort < 65535)
+ buf.append( m_upperPort );
+ }
+ }
+ // actions
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\", actions=\"") );
+ buf.append( makeStrings( m_actions, s_actions ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\")") );
+ return buf.makeStringAndClear();
+}
+
+//##################################################################################################
+
+//==================================================================================================
+class FilePermission : public Permission
+{
+ static char const * s_actions [];
+ sal_Int32 m_actions;
+
+ OUString m_url;
+ bool m_allFiles;
+
+public:
+ FilePermission(
+ io::FilePermission const & perm,
+ ::rtl::Reference< Permission > const & next = ::rtl::Reference< Permission >() )
+ SAL_THROW( () );
+ virtual bool implies( Permission const & perm ) const SAL_THROW( () );
+ virtual OUString toString() const SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+char const * FilePermission::s_actions [] = { "read", "write", "execute", "delete", 0 };
+//--------------------------------------------------------------------------------------------------
+static OUString const & getWorkingDir() SAL_THROW( () )
+{
+ static OUString * s_workingDir = 0;
+ if (! s_workingDir)
+ {
+ OUString workingDir;
+ ::osl_getProcessWorkingDir( &workingDir.pData );
+
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_workingDir)
+ {
+ static OUString s_dir( workingDir );
+ s_workingDir = &s_dir;
+ }
+ }
+ return *s_workingDir;
+}
+//__________________________________________________________________________________________________
+FilePermission::FilePermission(
+ io::FilePermission const & perm,
+ ::rtl::Reference< Permission > const & next )
+ SAL_THROW( () )
+ : Permission( FILE, next )
+ , m_actions( makeMask( perm.Actions, s_actions ) )
+ , m_url( perm.URL )
+ , m_allFiles( sal_False != perm.URL.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("<<ALL FILES>>")) )
+{
+ if (! m_allFiles)
+ {
+ if (m_url.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("*") ))
+ {
+ OUStringBuffer buf( 64 );
+ buf.append( getWorkingDir() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/*") );
+ m_url = buf.makeStringAndClear();
+ }
+ else if (m_url.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("-") ))
+ {
+ OUStringBuffer buf( 64 );
+ buf.append( getWorkingDir() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/-") );
+ m_url = buf.makeStringAndClear();
+ }
+ else if (0 != m_url.compareToAscii( RTL_CONSTASCII_STRINGPARAM("file:///") ))
+ {
+ // relative path
+ OUString out;
+ oslFileError rc = ::osl_getAbsoluteFileURL(
+ getWorkingDir().pData, perm.URL.pData, &out.pData );
+ m_url = (osl_File_E_None == rc ? out : perm.URL); // fallback
+ }
+#ifdef SAL_W32
+ // correct win drive letters
+ if (9 < m_url.getLength() && '|' == m_url[ 9 ]) // file:///X|
+ {
+ static OUString s_colon = OUSTR(":");
+ // common case in API is a ':' (sal), so convert '|' to ':'
+ m_url = m_url.replaceAt( 9, 1, s_colon );
+ }
+#endif
+ }
+}
+//__________________________________________________________________________________________________
+bool FilePermission::implies( Permission const & perm ) const SAL_THROW( () )
+{
+ // check type
+ if (FILE != perm.m_type)
+ return false;
+ FilePermission const & demanded = static_cast< FilePermission const & >( perm );
+
+ // check actions
+ if ((m_actions & demanded.m_actions) != demanded.m_actions)
+ return false;
+
+ // check url
+ if (m_allFiles)
+ return true;
+ if (demanded.m_allFiles)
+ return false;
+
+#ifdef SAL_W32
+ if (m_url.equalsIgnoreAsciiCase( demanded.m_url ))
+ return true;
+#else
+ if (m_url.equals( demanded.m_url ))
+ return true;
+#endif
+ if (m_url.getLength() > demanded.m_url.getLength())
+ return false;
+ // check /- wildcard: all files and recursive in that path
+ if (1 < m_url.getLength() &&
+ 0 == ::rtl_ustr_ascii_compare_WithLength( m_url.getStr() + m_url.getLength() - 2, 2, "/-" ))
+ {
+ // demanded url must start with granted path (including path trailing path sep)
+ sal_Int32 len = m_url.getLength() -1;
+#ifdef SAL_W32
+ return (0 == ::rtl_ustr_compareIgnoreAsciiCase_WithLength(
+ demanded.m_url.pData->buffer, len, m_url.pData->buffer, len ));
+#else
+ return (0 == ::rtl_ustr_reverseCompare_WithLength(
+ demanded.m_url.pData->buffer, len, m_url.pData->buffer, len ));
+#endif
+ }
+ // check /* wildcard: all files in that path (not recursive!)
+ if (1 < m_url.getLength() &&
+ 0 == ::rtl_ustr_ascii_compare_WithLength( m_url.getStr() + m_url.getLength() - 2, 2, "/*" ))
+ {
+ // demanded url must start with granted path (including path trailing path sep)
+ sal_Int32 len = m_url.getLength() -1;
+#ifdef SAL_W32
+ return ((0 == ::rtl_ustr_compareIgnoreAsciiCase_WithLength(
+ demanded.m_url.pData->buffer, len, m_url.pData->buffer, len )) &&
+ (0 > demanded.m_url.indexOf( '/', len ))); // in addition, no deeper pathes
+#else
+ return ((0 == ::rtl_ustr_reverseCompare_WithLength(
+ demanded.m_url.pData->buffer, len, m_url.pData->buffer, len )) &&
+ (0 > demanded.m_url.indexOf( '/', len ))); // in addition, no deeper pathes
+#endif
+ }
+ return false;
+}
+//__________________________________________________________________________________________________
+OUString FilePermission::toString() const SAL_THROW( () )
+{
+ OUStringBuffer buf( 48 );
+ // url
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("com.sun.star.io.FilePermission (url=\"") );
+ buf.append( m_url );
+ // actions
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\", actions=\"") );
+ buf.append( makeStrings( m_actions, s_actions ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\")") );
+ return buf.makeStringAndClear();
+}
+
+//##################################################################################################
+
+//==================================================================================================
+class RuntimePermission : public Permission
+{
+ OUString m_name;
+
+public:
+ inline RuntimePermission(
+ security::RuntimePermission const & perm,
+ ::rtl::Reference< Permission > const & next = ::rtl::Reference< Permission >() )
+ SAL_THROW( () )
+ : Permission( RUNTIME, next )
+ , m_name( perm.Name )
+ {}
+ virtual bool implies( Permission const & perm ) const SAL_THROW( () );
+ virtual OUString toString() const SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+bool RuntimePermission::implies( Permission const & perm ) const SAL_THROW( () )
+{
+ // check type
+ if (RUNTIME != perm.m_type)
+ return false;
+ RuntimePermission const & demanded = static_cast< RuntimePermission const & >( perm );
+
+ // check name
+ return (sal_False != m_name.equals( demanded.m_name ));
+}
+//__________________________________________________________________________________________________
+OUString RuntimePermission::toString() const SAL_THROW( () )
+{
+ OUStringBuffer buf( 48 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.security.RuntimePermission (name=\"") );
+ buf.append( m_name );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\")") );
+ return buf.makeStringAndClear();
+}
+
+//##################################################################################################
+
+//__________________________________________________________________________________________________
+bool AllPermission::implies( Permission const & ) const SAL_THROW( () )
+{
+ return true;
+}
+//__________________________________________________________________________________________________
+OUString AllPermission::toString() const SAL_THROW( () )
+{
+ return OUSTR("com.sun.star.security.AllPermission");
+}
+
+//##################################################################################################
+
+//__________________________________________________________________________________________________
+PermissionCollection::PermissionCollection(
+ Sequence< Any > const & permissions, PermissionCollection const & addition )
+ SAL_THROW( (RuntimeException) )
+ : m_head( addition.m_head )
+{
+ Any const * perms = permissions.getConstArray();
+ for ( sal_Int32 nPos = permissions.getLength(); nPos--; )
+ {
+ Any const & perm = perms[ nPos ];
+ Type const & perm_type = perm.getValueType();
+
+ // supported permission types
+ if (perm_type.equals( ::getCppuType( (io::FilePermission const *)0 ) ))
+ {
+ m_head = new FilePermission(
+ *reinterpret_cast< io::FilePermission const * >( perm.pData ), m_head );
+ }
+ else if (perm_type.equals( ::getCppuType( (connection::SocketPermission const *)0 ) ))
+ {
+ m_head = new SocketPermission(
+ *reinterpret_cast< connection::SocketPermission const * >( perm.pData ), m_head );
+ }
+ else if (perm_type.equals( ::getCppuType( (security::RuntimePermission const *)0 ) ))
+ {
+ m_head = new RuntimePermission(
+ *reinterpret_cast< security::RuntimePermission const * >( perm.pData ), m_head );
+ }
+ else if (perm_type.equals( ::getCppuType( (security::AllPermission const *)0 ) ))
+ {
+ m_head = new AllPermission( m_head );
+ }
+ else
+ {
+ OUStringBuffer buf( 48 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "checking for unsupported permission type: ") );
+ buf.append( perm_type.getTypeName() );
+ throw RuntimeException(
+ buf.makeStringAndClear(), Reference< XInterface >() );
+ }
+ }
+}
+#ifdef __DIAGNOSE
+//__________________________________________________________________________________________________
+Sequence< OUString > PermissionCollection::toStrings() const SAL_THROW( () )
+{
+ vector< OUString > strings;
+ strings.reserve( 8 );
+ for ( Permission * perm = m_head.get(); perm; perm = perm->m_next.get() )
+ {
+ strings.push_back( perm->toString() );
+ }
+ return Sequence< OUString >(
+ strings.empty() ? 0 : &strings[ 0 ], strings.size() );
+}
+#endif
+//__________________________________________________________________________________________________
+inline static bool __implies(
+ ::rtl::Reference< Permission > const & head, Permission const & demanded ) SAL_THROW( () )
+{
+ for ( Permission * perm = head.get(); perm; perm = perm->m_next.get() )
+ {
+ if (perm->implies( demanded ))
+ return true;
+ }
+ return false;
+}
+
+#ifdef __DIAGNOSE
+//--------------------------------------------------------------------------------------------------
+static void demanded_diag(
+ Permission const & perm )
+ SAL_THROW( () )
+{
+ OUStringBuffer buf( 48 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("demanding ") );
+ buf.append( perm.toString() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" => ok.") );
+ ::rtl::OString str(
+ ::rtl::OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( str.getStr() );
+}
+#endif
+//--------------------------------------------------------------------------------------------------
+static void throwAccessControlException(
+ Permission const & perm, Any const & demanded_perm )
+ SAL_THROW( (security::AccessControlException) )
+{
+ OUStringBuffer buf( 48 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("access denied: ") );
+ buf.append( perm.toString() );
+ throw security::AccessControlException(
+ buf.makeStringAndClear(), Reference< XInterface >(), demanded_perm );
+}
+//==================================================================================================
+void PermissionCollection::checkPermission( Any const & perm ) const
+ SAL_THROW( (RuntimeException) )
+{
+ Type const & demanded_type = perm.getValueType();
+
+ // supported permission types
+ // stack object of SimpleReferenceObject are ok, as long as they are not
+ // assigned to a ::rtl::Reference<> (=> delete this)
+ if (demanded_type.equals( ::getCppuType( (io::FilePermission const *)0 ) ))
+ {
+ FilePermission demanded(
+ *reinterpret_cast< io::FilePermission const * >( perm.pData ) );
+ if (__implies( m_head, demanded ))
+ {
+#ifdef __DIAGNOSE
+ demanded_diag( demanded );
+#endif
+ return;
+ }
+ throwAccessControlException( demanded, perm );
+ }
+ else if (demanded_type.equals( ::getCppuType( (connection::SocketPermission const *)0 ) ))
+ {
+ SocketPermission demanded(
+ *reinterpret_cast< connection::SocketPermission const * >( perm.pData ) );
+ if (__implies( m_head, demanded ))
+ {
+#ifdef __DIAGNOSE
+ demanded_diag( demanded );
+#endif
+ return;
+ }
+ throwAccessControlException( demanded, perm );
+ }
+ else if (demanded_type.equals( ::getCppuType( (security::RuntimePermission const *)0 ) ))
+ {
+ RuntimePermission demanded(
+ *reinterpret_cast< security::RuntimePermission const * >( perm.pData ) );
+ if (__implies( m_head, demanded ))
+ {
+#ifdef __DIAGNOSE
+ demanded_diag( demanded );
+#endif
+ return;
+ }
+ throwAccessControlException( demanded, perm );
+ }
+ else if (demanded_type.equals( ::getCppuType( (security::AllPermission const *)0 ) ))
+ {
+ AllPermission demanded;
+ if (__implies( m_head, demanded ))
+ {
+#ifdef __DIAGNOSE
+ demanded_diag( demanded );
+#endif
+ return;
+ }
+ throwAccessControlException( demanded, perm );
+ }
+ else
+ {
+ OUStringBuffer buf( 48 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("checking for unsupported permission type: ") );
+ buf.append( demanded_type.getTypeName() );
+ throw RuntimeException(
+ buf.makeStringAndClear(), Reference< XInterface >() );
+ }
+}
+
+}