21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.jndi.ldap;
27
28 import javax.naming.*;
29 import javax.naming.directory.*;
30 import javax.naming.spi.DirectoryManager;
31 import javax.naming.spi.DirStateFactory;
32
33 import java.io.IOException;
34 import java.io.ByteArrayInputStream;
35 import java.io.ByteArrayOutputStream;
36 import java.io.ObjectInputStream;
37 import java.io.ObjectOutputStream;
38 import java.io.ObjectStreamClass;
39 import java.io.InputStream;
40
41 import java.util.Hashtable;
42 import java.util.Vector;
43 import java.util.StringTokenizer;
44
45 import sun.misc.BASE64Encoder;
46 import sun.misc.BASE64Decoder;
47
48 import java.lang.reflect.Proxy;
49 import java.lang.reflect.Modifier;
50
51 /**
52 * Class containing static methods and constants for dealing with
53 * encoding/decoding JNDI References and Serialized Objects
54 * in LDAP.
55 * @author Vincent Ryan
56 * @author Rosanna Lee
57 */
58 final class Obj {
59
60 private Obj () {}; // Make sure no one can create one
61
62 // package private; used by Connection
63 static VersionHelper helper = VersionHelper.getVersionHelper();
64
65 // LDAP attributes used to support Java objects.
66 static final String[] JAVA_ATTRIBUTES = {
67 "objectClass",
307 if ((s = ref.getFactoryClassLocation()) != null) {
308 attrs.put(new BasicAttribute(JAVA_ATTRIBUTES[CODEBASE], s));
309 }
310
311 // Get original object's types if caller has not explicitly
312 // specified other type names
313 if (orig != null && attrs.get(JAVA_ATTRIBUTES[TYPENAME]) != null) {
314 Attribute tAttr =
315 LdapCtxFactory.createTypeNameAttr(orig.getClass());
316 if (tAttr != null) {
317 attrs.put(tAttr);
318 }
319 }
320
321 int count = ref.size();
322
323 if (count > 0) {
324
325 Attribute refAttr = new BasicAttribute(JAVA_ATTRIBUTES[REF_ADDR]);
326 RefAddr refAddr;
327 BASE64Encoder encoder = null;
328
329 for (int i = 0; i < count; i++) {
330 refAddr = ref.get(i);
331
332 if (refAddr instanceof StringRefAddr) {
333 refAttr.add(""+ separator + i +
334 separator + refAddr.getType() +
335 separator + refAddr.getContent());
336 } else {
337 if (encoder == null)
338 encoder = new BASE64Encoder();
339
340 refAttr.add(""+ separator + i +
341 separator + refAddr.getType() +
342 separator + separator +
343 encoder.encodeBuffer(serializeObject(refAddr)));
344 }
345 }
346 attrs.put(refAttr);
347 }
348 return attrs;
349 }
350
351 /*
352 * A RMI object is stored in the directory as
353 * javaClassName
354 * value: Object.getClass();
355 * javaRemoteLocation
356 * value: URL of RMI object (accessed through the RMI Registry)
357 * javaCodebase:
358 * value: URL of codebase of where to find classes for object
359 *
360 * Return the RMI Location URL itself. This will be turned into
361 * an RMI object when getObjectInstance() is called on it.
362 * %%% Ignore codebase for now. Depend on RMI registry to send code.-RL
363 * @deprecated For backward compatibility only
386
387 if ((attr = attrs.get(JAVA_ATTRIBUTES[FACTORY])) != null) {
388 factory = (String)attr.get();
389 }
390
391 Reference ref = new Reference(className, factory,
392 (codebases != null? codebases[0] : null));
393
394 /*
395 * string encoding of a RefAddr is either:
396 *
397 * #posn#<type>#<address>
398 * or
399 * #posn#<type>##<base64-encoded address>
400 */
401 if ((attr = attrs.get(JAVA_ATTRIBUTES[REF_ADDR])) != null) {
402
403 String val, posnStr, type;
404 char separator;
405 int start, sep, posn;
406 BASE64Decoder decoder = null;
407
408 ClassLoader cl = helper.getURLClassLoader(codebases);
409
410 /*
411 * Temporary Vector for decoded RefAddr addresses - used to ensure
412 * unordered addresses are correctly re-ordered.
413 */
414 Vector<RefAddr> refAddrList = new Vector<>();
415 refAddrList.setSize(attr.size());
416
417 for (NamingEnumeration<?> vals = attr.getAll(); vals.hasMore(); ) {
418
419 val = (String)vals.next();
420
421 if (val.length() == 0) {
422 throw new InvalidAttributeValueException(
423 "malformed " + JAVA_ATTRIBUTES[REF_ADDR] + " attribute - "+
424 "empty attribute value");
425 }
426 // first character denotes encoding separator
455 }
456 if ((type = val.substring(start, sep)) == null) {
457 throw new InvalidAttributeValueException(
458 "malformed " + JAVA_ATTRIBUTES[REF_ADDR] + " attribute - " +
459 "empty RefAddr type");
460 }
461 start = sep + 1; // skip over type and trailing separator
462
463 // extract content
464 if (start == val.length()) {
465 // Empty content
466 refAddrList.setElementAt(new StringRefAddr(type, null), posn);
467 } else if (val.charAt(start) == separator) {
468 // Double separators indicate a non-StringRefAddr
469 // Content is a Base64-encoded serialized RefAddr
470
471 ++start; // skip over consecutive separator
472 // %%% RL: exception if empty after double separator
473
474 if (decoder == null)
475 decoder = new BASE64Decoder();
476
477 RefAddr ra = (RefAddr)
478 deserializeObject(
479 decoder.decodeBuffer(val.substring(start)),
480 cl);
481
482 refAddrList.setElementAt(ra, posn);
483 } else {
484 // Single separator indicates a StringRefAddr
485 refAddrList.setElementAt(new StringRefAddr(type,
486 val.substring(start)), posn);
487 }
488 }
489
490 // Copy to real reference
491 for (int i = 0; i < refAddrList.size(); i++) {
492 ref.add(refAddrList.elementAt(i));
493 }
494 }
495
496 return (ref);
497 }
498
499 /*
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.jndi.ldap;
27
28 import javax.naming.*;
29 import javax.naming.directory.*;
30 import javax.naming.spi.DirectoryManager;
31 import javax.naming.spi.DirStateFactory;
32
33 import java.io.IOException;
34 import java.io.ByteArrayInputStream;
35 import java.io.ByteArrayOutputStream;
36 import java.io.ObjectInputStream;
37 import java.io.ObjectOutputStream;
38 import java.io.ObjectStreamClass;
39 import java.io.InputStream;
40
41 import java.util.Base64;
42 import java.util.Hashtable;
43 import java.util.Vector;
44 import java.util.StringTokenizer;
45
46 import java.lang.reflect.Proxy;
47 import java.lang.reflect.Modifier;
48
49 /**
50 * Class containing static methods and constants for dealing with
51 * encoding/decoding JNDI References and Serialized Objects
52 * in LDAP.
53 * @author Vincent Ryan
54 * @author Rosanna Lee
55 */
56 final class Obj {
57
58 private Obj () {}; // Make sure no one can create one
59
60 // package private; used by Connection
61 static VersionHelper helper = VersionHelper.getVersionHelper();
62
63 // LDAP attributes used to support Java objects.
64 static final String[] JAVA_ATTRIBUTES = {
65 "objectClass",
305 if ((s = ref.getFactoryClassLocation()) != null) {
306 attrs.put(new BasicAttribute(JAVA_ATTRIBUTES[CODEBASE], s));
307 }
308
309 // Get original object's types if caller has not explicitly
310 // specified other type names
311 if (orig != null && attrs.get(JAVA_ATTRIBUTES[TYPENAME]) != null) {
312 Attribute tAttr =
313 LdapCtxFactory.createTypeNameAttr(orig.getClass());
314 if (tAttr != null) {
315 attrs.put(tAttr);
316 }
317 }
318
319 int count = ref.size();
320
321 if (count > 0) {
322
323 Attribute refAttr = new BasicAttribute(JAVA_ATTRIBUTES[REF_ADDR]);
324 RefAddr refAddr;
325 Base64.Encoder encoder = null;
326
327 for (int i = 0; i < count; i++) {
328 refAddr = ref.get(i);
329
330 if (refAddr instanceof StringRefAddr) {
331 refAttr.add(""+ separator + i +
332 separator + refAddr.getType() +
333 separator + refAddr.getContent());
334 } else {
335 if (encoder == null)
336 encoder = Base64.getMimeEncoder();
337
338 // Base64.Encoder.encode method is used instead of
339 // encodeToString method to ensure Java object in LDAP
340 // is encoded with the same scheme as previous releases.
341 refAttr.add(""+ separator + i +
342 separator + refAddr.getType() +
343 separator + separator +
344 new String(encoder.encode(serializeObject(refAddr))));
345 }
346 }
347 attrs.put(refAttr);
348 }
349 return attrs;
350 }
351
352 /*
353 * A RMI object is stored in the directory as
354 * javaClassName
355 * value: Object.getClass();
356 * javaRemoteLocation
357 * value: URL of RMI object (accessed through the RMI Registry)
358 * javaCodebase:
359 * value: URL of codebase of where to find classes for object
360 *
361 * Return the RMI Location URL itself. This will be turned into
362 * an RMI object when getObjectInstance() is called on it.
363 * %%% Ignore codebase for now. Depend on RMI registry to send code.-RL
364 * @deprecated For backward compatibility only
387
388 if ((attr = attrs.get(JAVA_ATTRIBUTES[FACTORY])) != null) {
389 factory = (String)attr.get();
390 }
391
392 Reference ref = new Reference(className, factory,
393 (codebases != null? codebases[0] : null));
394
395 /*
396 * string encoding of a RefAddr is either:
397 *
398 * #posn#<type>#<address>
399 * or
400 * #posn#<type>##<base64-encoded address>
401 */
402 if ((attr = attrs.get(JAVA_ATTRIBUTES[REF_ADDR])) != null) {
403
404 String val, posnStr, type;
405 char separator;
406 int start, sep, posn;
407 Base64.Decoder decoder = null;
408
409 ClassLoader cl = helper.getURLClassLoader(codebases);
410
411 /*
412 * Temporary Vector for decoded RefAddr addresses - used to ensure
413 * unordered addresses are correctly re-ordered.
414 */
415 Vector<RefAddr> refAddrList = new Vector<>();
416 refAddrList.setSize(attr.size());
417
418 for (NamingEnumeration<?> vals = attr.getAll(); vals.hasMore(); ) {
419
420 val = (String)vals.next();
421
422 if (val.length() == 0) {
423 throw new InvalidAttributeValueException(
424 "malformed " + JAVA_ATTRIBUTES[REF_ADDR] + " attribute - "+
425 "empty attribute value");
426 }
427 // first character denotes encoding separator
456 }
457 if ((type = val.substring(start, sep)) == null) {
458 throw new InvalidAttributeValueException(
459 "malformed " + JAVA_ATTRIBUTES[REF_ADDR] + " attribute - " +
460 "empty RefAddr type");
461 }
462 start = sep + 1; // skip over type and trailing separator
463
464 // extract content
465 if (start == val.length()) {
466 // Empty content
467 refAddrList.setElementAt(new StringRefAddr(type, null), posn);
468 } else if (val.charAt(start) == separator) {
469 // Double separators indicate a non-StringRefAddr
470 // Content is a Base64-encoded serialized RefAddr
471
472 ++start; // skip over consecutive separator
473 // %%% RL: exception if empty after double separator
474
475 if (decoder == null)
476 decoder = Base64.getMimeDecoder();
477
478 // Java object in LDAP was encoded with the platform
479 // default charset.
480 RefAddr ra = (RefAddr)
481 deserializeObject(
482 decoder.decode(val.substring(start).getBytes()),
483 cl);
484
485 refAddrList.setElementAt(ra, posn);
486 } else {
487 // Single separator indicates a StringRefAddr
488 refAddrList.setElementAt(new StringRefAddr(type,
489 val.substring(start)), posn);
490 }
491 }
492
493 // Copy to real reference
494 for (int i = 0; i < refAddrList.size(); i++) {
495 ref.add(refAddrList.elementAt(i));
496 }
497 }
498
499 return (ref);
500 }
501
502 /*
|