1 // -*- Mode: C++; -*-
2 // Package : omniORB
3 // ior.cc Created on: 5/7/96
4 // Author : Sai Lai Lo (sll)
5 //
6 // Copyright (C) 2002-2013 Apasphere Ltd
7 // Copyright (C) 1996-1999 AT&T Laboratories Cambridge
8 //
9 // This file is part of the omniORB library
10 //
11 // The omniORB library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Lesser General Public
13 // License as published by the Free Software Foundation; either
14 // version 2.1 of the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 // Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License along with this library. If not, see http://www.gnu.org/licenses/
23 //
24 //
25 // Description:
26 // *** PROPRIETARY INTERFACE ***
27 //
28
29 #include <omniORB4/CORBA.h>
30 #include <omniORB4/omniInterceptors.h>
31 #include <omniORB4/omniURI.h>
32 #include <exceptiondefs.h>
33 #include <initialiser.h>
34 #include <giopBiDir.h>
35 #include <SocketCollection.h>
36 #include <orbParameters.h>
37 #include <stdio.h>
38
OMNI_USING_NAMESPACE(omni)39 OMNI_USING_NAMESPACE(omni)
40
41 void
42 IOP::TaggedProfile::operator>>= (cdrStream &s) const {
43 tag >>= s;
44 profile_data >>= s;
45 }
46
47
48 void
operator <<=(cdrStream & s)49 IOP::TaggedProfile::operator<<= (cdrStream &s) {
50 tag <<= s;
51 profile_data <<= s;
52 }
53
54
55 void
operator >>=(cdrStream & s) const56 IOP::TaggedComponent::operator>>= (cdrStream& s) const {
57 tag >>= s;
58 component_data >>= s;
59 }
60
61 void
operator <<=(cdrStream & s)62 IOP::TaggedComponent::operator<<= (cdrStream& s) {
63 tag <<= s;
64 component_data <<= s;
65 }
66
67
68 void
operator >>=(cdrStream & s) const69 IOP::ServiceContext::operator>>= (cdrStream& s) const {
70 context_id >>= s;
71 context_data >>= s;
72 }
73
74 void
operator <<=(cdrStream & s)75 IOP::ServiceContext::operator<<= (cdrStream& s) {
76 context_id <<= s;
77 context_data <<= s;
78 }
79
80 void
operator <<=(cdrStream & s)81 IOP::IOR::operator<<= (cdrStream& s) {
82 type_id = unmarshaltype_id(s);
83 profiles <<= s;
84 }
85
86 void
operator >>=(cdrStream & s)87 IOP::IOR::operator>>= (cdrStream& s) {
88 type_id >>= s;
89 profiles >>= s;
90 }
91
92
93 char*
unmarshaltype_id(cdrStream & s)94 IOP::IOR::unmarshaltype_id(cdrStream& s) {
95 CORBA::ULong idlen;
96 CORBA::String_var id;
97
98 idlen <<= s;
99
100 if (!s.checkInputOverrun(1,idlen))
101 OMNIORB_THROW(MARSHAL,MARSHAL_SequenceIsTooLong,
102 (CORBA::CompletionStatus)s.completion());
103
104 switch (idlen) {
105
106 case 0:
107 #ifdef NO_SLOPPY_NIL_REFERENCE
108 OMNIORB_THROW(MARSHAL,MARSHAL_StringNotEndWithNull,
109 (CORBA::CompletionStatus)s.completion());
110 #else
111 // According to the CORBA specification 2.0 section 10.6.2:
112 // Null object references are indicated by an empty set of
113 // profiles, and by a NULL type ID (a string which contain
114 // only *** a single terminating character ***).
115 //
116 // Therefore the idlen should be 1.
117 // Visibroker for C++ (Orbeline) 2.0 Release 1.51 gets it wrong
118 // and sends out a 0 len string.
119 // We quietly accept it here. Turn this off by defining
120 // NO_SLOPPY_NIL_REFERENCE
121 id = CORBA::string_alloc(1);
122 ((char*)id)[0] = '\0';
123 #endif
124 break;
125
126 case 1:
127 id = CORBA::string_alloc(1);
128 ((char*)id)[0] = s.unmarshalOctet();
129 if (((char*)id)[0] != '\0')
130 OMNIORB_THROW(MARSHAL,MARSHAL_StringNotEndWithNull,
131 (CORBA::CompletionStatus)s.completion());
132 idlen = 0;
133 break;
134
135 default:
136 id = CORBA::string_alloc(idlen);
137 s.get_octet_array((CORBA::Octet*)((const char*)id), idlen);
138 if( ((char*)id)[idlen - 1] != '\0' )
139 OMNIORB_THROW(MARSHAL,MARSHAL_StringNotEndWithNull,
140 (CORBA::CompletionStatus)s.completion());
141 break;
142 }
143
144 return id._retn();
145 }
146
147 void
operator >>=(cdrStream & s) const148 IIOP::Address::operator>>= (cdrStream& s) const {
149 s.marshalRawString(host);
150 port >>= s;
151 }
152
153 void
operator <<=(cdrStream & s)154 IIOP::Address::operator<<= (cdrStream& s) {
155 host = s.unmarshalRawString();
156 port <<= s;
157 }
158
159 void
encodeProfile(const IIOP::ProfileBody & body,IOP::TaggedProfile & profile)160 IIOP::encodeProfile(const IIOP::ProfileBody& body,IOP::TaggedProfile& profile)
161 {
162 profile.tag = IOP::TAG_INTERNET_IOP;
163
164 {
165 cdrEncapsulationStream s((CORBA::ULong)0,1);
166 s.marshalOctet(body.version.major);
167 s.marshalOctet(body.version.minor);
168 s.marshalRawString(body.address.host);
169 body.address.port >>= s;
170 body.object_key >>= s;
171
172 if (body.version.minor > 0) {
173 CORBA::ULong total = body.components.length();
174 total >>= s;
175 for (CORBA::ULong index=0; index < total; index++) {
176 body.components[index] >>= s;
177 }
178 }
179
180 _CORBA_Octet* p;
181 CORBA::ULong max;
182 CORBA::ULong len;
183 s.getOctetStream(p,max,len);
184 profile.profile_data.replace(max,len,p,1);
185 }
186 }
187
188 void
encodeMultiComponentProfile(const IOP::MultipleComponentProfile & body,IOP::TaggedProfile & profile)189 IIOP::encodeMultiComponentProfile(const IOP::MultipleComponentProfile& body,
190 IOP::TaggedProfile& profile)
191 {
192 profile.tag = IOP::TAG_MULTIPLE_COMPONENTS;
193
194 {
195 cdrEncapsulationStream s((CORBA::ULong)0,1);
196 CORBA::ULong total = body.length();
197 if (total) {
198 total >>= s;
199 for (CORBA::ULong index=0; index < total; index++) {
200 body[index] >>= s;
201 }
202 }
203 _CORBA_Octet* p;
204 CORBA::ULong max;
205 CORBA::ULong len;
206 s.getOctetStream(p,max,len);
207 profile.profile_data.replace(max,len,p,1);
208 }
209 }
210
211
212 void
unmarshalProfile(const IOP::TaggedProfile & profile,IIOP::ProfileBody & body)213 IIOP::unmarshalProfile(const IOP::TaggedProfile& profile,
214 IIOP::ProfileBody& body)
215 {
216 OMNIORB_ASSERT(profile.tag == IOP::TAG_INTERNET_IOP);
217
218 cdrEncapsulationStream s(profile.profile_data.get_buffer(),
219 profile.profile_data.length(),
220 1);
221
222 body.version.major = s.unmarshalOctet();
223 body.version.minor = s.unmarshalOctet();
224
225 if (body.version.major != 1)
226 OMNIORB_THROW(MARSHAL,MARSHAL_InvalidIOR,CORBA::COMPLETED_NO);
227
228 body.address.host = s.unmarshalRawString();
229 body.address.port <<= s;
230 body.object_key <<= s;
231
232 if (body.version.minor > 0) {
233 CORBA::ULong total;
234 total <<= s;
235 if (total) {
236 if (!s.checkInputOverrun(1,total))
237 OMNIORB_THROW(MARSHAL,MARSHAL_InvalidIOR,CORBA::COMPLETED_NO);
238 body.components.length(total);
239 for (CORBA::ULong index=0; index<total; index++) {
240 body.components[index] <<= s;
241 }
242 }
243 }
244
245 // Check that the profile body ends here.
246 if (s.checkInputOverrun(1,1)) {
247 if (orbParameters::strictIIOP) {
248 omniORB::logs(10, "IIOP Profile has garbage at end");
249 OMNIORB_THROW(MARSHAL,MARSHAL_InvalidIOR,CORBA::COMPLETED_NO);
250 }
251 else
252 omniORB::logs(1, "Warning: IIOP Profile has garbage at end. Ignoring.");
253 }
254 }
255
256 void
unmarshalMultiComponentProfile(const IOP::TaggedProfile & profile,IOP::MultipleComponentProfile & body)257 IIOP::unmarshalMultiComponentProfile(const IOP::TaggedProfile& profile,
258 IOP::MultipleComponentProfile& body)
259 {
260 OMNIORB_ASSERT(profile.tag == IOP::TAG_MULTIPLE_COMPONENTS);
261
262 cdrEncapsulationStream s(profile.profile_data.get_buffer(),
263 profile.profile_data.length(),
264 1);
265
266 CORBA::ULong newitems;
267 newitems <<= s;
268 if (newitems) {
269 if (!s.checkInputOverrun(1,newitems))
270 OMNIORB_THROW(MARSHAL,MARSHAL_InvalidIOR,CORBA::COMPLETED_NO);
271
272 CORBA::ULong oldlen = body.length();
273 body.length(oldlen + newitems);
274 for (CORBA::ULong index = oldlen; index < oldlen+newitems; index++) {
275 body[index] <<= s;
276 }
277 }
278 // Check that the profile body ends here.
279 if (s.checkInputOverrun(1,1)) {
280 if (orbParameters::strictIIOP) {
281 omniORB::logs(10, "Multi-component profile has garbage at end");
282 OMNIORB_THROW(MARSHAL,MARSHAL_InvalidIOR,CORBA::COMPLETED_NO);
283 }
284 else
285 omniORB::logs(1, "Warning: Multi-component profile has "
286 "garbage at end. Ignoring.");
287 }
288 }
289
290
291 void
unmarshalObjectKey(const IOP::TaggedProfile & profile,_CORBA_Unbounded_Sequence_Octet & key)292 IIOP::unmarshalObjectKey(const IOP::TaggedProfile& profile,
293 _CORBA_Unbounded_Sequence_Octet& key)
294 {
295 OMNIORB_ASSERT(profile.tag == IOP::TAG_INTERNET_IOP);
296
297 cdrEncapsulationStream s(profile.profile_data.get_buffer(),
298 profile.profile_data.length(),
299 1);
300
301 CORBA::ULong len;
302 CORBA::UShort port;
303
304 // skip version
305 s.skipInput(2);
306
307 // skip address & port
308 len <<= s;
309 s.skipInput(len);
310 port <<= s;
311
312 len <<= s; // Get object key length
313
314 if (len > profile.profile_data.length())
315 OMNIORB_THROW(MARSHAL, MARSHAL_PassEndOfMessage,
316 CORBA::COMPLETED_NO);
317
318 if (s.readOnly()) {
319 CORBA::Octet* p = (CORBA::Octet*)((omni::ptr_arith_t)s.bufPtr() +
320 s.currentInputPtr());
321 key.replace(len,len,p,0);
322 }
323 else {
324 // If the cdrEncapsulationStream had to copy the profile data, we
325 // have to copy it _again_ here, otherwise it will be out of scope
326 // before the key is used.
327 key.length(len);
328 s.get_octet_array(key.NP_data(), len);
329 }
330 }
331
332 //////////////////////////////////////////////////////////////////////////
333 //////////////////////////////////////////////////////////////////////////
334 void
unmarshal_TAG_ORB_TYPE(const IOP::TaggedComponent & c,omniIOR & ior)335 omniIOR::unmarshal_TAG_ORB_TYPE(const IOP::TaggedComponent& c, omniIOR& ior)
336 {
337 OMNIORB_ASSERT(c.tag == IOP::TAG_ORB_TYPE);
338 cdrEncapsulationStream e(c.component_data.get_buffer(),
339 c.component_data.length(),1);
340 CORBA::ULong v;
341 v <<= e;
342 ior.getIORInfo()->orbType(v);
343 }
344
345
346 void
unmarshal_TAG_ALTERNATE_IIOP_ADDRESS(const IOP::TaggedComponent & c,omniIOR & ior)347 omniIOR::unmarshal_TAG_ALTERNATE_IIOP_ADDRESS(const IOP::TaggedComponent& c, omniIOR& ior)
348 {
349 OMNIORB_ASSERT(c.tag == IOP::TAG_ALTERNATE_IIOP_ADDRESS);
350 cdrEncapsulationStream e(c.component_data.get_buffer(),
351 c.component_data.length(),1);
352
353 IIOP::Address v;
354 v.host = e.unmarshalRawString();
355 v.port <<= e;
356 giopAddress* address = giopAddress::fromTcpAddress(v);
357 if (address == 0) return;
358 ior.getIORInfo()->addresses().push_back(address);
359 }
360
361
362 //////////////////////////////////////////////////////////////////////////
363 //////////////////////////////////////////////////////////////////////////
364 void
unmarshal_TAG_SSL_SEC_TRANS(const IOP::TaggedComponent & c,omniIOR & ior)365 omniIOR::unmarshal_TAG_SSL_SEC_TRANS(const IOP::TaggedComponent& c,
366 omniIOR& ior) {
367
368 OMNIORB_ASSERT(c.tag == IOP::TAG_SSL_SEC_TRANS);
369 cdrEncapsulationStream e(c.component_data.get_buffer(),
370 c.component_data.length(),1);
371
372 CORBA::UShort target_supports, target_requires, port;
373
374 try {
375 switch (c.component_data.length()) {
376 // Remember this is an encapsulation, so the length includes the
377 // first endian octet plus the necessary paddings after it
378 case 8:
379 {
380 // This is the standard format
381 target_supports <<= e;
382 target_requires <<= e;
383 port <<= e;
384 break;
385 }
386 default:
387 {
388 omniORB::logs(1, " decode TAG_SSL_SEC_TRANS "
389 "Warning: Wrong component size. Attempt to decode "
390 "it as the Visibroker non-compilant format");
391 CORBA::ULong v;
392 v <<= e; target_supports = (CORBA::UShort)v;
393 v <<= e; target_requires = (CORBA::UShort)v;
394 port <<= e;
395 break;
396 }
397 }
398 }
399 catch (...) {
400 omniORB::logs(1," decode TAG_SSL_SEC_TRANS "
401 "Warning: fail to decode the component. The format neither "
402 "conforms to the standard or is Visibroker proprietary.");
403 return;
404 }
405
406 giopAddressList& addresses = ior.getIORInfo()->addresses();
407 // The first address in the list is the host port combo stored in the
408 // IOR's address field. We have to copy the host name from there.
409 const char* tcpaddr = 0;
410 giopAddressList::iterator i, last;
411 i = addresses.begin();
412 last = addresses.end();
413 for (; i != last; i++) {
414 if (omni::strMatch((*i)->type(),"giop:tcp")) {
415 tcpaddr = (*i)->address();
416 break;
417 }
418 }
419 if (tcpaddr == 0) return;
420
421 CORBA::UShort tcp_port;
422 CORBA::String_var tcp_host = omniURI::extractHostPort(tcpaddr+9, tcp_port);
423
424 IIOP::Address ssladdr;
425 ssladdr.host = tcp_host._retn();
426 ssladdr.port = port;
427 giopAddress* address = giopAddress::fromSslAddress(ssladdr);
428 // If we do not have ssl transport linked the return value will be 0
429 if (address == 0) return;
430 ior.getIORInfo()->addresses().push_back(address);
431 }
432
433
434 //////////////////////////////////////////////////////////////////////////
435 //////////////////////////////////////////////////////////////////////////
436
437 void
unmarshal_TAG_CSI_SEC_MECH_LIST(const IOP::TaggedComponent & c,omniIOR & ior)438 omniIOR::unmarshal_TAG_CSI_SEC_MECH_LIST(const IOP::TaggedComponent& c,
439 omniIOR& ior) {
440
441 OMNIORB_ASSERT(c.tag == IOP::TAG_CSI_SEC_MECH_LIST);
442 cdrEncapsulationStream e(c.component_data.get_buffer(),
443 c.component_data.length(),1);
444
445 CORBA::Boolean stateful = e.unmarshalBoolean();
446
447 CORBA::ULong mech_count;
448 mech_count <<= e;
449
450 if (mech_count > c.component_data.length())
451 OMNIORB_THROW(MARSHAL, MARSHAL_PassEndOfMessage,
452 CORBA::COMPLETED_NO);
453
454 for (CORBA::ULong mech_idx = 0; mech_idx != mech_count; ++mech_idx) {
455 CORBA::UShort target_requires;
456
457 CORBA::UShort as_target_supports, as_target_requires;
458 _CORBA_Unbounded_Sequence_Octet as_client_authentication_mech;
459 _CORBA_Unbounded_Sequence_Octet as_target_name;
460
461 CORBA::UShort sas_target_supports, sas_target_requires;
462 CORBA::ULong sas_privilege_authorities_len;
463 _CORBA_Unbounded_Sequence<_CORBA_Unbounded_Sequence_Octet> sas_supported_naming_mechanisms;
464 CORBA::ULong sas_supported_identity_types;
465
466 // CompoundSecMech structure
467 target_requires <<= e;
468
469 IOP::TaggedComponent transport_mech;
470 transport_mech <<= e;
471
472 // as_context_mech member
473 as_target_supports <<= e;
474 as_target_requires <<= e;
475 as_client_authentication_mech <<= e;
476 as_target_name <<= e;
477
478 // sas_context_mech member
479 sas_target_supports <<= e;
480 sas_target_requires <<= e;
481 sas_privilege_authorities_len <<= e;
482
483 if (sas_privilege_authorities_len > transport_mech.component_data.length())
484 OMNIORB_THROW(MARSHAL, MARSHAL_PassEndOfMessage,
485 CORBA::COMPLETED_NO);
486
487 for (CORBA::ULong pi = 0; pi != sas_privilege_authorities_len; ++pi) {
488 CORBA::ULong syntax;
489 _CORBA_Unbounded_Sequence_Octet name;
490
491 syntax <<= e;
492 name <<= e;
493 }
494 sas_supported_naming_mechanisms <<= e;
495 sas_supported_identity_types <<= e;
496
497 if (as_target_requires == 0 &&
498 sas_target_requires == 0 &&
499 transport_mech.tag == IOP::TAG_TLS_SEC_TRANS) {
500
501 // No higher-level requirements and a TLS transport tag -- we
502 // can support this component.
503 CORBA::UShort tls_target_supports, tls_target_requires;
504 CORBA::ULong addresses_len;
505
506 cdrEncapsulationStream tls_e(transport_mech.component_data.get_buffer(),
507 transport_mech.component_data.length(),1);
508
509 tls_target_supports <<= tls_e;
510 tls_target_requires <<= tls_e;
511 addresses_len <<= tls_e;
512
513 if (addresses_len > transport_mech.component_data.length())
514 OMNIORB_THROW(MARSHAL, MARSHAL_PassEndOfMessage,
515 CORBA::COMPLETED_NO);
516
517 for (CORBA::ULong ai = 0; ai != addresses_len; ++ai) {
518 IIOP::Address ssladdr;
519
520 ssladdr.host = tls_e.unmarshalRawString();
521 ssladdr.port <<= tls_e;
522
523 giopAddress* address = giopAddress::fromSslAddress(ssladdr);
524 // If we do not have ssl transport linked the return value will be 0
525
526 if (address == 0) return;
527 ior.getIORInfo()->addresses().push_back(address);
528 }
529 }
530 }
531 }
532
533
534 //////////////////////////////////////////////////////////////////////////
535 //////////////////////////////////////////////////////////////////////////
536 void
unmarshal_TAG_OMNIORB_BIDIR(const IOP::TaggedComponent & c,omniIOR & ior)537 omniIOR::unmarshal_TAG_OMNIORB_BIDIR(const IOP::TaggedComponent& c,
538 omniIOR& ior) {
539
540 OMNIORB_ASSERT(c.tag == IOP::TAG_OMNIORB_BIDIR);
541 OMNIORB_ASSERT(ior.pd_iorInfo);
542
543 cdrEncapsulationStream e(c.component_data.get_buffer(),
544 c.component_data.length(),1);
545
546 char* sendfrom = e.unmarshalRawString();
547
548 BiDirInfo* info = new BiDirInfo(sendfrom);
549
550 omniIOR::IORExtraInfoList& infolist = ior.pd_iorInfo->extraInfo();
551 CORBA::ULong index = infolist.length();
552 infolist.length(index+1);
553 infolist[index] = (omniIOR::IORExtraInfo*)info;
554 }
555
556 void
add_TAG_OMNIORB_BIDIR(const char * sendfrom,omniIOR & ior)557 omniIOR::add_TAG_OMNIORB_BIDIR(const char* sendfrom,omniIOR& ior) {
558
559 cdrEncapsulationStream s(CORBA::ULong(0),CORBA::Boolean(1));
560 s.marshalRawString(sendfrom);
561
562 IOP::MultipleComponentProfile body;
563 body.length(1);
564 body[0].tag = IOP::TAG_OMNIORB_BIDIR;
565 CORBA::Octet* p; CORBA::ULong max,len; s.getOctetStream(p,max,len);
566 body[0].component_data.replace(max,len,p,1);
567
568 CORBA::ULong index = ior.pd_iopProfiles->length();
569 ior.pd_iopProfiles->length(index+1);
570 IIOP::encodeMultiComponentProfile(body,ior.pd_iopProfiles[index]);
571 }
572
573 //////////////////////////////////////////////////////////////////////////
574 //////////////////////////////////////////////////////////////////////////
575 void
unmarshal_TAG_OMNIORB_UNIX_TRANS(const IOP::TaggedComponent & c,omniIOR & ior)576 omniIOR::unmarshal_TAG_OMNIORB_UNIX_TRANS(const IOP::TaggedComponent& c,
577 omniIOR& ior) {
578
579 OMNIORB_ASSERT(c.tag == IOP::TAG_OMNIORB_UNIX_TRANS);
580 OMNIORB_ASSERT(ior.pd_iorInfo);
581
582 cdrEncapsulationStream e(c.component_data.get_buffer(),
583 c.component_data.length(),1);
584
585 CORBA::String_var host;
586 host = e.unmarshalRawString();
587 CORBA::String_var filename;
588 filename = e.unmarshalRawString();
589
590 // Check if we are on the same host and hence can use unix socket.
591 char self[OMNIORB_HOSTNAME_MAX];
592 if (gethostname(&self[0],OMNIORB_HOSTNAME_MAX) == RC_SOCKET_ERROR) {
593 self[0] = '\0';
594 omniORB::logs(1, "Cannot get the name of this host.");
595 }
596 if (strcmp(self,host) != 0) return;
597
598 const char* format = "giop:unix:%s";
599
600 CORBA::ULong len = strlen(filename);
601 if (len == 0) return;
602 len += strlen(format);
603 CORBA::String_var addrstr(CORBA::string_alloc(len));
604 sprintf(addrstr,format,(const char*)filename);
605
606 giopAddress* address = giopAddress::str2Address(addrstr);
607 // If we do not have unix transport linked the return value will be 0
608 if (address == 0) return;
609 ior.getIORInfo()->addresses().push_back(address);
610 }
611
612 //////////////////////////////////////////////////////////////////////////
613 //////////////////////////////////////////////////////////////////////////
614 void
unmarshal_TAG_OMNIORB_PERSISTENT_ID(const IOP::TaggedComponent & c,omniIOR & ior)615 omniIOR::unmarshal_TAG_OMNIORB_PERSISTENT_ID(const IOP::TaggedComponent& c,
616 omniIOR& ior)
617 {
618 OMNIORB_ASSERT(c.tag == IOP::TAG_OMNIORB_PERSISTENT_ID);
619
620 CORBA::ULong len = orbParameters::persistentId.length();
621
622 if (len && len == c.component_data.length()) {
623
624 const CORBA::Octet* a = c.component_data.get_buffer();
625 const CORBA::Octet* b = orbParameters::persistentId.get_buffer();
626 for (CORBA::ULong i=0; i < len; i++) {
627 if (*a++ != *b++)
628 return;
629 }
630
631 omniIOR::IORExtraInfoList& extra = ior.pd_iorInfo->extraInfo();
632 CORBA::ULong index = extra.length();
633 extra.length(index+1);
634 extra[index] = new IORExtraInfo(IOP::TAG_OMNIORB_PERSISTENT_ID);
635 }
636 }
637
638
639 static void
logPersistentIdentifier()640 logPersistentIdentifier()
641 {
642 omniORB::logger l;
643 l << "Persistent server identifier: ";
644
645 int c, n;
646 for (CORBA::ULong i=0; i < orbParameters::persistentId.length(); i++) {
647 c = orbParameters::persistentId[i];
648 n = (c & 0xf0) >> 4;
649 if (n >= 10)
650 l << (char)('a' + n - 10);
651 else
652 l << (char)('0' + n);
653
654 n = c & 0xf;
655 if (n >= 10)
656 l << (char)('a' + n - 10);
657 else
658 l << (char)('0' + n);
659 }
660 l << "\n";
661 }
662
663
664 void
665 omniORB::
setPersistentServerIdentifier(const _CORBA_Unbounded_Sequence_Octet & id)666 setPersistentServerIdentifier(const _CORBA_Unbounded_Sequence_Octet& id)
667 {
668 if (orbParameters::persistentId.length()) {
669 // Once set, it must not be changed
670 OMNIORB_THROW(INITIALIZE, INITIALIZE_FailedLoadLibrary,
671 CORBA::COMPLETED_NO);
672 }
673
674 orbParameters::persistentId = id;
675
676 if (omniORB::trace(10)) {
677 logPersistentIdentifier();
678 }
679 }
680
681
682
683
684 OMNI_NAMESPACE_BEGIN(omni)
685
686 //////////////////////////////////////////////////////////////////////////
687 //////////////////////////////////////////////////////////////////////////
688 // For the TAGs that the ORB will look at, add a handler to the following
689 // table.
690 //
691 static struct {
692 IOP::ComponentId id;
693 void (*fn)(const IOP::TaggedComponent&,omniIOR&);
694 } componentUnmarshalHandlers[] = {
695 // This table must be arranged in ascending order of IOP::ComponentId
696
697 { IOP::TAG_ORB_TYPE,
698 omniIOR::unmarshal_TAG_ORB_TYPE },
699
700 { IOP::TAG_CODE_SETS,
701 omniIOR::unmarshal_TAG_CODE_SETS },
702
703 { IOP::TAG_POLICIES, 0 },
704
705 { IOP::TAG_ALTERNATE_IIOP_ADDRESS,
706 omniIOR::unmarshal_TAG_ALTERNATE_IIOP_ADDRESS },
707
708 { IOP::TAG_COMPLETE_OBJECT_KEY, 0 },
709 { IOP::TAG_ENDPOINT_ID_POSITION, 0 },
710 { IOP::TAG_LOCATION_POLICY, 0 },
711 { IOP::TAG_ASSOCIATION_OPTIONS, 0 },
712 { IOP::TAG_SEC_NAME, 0 },
713 { IOP::TAG_SPKM_1_SEC_MECH, 0 },
714 { IOP::TAG_SPKM_2_SEC_MECH, 0 },
715 { IOP::TAG_KERBEROSV5_SEC_MECH, 0 },
716 { IOP::TAG_CSI_ECMA_SECRET_SEC_MECH, 0 },
717 { IOP::TAG_CSI_ECMA_HYBRID_SEC_MECH, 0 },
718
719 { IOP::TAG_SSL_SEC_TRANS,
720 omniIOR::unmarshal_TAG_SSL_SEC_TRANS },
721
722 { IOP::TAG_CSI_ECMA_PUBLIC_SEC_MECH, 0 },
723 { IOP::TAG_GENERIC_SEC_MECH, 0 },
724 { IOP::TAG_FIREWALL_TRANS, 0 },
725 { IOP::TAG_SCCP_CONTACT_INFO, 0 },
726 { IOP::TAG_JAVA_CODEBASE, 0 },
727
728 { IOP::TAG_CSI_SEC_MECH_LIST,
729 omniIOR::unmarshal_TAG_CSI_SEC_MECH_LIST },
730
731 { IOP::TAG_DCE_STRING_BINDING, 0 },
732 { IOP::TAG_DCE_BINDING_NAME, 0 },
733 { IOP::TAG_DCE_NO_PIPES, 0 },
734 { IOP::TAG_DCE_SEC_MECH, 0 },
735 { IOP::TAG_INET_SEC_TRANS, 0 },
736
737 { IOP::TAG_PRIMARY, 0 },
738 { IOP::TAG_HEARTBEAT_ENABLED, 0 },
739
740 { IOP::TAG_OMNIORB_BIDIR,
741 omniIOR::unmarshal_TAG_OMNIORB_BIDIR },
742
743 { IOP::TAG_OMNIORB_UNIX_TRANS,
744 omniIOR::unmarshal_TAG_OMNIORB_UNIX_TRANS },
745
746 { IOP::TAG_OMNIORB_PERSISTENT_ID,
747 omniIOR::unmarshal_TAG_OMNIORB_PERSISTENT_ID },
748
749 { 0xffffffff, 0 }
750 };
751
752 static int tablesize = 0;
753
754 OMNI_NAMESPACE_END(omni)
755
756 /////////////////////////////////////////////////////////////////////////////
757 // EndPoints and default IOR contents //
758 /////////////////////////////////////////////////////////////////////////////
759
760 OMNI_NAMESPACE_BEGIN(omni)
761
762 typedef _CORBA_Unbounded_Sequence_Octet OctetSeq;
763 typedef _CORBA_Unbounded_Sequence<OctetSeq> OctetSeqSeq;
764 typedef _CORBA_Unbounded_Sequence<IIOP::Address> AddressSeq;
765
766 class IORPublish {
767 public:
768 IIOP::Address address;
769 OctetSeqSeq alternative_addrs;
770 OctetSeqSeq ssl_addrs;
771 OctetSeqSeq unix_addrs;
772 OctetSeq csi_component;
773 AddressSeq tls_addrs;
774 CORBA::UShort tls_supports;
775 CORBA::UShort tls_requires;
776 CORBA::Boolean csi_enabled;
777
IORPublish()778 inline IORPublish() : tls_supports(0), tls_requires(0), csi_enabled(0)
779 {
780 address.port = 0;
781 }
782 };
783
784 static IORPublish my_eps;
785
786 static OctetSeq my_code_set;
787 static OctetSeq my_orb_type;
788
789 _CORBA_Unbounded_Sequence_Octet orbParameters::persistentId;
790
OMNI_NAMESPACE_END(omni)791 OMNI_NAMESPACE_END(omni)
792
793
794 IORPublish*
795 omniPolicy::EndPointPublishPolicy::getEPs()
796 {
797 if (!pd_eps) {
798 omniORB::logs(20, "Override published endpoints:");
799
800 pd_eps = new IORPublish;
801
802 for (CORBA::ULong idx=0; idx != pd_value.length(); ++idx) {
803 const char* ep = pd_value[idx];
804
805 if (omniORB::trace(20)) {
806 omniORB::logger log;
807 log << " override endpoint " << idx << ": '" << ep << "'\n";
808 }
809 giopEndpoint::addToIOR(pd_value[idx], pd_eps);
810 }
811 }
812 return pd_eps;
813 }
814
~EndPointPublishPolicy()815 omniPolicy::EndPointPublishPolicy::~EndPointPublishPolicy()
816 {
817 if (pd_eps)
818 delete pd_eps;
819 }
820
821
822 /////////////////////////////////////////////////////////////////////////////
823 void
add_IIOP_ADDRESS(const IIOP::Address & address,IORPublish * eps)824 omniIOR::add_IIOP_ADDRESS(const IIOP::Address& address, IORPublish* eps)
825 {
826 if (!eps)
827 eps = &my_eps;
828
829 if (eps->address.port == 0) {
830 eps->address = address;
831 }
832 else {
833 add_TAG_ALTERNATE_IIOP_ADDRESS(address, eps);
834 }
835 }
836
837 /////////////////////////////////////////////////////////////////////////////
838 void
add_TAG_CODE_SETS(const CONV_FRAME::CodeSetComponentInfo & info)839 omniIOR::add_TAG_CODE_SETS(const CONV_FRAME::CodeSetComponentInfo& info)
840 {
841 cdrEncapsulationStream s(CORBA::ULong(0),CORBA::Boolean(1));
842 info >>= s;
843
844 CORBA::Octet* p; CORBA::ULong max,len; s.getOctetStream(p,max,len);
845 my_code_set.replace(max,len,p,1);
846 }
847
848 /////////////////////////////////////////////////////////////////////////////
849 void
add_TAG_ALTERNATE_IIOP_ADDRESS(const IIOP::Address & address,IORPublish * eps)850 omniIOR::add_TAG_ALTERNATE_IIOP_ADDRESS(const IIOP::Address& address,
851 IORPublish* eps)
852 {
853 if (!eps)
854 eps = &my_eps;
855
856 cdrEncapsulationStream s(CORBA::ULong(0),CORBA::Boolean(1));
857 s.marshalRawString(address.host);
858 address.port >>= s;
859
860 CORBA::ULong index = eps->alternative_addrs.length();
861 eps->alternative_addrs.length(index+1);
862
863 s.setOctetSeq(eps->alternative_addrs[index]);
864 }
865
866 /////////////////////////////////////////////////////////////////////////////
867 void
add_TAG_SSL_SEC_TRANS(const IIOP::Address & address,CORBA::UShort supports,CORBA::UShort requires,IORPublish * eps)868 omniIOR::add_TAG_SSL_SEC_TRANS(const IIOP::Address& address,
869 CORBA::UShort supports,
870 CORBA::UShort requires,
871 IORPublish* eps)
872 {
873 if (!eps)
874 eps = &my_eps;
875
876 {
877 // Add to list of TLS addresses
878 CORBA::ULong length = eps->tls_addrs.length();
879 eps->tls_addrs.length(length+1);
880
881 eps->tls_addrs[length] = address;
882 eps->tls_supports = supports;
883 eps->tls_requires = requires;
884 }
885
886 if (strlen(eps->address.host) == 0) {
887 eps->address.host = address.host;
888 }
889 else if (strcmp(eps->address.host, address.host) != 0) {
890 // The address does not match the IIOP address. Cannot add as an
891 // SSL address. Enable the minimal CSI support.
892 eps->csi_enabled = 1;
893 return;
894 }
895
896 cdrEncapsulationStream s(CORBA::ULong(0),CORBA::Boolean(1));
897 supports >>= s;
898 requires >>= s;
899 address.port >>= s;
900
901 CORBA::ULong index = eps->ssl_addrs.length();
902 eps->ssl_addrs.length(index+1);
903
904 s.setOctetSeq(eps->ssl_addrs[index]);
905 }
906
907 /////////////////////////////////////////////////////////////////////////////
908 static
add_TAG_CSI_SEC_MECH_LIST(const _CORBA_Unbounded_Sequence<IIOP::Address> & addrs,CORBA::UShort supports,CORBA::UShort requires,IORPublish * eps)909 void add_TAG_CSI_SEC_MECH_LIST(const _CORBA_Unbounded_Sequence<IIOP::Address>& addrs,
910 CORBA::UShort supports,
911 CORBA::UShort requires,
912 IORPublish* eps)
913 {
914 if (!eps)
915 eps = &my_eps;
916
917 // Anyone would think this structure was designed by committee...
918
919 if (omniORB::trace(10)) {
920 omniORB::logger log;
921 log << "Create CSIv2 security mechanism list for " << addrs.length()
922 << " addresses.\n";
923 }
924
925 cdrEncapsulationStream stream(CORBA::ULong(0),CORBA::Boolean(1));
926
927 CORBA::UShort zeroUShort = 0;
928 CORBA::ULong zeroULong = 0;
929
930 // struct CompoundSecMechList {
931 // boolean stateful;
932 // CompoundSecMechanisms mechanism_list;
933 // };
934 stream.marshalBoolean(0);
935 CORBA::ULong mechanism_count = 1;
936 mechanism_count >>= stream;
937
938 // struct CompoundSecMech {
939 // AssociationOptions taget_requires;
940 // IOP::TaggedComponent transport_mech;
941 // AS_ContextSec as_context_mech;
942 // SAS_ContextSec sas_context_mech;
943 // };
944
945 requires >>= stream;
946
947 IOP::TaggedComponent transport_mech;
948 transport_mech.tag = IOP::TAG_TLS_SEC_TRANS;
949
950 cdrEncapsulationStream mech_stream(CORBA::ULong(0),CORBA::Boolean(1));
951
952 supports >>= mech_stream;
953 requires >>= mech_stream;
954 addrs >>= mech_stream;
955
956 {
957 CORBA::Octet* p;
958 CORBA::ULong max, len;
959 mech_stream.getOctetStream(p,max,len);
960 transport_mech.component_data.replace(max, len, p, 1);
961 }
962 transport_mech >>= stream;
963
964 // struct AS_ContextSec {
965 // AssociationOptions target_supports;
966 // AssociationOptions target_requires;
967 // CSI::OID client_authentication_mech;
968 // CSI::GSS_NT_ExportedName target_name;
969 // };
970 zeroUShort >>= stream;
971 zeroUShort >>= stream;
972 zeroULong >>= stream;
973 zeroULong >>= stream;
974
975 // struct SAS_ContextSec {
976 // AssociationOptions target_supports;
977 // AssociationOptions target_requires;
978 // ServiceConfigurationList privilege_authorities;
979 // CSI::OIDList supported_naming_mechanisms;
980 // CSI::IdentityTokenType supported_identity_types;
981 // };
982 zeroUShort >>= stream;
983 zeroUShort >>= stream;
984 zeroULong >>= stream;
985 zeroULong >>= stream;
986 zeroULong >>= stream;
987
988 stream.setOctetSeq(eps->csi_component);
989 }
990
991
992 /////////////////////////////////////////////////////////////////////////////
993 void
add_TAG_OMNIORB_UNIX_TRANS(const char * filename,IORPublish * eps)994 omniIOR::add_TAG_OMNIORB_UNIX_TRANS(const char* filename,
995 IORPublish* eps)
996 {
997 if (!eps)
998 eps = &my_eps;
999
1000 OMNIORB_ASSERT(filename && strlen(filename) != 0);
1001
1002 char self[OMNIORB_HOSTNAME_MAX];
1003 if (gethostname(&self[0],OMNIORB_HOSTNAME_MAX) == RC_SOCKET_ERROR) {
1004 omniORB::logs(1, "Cannot get the name of this host.");
1005 self[0] = '\0';
1006 }
1007
1008 if (strlen(eps->address.host) == 0) {
1009 eps->address.host = (const char*) self;
1010 }
1011
1012 cdrEncapsulationStream s(CORBA::ULong(0),CORBA::Boolean(1));
1013
1014 s.marshalRawString(self);
1015 s.marshalRawString(filename);
1016
1017 CORBA::ULong index = eps->unix_addrs.length();
1018 eps->unix_addrs.length(index+1);
1019
1020 s.setOctetSeq(eps->unix_addrs[index]);
1021 }
1022
1023
OMNI_NAMESPACE_BEGIN(omni)1024 OMNI_NAMESPACE_BEGIN(omni)
1025
1026 /////////////////////////////////////////////////////////////////////////////
1027 static
1028 CORBA::Boolean
1029 insertSupportedComponents(omniInterceptors::encodeIOR_T::info_T& info)
1030 {
1031 IORPublish* eps = &my_eps;
1032
1033 const GIOP::Version& v = info.iiop.version;
1034 IOP::MultipleComponentProfile& cs = info.iiop.components;
1035 const CORBA::PolicyList* policies = info.hints.policies;
1036
1037 // Is there an endpoint publishing override policy?
1038 if (policies) {
1039 for (CORBA::ULong idx=0; idx != policies->length(); ++idx) {
1040 CORBA::Policy_ptr policy = (*policies)[idx];
1041
1042 if (policy->policy_type() == omniPolicy::ENDPOINT_PUBLISH_POLICY_TYPE) {
1043 omniPolicy::EndPointPublishPolicy_var epp
1044 = omniPolicy::EndPointPublishPolicy::_narrow(policy);
1045
1046 if (CORBA::is_nil(epp))
1047 OMNIORB_THROW(INV_POLICY, INV_POLICY_InvalidPolicyType,
1048 CORBA::COMPLETED_NO);
1049
1050 eps = epp->getEPs();
1051 break;
1052 }
1053 }
1054 }
1055
1056 if (strlen(info.iiop.address.host) == 0) {
1057 if (strlen(eps->address.host) == 0) {
1058 OMNIORB_THROW(MARSHAL,MARSHAL_InvalidIOR,CORBA::COMPLETED_NO);
1059 }
1060 info.iiop.address = eps->address;
1061 }
1062
1063 if ((v.major > 1 || v.minor >= 1) && my_orb_type.length()) {
1064 // 1.1 or later, Insert ORB TYPE
1065 IOP::TaggedComponent& c = omniIOR::newIIOPtaggedComponent(cs);
1066 c.tag = IOP::TAG_ORB_TYPE;
1067 CORBA::ULong max, len;
1068 max = my_orb_type.maximum();
1069 len = my_orb_type.length();
1070 c.component_data.replace(max,len,my_orb_type.get_buffer(),0);
1071 }
1072
1073 if ((v.major > 1 || v.minor >= 2) && my_code_set.length()) {
1074 // 1.2 or later, Insert CODE SET
1075 IOP::TaggedComponent& c = omniIOR::newIIOPtaggedComponent(cs);
1076 c.tag = IOP::TAG_CODE_SETS;
1077 CORBA::ULong max, len;
1078 max = my_code_set.maximum();
1079 len = my_code_set.length();
1080 c.component_data.replace(max,len,my_code_set.get_buffer(),0);
1081 }
1082
1083 if (v.major > 1 || v.minor >= 2) {
1084 // 1.2 or later, Insert ALTERNATIVE IIOP ADDRESS
1085 for (CORBA::ULong index = 0;
1086 index < eps->alternative_addrs.length(); index++) {
1087
1088 IOP::TaggedComponent& c = omniIOR::newIIOPtaggedComponent(cs);
1089 c.tag = IOP::TAG_ALTERNATE_IIOP_ADDRESS;
1090 CORBA::ULong max, len;
1091 max = eps->alternative_addrs[index].maximum();
1092 len = eps->alternative_addrs[index].length();
1093 c.component_data.replace(max,len,
1094 eps->alternative_addrs[index].get_buffer(),0);
1095 }
1096 }
1097
1098 if (v.major > 1 || v.minor >= 1) {
1099 // 1.1 or later, Insert SSL_SEC_TRANS
1100 for (CORBA::ULong index = 0;
1101 index < eps->ssl_addrs.length(); index++) {
1102
1103 IOP::TaggedComponent& c = omniIOR::newIIOPtaggedComponent(cs);
1104 c.tag = IOP::TAG_SSL_SEC_TRANS;
1105 CORBA::ULong max, len;
1106 max = eps->ssl_addrs[index].maximum();
1107 len = eps->ssl_addrs[index].length();
1108 c.component_data.replace(max,len,
1109 eps->ssl_addrs[index].get_buffer(),0);
1110 }
1111 }
1112
1113 if (v.major > 1 || v.minor >= 1) {
1114 // 1.1 or later, Insert CSI_SEC_MECH_LIST
1115 if (eps->csi_enabled) {
1116 if (!eps->csi_component.length()) {
1117 add_TAG_CSI_SEC_MECH_LIST(eps->tls_addrs,
1118 eps->tls_supports, eps->tls_requires, eps);
1119 }
1120 IOP::TaggedComponent& c = omniIOR::newIIOPtaggedComponent(cs);
1121 c.tag = IOP::TAG_CSI_SEC_MECH_LIST;
1122
1123 CORBA::ULong max, len;
1124 max = eps->csi_component.maximum();
1125 len = eps->csi_component.length();
1126 c.component_data.replace(max,len,
1127 eps->csi_component.get_buffer(),0);
1128 }
1129 }
1130
1131 if (v.major > 1 || v.minor >= 2) {
1132 // 1.2 or later, Insert omniORB unix transport
1133 for (CORBA::ULong index = 0;
1134 index < eps->unix_addrs.length(); index++) {
1135
1136 IOP::TaggedComponent& c = omniIOR::newIIOPtaggedComponent(cs);
1137 c.tag = IOP::TAG_OMNIORB_UNIX_TRANS;
1138 CORBA::ULong max, len;
1139 max = eps->unix_addrs[index].maximum();
1140 len = eps->unix_addrs[index].length();
1141 c.component_data.replace(max,len,
1142 eps->unix_addrs[index].get_buffer(),0);
1143 }
1144 }
1145
1146 if (v.major > 1 || v.minor >= 1) {
1147 // 1.1 or later, insert omniORB persistent id
1148 if (orbParameters::persistentId.length()) {
1149 IOP::TaggedComponent& c = omniIOR::newIIOPtaggedComponent(cs);
1150 c.tag = IOP::TAG_OMNIORB_PERSISTENT_ID;
1151 c.component_data.replace(orbParameters::persistentId.maximum(),
1152 orbParameters::persistentId.length(),
1153 orbParameters::persistentId.get_buffer(), 0);
1154 }
1155 }
1156
1157 return (info.default_only ? 0 : 1);
1158 }
1159
1160 /////////////////////////////////////////////////////////////////////////////
1161 static
1162 CORBA::Boolean
extractSupportedComponents(omniInterceptors::decodeIOR_T::info_T & info)1163 extractSupportedComponents(omniInterceptors::decodeIOR_T::info_T& info)
1164 {
1165 if (!info.has_iiop_body) return 1;
1166
1167 omniIOR::IORInfo& iorInfo = *(info.ior.getIORInfo());
1168
1169 iorInfo.version(info.iiop.version);
1170
1171 giopAddress* address = giopAddress::fromTcpAddress(info.iiop.address);
1172 if (address)
1173 iorInfo.addresses().push_back(address);
1174
1175 if (!tablesize) {
1176 while (componentUnmarshalHandlers[tablesize].id != 0xffffffff) tablesize++;
1177 }
1178
1179 const IOP::MultipleComponentProfile& components = info.iiop.components;
1180
1181 CORBA::ULong total = components.length();
1182 for (CORBA::ULong index = 0; index < total; index++) {
1183
1184 int top = tablesize;
1185 int bottom = 0;
1186
1187 do {
1188 int i = (top + bottom) >> 1;
1189 IOP::ComponentId id = componentUnmarshalHandlers[i].id;
1190 if (id == components[index].tag) {
1191 if (componentUnmarshalHandlers[i].fn) {
1192 componentUnmarshalHandlers[i].fn(components[index],info.ior);
1193 }
1194 break;
1195 }
1196 else if (id > components[index].tag) {
1197 top = i;
1198 }
1199 else {
1200 bottom = i + 1;
1201 }
1202 } while (top != bottom);
1203 }
1204 return 1;
1205 }
1206
1207
1208 /////////////////////////////////////////////////////////////////////////////
1209 // Module initialiser //
1210 /////////////////////////////////////////////////////////////////////////////
1211
1212 class omni_ior_initialiser : public omniInitialiser {
1213 public:
omni_ior_initialiser()1214 omni_ior_initialiser() {}
1215
attach()1216 void attach() {
1217 my_eps.address.port = 0;
1218
1219 omniORB::getInterceptors()->encodeIOR.add(insertSupportedComponents);
1220 omniORB::getInterceptors()->decodeIOR.add(extractSupportedComponents);
1221
1222 cdrEncapsulationStream s(8,1);
1223 omniORB_TAG_ORB_TYPE >>= s;
1224 _CORBA_Octet* p; CORBA::ULong max,len; s.getOctetStream(p,max,len);
1225 my_orb_type.replace(max,len,p,1);
1226
1227 if (omniORB::trace(10) && orbParameters::persistentId.length()) {
1228 logPersistentIdentifier();
1229 }
1230
1231 }
1232
detach()1233 void detach() {
1234 omniORB::getInterceptors()->encodeIOR.remove(insertSupportedComponents);
1235 omniORB::getInterceptors()->decodeIOR.remove(extractSupportedComponents);
1236
1237 _CORBA_Unbounded_Sequence_Octet::freebuf(my_orb_type.get_buffer(1));
1238
1239 my_eps.alternative_addrs.length(0);
1240 my_eps.ssl_addrs.length(0);
1241 my_eps.unix_addrs.length(0);
1242 my_eps.csi_component.length(0);
1243 my_eps.tls_addrs.length(0);
1244 my_eps.csi_enabled = 0;
1245 }
1246
1247 };
1248
1249 static omni_ior_initialiser initialiser;
1250
1251 omniInitialiser& omni_ior_initialiser_ = initialiser;
1252
1253 OMNI_NAMESPACE_END(omni)
1254