<html><head></head><body><div>Bi-directional GIOP as specified has a security problem, in that the way it works is the client sends a service context containing a sequence of ListenPoints:</div><div><br></div><pre>struct ListenPoint {</pre><pre>  string host;</pre><pre>  unsigned short port;</pre><pre>};</pre><pre>typedef sequence<ListenPoint> ListenPointList;</pre><pre><br></pre><pre>struct BiDirIIOPServiceContext {</pre><pre>  ListenPointList listen_points;</pre><pre>};</pre><div><br></div><div>Then the specification says:</div><div><br></div><div style="margin-left: 3ch;">"... If a host and port pair in a listen_points list matches a host and port, which the ORB intends to open a connection to, rather than open a new connection to that listen_point, the server may re-use any of the connections that were initiated by the client on which the listen point data was received."</div><div><br></div><div>What that means is that a client can send a service context that hijacks <i>any</i> outgoing calls that the server makes, just by claiming to be a suitable bi-directional target for the host and port!</div><div><br></div><div>To prevent that, omniORB only allows bi-directional calls to be made on object references that were received through the connection in question, in the assumption that if a client sent the object reference itself, it's fair to call it bidirectionally. In your case, getting the object references from the naming service, that clearly does not work.</div><div><br></div><div><br></div><div>There was an initiative to revise the bi-directional GIOP specification to address that, which is what is referred to in the code comment, but it was not accepted into the CORBA spec. The latest 3.4 / 3.3 CORBA spec still has the unchanged original mechanism. The document referred to in the source is only available to OMG members (which I currently am not), but I think a slightly later version of it is this, which is public:</div><div><br></div><div><a href="https://www.omg.org/cgi-bin/doc?orbos/01-08-03">https://www.omg.org/cgi-bin/doc?orbos/01-08-03</a></div><div><br></div><div>That includes a pretty complex cryptographic approach to avoid the problem. Not only is it complex, but it is now hopelessly obsolete because it requires the use of 1024-bit RSA and SHA-1 hashes, both of which are now considered weak. Regardless, that proposal was not adopted into the CORBA spec.</div><div><br></div><div><br></div><div>None of that helps you of course. I can think of two things you could do, one which is simple but requires changing your application, the other that might be more tricky.</div><div><br></div><div>The more tricky option is to modify omniORB to change the way it handles bi-directional, perhaps to relax the restriction that it only applies to object references received on the incoming connection. I think that will be tricky because it's quite deep-seated that the object reference matching is based on incoming connections.</div><div><br></div><div>The simpler thing would be for your client to expose an object that is a "lookup" object. Then when the server wants to look for a callback object, it calls into the client's lookup object (using bidirectional GIOP!), and that returns whichever object reference is required. The implementation of the lookup method could use the naming service, or look things up locally. The point of that design is that then the callback object reference <i>would</i> be received on the client's bidirectional connection, so the bidirectional logic would work.</div><div><br></div><div>Regards,</div><div><br></div><div>Duncan.</div><div><br></div><div><br></div><div>On Wed, 2022-04-20 at 12:39 +0000, Stefan Schweitzer via omniORB-list wrote:</div><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><div>Hello everybody,<br></div><div><br></div><div>I am trying to get my server application to pick up an existing rope from the client, and I am failing.<br></div><div><br></div><div>I have set up both my client and my server applications to support bidirectional GIOP. After debugging into omniORB, I am confident that all requirements regarding configuration have been met.<br></div><div><br></div><div>The problem seems to be of a different nature:<br></div><div>- Client invokes a server method but does NOT pass any object references. (This gets a TCP connection from client to server into existence.)<br></div><div>- Server wants do make callback to client.<br></div><div>- Server gets client IOR from COS Naming Service (!).<br></div><div>- omniObjRef::_unMarshal() unmarshals the string on the basis of a cdrMemoryStream passed by the calling method (which is omniObjRef::_fromString()).<br></div><div>- Since the stream is NOT a giopStream (but a cdrMemoryStream), _unMarshal() does NOT put TAG_OMNIORB_BIDIR into the IOR.<br></div><div>- This later leads to createObjRef() failing to select the existing bidir rope for the callback.<br></div><div><br></div><div>Why use the COS naming service to obtain the callback reference? - Because the receiver of the callback is one of hundreds of objects existing in the client, and the server is to decide who gets the callback, and we are reluctant to put hundreds of object references into any Server IDL interface method.<br></div><div><br></div><div>In the omniORB source code, I can see the following comment:<br></div><div><br></div><div>  // Provide interim BiDir GIOP support. Check the stream where this IOR<br></div><div>  // comes from. If it is a giopStream and this is the server side of<br></div><div>  // a bidirectional stream, add the component tag TAG_OMNIORB_BIDIR to the<br></div><div>  // ior's IOP profile list. The component will be decoded in createObjRef.<br></div><div>  //<br></div><div>  // In the next revision to bidir giop, as documented in OMG doc. 2001-06-04 <br></div><div>  // and if it ever gets adopted in a future GIOP version, the tag component<br></div><div>  // TAG_BI_DIR_GIOP will be embedded in the IOR and this step will be<br></div><div>  // redundent.<br></div><div><br></div><div>So, what does "interim BiDir GIOP support" mean here? Does it mean that server -> client rope selection works only in the scope of an upcall containing the client object reference (so the server unmarshals any object reference from a giopStream rather than a cdrMemoryStream)?<br></div><div><br></div><div>The CORBA standard says: " The client creates an object for exporting to a server, and arranges that the server receive an IOR for the object. The most common use case would be for the client to pass the IOR as a parameter in a GIOP request, but other mechanisms are possible, such as the use of a Name Service."<br></div><div><br></div><div>What about the TAG_BI_DIR_GIOP embedded in IORs; has it ever become part of the standard? I have not been able to find a lot of information about this.<br></div><div><br></div><div>Any hint is greatly appreciated. If I should be on the wrong track altogether, I would be glad to be told as well ;-). Thank you.<br></div><div><br></div><div>omniORB version 4.2.3<br></div><div><br></div><div>_______________________________________________<br></div><div>omniORB-list mailing list<br></div><div><a href="mailto:omniORB-list@omniorb-support.com">omniORB-list@omniorb-support.com</a><br></div><div><a href="https://www.omniorb-support.com/mailman/listinfo/omniorb-list">https://www.omniorb-support.com/mailman/listinfo/omniorb-list</a><br></div></blockquote><div><br></div><div><span><pre>-- <br></pre>Duncan Grisby <<a href="mailto:duncan@grisby.org">duncan@grisby.org</a>></span></div></body></html>