1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
24 #include <osl/diagnose.h>
25 #include <osl/socket.hxx>
26 #include <rtl/string.hxx>
27 #include <rtl/ustrbuf.hxx>
28 #include <uno/current_context.hxx>
30 #include <cppuhelper/implbase1.hxx>
31 #include <cppuhelper/bootstrap.hxx>
32 #include <cppuhelper/access_control.hxx>
34 #include <com/sun/star/lang/XComponent.hpp>
35 #include <com/sun/star/uno/XCurrentContext.hpp>
37 #include <com/sun/star/io/FilePermission.hpp>
39 #define USER_CREDS "access-control.user-credentials"
40 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
43 using namespace ::osl
;
44 using namespace ::rtl
;
45 using namespace ::cppu
;
46 using namespace ::com::sun::star
;
47 using namespace ::com::sun::star::uno
;
49 //--------------------------------------------------------------------------------------------------
50 static OUString
localhost( OUString
const & addition
) SAL_THROW(())
57 SocketAddr::resolveHostname( OUSTR("localhost"), addr
);
58 ::oslSocketResult rc
= ::osl_getDottedInetAddrOfSocketAddr( addr
.getHandle(), &ip
.pData
);
59 if (::osl_Socket_Ok
!= rc
)
60 fprintf(stdout
, "### cannot resolve localhost!" );
62 OUStringBuffer
buf( 48 );
64 buf
.append( addition
);
65 return buf
.makeStringAndClear();
68 //--------------------------------------------------------------------------------------------------
69 static inline void dispose( Reference
< XInterface
> const & x
)
70 SAL_THROW( (RuntimeException
) )
72 Reference
< lang::XComponent
> xComp( x
, UNO_QUERY
);
78 //==================================================================================================
79 class user_CurrentContext
80 : public ImplHelper1
< XCurrentContext
>
82 oslInterlockedCount m_refcount
;
84 Reference
< XCurrentContext
> m_xDelegate
;
88 inline user_CurrentContext(
89 Reference
< XCurrentContext
> const & xDelegate
,
90 OUString
const & userId
)
93 , m_xDelegate( xDelegate
)
94 , m_userId( makeAny( userId
) )
98 virtual void SAL_CALL
acquire()
100 virtual void SAL_CALL
release()
103 // XCurrentContext impl
104 virtual Any SAL_CALL
getValueByName( OUString
const & name
)
105 throw (RuntimeException
);
107 //__________________________________________________________________________________________________
108 void user_CurrentContext::acquire()
111 ::osl_atomic_increment( &m_refcount
);
113 //__________________________________________________________________________________________________
114 void user_CurrentContext::release()
117 if (! ::osl_atomic_decrement( &m_refcount
))
122 //__________________________________________________________________________________________________
123 Any
user_CurrentContext::getValueByName( OUString
const & name
)
124 throw (RuntimeException
)
126 if ( name
== USER_CREDS
".id" )
130 else if (m_xDelegate
.is())
132 return m_xDelegate
->getValueByName( name
);
140 // prepends line number
141 #define CHECK( check, negative_test ) \
147 bool thrown = true; \
153 catch (RuntimeException &) \
158 throw RuntimeException( \
159 OUSTR("expected RuntimeException upon check!"), Reference< XInterface >() ); \
167 catch (const RuntimeException & exc) \
169 OUStringBuffer buf( 64 ); \
170 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[line ") ); \
171 buf.append( (sal_Int32)__LINE__ ); \
172 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") ); \
173 buf.append( exc.Message ); \
174 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() ); \
181 permission com.sun.star.io.FilePermission "file:///usr/bin/ *", "read";
182 permission com.sun.star.io.FilePermission "file:///tmp/-", "read,write";
183 permission com.sun.star.io.FilePermission "file:///etc/profile", "read";
185 permission com.sun.star.security.RuntimePermission "DEF";
187 permission com.sun.star.connection.SocketPermission "127.0.0.1:-1023", "resolve, connect, listen";
188 permission com.sun.star.connection.SocketPermission "localhost:1024-", "accept, connect, listen, resolve,";
189 permission com.sun.star.connection.SocketPermission "*.sun.com:1024-", "resolve";
192 static void check_defaults_pos( AccessControl
& ac
, bool invert
= false )
195 CHECK( ac
.checkFilePermission( OUSTR("file:///usr/bin/bla"), OUSTR("read") ), invert
);
196 CHECK( ac
.checkFilePermission( OUSTR("file:///tmp/bla"), OUSTR("read,write") ), invert
);
197 CHECK( ac
.checkFilePermission( OUSTR("file:///tmp/path/path/bla"), OUSTR("write") ), invert
);
198 CHECK( ac
.checkFilePermission( OUSTR("file:///etc/profile"), OUSTR("read") ), invert
);
199 CHECK( ac
.checkRuntimePermission( OUSTR("DEF") ), invert
);
200 CHECK( ac
.checkSocketPermission( OUSTR("localhost:1024"), OUSTR("connect") ), invert
);
201 CHECK( ac
.checkSocketPermission( OUSTR("localhost:65535"), OUSTR("resolve") ), invert
);
202 CHECK( ac
.checkSocketPermission( localhost(OUSTR(":2048")), OUSTR("accept,listen") ), invert
);
203 CHECK( ac
.checkSocketPermission( localhost(OUSTR(":1024-")), OUSTR("accept,connect,listen,resolve") ), invert
);
204 CHECK( ac
.checkSocketPermission( OUSTR("localhost:-1023"), OUSTR("resolve,listen,connect") ), invert
);
205 CHECK( ac
.checkSocketPermission( OUSTR("jl-1036.germany.sun.com:1024-"), OUSTR("resolve") ), invert
);
207 static void check_defaults_neg( AccessControl
& ac
, bool invert
= false )
210 CHECK( ac
.checkFilePermission( OUSTR("file:///usr/tmp"), OUSTR("read") ), !invert
);
211 CHECK( ac
.checkFilePermission( OUSTR("file:///"), OUSTR("read") ), !invert
);
212 CHECK( ac
.checkFilePermission( OUSTR("file:///usr/bin"), OUSTR("read") ), !invert
);
213 CHECK( ac
.checkFilePermission( OUSTR("file:///usr/bin/bla"), OUSTR("write") ), !invert
);
214 CHECK( ac
.checkFilePermission( OUSTR("file:///usr/bin/bla"), OUSTR("execute") ), !invert
);
215 CHECK( ac
.checkFilePermission( OUSTR("file:///usr/bin/path/bla"), OUSTR("read") ), !invert
);
216 CHECK( ac
.checkFilePermission( OUSTR("file:///tmp"), OUSTR("read") ), !invert
);
217 CHECK( ac
.checkFilePermission( OUSTR("file:///tmp/"), OUSTR("read") ), !invert
);
218 CHECK( ac
.checkFilePermission( OUSTR("file:///tm"), OUSTR("read") ), !invert
);
219 CHECK( ac
.checkFilePermission( OUSTR("file:///etc/profile"), OUSTR("write") ), !invert
);
220 CHECK( ac
.checkFilePermission( OUSTR("file:///etc/profile/bla"), OUSTR("read") ), !invert
);
221 CHECK( ac
.checkFilePermission( OUSTR("file:///etc/blabla"), OUSTR("read,write,execute") ), !invert
);
222 CHECK( ac
.checkFilePermission( OUSTR("file:///home/root"), OUSTR("read,write,execute") ), !invert
);
223 CHECK( ac
.checkFilePermission( OUSTR("file:///root"), OUSTR("read,write,execute") ), !invert
);
224 CHECK( ac
.checkFilePermission( OUSTR("file:///root"), OUSTR("delete") ), !invert
);
225 CHECK( ac
.checkFilePermission( OUSTR("file:///root"), OUString() ), !invert
);
226 CHECK( ac
.checkRuntimePermission( OUSTR("ROOT") ), !invert
);
227 CHECK( ac
.checkSocketPermission( OUSTR("localhost:1023"), OUSTR("accept") ), !invert
);
228 CHECK( ac
.checkSocketPermission( OUSTR("localhost:123-"), OUSTR("accept") ), !invert
);
229 CHECK( ac
.checkSocketPermission( localhost(OUSTR(":-1023")), OUSTR("accept") ), !invert
);
230 CHECK( ac
.checkSocketPermission( OUSTR("localhost:-1023"), OUSTR("accept,resolve") ), !invert
);
231 CHECK( ac
.checkSocketPermission( OUSTR("sun.com:1024-"), OUSTR("resolve") ), !invert
);
237 permission com.sun.star.io.FilePermission "file:///home/dbo/-", "read,write";
238 permission com.sun.star.io.FilePermission "-", "read,write";
239 permission com.sun.star.io.FilePermission "file:///usr/local/dbo/ *", "read";
241 permission com.sun.star.security.RuntimePermission "DBO";
243 permission com.sun.star.connection.SocketPermission "dbo-1:1024-", "listen";
244 permission com.sun.star.connection.SocketPermission "dbo-11081:-1023", "resolve";
245 permission com.sun.star.connection.SocketPermission "dbo-11081:18", "listen";
246 permission com.sun.star.connection.SocketPermission "dbo-11081:20-24", "listen";
247 permission com.sun.star.connection.SocketPermission "dbo-11081", "connect";
250 static void check_dbo_pos( AccessControl
& ac
, bool invert
= false )
252 check_defaults_pos( ac
, invert
);
254 CHECK( ac
.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read") ), invert
);
255 CHECK( ac
.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("write") ), invert
);
256 CHECK( ac
.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read,write") ), invert
);
257 CHECK( ac
.checkFilePermission( OUSTR("file:///home/dbo/path/bla"), OUSTR("read,write") ), invert
);
258 CHECK( ac
.checkFilePermission( OUSTR("file:///home/dbo/path/path/bla"), OUSTR("read,write") ), invert
);
259 CHECK( ac
.checkFilePermission( OUSTR("file:///usr/local/dbo/*"), OUSTR("read") ), invert
);
260 CHECK( ac
.checkFilePermission( OUSTR("file:///usr/local/dbo/bla"), OUSTR("read") ), invert
);
261 CHECK( ac
.checkRuntimePermission( OUSTR("DBO") ), invert
);
262 CHECK( ac
.checkSocketPermission( OUSTR("dbo-1:1024-"), OUSTR("listen") ), invert
);
263 CHECK( ac
.checkSocketPermission( OUSTR("dbo-1:2048-3122"), OUSTR("listen") ), invert
);
264 CHECK( ac
.checkSocketPermission( OUSTR("dbo-1:2048-"), OUSTR("listen") ), invert
);
265 CHECK( ac
.checkSocketPermission( OUSTR("dbo-11081:-1023"), OUSTR("resolve") ), invert
);
266 CHECK( ac
.checkSocketPermission( OUSTR("dbo-11081:20-1023"), OUSTR("resolve") ), invert
);
267 CHECK( ac
.checkSocketPermission( OUSTR("dbo-11081:18"), OUSTR("listen") ), invert
);
268 CHECK( ac
.checkSocketPermission( OUSTR("dbo-11081:20-24"), OUSTR("listen") ), invert
);
269 CHECK( ac
.checkSocketPermission( OUSTR("dbo-11081:22"), OUSTR("listen") ), invert
);
270 CHECK( ac
.checkSocketPermission( OUSTR("dbo-11081"), OUSTR("connect") ), invert
);
271 CHECK( ac
.checkSocketPermission( OUSTR("dbo-11081:22"), OUSTR("connect") ), invert
);
273 static void check_dbo_neg( AccessControl
& ac
, bool invert
= false )
275 check_defaults_neg( ac
, invert
);
277 CHECK( ac
.checkFilePermission( OUSTR("file:///home/-"), OUSTR("read") ), !invert
);
278 CHECK( ac
.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("read") ), !invert
);
279 CHECK( ac
.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("write") ), !invert
);
280 CHECK( ac
.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("read,write") ), !invert
);
281 CHECK( ac
.checkFilePermission( OUSTR("file:///home/jbu/path/bla"), OUSTR("read") ), !invert
);
282 CHECK( ac
.checkFilePermission( OUSTR("file:///home/dbo/path/path/bla"), OUSTR("read,execute") ), !invert
);
283 CHECK( ac
.checkFilePermission( OUSTR("file:///usr/local/-"), OUSTR("read") ), !invert
);
284 CHECK( ac
.checkFilePermission( OUSTR("file:///usr/local/dbo/path/bla"), OUSTR("read") ), !invert
);
285 CHECK( ac
.checkFilePermission( OUSTR("file:///usr/local/dbo/path/path/bla"), OUSTR("read") ), !invert
);
286 CHECK( ac
.checkRuntimePermission( OUSTR("JBU") ), !invert
);
287 CHECK( ac
.checkSocketPermission( OUSTR("dbo-11081"), OUSTR("listen") ), !invert
);
288 CHECK( ac
.checkSocketPermission( OUSTR("dbo-11081:22"), OUSTR("accept") ), !invert
);
289 CHECK( ac
.checkSocketPermission( OUSTR("jbu-11096:22"), OUSTR("resolve") ), !invert
);
295 permission com.sun.star.io.FilePermission "file:///home/jbu/-", "read,write";
296 permission com.sun.star.io.FilePermission "*", "read,write";
298 permission com.sun.star.security.RuntimePermission "JBU";
300 permission com.sun.star.connection.SocketPermission "jbu-11096","resolve";
303 static void check_jbu_pos( AccessControl
& ac
, bool invert
= false )
305 check_defaults_pos( ac
, invert
);
307 CHECK( ac
.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("read") ), invert
);
308 CHECK( ac
.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("write") ), invert
);
309 CHECK( ac
.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("read,write") ), invert
);
310 CHECK( ac
.checkFilePermission( OUSTR("file:///home/jbu/path/bla"), OUSTR("read,write") ), invert
);
311 CHECK( ac
.checkFilePermission( OUSTR("file:///home/jbu/path/path/bla"), OUSTR("read,write") ), invert
);
312 CHECK( ac
.checkRuntimePermission( OUSTR("JBU") ), invert
);
313 CHECK( ac
.checkSocketPermission( OUSTR("jbu-11096"), OUSTR("resolve") ), invert
);
314 CHECK( ac
.checkSocketPermission( OUSTR("jbu-11096:20-24"), OUSTR("resolve") ), invert
);
315 CHECK( ac
.checkSocketPermission( OUSTR("dbo-11081.germany.sun.com:2048"), OUSTR("resolve") ), invert
);
317 static void check_jbu_neg( AccessControl
& ac
, bool invert
= false )
319 check_defaults_neg( ac
, invert
);
321 CHECK( ac
.checkFilePermission( OUSTR("file:///home/-"), OUSTR("read") ), !invert
);
322 CHECK( ac
.checkFilePermission( OUSTR("file:///home/dbo/path/bla"), OUSTR("read") ), !invert
);
323 CHECK( ac
.checkFilePermission( OUSTR("file:///home/dbo/path/path/bla"), OUSTR("read") ), !invert
);
324 CHECK( ac
.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read") ), !invert
);
325 CHECK( ac
.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("write") ), !invert
);
326 CHECK( ac
.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read,write") ), !invert
);
327 CHECK( ac
.checkFilePermission( OUSTR("file:///usr/local/-"), OUSTR("read") ), !invert
);
328 CHECK( ac
.checkFilePermission( OUSTR("file:///usr/local/dbo/bla"), OUSTR("read") ), !invert
);
329 CHECK( ac
.checkFilePermission( OUSTR("file:///usr/local/dbo/path/path/bla"), OUSTR("read") ), !invert
);
330 CHECK( ac
.checkRuntimePermission( OUSTR("DBO") ), !invert
);
331 CHECK( ac
.checkSocketPermission( OUSTR("jbu-11096:20-24"), OUSTR("accept") ), !invert
);
332 CHECK( ac
.checkSocketPermission( OUSTR("dbo-11081"), OUSTR("connect") ), !invert
);
333 CHECK( ac
.checkSocketPermission( OUSTR("dbo-11081.germany.sun.com"), OUSTR("connect") ), !invert
);
337 grant principal "root"
339 permission com.sun.star.security.AllPermission;
342 //==================================================================================================
343 static void check_root_pos( AccessControl
& ac
, bool invert
= false )
345 check_defaults_pos( ac
, invert
);
346 check_defaults_neg( ac
, !invert
);
347 check_dbo_pos( ac
, invert
);
348 check_dbo_neg( ac
, !invert
);
349 check_jbu_pos( ac
, invert
);
350 check_jbu_neg( ac
, !invert
);
351 // some more root positive
352 CHECK( ac
.checkFilePermission( OUSTR("file:///etc/blabla"), OUSTR("read,write,execute") ), invert
);
353 CHECK( ac
.checkFilePermission( OUSTR("file:///home/root"), OUSTR("read,write,execute") ), invert
);
354 CHECK( ac
.checkFilePermission( OUSTR("file:///root"), OUSTR("read,write,execute") ), invert
);
355 CHECK( ac
.checkRuntimePermission( OUSTR("ROOT") ), invert
);
358 //==================================================================================================
360 : public WeakImplHelper1
< security::XAccessControlContext
>
365 inline acc_Restr( Any
const & perm
= Any() ) SAL_THROW(())
369 // XAccessControlContext impl
370 virtual void SAL_CALL
checkPermission( Any
const & perm
)
371 throw (RuntimeException
);
373 //__________________________________________________________________________________________________
374 void acc_Restr::checkPermission( Any
const & perm
)
375 throw (RuntimeException
)
379 throw security::AccessControlException(
380 OUSTR("dyn violation!"), Reference
< XInterface
>(), perm
);
384 typedef void (* t_action
)( AccessControl
&, Any
const & arg
);
386 //==================================================================================================
388 : public WeakImplHelper1
< security::XAction
>
391 AccessControl
& m_ac
;
395 inline Action( t_action action
, AccessControl
& ac
, Any
const & arg
= Any() ) SAL_THROW(())
402 virtual Any SAL_CALL
run()
405 //__________________________________________________________________________________________________
409 (*m_action
)( m_ac
, m_arg
);
413 //==================================================================================================
414 // static void restr_file_permissions( AccessControl & ac )
416 // // running in dbo's domain
417 // /* permission com.sun.star.io.FilePermission "file:///home/dbo/-", ",,read , write "; */
418 // CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read,write,execute") ), true );
419 // CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read,write") ), false );
421 //==================================================================================================
422 static void all_dbo_permissions( AccessControl
& ac
, Any
const & )
427 //==================================================================================================
428 static void no_permissions( AccessControl
& ac
, Any
const & arg
)
430 check_dbo_pos( ac
, true );
432 // set privs to old dbo restr
433 Reference
< security::XAccessControlContext
> xContext
;
434 OSL_VERIFY( arg
>>= xContext
);
436 new Action( all_dbo_permissions
, ac
),
439 //==================================================================================================
440 static void check_dbo_dynamic( AccessControl
& ac
)
442 Any
arg( makeAny( ac
->getContext() ) );
444 new Action( no_permissions
, ac
, arg
),
453 Reference
< XComponentContext
> xContext( defaultBootstrap_InitialComponentContext(
454 OUSTR("../../test/security/test_security_singleuser.ini") ) );
456 ::fprintf( stderr
, "[security test] single-user checking dbo..." );
457 AccessControl
ac( xContext
);
460 check_dbo_dynamic( ac
);
461 ::fprintf( stderr
, "dbo checked.\n" );
466 xContext
= defaultBootstrap_InitialComponentContext(
467 OUSTR("../../test/security/test_security.ini") ); // UNO_AC=on
468 AccessControl
ac( xContext
);
471 // set up dbo current context
472 ContextLayer
layer( new user_CurrentContext( getCurrentContext(), OUSTR("dbo") ) );
473 ::fprintf( stderr
, "[security test] multi-user checking dbo..." );
476 check_dbo_dynamic( ac
);
477 ::fprintf( stderr
, "dbo checked.\n" );
480 // set up jbu current context
481 ContextLayer
layer( new user_CurrentContext( getCurrentContext(), OUSTR("jbu") ) );
482 ::fprintf( stderr
, "[security test] multi-user checking jbu..." );
485 ::fprintf( stderr
, "jbu checked.\n" );
488 // set up root current context
489 ContextLayer
layer( new user_CurrentContext( getCurrentContext(), OUSTR("root") ) );
490 ::fprintf( stderr
, "[security test] multi-user checking root..." );
491 check_root_pos( ac
);
492 ::fprintf( stderr
, "root checked.\n" );
495 // set up unknown guest user current context => default permissions
496 ContextLayer
layer( new user_CurrentContext( getCurrentContext(), OUSTR("guest") ) );
497 ::fprintf( stderr
, "[security test] multi-user checking guest..." );
498 check_defaults_pos( ac
);
499 check_defaults_neg( ac
);
500 ::fprintf( stderr
, "guest checked.\n" );
504 ::fprintf( stderr
, "security test succeeded.\n" );
507 catch (const Exception
& exc
)
509 OString
str( OUStringToOString( exc
.Message
, RTL_TEXTENCODING_ASCII_US
) );
510 ::fprintf( stderr
, "[security test] error: %s!\n", str
.getStr() );
515 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */