[omniORB] Interceptor access check - got there.

JHJE (Jan Holst Jensen) jhje at novonordisk.com
Mon Mar 20 16:26:07 GMT 2006


> 1) Sometimes there is no call descriptor. Seems to always be when the
> connection is established so I suspect that the server is 
> then handling a location forward request (?).

Turned out that it was in a "_is_a" call. I don't use calldescriptor()
anymore, so never mind.

The diff below adds write access checks to omniNames.cc - original
source from omniORB4.0.7 in omniNames-org.cc. Run omniNames with trace
level 10 or above to monitor access checks in action.

I hope that this can be useful to someone besides myself. It is OK for
blocking accidental overwrites of the name server but of course not good
enough for any real security.

I am fairly confident that the code is stable. I have run omniNames over
night with 4 machines (two Linux and two Windows) banging on it with the
script

  #!/bin/bash
  while ((1)); do
    the_ior=`nameclt resolve test.my_context/Echo.Object`
    nameclt bind test.my_context/EchoStressCopy.Object $the_ior
    nameclt -advanced rebind test.my_context/EchoStressCopy.Object
$the_ior
  done;

and I did not see any noticeable difference in CPU or memory usage
compared to running a plain vanilla omniNames.

I assume that it's OK to raise a NO_PERMISSION exception in the
interceptor ? It does not seem to do any harm as witnessed from the
stress test, and it produces the exact intended result on the client
side. But I was worried by the docs saying "If an interceptor returns
false, later interceptors are not called. You should only do that if you
really know what you are doing." Raising an exception is somewhat
equivalent, right ?

Finally, I apologize my old posting about access checks
http://www.omniorb-support.com/pipermail/omniorb-list/2003-June/023804.h
tml. Seems that the use of "PrincipalCurrent" is deprecated and was only
ever supported by MICO, judging from my Googling.

Cheers
-- Jan Holst Jensen, Novo Nordisk A/S, Denmark


*** omniNames-org.cc	Sun Mar 19 21:22:52 2006
--- omniNames.cc	Mon Mar 20 13:28:59 2006
***************
*** 31,36 ****
--- 31,46 ----
  #include <omnithread.h>
  #include <NamingContext_i.h>
  
+ // JHJe: Added following 7 includes.
+ #include <omniORB4/omniInterceptors.h>
+ #include <omniORB4/IOP_S.h>
+ #include <omniORB4/internal/giopStrand.h>
+ #include <omniORB4/internal/giopRope.h>
+ #include <omniORB4/internal/giopStreamImpl.h>
+ #include <omniORB4/internal/giopStream.h>
+ #include <omniORB4/internal/GIOP_S.h>
+ 
+ 
  #ifdef HAVE_STD
  #  include <iostream>
     using namespace std;
***************
*** 58,63 ****
--- 68,155 ----
  PortableServer::POA_var the_ins_poa;
  
  
+ // JHJe: Access check functions BEGIN.
+ 
+ OMNI_USING_NAMESPACE(omni)
+ 
+ const char* HOST_WRITE_ACCESS_FILE =
"/home/omni/omniNames.write.allow";
+ 
+ //
+ // Returns true if "peer_address" partially matches
+ // any entry in HOST_WRITE_ACCESS_FILE. See that file for 
+ // details and examples.
+ //
+ bool has_write_access(string& peer_address) {
+ 
+   ifstream access_list (HOST_WRITE_ACCESS_FILE);
+ 
+   if( !access_list.is_open() ) {
+     if( omniORB::trace(10) ) {
+       omniORB::logger log;
+       log << HOST_WRITE_ACCESS_FILE << " does not exist. No write
access checks enforced.\n";
+     }
+     return true;
+   }
+ 
+   bool result = false;
+   string valid_address;
+ 
+   while ( !access_list.eof() && !result ) {
+     getline(access_list, valid_address);
+     if( valid_address.length() > 0 && 
+         valid_address.find("#", 0) == string::npos ) {
+       result = peer_address.find(valid_address, 0) == 0;
+     }
+   }
+ 
+   return result;
+ }
+ 
+ //
+ // Interceptor implementing write access check.
+ //
+ static
+ CORBA::Boolean
+ check_write_access(omniInterceptors::serverReceiveRequest_T::info_T&
info) {
+ 
+   IOP_S& iop_stream = (IOP_S&)(info.giop_s);
+   string op_name = string(iop_stream.operation_name());
+ 
+   // Ignore read-only operations.
+   if( op_name != "bind" && 
+       op_name != "rebind" && 
+       op_name != "bind_context" && 
+       op_name != "rebind_context" && 
+       op_name != "unbind" && 
+       op_name != "new_context" && 
+       op_name != "bind_new_context" ) {
+     return true;
+   }
+ 
+   giopStrand& strand = (giopStrand&)((giopStream&)info.giop_s);
+   string strandPeerAddress = string(strand.connection->peeraddress());
+ 
+   if ( !has_write_access(strandPeerAddress) ) {
+     if( omniORB::trace(10) ) {
+       omniORB::logger log;
+       log << "Access denied to perform '" << op_name.c_str() << 
+              "' by " << strandPeerAddress.c_str() << "\n";
+     }
+     OMNIORB_THROW(NO_PERMISSION, 0, CORBA::COMPLETED_NO);
+   }
+ 
+   if( omniORB::trace(10) ) {
+     omniORB::logger log;
+     log << "Access granted to perform '" << op_name.c_str() << 
+            "' by " << strandPeerAddress.c_str() << "\n";
+   }
+ 
+   return true;
+ 
+ }
+ 
+ // JHJe: Access check functions END.
+ 
  void
  usage()
  {
***************
*** 205,210 ****
--- 297,306 ----
      return 1;
    }
  
+   // JHJe: Add write access check interceptor.
+   omniInterceptors* interceptors = omniORB::getInterceptors();
+   interceptors->serverReceiveRequest.add(check_write_access);
+ 
    try {
      CORBA::Object_var poaref =
orb->resolve_initial_references("RootPOA");
      PortableServer::POA_var poa =
PortableServer::POA::_narrow(poaref);


--------- /home/omni/omniNames.write.allow BEGIN -------------
# omniNames write allow list.
# JHJe 2006-03-17
#
# Blank lines and lines CONTAINING "#" are ignored.

# EXAMPLES:
# Allow a host name.
# giop:tcp:sc9.novo.dk:

# Partial address matching is used, so beware.
#
# E.g. allow anyone from 10.9 subnet access. 
# giop:tcp:10.9
#
# This will also allow clients from e.g. 10.9.18.250
# access.
# giop:tcp:10.9.18.25
#
# To enforce exact matching use the following:
# giop:tcp:10.9.18.25: 

#My own PC
giop:tcp:10.9.18.122:

#The test server running omniNames - so we can use nameclt.
giop:tcp:10.9.4.204:
--------- /home/omni/omniNames.write.allow END ---------------



More information about the omniORB-list mailing list